feat: refine admin forms, attendance and finance workflows

Squash merge PR #23.

Included changes:
- complete occupancy check-in required fields/default payload
- improve responsive admin management pages
- fix attendance edge cases and attendance period config
- refine wallet/finance-related workflow handling

Checks:
- npm run typecheck -w apps/admin
- npm run typecheck -w apps/server
This commit is contained in:
2026-07-18 12:54:10 +00:00
parent 92d303ed01
commit 375c7ec60b
64 changed files with 5169 additions and 2404 deletions

View File

@@ -1,6 +1,54 @@
import { describe, expect, it } from 'vitest';
import dayjs from 'dayjs';
import { buildTransferPayload } from './occupancy-form';
import { buildCheckInPayload, buildTransferPayload } from './occupancy-form';
describe('occupancy check-in form', () => {
it('submits all required manual check-in fields with defaults', () => {
expect(
buildCheckInPayload({
studentId: 1,
roomId: 2,
checkInDate: dayjs('2026-07-18'),
billingStartDate: dayjs('2026-07-18'),
stayType: 'short',
collectDeposit: true,
depositAmount: 500,
bedId: 3,
notes: ' 备注 ',
}),
).toEqual({
studentId: 1,
roomId: 2,
checkInDate: '2026-07-18',
billingStartDate: '2026-07-18',
stayType: 'short',
collectDeposit: true,
depositAmount: 500,
notes: '备注',
bedId: 3,
lockerId: undefined,
});
});
it('falls back to check-in date and short stay type', () => {
expect(
buildCheckInPayload({
studentId: 1,
roomId: 2,
checkInDate: dayjs('2026-07-18'),
collectDeposit: false,
bedId: 3,
}),
).toEqual(
expect.objectContaining({
billingStartDate: '2026-07-18',
stayType: 'short',
collectDeposit: false,
depositAmount: undefined,
}),
);
});
});
describe('occupancy transfer form', () => {
it('submits the target room resources with the transfer dates', () => {