You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
2.9 KiB
103 lines
2.9 KiB
import { prisma } from "@/lib/prisma";
|
|
import type { MarkupConfig } from "@prisma/client";
|
|
import { listAllCustomerIds } from "@/modules/auth/service-token";
|
|
import type { ParsedMarkupInput } from "@/modules/pricing/markup-validation";
|
|
|
|
export type MarkupConfigDto = {
|
|
customer_id: string;
|
|
markup_type: "percent" | "fixed";
|
|
markup_percent: number;
|
|
markup_fixed_amount: number | null;
|
|
operator_id: string;
|
|
remark: string | null;
|
|
updated_at: string;
|
|
};
|
|
|
|
export function serializeMarkupConfig(config: MarkupConfig): MarkupConfigDto {
|
|
return {
|
|
customer_id: config.customerId,
|
|
markup_type: config.markupType === "fixed" ? "fixed" : "percent",
|
|
markup_percent: Number(config.markupPercent),
|
|
markup_fixed_amount:
|
|
config.markupFixedAmount === null || config.markupFixedAmount === undefined
|
|
? null
|
|
: Number(config.markupFixedAmount),
|
|
operator_id: config.operatorId,
|
|
remark: config.remark,
|
|
updated_at: config.updatedAt.toISOString(),
|
|
};
|
|
}
|
|
|
|
export function defaultMarkupDto(customerId: string): MarkupConfigDto {
|
|
return {
|
|
customer_id: customerId,
|
|
markup_type: "percent",
|
|
markup_percent: 0,
|
|
markup_fixed_amount: null,
|
|
operator_id: "",
|
|
remark: null,
|
|
updated_at: new Date(0).toISOString(),
|
|
};
|
|
}
|
|
|
|
export async function upsertMarkupConfig(
|
|
customerId: string,
|
|
input: ParsedMarkupInput,
|
|
operatorId: string,
|
|
remark: string | null,
|
|
): Promise<MarkupConfigDto> {
|
|
const config = await prisma.markupConfig.upsert({
|
|
where: { customerId },
|
|
create: {
|
|
customerId,
|
|
markupType: input.markupType,
|
|
markupPercent: input.markupPercent,
|
|
markupFixedAmount: input.markupFixedAmount,
|
|
operatorId,
|
|
remark,
|
|
},
|
|
update: {
|
|
markupType: input.markupType,
|
|
markupPercent: input.markupPercent,
|
|
markupFixedAmount: input.markupFixedAmount,
|
|
operatorId,
|
|
remark,
|
|
isDeleted: false,
|
|
},
|
|
});
|
|
|
|
return serializeMarkupConfig(config);
|
|
}
|
|
|
|
export async function listAdminMarkupConfigs(options: {
|
|
page: number;
|
|
size: number;
|
|
keyword?: string;
|
|
}): Promise<{ list: MarkupConfigDto[]; total: number; page: number; size: number }> {
|
|
const keyword = options.keyword?.trim().toLowerCase() ?? "";
|
|
const customerIds = (await listAllCustomerIds()).filter((id) =>
|
|
keyword ? id.toLowerCase().includes(keyword) : true,
|
|
);
|
|
|
|
const configs = await prisma.markupConfig.findMany({
|
|
where: { customerId: { in: customerIds }, isDeleted: false },
|
|
});
|
|
const configMap = new Map(configs.map((c) => [c.customerId, c]));
|
|
|
|
const merged = customerIds.map((customerId) => {
|
|
const existing = configMap.get(customerId);
|
|
return existing ? serializeMarkupConfig(existing) : defaultMarkupDto(customerId);
|
|
});
|
|
|
|
const total = merged.length;
|
|
const start = (options.page - 1) * options.size;
|
|
const list = merged.slice(start, start + options.size);
|
|
|
|
return {
|
|
list,
|
|
total,
|
|
page: options.page,
|
|
size: options.size,
|
|
};
|
|
}
|