em = $em; parent::__construct(); } protected function configure() { $this->setName('joborder:fulfillopenjosnosms') ->setDescription('Fulfill open job orders without sending an SMS message.') ->setHelp('Mark open job orders as fulfilled and should not send a SMS message. Date format: YYYY-MM-DD') ->addArgument('end_date', InputArgument::REQUIRED, 'End date. Format: YYYY-MM-DD'); } protected function execute(InputInterface $input, OutputInterface $output) { // load batteries into hash $this->populateBatteryIndex(); // load sap batteries into hash $this->populateSAPBatteryIndex(); // get the input date $str_date_end = $input->getArgument('end_date'); // append the 23:59:59 to end date $str_date_end = $str_date_end . ' ' . '23:59:59'; // starting time to count is date schedule $date_end = new DateTime($str_date_end); // get current date and convert to string $current_date = new DateTime(); $str_current_date = $current_date->format('Y-m-d H:i:s'); // find all open job orders starting from input date and before // need to get customer id, customer vehicle id, service type, warranty class $conn = $this->em->getConnection(); $jo_sql = 'SELECT jo.id AS jo_id, c.id AS c_id, cv.id AS cv_id, jo.service_type, jo.warranty_class, jo.rider_id, jo.date_schedule FROM job_order jo, customer c, customer_vehicle cv WHERE jo.customer_id = c.id AND jo.cvehicle_id = cv.id AND jo.status IN (\'pending\', \'rider_assign\', \'assigned\', \'in_transit\', \'in_progress\') AND jo.date_schedule <= :date_end'; $stmt = $conn->prepare($jo_sql); $stmt->execute([ 'date_end' => $str_date_end]); $jo_results = $stmt->fetchAll(); error_log('JOs found ' . count($jo_results)); $total_jos = count($jo_results); $jo_ctr = 0; $running_jo_total = 0; $running_jo_event_total = 0; $update_jo_ctr = 0; $update_wheres = []; $create_jo_event_ctr = 0; $jo_event_values = ''; foreach ($jo_results as $jo_row) { // get the data first $jo_id = $jo_row['jo_id']; $cust_id = $jo_row['c_id']; $cv_id = $jo_row['cv_id']; $service_type = $jo_row['service_type']; $warranty_class = $jo_row['warranty_class']; $rider_id = $jo_row['rider_id']; $str_date_schedule = $jo_row['date_schedule']; $jo_ctr++; // fulfill JO $this->fulfillJO($conn, $jo_id, $update_jo_ctr, $update_wheres, $jo_ctr, $total_jos); // create JO event $this->createJOEvent($conn, $jo_id, $str_current_date, $rider_id, $create_jo_event_ctr, $jo_event_values, $jo_ctr, $total_jos); // error_log($jo_ctr . ' Processing JO ' . $jo_id); // check service type if ($service_type == ServiceType::BATTERY_REPLACEMENT_NEW) { // new battery so we need to create warranty so we need to get battery id from invoice $batt_id = $this->getBatteryInformation($conn, $jo_id); if (($batt_id != null) && (isset($this->batt_hash[$batt_id]))) $this->createWarrantyForJO($conn, $current_date, $str_date_schedule, $cust_id, $cv_id, $warranty_class, $batt_id); } } return 0; } protected function fulfillJO($conn, $jo_id, &$update_jo_ctr, &$update_wheres, $jo_ctr, $total_jos) { $update_wheres[] = 'id = ' . $jo_id; // update db when we reach max # of JOs or when we reach total number of jos if (($update_jo_ctr == self::JO_BATCH_CTR) || ($jo_ctr == $total_jos)) { $update_where_string = implode(' OR ' , $update_wheres); // update job order $fulfill_jo_sql = 'UPDATE job_order SET status = :fulfilled, delivery_status = :del_fulfilled WHERE ' . $update_where_string; // error_log($fulfill_jo_sql); $fulfill_jo_stmt = $conn->prepare($fulfill_jo_sql); $fulfill_jo_stmt->execute([ 'fulfilled' => JOStatus::FULFILLED, 'del_fulfilled' => DeliveryStatus::FULFILLED, ]); // reset the wheres string $update_wheres = []; // reset the update jo counter $update_jo_ctr = 0; } else $update_jo_ctr++; } protected function createJOEvent($conn, $jo_id, $str_current_date, $rider_id, &$create_jo_event_ctr, &$jo_event_value_string, $jo_ctr, $total_jos) { // create jo event // set user to admin that has id of 1 $user_id = 1; $r_id = 'NULL'; // need to check rider id if null since that will change the jo_event_values // check if rider is null if ($rider_id != NULL) $r_id = $rider_id; // need to check rider id if null since that will change the jo_event_values $jo_event_values = '(' . $user_id . ',' . $jo_id . ',\'' . $str_current_date . '\',\'' . $str_current_date . '\',\'' . JOEventType::FULFILL . '\',' . $r_id . ')'; if (strlen($jo_event_value_string) == 0) { // first entry to insert, no comma before $jo_event_value_string = $jo_event_values; } else { // need to insert a comma after the existing string $jo_event_value_string = $jo_event_value_string . ',' . $jo_event_values; } // insert to db when we reach max # of JOs or when we reach total number of jos if (($create_jo_event_ctr == self::JO_EVENT_BATCH_CTR) || ($jo_ctr == $total_jos)) { $create_jo_event_sql = 'INSERT into `jo_event` (create_user_id, job_order_id, date_create, date_happen, type_id, rider_id) VALUES ' . $jo_event_value_string . ';' . "\n"; // error_log($create_jo_event_sql); $create_jo_event_stmt = $conn->prepare($create_jo_event_sql); $create_jo_event_stmt->execute(); // reset the counter and value string $jo_event_value_string = ''; $create_jo_event_ctr = 0; } else $create_jo_event_ctr++; } protected function getBatteryInformation($conn, $jo_id) { // break this down into two sql calls // get the invoice for job order $i_sql = 'SELECT i.id FROM invoice i WHERE i.job_order_id = :jo_id'; $i_stmt = $conn->prepare($i_sql); $i_stmt->execute([ 'jo_id' => $jo_id, ]); $i_result = $i_stmt->fetch(); // check if invoice exists if (empty($i_result)) return null; $invoice_id = $i_result['id']; // get the battery id from invoice item $ii_sql = 'SELECT ii.battery_id FROM invoice_item ii WHERE ii.invoice_id = :invoice_id AND ii.battery_id IS NOT NULL'; $ii_stmt = $conn->prepare($ii_sql); $ii_stmt->execute([ 'invoice_id' => $invoice_id, ]); $ii_result = $ii_stmt->fetch(); // checking for result if (empty($ii_result)) return null; $batt_id = $ii_result['battery_id']; return $batt_id; } protected function createWarrantyForJO($conn, $current_date, $str_date_schedule, $cust_id, $cv_id, $warranty_class, $batt_id) { // convert current date to string since we use this for date_create $str_current_date = $current_date->format('Y-m-d H:i:s'); // get the warranty period based on warranty class from battery hash $warranty_period = $this->getWarrantyPeriod($batt_id, $warranty_class); // compute date expiry. // convert to DateTime date schedule $date_schedule = DateTime::createFromFormat('Y-m-d H:i:s', $str_date_schedule); $date_expire = $this->computeDateExpire($date_schedule, $warranty_period); // convert to string the expiry date $str_date_expire = $date_expire->format('Y-m-d H:i:s'); // check if date_expire is after or equal to the current date // if so, set warranty status to active $warranty_status = WarrantyStatus::EXPIRED; if ($date_expire >= $current_date) $warranty_status = WarrantyStatus::ACTIVE; // get customer $cust_info = $this->getCustomerInfo($conn, $cust_id); // get customer vehicle $cv_info = $this->getCustomerVehicleInfo($conn, $cv_id); // customer info $first_name = addslashes($cust_info['first_name']); $last_name = addslashes($cust_info['last_name']); $mobile = addslashes($cust_info['mobile']); // customer vehicle info $plate_number = $cv_info['plate_number']; $vehicle_id = $cv_info['vehicle_id']; // battery info $model_id = $this->batt_hash[$batt_id]['model_id']; $size_id = $this->batt_hash[$batt_id]['size_id']; // need to confirm that sap_code exists in sap_battery if (isset($this->sap_batt_hash['sap_code'])) $sap_code = $this->batt_hash[$batt_id]['sap_code']; else $sap_code = 'NULL'; /* // create array for the infile $warranty_data = [ $model_id, $size_id, $sap_code, $warranty_class, $plate_number, $warranty_status, $str_current_date, $str_date_schedule, $str_date_expire, $first_name, $last_name, $mobile, $vehicle_id, $cust_id, $WarrantySource::ADMIN_PANEL, ]; */ // populate the values string for the values to be inserted into warranty // check for sap_code. Not all batteries have sap_code if ($sap_code == 'NULL') { $value_string = '(' . $model_id . ',' . $size_id . ',' . $sap_code . ',\'' . $warranty_class . '\',\'' . $plate_number . '\',\'' . $warranty_status . '\',\'' . $str_current_date . '\',\'' . $str_date_schedule . '\',\'' . $str_date_expire . '\',\'' . $first_name . '\',\'' . $last_name . '\',\'' . $mobile . '\',' . 1 . ',' . $vehicle_id . ',' . $cust_id . ',\'' . WarrantySource::ADMIN_PANEL . '\')'; } else { $value_string = '(' . $model_id . ',' . $size_id . ',\'' . $sap_code . '\',\'' . $warranty_class . '\',\'' . $plate_number . '\',\'' . $warranty_status . '\',\'' . $str_current_date . '\',\'' . $str_date_schedule . '\',\'' . $str_date_expire . '\',\'' . $first_name . '\',\'' . $last_name . '\',\'' . $mobile . '\',' . 1 . ',' . $vehicle_id . ',' . $cust_id . ',\'' . WarrantySource::ADMIN_PANEL . '\')'; } $sql_statement = 'INSERT INTO `warranty` (bty_model_id,bty_size_id,sap_bty_id,warranty_class,plate_number,status,date_create,date_purchase,date_expire,first_name,last_name,mobile_number,flag_activated,vehicle_id,customer_id, create_source) VALUES ' . $value_string . ';' . "\n"; // error_log($sql_statement); $stmt = $conn->prepare($sql_statement); $stmt->execute(); // $this->createLoadDataFileForWarranty($warranty_data); } protected function getCustomerInfo($conn, $id) { $cust_info = []; $cust_sql = 'SELECT c.first_name, c.last_name, c.phone_mobile FROM customer c WHERE c.id = :id'; $cust_stmt = $conn->prepare($cust_sql); $cust_stmt->execute([ 'id' => $id, ]); $cust_result = $cust_stmt->fetch(); $cust_info = [ 'first_name' => $cust_result['first_name'], 'last_name' => $cust_result['last_name'], 'mobile' => $cust_result['phone_mobile'], ]; return $cust_info; } protected function getCustomerVehicleInfo($conn, $id) { $cv_info = []; $cv_sql = 'SELECT cv.plate_number, cv.vehicle_id FROM customer_vehicle cv WHERE cv.id = :id'; $cv_stmt = $conn->prepare($cv_sql); $cv_stmt->execute([ 'id' => $id, ]); $cv_result = $cv_stmt->fetch(); $plate_number = $cv_result['plate_number']; $clean_plate = $this->cleanPlateNumber($plate_number); $cv_info = [ 'plate_number' => $clean_plate, 'vehicle_id' => $cv_result['vehicle_id'], ]; return $cv_info; } protected function getWarrantyPeriod($batt_id, $warranty_class) { // set default period to that of private $period = $this->batt_hash[$batt_id]['warr_private']; if ($warranty_class == WarrantyClass::WTY_PRIVATE) { $period = $this->batt_hash[$batt_id]['warr_private']; return $period; } if ($warranty_class == WarrantyClass::WTY_COMMERCIAL) { $period = $this->batt_hash[$batt_id]['warr_commercial']; return $period; } if ($warranty_class == WarrantyClass::WTY_TNV) { $period = $this->batt_hash[$batt_id]['warr_tnv']; return $period; } return $period; } protected function computeDateExpire($purchase_date, $warranty_period) { $expire_date = clone $purchase_date; $expire_date->add(new DateInterval('P'.$warranty_period.'M')); return $expire_date; } protected function cleanPlateNumber($plate) { // trim plate number down to 20 characters $trim_plate = str_replace(' ','', $plate); // truncate plate number down to 20 (max length) $trunc_plate = substr($trim_plate, 0, 20); return strtoupper($trunc_plate); } protected function populateBatteryIndex() { $conn = $this->em->getConnection(); // get all the batteries $sql = 'SELECT b.id, b.model_id, b.size_id, b.sap_code, b.warr_private, b.warr_commercial, b.warr_tnv FROM battery b'; $stmt = $conn->prepare($sql); $stmt->execute(); $results = $stmt->fetchAll(); // go through the rows foreach ($results as $row) { // breaking this down for clarity $battery_id = $row['id']; $model_id = $row['model_id']; $size_id = $row['size_id']; $sap_code = trim($row['sap_code']); $warr_private = $row['warr_private']; $warr_commercial = $row['warr_commercial']; $warr_tnv = $row['warr_tnv']; $this->batt_hash[$battery_id] = [ 'sap_code' => $sap_code, 'model_id' => $model_id, 'size_id' => $size_id, 'warr_private' => $warr_private, 'warr_commercial' => $warr_commercial, 'warr_tnv' => $warr_tnv, ]; } } protected function populateSAPBatteryIndex() { $conn = $this->em->getConnection(); // get all the sap batteries $sql = 'SELECT sap.id, sap.brand_id, sap.size_id FROM sap_battery sap'; $stmt = $conn->prepare($sql); $stmt->execute(); $results = $stmt->fetchAll(); // go through the rows foreach ($results as $row) { // set warranty period to default warranty period for SAP batteries $this->sap_batt_hash[$row['id']] = [ 'sap_brand' => $row['brand_id'], 'sap_size' => $row['size_id'], 'warranty' => self::DEFAULT_SAP_WARRANTY, ]; } } }