From 0b438e302dcd93c15e6a8b658dd97553caf75ae3 Mon Sep 17 00:00:00 2001 From: Sampanna Rimal Date: Tue, 17 Sep 2024 16:34:40 +0545 Subject: [PATCH] salesentry filters --- .../Http/Controllers/ProductController.php | 13 +++ .../app/Repositories/ProductInterface.php | 1 + .../app/Repositories/ProductRepository.php | 5 ++ .../views/product/partials/action.blade.php | 4 +- Modules/Product/routes/web.php | 2 +- .../Http/Controllers/SalesEntryController.php | 14 +++- Modules/SalesEntry/app/Models/SalesEntry.php | 11 ++- .../app/Models/SalesEntryDetail.php | 15 +++- .../app/Repositories/SalesEntryInterface.php | 2 +- .../app/Repositories/SalesEntryRepository.php | 43 ++++++++-- ...09_09_130433_create_salesentries_table.php | 9 -- .../views/salesEntry/clone-product.blade.php | 43 ++++++---- .../views/salesEntry/index.blade.php | 13 +-- .../salesEntry/partials/action.blade.php | 84 +++++++++++++++++-- .../views/salesEntry/partials/menu.blade.php | 74 ++++++++++++++++ .../app/Http/Controllers/StockController.php | 12 +++ .../Stock/app/Repositories/StockInterface.php | 1 + .../app/Repositories/StockRepository.php | 5 ++ Modules/Stock/routes/web.php | 2 + 19 files changed, 303 insertions(+), 50 deletions(-) create mode 100644 Modules/SalesEntry/resources/views/salesEntry/partials/menu.blade.php diff --git a/Modules/Product/app/Http/Controllers/ProductController.php b/Modules/Product/app/Http/Controllers/ProductController.php index a82713d..44cf3ce 100644 --- a/Modules/Product/app/Http/Controllers/ProductController.php +++ b/Modules/Product/app/Http/Controllers/ProductController.php @@ -148,4 +148,17 @@ class ProductController extends Controller 'data' => $productModel, ]); } + + public function getProductsByCategory(Request $request) + { + $categoryId = $request->category_id; + try { + $products = $this->productRepository->getProductsByCategory($categoryId); + } catch (\Throwable $th) { + toastr()->error($th->getMessage()); + } + return response()->json(['products' => $products]); + } + + } diff --git a/Modules/Product/app/Repositories/ProductInterface.php b/Modules/Product/app/Repositories/ProductInterface.php index cbc9406..1c3447f 100644 --- a/Modules/Product/app/Repositories/ProductInterface.php +++ b/Modules/Product/app/Repositories/ProductInterface.php @@ -7,6 +7,7 @@ interface ProductInterface public function findAll(); public function getProductById($ProductId); public function getProductByEmail($email); + public function getProductsByCategory($categoryId); public function delete($ProductId); public function create($ProductDetails); public function update($ProductId, array $newDetails); diff --git a/Modules/Product/app/Repositories/ProductRepository.php b/Modules/Product/app/Repositories/ProductRepository.php index 6639459..78edd74 100644 --- a/Modules/Product/app/Repositories/ProductRepository.php +++ b/Modules/Product/app/Repositories/ProductRepository.php @@ -23,6 +23,11 @@ class ProductRepository implements ProductInterface return Product::where('email', $email)->first(); } + public function getProductsByCategory($categoryId) + { + return Product::where('category_id', $categoryId)->pluck('name', 'id'); + } + public function delete($ProductId) { Product::destroy($ProductId); diff --git a/Modules/Product/resources/views/product/partials/action.blade.php b/Modules/Product/resources/views/product/partials/action.blade.php index 99f017d..f53bb37 100644 --- a/Modules/Product/resources/views/product/partials/action.blade.php +++ b/Modules/Product/resources/views/product/partials/action.blade.php @@ -25,12 +25,12 @@
{{ html()->label('Description')->class('form-label') }} - {{ html()->textarea('desc')->class('form-control')->placeholder('Enter Description')->required() }} + {{ html()->textarea('desc')->class('form-control')->placeholder('Enter Description') }}
{{ html()->label('Remarks')->class('form-label') }} - {{ html()->textarea('remarks')->class('form-control')->placeholder('Enter Remarks')->required() }} + {{ html()->textarea('remarks')->class('form-control')->placeholder('Enter Remarks') }}
diff --git a/Modules/Product/routes/web.php b/Modules/Product/routes/web.php index 12a76b0..a1a1d47 100644 --- a/Modules/Product/routes/web.php +++ b/Modules/Product/routes/web.php @@ -26,6 +26,6 @@ Route::group([], function () { Route::resource('fabricCategory', FabricCategoryController::class)->names('fabricCategory'); Route::get('get-sub-categories', [SubCategoryController::class, 'getSubCategories'])->name('getSubCategories'); Route::get('product-details', [ProductController::class, 'getProductDetail'])->name('get-product-detail'); - + Route::get('/products-by-category', [ProductController::class, 'getProductsByCategory'])->name('products-by-category'); }); diff --git a/Modules/SalesEntry/app/Http/Controllers/SalesEntryController.php b/Modules/SalesEntry/app/Http/Controllers/SalesEntryController.php index c7f0f27..2ea6784 100644 --- a/Modules/SalesEntry/app/Http/Controllers/SalesEntryController.php +++ b/Modules/SalesEntry/app/Http/Controllers/SalesEntryController.php @@ -42,10 +42,14 @@ class SalesEntryController extends Controller /** * Display a listing of the resource. */ - public function index() + public function index(Request $request) { + $filters = $request->all(); $data['title'] = 'Sales Entries'; - $data['salesEntries'] = SalesEntry::all(); + $data['stockList'] = $this->stockRepository->pluck(); + $data['productList'] = $this->productRepository->pluck(); + $data['categoryList'] = $this->categoryRepository->pluck(); + $data['salesEntries'] = $this->salesEntryRepository->findAll($filters); return view('salesEntry::salesEntry.index', $data); } @@ -55,9 +59,9 @@ class SalesEntryController extends Controller public function create() { $data['title'] = 'New Sales Entry'; - $data['categoryList'] = $this->categoryRepository->pluck(); $data['stockList'] = $this->stockRepository->pluck(); $data['productList'] = $this->productRepository->pluck(); + $data['categoryList'] = $this->categoryRepository->pluck(); $data['customerList'] = $this->customerRepository->pluck(); $data['sizes'] = $this->fieldRepository->getDropdownByAlias('size'); $data['paymentModes'] = $this->fieldRepository->getDropdownByAlias('payment-mode'); @@ -127,9 +131,11 @@ class SalesEntryController extends Controller $productList= $this->productRepository->pluck('id'); $stockList= $this->stockRepository->pluck('id'); $categoryList= $this->categoryRepository->pluck('id'); + $sizes = $this->fieldRepository->getDropdownByAlias('size'); + $paymentModes = $this->fieldRepository->getDropdownByAlias('payment-mode'); return response()->json([ - 'view' => view('salesEntry::salesEntry.clone-product', compact('data', 'numInc', 'script', 'productList'))->render(), + 'view' => view('salesEntry::salesEntry.clone-product', compact('data', 'numInc', 'script', 'productList', 'categoryList', 'stockList', 'sizes', 'paymentModes'))->render(), ]); } } diff --git a/Modules/SalesEntry/app/Models/SalesEntry.php b/Modules/SalesEntry/app/Models/SalesEntry.php index 51f88fa..8373b53 100644 --- a/Modules/SalesEntry/app/Models/SalesEntry.php +++ b/Modules/SalesEntry/app/Models/SalesEntry.php @@ -15,7 +15,16 @@ class SalesEntry extends Model USE StatusTrait; protected $table = 'tbl_salesentries'; - protected $guarded = []; + protected $fillable = [ + 'customer_id', + 'sales_date', + 'payment', + 'paymentmode_id', + 'paymentref', + 'total_amt', + 'created_at', + 'updated_at' + ]; protected $appends = ['status_name']; diff --git a/Modules/SalesEntry/app/Models/SalesEntryDetail.php b/Modules/SalesEntry/app/Models/SalesEntryDetail.php index 732a39c..ca500e3 100644 --- a/Modules/SalesEntry/app/Models/SalesEntryDetail.php +++ b/Modules/SalesEntry/app/Models/SalesEntryDetail.php @@ -14,7 +14,20 @@ class SalesEntryDetail extends Model USE StatusTrait; protected $table = 'tbl_salesentrydetails'; - protected $guarded = []; + protected $fillable = [ + 'salesentry_id', + 'product_id', + 'category_id', + 'stock_id', + 'size_id', + 'unit', + 'rate', + 'quantity', + 'amount', + 'desc', + 'created_at', + 'updated_at' + ]; protected $appends = ['status_name']; diff --git a/Modules/SalesEntry/app/Repositories/SalesEntryInterface.php b/Modules/SalesEntry/app/Repositories/SalesEntryInterface.php index e251dda..3ddf639 100644 --- a/Modules/SalesEntry/app/Repositories/SalesEntryInterface.php +++ b/Modules/SalesEntry/app/Repositories/SalesEntryInterface.php @@ -6,7 +6,7 @@ use Illuminate\Http\Request; interface SalesEntryInterface { - public function findAll(); + public function findAll($filters); public function getSalesEntryById($SalesEntryId); public function getSalesEntryByEmail($email); public function delete($SalesEntryId); diff --git a/Modules/SalesEntry/app/Repositories/SalesEntryRepository.php b/Modules/SalesEntry/app/Repositories/SalesEntryRepository.php index 77ea0c7..250a838 100644 --- a/Modules/SalesEntry/app/Repositories/SalesEntryRepository.php +++ b/Modules/SalesEntry/app/Repositories/SalesEntryRepository.php @@ -9,10 +9,37 @@ use Illuminate\Support\Facades\DB; class SalesEntryRepository implements SalesEntryInterface { - public function findAll() + // public function findAll() + // { + // return SalesEntry::when(true, function ($query) { + // })->paginate(20); + // } + public function findAll($filters = [], $limit = null, $offset = null) { - return SalesEntry::when(true, function ($query) { - })->paginate(20); + return SalesEntry::when($filters, function ($query) use ($filters) { + + if (isset($filters["category_id"])) { + $query->whereHas('salesEntryDetails', function ( $query) use ($filters) { + $query->where('category_id', '=', $filters["category_id"]); + }); + } + if (isset($filters["product_id"])) { + $query->whereHas('salesEntryDetails', function ( $query) use ($filters) { + $query->where('product_id', '=', $filters["product_id"]); + }); + } + if (isset($filters["stock_id"])) { + $query->whereHas('salesEntryDetails', function ( $query) use ($filters) { + $query->where('stock_id', '=', $filters["stock_id"]); + }); + } + + if (isset($filters["date"])) { + $explodeDate = explode("to", $filters['date']); + $query->whereBetween("sales_date", [$explodeDate[0], preg_replace('/\s+/', '', $explodeDate[1])]); + } + + })->get(); } public function getSalesEntryById($SalesEntryId) @@ -44,12 +71,16 @@ class SalesEntryRepository implements SalesEntryInterface $request->merge(['salesentry_id' => $salesEntryData->id]); - foreach ($salesEntryDetails['product_id'] as $key => $productId) { + foreach ($salesEntryDetails['stock_id'] as $key => $stockId) { + // dd($request->input('salesentry_id')); $data = [ 'salesentry_id' => $request->input('salesentry_id'), - 'product_id' => $productId, - 'unit' => $salesEntryDetails['unit'][$key], + 'product_id' => $salesEntryDetails['product_id'][$key], + 'category_id' => $salesEntryDetails['category_id'][$key], + 'stock_id' => $salesEntryDetails['stock_id'][$key], + 'size_id' => $salesEntryDetails['size_id'][$key], 'rate' => $salesEntryDetails['rate'][$key], + // 'unit' => $salesEntryDetails['unit'][$key], 'quantity' => $salesEntryDetails['qty'][$key], 'amount' => $salesEntryDetails['amt'][$key], 'desc' => $salesEntryDetails['desc'][$key], diff --git a/Modules/SalesEntry/database/migrations/2024_09_09_130433_create_salesentries_table.php b/Modules/SalesEntry/database/migrations/2024_09_09_130433_create_salesentries_table.php index 39fa000..b1f1c0a 100644 --- a/Modules/SalesEntry/database/migrations/2024_09_09_130433_create_salesentries_table.php +++ b/Modules/SalesEntry/database/migrations/2024_09_09_130433_create_salesentries_table.php @@ -15,20 +15,11 @@ return new class extends Migration { Schema::create('tbl_salesentries', function (Blueprint $table) { $table->id(); - $table->string('title')->nullable(); - $table->string('slug')->nullable(); $table->date('sales_date')->nullable(); $table->unsignedBigInteger('customer_id')->nullable(); - $table->unsignedBigInteger('product_id')->nullable(); - $table->unsignedBigInteger('category_id')->nullable(); - $table->unsignedBigInteger('stock_id')->nullable(); - $table->unsignedBigInteger('size_id')->nullable(); $table->string('payment')->nullable(); $table->unsignedBigInteger('paymentmode_id')->nullable(); $table->string('paymentref')->nullable(); - $table->decimal('sub_total', 10, 2)->nullable(); - $table->decimal('tax', 10, 2)->nullable(); - $table->decimal('discount_amt', 10, 2)->nullable(); $table->decimal('total_amt', 10, 2)->nullable(); $table->timestamps(); }); diff --git a/Modules/SalesEntry/resources/views/salesEntry/clone-product.blade.php b/Modules/SalesEntry/resources/views/salesEntry/clone-product.blade.php index 735b87f..854b6b3 100644 --- a/Modules/SalesEntry/resources/views/salesEntry/clone-product.blade.php +++ b/Modules/SalesEntry/resources/views/salesEntry/clone-product.blade.php @@ -1,30 +1,45 @@
-
+
+ {{ html()->label('Category')->class('form-label') }} + @if (isset($editable) && $editable) + {{ html()->select('category_id[]', $categoryList, $item->category_id)->class('form-select category_id')->attributes(['id' => 'category_id'])->placeholder('Enter Category')->required() }} + @else + {{ html()->select('category_id[]', $categoryList)->class('form-select category_id')->attributes(['id' => 'category_id'])->placeholder('Enter Category')->required() }} + + @endif +
+
{{ html()->label('Product')->class('form-label') }} @if (isset($editable) && $editable) - {{ html()->select('product_id[]', $productList, $item->product_id)->class('form-select product_id')->attributes(['id' => 'product_id'])->placeholder('Enter Product Name')->required() }} + {{ html()->select('product_id[]', $productList, $item->product_id)->class('form-select product_id')->attributes(['id' => 'product_id'])->placeholder('')->required() }} @else + {{ html()->select('product_id[]', [], null)->class('form-select product_id')->attributes(['id' => 'product_id'])->placeholder('')->required()->disabled() }} + @endif - {{ html()->select('product_id[]', $productList)->class('form-select product_id')->attributes(['id' => 'product_id'])->placeholder('Enter Product Name')->required() }} - +
+
+ {{ html()->label('Stock')->class('form-label') }} + @if (isset($editable) && $editable) + {{ html()->select('stock_id[]', $stockList, $item->stock_id)->class('form-select stock_id')->attributes(['id' => 'stock_id'])->placeholder('')->required() }} + @else + {{ html()->select('stock_id[]', $stockList)->class('form-select stock_id')->attributes(['id' => 'stock_id'])->placeholder('')->required()->disabled() }} + @endif +
+
+ {{ html()->label('Size')->class('form-label') }} + {{ html()->select('size_id[]', $sizes)->class('form-select ')->placeholder('size') }}
-
- {{ html()->label('Unit')->class('form-label') }} - {{ html()->text('unit[]', isset($editable) && $editable ? $item->unit : null)->class('form-control unit')->placeholder('Enter Unit')->required()->attributes(['id' => 'unit']) }} - -
- -
+
{{ html()->label('Rate')->class('form-label') }} - {{ html()->text('rate[]', isset($editable) && $editable ? $item->rate : null)->class('form-control product-price cleave-numeral rate~~')->placeholder('Enter Rate')->attributes(['id' => 'rate']) }} + {{ html()->text('rate[]', isset($editable) && $editable ? $item->rate : null)->class('form-control product-price cleave-numeral rate~~')->placeholder('Enter Rate')->attributes(['id' => 'rate', 'onkeyup' => 'validateNumericInput(this)']) }}
-
+
{{ html()->label('Quantity')->class('form-label') }} - {{ html()->text('qty[]', isset($editable) && $editable ? $item->quantity : null)->class('form-control product-quantity cleave-numeral qty')->placeholder('Enter QTY')->attributes(['id' => 'qty']) }} + {{ html()->text('qty[]', isset($editable) && $editable ? $item->quantity : null)->class('form-control product-quantity cleave-numeral qty')->placeholder('Enter QTY')->attributes(['id' => 'qty', 'onkeyup' => 'validateNumericInput(this)']) }}
diff --git a/Modules/SalesEntry/resources/views/salesEntry/index.blade.php b/Modules/SalesEntry/resources/views/salesEntry/index.blade.php index 0ab2539..6775507 100644 --- a/Modules/SalesEntry/resources/views/salesEntry/index.blade.php +++ b/Modules/SalesEntry/resources/views/salesEntry/index.blade.php @@ -1,8 +1,9 @@ @extends('layouts.app') - @section('content')
+@include('salesEntry::salesEntry.partials.menu') +
@@ -24,20 +25,22 @@ Customer Sales Date Total Amount - Action + {{-- Action --}} @forelse ($salesEntries as $key => $item) + {{-- @dd($item) --}} {{ $key + 1 }} {{ $item->customer->customer_name }} {{ $item->sales_date }} {{ $item->total_amt }} - + {{-- - + --}} @empty @endforelse diff --git a/Modules/SalesEntry/resources/views/salesEntry/partials/action.blade.php b/Modules/SalesEntry/resources/views/salesEntry/partials/action.blade.php index b00839a..62a0a03 100644 --- a/Modules/SalesEntry/resources/views/salesEntry/partials/action.blade.php +++ b/Modules/SalesEntry/resources/views/salesEntry/partials/action.blade.php @@ -80,7 +80,7 @@
-
+
Payment Details
@@ -102,7 +102,7 @@
-
+
@@ -117,12 +117,11 @@ numberInc = $('.product-card').length $.ajax({ type: 'get', - url: '{{ url('clone-sales-product') }}', - + url: '{{ route('salesEntry.cloneSalesProduct') }}', data: { numberInc: numberInc }, - success: function(response) { + success: function(response) { $('.appendProductCard').append(response.view) // $('#salesEntry-container').html(response.view).fadeIn() }, @@ -143,6 +142,11 @@ recalculate(); }) + function validateNumericInput(input) { + // Allow only numbers and remove any non-numeric input + input.value = input.value.replace(/[^0-9]/g, ''); + } + function amountKeyup() { $("body").on('keyup', '.product-price', function() { @@ -187,8 +191,10 @@ // $("#shipping").val(shipping.toFixed(2)); $("#total").val(subtotal.toFixed(2)); } - + $(document).ready(function() { + $('.product_id').prop('disabled', true); + $('.stock_id').prop('disabled', true); $('body').on('change', '.product_id', function() { var selectedId = $(this).find(':selected').val(); var formRow = $(this).closest('.row'); @@ -214,6 +220,72 @@ }); } }); + + + // When category is selected, load products dynamically + $('body').on('change', '.category_id', function () { + var categoryId = $(this).val(); + var formRow = $(this).closest('.row'); + var productSelect = formRow.find('.product_id'); + var stockSelect = formRow.find('.stock_id'); + + // Reset stock field + + if (categoryId) { + $.ajax({ + type: 'GET', + url: '{{ route('products-by-category') }}', // Route to get products by category + data: {category_id:categoryId}, + success: function (response) { + productSelect.empty().append(''); + productSelect.prop('disabled', false); + + $.each(response.products, function (id, name) { + productSelect.append(''); + }); + }, + error: function (xhr) { + // Handle error + } + }); + stockSelect.empty().prop('disabled', true); + + } else { + productSelect.prop('disabled', true); + } + }); + + // When product is selected, load stocks dynamically + $('body').on('change', '.product_id', function () { + var productId = $(this).val(); + var formRow = $(this).closest('.row'); + var productSelect = formRow.find('.product_id'); + var stockSelect = formRow.find('.stock_id'); + + + if (productId) { + $.ajax({ + type: 'GET', + url: '{{ route('stocks-by-product') }}', // Route to get stocks by product + data: {product_id:productId}, + success: function (response) { + stockSelect.empty().append(''); + stockSelect.prop('disabled', false); + + $.each(response.stocks, function (id, title) { + stockSelect.append(''); + }); + }, + error: function (xhr) { + // Handle error + } + }); + } else { + stockSelect.prop('disabled', true); + } + }); }); + + @endpush diff --git a/Modules/SalesEntry/resources/views/salesEntry/partials/menu.blade.php b/Modules/SalesEntry/resources/views/salesEntry/partials/menu.blade.php new file mode 100644 index 0000000..c9926ad --- /dev/null +++ b/Modules/SalesEntry/resources/views/salesEntry/partials/menu.blade.php @@ -0,0 +1,74 @@ +
+
+
+
+ {{ html()->form('GET')->route('salesEntry.index')->open() }} +
+ {{--
+ +
--}} + +
+
+ {{ html()->text('date')->class('form-control')->value(request('date'))->placeholder('Date Range')->attributes([ + 'id' => 'datepicker-range', + 'data-provider' => 'flatpickr', + 'data-date-format' => 'Y-m-d', + 'data-range-date' => 'true', + ]) }} +
+
+ +
+ +
+
+ +
+
+ +
+ + {{--
--}} +
+
+ + {{-- + Reset --}} +
+
+
+
+ + Reset + {{-- + Reset --}} +
+
+ {{--
--}} + +
+ + {{ html()->form()->close() }} + +
+ + +
+ +
+
+ + diff --git a/Modules/Stock/app/Http/Controllers/StockController.php b/Modules/Stock/app/Http/Controllers/StockController.php index 44c7101..75fa2d2 100644 --- a/Modules/Stock/app/Http/Controllers/StockController.php +++ b/Modules/Stock/app/Http/Controllers/StockController.php @@ -94,4 +94,16 @@ class StockController extends Controller return response()->json(['status' => true, 'message' => 'Stock Deleted Successfully']); } + + public function getStocksByProduct(Request $request) + { + $productId = $request->product_id; + try { + $stocks = $this->stockRepository->getStocksByProduct($productId); + } catch (\Throwable $th) { + toastr()->error($th->getMessage()); + } + return response()->json(['stocks' => $stocks]); + } + } diff --git a/Modules/Stock/app/Repositories/StockInterface.php b/Modules/Stock/app/Repositories/StockInterface.php index 5b87f54..ea52870 100644 --- a/Modules/Stock/app/Repositories/StockInterface.php +++ b/Modules/Stock/app/Repositories/StockInterface.php @@ -7,6 +7,7 @@ interface StockInterface public function findAll(); public function getStockById($StockId); public function getStockByEmail($email); + public function getStocksByProduct($productId); public function delete($StockId); public function create($StockDetails); public function update($StockId, array $newDetails); diff --git a/Modules/Stock/app/Repositories/StockRepository.php b/Modules/Stock/app/Repositories/StockRepository.php index e4f91ce..a151116 100644 --- a/Modules/Stock/app/Repositories/StockRepository.php +++ b/Modules/Stock/app/Repositories/StockRepository.php @@ -23,6 +23,11 @@ class StockRepository implements StockInterface return Stock::where('email', $email)->first(); } + public function getStocksByProduct($productId) + { + return Stock::where('product_id', $productId)->pluck('title', 'id'); + } + public function delete($StockId) { Stock::destroy($StockId); diff --git a/Modules/Stock/routes/web.php b/Modules/Stock/routes/web.php index d5c03ae..0e216aa 100644 --- a/Modules/Stock/routes/web.php +++ b/Modules/Stock/routes/web.php @@ -19,5 +19,7 @@ use Modules\Stock\Http\Controllers\StockLocationController; Route::group([], function () { Route::resource('stock', StockController::class)->names('stock'); Route::resource('stockLocation', StockLocationController::class)->names('stockLocation'); + Route::get('/stocks-by-product', [StockController::class, 'getStocksByProduct'])->name('stocks-by-product'); + });