feat: 选票自动生成报销明细并支持集中分类(08-29-reimbursement-expense-policy-invoice-guard)
这个提交包含在:
@@ -0,0 +1,30 @@
|
||||
const { mapInvoiceDocumentMeta } = require("./invoiceDocumentMeta");
|
||||
const { buildBusinessValidationError } = require("../utils/businessValidationError");
|
||||
|
||||
function suggestInvoiceExpenseType(invoice, expenseTypes) {
|
||||
const { documentCategory } = mapInvoiceDocumentMeta(invoice);
|
||||
if (documentCategory !== "electronic_train_ticket") return null;
|
||||
|
||||
const expenseType = expenseTypes.find((type) => type.enabled === true && type.code === "travel_train");
|
||||
if (!expenseType) return null;
|
||||
|
||||
return { expenseTypeId: expenseType.id, source: "document_category" };
|
||||
}
|
||||
|
||||
function ensureClassifiedReimbursementItems(items) {
|
||||
const itemIds = items
|
||||
.filter((item) => !item.expense_type || item.expense_type.enabled === false)
|
||||
.map((item) => item.id);
|
||||
if (itemIds.length) {
|
||||
throw buildBusinessValidationError("reimbursement.items_expense_type_required", { itemIds }, 400);
|
||||
}
|
||||
}
|
||||
|
||||
function ensureReimbursementItemDescriptions(items) {
|
||||
const itemIds = items.filter((item) => !item.description?.trim()).map((item) => item.id);
|
||||
if (itemIds.length) {
|
||||
throw buildBusinessValidationError("reimbursement.items_description_required", { itemIds }, 400);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { suggestInvoiceExpenseType, ensureClassifiedReimbursementItems, ensureReimbursementItemDescriptions };
|
||||
在新工单中引用
屏蔽一个用户