import { QuotationFull } from 'src/stores/quotations/types'; export type ProductTree = { type?: string; id: string; title: string; subtitle: string; detail?: string; remark?: string; attributes?: Record; checked: boolean; opened: boolean; icon: string; fg: string; bg: string; value?: { vat: number; pricePerUnit: number; discount: number; amount: number; installmentNo?: number; serviceId?: string; service?: QuotationFull['productServiceList'][number]['service']; workId?: string; work?: QuotationFull['productServiceList'][number]['work']; productId: string; product: QuotationFull['productServiceList'][number]['product']; }; children?: ProductTree; }[]; export function quotationProductTree( list: { vat: number; pricePerUnit: number; discount: number; amount: number; installmentNo?: number; service?: QuotationFull['productServiceList'][number]['service']; work?: QuotationFull['productServiceList'][number]['work']; product: QuotationFull['productServiceList'][number]['product']; }[], ): ProductTree { const ret: ProductTree = []; for (let i = 0; i < list.length; i++) { const current = list[i]; if (ret.find((v) => v.id === current.service?.id)) continue; if (current.service && current.work) { const service = current.service; ret.push({ type: 'service', id: service.id, title: service.name, subtitle: service.code, attributes: service.attributes, detail: service.detail, opened: service.work.length > 0, checked: true, children: service.work.flatMap((work) => { const mapper = ( relation: (typeof work)['productOnWork'][number], ): ProductTree[number] => { return { type: 'product', id: relation.product.id, title: relation.product.name, subtitle: relation.product.code, detail: relation.product.detail, remark: relation.product.remark, opened: true, checked: !!list.find( (v) => v.service?.id === service.id && v.work?.id === work.id && v.product.id === relation.product.id, ), value: { vat: current.vat, pricePerUnit: current.pricePerUnit, discount: current.discount, amount: current.amount, serviceId: service.id, service: service, workId: work.id, work: work, productId: relation.product.id, product: relation.product, }, icon: 'mdi-shopping-outline', bg: 'hsla(var(--teal-10-hsl)/0.1)', fg: 'var(--teal-10)', }; }; if (!!work.name) { return { type: 'work', id: work.id, title: work.name, subtitle: ' ', attributes: work.attributes, opened: true, checked: !!list.find( (v) => v.service?.id === service.id && v.work?.id === work.id, ), children: work.productOnWork.map(mapper), icon: 'mdi-briefcase-outline', bg: 'hsla(var(--violet-11-hsl)/0.1)', fg: 'var(--violet-11)', }; } return work.productOnWork.map(mapper); }), icon: 'mdi-server-outline', bg: 'hsla(var(--orange-5-hsl)/0.1)', fg: 'var(--orange-5)', }); } else { ret.push({ type: 'product', id: current.product.id, title: current.product.name, subtitle: current.product.code, detail: current.product.detail, remark: current.product.remark, opened: true, checked: true, value: { vat: current.vat, pricePerUnit: current.pricePerUnit, discount: current.discount, amount: current.amount, productId: current.product.id, product: current.product, installmentNo: current.installmentNo, }, icon: 'mdi-shopping-outline', bg: 'hsla(var(--teal-10-hsl)/0.1)', fg: 'var(--teal-10)', }); } } return ret; }