diff --git a/src/Command/FulfillOpenJobOrderCommand.php b/src/Command/FulfillOpenJobOrderCommand.php index 2fefc0d6..e18b5d2d 100644 --- a/src/Command/FulfillOpenJobOrderCommand.php +++ b/src/Command/FulfillOpenJobOrderCommand.php @@ -22,20 +22,16 @@ use App\Ramcar\WarrantyClass; use App\Ramcar\ServiceType; use App\Ramcar\WarrantySource; -use App\Service\WarrantyHandler; - use DateTime; use DateInterval; class FulfillOpenJobOrderCommand extends Command { protected $em; - protected $wh; - public function __construct(EntityManagerInterface $em, WarrantyHandler $wh) + public function __construct(EntityManagerInterface $em) { $this->em = $em; - $this->wh = $wh; parent::__construct(); } @@ -50,140 +46,244 @@ class FulfillOpenJobOrderCommand extends Command protected function execute(InputInterface $input, OutputInterface $output) { - /* - $sap_code = 'WSLMF9BR-RV100-L'; - - error_log($sap_code); - - $conn = $this->em->getConnection(); - $sql = 'SELECT sap.id FROM sap_battery sap WHERE sap.id = :id'; - $stmt = $conn->prepare($sql); - $stmt->execute(array('id' => $sap_code)); - - $query_results = $stmt->fetchColumn(); - - error_log($query_results); - - return 0; - */ - // 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'; - // retrieve job orders that are open and have not been fulfilled starting from input date and before. // starting time to count is date schedule $date_end = new DateTime($str_date_end); - error_log('mogol ' . $date_end->format('Y-m-d H:i:s')); + // get current date and convert to string + $current_date = new DateTime(); + $str_current_date = $current_date->format('Y-m-d H:i:s'); - /* - $query = $this->em->createQuery('SELECT jo FROM App\Entity\JobOrder jo - WHERE (jo.status = :pending_status - OR jo.status = :rider_assign_status - OR jo.status = :assigned_status - OR jo.status = :in_progress_status - OR jo.status = :in_transit_status) - AND jo.date_schedule <= :date_end - AND jo.service_type = :stype'); + // 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(); - $query->setParameters([ - 'pending_status' => JOStatus::PENDING, - 'rider_assign_status' => JOStatus::RIDER_ASSIGN, - 'assigned_status' => JOStatus::ASSIGNED, - 'in_progress_status' => JOStatus::IN_PROGRESS, - 'in_transit_status' => JOStatus::IN_TRANSIT, - 'date_end' => $date_end, - 'stype' => ServiceType::BATTERY_REPLACEMENT_NEW, - ])->setMaxResults(1); + $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 = $query->getResult(); + $jo_results = $stmt->fetchAll(); - error_log('Found job orders ' . count($jo_results)); + error_log('JOs found ' . count($jo_results)); - // get user. Use the admin user. - $user = $this->em->getRepository(User::class)->find(1); - - foreach ($jo_results as $jo) + foreach ($jo_results as $jo_row) { - error_log('Fulfilling job order ' . $jo->getID()); + // 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']; - //$jo->fulfill(); + // fulfill JO, create job order event + $this->processJOAndJOEvent($conn, $jo_id, $str_current_date, $rider_id); - // set delivery status - //$jo->setDeliveryStatus(DeliveryStatus::FULFILLED); + // 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); - // create JO event - //$event = new JOEvent(); - //$event->setDateHappen(new DateTime()) - // ->setTypeID(JOEventType::FULFILL) - // ->setJobOrder($jo) - // ->setUser($user); - - //$this->em->persist($event); - - // check if new battery - // if yes, create warranty - if ($this->checkIfNewBattery($jo)) - { - $this->createWarranty($jo, $user); + $this->createWarrantyForJO($str_current_date, $date_schedule, $cust_id, $cv_id, $warranty_class, $batt_info); } - } - - $this->em->flush(); - */ + } return 0; + } - protected function checkIfNewBattery(JobOrder $jo) + protected function processJOAndJOEvent($conn, $jo_id, $str_current_date, $rider_id) { - if ($jo->getServiceType() == ServiceType::BATTERY_REPLACEMENT_NEW) - return true; + $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, + //]); - return false; + // 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 createWarranty(JobOrder $jo, User $user) + protected function getBatteryInformation($jo_id) { - $serial = null; - $warranty_class = $jo->getWarrantyClass(); - $first_name = $jo->getCustomer()->getFirstName(); - $last_name = $jo->getCustomer()->getLastName(); - $mobile_number = $jo->getCustomer()->getPhoneMobile(); + $batt_info = []; - // use date_schedule for warranty expiration computation - $date_purchase = $jo->getDateSchedule(); + // 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, + ]); - // validate plate number - $plate_number = Warranty::cleanPlateNumber($jo->getCustomerVehicle()->getPlateNumber()); - if ($plate_number != false) - { - $batt_list = array(); - $invoice = $jo->getInvoice(); - if (!empty($invoice)) - { - // get battery - $invoice_items = $invoice->getItems(); - foreach ($invoice_items as $item) - { - $battery = $item->getBattery(); - if ($battery != null) - { - $batt_list[] = $item->getBattery(); - } - } - } + $ii_result = $ii_stmt->fetch(); - $user_id = $user->getUsername(); - $source = WarrantySource::ADMIN_PANEL; - $this->wh->createWarranty($serial, $plate_number, $first_name, $last_name, $mobile_number, $batt_list, $date_purchase, $warranty_class, $user_id, $source, $jo->getCustomer(), $jo->getCustomerVehicle()->getVehicle()); - } - else - { - error_log('Invalid plate number for warranty. Plate number = ' . $jo->getCustomerVehicle()->getPlateNumber()); - } + $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)); + } + }