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

import { prisma } from "@/lib/prisma";
import type { MarkupConfig } from "@prisma/client";
import { listRegisteredCustomerIds } 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 = listRegisteredCustomerIds().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,
};
}