From 3f9ff855957e6c583f2620a2353317627b42f624 Mon Sep 17 00:00:00 2001 From: Fahim Date: Sun, 8 Aug 2021 21:52:15 +0600 Subject: [PATCH] Added: Sales Return Module & Sale Return Payments --- ..._021131_create_purchase_payments_table.php | 2 +- ...8_07_192203_create_sale_payments_table.php | 2 +- .../Sale/Http/Controllers/SaleController.php | 2 + .../Controllers/SalePaymentsController.php | 1 + .../Resources/views/partials/status.blade.php | 2 +- Modules/SalesReturn/Config/.gitkeep | 0 Modules/SalesReturn/Config/config.php | 5 + Modules/SalesReturn/Console/.gitkeep | 0 .../SalesReturn/Database/Migrations/.gitkeep | 0 ...08_08_175345_create_sale_returns_table.php | 48 ++++ ...75358_create_sale_return_details_table.php | 46 ++++ ...5406_create_sale_return_payments_table.php | 38 +++ Modules/SalesReturn/Database/Seeders/.gitkeep | 0 .../Seeders/SalesReturnDatabaseSeeder.php | 21 ++ .../SalesReturn/Database/factories/.gitkeep | 0 Modules/SalesReturn/Entities/.gitkeep | 0 Modules/SalesReturn/Entities/SaleReturn.php | 49 ++++ .../SalesReturn/Entities/SaleReturnDetail.php | 44 ++++ .../Entities/SaleReturnPayment.php | 34 +++ Modules/SalesReturn/Http/Controllers/.gitkeep | 0 .../SaleReturnPaymentsController.php | 147 +++++++++++ .../Controllers/SalesReturnController.php | 233 ++++++++++++++++++ Modules/SalesReturn/Http/Middleware/.gitkeep | 0 Modules/SalesReturn/Http/Requests/.gitkeep | 0 .../Http/Requests/StoreSaleReturnRequest.php | 40 +++ .../Http/Requests/UpdateSaleReturnRequest.php | 40 +++ Modules/SalesReturn/Providers/.gitkeep | 0 .../Providers/RouteServiceProvider.php | 69 ++++++ .../Providers/SalesReturnServiceProvider.php | 112 +++++++++ Modules/SalesReturn/Resources/assets/.gitkeep | 0 .../SalesReturn/Resources/assets/js/app.js | 0 .../Resources/assets/sass/app.scss | 0 Modules/SalesReturn/Resources/lang/.gitkeep | 0 Modules/SalesReturn/Resources/views/.gitkeep | 0 .../Resources/views/create.blade.php | 139 +++++++++++ .../Resources/views/edit.blade.php | 124 ++++++++++ .../Resources/views/index.blade.php | 40 +++ .../views/partials/actions.blade.php | 42 ++++ .../views/partials/payment-status.blade.php | 13 + .../Resources/views/partials/status.blade.php | 13 + .../Resources/views/payments/create.blade.php | 114 +++++++++ .../Resources/views/payments/edit.blade.php | 117 +++++++++ .../Resources/views/payments/index.blade.php | 37 +++ .../views/payments/partials/actions.blade.php | 19 ++ .../Resources/views/print.blade.php | 138 +++++++++++ .../Resources/views/show.blade.php | 140 +++++++++++ Modules/SalesReturn/Routes/.gitkeep | 0 Modules/SalesReturn/Routes/api.php | 18 ++ Modules/SalesReturn/Routes/web.php | 44 ++++ Modules/SalesReturn/Tests/Feature/.gitkeep | 0 Modules/SalesReturn/Tests/Unit/.gitkeep | 0 Modules/SalesReturn/composer.json | 23 ++ Modules/SalesReturn/module.json | 13 + Modules/SalesReturn/package.json | 17 ++ Modules/SalesReturn/webpack.mix.js | 14 ++ .../Seeders/PermissionsTableSeeder.php | 8 + app/DataTables/SalePaymentsDataTable.php | 5 - .../SaleReturnPaymentsDataTable.php | 78 ++++++ app/DataTables/SaleReturnsDataTable.php | 100 ++++++++ modules_statuses.json | 4 +- resources/views/layouts/menu.blade.php | 24 ++ 61 files changed, 2210 insertions(+), 9 deletions(-) create mode 100644 Modules/SalesReturn/Config/.gitkeep create mode 100644 Modules/SalesReturn/Config/config.php create mode 100644 Modules/SalesReturn/Console/.gitkeep create mode 100644 Modules/SalesReturn/Database/Migrations/.gitkeep create mode 100644 Modules/SalesReturn/Database/Migrations/2021_08_08_175345_create_sale_returns_table.php create mode 100644 Modules/SalesReturn/Database/Migrations/2021_08_08_175358_create_sale_return_details_table.php create mode 100644 Modules/SalesReturn/Database/Migrations/2021_08_08_175406_create_sale_return_payments_table.php create mode 100644 Modules/SalesReturn/Database/Seeders/.gitkeep create mode 100644 Modules/SalesReturn/Database/Seeders/SalesReturnDatabaseSeeder.php create mode 100644 Modules/SalesReturn/Database/factories/.gitkeep create mode 100644 Modules/SalesReturn/Entities/.gitkeep create mode 100644 Modules/SalesReturn/Entities/SaleReturn.php create mode 100644 Modules/SalesReturn/Entities/SaleReturnDetail.php create mode 100644 Modules/SalesReturn/Entities/SaleReturnPayment.php create mode 100644 Modules/SalesReturn/Http/Controllers/.gitkeep create mode 100644 Modules/SalesReturn/Http/Controllers/SaleReturnPaymentsController.php create mode 100644 Modules/SalesReturn/Http/Controllers/SalesReturnController.php create mode 100644 Modules/SalesReturn/Http/Middleware/.gitkeep create mode 100644 Modules/SalesReturn/Http/Requests/.gitkeep create mode 100644 Modules/SalesReturn/Http/Requests/StoreSaleReturnRequest.php create mode 100644 Modules/SalesReturn/Http/Requests/UpdateSaleReturnRequest.php create mode 100644 Modules/SalesReturn/Providers/.gitkeep create mode 100644 Modules/SalesReturn/Providers/RouteServiceProvider.php create mode 100644 Modules/SalesReturn/Providers/SalesReturnServiceProvider.php create mode 100644 Modules/SalesReturn/Resources/assets/.gitkeep create mode 100644 Modules/SalesReturn/Resources/assets/js/app.js create mode 100644 Modules/SalesReturn/Resources/assets/sass/app.scss create mode 100644 Modules/SalesReturn/Resources/lang/.gitkeep create mode 100644 Modules/SalesReturn/Resources/views/.gitkeep create mode 100644 Modules/SalesReturn/Resources/views/create.blade.php create mode 100644 Modules/SalesReturn/Resources/views/edit.blade.php create mode 100644 Modules/SalesReturn/Resources/views/index.blade.php create mode 100644 Modules/SalesReturn/Resources/views/partials/actions.blade.php create mode 100644 Modules/SalesReturn/Resources/views/partials/payment-status.blade.php create mode 100644 Modules/SalesReturn/Resources/views/partials/status.blade.php create mode 100644 Modules/SalesReturn/Resources/views/payments/create.blade.php create mode 100644 Modules/SalesReturn/Resources/views/payments/edit.blade.php create mode 100644 Modules/SalesReturn/Resources/views/payments/index.blade.php create mode 100644 Modules/SalesReturn/Resources/views/payments/partials/actions.blade.php create mode 100644 Modules/SalesReturn/Resources/views/print.blade.php create mode 100644 Modules/SalesReturn/Resources/views/show.blade.php create mode 100644 Modules/SalesReturn/Routes/.gitkeep create mode 100644 Modules/SalesReturn/Routes/api.php create mode 100644 Modules/SalesReturn/Routes/web.php create mode 100644 Modules/SalesReturn/Tests/Feature/.gitkeep create mode 100644 Modules/SalesReturn/Tests/Unit/.gitkeep create mode 100644 Modules/SalesReturn/composer.json create mode 100644 Modules/SalesReturn/module.json create mode 100644 Modules/SalesReturn/package.json create mode 100644 Modules/SalesReturn/webpack.mix.js create mode 100644 app/DataTables/SaleReturnPaymentsDataTable.php create mode 100644 app/DataTables/SaleReturnsDataTable.php diff --git a/Modules/Purchase/Database/Migrations/2021_08_08_021131_create_purchase_payments_table.php b/Modules/Purchase/Database/Migrations/2021_08_08_021131_create_purchase_payments_table.php index da8b2258..6f525ea6 100644 --- a/Modules/Purchase/Database/Migrations/2021_08_08_021131_create_purchase_payments_table.php +++ b/Modules/Purchase/Database/Migrations/2021_08_08_021131_create_purchase_payments_table.php @@ -21,7 +21,7 @@ class CreatePurchasePaymentsTable extends Migration $table->string('reference'); $table->string('payment_method'); $table->text('note')->nullable(); - $table->foreign('purchase_id')->references('id')->on('purchase_payments')->cascadeOnDelete(); + $table->foreign('purchase_id')->references('id')->on('purchases')->cascadeOnDelete(); $table->timestamps(); }); } 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 index 6323eef7..ed6cae77 100644 --- 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 @@ -21,7 +21,7 @@ class CreateSalePaymentsTable extends Migration $table->string('reference'); $table->string('payment_method'); $table->text('note')->nullable(); - $table->foreign('sale_id')->references('id')->on('sale_payments')->cascadeOnDelete(); + $table->foreign('sale_id')->references('id')->on('sales')->cascadeOnDelete(); $table->timestamps(); }); } diff --git a/Modules/Sale/Http/Controllers/SaleController.php b/Modules/Sale/Http/Controllers/SaleController.php index 03f97235..ff0f3302 100644 --- a/Modules/Sale/Http/Controllers/SaleController.php +++ b/Modules/Sale/Http/Controllers/SaleController.php @@ -39,6 +39,7 @@ class SaleController extends Controller public function store(StoreSaleRequest $request) { DB::transaction(function () use ($request) { $due_amount = $request->total_amount - $request->paid_amount; + if ($due_amount == $request->total_amount) { $payment_status = 'Unpaid'; } elseif ($due_amount > 0) { @@ -149,6 +150,7 @@ class SaleController extends Controller public function update(UpdateSaleRequest $request, Sale $sale) { DB::transaction(function () use ($request, $sale) { + $due_amount = $request->total_amount - $request->paid_amount; if ($due_amount == $request->total_amount) { $payment_status = 'Unpaid'; diff --git a/Modules/Sale/Http/Controllers/SalePaymentsController.php b/Modules/Sale/Http/Controllers/SalePaymentsController.php index bce4dc27..91ad1d9b 100644 --- a/Modules/Sale/Http/Controllers/SalePaymentsController.php +++ b/Modules/Sale/Http/Controllers/SalePaymentsController.php @@ -57,6 +57,7 @@ class SalePaymentsController extends Controller $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) { diff --git a/Modules/Sale/Resources/views/partials/status.blade.php b/Modules/Sale/Resources/views/partials/status.blade.php index 1960520b..e6f2dfe7 100644 --- a/Modules/Sale/Resources/views/partials/status.blade.php +++ b/Modules/Sale/Resources/views/partials/status.blade.php @@ -1,4 +1,4 @@ -d@if ($data->status == 'Pending') +@if ($data->status == 'Pending') {{ $data->status }} diff --git a/Modules/SalesReturn/Config/.gitkeep b/Modules/SalesReturn/Config/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/SalesReturn/Config/config.php b/Modules/SalesReturn/Config/config.php new file mode 100644 index 00000000..bb1b255d --- /dev/null +++ b/Modules/SalesReturn/Config/config.php @@ -0,0 +1,5 @@ + 'SalesReturn' +]; diff --git a/Modules/SalesReturn/Console/.gitkeep b/Modules/SalesReturn/Console/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/SalesReturn/Database/Migrations/.gitkeep b/Modules/SalesReturn/Database/Migrations/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/SalesReturn/Database/Migrations/2021_08_08_175345_create_sale_returns_table.php b/Modules/SalesReturn/Database/Migrations/2021_08_08_175345_create_sale_returns_table.php new file mode 100644 index 00000000..a42661af --- /dev/null +++ b/Modules/SalesReturn/Database/Migrations/2021_08_08_175345_create_sale_returns_table.php @@ -0,0 +1,48 @@ +id(); + $table->date('date'); + $table->string('reference'); + $table->unsignedBigInteger('customer_id')->nullable(); + $table->string('customer_name'); + $table->integer('tax_percentage')->default(0); + $table->integer('tax_amount')->default(0); + $table->integer('discount_percentage')->default(0); + $table->integer('discount_amount')->default(0); + $table->integer('shipping_amount')->default(0); + $table->integer('total_amount'); + $table->integer('paid_amount'); + $table->integer('due_amount'); + $table->string('status'); + $table->string('payment_status'); + $table->string('payment_method'); + $table->text('note')->nullable(); + $table->foreign('customer_id')->references('id')->on('customers')->nullOnDelete(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('sale_returns'); + } +} diff --git a/Modules/SalesReturn/Database/Migrations/2021_08_08_175358_create_sale_return_details_table.php b/Modules/SalesReturn/Database/Migrations/2021_08_08_175358_create_sale_return_details_table.php new file mode 100644 index 00000000..b2ab2cfa --- /dev/null +++ b/Modules/SalesReturn/Database/Migrations/2021_08_08_175358_create_sale_return_details_table.php @@ -0,0 +1,46 @@ +id(); + $table->unsignedBigInteger('sale_return_id'); + $table->unsignedBigInteger('product_id')->nullable(); + $table->string('product_name'); + $table->string('product_code'); + $table->integer('quantity'); + $table->integer('price'); + $table->integer('unit_price'); + $table->integer('sub_total'); + $table->integer('product_discount_amount'); + $table->string('product_discount_type')->default('fixed'); + $table->integer('product_tax_amount'); + $table->foreign('sale_return_id')->references('id') + ->on('sale_returns')->cascadeOnDelete(); + $table->foreign('product_id')->references('id') + ->on('products')->nullOnDelete(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('sale_return_details'); + } +} diff --git a/Modules/SalesReturn/Database/Migrations/2021_08_08_175406_create_sale_return_payments_table.php b/Modules/SalesReturn/Database/Migrations/2021_08_08_175406_create_sale_return_payments_table.php new file mode 100644 index 00000000..0a020875 --- /dev/null +++ b/Modules/SalesReturn/Database/Migrations/2021_08_08_175406_create_sale_return_payments_table.php @@ -0,0 +1,38 @@ +id(); + $table->unsignedBigInteger('sale_return_id'); + $table->integer('amount'); + $table->date('date'); + $table->string('reference'); + $table->string('payment_method'); + $table->text('note')->nullable(); + $table->foreign('sale_return_id')->references('id')->on('sale_returns')->cascadeOnDelete(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('sale_return_payments'); + } +} diff --git a/Modules/SalesReturn/Database/Seeders/.gitkeep b/Modules/SalesReturn/Database/Seeders/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/SalesReturn/Database/Seeders/SalesReturnDatabaseSeeder.php b/Modules/SalesReturn/Database/Seeders/SalesReturnDatabaseSeeder.php new file mode 100644 index 00000000..bdf64a6e --- /dev/null +++ b/Modules/SalesReturn/Database/Seeders/SalesReturnDatabaseSeeder.php @@ -0,0 +1,21 @@ +call("OthersTableSeeder"); + } +} diff --git a/Modules/SalesReturn/Database/factories/.gitkeep b/Modules/SalesReturn/Database/factories/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/SalesReturn/Entities/.gitkeep b/Modules/SalesReturn/Entities/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/SalesReturn/Entities/SaleReturn.php b/Modules/SalesReturn/Entities/SaleReturn.php new file mode 100644 index 00000000..96a55376 --- /dev/null +++ b/Modules/SalesReturn/Entities/SaleReturn.php @@ -0,0 +1,49 @@ +hasMany(SaleReturnDetail::class, 'sale_return_id', 'id'); + } + + public function saleReturnPayments() { + return $this->hasMany(SaleReturnPayment::class, 'sale_return_id', 'id'); + } + + public function getReferenceAttribute($value) { + return strtoupper($value) . '_' . str_pad($this->attributes['id'], 6, '0', STR_PAD_LEFT); + } + + public function getShippingAmountAttribute($value) { + return $value / 100; + } + + public function getPaidAmountAttribute($value) { + return $value / 100; + } + + public function getTotalAmountAttribute($value) { + return $value / 100; + } + + public function getDueAmountAttribute($value) { + return $value / 100; + } + + public function getTaxAmountAttribute($value) { + return $value / 100; + } + + public function getDiscountAmountAttribute($value) { + return $value / 100; + } +} diff --git a/Modules/SalesReturn/Entities/SaleReturnDetail.php b/Modules/SalesReturn/Entities/SaleReturnDetail.php new file mode 100644 index 00000000..9f7b5000 --- /dev/null +++ b/Modules/SalesReturn/Entities/SaleReturnDetail.php @@ -0,0 +1,44 @@ +belongsTo(Product::class, 'product_id', 'id'); + } + + public function saleReturn() { + return $this->belongsTo(SaleReturnPayment::class, 'sale_return_id', 'id'); + } + + public function getPriceAttribute($value) { + return $value / 100; + } + + public function getUnitPriceAttribute($value) { + return $value / 100; + } + + public function getSubTotalAttribute($value) { + return $value / 100; + } + + public function getProductDiscountAmountAttribute($value) { + return $value / 100; + } + + public function getProductTaxAmountAttribute($value) { + return $value / 100; + } +} diff --git a/Modules/SalesReturn/Entities/SaleReturnPayment.php b/Modules/SalesReturn/Entities/SaleReturnPayment.php new file mode 100644 index 00000000..eda96ee8 --- /dev/null +++ b/Modules/SalesReturn/Entities/SaleReturnPayment.php @@ -0,0 +1,34 @@ +belongsTo(SaleReturn::class, 'sale_return_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 scopeBySaleReturn($query) { + return $query->where('sale_return_id', request()->route('sale_return_id')); + } +} diff --git a/Modules/SalesReturn/Http/Controllers/.gitkeep b/Modules/SalesReturn/Http/Controllers/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/SalesReturn/Http/Controllers/SaleReturnPaymentsController.php b/Modules/SalesReturn/Http/Controllers/SaleReturnPaymentsController.php new file mode 100644 index 00000000..c54192ce --- /dev/null +++ b/Modules/SalesReturn/Http/Controllers/SaleReturnPaymentsController.php @@ -0,0 +1,147 @@ +render('salesreturn::payments.index', compact('sale_return')); + } + + + public function create($sale_return_id) { + abort_if(Gate::denies('access_sale_payments'), 403); + + $sale_return = SaleReturn::findOrFail($sale_return_id); + + return view('salesreturn::payments.create', compact('sale_return')); + } + + + 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_return_id' => 'required', + 'payment_method' => 'required|string|max:255' + ]); + + DB::transaction(function () use ($request) { + SaleReturnPayment::create([ + 'date' => $request->date, + 'reference' => $request->reference, + 'amount' => $request->amount, + 'note' => $request->note, + 'sale_return_id' => $request->sale_return_id, + 'payment_method' => $request->payment_method + ]); + + $sale_return = SaleReturn::findOrFail($request->sale_return_id); + + $due_amount = $sale_return->due_amount - $request->amount; + + if ($due_amount == $sale_return->total_amount) { + $payment_status = 'Unpaid'; + } elseif ($due_amount > 0) { + $payment_status = 'Partial'; + } else { + $payment_status = 'Paid'; + } + + $sale_return->update([ + 'paid_amount' => ($sale_return->paid_amount + $request->amount) * 100, + 'due_amount' => $due_amount * 100, + 'payment_status' => $payment_status + ]); + }); + + toast('Sale Return Payment Created!', 'success'); + + return redirect()->route('sale-returns.index'); + } + + + public function edit($sale_return_id, SaleReturnPayment $saleReturnPayment) { + abort_if(Gate::denies('access_sale_return_payments'), 403); + + $sale_return = SaleReturn::findOrFail($sale_return_id); + + return view('salesreturn::payments.edit', compact('saleReturnPayment', 'sale_return')); + } + + + public function update(Request $request, SaleReturnPayment $saleReturnPayment) { + abort_if(Gate::denies('access_sale_return_payments'), 403); + + $request->validate([ + 'date' => 'required|date', + 'reference' => 'required|string|max:255', + 'amount' => 'required|numeric', + 'note' => 'nullable|string|max:1000', + 'sale_return_id' => 'required', + 'payment_method' => 'required|string|max:255' + ]); + + DB::transaction(function () use ($request, $saleReturnPayment) { + $sale_return = $saleReturnPayment->saleReturn; + + $due_amount = ($sale_return->due_amount + $saleReturnPayment->amount) - $request->amount; + + if ($due_amount == $sale_return->total_amount) { + $payment_status = 'Unpaid'; + } elseif ($due_amount > 0) { + $payment_status = 'Partial'; + } else { + $payment_status = 'Paid'; + } + + $sale_return->update([ + 'paid_amount' => (($sale_return->paid_amount - $saleReturnPayment->amount) + $request->amount) * 100, + 'due_amount' => $due_amount * 100, + 'payment_status' => $payment_status + ]); + + $saleReturnPayment->update([ + 'date' => $request->date, + 'reference' => $request->reference, + 'amount' => $request->amount, + 'note' => $request->note, + 'sale_return_id' => $request->sale_return_id, + 'payment_method' => $request->payment_method + ]); + }); + + toast('Sale Return Payment Updated!', 'info'); + + return redirect()->route('sale-returns.index'); + } + + + public function destroy(SaleReturnPayment $saleReturnPayment) { + abort_if(Gate::denies('access_sale_return_payments'), 403); + + $saleReturnPayment->delete(); + + toast('Sale Return Payment Deleted!', 'warning'); + + return redirect()->route('sale-returns.index'); + } +} diff --git a/Modules/SalesReturn/Http/Controllers/SalesReturnController.php b/Modules/SalesReturn/Http/Controllers/SalesReturnController.php new file mode 100644 index 00000000..0613248d --- /dev/null +++ b/Modules/SalesReturn/Http/Controllers/SalesReturnController.php @@ -0,0 +1,233 @@ +render('salesreturn::index'); + } + + + public function create() { + abort_if(Gate::denies('create_sale_returns'), 403); + + Cart::instance('sale_return')->destroy(); + + return view('salesreturn::create'); + } + + + public function store(StoreSaleReturnRequest $request) { + DB::transaction(function () use ($request) { + $due_amount = $request->total_amount - $request->paid_amount; + + if ($due_amount == $request->total_amount) { + $payment_status = 'Unpaid'; + } elseif ($due_amount > 0) { + $payment_status = 'Partial'; + } else { + $payment_status = 'Paid'; + } + + $sale_return = SaleReturn::create([ + 'date' => $request->date, + 'reference' => $request->reference, + 'customer_id' => $request->customer_id, + 'customer_name' => Customer::findOrFail($request->customer_id)->customer_name, + 'tax_percentage' => $request->tax_percentage, + 'discount_percentage' => $request->discount_percentage, + 'shipping_amount' => $request->shipping_amount * 100, + 'paid_amount' => $request->paid_amount * 100, + 'total_amount' => $request->total_amount * 100, + 'due_amount' => $due_amount * 100, + 'status' => $request->status, + 'payment_status' => $payment_status, + 'payment_method' => $request->payment_method, + 'note' => $request->note, + 'tax_amount' => Cart::instance('sale_return')->tax() * 100, + 'discount_amount' => Cart::instance('sale_return')->discount() * 100, + ]); + + foreach (Cart::instance('sale_return')->content() as $cart_item) { + SaleReturnDetail::create([ + 'sale_return_id' => $sale_return->id, + 'product_id' => $cart_item->id, + 'product_name' => $cart_item->name, + 'product_code' => $cart_item->options->code, + 'quantity' => $cart_item->qty, + 'price' => $cart_item->price * 100, + 'unit_price' => $cart_item->options->unit_price * 100, + 'sub_total' => $cart_item->options->sub_total * 100, + 'product_discount_amount' => $cart_item->options->product_discount * 100, + 'product_discount_type' => $cart_item->options->product_discount_type, + 'product_tax_amount' => $cart_item->options->product_tax * 100, + ]); + + if ($request->status == 'Completed') { + $product = Product::findOrFail($cart_item->id); + $product->update([ + 'product_quantity' => $product->product_quantity + $cart_item->qty + ]); + } + } + + Cart::instance('sale_return')->destroy(); + + SaleReturnPayment::create([ + 'date' => $request->date, + 'reference' => 'INV/'.$sale_return->reference, + 'amount' => $sale_return->paid_amount, + 'sale_return_id' => $sale_return->id, + 'payment_method' => $request->payment_method + ]); + }); + + toast('Sale Return Created!', 'success'); + + return redirect()->route('sale-returns.index'); + } + + + public function show(SaleReturn $sale_return) { + abort_if(Gate::denies('show_sale_returns'), 403); + + $customer = Customer::findOrFail($sale_return->customer_id); + + return view('salesreturn::show', compact('sale_return', 'customer')); + } + + + public function edit(SaleReturn $sale_return) { + abort_if(Gate::denies('edit_sales'), 403); + + $sale_return_details = $sale_return->saleReturnDetails; + + Cart::instance('sale_return')->destroy(); + + $cart = Cart::instance('sale_return'); + + foreach ($sale_return_details as $sale_return_detail) { + $cart->add([ + 'id' => $sale_return_detail->product_id, + 'name' => $sale_return_detail->product_name, + 'qty' => $sale_return_detail->quantity, + 'price' => $sale_return_detail->price, + 'weight' => 1, + 'options' => [ + 'product_discount' => $sale_return_detail->product_discount_amount, + 'product_discount_type' => $sale_return_detail->product_discount_type, + 'sub_total' => $sale_return_detail->sub_total, + 'code' => $sale_return_detail->product_code, + 'stock' => Product::findOrFail($sale_return_detail->product_id)->product_quantity, + 'product_tax' => $sale_return_detail->product_tax_amount, + 'unit_price' => $sale_return_detail->unit_price + ] + ]); + } + + return view('salesreturn::edit', compact('sale_return')); + } + + + public function update(UpdateSaleReturnRequest $request, SaleReturn $sale_return) { + DB::transaction(function () use ($request, $sale_return) { + $due_amount = $request->total_amount - $request->paid_amount; + + if ($due_amount == $request->total_amount) { + $payment_status = 'Unpaid'; + } elseif ($due_amount > 0) { + $payment_status = 'Partial'; + } else { + $payment_status = 'Paid'; + } + + foreach ($sale_return->saleReturnDetails as $sale_return_detail) { + if ($sale_return->status == 'Completed') { + $product = Product::findOrFail($sale_return_detail->product_id); + $product->update([ + 'product_quantity' => $product->product_quantity - $sale_return_detail->quantity + ]); + } + $sale_return_detail->delete(); + } + + $sale_return->update([ + 'date' => $request->date, + 'reference' => $request->reference, + 'customer_id' => $request->customer_id, + 'customer_name' => Customer::findOrFail($request->customer_id)->customer_name, + 'tax_percentage' => $request->tax_percentage, + 'discount_percentage' => $request->discount_percentage, + 'shipping_amount' => $request->shipping_amount * 100, + 'paid_amount' => $request->paid_amount * 100, + 'total_amount' => $request->total_amount * 100, + 'due_amount' => $due_amount * 100, + 'status' => $request->status, + 'payment_status' => $payment_status, + 'payment_method' => $request->payment_method, + 'note' => $request->note, + 'tax_amount' => Cart::instance('sale_return')->tax() * 100, + 'discount_amount' => Cart::instance('sale_return')->discount() * 100, + ]); + + foreach (Cart::instance('sale_return')->content() as $cart_item) { + SaleReturnDetail::create([ + 'sale_return_id' => $sale_return->id, + 'product_id' => $cart_item->id, + 'product_name' => $cart_item->name, + 'product_code' => $cart_item->options->code, + 'quantity' => $cart_item->qty, + 'price' => $cart_item->price * 100, + 'unit_price' => $cart_item->options->unit_price * 100, + 'sub_total' => $cart_item->options->sub_total * 100, + 'product_discount_amount' => $cart_item->options->product_discount * 100, + 'product_discount_type' => $cart_item->options->product_discount_type, + 'product_tax_amount' => $cart_item->options->product_tax * 100, + ]); + + if ($request->status == 'Completed') { + $product = Product::findOrFail($cart_item->id); + $product->update([ + 'product_quantity' => $product->product_quantity + $cart_item->qty + ]); + } + } + + Cart::instance('sale_return')->destroy(); + }); + + toast('Sale Return Updated!', 'info'); + + return redirect()->route('sale-returns.index'); + } + + + public function destroy(SaleReturn $sale_return) { + abort_if(Gate::denies('delete_sale_returns'), 403); + + $sale_return->delete(); + + toast('Sale Return Deleted!', 'warning'); + + return redirect()->route('sale-returns.index'); + } +} diff --git a/Modules/SalesReturn/Http/Middleware/.gitkeep b/Modules/SalesReturn/Http/Middleware/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/SalesReturn/Http/Requests/.gitkeep b/Modules/SalesReturn/Http/Requests/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/SalesReturn/Http/Requests/StoreSaleReturnRequest.php b/Modules/SalesReturn/Http/Requests/StoreSaleReturnRequest.php new file mode 100644 index 00000000..a0aa186f --- /dev/null +++ b/Modules/SalesReturn/Http/Requests/StoreSaleReturnRequest.php @@ -0,0 +1,40 @@ + 'required|numeric', + 'reference' => 'required|string|max:255', + 'tax_percentage' => 'required|integer|min:0|max:100', + 'discount_percentage' => 'required|integer|min:0|max:100', + 'shipping_amount' => 'required|numeric', + 'total_amount' => 'required|numeric', + 'paid_amount' => 'required|numeric', + 'status' => 'required|string|max:255', + 'payment_method' => 'required|string|max:255', + 'note' => 'nullable|string|max:1000' + ]; + } + + /** + * Determine if the user is authorized to make this request. + * + * @return bool + */ + public function authorize() + { + return Gate::allows('create_sales'); + } +} diff --git a/Modules/SalesReturn/Http/Requests/UpdateSaleReturnRequest.php b/Modules/SalesReturn/Http/Requests/UpdateSaleReturnRequest.php new file mode 100644 index 00000000..50004f6a --- /dev/null +++ b/Modules/SalesReturn/Http/Requests/UpdateSaleReturnRequest.php @@ -0,0 +1,40 @@ + 'required|numeric', + 'reference' => 'required|string|max:255', + 'tax_percentage' => 'required|integer|min:0|max:100', + 'discount_percentage' => 'required|integer|min:0|max:100', + 'shipping_amount' => 'required|numeric', + 'total_amount' => 'required|numeric', + 'paid_amount' => 'required|numeric|max:' . $this->sale_return->total_amount, + 'status' => 'required|string|max:255', + 'payment_method' => 'required|string|max:255', + 'note' => 'nullable|string|max:1000' + ]; + } + + /** + * Determine if the user is authorized to make this request. + * + * @return bool + */ + public function authorize() + { + return Gate::allows('edit_sale_returns'); + } +} diff --git a/Modules/SalesReturn/Providers/.gitkeep b/Modules/SalesReturn/Providers/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/SalesReturn/Providers/RouteServiceProvider.php b/Modules/SalesReturn/Providers/RouteServiceProvider.php new file mode 100644 index 00000000..e4864eb1 --- /dev/null +++ b/Modules/SalesReturn/Providers/RouteServiceProvider.php @@ -0,0 +1,69 @@ +mapApiRoutes(); + + $this->mapWebRoutes(); + } + + /** + * Define the "web" routes for the application. + * + * These routes all receive session state, CSRF protection, etc. + * + * @return void + */ + protected function mapWebRoutes() + { + Route::middleware('web') + ->namespace($this->moduleNamespace) + ->group(module_path('SalesReturn', '/Routes/web.php')); + } + + /** + * Define the "api" routes for the application. + * + * These routes are typically stateless. + * + * @return void + */ + protected function mapApiRoutes() + { + Route::prefix('api') + ->middleware('api') + ->namespace($this->moduleNamespace) + ->group(module_path('SalesReturn', '/Routes/api.php')); + } +} diff --git a/Modules/SalesReturn/Providers/SalesReturnServiceProvider.php b/Modules/SalesReturn/Providers/SalesReturnServiceProvider.php new file mode 100644 index 00000000..288795cd --- /dev/null +++ b/Modules/SalesReturn/Providers/SalesReturnServiceProvider.php @@ -0,0 +1,112 @@ +registerTranslations(); + $this->registerConfig(); + $this->registerViews(); + $this->loadMigrationsFrom(module_path($this->moduleName, 'Database/Migrations')); + } + + /** + * Register the service provider. + * + * @return void + */ + public function register() + { + $this->app->register(RouteServiceProvider::class); + } + + /** + * Register config. + * + * @return void + */ + protected function registerConfig() + { + $this->publishes([ + module_path($this->moduleName, 'Config/config.php') => config_path($this->moduleNameLower . '.php'), + ], 'config'); + $this->mergeConfigFrom( + module_path($this->moduleName, 'Config/config.php'), $this->moduleNameLower + ); + } + + /** + * Register views. + * + * @return void + */ + public function registerViews() + { + $viewPath = resource_path('views/modules/' . $this->moduleNameLower); + + $sourcePath = module_path($this->moduleName, 'Resources/views'); + + $this->publishes([ + $sourcePath => $viewPath + ], ['views', $this->moduleNameLower . '-module-views']); + + $this->loadViewsFrom(array_merge($this->getPublishableViewPaths(), [$sourcePath]), $this->moduleNameLower); + } + + /** + * Register translations. + * + * @return void + */ + public function registerTranslations() + { + $langPath = resource_path('lang/modules/' . $this->moduleNameLower); + + if (is_dir($langPath)) { + $this->loadTranslationsFrom($langPath, $this->moduleNameLower); + } else { + $this->loadTranslationsFrom(module_path($this->moduleName, 'Resources/lang'), $this->moduleNameLower); + } + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides() + { + return []; + } + + private function getPublishableViewPaths(): array + { + $paths = []; + foreach (\Config::get('view.paths') as $path) { + if (is_dir($path . '/modules/' . $this->moduleNameLower)) { + $paths[] = $path . '/modules/' . $this->moduleNameLower; + } + } + return $paths; + } +} diff --git a/Modules/SalesReturn/Resources/assets/.gitkeep b/Modules/SalesReturn/Resources/assets/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/SalesReturn/Resources/assets/js/app.js b/Modules/SalesReturn/Resources/assets/js/app.js new file mode 100644 index 00000000..e69de29b diff --git a/Modules/SalesReturn/Resources/assets/sass/app.scss b/Modules/SalesReturn/Resources/assets/sass/app.scss new file mode 100644 index 00000000..e69de29b diff --git a/Modules/SalesReturn/Resources/lang/.gitkeep b/Modules/SalesReturn/Resources/lang/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/SalesReturn/Resources/views/.gitkeep b/Modules/SalesReturn/Resources/views/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/SalesReturn/Resources/views/create.blade.php b/Modules/SalesReturn/Resources/views/create.blade.php new file mode 100644 index 00000000..0a16503a --- /dev/null +++ b/Modules/SalesReturn/Resources/views/create.blade.php @@ -0,0 +1,139 @@ +@extends('layouts.app') + +@section('title', 'Create Sale Return') + +@section('breadcrumb') + +@endsection + +@section('content') +
+
+
+ +
+
+ +
+
+
+
+ @include('utils.alerts') +
+ @csrf + +
+
+
+ + +
+
+
+
+
+ + +
+
+
+
+
+
+ + +
+
+
+
+ + + +
+
+
+ + +
+
+
+
+
+ + +
+
+
+
+
+ +
+ +
+ +
+
+
+
+
+ +
+ + +
+ +
+ +
+ +
+
+
+
+
+@endsection + +@push('page_scripts') + + +@endpush diff --git a/Modules/SalesReturn/Resources/views/edit.blade.php b/Modules/SalesReturn/Resources/views/edit.blade.php new file mode 100644 index 00000000..afde797d7 --- /dev/null +++ b/Modules/SalesReturn/Resources/views/edit.blade.php @@ -0,0 +1,124 @@ +@extends('layouts.app') + +@section('title', 'Edit Sale Return') + +@section('breadcrumb') + +@endsection + +@section('content') +
+
+
+ +
+
+ +
+
+
+
+ @include('utils.alerts') +
+ @csrf + @method('patch') +
+
+
+ + +
+
+
+
+
+ + +
+
+
+
+
+
+ + +
+
+
+
+ + + +
+
+
+ + +
+
+
+
+
+ + +
+
+
+
+
+ + +
+
+
+ +
+ + +
+ +
+ +
+ +
+
+
+
+
+@endsection + +@push('page_scripts') + + +@endpush diff --git a/Modules/SalesReturn/Resources/views/index.blade.php b/Modules/SalesReturn/Resources/views/index.blade.php new file mode 100644 index 00000000..20cb496c --- /dev/null +++ b/Modules/SalesReturn/Resources/views/index.blade.php @@ -0,0 +1,40 @@ +@extends('layouts.app') + +@section('title', 'Sale Returns') + +@section('third_party_stylesheets') + +@endsection + +@section('breadcrumb') + +@endsection + +@section('content') +
+
+
+
+
+ + Add Sale Return + + +
+ +
+ {!! $dataTable->table() !!} +
+
+
+
+
+
+@endsection + +@push('page_scripts') + {!! $dataTable->scripts() !!} +@endpush diff --git a/Modules/SalesReturn/Resources/views/partials/actions.blade.php b/Modules/SalesReturn/Resources/views/partials/actions.blade.php new file mode 100644 index 00000000..c401b726 --- /dev/null +++ b/Modules/SalesReturn/Resources/views/partials/actions.blade.php @@ -0,0 +1,42 @@ +
+ + +
diff --git a/Modules/SalesReturn/Resources/views/partials/payment-status.blade.php b/Modules/SalesReturn/Resources/views/partials/payment-status.blade.php new file mode 100644 index 00000000..7ac6bf4c --- /dev/null +++ b/Modules/SalesReturn/Resources/views/partials/payment-status.blade.php @@ -0,0 +1,13 @@ +@if ($data->payment_status == 'Partial') + + {{ $data->payment_status }} + +@elseif ($data->payment_status == 'Paid') + + {{ $data->payment_status }} + +@else + + {{ $data->payment_status }} + +@endif diff --git a/Modules/SalesReturn/Resources/views/partials/status.blade.php b/Modules/SalesReturn/Resources/views/partials/status.blade.php new file mode 100644 index 00000000..e6f2dfe7 --- /dev/null +++ b/Modules/SalesReturn/Resources/views/partials/status.blade.php @@ -0,0 +1,13 @@ +@if ($data->status == 'Pending') + + {{ $data->status }} + +@elseif ($data->status == 'Shipped') + + {{ $data->status }} + +@else + + {{ $data->status }} + +@endif diff --git a/Modules/SalesReturn/Resources/views/payments/create.blade.php b/Modules/SalesReturn/Resources/views/payments/create.blade.php new file mode 100644 index 00000000..fca8985e --- /dev/null +++ b/Modules/SalesReturn/Resources/views/payments/create.blade.php @@ -0,0 +1,114 @@ +@extends('layouts.app') + +@section('title', 'Create Payment') + +@section('breadcrumb') + +@endsection + +@section('content') +
+
+ @csrf +
+
+ @include('utils.alerts') +
+ +
+
+
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+
+ +
+ +
+ +
+
+
+
+
+
+
+ + +
+
+
+
+ +
+ + +
+ + +
+
+
+
+
+
+@endsection + +@push('page_scripts') + + +@endpush + diff --git a/Modules/SalesReturn/Resources/views/payments/edit.blade.php b/Modules/SalesReturn/Resources/views/payments/edit.blade.php new file mode 100644 index 00000000..43f8e723 --- /dev/null +++ b/Modules/SalesReturn/Resources/views/payments/edit.blade.php @@ -0,0 +1,117 @@ +@extends('layouts.app') + +@section('title', 'Edit Payment') + +@section('breadcrumb') + +@endsection + +@section('content') +
+
+ @csrf + @method('patch') +
+
+ @include('utils.alerts') +
+ +
+
+
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+
+ +
+ +
+ +
+
+
+
+
+
+
+ + +
+
+
+
+ +
+ + +
+ + +
+
+
+
+
+
+@endsection + +@push('page_scripts') + + +@endpush + diff --git a/Modules/SalesReturn/Resources/views/payments/index.blade.php b/Modules/SalesReturn/Resources/views/payments/index.blade.php new file mode 100644 index 00000000..a92f0ebc --- /dev/null +++ b/Modules/SalesReturn/Resources/views/payments/index.blade.php @@ -0,0 +1,37 @@ +@extends('layouts.app') + +@section('title', 'Sale Payments') + +@section('third_party_stylesheets') + +@endsection + +@section('breadcrumb') + +@endsection + +@section('content') +
+
+
+ @include('utils.alerts') +
+
+
+ {!! $dataTable->table() !!} +
+
+
+
+
+
+@endsection + +@push('page_scripts') + {!! $dataTable->scripts() !!} +@endpush diff --git a/Modules/SalesReturn/Resources/views/payments/partials/actions.blade.php b/Modules/SalesReturn/Resources/views/payments/partials/actions.blade.php new file mode 100644 index 00000000..5532260d --- /dev/null +++ b/Modules/SalesReturn/Resources/views/payments/partials/actions.blade.php @@ -0,0 +1,19 @@ +@can('access_sale_return_payments') + + + +@endcan +@can('access_sale_return_payments') + +@endcan diff --git a/Modules/SalesReturn/Resources/views/print.blade.php b/Modules/SalesReturn/Resources/views/print.blade.php new file mode 100644 index 00000000..6c8061f8 --- /dev/null +++ b/Modules/SalesReturn/Resources/views/print.blade.php @@ -0,0 +1,138 @@ + + + + + + + Sale Return Details + + + +
+
+
+
+ Logo +

+ Reference:: {{ $sale_return->reference }} +

+
+
+
+
+
+

Company Info:

+
{{ settings()->company_name }}
+
{{ settings()->company_address }}
+
Email: {{ settings()->company_email }}
+
Phone: {{ settings()->company_phone }}
+
+ +
+

Customer Info:

+
{{ $customer->customer_name }}
+
{{ $customer->address }}
+
Email: {{ $customer->customer_email }}
+
Phone: {{ $customer->customer_phone }}
+
+ +
+

Invoice Info:

+
Invoice: INV/{{ $sale_return->reference }}
+
Date: {{ \Carbon\Carbon::parse($sale_return->date)->format('d M, Y') }}
+
+ Status: {{ $sale_return->status }} +
+
+ Payment Status: {{ $sale_return->payment_status }} +
+
+ +
+ +
+ + + + + + + + + + + + + + @foreach($sale_return->saleReturnDetails as $item) + + + + + + + + + + + + + + + + @endforeach + +
ProductNet Unit PriceStockQuantityDiscountTaxSub Total
+ {{ $item->product_name }}
+ + {{ $item->product_code }} + +
{{ format_currency($item->unit_price) }} + {{ $item->product->product_quantity }} + + {{ $item->quantity }} + + {{ format_currency($item->product_discount_amount) }} + + {{ format_currency($item->product_tax_amount) }} + + {{ format_currency($item->sub_total) }} +
+
+
+
+ + + + + + + + + + + + + + + + + + + +
Discount ({{ $sale_return->discount_percentage }}%){{ format_currency($sale_return->discount_amount) }}
Tax ({{ $sale_return->tax_percentage }}%){{ format_currency($sale_return->tax_amount) }}
Shipping){{ format_currency($sale_return->shipping_amount) }}
Grand Total{{ format_currency($sale_return->total_amount) }}
+
+
+
+
+

Computer generated invoice. {{ settings()->company_name }} © {{ date('Y') }}.

+
+
+
+
+
+
+
+ + diff --git a/Modules/SalesReturn/Resources/views/show.blade.php b/Modules/SalesReturn/Resources/views/show.blade.php new file mode 100644 index 00000000..4ae290a4 --- /dev/null +++ b/Modules/SalesReturn/Resources/views/show.blade.php @@ -0,0 +1,140 @@ +@extends('layouts.app') + +@section('title', 'Sales Details') + +@section('breadcrumb') + +@endsection + +@section('content') +
+
+
+
+
+
+ Reference: {{ $sale_return->reference }} +
+ + Print + + + Save + +
+
+
+
+
Company Info:
+
{{ settings()->company_name }}
+
{{ settings()->company_address }}
+
Email: {{ settings()->company_email }}
+
Phone: {{ settings()->company_phone }}
+
+ +
+
Customer Info:
+
{{ $customer->customer_name }}
+
{{ $customer->address }}
+
Email: {{ $customer->customer_email }}
+
Phone: {{ $customer->customer_phone }}
+
+ +
+
Invoice Info:
+
Invoice: INV/{{ $sale_return->reference }}
+
Date: {{ \Carbon\Carbon::parse($sale_return->date)->format('d M, Y') }}
+
+ Status: {{ $sale_return->status }} +
+
+ Payment Status: {{ $sale_return->payment_status }} +
+
+ +
+ +
+ + + + + + + + + + + + + + @foreach($sale_return->saleReturnDetails as $item) + + + + + + + + + + + + + + + + @endforeach + +
ProductNet Unit PriceStockQuantityDiscountTaxSub Total
+ {{ $item->product_name }}
+ + {{ $item->product_code }} + +
{{ format_currency($item->unit_price) }} + {{ $item->product->product_quantity }} + + {{ $item->quantity }} + + {{ format_currency($item->product_discount_amount) }} + + {{ format_currency($item->product_tax_amount) }} + + {{ format_currency($item->sub_total) }} +
+
+
+
+ + + + + + + + + + + + + + + + + + + +
Discount ({{ $sale_return->discount_percentage }}%){{ format_currency($sale_return->discount_amount) }}
Tax ({{ $sale_return->tax_percentage }}%){{ format_currency($sale_return->tax_amount) }}
Shipping){{ format_currency($sale_return->shipping_amount) }}
Grand Total{{ format_currency($sale_return->total_amount) }}
+
+
+
+
+
+
+
+@endsection + diff --git a/Modules/SalesReturn/Routes/.gitkeep b/Modules/SalesReturn/Routes/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/SalesReturn/Routes/api.php b/Modules/SalesReturn/Routes/api.php new file mode 100644 index 00000000..6d64ca74 --- /dev/null +++ b/Modules/SalesReturn/Routes/api.php @@ -0,0 +1,18 @@ +get('/salesreturn', function (Request $request) { + return $request->user(); +}); \ No newline at end of file diff --git a/Modules/SalesReturn/Routes/web.php b/Modules/SalesReturn/Routes/web.php new file mode 100644 index 00000000..f6f759b0 --- /dev/null +++ b/Modules/SalesReturn/Routes/web.php @@ -0,0 +1,44 @@ + 'auth'], function () { + //Generate PDF + Route::get('/sale-returns/pdf/{id}', function ($id) { + $saleReturn = \Modules\SalesReturn\Entities\SaleReturn::findOrFail($id); + $customer = \Modules\People\Entities\Customer::findOrFail($saleReturn->customer_id); + + $pdf = \PDF::loadView('salesreturn::print', [ + 'sale_return' => $saleReturn, + 'customer' => $customer, + ])->setPaper('a4'); + + return $pdf->stream('sale-return-'. $saleReturn->reference .'.pdf'); + })->name('sale-returns.pdf'); + + //Sale Returns + Route::resource('sale-returns', 'SalesReturnController'); + + //Payments + Route::get('/sale-return-payments/{sale_return_id}', 'SaleReturnPaymentsController@index') + ->name('sale-return-payments.index'); + Route::get('/sale-return-payments/{sale_return_id}/create', 'SaleReturnPaymentsController@create') + ->name('sale-return-payments.create'); + Route::post('/sale-return-payments/store', 'SaleReturnPaymentsController@store') + ->name('sale-return-payments.store'); + Route::get('/sale-return-payments/{sale_return_id}/edit/{saleReturnPayment}', 'SaleReturnPaymentsController@edit') + ->name('sale-return-payments.edit'); + Route::patch('/sale-return-payments/update/{saleReturnPayment}', 'SaleReturnPaymentsController@update') + ->name('sale-return-payments.update'); + Route::delete('/sale-return-payments/destroy/{saleReturnPayment}', 'SaleReturnPaymentsController@destroy') + ->name('sale-return-payments.destroy'); +}); diff --git a/Modules/SalesReturn/Tests/Feature/.gitkeep b/Modules/SalesReturn/Tests/Feature/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/SalesReturn/Tests/Unit/.gitkeep b/Modules/SalesReturn/Tests/Unit/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Modules/SalesReturn/composer.json b/Modules/SalesReturn/composer.json new file mode 100644 index 00000000..44f24558 --- /dev/null +++ b/Modules/SalesReturn/composer.json @@ -0,0 +1,23 @@ +{ + "name": "nwidart/salesreturn", + "description": "", + "authors": [ + { + "name": "Nicolas Widart", + "email": "n.widart@gmail.com" + } + ], + "extra": { + "laravel": { + "providers": [], + "aliases": { + + } + } + }, + "autoload": { + "psr-4": { + "Modules\\SalesReturn\\": "" + } + } +} diff --git a/Modules/SalesReturn/module.json b/Modules/SalesReturn/module.json new file mode 100644 index 00000000..39a39a48 --- /dev/null +++ b/Modules/SalesReturn/module.json @@ -0,0 +1,13 @@ +{ + "name": "SalesReturn", + "alias": "salesreturn", + "description": "", + "keywords": [], + "priority": 0, + "providers": [ + "Modules\\SalesReturn\\Providers\\SalesReturnServiceProvider" + ], + "aliases": {}, + "files": [], + "requires": [] +} diff --git a/Modules/SalesReturn/package.json b/Modules/SalesReturn/package.json new file mode 100644 index 00000000..4599509f --- /dev/null +++ b/Modules/SalesReturn/package.json @@ -0,0 +1,17 @@ +{ + "private": true, + "scripts": { + "dev": "npm run development", + "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", + "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", + "watch-poll": "npm run watch -- --watch-poll", + "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js", + "prod": "npm run production", + "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" + }, + "devDependencies": { + "cross-env": "^7.0", + "laravel-mix": "^5.0.1", + "laravel-mix-merge-manifest": "^0.1.2" + } +} diff --git a/Modules/SalesReturn/webpack.mix.js b/Modules/SalesReturn/webpack.mix.js new file mode 100644 index 00000000..97a5c6a9 --- /dev/null +++ b/Modules/SalesReturn/webpack.mix.js @@ -0,0 +1,14 @@ +const dotenvExpand = require('dotenv-expand'); +dotenvExpand(require('dotenv').config({ path: '../../.env'/*, debug: true*/})); + +const mix = require('laravel-mix'); +require('laravel-mix-merge-manifest'); + +mix.setPublicPath('../../public').mergeManifest(); + +mix.js(__dirname + '/Resources/assets/js/app.js', 'js/salesreturn.js') + .sass( __dirname + '/Resources/assets/sass/app.scss', 'css/salesreturn.css'); + +if (mix.inProduction()) { + mix.version(); +} diff --git a/Modules/User/Database/Seeders/PermissionsTableSeeder.php b/Modules/User/Database/Seeders/PermissionsTableSeeder.php index ee5ade6e..71fa7932 100644 --- a/Modules/User/Database/Seeders/PermissionsTableSeeder.php +++ b/Modules/User/Database/Seeders/PermissionsTableSeeder.php @@ -60,6 +60,14 @@ class PermissionsTableSeeder extends Seeder 'delete_sales', //Sale Payments 'access_sale_payments', + //Purchases + 'access_purchases', + 'create_purchases', + 'show_purchases', + 'edit_purchases', + 'delete_purchases', + //Purchase Payments + 'access_purchase_payments', //Currencies 'access_currencies', 'create_currencies', diff --git a/app/DataTables/SalePaymentsDataTable.php b/app/DataTables/SalePaymentsDataTable.php index 2fba4367..b2f8433f 100644 --- a/app/DataTables/SalePaymentsDataTable.php +++ b/app/DataTables/SalePaymentsDataTable.php @@ -48,11 +48,6 @@ class SalePaymentsDataTable extends DataTable ); } - /** - * Get columns. - * - * @return array - */ protected function getColumns() { return [ Column::make('date') diff --git a/app/DataTables/SaleReturnPaymentsDataTable.php b/app/DataTables/SaleReturnPaymentsDataTable.php new file mode 100644 index 00000000..b71eb7ab --- /dev/null +++ b/app/DataTables/SaleReturnPaymentsDataTable.php @@ -0,0 +1,78 @@ +eloquent($query) + ->addColumn('amount', function ($data) { + return format_currency($data->amount); + }) + ->addColumn('action', function ($data) { + return view('salesreturn::payments.partials.actions', compact('data')); + }); + } + + public function query(SaleReturnPayment $model) { + return $model->newQuery()->bySaleReturn()->with('saleReturn'); + } + + public function html() { + return $this->builder() + ->setTableId('sale-payments-table') + ->columns($this->getColumns()) + ->minifiedAjax() + ->dom("<'row'<'col-md-3'l><'col-md-5 mb-2'B><'col-md-4'f>> . + 'tr' . + <'row'<'col-md-5'i><'col-md-7 mt-2'p>>") + ->orderBy(5) + ->buttons( + Button::make('excel') + ->text(' Excel'), + Button::make('print') + ->text(' Print'), + Button::make('reset') + ->text(' Reset'), + Button::make('reload') + ->text(' Reload') + ); + } + + protected function getColumns() { + return [ + Column::make('date') + ->className('align-middle text-center'), + + Column::make('reference') + ->className('align-middle text-center'), + + Column::computed('amount') + ->className('align-middle text-center'), + + Column::make('payment_method') + ->className('align-middle text-center'), + + Column::computed('action') + ->exportable(false) + ->printable(false) + ->className('align-middle text-center'), + + Column::make('created_at') + ->visible(false), + ]; + } + + protected function filename() + { + return 'SaleReturnPayments_' . date('YmdHis'); + } +} diff --git a/app/DataTables/SaleReturnsDataTable.php b/app/DataTables/SaleReturnsDataTable.php new file mode 100644 index 00000000..df793422 --- /dev/null +++ b/app/DataTables/SaleReturnsDataTable.php @@ -0,0 +1,100 @@ +eloquent($query) + ->addColumn('total_amount', function ($data) { + return format_currency($data->total_amount); + }) + ->addColumn('paid_amount', function ($data) { + return format_currency($data->paid_amount); + }) + ->addColumn('due_amount', function ($data) { + return format_currency($data->due_amount); + }) + ->addColumn('status', function ($data) { + return view('salesreturn::partials.status', compact('data')); + }) + ->addColumn('payment_status', function ($data) { + return view('salesreturn::partials.payment-status', compact('data')); + }) + ->addColumn('action', function ($data) { + return view('salesreturn::partials.actions', compact('data')); + }); + } + + public function query(SaleReturn $model) { + return $model->newQuery(); + } + + public function html() { + return $this->builder() + ->setTableId('sale-returns-table') + ->columns($this->getColumns()) + ->minifiedAjax() + ->dom("<'row'<'col-md-3'l><'col-md-5 mb-2'B><'col-md-4'f>> . + 'tr' . + <'row'<'col-md-5'i><'col-md-7 mt-2'p>>") + ->orderBy(8) + ->buttons( + Button::make('excel') + ->text(' Excel'), + Button::make('print') + ->text(' Print'), + Button::make('reset') + ->text(' Reset'), + Button::make('reload') + ->text(' Reload') + ); + } + + protected function getColumns() { + return [ + Column::make('reference') + ->className('text-center align-middle'), + + Column::make('customer_name') + ->title('Customer') + ->className('text-center align-middle'), + + Column::computed('status') + ->className('text-center align-middle'), + + Column::computed('total_amount') + ->className('text-center align-middle'), + + Column::computed('paid_amount') + ->className('text-center align-middle'), + + Column::computed('due_amount') + ->className('text-center align-middle'), + + Column::computed('payment_status') + ->className('text-center align-middle'), + + Column::computed('action') + ->exportable(false) + ->printable(false) + ->className('text-center align-middle'), + + Column::make('created_at') + ->visible(false) + ]; + } + + protected function filename() + { + return 'SaleReturns_' . date('YmdHis'); + } +} diff --git a/modules_statuses.json b/modules_statuses.json index 236340eb..ab1a1793 100644 --- a/modules_statuses.json +++ b/modules_statuses.json @@ -8,5 +8,7 @@ "Currency": true, "Setting": true, "Sale": true, - "Purchase": true + "Purchase": true, + "SaleReturn": true, + "SalesReturn": true } \ No newline at end of file diff --git a/resources/views/layouts/menu.blade.php b/resources/views/layouts/menu.blade.php index e4c8f241..aa6bf313 100644 --- a/resources/views/layouts/menu.blade.php +++ b/resources/views/layouts/menu.blade.php @@ -110,6 +110,30 @@ @endcan +@can('access_sale_returns') +
  • + + Sale Returns + + @can('create_sale_returns') + + @endcan + +
  • +@endcan + @can('access_expenses')