/** * Reactive product display for entity items (ComponentItem, PieceItem). * * Resolves product information from entity.product, entity.__productDisplay, * or a selectedProduct ref, and produces display-ready computed properties. */ import { computed, type Ref } from 'vue' const currencyFormatter = new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR', currencyDisplay: 'narrowSymbol', }) function buildProductDisplay(product: any) { if (!product || typeof product !== 'object') return null const suppliers = Array.isArray(product.constructeurs) ? product.constructeurs .map((c: any) => c?.name) .filter((name: any) => typeof name === 'string' && name.trim().length > 0) .join(', ') : product.supplierLabel || null const priceValue = product.supplierPrice ?? product.price ?? product.priceLabel ?? product.priceDisplay ?? null let price: string | null = null if (priceValue !== null && priceValue !== undefined) { const parsed = Number(priceValue) if (!Number.isNaN(parsed)) { price = currencyFormatter.format(parsed) } else if (typeof priceValue === 'string' && priceValue.trim().length > 0) { price = priceValue } } return { name: product.name || product.label || product.reference || product.productName || null, reference: product.reference || null, category: product.typeProduct?.name || product.category || null, suppliers, price, } } export interface EntityProductDisplayDeps { entity: () => any selectedProduct?: Ref } export function useEntityProductDisplay(deps: EntityProductDisplayDeps) { const { entity, selectedProduct } = deps const displayProduct = computed(() => { // Priority: selectedProduct (for PieceItem) → entity.product → entity.__productDisplay if (selectedProduct?.value) { const normalized = buildProductDisplay(selectedProduct.value) if (normalized) return normalized } const explicit = entity().product || null const normalized = buildProductDisplay(explicit) if (normalized) return normalized const fallback = entity().__productDisplay if (fallback) { return { name: fallback.name || null, reference: fallback.reference || null, category: fallback.category || null, suppliers: fallback.suppliers || null, price: fallback.price || null, } } return null }) const displayProductName = computed(() => { if (displayProduct.value?.name) return displayProduct.value.name const e = entity() return e.product?.name || e.productName || e.productLabel || null }) const productInfoRows = computed(() => { if (!displayProduct.value) return [] const rows: { label: string; value: string }[] = [] if (displayProduct.value.reference) rows.push({ label: 'Référence', value: displayProduct.value.reference }) if (displayProduct.value.price) rows.push({ label: 'Prix indicatif', value: displayProduct.value.price }) if (displayProduct.value.suppliers) rows.push({ label: 'Fournisseur(s)', value: displayProduct.value.suppliers }) if (displayProduct.value.category) rows.push({ label: 'Catégorie', value: displayProduct.value.category }) return rows }) const productDocuments = computed(() => { const product = selectedProduct?.value || entity().product || null return Array.isArray(product?.documents) ? product.documents : [] }) return { displayProduct, displayProductName, productInfoRows, productDocuments, } }