diff --git a/config/routes/job_order.yaml b/config/routes/job_order.yaml index 3d8cb603..b1ac7872 100644 --- a/config/routes/job_order.yaml +++ b/config/routes/job_order.yaml @@ -8,11 +8,6 @@ jo_in_submit: controller: App\Controller\JobOrderController::incomingSubmit methods: [POST] -jo_in_invoice: - path: /job-order/generate-invoice - controller: App\Controller\JobOrderController::generateInvoice - methods: [POST] - jo_proc: path: /job-order/processing controller: App\Controller\JobOrderController::listRows @@ -59,4 +54,9 @@ jo_assign_form: jo_assign_submit: path: /job-order/assigning/{id} controller: App\Controller\JobOrderController::assigningSubmit + methods: [POST] + +jo_gen_invoice: + path: /job-order/generate-invoice + controller: App\Controller\JobOrderController::generateInvoice methods: [POST] \ No newline at end of file diff --git a/src/Controller/JobOrderController.php b/src/Controller/JobOrderController.php index 0d3e1a57..bab6eacb 100644 --- a/src/Controller/JobOrderController.php +++ b/src/Controller/JobOrderController.php @@ -7,6 +7,7 @@ use App\Ramcar\ServiceType; use App\Ramcar\JOStatus; use App\Ramcar\WarrantyClass; use App\Ramcar\DiscountApply; +use App\Ramcar\TradeInType; use App\Ramcar\InvoiceCriteria; use App\Entity\JobOrder; use App\Entity\BatteryManufacturer; @@ -15,6 +16,7 @@ use App\Entity\CustomerVehicle; use App\Entity\Outlet; use App\Entity\Promo; use App\Entity\Rider; +use App\Entity\Battery; use App\Service\InvoiceCreator; use App\Service\MapTools; @@ -50,6 +52,7 @@ class JobOrderController extends BaseController $params['warranty_classes'] = WarrantyClass::getCollection(); $params['statuses'] = JOStatus::getCollection(); $params['discount_apply'] = DiscountApply::getCollection(); + $params['trade_in_types'] = TradeInType::getCollection(); // response return $this->render('job-order/form.html.twig', $params); @@ -287,6 +290,7 @@ class JobOrderController extends BaseController $params['statuses'] = JOStatus::getCollection(); $params['promos'] = $em->getRepository(Promo::class)->findAll(); $params['discount_apply'] = DiscountApply::getCollection(); + $params['trade_in_types'] = TradeInType::getCollection(); // get closest outlets $outlets = $map_tools->getClosestOutlets($obj->getCoordinates(), 10, date("H:i:s")); @@ -426,6 +430,7 @@ class JobOrderController extends BaseController $params['statuses'] = JOStatus::getCollection(); $params['promos'] = $em->getRepository(Promo::class)->findAll(); $params['discount_apply'] = DiscountApply::getCollection(); + $params['trade_in_types'] = TradeInType::getCollection(); // get closest outlets $outlets = $map_tools->getClosestOutlets($obj->getCoordinates(), 10, date("H:i:s")); @@ -572,9 +577,85 @@ class JobOrderController extends BaseController public function generateInvoice(Request $req, InvoiceCreator $ic) { - // create new invoice object - $invoice = new InvoiceCriteria(); + $error = false; - //$invoice-> + $items = $req->request->get('items'); + $promo_id = $req->request->get('promo'); + + $em = $this->getDoctrine()->getManager(); + + // instantiate invoice criteria + $criteria = new InvoiceCriteria(); + + if (!empty($promo_id)) + { + // check if this is a valid promo + $promo = $em->getRepository(Promo::class)->find($promo_id); + + if (empty($promo)) + $error = 'Invalid promo specified.'; + else + $criteria->addPromo($promo); + } + + if (!$error) + { + foreach ($items as $item) + { + // check if this is a valid battery + $battery = $em->getRepository(Battery::class)->find($item['battery']); + + if (empty($battery)) + { + $error = 'Invalid battery specified.'; + break; + } + + // add to criteria + $criteria->addBattery($battery); + + // if this is a trade in, add trade in + if (!empty($item['trade_in']) && TradeInType::validate($item['trade_in'])) + $criteria->addTradeIn($item['trade_in'] == 'motolite' ? true : false); + } + } + + if ($error) + { + // something happened + return $this->json([ + 'success' => false, + 'error' => $error + ], 422); + } + + // generate the invoice + $iobj = $ic->processCriteria($criteria); + + // use invoice object values in a json friendly array + $invoice = [ + 'discount' => number_format($iobj->getDiscount(), 2), + 'trade_in' => number_format($iobj->getTradeIn(), 2), // TODO: computations not done yet for this on invoice creator + 'price' => number_format($iobj->getVATExclusivePrice(), 2), // TODO: computations not done yet for this on invoice creator + 'vat' => number_format($iobj->getVAT(), 2), + 'total_price' => number_format($iobj->getTotalPrice(), 2), + 'items' => [] + ]; + + foreach ($iobj->getItems() as $item) + { + $invoice['items'][] = [ + 'title' => $item->getTitle(), + 'quantity' => $item->getQuantity(), // TODO: quantities are always 1, hardcoded into InvoiceCreator. no way of accepting quantities on InvoiceCriteria + 'unit_price' => number_format($item->getPrice(), 2), + 'amount' => number_format($item->getPrice() * $item->getQuantity(), 2) // TODO: should this calculation should be a saved value on InvoiceItem instead? + ]; + } + + // return + return $this->json([ + 'success' => true, + 'invoice' => $invoice + ]); } } diff --git a/src/Entity/Invoice.php b/src/Entity/Invoice.php index e28a8f77..e92e9abf 100644 --- a/src/Entity/Invoice.php +++ b/src/Entity/Invoice.php @@ -1,6 +1,6 @@ discount; } + public function setTradeIn($trade_in) + { + $this->trade_in = $trade_in; + return $this; + } + + public function getTradeIn() + { + return $this->trade_in; + } + public function setVAT($vat) { $this->vat = $vat; @@ -182,6 +205,17 @@ class Invoice return $this->vat; } + public function setVATExclusivePrice($price) + { + $this->vat_exclusive_price = $price; + return $this; + } + + public function getVATExclusivePrice() + { + return $this->vat_exclusive_price; + } + public function setTotalPrice($price) { $this->total_price = $price; diff --git a/src/Entity/InvoiceItem.php b/src/Entity/InvoiceItem.php index 31fb887e..1ea66765 100644 --- a/src/Entity/InvoiceItem.php +++ b/src/Entity/InvoiceItem.php @@ -1,6 +1,6 @@ batteries; } - public function addPromo($promo) + public function addPromo(Promo $promo) { $this->promos[] = $promo; return $this; diff --git a/src/Ramcar/TradeInType.php b/src/Ramcar/TradeInType.php new file mode 100644 index 00000000..eeb559fa --- /dev/null +++ b/src/Ramcar/TradeInType.php @@ -0,0 +1,14 @@ + 'Motolite', + 'other' => 'Other', + ]; +} diff --git a/src/Service/InvoiceCreator.php b/src/Service/InvoiceCreator.php index bf5fdd00..b54635fd 100644 --- a/src/Service/InvoiceCreator.php +++ b/src/Service/InvoiceCreator.php @@ -35,9 +35,9 @@ class InvoiceCreator public function getTradeInRate($trade_in) { if ($trade_in == 'motolite') - return TIRATE_MOTOLITE; + return self::TIRATE_MOTOLITE; - return TIRATE_OTHER; + return self::TIRATE_OTHER; } public function processCriteria(InvoiceCriteria $criteria) @@ -71,9 +71,11 @@ class InvoiceCreator // add item $item = new InvoiceItem(); $item->setInvoice($invoice) - ->setTitle($batt->getModel() . ' ' . $batt->getSize()) + ->setTitle($batt->getModel()->getName() . ' ' . $batt->getSize()->getName()) ->setQuantity(1) ->setPrice($sell_price); + + $invoice->addItem($item); } // get trade-ins @@ -92,6 +94,8 @@ class InvoiceCreator ->setTitle('Trade-in battery') ->setQuantity(1) ->setPrice($ti_rate); + + $invoice->addItem($item); } // TODO: check if any promo is applied @@ -104,7 +108,7 @@ class InvoiceCreator // dump - Debug::dump($invoice, 1); + //Debug::dump($invoice, 1); return $invoice; } diff --git a/templates/job-order/form.html.twig b/templates/job-order/form.html.twig index 7c9e7166..32c94240 100644 --- a/templates/job-order/form.html.twig +++ b/templates/job-order/form.html.twig @@ -303,16 +303,14 @@