Merge branch '453-resq-july-30-release' of gitlab.com:jankstudio/resq into 463-resq-message-prompt-for-non-serviceable-area
This commit is contained in:
commit
87eee41958
16 changed files with 445 additions and 60 deletions
|
|
@ -74,3 +74,6 @@ MAPTILER_API_KEY=map_tiler_api_key
|
|||
|
||||
# API version
|
||||
API_VERSION=insert_api_version_here
|
||||
|
||||
#SSL_ENABLE for websockets
|
||||
SSL_ENABLE=set_to_true_or_false
|
||||
|
|
|
|||
|
|
@ -270,6 +270,8 @@ access_keys:
|
|||
label: Autoassign Test
|
||||
- id: jo_hub.list
|
||||
label: Hub View
|
||||
- id: jo_cancel.fulfill
|
||||
label: Fulfill Cancelled JO
|
||||
|
||||
- id: support
|
||||
label: Customer Support Access
|
||||
|
|
|
|||
|
|
@ -8,3 +8,4 @@ twig:
|
|||
mqtt_host: "%env(MQTT_WS_HOST)%"
|
||||
mqtt_port: "%env(MQTT_WS_PORT)%"
|
||||
dashboard_enable: "%env(DASHBOARD_ENABLE)%"
|
||||
ssl_enable: "%env(SSL_ENABLE)%"
|
||||
|
|
|
|||
|
|
@ -253,3 +253,12 @@ jo_hub_view_form:
|
|||
controller: App\Controller\JobOrderController::hubViewForm
|
||||
methods: [GET]
|
||||
|
||||
jo_fulfill_cancel_submit:
|
||||
path: /job-order/fulfillcancel/{id}
|
||||
controller: App\Controller\JobOrderController::fulfillCancelSubmit
|
||||
methods: [POST]
|
||||
|
||||
jo_cancel_reasons:
|
||||
path: /ajax/jo_cancel_reasons
|
||||
controller: App\Controller\JobOrderController::cancelReasons
|
||||
methods: [GET]
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
class MapEventHandler {
|
||||
constructor(options, dashmap) {
|
||||
constructor(options, dashmap, ssl) {
|
||||
this.options = options;
|
||||
this.dashmap = dashmap;
|
||||
this.ssl = ssl;
|
||||
}
|
||||
|
||||
connect(user_id, host, port) {
|
||||
|
|
@ -11,7 +12,7 @@ class MapEventHandler {
|
|||
|
||||
this.mqtt = new Paho.MQTT.Client(host, port, client_id);
|
||||
var options = {
|
||||
// useSSL: true,
|
||||
useSSL: this.ssl,
|
||||
timeout: 3,
|
||||
invocationContext: this,
|
||||
onSuccess: this.onConnect.bind(this),
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use App\Ramcar\JOStatus;
|
|||
use App\Ramcar\InvoiceCriteria;
|
||||
use App\Ramcar\CMBServiceType;
|
||||
use App\Ramcar\ServiceType;
|
||||
use App\Ramcar\JOCancelReasons;
|
||||
|
||||
use App\Entity\CustomerVehicle;
|
||||
use App\Entity\Promo;
|
||||
|
|
@ -631,7 +632,6 @@ class JobOrderController extends Controller
|
|||
$params['vmfgs'] = $em->getRepository(VehicleManufacturer::class)->findAll();
|
||||
$params['vmakes'] = $em->getRepository(Vehicle::class)->findAll();
|
||||
$params['return_url'] = $this->generateUrl('jo_all');
|
||||
$params['submit_url'] = '';
|
||||
$params['map_js_file'] = $gis->getJSJOFile();
|
||||
|
||||
$template = $params['template'];
|
||||
|
|
@ -1153,6 +1153,38 @@ class JobOrderController extends Controller
|
|||
return $this->render($template, $params);
|
||||
}
|
||||
|
||||
public function fulfillCancelSubmit(Request $req, JobOrderHandlerInterface $jo_handler, $id)
|
||||
{
|
||||
$this->denyAccessUnlessGranted('jo_cancel.fulfill', null, 'No access.');
|
||||
|
||||
// TODO: make the service function to fulfill the cancelled JO
|
||||
$error_array = [];
|
||||
$result = $jo_handler->fulfillCancelledJobOrder($req, $id);
|
||||
|
||||
$error_array = $result['error_array'];
|
||||
|
||||
// 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!'
|
||||
]);
|
||||
}
|
||||
|
||||
// ajax call
|
||||
public function cancelReasons()
|
||||
{
|
||||
return $this->json([
|
||||
'cancel_reasons' => JOCancelReasons::getCollection(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Menu(selected="jo_autoassign")
|
||||
|
|
|
|||
|
|
@ -334,6 +334,18 @@ class JobOrder
|
|||
*/
|
||||
protected $phone_mobile;
|
||||
|
||||
// flag if customer is willing to wait
|
||||
/**
|
||||
* @ORM\Column(type="boolean", nullable=true)
|
||||
*/
|
||||
protected $flag_will_wait;
|
||||
|
||||
// reason for not willing to wait
|
||||
/**
|
||||
* @ORM\Column(type="string", length=80, nullable=true)
|
||||
*/
|
||||
protected $reasons_not_waiting;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->date_create = new DateTime();
|
||||
|
|
@ -356,6 +368,8 @@ class JobOrder
|
|||
$this->meta = [];
|
||||
|
||||
$this->phone_mobile = '';
|
||||
|
||||
$this->flag_will_wait = true;
|
||||
}
|
||||
|
||||
public function getID()
|
||||
|
|
@ -962,5 +976,25 @@ class JobOrder
|
|||
return $this->phone_mobile;
|
||||
}
|
||||
|
||||
|
||||
public function setWillingToWait($flag = true)
|
||||
{
|
||||
$this->flag_will_wait = $flag;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isWillingToWait()
|
||||
{
|
||||
return $this->flag_will_wait;
|
||||
}
|
||||
|
||||
public function setReasonsNotWait($reasons)
|
||||
{
|
||||
$this->reasons_not_waiting = $reasons;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getReasonsNotWait()
|
||||
{
|
||||
return $this->reasons_not_waiting;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
16
src/Ramcar/CustomerNotWaitReason.php
Normal file
16
src/Ramcar/CustomerNotWaitReason.php
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace App\Ramcar;
|
||||
|
||||
class CustomerNotWaitReason extends NameValue
|
||||
{
|
||||
const EMERGENCY = 'emergency';
|
||||
const USE_VEHICLE_NOW = 'use_vehicle_now';
|
||||
const WITH_APPOINTMENT = 'with_appointment';
|
||||
|
||||
const COLLECTION = [
|
||||
'emergency' => 'Emergency',
|
||||
'use_vehicle_now' => 'Need to Use Vehicle Now',
|
||||
'with_appointment' => 'With Appointment',
|
||||
];
|
||||
}
|
||||
26
src/Ramcar/JOCancelReasons.php
Normal file
26
src/Ramcar/JOCancelReasons.php
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace App\Ramcar;
|
||||
|
||||
class JOCancelReasons extends NameValue
|
||||
{
|
||||
const WRONG_BATTERY = 'wrong_battery';
|
||||
const CUSTOMER_NO_SHOW = 'customer_no_show';
|
||||
const RESCHEDULE = 'reschedule';
|
||||
const LOCATION_CHANGE = 'location_change';
|
||||
const WORKING_BATTERY = 'battery_working';
|
||||
const LATE_DELIVERY = 'late_delivery';
|
||||
const CUSTOMER_BOUGHT_NEW_BATTERY = 'customer_bought_new_battery';
|
||||
const BATTERY_NO_STOCK = 'battery_no_stock';
|
||||
|
||||
const COLLECTION = [
|
||||
'wrong_battery' => 'Wrong Battery',
|
||||
'customer_no_show' => 'Customer No Show',
|
||||
'reschedule' => 'Reschedule',
|
||||
'location_change' => 'Change Location',
|
||||
'battery_working' => 'Battery is Already Working',
|
||||
'late_delivery' => 'Late Delivery',
|
||||
'customer_bought_new_battery' => 'Customer Already Bought New Battery from Nearby Outlet',
|
||||
'battery_no_stock' => 'No Stock of Battery',
|
||||
];
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@ class TransactionOrigin extends NameValue
|
|||
const VIP = 'vip';
|
||||
const MOBILE_APP = 'mobile_app';
|
||||
const WALK_IN = 'walk_in';
|
||||
const LAZADA = 'lazada';
|
||||
|
||||
// TODO: for now, resq also gets the walk-in option
|
||||
const COLLECTION = [
|
||||
|
|
@ -19,5 +20,6 @@ class TransactionOrigin extends NameValue
|
|||
'vip' => 'VIP',
|
||||
'mobile_app' => 'Mobile App',
|
||||
'walk_in' => 'Walk-in',
|
||||
'lazada' => 'Lazada',
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ use App\Ramcar\ModeOfPayment;
|
|||
use App\Ramcar\TransactionOrigin;
|
||||
use App\Ramcar\FacilitatedType;
|
||||
use App\Ramcar\JORejectionReason;
|
||||
use App\Ramcar\CustomerNotWaitReason;
|
||||
|
||||
use App\Service\InvoiceGeneratorInterface;
|
||||
use App\Service\JobOrderHandlerInterface;
|
||||
|
|
@ -183,6 +184,12 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
|||
else
|
||||
$row['assignor'] = $orow->getAssignedBy()->getFullName();
|
||||
|
||||
$hub_facilitated = $orow->getFacilitatedBy();
|
||||
if ($hub_facilitated == null)
|
||||
$row['hub_facilitated'] = '';
|
||||
else
|
||||
$row['hub_facilitated'] = $orow->getFacilitatedBy()->getName();
|
||||
|
||||
$rows[] = $row;
|
||||
}
|
||||
|
||||
|
|
@ -314,6 +321,17 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
|||
}
|
||||
}
|
||||
|
||||
// check if landmark is set
|
||||
if (empty($req->request->get('landmark')))
|
||||
$error_array['landmark'] = 'Landmark is required.';
|
||||
|
||||
// check if customer is not willing to wait
|
||||
$will_wait = $req->request->get('flag_will_wait');
|
||||
if ($will_wait)
|
||||
$reason = '';
|
||||
else
|
||||
$reason = $req->request->get('no_wait_reason');
|
||||
|
||||
// TODO: check status before saving since JO might already
|
||||
// have a status that needs to be retained
|
||||
|
||||
|
|
@ -343,7 +361,9 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
|||
->setORName($req->request->get('or_name'))
|
||||
->setPromoDetail($req->request->get('promo_detail'))
|
||||
->setModeOfPayment($req->request->get('mode_of_payment'))
|
||||
->setLandmark($req->request->get('landmark'));
|
||||
->setLandmark($req->request->get('landmark'))
|
||||
->setWillingToWait($req->request->get('flag_will_wait', false))
|
||||
->setReasonsNotWait($reason);
|
||||
|
||||
// check if user is null, meaning call to create came from API
|
||||
if ($user != null)
|
||||
|
|
@ -434,6 +454,17 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
|||
$error_array['coordinates'] = 'No map coordinates provided. Please click on a location on the map.';
|
||||
}
|
||||
|
||||
// check if landmark is set
|
||||
if (empty($req->request->get('landmark')))
|
||||
$error_array['landmark'] = 'Landmark is required.';
|
||||
|
||||
// check if customer is not willing to wait
|
||||
$will_wait = $req->request->get('flag_will_wait');
|
||||
if ($will_wait)
|
||||
$reason = '';
|
||||
else
|
||||
$reason = $req->request->get('no_wait_reason');
|
||||
|
||||
if (empty($error_array))
|
||||
{
|
||||
// get current user
|
||||
|
|
@ -458,7 +489,9 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
|||
->setORName($req->request->get('or_name'))
|
||||
->setPromoDetail($req->request->get('promo_detail'))
|
||||
->setModeOfPayment($req->request->get('mode_of_payment'))
|
||||
->setLandmark($req->request->get('landmark'));
|
||||
->setLandmark($req->request->get('landmark'))
|
||||
->setWillingToWait($req->request->get('flag_will_wait', false))
|
||||
->setReasonsNotWait($reason);
|
||||
|
||||
// did they change invoice?
|
||||
$invoice_items = $req->request->get('invoice_items', []);
|
||||
|
|
@ -492,6 +525,8 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
|||
->setTypeID(JOEventType::OPEN_EDIT)
|
||||
->setJobOrder($obj);
|
||||
|
||||
error_log('open edit?');
|
||||
|
||||
if ($user != null)
|
||||
{
|
||||
$event->setUser($user);
|
||||
|
|
@ -587,6 +622,17 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
|||
$fac_by = null;
|
||||
}
|
||||
|
||||
// check if landmark is set
|
||||
if (empty($req->request->get('landmark')))
|
||||
$error_array['landmark'] = 'Landmark is required.';
|
||||
|
||||
// check if customer is not willing to wait
|
||||
$will_wait = $req->request->get('flag_will_wait');
|
||||
if ($will_wait)
|
||||
$reason = '';
|
||||
else
|
||||
$reason = $req->request->get('no_wait_reason');
|
||||
|
||||
if (empty($error_array))
|
||||
{
|
||||
// coordinates
|
||||
|
|
@ -606,7 +652,10 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
|||
->setDeliveryAddress($req->request->get('delivery_address'))
|
||||
->setFacilitatedType($fac_type)
|
||||
->setFacilitatedBy($fac_by)
|
||||
->setHub($hub);
|
||||
->setHub($hub)
|
||||
->setLandmark($req->request->get('landmark'))
|
||||
->setWillingToWait($req->request->get('flag_will_wait', false))
|
||||
->setReasonsNotWait($reason);
|
||||
|
||||
// validate
|
||||
$errors = $this->validator->validate($obj);
|
||||
|
|
@ -680,6 +729,17 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
|||
}
|
||||
}
|
||||
|
||||
// check if landmark is set
|
||||
if (empty($req->request->get('landmark')))
|
||||
$error_array['landmark'] = 'Landmark is required.';
|
||||
|
||||
// check if customer is not willing to wait
|
||||
$will_wait = $req->request->get('flag_will_wait');
|
||||
if ($will_wait)
|
||||
$reason = '';
|
||||
else
|
||||
$reason = $req->request->get('no_wait_reason');
|
||||
|
||||
// get current user
|
||||
$user = $this->security->getUser();
|
||||
|
||||
|
|
@ -700,7 +760,10 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
|||
->setTier2Notes($req->request->get('tier2_notes'))
|
||||
->setDeliveryAddress($req->request->get('delivery_address'))
|
||||
->setDateAssign(new DateTime())
|
||||
->setRider($rider);
|
||||
->setRider($rider)
|
||||
->setLandmark($req->request->get('landmark'))
|
||||
->setWillingToWait($req->request->get('flag_will_wait', false))
|
||||
->setReasonsNotWait($reason);
|
||||
|
||||
if ($user != null)
|
||||
{
|
||||
|
|
@ -763,6 +826,17 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
|||
$error_array['coordinates'] = 'No map coordinates provided. Please click on a location on the map.';
|
||||
}
|
||||
|
||||
// check if landmark is set
|
||||
if (empty($req->request->get('landmark')))
|
||||
$error_array['landmark'] = 'Landmark is required.';
|
||||
|
||||
// check if customer is not willing to wait
|
||||
$will_wait = $req->request->get('flag_will_wait');
|
||||
if ($will_wait)
|
||||
$reason = '';
|
||||
else
|
||||
$reason = $req->request->get('no_wait_reason');
|
||||
|
||||
if (empty($error_array)) {
|
||||
// coordinates
|
||||
$point = new Point($req->request->get('coord_lng'), $req->request->get('coord_lat'));
|
||||
|
|
@ -777,7 +851,10 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
|||
->setDeliveryInstructions($req->request->get('delivery_instructions'))
|
||||
->setTier1Notes($req->request->get('tier1_notes'))
|
||||
->setTier2Notes($req->request->get('tier2_notes'))
|
||||
->setDeliveryAddress($req->request->get('delivery_address'));
|
||||
->setDeliveryAddress($req->request->get('delivery_address'))
|
||||
->setLandmark($req->request->get('landmark'))
|
||||
->setWillingToWait($req->request->get('flag_will_wait', false))
|
||||
->setReasonsNotWait($reason);
|
||||
|
||||
// validate
|
||||
$errors = $this->validator->validate($obj);
|
||||
|
|
@ -883,6 +960,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
|||
throw new NotFoundHttpException('The item does not exist');
|
||||
|
||||
$cancel_reason = $req->request->get('cancel_reason');
|
||||
error_log($cancel_reason);
|
||||
$obj->cancel($cancel_reason);
|
||||
|
||||
// the event
|
||||
|
|
@ -947,6 +1025,19 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
|||
}
|
||||
}
|
||||
|
||||
// check if landmark is set
|
||||
if (empty($req->request->get('landmark')))
|
||||
$error_array['landmark'] = 'Landmark is required.';
|
||||
|
||||
error_log($req->request->get('landmark'));
|
||||
|
||||
// check if customer is not willing to wait
|
||||
$will_wait = $req->request->get('flag_will_wait');
|
||||
if ($will_wait)
|
||||
$reason = '';
|
||||
else
|
||||
$reason = $req->request->get('no_wait_reason');
|
||||
|
||||
if (empty($error_array))
|
||||
{
|
||||
// rider mqtt event
|
||||
|
|
@ -974,6 +1065,9 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
|||
->setTier2Notes($req->request->get('tier2_notes'))
|
||||
->setDeliveryAddress($req->request->get('delivery_address'))
|
||||
->setHub($hub)
|
||||
->setLandmark($req->request->get('landmark'))
|
||||
->setWillingToWait($req->request->get('flag_will_wait', false))
|
||||
->setReasonsNotWait($reason)
|
||||
->clearRider();
|
||||
|
||||
if ($user != null)
|
||||
|
|
@ -1148,6 +1242,17 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
|||
}
|
||||
}
|
||||
|
||||
// check if landmark is set
|
||||
if (empty($req->request->get('landmark')))
|
||||
$error_array['landmark'] = 'Landmark is required.';
|
||||
|
||||
// check if customer is not willing to wait
|
||||
$will_wait = $req->request->get('flag_will_wait');
|
||||
if ($will_wait)
|
||||
$reason = '';
|
||||
else
|
||||
$reason = $req->request->get('no_wait_reason');
|
||||
|
||||
if (empty($error_array)) {
|
||||
// rider mqtt event
|
||||
// NOTE: need to send this before saving because rider will be cleared
|
||||
|
|
@ -1174,7 +1279,10 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
|||
->setTier2Notes($req->request->get('tier2_notes'))
|
||||
->setDeliveryAddress($req->request->get('delivery_address'))
|
||||
->setDateAssign(new DateTime())
|
||||
->setRider($rider);
|
||||
->setRider($rider)
|
||||
->setLandmark($req->request->get('landmark'))
|
||||
->setWillingToWait($req->request->get('flag_will_wait', false))
|
||||
->setReasonsNotWait($reason);
|
||||
|
||||
if ($user != null)
|
||||
{
|
||||
|
|
@ -1562,6 +1670,18 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
|||
$this->fillDropdownParameters($params);
|
||||
$this->fillFormTags($params);
|
||||
|
||||
// check JO status to determine the mode and submit_url to return
|
||||
if ($obj->getStatus() == JOStatus::CANCELLED)
|
||||
{
|
||||
$params['mode'] = 'fulfill-cancel';
|
||||
$params['submit_url'] = 'jo_fulfill_cancel_submit';
|
||||
}
|
||||
else
|
||||
{
|
||||
$params['mode'] = 'update-all';
|
||||
$params['submit_url'] = '';
|
||||
}
|
||||
|
||||
// get template to display
|
||||
$params['template'] = $this->getTwigTemplate('jo_all_form');
|
||||
|
||||
|
|
@ -2434,6 +2554,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
|||
$params['facilitated_types'] = FacilitatedType::getCollection();
|
||||
$params['facilitated_hubs'] = $fac_hubs;
|
||||
$params['sources'] = TransactionOrigin::getCollection();
|
||||
$params['no_wait_reasons'] = CustomerNotWaitReason::getCollection();
|
||||
}
|
||||
|
||||
protected function initFormTags(&$params)
|
||||
|
|
@ -2765,7 +2886,21 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
|||
->andWhere('h.flag_hub_view = :flag_hub_view')
|
||||
->setParameter('flag_hub_view', true);
|
||||
}
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
$c_date = new DateTime();
|
||||
$start_curr_date = $c_date->format('Y-m-d') . ' ' . '00:00:00';
|
||||
$end_curr_date = $c_date->format('Y-m-d') . ' ' . '23:59:00';
|
||||
|
|
@ -2779,6 +2914,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
|||
->setParameter('start_current_date', $start_current_date)
|
||||
->setParameter('end_current_date', $end_current_date)
|
||||
->setParameter('statuses', $status, Connection::PARAM_STR_ARRAY);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$query->where('q.status = :status')
|
||||
|
|
@ -2954,4 +3090,37 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
|||
return $params;
|
||||
}
|
||||
|
||||
public function fulfillCancelledJobOrder(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');
|
||||
|
||||
$obj->fulfill();
|
||||
|
||||
// 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);
|
||||
$em->flush();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ function initMap(r_markers, c_markers, icons) {
|
|||
return dashmap;
|
||||
}
|
||||
|
||||
function initEventHandler(dashmap) {
|
||||
function initEventHandler(dashmap, icons, ssl) {
|
||||
var options = {
|
||||
'track_jo': true,
|
||||
'track_rider': true,
|
||||
|
|
@ -58,7 +58,7 @@ function initEventHandler(dashmap) {
|
|||
},
|
||||
};
|
||||
|
||||
var event_handler = new MapEventHandler(options, dashmap);
|
||||
var event_handler = new MapEventHandler(options, dashmap, ssl);
|
||||
event_handler.connect('{{ app.user.getID }}', '{{ mqtt_host }}', {{ mqtt_port }});
|
||||
}
|
||||
|
||||
|
|
@ -94,8 +94,13 @@ var icons = {
|
|||
var r_markers = {};
|
||||
var c_markers = {};
|
||||
|
||||
var ssl = false;
|
||||
{% if ssl_enable == 'true' %}
|
||||
ssl = true;
|
||||
{% endif %}
|
||||
|
||||
var dashmap = initMap(r_markers, c_markers, icons);
|
||||
initEventHandler(dashmap, icons);
|
||||
initEventHandler(dashmap, icons, ssl);
|
||||
{% endif %}
|
||||
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -292,6 +292,22 @@
|
|||
<div class="form-control-feedback hide" data-field="date_schedule_time"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group m-form__group row">
|
||||
<div class="col-lg-6">
|
||||
<input type="checkbox" name="flag_will_wait" id="flag-will-wait" value="1"{{ obj.isWillingToWait ? ' checked' }} >
|
||||
<label class="switch-label">Willing to Wait</label>
|
||||
<div class="form-control-feedback hide" data-field="flag_will_wait"></div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<label data-field="no_wait_reason">Reason Why Not Willing to Wait</label>
|
||||
<select class="form-control m-input" id="no-wait-reason" name="no_wait_reason">
|
||||
{% for key, class in no_wait_reasons %}
|
||||
<option value="{{ key }}"{{ obj.getReasonsNotWait == key ? ' selected' }}>{{ class }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<div class="form-control-feedback hide" data-field="no_wait_reason"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group m-form__group row">
|
||||
<div class="col-lg-6">
|
||||
<label data-field="tier1_notes">Tier 1 Notes</label>
|
||||
|
|
@ -848,8 +864,12 @@
|
|||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
{% if mode != 'update-all' %}
|
||||
{% if mode == 'fulfill-cancel' and is_granted('jo_cancel.fulfill') %}
|
||||
<a href="{{ url('jo_fulfill_cancel_submit', {'id': obj.getID}) }}" class="btn btn-success btn-fulfill-cancel-job-order">Fulfill</a>
|
||||
{% else %}
|
||||
<button type="submit" class="btn btn-success">{{ mode == 'update-fulfillment' ? 'Fulfill' : 'Submit' }}</button>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if ftags.set_map_coordinate and is_granted('joborder.cancel') and not obj.isCancelled %}
|
||||
<a href="{{ url('jo_cancel', {'id': obj.getID}) }}" class="btn btn-danger btn-cancel-job-order">Cancel Job Order</a>
|
||||
{% endif %}
|
||||
|
|
@ -1734,27 +1754,34 @@ $(function() {
|
|||
|
||||
e.preventDefault();
|
||||
|
||||
var inputOptionsPromise = new Promise(function(resolve) {
|
||||
// get your data and pass it to resolve()
|
||||
$.getJSON("{{ url('jo_cancel_reasons') }}", function(data) {
|
||||
resolve(data.cancel_reasons)
|
||||
});
|
||||
});
|
||||
|
||||
swal({
|
||||
title: 'Cancel Job Order',
|
||||
html: 'Please enter the reason for cancellation of this job order:',
|
||||
input: 'textarea',
|
||||
inputClass: 'form-control',
|
||||
html: 'Please select the reason for cancellation of this job order:',
|
||||
input: 'select',
|
||||
inputOptions: inputOptionsPromise,
|
||||
type: 'warning',
|
||||
showCancelButton: true,
|
||||
closeOnCancel: true,
|
||||
width: '40rem',
|
||||
preConfirm: (reason) => {
|
||||
if (!reason) {
|
||||
swal.showValidationError(
|
||||
'Reason for cancellation is required.'
|
||||
)
|
||||
inputValidator: (value) => {
|
||||
return new Promise((resolve) => {
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
}
|
||||
}).then((reason) => {
|
||||
}).then((result) => {
|
||||
if (result.value) {
|
||||
$.ajax({
|
||||
method: "DELETE",
|
||||
url: url,
|
||||
data: {
|
||||
'cancel_reason': reason.value
|
||||
'cancel_reason': result.value
|
||||
}
|
||||
}).done(function(response) {
|
||||
swal({
|
||||
|
|
@ -1766,8 +1793,31 @@ $(function() {
|
|||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// fulfill cancelled job order
|
||||
$(".btn-fulfill-cancel-job-order").click(function(e) {
|
||||
var url = $(this).prop('href');
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
$.ajax({
|
||||
method: "POST",
|
||||
url: url,
|
||||
}).done(function(response) {
|
||||
swal({
|
||||
title: 'Done!',
|
||||
text: response.success,
|
||||
type: 'success',
|
||||
onClose: function() {
|
||||
window.location.href = "{{ return_url }}";
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -116,6 +116,10 @@
|
|||
field: 'delivery_address',
|
||||
title: 'Customer Area'
|
||||
},
|
||||
{
|
||||
field: 'hub_facilitated',
|
||||
title: 'Battery Facilitated By'
|
||||
},
|
||||
{
|
||||
field: 'type',
|
||||
title: 'Schedule'
|
||||
|
|
|
|||
|
|
@ -42,6 +42,17 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="m-input-icon m-input-icon--left">
|
||||
<div class="input-daterange input-group" id="date-range">
|
||||
<input role="presentation" type="text" class="form-control m-input" id="date_start" name="date_start" placeholder="Start date" />
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text"><i class="la la-ellipsis-h"></i></span>
|
||||
</div>
|
||||
<input role="presentation" type="text" class="form-control" id="date_end" name="date_end" placeholder="End date" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -59,6 +70,10 @@
|
|||
{% block scripts %}
|
||||
<script>
|
||||
$(function() {
|
||||
$("#date-range").datepicker({
|
||||
orientation: "bottom"
|
||||
});
|
||||
|
||||
var options = {
|
||||
data: {
|
||||
type: 'remote',
|
||||
|
|
@ -147,6 +162,22 @@
|
|||
$("#hub_list").on("change", function() {
|
||||
table.search($(this).val(), "hub");
|
||||
});
|
||||
|
||||
$("#date_start").on("change", function() {
|
||||
var date_start = $(this).val();
|
||||
var date_end = $("[name='date_end']").val();
|
||||
var date_array = [date_start, date_end];
|
||||
|
||||
table.search(date_array, "schedule_date");
|
||||
});
|
||||
|
||||
$("#date_end").on("change", function() {
|
||||
var date_end = $(this).val();
|
||||
var date_start = $("[name='date_start']").val();
|
||||
var date_array = [date_start, date_end];
|
||||
|
||||
table.search(date_array, "schedule_date");
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in a new issue