2982 lines
104 KiB
PHP
2982 lines
104 KiB
PHP
<?php
|
|
|
|
namespace App\Service\JobOrderHandler;
|
|
|
|
use Symfony\Component\Security\Core\Security;
|
|
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
|
|
|
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Doctrine\DBAL\Connection;
|
|
use Doctrine\DBAL\LockMode;
|
|
use Doctrine\ORM\PessimisticLockException;
|
|
|
|
use App\Entity\JobOrder;
|
|
use App\Entity\BatteryManufacturer;
|
|
use App\Entity\JOEvent;
|
|
use App\Entity\CustomerVehicle;
|
|
use App\Entity\Vehicle;
|
|
use App\Entity\Hub;
|
|
use App\Entity\Promo;
|
|
use App\Entity\Rider;
|
|
use App\Entity\JORejection;
|
|
use App\Entity\Warranty;
|
|
use App\Entity\Customer;
|
|
use App\Entity\ServiceCharge;
|
|
|
|
use App\Ramcar\InvoiceCriteria;
|
|
use App\Ramcar\CMBServiceType;
|
|
use App\Ramcar\CMBTradeInType;
|
|
use App\Ramcar\JOEventType;
|
|
use App\Ramcar\JOStatus;
|
|
use App\Ramcar\CMBWarrantyClass;
|
|
use App\Ramcar\DiscountApply;
|
|
use App\Ramcar\CMBModeOfPayment;
|
|
use App\Ramcar\TransactionOrigin;
|
|
use App\Ramcar\FacilitatedType;
|
|
use App\Ramcar\JORejectionReason;
|
|
|
|
use App\Service\InvoiceGeneratorInterface;
|
|
use App\Service\JobOrderHandlerInterface;
|
|
use App\Service\RiderAssignmentHandlerInterface;
|
|
use App\Service\CustomerHandlerInterface;
|
|
use App\Service\WarrantyHandler;
|
|
use App\Service\MQTTClient;
|
|
use App\Service\APNSClient;
|
|
use App\Service\MapTools;
|
|
|
|
use CrEOF\Spatial\PHP\Types\Geometry\Point;
|
|
|
|
use Mosquitto\Client as MosquittoClient;
|
|
|
|
use DateTime;
|
|
use DateInterval;
|
|
|
|
use FPDF;
|
|
|
|
class CMBJobOrderHandler implements JobOrderHandlerInterface
|
|
{
|
|
protected $em;
|
|
protected $ic;
|
|
protected $security;
|
|
protected $validator;
|
|
protected $translator;
|
|
protected $rah;
|
|
protected $country_code;
|
|
protected $wh;
|
|
protected $cust_handler;
|
|
|
|
protected $template_hash;
|
|
|
|
public function __construct(Security $security, EntityManagerInterface $em,
|
|
InvoiceGeneratorInterface $ic, ValidatorInterface $validator,
|
|
TranslatorInterface $translator, RiderAssignmentHandlerInterface $rah,
|
|
string $country_code, WarrantyHandler $wh,
|
|
CustomerHandlerInterface $cust_handler)
|
|
{
|
|
$this->em = $em;
|
|
$this->ic = $ic;
|
|
$this->security = $security;
|
|
$this->validator = $validator;
|
|
$this->translator = $translator;
|
|
$this->rah = $rah;
|
|
$this->country_code = $country_code;
|
|
$this->wh = $wh;
|
|
$this->cust_handler = $cust_handler;
|
|
|
|
$this->loadTemplates();
|
|
}
|
|
|
|
// get job order rows
|
|
public function getRows(Request $req, $tier)
|
|
{
|
|
// check which job order tier is being called for and confirm access
|
|
$tier_params = $this->checkTier($tier);
|
|
|
|
// get current user
|
|
$user = $this->security->getUser();
|
|
if ($user == null)
|
|
throw new AccessDeniedHttpException('No access.');
|
|
|
|
$hubs = $user->getHubs();
|
|
|
|
// get query builder
|
|
$qb = $this->em->getRepository(JobOrder::class)
|
|
->createQueryBuilder('q');
|
|
|
|
// get datatable params
|
|
$datatable = $req->request->get('datatable');
|
|
|
|
// count total records
|
|
$tquery = $qb->select('COUNT(q)');
|
|
|
|
$this->setQueryFilters($datatable, $tquery, $qb, $hubs, $tier, $tier_params['jo_status']);
|
|
|
|
$total = $tquery->getQuery()
|
|
->getSingleScalarResult();
|
|
|
|
// get current page number
|
|
$page = $datatable['pagination']['page'] ?? 1;
|
|
|
|
$perpage = $datatable['pagination']['perpage'];
|
|
$offset = ($page - 1) * $perpage;
|
|
|
|
// add metadata
|
|
$meta = [
|
|
'page' => $page,
|
|
'perpage' => $perpage,
|
|
'pages' => ceil($total / $perpage),
|
|
'total' => $total,
|
|
'sort' => 'asc',
|
|
'field' => 'id'
|
|
];
|
|
|
|
// build query
|
|
$qb = $this->em->getRepository(JobOrder::class)
|
|
->createQueryBuilder('q');
|
|
$query = $qb->select('q');
|
|
|
|
$this->setQueryFilters($datatable, $query, $qb, $hubs, $tier, $tier_params['jo_status']);
|
|
|
|
// check if sorting is present, otherwise use default
|
|
if (isset($datatable['sort']['field']) && !empty($datatable['sort']['field'])) {
|
|
$order = $datatable['sort']['sort'] ?? 'asc';
|
|
$query->orderBy('q.' . $datatable['sort']['field'], $order);
|
|
} else {
|
|
$query->orderBy('q.date_schedule', 'asc');
|
|
}
|
|
|
|
// get rows for this page
|
|
$query_obj = $query->setFirstResult($offset)
|
|
->setMaxResults($perpage)
|
|
->getQuery();
|
|
|
|
// error_log($query_obj->getSQL());
|
|
|
|
$obj_rows = $query_obj->getResult();
|
|
|
|
$statuses = JOStatus::getCollection();
|
|
$service_types = CMBServiceType::getCollection();
|
|
|
|
// process rows
|
|
$rows = [];
|
|
foreach ($obj_rows as $orow) {
|
|
// add row data
|
|
$row['id'] = $orow->getID();
|
|
$row['customer_name'] = $orow->getCustomer()->getFirstName() . ' ' . $orow->getCustomer()->getLastName();
|
|
$row['delivery_address'] = $orow->getDeliveryAddress();
|
|
$row['date_schedule'] = $orow->getDateSchedule()->format("d M Y g:i A");
|
|
$row['type'] = $orow->isAdvanceOrder() ? 'Advanced Order' : 'Immediate';
|
|
$row['service_type'] = $service_types[$orow->getServiceType()] ?? 'Unknown';
|
|
$row['status'] = $statuses[$orow->getStatus()];
|
|
$row['flag_advance'] = $orow->isAdvanceOrder();
|
|
$row['plate_number'] = $orow->getCustomerVehicle()->getPlateNumber();
|
|
$row['is_mobile'] = $orow->getSource() == TransactionOrigin::MOBILE_APP;
|
|
|
|
$processor = $orow->getProcessedBy();
|
|
if ($processor == null)
|
|
$row['processor'] = '';
|
|
else
|
|
$row['processor'] = $orow->getProcessedBy()->getFullName();
|
|
|
|
$assignor = $orow->getAssignedBy();
|
|
if ($assignor == null)
|
|
$row['assignor'] = '';
|
|
else
|
|
$row['assignor'] = $orow->getAssignedBy()->getFullName();
|
|
|
|
$rows[] = $row;
|
|
}
|
|
|
|
$params['meta'] = $meta;
|
|
$params['rows'] = $rows;
|
|
$params['tier_params'] = $tier_params;
|
|
|
|
return $params;
|
|
|
|
}
|
|
|
|
// get job orders
|
|
public function getJobOrders(Request $req)
|
|
{
|
|
// get search term
|
|
$term = $req->query->get('search');
|
|
|
|
// get querybuilder
|
|
$qb = $this->em->getRepository(JobOrder::class)
|
|
->createQueryBuilder('q');
|
|
|
|
// build expression now since we're reusing it
|
|
$jo_label = $qb->expr()->concat($qb->expr()->literal('#'), 'q.id', $qb->expr()->literal(' - '), 'c.first_name', $qb->expr()->literal(' '), 'c.last_name', $qb->expr()->literal(' (Plate No: '), 'v.plate_number', $qb->expr()->literal(')'));
|
|
|
|
// count total records
|
|
$tquery = $qb->select('COUNT(q)')
|
|
->join('q.customer', 'c')
|
|
->join('q.cus_vehicle', 'v');
|
|
|
|
// add filters to count query
|
|
if (!empty($term)) {
|
|
$tquery->where($jo_label . ' LIKE :filter')
|
|
->setParameter('filter', '%' . $term . '%');
|
|
}
|
|
|
|
$total = $tquery->getQuery()
|
|
->getSingleScalarResult();
|
|
|
|
// pagination vars
|
|
$page = $req->query->get('page') ?? 1;
|
|
$perpage = 20;
|
|
$offset = ($page - 1) * $perpage;
|
|
$pages = ceil($total / $perpage);
|
|
$has_more_pages = $page < $pages ? true : false;
|
|
|
|
// build main query
|
|
$query = $qb->select('q')
|
|
->addSelect($jo_label . ' as jo_label')
|
|
->addSelect('c.first_name as cust_first_name')
|
|
->addSelect('c.last_name as cust_last_name')
|
|
->addSelect('v.plate_number as vehicle_plate_number');
|
|
|
|
// add filters if needed
|
|
if (!empty($term)) {
|
|
$query->where($jo_label . ' LIKE :filter')
|
|
->setParameter('filter', '%' . $term . '%');
|
|
}
|
|
|
|
// get rows
|
|
$obj_rows = $query->orderBy('q.id', 'asc')
|
|
->setFirstResult($offset)
|
|
->setMaxResults($perpage)
|
|
->getQuery()
|
|
->getResult();
|
|
|
|
// build job order array
|
|
$job_orders = [];
|
|
|
|
foreach ($obj_rows as $jo) {
|
|
$service_type = CMBServiceType::getName($jo[0]->getServiceType());
|
|
|
|
$job_orders[] = [
|
|
'id' => $jo[0]->getID(),
|
|
'text' => $jo['jo_label'] . ' - ' . $service_type
|
|
];
|
|
}
|
|
|
|
$params['job_orders'] = $job_orders;
|
|
$params['has_more_pages'] = $has_more_pages;
|
|
|
|
return $params;
|
|
}
|
|
|
|
// creates/updates job order
|
|
public function generateJobOrder(Request $req, $id)
|
|
{
|
|
// initialize error list
|
|
$error_array = [];
|
|
|
|
$em = $this->em;
|
|
|
|
$jo = $em->getRepository(JobOrder::class)->find($id);
|
|
if (empty($jo))
|
|
{
|
|
// new job order
|
|
$jo = new JobOrder();
|
|
}
|
|
|
|
// check if lat and lng are provided
|
|
if (empty($req->request->get('coord_lng')) || empty($req->request->get('coord_lat'))) {
|
|
$error_array['coordinates'] = 'No map coordinates provided. Please click on a location on the map.';
|
|
}
|
|
|
|
// check if customer vehicle is set
|
|
if (empty($req->request->get('customer_vehicle'))) {
|
|
$error_array['customer_vehicle'] = 'No vehicle selected.';
|
|
} else {
|
|
// get customer vehicle
|
|
$cust_vehicle = $em->getRepository(CustomerVehicle::class)->find($req->request->get('customer_vehicle'));
|
|
|
|
if (empty($cust_vehicle)) {
|
|
$error_array['customer_vehicle'] = 'Invalid vehicle specified.';
|
|
}
|
|
}
|
|
|
|
if (empty($error_array)) {
|
|
// get current user
|
|
$user = $this->security->getUser();
|
|
|
|
// coordinates
|
|
$point = new Point($req->request->get('coord_lng'), $req->request->get('coord_lat'));
|
|
|
|
$stype = $req->request->get('service_type');
|
|
|
|
// set and save values
|
|
$jo->setDateSchedule(DateTime::createFromFormat("d M Y h:i A", $req->request->get('date_schedule_date') . " " . $req->request->get('date_schedule_time')))
|
|
->setCoordinates($point)
|
|
->setAdvanceOrder($req->request->get('flag_advance') ?? false)
|
|
->setServiceType($stype)
|
|
->setWarrantyClass($req->request->get('warranty_class'))
|
|
->setCustomer($cust_vehicle->getCustomer())
|
|
->setCustomerVehicle($cust_vehicle)
|
|
->setSource($req->request->get('source'))
|
|
->setStatus(JOStatus::PENDING)
|
|
->setDeliveryInstructions($req->request->get('delivery_instructions'))
|
|
->setTier1Notes($req->request->get('tier1_notes'))
|
|
->setTier2Notes($req->request->get('tier2_notes'))
|
|
->setDeliveryAddress($req->request->get('delivery_address'))
|
|
->setORName($req->request->get('or_name'))
|
|
->setPromoDetail($req->request->get('promo_detail'))
|
|
->setModeOfPayment($req->request->get('mode_of_payment'))
|
|
->setLandmark($req->request->get('landmark'));
|
|
|
|
// check if user is null, meaning call to create came from API
|
|
if ($user != null)
|
|
{
|
|
$jo->setCreatedBy($user);
|
|
}
|
|
|
|
// check if reference JO is set and validate
|
|
if (!empty($req->request->get('ref_jo'))) {
|
|
// get reference JO
|
|
$ref_jo = $em->getRepository(JobOrder::class)->find($req->request->get('ref_jo'));
|
|
|
|
if (empty($ref_jo)) {
|
|
$error_array['ref_jo'] = 'Invalid reference job order specified.';
|
|
} else {
|
|
$jo->setReferenceJO($ref_jo);
|
|
}
|
|
}
|
|
|
|
// call service to generate job order and invoice
|
|
$invoice_items = $req->request->get('invoice_items', []);
|
|
$promo_id = $req->request->get('invoice_promo');
|
|
$invoice_change = $req->request->get('invoice_change', 0);
|
|
|
|
// check if invoice changed
|
|
if ($invoice_change)
|
|
{
|
|
$this->ic->generateInvoiceCriteria($jo, $promo_id, $invoice_items, $error_array);
|
|
}
|
|
|
|
// validate
|
|
$errors = $this->validator->validate($jo);
|
|
|
|
// add errors to list
|
|
foreach ($errors as $error) {
|
|
$error_array[$error->getPropertyPath()] = $error->getMessage();
|
|
}
|
|
|
|
// check if errors are found
|
|
if (empty($error_array))
|
|
{
|
|
// validated, no error. save the job order
|
|
$em->persist($jo);
|
|
|
|
// the event
|
|
$event = new JOEvent();
|
|
$event->setDateHappen(new DateTime())
|
|
->setTypeID(JOEventType::CREATE)
|
|
->setJobOrder($jo);
|
|
|
|
if ($user != null)
|
|
{
|
|
$event->setUser($user);
|
|
}
|
|
|
|
$em->persist($event);
|
|
$em->flush();
|
|
}
|
|
}
|
|
|
|
return $error_array;
|
|
}
|
|
|
|
public function processOneStepJobOrder(Request $req, $id)
|
|
{
|
|
// initialize error list
|
|
$error_array = [];
|
|
|
|
$em = $this->em;
|
|
|
|
$jo = $em->getRepository(JobOrder::class)->find($id);
|
|
if (empty($jo))
|
|
{
|
|
// new job order
|
|
$jo = new JobOrder();
|
|
}
|
|
|
|
// check if lat and lng are provided
|
|
if (empty($req->request->get('coord_lng')) || empty($req->request->get('coord_lat'))) {
|
|
$error_array['coordinates'] = 'No map coordinates provided. Please click on a location on the map.';
|
|
}
|
|
|
|
// check if new customer
|
|
if ($req->request->get('new_customer'))
|
|
{
|
|
if (empty($req->request->get('customer_customer_notes')))
|
|
{
|
|
$error_array['customer_customer_notes'] = 'Customer notes cannot be null.';
|
|
}
|
|
|
|
// validate mobile phone
|
|
$valid_mobile = $this->cust_handler->validateMobileNumber($req->request->get('customer_phone_mobile'));
|
|
if (!($valid_mobile))
|
|
$error_array['customer_phone_mobile'] = 'Invalid mobile phone number.';
|
|
|
|
// find the vehicle using vid
|
|
$new_vehicle = $em->getRepository(Vehicle::class)->find($req->request->get('vid'));
|
|
if (empty($new_vehicle))
|
|
{
|
|
$error_array['cv_mfg'] = 'Invalid manufacturer specified.';
|
|
$error_array['cv_make'] = 'Invalid make specified.';
|
|
}
|
|
if (empty($error_array))
|
|
{
|
|
$new_cust = new Customer();
|
|
$new_cv = new CustomerVehicle();
|
|
|
|
$new_cust->setLastName($req->request->get('customer_last_name'))
|
|
->setFirstName($req->request->get('customer_first_name'))
|
|
->setPhoneMobile($req->request->get('customer_phone_mobile'))
|
|
->setPhoneLandline($req->request->get('customer_phone_landline'))
|
|
->setPhoneOffice($req->request->get('customer_phone_office'))
|
|
->setPhoneFax($req->request->get('customer_phone_fax'))
|
|
->setCustomerNotes($req->request->get('customer_customer_notes'));
|
|
|
|
$new_cv->setCustomer($new_cust)
|
|
->setVehicle($new_vehicle)
|
|
->setPlateNumber($req->request->get('cv_plate'))
|
|
->setModelYear($req->request->get('cv_year'))
|
|
->setColor('')
|
|
->setStatusCondition('')
|
|
->setFuelType('')
|
|
->setActive()
|
|
->setWarrantyCode($req->request->get('warranty_code'));
|
|
|
|
if (($req->request->get('service_type')) == CMBServiceType::BATTERY_REPLACEMENT_NEW)
|
|
{
|
|
$new_cv->setHasMotoliteBattery(true);
|
|
}
|
|
else
|
|
{
|
|
$new_cv->setHasMotoliteBattery(false);
|
|
}
|
|
|
|
// link JO to new customer
|
|
$jo->setCustomer($new_cust);
|
|
$jo->setCustomerVehicle($new_cv);
|
|
|
|
$em->persist($new_cust);
|
|
$em->persist($new_cv);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// check if customer vehicle is set
|
|
if (empty($req->request->get('customer_vehicle'))) {
|
|
$error_array['customer_vehicle'] = 'No vehicle selected.';
|
|
} else
|
|
{
|
|
// get customer vehicle
|
|
$cust_vehicle = $em->getRepository(CustomerVehicle::class)->find($req->request->get('customer_vehicle'));
|
|
|
|
if (empty($cust_vehicle)) {
|
|
$error_array['customer_vehicle'] = 'Invalid vehicle specified.';
|
|
}
|
|
else
|
|
{
|
|
$jo->setCustomerVehicle($cust_vehicle);
|
|
$jo->setCustomer($cust_vehicle->getCustomer());
|
|
|
|
// save serial into cv
|
|
$cust_vehicle->setWarrantyCode($req->request->get('warranty_code'));
|
|
|
|
$em->persist($cust_vehicle);
|
|
}
|
|
}
|
|
}
|
|
|
|
// check if hub AND rider is selected
|
|
if ((empty($req->request->get('hub_id'))) &&
|
|
(empty($req->request->get('rider_id')))) {
|
|
$error_array['hub'] = 'No hub selected.';
|
|
} else {
|
|
if (empty($req->request->get('rider_id'))) {
|
|
$error_array['rider'] = 'No rider selected.';
|
|
} else {
|
|
// get hub
|
|
$hub = $em->getRepository(Hub::class)->find($req->request->get('hub_id'));
|
|
|
|
if (empty($hub)) {
|
|
$error_array['hub'] = 'Invalid hub specified.';
|
|
} else {
|
|
// get rider
|
|
$rider = $em->getRepository(Rider::class)->find($req->request->get('rider_id'));
|
|
|
|
if (empty($rider)) {
|
|
$error_array['rider'] = 'Invalid rider specified.';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// get discount and set to meta
|
|
$discount = $req->request->get('invoice_promo');
|
|
|
|
// check if discount is greater than 50 or negative number
|
|
if (($discount > 50) || ($discount < 0))
|
|
$error_array['invoice_promo'] = 'Invalid discount specified';
|
|
|
|
if (empty($error_array))
|
|
{
|
|
// get current user
|
|
$user = $this->security->getUser();
|
|
|
|
// coordinates
|
|
$point = new Point($req->request->get('coord_lng'), $req->request->get('coord_lat'));
|
|
|
|
$stype = $req->request->get('service_type');
|
|
|
|
// set and save values
|
|
$jo->setDateSchedule(DateTime::createFromFormat("d M Y h:i A", $req->request->get('date_schedule_date') . " " . $req->request->get('date_schedule_time')))
|
|
->setCoordinates($point)
|
|
->setAdvanceOrder($req->request->get('flag_advance') ?? false)
|
|
->setServiceType($stype)
|
|
->setWarrantyClass($req->request->get('warranty_class'))
|
|
->setSource($req->request->get('source'))
|
|
->setStatus(JOStatus::ASSIGNED)
|
|
->setDeliveryInstructions($req->request->get('delivery_instructions'))
|
|
->setTier1Notes($req->request->get('tier1_notes'))
|
|
->setTier2Notes($req->request->get('tier2_notes'))
|
|
->setDeliveryAddress($req->request->get('delivery_address'))
|
|
->setORName($req->request->get('or_name'))
|
|
->setPromoDetail($req->request->get('promo_detail'))
|
|
->setModeOfPayment($req->request->get('mode_of_payment'))
|
|
->setLandmark($req->request->get('landmark'))
|
|
->setHub($hub)
|
|
->setRider($rider);
|
|
|
|
$jo->addMeta('discount', $discount);
|
|
|
|
// check if user is null, meaning call to create came from API
|
|
if ($user != null)
|
|
{
|
|
$jo->setCreatedBy($user);
|
|
}
|
|
|
|
// check if reference JO is set and validate
|
|
if (!empty($req->request->get('ref_jo'))) {
|
|
// get reference JO
|
|
$ref_jo = $em->getRepository(JobOrder::class)->find($req->request->get('ref_jo'));
|
|
|
|
if (empty($ref_jo)) {
|
|
$error_array['ref_jo'] = 'Invalid reference job order specified.';
|
|
} else {
|
|
$jo->setReferenceJO($ref_jo);
|
|
}
|
|
}
|
|
|
|
// call service to generate job order and invoice
|
|
$invoice_items = $req->request->get('invoice_items', []);
|
|
$promo_id = $req->request->get('invoice_promo');
|
|
$invoice_change = $req->request->get('invoice_change', 0);
|
|
|
|
// check if invoice changed
|
|
if ($invoice_change)
|
|
{
|
|
$this->ic->generateInvoiceCriteria($jo, $promo_id, $invoice_items, $error_array);
|
|
}
|
|
|
|
// validate
|
|
$errors = $this->validator->validate($jo);
|
|
|
|
// add errors to list
|
|
foreach ($errors as $error) {
|
|
$error_array[$error->getPropertyPath()] = $error->getMessage();
|
|
}
|
|
|
|
// check if errors are found
|
|
if (empty($error_array))
|
|
{
|
|
// validated, no error. save the job order
|
|
$em->persist($jo);
|
|
|
|
// the event
|
|
$event = new JOEvent();
|
|
$event->setDateHappen(new DateTime())
|
|
->setTypeID(JOEventType::CREATE)
|
|
->setJobOrder($jo);
|
|
|
|
if ($user != null)
|
|
{
|
|
$event->setUser($user);
|
|
}
|
|
|
|
$em->persist($event);
|
|
$em->flush();
|
|
}
|
|
}
|
|
|
|
return $error_array;
|
|
}
|
|
|
|
// dispatch job order
|
|
public function dispatchJobOrder(Request $req, int $id, MQTTClient $mclient)
|
|
{
|
|
// get object data
|
|
$em = $this->em;
|
|
$obj = $em->getRepository(JobOrder::class)->find($id);
|
|
$processor = $obj->getProcessedBy();
|
|
$user = $this->security->getUser();;
|
|
|
|
// check if we're the one processing, return error otherwise
|
|
if ($processor == null)
|
|
throw new AccessDeniedHttpException('Not the processor');
|
|
|
|
if ($processor != null && $processor->getID() != $user->getID())
|
|
throw new AccessDeniedHttpException('Not the processor');
|
|
|
|
// initialize error list
|
|
$error_array = [];
|
|
|
|
// make sure this object exists
|
|
if (empty($obj))
|
|
throw new NotFoundHttpException('The item does not exist');
|
|
|
|
// check if cancelled already
|
|
if (!$obj->canDispatch())
|
|
{
|
|
throw new NotFoundHttpException('Could not dispatch. Job Order is not pending.');
|
|
// TODO: have this handled better, so UI shows the error
|
|
// $error_array['dispatch'] = 'Could not dispatch. Job Order is not pending.';
|
|
}
|
|
|
|
// check if lat and lng are provided
|
|
if (empty($req->request->get('coord_lng')) || empty($req->request->get('coord_lat')))
|
|
{
|
|
$error_array['coordinates'] = 'No map coordinates provided. Please click on a location on the map.';
|
|
}
|
|
|
|
// check if hub is set
|
|
if (empty($req->request->get('hub')))
|
|
{
|
|
$error_array['hub'] = 'No hub selected.';
|
|
}
|
|
else
|
|
{
|
|
// get hub
|
|
$hub = $em->getRepository(Hub::class)->find($req->request->get('hub'));
|
|
|
|
if (empty($hub))
|
|
{
|
|
$error_array['hub'] = 'Invalid hub specified.';
|
|
}
|
|
}
|
|
|
|
// check facilitated type
|
|
$fac_type = $req->request->get('facilitated_type');
|
|
if (!empty($fac_type))
|
|
{
|
|
if (!FacilitatedType::validate($fac_type))
|
|
$fac_type = null;
|
|
}
|
|
else
|
|
$fac_type = null;
|
|
|
|
// check facilitated by
|
|
$fac_by_id = $req->request->get('facilitated_by');
|
|
$fac_by = null;
|
|
if (!empty($fac_by_id))
|
|
{
|
|
$fac_by = $em->getRepository(Hub::class)->find($fac_by_id);
|
|
if (empty($fac_by))
|
|
$fac_by = null;
|
|
}
|
|
|
|
if (empty($error_array))
|
|
{
|
|
// coordinates
|
|
$point = new Point($req->request->get('coord_lng'), $req->request->get('coord_lat'));
|
|
|
|
// set and save values
|
|
$obj->setDateSchedule(DateTime::createFromFormat("d M Y h:i A", $req->request->get('date_schedule_date') . " " . $req->request->get('date_schedule_time')))
|
|
->setCoordinates($point)
|
|
->setAdvanceOrder($req->request->get('flag_advance') ?? false)
|
|
->setServiceType($req->request->get('service_type'))
|
|
->setWarrantyClass($req->request->get('warranty_class'))
|
|
->setSource($req->request->get('source'))
|
|
->setStatus(JOStatus::RIDER_ASSIGN)
|
|
->setDeliveryInstructions($req->request->get('delivery_instructions'))
|
|
->setTier1Notes($req->request->get('tier1_notes'))
|
|
->setTier2Notes($req->request->get('tier2_notes'))
|
|
->setDeliveryAddress($req->request->get('delivery_address'))
|
|
->setFacilitatedType($fac_type)
|
|
->setFacilitatedBy($fac_by)
|
|
->setHub($hub);
|
|
|
|
// validate
|
|
$errors = $this->validator->validate($obj);
|
|
|
|
// add errors to list
|
|
foreach ($errors as $error) {
|
|
$error_array[$error->getPropertyPath()] = $error->getMessage();
|
|
}
|
|
}
|
|
|
|
if (empty($error_array))
|
|
{
|
|
// the event
|
|
$event = new JOEvent();
|
|
$event->setDateHappen(new DateTime())
|
|
->setTypeID(JOEventType::HUB_ASSIGN)
|
|
->setJobOrder($obj);
|
|
|
|
if ($user != null)
|
|
{
|
|
$event->setUser($user);
|
|
}
|
|
|
|
$em->persist($event);
|
|
|
|
// validated! save the entity
|
|
$em->flush();
|
|
|
|
// send event to mobile app
|
|
$payload = [
|
|
'event' => 'outlet_assign'
|
|
];
|
|
$mclient->sendEvent($obj, $payload);
|
|
}
|
|
|
|
return $error_array;
|
|
}
|
|
|
|
// assign job order
|
|
public function assignJobOrder(Request $req, $id)
|
|
{
|
|
// get object data
|
|
$em = $this->em;
|
|
$obj = $em->getRepository(JobOrder::class)->find($id);
|
|
|
|
// initialize error list
|
|
$error_array = [];
|
|
|
|
// make sure this object exists
|
|
if (empty($obj))
|
|
throw new NotFoundHttpException('The item does not exist');
|
|
|
|
// check if we can assign
|
|
if (!$obj->canAssign())
|
|
throw new NotFoundHttpException('Cannot assign rider to this job order.');
|
|
|
|
// check if lat and lng are provided
|
|
if (empty($req->request->get('coord_lng')) || empty($req->request->get('coord_lat'))) {
|
|
$error_array['coordinates'] = 'No map coordinates provided. Please click on a location on the map.';
|
|
}
|
|
|
|
// check if rider is set
|
|
if (empty($req->request->get('rider'))) {
|
|
$error_array['rider'] = 'No rider selected.';
|
|
} else {
|
|
// get rider
|
|
$rider = $em->getRepository(Rider::class)->find($req->request->get('rider'));
|
|
|
|
if (empty($rider)) {
|
|
$error_array['rider'] = 'Invalid rider specified.';
|
|
}
|
|
}
|
|
|
|
// get current user
|
|
$user = $this->security->getUser();
|
|
|
|
if (empty($error_array)) {
|
|
// coordinates
|
|
$point = new Point($req->request->get('coord_lng'), $req->request->get('coord_lat'));
|
|
|
|
// set and save values
|
|
$obj->setDateSchedule(DateTime::createFromFormat("d M Y h:i A", $req->request->get('date_schedule_date') . " " . $req->request->get('date_schedule_time')))
|
|
->setCoordinates($point)
|
|
->setAdvanceOrder($req->request->get('flag_advance') ?? false)
|
|
->setServiceType($req->request->get('service_type'))
|
|
->setWarrantyClass($req->request->get('warranty_class'))
|
|
->setSource($req->request->get('source'))
|
|
->setStatus(JOStatus::ASSIGNED)
|
|
->setDeliveryInstructions($req->request->get('delivery_instructions'))
|
|
->setTier1Notes($req->request->get('tier1_notes'))
|
|
->setTier2Notes($req->request->get('tier2_notes'))
|
|
->setDeliveryAddress($req->request->get('delivery_address'))
|
|
->setDateAssign(new DateTime())
|
|
->setRider($rider);
|
|
|
|
if ($user != null)
|
|
{
|
|
$obj->setAssignedBy($user);
|
|
}
|
|
|
|
// validate
|
|
$errors = $this->validator->validate($obj);
|
|
|
|
// add errors to list
|
|
foreach ($errors as $error) {
|
|
$error_array[$error->getPropertyPath()] = $error->getMessage();
|
|
}
|
|
}
|
|
|
|
if (empty($error_array))
|
|
{
|
|
// the event
|
|
$event = new JOEvent();
|
|
$event->setDateHappen(new DateTime())
|
|
->setTypeID(JOEventType::RIDER_ASSIGN)
|
|
->setJobOrder($obj);
|
|
|
|
if ($user != null)
|
|
{
|
|
$event->setUser($user);
|
|
}
|
|
|
|
$em->persist($event);
|
|
|
|
// validated! save the entity
|
|
$em->flush();
|
|
|
|
// call rider assignment handler's assignJobOrder
|
|
$this->rah->assignJobOrder($obj, $rider);
|
|
}
|
|
|
|
return $error_array;
|
|
}
|
|
|
|
// fulfill job order
|
|
public function fulfillJobOrder(Request $req, $id)
|
|
{
|
|
// initialize error list
|
|
$error_array = [];
|
|
|
|
// get object data
|
|
$em = $this->em;
|
|
$obj = $em->getRepository(JobOrder::class)->find($id);
|
|
|
|
// make sure this object exists
|
|
if (empty($obj))
|
|
throw new NotFoundHttpException('The item does not exist');
|
|
|
|
// check if lat and lng are provided
|
|
if (empty($req->request->get('coord_lng')) || empty($req->request->get('coord_lat'))) {
|
|
$error_array['coordinates'] = 'No map coordinates provided. Please click on a location on the map.';
|
|
}
|
|
|
|
if (empty($error_array)) {
|
|
// coordinates
|
|
$point = new Point($req->request->get('coord_lng'), $req->request->get('coord_lat'));
|
|
|
|
// set and save values
|
|
$obj->setDateSchedule(DateTime::createFromFormat("d M Y h:i A", $req->request->get('date_schedule_date') . " " . $req->request->get('date_schedule_time')))
|
|
->setCoordinates($point)
|
|
->setAdvanceOrder($req->request->get('flag_advance') ?? false)
|
|
->setServiceType($req->request->get('service_type'))
|
|
->setWarrantyClass($req->request->get('warranty_class'))
|
|
->setSource($req->request->get('source'))
|
|
->setDeliveryInstructions($req->request->get('delivery_instructions'))
|
|
->setTier1Notes($req->request->get('tier1_notes'))
|
|
->setTier2Notes($req->request->get('tier2_notes'))
|
|
->setDeliveryAddress($req->request->get('delivery_address'));
|
|
|
|
// validate
|
|
$errors = $this->validator->validate($obj);
|
|
|
|
// add errors to list
|
|
foreach ($errors as $error) {
|
|
$error_array[$error->getPropertyPath()] = $error->getMessage();
|
|
}
|
|
}
|
|
|
|
$obj->fulfill();
|
|
|
|
if (empty($error_array))
|
|
{
|
|
// the event
|
|
$event = new JOEvent();
|
|
$event->setDateHappen(new DateTime())
|
|
->setTypeID(JOEventType::FULFILL)
|
|
->setJobOrder($obj);
|
|
|
|
// get current user
|
|
$user = $this->security->getUser();
|
|
if ($user != null)
|
|
{
|
|
$event->setUser($user);
|
|
}
|
|
|
|
$event->setUser($user);
|
|
$em->persist($event);
|
|
|
|
// save to customer vehicle battery record
|
|
$this->updateVehicleBattery($obj);
|
|
|
|
// save serial to customer vehicle
|
|
$cust_vehicle = $obj->getCustomerVehicle();
|
|
$cust_vehicle->setWarrantyCode($req->request->get('warranty_code'));
|
|
|
|
$em->persist($cust_vehicle);
|
|
|
|
// get rider
|
|
$rider = $obj->getRider();
|
|
|
|
$image_url = $req->getScheme() . '://' . $req->getHttpHost() . $req->getBasePath() . '/assets/images/user.gif';
|
|
if ($rider->getImageFile() != null)
|
|
$image_url = $req->getScheme() . '://' . $req->getHttpHost() . $req->getBasePath() . '/uploads/' . $rider->getImageFile();
|
|
|
|
// call rider assignment handler's fulfillJobOrder
|
|
$this->rah->fulfillJobOrder($obj, $image_url, $rider);
|
|
|
|
// create the warranty if new battery only
|
|
if ($this->checkIfNewBattery($obj))
|
|
{
|
|
if (empty($req->request->get('warranty_code')))
|
|
$serial = null;
|
|
else
|
|
$serial = $req->request->get('warranty_code');
|
|
|
|
$warranty_class = $obj->getWarrantyClass();
|
|
$first_name = $obj->getCustomer()->getFirstName();
|
|
$last_name = $obj->getCustomer()->getLastName();
|
|
$mobile_number = $obj->getCustomer()->getPhoneMobile();
|
|
|
|
// check if date fulfilled is null
|
|
if ($obj->getDateFulfill() == null)
|
|
$date_purchase = $obj->getDateCreate();
|
|
else
|
|
$date_purchase = $obj->getDateFulfill();
|
|
|
|
// validate plate number
|
|
// $plate_number = $this->wh->cleanPlateNumber($jo->getCustomerVehicle()->getPlateNumber());
|
|
$plate_number = Warranty::cleanPlateNumber($obj->getCustomerVehicle()->getPlateNumber());
|
|
if ($plate_number != false)
|
|
{
|
|
$batt_list = array();
|
|
$invoice = $obj->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();
|
|
}
|
|
}
|
|
}
|
|
|
|
$this->wh->createWarranty($serial, $plate_number, $first_name, $last_name, $mobile_number, $batt_list, $date_purchase, $warranty_class);
|
|
}
|
|
}
|
|
|
|
// validated! save the entity
|
|
$em->flush();
|
|
}
|
|
}
|
|
|
|
// cancel job order
|
|
public function cancelJobOrder(Request $req, int $id, MQTTClient $mclient)
|
|
{
|
|
// get object data
|
|
$em = $this->em;
|
|
$obj = $em->getRepository(JobOrder::class)->find($id);
|
|
|
|
// make sure this object exists
|
|
if (empty($obj))
|
|
throw new NotFoundHttpException('The item does not exist');
|
|
|
|
$cancel_reason = $req->request->get('cancel_reason');
|
|
$obj->cancel($cancel_reason);
|
|
|
|
// the event
|
|
$event = new JOEvent();
|
|
$event->setDateHappen(new DateTime())
|
|
->setTypeID(JOEventType::CANCEL)
|
|
->setJobOrder($obj);
|
|
|
|
// get current user
|
|
$user = $this->security->getUser();
|
|
if ($user != null)
|
|
{
|
|
$event->setUser($user);
|
|
}
|
|
|
|
$event->setUser($user);
|
|
|
|
$em->persist($event);
|
|
|
|
// save
|
|
$em->flush();
|
|
|
|
// send mobile app event
|
|
$payload = [
|
|
'event' => 'cancelled',
|
|
'reason' => $cancel_reason,
|
|
'jo_id' => $obj->getID(),
|
|
];
|
|
$mclient->sendEvent($obj, $payload);
|
|
$mclient->sendRiderEvent($obj, $payload);
|
|
}
|
|
|
|
// set hub for job order
|
|
public function setHub($req, $id, $mclient)
|
|
{
|
|
// get object data
|
|
$em = $this->em;
|
|
$obj = $em->getRepository(JobOrder::class)->find($id);
|
|
$user = $this->security->getUser();
|
|
|
|
// initialize error list
|
|
$error_array = [];
|
|
|
|
// make sure this object exists
|
|
if (empty($obj))
|
|
throw new NotFoundHttpException('The item does not exist');
|
|
|
|
// check if lat and lng are provided
|
|
if (empty($req->request->get('coord_lng')) || empty($req->request->get('coord_lat'))) {
|
|
$error_array['coordinates'] = 'No map coordinates provided. Please click on a location on the map.';
|
|
}
|
|
|
|
// check if hub is set
|
|
if (empty($req->request->get('hub'))) {
|
|
$error_array['hub'] = 'No hub selected.';
|
|
} else {
|
|
// get hub
|
|
$hub = $em->getRepository(Hub::class)->find($req->request->get('hub'));
|
|
|
|
if (empty($hub)) {
|
|
$error_array['hub'] = 'Invalid hub specified.';
|
|
}
|
|
}
|
|
|
|
if (empty($error_array))
|
|
{
|
|
// rider mqtt event
|
|
// NOTE: need to send this before saving because rider will be cleared
|
|
$rider_payload = [
|
|
'event' => 'cancelled',
|
|
'reason' => 'Reassigned',
|
|
'jo_id' => $obj->getID(),
|
|
];
|
|
$mclient->sendRiderEvent($obj, $rider_payload);
|
|
|
|
// coordinates
|
|
$point = new Point($req->request->get('coord_lng'), $req->request->get('coord_lat'));
|
|
|
|
// set and save values
|
|
$obj->setDateSchedule(DateTime::createFromFormat("d M Y h:i A", $req->request->get('date_schedule_date') . " " . $req->request->get('date_schedule_time')))
|
|
->setCoordinates($point)
|
|
->setAdvanceOrder($req->request->get('flag_advance') ?? false)
|
|
->setServiceType($req->request->get('service_type'))
|
|
->setWarrantyClass($req->request->get('warranty_class'))
|
|
->setSource($req->request->get('source'))
|
|
->setStatus(JOStatus::RIDER_ASSIGN)
|
|
->setDeliveryInstructions($req->request->get('delivery_instructions'))
|
|
->setTier1Notes($req->request->get('tier1_notes'))
|
|
->setTier2Notes($req->request->get('tier2_notes'))
|
|
->setDeliveryAddress($req->request->get('delivery_address'))
|
|
->setHub($hub)
|
|
->clearRider();
|
|
|
|
if ($user != null)
|
|
{
|
|
$obj->setProcessedBy($user);
|
|
}
|
|
|
|
$em->persist($obj);
|
|
|
|
// validate
|
|
$errors = $this->validator->validate($obj);
|
|
|
|
// add errors to list
|
|
foreach ($errors as $error) {
|
|
$error_array[$error->getPropertyPath()] = $error->getMessage();
|
|
}
|
|
}
|
|
|
|
// check if any errors were found
|
|
if (empty($error_array)) {
|
|
|
|
// add event
|
|
$event = new JOEvent();
|
|
$event->setDateHappen(new DateTime())
|
|
->setTypeID(JOEventType::HUB_ASSIGN)
|
|
->setJobOrder($obj);
|
|
|
|
if ($user != null)
|
|
{
|
|
$event->setUser($user);
|
|
}
|
|
|
|
$em->persist($event);
|
|
|
|
// validated! save the entity
|
|
$em->flush();
|
|
|
|
// user mqtt event
|
|
$payload = [
|
|
'event' => 'outlet_assign'
|
|
];
|
|
$mclient->sendEvent($obj, $payload);
|
|
}
|
|
|
|
return $error_array;
|
|
}
|
|
|
|
// reject hub for job order
|
|
public function rejectHub($req, $id)
|
|
{
|
|
// get object data
|
|
$em = $this->em;
|
|
$jo = $em->getRepository(JobOrder::class)->find($id);
|
|
$processor = $jo->getProcessedBy();
|
|
$user = $this->security->getUser();
|
|
|
|
// check if we're the one processing, return error otherwise
|
|
if ($processor == null)
|
|
throw new AccessDeniedHttpException('Not the processor');
|
|
|
|
if ($user != null)
|
|
{
|
|
if ($processor != null && $processor->getID() != $user->getID())
|
|
throw new AccessDeniedHttpException('Not the processor');
|
|
}
|
|
|
|
// initialize error list
|
|
$error_array = [];
|
|
|
|
// make sure job order exists
|
|
if (empty($jo))
|
|
throw new NotFoundHttpException('The item does not exist');
|
|
|
|
// check if hub is set
|
|
if (empty($req->request->get('hub')))
|
|
{
|
|
$error_array['hub'] = 'No hub selected.';
|
|
}
|
|
else
|
|
{
|
|
// get hub
|
|
$hub = $em->getRepository(Hub::class)->find($req->request->get('hub'));
|
|
|
|
if (empty($hub))
|
|
{
|
|
$error_array['hub'] = 'Invalid hub specified.';
|
|
}
|
|
}
|
|
|
|
// check if this hub has already been rejected on this job order
|
|
$robj = $em->getRepository(JORejection::class)->findOneBy([
|
|
'job_order' => $jo,
|
|
'hub' => $hub
|
|
]);
|
|
|
|
if (!empty($robj))
|
|
$error_array['hub'] = 'This hub has already been rejected for the current job order.';
|
|
|
|
// check if reason is set
|
|
if (empty($req->request->get('reason')))
|
|
$error_array['reason'] = 'No reason selected.';
|
|
else if (!JORejectionReason::validate($req->request->get('reason')))
|
|
$error_array['reason'] = 'Invalid reason specified.';
|
|
|
|
if (empty($error_array))
|
|
{
|
|
// coordinates
|
|
$obj = new JORejection();
|
|
|
|
// set and save values
|
|
$obj->setDateCreate(new DateTime())
|
|
->setHub($hub)
|
|
->setJobOrder($jo)
|
|
->setReason($req->request->get('reason'))
|
|
->setRemarks($req->request->get('remarks'))
|
|
->setContactPerson($req->request->get('contact_person'));
|
|
|
|
if ($user != null)
|
|
{
|
|
$obj->setUser($user);
|
|
}
|
|
|
|
// validate
|
|
$errors = $this->validator->validate($obj);
|
|
|
|
// add errors to list
|
|
foreach ($errors as $error) {
|
|
$error_array[$error->getPropertyPath()] = $error->getMessage();
|
|
}
|
|
}
|
|
|
|
if (empty($error_array))
|
|
{
|
|
// validated! save the entity
|
|
$em->persist($obj);
|
|
$em->flush();
|
|
}
|
|
|
|
return $error_array;
|
|
|
|
}
|
|
|
|
// set rider for job order
|
|
public function setRider($req, $id, $mclient)
|
|
{
|
|
// initialize error list
|
|
$error_array = [];
|
|
|
|
// get object data
|
|
$em = $this->em;
|
|
$obj = $em->getRepository(JobOrder::class)->find($id);
|
|
$user = $this->security->getUser();
|
|
|
|
// make sure this object exists
|
|
if (empty($obj))
|
|
throw new NotFoundHttpException('The item does not exist');
|
|
|
|
// check if lat and lng are provided
|
|
if (empty($req->request->get('coord_lng')) || empty($req->request->get('coord_lat'))) {
|
|
$error_array['coordinates'] = 'No map coordinates provided. Please click on a location on the map.';
|
|
}
|
|
|
|
// check if rider is set
|
|
if (empty($req->request->get('rider'))) {
|
|
$error_array['rider'] = 'No rider selected.';
|
|
} else {
|
|
// get rider
|
|
$rider = $em->getRepository(Rider::class)->find($req->request->get('rider'));
|
|
|
|
if (empty($rider)) {
|
|
$error_array['rider'] = 'Invalid rider specified.';
|
|
}
|
|
}
|
|
|
|
if (empty($error_array)) {
|
|
// rider mqtt event
|
|
// NOTE: need to send this before saving because rider will be cleared
|
|
$rider_payload = [
|
|
'event' => 'cancelled',
|
|
'reason' => 'Reassigned',
|
|
'jo_id' => $obj->getID(),
|
|
];
|
|
$mclient->sendRiderEvent($obj, $rider_payload);
|
|
|
|
// coordinates
|
|
$point = new Point($req->request->get('coord_lng'), $req->request->get('coord_lat'));
|
|
|
|
// set and save values
|
|
$obj->setDateSchedule(DateTime::createFromFormat("d M Y h:i A", $req->request->get('date_schedule_date') . " " . $req->request->get('date_schedule_time')))
|
|
->setCoordinates($point)
|
|
->setAdvanceOrder($req->request->get('flag_advance') ?? false)
|
|
->setServiceType($req->request->get('service_type'))
|
|
->setWarrantyClass($req->request->get('warranty_class'))
|
|
->setSource($req->request->get('source'))
|
|
->setStatus(JOStatus::ASSIGNED)
|
|
->setDeliveryInstructions($req->request->get('delivery_instructions'))
|
|
->setTier1Notes($req->request->get('tier1_notes'))
|
|
->setTier2Notes($req->request->get('tier2_notes'))
|
|
->setDeliveryAddress($req->request->get('delivery_address'))
|
|
->setDateAssign(new DateTime())
|
|
->setRider($rider);
|
|
|
|
if ($user != null)
|
|
{
|
|
$obj->setAssignedBy($user);
|
|
}
|
|
|
|
// validate
|
|
$errors = $this->validator->validate($obj);
|
|
|
|
$em->persist($obj);
|
|
|
|
// add errors to list
|
|
foreach ($errors as $error) {
|
|
$error_array[$error->getPropertyPath()] = $error->getMessage();
|
|
}
|
|
}
|
|
|
|
// check if any errors were found
|
|
if (empty($error_array))
|
|
{
|
|
// add event
|
|
$event = new JOEvent();
|
|
$event->setDateHappen(new DateTime())
|
|
->setTypeID(JOEventType::RIDER_ASSIGN)
|
|
->setJobOrder($obj);
|
|
|
|
if ($user != null)
|
|
{
|
|
$event->setUser($user);
|
|
}
|
|
|
|
$em->persist($event);
|
|
|
|
// validated! save the entity
|
|
$em->flush();
|
|
|
|
// send event to mobile app
|
|
$payload = [
|
|
'event' => 'driver_assigned'
|
|
];
|
|
$mclient->sendEvent($obj, $payload);
|
|
$mclient->sendRiderEvent($obj, $payload);
|
|
}
|
|
|
|
return $error_array;
|
|
}
|
|
|
|
// unlock processor
|
|
public function unlockProcessor($id)
|
|
{
|
|
// clear lock
|
|
$em = $this->em;
|
|
$jo = $em->getRepository(JobOrder::class)->find($id);
|
|
if ($jo != null)
|
|
{
|
|
$jo->setProcessedBy(null);
|
|
|
|
$em->flush();
|
|
}
|
|
}
|
|
|
|
// unlock assignor
|
|
public function unlockAssignor($id)
|
|
{
|
|
// clear lock
|
|
$em = $this->em;
|
|
$jo = $em->getRepository(JobOrder::class)->find($id);
|
|
if ($jo != null)
|
|
{
|
|
$jo->setAssignedBy(null);
|
|
|
|
$em->flush();
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// initialize incoming job order form
|
|
public function initializeIncomingForm()
|
|
{
|
|
$params['obj'] = new JobOrder();
|
|
$params['mode'] = 'create';
|
|
|
|
$this->fillDropdownParameters($params);
|
|
$this->fillFormTags($params);
|
|
|
|
// get template to display
|
|
$params['template'] = $this->getTwigTemplate('jo_incoming_form');
|
|
|
|
// return params
|
|
return $params;
|
|
}
|
|
|
|
public function initializeOneStepForm()
|
|
{
|
|
$params['obj'] = new JobOrder();
|
|
$params['mode'] = 'onestep';
|
|
|
|
$this->fillDropdownParameters($params);
|
|
$this->fillFormTags($params);
|
|
|
|
// get template to display
|
|
$params['template'] = $this->getTwigTemplate('jo_onestep');
|
|
|
|
// return params
|
|
return $params;
|
|
}
|
|
|
|
public function initializeOneStepEditForm($id, $map_tools)
|
|
{
|
|
$em = $this->em;
|
|
$obj = $em->getRepository(JobOrder::class)->find($id);
|
|
|
|
$params['obj'] = $obj;
|
|
$params['mode'] = 'onestep-edit';
|
|
$params['cvid'] = $obj->getCustomerVehicle()->getID();
|
|
$params['vid'] = $obj->getCustomerVehicle()->getVehicle()->getID();
|
|
|
|
$this->fillDropdownParameters($params);
|
|
$this->fillFormTags($params);
|
|
|
|
// get the hubs
|
|
// TODO: move this snippet to a function
|
|
$hubs = $map_tools->getClosestHubs($obj->getCoordinates(), 50, date("H:i:s"));
|
|
|
|
$params['hubs'] = [];
|
|
|
|
// format duration and distance into friendly time
|
|
foreach ($hubs as $hub) {
|
|
// duration
|
|
$seconds = $hub['duration'];
|
|
|
|
if (!empty($seconds) && $seconds > 0) {
|
|
$hours = floor($seconds / 3600);
|
|
$minutes = ceil(($seconds / 60) % 60);
|
|
|
|
$hub['duration'] = ($hours > 0 ? number_format($hours) . " hr" . ($hours > 1 ? "s" : '') . ($minutes > 0 ? ", " : '') : '') . ($minutes > 0 ? number_format($minutes) . " min" . ($minutes > 1 ? "s" : '') : '');
|
|
} else {
|
|
$hub['duration'] = false;
|
|
}
|
|
|
|
// distance
|
|
$meters = $hub['distance'];
|
|
|
|
if (!empty($meters) && $meters > 0) {
|
|
$hub['distance'] = round($meters / 1000) . " km";
|
|
} else {
|
|
$hub['distance'] = false;
|
|
}
|
|
|
|
// counters
|
|
$hub['rider_count'] = count($hub['hub']->getAvailableRiders());
|
|
$hub['jo_count'] = count($hub['hub']->getForAssignmentJobOrders());
|
|
|
|
// check for rejection
|
|
$hub['flag_rejected'] = false;
|
|
$hub_id = $hub['hub']->getID();
|
|
|
|
$params['hubs'][] = $hub;
|
|
}
|
|
|
|
|
|
// get template to display
|
|
$params['template'] = $this->getTwigTemplate('jo_onestep_edit_form');
|
|
|
|
return $params;
|
|
}
|
|
|
|
// initialize open edit job order form
|
|
public function initializeOpenEditForm($id)
|
|
{
|
|
$em = $this->em;
|
|
$jo = $em->getRepository(JobOrder::class)->find($id);
|
|
|
|
$params['obj'] = $jo;
|
|
$params['mode'] = 'open_edit';
|
|
$params['cvid'] = $jo->getCustomerVehicle()->getID();
|
|
$params['vid'] = $jo->getCustomerVehicle()->getVehicle()->getID();
|
|
|
|
$this->fillDropdownParameters($params);
|
|
$this->fillFormTags($params);
|
|
|
|
// get template to display
|
|
$params['template'] = $this->getTwigTemplate('jo_open_edit_form');
|
|
|
|
return $params;
|
|
}
|
|
|
|
// initialize incoming vehicle form
|
|
public function initializeIncomingVehicleForm(int $cvid)
|
|
{
|
|
$params['mode'] = 'create_vehicle';
|
|
$params['cvid'] = $cvid;
|
|
|
|
$em = $this->em;
|
|
|
|
// get customer vehicle
|
|
$cv = $em->getRepository(CustomerVehicle::class)->find($cvid);
|
|
$params['vid'] = $cv->getVehicle()->getID();
|
|
|
|
// make sure this customer vehicle exists
|
|
if (empty($cv))
|
|
{
|
|
$em->getConnection()->rollback();
|
|
throw new NotFoundHttpException('The job order does not exist');
|
|
}
|
|
|
|
$jo = new JobOrder();
|
|
$jo->setCustomerVehicle($cv)
|
|
->setCustomer($cv->getCustomer());
|
|
|
|
$params['obj'] = $jo;
|
|
$this->fillDropdownParameters($params);
|
|
$this->fillFormTags($params);
|
|
|
|
// get template to display
|
|
$params['template'] = $this->getTwigTemplate('jo_incoming_vehicle_form');
|
|
|
|
return $params;
|
|
}
|
|
|
|
// initialize all job orders form for a specific job order id
|
|
public function initializeAllForm($id)
|
|
{
|
|
$em = $this->em;
|
|
|
|
$params['mode'] = 'update-all';
|
|
|
|
// get row data
|
|
$obj = $em->getRepository(JobOrder::class)->find($id);
|
|
|
|
// make sure this row exists
|
|
if (empty($obj))
|
|
throw new NotFoundHttpException('The job order does not exist');
|
|
|
|
$this->fillDropdownParameters($params);
|
|
$this->fillFormTags($params);
|
|
|
|
// get template to display
|
|
$params['template'] = $this->getTwigTemplate('jo_all_form');
|
|
|
|
$params['obj'] = $obj;
|
|
$params['status_cancelled'] = JOStatus::CANCELLED;
|
|
|
|
// timeline stuff (descending by time)
|
|
$params['timeline'] = [
|
|
[
|
|
'date' => date("M j"),
|
|
'time' => date("g:i A"),
|
|
'event' => "Event 4",
|
|
'color' => "#f4516c"
|
|
],
|
|
[
|
|
'date' => date("M j"),
|
|
'time' => date("g:i A"),
|
|
'event' => "Event 3",
|
|
'color' => "#34bfa3"
|
|
],
|
|
[
|
|
'date' => date("M j"),
|
|
'time' => date("g:i A"),
|
|
'event' => "Event 2",
|
|
'color' => "#716aca"
|
|
],
|
|
[
|
|
'date' => date("M j"),
|
|
'time' => date("g:i A"),
|
|
'event' => "Event 1",
|
|
'color' => "#ffb822"
|
|
],
|
|
];
|
|
|
|
return $params;
|
|
}
|
|
|
|
// initialize dispatch/processing job order form
|
|
public function initializeProcessingForm($id, $map_tools)
|
|
{
|
|
$em = $this->em;
|
|
|
|
// manual transaction since we're locking
|
|
$em->getConnection()->beginTransaction();
|
|
|
|
try
|
|
{
|
|
// lock and get data
|
|
$obj = $em->getRepository(JobOrder::class)->find($id, LockMode::PESSIMISTIC_READ);
|
|
|
|
// make sure this job order exists
|
|
if (empty($obj))
|
|
{
|
|
$em->getConnection()->rollback();
|
|
throw new NotFoundHttpException('The job order does not exist');
|
|
}
|
|
|
|
// check status
|
|
if ($obj->getStatus() != JOStatus::PENDING)
|
|
{
|
|
$em->getConnection()->rollback();
|
|
throw new NotFoundHttpException('The job order does not have a pending status');
|
|
}
|
|
|
|
// check if we are the processor
|
|
$processor = $obj->getProcessedBy();
|
|
// get current user
|
|
$user = $this->security->getUser();
|
|
if ($user != null)
|
|
{
|
|
// TODO: go back to list page and display alert / flash that says they cannot access it because they
|
|
// are not the processor
|
|
if ($processor != null && $processor->getID() != $user->getID())
|
|
{
|
|
$em->getConnection()->rollback();
|
|
throw new AccessDeniedHttpException('Not the processor');
|
|
}
|
|
|
|
// make this user be the processor
|
|
$obj->setProcessedBy($user);
|
|
}
|
|
$em->flush();
|
|
|
|
$em->getConnection()->commit();
|
|
}
|
|
catch(PessimisticLockException $e)
|
|
{
|
|
throw new AccessDeniedHttpException('Not the processor');
|
|
}
|
|
|
|
// NOTE: we are able to lock, everything should be fine now
|
|
|
|
$params['mode'] = 'update-processing';
|
|
$params['status_cancelled'] = JOStatus::CANCELLED;
|
|
|
|
$this->fillDropdownParameters($params);
|
|
$this->fillFormTags($params);
|
|
|
|
// get rejections
|
|
$rejections = $obj->getHubRejections();
|
|
|
|
// get rejection reasons
|
|
$params['rejection_reasons'] = JORejectionReason::getCollection();
|
|
|
|
// get closest hubs
|
|
$hubs = $map_tools->getClosestHubs($obj->getCoordinates(), 50, date("H:i:s"));
|
|
|
|
$params['hubs'] = [];
|
|
|
|
// format duration and distance into friendly time
|
|
foreach ($hubs as $hub) {
|
|
// duration
|
|
$seconds = $hub['duration'];
|
|
|
|
if (!empty($seconds) && $seconds > 0) {
|
|
$hours = floor($seconds / 3600);
|
|
$minutes = ceil(($seconds / 60) % 60);
|
|
|
|
$hub['duration'] = ($hours > 0 ? number_format($hours) . " hr" . ($hours > 1 ? "s" : '') . ($minutes > 0 ? ", " : '') : '') . ($minutes > 0 ? number_format($minutes) . " min" . ($minutes > 1 ? "s" : '') : '');
|
|
} else {
|
|
$hub['duration'] = false;
|
|
}
|
|
|
|
// distance
|
|
$meters = $hub['distance'];
|
|
|
|
if (!empty($meters) && $meters > 0) {
|
|
$hub['distance'] = round($meters / 1000) . " km";
|
|
} else {
|
|
$hub['distance'] = false;
|
|
}
|
|
|
|
// counters
|
|
$hub['rider_count'] = count($hub['hub']->getAvailableRiders());
|
|
$hub['jo_count'] = count($hub['hub']->getForAssignmentJobOrders());
|
|
|
|
// check for rejection
|
|
$hub['flag_rejected'] = false;
|
|
$hub_id = $hub['hub']->getID();
|
|
|
|
foreach ($rejections as $robj)
|
|
{
|
|
if ($robj->getHub()->getID() === $hub_id)
|
|
{
|
|
$hub['flag_rejected'] = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
$params['hubs'][] = $hub;
|
|
}
|
|
|
|
$params['obj'] = $obj;
|
|
// get template to display
|
|
$params['template'] = $this->getTwigTemplate('jo_processing_form');
|
|
|
|
return $params;
|
|
}
|
|
|
|
// initialize assign job order form
|
|
public function initializeAssignForm($id)
|
|
{
|
|
$em = $this->em;
|
|
|
|
// manual transaction since we're locking
|
|
$em->getConnection()->beginTransaction();
|
|
|
|
$params['mode'] = 'update-assigning';
|
|
|
|
try
|
|
{
|
|
// get row data
|
|
$obj = $em->getRepository(JobOrder::class)->find($id);
|
|
|
|
// make sure this row exists
|
|
if (empty($obj))
|
|
{
|
|
$em->getConnection()->rollback();
|
|
throw new NotFoundHttpException('The job order does not exist');
|
|
}
|
|
|
|
// check status
|
|
if ($obj->getStatus() != JOStatus::RIDER_ASSIGN)
|
|
{
|
|
$em->getConnection()->rollback();
|
|
throw new NotFoundHttpException('The job order does not have an assigning status');
|
|
}
|
|
|
|
// check if super user
|
|
$user = $this->security->getUser();
|
|
if ($user != null)
|
|
{
|
|
if ($user->isSuperAdmin())
|
|
{
|
|
// do nothing, just allow page to be accessed
|
|
}
|
|
else
|
|
{
|
|
// check if hub is assigned to current user
|
|
$user_hubs = $user->getHubs();
|
|
if (!in_array($obj->getHub()->getID(), $user_hubs))
|
|
{
|
|
$em->getConnection()->rollback();
|
|
throw new NotFoundHttpException('The job order is not on a hub assigned to this user');
|
|
}
|
|
|
|
// check if we are the assignor
|
|
$assignor = $obj->getAssignedBy();
|
|
|
|
if ($assignor != null && $assignor->getID() != $user->getID())
|
|
{
|
|
$em->getConnection()->rollback();
|
|
throw new AccessDeniedHttpException('Not the assignor');
|
|
}
|
|
|
|
// make this user be the assignor
|
|
$obj->setAssignedBy($user);
|
|
}
|
|
}
|
|
|
|
$em->flush();
|
|
|
|
$em->getConnection()->commit();
|
|
}
|
|
catch (PessimisticLockException $e)
|
|
{
|
|
throw new AccessDeniedHttpException('Not the assignor');
|
|
}
|
|
|
|
$this->fillDropdownParameters($params);
|
|
$this->fillFormTags($params);
|
|
|
|
// get template to display
|
|
$params['template'] = $this->getTwigTemplate('jo_assigning_form');
|
|
$params['obj'] = $obj;
|
|
$params['status_cancelled'] = JOStatus::CANCELLED;
|
|
|
|
return $params;
|
|
}
|
|
|
|
// initialize fulflll job order form
|
|
public function initializeFulfillmentForm($id)
|
|
{
|
|
$em = $this->em;
|
|
|
|
$params['mode'] = 'update-fulfillment';
|
|
|
|
// get row data
|
|
$obj = $em->getRepository(JobOrder::class)->find($id);
|
|
|
|
// make sure this row exists
|
|
if (empty($obj))
|
|
{
|
|
throw new NotFoundHttpException('The job order does not exist');
|
|
}
|
|
|
|
// check status
|
|
if (!in_array($obj->getStatus(), [JOStatus::ASSIGNED, JOStatus::IN_PROGRESS]))
|
|
{
|
|
throw new NotFoundHttpException('The job order does not have a fulfillment status');
|
|
}
|
|
|
|
// get current user
|
|
$user = $this->security->getUser();
|
|
|
|
// check if hub is assigned to current user
|
|
$user_hubs = $user->getHubs();
|
|
if (!in_array($obj->getHub()->getID(), $user_hubs))
|
|
{
|
|
throw new NotFoundHttpException('The job order is not on a hub assigned to this user');
|
|
}
|
|
|
|
$this->fillDropdownParameters($params);
|
|
$this->fillFormTags($params);
|
|
|
|
// get template to display
|
|
$params['template'] = $this->getTwigTemplate('jo_fulfillment_form');
|
|
$params['obj'] = $obj;
|
|
$params['status_cancelled'] = JOStatus::CANCELLED;
|
|
|
|
return $params;
|
|
}
|
|
|
|
// initialize hub form
|
|
public function initializeHubForm($id, $map_tools)
|
|
{
|
|
$em = $this->em;
|
|
|
|
$params['mode'] = 'update-reassign-hub';
|
|
|
|
// get row data
|
|
$obj = $em->getRepository(JobOrder::class)->find($id);
|
|
|
|
// make sure this row exists
|
|
if (empty($obj))
|
|
{
|
|
throw new NotFoundHttpException('The job order does not exist');
|
|
}
|
|
|
|
$this->fillDropdownParameters($params);
|
|
$this->fillFormTags($params);
|
|
|
|
// get rejections
|
|
$rejections = $obj->getHubRejections();
|
|
|
|
// get rejection reasons
|
|
$params['rejection_reasons'] = JORejectionReason::getCollection();
|
|
|
|
// get closest hubs
|
|
$hubs = $map_tools->getClosestHubs($obj->getCoordinates(), 50, date("H:i:s"));
|
|
|
|
$params['status_cancelled'] = JOStatus::CANCELLED;
|
|
$params['hubs'] = [];
|
|
|
|
// format duration and distance into friendly time
|
|
foreach ($hubs as $hub) {
|
|
// duration
|
|
$seconds = $hub['duration'];
|
|
|
|
if (!empty($seconds) && $seconds > 0) {
|
|
$hours = floor($seconds / 3600);
|
|
$minutes = ceil(($seconds / 60) % 60);
|
|
|
|
$hub['duration'] = ($hours > 0 ? number_format($hours) . " hr" . ($hours > 1 ? "s" : '') . ($minutes > 0 ? ", " : '') : '') . ($minutes > 0 ? number_format($minutes) . " min" . ($minutes > 1 ? "s" : '') : '');
|
|
} else {
|
|
$hub['duration'] = false;
|
|
}
|
|
|
|
// distance
|
|
$meters = $hub['distance'];
|
|
|
|
if (!empty($meters) && $meters > 0) {
|
|
$hub['distance'] = round($meters / 1000) . " km";
|
|
} else {
|
|
$hub['distance'] = false;
|
|
}
|
|
|
|
// counters
|
|
$hub['rider_count'] = count($hub['hub']->getAvailableRiders());
|
|
$hub['jo_count'] = count($hub['hub']->getForAssignmentJobOrders());
|
|
|
|
// check for rejection
|
|
$hub['flag_rejected'] = false;
|
|
$hub_id = $hub['hub']->getID();
|
|
|
|
foreach ($rejections as $robj)
|
|
{
|
|
if ($robj->getHub()->getID() === $hub_id)
|
|
{
|
|
$hub['flag_rejected'] = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
$params['hubs'][] = $hub;
|
|
}
|
|
|
|
$params['obj'] = $obj;
|
|
// get template to display
|
|
$params['template'] = $this->getTwigTemplate('jo_open_hub_form');
|
|
|
|
return $params;
|
|
}
|
|
|
|
// initialize rider form
|
|
public function initializeRiderForm($id)
|
|
{
|
|
$em = $this->em;
|
|
|
|
$params['mode'] = 'update-reassign-rider';
|
|
|
|
// get row data
|
|
$obj = $em->getRepository(JobOrder::class)->find($id);
|
|
|
|
// make sure this row exists
|
|
if (empty($obj))
|
|
{
|
|
$em->getConnection()->rollback();
|
|
throw new NotFoundHttpException('The job order does not exist');
|
|
}
|
|
|
|
// check status
|
|
if ($obj->getStatus() == JOStatus::PENDING)
|
|
{
|
|
$em->getConnection()->rollback();
|
|
throw new NotFoundHttpException('The job order does not have an assigned hub');
|
|
}
|
|
|
|
$this->fillDropdownParameters($params);
|
|
$this->fillFormTags($params);
|
|
|
|
$params['obj'] = $obj;
|
|
$params['status_cancelled'] = JOStatus::CANCELLED;
|
|
// get template to display
|
|
$params['template'] = $this->getTwigTemplate('jo_open_rider_form');
|
|
|
|
return $params;
|
|
}
|
|
|
|
// generate pdf form for job order
|
|
public function generatePDFForm($req, $id, $proj_path)
|
|
{
|
|
$em = $this->em;
|
|
$translator = $this->translator;
|
|
|
|
// get row data
|
|
$obj = $em->getRepository(JobOrder::class)->find($id);
|
|
|
|
// make sure this row exists
|
|
if (empty($obj))
|
|
throw new NotFoundHttpException('The job order does not exist');
|
|
|
|
// set output filename
|
|
$filename = 'job-order-' . $obj->getID() . '.pdf';
|
|
|
|
// translate the title and the logo for the pdf
|
|
$translated_title = $translator->trans('jo_title_pdf');
|
|
$translated_logo = $translator->trans('image_jo_pdf');
|
|
$translated_delivery_instructions_label = $translator->trans('delivery_instructions_label');
|
|
|
|
// generate the pdf
|
|
$pdf = new FPDF('P', 'mm', 'letter');
|
|
$pdf->AddPage();
|
|
$pdf->setTitle($translated_title . ' #' . $obj->getID());
|
|
$pdf->SetFillColor(211, 211, 211);
|
|
|
|
// style defaults
|
|
$margin = 10;
|
|
$page_width = $pdf->GetPageWidth() - ($margin * 2);
|
|
$table_col_width = $page_width / 12;
|
|
$line_height = 5;
|
|
$jo_line_height = 10;
|
|
$table_line_height = 7;
|
|
$font_face = 'Arial';
|
|
$body_font_size = 9;
|
|
$header_font_size = 9;
|
|
$jo_font_size = 16;
|
|
$col1_x = $margin;
|
|
$col2_x = 120;
|
|
$label_width = 40;
|
|
$val_width = 60;
|
|
|
|
// insert the logo
|
|
$image_path = $proj_path . $translated_logo;
|
|
$pdf->Image($image_path, $col1_x, 10);
|
|
|
|
// insert JO number
|
|
$pdf->SetFont($font_face, 'B', $jo_font_size);
|
|
$pdf->SetX($col2_x);
|
|
$pdf->Cell($label_width, $jo_line_height, 'JO Number:');
|
|
$pdf->SetTextColor(9, 65, 150);
|
|
$pdf->Cell(0, $jo_line_height, $obj->getID());
|
|
|
|
// insert customer info
|
|
$customer = $obj->getCustomer();
|
|
$pdf->SetFont($font_face, '', $body_font_size);
|
|
$pdf->SetTextColor(0, 0, 0);
|
|
|
|
$pdf->Ln($line_height * 7);
|
|
|
|
// get current Y
|
|
$y = $pdf->GetY();
|
|
|
|
$pdf->SetXY($col1_x, $y);
|
|
$pdf->Cell($label_width, $line_height, 'Customer Name:');
|
|
$pdf->MultiCell($val_width, $line_height, $customer ? $customer->getFirstName() . ' ' . $customer->getLastName() : '', 0, 'L');
|
|
|
|
// get Y after left cell
|
|
$y1 = $pdf->GetY();
|
|
|
|
$pdf->SetXY($col2_x, $y);
|
|
$pdf->Cell($label_width, $line_height, 'Mobile Phone:');
|
|
$pdf->MultiCell(0, $line_height, $customer && $customer->getPhoneMobile() ? $this->country_code . $customer->getPhoneMobile() : '', 0, 'L');
|
|
|
|
// get Y after right cell
|
|
$y2 = $pdf->GetY();
|
|
|
|
// get row height
|
|
$y = max($y1, $y2);
|
|
|
|
$pdf->SetXY($col1_x, $y);
|
|
$pdf->Cell($label_width, $line_height, 'Delivery Date:');
|
|
$pdf->MultiCell($val_width, $line_height, $obj->getDateSchedule() ? $obj->getDateSchedule()->format("m/d/Y") : '', 0, 'left');
|
|
|
|
// get Y after left cell
|
|
$y1 = $pdf->GetY();
|
|
|
|
$pdf->SetXY($col2_x, $y);
|
|
$pdf->Cell($label_width, $line_height, 'Landline:');
|
|
$pdf->MultiCell(0, $line_height, $customer && $customer->getPhoneLandline() ? $this->country_code . $customer->getPhoneLandline() : '', 0, 'L');
|
|
|
|
// get Y after right cell
|
|
$y2 = $pdf->GetY();
|
|
|
|
// get row height
|
|
$y = max($y1, $y2);
|
|
|
|
$pdf->SetXY($col2_x, $y);
|
|
$pdf->Cell($label_width, $line_height, 'Office Phone:');
|
|
$pdf->MultiCell(0, $line_height, $customer && $customer->getPhoneOffice() ? $this->country_code . $customer->getPhoneOffice() : '', 0, 'L');
|
|
|
|
$pdf->SetX($col2_x);
|
|
$pdf->Cell($label_width, $line_height, 'Fax:');
|
|
$pdf->MultiCell($val_width, $line_height, $customer && $customer->getPhoneFax() ? $this->country_code . $customer->getPhoneFax() : '', 0, 'L');
|
|
|
|
// insert vehicle info
|
|
$cv = $obj->getCustomerVehicle();
|
|
$vehicle = $cv->getVehicle();
|
|
$pdf->Ln();
|
|
$pdf->SetFont($font_face, 'B', $header_font_size);
|
|
$pdf->Cell($label_width, $line_height, 'Vehicle Details');
|
|
$pdf->Ln($line_height * 2);
|
|
|
|
// get current Y
|
|
$y = $pdf->GetY();
|
|
|
|
$pdf->SetFont($font_face, '', $body_font_size);
|
|
$pdf->Cell($label_width, $line_height, 'Plate Number:');
|
|
$pdf->MultiCell($val_width, $line_height, $cv ? $cv->getPlateNumber() : '', 0, 'L');
|
|
|
|
// get Y after left cell
|
|
$y1 = $pdf->GetY();
|
|
|
|
$pdf->SetXY($col2_x, $y);
|
|
$pdf->Cell($label_width, $line_height, 'Vehicle Color:');
|
|
$pdf->MultiCell(0, $line_height, $cv ? $cv->getColor() : '', 0, 'L');
|
|
|
|
// get Y after right cell
|
|
$y2 = $pdf->GetY();
|
|
|
|
// get row height
|
|
$y = max($y1, $y2);
|
|
|
|
$pdf->SetXY($col1_x, $y);
|
|
$pdf->Cell($label_width, $line_height, 'Brand:');
|
|
$pdf->MultiCell($val_width, $line_height, $vehicle && $vehicle->getManufacturer() ? $vehicle->getManufacturer()->getName() : '', 0, 'L');
|
|
|
|
// get Y after left cell
|
|
$y1 = $pdf->GetY();
|
|
|
|
$pdf->SetXY($col2_x, $y);
|
|
$pdf->Cell($label_width, $line_height, 'Model / Year:');
|
|
$pdf->MultiCell(0, $line_height, $cv ? $cv->getModelYear() : '', 0, 'L');
|
|
|
|
// get Y after right cell
|
|
$y2 = $pdf->GetY();
|
|
|
|
// get row height
|
|
$y = max($y1, $y2);
|
|
|
|
$pdf->SetXY($col1_x, $y);
|
|
$pdf->Cell($label_width, $line_height, 'Make:');
|
|
$pdf->MultiCell($val_width, $line_height, $vehicle ? $vehicle->getMake() : '', 0, 'L');
|
|
|
|
// insert battery info
|
|
$battery = $cv->getCurrentBattery();
|
|
$pdf->Ln();
|
|
$pdf->SetFont($font_face, 'B', $header_font_size);
|
|
$pdf->Cell($label_width, $line_height, 'Battery Details');
|
|
$pdf->Ln($line_height * 2);
|
|
|
|
$pdf->SetFont($font_face, '', $body_font_size);
|
|
|
|
// get current Y
|
|
$y = $pdf->GetY();
|
|
|
|
$pdf->Cell($label_width, $line_height, 'Current Battery:');
|
|
$pdf->MultiCell($val_width, $line_height, $battery && $battery->getManufacturer() && $battery->getModel() && $battery->getSize() ? $battery->getManufacturer()->getName() . ' ' . $battery->getModel()->getName() . ' ' . $battery->getSize()->getName() . ' (' . $battery->getProductCode() . ')' : '', 0, 'L');
|
|
|
|
// get Y after left cell
|
|
$y1 = $pdf->GetY();
|
|
|
|
$pdf->SetXY($col2_x, $y);
|
|
$pdf->Cell($label_width, $line_height, 'Serial Number:');
|
|
$pdf->MultiCell(0, $line_height, $cv ? $cv->getWarrantyCode() : '', 0, 'L');
|
|
|
|
// get Y after right cell
|
|
$y2 = $pdf->GetY();
|
|
|
|
// get row height
|
|
$y = max($y1, $y2);
|
|
|
|
$pdf->SetXY($col1_x, $y);
|
|
$pdf->Cell($label_width, $line_height, 'Wty. Exp. Date:');
|
|
$pdf->MultiCell($val_width, $line_height, $cv && $cv->getWarrantyExpiration() ? $cv->getWarrantyExpiration()->format("d/m/Y") : '', 0, 'L');
|
|
|
|
// insert transaction details
|
|
$pdf->Ln();
|
|
$pdf->SetFont($font_face, 'B', $header_font_size);
|
|
$pdf->Cell($label_width, $line_height, 'Transaction Details');
|
|
$pdf->Ln($line_height * 2);
|
|
|
|
$pdf->SetFont($font_face, '', $body_font_size);
|
|
|
|
// get current Y
|
|
$y = $pdf->GetY();
|
|
|
|
$pdf->Cell($label_width, $line_height, 'Warranty Class:');
|
|
$pdf->MultiCell($val_width, $line_height, CMBWarrantyClass::getName($obj->getWarrantyClass()), 0, 'L');
|
|
|
|
// get Y after left cell
|
|
$y1 = $pdf->GetY();
|
|
|
|
$pdf->SetXY($col2_x, $y);
|
|
$pdf->Cell($label_width, $line_height, 'Mode of Payment:');
|
|
$pdf->MultiCell(0, $line_height, CMBModeOfPayment::getName($obj->getModeOfPayment()), 0, 'L');
|
|
|
|
// get Y after right cell
|
|
$y2 = $pdf->GetY();
|
|
|
|
// get row height
|
|
$y = max($y1, $y2);
|
|
|
|
$pdf->Cell($label_width, $line_height, 'Delivery Address:');
|
|
$pdf->MultiCell($val_width, $line_height, $obj->getDeliveryAddress(), 0, 'L');
|
|
|
|
// get Y after left cell
|
|
$y1 = $pdf->GetY();
|
|
|
|
$pdf->SetXY($col2_x, $y);
|
|
$pdf->Cell($label_width, $line_height, 'Landmark:');
|
|
$pdf->MultiCell(0, $line_height, $obj->getLandMark(), 0, 'L');
|
|
|
|
// get Y after right cell
|
|
$y2 = $pdf->GetY();
|
|
|
|
// get row height
|
|
$y = max($y1, $y2);
|
|
|
|
$pdf->SetXY($col1_x, $y);
|
|
$pdf->Cell($label_width, $line_height, 'Dispatch Time:');
|
|
$pdf->MultiCell($val_width, $line_height, $obj->getDateSchedule() ? $obj->getDateSchedule()->format("g:i A") : '', 0, 'L');
|
|
|
|
// get Y after left cell
|
|
$y1 = $pdf->GetY();
|
|
|
|
$pdf->SetXY($col2_x, $y);
|
|
$pdf->Cell($label_width, $line_height, 'Dispatched By:');
|
|
$pdf->MultiCell(0, $line_height, $obj->getProcessedBy() ? $obj->getProcessedBy()->getFullName() : '', 0, 'L');
|
|
|
|
// get Y after right cell
|
|
$y2 = $pdf->GetY();
|
|
|
|
// get row height
|
|
$y = max($y1, $y2);
|
|
|
|
// insert delivery instructions
|
|
$pdf->SetY($y);
|
|
$pdf->Ln();
|
|
$pdf->SetFont($font_face, 'B', $header_font_size);
|
|
$pdf->Cell(0, $line_height, $translated_delivery_instructions_label);
|
|
$pdf->Ln();
|
|
|
|
$pdf->SetFont($font_face, '', $body_font_size);
|
|
$pdf->MultiCell(0, $line_height, $obj->getDeliveryInstructions(), 1, 'L');
|
|
|
|
// insert invoice details
|
|
$pdf->Ln();
|
|
$pdf->SetFont($font_face, 'B', $header_font_size);
|
|
$pdf->Cell($label_width, $line_height, 'Invoice Details');
|
|
$pdf->Ln();
|
|
|
|
// invoice table headers
|
|
$invoice = $obj->getInvoice();
|
|
$pdf->SetFont($font_face, 'B', $header_font_size);
|
|
$pdf->Cell($table_col_width * 6, $table_line_height, 'Item', 1, 0, 'L', 1);
|
|
$pdf->Cell($table_col_width * 2, $table_line_height, 'Quantity', 1, 0, 'R', 1);
|
|
$pdf->Cell($table_col_width * 2, $table_line_height, 'Unit Price', 1, 0, 'R', 1);
|
|
$pdf->Cell($table_col_width * 2, $table_line_height, 'Amount', 1, 1, 'R', 1);
|
|
$pdf->SetFont($font_face, '', $body_font_size);
|
|
|
|
// build invoice items table
|
|
if ($invoice && !empty($invoice->getItems()))
|
|
{
|
|
foreach ($invoice->getItems() as $item)
|
|
{
|
|
$pdf->Cell($table_col_width * 6, $table_line_height, $item->getTitle(), 1);
|
|
$pdf->Cell($table_col_width * 2, $table_line_height, number_format($item->getQuantity()), 1, 0, 'R');
|
|
$pdf->Cell($table_col_width * 2, $table_line_height, number_format($item->getPrice(), 2), 1, 0, 'R');
|
|
$pdf->Cell($table_col_width * 2, $table_line_height, number_format($item->getPrice() * $item->getQuantity(), 2), 1, 1, 'R');
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$pdf->Cell($table_col_width * 12, 7, 'No items', 1, 1);
|
|
}
|
|
|
|
$pdf->Ln($line_height * 2);
|
|
|
|
// get current Y
|
|
$y = $pdf->GetY();
|
|
|
|
// insert invoice footer details
|
|
$pdf->Cell($label_width, $line_height, 'Transaction Type:');
|
|
$pdf->MultiCell($val_width, $line_height, CMBServiceType::getName($obj->getServiceType()), 0, 'L');
|
|
|
|
// get Y after left cell
|
|
$y1 = $pdf->GetY();
|
|
|
|
$pdf->SetXY($col2_x, $y);
|
|
$pdf->SetFont($font_face, 'B');
|
|
$pdf->Cell($label_width, $line_height, 'SUBTOTAL:');
|
|
$pdf->SetFont($font_face, '');
|
|
$pdf->MultiCell(0, $line_height, $invoice ? number_format($invoice->getVATExclusivePrice(), 2) : '', 0, 'R');
|
|
|
|
// get Y after right cell
|
|
$y2 = $pdf->GetY();
|
|
|
|
// get row height
|
|
$y = max($y1, $y2);
|
|
|
|
$pdf->SetXY($col1_x, $y);
|
|
$pdf->Cell($label_width, $line_height, 'OR Name:');
|
|
$pdf->MultiCell($val_width, $line_height, $obj->getORName(), 0, 'L');
|
|
|
|
// get Y after left cell
|
|
$y1 = $pdf->GetY();
|
|
|
|
$pdf->SetXY($col2_x, $y);
|
|
$pdf->SetFont($font_face, 'B');
|
|
$pdf->Cell($label_width, $line_height, 'TAX:');
|
|
$pdf->SetFont($font_face, '');
|
|
$pdf->MultiCell(0, $line_height, $invoice ? number_format($invoice->getVAT(), 2) : '', 0, 'R');
|
|
|
|
// get Y after right cell
|
|
$y2 = $pdf->GetY();
|
|
|
|
// get row height
|
|
$y = max($y1, $y2);
|
|
|
|
$pdf->SetXY($col1_x, $y);
|
|
$pdf->Cell($label_width, $line_height, 'Emp. ID/Card No./Ref. By:');
|
|
$pdf->MultiCell($val_width, $line_height, $obj->getPromoDetail(), 0, 'L');
|
|
|
|
// get Y after left cell
|
|
$y1 = $pdf->GetY();
|
|
|
|
$pdf->SetXY($col2_x, $y);
|
|
$pdf->SetFont($font_face, 'B');
|
|
$pdf->Cell($label_width, $line_height, 'DISCOUNT:');
|
|
$pdf->SetFont($font_face, '');
|
|
$pdf->MultiCell(0, $line_height, $invoice ? number_format($invoice->getDiscount(), 2) : '', 0, 'R');
|
|
|
|
// get Y after right cell
|
|
$y2 = $pdf->GetY();
|
|
|
|
// get row height
|
|
$y = max($y1, $y2);
|
|
|
|
$pdf->SetXY($col1_x, $y);
|
|
$pdf->Cell($label_width, $line_height, 'Discount Type:');
|
|
$pdf->MultiCell($val_width, $line_height, $invoice && $invoice->getPromo() ? $invoice->getPromo()->getName() : '', 0, 'L');
|
|
|
|
$pdf->SetXY($col2_x, $y);
|
|
$pdf->SetFont($font_face, 'B');
|
|
$pdf->Cell($label_width, $line_height, 'FINAL AMOUNT:');
|
|
$pdf->MultiCell(0, $line_height, $invoice ? number_format($invoice->getTotalPrice(), 2) : '', 0, 'R');
|
|
$pdf->SetFont($font_face, '');
|
|
|
|
$params['obj'] = $pdf;
|
|
$params['filename'] = $filename;
|
|
|
|
return $params;
|
|
}
|
|
|
|
public function getTwigTemplate($id)
|
|
{
|
|
if (isset($this->template_hash[$id]))
|
|
{
|
|
return $this->template_hash[$id];
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function updateVehicleBattery(JobOrder $jo)
|
|
{
|
|
// check if new battery
|
|
if (!($this->checkIfNewBattery($jo)))
|
|
return;
|
|
|
|
// customer vehicle
|
|
$cv = $jo->getCustomerVehicle();
|
|
if ($cv == null)
|
|
return;
|
|
|
|
// invoice
|
|
$invoice = $jo->getInvoice();
|
|
if ($invoice == null)
|
|
return;
|
|
|
|
// invoice items
|
|
$items = $invoice->getItems();
|
|
if (count($items) <= 0)
|
|
return;
|
|
|
|
// get first battery from invoice
|
|
$battery = null;
|
|
foreach ($items as $item)
|
|
{
|
|
$battery = $item->getBattery();
|
|
if ($battery != null)
|
|
break;
|
|
}
|
|
|
|
// no battery in order
|
|
if ($battery == null)
|
|
return;
|
|
|
|
// warranty expiration
|
|
// use GetWarrantyPrivate for passenger warranty
|
|
$warr_months = 0;
|
|
$warr = $jo->getWarrantyClass();
|
|
if ($warr == CMBWarrantyClass::WTY_PASSENGER)
|
|
$warr_months = $battery->getWarrantyPrivate();
|
|
else if ($warr == CMBWarrantyClass::WTY_COMMERCIAL)
|
|
$warr_months = $battery->getWarrantyCommercial();
|
|
|
|
$warr_date = new DateTime();
|
|
$warr_date->add(new DateInterval('P' . $warr_months . 'M'));
|
|
|
|
// update customer vehicle battery
|
|
$cv->setCurrentBattery($battery)
|
|
->setHasMotoliteBattery(true)
|
|
->setWarrantyExpiration($warr_date);
|
|
}
|
|
|
|
public function getOtherParameters()
|
|
{
|
|
// get riders for dropdown
|
|
$params['riders'] = $this->em->getRepository(Rider::class)->findAll();
|
|
|
|
return $params;
|
|
}
|
|
|
|
public function checkIfNewBattery(JobOrder $jo)
|
|
{
|
|
if ($jo->getServiceType() == CMBServiceType::BATTERY_REPLACEMENT_NEW)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
public function initializeWalkinForm()
|
|
{
|
|
$params['obj'] = new JobOrder();
|
|
$params['mode'] = 'walk-in';
|
|
|
|
$this->fillDropdownParameters($params);
|
|
$this->fillFormTags($params);
|
|
|
|
// get template to display
|
|
$params['template'] = $this->getTwigTemplate('jo_walkin');
|
|
|
|
// return params
|
|
return $params;
|
|
}
|
|
|
|
public function processWalkinJobOrder(Request $req, $id)
|
|
{
|
|
// initialize error list
|
|
$error_array = [];
|
|
|
|
$em = $this->em;
|
|
|
|
$jo = $em->getRepository(JobOrder::class)->find($id);
|
|
if (empty($jo))
|
|
{
|
|
// new job order
|
|
$jo = new JobOrder();
|
|
}
|
|
|
|
// check if new customer
|
|
if ($req->request->get('new_customer'))
|
|
{
|
|
if (empty($req->request->get('customer_customer_notes')))
|
|
{
|
|
$error_array['customer_customer_notes'] = 'Customer notes cannot be null.';
|
|
}
|
|
|
|
// validate mobile phone
|
|
$valid_mobile = $this->cust_handler->validateMobileNumber($req->request->get('customer_phone_mobile'));
|
|
if (!($valid_mobile))
|
|
$error_array['customer_phone_mobile'] = 'Invalid mobile phone number.';
|
|
|
|
// find the vehicle using vid
|
|
$new_vehicle = $em->getRepository(Vehicle::class)->find($req->request->get('vid'));
|
|
if (empty($new_vehicle))
|
|
{
|
|
$error_array['cv_mfg'] = 'Invalid manufacturer specified.';
|
|
$error_array['cv_make'] = 'Invalid make specified.';
|
|
}
|
|
|
|
if (empty($error_array))
|
|
{
|
|
$new_cust = new Customer();
|
|
$new_cv = new CustomerVehicle();
|
|
|
|
$new_cust->setLastName($req->request->get('customer_last_name'))
|
|
->setFirstName($req->request->get('customer_first_name'))
|
|
->setPhoneMobile($req->request->get('customer_phone_mobile'))
|
|
->setPhoneLandline($req->request->get('customer_phone_landline'))
|
|
->setPhoneOffice($req->request->get('customer_phone_office'))
|
|
->setPhoneFax($req->request->get('customer_phone_fax'))
|
|
->setCustomerNotes($req->request->get('customer_customer_notes'));
|
|
|
|
$new_cv->setCustomer($new_cust)
|
|
->setVehicle($new_vehicle)
|
|
->setPlateNumber($req->request->get('cv_plate'))
|
|
->setModelYear($req->request->get('cv_year'))
|
|
->setColor('')
|
|
->setStatusCondition('')
|
|
->setFuelType('')
|
|
->setActive()
|
|
->setWarrantyCode($req->request->get('warranty_code'));
|
|
|
|
if (($req->request->get('service_type')) == CMBServiceType::BATTERY_REPLACEMENT_NEW)
|
|
{
|
|
$new_cv->setHasMotoliteBattery(true);
|
|
}
|
|
else
|
|
{
|
|
$new_cv->setHasMotoliteBattery(false);
|
|
}
|
|
|
|
// link JO to new customer
|
|
$jo->setCustomer($new_cust);
|
|
$jo->setCustomerVehicle($new_cv);
|
|
|
|
$em->persist($new_cust);
|
|
$em->persist($new_cv);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// check if customer vehicle is set
|
|
if (empty($req->request->get('customer_vehicle'))) {
|
|
$error_array['customer_vehicle'] = 'No vehicle selected.';
|
|
} else
|
|
{
|
|
// get customer vehicle
|
|
$cust_vehicle = $em->getRepository(CustomerVehicle::class)->find($req->request->get('customer_vehicle'));
|
|
|
|
if (empty($cust_vehicle)) {
|
|
$error_array['customer_vehicle'] = 'Invalid vehicle specified.';
|
|
}
|
|
else
|
|
{
|
|
$jo->setCustomerVehicle($cust_vehicle);
|
|
$jo->setCustomer($cust_vehicle->getCustomer());
|
|
|
|
// save serial into cv
|
|
$cust_vehicle->setWarrantyCode($req->request->get('warranty_code'));
|
|
|
|
$em->persist($cust_vehicle);
|
|
}
|
|
}
|
|
}
|
|
|
|
// check if hub is selected
|
|
if (empty($req->request->get('hub_id')))
|
|
$error_array['hub'] = 'No hub selected.';
|
|
else
|
|
{
|
|
// get hub
|
|
$hub = $em->getRepository(Hub::class)->find($req->request->get('hub_id'));
|
|
|
|
if (empty($hub))
|
|
$error_array['hub'] = 'Invalid hub specified.';
|
|
|
|
// get hub coordinates
|
|
$hub_coordinates = $hub->getCoordinates();
|
|
}
|
|
|
|
// get discount and set to meta
|
|
$discount = $req->request->get('invoice_promo');
|
|
|
|
// check if discount is greater than 50 or negative number
|
|
if (($discount > 50) || ($discount < 0))
|
|
$error_array['invoice_promo'] = 'Invalid discount specified';
|
|
|
|
if (empty($error_array))
|
|
{
|
|
// get current user
|
|
$user = $this->security->getUser();
|
|
|
|
$stype = $req->request->get('service_type');
|
|
|
|
// set and save values
|
|
$jo->setDateSchedule(DateTime::createFromFormat("d M Y h:i A", $req->request->get('date_schedule_date') . " " . $req->request->get('date_schedule_time')))
|
|
->setAdvanceOrder($req->request->get('flag_advance') ?? false)
|
|
->setServiceType($stype)
|
|
->setWarrantyClass($req->request->get('warranty_class'))
|
|
->setSource($req->request->get('source'))
|
|
->setStatus(JOStatus::FULFILLED)
|
|
->setTier1Notes($req->request->get('tier1_notes'))
|
|
->setTier2Notes($req->request->get('tier2_notes'))
|
|
->setORName($req->request->get('or_name'))
|
|
->setPromoDetail($req->request->get('promo_detail'))
|
|
->setModeOfPayment($req->request->get('mode_of_payment'))
|
|
->setLandmark($req->request->get('landmark'))
|
|
->setDeliveryAddress('Walk-in')
|
|
->setLandmark('Walk-in')
|
|
->setCoordinates($hub_coordinates)
|
|
->setHub($hub);
|
|
|
|
$jo->addMeta('discount', $discount);
|
|
|
|
// check if user is null, meaning call to create came from API
|
|
if ($user != null)
|
|
{
|
|
$jo->setCreatedBy($user);
|
|
}
|
|
|
|
// check if reference JO is set and validate
|
|
if (!empty($req->request->get('ref_jo'))) {
|
|
// get reference JO
|
|
$ref_jo = $em->getRepository(JobOrder::class)->find($req->request->get('ref_jo'));
|
|
|
|
if (empty($ref_jo)) {
|
|
$error_array['ref_jo'] = 'Invalid reference job order specified.';
|
|
} else {
|
|
$jo->setReferenceJO($ref_jo);
|
|
}
|
|
}
|
|
|
|
// call service to generate job order and invoice
|
|
$invoice_items = $req->request->get('invoice_items', []);
|
|
$promo_id = $req->request->get('invoice_promo');
|
|
$invoice_change = $req->request->get('invoice_change', 0);
|
|
|
|
// check if invoice changed
|
|
if ($invoice_change)
|
|
{
|
|
$this->ic->generateInvoiceCriteria($jo, $promo_id, $invoice_items, $error_array);
|
|
}
|
|
|
|
// validate
|
|
$errors = $this->validator->validate($jo);
|
|
|
|
// add errors to list
|
|
foreach ($errors as $error) {
|
|
$error_array[$error->getPropertyPath()] = $error->getMessage();
|
|
}
|
|
|
|
// check if errors are found
|
|
if (empty($error_array))
|
|
{
|
|
// validated, no error. save the job order
|
|
$em->persist($jo);
|
|
|
|
// the event
|
|
$event = new JOEvent();
|
|
$event->setDateHappen(new DateTime())
|
|
->setTypeID(JOEventType::CREATE)
|
|
->setJobOrder($jo);
|
|
|
|
if ($user != null)
|
|
{
|
|
$event->setUser($user);
|
|
}
|
|
|
|
$em->persist($event);
|
|
|
|
// save to customer vehicle battery record
|
|
$this->updateVehicleBattery($jo);
|
|
|
|
// save serial to customer vehicle
|
|
$cust_vehicle = $jo->getCustomerVehicle();
|
|
$cust_vehicle->setWarrantyCode($req->request->get('warranty_code'));
|
|
|
|
$em->persist($cust_vehicle);
|
|
|
|
// create the warranty if new battery only
|
|
if ($this->checkIfNewBattery($jo))
|
|
{
|
|
if (empty($req->request->get('warranty_code')))
|
|
$serial = null;
|
|
else
|
|
$serial = $req->request->get('warranty_code');
|
|
|
|
$warranty_class = $jo->getWarrantyClass();
|
|
$first_name = $jo->getCustomer()->getFirstName();
|
|
$last_name = $jo->getCustomer()->getLastName();
|
|
$mobile_number = $jo->getCustomer()->getPhoneMobile();
|
|
|
|
// check if date fulfilled is null
|
|
if ($jo->getDateFulfill() == null)
|
|
$date_purchase = $jo->getDateCreate();
|
|
else
|
|
$date_purchase = $jo->getDateFulfill();
|
|
|
|
// validate plate number
|
|
// $plate_number = $this->wh->cleanPlateNumber($jo->getCustomerVehicle()->getPlateNumber());
|
|
$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();
|
|
}
|
|
}
|
|
}
|
|
|
|
$this->wh->createWarranty($serial, $plate_number, $first_name, $last_name, $mobile_number, $batt_list, $date_purchase, $warranty_class);
|
|
}
|
|
}
|
|
|
|
$em->flush();
|
|
}
|
|
}
|
|
|
|
return $error_array;
|
|
}
|
|
|
|
public function initializeWalkinEditForm($id)
|
|
{
|
|
$em = $this->em;
|
|
$obj = $em->getRepository(JobOrder::class)->find($id);
|
|
|
|
$params['obj'] = $obj;
|
|
$params['mode'] = 'walk-in-edit';
|
|
$params['cvid'] = $obj->getCustomerVehicle()->getID();
|
|
$params['vid'] = $obj->getCustomerVehicle()->getVehicle()->getID();
|
|
|
|
$this->fillDropdownParameters($params);
|
|
$this->fillFormTags($params);
|
|
|
|
// get template to display
|
|
$params['template'] = $this->getTwigTemplate('jo_walkin_edit');
|
|
|
|
// return params
|
|
return $params;
|
|
}
|
|
|
|
protected function fillDropdownParameters(&$params)
|
|
{
|
|
$em = $this->em;
|
|
|
|
// db loaded
|
|
$params['bmfgs'] = $em->getRepository(BatteryManufacturer::class)->findAll();
|
|
$params['promos'] = $em->getRepository(Promo::class)->findAll();
|
|
$params['service_charges'] = $em->getRepository(ServiceCharge::class)->findAll();
|
|
|
|
// list of hubs
|
|
$hubs = $em->getRepository(Hub::class)->findBy([], ['name' => 'ASC']);
|
|
$fac_hubs = [];
|
|
foreach ($hubs as $hub)
|
|
{
|
|
$fac_hubs[$hub->getID()] = $hub->getName() . ' - ' . $hub->getBranch();
|
|
}
|
|
|
|
// name values
|
|
$params['service_types'] = CMBServiceType::getCollection();
|
|
$params['warranty_classes'] = CMBWarrantyClass::getCollection();
|
|
$params['modes_of_payment'] = CMBModeOfPayment::getCollection();
|
|
$params['statuses'] = JOStatus::getCollection();
|
|
$params['discount_apply'] = DiscountApply::getCollection();
|
|
$params['trade_in_types'] = CMBTradeInType::getCollection();
|
|
$params['facilitated_types'] = FacilitatedType::getCollection();
|
|
$params['facilitated_hubs'] = $fac_hubs;
|
|
$params['sources'] = TransactionOrigin::getCollection();
|
|
}
|
|
|
|
protected function initFormTags(&$params)
|
|
{
|
|
// default to editing, as we have more forms editing than creating
|
|
$params['ftags'] = [
|
|
'title' => 'Job Order Form',
|
|
'vehicle_dropdown' => false,
|
|
'invoice_edit' => false,
|
|
'set_map_coordinate' => true,
|
|
'preset_vehicle' => false,
|
|
'ticket_table' => true,
|
|
'cancel_button' => true,
|
|
];
|
|
}
|
|
|
|
protected function fillFormTags(&$params)
|
|
{
|
|
$this->initFormTags($params);
|
|
|
|
switch ($params['mode'])
|
|
{
|
|
case 'create':
|
|
$params['ftags']['vehicle_dropdown'] = true;
|
|
$params['ftags']['set_map_coordinate'] = false;
|
|
$params['ftags']['invoice_edit'] = true;
|
|
$params['ftags']['ticket_table'] = false;
|
|
$params['ftags']['cancel_button'] = false;
|
|
break;
|
|
case 'create_vehicle':
|
|
$params['ftags']['set_map_coordinate'] = false;
|
|
$params['ftags']['invoice_edit'] = true;
|
|
$params['ftags']['preset_vehicle'] = true;
|
|
$params['ftags']['ticket_table'] = false;
|
|
$params['ftags']['cancel_button'] = false;
|
|
break;
|
|
case 'open_edit':
|
|
$params['ftags']['invoice_edit'] = true;
|
|
$params['ftags']['preset_vehicle'] = true;
|
|
break;
|
|
case 'onestep':
|
|
$params['ftags']['vehicle_dropdown'] = true;
|
|
$params['ftags']['set_map_coordinate'] = false;
|
|
$params['ftags']['invoice_edit'] = true;
|
|
$params['ftags']['ticket_table'] = false;
|
|
$params['ftags']['cancel_button'] = false;
|
|
break;
|
|
case 'onestep-edit':
|
|
$params['ftags']['invoice_edit'] = true;
|
|
$params['ftags']['preset_vehicle'] = true;
|
|
break;
|
|
case 'walk-in':
|
|
$params['ftags']['vehicle_dropdown'] = true;
|
|
$params['ftags']['set_map_coordinate'] = false;
|
|
$params['ftags']['invoice_edit'] = true;
|
|
$params['ftags']['ticket_table'] = false;
|
|
$params['ftags']['cancel_button'] = false;
|
|
break;
|
|
case 'walk-in-edit':
|
|
$params['ftags']['invoice_edit'] = true;
|
|
$params['ftags']['preset_vehicle'] = true;
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
protected function loadTemplates()
|
|
{
|
|
$this->template_hash = [];
|
|
|
|
// add all twig templates for job order to hash
|
|
// TODO: put this in an array declaration
|
|
// $this->template_hash = [
|
|
// 'blah' => 'blah',
|
|
// ];
|
|
$this->template_hash['jo_incoming_form'] = 'job-order/cmb.form.html.twig';
|
|
$this->template_hash['jo_open_edit_form'] = 'job-order/cmb.form.html.twig';
|
|
$this->template_hash['jo_incoming_vehicle_form'] = 'job-order/cmb.form.html.twig';
|
|
$this->template_hash['jo_processing_form'] = 'job-order/cmb.form.html.twig';
|
|
$this->template_hash['jo_assigning_form'] = 'job-order/cmb.form.html.twig';
|
|
$this->template_hash['jo_fulfillment_form'] = 'job-order/cmb.form.html.twig';
|
|
$this->template_hash['jo_open_hub_form'] = 'job-order/cmb.form.html.twig';
|
|
$this->template_hash['jo_open_rider_form'] = 'job-order/cmb.form.html.twig';
|
|
$this->template_hash['jo_all_form'] = 'job-order/cmb.form.html.twig';
|
|
$this->template_hash['jo_list_processing'] = 'job-order/list.processing.html.twig';
|
|
$this->template_hash['jo_list_assigning'] = 'job-order/list.assigning.html.twig';
|
|
$this->template_hash['jo_list_fulfillment'] = 'job-order/list.fulfillment.html.twig';
|
|
$this->template_hash['jo_list_open'] = 'job-order/list.open.html.twig';
|
|
$this->template_hash['jo_list_all'] = 'job-order/list.all.html.twig';
|
|
$this->template_hash['jo_onestep'] = 'job-order/cmb.form.onestep.html.twig';
|
|
$this->template_hash['jo_onestep_edit_form'] = 'job-order/cmb.form.onestep.html.twig';
|
|
$this->template_hash['jo_walkin'] = 'job-order/cmb.form.walkin.html.twig';
|
|
$this->template_hash['jo_walkin_edit'] = 'job-order/cmb.form.walkin.html.twig';
|
|
}
|
|
|
|
protected function checkTier($tier)
|
|
{
|
|
// check specified tier
|
|
switch ($tier) {
|
|
case 'proc':
|
|
$tier_key = 'jo_proc';
|
|
$tier_name = 'Dispatch';
|
|
$rows_route = 'jo_proc_rows';
|
|
$edit_route = 'jo_proc_form';
|
|
$unlock_route = 'jo_proc_unlock';
|
|
$jo_status = JOStatus::PENDING;
|
|
break;
|
|
case 'assign':
|
|
$tier_key = 'jo_assign';
|
|
$tier_name = 'Assigning';
|
|
$rows_route = 'jo_assign_rows';
|
|
$edit_route = 'jo_assign_form';
|
|
$unlock_route = 'jo_assign_unlock';
|
|
$jo_status = JOStatus::RIDER_ASSIGN;
|
|
break;
|
|
case 'fulfill':
|
|
$tier_key = 'jo_fulfill';
|
|
$tier_name = 'Fullfillment';
|
|
$rows_route = 'jo_fulfill_rows';
|
|
$edit_route = 'jo_fulfill_form';
|
|
$unlock_route = '';
|
|
$jo_status = [
|
|
JOStatus::ASSIGNED,
|
|
JOStatus::IN_PROGRESS
|
|
];
|
|
break;
|
|
case 'open':
|
|
$tier_key = 'jo_open';
|
|
$tier_name = 'Open';
|
|
$rows_route = 'jo_open_rows';
|
|
$edit_route = '';
|
|
$unlock_route = '';
|
|
$jo_status = [
|
|
JOStatus::PENDING,
|
|
JOStatus::RIDER_ASSIGN,
|
|
JOStatus::ASSIGNED,
|
|
JOStatus::IN_PROGRESS,
|
|
JOStatus::IN_TRANSIT,
|
|
];
|
|
break;
|
|
case 'all':
|
|
$tier_key = 'jo_open';
|
|
$tier_name = 'Open';
|
|
$rows_route = 'jo_open_rows';
|
|
$edit_route = 'jo_all_form';
|
|
$unlock_route = '';
|
|
$jo_status = '';
|
|
break;
|
|
default:
|
|
throw new AccessDeniedHttpException('No access.');
|
|
}
|
|
|
|
// check acl
|
|
if (!($this->security->isGranted($tier_key . '.list')))
|
|
throw new AccessDeniedHttpException('No access.');
|
|
|
|
// return params if allowed access
|
|
return [
|
|
'key' => $tier_key,
|
|
'name' => $tier_name,
|
|
'rows_route' => $rows_route,
|
|
'edit_route' => $edit_route,
|
|
'unlock_route' => $unlock_route,
|
|
'jo_status' => $jo_status
|
|
];
|
|
}
|
|
|
|
// TODO: re-enable search, figure out how to group the orWhere filters into one, so can execute that plus the pending filter
|
|
// check if datatable filter is present and append to query
|
|
protected function setQueryFilters($datatable, &$query, $qb, $hubs, $tier, $status)
|
|
{
|
|
switch ($tier)
|
|
{
|
|
case 'fulfill':
|
|
if (isset($datatable['query']['data-rows-search']))
|
|
{
|
|
$query->innerJoin('q.cus_vehicle', 'cv')
|
|
->innerJoin('q.customer', 'c')
|
|
->where('cv.plate_number like :filter')
|
|
->orWhere('c.phone_mobile like :filter')
|
|
->orWhere('c.first_name like :filter or c.last_name like :filter')
|
|
->setParameter('filter', $datatable['query']['data-rows-search'] . '%');
|
|
}
|
|
if (isset($datatable['query']['rider']))
|
|
{
|
|
$query->innerJoin('q.rider', 'r')
|
|
->andWhere('r.id = :rider_id')
|
|
->setParameter('rider_id', $datatable['query']['rider']);
|
|
}
|
|
if (isset($datatable['query']['schedule_date']))
|
|
{
|
|
$start = $datatable['query']['schedule_date'][0] . ' ' . '00:00:00';
|
|
$end = $datatable['query']['schedule_date'][1] . ' ' . '23:59:00';
|
|
|
|
$date_start = DateTime::createFromFormat('m/d/Y H:i:s', $start);
|
|
$date_end = DateTime::createFromFormat('m/d/Y H:i:s', $end);
|
|
|
|
$query->andWhere('q.date_schedule >= :date_start')
|
|
->andWhere('q.date_schedule <= :date_end')
|
|
->setParameter('date_start', $date_start)
|
|
->setParameter('date_end', $date_end);
|
|
}
|
|
|
|
$query->andWhere('q.status IN (:statuses)')
|
|
->andWhere('q.hub IN (:hubs)')
|
|
->setParameter('statuses', $status, Connection::PARAM_STR_ARRAY)
|
|
->setParameter('hubs', $hubs, Connection::PARAM_STR_ARRAY);
|
|
break;
|
|
case 'assign':
|
|
$query->where('q.status = :status')
|
|
->andWhere('q.hub IN (:hubs)')
|
|
->setParameter('status', $status)
|
|
->setParameter('hubs', $hubs, Connection::PARAM_STR_ARRAY);
|
|
break;
|
|
case 'open':
|
|
if (isset($datatable['query']['data-rows-search']))
|
|
{
|
|
$query->innerJoin('q.cus_vehicle', 'cv')
|
|
->innerJoin('q.customer', 'c')
|
|
->where('q.status IN (:statuses)')
|
|
->andWhere('cv.plate_number like :filter or c.first_name like :filter or c.last_name like :filter or c.phone_mobile like :filter')
|
|
->setParameter('statuses', $status, Connection::PARAM_STR_ARRAY)
|
|
->setParameter('filter', $datatable['query']['data-rows-search'] . '%');
|
|
}
|
|
else
|
|
{
|
|
$query->where('q.status IN (:statuses)')
|
|
->setParameter('statuses', $status, Connection::PARAM_STR_ARRAY);
|
|
}
|
|
if (isset($datatable['query']['rider']))
|
|
{
|
|
$query->innerJoin('q.rider', 'r')
|
|
->andWhere('r.id = :rider_id')
|
|
->setParameter('rider_id', $datatable['query']['rider']);
|
|
}
|
|
if (isset($datatable['query']['schedule_date']))
|
|
{
|
|
$start = $datatable['query']['schedule_date'][0] . ' ' . '00:00:00';
|
|
$end = $datatable['query']['schedule_date'][1] . ' ' . '23:59:00';
|
|
|
|
$date_start = DateTime::createFromFormat('m/d/Y H:i:s', $start);
|
|
$date_end = DateTime::createFromFormat('m/d/Y H:i:s', $end);
|
|
|
|
$query->andWhere('q.date_schedule >= :date_start')
|
|
->andWhere('q.date_schedule <= :date_end')
|
|
->setParameter('date_start', $date_start)
|
|
->setParameter('date_end', $date_end);
|
|
}
|
|
break;
|
|
case 'all':
|
|
if (isset($datatable['query']['data-rows-search']))
|
|
{
|
|
$query->innerJoin('q.cus_vehicle', 'cv')
|
|
->innerJoin('q.customer', 'c')
|
|
->where('cv.plate_number like :filter')
|
|
->orWhere('c.phone_mobile like :filter')
|
|
->orWhere('c.first_name like :filter or c.last_name like :filter')
|
|
->setParameter('filter', $datatable['query']['data-rows-search'] . '%');
|
|
}
|
|
if (isset($datatable['query']['rider']))
|
|
{
|
|
$query->innerJoin('q.rider', 'r')
|
|
->andWhere('r.id = :rider_id')
|
|
->setParameter('rider_id', $datatable['query']['rider']);
|
|
}
|
|
if (isset($datatable['query']['schedule_date']))
|
|
{
|
|
$start = $datatable['query']['schedule_date'][0] . ' ' . '00:00:00';
|
|
$end = $datatable['query']['schedule_date'][1] . ' ' . '23:59:00';
|
|
|
|
$date_start = DateTime::createFromFormat('m/d/Y H:i:s', $start);
|
|
$date_end = DateTime::createFromFormat('m/d/Y H:i:s', $end);
|
|
|
|
$query->andWhere('q.date_schedule >= :date_start')
|
|
->andWhere('q.date_schedule <= :date_end')
|
|
->setParameter('date_start', $date_start)
|
|
->setParameter('date_end', $date_end);
|
|
}
|
|
break;
|
|
default:
|
|
$query->where('q.status = :status')
|
|
->setParameter('status', $status);
|
|
}
|
|
}
|
|
}
|