237 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			237 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| namespace App\Jobs\Purchase;
 | |
| 
 | |
| use App\Abstracts\Job;
 | |
| use App\Events\Purchase\BillUpdated;
 | |
| use App\Events\Purchase\BillUpdating;
 | |
| use App\Models\Purchase\Bill;
 | |
| use App\Models\Purchase\BillTotal;
 | |
| use App\Traits\Currencies;
 | |
| use App\Traits\DateTime;
 | |
| use App\Traits\Relationships;
 | |
| 
 | |
| class UpdateBill extends Job
 | |
| {
 | |
|     use Currencies, DateTime, Relationships;
 | |
| 
 | |
|     protected $bill;
 | |
| 
 | |
|     protected $request;
 | |
| 
 | |
|     /**
 | |
|      * Create a new job instance.
 | |
|      *
 | |
|      * @param  $request
 | |
|      */
 | |
|     public function __construct($bill, $request)
 | |
|     {
 | |
|         $this->bill = $bill;
 | |
|         $this->request = $this->getRequestInstance($request);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Execute the job.
 | |
|      *
 | |
|      * @return Bill
 | |
|      */
 | |
|     public function handle()
 | |
|     {
 | |
|         if (empty($this->request['amount'])) {
 | |
|             $this->request['amount'] = 0;
 | |
|         }
 | |
| 
 | |
|         event(new BillUpdating($this->bill, $this->request));
 | |
| 
 | |
|         // Upload attachment
 | |
|         if ($this->request->file('attachment')) {
 | |
|             $media = $this->getMedia($this->request->file('attachment'), 'bills');
 | |
| 
 | |
|             $this->bill->attachMedia($media, 'attachment');
 | |
|         }
 | |
| 
 | |
|         $this->createItemsAndTotals();
 | |
| 
 | |
|         $bill_paid = $this->bill->paid;
 | |
| 
 | |
|         unset($this->bill->reconciled);
 | |
| 
 | |
|         if (($bill_paid) && $this->request['amount'] > $bill_paid) {
 | |
|             $this->request['status'] = 'partial';
 | |
|         }
 | |
| 
 | |
|         $this->bill->update($this->request->input());
 | |
| 
 | |
|         $this->bill->updateRecurring();
 | |
| 
 | |
|         event(new BillUpdated($this->bill));
 | |
| 
 | |
|         return $this->bill;
 | |
|     }
 | |
| 
 | |
|     protected function createItemsAndTotals()
 | |
|     {
 | |
|         // Create items
 | |
|         list($sub_total, $discount_amount_total, $taxes) = $this->createItems();
 | |
| 
 | |
|         // Delete current totals
 | |
|         $this->deleteRelationships($this->bill, 'totals');
 | |
| 
 | |
|         $sort_order = 1;
 | |
| 
 | |
|         // Add sub total
 | |
|         BillTotal::create([
 | |
|             'company_id' => $this->bill->company_id,
 | |
|             'bill_id' => $this->bill->id,
 | |
|             'code' => 'sub_total',
 | |
|             'name' => 'bills.sub_total',
 | |
|             'amount' => $sub_total,
 | |
|             'sort_order' => $sort_order,
 | |
|         ]);
 | |
| 
 | |
|         $this->request['amount'] += $sub_total;
 | |
| 
 | |
|         $sort_order++;
 | |
| 
 | |
|         // Add discount
 | |
|         if ($discount_amount_total > 0) {
 | |
|             BillTotal::create([
 | |
|                 'company_id' => $this->bill->company_id,
 | |
|                 'bill_id' => $this->bill->id,
 | |
|                 'code' => 'item_discount',
 | |
|                 'name' => 'bills.item_discount',
 | |
|                 'amount' => $discount_amount_total,
 | |
|                 'sort_order' => $sort_order,
 | |
|             ]);
 | |
| 
 | |
|             $this->request['amount'] -= $discount_amount_total;
 | |
| 
 | |
|             $sort_order++;
 | |
|         }
 | |
| 
 | |
|         if (!empty($this->request['discount'])) {
 | |
|             $discount_total = ($sub_total - $discount_amount_total) * ($this->request['discount'] / 100);
 | |
| 
 | |
|             BillTotal::create([
 | |
|                 'company_id' => $this->bill->company_id,
 | |
|                 'bill_id' => $this->bill->id,
 | |
|                 'code' => 'discount',
 | |
|                 'name' => 'bills.discount',
 | |
|                 'amount' => $discount_total,
 | |
|                 'sort_order' => $sort_order,
 | |
|             ]);
 | |
| 
 | |
|             $this->request['amount'] -= $discount_total;
 | |
| 
 | |
|             $sort_order++;
 | |
|         }
 | |
| 
 | |
|         // Add taxes
 | |
|         if (!empty($taxes)) {
 | |
|             foreach ($taxes as $tax) {
 | |
|                 BillTotal::create([
 | |
|                     'company_id' => $this->bill->company_id,
 | |
|                     'bill_id' => $this->bill->id,
 | |
|                     'code' => 'tax',
 | |
|                     'name' => $tax['name'],
 | |
|                     'amount' => $tax['amount'],
 | |
|                     'sort_order' => $sort_order,
 | |
|                 ]);
 | |
| 
 | |
|                 $this->request['amount'] += $tax['amount'];
 | |
| 
 | |
|                 $sort_order++;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // Add extra totals, i.e. shipping fee
 | |
|         if (!empty($this->request['totals'])) {
 | |
|             foreach ($this->request['totals'] as $total) {
 | |
|                 $total['company_id'] = $this->bill->company_id;
 | |
|                 $total['bill_id'] = $this->bill->id;
 | |
|                 $total['sort_order'] = $sort_order;
 | |
| 
 | |
|                 if (empty($total['code'])) {
 | |
|                     $total['code'] = 'extra';
 | |
|                 }
 | |
| 
 | |
|                 BillTotal::create($total);
 | |
| 
 | |
|                 if (empty($total['operator']) || ($total['operator'] == 'addition')) {
 | |
|                     $this->request['amount'] += $total['amount'];
 | |
|                 } else {
 | |
|                     // subtraction
 | |
|                     $this->request['amount'] -= $total['amount'];
 | |
|                 }
 | |
| 
 | |
|                 $sort_order++;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // Add total
 | |
|         BillTotal::create([
 | |
|             'company_id' => $this->bill->company_id,
 | |
|             'bill_id' => $this->bill->id,
 | |
|             'code' => 'total',
 | |
|             'name' => 'bills.total',
 | |
|             'amount' => $this->request['amount'],
 | |
|             'sort_order' => $sort_order,
 | |
|         ]);
 | |
|     }
 | |
| 
 | |
|     protected function createItems()
 | |
|     {
 | |
|         $sub_total = $discount_amount = $discount_amount_total = 0;
 | |
| 
 | |
|         $taxes = [];
 | |
| 
 | |
|         if (empty($this->request['items'])) {
 | |
|             return [$sub_total, $discount_amount_total, $taxes];
 | |
|         }
 | |
| 
 | |
|         // Delete current items
 | |
|         $this->deleteRelationships($this->bill, ['items', 'item_taxes']);
 | |
| 
 | |
|         foreach ((array) $this->request['items'] as $item) {
 | |
|             $item['global_discount'] = 0;
 | |
| 
 | |
|             if (!empty($this->request['discount'])) {
 | |
|                 $item['global_discount'] = $this->request['discount'];
 | |
|             }
 | |
| 
 | |
|             $bill_item = $this->dispatch(new CreateBillItem($item, $this->bill));
 | |
| 
 | |
|             $item_amount = (double) $item['price'] * (double) $item['quantity'];
 | |
| 
 | |
|             $discount_amount = 0;
 | |
| 
 | |
|             if (!empty($item['discount'])) {
 | |
|                 $discount_amount = ($item_amount * ($item['discount'] / 100));
 | |
|             }
 | |
| 
 | |
|             // Calculate totals
 | |
|             $sub_total += $bill_item->total + $discount_amount;
 | |
| 
 | |
|             $discount_amount_total += $discount_amount;
 | |
| 
 | |
|             if (!$bill_item->item_taxes) {
 | |
|                 continue;
 | |
|             }
 | |
| 
 | |
|             // Set taxes
 | |
|             foreach ((array) $bill_item->item_taxes as $item_tax) {
 | |
|                 if (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 [$sub_total, $discount_amount_total, $taxes];
 | |
|     }
 | |
| }
 |