Initial commit: intercompany ledger app
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
# Behavior Specification
|
||||
|
||||
## Access Boundaries
|
||||
|
||||
- `/admin.html` is the group administrator portal and can access all companies.
|
||||
- `/company.html` is the cashier portal and is scoped to exactly one company.
|
||||
- A company user is created by an administrator and stores login name, default
|
||||
password state, company, cashier name, status, and last sign-in time.
|
||||
- Every read, export, upload, reminder, confirmation, and setting change is
|
||||
permission checked on the server; client-side hiding is not authorization.
|
||||
|
||||
## Import Lifecycle
|
||||
|
||||
`待上传 -> 已上传 -> 解析中 -> 已解析 -> 待处理 -> 已确认`
|
||||
|
||||
- Original files are stored and hashed before parsing.
|
||||
- Header signatures select the bank template; unknown or ambiguous headers go
|
||||
to review rather than being guessed.
|
||||
- Rows are normalized into date, direction, amount, balance, account,
|
||||
counterparty name/account, bank identifiers, summary, and source location.
|
||||
- Duplicate files and duplicate rows are flagged before they can affect totals.
|
||||
- Unknown-template errors show the original upload filename, scanned worksheet,
|
||||
and likely header rows. Server temporary filenames are never shown to users.
|
||||
|
||||
## Manual Records
|
||||
|
||||
`草稿 -> 待总账复核 -> 已确认 / 已退回 / 异常待处理`
|
||||
|
||||
- A cashier can submit a manual record only for the bound company, with date,
|
||||
direction, amount, funding source, counterparty, subject, summary, and reason.
|
||||
- Personal transit is an explicit funding-source option. A bank account may be
|
||||
referenced, but the manual record never becomes or edits a bank source row.
|
||||
- Supporting evidence and an optional related bank reference are retained with
|
||||
operator, submission time, review decision, reason, and review time.
|
||||
- Only `已确认` manual records can join canonical events or affect positions.
|
||||
Pending, returned, and exceptional records remain visible but excluded.
|
||||
|
||||
## Bank Account Registration
|
||||
|
||||
`公司端提交 -> 待总账复核 -> 已启用 / 已退回 / 已停用`
|
||||
|
||||
- Company users register accounts only for their bound company. Administrators
|
||||
review ownership, bank, account number, type, and effective date.
|
||||
- Before `已启用`, an account is excluded from ownership recognition, statement
|
||||
upload choices, same-company transfer detection, and coverage calculations.
|
||||
- Every decision retains submitter, reviewer, timestamps, and reason. Account
|
||||
numbers are unique within the active master data.
|
||||
|
||||
## Classification And Matching
|
||||
|
||||
1. Resolve the source account owner from account master data.
|
||||
2. Resolve the counterparty using account number first and audited aliases second.
|
||||
3. Same owner means `同公司账户调拨`; retain it in flow history and exclude it
|
||||
from intercompany totals.
|
||||
4. Different owners create or join one canonical intercompany event. A matched
|
||||
pair of bank rows counts once.
|
||||
5. No reliable counterparty match means `外部或待识别` and cannot affect an
|
||||
intercompany position until resolved.
|
||||
6. Direction and amount are deterministic. Subject is assigned by explicit
|
||||
rules; unresolved subjects enter review and may be confirmed manually with
|
||||
operator, reason, and timestamp.
|
||||
|
||||
## Position Hierarchy
|
||||
|
||||
The administrator can navigate the following levels without losing context:
|
||||
|
||||
1. Company debit total and credit total for the effective period.
|
||||
2. Debit entries and credit entries for that company.
|
||||
3. Counterparty totals grouped by `应收`, `应付`, `其他应收`, `其他应付`.
|
||||
4. Individual canonical transfers and their original bank-side evidence.
|
||||
|
||||
Pair query accepts two different companies and shows both viewpoints, opening
|
||||
balance, period movement, closing position, unresolved amount, and transactions.
|
||||
|
||||
## Calculation Window And Closing
|
||||
|
||||
- Rows with transaction date earlier than the global start date are excluded
|
||||
from all position calculations but remain queryable as archived evidence.
|
||||
- Coverage is evaluated per bank account as date intervals, not by upload month.
|
||||
- A missing interval between the start date and earliest accepted statement, or
|
||||
between accepted statements, creates a gap visible in both portals.
|
||||
- Cashier `无业务校准` closes a gap only after a reason is submitted. It does
|
||||
not fabricate bank rows and remains visible in the audit trail.
|
||||
- Monthly closing freezes the period result. Later files affecting a closed
|
||||
period create a reopening exception; they do not silently rewrite the close.
|
||||
|
||||
## Flow Management And Export
|
||||
|
||||
- Administrator filters flows by company, bank, account, date, direction,
|
||||
counterparty, match state, and keyword.
|
||||
- Cashier has the same flow tools within the bound company only.
|
||||
- Export uses a stable custom schema and preserves source bank, source account,
|
||||
bank transaction id/reference, original summary, import batch, match state,
|
||||
and source-row locator.
|
||||
|
||||
## Reminders
|
||||
|
||||
- Automatic reminders are generated for missing monthly uploads, coverage gaps,
|
||||
single-side candidates, unmatched internal flows, and overdue exceptions.
|
||||
- Administrator can send a manual in-product reminder to one company with a
|
||||
message and due date.
|
||||
- Reminders have `未读`, `已读`, `处理中`, and `已完成` states and retain sender,
|
||||
recipient, trigger, timestamps, and linked task.
|
||||
|
||||
## Homepage Priorities
|
||||
|
||||
- Administrator homepage: accounting-window status, urgent management queue,
|
||||
company debit/credit directory, and A-B quick query. Import history is not on
|
||||
the homepage.
|
||||
- Cashier homepage: missing uploads, gaps, one-sided matching, unmatched flows,
|
||||
and the next direct action for the bound company.
|
||||
Reference in New Issue
Block a user