diff --git a/src/Command/GenerateBatteryCompatibilityCommand.php b/src/Command/GenerateBatteryCompatibilityCommand.php index e4ca2d6c..8c219f67 100644 --- a/src/Command/GenerateBatteryCompatibilityCommand.php +++ b/src/Command/GenerateBatteryCompatibilityCommand.php @@ -43,7 +43,7 @@ class GenerateBatteryCompatibilityCommand extends Command $vehicles = $vm->getVehicles(); foreach ($vehicles as $vehicle) { - $batteries = $vehicle->getBatteries(); + $batteries = $vehicle->getActiveBatteries(); $comp_batt = []; foreach ($batteries as $battery) { diff --git a/src/Controller/APIController.php b/src/Controller/APIController.php index 6e4d9ed2..05f50243 100644 --- a/src/Controller/APIController.php +++ b/src/Controller/APIController.php @@ -823,7 +823,8 @@ class APIController extends Controller implements LoggedController // batteries $batt_list = []; - $batts = $vehicle->getBatteries(); + // $batts = $vehicle->getBatteries(); + $batts = $vehicle->getActiveBatteries(); foreach ($batts as $batt) { // TODO: Add warranty_tnv to battery information diff --git a/src/Controller/BatteryController.php b/src/Controller/BatteryController.php index e392dd6b..b63e52e9 100644 --- a/src/Controller/BatteryController.php +++ b/src/Controller/BatteryController.php @@ -117,6 +117,7 @@ class BatteryController extends Controller $row['height'] = $orow[0]->getHeight(); $row['total_height'] = $orow[0]->getTotalHeight(); $row['image_file'] = $orow[0]->getImageFile(); + $row['flag_active'] = $orow[0]->isActive(); // add row metadata $row['meta'] = [ @@ -182,7 +183,8 @@ class BatteryController extends Controller ->setHeight($req->request->get('height')) ->setTotalHeight($req->request->get('total_height')) ->setSellingPrice($req->request->get('sell_price')) - ->setImageFile($req->request->get('image_file')); + ->setImageFile($req->request->get('image_file')) + ->setActive($req->request->get('flag_active', false)); // initialize error list $error_array = []; @@ -308,6 +310,7 @@ class BatteryController extends Controller ->setTotalHeight($req->request->get('total_height')) ->setSellingPrice($req->request->get('sell_price')) ->setImageFile($req->request->get('image_file')) + ->setActive($req->request->get('flag_active', false)) ->clearVehicles(); // initialize error list @@ -424,7 +427,7 @@ class BatteryController extends Controller $bmodel_id = $req->query->get('model_id'); $bsize_id = $req->query->get('size_id'); - // find the battery using model and size + // find the battery using model and size and battery must be active $em = $this->getDoctrine()->getManager(); $query = $em->createQuery('SELECT b FROM App\Entity\Battery b JOIN b.model bm @@ -432,7 +435,8 @@ class BatteryController extends Controller JOIN b.manufacturer bmfg WHERE bm.id = :bm_id AND bs.id = :bs_id - AND bmfg.id = :bmfg_id') + AND bmfg.id = :bmfg_id + AND b.flag_active = true') ->setParameter('bmfg_id', $bmfg_id) ->setParameter('bm_id', $bmodel_id) ->setParameter('bs_id', $bsize_id); diff --git a/src/Controller/BatteryManufacturerController.php b/src/Controller/BatteryManufacturerController.php index ad93d3df..c717a678 100644 --- a/src/Controller/BatteryManufacturerController.php +++ b/src/Controller/BatteryManufacturerController.php @@ -270,7 +270,7 @@ class BatteryManufacturerController extends Controller // get row data $em = $this->getDoctrine()->getManager(); - $all_batts = $em->getRepository(Battery::class)->findAll(); + $all_batts = $em->getRepository(Battery::class)->findBy(['flag_active' => true]); foreach ($all_batts as $battery) { diff --git a/src/Controller/CAPI/RiderAppController.php b/src/Controller/CAPI/RiderAppController.php index 1a293058..6a6d3d91 100644 --- a/src/Controller/CAPI/RiderAppController.php +++ b/src/Controller/CAPI/RiderAppController.php @@ -1043,7 +1043,7 @@ class RiderAppController extends APIController if ($rider == null) return new APIResponse(false, 'No rider found.'); - $batts = $em->getRepository(Battery::class)->findAll(); + $batts = $em->getRepository(Battery::class)->findBy(['flag_active' => true]); $models = $em->getRepository(BatteryModel::class)->findAll(); $sizes = $em->getRepository(BatterySize::class)->findAll(); diff --git a/src/Controller/TAPI/BatteryController.php b/src/Controller/TAPI/BatteryController.php index 7e015fe6..0874b792 100644 --- a/src/Controller/TAPI/BatteryController.php +++ b/src/Controller/TAPI/BatteryController.php @@ -45,7 +45,8 @@ class BatteryController extends APIController // batteries $batt_list = []; - $batts = $vehicle->getBatteries(); + // $batts = $vehicle->getBatteries(); + $batts = $vehicle->getActiveBatteries(); foreach ($batts as $batt) { // TODO: Add warranty_tnv to battery information diff --git a/src/Controller/VehicleController.php b/src/Controller/VehicleController.php index 7c388062..afe45fc5 100644 --- a/src/Controller/VehicleController.php +++ b/src/Controller/VehicleController.php @@ -485,7 +485,7 @@ class VehicleController extends Controller // get row data $em = $this->getDoctrine()->getManager(); $vobj = $em->getRepository(Vehicle::class)->find($req->request->get('vehicle_id')); - $all_batts = $em->getRepository(Battery::class)->findAll(); + $all_batts = $em->getRepository(Battery::class)->findBy(['flag_active' => true]); if (empty($vobj)) throw $this->createNotFoundException('The item does not exist'); @@ -495,19 +495,20 @@ class VehicleController extends Controller $battery_index = []; // get compatible batteries from selected manufacturer - foreach ($vobj->getBatteries() as $battery) + // foreach ($vobj->getBatteries() as $battery) + foreach ($vobj->getActiveBatteries() as $battery) { - $batteries[] = [ - 'id' => $battery->getID(), - 'mfg_name' => $battery->getManufacturer()->getName(), - 'model_name' => $battery->getModel()->getName(), - 'size_name' => $battery->getSize()->getName(), - 'prod_code' => $battery->getProductCode(), - 'sell_price' => $battery->getSellingPrice(), - 'warr_private' => $battery->getWarrantyPrivate(), - 'warr_commercial' => $battery->getWarrantyCommercial(), - ]; - $battery_index[$battery->getID()] = 1; + $batteries[] = [ + 'id' => $battery->getID(), + 'mfg_name' => $battery->getManufacturer()->getName(), + 'model_name' => $battery->getModel()->getName(), + 'size_name' => $battery->getSize()->getName(), + 'prod_code' => $battery->getProductCode(), + 'sell_price' => $battery->getSellingPrice(), + 'warr_private' => $battery->getWarrantyPrivate(), + 'warr_commercial' => $battery->getWarrantyCommercial(), + ]; + $battery_index[$battery->getID()] = 1; } // add all other batteries, because they want options diff --git a/src/Entity/Battery.php b/src/Entity/Battery.php index 8adf4f65..89104bcf 100644 --- a/src/Entity/Battery.php +++ b/src/Entity/Battery.php @@ -147,6 +147,12 @@ class Battery */ protected $image_file; + // flag if battery is active + /** + * @ORM\Column(type="boolean", options={"default": true}) + */ + protected $flag_active; + public function __construct() { $this->vehicles = new ArrayCollection(); @@ -159,6 +165,8 @@ class Battery $this->total_height = 0; $this->date_create = new DateTime(); + + $this->flag_active = true; } public function getID() @@ -382,4 +390,15 @@ class Battery { return $this->image_file; } + + public function isActive() + { + return $this->flag_active; + } + + public function setActive($flag_active = true) + { + $this->flag_active = $flag_active; + return $this; + } } diff --git a/src/Entity/Vehicle.php b/src/Entity/Vehicle.php index 61fdcec9..97a35da4 100644 --- a/src/Entity/Vehicle.php +++ b/src/Entity/Vehicle.php @@ -4,6 +4,8 @@ namespace App\Entity; use Doctrine\ORM\Mapping as ORM; use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Criteria; + use Symfony\Component\Validator\Constraints as Assert; /** @@ -177,4 +179,12 @@ class Vehicle { return $this->cust_vehicles; } + + public function getActiveBatteries() + { + $crit = Criteria::create(); + $crit->where(Criteria::expr()->eq('flag_active', true)); + + return $this->batteries->matching($crit); + } } diff --git a/src/Service/JobOrderHandler/ResqJobOrderHandler.php b/src/Service/JobOrderHandler/ResqJobOrderHandler.php index 5f88b057..9a9a44a5 100644 --- a/src/Service/JobOrderHandler/ResqJobOrderHandler.php +++ b/src/Service/JobOrderHandler/ResqJobOrderHandler.php @@ -1660,6 +1660,11 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface // validated! save the entity $em->persist($obj); $em->flush(); + + // check if hub has valid mobile number + $phone_number = $this->country_code . $hub->getNotifNumber(); + if (!empty($phone_number)) + $this->sendSMSHubRejection($phone_number, $obj, $jo); } return $error_array; @@ -2404,9 +2409,19 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface $hub['distance'] = false; } + // get rider counts + $rider_counts = $this->getHubRiderCounts($hub['hub']); + // counters - $hub['rider_count'] = count($hub['hub']->getAvailableRiders()); + // get only the active riders for the total rider count per hub + // $hub['rider_count'] = count($hub['hub']->getAvailableRiders()); + $hub['rider_count'] = count($hub['hub']->getActiveRiders()); $hub['redis_jo_count'] = $hub['jo_count']; + + $hub['rider_logged_in'] = $rider_counts['logged_in']; + $hub['rider_in_transit'] = $rider_counts['in_transit']; + $hub['rider_available'] = $rider_counts['available']; + //$hub['redis_jo_count'] = 0; // $hub['jo_count'] = count($hub['hub']->getForAssignmentJobOrders()); $hub['jo_count'] = $hub['redis_jo_count']; @@ -2553,6 +2568,10 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface $this->fillDropdownParameters($params); $this->fillFormTags($params); + // get the rider data to display for table + $rider_data = $this->getRiderDataForAssignment($obj); + $params['rider_data'] = $rider_data; + // get template to display $params['template'] = $this->getTwigTemplate('jo_assigning_form'); $params['obj'] = $obj; @@ -2715,10 +2734,20 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface $hub['distance'] = false; } + // get rider counts + $rider_counts = $this->getHubRiderCounts($hub['hub']); + // counters - $hub['rider_count'] = count($hub['hub']->getAvailableRiders()); + // get only the active riders for the total rider count per hub + // $hub['rider_count'] = count($hub['hub']->getAvailableRiders()); + $hub['rider_count'] = count($hub['hub']->getActiveRiders()); // $hub['redis_jo_count'] = $hub['jo_count']; $hub['redis_jo_count'] = 0; + + $hub['rider_logged_in'] = $rider_counts['logged_in']; + $hub['rider_in_transit'] = $rider_counts['in_transit']; + $hub['rider_available'] = $rider_counts['available']; + // $hub['jo_count'] = count($hub['hub']->getForAssignmentJobOrders()); $hub['jo_count'] = $hub['redis_jo_count']; @@ -2818,6 +2847,10 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface $this->fillDropdownParameters($params); $this->fillFormTags($params); + // get the rider data to display for table + $rider_data = $this->getRiderDataForAssignment($obj); + $params['rider_data'] = $rider_data; + $params['obj'] = $obj; $params['status_cancelled'] = JOStatus::CANCELLED; // get template to display @@ -3273,6 +3306,34 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface return false; } + protected function getHubRiderCounts($hub) + { + $em = $this->em; + + $hub_id = $hub->getID(); + + // get in transit rider count aka flag_available is false AND current_jo_id is not null AND rider is active + $in_transit_query = $em->createQuery('SELECT count(r.id) FROM App\Entity\Rider r JOIN r.hub h WHERE h.id = :hub_id AND r.flag_available = false AND r.current_job_order IS NOT NULL AND r.flag_active = true'); + $in_transit_query->setParameters(['hub_id' => $hub_id]); + $in_transit_count = $in_transit_query->getSingleScalarResult(); + + // get available rider count aka flag_available is true AND current_jo_id is null AND rider is active + $available_query = $em->createQuery('SELECT count(r.id) FROM App\Entity\Rider r JOIN r.hub h WHERE h.id = :hub_id AND r.flag_available = true AND r.current_job_order IS NULL AND r.flag_active = true'); + $available_query->setParameters(['hub_id' => $hub_id]); + $available_count = $available_query->getSingleScalarResult(); + + // on duty count = in transit + available + $logged_in_count = $in_transit_count + $available_count; + + $rider_count = [ + 'logged_in' => $logged_in_count, + 'in_transit' => $in_transit_count, + 'available' => $available_count, + ]; + + return $rider_count; + } + protected function fillDropdownParameters(&$params) { $em = $this->em; @@ -3495,6 +3556,49 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface ]; } + protected function getRiderDataForAssignment($obj) + { + $hub = $obj->getHub(); + + $rider_data = []; + + // get all active riders of hub + $active_riders = $hub->getActiveRiders(); + + // need to get first name, last name, contact number, plate number, status, image file + // status: Online (rider is logged in app), Offline (rider is not logged in app), In transit + + foreach ($active_riders as $rider) + { + // in transit - flag_available = 0 AND current_job_order is not null + // online - flag_available = 1 + // offline - flag_available = 0 AND current_job_order is null + $rider_status = ''; + + if ($rider->isAvailable()) + { + $rider_status = 'Online'; + } + else + { + if ($rider->getCurrentJobOrder() == null) + $rider_status = 'Offline'; + else + $rider_status = 'In transit'; + } + + $rider_data[$rider->getID()] = [ + 'first_name' => $rider->getFirstName(), + 'last_name' => $rider->getLastName(), + 'contact_number' => $rider->getContactNumber(), + 'plate_number' => $rider->getPlateNumber(), + 'image_file' => $rider->getImageFile(), + 'status' => $rider_status, + ]; + } + return $rider_data; + } + // 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) @@ -3909,4 +4013,38 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface $this->rt->sendSMS($phone_number, $this->translator->trans('message.battery_brand_allcaps'), $message); } + protected function sendSMSHubRejection($phone_number, $rejection, $jo) + { + // sms content + // Job Order # - can get from jo + // Order Date and Time - get from jo + // Date and Time Rejected - get from rejection + // Enrollee Name - get from rejection ($hub->getName() . ' - ' . $hub->getBranch()) + // Reason of Rejection - get from rejection + // Remarks - get from rejection + // Type of Service - get from jo + + $hub = $rejection->getHub(); + $jo_id = $jo->getID(); + + // convert to string format the date fields (order date and time and date and time rejected) + $order_date_time = $jo->getDateCreate()->format('d M Y g:i A'); + $reject_date_time = $rejection->getDateCreate()->format('d M Y g:i A'); + + $enrollee = $hub->getName() . ' - ' . $hub->getBranch(); + $reason = JORejectionReason::getName($rejection->getReason()); + $remarks = $rejection->getRemarks(); + + $service_type = ServiceType::getName($jo->getServiceType()); + + $msg = 'Job Order #: ' . $jo_id . "\n" . 'Order Date and Time: ' . $order_date_time . "\n" . + 'Date and Time Rejected: ' . $reject_date_time . "\n" . 'Enrollee Name: ' . $enrollee . "\n" . + 'Reason of Rejection: ' . $reason . "\n" . 'Remarks: ' . $remarks . "\n" . + 'Type of Service: ' . $service_type; + + // error_log($msg); + + $this->rt->sendSMS($phone_number, $this->translator->trans('message.battery_brand_allcaps'), $msg); + } + } diff --git a/src/Service/RiderAPIHandler/ResqRiderAPIHandler.php b/src/Service/RiderAPIHandler/ResqRiderAPIHandler.php index 5cc903c9..a543f39d 100644 --- a/src/Service/RiderAPIHandler/ResqRiderAPIHandler.php +++ b/src/Service/RiderAPIHandler/ResqRiderAPIHandler.php @@ -714,7 +714,7 @@ class ResqRiderAPIHandler implements RiderAPIHandlerInterface if (isset($data['error'])) return $data; - $batts = $this->em->getRepository(Battery::class)->findAll(); + $batts = $this->em->getRepository(Battery::class)->findBy(['flag_active' => true]); $models = $this->em->getRepository(BatteryModel::class)->findAll(); $sizes = $this->em->getRepository(BatterySize::class)->findAll(); diff --git a/templates/battery/form.html.twig b/templates/battery/form.html.twig index 53adb693..4ac05437 100644 --- a/templates/battery/form.html.twig +++ b/templates/battery/form.html.twig @@ -101,6 +101,20 @@
+
+
+ + + + +
+
+
+
-
- - -
- - - - - - - - - - - - - {% set avail_riders = obj.getHub.getAvailableRiders|default([]) %} - - - +
+ + +
+
First NameLast NameContact No.Plate NumberStatus
- No riders available. -
+ + + + + + + + + + + + + {% if obj.getHub %} + {% for key, data in rider_data %} + + + + + + + + + {% endfor %} + {% endif %} + +
First NameLast NameContact No.Plate NumberStatus
+
+
{{ data['first_name'] }} {{ data['last_name'] }} {{ data['contact_number'] }} {{ data['plate_number'] }} {{ data['status'] }}
+
+
+
{% endif %} diff --git a/templates/vehicle/form.html.twig b/templates/vehicle/form.html.twig index 09bee95f..99ecbc0f 100644 --- a/templates/vehicle/form.html.twig +++ b/templates/vehicle/form.html.twig @@ -233,13 +233,13 @@ $(function() { var batteryIds = []; var battMfgModelSize = [] - {% for batt in obj.getBatteries %} + {% for batt in obj.getActiveBatteries %} trow = { id: "{{ batt.getID }}", manufacturer: "{{ batt.getManufacturer.getName|default('') }} ", model: "{{ batt.getModel.getName|default('') }}", size: "{{ batt.getSize.getName|default('') }}", - sell_price: "{{ batt.getSellingPrice }}" + sell_price: "{{ batt.getSellingPrice }}", }; battRows.push(trow);