resq/src/Command/ImportCarClubCustomerDataCommand.php
2021-05-31 10:36:45 +00:00

387 lines
14 KiB
PHP

<?php
namespace App\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\ORM\EntityManagerInterface;
use DateTime;
use App\Entity\Customer;
use App\Entity\CustomerTag;
class ImportCarClubCustomerDataCommand extends Command
{
// field index in csv file
const F_TIMESTAMP = 0;
const F_DPA = 1;
const F_FIRST_NAME = 2;
const F_MIDDLE_NAME = 3;
const F_LAST_NAME = 4;
const F_BIRTHDATE = 5;
const F_ADDRESS = 6;
const F_CITY = 7;
const F_REGION = 8;
const F_CAR_CLUB = 9;
const F_POSITION = 10;
const F_MEMBER_NUM = 11;
const F_VEHICLE = 12;
const F_VEHICLE_EXCEL = 13;
const F_BATT_SIZE = 14;
const F_REPLACE_SKED = 15;
const F_DEALER_VISIT = 16;
const F_CONTACT_NUM = 17;
const F_BWI_LOCATION = 18;
const F_SAP_CODE = 19;
const F_SKU = 20;
const F_QTY = 21;
protected $em;
protected $cust_tag_hash;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
$this->loadCustomerTags();
parent::__construct();
}
protected function configure()
{
$this->setName('customer:createfromcarclub')
->setDescription('Create customers from car club file.')
->setHelp('Creates customers from car club file.')
->addArgument('input_file', InputArgument::REQUIRED, 'Path to the output CSV file with the car club info.')
->addArgument('output_file', InputArgument::REQUIRED, 'Output filename');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$csv_file = $input->getArgument('input_file');
$output_file = $input->getArgument('output_file');
// attempt to open file
try
{
$fh = fopen($csv_file, "r");
}
catch (Exception $e)
{
throw new Exception('The file "' . $csv_file . '" could be opened.');
}
$row_num = 1;
$output_info = [];
while (($fields = fgetcsv($fh)) !== false)
{
// ignore first row
if ($row_num == 1)
{
$row_num++;
continue;
}
$timestamp = trim($fields[self::F_TIMESTAMP]);
$mname = trim($fields[self::F_MIDDLE_NAME]);
$birthdate = trim($fields[self::F_BIRTHDATE]);
$address = trim($fields[self::F_ADDRESS]);
$city = trim($fields[self::F_CITY]);
$region = trim($fields[self::F_REGION]);
$car_club = trim($fields[self::F_CAR_CLUB]);
$position = trim($fields[self::F_POSITION]);
$member_number = trim($fields[self::F_MEMBER_NUM]);
$vehicle = trim($fields[self::F_VEHICLE]);
$vehicle_excel = trim($fields[self::F_VEHICLE_EXCEL]);
$batt_size = trim($fields[self::F_BATT_SIZE]);
$replace_sked = trim($fields[self::F_REPLACE_SKED]);
$dealer_visit = trim($fields[self::F_DEALER_VISIT]);
$bwi_location = trim($fields[self::F_BWI_LOCATION]);
$sap_code = trim($fields[self::F_SAP_CODE]);
$sku = trim($fields[self::F_SKU]);
$qty = trim($fields[self::F_QTY]);
$fname = trim($fields[self::F_FIRST_NAME]);
$lname = trim($fields[self::F_LAST_NAME]);
$dpa = trim($fields[self::F_DPA]);
$contact_number = trim($fields[SELF::F_CONTACT_NUM]);
// check customer tag
// find the customer tag for club
$tag_name = $this->normalizeClubName($car_club);
error_log($tag_name);
$cust_tag = null;
if (!isset($this->cust_tag_hash[$tag_name]))
{
error_log('customer tag not in hash...');
// create the customer tag
$new_cust_tag = new CustomerTag();
$tag_details = json_decode('{"type":"car club"}', true);
$new_cust_tag->setID($tag_name)
->setName(strtoupper($car_club))
->setTagDetails($tag_details);
$this->em->persist($new_cust_tag);
// need to flush before adding to hash
$this->em->flush();
$this->cust_tag_hash[$tag_name] = $new_cust_tag;
}
$cust_tag = $this->cust_tag_hash[$tag_name];
// check in case of multiple numbers
// check contact number if mobile or not
// check for spaces, slash, and forward slash
$contact_num_array = [];
$cust_id = '';
if (preg_match('/[\\\s\/]/', $contact_number))
{
$contact_num_array = preg_split('/[\\\s\/]/', $contact_number);
}
else
{
// only one mobile number
$contact_num_array[] = $contact_number;
}
foreach ($contact_num_array as $contact_num)
{
$c_num = trim($contact_num);
if (empty($c_num))
{
// add info to output array
$output_info[] = $this->addCustomerInfoEntry($timestamp, $dpa, $fname, $mname, $lname, $birthdate, $address, $city,
$region, $car_club, $position, $member_number, $vehicle, $vehicle_excel, $batt_size, $replace_sked,
$dealer_visit, $contact_number, $bwi_location, $sap_code, $sku, $qty, 'NOT CREATED', 'Missing contact number', $cust_id);
continue;
}
// remove any non digit character from string
$clean_number = preg_replace('~\D~', '', $c_num);
error_log('cleaned ' . $clean_number);
// does it fit our 09XXXXXXXXX pattern?
if (preg_match('/^09[0-9]{9}$/', $clean_number))
{
// remove first '0'
$clean_number = substr($clean_number, 1);
error_log("CONVERTED TO $clean_number");
}
// does it fit our 63XXXXXXXXXX pattern?
if (preg_match('/^63[0-9]{10}$/', $clean_number))
{
// remove the 63
$clean_number = substr($clean_number, 2);
error_log("CONVERTED TO $clean_number");
}
// does it fit our 9XXXXXXXXX pattern?
if (!preg_match('/^9[0-9]{9}$/', $clean_number))
{
error_log('not a mobile number');
// set clean_number to blank since we don't save a non-mobile number
$clean_number = '';
}
$customers = $this->findCustomerByNumber($c_num);
if (empty($customers))
{
error_log('Creating customer...');
error_log('cust tag id ' . $cust_tag->getID());
// check dpa
$is_dpa = false;
if (strtoupper($dpa) == 'YES')
$is_dpa = true;
// get the customer tag?
$c_tag = $this->em->getRepository(CustomerTag::class)->find($cust_tag->getID());
// create new customer
$new_cust = new Customer();
$new_cust->setFirstName($fname)
->setLastName($lname)
->setPhoneMobile($clean_number)
->setDpaConsent($is_dpa)
->setCreateSource('car_club_file')
->addCustomerTag($c_tag);
$this->em->persist($new_cust);
$this->em->flush();
// get customer id of new customer here
$cust_id = $new_cust->getId();
$this->em->clear();
// add info to output array
$output_info[] = $this->addCustomerInfoEntry($timestamp, $dpa, $fname, $mname, $lname, $birthdate, $address, $city,
$region, $car_club, $position, $member_number, $vehicle, $vehicle_excel, $batt_size, $replace_sked,
$dealer_visit, $contact_number, $bwi_location, $sap_code, $sku, $qty, 'CREATED', '', $cust_id);
}
else
{
error_log('Updating customer...');
// add customer tag to existing customer
foreach ($customers as $customer)
{
$cust_id = $customer->getID();
// need to check if customer tag already exists for customer
$tag_exists = $customer->getCustomerTag($cust_tag->getID());
if ($tag_exists == null)
{
$customer->addCustomerTag($cust_tag);
// add info to output array
$output_info[] = $this->addCustomerInfoEntry($timestamp, $dpa, $fname, $mname, $lname, $birthdate, $address, $city,
$region, $car_club, $position, $member_number, $vehicle, $vehicle_excel, $batt_size, $replace_sked,
$dealer_visit, $contact_number, $bwi_location, $sap_code, $sku, $qty, 'UPDATED', '', $cust_id);
}
else
{
// add info to output array
$output_info[] = $this->addCustomerInfoEntry($timestamp, $dpa, $fname, $mname, $lname, $birthdate, $address, $city,
$region, $car_club, $position, $member_number, $vehicle, $vehicle_excel, $batt_size, $replace_sked,
$dealer_visit, $contact_number, $bwi_location, $sap_code, $sku, $qty, 'NOT CREATED/UPDATED', 'CUSTOMER AND TAG ALREADY EXIST', $cust_id);
}
}
$this->em->flush();
$this->em->clear();
}
}
$row_num++;
}
// write to output file
$this->outputCustomerInfo($output_file, $output_info);
fclose($fh);
return 0;
}
protected function findCustomerByNumber($number)
{
$customers = $this->em->getRepository(Customer::class)->findBy(['phone_mobile' => $number]);
return $customers;
}
protected function addCustomerInfoEntry($timestamp, $dpa, $fname, $mname, $lname, $birthdate, $address, $city,
$region, $car_club, $position, $member_number, $vehicle, $vehicle_excel, $batt_size, $replace_sked,
$dealer_visit, $contact_number, $bwi_location, $sap_code, $sku, $qty, $status, $reason, $cust_id)
{
$output_entry = [
$timestamp,
$dpa,
$fname,
$mname,
$lname,
$birthdate,
$address,
$city,
$region,
$car_club,
$position,
$member_number,
$vehicle,
$vehicle_excel,
$batt_size,
$replace_sked,
$dealer_visit,
$contact_number,
$bwi_location,
$sap_code,
$sku,
$qty,
$status,
$reason,
$cust_id
];
return $output_entry;
}
protected function outputCustomerInfo($output_file, $entries)
{
try
{
$fh = fopen($output_file, "w");
}
catch (Exception $e)
{
throw new Exception('The file "' . $report_file . '" could be opened.');
}
// write the headers
fputcsv($fh, [
'Timestamp',
'I have read and understood and agreed to the confidentiality of this form request',
'First Name',
'Middle Name',
'Last Name',
'Birth date',
'Address',
'City',
'Region',
'Car Club/Organization',
'Position in the organization',
'Official Member Number (type NA if not applicable)',
'Vehicles you own? Year - Make -Model - Plate/Conduction number (ex 2017 NISSAN NAVARA ABC 1234) you can indicate all your vehicles',
'If your were given a chance to EXperience the New Motolite Excel, Choose 1 vehicle and it\'s plate/conduction number',
'What is the Battery size of the vehicle you with to EXperience the New Motolite Excel',
'Given a specific date, when can you schedule your replacement?',
'Will you be able to visit our dealer that we will assign nearest to you?',
'Contact Number',
'BWI LOCATION',
'SAP CODE',
'SKU',
'QTY',
'Status',
'Reason',
'Customer ID',
]);
foreach($entries as $row)
{
fputcsv($fh, $row);
}
fclose($fh);
}
protected function loadCustomerTags()
{
$this->cust_tag_hash = [];
$cust_tags = $this->em->getRepository(CustomerTag::class)->findAll();
foreach ($cust_tags as $cust_tag)
{
$tag_id = $cust_tag->getID();
$this->cust_tag_hash[$tag_id] = $cust_tag;
}
}
protected function normalizeClubName($name)
{
// uppercase the name
$clean_name = trim(strtoupper($name));
// remove apostrophes
$clean_name = str_replace("'", '', $clean_name);
// replace all special characters except ampersand (&) with whitespace
$clean_name = trim(preg_replace('/[^A-Za-z0-9&]/', ' ', $clean_name));
// replace spaces with underscore (_)
$clean_name = preg_replace('/\s+/', '_', $clean_name);
// prepend 'TAG_'
$tag_name = 'TAG_' . $clean_name;
return $tag_name;
}
}