/** * Machine detail page — update/mutation methods. * * Extracted from useMachineDetailData.ts to keep the orchestrator under 500 lines. */ import type { Ref } from 'vue' import { uniqueConstructeurIds, constructeurIdsFromLinks } from '~/shared/constructeurUtils' import type { ConstructeurLinkEntry } from '~/shared/constructeurUtils' type AnyRecord = Record export interface UseMachineDetailUpdatesDeps { machine: Ref machineName: Ref machineReference: Ref machineSiteId: Ref machineConstructeurIds: Ref constructeurLinks: Ref originalConstructeurLinks: Ref machineDocumentsLoaded: Ref machineComponentLinks: Ref machinePieceLinks: Ref machineProductLinks: Ref applyMachineLinks: (data: AnyRecord) => boolean refreshMachineDocuments: () => Promise transformComponentCustomFields: (items: AnyRecord[]) => AnyRecord[] transformCustomFields: (items: AnyRecord[]) => AnyRecord[] loadProductDocuments: () => Promise upsertCustomFieldValue: ( fieldId: string, entityType: string, entityId: string, value: unknown, ) => Promise updateMachineApi: (id: string, data: any) => Promise updateComposantApi: (id: string, data: any) => Promise updatePieceApi: (id: string, data: any) => Promise apiPatch: (endpoint: string, data?: unknown) => Promise toast: { showInfo: (msg: string) => void } syncLinks: ( entityType: 'machine' | 'piece' | 'composant' | 'product', entityId: string, originalLinks: ConstructeurLinkEntry[], formLinks: ConstructeurLinkEntry[], ) => Promise } export function useMachineDetailUpdates(deps: UseMachineDetailUpdatesDeps) { const { machine, machineName, machineReference, machineSiteId, machineConstructeurIds, constructeurLinks, originalConstructeurLinks, machineComponentLinks, machinePieceLinks, applyMachineLinks, loadProductDocuments, transformComponentCustomFields, transformCustomFields, upsertCustomFieldValue, updateMachineApi, updateComposantApi, updatePieceApi, apiPatch, toast, syncLinks, } = deps const updateMachineInfo = async () => { if (!machine.value) return try { const payload: Record = {} if (machineName.value !== machine.value.name) payload.name = machineName.value if (machineReference.value !== machine.value.reference) payload.reference = machineReference.value if ((machineSiteId.value || undefined) !== ((machine.value.siteId as string) || (machine.value.site as any)?.id || undefined)) payload.siteId = machineSiteId.value || undefined const result: any = await updateMachineApi(machine.value.id as string, payload as any) if (result.success) { const machinePayload = result.data?.machine && typeof result.data.machine === 'object' ? result.data.machine : result.data if (machinePayload && typeof machinePayload === 'object') { machine.value = { ...machine.value, ...machinePayload, documents: machinePayload.documents || machine.value.documents || [], customFieldValues: machinePayload.customFieldValues || machine.value.customFieldValues || [], } const linksApplied = applyMachineLinks(result.data) if (linksApplied && machine.value) { machine.value.componentLinks = machineComponentLinks.value machine.value.pieceLinks = machinePieceLinks.value } loadProductDocuments().catch(() => {}) } } // Sync constructeur links after entity save await syncLinks('machine', machine.value!.id as string, originalConstructeurLinks.value, constructeurLinks.value) originalConstructeurLinks.value = constructeurLinks.value.map(l => ({ ...l })) } catch (error) { console.error('Erreur lors de la mise à jour de la machine:', error) } } const updateComponent = async (updatedComponent: AnyRecord) => { try { const cIds = uniqueConstructeurIds( updatedComponent.constructeurIds, updatedComponent.constructeurId, updatedComponent.constructeur, ) const productId = updatedComponent.productId ? String(updatedComponent.productId) : null const prixStr = updatedComponent.prix !== null && updatedComponent.prix !== undefined && String(updatedComponent.prix).trim() !== '' ? String(updatedComponent.prix) : null const result: any = await updateComposantApi(updatedComponent.id as string, { name: updatedComponent.name, reference: updatedComponent.reference, constructeurIds: cIds, prix: prixStr, productId, } as any) if (result.success) { const transformed = transformComponentCustomFields([result.data])[0] Object.assign(updatedComponent, transformed) } } catch (error) { console.error('Erreur lors de la mise à jour du composant:', error) } } const _buildAndUpdatePiece = async (updatedPiece: AnyRecord) => { const cIds = uniqueConstructeurIds( updatedPiece.constructeurIds, updatedPiece.constructeurId, updatedPiece.constructeur, ) const productId = updatedPiece.productId ? String(updatedPiece.productId) : null const prixStr = updatedPiece.prix !== null && updatedPiece.prix !== undefined && String(updatedPiece.prix).trim() !== '' ? String(updatedPiece.prix) : null const result: any = await updatePieceApi(updatedPiece.id as string, { name: updatedPiece.name, reference: updatedPiece.reference || null, constructeurIds: cIds, prix: prixStr, productId, } as any) if (result.success) { const transformed = transformCustomFields([result.data])[0] Object.assign(updatedPiece, transformed) } return result } const updatePieceFromComponent = async (updatedPiece: AnyRecord) => { try { const result = await _buildAndUpdatePiece(updatedPiece) if (result?.success && updatedPiece.customFields) { const fieldsToSave = (updatedPiece.customFields as AnyRecord[]).filter( (field) => field.value !== undefined, ) if (fieldsToSave.length) { await Promise.allSettled( fieldsToSave.map((field) => upsertCustomFieldValue( field.id as string, 'piece', updatedPiece.id as string, field.value, ), ), ) } } // Update slot quantity if this is a composant structure piece const slotId = updatedPiece.slotId as string | null const quantity = typeof updatedPiece.quantity === 'number' ? Math.max(1, updatedPiece.quantity) : null if (slotId && quantity !== null) { await apiPatch(`/composant-piece-slots/${slotId}`, { quantity }) } } catch (error) { console.error('Erreur lors de la mise à jour de la pièce:', error) } } const updatePieceInfo = async (updatedPiece: AnyRecord) => { try { await _buildAndUpdatePiece(updatedPiece) // Update link quantity if this is a direct machine piece const linkId = updatedPiece.linkId || updatedPiece.machinePieceLinkId const quantity = typeof updatedPiece.quantity === 'number' ? Math.max(1, updatedPiece.quantity) : null if (linkId && quantity !== null) { await apiPatch(`/machine_piece_links/${linkId}`, { quantity }) } } catch (error) { console.error('Erreur lors de la mise à jour de la pièce:', error) } } const handleMachineConstructeurChange = (value: unknown) => { const newIds = uniqueConstructeurIds(value) machineConstructeurIds.value = newIds // Sync constructeurLinks: keep existing entries, add new ones const existingMap = new Map(constructeurLinks.value.map(l => [l.constructeurId, l])) constructeurLinks.value = newIds.map(id => existingMap.get(id) ?? { constructeurId: id, supplierReference: null }, ) } const editComponent = () => { toast.showInfo('La modification des composants sera bientôt disponible') } const editPiece = () => { toast.showInfo('La modification des pièces sera bientôt disponible') } return { updateMachineInfo, updateComponent, updatePieceFromComponent, updatePieceInfo, handleMachineConstructeurChange, editComponent, editPiece, } }