diff --git a/src/Invoice/ServiceType.php b/src/Invoice/ServiceType.php new file mode 100644 index 00000000..e27f2bc6 --- /dev/null +++ b/src/Invoice/ServiceType.php @@ -0,0 +1,26 @@ +getServiceType()) + return true; + } + + return false; + } + + public function getTemplate() + { + return 'invoice/service_type.html.twig'; + } +} diff --git a/src/InvoiceCriteria.php b/src/InvoiceCriteria.php new file mode 100644 index 00000000..886d6024 --- /dev/null +++ b/src/InvoiceCriteria.php @@ -0,0 +1,169 @@ +stype = 0; + $this->promos = []; + $this->entries = []; + $this->cv = null; + $this->flag_coolant = false; + $this->discount = 0; + $this->service_charges = []; + $this->flag_taxable = false; + } + + public function setServiceType($stype) + { + // TODO: validate service type + $this->stype = $stype; + return $this; + } + + public function getServiceType() + { + return $this->stype; + } + + /* + public function addBattery(Battery $battery, $qty = 1) + { + for ($i = 0; $i < $qty; $i++) + $this->batteries[] = $battery; + return $this; + } + + public function getBatteries() + { + return $this->batteries; + } + */ + + public function addPromo(Promo $promo) + { + $this->promos[] = $promo; + return $this; + } + + public function getPromos() + { + return $this->promos; + } + + /* + public function addTradeIn($is_motolite, $qty = 1) + { + // NOTE: this asumes that all the rates for trade-ins are standardized + // for motolite and non-motolite trade-ins + + for ($i = 0; $i < $qty; $i++) + { + if ($is_motolite) + $trade_in = 'motolite'; + else + $trade_in = 'other'; + + $this->trade_ins[] = $trade_in; + } + return $this; + } + + public function getTradeIns() + { + return $this->trade_ins; + } + */ + + public function addEntry($battery, $trade_in, $qty) + { + // trade_in is null if no trade_in specified + + $entry = [ + 'battery' => $battery, + 'trade_in' => $trade_in, + 'qty' => $qty + ]; + + $this->entries[] = $entry; + } + + public function getEntries() + { + return $this->entries; + } + + public function setCustomerVehicle(CustomerVehicle $cv = null) + { + $this->cv = $cv; + return $this; + } + + public function getCustomerVehicle() + { + return $this->cv; + } + + public function setHasCoolant($flag = true) + { + $this->flag_coolant = $flag; + return $this; + } + + public function hasCoolant() + { + return $this->flag_coolant; + } + + public function setDiscount($discount) + { + $this->discount = $discount; + return $this; + } + + public function getDiscount() + { + return $this->discount; + } + + public function addServiceCharge(ServiceCharge $service_charge) + { + $this->service_charges[] = $service_charge; + return $this; + } + + public function getServiceCharges() + { + return $this->service_charges; + } + + public function setIsTaxable($flag = true) + { + $this->flag_taxable = $flag; + return $this; + } + + public function isTaxable() + { + return $this->flag_taxable; + } + +} diff --git a/src/InvoiceInterface.php b/src/InvoiceInterface.php new file mode 100644 index 00000000..704e4e46 --- /dev/null +++ b/src/InvoiceInterface.php @@ -0,0 +1,12 @@ +getSellingPrice(); - - $computed_price = bcmul($sell_price, $qty, 2); - $invoice_batteries = [ - 'title' => $battery->getModel()->getName() . ' ' . $battery->getSize()->getName(), - 'battery' => $battery, - 'qty' => $qty, - 'sell_price' => $computed_price, - 'vat' => 0.0, - 'vat_ex_price' => 0.0, - ]; - - $total['sell_price'] = bcadd($total['sell_price'], $computed_price, 2); - $total['vat'] += 0.00; - $total['vat_ex_price'] += 0.00; - - $total['total_price'] = bcadd($total['total_price'], $computed_price, 2); - } - - return $invoice_batteries; - } -} diff --git a/src/Service/InvoiceManager.php b/src/Service/InvoiceManager.php index ddb108e2..8d608e89 100644 --- a/src/Service/InvoiceManager.php +++ b/src/Service/InvoiceManager.php @@ -17,143 +17,6 @@ use App\Entity\Battery; class InvoiceManager { - protected $security; - protected $em; - protected $validator; - protected $inv_batt; - protected $inv_trade; - protected $inv_tax; - - public function __construct(Security $service, EntityManagerInterface $em, ValidatorInterface $validator, - InvoiceBatteryManager $inv_batt, InvoiceTradeInManager $inv_trade, InvoiceTaxManager $inv_tax) - { - $this->security = $security; - $this->em = $em; - $this->validator = $validator; - $this->inv_batt = $inv_batt; - $this->inv_trade = $inv_trade; - $this->inv_tax = $inv_tax; - } - - public function generateInvoice(InvoiceCriteria $criteria) - { - // initialize - $invoice = new Invoice(); - $total = [ - 'sell_price' => 0.0, - 'vat' => 0.0, - 'vat_ex_price' => 0.0, - 'ti_rate' => 0.0, - 'total_price' => 0.0, - 'discount' => 0.0, - ]; - - $stype = $criteria->getServiceType(); - $cv = $criteria->getCustomerVehicle(); - $has_coolant = $criteria->hasCoolant(); - - switch($stype) - { - case ServiceType::JUMPSTART_TROUBLESHOOT: - $this->processJumpstart($total, $invoice); - break; - case ServiceType::JUMPSTART_WARRANTY: - $this->processJumpstartWarranty($total, $invoice); - break; - case ServiceType::BATTERY_REPLACEMENT_NEW: - $this->processEntries($total, $criteria, $invoice); - $this->processDiscount($total, $criteria, $invoice, $cust_tag_info); - break; - case ServiceType::BATTERY_REPLACEMENT_WARRANTY: - $this->processWarranty($total, $criteria, $invoice); - break; - case ServiceType::POST_RECHARGED: - $this->processRecharge($total, $invoice); - break; - case ServiceType::POST_REPLACEMENT: - $this->processReplacement($total, $invoice); - break; - case ServiceType::TIRE_REPAIR: - $this->processTireRepair($total, $invoice, $cv); - break; - case ServiceType::OVERHEAT_ASSISTANCE: - $this->processOverheat($total, $invoice, $cv, $has_coolant); - break; - case ServiceType::EMERGENCY_REFUEL: - $ftype = $criteria->getCustomerVehicle()->getFuelType(); - $this->processRefuel($total, $invoice, $cv); - break; - } - - // process promos here? - - // get current user - $user = $this->security->getUser(); - // check if user is User or APIUser - if ($user instanceof User) - { - $invoice->setCreatedBy($user); - } - - $invoice->setTotalPrice($total['total_price']) - ->setVATExclusivePrice($total['vat_ex_price']) - ->setVAT($total['vat']) - ->setDiscount($total['discount']) - ->setTradeIn($total['ti_rate']) - ->setStatus(InvoiceStatus::DRAFT); - - return $invoice; - } - - // process battery sales and trade-ins - protected function processEntries(&$total, InvoiceCriteria $criteria, Invoice $invoice) - { - $entries = $criteria->getEntries(); - - $con_batts = []; - $con_tis = []; - foreach($entries as $entry) - { - // batteries purchased should have trade_in set to null - $batt = $entry['battery']; - $qty = $entry['qty']; - $trade_in = $entry['trade_in']; - $size = $batt->getSize(); - - // consolidate batteries - $batt_id = $batt->getID(); - if (!isset($con_batts[$batt_id])) - $con_batts[$batt->getID()] = [ - 'batt' => $batt, - 'qty' => 0 - ]; - $con_batts[$batt_id]['qty']++; - - // no trade-in - if ($trade_in == null) - continue; - - // consolidate trade-ins - // need to set battery for trade in so we know what battery is for trade in - // possible that battery purchased is not the same battery for trade in - $ti_key = $size->getID() . '|' . $trade_in; - if (!isset($con_tis[$ti_key])) - $con_tis[$ti_key] = [ - 'batt' => $batt, - 'size' => $size, - 'trade_in' => $trade_in, - 'qty' => 0 - ]; - $con_tis[$ti_key]['qty']++; - } - - $inv_batt_entries = $this->inv_batt->processBatteries($con_batts, $total); - $inv_trade_in_entries = $this->inv_trade->processTradeIns($con_tis, $total); - - // check if we need to compute tax - if ($criteria->isTaxable()) - { - $this->inv_tax->computeTax($inv_batt_entries, $total); - } - } + // TODO: get list of invoice rules from .env + // TODO: get the service type fees } diff --git a/src/Service/InvoiceTaxManager.php b/src/Service/InvoiceTaxManager.php deleted file mode 100644 index 1535c68e..00000000 --- a/src/Service/InvoiceTaxManager.php +++ /dev/null @@ -1,29 +0,0 @@ -getTaxAmount($sell_price); - $vat_ex_price = $this->getTaxExclusivePrice($sell_price); - - // TODO: add to the total array the computed vat prices - } - } - - // TODO: use bc functions for these - protected function getTaxAmount($price) - { - $vat_ex_price = $this->getTaxExclusivePrice($price); - return $price - $vat_ex_price; - } - - protected function getTaxExclusivePrice($price) - { - return round($price / (1 + self::TAX_RATE), 2); - } -} diff --git a/src/Service/InvoiceTradeInManager.php b/src/Service/InvoiceTradeInManager.php deleted file mode 100644 index e0e04308..00000000 --- a/src/Service/InvoiceTradeInManager.php +++ /dev/null @@ -1,53 +0,0 @@ -getTradeInRate($ti); - - $ti_price = bcmul($ti_rate, -1, 2); - $invoice_trade_ins = [ - 'title' => 'Trade-in ' . TradeInType::getName($ti['trade_in']) . ' ' . $ti['size']->getName() . ' battery'), - 'qty' => $qty, - 'price' => $ti_price, - ]; - - $tti_price = bcmul($ti_rate, $qty, 2); - - $total['ti_rate'] = bcadd($total['ti_rate'], $tti_price, 2); - $total['total_price'] = bcsub($total['total_price'], $tti_price, 2); - } - - return $invoice_trade_ins; - } - - protected function getTradeInRate($ti) - { - $size = $ti['size']; - $trade_in = $ti['trade_in']; - - if ($trade_in == null) - return 0; - - switch ($trade_in) - { - case TradeInType::MOTOLITE: - return $size->getTIPriceMotolite(); - case TradeInType::PREMIUM: - return $size->getTIPricePremium(); - case TradeInType::OTHER: - return $size->getTIPriceOther(); - } - - return 0; - } -}