feat: reverse tree convert
This commit is contained in:
parent
d5c8ce85b6
commit
13cf2da9f9
3 changed files with 147 additions and 33 deletions
106
src/pages/05_quotation/utils.ts
Normal file
106
src/pages/05_quotation/utils.ts
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
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;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue