diff --git a/src/Service/InvoiceGenerator/CMBInvoiceGenerator.php b/src/Service/InvoiceGenerator/CMBInvoiceGenerator.php index 00f4cac3..cd08f2a6 100644 --- a/src/Service/InvoiceGenerator/CMBInvoiceGenerator.php +++ b/src/Service/InvoiceGenerator/CMBInvoiceGenerator.php @@ -3,6 +3,9 @@ namespace App\Service\InvoiceGenerator; use Symfony\Component\Security\Core\Security; +use Symfony\Component\Validator\Validator\ValidatorInterface; + +use Doctrine\ORM\EntityManagerInterface; use App\Ramcar\InvoiceCriteria; use App\Ramcar\InvoiceStatus; @@ -13,6 +16,8 @@ use App\Ramcar\FuelType; use App\Entity\Invoice; use App\Entity\InvoiceItem; +use App\Entity\Battery; +use App\Entity\Promo; use App\Entity\User; use App\Service\InvoiceGeneratorInterface; @@ -33,11 +38,16 @@ class CMBInvoiceGenerator implements InvoiceGeneratorInterface const REFUEL_FEE_DIESEL = 220; private $security; + protected $em; + protected $validator; // creates invoice based on the criteria sent - public function __construct(Security $security) + public function __construct(Security $security, EntityManagerInterface $em, + ValidatorInterface $validator) { $this->security = $security; + $this->em = $em; + $this->validator = $validator; } public function generateInvoice(InvoiceCriteria $criteria) @@ -121,6 +131,69 @@ class CMBInvoiceGenerator implements InvoiceGeneratorInterface return $invoice; } + // generate invoice criteria + public function generateInvoiceCriteria($jo, $promo_id, $invoice_items, &$error_array) + { + $em = $this->em; + + // instantiate the invoice criteria + $criteria = new InvoiceCriteria(); + $criteria->setServiceType($jo->getServiceType()) + ->setCustomerVehicle($jo->getCustomerVehicle()); + + $ierror = $this->invoicePromo($criteria, $promo_id); + + if (!$ierror && !empty($invoice_items)) + { + // check for trade-in so we can mark it for mobile app + foreach ($invoice_items as $item) + { + // get first trade-in + if (!empty($item['trade_in'])) + { + $jo->getTradeInType($item['trade_in']); + break; + } + } + + $ierror = $this->invoiceBatteries($criteria, $invoice_items); + } + + if ($ierror) + { + $error_array['invoice'] = $ierror; + } + + else + { + // generate the invoice + $iobj = $this->generateInvoice($criteria); + + // validate + $ierrors = $this->validator->validate($iobj); + + // add errors to list + foreach ($ierrors as $error) { + $error_array[$error->getPropertyPath()] = $error->getMessage(); + } + + // check if invoice already exists for JO + $old_invoice = $jo->getInvoice(); + if ($old_invoice != null) + { + // remove old invoice + $em->remove($old_invoice); + $em->flush(); + } + + // add invoice to JO + $jo->setInvoice($iobj); + + $em->persist($iobj); + + } + } + protected function getTaxAmount($price) { $vat_ex_price = $this->getTaxExclusivePrice($price); @@ -154,6 +227,75 @@ class CMBInvoiceGenerator implements InvoiceGeneratorInterface return 0; } + protected function invoicePromo(InvoiceCriteria $criteria, $promo_id) + { + // return error if there's a problem, false otherwise + // check service type + $stype = $criteria->getServiceType(); + if ($stype != ServiceType::BATTERY_REPLACEMENT_NEW) + return null; + + + if (empty($promo_id)) + { + return false; + } + + // check if this is a valid promo + $promo = $this->em->getRepository(Promo::class)->find($promo_id); + + if (empty($promo)) + return 'Invalid promo specified.'; + + $criteria->addPromo($promo); + return false; + } + + protected function invoiceBatteries(InvoiceCriteria $criteria, $items) + { + // check service type + $stype = $criteria->getServiceType(); + if ($stype != ServiceType::BATTERY_REPLACEMENT_NEW && $stype != ServiceType::BATTERY_REPLACEMENT_WARRANTY) + return null; + + // return error if there's a problem, false otherwise + if (!empty($items)) + { + foreach ($items as $item) + { + // check if this is a valid battery + $battery = $this->em->getRepository(Battery::class)->find($item['battery']); + + if (empty($battery)) + { + $error = 'Invalid battery specified.'; + return $error; + } + + // quantity + $qty = $item['quantity']; + if ($qty < 1) + continue; + + /* + // add to criteria + $criteria->addBattery($battery, $qty); + */ + + // if this is a trade in, add trade in + if (!empty($item['trade_in']) && TradeInType::validate($item['trade_in'])) + $trade_in = $item['trade_in']; + else + $trade_in = null; + + $criteria->addEntry($battery, $trade_in, $qty); + } + } + + return null; + } + + protected function processEntries(&$total, InvoiceCriteria $criteria, Invoice $invoice) { // error_log('processing entries...'); diff --git a/src/Service/InvoiceGenerator/ResqInvoiceGenerator.php b/src/Service/InvoiceGenerator/ResqInvoiceGenerator.php index ed363ddd..1eddd0a2 100644 --- a/src/Service/InvoiceGenerator/ResqInvoiceGenerator.php +++ b/src/Service/InvoiceGenerator/ResqInvoiceGenerator.php @@ -3,6 +3,9 @@ namespace App\Service\InvoiceGenerator; use Symfony\Component\Security\Core\Security; +use Symfony\Component\Validator\Validator\ValidatorInterface; + +use Doctrine\ORM\EntityManagerInterface; use App\Ramcar\InvoiceCriteria; use App\Ramcar\InvoiceStatus; @@ -33,11 +36,16 @@ class ResqInvoiceGenerator implements InvoiceGeneratorInterface const REFUEL_FEE_DIESEL = 220; private $security; + protected $em; + protected $validator; // creates invoice based on the criteria sent - public function __construct(Security $security) + public function __construct(Security $security, EntityManagerInterface $em, + ValidatorInterface $validator) { $this->security = $security; + $this->em = $em; + $this->validator = $validator; } public function generateInvoice(InvoiceCriteria $criteria) @@ -108,9 +116,6 @@ class ResqInvoiceGenerator implements InvoiceGeneratorInterface $invoice->setCreatedBy($user); } - // NOTE: we compute and save VAT up to the 2nd decimal place. - // it's only in the display when viewing a job order, where - // VAT is seen as a whole number. $invoice->setTotalPrice($total['total_price']) ->setVATExclusivePrice($total['vat_ex_price']) ->setVAT($total['vat']) @@ -124,6 +129,69 @@ class ResqInvoiceGenerator implements InvoiceGeneratorInterface return $invoice; } + // generate invoice criteria + public function generateInvoiceCriteria($jo, $promo_id, $invoice_items, &$error_array) + { + $em = $this->em; + + // instantiate the invoice criteria + $criteria = new InvoiceCriteria(); + $criteria->setServiceType($jo->getServiceType()) + ->setCustomerVehicle($jo->getCustomerVehicle()); + + $ierror = $this->invoicePromo($criteria, $promo_id); + + if (!$ierror && !empty($invoice_items)) + { + // check for trade-in so we can mark it for mobile app + foreach ($invoice_items as $item) + { + // get first trade-in + if (!empty($item['trade_in'])) + { + $jo->getTradeInType($item['trade_in']); + break; + } + } + + $ierror = $this->invoiceBatteries($criteria, $invoice_items); + } + + if ($ierror) + { + $error_array['invoice'] = $ierror; + } + + else + { + // generate the invoice + $iobj = $this->generateInvoice($criteria); + + // validate + $ierrors = $this->validator->validate($iobj); + + // add errors to list + foreach ($ierrors as $error) { + $error_array[$error->getPropertyPath()] = $error->getMessage(); + } + + // check if invoice already exists for JO + $old_invoice = $jo->getInvoice(); + if ($old_invoice != null) + { + // remove old invoice + $em->remove($old_invoice); + $em->flush(); + } + + // add invoice to JO + $jo->setInvoice($iobj); + + $em->persist($iobj); + + } + } + protected function getTaxAmount($price) { $vat_ex_price = $this->getTaxExclusivePrice($price); @@ -157,6 +225,75 @@ class ResqInvoiceGenerator implements InvoiceGeneratorInterface return 0; } + protected function invoicePromo(InvoiceCriteria $criteria, $promo_id) + { + // return error if there's a problem, false otherwise + // check service type + $stype = $criteria->getServiceType(); + if ($stype != ServiceType::BATTERY_REPLACEMENT_NEW) + return null; + + + if (empty($promo_id)) + { + return false; + } + + // check if this is a valid promo + $promo = $this->em->getRepository(Promo::class)->find($promo_id); + + if (empty($promo)) + return 'Invalid promo specified.'; + + $criteria->addPromo($promo); + return false; + } + + protected function invoiceBatteries(InvoiceCriteria $criteria, $items) + { + // check service type + $stype = $criteria->getServiceType(); + if ($stype != ServiceType::BATTERY_REPLACEMENT_NEW && $stype != ServiceType::BATTERY_REPLACEMENT_WARRANTY) + return null; + + // return error if there's a problem, false otherwise + if (!empty($items)) + { + foreach ($items as $item) + { + // check if this is a valid battery + $battery = $this->em->getRepository(Battery::class)->find($item['battery']); + + if (empty($battery)) + { + $error = 'Invalid battery specified.'; + return $error; + } + + // quantity + $qty = $item['quantity']; + if ($qty < 1) + continue; + + /* + // add to criteria + $criteria->addBattery($battery, $qty); + */ + + // if this is a trade in, add trade in + if (!empty($item['trade_in']) && TradeInType::validate($item['trade_in'])) + $trade_in = $item['trade_in']; + else + $trade_in = null; + + $criteria->addEntry($battery, $trade_in, $qty); + } + } + + return null; + } + + protected function processEntries(&$total, InvoiceCriteria $criteria, Invoice $invoice) { // error_log('processing entries...'); diff --git a/src/Service/InvoiceGeneratorInterface.php b/src/Service/InvoiceGeneratorInterface.php index b5fee76f..85407c30 100644 --- a/src/Service/InvoiceGeneratorInterface.php +++ b/src/Service/InvoiceGeneratorInterface.php @@ -3,6 +3,7 @@ namespace App\Service; use App\Entity\Invoice; +use App\Entity\JobOrder; use App\Ramcar\InvoiceCriteria; @@ -11,4 +12,7 @@ interface InvoiceGeneratorInterface // generate invoice using a criteria public function generateInvoice(InvoiceCriteria $criteria); + // generate invoice criteria + public function generateInvoiceCriteria(JobOrder $jo, int $promo_id, array $invoice_items, array &$error_array); + } diff --git a/src/Service/JobOrderHandler/CMBJobOrderHandler.php b/src/Service/JobOrderHandler/CMBJobOrderHandler.php index a7b8ba16..45975fc7 100644 --- a/src/Service/JobOrderHandler/CMBJobOrderHandler.php +++ b/src/Service/JobOrderHandler/CMBJobOrderHandler.php @@ -16,7 +16,6 @@ use Doctrine\DBAL\LockMode; use Doctrine\ORM\PessimisticLockException; use App\Entity\JobOrder; -use App\Entity\Battery; use App\Entity\BatteryManufacturer; use App\Entity\JOEvent; use App\Entity\CustomerVehicle; @@ -338,8 +337,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface // check if invoice changed if ($invoice_change) { - // TODO: move invoice processing to InvoiceGenerator - $this->processInvoice($jo, $promo_id, $invoice_items, $error_array); + $this->ic->generateInvoiceCriteria($jo, $promo_id, $invoice_items, $error_array); } // validate @@ -2154,134 +2152,4 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface ->setParameter('status', $status); } } - - // TODO: move this to InvoiceGenerator - protected function processInvoice($jo, $promo_id, $invoice_items, &$error_array) - { - // instantiate the invoice criteria - $criteria = new InvoiceCriteria(); - $criteria->setServiceType($jo->getServiceType()) - ->setCustomerVehicle($jo->getCustomerVehicle()); - - $ierror = $this->invoicePromo($criteria, $promo_id); - - if (!$ierror && !empty($invoice_items)) - { - // check for trade-in so we can mark it for mobile app - foreach ($invoice_items as $item) - { - // get first trade-in - if (!empty($item['trade_in'])) - { - $jo->getTradeInType($item['trade_in']); - break; - } - } - - $ierror = $this->invoiceBatteries($criteria, $invoice_items); - } - - if ($ierror) - { - $error_array['invoice'] = $ierror; - } - else - { - // generate the invoice - $iobj = $this->ic->generateInvoice($criteria); - - // validate - $ierrors = $this->validator->validate($iobj); - - // add errors to list - foreach ($ierrors as $error) { - $error_array[$error->getPropertyPath()] = $error->getMessage(); - } - - // check if invoice already exists for JO - $old_invoice = $jo->getInvoice(); - if ($old_invoice != null) - { - // remove old invoice - $this->em->remove($old_invoice); - $this->em->flush(); - } - - // add invoice to JO - $jo->setInvoice($iobj); - - $this->em->persist($iobj); - - } - } - - //TODO: move this to InvoiceGenerator - protected function invoicePromo(InvoiceCriteria $criteria, $promo_id) - { - // return error if there's a problem, false otherwise - // check service type - $stype = $criteria->getServiceType(); - if ($stype != ServiceType::BATTERY_REPLACEMENT_NEW) - return null; - - - if (empty($promo_id)) - { - return false; - } - - // check if this is a valid promo - $promo = $this->em->getRepository(Promo::class)->find($promo_id); - - if (empty($promo)) - return 'Invalid promo specified.'; - - $criteria->addPromo($promo); - return false; - } - - // TODO: move this to InvoiceGenerator - protected function invoiceBatteries(InvoiceCriteria $criteria, $items) - { - // check service type - $stype = $criteria->getServiceType(); - if ($stype != ServiceType::BATTERY_REPLACEMENT_NEW && $stype != ServiceType::BATTERY_REPLACEMENT_WARRANTY) - return null; - - // return error if there's a problem, false otherwise - if (!empty($items)) - { - foreach ($items as $item) - { - // check if this is a valid battery - $battery = $this->em->getRepository(Battery::class)->find($item['battery']); - - if (empty($battery)) - { - $error = 'Invalid battery specified.'; - return $error; - } - - // quantity - $qty = $item['quantity']; - if ($qty < 1) - continue; - - /* - // add to criteria - $criteria->addBattery($battery, $qty); - */ - - // if this is a trade in, add trade in - if (!empty($item['trade_in']) && TradeInType::validate($item['trade_in'])) - $trade_in = $item['trade_in']; - else - $trade_in = null; - - $criteria->addEntry($battery, $trade_in, $qty); - } - } - - return null; - } } diff --git a/src/Service/JobOrderHandler/ResqJobOrderHandler.php b/src/Service/JobOrderHandler/ResqJobOrderHandler.php index 1b926d84..1348c80d 100644 --- a/src/Service/JobOrderHandler/ResqJobOrderHandler.php +++ b/src/Service/JobOrderHandler/ResqJobOrderHandler.php @@ -16,7 +16,6 @@ use Doctrine\DBAL\LockMode; use Doctrine\ORM\PessimisticLockException; use App\Entity\JobOrder; -use App\Entity\Battery; use App\Entity\BatteryManufacturer; use App\Entity\JOEvent; use App\Entity\CustomerVehicle; @@ -338,8 +337,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface // check if invoice changed if ($invoice_change) { - // TODO: move invoice processing to InvoiceGenerator - $this->processInvoice($jo, $promo_id, $invoice_items, $error_array); + $this->ic->generateInvoiceCriteria($jo, $promo_id, $invoice_items, $error_array); } // validate @@ -2154,134 +2152,4 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface ->setParameter('status', $status); } } - - // TODO: move this to InvoiceGenerator - protected function processInvoice($jo, $promo_id, $invoice_items, &$error_array) - { - // instantiate the invoice criteria - $criteria = new InvoiceCriteria(); - $criteria->setServiceType($jo->getServiceType()) - ->setCustomerVehicle($jo->getCustomerVehicle()); - - $ierror = $this->invoicePromo($criteria, $promo_id); - - if (!$ierror && !empty($invoice_items)) - { - // check for trade-in so we can mark it for mobile app - foreach ($invoice_items as $item) - { - // get first trade-in - if (!empty($item['trade_in'])) - { - $jo->getTradeInType($item['trade_in']); - break; - } - } - - $ierror = $this->invoiceBatteries($criteria, $invoice_items); - } - - if ($ierror) - { - $error_array['invoice'] = $ierror; - } - else - { - // generate the invoice - $iobj = $this->ic->generateInvoice($criteria); - - // validate - $ierrors = $this->validator->validate($iobj); - - // add errors to list - foreach ($ierrors as $error) { - $error_array[$error->getPropertyPath()] = $error->getMessage(); - } - - // check if invoice already exists for JO - $old_invoice = $jo->getInvoice(); - if ($old_invoice != null) - { - // remove old invoice - $this->em->remove($old_invoice); - $this->em->flush(); - } - - // add invoice to JO - $jo->setInvoice($iobj); - - $this->em->persist($iobj); - - } - } - - //TODO: move this to InvoiceGenerator - protected function invoicePromo(InvoiceCriteria $criteria, $promo_id) - { - // return error if there's a problem, false otherwise - // check service type - $stype = $criteria->getServiceType(); - if ($stype != ServiceType::BATTERY_REPLACEMENT_NEW) - return null; - - - if (empty($promo_id)) - { - return false; - } - - // check if this is a valid promo - $promo = $this->em->getRepository(Promo::class)->find($promo_id); - - if (empty($promo)) - return 'Invalid promo specified.'; - - $criteria->addPromo($promo); - return false; - } - - // TODO: move this to InvoiceGenerator - protected function invoiceBatteries(InvoiceCriteria $criteria, $items) - { - // check service type - $stype = $criteria->getServiceType(); - if ($stype != ServiceType::BATTERY_REPLACEMENT_NEW && $stype != ServiceType::BATTERY_REPLACEMENT_WARRANTY) - return null; - - // return error if there's a problem, false otherwise - if (!empty($items)) - { - foreach ($items as $item) - { - // check if this is a valid battery - $battery = $this->em->getRepository(Battery::class)->find($item['battery']); - - if (empty($battery)) - { - $error = 'Invalid battery specified.'; - return $error; - } - - // quantity - $qty = $item['quantity']; - if ($qty < 1) - continue; - - /* - // add to criteria - $criteria->addBattery($battery, $qty); - */ - - // if this is a trade in, add trade in - if (!empty($item['trade_in']) && TradeInType::validate($item['trade_in'])) - $trade_in = $item['trade_in']; - else - $trade_in = null; - - $criteria->addEntry($battery, $trade_in, $qty); - } - } - - return null; - } }