fix(piece) : persist slot quantity on blur and send prix as string

- Save composant piece slot quantity via PATCH on blur
- Pass slotId through hierarchy and selection entries
- Send prix as string (not number) to match backend expectation
- Show quantity in view mode when > 1
- Allow quantity edit for all pieces (not just root-level)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Matthieu
2026-03-13 11:19:09 +01:00
parent 139ba183de
commit 5912216a89
7 changed files with 44 additions and 15 deletions

View File

@@ -7,6 +7,7 @@ import { useProductTypes } from '~/composables/useProductTypes'
import { usePieces } from '~/composables/usePieces'
import { useProducts } from '~/composables/useProducts'
import { useCustomFields } from '~/composables/useCustomFields'
import type { SelectionEntry } from '~/shared/utils/structureSelectionUtils'
import { useApi } from '~/composables/useApi'
import { useToast } from '~/composables/useToast'
import { extractRelationId } from '~/shared/apiRelations'
@@ -53,7 +54,7 @@ const historyFieldLabels: Record<string, string> = {
export function useComponentEdit(componentId: string) {
const { canEdit } = usePermissions()
const router = useRouter()
const { get } = useApi()
const { get, patch } = useApi()
const { componentTypes, loadComponentTypes } = useComponentTypes()
const { pieceTypes, loadPieceTypes } = usePieceTypes()
const { productTypes, loadProductTypes } = useProductTypes()
@@ -269,6 +270,21 @@ export function useComponentEdit(componentId: string) {
}
})
const saveSlotQuantity = async (entry: SelectionEntry) => {
const slotId = entry.slotId
const quantity = typeof entry._definition?.quantity === 'number'
? Math.max(1, entry._definition.quantity)
: null
if (!slotId || quantity === null) return
try {
await patch(`/composant-piece-slots/${slotId}`, { quantity })
toast.showSuccess('Quantité mise à jour')
}
catch (error: any) {
toast.showError(error?.message || 'Erreur lors de la mise à jour de la quantité')
}
}
const submitEdition = async () => {
if (!component.value) {
return
@@ -299,10 +315,6 @@ export function useComponentEdit(componentId: string) {
payload.prix = null
}
if (component.value.structure) {
payload.structure = component.value.structure
}
saving.value = true
try {
const result = await updateComposant(component.value.id, payload)
@@ -457,6 +469,7 @@ export function useComponentEdit(componentId: string) {
handleFilesAdded,
refreshDocuments,
submitEdition,
saveSlotQuantity,
resolvePieceLabel,
resolveProductLabel,
resolveSubcomponentLabel,

View File

@@ -110,18 +110,18 @@ export function useMachineDetailUpdates(deps: UseMachineDetailUpdatesDeps) {
const productId = updatedComponent.productId
? String(updatedComponent.productId)
: null
const prix =
const prixStr =
updatedComponent.prix !== null &&
updatedComponent.prix !== undefined &&
String(updatedComponent.prix).trim() !== ''
? Number(updatedComponent.prix)
? String(updatedComponent.prix)
: null
const result: any = await updateComposantApi(updatedComponent.id as string, {
name: updatedComponent.name,
reference: updatedComponent.reference,
constructeurIds: cIds,
prix: Number.isNaN(prix) ? null : prix,
prix: prixStr,
productId,
} as any)
if (result.success) {
@@ -140,18 +140,18 @@ export function useMachineDetailUpdates(deps: UseMachineDetailUpdatesDeps) {
updatedPiece.constructeur,
)
const productId = updatedPiece.productId ? String(updatedPiece.productId) : null
const prix =
const prixStr =
updatedPiece.prix !== null &&
updatedPiece.prix !== undefined &&
String(updatedPiece.prix).trim() !== ''
? Number(updatedPiece.prix)
? String(updatedPiece.prix)
: null
const result: any = await updatePieceApi(updatedPiece.id as string, {
name: updatedPiece.name,
reference: updatedPiece.reference || null,
constructeurIds: cIds,
prix: Number.isNaN(prix) ? null : prix,
prix: prixStr,
productId,
} as any)
if (result.success) {
@@ -181,6 +181,13 @@ export function useMachineDetailUpdates(deps: UseMachineDetailUpdatesDeps) {
)
}
}
// 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)
}

View File

@@ -237,6 +237,7 @@ export const buildMachineHierarchyFromLinks = (
constructeurs: resolved?.constructeurs || [],
documents: [],
quantity,
slotId: def.slotId || definition.slotId || null,
typePieceId: resolved?.typePieceId || definition.typePieceId || def.typePieceId || null,
typePiece: resolved?.typePiece || null,
parentComponentLinkId: machineComponentLinkId,