diff --git a/initial_sql/sql_insert_service_charge_data.sql b/initial_sql/sql_insert_service_charge_data.sql new file mode 100644 index 00000000..bab3fdf5 --- /dev/null +++ b/initial_sql/sql_insert_service_charge_data.sql @@ -0,0 +1 @@ +INSERT INTO `service_charge` VALUES(1,'Bangi',20),(2,'Banting',30),(3,'Bdr Saujana Utama',20),(4,'Bdr Seri Coalfields',30),(5,'Bdr Baru Bangi',20),(6,'Bdr Saujana Putra',20),(7,'Bukit Beruntung',30),(8,'Cyberjaya',20),(9,'Dengkil',30),(10,'Hulu Langat',20),(11,'Jenjarom',30),(12,'Klia',30),(13,'Meru',20),(14,'Port Klang',20),(15,'Pulau Indah',30),(16,'Puncak Alam',20),(17,'Putrajaya',20),(18,'Rawang',30),(19,'Salak Tinggi',30),(20,'Semenyih',20),(21,'Sepang',30),(22,'Serendah',30),(23,'Sungai Buloh',20),(24,'Teluk Panglima Garang',30),(25,'Uitm Puncak Alam',20),(26,'12am - 7am',10),(27,'Out of define Klg Valley',20),(28,'Airport',35),(29,'Jump start',50),(30,'Product warranty service charge - existing BA customer',20),(31,'Product warranty service charge - non BA customer',40); diff --git a/src/Controller/JobOrderController.php b/src/Controller/JobOrderController.php index d50471fe..c06383c7 100644 --- a/src/Controller/JobOrderController.php +++ b/src/Controller/JobOrderController.php @@ -694,6 +694,7 @@ class JobOrderController extends Controller $items = $req->request->get('items'); $promo_id = $req->request->get('promo'); $cvid = $req->request->get('cvid'); + $service_charges = $req->request->get('service_charges'); $em = $this->getDoctrine()->getManager(); @@ -740,6 +741,9 @@ class JobOrderController extends Controller // TODO: this snippet should be in the invoice generator $error = $ic->validateDiscount($criteria, $promo_id); + // process service charges + $error = $ic->invoiceServiceCharges($criteria, $service_charges); + if (!$error) $error = $ic->invoiceBatteries($criteria, $items); diff --git a/src/Entity/JobOrder.php b/src/Entity/JobOrder.php index 08a1f15a..8484ac8d 100644 --- a/src/Entity/JobOrder.php +++ b/src/Entity/JobOrder.php @@ -821,4 +821,5 @@ class JobOrder { return $this->meta[$id]; } + } diff --git a/src/Entity/ServiceCharge.php b/src/Entity/ServiceCharge.php new file mode 100644 index 00000000..8ba224cf --- /dev/null +++ b/src/Entity/ServiceCharge.php @@ -0,0 +1,64 @@ +amount = 0; + } + + public function getID() + { + return $this->id; + } + + public function setName($name) + { + $this->name = $name; + return $this; + } + + public function getName() + { + return $this->name; + } + + public function setAmount($amount) + { + $this->amount = $amount; + return $this; + } + + public function getAmount() + { + return $this->amount; + } +} diff --git a/src/Ramcar/InvoiceCriteria.php b/src/Ramcar/InvoiceCriteria.php index 49290e33..6665226d 100644 --- a/src/Ramcar/InvoiceCriteria.php +++ b/src/Ramcar/InvoiceCriteria.php @@ -5,6 +5,7 @@ namespace App\Ramcar; use App\Entity\Battery; use App\Entity\Promo; use App\Entity\CustomerVehicle; +use App\Entity\ServiceCharge; class InvoiceCriteria { @@ -13,6 +14,7 @@ class InvoiceCriteria protected $cv; protected $flag_coolant; protected $discount; + protected $service_charges; // entries are battery and trade-in combos protected $entries; @@ -25,6 +27,7 @@ class InvoiceCriteria $this->cv = null; $this->flag_coolant = false; $this->discount = 0; + $this->service_charges = []; } public function setServiceType($stype) @@ -138,4 +141,16 @@ class InvoiceCriteria { return $this->discount; } + + public function addServiceCharge(ServiceCharge $service_charge) + { + $this->service_charges[] = $service_charge; + return $this; + } + + public function getServiceCharges() + { + return $this->service_charges; + } + } diff --git a/src/Service/InvoiceGenerator/CMBInvoiceGenerator.php b/src/Service/InvoiceGenerator/CMBInvoiceGenerator.php index 73f4524e..cc1cb020 100644 --- a/src/Service/InvoiceGenerator/CMBInvoiceGenerator.php +++ b/src/Service/InvoiceGenerator/CMBInvoiceGenerator.php @@ -18,6 +18,7 @@ use App\Entity\Invoice; use App\Entity\InvoiceItem; use App\Entity\Battery; use App\Entity\User; +use App\Entity\ServiceCharge; use App\Service\InvoiceGeneratorInterface; @@ -105,6 +106,13 @@ class CMBInvoiceGenerator implements InvoiceGeneratorInterface // break; } + // process service charges if any + $service_charges = $criteria->getServiceCharges(); + if (count($service_charges) > 0) + { + $this->processServiceCharges($total, $criteria, $invoice); + } + // get current user $user = $this->security->getUser(); if ($user != null) @@ -126,7 +134,7 @@ class CMBInvoiceGenerator implements InvoiceGeneratorInterface } // generate invoice criteria - public function generateInvoiceCriteria($jo, $promo_id, $invoice_items, &$error_array) + public function generateInvoiceCriteria($jo, $discount, $invoice_items, &$error_array) { $em = $this->em; @@ -135,7 +143,6 @@ class CMBInvoiceGenerator implements InvoiceGeneratorInterface $criteria->setServiceType($jo->getServiceType()) ->setCustomerVehicle($jo->getCustomerVehicle()); - $discount = $promo_id; $ierror = $this->validateDiscount($criteria, $discount); if (!$ierror && !empty($invoice_items)) @@ -154,11 +161,19 @@ class CMBInvoiceGenerator implements InvoiceGeneratorInterface $ierror = $this->invoiceBatteries($criteria, $invoice_items); } + // get the meta for service charges + $service_charges = $jo->getMeta('service_charges'); + if (!empty($service_charges)) + { + $service_charges = $jo->getMeta('service_charges'); + + $this->invoiceServiceCharges($criteria, $service_charges); + } + if ($ierror) { $error_array['invoice'] = $ierror; } - else { // generate the invoice @@ -287,6 +302,28 @@ class CMBInvoiceGenerator implements InvoiceGeneratorInterface return null; } + public function invoiceServiceCharges(InvoiceCriteria $criteria, $service_charges) + { + if (!empty($service_charges)) + { + foreach ($service_charges as $service_charge) + { + // check if valid service charge + $sc = $this->em->getRepository(ServiceCharge::class)->find($service_charge['id']); + + if (empty($sc)) + { + $error = 'Invalid service charge specified.'; + return $error; + } + + $criteria->addServiceCharge($sc); + } + } + + return null; + } + protected function processEntries(&$total, InvoiceCriteria $criteria, Invoice $invoice) { @@ -605,4 +642,24 @@ class CMBInvoiceGenerator implements InvoiceGeneratorInterface $total['vat'] = $vat; } + protected function processServiceCharges(&$total, InvoiceCriteria $criteria, Invoice $invoice) + { + $service_charges = $criteria->getServiceCharges(); + + foreach ($service_charges as $service_charge) + { + $amount = $service_charge->getAmount(); + $title = 'Service Charge - ' . $service_charge->getName(); + + $total['total_price'] += $amount; + // add item + $item = new InvoiceItem(); + $item->setInvoice($invoice) + ->setTitle($title) + ->setQuantity(1) + ->setPrice($amount); + + $invoice->addItem($item); + } + } } diff --git a/src/Service/JobOrderHandler/CMBJobOrderHandler.php b/src/Service/JobOrderHandler/CMBJobOrderHandler.php index cfdab814..36062f7e 100644 --- a/src/Service/JobOrderHandler/CMBJobOrderHandler.php +++ b/src/Service/JobOrderHandler/CMBJobOrderHandler.php @@ -26,6 +26,7 @@ use App\Entity\Rider; use App\Entity\JORejection; use App\Entity\Warranty; use App\Entity\Customer; +use App\Entity\ServiceCharge; use App\Ramcar\InvoiceCriteria; use App\Ramcar\CMBServiceType; @@ -351,13 +352,13 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // call service to generate job order and invoice $invoice_items = $req->request->get('invoice_items', []); - $promo_id = $req->request->get('invoice_promo'); + $discount = $req->request->get('invoice_discount'); $invoice_change = $req->request->get('invoice_change', 0); // check if invoice changed if ($invoice_change) { - $this->ic->generateInvoiceCriteria($jo, $promo_id, $invoice_items, $error_array); + $this->ic->generateInvoiceCriteria($jo, $discount, $invoice_items, $error_array); } // validate @@ -523,11 +524,14 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface } // get discount and set to meta - $discount = $req->request->get('invoice_promo'); + $discount = $req->request->get('invoice_discount', []); // check if discount is greater than 50 or negative number if (($discount > 50) || ($discount < 0)) - $error_array['invoice_promo'] = 'Invalid discount specified'; + $error_array['invoice_discount'] = 'Invalid discount specified'; + + // get list of service charges + $service_charges = $req->request->get('service_charges', []); if (empty($error_array)) { @@ -559,6 +563,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface ->setRider($rider); $jo->addMeta('discount', $discount); + $jo->addMeta('service_charges', $service_charges); // check if user is null, meaning call to create came from API if ($user != null) @@ -580,13 +585,13 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // call service to generate job order and invoice $invoice_items = $req->request->get('invoice_items', []); - $promo_id = $req->request->get('invoice_promo'); + $discount = $req->request->get('invoice_discount'); $invoice_change = $req->request->get('invoice_change', 0); // check if invoice changed if ($invoice_change) { - $this->ic->generateInvoiceCriteria($jo, $promo_id, $invoice_items, $error_array); + $this->ic->generateInvoiceCriteria($jo, $discount, $invoice_items, $error_array); } // validate @@ -1402,6 +1407,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface $params['mode'] = 'onestep-edit'; $params['cvid'] = $obj->getCustomerVehicle()->getID(); $params['vid'] = $obj->getCustomerVehicle()->getVehicle()->getID(); + $params['jo_service_charges'] = $obj->getMeta('service_charges'); $this->fillDropdownParameters($params); $this->fillFormTags($params); @@ -2498,11 +2504,11 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface } // get discount and set to meta - $discount = $req->request->get('invoice_promo'); + $discount = $req->request->get('invoice_discount'); // check if discount is greater than 50 or negative number if (($discount > 50) || ($discount < 0)) - $error_array['invoice_promo'] = 'Invalid discount specified'; + $error_array['invoice_discount'] = 'Invalid discount specified'; if (empty($error_array)) { @@ -2551,13 +2557,13 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // call service to generate job order and invoice $invoice_items = $req->request->get('invoice_items', []); - $promo_id = $req->request->get('invoice_promo'); + $discount = $req->request->get('invoice_discount'); $invoice_change = $req->request->get('invoice_change', 0); // check if invoice changed if ($invoice_change) { - $this->ic->generateInvoiceCriteria($jo, $promo_id, $invoice_items, $error_array); + $this->ic->generateInvoiceCriteria($jo, $discount, $invoice_items, $error_array); } // validate @@ -2674,6 +2680,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // db loaded $params['bmfgs'] = $em->getRepository(BatteryManufacturer::class)->findAll(); $params['promos'] = $em->getRepository(Promo::class)->findAll(); + $params['service_charges'] = $em->getRepository(ServiceCharge::class)->findAll(); // list of hubs $hubs = $em->getRepository(Hub::class)->findBy([], ['name' => 'ASC']); diff --git a/templates/job-order/cmb.form.onestep.html.twig b/templates/job-order/cmb.form.onestep.html.twig index 34fe7af4..d58b707a 100644 --- a/templates/job-order/cmb.form.onestep.html.twig +++ b/templates/job-order/cmb.form.onestep.html.twig @@ -477,6 +477,40 @@ +
+
+
+

+ Service Charges +

+
+
+
+ +
+
+ + {% for jo_sc_key, jo_sc in jo_service_charges %} +
+
+
+ +
+
+
+ +
+
+ +
+
+ {% endfor %} +
+
@@ -498,12 +532,12 @@
- + {% if ftags.invoice_edit %} - - + + {% else %} - + {% endif %}
@@ -960,6 +994,9 @@ $(function() { // add invoice items to data fields['invoice_items'] = invoiceItems; + // add service charges to data + fields['service_charges'] = sc_array; + {% if mode in ['update-processing', 'update-reassign-hub'] %} // add selected hub to data fields['hub'] = selectedHub; @@ -1267,6 +1304,7 @@ $(function() { }); var invoiceItems = []; + var sc_array = []; // populate invoiceItems if editing so that we don't lose the battery {% if mode in ['open-edit', 'onestep-edit', 'walk-in-edit'] %} @@ -1322,7 +1360,7 @@ $(function() { }); // update invoice when promo is changed - $("#invoice-promo").change(function() { + $("#invoice-discount").change(function() { generateInvoice(); }); @@ -1333,8 +1371,9 @@ $(function() { // reset the invoice table $("#btn-reset-invoice").click(function() { - $("#invoice-promo").prop('selectedIndex', 0); + $("#invoice-discount").prop('selectedIndex', 0); invoiceItems = []; + sc_array = []; generateInvoice(); }); @@ -1343,29 +1382,34 @@ $(function() { generateInvoice(); }); - function generateInvoice() { - var promo = $("#invoice-promo").val(); - var table = $("#invoice-table tbody"); + function generateInvoice() { + var discount = $("#invoice-discount").val(); + var table = $("#invoice-table tbody"); var stype = $("#service_type").val(); var cvid = $("#customer-vehicle").val(); - // generate invoice values - $.ajax({ - method: "POST", - url: "{{ url('jo_gen_invoice') }}", - data: { + $.each(sc_array, function(index){ + console.log('generateInvoice ' + this.id); + }); + + // generate invoice values + $.ajax({ + method: "POST", + url: "{{ url('jo_gen_invoice') }}", + data: { 'stype': stype, - 'items': invoiceItems, - 'promo': promo, - 'cvid': cvid - } - }).done(function(response) { + 'items': invoiceItems, + 'promo': discount, + 'cvid': cvid, + 'service_charges': sc_array, + } + }).done(function(response) { // mark as invoice changed $("#invoice-change").val(1); - var invoice = response.invoice; + var invoice = response.invoice; // populate totals - $("#invoice-promo-discount").val(invoice.discount); + $("#invoice-discount").val(invoice.discount); $("#invoice-price").val(invoice.price); $("#invoice-trade-in").val(invoice.trade_in); $("#invoice-vat").val(invoice.vat); @@ -1607,6 +1651,78 @@ $(function() { }); }); }); + + // service charge add + $('#btn-sc-add').click(function(e) { + console.log('adding service charge'); + // add dropdown before the button + var html = '
'; + html += '
'; + html += '
'; + html += ''; + html += '
'; + html += '
'; + html += '
'; + html += ''; + html += '
'; + html += '
'; + html += ''; + html += '
'; + html += '
'; + + $('#sc-section').append(html); + + // clear the sc_array + sc_array.length = 0; + + // trigger change in select + $('#sc-section').find('.sc-select').last().change(); + return false; + }); + + // service charge remove + $('body').on('click', '.btn-sc-remove', function(e) { + console.log('removing service charge'); + + $(this).closest('.row').remove(); + + sc_array.length = 0; + + // get the service charges + $('.sc-select').each(function() { + var id = $(this).children('option:selected').val(); + sc_array.push({ + id: id, + }); + }); + + generateInvoice(); + + return false; + }); + + $('body').on('change', '.sc-select', function(e) { + var amount = $(this).children('option:selected').data('amount'); + $(this).closest('.row').find('.sc-amount').val(amount); + + // clear the sc_array + sc_array.length = 0; + + // get the service charges + $('.sc-select').each(function() { + var id = $(this).children('option:selected').val(); + sc_array.push({ + id: id, + }); + }); + + generateInvoice(); + }); + }); {% endblock %} diff --git a/templates/job-order/cmb.form.walkin.html.twig b/templates/job-order/cmb.form.walkin.html.twig index 8f764956..1a833e63 100644 --- a/templates/job-order/cmb.form.walkin.html.twig +++ b/templates/job-order/cmb.form.walkin.html.twig @@ -393,12 +393,12 @@
- + {% if ftags.invoice_edit %} - - + + {% else %} - + {% endif %}
@@ -936,8 +936,8 @@ var vdata = false; generateInvoice(); }); - // update invoice when promo is changed - $("#invoice-promo").change(function() { + // update invoice when discount is changed + $("#invoice-discount").change(function() { generateInvoice(); }); @@ -948,7 +948,7 @@ var vdata = false; // reset the invoice table $("#btn-reset-invoice").click(function() { - $("#invoice-promo").prop('selectedIndex', 0); + $("#invoice-discount").prop('selectedIndex', 0); invoiceItems = []; generateInvoice(); }); @@ -959,7 +959,7 @@ var vdata = false; }); function generateInvoice() { - var promo = $("#invoice-promo").val(); + var discount = $("#invoice-discount").val(); var table = $("#invoice-table tbody"); var stype = $("#service_type").val(); var cvid = $("#customer-vehicle").val(); @@ -971,7 +971,7 @@ var vdata = false; data: { 'stype': stype, 'items': invoiceItems, - 'promo': promo, + 'promo': discount, 'cvid': cvid } }).done(function(response) { @@ -980,7 +980,7 @@ var vdata = false; var invoice = response.invoice; // populate totals - $("#invoice-promo-discount").val(invoice.discount); + $("#invoice-discount").val(invoice.discount); $("#invoice-price").val(invoice.price); $("#invoice-trade-in").val(invoice.trade_in); $("#invoice-vat").val(invoice.vat);