1611 lines
51 KiB
PHP
1611 lines
51 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\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\Battery;
|
|
use App\Entity\BatteryManufacturer;
|
|
use App\Entity\JOEvent;
|
|
use App\Entity\CustomerVehicle;
|
|
use App\Entity\Hub;
|
|
use App\Entity\Promo;
|
|
use App\Entity\Rider;
|
|
use App\Entity\JORejection;
|
|
|
|
use App\Ramcar\InvoiceCriteria;
|
|
use App\Ramcar\ServiceType;
|
|
use App\Ramcar\TradeInType;
|
|
use App\Ramcar\JOEventType;
|
|
use App\Ramcar\JOStatus;
|
|
use App\Ramcar\WarrantyClass;
|
|
use App\Ramcar\DiscountApply;
|
|
use App\Ramcar\ModeOfPayment;
|
|
use App\Ramcar\TransactionOrigin;
|
|
use App\Ramcar\FacilitatedType;
|
|
use App\Ramcar\JORejectionReason;
|
|
|
|
use App\Service\InvoiceGeneratorInterface;
|
|
use App\Service\JobOrderHandlerInterface;
|
|
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;
|
|
|
|
class ResqJobOrderHandler implements JobOrderHandlerInterface
|
|
{
|
|
protected $em;
|
|
protected $ic;
|
|
|
|
public function __construct(Security $security, EntityManagerInterface $em,
|
|
InvoiceGeneratorInterface $ic, ValidatorInterface $validator)
|
|
{
|
|
$this->em = $em;
|
|
$this->ic = $ic;
|
|
$this->security = $security;
|
|
$this->validator = $validator;
|
|
}
|
|
|
|
// 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)
|
|
{
|
|
// TODO: move invoice processing to InvoiceGenerator
|
|
$this->processInvoice($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, MQTTCLient $mclient, APNSClient $aclient)
|
|
{
|
|
// 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))
|
|
{
|
|
// set rider unavailable
|
|
$rider->setAvailable(false);
|
|
|
|
// 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();
|
|
|
|
// send event to mobile app
|
|
$payload = [
|
|
'event' => 'driver_assigned'
|
|
];
|
|
$mclient->sendEvent($obj, $payload);
|
|
$mclient->sendRiderEvent($obj, $payload);
|
|
|
|
// sned push notification
|
|
$aclient->sendPush($obj, "A RESQ rider is on his way to you.");
|
|
}
|
|
|
|
return $error_array;
|
|
}
|
|
|
|
// fulfill job order
|
|
public function fulfillJobOrder(Request $req, $id, MQTTClient $mclient)
|
|
{
|
|
// 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);
|
|
|
|
// validated! save the entity
|
|
$em->flush();
|
|
|
|
// 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();
|
|
|
|
// send to mqtt
|
|
$payload = [
|
|
'event' => 'fulfilled',
|
|
'jo_id' => $obj->getID(),
|
|
'driver_image' => $image_url,
|
|
'driver_name' => $rider->getFullName(),
|
|
'driver_id' => $rider->getID(),
|
|
];
|
|
$mclient->sendEvent($obj, $payload);
|
|
$mclient->sendRiderEvent($obj, $payload);
|
|
}
|
|
}
|
|
|
|
// 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);
|
|
|
|
// return params
|
|
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);
|
|
|
|
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);
|
|
|
|
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);
|
|
|
|
$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 initializeDispatchForm($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;
|
|
|
|
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);
|
|
|
|
$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);
|
|
|
|
$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;
|
|
|
|
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;
|
|
|
|
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();
|
|
|
|
// 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'] = ServiceType::getCollection();
|
|
$params['warranty_classes'] = WarrantyClass::getCollection();
|
|
$params['modes_of_payment'] = ModeOfPayment::getCollection();
|
|
$params['statuses'] = JOStatus::getCollection();
|
|
$params['discount_apply'] = DiscountApply::getCollection();
|
|
$params['trade_in_types'] = TradeInType::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;
|
|
}
|
|
}
|
|
|
|
protected function updateVehicleBattery(JobOrder $jo)
|
|
{
|
|
// check if new battery
|
|
if ($jo->getServiceType() != ServiceType::BATTERY_REPLACEMENT_NEW)
|
|
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
|
|
$warr = $jo->getWarrantyClass();
|
|
if ($warr == WarrantyClass::WTY_PRIVATE)
|
|
$warr_months = $battery->getWarrantyPrivate();
|
|
else if ($warr == WarrantyClass::WTY_COMMERCIAL)
|
|
$warr_months = $battery->getWarrantyCommercial();
|
|
else if ($warr == WarrantyClass::WTY_TNV)
|
|
$warr_months = 12;
|
|
|
|
$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);
|
|
}
|
|
|
|
|
|
// TODO: move this to InvoiceGenerator
|
|
protected function processInvoice($jo, $promo_id, $invoice_items, &$error_array)
|
|
{
|
|
// instantiate the invoice criteria
|
|
$criteria = new InvoiceCriteria();
|
|
$criteria->setServiceType($jo->getServiceType())
|
|
->setCustomerVehicle($jo->getCustomerVehicle());
|
|
|
|
$ierror = $this->invoicePromo($criteria, $promo_id);
|
|
|
|
if (!$ierror && !empty($invoice_items))
|
|
{
|
|
// check for trade-in so we can mark it for mobile app
|
|
foreach ($invoice_items as $item)
|
|
{
|
|
// get first trade-in
|
|
if (!empty($item['trade_in']))
|
|
{
|
|
$jo->getTradeInType($item['trade_in']);
|
|
break;
|
|
}
|
|
}
|
|
|
|
$ierror = $this->invoiceBatteries($criteria, $invoice_items);
|
|
}
|
|
|
|
if ($ierror)
|
|
{
|
|
$error_array['invoice'] = $ierror;
|
|
}
|
|
else
|
|
{
|
|
// generate the invoice
|
|
$iobj = $this->ic->generateInvoice($criteria);
|
|
|
|
// validate
|
|
$ierrors = $this->validator->validate($iobj);
|
|
|
|
// add errors to list
|
|
foreach ($ierrors as $error) {
|
|
$error_array[$error->getPropertyPath()] = $error->getMessage();
|
|
}
|
|
|
|
// check if invoice already exists for JO
|
|
$old_invoice = $jo->getInvoice();
|
|
if ($old_invoice != null)
|
|
{
|
|
// remove old invoice
|
|
$this->em->remove($old_invoice);
|
|
$this->em->flush();
|
|
}
|
|
|
|
// add invoice to JO
|
|
$jo->setInvoice($iobj);
|
|
|
|
$this->em->persist($iobj);
|
|
|
|
}
|
|
}
|
|
|
|
//TODO: move this to InvoiceGenerator
|
|
protected function invoicePromo(InvoiceCriteria $criteria, $promo_id)
|
|
{
|
|
// return error if there's a problem, false otherwise
|
|
// check service type
|
|
$stype = $criteria->getServiceType();
|
|
if ($stype != ServiceType::BATTERY_REPLACEMENT_NEW)
|
|
return null;
|
|
|
|
|
|
if (empty($promo_id))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// check if this is a valid promo
|
|
$promo = $this->em->getRepository(Promo::class)->find($promo_id);
|
|
|
|
if (empty($promo))
|
|
return 'Invalid promo specified.';
|
|
|
|
$criteria->addPromo($promo);
|
|
return false;
|
|
}
|
|
|
|
// TODO: move this to InvoiceGenerator
|
|
protected function invoiceBatteries(InvoiceCriteria $criteria, $items)
|
|
{
|
|
// check service type
|
|
$stype = $criteria->getServiceType();
|
|
if ($stype != ServiceType::BATTERY_REPLACEMENT_NEW && $stype != ServiceType::BATTERY_REPLACEMENT_WARRANTY)
|
|
return null;
|
|
|
|
// return error if there's a problem, false otherwise
|
|
if (!empty($items))
|
|
{
|
|
foreach ($items as $item)
|
|
{
|
|
// check if this is a valid battery
|
|
$battery = $this->em->getRepository(Battery::class)->find($item['battery']);
|
|
|
|
if (empty($battery))
|
|
{
|
|
$error = 'Invalid battery specified.';
|
|
return $error;
|
|
}
|
|
|
|
// quantity
|
|
$qty = $item['quantity'];
|
|
if ($qty < 1)
|
|
continue;
|
|
|
|
/*
|
|
// add to criteria
|
|
$criteria->addBattery($battery, $qty);
|
|
*/
|
|
|
|
// if this is a trade in, add trade in
|
|
if (!empty($item['trade_in']) && TradeInType::validate($item['trade_in']))
|
|
$trade_in = $item['trade_in'];
|
|
else
|
|
$trade_in = null;
|
|
|
|
$criteria->addEntry($battery, $trade_in, $qty);
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|