File manager - Edit - /var/www/payraty/inventory_main/app/Services/Invoice/InvoiceService.php
Back
<?php namespace App\Services\Invoice; use App\Models\SaleReturn; use App\Models\SaleReturnItemRequest; use App\Models\SaleReturnItems; use App\Models\SaleReturnRequest; use App\Traits\ApiReturnFormatTrait; use PDF; use Throwable; use Carbon\Carbon; use App\Models\Invoice; use App\Models\Product; use App\Mail\InvoiceSend; use App\Models\Warehouse; use App\Models\InvoiceItem; use Illuminate\Support\Str; use App\Models\ProductStock; use App\Services\BaseService; use App\Models\InvoicePayment; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Mail; use App\Services\Payments\PaypalService; use App\Services\Payments\StripeService; use App\Services\Product\ProductService; /** * InvoiceService */ class InvoiceService extends BaseService { use ApiReturnFormatTrait; protected $productService; protected $stripeService; protected $paypalService; protected $productStock; protected $product; /** * __construct * * @return void */ public function __construct() { $model = new Invoice(); parent::__construct($model); $this->productService = app(ProductService::class); $this->stripeService = app(StripeService::class); $this->paypalService = app(PaypalService::class); $this->productStock = app(ProductStock::class); $this->product = app(Product::class); } /** * getAllStatus * * @return array */ public function getAllStatus(): array { try { return $this->model::INVOICE_ALL_STATUS; } catch (Throwable $th) { throw $th; } } /** * filterPaymentByDateRange * * @param mixed $start * @param mixed $end * @param mixed $with * @return void */ public function filterPaymentByDateRange($start = null, $end = null, $with = []) { try { $query = InvoicePayment::query()->with($with); if ($start) { $query->whereDate('date', '>=', $start); } if ($end) { $query->whereDate('date', '<=', $end); } return $query->when(request('warehouse'), function ($q){ $q->whereHas('invoice.warehouse', function ($q){ $q->where('warehouse_id', request('warehouse')); }); }) ->when(Auth()->guard('customer')->check(), function($q){ $q->whereHas('invoice', function ($q){ $q->where('customer_id', Auth()->guard('customer')->id()); }); }) ->when(Auth()->guard('api_customer')->check(), function($q){ $q->whereHas('invoice', function ($q){ $q->where('customer_id', Auth()->guard('api_customer')->id()); }); }) ->whereNotNull('amount')->orderBy('date', 'DESC')->get(); } catch (Throwable $th) { throw $th; } } public function invoiceCustomerEmail($id) { $invoice = $this->get($id); if ($invoice->customer_id) { return $invoice->customer['email']; } else { return ''; } } /** * getAllPayments * * @return void */ public function getAllPayments($with = []) { return InvoicePayment::with($with) ->when(request('warehouse'), function ($q){ $q->whereHas('invoice.warehouse', function ($q){ $q->where('warehouse_id', request('warehouse')); }); }) ->when(Auth()->guard('customer')->check(), function($q){ $q->whereHas('invoice', function ($q){ $q->where('customer_id', Auth()->guard('customer')->id()); }); }) ->when(Auth()->guard('api_customer')->check(), function($q){ $q->whereHas('invoice', function ($q){ $q->where('customer_id', Auth()->guard('api_customer')->id()); }); }) ->whereNotNull('amount')->get(); } /** * filterByDateRange * * @param mixed $start * @param mixed $end * @param mixed $with * @return void */ public function filterByDateRange($start = null, $end = null, $with = []) { try { $query = $this->model::query()->with($with); if ($start) { $query->whereDate('date', '>=', $start); } if ($end) { $query->whereDate('date', '<=', $end); } return $query->when(request('warehouse'), function($q) { return $q->where('warehouse_id', request('warehouse')); }) ->when(Auth::guard('customer')->check(), function($q) { return $q->where('customer_id', Auth::guard('customer')->id()); }) ->when(Auth::guard('api_customer')->check(), function($q) { return $q->where('customer_id', Auth::guard('api_customer')->id()); }) ->orderBy('date', 'DESC') ->get(); } catch (Throwable $th) { throw $th; } } public function filterWareHouseWiseAll($with = []) { try { return $this->model::query() ->with($with) ->when(request('warehouse'), function($q) { return $q->where('warehouse_id', request('warehouse')); }) ->when(Auth::guard('customer')->check(), function($q) { return $q->where('customer_id', Auth::guard('customer')->id()); }) ->when(Auth::guard('api_customer')->check(), function($q) { return $q->where('customer_id', Auth::guard('api_customer')->id()); }) ->orderBy('date', 'DESC') ->get(); } catch (Throwable $th) { throw $th; } } /** * download * * @param mixed $id * @return void */ public function download($id) { try { $invoice = $this->get($id, ['items']); if(auth()->guard('api_customer')->check()){ if(!$invoice){ return $this->responseWithError('Invoice not found',[],404); } if($invoice->customer_id != auth()->guard('api_customer')->user()->id){ return $this->responseWithError('You are not authorized to view this invoice',[],403); } } if(!$invoice){ abort(404); } $pdf = PDF::loadView('admin.invoices.pdf.invoice', ['data' => $invoice]); // return view('admin.invoices.pdf.invoice', ['data' => $invoice]); // return $pdf->stream('Invoice_'. make8digits($invoice->id) .'.pdf'); return $pdf->download('Invoice_'. make8digits($invoice->id) .'.pdf'); } catch (Throwable $th) { if(auth()->guard('api_customer')->check()){ return $this->responseWithError($th->getMessage(),[],500); } throw $th; } } /** * storeOrUpdate * * @param mixed $data * @param mixed $id * @return void */ public function storeOrUpdate(array $data, $id = null) { try { DB::beginTransaction(); if ($id) { $invoice = $this->model::findOrFail($id); } else { $invoice = new $this->model(); if(Auth()->guard('customer')->check()) { // $invoice->created_by = Auth()->guard('customer')->user()->id; }elseif(Auth()->guard('api_customer')->check()){ if($data['customer_id'] != Auth()->guard('api_customer')->user()->id) { $data['customer_id'] = Auth()->guard('api_customer')->user()->id; } // $invoice->created_by = Auth()->guard('api_customer')->user()->id; }else{ $invoice->created_by = Auth::id(); } } $invoice->date = Carbon::parse($data['date'])->format('Y-m-d H:i:s'); $invoice->due_date = Carbon::parse($data['due_date'])->format('Y-m-d H:i:s'); $invoice->customer_id = $data['customer_id']; $invoice->customer = $data['customer']; $invoice->warehouse_id = $data['warehouse_id']; $invoice->billing_info = $data['billing']; $invoice->shipping_info = $data['shipping']; $invoice->items_data = $data['items']; $invoice->total_paid = ($data['payment_type'] == $this->model::PAYMENT_TYPE_CASH || $data['payment_type'] == $this->model::PAYMENT_TYPE_BANK) ? $data['total_paid'] : 0; $invoice->last_paid = $data['total_paid']; $invoice->payment_type = $data['payment_type']; if (isset($data['bank_info'])) { $invoice->bank_info = $data['bank_info'] ?? null; } $invoice->global_discount = $data['discount']; $invoice->global_discount_type = $data['discount_type']; $invoice->notes = $data['notes']; $invoice->status = $this->model::STATUS_PENDING; $invoice->token = Str::random(64); $invoice->updated_by = Auth::id(); if(Auth()->guard('customer')->check() || Auth()->guard('api_customer')->check()){ $invoice->delivery_status = $this->model::DELIVERY_STATUS_PENDING; $invoice->invoice_created_from = $this->model::CREATED_FROM_CUSTOMER; }else{ if(isset($data['is_delivered']) && $data['is_delivered'] != null && $data['is_delivered'] == true){ $invoice->delivery_status = $this->model::DELIVERY_STATUS_DELIVERED; }else{ $invoice->delivery_status = $this->model::DELIVERY_STATUS_PENDING; } } $invoice->save(); $gross_total = 0; $total_tax = 0; $total_discount = 0; if (request()->method() == "PUT") { $this->stockPlusUpdate($data['items'], $id); } // Delete old item InvoiceItem::where('invoice_id', $id)->delete(); // Add new item if ($data['items']) { foreach ($data['items'] as $item) { $product = $this->productService->get($item['product_id']); if (!$product) continue; $i_item = new InvoiceItem(); $i_item->invoice_id = $invoice->id; $i_item->product_id = $item['product_id']; $i_item->product_stock_id = $item['id']; $i_item->product_name = $product->name; $i_item->sku = $product->sku; $i_item->quantity = $item['quantity']; $i_item->price = $item['price']; $i_item->discount = $item['discount']; $i_item->discount_type = $item['discount_type']; $i_item->sub_total = $item['price'] * $item['quantity']; // Tax percent if ($product->tax_status == Product::TAX_INCLUDED) { if ($product->custom_tax) { $i_item->tax = $product->custom_tax; } else { $i_item->tax = getDefaultTax(); } } // Calculate discount $discount_amount = 0; if ($item['discount_type'] == $this->model::DISCOUNT_PERCENT) { $discount_amount = $item['price'] * ($item['discount'] / 100); } else { $discount_amount = $item['discount']; } $i_item->sub_total = ($item['price'] - $discount_amount) * $item['quantity']; $i_item->save(); $gross_total += $i_item->sub_total; // Calculate discount $total_discount += $discount_amount * $item['quantity']; // Calculate tax $tax_amount = $item['price'] * ($i_item->tax / 100); $total_tax += $tax_amount * $i_item->quantity; } } $this->stockUpdate($data['items']); // If update delete old paymets if ($id) { InvoicePayment::where('invoice_id', $id)->delete(); } // Invoice payment if ($data['payment_type'] == $this->model::PAYMENT_TYPE_CASH || $data['payment_type'] == $this->model::PAYMENT_TYPE_BANK) { $payment = new InvoicePayment(); $payment->invoice_id = $invoice->id; $payment->date = Carbon::parse($data['date'])->format('Y-m-d H:i:s'); $payment->payment_type = $data['payment_type']; $payment->amount = $data['total_paid']; $payment->bank_info = json_encode($invoice->bank_info); $payment->created_by = Auth::id(); $payment->save(); } $total = $gross_total; // Calculate global discount $global_discount_amount = 0; if ($data['discount_type'] == $this->model::DISCOUNT_PERCENT) { $global_discount_amount = $total * ($data['discount'] / 100); } else { $global_discount_amount = $item['discount']; } $total -= $global_discount_amount; $total_discount += $global_discount_amount; // Update invoice info $invoice->tax_amount = $total_tax; $invoice->discount_amount = $total_discount; $invoice->total = $total + $total_tax; // Update status if ($data['payment_type'] == $this->model::PAYMENT_TYPE_CASH && $data['total_paid'] > 0) { if ($data['total_paid'] >= $total) { $invoice->status = $this->model::STATUS_PAID; } else { $invoice->status = $this->model::STATUS_PARTIALLY_PAID; } } if((auth()->guard('customer')->check() || auth()->guard('api_customer')->check()) && $invoice->payment_type == 'online') { $invoice->status = $this->model::STATUS_PENDING; $invoice->last_paid = $total + $total_tax; $invoice->payment_type = 'online'; } $invoice->save(); DB::commit(); return $invoice; } catch (Throwable $th) { DB::rollBack(); throw $th; } } public function stockCheck($stock_id, $quantity) { $stock = ProductStock::find($stock_id); if($stock == null){ abort(422, 'Stock not available'); } if ($stock->quantity < $quantity) { if(auth()->guard('api_customer')->check() || auth()->guard('api')->check()){ return false; }else{ abort(422, 'Stock not available'); } } return true; } /** * addPayment * * @param mixed $data * @return void */ public function addPayment(array $data) { try { $invoice = $this->get($data['invoice_id']); $payment = new InvoicePayment(); $payment->invoice_id = $invoice->id; $payment->date = $data['date']; $payment->payment_type = $data['payment_type']; $payment->amount = $data['amount']; $payment->notes = $data['notes']; $payment->created_by = Auth::id(); if ($payment->save()) { $invoice->total_paid = $invoice->total_paid + $payment->amount; $invoice->save(); } return $payment; } catch (Throwable $th) { throw $th; } } /** * getPayments * * @param mixed $invoice_id * @return void */ public function getPayments($invoice_id) { try { return InvoicePayment::where('invoice_id', $invoice_id)->orderBy('id', 'DESC')->get(); } catch (Throwable $th) { throw $th; } } public function deleteInvoice($id) { try { DB::beginTransaction(); $invoice = Invoice::where('id', $id)->with('items')->first(); $invoice_items = $invoice->items; $invoice_sale_return_request = SaleReturnRequest::where('invoice_id', $id)->first(); $sale_return = SaleReturn::where('invoice_id', $id)->first(); foreach ($invoice_items as $invoice_item) { SaleReturnItemRequest::where('invoice_item_id', $invoice_item->id)->delete(); SaleReturnItems::where('invoice_item_id', $invoice_item->id)->delete(); } if ($invoice_sale_return_request) { $invoice_sale_return_request->delete(); } if($sale_return){ $sale_return->delete(); } if ($invoice->delete()) { DB::commit(); flash(__('custom.invoice_deleted_successful'))->success(); return true; } else { DB::rollBack(); flash(__('custom.invoice_deleted_failed'))->error(); return false; } return redirect()->route('admin.invoices.index'); } catch (Throwable $th) { DB::rollBack(); flash(__('custom.invoice_deleted_failed'))->error(); return false; } } public function deleteInvoiceByAPI($id) { try { DB::beginTransaction(); $invoice = Invoice::where('id', $id)->with('items')->first(); $invoice_items = $invoice->items; $invoice_sale_return_request = SaleReturnRequest::where('invoice_id', $id)->first(); $sale_return = SaleReturn::where('invoice_id', $id)->first(); foreach ($invoice_items as $invoice_item) { SaleReturnItemRequest::where('invoice_item_id', $invoice_item->id)->delete(); SaleReturnItems::where('invoice_item_id', $invoice_item->id)->delete(); } if ($invoice_sale_return_request) { $invoice_sale_return_request->delete(); } if($sale_return){ $sale_return->delete(); } if ($invoice->delete()) { DB::commit(); return true; } else { DB::rollBack(); return true; } } catch (Throwable $th) { DB::rollBack(); return false; } } /** * deletePayment * * @param mixed $id * @return void */ public function deletePayment($id) { try { $payment = InvoicePayment::findOrFail($id); // Get the invoice $invoice = $this->get($payment->invoice_id); // Adjust paid amount $invoice->total_paid = $invoice->total_paid - $payment->amount; $invoice->save(); if($invoice->total > $invoice->total_paid && $invoice->total_paid > 0) { $invoice->status = $this->model::STATUS_PARTIALLY_PAID; }elseif($invoice->total_paid == 0) { $invoice->status = $this->model::STATUS_PENDING; }elseif ($invoice->total_paid >= $invoice->total) { $invoice->status = $this->model::STATUS_PAID; } $invoice->save(); return $payment->delete(); } catch (Throwable $th) { throw $th; } } /** * sendInvoice * * @param mixed $data * @return void */ public function sendInvoice(array $data) { try { $invoice = $this->get($data['invoice_id']); return Mail::to($data['email'])->send(new InvoiceSend($invoice)); } catch (Throwable $th) { throw $th; } } /** * getByToken * * @param mixed $token * @return void */ public function getByToken($token) { try { return $this->model::where('token', $token)->first(); } catch (Throwable $th) { throw $th; } } /** * generateInvoiceNo * * @return void */ public function generateInvoiceNo() { // Generate invoice no $invoice_no = 1; $last_sale = $this->model::latest()->first(); if ($last_sale) $invoice_no = $last_sale->id + 1; return sprintf("%08d", $invoice_no); } /** * payByStripe * * @param mixed $invoice_id * @return void */ public function payByStripe($invoice_id) { $invoice = $this->get($invoice_id); if (!$invoice) abort(404); return $this->stripeService->pay($invoice); } /** * stripePaymentSuccess * * @param mixed $invoice_id * @return void */ public function stripePaymentSuccess($invoice_id) { $invoice = $this->get($invoice_id); if (!$invoice) abort(404); $invoice->total_paid = $invoice->total_paid + $invoice->last_paid; $invoice->payment_type = $this->model::PAYMENT_TYPE_STRIPE; if ($invoice->total_paid >= $invoice->total) { $invoice->status = $this->model::STATUS_PAID; } else { $invoice->status = $this->model::STATUS_PARTIALLY_PAID; } $invoice->save(); // Store payment $payment = new InvoicePayment(); $payment->invoice_id = $invoice->id; $payment->date = Carbon::parse(Carbon::now())->format('Y-m-d H:i:s'); $payment->payment_type = $invoice->payment_type; $payment->amount = $invoice->last_paid; $payment->save(); return true; } /** * paypalPaymentSuccess * * @param mixed $invoice_id * @param mixed $order_id * @return void */ public function paypalPaymentSuccess($invoice_id, $order_id) { $transaction_amount = $this->paypalService->getTransaction($order_id); if (!$transaction_amount) abort(404); $invoice = $this->get($invoice_id); if (!$invoice) abort(404); $invoice->total_paid = $invoice->total_paid + $transaction_amount; if ($invoice->total_paid >= $invoice->total) { $invoice->status = $this->model::STATUS_PAID; } else { $invoice->status = $this->model::STATUS_PARTIALLY_PAID; } $invoice->payment_type = $this->model::PAYMENT_TYPE_PAYPAL; $invoice->save(); // Store payment $payment = new InvoicePayment(); $payment->invoice_id = $invoice->id; $payment->date = Carbon::parse(Carbon::now())->format('Y-m-d H:i:s'); $payment->payment_type = $invoice->payment_type; $payment->amount = $transaction_amount; $payment->save(); return true; } /** * makePayment * * @param mixed $invoice_id * @param mixed $data * @return void */ public function makePayment($invoice_id, $data) { $invoice = $this->get($invoice_id); if (!$invoice) abort(404); $invoice->last_paid = $data['last_paid']; $invoice->payment_type = $data['payment_type']; if ($data['payment_type'] == $this->model::PAYMENT_TYPE_CASH || $data['payment_type'] == $this->model::PAYMENT_TYPE_BANK) { $invoice->total_paid = $invoice->total_paid + $data['last_paid']; $invoice->bank_info = json_encode($data['bank_info']) ?? null; if ($invoice->total_paid >= $invoice->total) { $invoice->status = $this->model::STATUS_PAID; } else { $invoice->status = $this->model::STATUS_PARTIALLY_PAID; } } else { $invoice->status = $this->model::STATUS_PENDING; } $invoice->save(); if ($data['payment_type'] == $this->model::PAYMENT_TYPE_CASH || $data['payment_type'] == $this->model::PAYMENT_TYPE_BANK) { // Store payment $payment = new InvoicePayment(); $payment->invoice_id = $invoice->id; $payment->date = Carbon::parse(Carbon::now())->format('Y-m-d H:i:s'); $payment->payment_type = $invoice->payment_type; $payment->amount = $invoice->last_paid; $payment->bank_info = json_encode($data['bank_info']) ?? null; $payment->save(); } return true; } /** * stockUpdate * * @param mixed $items * @return void */ private function stockUpdate($items) { if (isset($items)) { foreach ($items as $key => $item) { if ($item['id']) { $stock = $this->getStock($item['id']); if ($stock) { $stock->update([ 'quantity' => $stock->quantity - $item['quantity'] ]); } $productStock = $this->product->newQuery()->where('id', $item['product_id'])->first(); $productStock->update([ 'stock' => $productStock->stock - $item['quantity'] ]); } } } } private function stockPlusUpdate($items, $id) { if (isset($items)) { foreach ($items as $key => $item) { if ($item['id']) { $itemTableQuantity = optional(InvoiceItem::query() ->where('invoice_id', $id) ->where('product_id', $item['product_id']) ->where('product_stock_id', $item['id']) ->first())->quantity ?: 0; $stock = $this->getStock($item['id']); if ($stock) { $stock->update([ 'quantity' => $stock->quantity + $itemTableQuantity ]); } $productStock = $this->product->newQuery()->where('id', $item['product_id'])->first(); $productStock->update([ 'stock' => $productStock->stock + $itemTableQuantity ]); } } } } /** * getStock * * @param mixed $product * @return void */ public function getStock($product_stock_id) { return $this->productStock->newQuery()->where('id', $product_stock_id)->first(); // if (request('warehouse_id')){ // $defaultWarehouse = request('warehouse_id'); // }else{ // $defaultWarehouse = Warehouse::query()->where('is_default', true)->first()->id; // } // // return $this->productStock // ->newQuery() // ->where('product_id', $product) // ->where('warehouse_id', $defaultWarehouse) // ->first(); } public function deliveryStatusChange($id,$status) { $invoice = $this->get($id,'items.product'); if (!$invoice) abort(404); if($invoice->delivery_status == $this->model::DELIVERY_STATUS_CANCELED && $status != $this->model::DELIVERY_STATUS_CANCELED){ $this->stockUpdate($this->makeItemObj($invoice->items)); }elseif ($invoice->delivery_status == $this->model::DELIVERY_STATUS_DELIVERED && $status != $this->model::DELIVERY_STATUS_DELIVERED){ $this->stockPlusUpdate($this->makeItemObj($invoice->items),$id); } $invoice->delivery_status = $status; $invoice->save(); return true; } private function makeItemObj($items) { $itemObj = []; foreach ($items as $key => $item) { $itemObj[] = [ 'id' => $item->product_stock_id, 'product_id' => $item->product_id, 'split_sale' => optional($item->product)->split_sale, 'sku' => $item->sku, 'name' => $item->product_name, 'price' => $item->price, 'stock' => $item->product, 'quantity' => $item->quantity, 'tax_status' => $item->product, 'custom_tax' => $item->tax, 'discount' => $item->discount, 'discount_type' => $item->discount_type, ]; } return $itemObj; } public function getInvoiceList(){ $user_id = auth()->guard('api_customer')->check() ? auth()->guard('api_customer')->user()->id : (auth()->guard('customer')->check() ? auth()->guard('customer')->user()->id : null); return Invoice::with('warehouse') ->when($user_id, function ($query) use ($user_id) { $query->where('customer_id', $user_id); }) ->select('invoices.*')->paginate(10); } }
| ver. 1.4 |
Github
|
.
| PHP 8.3.30 | Generation time: 0 |
proxy
|
phpinfo
|
Settings