From fe9ce1c73333a4bc8de7110221ddd4d5cd40bf67 Mon Sep 17 00:00:00 2001 From: cuneytsenturk Date: Wed, 7 Nov 2018 11:06:38 +0300 Subject: [PATCH] Bill create and update tax changes finished --- app/Http/Controllers/Expenses/Bills.php | 341 +--------------------- app/Http/Controllers/Incomes/Invoices.php | 60 ---- app/Jobs/Expense/CreateBill.php | 170 +++++++++++ app/Jobs/Expense/CreateBillItem.php | 202 +++++++++++++ app/Jobs/Expense/CreateBillPayment.php | 52 ++++ app/Jobs/Expense/UpdateBill.php | 319 ++++++++++++++++++++ 6 files changed, 749 insertions(+), 395 deletions(-) create mode 100644 app/Jobs/Expense/CreateBill.php create mode 100644 app/Jobs/Expense/CreateBillItem.php create mode 100644 app/Jobs/Expense/CreateBillPayment.php create mode 100644 app/Jobs/Expense/UpdateBill.php diff --git a/app/Http/Controllers/Expenses/Bills.php b/app/Http/Controllers/Expenses/Bills.php index 5dd6c2b7e..daf3dc4e1 100644 --- a/app/Http/Controllers/Expenses/Bills.php +++ b/app/Http/Controllers/Expenses/Bills.php @@ -8,6 +8,9 @@ use App\Events\BillUpdated; use App\Http\Controllers\Controller; use App\Http\Requests\Expense\Bill as Request; use App\Http\Requests\Expense\BillPayment as PaymentRequest; +use App\Jobs\Expense\CreateBill; +use App\Jobs\Expense\UpdateBill; +use App\Jobs\Expense\CreateBillPayment; use App\Models\Banking\Account; use App\Models\Common\Media; use App\Models\Expense\BillStatus; @@ -111,137 +114,7 @@ class Bills extends Controller */ public function store(Request $request) { - $bill = Bill::create($request->input()); - - // Upload attachment - if ($request->file('attachment')) { - $media = $this->getMedia($request->file('attachment'), 'bills'); - - $bill->attachMedia($media, 'attachment'); - } - - $taxes = []; - - $tax_total = 0; - $sub_total = 0; - $discount_total = 0; - $discount = $request['discount']; - - $bill_item = []; - $bill_item['company_id'] = $request['company_id']; - $bill_item['bill_id'] = $bill->id; - - if ($request['item']) { - foreach ($request['item'] as $item) { - $item_sku = ''; - - if (!empty($item['item_id'])) { - $item_object = Item::find($item['item_id']); - - $item['name'] = $item_object->name; - $item_sku = $item_object->sku; - - // Increase stock (item bought) - $item_object->quantity += $item['quantity']; - $item_object->save(); - } - - $item_tax = 0; - $item_taxes = []; - $bill_item_taxes = []; - - if (!empty($item['tax_id'])) { - foreach ($item['tax_id'] as $tax_id) { - $tax_object = Tax::find($tax_id); - - $item_taxes[] = $tax_id; - - $tax = (((double) $item['price'] * (double) $item['quantity']) / 100) * $tax_object->rate; - - // Apply discount to tax - if ($discount) { - $tax = $tax - ($tax * ($discount / 100)); - } - - $bill_item_taxes[] = [ - 'company_id' => $request['company_id'], - 'bill_id' => $bill->id, - 'tax_id' => $tax_id, - 'name' => $tax_object->name, - 'amount' => $tax, - ]; - - $item_tax += $tax; - } - } - - $bill_item['item_id'] = $item['item_id']; - $bill_item['name'] = str_limit($item['name'], 180, ''); - $bill_item['sku'] = $item_sku; - $bill_item['quantity'] = (double) $item['quantity']; - $bill_item['price'] = (double) $item['price']; - $bill_item['tax'] = $item_tax; - $bill_item['tax_id'] = 0;//$tax_id; - $bill_item['total'] = (double) $item['price'] * (double) $item['quantity']; - - $bill_item_created = BillItem::create($bill_item); - - if ($bill_item_taxes) { - foreach ($bill_item_taxes as $bill_item_tax) { - $bill_item_tax['bill_item_id'] = $bill_item_created->id; - - BillItemTax::create($bill_item_tax); - - // Set taxes - if (isset($taxes) && array_key_exists($bill_item_tax['tax_id'], $taxes)) { - $taxes[$bill_item_tax['tax_id']]['amount'] += $bill_item_tax['amount']; - } else { - $taxes[$bill_item_tax['tax_id']] = [ - 'name' => $bill_item_tax['name'], - 'amount' => $bill_item_tax['amount'] - ]; - } - } - } - - // Calculate totals - $tax_total += $item_tax; - $sub_total += $bill_item['total']; - } - } - - $s_total = $sub_total; - - // Apply discount to total - if ($discount) { - $s_discount = $s_total * ($discount / 100); - $discount_total += $s_discount; - $s_total = $s_total - $s_discount; - } - - $amount = $s_total + $tax_total; - - $request['amount'] = money($amount, $request['currency_code'])->getAmount(); - - $bill->update($request->input()); - - // Add bill totals - $this->addTotals($bill, $request, $taxes, $sub_total, $discount_total, $tax_total); - - // Add bill history - BillHistory::create([ - 'company_id' => session('company_id'), - 'bill_id' => $bill->id, - 'status_code' => 'draft', - 'notify' => 0, - 'description' => trans('messages.success.added', ['type' => $bill->bill_number]), - ]); - - // Recurring - $bill->createRecurring(); - - // Fire the event to make it extendible - event(new BillCreated($bill)); + $bill = dispatch(new CreateBill($request)); $message = trans('messages.success.added', ['type' => trans_choice('general.bills', 1)]); @@ -354,127 +227,7 @@ class Bills extends Controller */ public function update(Bill $bill, Request $request) { - $taxes = []; - - $tax_total = 0; - $sub_total = 0; - $discount_total = 0; - $discount = $request['discount']; - - $bill_item = []; - $bill_item['company_id'] = $request['company_id']; - $bill_item['bill_id'] = $bill->id; - - if ($request['item']) { - $this->deleteRelationships($bill, 'items'); - - foreach ($request['item'] as $item) { - unset($tax_object); - $item_sku = ''; - - if (!empty($item['item_id'])) { - $item_object = Item::find($item['item_id']); - - $item['name'] = $item_object->name; - $item_sku = $item_object->sku; - } - - $item_tax = 0; - $item_taxes = []; - $bill_item_taxes = []; - - if (!empty($item['tax_id'])) { - foreach ($item['tax_id'] as $tax_id) { - $tax_object = Tax::find($tax_id); - - $item_taxes[] = $tax_id; - - $tax = (((double) $item['price'] * (double) $item['quantity']) / 100) * $tax_object->rate; - - // Apply discount to tax - if ($discount) { - $tax = $tax - ($tax * ($discount / 100)); - } - - $bill_item_taxes[] = [ - 'company_id' => $request['company_id'], - 'bill_id' => $bill->id, - 'tax_id' => $tax_id, - 'name' => $tax_object->name, - 'amount' => $tax, - ]; - - $item_tax += $tax; - } - } - - $bill_item['item_id'] = $item['item_id']; - $bill_item['name'] = str_limit($item['name'], 180, ''); - $bill_item['sku'] = $item_sku; - $bill_item['quantity'] = (double) $item['quantity']; - $bill_item['price'] = (double) $item['price']; - $bill_item['tax'] = $item_tax; - $bill_item['tax_id'] = 0;//$tax_id; - $bill_item['total'] = (double) $item['price'] * (double) $item['quantity']; - - $tax_total += $item_tax; - $sub_total += $bill_item['total']; - - $bill_item_created = BillItem::create($bill_item); - - if ($bill_item_taxes) { - foreach ($bill_item_taxes as $bill_item_tax) { - $bill_item_tax['bill_item_id'] = $bill_item_created->id; - - BillItemTax::create($bill_item_tax); - - // Set taxes - if (isset($taxes) && array_key_exists($bill_item_tax['tax_id'], $taxes)) { - $taxes[$bill_item_tax['tax_id']]['amount'] += $bill_item_tax['amount']; - } else { - $taxes[$bill_item_tax['tax_id']] = [ - 'name' => $bill_item_tax['name'], - 'amount' => $bill_item_tax['amount'] - ]; - } - } - } - } - } - - $s_total = $sub_total; - - // Apply discount to total - if ($discount) { - $s_discount = $s_total * ($discount / 100); - $discount_total += $s_discount; - $s_total = $s_total - $s_discount; - } - - $amount = $s_total + $tax_total; - - $request['amount'] = money($amount, $request['currency_code'])->getAmount(); - - $bill->update($request->input()); - - // Upload attachment - if ($request->file('attachment')) { - $media = $this->getMedia($request->file('attachment'), 'bills'); - - $bill->attachMedia($media, 'attachment'); - } - - // Delete previous bill totals - $this->deleteRelationships($bill, 'totals'); - - // Add bill totals - $this->addTotals($bill, $request, $taxes, $sub_total, $discount_total, $tax_total); - - // Recurring - $bill->updateRecurring(); - - // Fire the event to make it extendible - event(new BillUpdated($bill)); + $bill = dispatch(new UpdateBill($bill, $request)); $message = trans('messages.success.updated', ['type' => trans_choice('general.bills', 1)]); @@ -655,20 +408,7 @@ class Bills extends Controller $bill->save(); - $bill_payment_request = [ - 'company_id' => $request['company_id'], - 'bill_id' => $request['bill_id'], - 'account_id' => $request['account_id'], - 'paid_at' => $request['paid_at'], - 'amount' => $request['amount'], - 'currency_code' => $request['currency_code'], - 'currency_rate' => $request['currency_rate'], - 'description' => $request['description'], - 'payment_method' => $request['payment_method'], - 'reference' => $request['reference'] - ]; - - $bill_payment = BillPayment::create($bill_payment_request); + $bill_payment = dispatch(new CreateBillPayment($request, $bill)); // Upload attachment if ($request->file('attachment')) { @@ -677,15 +417,6 @@ class Bills extends Controller $bill_payment->attachMedia($media, 'attachment'); } - $request['status_code'] = $bill->bill_status_code; - $request['notify'] = 0; - - $desc_amount = money((float) $request['amount'], (string) $request['currency_code'], true)->format(); - - $request['description'] = $desc_amount . ' ' . trans_choice('general.payments', 1); - - BillHistory::create($request->input()); - $message = trans('messages.success.added', ['type' => trans_choice('general.payments', 1)]); return response()->json([ @@ -794,64 +525,4 @@ class Bills extends Controller return $bill; } - - protected function addTotals($bill, $request, $taxes, $sub_total, $discount_total, $tax_total) - { - $sort_order = 1; - - // Added bill sub total - BillTotal::create([ - 'company_id' => $request['company_id'], - 'bill_id' => $bill->id, - 'code' => 'sub_total', - 'name' => 'bills.sub_total', - 'amount' => $sub_total, - 'sort_order' => $sort_order, - ]); - - $sort_order++; - - // Added bill discount - if ($discount_total) { - BillTotal::create([ - 'company_id' => $request['company_id'], - 'bill_id' => $bill->id, - 'code' => 'discount', - 'name' => 'bills.discount', - 'amount' => $discount_total, - 'sort_order' => $sort_order, - ]); - - // This is for total - $sub_total = $sub_total - $discount_total; - - $sort_order++; - } - - // Added bill taxes - if (isset($taxes)) { - foreach ($taxes as $tax) { - BillTotal::create([ - 'company_id' => $request['company_id'], - 'bill_id' => $bill->id, - 'code' => 'tax', - 'name' => $tax['name'], - 'amount' => $tax['amount'], - 'sort_order' => $sort_order, - ]); - - $sort_order++; - } - } - - // Added bill total - BillTotal::create([ - 'company_id' => $request['company_id'], - 'bill_id' => $bill->id, - 'code' => 'total', - 'name' => 'bills.total', - 'amount' => $sub_total + $tax_total, - 'sort_order' => $sort_order, - ]); - } } diff --git a/app/Http/Controllers/Incomes/Invoices.php b/app/Http/Controllers/Incomes/Invoices.php index cb1183193..28c421963 100644 --- a/app/Http/Controllers/Incomes/Invoices.php +++ b/app/Http/Controllers/Incomes/Invoices.php @@ -654,64 +654,4 @@ class Invoices extends Controller return $invoice; } - - protected function addTotals($invoice, $request, $taxes, $sub_total, $discount_total, $tax_total) - { - $sort_order = 1; - - // Added invoice sub total - InvoiceTotal::create([ - 'company_id' => $request['company_id'], - 'invoice_id' => $invoice->id, - 'code' => 'sub_total', - 'name' => 'invoices.sub_total', - 'amount' => $sub_total, - 'sort_order' => $sort_order, - ]); - - $sort_order++; - - // Added invoice discount - if ($discount_total) { - InvoiceTotal::create([ - 'company_id' => $request['company_id'], - 'invoice_id' => $invoice->id, - 'code' => 'discount', - 'name' => 'invoices.discount', - 'amount' => $discount_total, - 'sort_order' => $sort_order, - ]); - - // This is for total - $sub_total = $sub_total - $discount_total; - - $sort_order++; - } - - // Added invoice taxes - if (isset($taxes)) { - foreach ($taxes as $tax) { - InvoiceTotal::create([ - 'company_id' => $request['company_id'], - 'invoice_id' => $invoice->id, - 'code' => 'tax', - 'name' => $tax['name'], - 'amount' => $tax['amount'], - 'sort_order' => $sort_order, - ]); - - $sort_order++; - } - } - - // Added invoice total - InvoiceTotal::create([ - 'company_id' => $request['company_id'], - 'invoice_id' => $invoice->id, - 'code' => 'total', - 'name' => 'invoices.total', - 'amount' => $sub_total + $tax_total, - 'sort_order' => $sort_order, - ]); - } } diff --git a/app/Jobs/Expense/CreateBill.php b/app/Jobs/Expense/CreateBill.php new file mode 100644 index 000000000..d5555a348 --- /dev/null +++ b/app/Jobs/Expense/CreateBill.php @@ -0,0 +1,170 @@ +request = $request; + } + + /** + * Execute the job. + * + * @return Invoice + */ + public function handle() + { + $bill = Bill::create($this->request->input()); + + // Upload attachment + if ($this->request->file('attachment')) { + $media = $this->getMedia($this->request->file('attachment'), 'bills'); + + $bill->attachMedia($media, 'attachment'); + } + + $taxes = []; + + $tax_total = 0; + $sub_total = 0; + $discount_total = 0; + $discount = $this->request['discount']; + + if ($this->request['item']) { + foreach ($this->request['item'] as $item) { + $bill_item = dispatch(new CreateBillItem($item, $bill, $discount)); + + // Calculate totals + $tax_total += $bill_item->tax; + $sub_total += $bill_item->total; + + // Set taxes + foreach ($bill_item->item_taxes as $item_tax) { + if (isset($taxes) && array_key_exists($item_tax['tax_id'], $taxes)) { + $taxes[$item_tax['tax_id']]['amount'] += $item_tax['amount']; + } else { + $taxes[$item_tax['tax_id']] = [ + 'name' => $item_tax['name'], + 'amount' => $item_tax['amount'] + ]; + } + } + } + } + + $s_total = $sub_total; + + // Apply discount to total + if ($discount) { + $s_discount = $s_total * ($discount / 100); + $discount_total += $s_discount; + $s_total = $s_total - $s_discount; + } + + $amount = $s_total + $tax_total; + + $request['amount'] = money($amount, $this->request['currency_code'])->getAmount(); + + $bill->update($this->request->input()); + + // Add bill totals + $this->addTotals($bill, $this->request, $taxes, $sub_total, $discount_total, $tax_total); + + // Add bill history + BillHistory::create([ + 'company_id' => session('company_id'), + 'bill_id' => $bill->id, + 'status_code' => 'draft', + 'notify' => 0, + 'description' => trans('messages.success.added', ['type' => $bill->bill_number]), + ]); + + // Recurring + $bill->createRecurring(); + + // Fire the event to make it extendible + event(new BillCreated($bill)); + + return $bill; + } + + protected function addTotals($bill, $request, $taxes, $sub_total, $discount_total, $tax_total) + { + $sort_order = 1; + + // Added bill sub total + BillTotal::create([ + 'company_id' => $request['company_id'], + 'bill_id' => $bill->id, + 'code' => 'sub_total', + 'name' => 'bills.sub_total', + 'amount' => $sub_total, + 'sort_order' => $sort_order, + ]); + + $sort_order++; + + // Added bill discount + if ($discount_total) { + BillTotal::create([ + 'company_id' => $request['company_id'], + 'bill_id' => $bill->id, + 'code' => 'discount', + 'name' => 'bills.discount', + 'amount' => $discount_total, + 'sort_order' => $sort_order, + ]); + + // This is for total + $sub_total = $sub_total - $discount_total; + + $sort_order++; + } + + // Added bill taxes + if (isset($taxes)) { + foreach ($taxes as $tax) { + BillTotal::create([ + 'company_id' => $request['company_id'], + 'bill_id' => $bill->id, + 'code' => 'tax', + 'name' => $tax['name'], + 'amount' => $tax['amount'], + 'sort_order' => $sort_order, + ]); + + $sort_order++; + } + } + + // Added bill total + BillTotal::create([ + 'company_id' => $request['company_id'], + 'bill_id' => $bill->id, + 'code' => 'total', + 'name' => 'bills.total', + 'amount' => $sub_total + $tax_total, + 'sort_order' => $sort_order, + ]); + } +} diff --git a/app/Jobs/Expense/CreateBillItem.php b/app/Jobs/Expense/CreateBillItem.php new file mode 100644 index 000000000..093f167d9 --- /dev/null +++ b/app/Jobs/Expense/CreateBillItem.php @@ -0,0 +1,202 @@ +data = $data; + $this->bill = $bill; + $this->discount = $discount; + } + + /** + * Execute the job. + * + * @return BillItem + */ + public function handle() + { + $item_sku = ''; + + $item_id = !empty($this->data['item_id']) ? $this->data['item_id'] : 0; + $item_amount = (double) $this->data['price'] * (double) $this->data['quantity']; + + $item_discount_amount = $item_amount; + + // Apply discount to tax + if ($this->discount) { + $item_discount_amount = $item_amount * ($this->discount / 100); + } + + if (!empty($item_id)) { + $item_object = Item::find($item_id); + + $this->data['name'] = $item_object->name; + $item_sku = $item_object->sku; + + // Increase stock (item bought) + $item_object->quantity += $this->data['quantity']; + $item_object->save(); + } elseif (!empty($this->data['sku'])) { + $item_sku = $this->data['sku']; + } + + $tax_amount = 0; + $item_taxes = []; + $item_tax_total = 0; + + if (!empty($this->data['tax_id'])) { + $calculates = $compounds = $taxes = []; + + foreach ((array) $this->data['tax_id'] as $tax_id) { + $tax = Tax::find($tax_id); + + switch ($tax->type) { + case 'calculate': + $calculates[] = $tax; + break; + case 'compound': + $compounds[] = $tax; + break; + case 'normal': + default: + $taxes[] = $tax; + + $tax_amount = ($item_discount_amount / 100) * $tax->rate; + + $item_taxes[] = [ + 'company_id' => $this->bill->company_id, + 'bill_id' => $this->bill->id, + 'tax_id' => $tax_id, + 'name' => $tax->name, + 'amount' => $tax_amount, + ]; + + $item_tax_total += $tax_amount; + break; + } + } + + if ($calculates) { + if ($this->discount) { + $item_tax_total = 0; + + if ($taxes) { + foreach ($taxes as $tax) { + $item_tax_amount = ($item_amount / 100) * $tax->rate; + + $item_tax_total += $item_tax_amount; + } + } + + foreach ($calculates as $calculate) { + $item_sub_and_tax_total = $item_amount + $item_tax_total; + + $item_tax_total = $item_sub_and_tax_total - (($item_sub_and_tax_total * (100 - $calculate->rate)) / 100); + + $item_sub_total = $item_sub_and_tax_total - $item_tax_total; + + $item_discount_amount = $item_sub_total - ($item_sub_total * ($this->discount / 100)); + } + } else { + foreach ($calculates as $calculate) { + $item_sub_and_tax_total = $item_discount_amount + $item_tax_total; + + $item_tax_total = $tax_amount = $item_sub_and_tax_total - ($item_sub_and_tax_total / (1 + ($calculate->rate / 100))); + + $item_taxes[] = [ + 'company_id' => $this->bill->company_id, + 'bill_id' => $this->bill->id, + 'tax_id' => $calculate->id, + 'name' => $calculate->name, + 'amount' => $tax_amount, + ]; + + $item_amount = $item_sub_and_tax_total - $item_tax_total; + } + } + } + + if ($compounds) { + foreach ($compounds as $compound) { + $tax_amount = (($item_discount_amount + $item_tax_total) / 100) * $compound->rate; + + $item_tax_total += $tax_amount; + + $item_taxes[] = [ + 'company_id' => $this->bill->company_id, + 'bill_id' => $this->bill->id, + 'tax_id' => $compound->id, + 'name' => $compound->name, + 'amount' => $tax_amount, + ]; + } + } + } + + $bill_item = BillItem::create([ + 'company_id' => $this->bill->company_id, + 'bill_id' => $this->bill->id, + 'item_id' => $item_id, + 'name' => str_limit($this->data['name'], 180, ''), + 'sku' => $item_sku, + 'quantity' => (double) $this->data['quantity'], + 'price' => (double) $this->data['price'], + 'tax' => $item_tax_total, + 'tax_id' => 0, + 'total' => $item_amount, + ]); + + if (!empty($this->data['tax_id'])) { + // set item_taxes for + $bill_item->item_taxes = $item_taxes; + $bill_item->calculates = $calculates; + $bill_item->compounds = $compounds; + } + + if ($item_taxes) { + foreach ($item_taxes as $item_tax) { + $item_tax['bill_item_id'] = $bill_item->id; + + BillItemTax::create($item_tax); + + // Set taxes + if (isset($taxes) && array_key_exists($item_tax['tax_id'], $taxes)) { + $taxes[$item_tax['tax_id']]['amount'] += $item_tax['amount']; + } else { + $taxes[$item_tax['tax_id']] = [ + 'name' => $item_tax['name'], + 'amount' => $item_tax['amount'] + ]; + } + } + } + + return $bill_item; + } +} diff --git a/app/Jobs/Expense/CreateBillPayment.php b/app/Jobs/Expense/CreateBillPayment.php new file mode 100644 index 000000000..41770139d --- /dev/null +++ b/app/Jobs/Expense/CreateBillPayment.php @@ -0,0 +1,52 @@ +request = $request; + $this->bill = $bill; + } + + /** + * Execute the job. + * + * @return BillPayment + */ + public function handle() + { + $bill_payment = BillPayment::create($this->request->input()); + + $desc_amount = money((float) $bill_payment->amount, (string) $bill_payment->currency_code, true)->format(); + + $history_data = [ + 'company_id' => $bill_payment->company_id, + 'bill_id' => $bill_payment->bill_id, + 'status_code' => $this->bill->bill_status_code, + 'notify' => '0', + 'description' => $desc_amount . ' ' . trans_choice('general.payments', 1), + ]; + + BillHistory::create($history_data); + + return $bill_payment; + } +} diff --git a/app/Jobs/Expense/UpdateBill.php b/app/Jobs/Expense/UpdateBill.php new file mode 100644 index 000000000..1d712626d --- /dev/null +++ b/app/Jobs/Expense/UpdateBill.php @@ -0,0 +1,319 @@ +bill = $bill; + $this->request = $request; + } + + /** + * Execute the job. + * + * @return Bill + */ + public function handle() + { + // Upload attachment + if ($this->request->file('attachment')) { + $media = $this->getMedia($this->request->file('attachment'), 'bills'); + + $this->bill->attachMedia($media, 'attachment'); + } + + $taxes = []; + + $tax_total = 0; + $sub_total = 0; + $discount_total = 0; + $discount = $this->request['discount']; + + if ($this->request['item']) { + $this->deleteRelationships($this->bill, 'items'); + + foreach ($this->request['item'] as $item) { + $bill_item = dispatch(new CreateBillItem($item, $this->bill, $discount)); + + // Calculate totals + $tax_total += $bill_item->tax; + $sub_total += $bill_item->total; + + // Set taxes + foreach ($bill_item->item_taxes as $item_tax) { + if (isset($taxes) && array_key_exists($item_tax['tax_id'], $taxes)) { + $taxes[$item_tax['tax_id']]['amount'] += $item_tax['amount']; + } else { + $taxes[$item_tax['tax_id']] = [ + 'name' => $item_tax['name'], + 'amount' => $item_tax['amount'] + ]; + } + } + } + } + + $s_total = $sub_total; + + // Apply discount to total + if ($discount) { + $s_discount = $s_total * ($discount / 100); + $discount_total += $s_discount; + $s_total = $s_total - $s_discount; + } + + $amount = $s_total + $tax_total; + + $this->request['amount'] = money($amount, $this->request['currency_code'])->getAmount(); + + $this->bill->update($this->request->input()); + + // Delete previous bill totals + $this->deleteRelationships($this->bill, 'totals'); + + // Add bill totals + $this->addTotals($this->bill, $this->request, $taxes, $sub_total, $discount_total, $tax_total); + + // Recurring + $this->bill->updateRecurring(); + + // Fire the event to make it extensible + event(new BillUpdated($this->bill)); + + return $this->bill; + } + + protected function addTotals($bill, $request, $taxes, $sub_total, $discount_total, $tax_total) + { + $sort_order = 1; + + // Added bill sub total + BillTotal::create([ + 'company_id' => $request['company_id'], + 'bill_id' => $bill->id, + 'code' => 'sub_total', + 'name' => 'bills.sub_total', + 'amount' => $sub_total, + 'sort_order' => $sort_order, + ]); + + $sort_order++; + + // Added bill discount + if ($discount_total) { + BillTotal::create([ + 'company_id' => $request['company_id'], + 'bill_id' => $bill->id, + 'code' => 'discount', + 'name' => 'bills.discount', + 'amount' => $discount_total, + 'sort_order' => $sort_order, + ]); + + // This is for total + $sub_total = $sub_total - $discount_total; + + $sort_order++; + } + + // Added bill taxes + if (isset($taxes)) { + foreach ($taxes as $tax) { + BillTotal::create([ + 'company_id' => $request['company_id'], + 'bill_id' => $bill->id, + 'code' => 'tax', + 'name' => $tax['name'], + 'amount' => $tax['amount'], + 'sort_order' => $sort_order, + ]); + + $sort_order++; + } + } + + // Added bill total + BillTotal::create([ + 'company_id' => $request['company_id'], + 'bill_id' => $bill->id, + 'code' => 'total', + 'name' => 'bills.total', + 'amount' => $sub_total + $tax_total, + 'sort_order' => $sort_order, + ]); + } + + /** + * Mass delete relationships with events being fired. + * + * @param $model + * @param $relationships + * + * @return void + */ + public function deleteRelationships($model, $relationships) + { + foreach ((array) $relationships as $relationship) { + if (empty($model->$relationship)) { + continue; + } + + $items = $model->$relationship->all(); + + if ($items instanceof Collection) { + $items = $items->all(); + } + + foreach ((array) $items as $item) { + $item->delete(); + } + } + } + + function test() { + + $taxes = []; + + $tax_total = 0; + $sub_total = 0; + $discount_total = 0; + $discount = $request['discount']; + + $bill_item = []; + $bill_item['company_id'] = $request['company_id']; + $bill_item['bill_id'] = $bill->id; + + if ($request['item']) { + $this->deleteRelationships($bill, 'items'); + + foreach ($request['item'] as $item) { + unset($tax_object); + $item_sku = ''; + + if (!empty($item['item_id'])) { + $item_object = Item::find($item['item_id']); + + $item['name'] = $item_object->name; + $item_sku = $item_object->sku; + } + + $item_tax = 0; + $item_taxes = []; + $bill_item_taxes = []; + + if (!empty($item['tax_id'])) { + foreach ($item['tax_id'] as $tax_id) { + $tax_object = Tax::find($tax_id); + + $item_taxes[] = $tax_id; + + $tax = (((double) $item['price'] * (double) $item['quantity']) / 100) * $tax_object->rate; + + // Apply discount to tax + if ($discount) { + $tax = $tax - ($tax * ($discount / 100)); + } + + $bill_item_taxes[] = [ + 'company_id' => $request['company_id'], + 'bill_id' => $bill->id, + 'tax_id' => $tax_id, + 'name' => $tax_object->name, + 'amount' => $tax, + ]; + + $item_tax += $tax; + } + } + + $bill_item['item_id'] = $item['item_id']; + $bill_item['name'] = str_limit($item['name'], 180, ''); + $bill_item['sku'] = $item_sku; + $bill_item['quantity'] = (double) $item['quantity']; + $bill_item['price'] = (double) $item['price']; + $bill_item['tax'] = $item_tax; + $bill_item['tax_id'] = 0;//$tax_id; + $bill_item['total'] = (double) $item['price'] * (double) $item['quantity']; + + $tax_total += $item_tax; + $sub_total += $bill_item['total']; + + $bill_item_created = BillItem::create($bill_item); + + if ($bill_item_taxes) { + foreach ($bill_item_taxes as $bill_item_tax) { + $bill_item_tax['bill_item_id'] = $bill_item_created->id; + + BillItemTax::create($bill_item_tax); + + // Set taxes + if (isset($taxes) && array_key_exists($bill_item_tax['tax_id'], $taxes)) { + $taxes[$bill_item_tax['tax_id']]['amount'] += $bill_item_tax['amount']; + } else { + $taxes[$bill_item_tax['tax_id']] = [ + 'name' => $bill_item_tax['name'], + 'amount' => $bill_item_tax['amount'] + ]; + } + } + } + } + } + + $s_total = $sub_total; + + // Apply discount to total + if ($discount) { + $s_discount = $s_total * ($discount / 100); + $discount_total += $s_discount; + $s_total = $s_total - $s_discount; + } + + $amount = $s_total + $tax_total; + + $request['amount'] = money($amount, $request['currency_code'])->getAmount(); + + $bill->update($request->input()); + + // Upload attachment + if ($request->file('attachment')) { + $media = $this->getMedia($request->file('attachment'), 'bills'); + + $bill->attachMedia($media, 'attachment'); + } + + // Delete previous bill totals + $this->deleteRelationships($bill, 'totals'); + + // Add bill totals + $this->addTotals($bill, $request, $taxes, $sub_total, $discount_total, $tax_total); + + // Recurring + $bill->updateRecurring(); + + // Fire the event to make it extendible + event(new BillUpdated($bill)); + } +}