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) { // 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, i 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 != :cancelled OR jo.status != :fulfilled) AND jo.date_schedule <= :date_end'; $stmt = $conn->prepare($jo_sql); $stmt->execute(['cancelled' => JOStatus::CANCELLED, 'fulfilled' => JOStatus::FULFILLED, 'date_end' => $str_date_end]); $jo_results = $stmt->fetchAll(); error_log('JOs found ' . count($jo_results)); 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']; $date_schedule = $jo_row['date_schedule']; // fulfill JO, create job order event $this->processJOAndJOEvent($conn, $jo_id, $str_current_date, $rider_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 information $batt_info = $this->getBatteryInformation($jo_id); $this->createWarrantyForJO($str_current_date, $date_schedule, $cust_id, $cv_id, $warranty_class, $batt_info); } } return 0; } protected function processJOAndJOEvent($conn, $jo_id, $str_current_date, $rider_id) { $fulfill_jo_sql = 'UPDATE job_order SET status = :fulfilled WHERE id = :jo_id'; $fulfill_jo_stmt = $conn->prepare($fulfill_jo_sql); // TODO: don't forget to uncomment this when testing the whole thing //$fulfill_jo_stmt->execute([ // 'fulfilled' => JOStatus::FULFILLED, // 'jo_id' => $jo_id, //]); // create jo event // set user to admin that has id of 1 $user_id = 1; $jo_event_values = '(' . $user_id . ',' . $jo_id . ',\'' . $str_current_date . '\',\'' . $str_current_date . '\',\'' . JOEventType::FULFILL . '\',' . $rider_id . ')'; $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_values . ';' . "\n"; // error_log($create_jo_event_sql); $create_jo_event_stmt = $conn->prepare($create_jo_event_sql); // TODO: don't forget to uncomment this when testing the whole thing // $create_jo_event_stmt->execute(); } protected function getBatteryInformation($jo_id) { $batt_info = []; // get the battery id from invoice item $ii_sql = 'SELECT ii.id, ii.battery_id FROM invoice i, invoice_item ii WHERE i.job_order_id = :jo_id AND ii.invoice_id = i.id AND ii.battery_id IS NOT NULL'; $ii_stmt = $conn->prepare($ii_sql); $ii_stmt->execute([ 'jo_id' => $jo_id, ]); $ii_result = $ii_stmt->fetch(); $batt_id = $ii_result['battery_id']; // for battery, we need model id, size id, sap_code, warr_private, warr_commercial, warr_tnv $batt_sql = 'SELECT b.model_id, b.size_id, b.sap_code, b.warr_private, b.warr_commercial, b.warr_tnv FROM battery b WHERE b.id = :batt_id'; $batt_stmt = $conn->prepare($batt_sql); $batt_stmt->execute([ 'batt_id' => $batt_id, ]); $batt_result = $batt_stmt->fetch(); $batt_info[] = [ 'model_id' => $batt_result['model_id'], 'size_id' => $batt_result['size_id'], 'sap_code' => $batt_result['sap_code'], 'warr_private' => $batt_result['warr_private'], 'warr_commercial' => $batt_result['warr_commercial'], 'warr_tnv' => $batt_result['warr_tnv'], ]; return $batt_info; } protected function createWarrantyForJO($str_current_date, $date_schedule, $cust_id, $cv_id, $warranty_class, $batt_info) { $conn = $this->em->getConnection(); // prepare warranty info // convert date schedule to string since we use this for date_purchase $str_date_purchase = $date_schedule->format('Y-m-d H:i:s'); // get the warranty period based on warranty class from batt_info $warranty_period = $this->getWarrantyPeriod($batt_info, $warranty_class); // compute date expiry $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'); // get customer $cust_info = $this->getCustomerInfo($conn, $cust_id); // get customer vehicle $cv_info = $this->getCustomerVehicleInfo($conn, $cv_id); // TODO: prep sql_values for the insert warranty statement $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 ' . $sql_values . ';' . "\n"; } 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 FROM customer_vechicle 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, ]; return $cv_info; } protected function getWarrantyPeriod($batt_info, $warranty_class) { // set default period to that of private $period = $batt_info['warr_private'] ; if ($warranty_class == WarrantyClass::WTY_PRIVATE) { $period = $batt_info['warr_private']; return $period; } if ($warranty_class == WarrantyClass::WTY_COMMERCIAL) { $period = $batt_info['warr_commercial']; return $period; } if ($warranty_class == WarrantyClass::WTY_TNV) { $period = $batt_info['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) { return strtoupper(str_replace(' ', '', $plate)); } }