diff --git a/Modules/Sale/Database/Migrations/2021_08_07_192203_create_sale_payments_table.php b/Modules/Sale/Database/Migrations/2021_08_07_192203_create_sale_payments_table.php new file mode 100644 index 00000000..6323eef7 --- /dev/null +++ b/Modules/Sale/Database/Migrations/2021_08_07_192203_create_sale_payments_table.php @@ -0,0 +1,38 @@ +id(); + $table->unsignedBigInteger('sale_id'); + $table->integer('amount'); + $table->date('date'); + $table->string('reference'); + $table->string('payment_method'); + $table->text('note')->nullable(); + $table->foreign('sale_id')->references('id')->on('sale_payments')->cascadeOnDelete(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('sale_payments'); + } +} diff --git a/Modules/Sale/Entities/Sale.php b/Modules/Sale/Entities/Sale.php index b07f364b..35f1cd04 100644 --- a/Modules/Sale/Entities/Sale.php +++ b/Modules/Sale/Entities/Sale.php @@ -15,6 +15,10 @@ class Sale extends Model return $this->hasMany(SaleDetails::class, 'sale_id', 'id'); } + public function salePayments() { + return $this->hasMany(SalePayment::class, 'sale_id', 'id'); + } + public function getReferenceAttribute($value) { return strtoupper($value) . '_' . str_pad($this->attributes['id'], 6, '0', STR_PAD_LEFT); } diff --git a/Modules/Sale/Entities/SalePayment.php b/Modules/Sale/Entities/SalePayment.php new file mode 100644 index 00000000..6f11956b --- /dev/null +++ b/Modules/Sale/Entities/SalePayment.php @@ -0,0 +1,35 @@ +belongsTo(Sale::class, 'sale_id', 'id'); + } + + public function setAmountAttribute($value) { + $this->attributes['amount'] = $value * 100; + } + + public function getAmountAttribute($value) { + return $value / 100; + } + + public function getDateAttribute($value) { + return Carbon::parse($value)->format('d M, Y'); + } + + public function scopeBySale($query) { + return $query->where('sale_id', request()->route('sale_id')); + } +} diff --git a/Modules/Sale/Http/Controllers/SaleController.php b/Modules/Sale/Http/Controllers/SaleController.php index bf469992..03f97235 100644 --- a/Modules/Sale/Http/Controllers/SaleController.php +++ b/Modules/Sale/Http/Controllers/SaleController.php @@ -13,6 +13,7 @@ use Modules\People\Entities\Customer; use Modules\Product\Entities\Product; use Modules\Sale\Entities\Sale; use Modules\Sale\Entities\SaleDetails; +use Modules\Sale\Entities\SalePayment; use Modules\Sale\Http\Requests\StoreSaleRequest; use Modules\Sale\Http\Requests\UpdateSaleRequest; @@ -89,6 +90,14 @@ class SaleController extends Controller } Cart::instance('sale')->destroy(); + + SalePayment::create([ + 'date' => $request->date, + 'reference' => 'INV/'.$sale->reference, + 'amount' => $sale->paid_amount, + 'sale_id' => $sale->id, + 'payment_method' => $request->payment_method + ]); }); toast('Sale Created!', 'success'); diff --git a/Modules/Sale/Http/Controllers/SalePaymentsController.php b/Modules/Sale/Http/Controllers/SalePaymentsController.php new file mode 100644 index 00000000..bce4dc27 --- /dev/null +++ b/Modules/Sale/Http/Controllers/SalePaymentsController.php @@ -0,0 +1,146 @@ +render('sale::payments.index', compact('sale')); + } + + + public function create($sale_id) { + abort_if(Gate::denies('access_sale_payments'), 403); + + $sale = Sale::findOrFail($sale_id); + + return view('sale::payments.create', compact('sale')); + } + + + public function store(Request $request) { + abort_if(Gate::denies('access_sale_payments'), 403); + + $request->validate([ + 'date' => 'required|date', + 'reference' => 'required|string|max:255', + 'amount' => 'required|numeric', + 'note' => 'nullable|string|max:1000', + 'sale_id' => 'required', + 'payment_method' => 'required|string|max:255' + ]); + + DB::transaction(function () use ($request) { + SalePayment::create([ + 'date' => $request->date, + 'reference' => $request->reference, + 'amount' => $request->amount, + 'note' => $request->note, + 'sale_id' => $request->sale_id, + 'payment_method' => $request->payment_method + ]); + + $sale = Sale::findOrFail($request->sale_id); + + $due_amount = $sale->due_amount - $request->amount; + if ($due_amount == $sale->total_amount) { + $payment_status = 'Unpaid'; + } elseif ($due_amount > 0) { + $payment_status = 'Partial'; + } else { + $payment_status = 'Paid'; + } + + $sale->update([ + 'paid_amount' => ($sale->paid_amount + $request->amount) * 100, + 'due_amount' => $due_amount * 100, + 'payment_status' => $payment_status + ]); + }); + + toast('Sale Payment Created!', 'success'); + + return redirect()->route('sales.index'); + } + + + public function edit($sale_id, SalePayment $salePayment) { + abort_if(Gate::denies('access_sale_payments'), 403); + + $sale = Sale::findOrFail($sale_id); + + return view('sale::payments.edit', compact('salePayment', 'sale')); + } + + + public function update(Request $request, SalePayment $salePayment) { + abort_if(Gate::denies('access_sale_payments'), 403); + + $request->validate([ + 'date' => 'required|date', + 'reference' => 'required|string|max:255', + 'amount' => 'required|numeric', + 'note' => 'nullable|string|max:1000', + 'sale_id' => 'required', + 'payment_method' => 'required|string|max:255' + ]); + + DB::transaction(function () use ($request, $salePayment) { + $sale = $salePayment->sale; + + $due_amount = ($sale->due_amount + $salePayment->amount) - $request->amount; + + if ($due_amount == $sale->total_amount) { + $payment_status = 'Unpaid'; + } elseif ($due_amount > 0) { + $payment_status = 'Partial'; + } else { + $payment_status = 'Paid'; + } + + $sale->update([ + 'paid_amount' => (($sale->paid_amount - $salePayment->amount) + $request->amount) * 100, + 'due_amount' => $due_amount * 100, + 'payment_status' => $payment_status + ]); + + $salePayment->update([ + 'date' => $request->date, + 'reference' => $request->reference, + 'amount' => $request->amount, + 'note' => $request->note, + 'sale_id' => $request->sale_id, + 'payment_method' => $request->payment_method + ]); + }); + + toast('Sale Payment Updated!', 'info'); + + return redirect()->route('sales.index'); + } + + + public function destroy(SalePayment $salePayment) { + abort_if(Gate::denies('access_sale_payments'), 403); + + $salePayment->delete(); + + toast('Sale Payment Deleted!', 'warning'); + + return redirect()->route('sales.index'); + } +} diff --git a/Modules/Sale/Resources/views/edit.blade.php b/Modules/Sale/Resources/views/edit.blade.php index 931b8ed0..f8373f28 100644 --- a/Modules/Sale/Resources/views/edit.blade.php +++ b/Modules/Sale/Resources/views/edit.blade.php @@ -30,7 +30,7 @@