diff --git a/app/Factory/InvoiceItemFactory.php b/app/Factory/InvoiceItemFactory.php index 2396e3df154f..ed7a9c681dfb 100644 --- a/app/Factory/InvoiceItemFactory.php +++ b/app/Factory/InvoiceItemFactory.php @@ -67,7 +67,9 @@ class InvoiceItemFactory $item->custom_value2 = $faker->realText(10); $item->custom_value3 = $faker->realText(10); $item->custom_value4 = $faker->realText(10); - + $item->tax_name1 = 'GST'; + $item->tax_rate1 = '10.00'; + $data[] = $item; } diff --git a/app/Helpers/Invoice/InvoiceItemCalc.php b/app/Helpers/Invoice/InvoiceItemCalc.php index 879de4c5a64f..4edd67ff6e93 100644 --- a/app/Helpers/Invoice/InvoiceItemCalc.php +++ b/app/Helpers/Invoice/InvoiceItemCalc.php @@ -123,7 +123,7 @@ class InvoiceItemCalc $key = str_replace(" ", "", $tax_name.$tax_rate); - $group_tax[$key] = ['total' => $tax_total, 'tax_name' => $tax_name . ' ' . $tax_rate]; + $group_tax = [$key => ['total' => $tax_total, 'tax_name' => $tax_name . ' ' . $tax_rate.'%']]; $this->tax_collection->push(collect($group_tax)); diff --git a/app/Listeners/Invoice/CreateInvoicePdf.php b/app/Listeners/Invoice/CreateInvoicePdf.php index 8c4762cce318..7fd70b729771 100644 --- a/app/Listeners/Invoice/CreateInvoicePdf.php +++ b/app/Listeners/Invoice/CreateInvoicePdf.php @@ -18,6 +18,7 @@ use Illuminate\Support\Facades\Blade; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Storage; use Spatie\Browsershot\Browsershot; +use Symfony\Component\Debug\Exception\FatalThrowableError; class CreateInvoicePdf implements ShouldQueue { @@ -136,7 +137,7 @@ class CreateInvoicePdf implements ShouldQueue ob_end_clean(); } - throw new \FatalThrowableError($e); + throw new FatalThrowableError($e); } return ob_get_clean(); diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index 761b9f3a34db..7e2d694779ff 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -11,6 +11,7 @@ namespace App\Models; +use App\Helpers\Invoice\InvoiceCalc; use App\Models\Currency; use App\Models\Filterable; use App\Utils\Number; @@ -251,4 +252,17 @@ class Invoice extends BaseModel return File::exists(resource_path($this->settings->design)) ? File::get(resource_path($this->settings->design)) : File::get(resource_path('views/pdf/design1.blade.php')); } + /** + * Access the invoice calculator object + * + * @return object The invoice calculator object getters + */ + public function calc() + { + + $invoice_calc = new InvoiceCalc($this, $this->client->getMergedSettings()); + + return $invoice_calc->build(); + + } } \ No newline at end of file diff --git a/app/Utils/Traits/MakesInvoiceValues.php b/app/Utils/Traits/MakesInvoiceValues.php index 6fc5db848c4d..f83052e845c6 100644 --- a/app/Utils/Traits/MakesInvoiceValues.php +++ b/app/Utils/Traits/MakesInvoiceValues.php @@ -163,30 +163,31 @@ trait MakesInvoiceValues $data['$due_date'] = $this->due_date; $data['$invoice_number'] = $this->invoice_number; $data['$po_number'] = $this->po_number; - // $data['$discount'] = ; - // $data['$taxes'] = ; + $data['$discount'] = $this->calc()->getTotalDiscount(); + $data['$taxes'] = $this->calc()->getTotalTaxes(); + $data['$line_taxes'] = $this->calc()->getTaxMap(); // $data['$tax'] = ; // $data['$item'] = ; // $data['$description'] = ; // $data['$unit_cost'] = ; // $data['$quantity'] = ; // $data['$line_total'] = ; - // $data['$subtotal'] = ; // $data['$paid_to_date'] = ; + $data['$subtotal'] = Number::formatMoney($this->calc()->getSubTotal(), $this->client->currency(), $this->client->country, $this->client->settings); $data['$balance_due'] = Number::formatMoney($this->balance, $this->client->currency(), $this->client->country, $this->client->settings); $data['$partial_due'] = Number::formatMoney($this->partial, $this->client->currency(), $this->client->country, $this->client->settings); + $data['$total'] = Number::formatMoney($this->calc()->getTotal(), $this->client->currency(), $this->client->country, $this->client->settings); + $data['$balance'] = Number::formatMoney($this->calc()->getBalance(), $this->client->currency(), $this->client->country, $this->client->settings); $data['$terms'] = $this->terms; // $data['$your_invoice'] = ; // $data['$quote'] = ; // $data['$your_quote'] = ; // $data['$quote_date'] = ; // $data['$quote_number'] = ; - $data['$total'] = Number::formatMoney($this->amount, $this->client->currency(), $this->client->country, $this->client->settings); // $data['$invoice_issued_to'] = ; // $data['$quote_issued_to'] = ; // $data['$rate'] = ; // $data['$hours'] = ; - // $data['$balance'] = ; // $data['$from'] = ; // $data['$to'] = ; // $data['$invoice_to'] = ; @@ -303,8 +304,8 @@ trait MakesInvoiceValues */ private function transformColumnsForHeader(array $columns) :array { - - $columns = array_intersect(self::$master_columns, $columns); + $pre_columns = $columns; + $columns = array_intersect($columns, self::$master_columns); return str_replace([ 'tax_name1', @@ -329,7 +330,7 @@ trait MakesInvoiceValues private function transformColumnsForLineItems(array $columns) :array { /* Removes any invalid columns the user has entered. */ - $columns = array_intersect(self::$master_columns, $columns); + $columns = array_intersect($columns, self::$master_columns); return str_replace([ 'custom_invoice_label1', diff --git a/resources/views/pdf/design1.blade.php b/resources/views/pdf/design1.blade.php index 8bb01d4df7aa..7ac39311cba1 100644 --- a/resources/views/pdf/design1.blade.php +++ b/resources/views/pdf/design1.blade.php @@ -168,17 +168,47 @@ custom_label3 ( will show as the following parameter as its value -> custom_invoice_value3 ) custom_label4 ( will show as the following parameter as its value -> custom_invoice_value4 ) --}} - {!! $invoice->table(['product_key', 'notes', 'cost','quantity', 'line_total']) !!} + {!! $invoice->table(['product_key', 'notes', 'cost','quantity', 'discount', 'tax_name1', 'line_total']) !!} - + - + + + + + + + + + + + + + + + + + + + + +
- Total: $385.00 + $subtotal_label: $subtotal
+ $taxes_label: $taxes +
+ $taxes_label: $line_taxes +
+ $discount_label: $discount +
+ $total_label: $total +
+ $balance_label: $balance +
diff --git a/tests/Unit/MakesInvoiceValuesTest.php b/tests/Unit/MakesInvoiceValuesTest.php index ef79b1fadeb3..a00af996446a 100644 --- a/tests/Unit/MakesInvoiceValuesTest.php +++ b/tests/Unit/MakesInvoiceValuesTest.php @@ -31,6 +31,68 @@ class MakesInvoiceValuesTest extends TestCase $this->assertFalse(in_array("custom_invoice_value1", $columns)); } + public function testFilteringItemTaxes() + { + $taxes = collect(); + $tax_name = "GST"; + $tax_rate = "10.00"; + + $key = str_replace(" ", "", $tax_name.$tax_rate); + + $group_tax = collect(['key' => $key, 'total' => 20, 'tax_name' => $tax_name . ' ' . $tax_rate.'%']); + $taxes->push($group_tax); + $group_tax = collect(['key' => $key, 'total' => 30, 'tax_name' => $tax_name . ' ' . $tax_rate.'%']); + $taxes->push($group_tax); + $group_tax = collect(['key' => $key, 'total' => 30, 'tax_name' => $tax_name . ' ' . $tax_rate.'%']); + $taxes->push($group_tax); + $group_tax = collect(['key' => $key, 'total' => 20, 'tax_name' => $tax_name . ' ' . $tax_rate.'%']); + $taxes->push($group_tax); + $group_tax = collect(['key' => 'VAT', 'total' => 20, 'tax_name' => 'VAT' . ' ' . '17.5%']); + $taxes->push($group_tax); + + $this->assertEquals(5, $taxes->count()); + + $keys = $taxes->pluck('key')->unique(); + + $this->assertEquals("GST10.00", $keys->first()); + + $tax_array = []; + + foreach($keys as $key) + { + + $tax_name = $taxes->filter(function ($value, $k) use($key){ + return $value['key'] == $key; + })->pluck('tax_name')->first(); + + $total_line_tax = $taxes->filter(function ($value, $k) use($key){ + return $value['key'] == $key; + })->sum('total'); + + $tax_array[] = ['name' => $tax_name, 'total' => $total_line_tax]; + + } + + $this->assertEquals("GST10.00", print_r($tax_array)); + // $this->assertEquals("GST10.00", $keys->keys()); + + foreach($keys as $key) + { + + $this->assertEquals("GST10.00", $key); + + $tax_group = $taxes->groupBy($key); + + $this->assertEquals('hi', $tax_group); + $tax_group->sum('total'); + + $this->assertEquals(100, $tax_group->sum('total')); + + } + + + + } }