$(document).ready(function () { var $sidebarPlan = $(".lg-sub-plan"); var $subPlan = $(".sub-plan"); var isActive = $(window).width() >= 1150; $(".side-bar, .section-container").toggleClass("active", isActive); if (isActive) { $sidebarPlan.hide(); $subPlan.show(); $(".side-bar-addon, .side-bar-addon-2, .side-bar-addon-3").hide(); } else { $sidebarPlan.show(); $subPlan.hide(); $(".side-bar-addon, .side-bar-addon-2, .side-bar-addon-3").show(); } }); // get number only function getNumericValue(value) { return parseFloat(value.replace(/[^0-9.-]+/g, "")) || 0; } // Update the cart list and call the callback once complete function fetchUpdatedCart(callback) { let url = $("#purchase-cart").val(); $.ajax({ url: url, type: "GET", success: function (response) { $("#purchase_cart_list").html(response); if (typeof callback === "function") callback(); // Call the callback after updating the cart }, }); } //increase quantity $(document).on("click", ".plus-btn", function (e) { e.preventDefault(); let $row = $(this).closest("tr"); let rowId = $row.data("row_id"); let updateRoute = $row.data("update_route"); let $qtyInput = $row.find(".cart-qty"); let currentQty = parseFloat($qtyInput.val()); let newQty = currentQty + 1; $qtyInput.val(newQty); updateCartQuantity(rowId, newQty, updateRoute); }); //decrease quantity $(document).on("click", ".minus-btn", function (e) { e.preventDefault(); let $row = $(this).closest("tr"); let rowId = $row.data("row_id"); let updateRoute = $row.data("update_route"); let $qtyInput = $row.find(".cart-qty"); let currentQty = parseFloat($qtyInput.val()); // Ensure quantity does not go below 1 if (currentQty > 1) { let newQty = currentQty - 1; $qtyInput.val(newQty); updateCartQuantity(rowId, newQty, updateRoute); } }); // Cart quantity input field change event $(document).on("change", ".cart-qty", function () { let $row = $(this).closest("tr"); let rowId = $row.data("row_id"); let updateRoute = $row.data("update_route"); let newQty = parseFloat($(this).val()); // Ensure quantity does not go below 1 if (newQty >= 0) { updateCartQuantity(rowId, newQty, updateRoute); } }); // Remove item from the cart $(document).on("click", ".remove-btn", function (e) { e.preventDefault(); var $row = $(this).closest("tr"); var destroyRoute = $row.data("destroy_route"); $.ajax({ url: destroyRoute, type: "DELETE", success: function (response) { if (response.success) { // Item was successfully removed, fade out and remove the row from DOM $row.fadeOut(400, function () { $(this).remove(); }); // Recalculate and update cart totals fetchUpdatedCart(calTotalAmount); } else { toastr.error(response.message || "Failed to remove item"); } }, error: function () { toastr.error("Error removing item from cart"); }, }); }); // Function to update cart item with the new quantity function updateCartQuantity(rowId, newQty, updateRoute) { $.ajax({ url: updateRoute, type: "PUT", data: { rowId: rowId, qty: newQty, }, success: function (response) { if (response.success) { fetchUpdatedCart(calTotalAmount); // Re-fetch the cart and recalculate the total amount } else { toastr.error(response.message || "Failed to update quantity"); } }, error: function () { toastr.error("Error updating cart quantity"); }, }); } // Clear the cart and then refresh the UI with updated values function clearCart(cartType) { let route = $("#clear-cart").val(); $.ajax({ type: "POST", url: route, data: { type: cartType, }, dataType: "json", success: function (response) { fetchUpdatedCart(calTotalAmount); // Call calTotalAmount after cart fetch completes }, error: function () { console.error("There was an issue clearing the cart."); }, }); } /** Add to cart start **/ let selectedProduct = {}; $(document).on("click", "#single-product", function () { showProductModal($(this)); }); function autoOpenModal(id) { let element = $("#products-list").find(".single-product." + id); showProductModal(element); } function showProductModal(element) { selectedProduct = { product_id: element.data("product_id"), product_code: element.data("product_code"), product_unit_id: element.data("product_unit_id"), product_unit_name: element.data("product_unit_name"), product_image: element.data("product_image"), product_name: element.find(".product_name").text(), brand: element.data("brand"), stock: element.data("stock"), purchase_price: element.data("purchase_price"), sales_price: element.data("sales_price"), whole_sale_price: element.data("whole_sale_price"), dealer_price: element.data("dealer_price"), product_type: element.data("product_type"), vat_id: element.data("vat_id"), vat_rate: element.data("vat_rate"), }; // Set modal display values $("#product_name").text(selectedProduct.product_name); $("#brand").text(selectedProduct.brand); $("#stock").text(selectedProduct.stock); $("#purchase_price").val(selectedProduct.purchase_price); $("#sales_price").val(selectedProduct.sales_price); $("#whole_sale_price").val(selectedProduct.whole_sale_price); $("#dealer_price").val(selectedProduct.dealer_price); $("#batch_no").val(""); // show/hide variant field according to Product Type if (selectedProduct.product_type === "variant") { $("#variant_name").closest(".col-lg-6").removeClass("d-none"); $("#variant_name").prop("disabled", false); loadVariantOptions(selectedProduct.product_id); } else { $("#variant_name").closest(".col-lg-6").addClass("d-none"); $("#variant_name").prop("disabled", true); $("#variant_name").html(''); } // Read expire_date_type safely from hidden input const settingExpireType = $("#setting_expire_type").val() || "dmy"; const $expireInput = $("#expire_date"); if ($expireInput.length) { if (settingExpireType === "my") { $expireInput.attr("type", "month"); } else { $expireInput.attr("type", "date"); } } $("#product-modal").modal("show"); } $(".product-filter").on("submit", function (e) { e.preventDefault(); }); let savingLoader = '
Loading...
', $purchase_modal_reload = $("#purchase_modal"); $purchase_modal_reload.initFormValidation(), // item modal action $("#purchase_modal").on("submit", function (e) { e.preventDefault(); let t = $(this).find(".submit-btn"), a = t.html(); let url = $(this).data("route"); let quantity = parseFloat($("#product_qty").val()); $purchase_modal_reload.valid() && $.ajax({ url: url, type: "POST", data: { type: "purchase", id: selectedProduct.product_id, name: selectedProduct.product_name, quantity: quantity, price: parseFloat($("#purchase_price").val()) || selectedProduct.purchase_price, sales_price: parseFloat($("#sales_price").val()), whole_sale_price: parseFloat($("#whole_sale_price").val()), dealer_price: parseFloat($("#dealer_price").val()), batch_no: $("#batch_no").val(), expire_date: $("#expire_date").val(), product_code: selectedProduct.product_code, product_unit_id: selectedProduct.product_unit_id, product_unit_name: selectedProduct.product_unit_name, product_image: selectedProduct.product_image, warehouse_id: $("#warehouse_id").val(), variant_name: $("#variant_name").val(), vat_id: selectedProduct.vat_id, vat_rate: selectedProduct.vat_rate }, beforeSend: function () { t.html(savingLoader).attr("disabled", !0); }, success: function (response) { t.html(a).removeClass("disabled").attr("disabled", !1); if (response.success) { fetchUpdatedCart(calTotalAmount); // Update totals after cart fetch completes $("#product-modal").modal("hide"); $("#product_qty").val(""); $("#variant_name").val(""); $("#warehouse_id").val(""); $("#expire_date").val(""); } else { toastr.error( response.message || "Failed to add product to cart." ); } }, error: function (xhr) { toastr.error( "An error occurred while adding product to cart." ); }, }); }); /** Add to cart End **/ // Function to load variant options function loadVariantOptions(product_id) { let url = $("#get-product-variants").val() + '/' + product_id; $.ajax({ url: url, type: "GET", success: function (res) { let options = ''; res.forEach(function (variant) { // Store batch_no as data attribute options += ``; }); $("#variant_name").html(options); // Clear field when product modal opens $("#batch_no").val(''); $("#expire_date").val(''); }, }); } // variant options on change event $(document).on("change", "#variant_name", function () { let selectedOption = $(this).find(":selected"); let batchNo = selectedOption.data("batch") || ''; $("#batch_no").val(batchNo); let expireDate = selectedOption.data("expire_date") || ''; // Adjust format if type=month const $expireInput = $("#expire_date"); if ($expireInput.attr("type") === "month" && expireDate) { expireDate = expireDate.slice(0, 7); // yyyy-MM } $expireInput.val(expireDate); }); // Trigger calculation whenever Discount, or Receive Amount fields change $("#discount_amount, #receive_amount, #shipping_charge").on( "input", function () { calTotalAmount(); } ); // vat calculation $(".vat_select").on("change", function () { let vatRate = parseFloat($(this).find(":selected").data("rate")) || 0; let subtotal = getNumericValue($("#sub_total").text()) || 0; let vatAmount = (subtotal * vatRate) / 100; $("#vat_amount").val(vatAmount.toFixed(2)); calTotalAmount(); }); // discount calculation $(".discount_type").on("change", function () { calTotalAmount(); }); // Function to calculate the total amount function calTotalAmount() { let subtotal = 0; let vat_amount = 0; // Calculate subtotal and VAT from cart list $("#purchase_cart_list tr").each(function () { let cart_qty = getNumericValue($(this).find(".cart-qty").val()) || 0; let cart_price = getNumericValue($(this).find(".price").val()) || 0; let cart_subtotal = cart_qty * cart_price; subtotal += cart_subtotal; let cart_vat_rate = parseFloat($(this).data("vat_rate")) || 0; let cart_vat_amount = (cart_subtotal * cart_vat_rate) / 100; vat_amount += cart_vat_amount; // Update line total on the UI $(this).find(".cart-subtotal").text(currencyFormat(cart_subtotal)); $(this).find(".cart-vat-value").text(currencyFormat(cart_vat_amount)); }); $("#sub_total").text(currencyFormat(subtotal)); // Display total VAT $("#vat_amount").val(vat_amount.toFixed(2)); // Subtotal with VAT let subtotal_with_vat = subtotal + vat_amount; // Discount let discount_amount = getNumericValue($("#discount_amount").val()) || 0; let discount_type = $(".discount_type").val(); if (discount_type == "percent") { discount_amount = (subtotal_with_vat * discount_amount) / 100; if (discount_amount > subtotal_with_vat) { toastr.error( "Discount cannot be more than 100% of the amount after VAT!" ); discount_amount = subtotal_with_vat; $("#discount_amount").val(100); } } else { if (discount_amount > subtotal_with_vat) { toastr.error("Discount cannot be more than the amount after VAT!"); discount_amount = subtotal_with_vat; $("#discount_amount").val(discount_amount); } } // Shipping Charge let shipping_charge = getNumericValue($("#shipping_charge").val()) || 0; // Total Amount (after VAT + shipping, then discount) let total_amount = subtotal_with_vat + shipping_charge - discount_amount; $("#total_amount").text(currencyFormat(total_amount)); // Receive Amount let receive_amount = getNumericValue($("#receive_amount").val()) || 0; if (receive_amount < 0) { toastr.error("Receive amount cannot be less than 0!"); receive_amount = 0; $("#receive_amount").val(receive_amount); } // Change Amount let change_amount = receive_amount > total_amount ? receive_amount - total_amount : 0; $("#change_amount").val(change_amount.toFixed(2)); // Due Amount let due_amount = total_amount > receive_amount ? total_amount - receive_amount : 0; $("#due_amount").val(due_amount.toFixed(2)); } calTotalAmount(); // Cancel btn action $(".cancel-sale-btn").on("click", function (e) { e.preventDefault(); clearCart("purchase"); }); $(".product-filter").on("input", ".search-input", function (e) { fetchProducts(); }); let autoOpenedForSearch = false; // Prevent repeated modal open per search function fetchProducts() { var form = $("form.product-filter")[0]; $.ajax({ type: "POST", url: $(form).attr("action"), data: new FormData(form), dataType: "json", contentType: false, cache: false, processData: false, success: function (res) { // Show products $("#products-list").html(res.data); // Open modal if one product found and not opened yet const searchTerm = $("#purchase_product_search").val().trim(); if ( res.total_products && res.product_id && searchTerm !== "" && !autoOpenedForSearch ) { autoOpenedForSearch = true; autoOpenModal(res.product_id); $("#purchase_product_search").val(""); // Reset when modal closes and reload list $("#product-modal").one("hidden.bs.modal", function () { autoOpenedForSearch = false; fetchProducts(); }); } }, }); } $(document).on("click", ".category-content", function () { let url = $("#category-filter").val(); const categoryId = $(this).data("id"); $.ajax({ type: "POST", url: url, data: { category_id: categoryId }, success: function (response) { $(".product-list-container").html(response.data); }, }); }); $(document).on("click", ".brand-search", function () { let url = $("#brand-filter").val(); const brandId = $(this).data("id"); $.ajax({ type: "POST", url: url, data: { brand_id: brandId }, success: function (response) { $(".product-list-container").html(response.data); }, }); }); // Category Filter $(".category-search").on("input", function (e) { e.preventDefault(); // Get search query const search = $(this).val(); const route = $(this).closest("form").data("route"); $.ajax({ type: "POST", url: route, data: { search: search, }, success: function (response) { $("#category-data").html(response.categories); }, }); }); // brand Filter $(".brand-search").on("input", function (e) { e.preventDefault(); // Get search query const search = $(this).val(); const route = $(this).closest("form").data("route"); $.ajax({ type: "POST", url: route, data: { search: search, }, success: function (response) { $("#brand-data").html(response.brands); }, }); }); $(document).on("submit", "#categorySearchForm, #brandSearchForm", function (e) { e.preventDefault(); }); // When select brand or product $(document).on("click", ".category-list, .brand-list", function () { const isCategory = $(this).hasClass("category-list"); const filterType = isCategory ? "category_id" : "brand_id"; const filterId = $(this).data("id"); const route = $(this).data("route"); // product filter route const searchTerm = $("#purchase_product_search").val(); $.ajax({ type: "POST", url: route, data: { search: searchTerm, [filterType]: filterId, // Dynamically set category_id or brand_id }, success: function (response) { $("#products-list").html(response.data); $("#category-list").html(response.categories); $("#brand-list").html(response.brands); }, }); }); // Update cart $(document).on("change", ".batch_no, .expire_date, .price", function () { let $row = $(this).closest("tr"); let updateRoute = $row.data("update_route"); // Get values let expire_date = $row.find(".expire_date").val(); let priceVal = $row.find(".price").val(); let batch_no = $row.find(".batch_no").val(); // Parse and validate price let price = parseFloat(priceVal); if (isNaN(price) || price < 0) { toastr.error("Price cannot be negative or empty."); return; } // Optional: clean batch_no if (batch_no === null || batch_no === undefined) { batch_no = ""; } // Prepare data let data = { batch_no: batch_no, expire_date: expire_date, price: price, }; // Call update function updateCart(data, updateRoute); }); // Function to update cart item with the new quantity function updateCart(data, updateRoute) { $.ajax({ url: updateRoute, type: "PUT", data: data, success: function (response) { if (response.success) { fetchUpdatedCart(calTotalAmount); // Refresh the cart and recalculate totals } else { toastr.error(response.message || "Failed to update cart"); } }, }); }