diff --git a/app/Factory/InvoiceItemFactory.php b/app/Factory/InvoiceItemFactory.php index 6fee332a41..4e6573f7d4 100644 --- a/app/Factory/InvoiceItemFactory.php +++ b/app/Factory/InvoiceItemFactory.php @@ -29,6 +29,8 @@ class InvoiceItemFactory $item->tax_rate1 = 0; $item->tax_name2 = ''; $item->tax_rate2 = 0; + $item->tax_name3 = ''; + $item->tax_rate3 = 0; $item->sort_id = 0; $item->line_total = 0; $item->date = Carbon::now(); diff --git a/app/Helpers/Invoice/InvoiceItemSum.php b/app/Helpers/Invoice/InvoiceItemSum.php index 846175e0d6..14f5544632 100644 --- a/app/Helpers/Invoice/InvoiceItemSum.php +++ b/app/Helpers/Invoice/InvoiceItemSum.php @@ -12,6 +12,7 @@ namespace App\Helpers\Invoice; use App\Helpers\Invoice\Discounter; +use App\Helpers\Invoice\Taxer; use App\Models\Invoice; use App\Utils\Traits\NumberFormatter; use Illuminate\Support\Collection; @@ -21,6 +22,7 @@ class InvoiceItemSum use NumberFormatter; use Discounter; + use Taxer; protected $settings; @@ -116,60 +118,75 @@ class InvoiceItemSum } private function calcTaxes() - { + {\Log::error(print_r($this->settings,1)); + if($this->settings->inclusive_taxes == true) + return $this->calcInclusiveTaxes(); + +\Log::error("calculating exclusive taxes"); +\Log::error($this->settings->inclusive_taxes); + $item_tax = 0; - if(isset($this->item->tax_rate1) && $this->item->tax_rate1 > 0) - { - $tax_rate1 = $this->formatValue($this->item->tax_rate1, $this->currency->precision); - if($this->settings->inclusive_taxes) - $item_tax_rate1_total = $this->formatValue(($this->item->line_total - ($this->item->line_total / (1+$tax_rate1/100))) , $this->currency->precision); - else - $item_tax_rate1_total = $this->formatValue(($this->item->line_total * $tax_rate1/100), $this->currency->precision); + $item_tax_rate1_total = $this->calcLineTax($this->item->tax_rate1, $this->item); $item_tax += $item_tax_rate1_total; $this->groupTax($this->item->tax_name1, $this->item->tax_rate1, $item_tax_rate1_total); - } + - if(isset($this->item->tax_rate2) && $this->item->tax_rate2 > 0) - { - $tax_rate2 = $this->formatValue($this->item->tax_rate2, $this->currency->precision); - - if($this->settings->inclusive_taxes) - $item_tax_rate2_total = $this->formatValue(($this->item->line_total - ($this->item->line_total / (1+$tax_rate2/100))) , $this->currency->precision); - else - $item_tax_rate2_total = $this->formatValue(($this->item->line_total * $tax_rate2/100), $this->currency->precision); + $item_tax_rate2_total = $this->calcLineTax($this->item->tax_rate2, $this->item); $item_tax += $item_tax_rate2_total; $this->groupTax($this->item->tax_name2, $this->item->tax_rate2, $item_tax_rate2_total); - } - if(isset($this->item->tax_rate3) && $this->item->tax_rate3 > 0) - { - $tax_rate3 = $this->formatValue($this->item->tax_rate3, $this->currency->precision); - - if($this->settings->inclusive_taxes) - $item_tax_rate3_total = $this->formatValue(($this->item->line_total - ($this->item->line_total / (1+$tax_rate3/100))) , $this->currency->precision); - else - $item_tax_rate3_total = $this->formatValue(($this->item->line_total * $tax_rate3/100), $this->currency->precision); + $item_tax_rate3_total = $this->calcLineTax($this->item->tax_rate3, $this->item); $item_tax += $item_tax_rate3_total; $this->groupTax($this->item->tax_name3, $this->item->tax_rate3, $item_tax_rate3_total); - } //todo if exclusive add on top, if inclusive need to reduce item rates - $this->setTotalTaxes($item_tax); return $this; } + /** + * Inclusive taxes are a different beast + * the line totals are changed when implementing + * inclusive taxes so we need to handle this away from the + * calcTaxes method. + * + */ + private function calcInclusiveTaxes() + { +\Log::error("calculating inclusive taxes"); + $tax1 = $this->inclusiveTax($this->item->tax_rate1, $this->item); + $tax2 = $this->inclusiveTax($this->item->tax_rate2, $this->item); + $tax3 = $this->inclusiveTax($this->item->tax_rate3, $this->item); + + if($tax1>0) + $this->groupTax($this->item->tax_name1, $this->item->tax_rate1, $tax1); + + if($tax2>0) + $this->groupTax($this->item->tax_name2, $this->item->tax_rate2, $tax2); + + if($tax3>0) + $this->groupTax($this->item->tax_name3, $this->item->tax_rate3, $tax3); + + $total_taxes = ($tax1 + $tax2 + $tax3); + + $this->setTotalTaxes($this->getTotalTaxes() + $total_taxes); + + $this->item->line_total -= $total_taxes; + + return $this; + } + private function groupTax($tax_name, $tax_rate, $tax_total) { $group_tax = []; diff --git a/app/Helpers/Invoice/InvoiceSum.php b/app/Helpers/Invoice/InvoiceSum.php index f79313d41d..5c40be187c 100644 --- a/app/Helpers/Invoice/InvoiceSum.php +++ b/app/Helpers/Invoice/InvoiceSum.php @@ -45,6 +45,8 @@ class InvoiceSum private $total_custom_values; private $total_tax_map; + + private $sub_total; /** * Constructs the object with Invoice and Settings object * @@ -81,6 +83,7 @@ class InvoiceSum $this->invoice_items->process(); $this->invoice->line_items = $this->invoice_items->getLineItems(); $this->total = $this->invoice_items->getSubTotal(); + $this->setSubTotal($this->invoice_items->getSubTotal()); return $this; } @@ -164,6 +167,10 @@ class InvoiceSum if($this->settings->inclusive_taxes === false) $this->total += $this->total_taxes; + else + { + $this->setSubTotal($this->getSubTotal() - $this->total_taxes); + } return $this; @@ -202,7 +209,13 @@ class InvoiceSum public function getSubTotal() { - return $this->invoice_items->getSubTotal(); + return $this->sub_total; + } + + public function setSubTotal($value) + { + $this->sub_total = $value; + return $this; } public function getTotalDiscount() diff --git a/app/Helpers/Invoice/Taxer.php b/app/Helpers/Invoice/Taxer.php index d353230b7b..16b42f80f3 100644 --- a/app/Helpers/Invoice/Taxer.php +++ b/app/Helpers/Invoice/Taxer.php @@ -22,4 +22,32 @@ trait Taxer return round($amount * (($tax_rate ? $tax_rate : 0) / 100), 2); } + public function calcLineTax($tax_rate, $item) + { + if(!isset($tax_rate) || $tax_rate == 0) + return 0; + + if($this->settings->inclusive_taxes) + return $this->inclusiveTax($tax_rate, $item); + + return $this->exclusiveTax($tax_rate, $item); + } + + public function exclusiveTax($tax_rate, $item) + { + + $tax_rate = $this->formatValue($tax_rate, $this->currency->precision); + + return $this->formatValue(($item->line_total * $tax_rate/100), $this->currency->precision); + + } + + public function inclusiveTax($tax_rate, $item) + { + + $tax_rate = $this->formatValue($tax_rate, $this->currency->precision); + + return $this->formatValue(($item->line_total - ($item->line_total / (1+$tax_rate/100))) , $this->currency->precision); + } + } diff --git a/app/Utils/Traits/MakesInvoiceValues.php b/app/Utils/Traits/MakesInvoiceValues.php index 04d6f3b29a..bbd72c47b1 100644 --- a/app/Utils/Traits/MakesInvoiceValues.php +++ b/app/Utils/Traits/MakesInvoiceValues.php @@ -426,7 +426,7 @@ trait MakesInvoiceValues $data = ''; - if($this->calc()->getTotalTaxMap()->count() == 0) + if(count($this->calc()->getTotalTaxMap()) == 0) return $data; foreach($this->calc()->getTotalTaxMap() as $tax) diff --git a/database/seeds/RandomDataSeeder.php b/database/seeds/RandomDataSeeder.php index c4289bd77c..4017db3eb1 100644 --- a/database/seeds/RandomDataSeeder.php +++ b/database/seeds/RandomDataSeeder.php @@ -113,13 +113,16 @@ class RandomDataSeeder extends Seeder factory(\App\Models\Product::class,50)->create(['user_id' => $user->id, 'company_id' => $company->id]); /** Invoice Factory */ - factory(\App\Models\Invoice::class,500)->create(['user_id' => $user->id, 'company_id' => $company->id, 'client_id' => $client->id, 'settings' => ClientSettings::buildClientSettings($company->settings, $client->settings)]); + factory(\App\Models\Invoice::class,50)->create(['user_id' => $user->id, 'company_id' => $company->id, 'client_id' => $client->id, 'settings' => ClientSettings::buildClientSettings($company->settings, $client->settings)]); $invoices = Invoice::all(); $invoice_repo = new InvoiceRepository(); $invoices->each(function ($invoice) use($invoice_repo, $user, $company, $client){ - + + //$invoice->settings->inclusive_taxes = (bool)random_int(0, 1); + $invoice->settings->inclusive_taxes = true; + $invoice_calc = new InvoiceSum($invoice, $invoice->settings); $invoice = $invoice_calc->build()->getInvoice();