@@ -341,6 +356,14 @@ const childComponents = computed(() => {
return Array.isArray(list) ? list : []
})
+// --- Pieces split: real links vs structure definitions ---
+const allPieces = computed(() => {
+ const list = props.component.pieces
+ return Array.isArray(list) ? list : []
+})
+const linkedPieces = computed(() => allPieces.value.filter((p) => !p._structurePiece))
+const structurePieces = computed(() => allPieces.value.filter((p) => p._structurePiece))
+
// --- Constructeurs ---
const { constructeurs } = useConstructeurs()
diff --git a/app/components/machine/MachinePiecesCard.vue b/app/components/machine/MachinePiecesCard.vue
index 2dbe97c..20d2c72 100644
--- a/app/components/machine/MachinePiecesCard.vue
+++ b/app/components/machine/MachinePiecesCard.vue
@@ -28,10 +28,11 @@
@@ -62,6 +63,7 @@ defineProps<{
defineEmits<{
'toggle-collapse': []
+ 'update-piece': [piece: any]
'edit-piece': [piece: any]
'add-piece': []
'remove-piece': [linkId: string]
diff --git a/app/composables/useEntityDocuments.ts b/app/composables/useEntityDocuments.ts
index 00d8064..91d2883 100644
--- a/app/composables/useEntityDocuments.ts
+++ b/app/composables/useEntityDocuments.ts
@@ -56,7 +56,7 @@ export function useEntityDocuments(deps: EntityDocumentsDeps) {
// CRUD operations
const refreshDocuments = async () => {
const e = entity()
- if (!e?.id) return
+ if (!e?.id || e._structurePiece) return
loadingDocuments.value = true
try {
const result: any = await loadDocumentsFn(e.id, { updateStore: false })
diff --git a/app/composables/useMachineDetailData.ts b/app/composables/useMachineDetailData.ts
index 13e102a..c8511ce 100644
--- a/app/composables/useMachineDetailData.ts
+++ b/app/composables/useMachineDetailData.ts
@@ -42,7 +42,7 @@ export function useMachineDetailData(machineId: string) {
const { componentTypes, loadComponentTypes } = useComponentTypes()
const { pieceTypes, loadPieceTypes } = usePieceTypes()
const { upsertCustomFieldValue } = useCustomFields()
- const { get } = useApi()
+ const { get, patch: apiPatch } = useApi()
const toast = useToast()
const { constructeurs, loadConstructeurs } = useConstructeurs()
const { sites, loadSites } = useSites()
@@ -274,6 +274,7 @@ export function useMachineDetailData(machineId: string) {
updateMachineApi,
updateComposantApi: updateComposantApi,
updatePieceApi,
+ apiPatch,
toast,
})
diff --git a/app/composables/useMachineDetailUpdates.ts b/app/composables/useMachineDetailUpdates.ts
index 3e0d657..3b779f4 100644
--- a/app/composables/useMachineDetailUpdates.ts
+++ b/app/composables/useMachineDetailUpdates.ts
@@ -33,6 +33,7 @@ export interface UseMachineDetailUpdatesDeps {
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 }
}
@@ -53,6 +54,7 @@ export function useMachineDetailUpdates(deps: UseMachineDetailUpdatesDeps) {
updateMachineApi,
updateComposantApi,
updatePieceApi,
+ apiPatch,
toast,
} = deps
@@ -147,7 +149,7 @@ export function useMachineDetailUpdates(deps: UseMachineDetailUpdatesDeps) {
const result: any = await updatePieceApi(updatedPiece.id as string, {
name: updatedPiece.name,
- reference: updatedPiece.reference,
+ reference: updatedPiece.reference || null,
constructeurIds: cIds,
prix: Number.isNaN(prix) ? null : prix,
productId,
@@ -187,6 +189,13 @@ export function useMachineDetailUpdates(deps: UseMachineDetailUpdatesDeps) {
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)
}
diff --git a/app/composables/useMachineHierarchy.ts b/app/composables/useMachineHierarchy.ts
index 6598a84..df7b28e 100644
--- a/app/composables/useMachineHierarchy.ts
+++ b/app/composables/useMachineHierarchy.ts
@@ -181,6 +181,7 @@ export const buildMachineHierarchyFromLinks = (
parentLinkId: resolveIdentifier(link.parentLinkId, link.parentMachinePieceLinkId, appliedPiece.parentLinkId),
parentPieceLinkId: resolveIdentifier(link.parentPieceLinkId, appliedPiece.parentPieceLinkId),
parentPieceId: resolveIdentifier(appliedPiece.parentPieceId, link.parentPieceId),
+ quantity: typeof link.quantity === 'number' ? link.quantity : 1,
definition: appliedPiece.definition || originalPiece?.definition || {},
customFields: appliedPiece.customFields || [],
}
@@ -214,10 +215,38 @@ export const buildMachineHierarchyFromLinks = (
const componentName = (compOverrides?.name || appliedComponent.name || (appliedComponent.definition as AnyRecord)?.alias || (appliedComponent.definition as AnyRecord)?.name || originalComponent?.name || 'Composant') as string
- const pieces = Array.isArray(link.pieceLinks)
+ const linkedPieces = Array.isArray(link.pieceLinks)
? (link.pieceLinks as AnyRecord[]).map((pl) => createPieceNode(pl, componentName)).filter(Boolean) as AnyRecord[]
: []
+ // If no linked pieces exist, build read-only entries from the composant's structure
+ const structurePieceDefs = (!linkedPieces.length && appliedComponent.structure && typeof appliedComponent.structure === 'object')
+ ? (Array.isArray((appliedComponent.structure as AnyRecord).pieces) ? (appliedComponent.structure as AnyRecord).pieces as AnyRecord[] : [])
+ : []
+ const structurePieces = structurePieceDefs.map((def, index) => {
+ const definition = (def.definition && typeof def.definition === 'object' ? def.definition : def) as AnyRecord
+ const resolved = (def.resolvedPiece && typeof def.resolvedPiece === 'object' ? def.resolvedPiece : null) as AnyRecord | null
+ const quantity = typeof definition.quantity === 'number' ? definition.quantity : (typeof def.quantity === 'number' ? def.quantity : 1)
+ return {
+ ...(resolved || {}),
+ id: resolved?.id || `structure-piece-${composantId}-${index}`,
+ pieceId: resolved?.id || null,
+ name: resolved?.name || definition.role || definition.name || def.role || def.name || `Pièce ${index + 1}`,
+ reference: resolved?.reference || definition.reference || def.reference || null,
+ prix: resolved?.prix ?? null,
+ constructeurs: resolved?.constructeurs || [],
+ documents: [],
+ quantity,
+ typePieceId: resolved?.typePieceId || definition.typePieceId || def.typePieceId || null,
+ typePiece: resolved?.typePiece || null,
+ parentComponentLinkId: machineComponentLinkId,
+ parentComponentName: componentName,
+ _structurePiece: true,
+ }
+ }) as AnyRecord[]
+
+ const pieces = linkedPieces.length ? linkedPieces : structurePieces
+
const subComponents = Array.isArray(link.childLinks)
? (link.childLinks as AnyRecord[]).map(createComponentNode).filter(Boolean) as AnyRecord[]
: []