"use strict"; let allProducts = []; // Asset path helper function assetPath(path) { let baseUrl = $("#asset_base_url").val() || ""; return baseUrl.replace(/\/$/, "") + "/" + path.replace(/^\/+/, ""); } // renders product dropdown list function populateProducts(products) { const $dropdownList = $("#dropdownList"); $dropdownList.empty(); if (products.length === 0) { $dropdownList.append( '
No products available
' ); return; } const cartRoute = $("#cart-store-url").val(); $.each(products, function (index, product) { const imageUrl = assetPath( product.productPicture ?? "assets/images/products/box.svg" ); let html = ""; // if multiple stocks if (product.stocks && product.stocks.length > 1) { html += `
${ product.productName }

Code : ${product.productCode}

`; product.stocks.forEach((stock) => { html += `
Batch: ${stock.batch_no ?? "N/A"} ${ product.color ? ", Color: " + product.color : "" } In Stock: ${ stock.productStock }
${currencyFormat( stock.productSalePrice )}
`; }); html += `
`; } else { const singleStock = Array.isArray(product.stocks) && product.stocks.length > 0 ? product.stocks[0] : {}; html += `
${ product.productName }

Code : ${product.productCode}

Batch: ${singleStock.batch_no ?? "N/A"} ${ product.color ? ", Color: " + product.color : "" } In Stock: ${ Array.isArray(product.stocks) ? product.stocks.reduce( (sum, stock) => sum + stock.productStock, 0 ) : 0 }
${currencyFormat( singleStock.productSalePrice ?? 0 )}
`; } $dropdownList.append(html); }); } // load all products initially const allProductsUrl = $("#all-products").val(); if (allProductsUrl) { $.get(allProductsUrl, function (products) { allProducts = products; // store globally populateProducts(allProducts); }); } // Filter products based on branch & warehouse function filterProducts() { const branchId = $("#from_branch").val(); const warehouseId = $("#from_warehouse").val(); const filtered = allProducts .map((product) => { if (!product.stocks || product.stocks.length === 0) return null; // filter stocks by selected branch & warehouse const filteredStocks = product.stocks.filter((stock) => { const branchMatch = !branchId || stock.branch_id == branchId; const warehouseMatch = !warehouseId || stock.warehouse_id == warehouseId; return branchMatch && warehouseMatch && stock.productStock > 0; }); if (filteredStocks.length === 0) return null; return { ...product, // copy product data, keep only filtered stocks stocks: filteredStocks, }; }) .filter(Boolean); // remove nulls populateProducts(filtered); } // toggle product dropdown visibility const $dropdown = $("#dropdownList"); const $searchContainer = $("#searchContainer"); const $productSearch = $("#productSearch"); const $arrow = $("#arrow"); $("#productDropdown .product-selected").on("click", function (e) { e.stopPropagation(); $dropdown.toggle(); $searchContainer.toggleClass("hidden"); $arrow.toggleClass("product-rotate"); }); // Close dropdown if clicked outside $(document).on("click", function (e) { if (!$(e.target).closest("#productDropdown").length) { $dropdown.hide(); $searchContainer.addClass("hidden"); $arrow.removeClass("product-rotate"); } }); // product search also respects filter $productSearch.on("keyup", function () { const searchTerm = $(this).val().toLowerCase(); $("#dropdownList .product-option-item").each(function () { const name = String($(this).data("product_name") || "").toLowerCase(); const code = String($(this).data("product_code") || "").toLowerCase(); $(this).toggle(name.includes(searchTerm) || code.includes(searchTerm)); }); }); // Add to cart on batch click $("#dropdownList").on("click", ".add-batch-item", function (e) { e.stopPropagation(); const $item = $(this); $dropdown.hide(); $searchContainer.addClass("hidden"); $arrow.removeClass("product-rotate"); let stockId = $item.data("product_stock_id"); let productId = $item.data("product_id"); let name = $item.data("product_name"); let code = $item.data("product_code"); let price = parseFloat($item.data("default_price") || 0); let batchNo = $item.data("batch_no") || ""; let image = $item.data("product_image") || assetPath("assets/images/products/box.svg"); // If row exists increment qty let existingRow = $("#product-row-" + stockId); if (existingRow.length) { let qtyInput = existingRow.find(".dynamic-qty"); qtyInput.val((parseInt(qtyInput.val()) || 1) + 1).trigger("input"); return; } let rowHtml = ` ${name} ${code} ${batchNo}
${price.toFixed(2)} `; $("#product-list").append(rowHtml); updateTotals(); }); // Cart qty, price, discount, tax change $("#product-list").on( "input", ".dynamic-qty, .unit-price, .discount, .tax", function () { let $row = $(this).closest("tr"); let qty = parseFloat($row.find(".dynamic-qty").val()) || 0; let price = parseFloat($row.find(".unit-price").val()) || 0; let discount = parseFloat($row.find(".discount").val()) || 0; let tax = parseFloat($row.find(".tax").val()) || 0; let subtotal = qty * price + tax - discount; $row.find(".sub-total").text(subtotal.toFixed(2)); updateTotals(); } ); // increment / decrement buttons $("#product-list").on("click", ".adding-btn", function () { let $row = $(this).closest("tr"); let $qty = $row.find(".dynamic-qty"); $qty.val((parseInt($qty.val()) || 0) + 1).trigger("input"); }); $("#product-list").on("click", ".subtract-btn", function () { let $row = $(this).closest("tr"); let $qty = $row.find(".dynamic-qty"); let current = parseInt($qty.val()) || 1; if (current > 1) $qty.val(current - 1).trigger("input"); }); // remove row $("#product-list").on("click", ".remove-btn", function () { $(this).closest("tr").remove(); updateTotals(); }); // update totals function function updateTotals() { let subTotal = 0, totalDiscount = 0, totalTax = 0, grandTotal = 0; $("#product-list tr").each(function () { let qty = parseFloat($(this).find(".dynamic-qty").val()) || 0; let price = parseFloat($(this).find(".unit-price").val()) || 0; let discount = parseFloat($(this).find(".discount").val()) || 0; let tax = parseFloat($(this).find(".tax").val()) || 0; let lineBase = qty * price; let lineWithTax = lineBase + tax; let lineSubtotal = lineWithTax - discount; $(this).find(".sub-total").text(lineSubtotal.toFixed(2)); subTotal += lineBase; totalTax += tax; totalDiscount += discount; grandTotal += lineSubtotal; }); let shipping = parseFloat($("#shipping_amount").val()) || 0; grandTotal += shipping; $("#total_amount").text(subTotal.toFixed(2)); $("#tax_amount").text(totalTax.toFixed(2)); $("#discount_amount").text(totalDiscount.toFixed(2)); $("#grand_total_amount").text(grandTotal.toFixed(2)); } // Trigger totals update on shipping change $("#shipping_amount").on("input", function () { updateTotals(); }); const allWarehousesUrl = $("#branch_wise_warehouses").val(); function loadWarehouses(branchId, warehouseSelect) { if (!allWarehousesUrl) return; $.ajax({ url: allWarehousesUrl, type: "GET", data: { branch_id: branchId }, success: function (warehouses) { let options = ''; if (warehouses.length > 0) { $.each(warehouses, function (i, wh) { options += ``; }); } else { options += ``; } $(warehouseSelect).html(options); }, error: function () { $(warehouseSelect).html(''); } }); } // Load all warehouses initially loadWarehouses("", "#from_warehouse"); loadWarehouses("", "#to_warehouse"); // When "from_branch" changes $("#from_branch").on("change", function () { let branchId = $(this).val(); // Clear cart and update totals $("#product-list").empty(); updateTotals(); // Reload "from_warehouse" options based on selected branch loadWarehouses(branchId, "#from_warehouse"); // Filter products based on new branch & warehouse filterProducts(); }); // When "to_branch" changes $("#to_branch").on("change", function () { let branchId = $(this).val(); let hasActiveBranch = $("#hasActiveBranch").val() == "1"; // Only reload "to_warehouse" if no active branch if (!hasActiveBranch) { loadWarehouses(branchId, "#to_warehouse"); } }); // When "from_warehouse" changes $("#from_warehouse").on("change", function () { // Clear cart and update totals $("#product-list").empty(); updateTotals(); // Filter products based on new warehouse filterProducts(); });