Rev 36215 | Blame | Compare with Previous | Last modification | View Log | RSS feed
$(document).on('click', '.mk-pur-sale-ratio-panel', function () {doGetAjaxRequestHandler(`${context}/pur-sale-ratio/panel`, function (response) {$('#main-content').html(response);});});$(document).on('change', '#purSaleStartDate, #purSaleEndDate, #purSaleBrand', function () {console.log("change clicked...");let startDate = $('input[name="startDate"]').val();let endDate = $('input[name="endDate"]').val();let brand = $('select[name="brand"]').val();let supplierId = $('select[name="supplier"]').val();if (!startDate) {alert("Please select start date");return;}if (!endDate) {alert("Please select end date");return;}if (!brand) {alert("Please select brand");return;}if (!supplierId) {supplierId = 0;}doGetAjaxRequestHandler(`${context}/pur-sale-ratio/brandSuppliers?startDate=${startDate}&endDate=${endDate}&brand=${brand}&supplierId=${supplierId}`, function (response) {if (response.hasOwnProperty('purchaseSaleQuantities') && response.purchaseSaleQuantities.length) {createPurchaseSaleBarChart(response.purchaseSaleQuantities, startDate, endDate, brand, supplierId);} else {if (salesChart) salesChart.destroy();if (catalogChart) catalogChart.destroy();}console.log('Purchase sale ratio data fetched successfully',response);if (response.hasOwnProperty('brandWiseSuppliers') && response.brandWiseSuppliers.length) {$('.suppliersList').empty();$('.suppliersList').append(`<option selected disabled>Select Supplier</option>`);$('.suppliersList').append(`<option value="0">All Supplier</option>`);response.brandWiseSuppliers.forEach(function (supplier) {$('.suppliersList').append(`<option value="${supplier.supplierId}">${supplier.supplierName}</option>`);});}});});$(document).on('change', '#purSaleSupplier', function () {let startDate = $('input[name="startDate"]').val();let endDate = $('input[name="endDate"]').val();let brand = $('select[name="brand"]').val();let supplierId = $(this).val();doGetAjaxRequestHandler(`${context}/pur-sale-ratio/data?startDate=${startDate}&endDate=${endDate}&brand=${brand}&supplierId=${supplierId}`, function (response) {if (response.length) {createPurchaseSaleBarChart(response, startDate, endDate, brand, supplierId);}});});let salesChart, catalogChart;let currentPurchaseSaleData = [];let currentCatalogData = [];Chart.register(ChartDataLabels);$(document).on('click', '#exportCsvBtn', function () {exportPurchaseSaleCSV();});function exportPurchaseSaleCSV() {if (!currentPurchaseSaleData.length) {alert('No data to export');return;}let startDate = $('input[name="startDate"]').val();let endDate = $('input[name="endDate"]').val();let brand = $('select[name="brand"]').val() || '';let supplierId = $('select[name="supplier"]').val() || 0;doGetAjaxRequestHandler(`${context}/pur-sale-ratio/catalog-export?startDate=${startDate}&endDate=${endDate}&brand=${brand}&supplierId=${supplierId}`, function (response) {let csvContent = 'Model,Status,Purchase,Sale,Sale %,Unsold (0-5 Days),Unsold (6-15 Days),Unsold (16-30 Days),Unsold (31-45 Days),Unsold (>45 Days)\n';response.forEach(row => {let pct = row.purchase > 0 ? ((row.sale / row.purchase) * 100).toFixed(1) : '0.0';csvContent += `${row.model},${row.status},${row.purchase},${row.sale},${pct}%,${row.unsold5},${row.unsold15},${row.unsold30},${row.unsold45},${row.unsoldAbove45}\n`;});let fileName = `purchase_sale_ratio_${brand}_${startDate}_to_${endDate}.csv`;let blob = new Blob([csvContent], {type: 'text/csv;charset=utf-8;'});let link = document.createElement('a');link.href = URL.createObjectURL(blob);link.download = fileName;link.click();URL.revokeObjectURL(link.href);});}function createPurchaseSaleBarChart(response, startDate, endDate, brand, supplierId) {response = arrangeLabelsOrder(response);currentPurchaseSaleData = response;currentCatalogData = [];$('#exportCsvBtn').show();let labels = [], totalQuantities = [], soldQuantities = [];labels = response.map(sale => sale.status);totalQuantities = response.map(sale => sale.totalQuantity);soldQuantities = response.map(sale => sale.soldQuantity);const ctx = document.getElementById('salesChart').getContext('2d');//destroy salesChart data if availableif (salesChart) {salesChart.destroy();}if (catalogChart) {catalogChart.destroy();}const percentageData = soldQuantities.map((sale, i) => ((sale / totalQuantities[i]) * 100).toFixed(1));// Chart.js configurationsalesChart = new Chart(ctx, {type: 'bar',data: {labels: labels, // Labels for each bardatasets: [{label: 'Purchase',data: totalQuantities,backgroundColor: 'rgba(255, 99, 132, 0.6)', // Red barsborderColor: 'rgba(255, 99, 132, 1)',borderWidth: 1},{label: 'Sale',data: soldQuantities,backgroundColor: 'rgba(144, 238, 144, 0.6)', // Green barsborderColor: 'rgba(144, 238, 144, 1)',borderWidth: 1}]},options: {responsive: true,plugins: {tooltip: {enabled: false,},legend: {position: 'top',},datalabels: {display: true,color: 'black',font: {size: 12,},formatter: function (value, context) {const index = context.dataIndex;const purchase = totalQuantities[index];const sale = soldQuantities[index];const percentage = percentageData[index];if (context.dataset.label === 'Purchase') {return `${purchase}`;} else {return `${sale} (${percentage}%)`;}},align: 'end', // Place labels at the center of the barsanchor: 'center', // Align labels to the center of each bar pairoffset: 5, // Adjust positioning for better visibility if needed},}, onClick: function (event, activeElements) {if (activeElements.length > 0) {const element = activeElements[0]; // Get the clicked elementconst datasetIndex = element.datasetIndex; // Get the dataset (Sale or Purchase)const dataIndex = element.index; // Get the index of the clicked barconst label = this.data.labels[dataIndex]; // Get the label for the clicked barconst value = this.data.datasets[datasetIndex].data[dataIndex]; // Get the value of the clicked bar// Show an alert with the label and valuecatalogPurchaseSaleChart(startDate, endDate, brand, supplierId, label);}},indexAxis: 'y',scales: {x: {beginAtZero: true,title: {display: true,text: 'Quantity',color: '#000000'}},y: {title: {display: true,text: 'Status',color: '#000000'}}}}});}function catalogPurchaseSaleChart(startDate, endDate, brand, supplierId, label) {doGetAjaxRequestHandler(`${context}/pur-sale-ratio/catalog-quantity?startDate=${startDate}&endDate=${endDate}&brand=${brand}&supplierId=${supplierId}&label=${label}`, function (response) {console.log("response to check status - ",response);createCatalogPurchaseSaleBarChart(response, startDate, endDate, supplierId);});}function getCatalogAgeDetail(startDate, endDate, supplierId, label,status) {// /catalog-age-detaillet modelNumber = label;doGetAjaxRequestHandler(`${context}/pur-sale-ratio/catalog-age-detail?startDate=${startDate}&endDate=${endDate}&modelNumber=${modelNumber}&supplierId=${supplierId}&status=${status}`, function (response) {$('#catalog-age-div #catalogModalBody').html(response);$('#catalog-age-div').modal('show');});}function createCatalogPurchaseSaleBarChart(response, startDate, endDate, supplierId) {let labels = [], totalQuantities = [], soldQuantities = [];let filterResponse = response.filter(res => res.sale !== res.purchase);currentCatalogData = filterResponse;labels = filterResponse.map(sale => sale.model);totalQuantities = filterResponse.map(sale => sale.purchase);soldQuantities = filterResponse.map(sale => sale.sale);let status = filterResponse.map(sale => sale.status)[0];let charContainer = document.getElementById('chartContainer');//destroy old Catalog Chart Container$('#catalogChartContainer').remove();//create new Catalog Chart Containerlet newCatalogChartContainer = document.createElement('div');newCatalogChartContainer.id = 'catalogChartContainer';newCatalogChartContainer.classList.add('col-md-6');let canvas = document.createElement('canvas');let catalogChartHeight;switch (labels.length) {case 1:catalogChartHeight = 150;break;case 2:catalogChartHeight = 200;break;case 3:catalogChartHeight = 250;break;case 4:catalogChartHeight = 250;break;default:catalogChartHeight = labels.length * 2 * 25;break;}newCatalogChartContainer.style.height = catalogChartHeight + 'px';const ctx = canvas.getContext('2d');//destroy catalogChart data if availableif (catalogChart) {catalogChart.destroy();}const percentageData = soldQuantities.map((sale, i) => ((sale / totalQuantities[i]) * 100).toFixed(1));// Chart.js configuration//Chart.register(ChartDataLabels);catalogChart = new Chart(ctx, {type: 'bar',data: {labels: labels, // Labels for each bardatasets: [{label: 'Purchase',data: totalQuantities,backgroundColor: 'rgba(255, 99, 132, 0.6)', // Red barsborderColor: 'rgba(255, 99, 132, 1)',borderWidth: 1},{label: 'Sale',data: soldQuantities,backgroundColor: 'rgba(144, 238, 144, 0.6)', // Green barsborderColor: 'rgba(144, 238, 144, 1)',borderWidth: 1,}]},options: {responsive: true,maintainAspectRatio: false,plugins: {tooltip: {enabled: false,},legend: {position: 'top',},datalabels: {display: true,color: 'black',font: {size: 12,},formatter: function (value, context) {const index = context.dataIndex;const purchase = totalQuantities[index];const sale = soldQuantities[index];const percentage = percentageData[index];if (context.dataset.label === 'Purchase') {return `${purchase}`;} else {return `${sale} (${percentage}%)`;}},align: 'end', // Place labels at the center of the barsanchor: 'center', // Align labels to the center of each bar pairoffset: 5, // Adjust positioning for better visibility if needed},}, onClick: function (event, activeElements) {if (activeElements.length > 0) {const element = activeElements[0]; // Get the clicked elementconst datasetIndex = element.datasetIndex; // Get the dataset (Sale or Purchase)const dataIndex = element.index; // Get the index of the clicked barconst modelNumber = this.data.labels[dataIndex]; // Get the label for the clicked bar that is modelNumber this timeconst value = this.data.datasets[datasetIndex].data[dataIndex]; // Get the value of the clicked bargetCatalogAgeDetail(startDate, endDate, supplierId, modelNumber,status);}},indexAxis: 'y',scales: {x: {beginAtZero: true,title: {display: true,text: 'Quantity',color: '#000000'}},y: {title: {display: true,text: 'Models',color: '#000000'}}}}});newCatalogChartContainer.appendChild(canvas);charContainer.appendChild(newCatalogChartContainer);}function arrangeLabelsOrder(responseData) {const requiredOrder = ['HID', 'FASTMOVING', 'SLOWMOVING', 'OTHER'];const orderMap = {};requiredOrder.forEach((label, index) => {orderMap[label] = index;});const sortedResponse = responseData.sort((a, b) => {const indexA = orderMap[a.status] !== undefined ? orderMap[a.status] : Infinity;const indexB = orderMap[b.status] !== undefined ? orderMap[b.status] : Infinity;return indexA - indexB;});return sortedResponse;}