diff --git a/config/acl.yaml b/config/acl.yaml
index ea81ada5..513fd650 100644
--- a/config/acl.yaml
+++ b/config/acl.yaml
@@ -274,8 +274,12 @@ access_keys:
label: View Behind Schedule
- id: jo_advance_order.form
label: New Advance Order
+ - id: jo_advance_order.edit
+ label: New Advance Order Edit
- id: jo_assign_advance_order.form
label: Assign Advance Order
+ - id: jo_assign_advance_order.edit
+ label: Assign Advance Order Edit
- id: support
label: Customer Support Access
diff --git a/config/menu.yaml b/config/menu.yaml
index c216839b..248fb3b8 100644
--- a/config/menu.yaml
+++ b/config/menu.yaml
@@ -110,7 +110,7 @@ main_menu:
acl: jo_advance_order.form
label: New Advance Order
parent: joborder
- - id: jo_advance_order_assign_form
+ - id: jo_assign_advance_order_form
acl: jo_assign_advance_order.form
label: Assign Advance Order
parent: joborder
diff --git a/config/routes/job_order.yaml b/config/routes/job_order.yaml
index 45623b22..eb296cfc 100644
--- a/config/routes/job_order.yaml
+++ b/config/routes/job_order.yaml
@@ -281,7 +281,7 @@ jo_advance_order_edit_form:
methods: [GET]
jo_advance_order_edit_submit:
- path: /job-order/onestep/{id}/edit
+ path: /job-order/advance-order/{id}/edit
controller: App\Controller\JobOrderController::advanceOrderEditSubmit
methods: [POST]
diff --git a/src/Controller/JobOrderController.php b/src/Controller/JobOrderController.php
index d8ff3b06..3b4887a6 100644
--- a/src/Controller/JobOrderController.php
+++ b/src/Controller/JobOrderController.php
@@ -228,7 +228,7 @@ class JobOrderController extends Controller
}
/**
- * @Menu(selected="jo_all")
+ * @Menu(selected="jo_/viewall")
*/
public function listAll(JobOrderHandlerInterface $jo_handler)
{
@@ -284,18 +284,18 @@ class JobOrderController extends Controller
$rows[$key]['meta']['reassign_rider_url'] = $this->generateUrl('jo_open_rider_form', ['id' => $jo_id]);
// $rows[$key]['meta']['edit_url'] = $this->generateUrl('jo_open_edit_form', ['id' => $jo_id]);
$rows[$key]['meta']['edit_url'] = $this->generateUrl($jo_handler->getEditRoute($jo_id, $tier_params['edit_route']), ['id' => $jo_id]);
- $rows[$key]['meta']['onestep_edit_url'] = $this->generateUrl('jo_onestep_edit_form', ['id' => $jo_id]);
+ //$rows[$key]['meta']['onestep_edit_url'] = $this->generateUrl('jo_onestep_edit_form', ['id' => $jo_id]);
}
else if ($tier == 'behind_schedule')
{
$rows[$key]['meta']['edit_url'] = $this->generateUrl($jo_handler->getEditRoute($jo_id, $tier_params['edit_route']), ['id' => $jo_id]);
- $rows[$key]['meta']['onestep_edit_url'] = $this->generateUrl('jo_onestep_edit_form', ['id' => $jo_id]);
+ //$rows[$key]['meta']['onestep_edit_url'] = $this->generateUrl('jo_onestep_edit_form', ['id' => $jo_id]);
}
else
{
// $rows[$key]['meta']['update_url'] = $this->generateUrl($tier_params['edit_route'], ['id' => $jo_id]);
- $rows[$key]['meta']['update_url'] = $this->generateUrl($jo_handler->getEditRoute($jo_id, $tier_params['edit_route']), ['id' => $jo_id]);
- $rows[$key]['meta']['onestep_edit_url'] = $this->generateUrl('jo_onestep_edit_form', ['id' => $jo_id]);
+ $rows[$key]['meta']['edit_url'] = $this->generateUrl($jo_handler->getEditRoute($jo_id, $tier_params['edit_route']), ['id' => $jo_id]);
+ //$rows[$key]['meta']['onestep_edit_url'] = $this->generateUrl('jo_onestep_edit_form', ['id' => $jo_id]);
$rows[$key]['meta']['pdf_url'] = $this->generateUrl('jo_pdf_form', ['id' => $jo_id]);
}
@@ -1095,6 +1095,77 @@ class JobOrderController extends Controller
return $this->render($template, $params);
}
+ public function advanceOrderSubmit(Request $req, JobOrderHandlerInterface $jo_handler, MQTTClient $mclient)
+ {
+ $this->denyAccessUnlessGranted('jo_advance_order.form', null, 'No access.');
+
+ // initialize error list
+ $error_array = [];
+ $id = -1;
+ $error_array = $jo_handler->processAdvanceOrderJobOrder($req, $id, $mclient);
+
+ // check if any errors were found
+ if (!empty($error_array)) {
+ // return validation failure response
+ return $this->json([
+ 'success' => false,
+ 'errors' => $error_array
+ ], 422);
+ }
+
+
+ // return successful response
+ return $this->json([
+ 'success' => 'Changes have been saved!'
+ ]);
+ }
+
+ /**
+ * @Menu(selected="jo_advance_order_edit_form")
+ */
+ public function advanceOrderEditForm($id, EntityManagerInterface $em, JobOrderHandlerInterface $jo_handler,
+ GISManagerInterface $gis, MapTools $map_tools)
+ {
+ $this->denyAccessUnlessGranted('jo_advance_order.edit', null, 'No access.');
+
+ $params = $jo_handler->initializeAdvanceOrderEditForm($id, $map_tools);
+ $params['submit_url'] = $this->generateUrl('jo_advance_order_edit_submit', ['id' => $id]);
+ $params['return_url'] = $this->generateUrl('jo_open');
+ $params['map_js_file'] = $gis->getJSJOFile();
+ $params['vmfgs'] = $em->getRepository(VehicleManufacturer::class)->findAll();
+ $params['vmakes'] = $em->getRepository(Vehicle::class)->findAll();
+
+ $template = $params['template'];
+
+ // response
+ return $this->render($template, $params);
+ }
+
+ public function advanceOrderEditSubmit(Request $req, JobOrderHandlerInterface $jo_handler, $id, MQTTClient $mclient)
+ {
+ $this->denyAccessUnlessGranted('jo_advance_order.edit', null, 'No access.');
+
+ $error_array = [];
+ $error_array = $jo_handler->processAdvanceOrderJobOrder($req, $id, $mclient);
+
+ // check if any errors were found
+ if (!empty($error_array)) {
+ // return validation failure response
+ return $this->json([
+ 'success' => false,
+ 'errors' => $error_array
+ ], 422);
+ }
+
+
+ // return successful response
+ return $this->json([
+ 'success' => 'Changes have been saved!'
+ ]);
+ }
+
+
+
/**
* @Menu(selected="jo_hub_view")
*/
diff --git a/src/Service/JobOrderHandler/CMBJobOrderHandler.php b/src/Service/JobOrderHandler/CMBJobOrderHandler.php
index 998bc41b..3bc46ef2 100644
--- a/src/Service/JobOrderHandler/CMBJobOrderHandler.php
+++ b/src/Service/JobOrderHandler/CMBJobOrderHandler.php
@@ -2907,6 +2907,358 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
return $params;
}
+ public function processAdvanceOrderJobOrder(Request $req, $id, MQTTClient $mclient)
+ {
+ // initialize error list
+ $error_array = [];
+
+ $em = $this->em;
+
+ $jo = $em->getRepository(JobOrder::class)->find($id);
+ $event_type = CMBJOEventType::OPEN_EDIT;
+ if (empty($jo))
+ {
+ // new job order
+ $jo = new JobOrder();
+ $event_type = CMBJOEventType::CREATE;
+ }
+
+ // 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 responsible party is present
+ if (empty($req->request->get('responsible_party')))
+ $error_array['responsible_party'] = 'Responsible party is required.';
+
+ // check if new customer
+ if ($req->request->get('new_customer', false))
+ {
+ // validate mobile phone
+ $valid_mobile = $this->cust_handler->validateMobileNumber($req->request->get('phone_mobile'));
+ if (!($valid_mobile))
+ $error_array['phone_mobile'] = 'Invalid mobile phone number.';
+
+ // check if plate number is in request
+ if (empty(trim($req->request->get('plate_number'))))
+ $error_array['plate_number'] = 'Plate number is required.';
+
+ // 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('last_name'))
+ ->setFirstName($req->request->get('first_name'))
+ ->setPhoneMobile($req->request->get('phone_mobile'))
+ ->setPhoneLandline($req->request->get('phone_landline'))
+ ->setPhoneOffice($req->request->get('phone_office'))
+ ->setCustomerNotes($req->request->get('customer_notes'));
+
+ $new_cv->setCustomer($new_cust)
+ ->setVehicle($new_vehicle)
+ ->setPlateNumber(trim($req->request->get('plate_number')))
+ ->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.';
+ }
+
+ // delivery address
+ if (empty($req->request->get('delivery_address')))
+ $error_array['delivery_address'] = 'Delivery address is required.';
+
+ // get discount and set to meta
+ $discount = $req->request->get('invoice_discount');
+
+ if (($discount > 60) || ($discount < 0))
+ {
+ $error_array['invoice_discount'] = 'Invalid discount specified';
+ }
+
+ // get list of service charges
+ $service_charges = $req->request->get('service_charges', []);
+
+ 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'))
+ ->setDeliveryInstructions($req->request->get('delivery_instructions'))
+ ->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)
+ ->setResponsibleParty($req->request->get('responsible_party', ''))
+ ->setStatus(JOStatus::RIDER_ASSIGN);
+
+ $jo->addMeta('discount', $discount);
+ $jo->addMeta('service_charges', $service_charges);
+
+ // 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 invoice
+ $invoice_items = $req->request->get('invoice_items', []);
+ $discount = $req->request->get('invoice_discount');
+ $invoice_change = $req->request->get('invoice_change', 0);
+
+ // check if invoice changed
+ if ($invoice_change)
+ {
+ $this->ic->generateInvoiceCriteria($jo, $discount, $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($event_type)
+ ->setJobOrder($jo);
+
+ if ($user != null)
+ {
+ $event->setUser($user);
+ }
+
+ $em->persist($event);
+ $em->flush();
+ }
+ }
+
+ return $error_array;
+ }
+
+ public function initializeAdvanceOrderEditForm($id, $map_tools)
+ {
+ $em = $this->em;
+ $obj = $em->getRepository(JobOrder::class)->find($id);
+
+ $params['obj'] = $obj;
+ $params['mode'] = 'advanceorder-edit';
+ $params['cvid'] = $obj->getCustomerVehicle()->getID();
+ $params['vid'] = $obj->getCustomerVehicle()->getVehicle()->getID();
+ $params['current_date'] = new DateTime();
+
+ // get service charges
+ $sc_array = [];
+ $jo_service_charges = $obj->getMeta('service_charges');
+ if (!(empty($jo_service_charges)))
+ {
+ foreach ($jo_service_charges as $jo_sc_id)
+ {
+ // find service charge
+ $sc_obj = $em->getRepository(ServiceCharge::class)->find($jo_sc_id);
+
+ $sc_array[] = $sc_obj;
+ }
+ }
+
+ $params['jo_service_charges'] = $sc_array;
+
+ // get odometer
+ $odometer = $obj->getMeta('odometer');
+
+ $params['odometer'] = $odometer;
+
+ // get customer email used in JO
+ $email = $obj->getMeta('customer_email');
+
+ $params['email'] = $email;
+
+ // get images if any
+ $jo_extra = $obj->getJOExtra();
+ $pic_array = [];
+ $params['signature'] = null;
+ if ($jo_extra != null)
+ {
+ $img_1 = $jo_extra->getImage1Filename();
+ $img_2 = $jo_extra->getImage2Filename();
+ $img_3 = $jo_extra->getImage3Filename();
+ $img_4 = $jo_extra->getImage4Filename();
+
+ $other_images = $jo_extra->getOtherImages();
+
+ $cust_signature = $jo_extra->getCustomerSignature();
+
+ if ($img_1 != null)
+ $pic_array['image_1'] = $img_1;
+ if ($img_2 != null)
+ $pic_array['image_2'] = $img_2;
+ if ($img_3 != null)
+ $pic_array['image_3'] = $img_3;
+ if ($img_4 != null)
+ $pic_array['image_4'] = $img_4;
+
+ if ($other_images != null)
+ {
+ foreach ($other_images as $img)
+ {
+ $pic_array['other_images'][] = $img;
+ }
+ }
+
+ $params['signature'] = $cust_signature;
+ }
+
+ $params['jo_pictures'] = $pic_array;
+
+ $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_advanceorder_edit_form');
+
+ return $params;
+ }
+
protected function fillDropdownParameters(&$params)
{
$em = $this->em;
@@ -3006,6 +3358,11 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
$params['ftags']['ticket_table'] = false;
$params['ftags']['cancel_button'] = false;
break;
+ case 'advanceorder-edit':
+ $params['ftags']['invoice_edit'] = true;
+ $params['ftags']['preset_vehicle'] = true;
+ break;
+
}
}
@@ -3031,6 +3388,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
$this->template_hash['jo_popup'] = 'job-order/cmb.popup.html.twig';
$this->template_hash['jo_behind_schedule'] = 'job-order/cmb.list.behindschedule.html.twig';
$this->template_hash['jo_advanceorder_form'] = 'job-order/cmb.form.advanceorder.html.twig';
+ $this->template_hash['jo_advanceorder_edit_form'] = 'job-order/cmb.form.advanceorder.html.twig';
}
protected function checkTier($tier)
@@ -3286,11 +3644,20 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
if (empty($jo))
throw new NotFoundHttpException('The item does not exist');
+ $edit_route = '';
// check transaction origin
if ($jo->getSource() == CMBTransactionOrigin::WALK_IN)
- return 'jo_walkin_edit_form';
+ $edit_route = 'jo_walkin_edit_form';
else
- return 'jo_onestep_edit_form';
+ {
+ // need to check if onestep or not
+ if ($jo->getStatus() == JOStatus::ASSIGNED)
+ $edit_route = 'jo_onestep_edit_form';
+ else
+ $edit_route = 'jo_advance_order_edit_form';
+ }
+
+ return $edit_route;
}
protected function generateDiscountOptions()
diff --git a/templates/job-order/cmb.list.all.html.twig b/templates/job-order/cmb.list.all.html.twig
index 17c7be16..49d04ae2 100644
--- a/templates/job-order/cmb.list.all.html.twig
+++ b/templates/job-order/cmb.list.all.html.twig
@@ -115,7 +115,7 @@
sortable: false,
overflow: 'visible',
template: function (row, index, datatable) {
- var actions = '';
+ var actions = '';
actions += '';
return actions;
diff --git a/templates/job-order/cmb.list.behindschedule.html.twig b/templates/job-order/cmb.list.behindschedule.html.twig
index 2ed1bbeb..5f9a9c57 100644
--- a/templates/job-order/cmb.list.behindschedule.html.twig
+++ b/templates/job-order/cmb.list.behindschedule.html.twig
@@ -103,8 +103,8 @@
sortable: false,
overflow: 'visible',
template: function (row, index, datatable) {
- {% if is_granted('jo_onestep.edit') %}
- var actions = '';
+ {% if is_granted('jo_onestep.edit') or is_granted('jo_advance_order.edit') or is_granted('jo_assign_advance_order.edit') %}
+ var actions = '';
{% endif %}
return actions;
diff --git a/templates/job-order/cmb.list.open.html.twig b/templates/job-order/cmb.list.open.html.twig
index aac00d65..21669275 100644
--- a/templates/job-order/cmb.list.open.html.twig
+++ b/templates/job-order/cmb.list.open.html.twig
@@ -114,8 +114,8 @@
sortable: false,
overflow: 'visible',
template: function (row, index, datatable) {
- {% if is_granted('jo_onestep.edit') %}
- var actions = '';
+ {% if is_granted('jo_onestep.edit') or is_granted('jo_advance_order.edit') or is_granted('jo_assign_advance_order.edit') %}
+ var actions = '';
{% endif %}
return actions;