Enhancement version 1

This commit is contained in:
seranjivi 2026-04-28 18:33:54 +05:30
parent 95a3578d80
commit 5f37883a3b
5 changed files with 627 additions and 369 deletions

View File

@ -127,6 +127,29 @@ const ProductDetails = ({
// Use provided quarterPeriods or fall back to defaults // Use provided quarterPeriods or fall back to defaults
const periods = quarterPeriods || product?.quarterPeriods || defaultQuarterPeriods; const periods = quarterPeriods || product?.quarterPeriods || defaultQuarterPeriods;
// Determine if we should hide PREVIOUS QUARTER section for specific year/quarter combinations
// Uses quarterPeriods (API response) as primary source since that's what drives the UI
const shouldHidePreviousQuarter = React.useMemo(() => {
const effectiveYear = (periods?.current_year || new Date().getFullYear()).toString();
const rawQuarter = periods?.current_quarter || 'Q1';
const normalizedQuarter = rawQuarter.toString().toUpperCase().startsWith('Q')
? rawQuarter.toString().toUpperCase()
: `Q${rawQuarter}`;
return (effectiveYear === '2022' && normalizedQuarter === 'Q1') ||
(effectiveYear === '2025' && normalizedQuarter === 'Q1');
}, [periods]);
// Determine if we should hide FORECAST section for specific year/quarter combinations
// Uses quarterPeriods (API response) as primary source since that's what drives the UI
const shouldHideForecast = React.useMemo(() => {
const effectiveYear = (periods?.current_year || new Date().getFullYear()).toString();
const rawQuarter = periods?.current_quarter || 'Q1';
const normalizedQuarter = rawQuarter.toString().toUpperCase().startsWith('Q')
? rawQuarter.toString().toUpperCase()
: `Q${rawQuarter}`;
return effectiveYear === '2022' && normalizedQuarter === 'Q4';
}, [periods]);
const navigate = useNavigate(); const navigate = useNavigate();
// Function to save resubmission data to localStorage // Function to save resubmission data to localStorage
@ -460,19 +483,25 @@ const ProductDetails = ({
<th rowSpan="2" className="border border-gray-300 py-2 px-3 text-left bg-[#F2ECCF] w-[140px]"> <th rowSpan="2" className="border border-gray-300 py-2 px-3 text-left bg-[#F2ECCF] w-[140px]">
Metric Metric
</th> </th>
{!shouldHidePreviousQuarter && (
<th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#E9F6FF]"> <th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#E9F6FF]">
{periods.previous_quarter}-{periods.previous_year} (Previous Quarter) {periods.previous_quarter}-{periods.previous_year} (Previous Quarter)
</th> </th>
)}
<th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#F3FAF4]"> <th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#F3FAF4]">
{periods.current_quarter}-{periods.current_year} (Current Quarter) {periods.current_quarter}-{periods.current_year} (Current Quarter)
</th> </th>
{!shouldHideForecast && (
<th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#FFF7E9]"> <th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#FFF7E9]">
{periods.forecast_quarter}-{periods.forecast_year} (Next Quarter) {periods.forecast_quarter}-{periods.forecast_year} (Next Quarter)
</th> </th>
)}
</tr> </tr>
{/* Second header row */} {/* Second header row */}
<tr className="bg-white text-[13px] font-medium"> <tr className="bg-white text-[13px] font-medium">
{!shouldHidePreviousQuarter && (
<>
<th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]"> <th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]">
{periods.previous_month.previous_period_one} {periods.previous_month.previous_period_one}
</th> </th>
@ -482,6 +511,8 @@ const ProductDetails = ({
<th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]"> <th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]">
{periods.previous_month.previous_period_three} {periods.previous_month.previous_period_three}
</th> </th>
</>
)}
<th className="border border-gray-300 py-2 px-3 bg-[#F3FAF4] text-[#2F663C]"> <th className="border border-gray-300 py-2 px-3 bg-[#F3FAF4] text-[#2F663C]">
{periods.current_month.current_period_one} {periods.current_month.current_period_one}
</th> </th>
@ -491,6 +522,8 @@ const ProductDetails = ({
<th className="border border-gray-300 py-2 px-3 bg-[#F3FAF4] text-[#2F663C]"> <th className="border border-gray-300 py-2 px-3 bg-[#F3FAF4] text-[#2F663C]">
{periods.current_month.current_period_three} {periods.current_month.current_period_three}
</th> </th>
{!shouldHideForecast && (
<>
<th className="border border-gray-300 py-2 px-3 bg-[#FFF7E9] text-[#F29F0E]"> <th className="border border-gray-300 py-2 px-3 bg-[#FFF7E9] text-[#F29F0E]">
{periods.forecast_month.forecast_period_one} {periods.forecast_month.forecast_period_one}
</th> </th>
@ -500,6 +533,8 @@ const ProductDetails = ({
<th className="border border-gray-300 py-2 px-3 bg-[#FFF7E9] text-[#F29F0E]"> <th className="border border-gray-300 py-2 px-3 bg-[#FFF7E9] text-[#F29F0E]">
{periods.forecast_month.forecast_period_three} {periods.forecast_month.forecast_period_three}
</th> </th>
</>
)}
</tr> </tr>
</thead> </thead>
@ -509,15 +544,23 @@ const ProductDetails = ({
<td className="border border-gray-300 py-2 px-3 text-left font-medium"> <td className="border border-gray-300 py-2 px-3 text-left font-medium">
Quantity ({formattedProduct.unit}) Quantity ({formattedProduct.unit})
</td> </td>
{!shouldHidePreviousQuarter && (
<>
<td className="border border-gray-300 py-2">{formattedProduct.q4_oct_quantity}</td> <td className="border border-gray-300 py-2">{formattedProduct.q4_oct_quantity}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q4_nov_quantity}</td> <td className="border border-gray-300 py-2">{formattedProduct.q4_nov_quantity}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q4_dec_quantity}</td> <td className="border border-gray-300 py-2">{formattedProduct.q4_dec_quantity}</td>
</>
)}
<td className="border border-gray-300 py-2">{formattedProduct.q1_jan_quantity}</td> <td className="border border-gray-300 py-2">{formattedProduct.q1_jan_quantity}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q1_feb_quantity}</td> <td className="border border-gray-300 py-2">{formattedProduct.q1_feb_quantity}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q1_mar_quantity}</td> <td className="border border-gray-300 py-2">{formattedProduct.q1_mar_quantity}</td>
{!shouldHideForecast && (
<>
<td className="border border-gray-300 py-2">{formattedProduct.q2_apr_quantity}</td> <td className="border border-gray-300 py-2">{formattedProduct.q2_apr_quantity}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q2_may_quantity}</td> <td className="border border-gray-300 py-2">{formattedProduct.q2_may_quantity}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q2_jun_quantity}</td> <td className="border border-gray-300 py-2">{formattedProduct.q2_jun_quantity}</td>
</>
)}
</tr> </tr>
{/* Cost Row */} {/* Cost Row */}
@ -525,15 +568,23 @@ const ProductDetails = ({
<td className="border border-gray-300 py-2 px-3 text-left font-medium"> <td className="border border-gray-300 py-2 px-3 text-left font-medium">
Value (AED) Value (AED)
</td> </td>
{!shouldHidePreviousQuarter && (
<>
<td className="border border-gray-300 py-2">{formattedProduct.q4_oct_cost}</td> <td className="border border-gray-300 py-2">{formattedProduct.q4_oct_cost}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q4_nov_cost}</td> <td className="border border-gray-300 py-2">{formattedProduct.q4_nov_cost}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q4_dec_cost}</td> <td className="border border-gray-300 py-2">{formattedProduct.q4_dec_cost}</td>
</>
)}
<td className="border border-gray-300 py-2">{formattedProduct.q1_jan_cost}</td> <td className="border border-gray-300 py-2">{formattedProduct.q1_jan_cost}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q1_feb_cost}</td> <td className="border border-gray-300 py-2">{formattedProduct.q1_feb_cost}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q1_mar_cost}</td> <td className="border border-gray-300 py-2">{formattedProduct.q1_mar_cost}</td>
{!shouldHideForecast && (
<>
<td className="border border-gray-300 py-2">{formattedProduct.q2_apr_cost}</td> <td className="border border-gray-300 py-2">{formattedProduct.q2_apr_cost}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q2_may_cost}</td> <td className="border border-gray-300 py-2">{formattedProduct.q2_may_cost}</td>
<td className="border border-gray-300 py-2">{formattedProduct.q2_jun_cost}</td> <td className="border border-gray-300 py-2">{formattedProduct.q2_jun_cost}</td>
</>
)}
</tr> </tr>
{/* Reason Current */} {/* Reason Current */}
@ -541,15 +592,19 @@ const ProductDetails = ({
<td className="border border-gray-300 py-2 px-3 text-left font-medium"> <td className="border border-gray-300 py-2 px-3 text-left font-medium">
Reason (Current) Reason (Current)
</td> </td>
{!shouldHidePreviousQuarter && (
<td colSpan="3" className="border border-gray-300 py-2 text-center"> <td colSpan="3" className="border border-gray-300 py-2 text-center">
-- -- -- --
</td> </td>
)}
<td colSpan="3" className="border border-gray-300 py-2 text-center bg-[#F3FAF4] text-[#2F663C]"> <td colSpan="3" className="border border-gray-300 py-2 text-center bg-[#F3FAF4] text-[#2F663C]">
{formattedProduct.variationReason} {formattedProduct.variationReason}
</td> </td>
{!shouldHideForecast && (
<td colSpan="3" className="border border-gray-300 py-2 text-center"> <td colSpan="3" className="border border-gray-300 py-2 text-center">
-- -- -- --
</td> </td>
)}
</tr> </tr>
{/* Reason Forecast */} {/* Reason Forecast */}
@ -557,12 +612,19 @@ const ProductDetails = ({
<td className="border border-gray-300 py-2 px-3 text-left font-medium"> <td className="border border-gray-300 py-2 px-3 text-left font-medium">
Reason (Forecast) Reason (Forecast)
</td> </td>
<td colSpan="6" className="border border-gray-300 py-2 text-center"> {!shouldHidePreviousQuarter && (
<td colSpan="3" className="border border-gray-300 py-2 text-center">
-- -- -- --
</td> </td>
)}
<td colSpan="3" className="border border-gray-300 py-2 text-center">
-- --
</td>
{!shouldHideForecast && (
<td colSpan="3" className="border border-gray-300 py-2 text-center bg-[#FFF7E9] text-[#F29F0E]"> <td colSpan="3" className="border border-gray-300 py-2 text-center bg-[#FFF7E9] text-[#F29F0E]">
{formattedProduct.zeroTargetReason} {formattedProduct.zeroTargetReason}
</td> </td>
)}
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@ -501,6 +501,29 @@ const ProductData = ({
const [isInitialLoad, setIsInitialLoad] = React.useState(true); const [isInitialLoad, setIsInitialLoad] = React.useState(true);
const [quarterPeriods, setQuarterPeriods] = React.useState(null); const [quarterPeriods, setQuarterPeriods] = React.useState(null);
const [isLoadingPeriods, setIsLoadingPeriods] = React.useState(false); const [isLoadingPeriods, setIsLoadingPeriods] = React.useState(false);
// Determine if we should hide PREVIOUS QUARTER section for specific year/quarter combinations
// Uses quarterPeriods (API response) as primary source since that's what drives the UI
const shouldHidePreviousQuarter = React.useMemo(() => {
const effectiveYear = (quarterPeriods?.current_year || year || '').toString();
const rawQuarter = quarterPeriods?.current_quarter || quarter || '';
const normalizedQuarter = rawQuarter.toString().toUpperCase().startsWith('Q')
? rawQuarter.toString().toUpperCase()
: `Q${rawQuarter}`;
return (effectiveYear === '2022' && normalizedQuarter === 'Q1') ||
(effectiveYear === '2025' && normalizedQuarter === 'Q1');
}, [quarterPeriods, year, quarter]);
// Determine if we should hide FORECAST section for specific year/quarter combinations
// Uses quarterPeriods (API response) as primary source since that's what drives the UI
const shouldHideForecast = React.useMemo(() => {
const effectiveYear = (quarterPeriods?.current_year || year || '').toString();
const rawQuarter = quarterPeriods?.current_quarter || quarter || '';
const normalizedQuarter = rawQuarter.toString().toUpperCase().startsWith('Q')
? rawQuarter.toString().toUpperCase()
: `Q${rawQuarter}`;
return effectiveYear === '2022' && normalizedQuarter === 'Q4';
}, [quarterPeriods, year, quarter]);
const [showOtherVariationReason, setShowOtherVariationReason] = React.useState({}); const [showOtherVariationReason, setShowOtherVariationReason] = React.useState({});
const [showOtherZeroTargetReason, setShowOtherZeroTargetReason] = React.useState({}); const [showOtherZeroTargetReason, setShowOtherZeroTargetReason] = React.useState({});
const [formErrors, setFormErrors] = React.useState({}); const [formErrors, setFormErrors] = React.useState({});
@ -2648,7 +2671,7 @@ useEffect(() => {
<h3 className="font-semibold mb-4 text-base">Data definitions</h3> <h3 className="font-semibold mb-4 text-base">Data definitions</h3>
<p className="mb-3"><strong>Product (HS Code Name):</strong> Standard trade classification. Start typing to search by code or name.</p> <p className="mb-3"><strong>Product (HS Code Name):</strong> Standard trade classification. Start typing to search by code or name.</p>
<p className="mb-3"><strong>Quantity (Qty):</strong> Physical output produced in the month, measured in the selected unit.</p> <p className="mb-3"><strong>Quantity (Qty):</strong> Physical output produced in the month, measured in the selected unit.</p>
<p className="mb-3"><strong>Value (AED <img src={uae_currency} alt="AED" className="inline-block w-5 h-5 -mt-0.5" />):</strong> The net monthly sales value of a single product excluding VAT and any applicable duties. Do not include sales margins.<br /><em><strong>Formula:</strong></em> Sales Value (VAT, Duties, etc)</p> <p className="mb-3"><strong>Value (AED <img src={uae_currency} alt="AED" className="inline-block w-5 h-5 -mt-0.5" />):</strong> The net monthly gross sales value of a single product excluding VAT and any applicable duties. Do not include sales margins.<br /><em><strong>Formula:</strong></em> Gross Sales Value (VAT, Duties, etc)</p>
<p className="mb-0"><strong>Annual Installed Capacity:</strong> Maximum achievable annual output under normal operating conditions with existing equipment; do not include extraordinary overtime.</p> <p className="mb-0"><strong>Annual Installed Capacity:</strong> Maximum achievable annual output under normal operating conditions with existing equipment; do not include extraordinary overtime.</p>
</div> </div>
)} )}
@ -2908,7 +2931,12 @@ useEffect(() => {
</div> </div>
</div> </div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4"> <div className={`grid grid-cols-1 gap-4 ${
(shouldHidePreviousQuarter && shouldHideForecast) ? 'md:grid-cols-1' :
(shouldHidePreviousQuarter || shouldHideForecast) ? 'md:grid-cols-2' :
'md:grid-cols-3'
}`}>
{!shouldHidePreviousQuarter && (
<SectionBox <SectionBox
title={quarterPeriods ? `PREVIOUS QUARTER (${quarterPeriods.previous_quarter}-${quarterPeriods.previous_year})` : 'PREVIOUS QUARTER (Q-YYYY)'} title={quarterPeriods ? `PREVIOUS QUARTER (${quarterPeriods.previous_quarter}-${quarterPeriods.previous_year})` : 'PREVIOUS QUARTER (Q-YYYY)'}
badgeBg="#E7F5FF" badgeBg="#E7F5FF"
@ -3015,6 +3043,7 @@ useEffect(() => {
</div> </div>
</div> </div>
</SectionBox> </SectionBox>
)}
<SectionBox <SectionBox
title={quarterPeriods ? `CURRENT QUARTER (${quarterPeriods.current_quarter} ${quarterPeriods.current_year})` : `CURRENT QUARTER (${quarter}-${year})`} title={quarterPeriods ? `CURRENT QUARTER (${quarterPeriods.current_quarter} ${quarterPeriods.current_year})` : `CURRENT QUARTER (${quarter}-${year})`}
@ -3176,6 +3205,7 @@ useEffect(() => {
</div> </div>
</SectionBox> </SectionBox>
{!shouldHideForecast && (
<SectionBox <SectionBox
title={`NEXT QUARTER FORECAST (${quarterPeriods?.forecast_quarter || 'Q'}-${quarterPeriods?.forecast_year || '2025'})`} title={`NEXT QUARTER FORECAST (${quarterPeriods?.forecast_quarter || 'Q'}-${quarterPeriods?.forecast_year || '2025'})`}
badgeBg="#FFF7E9" badgeBg="#FFF7E9"
@ -3320,6 +3350,7 @@ useEffect(() => {
</div> </div>
</div> </div>
</SectionBox> </SectionBox>
)}
</div> </div>
</div> </div>
</Card> </Card>

View File

@ -375,6 +375,29 @@ const ReviewSubmit = ({
return ''; return '';
}); });
// Determine if we should hide PREVIOUS QUARTER section for specific year/quarter combinations
// Uses quarterPeriods (API response) as primary source since that's what drives the UI
const shouldHidePreviousQuarter = React.useMemo(() => {
const effectiveYear = (quarterPeriods?.current_year || year || '').toString();
const rawQuarter = quarterPeriods?.current_quarter || quarter || '';
const normalizedQuarter = rawQuarter.toString().toUpperCase().startsWith('Q')
? rawQuarter.toString().toUpperCase()
: `Q${rawQuarter}`;
return (effectiveYear === '2022' && normalizedQuarter === 'Q1') ||
(effectiveYear === '2025' && normalizedQuarter === 'Q1');
}, [quarterPeriods, year, quarter]);
// Determine if we should hide FORECAST section for specific year/quarter combinations
// Uses quarterPeriods (API response) as primary source since that's what drives the UI
const shouldHideForecast = React.useMemo(() => {
const effectiveYear = (quarterPeriods?.current_year || year || '').toString();
const rawQuarter = quarterPeriods?.current_quarter || quarter || '';
const normalizedQuarter = rawQuarter.toString().toUpperCase().startsWith('Q')
? rawQuarter.toString().toUpperCase()
: `Q${rawQuarter}`;
return effectiveYear === '2022' && normalizedQuarter === 'Q4';
}, [quarterPeriods, year, quarter]);
useEffect(() => { useEffect(() => {
const fetchEmiratesData = async () => { const fetchEmiratesData = async () => {
try { try {
@ -1021,24 +1044,28 @@ if (!establishment) {
Metric Metric
</th> </th>
{isLoading ? ( {isLoading ? (
<th colSpan="9" className="border border-gray-300 py-2 px-3 bg-[#F2ECCF]"> <th colSpan={shouldHidePreviousQuarter && shouldHideForecast ? "3" : (shouldHidePreviousQuarter || shouldHideForecast ? "6" : "9")} className="border border-gray-300 py-2 px-3 bg-[#F2ECCF]">
Loading quarters... Loading quarters...
</th> </th>
) : error ? ( ) : error ? (
<th colSpan="9" className="border border-gray-300 py-2 px-3 bg-[#F2ECCF] text-red-500"> <th colSpan={shouldHidePreviousQuarter && shouldHideForecast ? "3" : (shouldHidePreviousQuarter || shouldHideForecast ? "6" : "9")} className="border border-gray-300 py-2 px-3 bg-[#F2ECCF] text-red-500">
{error} {error}
</th> </th>
) : ( ) : (
<> <>
{!shouldHidePreviousQuarter && (
<th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#F2ECCF]"> <th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#F2ECCF]">
{quarterPeriods?.previous_quarter}-{quarterPeriods?.previous_year} (Previous Quarter) {quarterPeriods?.previous_quarter}-{quarterPeriods?.previous_year} (Previous Quarter)
</th> </th>
)}
<th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#F2ECCF]"> <th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#F2ECCF]">
{quarterPeriods?.current_quarter}-{quarterPeriods?.current_year} (Current Quarter) {quarterPeriods?.current_quarter}-{quarterPeriods?.current_year} (Current Quarter)
</th> </th>
{!shouldHideForecast && (
<th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#F2ECCF]"> <th colSpan="3" className="border border-gray-300 py-2 px-3 bg-[#F2ECCF]">
{quarterPeriods?.forecast_quarter}-{quarterPeriods?.forecast_year} (Next Quarter) {quarterPeriods?.forecast_quarter}-{quarterPeriods?.forecast_year} (Next Quarter)
</th> </th>
)}
</> </>
)} )}
</tr> </tr>
@ -1046,12 +1073,14 @@ if (!establishment) {
{/* Second header row */} {/* Second header row */}
<tr className="bg-white text-[13px] font-medium"> <tr className="bg-white text-[13px] font-medium">
{isLoading ? ( {isLoading ? (
<th colSpan="9" className="py-2">Loading months...</th> <th colSpan={shouldHidePreviousQuarter && shouldHideForecast ? "3" : (shouldHidePreviousQuarter || shouldHideForecast ? "6" : "9")} className="py-2">Loading months...</th>
) : error ? ( ) : error ? (
<th colSpan="9" className="py-2 text-red-500">{error}</th> <th colSpan={shouldHidePreviousQuarter && shouldHideForecast ? "3" : (shouldHidePreviousQuarter || shouldHideForecast ? "6" : "9")} className="py-2 text-red-500">{error}</th>
) : ( ) : (
<> <>
{/* Previous Quarter Months */} {/* Previous Quarter Months */}
{!shouldHidePreviousQuarter && (
<>
<th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]"> <th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]">
{quarterPeriods?.previous_month?.previous_period_one} {quarterPeriods?.previous_month?.previous_period_one}
</th> </th>
@ -1061,6 +1090,8 @@ if (!establishment) {
<th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]"> <th className="border border-gray-300 py-2 px-3 bg-[#E9F6FF] text-[#286CFF]">
{quarterPeriods?.previous_month?.previous_period_three} {quarterPeriods?.previous_month?.previous_period_three}
</th> </th>
</>
)}
{/* Current Quarter Months */} {/* Current Quarter Months */}
<th className="border border-gray-300 py-2 px-3 bg-[#F3FAF4] text-[#2F663C]"> <th className="border border-gray-300 py-2 px-3 bg-[#F3FAF4] text-[#2F663C]">
@ -1074,6 +1105,8 @@ if (!establishment) {
</th> </th>
{/* Next Quarter Months */} {/* Next Quarter Months */}
{!shouldHideForecast && (
<>
<th className="border border-gray-300 py-2 px-3 bg-[#FFF7E9] text-[#F29F0E]"> <th className="border border-gray-300 py-2 px-3 bg-[#FFF7E9] text-[#F29F0E]">
{quarterPeriods?.forecast_month?.forecast_period_one} {quarterPeriods?.forecast_month?.forecast_period_one}
</th> </th>
@ -1085,6 +1118,8 @@ if (!establishment) {
</th> </th>
</> </>
)} )}
</>
)}
</tr> </tr>
</thead> </thead>
@ -1094,15 +1129,23 @@ if (!establishment) {
<td className="border border-gray-300 py-2 px-3 text-left font-medium"> <td className="border border-gray-300 py-2 px-3 text-left font-medium">
Quantity ({product.unit || 'units'}) Quantity ({product.unit || 'units'})
</td> </td>
{!shouldHidePreviousQuarter && (
<>
<td className="border border-gray-300 py-2">{product.q4_oct_quantity || '—'}</td> <td className="border border-gray-300 py-2">{product.q4_oct_quantity || '—'}</td>
<td className="border border-gray-300 py-2">{product.q4_nov_quantity || '—'}</td> <td className="border border-gray-300 py-2">{product.q4_nov_quantity || '—'}</td>
<td className="border border-gray-300 py-2">{product.q4_dec_quantity || '—'}</td> <td className="border border-gray-300 py-2">{product.q4_dec_quantity || '—'}</td>
</>
)}
<td className="border border-gray-300 py-2">{product.q1_jan_quantity || '—'}</td> <td className="border border-gray-300 py-2">{product.q1_jan_quantity || '—'}</td>
<td className="border border-gray-300 py-2">{product.q1_feb_quantity || '—'}</td> <td className="border border-gray-300 py-2">{product.q1_feb_quantity || '—'}</td>
<td className="border border-gray-300 py-2">{product.q1_mar_quantity || '—'}</td> <td className="border border-gray-300 py-2">{product.q1_mar_quantity || '—'}</td>
{!shouldHideForecast && (
<>
<td className="border border-gray-300 py-2">{product.q2_apr_quantity || '—'}</td> <td className="border border-gray-300 py-2">{product.q2_apr_quantity || '—'}</td>
<td className="border border-gray-300 py-2">{product.q2_may_quantity || '—'}</td> <td className="border border-gray-300 py-2">{product.q2_may_quantity || '—'}</td>
<td className="border border-gray-300 py-2">{product.q2_jun_quantity || '—'}</td> <td className="border border-gray-300 py-2">{product.q2_jun_quantity || '—'}</td>
</>
)}
</tr> </tr>
{/* Cost Row */} {/* Cost Row */}
@ -1110,15 +1153,23 @@ if (!establishment) {
<td className="border border-gray-300 py-2 px-3 text-left font-medium"> <td className="border border-gray-300 py-2 px-3 text-left font-medium">
Value (AED) Value (AED)
</td> </td>
{!shouldHidePreviousQuarter && (
<>
<td className="border border-gray-300 py-2">{product.q4_oct_cost || '—'}</td> <td className="border border-gray-300 py-2">{product.q4_oct_cost || '—'}</td>
<td className="border border-gray-300 py-2">{product.q4_nov_cost || '—'}</td> <td className="border border-gray-300 py-2">{product.q4_nov_cost || '—'}</td>
<td className="border border-gray-300 py-2">{product.q4_dec_cost || '—'}</td> <td className="border border-gray-300 py-2">{product.q4_dec_cost || '—'}</td>
</>
)}
<td className="border border-gray-300 py-2">{product.q1_jan_cost || '—'}</td> <td className="border border-gray-300 py-2">{product.q1_jan_cost || '—'}</td>
<td className="border border-gray-300 py-2">{product.q1_feb_cost || '—'}</td> <td className="border border-gray-300 py-2">{product.q1_feb_cost || '—'}</td>
<td className="border border-gray-300 py-2">{product.q1_mar_cost || '—'}</td> <td className="border border-gray-300 py-2">{product.q1_mar_cost || '—'}</td>
{!shouldHideForecast && (
<>
<td className="border border-gray-300 py-2">{product.q2_apr_cost || '—'}</td> <td className="border border-gray-300 py-2">{product.q2_apr_cost || '—'}</td>
<td className="border border-gray-300 py-2">{product.q2_may_cost || '—'}</td> <td className="border border-gray-300 py-2">{product.q2_may_cost || '—'}</td>
<td className="border border-gray-300 py-2">{product.q2_jun_cost || '—'}</td> <td className="border border-gray-300 py-2">{product.q2_jun_cost || '—'}</td>
</>
)}
</tr> </tr>
{/* Reason Current */} {/* Reason Current */}
@ -1126,9 +1177,11 @@ if (!establishment) {
<td className="border border-gray-300 py-2 px-3 text-left font-medium"> <td className="border border-gray-300 py-2 px-3 text-left font-medium">
Reason (Current) Reason (Current)
</td> </td>
{!shouldHidePreviousQuarter && (
<td colSpan="3" className="border border-gray-300 py-2 text-center"> <td colSpan="3" className="border border-gray-300 py-2 text-center">
-- -- -- --
</td> </td>
)}
<td colSpan="3" className="border border-gray-300 py-2 text-center bg-[#F3FAF4] text-[#2F663C]"> <td colSpan="3" className="border border-gray-300 py-2 text-center bg-[#F3FAF4] text-[#2F663C]">
<div className="flex flex-col items-center"> <div className="flex flex-col items-center">
{product.otherVariationReason ? ( {product.otherVariationReason ? (
@ -1138,9 +1191,11 @@ if (!establishment) {
)} )}
</div> </div>
</td> </td>
{!shouldHideForecast && (
<td colSpan="3" className="border border-gray-300 py-2 text-center"> <td colSpan="3" className="border border-gray-300 py-2 text-center">
-- -- -- --
</td> </td>
)}
</tr> </tr>
{/* Reason Forecast */} {/* Reason Forecast */}
@ -1148,9 +1203,15 @@ if (!establishment) {
<td className="border border-gray-300 py-2 px-3 text-left font-medium"> <td className="border border-gray-300 py-2 px-3 text-left font-medium">
Reason (Forecast) Reason (Forecast)
</td> </td>
<td colSpan="6" className="border border-gray-300 py-2 text-center"> {!shouldHidePreviousQuarter && (
<td colSpan="3" className="border border-gray-300 py-2 text-center">
-- -- -- --
</td> </td>
)}
<td colSpan="3" className="border border-gray-300 py-2 text-center">
-- --
</td>
{!shouldHideForecast && (
<td colSpan="3" className="border border-gray-300 py-2 text-center bg-[#FFF7E9] text-[#F29F0E]"> <td colSpan="3" className="border border-gray-300 py-2 text-center bg-[#FFF7E9] text-[#F29F0E]">
<div className="flex flex-col items-center"> <div className="flex flex-col items-center">
{product.otherZeroTargetReason ? ( {product.otherZeroTargetReason ? (
@ -1160,6 +1221,7 @@ if (!establishment) {
)} )}
</div> </div>
</td> </td>
)}
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@ -393,6 +393,29 @@ const ValidationReview = () => {
const [additionalForecastMonths, setAdditionalForecastMonths] = React.useState(['', '', '']); const [additionalForecastMonths, setAdditionalForecastMonths] = React.useState(['', '', '']);
const [emirates, setEmirates] = useState([]); const [emirates, setEmirates] = useState([]);
// Determine if we should hide PREVIOUS QUARTER section for specific year/quarter combinations
// Uses quarterPeriods (API response) as primary source since that's what drives the UI
const shouldHidePreviousQuarter = React.useMemo(() => {
const effectiveYear = (quarterPeriods?.current_year || new Date().getFullYear()).toString();
const rawQuarter = quarterPeriods?.current_quarter || 'Q1';
const normalizedQuarter = rawQuarter.toString().toUpperCase().startsWith('Q')
? rawQuarter.toString().toUpperCase()
: `Q${rawQuarter}`;
return (effectiveYear === '2022' && normalizedQuarter === 'Q1') ||
(effectiveYear === '2025' && normalizedQuarter === 'Q1');
}, [quarterPeriods]);
// Determine if we should hide FORECAST section for specific year/quarter combinations
// Uses quarterPeriods (API response) as primary source since that's what drives the UI
const shouldHideForecast = React.useMemo(() => {
const effectiveYear = (quarterPeriods?.current_year || new Date().getFullYear()).toString();
const rawQuarter = quarterPeriods?.current_quarter || 'Q1';
const normalizedQuarter = rawQuarter.toString().toUpperCase().startsWith('Q')
? rawQuarter.toString().toUpperCase()
: `Q${rawQuarter}`;
return effectiveYear === '2022' && normalizedQuarter === 'Q4';
}, [quarterPeriods]);
React.useEffect(() => { React.useEffect(() => {
const fetchSubmission = async () => { const fetchSubmission = async () => {
if (!id) { if (!id) {
@ -1160,31 +1183,39 @@ setAdditionalForecastMonths([
{showPreviousNext ? ( {showPreviousNext ? (
<> <>
{/* 12 columns when showPreviousNext is true */} {/* 12 columns when showPreviousNext is true */}
{!shouldHidePreviousQuarter && (
<th colSpan="3" className="bg-[#F2ECCF] text-[#92722A] px-4 py-2 text-xs font-semibold uppercase text-center border border-[#E5E7EB]"> <th colSpan="3" className="bg-[#F2ECCF] text-[#92722A] px-4 py-2 text-xs font-semibold uppercase text-center border border-[#E5E7EB]">
{previousLabel || 'Q1 2024'} (PREVIOUS QUARTER) {previousLabel || 'Q1 2024'} (PREVIOUS QUARTER)
</th> </th>
)}
<th colSpan="3" className="bg-[#F2ECCF] text-[#92722A] px-4 py-2 text-xs font-semibold uppercase text-center border border-[#E5E7EB]"> <th colSpan="3" className="bg-[#F2ECCF] text-[#92722A] px-4 py-2 text-xs font-semibold uppercase text-center border border-[#E5E7EB]">
{currentLabel || 'Q2 2024'} (CURRENT QUARTER) {currentLabel || 'Q2 2024'} (CURRENT QUARTER)
</th> </th>
<th colSpan="3" className="bg-[#F2ECCF] text-[#92722A] px-4 py-2 text-xs font-semibold uppercase text-center border border-[#E5E7EB]"> <th colSpan="3" className="bg-[#F2ECCF] text-[#92722A] px-4 py-2 text-xs font-semibold uppercase text-center border border-[#E5E7EB]">
{additionalForecastLabel || ''} (PREVIOUS FORECAST) {additionalForecastLabel || ''} (PREVIOUS FORECAST)
</th> </th>
{!shouldHideForecast && (
<th colSpan="3" className="bg-[#F2ECCF] text-[#92722A] px-4 py-2 text-xs font-semibold uppercase text-center border border-[#E5E7EB]"> <th colSpan="3" className="bg-[#F2ECCF] text-[#92722A] px-4 py-2 text-xs font-semibold uppercase text-center border border-[#E5E7EB]">
{forecastLabel || 'Q3 2024'} (NEXT YEAR FORECAST) {forecastLabel || 'Q3 2024'} (NEXT YEAR FORECAST)
</th> </th>
)}
</> </>
) : ( ) : (
<> <>
{/* 9 columns when showPreviousNext is false */} {/* 9 columns when showPreviousNext is false */}
{!shouldHidePreviousQuarter && (
<th colSpan="3" className="bg-[#F2ECCF] text-[#92722A] px-4 py-2 text-xs font-semibold uppercase text-center border border-[#E5E7EB]"> <th colSpan="3" className="bg-[#F2ECCF] text-[#92722A] px-4 py-2 text-xs font-semibold uppercase text-center border border-[#E5E7EB]">
{previousLabel || 'Q1 2024'} (PREVIOUS QUARTER) {previousLabel || 'Q1 2024'} (PREVIOUS QUARTER)
</th> </th>
)}
<th colSpan="3" className="bg-[#F2ECCF] text-[#92722A] px-4 py-2 text-xs font-semibold uppercase text-center border border-[#E5E7EB]"> <th colSpan="3" className="bg-[#F2ECCF] text-[#92722A] px-4 py-2 text-xs font-semibold uppercase text-center border border-[#E5E7EB]">
{currentLabel || 'Q2 2024'} (CURRENT QUARTER) {currentLabel || 'Q2 2024'} (CURRENT QUARTER)
</th> </th>
{!shouldHideForecast && (
<th colSpan="3" className="bg-[#F2ECCF] text-[#92722A] px-4 py-2 text-xs font-semibold uppercase text-center border border-[#E5E7EB]"> <th colSpan="3" className="bg-[#F2ECCF] text-[#92722A] px-4 py-2 text-xs font-semibold uppercase text-center border border-[#E5E7EB]">
{forecastLabel || 'Q3 2024'} (NEXT YEAR FORECAST) {forecastLabel || 'Q3 2024'} (NEXT YEAR FORECAST)
</th> </th>
)}
</> </>
)} )}
</tr> </tr>
@ -1193,6 +1224,8 @@ setAdditionalForecastMonths([
{showPreviousNext ? ( {showPreviousNext ? (
<> <>
{/* Previous Quarter Months */} {/* Previous Quarter Months */}
{!shouldHidePreviousQuarter && (
<>
<th className="bg-[#F4F8FF] px-3 py-2 font-medium text-[#286CFF] border border-[#E5E7EB] text-center min-w-[100px]"> <th className="bg-[#F4F8FF] px-3 py-2 font-medium text-[#286CFF] border border-[#E5E7EB] text-center min-w-[100px]">
{previousMonths?.previous_period_one || 'Jan'} {previousMonths?.previous_period_one || 'Jan'}
</th> </th>
@ -1202,6 +1235,8 @@ setAdditionalForecastMonths([
<th className="bg-[#F4F8FF] px-3 py-2 font-medium text-[#286CFF] border border-[#E5E7EB] text-center min-w-[100px]"> <th className="bg-[#F4F8FF] px-3 py-2 font-medium text-[#286CFF] border border-[#E5E7EB] text-center min-w-[100px]">
{previousMonths?.previous_period_three || 'Mar'} {previousMonths?.previous_period_three || 'Mar'}
</th> </th>
</>
)}
{/* Current Quarter Months */} {/* Current Quarter Months */}
<th className="bg-[#F3FAF4] px-3 py-2 font-medium text-[#2F663C] border border-[#E5E7EB] text-center min-w-[100px]"> <th className="bg-[#F3FAF4] px-3 py-2 font-medium text-[#2F663C] border border-[#E5E7EB] text-center min-w-[100px]">
@ -1226,6 +1261,8 @@ setAdditionalForecastMonths([
</th> </th>
{/* Next Year Forecast Months */} {/* Next Year Forecast Months */}
{!shouldHideForecast && (
<>
<th className="bg-[#FFF6EC] px-3 py-2 font-medium text-[#F29F0E] border border-[#E5E7EB] text-center min-w-[100px]"> <th className="bg-[#FFF6EC] px-3 py-2 font-medium text-[#F29F0E] border border-[#E5E7EB] text-center min-w-[100px]">
{forecastMonths?.forecast_period_one || 'Oct'} {forecastMonths?.forecast_period_one || 'Oct'}
</th> </th>
@ -1236,9 +1273,13 @@ setAdditionalForecastMonths([
{forecastMonths?.forecast_period_three || 'Dec'} {forecastMonths?.forecast_period_three || 'Dec'}
</th> </th>
</> </>
)}
</>
) : ( ) : (
<> <>
{/* Previous Quarter Months */} {/* Previous Quarter Months */}
{!shouldHidePreviousQuarter && (
<>
<th className="bg-[#F4F8FF] px-3 py-2 font-medium text-[#286CFF] border border-[#E5E7EB] text-center min-w-[100px]"> <th className="bg-[#F4F8FF] px-3 py-2 font-medium text-[#286CFF] border border-[#E5E7EB] text-center min-w-[100px]">
{previousMonths?.previous_period_one || 'Jan'} {previousMonths?.previous_period_one || 'Jan'}
</th> </th>
@ -1248,6 +1289,8 @@ setAdditionalForecastMonths([
<th className="bg-[#F4F8FF] px-3 py-2 font-medium text-[#286CFF] border border-[#E5E7EB] text-center min-w-[100px]"> <th className="bg-[#F4F8FF] px-3 py-2 font-medium text-[#286CFF] border border-[#E5E7EB] text-center min-w-[100px]">
{previousMonths?.previous_period_three || 'Mar'} {previousMonths?.previous_period_three || 'Mar'}
</th> </th>
</>
)}
{/* Current Quarter Months */} {/* Current Quarter Months */}
<th className="bg-[#F3FAF4] px-3 py-2 font-medium text-[#2F663C] border border-[#E5E7EB] text-center min-w-[100px]"> <th className="bg-[#F3FAF4] px-3 py-2 font-medium text-[#2F663C] border border-[#E5E7EB] text-center min-w-[100px]">
@ -1261,6 +1304,8 @@ setAdditionalForecastMonths([
</th> </th>
{/* Next Year Forecast Months */} {/* Next Year Forecast Months */}
{!shouldHideForecast && (
<>
<th className="bg-[#FFF6EC] px-3 py-2 font-medium text-[#F29F0E] border border-[#E5E7EB] text-center min-w-[100px]"> <th className="bg-[#FFF6EC] px-3 py-2 font-medium text-[#F29F0E] border border-[#E5E7EB] text-center min-w-[100px]">
{forecastMonths?.forecast_period_one || 'Jul'} {forecastMonths?.forecast_period_one || 'Jul'}
</th> </th>
@ -1272,6 +1317,8 @@ setAdditionalForecastMonths([
</th> </th>
</> </>
)} )}
</>
)}
</tr> </tr>
</thead> </thead>
@ -1284,6 +1331,8 @@ setAdditionalForecastMonths([
{showPreviousNext ? ( {showPreviousNext ? (
<> <>
{/* Previous Quarter Month 1 (BASE) - NO VARIANCE */} {/* Previous Quarter Month 1 (BASE) - NO VARIANCE */}
{!shouldHidePreviousQuarter && (
<>
<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"> <span className="font-medium">
@ -1319,15 +1368,17 @@ setAdditionalForecastMonths([
)} )}
</div> </div>
</td> </td>
</>
)}
{/* Current Quarter Month 1 */} {/* 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)}`}> <td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(shouldHidePreviousQuarter ? null : product.previous_quantity_period_three, product.current_quantity_period_one, shouldHidePreviousQuarter ? false : isPreviousQuarterAllZeros)} ${getBorderClass(shouldHidePreviousQuarter ? null : product.previous_quantity_period_three, product.current_quantity_period_one, shouldHidePreviousQuarter ? false : isPreviousQuarterAllZeros)}`}>
<div className="flex flex-col items-center justify-center"> <div className="flex flex-col items-center justify-center">
<span className="font-medium"> <span className="font-medium">
{product.current_quantity_period_one || "0"} {product.current_quantity_period_one || "0"}
</span> </span>
{/* If previous quarter is all zeros, treat this as FIRST month */} {/* If previous quarter is all zeros, treat this as FIRST month */}
{!isPreviousQuarterAllZeros && getVarianceDisplay( {!shouldHidePreviousQuarter && !isPreviousQuarterAllZeros && getVarianceDisplay(
product.previous_quantity_period_three, product.previous_quantity_period_three,
product.current_quantity_period_one product.current_quantity_period_one
)} )}
@ -1390,6 +1441,8 @@ setAdditionalForecastMonths([
})()} })()}
{/* NEXT YEAR FORECAST Data (original from submission) */} {/* NEXT YEAR FORECAST Data (original from submission) */}
{!shouldHideForecast && (
<>
<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)}`}> <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>
@ -1409,16 +1462,21 @@ setAdditionalForecastMonths([
</div> </div>
</td> </td>
</> </>
)}
</>
) : ( ) : (
<> <>
{/* Previous Quarter Month 1 */} {/* Previous Quarter Month 1 */}
{!shouldHidePreviousQuarter && (
<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 */} {/* Previous Quarter Month 2 */}
{!shouldHidePreviousQuarter && (
<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>
@ -1428,8 +1486,10 @@ setAdditionalForecastMonths([
)} )}
</div> </div>
</td> </td>
)}
{/* Previous Quarter Month 3 */} {/* Previous Quarter Month 3 */}
{!shouldHidePreviousQuarter && (
<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)}`}> <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>
@ -1439,12 +1499,13 @@ setAdditionalForecastMonths([
)} )}
</div> </div>
</td> </td>
)}
{/* Current Quarter Month 1 */} {/* 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)}`}> <td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(shouldHidePreviousQuarter ? null : product.previous_quantity_period_three, product.current_quantity_period_one, shouldHidePreviousQuarter ? false : isPreviousQuarterAllZeros)} ${getBorderClass(shouldHidePreviousQuarter ? null : product.previous_quantity_period_three, product.current_quantity_period_one, shouldHidePreviousQuarter ? false : 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>
{!isPreviousQuarterAllZeros && getVarianceDisplay( {!shouldHidePreviousQuarter && !isPreviousQuarterAllZeros && getVarianceDisplay(
product.previous_quantity_period_three, product.previous_quantity_period_three,
product.current_quantity_period_one product.current_quantity_period_one
)} )}
@ -1517,6 +1578,8 @@ setAdditionalForecastMonths([
{showPreviousNext ? ( {showPreviousNext ? (
<> <>
{/* Previous Cost Month 1 (BASE) - NO VARIANCE */} {/* Previous Cost Month 1 (BASE) - NO VARIANCE */}
{!shouldHidePreviousQuarter && (
<>
<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"> <span className="font-medium">
@ -1550,12 +1613,14 @@ setAdditionalForecastMonths([
)} )}
</div> </div>
</td> </td>
</>
)}
{/* Current Quarter Cost Month 1 */} {/* 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)}`}> <td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(shouldHidePreviousQuarter ? null : product.previous_cost_period_three, product.current_cost_period_one, shouldHidePreviousQuarter ? false : isPreviousQuarterCostAllZeros)} ${getBorderClass(shouldHidePreviousQuarter ? null : product.previous_cost_period_three, product.current_cost_period_one, shouldHidePreviousQuarter ? false : 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>
{!isPreviousQuarterCostAllZeros && getVarianceDisplay(product.previous_cost_period_three, product.current_cost_period_one)} {!shouldHidePreviousQuarter && !isPreviousQuarterCostAllZeros && getVarianceDisplay(product.previous_cost_period_three, product.current_cost_period_one)}
</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, false)} ${getBorderClass(product.current_cost_period_one, product.current_cost_period_two, false)}`}> <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)}`}>
@ -1599,6 +1664,8 @@ setAdditionalForecastMonths([
})()} })()}
{/* NEXT YEAR FORECAST Cost (original from submission) */} {/* NEXT YEAR FORECAST Cost (original from submission) */}
{!shouldHideForecast && (
<>
<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)}`}> <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>
@ -1618,16 +1685,21 @@ setAdditionalForecastMonths([
</div> </div>
</td> </td>
</> </>
)}
</>
) : ( ) : (
<> <>
{/* Previous Cost Month 1 */} {/* Previous Cost Month 1 */}
{!shouldHidePreviousQuarter && (
<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 */} {/* Previous Cost Month 2 */}
{!shouldHidePreviousQuarter && (
<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>
@ -1637,8 +1709,10 @@ setAdditionalForecastMonths([
)} )}
</div> </div>
</td> </td>
)}
{/* Previous Cost Month 3 */} {/* Previous Cost Month 3 */}
{!shouldHidePreviousQuarter && (
<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)}`}> <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>
@ -1648,12 +1722,13 @@ setAdditionalForecastMonths([
)} )}
</div> </div>
</td> </td>
)}
{/* Current Cost Month 1 */} {/* 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)}`}> <td className={`px-3 py-3 border border-[#E5E7EB] text-center ${getCellClass(shouldHidePreviousQuarter ? null : product.previous_cost_period_three, product.current_cost_period_one, shouldHidePreviousQuarter ? false : isPreviousQuarterCostAllZeros)} ${getBorderClass(shouldHidePreviousQuarter ? null : product.previous_cost_period_three, product.current_cost_period_one, shouldHidePreviousQuarter ? false : 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>
{!isPreviousQuarterCostAllZeros && getVarianceDisplay( {!shouldHidePreviousQuarter && !isPreviousQuarterCostAllZeros && getVarianceDisplay(
product.previous_cost_period_three, product.previous_cost_period_three,
product.current_cost_period_one product.current_cost_period_one
)} )}
@ -1683,6 +1758,7 @@ setAdditionalForecastMonths([
</td> </td>
{/* Forecast Cost Month 1 */} {/* Forecast Cost Month 1 */}
{!shouldHideForecast && (
<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)}`}> <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>
@ -1692,8 +1768,10 @@ setAdditionalForecastMonths([
)} )}
</div> </div>
</td> </td>
)}
{/* Forecast Cost Month 2 */} {/* Forecast Cost Month 2 */}
{!shouldHideForecast && (
<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)}`}> <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>
@ -1703,8 +1781,10 @@ setAdditionalForecastMonths([
)} )}
</div> </div>
</td> </td>
)}
{/* Forecast Cost Month 3 */} {/* Forecast Cost Month 3 */}
{!shouldHideForecast && (
<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)}`}> <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>
@ -1714,6 +1794,7 @@ setAdditionalForecastMonths([
)} )}
</div> </div>
</td> </td>
)}
</> </>
)} )}
</tr> </tr>
@ -1724,9 +1805,11 @@ setAdditionalForecastMonths([
</td> </td>
{showPreviousNext ? ( {showPreviousNext ? (
<> <>
{!shouldHidePreviousQuarter && (
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]"> <td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
</td> </td>
)}
<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 ?
@ -1738,18 +1821,19 @@ setAdditionalForecastMonths([
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]"> <td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
</td> </td>
{/* Next Year Forecast (colSpan 3) */} {!shouldHideForecast && (
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]"> <td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
</td> </td>
)}
</> </>
) : ( ) : (
<> <>
{/* Previous Quarter (colSpan 3) */} {!shouldHidePreviousQuarter && (
<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) */} )}
<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 ?
@ -1757,10 +1841,11 @@ setAdditionalForecastMonths([
: 'No reason provided') : 'No reason provided')
} }
</td> </td>
{/* Next Year Forecast (colSpan 3) */} {!shouldHideForecast && (
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]"> <td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
</td> </td>
)}
</> </>
)} )}
</tr> </tr>
@ -1771,15 +1856,18 @@ setAdditionalForecastMonths([
</td> </td>
{showPreviousNext ? ( {showPreviousNext ? (
<> <>
{!shouldHidePreviousQuarter && (
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
</td>
)}
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]"> <td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
</td> </td>
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]"> <td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
</td> </td>
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]"> {!shouldHideForecast && (
</td>
<td colSpan="3" className="px-4 py-3 text-center bg-[#FFF2E0] text-[#D97706] font-medium border border-[#E5E7EB]"> <td colSpan="3" className="px-4 py-3 text-center bg-[#FFF2E0] text-[#D97706] font-medium border border-[#E5E7EB]">
{product.other_zero_target_reason || {product.other_zero_target_reason ||
(product?.zero_target_reason?.reason ? (product?.zero_target_reason?.reason ?
@ -1787,15 +1875,19 @@ setAdditionalForecastMonths([
: 'No reason provided') : 'No reason provided')
} }
</td> </td>
)}
</> </>
) : ( ) : (
<> <>
{!shouldHidePreviousQuarter && (
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]"> <td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
</td> </td>
)}
<td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]"> <td colSpan="3" className="text-center text-[#6B7280] border border-[#E5E7EB]">
</td> </td>
{!shouldHideForecast && (
<td colSpan="3" className="px-4 py-3 text-center bg-[#FFF2E0] text-[#D97706] font-medium border border-[#E5E7EB]"> <td colSpan="3" className="px-4 py-3 text-center bg-[#FFF2E0] text-[#D97706] font-medium border border-[#E5E7EB]">
{product.other_zero_target_reason || {product.other_zero_target_reason ||
(product?.zero_target_reason?.reason ? (product?.zero_target_reason?.reason ?
@ -1803,6 +1895,7 @@ setAdditionalForecastMonths([
: 'No reason provided') : 'No reason provided')
} }
</td> </td>
)}
</> </>
)} )}
</tr> </tr>

View File

@ -2567,6 +2567,16 @@ const handleView = async (id) => {
} }
} }
// ISIC code validation for industryCodeBusiness field
if (field === 'industryCodeBusiness' && value) {
if (!/^\d+$/.test(value)) {
return 'ISIC code must contain only digits';
}
if (value.length < 10 || value.length > 32) {
return 'Industry Code must be between 10 and 32 digits';
}
}
const numericFields = [ const numericFields = [
'employmentEmiratiMale', 'employmentEmiratiMale',
'employmentEmiratiFemale', 'employmentEmiratiFemale',