diff --git a/ipi-survey-platform/src/components/survey/ProductData/ProductData.jsx b/ipi-survey-platform/src/components/survey/ProductData/ProductData.jsx index 10407cb..e42dcf5 100644 --- a/ipi-survey-platform/src/components/survey/ProductData/ProductData.jsx +++ b/ipi-survey-platform/src/components/survey/ProductData/ProductData.jsx @@ -1899,7 +1899,7 @@ useEffect(() => {
Product (HS Code – Name): Standard trade classification. Start typing to search by code or name.
Quantity (Qty): Physical output produced in the month, measured in the selected unit.
-Value (AED ): Total production value for that month for a single product, excluding VAT/ duties. sales value for that product - VAT.
Value (AED ): The net monthly sales value of a single product excluding VAT and any applicable duties. Do not include sales margins.
Formula: Sales Value − (VAT, Duties, etc)
Annual Installed Capacity: Maximum achievable annual output under normal operating conditions with existing equipment; do not include extraordinary overtime.
)} diff --git a/ipi-survey-platform/src/pages/Admin/configuration/EditCompanyProfile.jsx b/ipi-survey-platform/src/pages/Admin/configuration/EditCompanyProfile.jsx index e8efec9..3c17736 100644 --- a/ipi-survey-platform/src/pages/Admin/configuration/EditCompanyProfile.jsx +++ b/ipi-survey-platform/src/pages/Admin/configuration/EditCompanyProfile.jsx @@ -1,7 +1,8 @@ import React, { useState, useMemo, useCallback, useEffect, useRef } from "react"; import { useNavigate, useParams, useSearchParams } from 'react-router-dom'; import { FaBuilding } from 'react-icons/fa6'; -import { MdAdminPanelSettings } from "react-icons/md"; +import { MdAdminPanelSettings, MdOutlineCheckBoxOutlineBlank } from "react-icons/md"; +import { IoMdCheckbox, IoMdCheckboxOutline } from "react-icons/io"; import { TextField, SelectField, PhoneField } from "@/components/common/FormControls"; import Loader from "@/components/common/Loader"; import { fetchEstablishmentDetail, updateEstablishment } from '@/services/establishments/establishmentService'; @@ -101,6 +102,7 @@ const EditCompanyProfile = () => { const [isLoadingCities, setIsLoadingCities] = useState(false); const [visibleProductCount, setVisibleProductCount] = useState(14); const [isLoadingMore, setIsLoadingMore] = useState(false); + const [checkedProducts, setCheckedProducts] = useState(new Set()); const initialSnapshotRef = useRef(null); const productListRef = useRef(null); @@ -312,7 +314,91 @@ const EditCompanyProfile = () => { setAvailableProducts(filtered); }; - + + // Handle checkbox toggle for selected products + const handleCheckboxToggle = (productValue) => { + setCheckedProducts(prev => { + const newChecked = new Set(prev); + const product = selectedProducts.find(p => + (p.value && (p.value === productValue || p.value === productValue || p.value === productValue)) || + (p.id && (p.id === productValue || p.id === productValue || p.id === productValue)) || + (p.product_id && (p.product_id === productValue || p.product_id === productValue || p.product_id === productValue)) + ); + + if (newChecked.has(productValue)) { + // Unchecking: move product from selected to available + newChecked.delete(productValue); + + if (product) { + // Add product back to available products + setAvailableProducts(prev => { + const alreadyExists = prev.some(p => + (p.value && (p.value === product.value || p.value === product.id || p.value === product.product_id)) || + (p.id && (p.id === product.id || p.id === product.value || p.id === product.product_id)) || + (p.product_id && (p.product_id === product.product_id || p.product_id === product.id || p.product_id === product.value)) + ); + + if (!alreadyExists) { + return [...prev, product]; + } + return prev; + }); + } + } else { + // Re-checking: remove newly added products and restore original + newChecked.add(productValue); + + // Remove from available products + setAvailableProducts(prev => + prev.filter(p => + !(p.value && (p.value === productValue || p.value === productValue || p.value === productValue)) && + !(p.id && (p.id === productValue || p.id === productValue || p.id === productValue)) && + !(p.product_id && (p.product_id === productValue || p.product_id === productValue || p.product_id === productValue)) + ) + ); + + // If this is an original product being re-checked, remove newly added products + if (product && product.isExisting) { + // Find all newly added products (not original) + const newlyAddedProducts = selectedProducts.filter(p => + !p.isExisting && newlyAddedProductIds.has(p.value || p.id || p.product_id) + ); + + if (newlyAddedProducts.length > 0) { + // Remove newly added products from selected list + setSelectedProducts(prev => + prev.filter(p => + !(p.value && newlyAddedProducts.some(np => np.value === p.value || np.value === p.id || np.value === p.product_id)) && + !(p.id && newlyAddedProducts.some(np => np.id === p.id || np.id === p.value || np.id === p.product_id)) && + !(p.product_id && newlyAddedProducts.some(np => np.product_id === p.product_id || np.product_id === p.id || np.product_id === p.value)) + ) + ); + + // Add newly added products back to available products + setAvailableProducts(prev => { + const productsToAdd = newlyAddedProducts.filter(np => + !prev.some(p => + (p.value && (p.value === np.value || p.value === np.id || p.value === np.product_id)) || + (p.id && (p.id === np.id || p.id === np.value || p.id === np.product_id)) || + (p.product_id && (p.product_id === np.product_id || p.product_id === np.id || p.product_id === np.value)) + ) + ); + return [...prev, ...productsToAdd]; + }); + + // Clear newly added product IDs + setNewlyAddedProductIds(new Set()); + + // Show alert to user + alert('Original product restored. Replacement products have been removed.'); + } + } + } + + return newChecked; + }); + }; + // Handle adding a product const handleAddProduct = (product) => { setSelectedProducts(prev => { @@ -327,6 +413,15 @@ const EditCompanyProfile = () => { return prev; // Don't add duplicate } + // Count current newly added products (excluding original products) + const currentNewlyAdded = prev.filter(p => newlyAddedProductIds.has(p.value || p.id || p.product_id)); + + // Allow up to 4 newly added products + if (currentNewlyAdded.length >= 4) { + alert('Maximum of 4 replacement products can be added.'); + return prev; + } + return [...prev, product]; }); @@ -343,18 +438,17 @@ const EditCompanyProfile = () => { setNewlyAddedProductIds(prev => new Set([...prev, product.value || product.id || product.product_id]) ); + + // Set newly added product as checked by default + setCheckedProducts(prev => + new Set([...prev, product.value || product.id || product.product_id]) + ); }; // Remove product handler const handleRemoveProduct = (product) => { - // First, add the removed product back to available products if it matches the search - const searchTerm = productSearchTerm.toLowerCase(); - const shouldAddToAvailable = - !productSearchTerm || - (product.label?.toLowerCase().includes(searchTerm) || - product.hs_code?.toLowerCase().includes(searchTerm) || - (product.product_name && product.product_name.toLowerCase().includes(searchTerm))); - + const productId = product.value || product.id || product.product_id; + // Remove from selected products setSelectedProducts(prev => prev.filter(p => @@ -364,31 +458,34 @@ const EditCompanyProfile = () => { ) ); - // Add back to available products if it matches the current search - if (shouldAddToAvailable) { - setAvailableProducts(prev => { - // Check if already in available products - const alreadyExists = prev.some(p => - (p.value && (p.value === product.value || p.value === product.id || p.value === product.product_id)) || + // Remove from checked products + setCheckedProducts(prev => { + const newChecked = new Set(prev); + newChecked.delete(productId); + return newChecked; + }); + + // Remove from newly added product IDs if it's a newly added product + setNewlyAddedProductIds(prev => { + const newIds = new Set(prev); + newIds.delete(productId); + return newIds; + }); + + // Always add back to available products + setAvailableProducts(prev => { + // Check if already in available products + const alreadyExists = prev.some(p => + (p.value && (p.value === product.value || p.value === product.id || p.value === product.product_id)) || (p.id && (p.id === product.id || p.id === product.value || p.id === product.product_id)) || (p.product_id && (p.product_id === product.product_id || p.product_id === product.id || p.product_id === product.value)) - ); - - if (!alreadyExists) { - // Get all products (including the one being removed) - const allProducts = [...prev, ...selectedProducts]; - const uniqueProducts = allProducts.filter((p, index, self) => - index === self.findIndex(t => - (t.value && (t.value === p.value || t.value === p.id || t.value === p.product_id)) || - (t.id && (t.id === p.id || t.id === p.value || t.id === p.product_id)) || - (t.product_id && (t.product_id === p.product_id || t.product_id === p.id || t.product_id === p.value)) - ) - ); - return uniqueProducts; - } - return prev; - }); - } + ); + + if (!alreadyExists) { + return [...prev, product]; + } + return prev; + }); }; // Reset visible count when products change or search is performed @@ -508,6 +605,8 @@ const EditCompanyProfile = () => { setSelectedProducts(formattedSelectedProducts); // Initialize newly added products as empty since we're loading existing data setNewlyAddedProductIds(new Set()); + // Initialize all selected products as checked by default + setCheckedProducts(new Set(formattedSelectedProducts.map(p => p.value || p.id || p.product_id))); // Now load available products with selected ones filtered out const filteredAvailable = allProducts.filter(product => { @@ -625,11 +724,12 @@ const EditCompanyProfile = () => { (Number(form.employmentNonEmiratiFemale) || 0), updated_by: 1, establishment_products: Array.isArray(selectedProducts) && selectedProducts.length > 0 - ? selectedProducts.map(p => ({ + ? selectedProducts + .filter(p => checkedProducts.has(p.value || p.id || p.product_id)) + .map(p => ({ product_id: Number(p.value) || 0, action_done_by: p.action_done_by || "establishment_users", created_by: p.created_by || establishmentId - })) : [], }; @@ -710,6 +810,7 @@ const EditCompanyProfile = () => { error={fieldErrors.permanentFactoryCode} /> */} {/*