完善差旅补助规定与费用类型(07-28-travel-reimbursement-guide)
这个提交包含在:
@@ -383,6 +383,96 @@ node scripts/qa/check-ocr-provider-samples.mjs \
|
||||
The caller records stdout before applying the exit-code gate; it never uses a
|
||||
`set -e` assignment whose non-zero status exits before the JSON is emitted.
|
||||
|
||||
## Scenario: Travel Allowance Expense-Type Boundary
|
||||
|
||||
### 1. Scope / Trigger
|
||||
|
||||
- Trigger: adding or changing travel reimbursement types, travel-request
|
||||
transport mappings, allowance policies or expense standards.
|
||||
- Purpose: keep intercity transport reimbursed by evidence separate from the
|
||||
two daily lump-sum allowances, and avoid false over-limit results until the
|
||||
reimbursement item model supports a day count.
|
||||
|
||||
### 2. Signatures
|
||||
|
||||
- Seed contract in `server/src/scripts/seed-config.js`:
|
||||
- `travel_bus` -> `大巴车票`.
|
||||
- `travel_meal` -> `伙食补助费`.
|
||||
- `travel_local_transport_allowance` -> `市内交通补助费`.
|
||||
- Travel conversion contract in `server/src/routes/reimbursements.js`:
|
||||
`TRAVEL_TRANSPORT_EXPENSE_TYPE_CODES.bus === "travel_bus"`.
|
||||
- Current item data boundary: `ReimbursementItem` stores expense type, date,
|
||||
amount and description, but no quantity or eligible-day count.
|
||||
|
||||
### 3. Contracts
|
||||
|
||||
- `travel_bus` always means an intercity bus/coach ticket created from or used
|
||||
with a travel segment. It must not represent local transport allowance.
|
||||
- Meal allowance is CNY 100 per eligible person-day; local transport allowance
|
||||
is CNY 80 per eligible person-day. Both are lump-sum items without an invoice.
|
||||
- Employees create one item per allowance, set the amount to eligible days
|
||||
multiplied by the rate, and write the date range, day count, rate and formula
|
||||
in the description. Supervisor and finance review that calculation.
|
||||
- Departure and return dates each count as one natural day; same-day return is
|
||||
one day. Personal extensions do not count. Meals or vehicles paid directly
|
||||
by the company or another organization exclude the corresponding allowance.
|
||||
- Claiming meal allowance excludes separate personal meal reimbursement;
|
||||
claiming local transport allowance excludes bus, metro, taxi and ride-hailing
|
||||
reimbursement during the trip. Intercity transport, accommodation and other
|
||||
approved necessary expenses remain evidence-based actual reimbursement.
|
||||
- `ExpenseStandard.per_unit=day` currently does not multiply `max_amount` by a
|
||||
day count. Do not seed or configure CNY 100/CNY 80 warn/block standards until
|
||||
item quantity/day multiplication is implemented end to end.
|
||||
|
||||
### 4. Validation & Error Matrix
|
||||
|
||||
- Travel segment `bus` maps to an allowance type -> block the change; preserve
|
||||
`travel_bus` and add/use the separate allowance code.
|
||||
- CNY 100 or CNY 80 daily rate configured as the current item-level maximum ->
|
||||
remove/disable it because a multi-day allowance would be falsely over limit.
|
||||
- Allowance item lacks date range, eligible-day count, rate or formula -> return
|
||||
for completion during supervisor/finance review; do not invent a day count.
|
||||
- Company/other party directly bore the corresponding cost -> exclude those
|
||||
days from the applicable allowance and record the reason.
|
||||
|
||||
### 5. Good/Base/Bad Cases
|
||||
|
||||
- Good: a three-day eligible trip uses separate meal and local-transport items
|
||||
whose descriptions show `3 天 × 单价`, while rail/hotel items carry PDFs and
|
||||
required payment evidence.
|
||||
- Base: intercity coach travel uses `travel_bus` / `大巴车票` and remains an
|
||||
actual-expense item with valid evidence.
|
||||
- Bad: rename `travel_bus` to local transport allowance, or configure a CNY 80
|
||||
item maximum and thereby reject a valid multi-day allowance.
|
||||
|
||||
### 6. Tests Required
|
||||
|
||||
- Seed-default unit test asserts all three codes and Chinese names are distinct.
|
||||
- Travel-request conversion test asserts `transport_type=bus` produces an item
|
||||
whose expense type code is `travel_bus` and description identifies `大巴`.
|
||||
- When automatic day calculation is later implemented, add service and route
|
||||
tests for same-day, multi-day, personal-extension and directly-borne cases
|
||||
before enabling any daily standard.
|
||||
- Documentation checks must keep the employee guide, reimbursement fact source
|
||||
and production expense-type names aligned.
|
||||
|
||||
### 7. Wrong vs Correct
|
||||
|
||||
#### Wrong
|
||||
|
||||
```js
|
||||
const TRAVEL_TRANSPORT_EXPENSE_TYPE_CODES = { bus: "travel_local_transport_allowance" };
|
||||
// Current fee control compares the whole multi-day item directly with 80.
|
||||
```
|
||||
|
||||
#### Correct
|
||||
|
||||
```js
|
||||
const TRAVEL_TRANSPORT_EXPENSE_TYPE_CODES = { bus: "travel_bus" };
|
||||
// Local transport allowance is a separate manually calculated item until the
|
||||
// model and fee-control service both support eligible-day multiplication.
|
||||
```
|
||||
|
||||
## Scenario: Payment Batch Receipt Attention Count
|
||||
|
||||
### 1. Scope / Trigger
|
||||
|
||||
在新工单中引用
屏蔽一个用户