FCSC Bug fixed
This commit is contained in:
parent
8186987cb0
commit
8b1b09d8ba
@ -84,17 +84,29 @@ export const SurveyStatus = () => {
|
||||
}, []);
|
||||
|
||||
const handleStartSurvey = (survey) => {
|
||||
// Store the survey data in localStorage
|
||||
localStorage.setItem('currentSurvey', JSON.stringify({
|
||||
// Prepare survey data with all required fields
|
||||
const surveyData = {
|
||||
quarter: survey.quarter,
|
||||
year: survey.year,
|
||||
startDate: survey.startDate,
|
||||
endDate: survey.endDate,
|
||||
title: survey.title
|
||||
}));
|
||||
title: survey.title,
|
||||
// Include establishment data if available
|
||||
establishment: survey.establishment || null
|
||||
};
|
||||
|
||||
// Navigate to the survey page
|
||||
navigate('/survey');
|
||||
// Store the survey data in localStorage
|
||||
localStorage.setItem('currentSurvey', JSON.stringify(surveyData));
|
||||
|
||||
// Navigate to the survey page with survey data in state
|
||||
navigate('/survey', {
|
||||
state: {
|
||||
survey: surveyData,
|
||||
isResubmit: survey.status === 'Submitted', // Mark as resubmit if status is 'Submitted'
|
||||
// Include establishment data in the location state
|
||||
establishment: survey.establishment || null
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const nextDeadline = dashboardData?.next_deadline;
|
||||
|
||||
@ -157,24 +157,24 @@ const EstablishmentInfo = ({
|
||||
}, [data]);
|
||||
|
||||
const info = React.useMemo(
|
||||
() => ({
|
||||
quarter: surveyData.quarter || '',
|
||||
year: surveyData.year || '',
|
||||
establishmentName: '',
|
||||
permanentFactoryCode: '',
|
||||
industryCode: '',
|
||||
licenseNumber: '',
|
||||
isicCode: '',
|
||||
emirate: '',
|
||||
establishment_contact_email: data?.establishment_contact_email || '',
|
||||
employeeInfo: {
|
||||
...defaultEmployeeInfo,
|
||||
...(data.employeeInfo || {}),
|
||||
},
|
||||
...data,
|
||||
}),
|
||||
[data]
|
||||
);
|
||||
() => ({
|
||||
quarter: surveyData.quarter || '',
|
||||
year: surveyData.year || '',
|
||||
establishmentName: data.establishmentName || '',
|
||||
permanentFactoryCode: data.permanentFactoryCode || '',
|
||||
industryCode: data.industryCode || '',
|
||||
licenseNumber: data.licenseNumber || '',
|
||||
isicCode: data.isicCode || '',
|
||||
emirate: data.emirate || '',
|
||||
establishment_contact_email: data.establishment_contact_email || '',
|
||||
employeeInfo: {
|
||||
...defaultEmployeeInfo,
|
||||
...(data.employeeInfo || {}),
|
||||
},
|
||||
...data,
|
||||
}),
|
||||
[data, surveyData.quarter, surveyData.year]
|
||||
);
|
||||
|
||||
const handleFieldChange = (field) => (event) => {
|
||||
onChange({
|
||||
|
||||
@ -314,22 +314,23 @@ const ProductData = ({
|
||||
const [unitsError, setUnitsError] = React.useState('');
|
||||
const [activeTab, setActiveTab] = React.useState('current');
|
||||
const [isInitialLoad, setIsInitialLoad] = React.useState(true);
|
||||
const [quarterPeriods, setQuarterPeriods] = React.useState(null);
|
||||
const [isLoadingPeriods, setIsLoadingPeriods] = React.useState(false);
|
||||
const [showOtherVariationReason, setShowOtherVariationReason] = React.useState({});
|
||||
const [showOtherZeroTargetReason, setShowOtherZeroTargetReason] = React.useState({});
|
||||
const [formErrors, setFormErrors] = React.useState({});
|
||||
const [remarks, setRemarks] = React.useState(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
const savedRemarks = localStorage.getItem('surveyRemarks');
|
||||
return savedRemarks || '';
|
||||
return localStorage.getItem('surveyRemarks') || '';
|
||||
}
|
||||
return '';
|
||||
});
|
||||
const [formErrors, setFormErrors] = React.useState({});
|
||||
const [quarterPeriods, setQuarterPeriods] = useState(null);
|
||||
const [isLoadingPeriods, setIsLoadingPeriods] = useState(false);
|
||||
|
||||
const handleRemarksChange = (e) => {
|
||||
const newRemarks = e.target.value;
|
||||
setRemarks(newRemarks);
|
||||
const value = e.target.value;
|
||||
setRemarks(value);
|
||||
if (typeof window !== 'undefined') {
|
||||
localStorage.setItem('surveyRemarks', newRemarks);
|
||||
localStorage.setItem('surveyRemarks', value);
|
||||
}
|
||||
};
|
||||
|
||||
@ -362,12 +363,13 @@ const ProductData = ({
|
||||
setReasonsError('');
|
||||
try {
|
||||
const reasons = await fetchVariationReasons({ signal: variationController.signal });
|
||||
setVariationReasons(reasons);
|
||||
console.log('Loaded variation reasons:', reasons);
|
||||
setVariationReasons(reasons || []);
|
||||
setReasonsError('');
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch variation reasons:', error);
|
||||
if (error.name !== 'AbortError') {
|
||||
// console.error('Failed to fetch variation reasons', error);
|
||||
// setReasonsError('Failed to load variation reasons.');
|
||||
setReasonsError('Failed to load variation reasons.');
|
||||
}
|
||||
} finally {
|
||||
setIsLoadingReasons(false);
|
||||
@ -464,12 +466,12 @@ const ProductData = ({
|
||||
const formattedProducts = response.data.establishment_products.map(item => {
|
||||
const product = item.product || {};
|
||||
return {
|
||||
value: product.hs_code || '',
|
||||
value: item.product_id, // Use product_id as the value
|
||||
label: product.product_name ?
|
||||
`${product.product_name} (${product.hs_code || 'N/A'})` :
|
||||
'Unknown Product',
|
||||
productId: item.product_id, // Include the actual product ID
|
||||
productData: product // Include the full product data
|
||||
originalData: product, // Store the full product data
|
||||
hsCode: product.hs_code // Store HS code separately for display
|
||||
};
|
||||
});
|
||||
|
||||
@ -674,86 +676,96 @@ const location = useLocation();
|
||||
}
|
||||
};
|
||||
|
||||
// const handleProductSelect = async (productId, establishmentId, id) => {
|
||||
// if (!productId || !establishmentId) return;
|
||||
|
||||
// try {
|
||||
// const forecastData = await fetchPreviousForecastData(productId, establishmentId);
|
||||
// console.log('Forecast data received:', forecastData);
|
||||
|
||||
// if (!forecastData) {
|
||||
// console.warn('No forecast data received for product:', productId);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// // Check if the response has a data property (nested response) or is the data itself
|
||||
// const data = forecastData.data || forecastData;
|
||||
|
||||
// const updatedProducts = products.map(product => {
|
||||
// if (product.id === id) {
|
||||
// return {
|
||||
// ...product,
|
||||
// octQuantity: data.previous_quantity_period_one || '',
|
||||
// novQuantity: data.previous_quantity_period_two || '',
|
||||
// decQuantity: data.previous_quantity_period_three || '',
|
||||
// octCost: data.previous_cost_period_one || '',
|
||||
// novCost: data.previous_cost_period_two || '',
|
||||
// decCost: data.previous_cost_period_three || '',
|
||||
// capacity: data.annual_installed_capacity || ''
|
||||
// };
|
||||
// }
|
||||
// return product;
|
||||
// });
|
||||
|
||||
// onProductsChange(updatedProducts);
|
||||
// } catch (error) {
|
||||
// console.error('Error in handleProductSelect:', error);
|
||||
// }
|
||||
// };
|
||||
|
||||
const updateProductField = (id, field, value, options = null) => {
|
||||
const updatedProducts = products.map(product => {
|
||||
if (product.id === id) {
|
||||
// Clear error for the field being updated
|
||||
// Check if 'Others' is selected for variation reason
|
||||
if (field === 'variationReason' || field === 'otherVariationReason') {
|
||||
if (field === 'variationReason') {
|
||||
const selectedReason = options?.find(r => r.value === value || r.id === value);
|
||||
// Check both name and label for 'other' to be more flexible
|
||||
const isOtherSelected = selectedReason && (
|
||||
(selectedReason.name && selectedReason.name.toLowerCase().includes('other')) ||
|
||||
(selectedReason.label && selectedReason.label.toLowerCase().includes('other'))
|
||||
);
|
||||
|
||||
console.log('Selected reason:', selectedReason, 'Is other:', isOtherSelected);
|
||||
|
||||
// Update the showOtherVariationReason state for this product
|
||||
setShowOtherVariationReason(prev => ({
|
||||
...prev,
|
||||
[id]: isOtherSelected
|
||||
}));
|
||||
|
||||
// If not 'Others', clear any existing other reason
|
||||
if (!isOtherSelected) {
|
||||
return {
|
||||
...product,
|
||||
variationReason: value,
|
||||
variationReasonName: selectedReason?.label || selectedReason?.name || '',
|
||||
otherVariationReason: '',
|
||||
[field]: value
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
...product,
|
||||
variationReason: value,
|
||||
variationReasonName: selectedReason?.label || selectedReason?.name || '',
|
||||
[field]: value
|
||||
};
|
||||
} else {
|
||||
// Handle otherVariationReason update
|
||||
return {
|
||||
...product,
|
||||
[field]: value
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
...product,
|
||||
variationReason: value,
|
||||
variationReasonName: selectedReason?.label || selectedReason?.name || '',
|
||||
[field]: value
|
||||
};
|
||||
}
|
||||
|
||||
// Handle product selection
|
||||
if (field === 'product') {
|
||||
const selectedProduct = options?.find(opt => opt.value === value);
|
||||
const updatedProduct = {
|
||||
...product,
|
||||
product: selectedProduct?.value || value,
|
||||
product: selectedProduct?.value || value,
|
||||
productName: selectedProduct?.label || '',
|
||||
productId: selectedProduct?.value || ''
|
||||
hsCode: selectedProduct?.hsCode || '',
|
||||
productData: selectedProduct?.originalData || null
|
||||
};
|
||||
|
||||
// Fetch previous forecast data when product is selected
|
||||
if (selectedProduct?.value) {
|
||||
// Try to get establishmentId from sessionStorage first, then fallback to localStorage
|
||||
let establishmentId = sessionStorage.getItem('establishment_id') ||
|
||||
localStorage.getItem('establishmentId') ||
|
||||
localStorage.getItem('establishment_id');
|
||||
|
||||
const establishmentId = sessionStorage.getItem('establishment_id') ||
|
||||
localStorage.getItem('establishmentId') ||
|
||||
localStorage.getItem('establishment_id');
|
||||
|
||||
if (establishmentId && quarter && year) {
|
||||
// Get the actual product ID from the selected product object
|
||||
const selectedProductId = selectedProduct.originalData?.id || selectedProduct.value;
|
||||
// Use the product_id directly as the value
|
||||
const productId = selectedProduct.value;
|
||||
|
||||
console.log('Fetching forecast data for:', {
|
||||
productId: selectedProductId,
|
||||
productId,
|
||||
establishmentId,
|
||||
quarter,
|
||||
year,
|
||||
storageSource: sessionStorage.getItem('establishment_id') ? 'sessionStorage' : 'localStorage'
|
||||
});
|
||||
handleProductSelect(selectedProductId, establishmentId, id);
|
||||
|
||||
// Call handleProductSelect with the product ID
|
||||
handleProductSelect(productId, establishmentId, id);
|
||||
} else {
|
||||
console.warn('Missing required parameters for forecast data fetch:', {
|
||||
hasEstablishmentId: !!establishmentId,
|
||||
establishmentIdValue: establishmentId, // Log the actual value for debugging
|
||||
hasQuarter: !!quarter,
|
||||
hasYear: !!year,
|
||||
availableStorage: {
|
||||
sessionStorage: sessionStorage.getItem('establishment_id') ? 'exists' : 'not found',
|
||||
localStorage: localStorage.getItem('establishmentId') ? 'exists' : 'not found',
|
||||
localStorageAlt: localStorage.getItem('establishment_id') ? 'exists' : 'not found'
|
||||
}
|
||||
hasYear: !!year
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -773,6 +785,29 @@ const location = useLocation();
|
||||
// When variation reason is selected, store both ID and name
|
||||
if (field === 'variationReason') {
|
||||
const selectedReason = options.find(r => r.value === value || r.id === value);
|
||||
// Check both name and label for 'other' to be more flexible
|
||||
const isOtherSelected = selectedReason && (
|
||||
(selectedReason.name && selectedReason.name.toLowerCase().includes('other')) ||
|
||||
(selectedReason.label && selectedReason.label.toLowerCase().includes('other'))
|
||||
);
|
||||
|
||||
// Update the showOtherVariationReason state for this product
|
||||
setShowOtherVariationReason(prev => ({
|
||||
...prev,
|
||||
[id]: isOtherSelected
|
||||
}));
|
||||
|
||||
// If not 'Others', clear any existing other reason
|
||||
if (!isOtherSelected) {
|
||||
return {
|
||||
...product,
|
||||
variationReason: value,
|
||||
variationReasonName: selectedReason?.label || selectedReason?.name || '',
|
||||
otherVariationReason: '',
|
||||
[field]: value
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
...product,
|
||||
variationReason: value,
|
||||
@ -780,10 +815,35 @@ const location = useLocation();
|
||||
[field]: value
|
||||
};
|
||||
}
|
||||
|
||||
// When zero target reason is selected, store both ID and name
|
||||
|
||||
// Handle zero target reason selection
|
||||
if (field === 'zeroTargetReason') {
|
||||
const selectedReason = options.find(r => r.value === value || r.id === value);
|
||||
const selectedReason = options?.find(r => r.value === value || r.id === value);
|
||||
// Check both name and label for 'other' to be more flexible
|
||||
const isOtherSelected = selectedReason && (
|
||||
(selectedReason.name && selectedReason.name.toLowerCase().includes('other')) ||
|
||||
(selectedReason.label && selectedReason.label.toLowerCase().includes('other'))
|
||||
);
|
||||
|
||||
console.log('Selected zero target reason:', selectedReason, 'Is other:', isOtherSelected);
|
||||
|
||||
// Update the showOtherZeroTargetReason state for this product
|
||||
setShowOtherZeroTargetReason(prev => ({
|
||||
...prev,
|
||||
[id]: isOtherSelected
|
||||
}));
|
||||
|
||||
// If not 'Others', clear any existing other reason
|
||||
if (!isOtherSelected) {
|
||||
return {
|
||||
...product,
|
||||
zeroTargetReason: value,
|
||||
zeroTargetReasonName: selectedReason?.label || selectedReason?.name || '',
|
||||
otherZeroTargetReason: '',
|
||||
[field]: value
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
...product,
|
||||
zeroTargetReason: value,
|
||||
@ -791,76 +851,72 @@ const location = useLocation();
|
||||
[field]: value
|
||||
};
|
||||
}
|
||||
|
||||
return { ...product, [field]: value };
|
||||
}
|
||||
return product;
|
||||
});
|
||||
|
||||
// Clear error for the field being updated
|
||||
const productIndex = products.findIndex(p => p.id === id);
|
||||
if (productIndex !== -1) {
|
||||
const errorKey = `${field}_${productIndex}`;
|
||||
if (formErrors[errorKey] && value) {
|
||||
const newErrors = { ...formErrors };
|
||||
delete newErrors[errorKey];
|
||||
setFormErrors(newErrors);
|
||||
}
|
||||
|
||||
return { ...product, [field]: value };
|
||||
}
|
||||
|
||||
onProductsChange(updatedProducts);
|
||||
};
|
||||
return product;
|
||||
});
|
||||
|
||||
// Clear error for the field being updated
|
||||
const productIndex = products.findIndex(p => p.id === id);
|
||||
if (productIndex !== -1) {
|
||||
const errorKey = `${field}_${productIndex}`;
|
||||
if (formErrors[errorKey] && value) {
|
||||
const newErrors = { ...formErrors };
|
||||
delete newErrors[errorKey];
|
||||
setFormErrors(newErrors);
|
||||
}
|
||||
}
|
||||
|
||||
const handleProductSelect = async (productId, establishmentId, id) => {
|
||||
if (!productId || !establishmentId) {
|
||||
console.warn('Missing required parameters in handleProductSelect:', {
|
||||
hasProductId: !!productId,
|
||||
hasEstablishmentId: !!establishmentId
|
||||
});
|
||||
onProductsChange(updatedProducts);
|
||||
};
|
||||
|
||||
const handleProductSelect = async (productId, establishmentId, id) => {
|
||||
if (!productId || !establishmentId) {
|
||||
console.warn('Missing required parameters in handleProductSelect:', {
|
||||
hasProductId: !!productId,
|
||||
hasEstablishmentId: !!establishmentId
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const forecastData = await fetchPreviousForecastData(productId, establishmentId);
|
||||
if (!forecastData) {
|
||||
console.warn('No forecast data received for product:', productId);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const forecastData = await fetchPreviousForecastData(productId, establishmentId);
|
||||
if (!forecastData) {
|
||||
console.warn('No forecast data received for product:', productId);
|
||||
return;
|
||||
// Check if the response has a data property (nested response) or is the data itself
|
||||
const data = forecastData.data || forecastData;
|
||||
console.log('Processing forecast data:', data);
|
||||
|
||||
const updatedProducts = products.map(product => {
|
||||
if (product.id === id) {
|
||||
return {
|
||||
...product,
|
||||
octQuantity: data.previous_quantity_period_one || '',
|
||||
novQuantity: data.previous_quantity_period_two || '',
|
||||
decQuantity: data.previous_quantity_period_three || '',
|
||||
octCost: data.previous_cost_period_one || '',
|
||||
novCost: data.previous_cost_period_two || '',
|
||||
decCost: data.previous_cost_period_three || '',
|
||||
capacity: data.annual_installed_capacity || ''
|
||||
};
|
||||
}
|
||||
|
||||
// Check if the response has a data property (nested response) or is the data itself
|
||||
const data = forecastData.data || forecastData;
|
||||
console.log('Processing forecast data:', data);
|
||||
|
||||
const updatedProducts = products.map(product => {
|
||||
if (product.id === id) {
|
||||
const updatedProduct = {
|
||||
...product,
|
||||
octQuantity: data.previous_quantity_period_one || '',
|
||||
novQuantity: data.previous_quantity_period_two || '',
|
||||
decQuantity: data.previous_quantity_period_three || '',
|
||||
octCost: data.previous_cost_period_one || '',
|
||||
novCost: data.previous_cost_period_two || '',
|
||||
decCost: data.previous_cost_period_three || '',
|
||||
capacity: data.annual_installed_capacity || ''
|
||||
};
|
||||
console.log('Updated product data:', updatedProduct);
|
||||
return updatedProduct;
|
||||
}
|
||||
return product;
|
||||
});
|
||||
|
||||
console.log('Updating products with new data');
|
||||
onProductsChange(updatedProducts);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error in handleProductSelect:', {
|
||||
message: error.message,
|
||||
error: error,
|
||||
stack: error.stack
|
||||
});
|
||||
}
|
||||
};
|
||||
return product;
|
||||
});
|
||||
|
||||
console.log('Updating products with new data');
|
||||
onProductsChange(updatedProducts);
|
||||
} catch (error) {
|
||||
console.error('Error in handleProductSelect:', {
|
||||
message: error.message,
|
||||
error: error,
|
||||
stack: error.stack
|
||||
});
|
||||
}
|
||||
};
|
||||
const canAddMoreProducts = products.length < MAX_PRODUCTS;
|
||||
|
||||
const isLoading = loading || isLoadingReasons || isLoadingZeroReasons || isLoadingProducts || isLoadingUnits;
|
||||
@ -1323,6 +1379,18 @@ const location = useLocation();
|
||||
value={p.variationReason || ''}
|
||||
onChange={(e) => updateProductField(p.id, 'variationReason', e.target.value, variationReasons)}
|
||||
/>
|
||||
{(showOtherVariationReason[p.id] || (p.variationReason && (p.variationReason.toString().toLowerCase().includes('other') || (variationReasons.find(r => r.value === p.variationReason)?.name?.toLowerCase().includes('other') || variationReasons.find(r => r.value === p.variationReason)?.label?.toLowerCase().includes('other'))))) && (
|
||||
<div className="mt-3 p-3 bg-gray-50 rounded-md border border-gray-200">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">Please specify the reason</label>
|
||||
<Input
|
||||
className="w-full"
|
||||
placeholder="Enter your reason here..."
|
||||
value={p.otherVariationReason || ''}
|
||||
onChange={(e) => updateProductField(p.id, 'otherVariationReason', e.target.value)}
|
||||
/>
|
||||
<p className="mt-1 text-xs text-gray-500">Please provide details about the variation reason</p>
|
||||
</div>
|
||||
)}
|
||||
{reasonsError && variationReasons.length === 0 && (
|
||||
<p className="mt-1 text-xs text-red-600">{reasonsError}</p>
|
||||
)}
|
||||
@ -1458,6 +1526,18 @@ const location = useLocation();
|
||||
value={p.zeroTargetReason || ''}
|
||||
onChange={(e) => updateProductField(p.id, 'zeroTargetReason', e.target.value, zeroTargetReasons)}
|
||||
/>
|
||||
{(showOtherZeroTargetReason[p.id] || (p.zeroTargetReason && (p.zeroTargetReason.toString().toLowerCase().includes('other') || (zeroTargetReasons.find(r => r.value === p.zeroTargetReason)?.name?.toLowerCase().includes('other') || zeroTargetReasons.find(r => r.value === p.zeroTargetReason)?.label?.toLowerCase().includes('other'))))) && (
|
||||
<div className="mt-3 p-3 bg-gray-50 rounded-md border border-gray-200">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">Please specify the reason</label>
|
||||
<Input
|
||||
className="w-full"
|
||||
placeholder="Enter your reason here..."
|
||||
value={p.otherZeroTargetReason || ''}
|
||||
onChange={(e) => updateProductField(p.id, 'otherZeroTargetReason', e.target.value)}
|
||||
/>
|
||||
<p className="mt-1 text-xs text-gray-500">Please provide details about the zero target reason</p>
|
||||
</div>
|
||||
)}
|
||||
{zeroReasonsError && zeroTargetReasons.length === 0 && (
|
||||
<p className="mt-1 text-xs text-red-600">{zeroReasonsError}</p>
|
||||
)}
|
||||
|
||||
@ -222,9 +222,11 @@ const buildProductRows = (products = [], options = {}) => {
|
||||
q4_nov_cost: formatNumber(product.novCost) || '—',
|
||||
q4_dec_cost: formatNumber(product.decCost) || '—',
|
||||
|
||||
// Reasons and remarks - use display names
|
||||
// Reasons and remarks - use display names and include other reasons
|
||||
variationReason: variationReasonName,
|
||||
otherVariationReason: product.otherVariationReason || '',
|
||||
zeroTargetReason: zeroTargetReasonName,
|
||||
otherZeroTargetReason: product.otherZeroTargetReason || '',
|
||||
remarks: product.remarks || '',
|
||||
|
||||
// Keep the raw product data for debugging
|
||||
@ -243,6 +245,80 @@ const buildProductRows = (products = [], options = {}) => {
|
||||
return rows.filter(Boolean);
|
||||
};
|
||||
|
||||
const formatSubmissionData = (establishment, products, remarks = '') => {
|
||||
if (!establishment) {
|
||||
throw new Error('Establishment data is required');
|
||||
}
|
||||
|
||||
// Get employee info with proper fallbacks
|
||||
const employeeInfo = establishment.employeeInfo || {};
|
||||
const emiratiMale = parseInt(employeeInfo.emiratiMale) || 0;
|
||||
const emiratiFemale = parseInt(employeeInfo.emiratiFemale) || 0;
|
||||
const nonEmiratiMale = parseInt(employeeInfo.nonEmiratiMale) || 0;
|
||||
const nonEmiratiFemale = parseInt(employeeInfo.nonEmiratiFemale) || 0;
|
||||
const totalEmirati = emiratiMale + emiratiFemale;
|
||||
const totalEmployees = totalEmirati + nonEmiratiMale + nonEmiratiFemale;
|
||||
|
||||
// Format products data
|
||||
const formattedProducts = products.map(product => ({
|
||||
product_id: parseInt(product.productId) || 0,
|
||||
unit_id: parseInt(product.unit) || 0,
|
||||
annual_installed_capacity: product.capacity?.toString() || '',
|
||||
|
||||
// Previous quarter (Oct-Dec)
|
||||
previous_quantity_period_one: product.octQuantity?.toString() || '0',
|
||||
previous_quantity_period_two: product.novQuantity?.toString() || '0',
|
||||
previous_quantity_period_three: product.decQuantity?.toString() || '0',
|
||||
previous_cost_period_one: product.octCost?.toString() || '0',
|
||||
previous_cost_period_two: product.novCost?.toString() || '0',
|
||||
previous_cost_period_three: product.decCost?.toString() || '0',
|
||||
|
||||
// Current quarter (Jan-Mar)
|
||||
current_quantity_period_one: product.janQuantity?.toString() || '0',
|
||||
current_quantity_period_two: product.febQuantity?.toString() || '0',
|
||||
current_quantity_period_three: product.marQuantity?.toString() || '0',
|
||||
current_cost_period_one: product.janCost?.toString() || '0',
|
||||
current_cost_period_two: product.febCost?.toString() || '0',
|
||||
current_cost_period_three: product.marCost?.toString() || '0',
|
||||
|
||||
// Next quarter forecast (Apr-Jun)
|
||||
forecast_quantity_period_one: product.aprQuantity?.toString() || '0',
|
||||
forecast_quantity_period_two: product.mayQuantity?.toString() || '0',
|
||||
forecast_quantity_period_three: product.junQuantity?.toString() || '0',
|
||||
forecast_cost_period_one: product.aprCost?.toString() || '0',
|
||||
forecast_cost_period_two: product.mayCost?.toString() || '0',
|
||||
forecast_cost_period_three: product.junCost?.toString() || '0',
|
||||
|
||||
// Totals (calculated on backend if needed)
|
||||
previous_quantity: '',
|
||||
previous_cost: '',
|
||||
current_quantity: '',
|
||||
current_cost: '',
|
||||
forecast_quantity: '',
|
||||
forecast_cost: '',
|
||||
|
||||
// Reasons and remarks
|
||||
variation_reason_master_id: product.variationReason?.toString() || '',
|
||||
other_variation_reason: product.otherVariationReason?.toString() || '',
|
||||
zero_target_reason_master_id: product.zeroTargetReason?.toString() || '',
|
||||
other_zero_target_reason: product.otherZeroTargetReason?.toString() || '',
|
||||
remarks: product.remarks || remarks || ''
|
||||
}));
|
||||
|
||||
return {
|
||||
establishment_id: parseInt(establishment.id) || 0,
|
||||
quarter: establishment.quarter || 'Q1', // Should come from your app state
|
||||
year: parseInt(establishment.year) || new Date().getFullYear(),
|
||||
emirati_male: emiratiMale,
|
||||
emirati_female: emiratiFemale,
|
||||
non_emirati_male: nonEmiratiMale,
|
||||
non_emirati_female: nonEmiratiFemale,
|
||||
total_emirati: totalEmirati,
|
||||
total_employees: totalEmployees,
|
||||
products: formattedProducts
|
||||
};
|
||||
};
|
||||
|
||||
const ReviewSubmit = ({
|
||||
establishment,
|
||||
products = [],
|
||||
@ -253,15 +329,37 @@ const ReviewSubmit = ({
|
||||
isSubmitting = false,
|
||||
hasSubmitted = false,
|
||||
submitButtonText = 'Submit',
|
||||
quarter = 'Q1',
|
||||
year = new Date().getFullYear()
|
||||
}) => {
|
||||
const [confirm, setConfirm] = React.useState(false);
|
||||
const [remarks, setRemarks] = React.useState(() => {
|
||||
// Load remarks from localStorage on component mount
|
||||
if (typeof window !== 'undefined') {
|
||||
return localStorage.getItem('surveyRemarks') || '';
|
||||
}
|
||||
return '';
|
||||
});
|
||||
|
||||
const handleSubmit = () => {
|
||||
try {
|
||||
const submissionData = formatSubmissionData(
|
||||
{ ...establishment, quarter, year },
|
||||
products,
|
||||
remarks
|
||||
);
|
||||
console.log('Submitting data:', submissionData);
|
||||
onSubmit(submissionData);
|
||||
setConfirm(false);
|
||||
} catch (error) {
|
||||
console.error('Error formatting submission data:', error);
|
||||
if (onToastClose) {
|
||||
onToastClose({
|
||||
type: 'error',
|
||||
message: 'Failed to prepare data for submission. Please check your input.'
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
const establishmentDetails = React.useMemo(() => buildEstablishmentDetails(establishment), [establishment]);
|
||||
const employmentDetails = React.useMemo(() => buildEmploymentDetails(establishment), [establishment]);
|
||||
const productRows = React.useMemo(() => buildProductRows(products), [products]);
|
||||
@ -689,7 +787,14 @@ const ReviewSubmit = ({
|
||||
-- --
|
||||
</td>
|
||||
<td colSpan="3" className="border border-gray-300 py-2 text-center bg-[#F3FAF4] text-[#2F663C]">
|
||||
{product.variationReasonName || product.variationReason || '—'}
|
||||
<div className="flex flex-col items-center">
|
||||
<div>{product.variationReasonName || product.variationReason || '—'}</div>
|
||||
{product.otherVariationReason && (
|
||||
<div className="mt-1 text-xs text-gray-600">
|
||||
{product.otherVariationReason}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</td>
|
||||
<td colSpan="3" className="border border-gray-300 py-2 text-center">
|
||||
-- --
|
||||
@ -705,7 +810,14 @@ const ReviewSubmit = ({
|
||||
-- --
|
||||
</td>
|
||||
<td colSpan="3" className="border border-gray-300 py-2 text-center bg-[#FFF7E9] text-[#F29F0E]">
|
||||
{product.zeroTargetReasonName || product.zeroTargetReason || '—'}
|
||||
<div className="flex flex-col items-center">
|
||||
<div>{product.zeroTargetReasonName || product.zeroTargetReason || '—'}</div>
|
||||
{product.otherZeroTargetReason && (
|
||||
<div className="mt-1 text-xs text-gray-600 ">
|
||||
{product.otherZeroTargetReason}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
@ -81,18 +81,80 @@ const Survey = () => {
|
||||
}, [initialStepFromState]);
|
||||
|
||||
useEffect(() => {
|
||||
const savedSurvey = localStorage.getItem('currentSurvey');
|
||||
if (savedSurvey) {
|
||||
const surveyData = JSON.parse(savedSurvey);
|
||||
setSurveyData(surveyData);
|
||||
// Update the establishmentData with the saved survey data
|
||||
setEstablishmentData(prev => ({
|
||||
...prev,
|
||||
quarter: surveyData.quarter || '',
|
||||
year: surveyData.year || ''
|
||||
}));
|
||||
// First check if we have survey data in the navigation state
|
||||
if (locationState?.survey) {
|
||||
const { quarter, year, establishment } = locationState.survey;
|
||||
setSurveyData(locationState.survey);
|
||||
|
||||
// If we have establishment data in the navigation state, use it
|
||||
if (establishment) {
|
||||
setEstablishmentData(prev => ({
|
||||
...prev,
|
||||
quarter: quarter || '',
|
||||
year: year || '',
|
||||
establishmentName: establishment.establishmentName || prev.establishmentName,
|
||||
permanentFactoryCode: establishment.permanentFactoryCode || prev.permanentFactoryCode,
|
||||
industryCode: establishment.industryCode || prev.industryCode,
|
||||
licenseNumber: establishment.licenseNumber || prev.licenseNumber,
|
||||
isicCode: establishment.isicCode || prev.isicCode,
|
||||
emirate: establishment.emirate || prev.emirate,
|
||||
employeeInfo: {
|
||||
emiratiMale: establishment.employeeInfo?.emiratiMale || prev.employeeInfo.emiratiMale,
|
||||
emiratiFemale: establishment.employeeInfo?.emiratiFemale || prev.employeeInfo.emiratiFemale,
|
||||
nonEmiratiMale: establishment.employeeInfo?.nonEmiratiMale || prev.employeeInfo.nonEmiratiMale,
|
||||
nonEmiratiFemale: establishment.employeeInfo?.nonEmiratiFemale || prev.employeeInfo.nonEmiratiFemale,
|
||||
totalEmirati: establishment.employeeInfo?.totalEmirati || prev.employeeInfo.totalEmirati,
|
||||
totalEmployees: establishment.employeeInfo?.totalEmployees || prev.employeeInfo.totalEmployees
|
||||
}
|
||||
}));
|
||||
} else {
|
||||
setEstablishmentData(prev => ({
|
||||
...prev,
|
||||
quarter: quarter || '',
|
||||
year: year || ''
|
||||
}));
|
||||
}
|
||||
|
||||
// Also save to localStorage for page refreshes
|
||||
localStorage.setItem('currentSurvey', JSON.stringify(locationState.survey));
|
||||
} else {
|
||||
// Fall back to localStorage if no data in navigation state
|
||||
const savedSurvey = localStorage.getItem('currentSurvey');
|
||||
if (savedSurvey) {
|
||||
const surveyData = JSON.parse(savedSurvey);
|
||||
setSurveyData(surveyData);
|
||||
|
||||
if (surveyData.establishment) {
|
||||
const { establishment } = surveyData;
|
||||
setEstablishmentData(prev => ({
|
||||
...prev,
|
||||
quarter: surveyData.quarter || '',
|
||||
year: surveyData.year || '',
|
||||
establishmentName: establishment.establishmentName || prev.establishmentName,
|
||||
permanentFactoryCode: establishment.permanentFactoryCode || prev.permanentFactoryCode,
|
||||
industryCode: establishment.industryCode || prev.industryCode,
|
||||
licenseNumber: establishment.licenseNumber || prev.licenseNumber,
|
||||
isicCode: establishment.isicCode || prev.isicCode,
|
||||
emirate: establishment.emirate || prev.emirate,
|
||||
employeeInfo: {
|
||||
emiratiMale: establishment.employeeInfo?.emiratiMale || prev.employeeInfo.emiratiMale,
|
||||
emiratiFemale: establishment.employeeInfo?.emiratiFemale || prev.employeeInfo.emiratiFemale,
|
||||
nonEmiratiMale: establishment.employeeInfo?.nonEmiratiMale || prev.employeeInfo.nonEmiratiMale,
|
||||
nonEmiratiFemale: establishment.employeeInfo?.nonEmiratiFemale || prev.employeeInfo.nonEmiratiFemale,
|
||||
totalEmirati: establishment.employeeInfo?.totalEmirati || prev.employeeInfo.totalEmirati,
|
||||
totalEmployees: establishment.employeeInfo?.totalEmployees || prev.employeeInfo.totalEmployees
|
||||
}
|
||||
}));
|
||||
} else {
|
||||
setEstablishmentData(prev => ({
|
||||
...prev,
|
||||
quarter: surveyData.quarter || '',
|
||||
year: surveyData.year || ''
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
}, [locationState]);
|
||||
|
||||
// Function to fetch current quarter and year from dashboard
|
||||
const fetchCurrentQuarterAndYear = async () => {
|
||||
@ -115,13 +177,28 @@ const Survey = () => {
|
||||
|
||||
const initializeSurveyData = async () => {
|
||||
try {
|
||||
// If this is a resubmission, use the quarter and year from the submission
|
||||
// If this is a resubmission, use the data from the submission
|
||||
if (isResubmit && locationState?.submission) {
|
||||
if (!cancelled) {
|
||||
const submission = locationState.submission;
|
||||
setEstablishmentData(prev => ({
|
||||
...prev,
|
||||
quarter: locationState.submission.quarter || '',
|
||||
year: locationState.submission.year?.toString() || ''
|
||||
quarter: submission.quarter || '',
|
||||
year: submission.year?.toString() || '',
|
||||
establishmentName: submission.establishment_name || prev.establishmentName,
|
||||
permanentFactoryCode: submission.permanent_factory_code || prev.permanentFactoryCode,
|
||||
industryCode: submission.industry_code || prev.industryCode,
|
||||
licenseNumber: submission.license_number || prev.licenseNumber,
|
||||
isicCode: submission.isic_code || prev.isicCode,
|
||||
emirate: submission.emirate || prev.emirate,
|
||||
employeeInfo: {
|
||||
emiratiMale: submission.emirati_male || prev.employeeInfo.emiratiMale,
|
||||
emiratiFemale: submission.emirati_female || prev.employeeInfo.emiratiFemale,
|
||||
nonEmiratiMale: submission.non_emirati_male || prev.employeeInfo.nonEmiratiMale,
|
||||
nonEmiratiFemale: submission.non_emirati_female || prev.employeeInfo.nonEmiratiFemale,
|
||||
totalEmirati: submission.total_emirati || prev.employeeInfo.totalEmirati,
|
||||
totalEmployees: submission.total_employees || prev.employeeInfo.totalEmployees
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user