fixed
This commit is contained in:
parent
be6aa1d053
commit
4164ffe4a6
@ -7,7 +7,6 @@ import { getBeforePreviousData, getQuarterPeriods } from '@/services/submissions
|
|||||||
import { getProductSubmissionHistory } from '@/services/submissions/submissionService';
|
import { getProductSubmissionHistory } from '@/services/submissions/submissionService';
|
||||||
import { Line } from 'react-chartjs-2';
|
import { Line } from 'react-chartjs-2';
|
||||||
|
|
||||||
|
|
||||||
// Helper function to get months for quarter
|
// Helper function to get months for quarter
|
||||||
const getMonthsForQuarter = (quarter, year) => {
|
const getMonthsForQuarter = (quarter, year) => {
|
||||||
const monthMap = {
|
const monthMap = {
|
||||||
@ -236,71 +235,6 @@ const ProductChart = ({ product, establishmentId }) => {
|
|||||||
},
|
},
|
||||||
plugins: {
|
plugins: {
|
||||||
legend: {
|
legend: {
|
||||||
// position: 'top',
|
|
||||||
// align: 'center',
|
|
||||||
// labels: {
|
|
||||||
// usePointStyle: true,
|
|
||||||
// boxWidth: 12,
|
|
||||||
// boxHeight: 12,
|
|
||||||
// padding: 12,
|
|
||||||
// font: {
|
|
||||||
// size: 12,
|
|
||||||
// lineHeight: '16px'
|
|
||||||
// },
|
|
||||||
// generateLabels: function(chart) {
|
|
||||||
// const data = chart.data;
|
|
||||||
// if (data.labels.length && data.datasets.length) {
|
|
||||||
// return chart.data.datasets.map((dataset, i) => {
|
|
||||||
// const meta = chart.getDatasetMeta(i);
|
|
||||||
// let label = dataset.label || '';
|
|
||||||
// label = ' ' + label.trim();
|
|
||||||
|
|
||||||
// // For Annual Capacity (dashed line)
|
|
||||||
// if (label.includes('Annual Capacity')) {
|
|
||||||
// return {
|
|
||||||
// text: label,
|
|
||||||
// fillStyle: 'transparent',
|
|
||||||
// hidden: !meta.visible,
|
|
||||||
// lineDash: [3, 3],
|
|
||||||
// lineWidth: 2,
|
|
||||||
// strokeStyle: dataset.borderColor,
|
|
||||||
// pointStyle: 'line',
|
|
||||||
// rotation: 0,
|
|
||||||
// datasetIndex: i
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // For Quantity (solid line)
|
|
||||||
// if (label.includes('Quantity')) {
|
|
||||||
// return {
|
|
||||||
// text: label,
|
|
||||||
// fillStyle: 'transparent',
|
|
||||||
// hidden: !meta.visible,
|
|
||||||
// lineDash: [],
|
|
||||||
// lineWidth: 2,
|
|
||||||
// strokeStyle: dataset.borderColor,
|
|
||||||
// pointStyle: 'line',
|
|
||||||
// rotation: 0,
|
|
||||||
// datasetIndex: i
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // For bar items (Previous, Current, Forecast) - square boxes
|
|
||||||
// return {
|
|
||||||
// text: label,
|
|
||||||
// fillStyle: dataset.backgroundColor,
|
|
||||||
// hidden: !meta.visible,
|
|
||||||
// lineWidth: 0,
|
|
||||||
// strokeStyle: 'transparent',
|
|
||||||
// pointStyle: 'rect',
|
|
||||||
// rotation: 0,
|
|
||||||
// datasetIndex: i
|
|
||||||
// };
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// return [];
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
display:false,
|
display:false,
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
@ -618,7 +552,6 @@ const ValidationReview = () => {
|
|||||||
productId
|
productId
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
let mappedDataMap = {};
|
let mappedDataMap = {};
|
||||||
|
|
||||||
submissionData?.products?.forEach((product) => {
|
submissionData?.products?.forEach((product) => {
|
||||||
@ -670,9 +603,6 @@ setAdditionalForecastMonths([
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Helper to get forecast data for a specific product
|
// Helper to get forecast data for a specific product
|
||||||
const getCurrentYearForecastData = (productId) => {
|
const getCurrentYearForecastData = (productId) => {
|
||||||
if (!showPreviousNext || !productId) {
|
if (!showPreviousNext || !productId) {
|
||||||
@ -771,34 +701,34 @@ setAdditionalForecastMonths([
|
|||||||
};
|
};
|
||||||
|
|
||||||
const calculateVariance = (previous, current) => {
|
const calculateVariance = (previous, current) => {
|
||||||
const previousNum = parseFloat(previous) || 0;
|
const previousNum = Number(previous);
|
||||||
const currentNum = parseFloat(current) || 0;
|
const currentNum = Number(current);
|
||||||
|
|
||||||
if (previousNum === 0) {
|
if (isNaN(previousNum) || isNaN(currentNum)) return 0;
|
||||||
return currentNum === 0 ? 0 : 100;
|
|
||||||
}
|
// both 0 → no variance
|
||||||
|
if (previousNum === 0 && currentNum === 0) return 0;
|
||||||
|
|
||||||
|
// 0 → value (special case)
|
||||||
|
if (previousNum === 0) return 100;
|
||||||
|
|
||||||
return ((currentNum - previousNum) / Math.abs(previousNum)) * 100;
|
return ((currentNum - previousNum) / Math.abs(previousNum)) * 100;
|
||||||
};
|
};
|
||||||
|
|
||||||
const formatPercentage = (variance) => {
|
const formatPercentage = (variance) => {
|
||||||
const absVariance = Math.abs(variance);
|
if (variance === 0) return '0%';
|
||||||
|
|
||||||
if (absVariance === 0) return '0%';
|
const sign = variance > 0 ? '+' : '';
|
||||||
|
const abs = Math.abs(variance);
|
||||||
|
|
||||||
if (absVariance >= 1000) {
|
if (abs >= 100) return `${sign}${Math.round(variance)}%`;
|
||||||
return `${variance > 0 ? '+' : ''}${Math.round(variance).toLocaleString()}%`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (absVariance >= 100) {
|
return `${sign}${variance.toFixed(1)}%`;
|
||||||
return `${variance > 0 ? '+' : ''}${Math.round(variance)}%`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return `${variance > 0 ? '+' : ''}${variance.toFixed(1)}%`;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const getVarianceDisplay = (previousValue, currentValue, isFirstMonth = false) => {
|
const getVarianceDisplay = (previousValue, currentValue, isFirstMonth = false) => {
|
||||||
if (isFirstMonth) return null;
|
if (isFirstMonth) return null;
|
||||||
|
if (previousValue == null || currentValue == null) return null;
|
||||||
|
|
||||||
const variance = calculateVariance(previousValue, currentValue);
|
const variance = calculateVariance(previousValue, currentValue);
|
||||||
const absVariance = Math.abs(variance);
|
const absVariance = Math.abs(variance);
|
||||||
@ -806,49 +736,45 @@ setAdditionalForecastMonths([
|
|||||||
if (absVariance === 0) {
|
if (absVariance === 0) {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center justify-center mt-1">
|
<div className="flex items-center justify-center mt-1">
|
||||||
<span className='text-[#286CFF] text-xs'>0%</span>
|
<span className="text-[#286CFF] text-xs">0%</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const isPositive = variance > 0;
|
const isPositive = variance > 0;
|
||||||
const arrow = isPositive ? '▲' : '▼';
|
const arrow = isPositive ? '▲' : '▼';
|
||||||
|
const color = isPositive ? 'text-[#1E7C34]' : 'text-[#B52520]';
|
||||||
let colorClass = isPositive ? 'text-[#1E7C34]' : 'text-[#B52520]';
|
|
||||||
|
|
||||||
const percentage = formatPercentage(variance);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center justify-center mt-1">
|
<div className="flex items-center justify-center mt-1">
|
||||||
<span className={`text-xs ${colorClass}`}>{arrow} {percentage}</span>
|
<span className={`text-xs ${color}`}>
|
||||||
|
{arrow} {formatPercentage(variance)}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getCellClass = (previousValue, currentValue, isFirstMonth = false) => {
|
const getCellClass = (previousValue, currentValue, isFirstMonth = false) => {
|
||||||
if (isFirstMonth || !varianceHighlighting) return '';
|
if (isFirstMonth || !varianceHighlighting) return '';
|
||||||
|
|
||||||
const variance = calculateVariance(previousValue, currentValue);
|
const variance = calculateVariance(previousValue, currentValue);
|
||||||
const absVariance = Math.abs(variance);
|
const absVariance = Math.abs(variance);
|
||||||
|
|
||||||
// 🟡 Above 100 selected → ONLY > 100% highlight
|
// 🔴 threshold > 100 → only highlight above 100
|
||||||
if (threshold > 100) {
|
if (threshold > 100) {
|
||||||
if (absVariance <= 100) return '';
|
if (absVariance <= 100) return '';
|
||||||
return variance > 0 ? 'bg-[#F0FDF4]' : 'bg-[#FEF2F2]';
|
return variance > 0 ? 'bg-[#F0FDF4]' : 'bg-[#FEF2F2]';
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🟢 Normal case (≤ threshold)
|
// 🟢 NORMAL: highlight WITHIN threshold
|
||||||
if (absVariance > threshold) return '';
|
if (absVariance > threshold) return '';
|
||||||
|
|
||||||
return variance > 0 ? 'bg-[#F0FDF4]' : 'bg-[#FEF2F2]';
|
return variance > 0 ? 'bg-[#F0FDF4]' : 'bg-[#FEF2F2]';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getBorderClass = (previousValue, currentValue, isFirstMonth = false) => {
|
||||||
|
|
||||||
const getBorderClass = (previousValue, currentValue, isFirstMonth = false) => {
|
|
||||||
if (isFirstMonth || !varianceHighlighting) return '';
|
if (isFirstMonth || !varianceHighlighting) return '';
|
||||||
|
|
||||||
// 🔴 Above 100 selected → no border highlight
|
|
||||||
if (threshold > 100) return '';
|
if (threshold > 100) return '';
|
||||||
|
|
||||||
const variance = calculateVariance(previousValue, currentValue);
|
const variance = calculateVariance(previousValue, currentValue);
|
||||||
@ -859,13 +785,11 @@ const getBorderClass = (previousValue, currentValue, isFirstMonth = false) => {
|
|||||||
return variance > 0
|
return variance > 0
|
||||||
? 'border-2 border-[#1E7C34]'
|
? 'border-2 border-[#1E7C34]'
|
||||||
: 'border-2 border-[#B52520]';
|
: 'border-2 border-[#B52520]';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getQuarterYearLabel = (quarter, year) => {
|
||||||
const getQuarterYearLabel = (quarter, year) => {
|
|
||||||
return `${quarter} ${year}`;
|
return `${quarter} ${year}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return (
|
return (
|
||||||
@ -939,21 +863,11 @@ const getQuarterYearLabel = (quarter, year) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const previousLabel = getQuarterYearLabel(previousQuarter, previousYear);
|
const previousLabel = getQuarterYearLabel(previousQuarter, previousYear);
|
||||||
const currentLabel = getQuarterYearLabel(currentQuarter, currentYear);
|
const currentLabel = getQuarterYearLabel(currentQuarter, currentYear);
|
||||||
|
const forecastLabel = getQuarterYearLabel(forecastQuarter, forecastYear);
|
||||||
// Next Year Forecast
|
|
||||||
const forecastLabel = getQuarterYearLabel(forecastQuarter, forecastYear );
|
|
||||||
|
|
||||||
// Optional: Previous Forecast (same year usually)
|
|
||||||
// const additionalForecastLabel = getQuarterYearLabel(forecastQuarter, currentYear);
|
|
||||||
|
|
||||||
// Use generated year labels or fallback to full year display
|
|
||||||
// const previousLabel = yearLabels?.previous || `${previousQuarter} ${previousYear}`;
|
|
||||||
// const currentLabel = yearLabels?.current || `${currentQuarter} ${currentYear}`;
|
|
||||||
// const forecastLabel = yearLabels?.forecast || `${forecastQuarter} ${forecastYear}`;
|
|
||||||
|
|
||||||
// Calculate additional forecast label dynamically
|
// Calculate additional forecast label dynamically
|
||||||
const additionalForecastLabel = showPreviousNext
|
const additionalForecastLabel = showPreviousNext
|
||||||
? additionalForecastQuarter === "No"
|
? additionalForecastQuarter === "No"
|
||||||
? "No"
|
? "No"
|
||||||
: [additionalForecastQuarter, additionalForecastYear]
|
: [additionalForecastQuarter, additionalForecastYear]
|
||||||
@ -961,8 +875,6 @@ const additionalForecastLabel = showPreviousNext
|
|||||||
.join(" ")
|
.join(" ")
|
||||||
: "";
|
: "";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const establishmentDetails = [
|
const establishmentDetails = [
|
||||||
{
|
{
|
||||||
label: 'Establishment Name',
|
label: 'Establishment Name',
|
||||||
@ -1089,7 +1001,20 @@ const additionalForecastLabel = showPreviousNext
|
|||||||
|
|
||||||
{submissionData?.products?.length > 0 ? (
|
{submissionData?.products?.length > 0 ? (
|
||||||
<div className={`grid gap-4 ${submissionData.products.length === 1 ? 'grid-cols-1' : 'grid-cols-1 '}`}>
|
<div className={`grid gap-4 ${submissionData.products.length === 1 ? 'grid-cols-1' : 'grid-cols-1 '}`}>
|
||||||
{submissionData.products.map((product, idx) => (
|
{submissionData.products.map((product, idx) => {
|
||||||
|
// Check if previous quarter has any non-zero values
|
||||||
|
const isPreviousQuarterAllZeros =
|
||||||
|
(!product.previous_quantity_period_one || Number(product.previous_quantity_period_one) === 0) &&
|
||||||
|
(!product.previous_quantity_period_two || Number(product.previous_quantity_period_two) === 0) &&
|
||||||
|
(!product.previous_quantity_period_three || Number(product.previous_quantity_period_three) === 0);
|
||||||
|
|
||||||
|
// For cost also check
|
||||||
|
const isPreviousQuarterCostAllZeros =
|
||||||
|
(!product.previous_cost_period_one || Number(product.previous_cost_period_one) === 0) &&
|
||||||
|
(!product.previous_cost_period_two || Number(product.previous_cost_period_two) === 0) &&
|
||||||
|
(!product.previous_cost_period_three || Number(product.previous_cost_period_three) === 0);
|
||||||
|
|
||||||
|
return (
|
||||||
<section key={product.id || idx} className="rounded-[16px] bg-white p-6 shadow-[0_16px_32px_rgba(15,23,42,0.08)] ring-1 ring-[#E5E7EB] space-y-5">
|
<section key={product.id || idx} className="rounded-[16px] bg-white p-6 shadow-[0_16px_32px_rgba(15,23,42,0.08)] ring-1 ring-[#E5E7EB] space-y-5">
|
||||||
<div className="flex flex-wrap items-center justify-between gap-4">
|
<div className="flex flex-wrap items-center justify-between gap-4">
|
||||||
<div className="text-sm font-semibold text-[#232528]">
|
<div className="text-sm font-semibold text-[#232528]">
|
||||||
@ -1181,10 +1106,7 @@ const additionalForecastLabel = showPreviousNext
|
|||||||
? "Cells with variance > 100% will be highlighted"
|
? "Cells with variance > 100% will be highlighted"
|
||||||
: `Cells with variance ≤ ${threshold}% will be highlighted`}
|
: `Cells with variance ≤ ${threshold}% will be highlighted`}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<table className="min-w-full text-sm text-left border-collapse">
|
<table className="min-w-full text-sm text-left border-collapse">
|
||||||
<thead>
|
<thead>
|
||||||
@ -1309,7 +1231,7 @@ const additionalForecastLabel = showPreviousNext
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr className="border-t border-[#E5E7EB]">
|
<tr className="border-t border-[#E5E7EB]">
|
||||||
@ -1319,42 +1241,82 @@ const additionalForecastLabel = showPreviousNext
|
|||||||
|
|
||||||
{showPreviousNext ? (
|
{showPreviousNext ? (
|
||||||
<>
|
<>
|
||||||
{/* Previous Quarter Data */}
|
{/* Previous Quarter – Month 1 (BASE) - NO VARIANCE */}
|
||||||
<td className="px-3 py-3 border border-[#E5E7EB] text-center">
|
<td className="px-3 py-3 border border-[#E5E7EB] text-center">
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.previous_quantity_period_one || '0'}</span>
|
<span className="font-medium">
|
||||||
</div>
|
{product.previous_quantity_period_one || "0"}
|
||||||
</td>
|
</span>
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_quantity_period_one, product.previous_quantity_period_two, true)} ${getBorderClass(product.previous_quantity_period_one, product.previous_quantity_period_two, true)}`}>
|
|
||||||
<div className="flex flex-col items-center justify-center">
|
|
||||||
<span className="font-medium">{product.previous_quantity_period_two || '0'}</span>
|
|
||||||
{getVarianceDisplay(product.previous_quantity_period_one, product.previous_quantity_period_two, true)}
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_quantity_period_two, product.previous_quantity_period_three)} ${getBorderClass(product.previous_quantity_period_two, product.previous_quantity_period_three)}`}>
|
|
||||||
<div className="flex flex-col items-center justify-center">
|
|
||||||
<span className="font-medium">{product.previous_quantity_period_three || '0'}</span>
|
|
||||||
{getVarianceDisplay(product.previous_quantity_period_two, product.previous_quantity_period_three)}
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
{/* Current Quarter Data */}
|
{/* Previous Quarter – Month 2 */}
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_quantity_period_three, product.current_quantity_period_one)} ${getBorderClass(product.previous_quantity_period_three, product.current_quantity_period_one)}`}>
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_quantity_period_one, product.previous_quantity_period_two, true)} ${getBorderClass(product.previous_quantity_period_one, product.previous_quantity_period_two, true)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.current_quantity_period_one || '0'}</span>
|
<span className="font-medium">
|
||||||
{getVarianceDisplay(product.previous_quantity_period_three, product.current_quantity_period_one)}
|
{product.previous_quantity_period_two || "0"}
|
||||||
|
</span>
|
||||||
|
{/* If previous quarter has values, show variance from 2nd column */}
|
||||||
|
{!isPreviousQuarterAllZeros && getVarianceDisplay(
|
||||||
|
product.previous_quantity_period_one,
|
||||||
|
product.previous_quantity_period_two
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_quantity_period_one, product.current_quantity_period_two)} ${getBorderClass(product.current_quantity_period_one, product.current_quantity_period_two)}`}>
|
|
||||||
|
{/* Previous Quarter – Month 3 */}
|
||||||
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_quantity_period_two, product.previous_quantity_period_three, isPreviousQuarterAllZeros)} ${getBorderClass(product.previous_quantity_period_two, product.previous_quantity_period_three, isPreviousQuarterAllZeros)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.current_quantity_period_two || '0'}</span>
|
<span className="font-medium">
|
||||||
{getVarianceDisplay(product.current_quantity_period_one, product.current_quantity_period_two)}
|
{product.previous_quantity_period_three || "0"}
|
||||||
|
</span>
|
||||||
|
{/* If previous quarter has values, show variance */}
|
||||||
|
{!isPreviousQuarterAllZeros && getVarianceDisplay(
|
||||||
|
product.previous_quantity_period_two,
|
||||||
|
product.previous_quantity_period_three
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_quantity_period_two, product.current_quantity_period_three)} ${getBorderClass(product.current_quantity_period_two, product.current_quantity_period_three)}`}>
|
|
||||||
|
{/* Current Quarter – Month 1 */}
|
||||||
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_quantity_period_three, product.current_quantity_period_one, isPreviousQuarterAllZeros)} ${getBorderClass(product.previous_quantity_period_three, product.current_quantity_period_one, isPreviousQuarterAllZeros)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.current_quantity_period_three || '0'}</span>
|
<span className="font-medium">
|
||||||
{getVarianceDisplay(product.current_quantity_period_two, product.current_quantity_period_three)}
|
{product.current_quantity_period_one || "0"}
|
||||||
|
</span>
|
||||||
|
{/* If previous quarter is all zeros, treat this as FIRST month */}
|
||||||
|
{!isPreviousQuarterAllZeros && getVarianceDisplay(
|
||||||
|
product.previous_quantity_period_three,
|
||||||
|
product.current_quantity_period_one
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
{/* Current Quarter – Month 2 */}
|
||||||
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_quantity_period_one, product.current_quantity_period_two, false)} ${getBorderClass(product.current_quantity_period_one, product.current_quantity_period_two, false)}`}>
|
||||||
|
<div className="flex flex-col items-center justify-center">
|
||||||
|
<span className="font-medium">
|
||||||
|
{product.current_quantity_period_two || "0"}
|
||||||
|
</span>
|
||||||
|
{/* Always show variance for Month 2 (vs Month 1) */}
|
||||||
|
{getVarianceDisplay(
|
||||||
|
product.current_quantity_period_one,
|
||||||
|
product.current_quantity_period_two
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
{/* Current Quarter – Month 3 */}
|
||||||
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_quantity_period_two, product.current_quantity_period_three, false)} ${getBorderClass(product.current_quantity_period_two, product.current_quantity_period_three, false)}`}>
|
||||||
|
<div className="flex flex-col items-center justify-center">
|
||||||
|
<span className="font-medium">
|
||||||
|
{product.current_quantity_period_three || "0"}
|
||||||
|
</span>
|
||||||
|
{/* Always show variance for Month 3 (vs Month 2) */}
|
||||||
|
{getVarianceDisplay(
|
||||||
|
product.current_quantity_period_two,
|
||||||
|
product.current_quantity_period_three
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
@ -1363,19 +1325,19 @@ const additionalForecastLabel = showPreviousNext
|
|||||||
const historicalData = getCurrentYearForecastData(product?.product?.id);
|
const historicalData = getCurrentYearForecastData(product?.product?.id);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_quantity_period_three, historicalData.forecast_quantity_period_one)} ${getBorderClass(product.current_quantity_period_three, historicalData.forecast_quantity_period_one)}`}>
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_quantity_period_three, historicalData.forecast_quantity_period_one, false)} ${getBorderClass(product.current_quantity_period_three, historicalData.forecast_quantity_period_one, false)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{historicalData.forecast_quantity_period_one || '0'}</span>
|
<span className="font-medium">{historicalData.forecast_quantity_period_one || '0'}</span>
|
||||||
{getVarianceDisplay(product.current_quantity_period_three, historicalData.forecast_quantity_period_one)}
|
{getVarianceDisplay(product.current_quantity_period_three, historicalData.forecast_quantity_period_one)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(historicalData.forecast_quantity_period_one, historicalData.forecast_quantity_period_two)} ${getBorderClass(historicalData.forecast_quantity_period_one, historicalData.forecast_quantity_period_two)}`}>
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(historicalData.forecast_quantity_period_one, historicalData.forecast_quantity_period_two, false)} ${getBorderClass(historicalData.forecast_quantity_period_one, historicalData.forecast_quantity_period_two, false)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{historicalData.forecast_quantity_period_two || '0'}</span>
|
<span className="font-medium">{historicalData.forecast_quantity_period_two || '0'}</span>
|
||||||
{getVarianceDisplay(historicalData.forecast_quantity_period_one, historicalData.forecast_quantity_period_two)}
|
{getVarianceDisplay(historicalData.forecast_quantity_period_one, historicalData.forecast_quantity_period_two)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(historicalData.forecast_quantity_period_two, historicalData.forecast_quantity_period_three)} ${getBorderClass(historicalData.forecast_quantity_period_two, historicalData.forecast_quantity_period_three)}`}>
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(historicalData.forecast_quantity_period_two, historicalData.forecast_quantity_period_three, false)} ${getBorderClass(historicalData.forecast_quantity_period_two, historicalData.forecast_quantity_period_three, false)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{historicalData.forecast_quantity_period_three || '0'}</span>
|
<span className="font-medium">{historicalData.forecast_quantity_period_three || '0'}</span>
|
||||||
{getVarianceDisplay(historicalData.forecast_quantity_period_two, historicalData.forecast_quantity_period_three)}
|
{getVarianceDisplay(historicalData.forecast_quantity_period_two, historicalData.forecast_quantity_period_three)}
|
||||||
@ -1386,19 +1348,19 @@ const additionalForecastLabel = showPreviousNext
|
|||||||
})()}
|
})()}
|
||||||
|
|
||||||
{/* NEXT YEAR FORECAST Data (original from submission) */}
|
{/* NEXT YEAR FORECAST Data (original from submission) */}
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_quantity_period_three, product.forecast_quantity_period_one)} ${getBorderClass(product.current_quantity_period_three, product.forecast_quantity_period_one)}`}>
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_quantity_period_three, product.forecast_quantity_period_one, false)} ${getBorderClass(product.current_quantity_period_three, product.forecast_quantity_period_one, false)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.forecast_quantity_period_one || '0'}</span>
|
<span className="font-medium">{product.forecast_quantity_period_one || '0'}</span>
|
||||||
{getVarianceDisplay(product.current_quantity_period_three, product.forecast_quantity_period_one)}
|
{getVarianceDisplay(product.current_quantity_period_three, product.forecast_quantity_period_one)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_quantity_period_one, product.forecast_quantity_period_two)} ${getBorderClass(product.forecast_quantity_period_one, product.forecast_quantity_period_two)}`}>
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_quantity_period_one, product.forecast_quantity_period_two, false)} ${getBorderClass(product.forecast_quantity_period_one, product.forecast_quantity_period_two, false)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.forecast_quantity_period_two || '0'}</span>
|
<span className="font-medium">{product.forecast_quantity_period_two || '0'}</span>
|
||||||
{getVarianceDisplay(product.forecast_quantity_period_one, product.forecast_quantity_period_two)}
|
{getVarianceDisplay(product.forecast_quantity_period_one, product.forecast_quantity_period_two)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_quantity_period_two, product.forecast_quantity_period_three)} ${getBorderClass(product.forecast_quantity_period_two, product.forecast_quantity_period_three)}`}>
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_quantity_period_two, product.forecast_quantity_period_three, false)} ${getBorderClass(product.forecast_quantity_period_two, product.forecast_quantity_period_three, false)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.forecast_quantity_period_three || '0'}</span>
|
<span className="font-medium">{product.forecast_quantity_period_three || '0'}</span>
|
||||||
{getVarianceDisplay(product.forecast_quantity_period_two, product.forecast_quantity_period_three)}
|
{getVarianceDisplay(product.forecast_quantity_period_two, product.forecast_quantity_period_three)}
|
||||||
@ -1407,59 +1369,98 @@ const additionalForecastLabel = showPreviousNext
|
|||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
|
{/* Previous Quarter – Month 1 */}
|
||||||
<td className="px-3 py-3 border border-[#E5E7EB] text-center">
|
<td className="px-3 py-3 border border-[#E5E7EB] text-center">
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.previous_quantity_period_one || '0'}</span>
|
<span className="font-medium">{product.previous_quantity_period_one || '0'}</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
{/* Previous Quarter – Month 2 */}
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_quantity_period_one, product.previous_quantity_period_two, true)} ${getBorderClass(product.previous_quantity_period_one, product.previous_quantity_period_two, true)}`}>
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_quantity_period_one, product.previous_quantity_period_two, true)} ${getBorderClass(product.previous_quantity_period_one, product.previous_quantity_period_two, true)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.previous_quantity_period_two || '0'}</span>
|
<span className="font-medium">{product.previous_quantity_period_two || '0'}</span>
|
||||||
{getVarianceDisplay(product.previous_quantity_period_one, product.previous_quantity_period_two, true)}
|
{!isPreviousQuarterAllZeros && getVarianceDisplay(
|
||||||
|
product.previous_quantity_period_one,
|
||||||
|
product.previous_quantity_period_two
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_quantity_period_two, product.previous_quantity_period_three)} ${getBorderClass(product.previous_quantity_period_two, product.previous_quantity_period_three)}`}>
|
|
||||||
|
{/* Previous Quarter – Month 3 */}
|
||||||
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_quantity_period_two, product.previous_quantity_period_three, isPreviousQuarterAllZeros)} ${getBorderClass(product.previous_quantity_period_two, product.previous_quantity_period_three, isPreviousQuarterAllZeros)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.previous_quantity_period_three || '0'}</span>
|
<span className="font-medium">{product.previous_quantity_period_three || '0'}</span>
|
||||||
{getVarianceDisplay(product.previous_quantity_period_two, product.previous_quantity_period_three)}
|
{!isPreviousQuarterAllZeros && getVarianceDisplay(
|
||||||
|
product.previous_quantity_period_two,
|
||||||
|
product.previous_quantity_period_three
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_quantity_period_three, product.current_quantity_period_one)} ${getBorderClass(product.previous_quantity_period_three, product.current_quantity_period_one)}`}>
|
{/* Current Quarter – Month 1 */}
|
||||||
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_quantity_period_three, product.current_quantity_period_one, isPreviousQuarterAllZeros)} ${getBorderClass(product.previous_quantity_period_three, product.current_quantity_period_one, isPreviousQuarterAllZeros)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.current_quantity_period_one || '0'}</span>
|
<span className="font-medium">{product.current_quantity_period_one || '0'}</span>
|
||||||
{getVarianceDisplay(product.previous_quantity_period_three, product.current_quantity_period_one)}
|
{!isPreviousQuarterAllZeros && getVarianceDisplay(
|
||||||
</div>
|
product.previous_quantity_period_three,
|
||||||
</td>
|
product.current_quantity_period_one
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_quantity_period_one, product.current_quantity_period_two)} ${getBorderClass(product.current_quantity_period_one, product.current_quantity_period_two)}`}>
|
)}
|
||||||
<div className="flex flex-col items-center justify-center">
|
|
||||||
<span className="font-medium">{product.current_quantity_period_two || '0'}</span>
|
|
||||||
{getVarianceDisplay(product.current_quantity_period_one, product.current_quantity_period_two)}
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_quantity_period_two, product.current_quantity_period_three)} ${getBorderClass(product.current_quantity_period_two, product.current_quantity_period_three)}`}>
|
|
||||||
<div className="flex flex-col items-center justify-center">
|
|
||||||
<span className="font-medium">{product.current_quantity_period_three || '0'}</span>
|
|
||||||
{getVarianceDisplay(product.current_quantity_period_two, product.current_quantity_period_three)}
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_quantity_period_three, product.forecast_quantity_period_one)} ${getBorderClass(product.current_quantity_period_three, product.forecast_quantity_period_one)}`}>
|
{/* Current Quarter – Month 2 */}
|
||||||
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_quantity_period_one, product.current_quantity_period_two, false)} ${getBorderClass(product.current_quantity_period_one, product.current_quantity_period_two, false)}`}>
|
||||||
|
<div className="flex flex-col items-center justify-center">
|
||||||
|
<span className="font-medium">{product.current_quantity_period_two || '0'}</span>
|
||||||
|
{getVarianceDisplay(
|
||||||
|
product.current_quantity_period_one,
|
||||||
|
product.current_quantity_period_two
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
{/* Current Quarter – Month 3 */}
|
||||||
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_quantity_period_two, product.current_quantity_period_three, false)} ${getBorderClass(product.current_quantity_period_two, product.current_quantity_period_three, false)}`}>
|
||||||
|
<div className="flex flex-col items-center justify-center">
|
||||||
|
<span className="font-medium">{product.current_quantity_period_three || '0'}</span>
|
||||||
|
{getVarianceDisplay(
|
||||||
|
product.current_quantity_period_two,
|
||||||
|
product.current_quantity_period_three
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
{/* Next Year Forecast – Month 1 */}
|
||||||
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_quantity_period_three, product.forecast_quantity_period_one, false)} ${getBorderClass(product.current_quantity_period_three, product.forecast_quantity_period_one, false)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.forecast_quantity_period_one || '0'}</span>
|
<span className="font-medium">{product.forecast_quantity_period_one || '0'}</span>
|
||||||
{getVarianceDisplay(product.current_quantity_period_three, product.forecast_quantity_period_one)}
|
{getVarianceDisplay(
|
||||||
|
product.current_quantity_period_three,
|
||||||
|
product.forecast_quantity_period_one
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_quantity_period_one, product.forecast_quantity_period_two)} ${getBorderClass(product.forecast_quantity_period_one, product.forecast_quantity_period_two)}`}>
|
|
||||||
|
{/* Next Year Forecast – Month 2 */}
|
||||||
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_quantity_period_one, product.forecast_quantity_period_two, false)} ${getBorderClass(product.forecast_quantity_period_one, product.forecast_quantity_period_two, false)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.forecast_quantity_period_two || '0'}</span>
|
<span className="font-medium">{product.forecast_quantity_period_two || '0'}</span>
|
||||||
{getVarianceDisplay(product.forecast_quantity_period_one, product.forecast_quantity_period_two)}
|
{getVarianceDisplay(
|
||||||
|
product.forecast_quantity_period_one,
|
||||||
|
product.forecast_quantity_period_two
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_quantity_period_two, product.forecast_quantity_period_three)} ${getBorderClass(product.forecast_quantity_period_two, product.forecast_quantity_period_three)}`}>
|
|
||||||
|
{/* Next Year Forecast – Month 3 */}
|
||||||
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_quantity_period_two, product.forecast_quantity_period_three, false)} ${getBorderClass(product.forecast_quantity_period_two, product.forecast_quantity_period_three, false)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.forecast_quantity_period_three || '0'}</span>
|
<span className="font-medium">{product.forecast_quantity_period_three || '0'}</span>
|
||||||
{getVarianceDisplay(product.forecast_quantity_period_two, product.forecast_quantity_period_three)}
|
{getVarianceDisplay(
|
||||||
|
product.forecast_quantity_period_two,
|
||||||
|
product.forecast_quantity_period_three
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</>
|
</>
|
||||||
@ -1473,39 +1474,55 @@ const additionalForecastLabel = showPreviousNext
|
|||||||
|
|
||||||
{showPreviousNext ? (
|
{showPreviousNext ? (
|
||||||
<>
|
<>
|
||||||
{/* Previous Quarter Cost */}
|
{/* Previous Cost – Month 1 (BASE) - NO VARIANCE */}
|
||||||
<td className="px-3 py-3 border border-[#E5E7EB] text-center">
|
<td className="px-3 py-3 border border-[#E5E7EB] text-center">
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.previous_cost_period_one || '0'}</span>
|
<span className="font-medium">
|
||||||
</div>
|
{product.previous_cost_period_one || "0"}
|
||||||
</td>
|
</span>
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_cost_period_one, product.previous_cost_period_two, true)} ${getBorderClass(product.previous_cost_period_one, product.previous_cost_period_two, true)}`}>
|
|
||||||
<div className="flex flex-col items-center justify-center">
|
|
||||||
<span className="font-medium">{product.previous_cost_period_two || '0'}</span>
|
|
||||||
{getVarianceDisplay(product.previous_cost_period_one, product.previous_cost_period_two, true)}
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_cost_period_two, product.previous_cost_period_three)} ${getBorderClass(product.previous_cost_period_two, product.previous_cost_period_three)}`}>
|
|
||||||
<div className="flex flex-col items-center justify-center">
|
|
||||||
<span className="font-medium">{product.previous_cost_period_three || '0'}</span>
|
|
||||||
{getVarianceDisplay(product.previous_cost_period_two, product.previous_cost_period_three)}
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
{/* Current Quarter Cost */}
|
{/* Previous Cost – Month 2 */}
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_cost_period_three, product.current_cost_period_one)} ${getBorderClass(product.previous_cost_period_three, product.current_cost_period_one)}`}>
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_cost_period_one, product.previous_cost_period_two, true)} ${getBorderClass(product.previous_cost_period_one, product.previous_cost_period_two, true)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.current_cost_period_one || '0'}</span>
|
<span className="font-medium">
|
||||||
{getVarianceDisplay(product.previous_cost_period_three, product.current_cost_period_one)}
|
{product.previous_cost_period_two || "0"}
|
||||||
|
</span>
|
||||||
|
{!isPreviousQuarterCostAllZeros && getVarianceDisplay(
|
||||||
|
product.previous_cost_period_one,
|
||||||
|
product.previous_cost_period_two
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_cost_period_one, product.current_cost_period_two)} ${getBorderClass(product.current_cost_period_one, product.current_cost_period_two)}`}>
|
|
||||||
|
{/* Previous Cost – Month 3 */}
|
||||||
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_cost_period_two, product.previous_cost_period_three, isPreviousQuarterCostAllZeros)} ${getBorderClass(product.previous_cost_period_two, product.previous_cost_period_three, isPreviousQuarterCostAllZeros)}`}>
|
||||||
|
<div className="flex flex-col items-center justify-center">
|
||||||
|
<span className="font-medium">
|
||||||
|
{product.previous_cost_period_three || "0"}
|
||||||
|
</span>
|
||||||
|
{!isPreviousQuarterCostAllZeros && getVarianceDisplay(
|
||||||
|
product.previous_cost_period_two,
|
||||||
|
product.previous_cost_period_three
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
{/* Current Quarter Cost – Month 1 */}
|
||||||
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_cost_period_three, product.current_cost_period_one, isPreviousQuarterCostAllZeros)} ${getBorderClass(product.previous_cost_period_three, product.current_cost_period_one, isPreviousQuarterCostAllZeros)}`}>
|
||||||
|
<div className="flex flex-col items-center justify-center">
|
||||||
|
<span className="font-medium">{product.current_cost_period_one || '0'}</span>
|
||||||
|
{!isPreviousQuarterCostAllZeros && getVarianceDisplay(product.previous_cost_period_three, product.current_cost_period_one)}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_cost_period_one, product.current_cost_period_two, false)} ${getBorderClass(product.current_cost_period_one, product.current_cost_period_two, false)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.current_cost_period_two || '0'}</span>
|
<span className="font-medium">{product.current_cost_period_two || '0'}</span>
|
||||||
{getVarianceDisplay(product.current_cost_period_one, product.current_cost_period_two)}
|
{getVarianceDisplay(product.current_cost_period_one, product.current_cost_period_two)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_cost_period_two, product.current_cost_period_three)} ${getBorderClass(product.current_cost_period_two, product.current_cost_period_three)}`}>
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_cost_period_two, product.current_cost_period_three, false)} ${getBorderClass(product.current_cost_period_two, product.current_cost_period_three, false)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.current_cost_period_three || '0'}</span>
|
<span className="font-medium">{product.current_cost_period_three || '0'}</span>
|
||||||
{getVarianceDisplay(product.current_cost_period_two, product.current_cost_period_three)}
|
{getVarianceDisplay(product.current_cost_period_two, product.current_cost_period_three)}
|
||||||
@ -1517,19 +1534,19 @@ const additionalForecastLabel = showPreviousNext
|
|||||||
const historicalData = getCurrentYearForecastData(product?.product?.id);
|
const historicalData = getCurrentYearForecastData(product?.product?.id);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_cost_period_three, historicalData.forecast_cost_period_one)} ${getBorderClass(product.current_cost_period_three, historicalData.forecast_cost_period_one)}`}>
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_cost_period_three, historicalData.forecast_cost_period_one, false)} ${getBorderClass(product.current_cost_period_three, historicalData.forecast_cost_period_one, false)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{historicalData.forecast_cost_period_one || '0'}</span>
|
<span className="font-medium">{historicalData.forecast_cost_period_one || '0'}</span>
|
||||||
{getVarianceDisplay(product.current_cost_period_three, historicalData.forecast_cost_period_one)}
|
{getVarianceDisplay(product.current_cost_period_three, historicalData.forecast_cost_period_one)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(historicalData.forecast_cost_period_one, historicalData.forecast_cost_period_two)} ${getBorderClass(historicalData.forecast_cost_period_one, historicalData.forecast_cost_period_two)}`}>
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(historicalData.forecast_cost_period_one, historicalData.forecast_cost_period_two, false)} ${getBorderClass(historicalData.forecast_cost_period_one, historicalData.forecast_cost_period_two, false)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{historicalData.forecast_cost_period_two || '0'}</span>
|
<span className="font-medium">{historicalData.forecast_cost_period_two || '0'}</span>
|
||||||
{getVarianceDisplay(historicalData.forecast_cost_period_one, historicalData.forecast_cost_period_two)}
|
{getVarianceDisplay(historicalData.forecast_cost_period_one, historicalData.forecast_cost_period_two)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(historicalData.forecast_cost_period_two, historicalData.forecast_cost_period_three)} ${getBorderClass(historicalData.forecast_cost_period_two, historicalData.forecast_cost_period_three)}`}>
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(historicalData.forecast_cost_period_two, historicalData.forecast_cost_period_three, false)} ${getBorderClass(historicalData.forecast_cost_period_two, historicalData.forecast_cost_period_three, false)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{historicalData.forecast_cost_period_three || '0'}</span>
|
<span className="font-medium">{historicalData.forecast_cost_period_three || '0'}</span>
|
||||||
{getVarianceDisplay(historicalData.forecast_cost_period_two, historicalData.forecast_cost_period_three)}
|
{getVarianceDisplay(historicalData.forecast_cost_period_two, historicalData.forecast_cost_period_three)}
|
||||||
@ -1540,19 +1557,19 @@ const additionalForecastLabel = showPreviousNext
|
|||||||
})()}
|
})()}
|
||||||
|
|
||||||
{/* NEXT YEAR FORECAST Cost (original from submission) */}
|
{/* NEXT YEAR FORECAST Cost (original from submission) */}
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_cost_period_three, product.forecast_cost_period_one)} ${getBorderClass(product.current_cost_period_three, product.forecast_cost_period_one)}`}>
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_cost_period_three, product.forecast_cost_period_one, false)} ${getBorderClass(product.current_cost_period_three, product.forecast_cost_period_one, false)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.forecast_cost_period_one || '0'}</span>
|
<span className="font-medium">{product.forecast_cost_period_one || '0'}</span>
|
||||||
{getVarianceDisplay(product.current_cost_period_three, product.forecast_cost_period_one)}
|
{getVarianceDisplay(product.current_cost_period_three, product.forecast_cost_period_one)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_cost_period_one, product.forecast_cost_period_two)} ${getBorderClass(product.forecast_cost_period_one, product.forecast_cost_period_two)}`}>
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_cost_period_one, product.forecast_cost_period_two, false)} ${getBorderClass(product.forecast_cost_period_one, product.forecast_cost_period_two, false)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.forecast_cost_period_two || '0'}</span>
|
<span className="font-medium">{product.forecast_cost_period_two || '0'}</span>
|
||||||
{getVarianceDisplay(product.forecast_cost_period_one, product.forecast_cost_period_two)}
|
{getVarianceDisplay(product.forecast_cost_period_one, product.forecast_cost_period_two)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_cost_period_two, product.forecast_cost_period_three)} ${getBorderClass(product.forecast_cost_period_two, product.forecast_cost_period_three)}`}>
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_cost_period_two, product.forecast_cost_period_three, false)} ${getBorderClass(product.forecast_cost_period_two, product.forecast_cost_period_three, false)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.forecast_cost_period_three || '0'}</span>
|
<span className="font-medium">{product.forecast_cost_period_three || '0'}</span>
|
||||||
{getVarianceDisplay(product.forecast_cost_period_two, product.forecast_cost_period_three)}
|
{getVarianceDisplay(product.forecast_cost_period_two, product.forecast_cost_period_three)}
|
||||||
@ -1561,65 +1578,105 @@ const additionalForecastLabel = showPreviousNext
|
|||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
|
{/* Previous Cost – Month 1 */}
|
||||||
<td className="px-3 py-3 border border-[#E5E7EB] text-center">
|
<td className="px-3 py-3 border border-[#E5E7EB] text-center">
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.previous_cost_period_one || '0'}</span>
|
<span className="font-medium">{product.previous_cost_period_one || '0'}</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
{/* Previous Cost – Month 2 */}
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_cost_period_one, product.previous_cost_period_two, true)} ${getBorderClass(product.previous_cost_period_one, product.previous_cost_period_two, true)}`}>
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_cost_period_one, product.previous_cost_period_two, true)} ${getBorderClass(product.previous_cost_period_one, product.previous_cost_period_two, true)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.previous_cost_period_two || '0'}</span>
|
<span className="font-medium">{product.previous_cost_period_two || '0'}</span>
|
||||||
{getVarianceDisplay(product.previous_cost_period_one, product.previous_cost_period_two, true)}
|
{!isPreviousQuarterCostAllZeros && getVarianceDisplay(
|
||||||
|
product.previous_cost_period_one,
|
||||||
|
product.previous_cost_period_two
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_cost_period_two, product.previous_cost_period_three)} ${getBorderClass(product.previous_cost_period_two, product.previous_cost_period_three)}`}>
|
|
||||||
|
{/* Previous Cost – Month 3 */}
|
||||||
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_cost_period_two, product.previous_cost_period_three, isPreviousQuarterCostAllZeros)} ${getBorderClass(product.previous_cost_period_two, product.previous_cost_period_three, isPreviousQuarterCostAllZeros)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.previous_cost_period_three || '0'}</span>
|
<span className="font-medium">{product.previous_cost_period_three || '0'}</span>
|
||||||
{getVarianceDisplay(product.previous_cost_period_two, product.previous_cost_period_three)}
|
{!isPreviousQuarterCostAllZeros && getVarianceDisplay(
|
||||||
|
product.previous_cost_period_two,
|
||||||
|
product.previous_cost_period_three
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_cost_period_three, product.current_cost_period_one)} ${getBorderClass(product.previous_cost_period_three, product.current_cost_period_one)}`}>
|
{/* Current Cost – Month 1 */}
|
||||||
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.previous_cost_period_three, product.current_cost_period_one, isPreviousQuarterCostAllZeros)} ${getBorderClass(product.previous_cost_period_three, product.current_cost_period_one, isPreviousQuarterCostAllZeros)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.current_cost_period_one || '0'}</span>
|
<span className="font-medium">{product.current_cost_period_one || '0'}</span>
|
||||||
{getVarianceDisplay(product.previous_cost_period_three, product.current_cost_period_one)}
|
{!isPreviousQuarterCostAllZeros && getVarianceDisplay(
|
||||||
</div>
|
product.previous_cost_period_three,
|
||||||
</td>
|
product.current_cost_period_one
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_cost_period_one, product.current_cost_period_two)} ${getBorderClass(product.current_cost_period_one, product.current_cost_period_two)}`}>
|
)}
|
||||||
<div className="flex flex-col items-center justify-center">
|
|
||||||
<span className="font-medium">{product.current_cost_period_two || '0'}</span>
|
|
||||||
{getVarianceDisplay(product.current_cost_period_one, product.current_cost_period_two)}
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_cost_period_two, product.current_cost_period_three)} ${getBorderClass(product.current_cost_period_two, product.current_cost_period_three)}`}>
|
|
||||||
<div className="flex flex-col items-center justify-center">
|
|
||||||
<span className="font-medium">{product.current_cost_period_three || '0'}</span>
|
|
||||||
{getVarianceDisplay(product.current_cost_period_two, product.current_cost_period_three)}
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_cost_period_three, product.forecast_cost_period_one)} ${getBorderClass(product.current_cost_period_three, product.forecast_cost_period_one)}`}>
|
{/* Current Cost – Month 2 */}
|
||||||
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_cost_period_one, product.current_cost_period_two, false)} ${getBorderClass(product.current_cost_period_one, product.current_cost_period_two, false)}`}>
|
||||||
|
<div className="flex flex-col items-center justify-center">
|
||||||
|
<span className="font-medium">{product.current_cost_period_two || '0'}</span>
|
||||||
|
{getVarianceDisplay(
|
||||||
|
product.current_cost_period_one,
|
||||||
|
product.current_cost_period_two
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
{/* Current Cost – Month 3 */}
|
||||||
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_cost_period_two, product.current_cost_period_three, false)} ${getBorderClass(product.current_cost_period_two, product.current_cost_period_three, false)}`}>
|
||||||
|
<div className="flex flex-col items-center justify-center">
|
||||||
|
<span className="font-medium">{product.current_cost_period_three || '0'}</span>
|
||||||
|
{getVarianceDisplay(
|
||||||
|
product.current_cost_period_two,
|
||||||
|
product.current_cost_period_three
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
{/* Forecast Cost – Month 1 */}
|
||||||
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.current_cost_period_three, product.forecast_cost_period_one, false)} ${getBorderClass(product.current_cost_period_three, product.forecast_cost_period_one, false)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.forecast_cost_period_one || '0'}</span>
|
<span className="font-medium">{product.forecast_cost_period_one || '0'}</span>
|
||||||
{getVarianceDisplay(product.current_cost_period_three, product.forecast_cost_period_one)}
|
{getVarianceDisplay(
|
||||||
|
product.current_cost_period_three,
|
||||||
|
product.forecast_cost_period_one
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_cost_period_one, product.forecast_cost_period_two)} ${getBorderClass(product.forecast_cost_period_one, product.forecast_cost_period_two)}`}>
|
|
||||||
|
{/* Forecast Cost – Month 2 */}
|
||||||
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_cost_period_one, product.forecast_cost_period_two, false)} ${getBorderClass(product.forecast_cost_period_one, product.forecast_cost_period_two, false)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.forecast_cost_period_two || '0'}</span>
|
<span className="font-medium">{product.forecast_cost_period_two || '0'}</span>
|
||||||
{getVarianceDisplay(product.forecast_cost_period_one, product.forecast_cost_period_two)}
|
{getVarianceDisplay(
|
||||||
|
product.forecast_cost_period_one,
|
||||||
|
product.forecast_cost_period_two
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_cost_period_two, product.forecast_cost_period_three)} ${getBorderClass(product.forecast_cost_period_two, product.forecast_cost_period_three)}`}>
|
|
||||||
|
{/* Forecast Cost – Month 3 */}
|
||||||
|
<td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(product.forecast_cost_period_two, product.forecast_cost_period_three, false)} ${getBorderClass(product.forecast_cost_period_two, product.forecast_cost_period_three, false)}`}>
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
<span className="font-medium">{product.forecast_cost_period_three || '0'}</span>
|
<span className="font-medium">{product.forecast_cost_period_three || '0'}</span>
|
||||||
{getVarianceDisplay(product.forecast_cost_period_two, product.forecast_cost_period_three)}
|
{getVarianceDisplay(
|
||||||
|
product.forecast_cost_period_two,
|
||||||
|
product.forecast_cost_period_three
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</tr>
|
</tr>
|
||||||
<tr className="border-t border-[#E5E7EB]">
|
|
||||||
|
<tr className="border-t border-[#E5E7EB]">
|
||||||
<td className="bg-[#FFFCF2] px-4 py-3 font-medium text-[#232528] border border-[#E5E7EB]">
|
<td className="bg-[#FFFCF2] px-4 py-3 font-medium text-[#232528] border border-[#E5E7EB]">
|
||||||
Reason (Current)
|
Reason (Current)
|
||||||
</td>
|
</td>
|
||||||
@ -1650,7 +1707,7 @@ const additionalForecastLabel = showPreviousNext
|
|||||||
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
|
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
|
||||||
–
|
–
|
||||||
</td>
|
</td>
|
||||||
{/* Current Quarter (colSpan 3) - இங்குதான் Reason (Current) இருக்க வேண்டும் */}
|
{/* Current Quarter (colSpan 3) */}
|
||||||
<td colSpan="3" className="px-4 py-3 text-center bg-[#E9F6EC] text-[#1E7C34] font-medium border border-[#E5E7EB]">
|
<td colSpan="3" className="px-4 py-3 text-center bg-[#E9F6EC] text-[#1E7C34] font-medium border border-[#E5E7EB]">
|
||||||
{product.other_variation_reason ||
|
{product.other_variation_reason ||
|
||||||
(product?.variation_reason?.reason ?
|
(product?.variation_reason?.reason ?
|
||||||
@ -1664,7 +1721,8 @@ const additionalForecastLabel = showPreviousNext
|
|||||||
</td>
|
</td>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr className="border-t border-[#E5E7EB]">
|
<tr className="border-t border-[#E5E7EB]">
|
||||||
<td className="bg-[#FFFCF2] px-4 py-3 font-medium text-[#232528] border border-[#E5E7EB]">
|
<td className="bg-[#FFFCF2] px-4 py-3 font-medium text-[#232528] border border-[#E5E7EB]">
|
||||||
Reason (Forecast)
|
Reason (Forecast)
|
||||||
@ -1726,7 +1784,8 @@ const additionalForecastLabel = showPreviousNext
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
))}
|
);
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="rounded-lg bg-amber-50 border border-amber-200 p-6 text-center">
|
<div className="rounded-lg bg-amber-50 border border-amber-200 p-6 text-center">
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user