jws-frontend/src/pages/05_quotation/utils.ts

107 lines
2.9 KiB
TypeScript
Raw Normal View History

2024-10-08 17:32:28 +07:00
import { QuotationFull } from 'src/stores/quotations/types';
export type ProductTree = {
id: string;
title: string;
subtitle: string;
checked: boolean;
opened: boolean;
icon: string;
fg: string;
bg: string;
value?: {
vat: number;
pricePerUnit: number;
discount: number;
amount: 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: {
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({
id: service.id,
title: service.name,
subtitle: service.code,
opened: service.work.length > 0,
checked: true,
children: service.work.flatMap((work) => {
const mapper = (
relation: (typeof work)['productOnWork'][number],
) => ({
id: relation.product.id,
title: relation.product.name,
subtitle: relation.product.code,
opened: true,
checked: !!list.find(
(v) =>
v.service?.id === service.id &&
v.work?.id === work.id &&
v.product.id === relation.product.id,
),
icon: 'mdi-shopping-outline',
bg: 'hsla(var(--teal-10-hsl)/0.1)',
fg: 'var(--teal-10)',
});
if (!!work.name) {
return {
id: work.id,
title: work.name,
subtitle: ' ',
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({
id: current.product.id,
title: current.product.name,
subtitle: current.product.code,
opened: true,
checked: true,
icon: 'mdi-shopping-outline',
bg: 'hsla(var(--teal-10-hsl)/0.1)',
fg: 'var(--teal-10)',
});
}
}
return ret;
}