111 lines
3.5 KiB
JavaScript
111 lines
3.5 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import test from 'node:test'
|
|
|
|
import {
|
|
BUDGET_EXPENSE_TYPE_OPTIONS,
|
|
BUDGET_ONTOLOGY_FIELDS,
|
|
BUDGET_QUARTER_OPTIONS,
|
|
BUDGET_VISIBLE_EXPENSE_TYPE_OPTIONS,
|
|
BUDGET_YEAR_OPTIONS,
|
|
buildBudgetOntologyContext
|
|
} from '../src/utils/budgetOntology.js'
|
|
|
|
test('budget ontology fields expose required budget center keys', () => {
|
|
const requiredKeys = BUDGET_ONTOLOGY_FIELDS
|
|
.filter((field) => field.required)
|
|
.map((field) => field.key)
|
|
|
|
assert.deepEqual(requiredKeys, [
|
|
'budget_period',
|
|
'department',
|
|
'cost_center',
|
|
'budget_owner',
|
|
'budget_version',
|
|
'budget_status',
|
|
'budget_subject',
|
|
'budget_amount',
|
|
'warning_threshold',
|
|
'control_action'
|
|
])
|
|
})
|
|
|
|
test('budget ontology context maps dialog fields to ontology payload', () => {
|
|
const context = buildBudgetOntologyContext({
|
|
form: {
|
|
budgetYear: '2026',
|
|
budgetQuarter: 'Q2',
|
|
departmentCode: 'MARKET-DEPT',
|
|
budgetOwner: '张晓明',
|
|
budgetVersion: 'V1.0(初始版本)',
|
|
budgetStatus: '编制中',
|
|
budgetDescription: '市场部预算编制'
|
|
},
|
|
departments: [
|
|
{ code: 'MARKET-DEPT', name: '市场部', costCenter: 'CC-4100' }
|
|
],
|
|
rows: [
|
|
{
|
|
budgetSubject: '差旅',
|
|
budgetSubjectCode: 'travel',
|
|
budgetAmount: '600,000.00',
|
|
warningThreshold: '80%',
|
|
controlAction: '提醒',
|
|
budgetRemark: '差旅相关费用'
|
|
}
|
|
]
|
|
})
|
|
|
|
assert.equal(context.document_type, 'budget_plan')
|
|
assert.equal(context.conversation_scenario, 'budget')
|
|
assert.equal(context.budget_header.budget_period, '2026年Q2')
|
|
assert.equal(context.budget_header.budget_year, '2026')
|
|
assert.equal(context.budget_header.budget_quarter, 'Q2')
|
|
assert.equal(context.budget_header.department, '市场部')
|
|
assert.equal(context.budget_header.cost_center, 'CC-4100')
|
|
assert.equal(context.budget_details[0].budget_subject_code, 'travel')
|
|
assert.equal(context.budget_details[0].expense_type, 'travel')
|
|
assert.equal(context.budget_details[0].expense_type_label, '差旅')
|
|
assert.equal(context.budget_details[0].warning_threshold, '80%')
|
|
})
|
|
|
|
test('budget ontology includes approval review execution metrics', () => {
|
|
const fieldKeys = BUDGET_ONTOLOGY_FIELDS.map((field) => field.key)
|
|
|
|
assert.ok(fieldKeys.includes('claim_amount'))
|
|
assert.ok(fieldKeys.includes('claim_amount_ratio'))
|
|
assert.ok(fieldKeys.includes('usage_rate'))
|
|
assert.ok(fieldKeys.includes('after_usage_rate'))
|
|
assert.ok(fieldKeys.includes('remaining_budget_ratio'))
|
|
assert.ok(fieldKeys.includes('available_before_amount'))
|
|
assert.ok(fieldKeys.includes('over_budget_amount'))
|
|
})
|
|
|
|
test('budget expense type options expose real expense type codes', () => {
|
|
const optionCodes = BUDGET_EXPENSE_TYPE_OPTIONS.map((item) => item.value)
|
|
|
|
assert.deepEqual(optionCodes, [
|
|
'travel',
|
|
'hotel',
|
|
'transport',
|
|
'meal',
|
|
'meeting',
|
|
'marketing',
|
|
'office',
|
|
'training',
|
|
'software',
|
|
'communication',
|
|
'welfare'
|
|
])
|
|
})
|
|
|
|
test('budget center visible expense type options only expose current supported budget subjects', () => {
|
|
const optionLabels = BUDGET_VISIBLE_EXPENSE_TYPE_OPTIONS.map((item) => item.label)
|
|
|
|
assert.deepEqual(optionLabels, ['差旅', '通信', '招待费', '办公用品'])
|
|
})
|
|
|
|
test('budget center exposes separate year and quarter dimensions', () => {
|
|
assert.deepEqual(BUDGET_YEAR_OPTIONS, ['2026', '2027', '2028'])
|
|
assert.deepEqual(BUDGET_QUARTER_OPTIONS, ['Q1', 'Q2', 'Q3', 'Q4'])
|
|
})
|