完善差旅补助规定与费用类型(07-28-travel-reimbursement-guide)
这个提交包含在:
@@ -7,8 +7,13 @@ const ENABLED_EXPENSE_TYPES = [
|
||||
{ code: "travel_train", name: "火车票", category: "travel" },
|
||||
{ code: "travel_taxi", name: "打车费", category: "travel" },
|
||||
{ code: "travel_hotel", name: "住宿费", category: "travel" },
|
||||
{ code: "travel_bus", name: "市内交通", category: "travel" },
|
||||
{ code: "travel_meal", name: "差旅餐补", category: "travel" },
|
||||
{ code: "travel_bus", name: "大巴车票", category: "travel" },
|
||||
{ code: "travel_meal", name: "伙食补助费", category: "travel" },
|
||||
{
|
||||
code: "travel_local_transport_allowance",
|
||||
name: "市内交通补助费",
|
||||
category: "travel",
|
||||
},
|
||||
{ code: "travel_fuel", name: "油费", category: "travel" },
|
||||
{ code: "travel_toll", name: "过路费", category: "travel" },
|
||||
{ code: "travel_parking", name: "停车费", category: "travel" },
|
||||
@@ -1088,5 +1093,7 @@ if (require.main === module) {
|
||||
|
||||
module.exports = {
|
||||
DEFAULT_APPROVAL_RULES,
|
||||
ENABLED_EXPENSE_TYPES,
|
||||
seedApprovalRules,
|
||||
seedExpenseTypes,
|
||||
};
|
||||
|
||||
@@ -21,7 +21,7 @@ function buildTemplate(overrides = {}) {
|
||||
return {
|
||||
id: TEMPLATE_ID,
|
||||
name: "国内差旅报销",
|
||||
description: "机票、火车票与市内交通占位模板",
|
||||
description: "机票、火车票与大巴车票占位模板",
|
||||
items: [
|
||||
{
|
||||
expenseTypeId: EXPENSE_TYPE_ID,
|
||||
|
||||
@@ -60,7 +60,7 @@ function buildTemplate(overrides = {}) {
|
||||
},
|
||||
{
|
||||
expenseTypeId: BUS_TYPE_ID,
|
||||
description: "市内交通占位",
|
||||
description: "大巴车票占位",
|
||||
},
|
||||
],
|
||||
...overrides,
|
||||
@@ -127,7 +127,7 @@ async function buildApp(options = {}) {
|
||||
expenseTypes: options.expenseTypes ?? [
|
||||
{ id: AIRFARE_TYPE_ID, code: "travel_airfare", name: "机票", category: "travel", enabled: true },
|
||||
{ id: TRAIN_TYPE_ID, code: "travel_train", name: "火车票", category: "travel", enabled: true },
|
||||
{ id: BUS_TYPE_ID, code: "travel_bus", name: "市内交通", category: "travel", enabled: true },
|
||||
{ id: BUS_TYPE_ID, code: "travel_bus", name: "大巴车票", category: "travel", enabled: true },
|
||||
{ id: TAXI_TYPE_ID, code: "travel_taxi", name: "打车费", category: "travel", enabled: true },
|
||||
{ id: TRANSPORT_TYPE_ID, code: "transport", name: "legacy-交通费", category: "travel", enabled: true },
|
||||
],
|
||||
|
||||
@@ -1,8 +1,51 @@
|
||||
const {
|
||||
DEFAULT_APPROVAL_RULES,
|
||||
ENABLED_EXPENSE_TYPES,
|
||||
seedApprovalRules,
|
||||
seedExpenseTypes,
|
||||
} = require("../../../src/scripts/seed-config");
|
||||
|
||||
describe("default travel expense types", () => {
|
||||
it("keeps intercity bus tickets separate from the two travel allowances", () => {
|
||||
expect(ENABLED_EXPENSE_TYPES).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ code: "travel_bus", name: "大巴车票", category: "travel" }),
|
||||
expect.objectContaining({ code: "travel_meal", name: "伙食补助费", category: "travel" }),
|
||||
expect.objectContaining({
|
||||
code: "travel_local_transport_allowance",
|
||||
name: "市内交通补助费",
|
||||
category: "travel",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
|
||||
const travelCodes = ENABLED_EXPENSE_TYPES.filter((item) =>
|
||||
["travel_bus", "travel_meal", "travel_local_transport_allowance"].includes(item.code),
|
||||
);
|
||||
expect(travelCodes).toHaveLength(3);
|
||||
});
|
||||
|
||||
it("upserts the distinct travel types by stable code", async () => {
|
||||
const upsert = vi.fn().mockResolvedValue({});
|
||||
|
||||
await seedExpenseTypes({ expenseType: { upsert } });
|
||||
|
||||
for (const [code, name] of [
|
||||
["travel_bus", "大巴车票"],
|
||||
["travel_meal", "伙食补助费"],
|
||||
["travel_local_transport_allowance", "市内交通补助费"],
|
||||
]) {
|
||||
expect(upsert).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
where: { code },
|
||||
update: expect.objectContaining({ name, enabled: true }),
|
||||
create: expect.objectContaining({ code, name, enabled: true }),
|
||||
}),
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("small-team default reimbursement approval rules", () => {
|
||||
it("uses finance for every owner fallback and finance review node", () => {
|
||||
expect(DEFAULT_APPROVAL_RULES).toEqual([
|
||||
|
||||
在新工单中引用
屏蔽一个用户