diff --git a/app/src/components/layout/sidebarRight/analysis/Analysis.tsx b/app/src/components/layout/sidebarRight/analysis/Analysis.tsx index b314f19..6da2f8b 100644 --- a/app/src/components/layout/sidebarRight/analysis/Analysis.tsx +++ b/app/src/components/layout/sidebarRight/analysis/Analysis.tsx @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import { AIIcon } from "../../../icons/ExportCommonIcons"; import RegularDropDown from "../../../ui/inputs/RegularDropDown"; import { AnalysisPresetsType } from "../../../../types/analysis"; @@ -19,55 +19,66 @@ const Analysis: React.FC = () => { // { type: "default", inputs: { label: "Machine uptime", activeOption: "%" } }, ], "Production capacity": [ - { type: "range", inputs: { label: "Shift length", activeOption: "hr" } }, - { type: "default", inputs: { label: "Shifts / day", activeOption: "unit" } }, - { type: "default", inputs: { label: "Working days / year", activeOption: "days" } }, - { type: "default", inputs: { label: "Yield rate", activeOption: "%" } }, + { type: "range", inputs: { label: "Shift length", activeOption: "hr", defaultValue: 8 } }, + { type: "default", inputs: { label: "Shifts / day", activeOption: "unit", defaultValue: 2 } }, + { type: "default", inputs: { label: "Working days / year", activeOption: "days", defaultValue: 300 } }, + { type: "default", inputs: { label: "Yield rate", activeOption: "%", defaultValue: 90 } }, ], ROI: [ { type: "default", - inputs: { label: "Selling price", activeOption: "INR" }, + inputs: { label: "Selling price", activeOption: "INR", defaultValue: 1500 }, }, { type: "default", - inputs: { label: "Material cost", activeOption: "INR" }, + inputs: { label: "Material cost", activeOption: "INR", defaultValue: 300 }, }, { type: "default", - inputs: { label: "Labor Cost", activeOption: "INR" }, + inputs: { label: "Labor Cost", activeOption: "INR", defaultValue: 200 }, }, { type: "default", - inputs: { label: "Maintenance cost", activeOption: "INR" }, + inputs: { label: "Maintenance cost", activeOption: "INR", defaultValue: 1200 }, }, { type: "default", - inputs: { label: "Electricity cost", activeOption: "INR" }, + inputs: { label: "Electricity cost", activeOption: "INR", defaultValue: 1000 }, }, { type: "default", - inputs: { label: "Fixed costs", activeOption: "INR" }, + inputs: { label: "Fixed costs", activeOption: "INR", defaultValue: 5000 }, }, { type: "default", - inputs: { label: "Initial Investment", activeOption: "INR" }, + inputs: { label: "Initial Investment", activeOption: "INR", defaultValue: 100000 }, }, { type: "default", - inputs: { label: "Salvage value", activeOption: "Hrs" }, + inputs: { label: "Salvage value", activeOption: "Hrs", defaultValue: 5000 }, }, { type: "default", - inputs: { label: "Production period", activeOption: "yrs" }, + inputs: { label: "Production period", activeOption: "yrs", defaultValue: 5 }, }, { type: "default", - inputs: { label: "Tax rate", activeOption: "%" }, + inputs: { label: "Tax rate", activeOption: "%", defaultValue: 30 }, }, ], }; + useEffect(() => { + Object.values(AnalysisPresets).forEach((category) => { + category.forEach((item) => { + const { label, defaultValue } = item.inputs; + if (defaultValue !== undefined) { + updateInputValue(label, defaultValue.toString()); + } + }); + }); + }, []); + const { inputValues, setInputValues, updateInputValue } = useInputValues(); return ( diff --git a/app/src/components/layout/sidebarRight/analysis/RenderAnalysisInputs.tsx b/app/src/components/layout/sidebarRight/analysis/RenderAnalysisInputs.tsx index 6f52438..30df2c5 100644 --- a/app/src/components/layout/sidebarRight/analysis/RenderAnalysisInputs.tsx +++ b/app/src/components/layout/sidebarRight/analysis/RenderAnalysisInputs.tsx @@ -10,7 +10,8 @@ interface InputRendererProps { onInputChange: (label: string, value: string) => void; } -const RenderAnalysisInputs: React.FC = ({ keyName, presets,inputValues, onInputChange }) => { +const RenderAnalysisInputs: React.FC = ({ keyName, presets, inputValues, onInputChange }) => { + return (
{presets.map((preset, index) => { @@ -19,7 +20,7 @@ const RenderAnalysisInputs: React.FC = ({ keyName, presets,i onInputChange(preset.inputs.label, newValue)} /> @@ -32,7 +33,7 @@ const RenderAnalysisInputs: React.FC = ({ keyName, presets,i label={preset.inputs.label} min={0} max={8} - value={5} + value={Number(preset.inputs.defaultValue) || Number(inputValues[preset.inputs.label]) || 5} /> ); } diff --git a/app/src/components/ui/analysis/ThroughputSummary.tsx b/app/src/components/ui/analysis/ThroughputSummary.tsx index 0568b5d..22cb95a 100644 --- a/app/src/components/ui/analysis/ThroughputSummary.tsx +++ b/app/src/components/ui/analysis/ThroughputSummary.tsx @@ -26,6 +26,7 @@ const ProductionCapacity = ({ const [isLoading, setIsLoading] = useState(true); useEffect(() => { + console.log('throughputData: ', throughputData); if (throughputData > 0) { setIsLoading(false); } else { diff --git a/app/src/components/ui/list/List.tsx b/app/src/components/ui/list/List.tsx index 22653ff..08cf504 100644 --- a/app/src/components/ui/list/List.tsx +++ b/app/src/components/ui/list/List.tsx @@ -122,7 +122,7 @@ const List: React.FC = ({ items = [], remove }) => { zoneUuid: selectedZone.zoneUuid, zoneName: newName, }; - const response = await zoneCameraUpdate(zonesdata, organization,projectId); + const response = await zoneCameraUpdate(zonesdata, organization, projectId); if (response.message === "zone updated") { setSelectedZone((prev) => ({ ...prev, zoneName: newName })); setZones((prevZones: any[]) => @@ -143,9 +143,10 @@ const List: React.FC = ({ items = [], remove }) => { let response = await setFloorItemApi( organization, zoneAssetId.id, - newName + newName, + projectId ); - // console.log("response: ", response); + console.log("response: ", response); setName(zoneAssetId.id, response.modelName); } diff --git a/app/src/modules/simulation/analysis/ROI/roiData.tsx b/app/src/modules/simulation/analysis/ROI/roiData.tsx index 6551d54..59bf784 100644 --- a/app/src/modules/simulation/analysis/ROI/roiData.tsx +++ b/app/src/modules/simulation/analysis/ROI/roiData.tsx @@ -16,6 +16,7 @@ export default function ROIData() { useEffect(() => { if (!isPlaying) { + console.log("running ROIData effect"); setRoiSummaryData({ productName: "", roiPercentage: 0, @@ -25,11 +26,10 @@ export default function ROIData() { netProfit: 0, netLoss: 0, }) + return; } - if (inputValues === undefined) return; - const electricityCost = parseFloat(inputValues["Electricity cost"]); const fixedCost = parseFloat(inputValues["Fixed costs"]); const laborCost = parseFloat(inputValues["Labor Cost"]); @@ -60,23 +60,14 @@ export default function ROIData() { const totalAnnualCost = totalMaterialCost + totalLaborCost + totalEnergyCost + totalMaintenanceCost; // Annual Profit const annualProfit = annualRevenue - totalAnnualCost; - + // Net Profit over production period const netProfit = annualProfit * productionPeriod; // ROI const roiPercentage = ((netProfit + salvageValue - initialInvestment) / initialInvestment) * 100; // Payback Period const paybackPeriod = initialInvestment / (annualProfit || 1); // Avoid division by 0 - - // - // - // - // - // - // - // - // setRoiSummaryData({ productName: selectedProduct.productName, @@ -99,17 +90,9 @@ export default function ROIData() { const netProfitForTarget = profitForTargetUnits > 0 ? profitForTargetUnits : 0; const netLossForTarget = profitForTargetUnits < 0 ? -profitForTargetUnits : 0; - - // - // - // - // - // - // - const productData = getProductById(selectedProduct.productUuid); - - + + setCompareProducts(prev => { const newData = { productUuid: productData?.productUuid, @@ -140,11 +123,30 @@ export default function ROIData() { return [...prev, newData]; } }); - // console.log('compareProducts: ', compareProducts); - + + } - }, [inputValues, productionCapacityData]); + }, [inputValues, productionCapacityData, selectedProduct?.productUuid]); + useEffect(() => { + + console.log('compareProducts: ', compareProducts); + }, [compareProducts]); + useEffect(() => { + // Clear ROI summary data when product changes + setRoiSummaryData({ + productName: "", + roiPercentage: 0, + paybackPeriod: 0, + totalCost: 0, + revenueGenerated: 0, + netProfit: 0, + netLoss: 0, + }); + + // Optionally clear comparison data for this product only + setCompareProducts(prev => prev.filter(p => p.productUuid !== selectedProduct.productUuid)); + }, [selectedProduct?.productUuid]); return ( <> diff --git a/app/src/modules/simulation/analysis/productionCapacity/productionCapacityData.tsx b/app/src/modules/simulation/analysis/productionCapacity/productionCapacityData.tsx index 5c376a7..a9966ef 100644 --- a/app/src/modules/simulation/analysis/productionCapacity/productionCapacityData.tsx +++ b/app/src/modules/simulation/analysis/productionCapacity/productionCapacityData.tsx @@ -1,12 +1,15 @@ import React, { useEffect } from 'react' import { useInputValues, useProductionCapacityData, useThroughPutData } from '../../../../store/builder/store' import { usePlayButtonStore } from '../../../../store/usePlayButtonStore'; +import { useProductContext } from '../../products/productContext'; export default function ProductionCapacityData() { const { throughputData } = useThroughPutData() const { productionCapacityData, setProductionCapacityData } = useProductionCapacityData() const { inputValues } = useInputValues(); const { isPlaying } = usePlayButtonStore(); + const { selectedProductStore } = useProductContext(); + const { selectedProduct } = selectedProductStore(); useEffect(() => { if (!isPlaying) { @@ -16,32 +19,42 @@ export default function ProductionCapacityData() { if (!inputValues || throughputData === undefined) return; const shiftLength = parseFloat(inputValues["Shift length"]); + console.log('shiftLength: ', shiftLength); + const shiftsPerDay = parseFloat(inputValues["Shifts / day"]); + const workingDaysPerYear = parseFloat(inputValues["Working days / year"]); + const yieldRate = parseFloat(inputValues["Yield rate"]); + if (!isNaN(shiftLength) && !isNaN(shiftsPerDay) && !isNaN(workingDaysPerYear) && - !isNaN(yieldRate) && throughputData >= 0) { + !isNaN(yieldRate) && throughputData > 0) { // Total units produced per day before yield const dailyProduction = throughputData * shiftLength * shiftsPerDay; - + // Units after applying yield rate const goodUnitsPerDay = dailyProduction * (yieldRate / 100); - + // Annual output const annualProduction = goodUnitsPerDay * workingDaysPerYear; - + // Final production capacity per hour (after yield) const productionPerHour = throughputData * (yieldRate / 100); - + // Set the final capacity (units/hour) setProductionCapacityData(Number(productionPerHour.toFixed(2))); } }, [throughputData, inputValues]); + useEffect(() => { + + setProductionCapacityData(0); + + }, [selectedProduct?.productUuid]); return ( <> diff --git a/app/src/modules/simulation/analysis/throughPut/throughPutData.tsx b/app/src/modules/simulation/analysis/throughPut/throughPutData.tsx index 78bd1a7..fa43e0b 100644 --- a/app/src/modules/simulation/analysis/throughPut/throughPutData.tsx +++ b/app/src/modules/simulation/analysis/throughPut/throughPutData.tsx @@ -36,7 +36,7 @@ export default function ThroughPutData() { setMaterialCycleTime(0); setProcessBar([]); setThroughputData(0); - return; + return; } else { let process: any = []; const fetchProductSequenceData = async () => { @@ -83,7 +83,7 @@ export default function ThroughPutData() { .forEach(storage => { if (storage.activeTime > 0) { // totalActiveTime += storage.activeTime; -// + // } }); } @@ -92,7 +92,7 @@ export default function ThroughPutData() { totalItems += sequence.length; }); - + setMachineCount(totalItems); setMachineActiveTime(totalActiveTime); let arr = process.map((item: any) => ({ @@ -107,15 +107,15 @@ export default function ThroughPutData() { fetchProductSequenceData(); } // if (materialCycleTime <= 0) return - }, [products, selectedProduct, getProductById, setMachineCount, materialCycleTime, armBots, vehicles, machines]); + }, [products, selectedProduct?.productUuid, getProductById, setMachineCount, materialCycleTime, armBots, vehicles, machines]); useEffect(() => { + let timeoutId: ReturnType; async function getMachineActive() { const productData = getProductById(selectedProduct.productUuid); let anyArmActive; let anyVehicleActive; let anyMachineActive; - if (productData) { const productSequenceData = await determineExecutionMachineSequences([productData]); if (productSequenceData?.length > 0) { @@ -161,7 +161,7 @@ export default function ThroughPutData() { const allInactive = !anyArmActive && !anyVehicleActive && !anyMachineActive; if (allInactive && materials.length === 0 && materialHistory.length > 0) { - + let totalCycleTimeSum = 0; let cycleCount = 0; @@ -182,11 +182,15 @@ export default function ThroughPutData() { } } if (isPlaying) { - setTimeout(() => { + timeoutId = setTimeout(() => { getMachineActive(); - }, 500) + }, 1500); } - }, [armBots, materials, materialHistory, machines, vehicles, selectedProduct]) + + return () => { + if (timeoutId) clearTimeout(timeoutId); + }; + }, [armBots, materials, materialHistory, machines, vehicles, selectedProduct?.productUuid]) useEffect(() => { if (machineActiveTime > 0 && materialCycleTime > 0 && machineCount > 0) { @@ -196,7 +200,16 @@ export default function ThroughPutData() { setThroughputData(Number(throughput.toFixed(2))); // Keep as number // } - }, [machineActiveTime, materialCycleTime, machineCount]); + }, [machineActiveTime, materialCycleTime, machineCount, selectedProduct?.productUuid]); + useEffect(() => { + totalActiveTime = 0; + totalItems = 0; + setMachineCount(0); + setMachineActiveTime(0); + setMaterialCycleTime(0); + setProcessBar([]); + setThroughputData(0); + }, [selectedProduct?.productUuid]); return ( <> diff --git a/app/src/services/factoryBuilder/assest/floorAsset/setFloorItemApi.ts b/app/src/services/factoryBuilder/assest/floorAsset/setFloorItemApi.ts index d9e67e9..aa745ae 100644 --- a/app/src/services/factoryBuilder/assest/floorAsset/setFloorItemApi.ts +++ b/app/src/services/factoryBuilder/assest/floorAsset/setFloorItemApi.ts @@ -3,24 +3,25 @@ export const setFloorItemApi = async ( organization: string, modelUuid?: string, modelName?: string, + projectId?: string, modelfileID?: string, position?: Object, rotation?: Object, isLocked?: boolean, - isVisible?: boolean + isVisible?: boolean, ) => { try { const body: any = { organization, modelUuid, modelName, + projectId, position, rotation, modelfileID, isLocked, isVisible, }; - const response = await fetch(`${url_Backend_dwinzo}/api/V1/setAsset`, { method: "POST", headers: { diff --git a/app/src/store/simulation/useMaterialStore.ts b/app/src/store/simulation/useMaterialStore.ts index 123ebb0..a500d9a 100644 --- a/app/src/store/simulation/useMaterialStore.ts +++ b/app/src/store/simulation/useMaterialStore.ts @@ -88,6 +88,7 @@ export const createMaterialStore = () => { clearMaterials: () => { set((state) => { state.materials = []; + state.materialHistory = []; }); }, diff --git a/app/src/types/analysis.d.ts b/app/src/types/analysis.d.ts index 151afb4..41f9f81 100644 --- a/app/src/types/analysis.d.ts +++ b/app/src/types/analysis.d.ts @@ -5,6 +5,7 @@ type Preset = { activeOption: string; min?: number; max?: number; + defaultValue?: string | number; }; };