resq/src/Command/FulfillOpenJobOrderCommand.php

289 lines
9.5 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 App\Entity\JobOrder;
use App\Entity\JOEvent;
use App\Entity\User;
use App\Entity\Warranty;
use App\Entity\SAPBattery;
use App\Ramcar\JOStatus;
use App\Ramcar\JOEventType;
use App\Ramcar\DeliveryStatus;
use App\Ramcar\WarrantyClass;
use App\Ramcar\ServiceType;
use App\Ramcar\WarrantySource;
use DateTime;
use DateInterval;
class FulfillOpenJobOrderCommand extends Command
{
protected $em;
public function __construct(EntityManagerInterface $em)
{
$this->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));
}
}