From 9b363d88bbcfc6bbaca08a3f1261d83ebaedf80d Mon Sep 17 00:00:00 2001 From: Malini Date: Wed, 12 Nov 2025 13:56:53 +0530 Subject: [PATCH] bug fixed in the product data --- .../components/overview/DetailedOverview.jsx | 6 +- .../components/overview/ProductDetails.jsx | 11 +- .../survey/ProductData/ProductData.jsx | 140 ++++++++++++------ .../survey/ReviewSubmit/ReviewSubmit.jsx | 60 +++++--- .../src/pages/Overview/Overview.jsx | 4 +- .../src/pages/Survey/Survey.jsx | 2 +- .../services/submissions/submissionService.js | 23 ++- 7 files changed, 169 insertions(+), 77 deletions(-) diff --git a/ipi-survey-platform/src/components/overview/DetailedOverview.jsx b/ipi-survey-platform/src/components/overview/DetailedOverview.jsx index d0cbdbb..6b37f84 100644 --- a/ipi-survey-platform/src/components/overview/DetailedOverview.jsx +++ b/ipi-survey-platform/src/components/overview/DetailedOverview.jsx @@ -129,7 +129,10 @@ export const DetailedOverview = ({ submission, onBack }) => { const matchesStatus = selectedStatus === '' || (selectedStatus === 'pending' && !product.is_active) || - (selectedStatus === 'approved' && product.is_active); + (selectedStatus === 'approved' && product.is_active) + (selectedStatus === 'resubmitted' && product.status === 'Resubmitted') + (selectedStatus === 'submitted' && product.status === 'Submitted') + (selectedStatus === 'rejected' && product.status === 'Rejected'); return matchesSearch && matchesStatus; }); @@ -362,6 +365,7 @@ export const DetailedOverview = ({ submission, onBack }) => { + { try { const establishmentId = sessionStorage.getItem('establishment_id'); - if (!establishmentId) { - console.error('Establishment ID not found in session storage'); - return; - } + if (!establishmentId) return; - const response = await fetchEstablishmentDetail(establishmentId); - if (response && response.data && Array.isArray(response.data.establishment_products)) { - // Transform products data to match the expected format - const formattedProducts = response.data.establishment_products.map(item => { - const product = item.product || {}; - return { - value: item.product_id, // Use product_id as the value - label: product.product_name ? - `${product.product_name} (${product.hs_code || 'N/A'})` : - 'Unknown Product', - originalData: product, // Store the full product data - hsCode: product.hs_code // Store HS code separately for display - }; - }); - - // Update the product options state - setProductOptions(formattedProducts); - - // If you need to update the form with initial products, uncomment and modify: - // if (formattedProducts.length > 0) { - // const initialProducts = formattedProducts.map((product, index) => ({ - // id: index + 1, - // product: product.value, - // unit: '', - // // ... other default values - // })); - // onProductsChange(initialProducts); - // } - } + const fetchProducts = async () => { + setIsLoadingProducts(true); + setProductsError(''); + try { + // Get products from getEstablishmentProducts + const apiResponse = await getEstablishmentProducts(establishmentId); + console.log('Products from API:', apiResponse); // Debug log + + // Ensure we're working with an array and handle the response structure + const productsList = Array.isArray(apiResponse) ? apiResponse : (apiResponse?.data || []); + + const formattedProducts = productsList.map(product => { + // Handle nested properties with dot notation + const productName = product['product.product_name'] || product.product_name || ''; + const hsCode = product['product.hs_code'] || product.hs_code || ''; + const unitName = product['product.unit.uom'] || ''; + + return { + value: product.id.toString(), + label: hsCode ? `${hsCode} - ${productName}` : productName, + originalData: product, + hsCode: hsCode, + name: productName, + productId: product.product_id, // Use product_id instead of id + product_id: product.product_id, // Add product_id directly to the object + unit: unitName + }; + }); + + + console.log('Formatted products:', formattedProducts); // Debug log + setProductOptions(formattedProducts); + } catch (error) { + console.error('Error fetching products:', error); + setProductsError('Failed to load products. Please try again.'); + } finally { + setIsLoadingProducts(false); + } + }; + + await fetchProducts(); } catch (err) { - console.error('Error fetching establishment products:', err); - setError('Failed to load establishment products'); + console.error('Error in fetchEstablishmentProducts:', err); + setProductsError('Failed to load establishment products. Please try again.'); + setIsLoadingProducts(false); } }; fetchEstablishmentProducts(); }, []); + // Moved inside the component React.useEffect(() => { const maxId = products.reduce((max, item) => (item && typeof item.id === 'number' ? Math.max(max, item.id) : max), 0); if (maxId >= nextId.current) { @@ -926,8 +937,8 @@ const handleProductSelect = async (productId, establishmentId, id) => {
{isLoading && (
-
-
+
+
)}

Step 2: Product Data — Monthly Output & Cost

@@ -1084,29 +1095,52 @@ const handleProductSelect = async (productId, establishmentId, id) => { { const selectedValue = e.target.value; + console.log('Selected product value:', selectedValue); // Debug log + // Clear error when user selects a product if (formErrors[`product_${idx}`]) { const newErrors = { ...formErrors }; delete newErrors[`product_${idx}`]; setFormErrors(newErrors); } + // Find the selected product from options const selectedProduct = productOptions.find(opt => opt.value === selectedValue); - // Update the product with all necessary fields + console.log('Selected product:', selectedProduct); // Debug log + // Get unit information from the selected product + const unitId = selectedProduct?.originalData?.['product.unit.id']; + const unitName = selectedProduct?.originalData?.['product.unit.uom'] || + selectedProduct?.originalData?.unit?.uom || + selectedProduct?.unit || ''; + + // Create updated product with all necessary fields including unit info const updatedProduct = { ...p, product: selectedProduct?.value || selectedValue, - productName: selectedProduct?.label || '', - productId: selectedProduct?.productId || selectedValue, // Use the actual product ID - product_id: selectedProduct?.productId || selectedValue // Add product_id for submission + productId: selectedProduct?.value || selectedValue, + product_id: selectedProduct?.value || selectedValue, + hs_code: selectedProduct?.hsCode || p.hs_code, + name: selectedProduct?.name || p.name, + originalData: selectedProduct?.originalData || p.originalData, + // Set unit information + unit: unitId ? unitId.toString() : '', + unitName: unitName, + unit_id: unitId, + // Clear any previous unit-related errors + ...(formErrors[`unit_${idx}`] && { unitError: undefined }) }; + // Update the products array with the updated product - const updatedProducts = products.map(prod => - prod.id === p.id ? updatedProduct : prod + const updatedProducts = products.map((prod, i) => + i === idx ? updatedProduct : prod ); + + console.log('Updated products:', updatedProducts); // Debug log + + // Update the parent component's state onProductsChange(updatedProducts); // After updating the product, fetch forecast data if we have a valid product and establishment ID @@ -1134,8 +1168,8 @@ const handleProductSelect = async (productId, establishmentId, id) => { capacity: data.annual_installed_capacity || '' }; - const finalUpdatedProducts = updatedProducts.map(prod => - prod.id === p.id ? updatedWithForecast : prod + const finalUpdatedProducts = updatedProducts.map((prod, i) => + i === idx ? updatedWithForecast : prod ); onProductsChange(finalUpdatedProducts); @@ -1163,7 +1197,7 @@ const handleProductSelect = async (productId, establishmentId, id) => {
{ @@ -1173,10 +1207,18 @@ const handleProductSelect = async (productId, establishmentId, id) => { delete newErrors[`unit_${idx}`]; setFormErrors(newErrors); } + // Find the selected unit to get its name + const selectedUnit = unitOptions.find(unit => unit.value === e.target.value); updateProductField(p.id, 'unit', e.target.value, unitOptions); + // Also update unit name if a valid unit is selected + if (selectedUnit) { + updateProductField(p.id, 'unitName', selectedUnit.label || selectedUnit.name); + updateProductField(p.id, 'unit_id', selectedUnit.id || e.target.value); + } }} loading={isLoadingUnits} error={!!formErrors[`unit_${idx}`]} + isDisabled={!!p.unitName} // Disable if unit is auto-filled from product />
{formErrors[`unit_${idx}`] && ( diff --git a/ipi-survey-platform/src/components/survey/ReviewSubmit/ReviewSubmit.jsx b/ipi-survey-platform/src/components/survey/ReviewSubmit/ReviewSubmit.jsx index acb9d69..3790504 100644 --- a/ipi-survey-platform/src/components/survey/ReviewSubmit/ReviewSubmit.jsx +++ b/ipi-survey-platform/src/components/survey/ReviewSubmit/ReviewSubmit.jsx @@ -170,12 +170,17 @@ const buildProductRows = (products = [], options = {}) => { } try { - // Find the full product details from productOptions if available - const fullProduct = productOptions.find(p => p.id === product.productId || p.value === product.productId); - // Extract product details with better fallbacks + // Find the full product details from originalData or product + const originalData = product.originalData || {}; const productId = product.id || `product-${Math.random().toString(36).substr(2, 9)}`; - const productName = fullProduct?.label || fullProduct?.name || product.productName || product.product?.name || product.product; - const productCode = fullProduct?.code || product.productCode || product.code || product.product?.code || product.id || `CODE-${index + 1}`; + + // Get HS Code and Product Name from original data or product + const hsCode = originalData['product.hs_code'] || product.hs_code || ''; + const productName = originalData['product.product_name'] || product.product_name || product.productName || product.product?.name || product.product; + + // Format the display name as "HS Code - Product Name" if HS code exists + const displayName = hsCode ? `${hsCode} - ${productName}` : productName; + const productCode = hsCode || product.id || `CODE-${index + 1}`; console.log("productCode",productCode) // Use stored unitName if available, otherwise try to find it in unitOptions let unitName = product.unitName; @@ -193,8 +198,10 @@ const buildProductRows = (products = [], options = {}) => { // Map the quantity and cost data from the product form const row = { id: productId, - product: productName, + product: displayName, productCode: productCode, + hsCode: hsCode, + productName: productName, unit: unitName, // Use display name instead of ID capacity: capacity, @@ -260,8 +267,20 @@ const formatSubmissionData = (establishment, products, remarks = '') => { const totalEmployees = totalEmirati + nonEmiratiMale + nonEmiratiFemale; // Format products data - const formattedProducts = products.map(product => ({ - product_id: parseInt(product.productId) || 0, + console.log('Original products data:', JSON.stringify(products, null, 2)); + const formattedProducts = products.map(product => { + // Get the actual product_id from the originalData if available + const originalData = product.originalData || {}; + console.log('Original data for product:', JSON.stringify(originalData, null, 2)); + + // Get the product_id directly from the originalData object + // originalData has both id (establishment product ID) and product_id (actual product ID) + const productId = originalData.product_id || originalData.id; // Use product_id (56) with fallback to id + + console.log('Selected product ID:', productId); + + return { + product_id: parseInt(productId) || 0, unit_id: parseInt(product.unit) || 0, annual_installed_capacity: product.capacity?.toString() || '', @@ -301,9 +320,10 @@ const formatSubmissionData = (establishment, products, 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 || '' - })); + other_zero_target_reason: product.otherZeroTargetReason?.toString() || '', + remarks: product.remarks || remarks || '' + }; + }); return { establishment_id: parseInt(establishment.id) || 0, @@ -788,11 +808,10 @@ const ReviewSubmit = ({
-
{product.variationReasonName || product.variationReason || '—'}
- {product.otherVariationReason && ( -
- {product.otherVariationReason} -
+ {product.otherVariationReason ? ( +
{product.otherVariationReason}
+ ) : ( +
{product.variationReasonName?.replace('Others: ', '') || product.variationReason?.replace('Others: ', '') || '—'}
)}
@@ -811,11 +830,10 @@ const ReviewSubmit = ({
-
{product.zeroTargetReasonName || product.zeroTargetReason || '—'}
- {product.otherZeroTargetReason && ( -
- {product.otherZeroTargetReason} -
+ {product.otherZeroTargetReason ? ( +
{product.otherZeroTargetReason}
+ ) : ( +
{product.zeroTargetReasonName?.replace('Others: ', '') || product.zeroTargetReason?.replace('Others: ', '') || '—'}
)}
diff --git a/ipi-survey-platform/src/pages/Overview/Overview.jsx b/ipi-survey-platform/src/pages/Overview/Overview.jsx index ed72c07..3f2ee89 100644 --- a/ipi-survey-platform/src/pages/Overview/Overview.jsx +++ b/ipi-survey-platform/src/pages/Overview/Overview.jsx @@ -81,7 +81,8 @@ const Overview = () => { !selectedStatus || (selectedStatus === 'approved' && record.status === 'Approved') || (selectedStatus === 'submitted' && record.status === 'Submitted') || - (selectedStatus === 'rejected' && record.status === 'Rejected'); + (selectedStatus === 'rejected' && record.status === 'Rejected') || + (selectedStatus === 'resubmitted' && record.status === 'Resubmitted'); return matchesSearch && matchesStatus; }); @@ -185,6 +186,7 @@ const Overview = () => { + { // Map monthly data to period-specific fields return { ...(isResubmitFlow && productId ? { id: productId } : {}), // Only include ID during resubmit - product_id: parseNumber(product.productId) || parseNumber(product.product), + product_id: parseNumber(product.originalData?.product_id) || parseNumber(product.product_id) || parseNumber(product.productId) || parseNumber(product.product), unit_id: parseNumber(product.unitId) || parseNumber(product.unit), annual_installed_capacity: stringify(product.capacity), diff --git a/ipi-survey-platform/src/services/submissions/submissionService.js b/ipi-survey-platform/src/services/submissions/submissionService.js index 1957287..7f2a1a8 100644 --- a/ipi-survey-platform/src/services/submissions/submissionService.js +++ b/ipi-survey-platform/src/services/submissions/submissionService.js @@ -3,6 +3,7 @@ import resolveEstablishmentId from '@/services/utils/establishment'; import { putRequest } from '../api/CommonService'; const endpoint = '/submissions'; +const ESTABLISHMENT_PRODUCTS_ENDPOINT = '/establishment-products'; const QUARTER_PERIODS_ENDPOINT = '/getQuarterPeriods'; // Add this new function to fetch submissions with pagination @@ -141,6 +142,25 @@ export const getSubmissionAuditHistory = async (establishmentId, params = {}) => } }; +export const getEstablishmentProducts = async (establishmentId, config = {}) => { + try { + if (!establishmentId) { + throw new Error('Establishment ID is required to fetch establishment products'); + } + const response = await getRequest(ESTABLISHMENT_PRODUCTS_ENDPOINT, { + ...config, + params: { + establishment_id: establishmentId, + ...(config.params || {}) + } + }); + return response.data; + } catch (error) { + console.error('Error fetching establishment products:', error); + throw error; + } +}; + export default { getSubmissions, submitSurvey, @@ -150,5 +170,6 @@ export default { getQuarterPeriods, getPreviousForecastData, getSubmissionHistoryByEstablishment, - getSubmissionAuditHistory + getSubmissionAuditHistory, + getEstablishmentProducts }; \ No newline at end of file