3859 lines
138 KiB
PHP
3859 lines
138 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\Hub;
|
|
use App\Entity\Promo;
|
|
use App\Entity\Rider;
|
|
use App\Entity\JORejection;
|
|
use App\Entity\Warranty;
|
|
use App\Entity\Customer;
|
|
use App\Entity\CustomerTag;
|
|
use App\Entity\EmergencyType;
|
|
|
|
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\Ramcar\CustomerNotWaitReason;
|
|
use App\Ramcar\NoTradeInReason;
|
|
use App\Ramcar\WillingToWaitContent;
|
|
use App\Ramcar\WarrantySource;
|
|
use App\Ramcar\HubCriteria;
|
|
use App\Ramcar\DeliveryStatus;
|
|
use App\Ramcar\SourceOfAwareness;
|
|
use App\Ramcar\InitialConcern;
|
|
use App\Ramcar\CustomerClassification;
|
|
use App\Ramcar\Gender;
|
|
use App\Ramcar\CallerClassification;
|
|
|
|
use App\Service\InvoiceGeneratorInterface;
|
|
use App\Service\JobOrderHandlerInterface;
|
|
use App\Service\RiderAssignmentHandlerInterface;
|
|
use App\Service\WarrantyHandler;
|
|
use App\Service\MQTTClient;
|
|
use App\Service\APNSClient;
|
|
use App\Service\MapTools;
|
|
use App\Service\RisingTideGateway;
|
|
use App\Service\PromoLogger;
|
|
use App\Service\HubSelector;
|
|
use App\Service\HubDistributor;
|
|
use App\Service\HubFilteringGeoChecker;
|
|
|
|
use CrEOF\Spatial\PHP\Types\Geometry\Point;
|
|
|
|
use Mosquitto\Client as MosquittoClient;
|
|
|
|
use DateTime;
|
|
use DateInterval;
|
|
|
|
use FPDF;
|
|
|
|
class ResqJobOrderHandler implements JobOrderHandlerInterface
|
|
{
|
|
protected $em;
|
|
protected $ic;
|
|
protected $security;
|
|
protected $validator;
|
|
protected $translator;
|
|
protected $rah;
|
|
protected $country_code;
|
|
protected $wh;
|
|
protected $rt;
|
|
protected $promo_logger;
|
|
protected $hub_dist;
|
|
protected $hub_geofence;
|
|
protected $cust_distance_limit;
|
|
protected $hub_filter_enable;
|
|
|
|
protected $template_hash;
|
|
|
|
public function __construct(Security $security, EntityManagerInterface $em,
|
|
InvoiceGeneratorInterface $ic, ValidatorInterface $validator,
|
|
TranslatorInterface $translator, RiderAssignmentHandlerInterface $rah,
|
|
string $country_code, WarrantyHandler $wh, RisingTideGateway $rt,
|
|
PromoLogger $promo_logger, HubDistributor $hub_dist, HubFilteringGeoChecker $hub_geofence,
|
|
string $cust_distance_limit, string $hub_filter_enabled)
|
|
{
|
|
$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->rt = $rt;
|
|
$this->promo_logger = $promo_logger;
|
|
$this->hub_dist = $hub_dist;
|
|
$this->hub_geofence = $hub_geofence;
|
|
$this->cust_distance_limit = $cust_distance_limit;
|
|
$this->hub_filter_enabled = $hub_filter_enabled;
|
|
|
|
$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 = ServiceType::getCollection();
|
|
|
|
// process rows
|
|
$rows = [];
|
|
foreach ($obj_rows as $orow) {
|
|
$is_vip = false;
|
|
$is_emergency = false;
|
|
|
|
// check if customer is vip
|
|
$cust_class = $orow->getCustomer()->getCustomerClassification();
|
|
if ($cust_class == CustomerClassification::VIP)
|
|
$is_vip = true;
|
|
|
|
// check if customer is not willing to wait
|
|
$will_not_wait = $orow->getWillWait();
|
|
if ($will_not_wait == WillingToWaitContent::NOT_WILLING_TO_WAIT)
|
|
{
|
|
// check if reason is emergency or rush
|
|
$reason = $orow->getReasonNotWait();
|
|
if (($reason == CustomerNotWaitReason::EMERGENCY) ||
|
|
($reason == CustomerNotWaitReason::RUSH_REQUEST))
|
|
$is_emergency = true;
|
|
}
|
|
|
|
// 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()];
|
|
$row['status'] = $statuses[$orow->getStatus()];
|
|
$row['flag_advance'] = $orow->isAdvanceOrder();
|
|
$row['plate_number'] = $orow->getCustomerVehicle()->getPlateNumber();
|
|
$row['is_mobile'] = $orow->getSource() == TransactionOrigin::MOBILE_APP;
|
|
$row['is_vip'] = $is_vip;
|
|
$row['is_emergency'] = $is_emergency;
|
|
|
|
$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();
|
|
|
|
$hub_facilitated = $orow->getFacilitatedBy();
|
|
if ($hub_facilitated == null)
|
|
$row['hub_facilitated'] = '';
|
|
else
|
|
$row['hub_facilitated'] = $orow->getFacilitatedBy()->getName();
|
|
|
|
$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 = ServiceType::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 job order
|
|
public function generateJobOrder(Request $req, $id)
|
|
{
|
|
// initialize error list
|
|
$error_array = [];
|
|
|
|
$em = $this->em;
|
|
|
|
$jo = $em->getRepository(JobOrder::class)->find($id);
|
|
// flag for new job order for the customer tags
|
|
$flag_new_jo = false;
|
|
if (empty($jo))
|
|
{
|
|
// new job order
|
|
$jo = new JobOrder();
|
|
$flag_new_jo = true;
|
|
}
|
|
|
|
// find customer
|
|
$cust_id = $req->request->get('cid');
|
|
$customer = $em->getRepository(Customer::class)->find($cust_id);
|
|
if (empty($customer))
|
|
{
|
|
$error_array['customer_vehicle'] = 'Invalid customer specified.';
|
|
}
|
|
else
|
|
{
|
|
// get email, dpa_consent, promo_sms, and promo_email, if set
|
|
// check for dpa access
|
|
$is_dpa_checked = true;
|
|
if ($this->security->isGranted('customer.dpa'))
|
|
$is_dpa_checked = $req->request->get('flag_dpa_consent', false);
|
|
|
|
// check if email marketing promo is checked
|
|
$is_email_promo_checked = $req->request->get('flag_promo_email');
|
|
if ($is_email_promo_checked)
|
|
{
|
|
// check email field
|
|
if (empty($req->request->get('customer_email')))
|
|
$error_array['customer_email'] = 'Email address required.';
|
|
}
|
|
|
|
$customer->setEmail($req->request->get('customer_email'))
|
|
->setPromoSms($req->request->get('flag_promo_sms', false))
|
|
->setPromoEmail($req->request->get('flag_promo_email', false))
|
|
->setResearchSms($req->request->get('flag_research_sms', false))
|
|
->setResearchEmail($req->request->get('flag_research_email', false))
|
|
->setDpaConsent($is_dpa_checked);
|
|
}
|
|
|
|
// 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.';
|
|
}
|
|
}
|
|
|
|
// 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_willing_to_wait');
|
|
$reason = '';
|
|
$more_reason = '';
|
|
if ($will_wait == WillingToWaitContent::NOT_WILLING_TO_WAIT)
|
|
{
|
|
// get the reason and text
|
|
$reason = $req->request->get('no_wait_reason');
|
|
$more_reason = $req->request->get('not_wait_notes');
|
|
}
|
|
|
|
// check if service is battery sales
|
|
$stype = $req->request->get('service_type');
|
|
$no_trade_in_reason = '';
|
|
if ($stype == ServiceType::BATTERY_REPLACEMENT_NEW)
|
|
{
|
|
// check if trade in
|
|
$is_trade_in = $req->request->get('invoice_trade_in_type');
|
|
if (empty($is_trade_in))
|
|
{
|
|
$no_trade_in_reason = $req->request->get('no_trade_in_reason');
|
|
|
|
if (empty($no_trade_in_reason))
|
|
$error_array['no_trade_in_reason'] = 'No trade in reason required.';
|
|
}
|
|
}
|
|
|
|
// get source of awareness if any
|
|
$soa_type = $req->request->get('source_of_awareness', '');
|
|
|
|
// get remarks
|
|
$remarks = $req->request->get('remarks', '');
|
|
|
|
// get initial concern if any
|
|
$initial_concern = $req->request->get('initial_concern', '');
|
|
|
|
// get initial concern notes if any
|
|
$initial_concern_notes = $req->request->get('initial_concern_notes', '');
|
|
|
|
// get gender if any
|
|
$gender = $req->request->get('gender', '');
|
|
|
|
// get caller classification if any
|
|
$caller_class = $req->request->get('caller_class','');
|
|
|
|
// get emergency type if any
|
|
$etype_id = $req->request->get('emergency_type', 0);
|
|
$etype = $em->getRepository(EmergencyType::class)->find($etype_id);
|
|
|
|
// TODO: check status before saving since JO might already
|
|
// have a status that needs to be retained
|
|
|
|
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'));
|
|
|
|
// 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'))
|
|
->setWillWait($req->request->get('flag_willing_to_wait'))
|
|
->setReasonNotWait($reason)
|
|
->setNotWaitingNotes($more_reason)
|
|
->setNoTradeInReason($no_trade_in_reason)
|
|
->setSourceOfAwareness($soa_type)
|
|
->setRemarks($remarks)
|
|
->setInitialConcern($initial_concern)
|
|
->setInitialConcernNotes($initial_concern_notes)
|
|
->setCallerClassification($caller_class)
|
|
->setGender($gender)
|
|
->setEmergencyType($etype);
|
|
|
|
// 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);
|
|
}
|
|
}
|
|
|
|
// check service type if new battery
|
|
// check if new JO
|
|
if (($stype == ServiceType::BATTERY_REPLACEMENT_NEW) &&
|
|
($flag_new_jo))
|
|
{
|
|
// check if customer has customer tag promo
|
|
if (($customer->getCustomerTag('TAG_CAR_CLUB_OFFICER_PROMO')) ||
|
|
($customer->getCustomerTag('TAG_CAR_CLUB_MEMBER_PROMO')))
|
|
{
|
|
// if has customer tag, customer has not availed of promo, get the hub where customer is pre-registered
|
|
$car_club_hub = $customer->getCarClubCustomerHub();
|
|
if ($car_club_hub != null)
|
|
{
|
|
// assign hub, change the jo status
|
|
$hub = $car_club_hub->getHub();
|
|
$jo->setHub($hub)
|
|
->setStatus(JOStatus::RIDER_ASSIGN);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// 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 and customer
|
|
$em->persist($jo);
|
|
$em->persist($customer);
|
|
|
|
// the event
|
|
$event = new JOEvent();
|
|
$event->setDateHappen(new DateTime())
|
|
->setTypeID(JOEventType::CREATE)
|
|
->setJobOrder($jo);
|
|
|
|
if ($user != null)
|
|
{
|
|
$event->setUser($user);
|
|
}
|
|
|
|
$em->persist($event);
|
|
|
|
// check if JOStatus is rider assign
|
|
if ($jo->getStatus() == JOStatus::RIDER_ASSIGN)
|
|
{
|
|
$rider_assign_event = new JOEvent();
|
|
$rider_assign_event->setDateHappen(new DateTime())
|
|
->setTypeID(JOEventType::HUB_ASSIGN)
|
|
->setJobOrder($jo);
|
|
|
|
if ($user != null)
|
|
{
|
|
$rider_assign_event->setUser($user);
|
|
}
|
|
$em->persist($rider_assign_event);
|
|
}
|
|
|
|
$em->flush();
|
|
}
|
|
}
|
|
|
|
$data['error_array'] = $error_array;
|
|
|
|
if ($jo != null)
|
|
{
|
|
$data['job_order'] = $jo;
|
|
|
|
// need to get the customer tags but only if new JO
|
|
if ($flag_new_jo)
|
|
{
|
|
// check service type
|
|
if ($jo->getServiceType() == ServiceType::BATTERY_REPLACEMENT_NEW)
|
|
{
|
|
$customer = $cust_vehicle->getCustomer();
|
|
$customer_tags = $customer->getCustomerTagObjects();
|
|
if (!empty($customer_tags))
|
|
{
|
|
foreach ($customer_tags as $customer_tag)
|
|
{
|
|
if ($customer_tag->getID() == $jo->getInvoice()->getUsedCustomerTagId())
|
|
{
|
|
// remove associated entity
|
|
$customer->removeCustomerTag($customer_tag);
|
|
|
|
// log the availment of promo from customer
|
|
$created_by = $jo->getCreatedBy()->getUsername();
|
|
$cust_id = $jo->getCustomer()->getID();
|
|
$cust_fname = $jo->getCustomer()->getFirstName();
|
|
$cust_lname = $jo->getCustomer()->getLastName();
|
|
$jo_id = $jo->getID();
|
|
$invoice_id = $jo->getInvoice()->getID();
|
|
// TODO: check if we store total price of invoice or just the discounted amount
|
|
$amount = $jo->getInvoice()->getTotalPrice();
|
|
$this->promo_logger->logPromoInfo($created_by, $cust_id, $cust_fname, $cust_lname, $jo_id,
|
|
$invoice_id, $amount);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
// updates job order
|
|
public function openEditJobOrder(Request $req, $id)
|
|
{
|
|
$em = $this->em;
|
|
|
|
$obj = $em->getRepository(JobOrder::class)->find($id);
|
|
|
|
// initialize error list
|
|
$error_array = [];
|
|
|
|
// make sure this object exists
|
|
if (empty($obj))
|
|
throw $this->createNotFoundException('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 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_willing_to_wait');
|
|
$reason = '';
|
|
$more_reason = '';
|
|
if ($will_wait == WillingToWaitContent::NOT_WILLING_TO_WAIT)
|
|
{
|
|
// get the reason and text
|
|
$reason = $req->request->get('no_wait_reason');
|
|
$more_reason = $req->request->get('not_wait_notes');
|
|
}
|
|
|
|
// check if service type is battery sales
|
|
$stype = $req->request->get('service_type');
|
|
$no_trade_in_reason = '';
|
|
if ($stype == ServiceType::BATTERY_REPLACEMENT_NEW)
|
|
{
|
|
// check if trade in
|
|
$is_trade_in = $req->request->get('invoice_trade_in_type');
|
|
if (empty($is_trade_in))
|
|
{
|
|
$no_trade_in_reason = $req->request->get('no_trade_in_reason');
|
|
|
|
if (empty($no_trade_in_reason))
|
|
$error_array['no_trade_in_reason'] = 'No trade in reason required.';
|
|
}
|
|
}
|
|
|
|
// get source of awareness if any
|
|
$soa_type = $req->request->get('source_of_awareness', '');
|
|
|
|
// get remarks
|
|
$remarks = $req->request->get('remarks', '');
|
|
|
|
// get initial concern if any
|
|
$initial_concern = $req->request->get('initial_concern', '');
|
|
|
|
// get initial concern notes if any
|
|
$initial_concern_notes = $req->request->get('initial_concern_notes', '');
|
|
|
|
// get gender if any
|
|
$gender = $req->request->get('gender', '');
|
|
|
|
// get caller classification if any
|
|
$caller_class = $req->request->get('caller_class', '');
|
|
|
|
// get emergency type if any
|
|
$etype_id = $req->request->get('emergency_type', 0);
|
|
$etype = $em->getRepository(EmergencyType::class)->find($etype_id);
|
|
|
|
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'));
|
|
|
|
// 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($stype)
|
|
->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'))
|
|
->setORName($req->request->get('or_name'))
|
|
->setPromoDetail($req->request->get('promo_detail'))
|
|
->setModeOfPayment($req->request->get('mode_of_payment'))
|
|
->setLandmark($req->request->get('landmark'))
|
|
->setWillWait($req->request->get('flag_willing_to_wait'))
|
|
->setReasonNotWait($reason)
|
|
->setNotWaitingNotes($more_reason)
|
|
->setNoTradeInReason($no_trade_in_reason)
|
|
->setSourceOfAwareness($soa_type)
|
|
->setRemarks($remarks)
|
|
->setInitialConcern($initial_concern)
|
|
->setInitialConcernNotes($initial_concern_notes)
|
|
->setCallerClassification($caller_class)
|
|
->setGender($gender)
|
|
->setEmergencyType($etype);
|
|
|
|
// did they change invoice?
|
|
$invoice_items = $req->request->get('invoice_items', []);
|
|
$promo_id = $req->request->get('invoice_promo');
|
|
$invoice_change = $req->request->get('invoice_change', 0);
|
|
if ($invoice_change)
|
|
{
|
|
$this->ic->generateInvoiceCriteria($obj, $promo_id, $invoice_items, $error_array);
|
|
}
|
|
|
|
// 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)) {
|
|
// return validation failure response
|
|
return $this->json([
|
|
'success' => false,
|
|
'errors' => $error_array
|
|
], 422);
|
|
}
|
|
|
|
// the event
|
|
$event = new JOEvent();
|
|
$event->setDateHappen(new DateTime())
|
|
->setTypeID(JOEventType::OPEN_EDIT)
|
|
->setJobOrder($obj);
|
|
|
|
error_log('open edit?');
|
|
|
|
if ($user != null)
|
|
{
|
|
$event->setUser($user);
|
|
}
|
|
|
|
$em->persist($event);
|
|
|
|
// validated! save the entity
|
|
$em->flush();
|
|
}
|
|
|
|
$data['error_array'] = $error_array;
|
|
|
|
if ($obj != null)
|
|
{
|
|
$data['job_order'] = $obj;
|
|
}
|
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
|
|
// 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_willing_to_wait');
|
|
$reason = '';
|
|
$more_reason = '';
|
|
if ($will_wait == WillingToWaitContent::NOT_WILLING_TO_WAIT)
|
|
{
|
|
// get the reason and text
|
|
$reason = $req->request->get('no_wait_reason');
|
|
$more_reason = $req->request->get('not_wait_notes');
|
|
}
|
|
|
|
// get source of awareness if any
|
|
$soa_type = $req->request->get('source_of_awareness', '');
|
|
|
|
// get remarks
|
|
$remarks = $req->request->get('remarks', '');
|
|
|
|
// get initial concern if any
|
|
$initial_concern = $req->request->get('initial_concern', '');
|
|
|
|
// get initial concern notes if any
|
|
$initial_concern_notes = $req->request->get('initial_concern_notes', '');
|
|
|
|
// get gender if any
|
|
$gender = $req->request->get('gender', '');
|
|
|
|
// get caller classification if any
|
|
$caller_class = $req->request->get('caller_class', '');
|
|
|
|
// get emergency type if any
|
|
$etype_id = $req->request->get('emergency_type', 0);
|
|
$etype = $em->getRepository(EmergencyType::class)->find($etype_id);
|
|
|
|
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)
|
|
->setLandmark($req->request->get('landmark'))
|
|
->setWillWait($req->request->get('flag_willing_to_wait'))
|
|
->setReasonNotWait($reason)
|
|
->setNotWaitingNotes($more_reason)
|
|
->setSourceOfAwareness($soa_type)
|
|
->setRemarks($remarks)
|
|
->setInitialConcern($initial_concern)
|
|
->setInitialConcernNotes($initial_concern_notes)
|
|
->setGender($gender)
|
|
->setCallerClassification($caller_class)
|
|
->setEmergencyType($etype);
|
|
|
|
// 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);
|
|
|
|
// update redis hub jo count
|
|
$this->hub_dist->incrementJoCountForHub($hub);
|
|
}
|
|
|
|
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.';
|
|
}
|
|
}
|
|
|
|
// 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_willing_to_wait');
|
|
$reason = '';
|
|
$more_reason = '';
|
|
if ($will_wait == WillingToWaitContent::NOT_WILLING_TO_WAIT)
|
|
{
|
|
// get the reason and text
|
|
$reason = $req->request->get('no_wait_reason');
|
|
$more_reason = $req->request->get('not_wait_notes');
|
|
}
|
|
|
|
// get source of awareness if any
|
|
$soa_type = $req->request->get('source_of_awareness', '');
|
|
|
|
// get remarks
|
|
$remarks = $req->request->get('remarks', '');
|
|
|
|
// get initial concern if any
|
|
$initial_concern = $req->request->get('initial_concern', '');
|
|
|
|
// get initial concern notes if any
|
|
$initial_concern_notes = $req->request->get('initial_concern_notes', '');
|
|
|
|
// get gender if any
|
|
$gender = $req->request->get('gender', '');
|
|
|
|
// get caller classification if any
|
|
$caller_class = $req->request->get('caller_class', '');
|
|
|
|
// get emergency type if any
|
|
$etype_id = $req->request->get('emergency_type', 0);
|
|
$etype = $em->getRepository(EmergencyType::class)->find($etype_id);
|
|
|
|
// 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)
|
|
->setLandmark($req->request->get('landmark'))
|
|
->setWillWait($req->request->get('flag_willing_to_wait'))
|
|
->setReasonNotWait($reason)
|
|
->setNotWaitingNotes($more_reason)
|
|
->setDeliveryStatus(DeliveryStatus::RIDER_ASSIGN)
|
|
->setSourceOfAwareness($soa_type)
|
|
->setRemarks($remarks)
|
|
->setInitialConcern($initial_concern)
|
|
->setInitialConcernNotes($initial_concern_notes)
|
|
->setCallerClassification($caller_class)
|
|
->setGender($gender)
|
|
->setEmergencyType($etype);
|
|
|
|
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);
|
|
|
|
// set rider's current job order
|
|
$rider->setCurrentJobOrder($obj);
|
|
|
|
// 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.';
|
|
}
|
|
|
|
// 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_willing_to_wait');
|
|
$reason = '';
|
|
$more_reason = '';
|
|
if ($will_wait == WillingToWaitContent::NOT_WILLING_TO_WAIT)
|
|
{
|
|
// get the reason and text
|
|
$reason = $req->request->get('no_wait_reason');
|
|
$more_reason = $req->request->get('not_wait_notes');
|
|
}
|
|
|
|
// get source of awareness if any
|
|
$soa_type = $req->request->get('source_of_awareness', '');
|
|
|
|
// get remarks
|
|
$remarks = $req->request->get('remarks', '');
|
|
|
|
// get initial concern if any
|
|
$initial_concern = $req->request->get('initial_concern', '');
|
|
|
|
// get initial concern notes if any
|
|
$initial_concern_notes = $req->request->get('initial_concern_notes', '');
|
|
|
|
// get gender if any
|
|
$gender = $req->request->get('gender', '');
|
|
|
|
// get caller classification if any
|
|
$caller_class = $req->request->get('caller_class', '');
|
|
|
|
// get emergency type if any
|
|
$etype_id = $req->request->get('emergency_type', 0);
|
|
$etype = $em->getRepository(EmergencyType::class)->find($etype_id);
|
|
|
|
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'))
|
|
->setLandmark($req->request->get('landmark'))
|
|
->setWillWait($req->request->get('flag_willing_to_wait'))
|
|
->setReasonNotWait($reason)
|
|
->setNotWaitingNotes($more_reason)
|
|
->setDeliveryStatus(DeliveryStatus::FULFILLED)
|
|
->setSourceOfAwareness($soa_type)
|
|
->setRemarks($remarks)
|
|
->setInitialConcern($initial_concern)
|
|
->setInitialConcernNotes($initial_concern_notes)
|
|
->setGender($gender)
|
|
->setCallerClassification($caller_class)
|
|
->setEmergencyType($etype);
|
|
|
|
// validate
|
|
$errors = $this->validator->validate($obj);
|
|
|
|
// add errors to list
|
|
foreach ($errors as $error) {
|
|
$error_array[$error->getPropertyPath()] = $error->getMessage();
|
|
}
|
|
}
|
|
|
|
if (empty($error_array))
|
|
{
|
|
$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);
|
|
|
|
// 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();
|
|
|
|
// call rider assignment handler's fulfillJobOrder
|
|
$this->rah->fulfillJobOrder($obj, $image_url, $rider);
|
|
|
|
// create the warranty if new battery only
|
|
if ($this->checkIfNewBattery($obj))
|
|
{
|
|
$serial = null;
|
|
$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();
|
|
|
|
// use date_schedule for warranty expiration computation
|
|
$date_purchase = $obj->getDateSchedule();
|
|
|
|
// 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();
|
|
}
|
|
}
|
|
}
|
|
|
|
$user_id = $user->getUsername();
|
|
$source = WarrantySource::ADMIN_PANEL;
|
|
$this->wh->createWarranty($serial, $plate_number, $first_name, $last_name, $mobile_number, $batt_list, $date_purchase, $warranty_class, $user_id, $source, $obj->getCustomer(), $obj->getCustomerVehicle()->getVehicle());
|
|
}
|
|
else
|
|
error_log('Invalid plate number for warranty. Plate number = ' . $obj->getCustomerVehicle()->getPlateNumber());
|
|
}
|
|
|
|
// send SMS to customer
|
|
// prepend country code to number
|
|
$phone_number = $this->country_code . $obj->getCustomer()->getPhoneMobile();
|
|
if (!empty($phone_number))
|
|
$this->sendSMSToCustomer($phone_number);
|
|
}
|
|
|
|
return $error_array;
|
|
}
|
|
|
|
// 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');
|
|
//error_log('cancel_reason ' . $cancel_reason);
|
|
|
|
$obj->setDeliveryStatus(DeliveryStatus::CANCELLED);
|
|
|
|
$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.';
|
|
}
|
|
}
|
|
|
|
// 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_willing_to_wait');
|
|
$reason = '';
|
|
$more_reason = '';
|
|
if ($will_wait == WillingToWaitContent::NOT_WILLING_TO_WAIT)
|
|
{
|
|
// get the reason and text
|
|
$reason = $req->request->get('no_wait_reason');
|
|
$more_reason = $req->request->get('not_wait_notes');
|
|
}
|
|
|
|
// get source of awareness if any
|
|
$soa_type = $req->request->get('source_of_awareness', '');
|
|
|
|
// get remarks
|
|
$remarks = $req->request->get('remarks', '');
|
|
|
|
// get initial concern if any
|
|
$initial_concern = $req->request->get('initial_concern', '');
|
|
|
|
// get initial concern notes if any
|
|
$initial_concern_notes = $req->request->get('initial_concern_notes', '');
|
|
|
|
// get gender if any
|
|
$gender = $req->request->get('gender', '');
|
|
|
|
// get caller classification if any
|
|
$caller_class = $req->request->get('caller_class', '');
|
|
|
|
// get emergency type if any
|
|
$etype_id = $req->request->get('emergency_type', 0);
|
|
$etype = $em->getRepository(EmergencyType::class)->find($etype_id);
|
|
|
|
// get previously assigned hub, if any
|
|
$old_hub = $obj->getHub();
|
|
|
|
// get previously assigned rider, if any
|
|
$old_rider = $obj->getRider();
|
|
|
|
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);
|
|
|
|
// need to unset first rider's current job order
|
|
$old_rider = $obj->getRider();
|
|
if ($old_rider != null)
|
|
{
|
|
if (($old_rider->getCurrentJobOrder() != null) &&
|
|
($old_rider->getCurrentJobOrder()->getID() == $obj->getID()))
|
|
{
|
|
$old_rider->setCurrentJobOrder();
|
|
// set available flag for first rider
|
|
$old_rider->setAvailable(true);
|
|
}
|
|
}
|
|
|
|
// 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)
|
|
->setLandmark($req->request->get('landmark'))
|
|
->setWillWait($req->request->get('flag_willing_to_wait'))
|
|
->setReasonNotWait($reason)
|
|
->setNotWaitingNotes($more_reason)
|
|
->setSourceOfAwareness($soa_type)
|
|
->setRemarks($remarks)
|
|
->setInitialConcern($initial_concern)
|
|
->setInitialConcernNotes($initial_concern_notes)
|
|
->setGender($gender)
|
|
->setCallerClassification($caller_class)
|
|
->setEmergencyType($etype)
|
|
->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);
|
|
|
|
// update redis hub_jo_count for hub
|
|
// decrement old hub's count and increment new hub's count
|
|
if ($old_hub != null)
|
|
$this->hub_dist->decrementJoCountForHub($old_hub);
|
|
if ($hub != null)
|
|
$this->hub_dist->incrementJoCountForHub($hub);
|
|
}
|
|
|
|
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.';
|
|
}
|
|
}
|
|
|
|
// 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_willing_to_wait');
|
|
$reason = '';
|
|
$more_reason = '';
|
|
if ($will_wait == WillingToWaitContent::NOT_WILLING_TO_WAIT)
|
|
{
|
|
// get the reason and text
|
|
$reason = $req->request->get('no_wait_reason');
|
|
$more_reason = $req->request->get('not_wait_notes');
|
|
}
|
|
|
|
// get source of awareness if any
|
|
$soa_type = $req->request->get('source_of_awareness', '');
|
|
|
|
// get remarks
|
|
$remarks = $req->request->get('remarks', '');
|
|
|
|
// get initial concern if any
|
|
$initial_concern = $req->request->get('initial_concern', '');
|
|
|
|
// get initial concern notes if any
|
|
$initial_concern_notes = $req->request->get('initial_concern_notes', '');
|
|
|
|
// get gender if any
|
|
$gender = $req->request->get('gender', '');
|
|
|
|
// get caller classification if any
|
|
$caller_class = $req->request->get('caller_class', '');
|
|
|
|
// get emergency type if any
|
|
$etype_id = $req->request->get('emergency_type', 0);
|
|
$etype = $em->getRepository(EmergencyType::class)->find($etype_id);
|
|
|
|
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);
|
|
|
|
// need to unset first rider's current job order
|
|
$old_rider = $obj->getRider();
|
|
if ($old_rider != null)
|
|
{
|
|
if (($old_rider->getCurrentJobOrder() != null) &&
|
|
($old_rider->getCurrentJobOrder()->getID() == $obj->getID()))
|
|
{
|
|
$old_rider->setCurrentJobOrder();
|
|
// set available flag for first rider
|
|
$old_rider->setAvailable(true);
|
|
}
|
|
}
|
|
|
|
// 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)
|
|
->setLandmark($req->request->get('landmark'))
|
|
->setWillWait($req->request->get('flag_willing_to_wait'))
|
|
->setReasonNotWait($reason)
|
|
->setNotWaitingNotes($more_reason)
|
|
->setSourceOfAwareness($soa_type)
|
|
->setRemarks($remarks)
|
|
->setDeliveryStatus(DeliveryStatus::RIDER_ASSIGN)
|
|
->setInitialConcern($initial_concern)
|
|
->setInitialConcernNotes($initial_concern_notes)
|
|
->setGender($gender)
|
|
->setCallerClassification($caller_class)
|
|
->setEmergencyType($etype);
|
|
|
|
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))
|
|
{
|
|
// set new rider's current job order
|
|
$rider->setCurrentJobOrder($obj);
|
|
|
|
// set new rider's availability to false
|
|
$rider->setAvailable(false);
|
|
|
|
// 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();
|
|
}
|
|
|
|
}
|
|
|
|
// CMB code
|
|
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 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.';
|
|
}
|
|
}
|
|
|
|
// 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.';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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::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);
|
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
|
// 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;
|
|
}
|
|
|
|
// CMB code
|
|
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;
|
|
}
|
|
|
|
// CMB code
|
|
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);
|
|
|
|
// 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');
|
|
|
|
$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, HubSelector $hub_selector, $motiv)
|
|
{
|
|
$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();
|
|
|
|
$hub_criteria = new HubCriteria();
|
|
|
|
// TODO: need to factor out the setting of HubCriteria fields
|
|
// get battery (if any)
|
|
$skus = [];
|
|
$items = [];
|
|
$invoice = $obj->getInvoice();
|
|
$inv_items = $invoice->getItems();
|
|
foreach ($inv_items as $inv_item)
|
|
{
|
|
$batt = $inv_item->getBattery();
|
|
if ($batt == null)
|
|
continue;
|
|
|
|
$skus[] = $batt->getSapCode();
|
|
$item_count = 1;
|
|
if (!empty($batt->getSapCode()))
|
|
{
|
|
$sap_code = $batt->getSapCode();
|
|
if (isset($items[$sap_code]))
|
|
$items[$sap_code] = $item_count + 1;
|
|
else
|
|
$items[$sap_code] = $item_count;
|
|
|
|
$hub_criteria->addItem($sap_code, $item_count);
|
|
}
|
|
}
|
|
|
|
// get closest hubs
|
|
// set more hub criteria fields
|
|
$long = $obj->getCoordinates()->getLongitude();
|
|
$lat = $obj->getCoordinates()->getLatitude();
|
|
|
|
// set result limit and location and date_time
|
|
$hub_criteria->setPoint($obj->getCoordinates())
|
|
->setDateTime($obj->getDateSchedule())
|
|
->setLimitResults(50);
|
|
|
|
// check if hub filter is enabled. If not, use default values
|
|
// for the rest of the HubCriteria fields
|
|
if ($this->hub_filter_enabled == 'true')
|
|
{
|
|
error_log('hub filter is enabled');
|
|
if ($this->hub_geofence->isCovered($long, $lat))
|
|
{
|
|
// if true, set other values for HubCriteria
|
|
error_log('Area is covered by hub filtering');
|
|
$hub_criteria->setLimitDistance($this->cust_distance_limit)
|
|
->setPaymentMethod($obj->getModeOfPayment())
|
|
->setJoType($obj->getServiceType())
|
|
->setRoundRobin(true);
|
|
}
|
|
}
|
|
|
|
// check if emergency or not
|
|
$willing_to_wait = $obj->getWillWait();
|
|
if ($willing_to_wait == WillingToWaitContent::NOT_WILLING_TO_WAIT)
|
|
{
|
|
// reset distance limit if emergency
|
|
$hub_criteria->setLimitDistance(500);
|
|
$hub_criteria->setEmergency(true);
|
|
}
|
|
|
|
// get JO and customer id for logging purposes
|
|
$jo_id = $obj->getID();
|
|
$customer_id = $obj->getCustomer()->getID();
|
|
|
|
$hub_criteria->setJobOrderId($jo_id)
|
|
->setCustomerId($customer_id);
|
|
|
|
$hubs = $hub_selector->find($hub_criteria);
|
|
|
|
$params['hubs'] = [];
|
|
|
|
$branch_codes = [];
|
|
$inv_data = [];
|
|
|
|
// 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['redis_jo_count'] = $hub['jo_count'];
|
|
//$hub['redis_jo_count'] = 0;
|
|
// $hub['jo_count'] = count($hub['hub']->getForAssignmentJobOrders());
|
|
$hub['jo_count'] = $hub['redis_jo_count'];
|
|
|
|
// 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;
|
|
}
|
|
}
|
|
|
|
// handle inventory data
|
|
$bcode = $hub['hub']->getBranchCode();
|
|
$hub['inventory'] = 0;
|
|
if ($bcode != '')
|
|
{
|
|
$branch_codes[] = $bcode;
|
|
$inv_data[$bcode] = [
|
|
'hub_id' => $hub_id,
|
|
'branch_code' => $bcode,
|
|
'inventory' => 0,
|
|
];
|
|
}
|
|
|
|
$params['hubs'][$hub_id] = $hub;
|
|
}
|
|
|
|
$params['obj'] = $obj;
|
|
// get template to display
|
|
$params['template'] = $this->getTwigTemplate('jo_processing_form');
|
|
|
|
// get battery (if any)
|
|
$skus = [];
|
|
$invoice = $obj->getInvoice();
|
|
$inv_items = $invoice->getItems();
|
|
foreach ($inv_items as $inv_item)
|
|
{
|
|
$batt = $inv_item->getBattery();
|
|
if ($batt == null)
|
|
continue;
|
|
|
|
$skus[] = $batt->getSapCode();
|
|
}
|
|
|
|
// get inventory
|
|
$mres = $motiv->getInventory($branch_codes, $skus);
|
|
foreach ($mres as $mres_item)
|
|
{
|
|
$bcode = $mres_item['BranchCode'];
|
|
$inv_count = $mres_item['Quantity'];
|
|
if (isset($inv_data[$bcode]))
|
|
{
|
|
$hub_id = $inv_data[$bcode]['hub_id'];
|
|
|
|
$params['hubs'][$hub_id]['inventory'] = $inv_count;
|
|
}
|
|
}
|
|
|
|
error_log(print_r($mres, true));
|
|
|
|
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, HubSelector $hub_selector, $motiv)
|
|
{
|
|
$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();
|
|
|
|
$hub_criteria = new HubCriteria();
|
|
|
|
// get battery (if any)
|
|
$skus = [];
|
|
$items = [];
|
|
$invoice = $obj->getInvoice();
|
|
$inv_items = $invoice->getItems();
|
|
foreach ($inv_items as $inv_item)
|
|
{
|
|
$batt = $inv_item->getBattery();
|
|
if ($batt == null)
|
|
continue;
|
|
|
|
$skus[] = $batt->getSapCode();
|
|
$item_count = 1;
|
|
if (!empty($batt->getSapCode()))
|
|
{
|
|
$sap_code = $batt->getSapCode();
|
|
if (isset($items[$sap_code]))
|
|
$items[$sap_code] = $item_count + 1;
|
|
else
|
|
$items[$sap_code] = $item_count;
|
|
}
|
|
|
|
$hub_criteria->addItem($sap_code, $item_count);
|
|
}
|
|
|
|
// get closest hubs
|
|
// set more hub criteria fields
|
|
$long = $obj->getCoordinates()->getLongitude();
|
|
$lat = $obj->getCoordinates()->getLatitude();
|
|
|
|
$hub_criteria->setPoint($obj->getCoordinates())
|
|
->setDateTime($obj->getDateSchedule())
|
|
->setLimitResults(50);
|
|
|
|
if ($this->hub_geofence->isCovered($long, $lat))
|
|
{
|
|
// if true, set other values for HubCriteria
|
|
// error_log('Area is covered by hub');
|
|
$hub_criteria->setLimitDistance($this->cust_distance_limit)
|
|
->setPaymentMethod($obj->getModeOfPayment())
|
|
->setJoType($obj->getServiceType())
|
|
->setRoundRobin(true);
|
|
}
|
|
|
|
// check if emergency or not
|
|
$willing_to_wait = $obj->getWillWait();
|
|
if ($willing_to_wait == WillingToWaitContent::NOT_WILLING_TO_WAIT)
|
|
$hub_criteria->setEmergency(true);
|
|
|
|
// get JO and customer id for logging purposes
|
|
$jo_id = $obj->getID();
|
|
$customer_id = $obj->getCustomer()->getID();
|
|
|
|
$hub_criteria->setJobOrderId($jo_id)
|
|
->setCustomerId($customer_id);
|
|
|
|
$hubs = $hub_selector->find($hub_criteria);
|
|
|
|
$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['redis_jo_count'] = $hub['jo_count'];
|
|
$hub['redis_jo_count'] = 0;
|
|
// $hub['jo_count'] = count($hub['hub']->getForAssignmentJobOrders());
|
|
$hub['jo_count'] = $hub['redis_jo_count'];
|
|
|
|
// 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;
|
|
}
|
|
}
|
|
|
|
// handle inventory data
|
|
$bcode = $hub['hub']->getBranchCode();
|
|
$hub['inventory'] = 0;
|
|
if ($bcode != '')
|
|
{
|
|
$branch_codes[] = $bcode;
|
|
$inv_data[$bcode] = [
|
|
'hub_id' => $hub_id,
|
|
'branch_code' => $bcode,
|
|
'inventory' => 0,
|
|
];
|
|
}
|
|
|
|
$params['hubs'][$hub_id] = $hub;
|
|
}
|
|
|
|
// get battery (if any)
|
|
$skus = [];
|
|
$invoice = $obj->getInvoice();
|
|
$inv_items = $invoice->getItems();
|
|
foreach ($inv_items as $inv_item)
|
|
{
|
|
$batt = $inv_item->getBattery();
|
|
if ($batt == null)
|
|
continue;
|
|
|
|
$skus[] = $batt->getSapCode();
|
|
}
|
|
|
|
// get inventory
|
|
$mres = $motiv->getInventory($branch_codes, $skus);
|
|
foreach ($mres as $mres_item)
|
|
{
|
|
$bcode = $mres_item['BranchCode'];
|
|
$inv_count = $mres_item['Quantity'];
|
|
if (isset($inv_data[$bcode]))
|
|
{
|
|
$hub_id = $inv_data[$bcode]['hub_id'];
|
|
|
|
$params['hubs'][$hub_id]['inventory'] = $inv_count;
|
|
}
|
|
}
|
|
|
|
error_log(print_r($mres, true));
|
|
|
|
$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');
|
|
|
|
// 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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.warranty_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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.warranty_class'));
|
|
$pdf->MultiCell($val_width, $line_height, WarrantyClass::getName($obj->getWarrantyClass()), 0, 'L');
|
|
|
|
// get Y after left cell
|
|
$y1 = $pdf->GetY();
|
|
|
|
$pdf->SetXY($col2_x, $y);
|
|
$pdf->Cell($label_width, $line_height, $translator->trans('label.pdf.mode_of_payment'));
|
|
$pdf->MultiCell(0, $line_height, ModeOfPayment::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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.delivery_instructions'));
|
|
$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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.item'), 1, 0, 'L', 1);
|
|
$pdf->Cell($table_col_width * 2, $table_line_height, $translator->trans('label.pdf.quantity'), 1, 0, 'R', 1);
|
|
$pdf->Cell($table_col_width * 2, $table_line_height, $translator->trans('label.pdf.unit_price'), 1, 0, 'R', 1);
|
|
$pdf->Cell($table_col_width * 2, $table_line_height, $translator->trans('label.pdf.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, $translator->trans('label.pdf.transaction_type'));
|
|
$pdf->MultiCell($val_width, $line_height, ServiceType::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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.emp_id_ref'));
|
|
$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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.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, $translator->trans('label.pdf.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 getOtherParameters()
|
|
{
|
|
// get riders for dropdown
|
|
$params['riders'] = $this->em->getRepository(Rider::class)->findAll();
|
|
|
|
// get hubs for dropdown
|
|
$params['hubs'] = $this->em->getRepository(Hub::class)->findBy(['flag_hub_view' => true]);
|
|
|
|
return $params;
|
|
}
|
|
|
|
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
|
|
$warr = $jo->getWarrantyClass();
|
|
$warr_months = 0;
|
|
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);
|
|
}
|
|
|
|
public function checkIfNewBattery(JobOrder $jo)
|
|
{
|
|
if ($jo->getServiceType() == ServiceType::BATTERY_REPLACEMENT_NEW)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
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 emergency types
|
|
$e_types = $em->getRepository(EmergencyType::class)->findBy([], ['name' => 'ASC']);
|
|
$emergency_types = [];
|
|
foreach ($e_types as $e_type)
|
|
{
|
|
$emergency_types[$e_type->getID()] = $e_type->getName();
|
|
}
|
|
$params['emergency_types'] = $emergency_types;
|
|
|
|
// 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();
|
|
}
|
|
|
|
// list of customer tags
|
|
$params['customer_tags'] = $em->getRepository(CustomerTag::class)->findAll();
|
|
|
|
// 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();
|
|
$params['willing_to_wait_content'] = WillingToWaitContent::getCollection();
|
|
$params['no_wait_reasons'] = CustomerNotWaitReason::getCollection();
|
|
$params['no_trade_in_reasons'] = NoTradeInReason::getCollection();
|
|
$params['soa_types'] = SourceOfAwareness::getCollection();
|
|
$params['initial_concern'] = InitialConcern::getCollection();
|
|
$params['genders'] = Gender::getCollection();
|
|
$params['caller_classifications'] = CallerClassification::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;
|
|
}
|
|
}
|
|
|
|
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/form.html.twig';
|
|
$this->template_hash['jo_open_edit_form'] = 'job-order/form.html.twig';
|
|
$this->template_hash['jo_incoming_vehicle_form'] = 'job-order/form.html.twig';
|
|
$this->template_hash['jo_processing_form'] = 'job-order/form.html.twig';
|
|
$this->template_hash['jo_assigning_form'] = 'job-order/form.html.twig';
|
|
$this->template_hash['jo_fulfillment_form'] = 'job-order/form.html.twig';
|
|
$this->template_hash['jo_open_hub_form'] = 'job-order/form.html.twig';
|
|
$this->template_hash['jo_open_rider_form'] = 'job-order/form.html.twig';
|
|
$this->template_hash['jo_all_form'] = 'job-order/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_popup'] = 'job-order/popup.html.twig';
|
|
$this->template_hash['jo_hub_list'] = 'job-order/list.hubview.html.twig';
|
|
$this->template_hash['jo_hub_view_form'] = 'job-order/form.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;
|
|
case 'hub_view_all':
|
|
$tier_key = 'jo_hub';
|
|
$tier_name = 'Open';
|
|
$rows_route = 'jo_hub_view_rows';
|
|
$edit_route = 'jo_hub_view_form';
|
|
$unlock_route = '';
|
|
$jo_status = [
|
|
JOStatus::PENDING,
|
|
JOStatus::RIDER_ASSIGN,
|
|
JOStatus::ASSIGNED,
|
|
JOStatus::IN_PROGRESS,
|
|
JOStatus::IN_TRANSIT,
|
|
];
|
|
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'] . '%'); */
|
|
$query->where('q.plate_number like :filter')
|
|
->orWhere('q.phone_mobile like :filter')
|
|
->orWhere('q.first_name like :filter')
|
|
->orWhere('q.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'] . '%');
|
|
*/
|
|
$query->where('q.plate_number like :filter')
|
|
->orWhere('q.phone_mobile like :filter')
|
|
->orWhere('q.first_name like :filter')
|
|
->orWhere('q.last_name like :filter')
|
|
->orWhere('q.status IN (:statuses)')
|
|
->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'] . '%');
|
|
*/
|
|
$query->where('q.plate_number like :filter')
|
|
->orWhere('q.phone_mobile like :filter')
|
|
->orWhere('q.first_name like :filter')
|
|
->orWhere('q.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;
|
|
case 'hub_view_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'] . '%');
|
|
*/
|
|
$query->where('q.plate_number like :filter')
|
|
->orWhere('q.phone_mobile like :filter')
|
|
->orWhere('q.first_name like :filter')
|
|
->orWhere('q.last_name like :filter')
|
|
->setParameter('filter', $datatable['query']['data-rows-search'] . '%');
|
|
}
|
|
if (isset($datatable['query']['hub']))
|
|
{
|
|
$query->innerJoin('q.hub', 'h')
|
|
->andWhere('h.id = :hub_id')
|
|
->setParameter('hub_id', $datatable['query']['hub']);
|
|
}
|
|
else
|
|
{
|
|
$query->innerJoin('q.hub', 'h')
|
|
->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';
|
|
|
|
$start_current_date = DateTime::createFromFormat('Y-m-d H:i:s', $start_curr_date);
|
|
$end_current_date = DateTime::createFromFormat('Y-m-d H:i:s', $end_curr_date);
|
|
|
|
$query->andWhere('q.date_schedule >= :start_current_date')
|
|
->andWhere('q.date_schedule <= :end_current_date')
|
|
->andWhere('q.status IN (:statuses)')
|
|
->setParameter('start_current_date', $start_current_date)
|
|
->setParameter('end_current_date', $end_current_date)
|
|
->setParameter('statuses', $status, Connection::PARAM_STR_ARRAY);
|
|
}
|
|
break;
|
|
case 'proc':
|
|
$query->where('q.status = :status')
|
|
->andWhere('q.source <> :source')
|
|
->setParameter('status', $status)
|
|
->setParameter('source', TransactionOrigin::MOBILE_APP);
|
|
|
|
break;
|
|
default:
|
|
$query->where('q.status = :status')
|
|
->setParameter('status', $status);
|
|
}
|
|
}
|
|
|
|
public function getEditRoute($jo_id, $tier)
|
|
{
|
|
if (empty($tier))
|
|
return 'jo_open_edit_form';
|
|
|
|
return $tier;
|
|
}
|
|
|
|
public function getHubViewRows(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 = ServiceType::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()];
|
|
$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;
|
|
}
|
|
|
|
public function initializeHubViewForm($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_hub_view_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;
|
|
}
|
|
|
|
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();
|
|
}
|
|
|
|
public function sendSMSToCustomer($phone_number)
|
|
{
|
|
// TODO: put this in config file or somewhere
|
|
$message = $this->translator->trans('message.joborder_completed');
|
|
$this->rt->sendSMS($phone_number, $this->translator->trans('message.battery_brand_allcaps'), $message);
|
|
}
|
|
|
|
}
|