em = $em; $this->initSAPBatteryHash(); $this->initSAPBatterySizeHash(); $this->initSAPBatteryBrandHash(); parent::__construct(); } protected function configure() { $this->setName('sap_battery:delta') ->setDescription('Update SAP battery table with new SAP battery data.') ->setHelp('Creates SAP battery data entries from CSV file.') ->addArgument('file', InputArgument::REQUIRED, 'Path to the CSV file.') ->addArgument('output_file', InputArgument::REQUIRED, 'Path to the output CSV file.'); } protected function execute(InputInterface $input, OutputInterface $output) { $csv_file = $input->getArgument('file'); $report_file = $input->getArgument('output_file'); // CSV column order: // 0 - brand // 1 - sku // 2 - size // attempt to open file try { $fh = fopen($csv_file, "r"); } catch (Exception $e) { throw new Exception('The file "' . $csv_file . '" could not be read.'); } // get entity manager $em = $this->em; // loop through the rows $row_num = 0; error_log('Processing sap battery csv file...'); $existing_brands = []; $existing_sizes = []; $existing_batteries = []; $added_brands = []; $added_sizes = []; $added_batteries = []; $not_added_batteries = []; $total_processed = 0; $total_not_processed = 0; while (($fields = fgetcsv($fh)) !== false) { // data starts at row 1 if ($row_num < 1) { $row_num++; continue; } // check if blank row if ((strlen(trim($fields[0])) == 0) && (strlen(trim($fields[1])) == 0) && (strlen(trim($fields[2])) == 0)) { $total_not_processed++; continue; } // clean up fields $clean_brand = $this->normalizeName(trim($fields[0])); $clean_sku = $this->normalizeName(trim($fields[1])); $clean_size = $this->normalizeName(trim($fields[2])); if ((empty($clean_brand)) || (empty($clean_sku)) || (empty($clean_size))) { $not_added_batteries[] = [ 'sku' => $clean_sku, 'brand' => $clean_brand, 'size' => $clean_size, ]; $total_not_processed++; continue; } // check if sap battery code already exists if (!isset($this->sap_battery_hash[$clean_sku])) { // check if brand in system $sap_brand = null; if (!isset($this->sap_battery_brand_hash[$clean_brand])) { // add brand $sap_brand = new SAPBatteryBrand(); $sap_brand->setName($clean_brand); $em->persist($sap_brand); // add to list of added brands $added_brands[$clean_brand] = $clean_brand; //$output->writeln('Adding brand: ' . $clean_brand); // add to hash $this->sap_battery_brand_hash[$clean_brand] = $sap_brand; } else { // get the brand $sap_brand = $this->sap_battery_brand_hash[$clean_brand]; // need to check if this is in added_brands because the hash contains // existing + added. What we need is the list of existing only if (!isset($added_brands[$clean_brand])) { // add to list of existing brands //$output->writeln('Brand already in db ' . $clean_brand); $existing_brands[$clean_brand] = $clean_brand; } } // check if size in system $sap_size = null; if (!isset($this->sap_battery_size_hash[$clean_size])) { // add size $sap_size = new SAPBatterySize(); $sap_size->setName($clean_size); $em->persist($sap_size); // add to list of added sizes $added_sizes[$clean_size] = $clean_size; //$output->writeln('Adding size: ' . $clean_size); // add to hash $this->sap_battery_size_hash[$clean_size] = $sap_size; } else { // get the size $sap_size = $this->sap_battery_size_hash[$clean_size]; // need to check if this is in added_sizes because the hash contains // existing + added. What we need is the list of existing only if (!isset($added_sizes[$clean_size])) { // add to list of existing sizes //$output->writeln('Size already in db ' . $clean_size); $existing_sizes[$clean_size] = $clean_size; } } // add the sap_battery // create sap battery entry $sap_battery = new SAPBattery(); $sap_battery->setID($clean_sku) ->setSize($sap_size) ->setBrand($sap_brand); $em->persist($sap_battery); // add to list of added batteries $added_batteries[$clean_sku] = $clean_sku; //$output->writeln('Adding battery: ' . $clean_sku); // add to hash $this->sap_battery_hash[$clean_sku] = $sap_battery; } else { // TODO: for now, assume that the brand and size in system == brand and size in csv file // need to check if this is in added_batteries because the hash contains // existing + added. What we need is the list of existing only if (!isset($added_batteries[$clean_sku])) { // add to list of existing batteries //$output->writeln('Battery already in db ' . $clean_sku); $existing_batteries[$clean_sku] = $this->sap_battery_hash[$clean_sku]; if (!isset($existing_brands[$clean_brand])) $existing_brands[$clean_brand] = $clean_brand; if (!isset($existing_sizes[$clean_size])) $existing_sizes[$clean_size] = $clean_size; } } $total_processed++; $row_num++; } $em->flush(); // need to output the list of added and not added data $this->writeOutputFile($report_file, $added_brands, $added_sizes, $added_batteries, $existing_brands, $existing_sizes, $existing_batteries, $total_processed, $not_added_batteries, $total_not_processed); return 0; } protected function initSAPBatteryHash() { $this->sap_battery_hash = []; $batts = $this->em->getRepository(SAPBattery::class)->findAll(); foreach ($batts as $batt) { $id = $this->normalizeName($batt->getID()); $this->sap_battery_hash[$id] = $batt; } } protected function initSAPBatterySizeHash() { $this->sap_battery_size_hash = []; $sizes = $this->em->getRepository(SAPBatterySize::class)->findAll(); foreach ($sizes as $size) { $name = $this->normalizeName($size->getName()); $this->sap_battery_size_hash[$name] = $size; } } protected function initSAPBatteryBrandHash() { $this->sap_battery_brand_hash = []; $brands = $this->em->getRepository(SAPBatteryBrand::class)->findAll(); foreach ($brands as $brand) { $name = $this->normalizeName($brand->getName()); $this->sap_battery_brand_hash[$name] = $brand; } } protected function writeOutputFile($report_file, $added_brands, $added_sizes, $added_batteries, $existing_brands, $existing_sizes, $existing_batteries, $total_processed, $bad_battery_data, $total_not_processed) { try { $fh = fopen($report_file, "w"); } catch (Exception $e) { throw new Exception('The file "' . $report_file . '" could be opened.'); } fputs($fh, 'Total entries processed: ' . $total_processed . "\n"); fputs($fh, 'Total entries not processed: ' . $total_not_processed . "\n"); fputs($fh, 'Total brands added: ' . count($added_brands) . "\n"); fputs($fh, 'Total sizes added: ' . count($added_sizes) . "\n"); fputs($fh, 'Total batteries added: ' . count($added_batteries) . "\n"); fputs($fh, 'Total number of brands in csv file that are in the system: ' . count($existing_brands) . "\n"); fputs($fh, 'Total number of sizes in csv file that are in the system: ' . count($existing_sizes) . "\n"); fputs($fh, 'Total number of batteries in csv file that are in the system: ' . count($existing_batteries) . "\n"); // write the batteries with bad data fputs($fh, 'Entry Not Added: ' . "\n"); foreach($bad_battery_data as $bad_batt) { $battery_line = $bad_batt['sku'] . ' ' . $bad_batt['brand'] . ' ' . $bad_batt['size']; fputs($fh, $battery_line, strlen($battery_line)); fputs($fh, "\n"); } // write the added batteries // check the existing brands array for the added ones $not_added_batteries = []; fputs($fh, 'Added Batteries: ' . "\n"); foreach($added_batteries as $added_battery) { fputs($fh, $added_battery, strlen($added_battery)); fputs($fh, "\n"); } // write the added brands // check the existing arrays for the added ones $not_added_brands = []; fputs($fh, 'Added Brands: ' . "\n"); foreach ($added_brands as $added_brand) { fputs($fh, $added_brand, strlen($added_brand)); fputs($fh, "\n"); } // write the added sizes // check the existing array for the added ones $not_added_sizes = []; fputs($fh, 'Added Sizes: ' . "\n"); foreach ($added_sizes as $added_size) { fputs($fh, $added_size, strlen($added_size)); fputs($fh, "\n"); } // write the not added batteries fputs($fh, 'Batteries already in system: ' . "\n"); foreach($existing_batteries as $not_added_battery) { fputs($fh, $not_added_battery->getID(), strlen($not_added_battery->getID())); fputs($fh, "\n"); } // write the not added brands fputs($fh, 'Brands already in system: ' . "\n"); foreach($existing_brands as $not_added_brand) { fputs($fh, $not_added_brand, strlen($not_added_brand)); fputs($fh, "\n"); } // write the not added sizes fputs($fh, 'Sizes already in system: ' . "\n"); foreach($existing_sizes as $not_added_size) { fputs($fh, $not_added_size, strlen($not_added_size)); fputs($fh, "\n"); } fclose($fh); } protected function normalizeName($name) { $normalized_key = trim(strtoupper($name)); return $normalized_key; } }