"use strict"; function currencyFormat(amount, type = "icon", decimals = 2) { let symbol = $("#currency_symbol").val(); let position = $("#currency_position").val(); let code = $("#currency_code").val(); let formattedAmount = formatNumber(amount, decimals); // Abbreviate number // Apply currency format based on the position and type if (type == "icon" || type == "symbol") { return position == "right" ? formattedAmount + symbol : symbol + formattedAmount; } else { return position == "right" ? formattedAmount + " " + code : code + " " + formattedAmount; } } function formatNumber(number, decimals = 2) { if (number >= 1e9) { return removeTrailingZeros((number / 1e9).toFixed(decimals)) + "B"; } else if (number >= 1e6) { return removeTrailingZeros((number / 1e6).toFixed(decimals)) + "M"; } else if (number >= 1e3) { return removeTrailingZeros((number / 1e3).toFixed(decimals)) + "K"; } else { return removeTrailingZeros(number.toFixed(decimals)); } } function removeTrailingZeros(value) { return parseFloat(value).toString(); } let branchRevenueChart; $(document).ready(function () { const ctxBranchRevenue = document .getElementById("branchRevenueChart") .getContext("2d"); function totalEarningExpenseChart(months, incomeData, expenseData) { if (branchRevenueChart) { branchRevenueChart.destroy(); } const allData = [...incomeData, ...expenseData]; const maxValue = Math.max(...allData); // Gradient Backgrounds const incomeBgGradient = ctxBranchRevenue.createLinearGradient(0, 0, 0, 400); incomeBgGradient.addColorStop(0, "rgba(42, 180, 249, 0.17)"); incomeBgGradient.addColorStop(1, "rgba(34, 201, 177, 0)"); const expenseBgGradient = ctxBranchRevenue.createLinearGradient(0, 0, 0, 400); expenseBgGradient.addColorStop(0, "rgba(248, 107, 35, 0.12)"); expenseBgGradient.addColorStop(1, "rgba(249, 190, 16, 0)"); // Solid Gradients for border lines const incomeLine = ctxBranchRevenue.createLinearGradient(0, 0, 400, 0); incomeLine.addColorStop(0, "#019934"); incomeLine.addColorStop(1, "#019934"); const expenseLine = ctxBranchRevenue.createLinearGradient(0, 0, 400, 0); expenseLine.addColorStop(0, "#FF9500"); expenseLine.addColorStop(1, "#FF9500"); branchRevenueChart = new Chart(ctxBranchRevenue, { type: "line", data: { labels: months, datasets: [ { label: "Profit", data: incomeData, borderColor: incomeLine, backgroundColor: incomeBgGradient, fill: true, tension: 0.4, pointBackgroundColor: "#019934", pointRadius: 0, pointHoverRadius: 5, }, { label: "Loss", data: expenseData, borderColor: expenseLine, backgroundColor: expenseBgGradient, fill: true, tension: 0.4, pointBackgroundColor: "#FF9500", pointRadius: 0, pointHoverRadius: 5, }, ], }, options: { responsive: true, maintainAspectRatio: false, interaction: { mode: "index", intersect: false }, plugins: { tooltip: { backgroundColor: "#ffffff", titleColor: "#000000", bodyColor: "#000000", borderColor: "#e5e7eb", borderWidth: 1, callbacks: { label: function (context) { const value = parseFloat(context.raw); return `${context.dataset.label} : ${(value)}`; }, }, }, legend: { display: false }, }, scales: { y: { beginAtZero: true, grid: { drawBorder: false, color: "#C2C6CE", borderDash: [4, 4] }, ticks: { callback: function (value) { if (maxValue < 1000) return value; else if (maxValue < 100000) return (value / 1000) + 'k'; else return (value / 100000).toFixed(1) + 'M'; }, }, }, x: { grid: { display: false } }, }, }, }); } function fetchIncomeExpense(year) { const route = $("#incomeExpenseRoute").val(); $.ajax({ url: route, type: "GET", data: { year: year }, success: function (data) { const months = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ]; const incomeData = Array(12).fill(0); const expenseData = Array(12).fill(0); data.incomes.forEach((item) => { const monthIndex = item.month_number - 1; incomeData[monthIndex] = parseFloat(item.total); }); data.expenses.forEach((item) => { const monthIndex = item.month_number - 1; expenseData[monthIndex] = parseFloat(item.total); }); const totalIncome = incomeData.reduce((a, b) => a + b, 0); const totalExpense = expenseData.reduce((a, b) => a + b, 0); $(".profit-value").text(currencyFormat(totalIncome)); $(".loss-value").text(currencyFormat(totalExpense)); totalEarningExpenseChart(months, incomeData, expenseData); }, error: function (err) { console.error("Error fetching income/expense data:", err); }, }); } // Initial load const selectedYear = $(".overview-year").val(); fetchIncomeExpense(selectedYear); // On year change $(".overview-year").on("change", function () { const year = $(this).val(); fetchIncomeExpense(year); }); }); // Profit Loss Reports -----------------------> const profitLossCanvas = document.getElementById("profitLossChart"); const ctxProfitLoss = profitLossCanvas.getContext("2d"); const gradientProfit = ctxProfitLoss.createLinearGradient(0, 0, 0, profitLossCanvas.height); gradientProfit.addColorStop(0, "#05C535"); gradientProfit.addColorStop(1, "#36F165"); const gradientLoss = ctxProfitLoss.createLinearGradient(0, 0, 0, profitLossCanvas.height); gradientLoss.addColorStop(0, "#FF8983"); gradientLoss.addColorStop(1, "#FF3B30"); // Initial static values (will be updated dynamically) let profit = 0; let loss = 0; const profitLossData = { labels: ["Income", "Expense"], datasets: [ { data: [profit, loss], backgroundColor: [gradientProfit, gradientLoss], hoverOffset: 5, }, ], }; const profitLossConfig = { type: "pie", data: profitLossData, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false }, tooltip: { enabled: true, backgroundColor: "#FFFFFF", titleColor: "#000000", bodyColor: "#000000", borderWidth: 1, displayColors: false, callbacks: { label: function (context) { const label = context.label || ''; const value = parseFloat(context.parsed || 0); const formattedValue = value.toFixed(2); return `${label}: ${formattedValue}`; }, }, }, }, }, }; const profitLossChart = new Chart(ctxProfitLoss, profitLossConfig); // Dynamic update function const chartRoute = document.getElementById("salePurchaseChartRoute").value; const yearSelector = document.querySelector(".overview-loss-profit-year"); function updateProfitLossChart(year) { fetch(`${chartRoute}?year=${year}`) .then(res => res.json()) .then(data => { profit = data.profit ?? 0; loss = data.loss ?? 0; // Update chart dataset profitLossChart.data.datasets[0].data = [profit, loss]; profitLossChart.update(); // ✅ Use your currencyFormat for displayed values too document.querySelector(".profit").textContent = currencyFormat(profit); document.querySelector(".loss").textContent = currencyFormat(loss); }) .catch(err => { console.error("Error fetching profit/loss data:", err); }); } // Initial load updateProfitLossChart(yearSelector.value); // On year change yearSelector.addEventListener("change", function () { updateProfitLossChart(this.value); }); // Responsive resize window.addEventListener("resize", function () { profitLossChart.resize(); }); // for sale data $(document).ready(function() { var route = $('#branchWiseSaleRoute').val(); // Load current year sales on page load var currentYear = $('.branch-wise-sales-year').val(); fetchBranchWiseSales(currentYear); // Listen for year change $('.branch-wise-sales-year').on('change', function() { var year = $(this).val(); fetchBranchWiseSales(year); }); function fetchBranchWiseSales(year) { $.ajax({ url: route, type: 'GET', data: { year: year }, dataType: 'json', success: function(data) { var tbody = $('#sale-data'); tbody.empty(); // clear existing table rows $.each(data, function(index, branch) { var row = ` ${index + 1} ${branch.name} ${branch.sales_sum_total_amount_formatted} ${branch.sales_sum_paid_amount_formatted} ${branch.sales_sum_due_amount_formatted} `; tbody.append(row); }); }, error: function(xhr, status, error) { console.error('Error fetching branch sales:', error); } }); } }); // for purchase data $(document).ready(function() { function fetchBranchPurchases(year) { let url = $('#branchWisePurchaseRoute').val(); $.ajax({ url: url, method: 'GET', data: { year: year }, dataType: 'json', success: function(response) { let tbody = $('#purchase-data'); tbody.empty(); $.each(response, function(index, branch) { let row = ` ${index + 1} ${branch.name} ${branch.purchases_sum_total_amount_formatted} ${branch.purchases_sum_paid_amount_formatted} ${branch.purchases_sum_due_amount_formatted} `; tbody.append(row); }); }, error: function(xhr, status, error) { console.error('Error fetching branch purchases:', error); } }); } // Initial load for current year let currentYear = $('.batch-wise-purchases-year').val(); fetchBranchPurchases(currentYear); // Fetch data on year change $('.batch-wise-purchases-year').on('change', function() { let selectedYear = $(this).val(); fetchBranchPurchases(selectedYear); }); });