weaver-work-cli 0.1.26 → 0.1.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -2
- package/dist/cmd/setup/index.js +1 -1
- package/dist/internal/e10/auth/commands.js +1 -6
- package/dist/internal/e10/auth/messages.js +3 -0
- package/dist/internal/e10/auth/session.js +8 -0
- package/dist/internal/e10/auth-recovery.js +148 -0
- package/dist/internal/e10/client.js +47 -15
- package/dist/internal/e10/context.js +8 -8
- package/dist/internal/e10/index.js +1 -0
- package/dist/internal/e10/request-runtime.js +51 -9
- package/dist/shortcuts/archive/host.js +3 -2
- package/dist/shortcuts/archive/manifest.js +1 -1
- package/dist/shortcuts/archive-oa/host.js +2 -1
- package/dist/shortcuts/archive-oa/manifest.js +1 -1
- package/dist/shortcuts/asset/host.js +7 -6
- package/dist/shortcuts/blog/host.js +4 -3
- package/dist/shortcuts/caizhilian/host.js +3 -2
- package/dist/shortcuts/caizhilian/manifest.js +1 -1
- package/dist/shortcuts/calendar/host.js +2 -1
- package/dist/shortcuts/contract/host.js +34 -59
- package/dist/shortcuts/ehr/host.js +2 -1
- package/dist/shortcuts/esb/host.js +2 -1
- package/dist/shortcuts/fna/host.js +6 -3
- package/dist/shortcuts/fna/manifest.js +10 -5
- package/dist/shortcuts/fna/operations/expense-chart.js +162 -0
- package/dist/shortcuts/fna/operations/registry.js +2 -0
- package/dist/shortcuts/hrm/host.js +2 -1
- package/dist/shortcuts/im/host.js +3 -2
- package/dist/shortcuts/invoice/host.js +7 -6
- package/dist/shortcuts/invoice/manifest.js +21 -141
- package/dist/shortcuts/invoice/operations/issuing-qys.js +134 -167
- package/dist/shortcuts/invoice/operations/registry.js +1 -6
- package/dist/shortcuts/jiuchuanhui/host.js +2 -1
- package/dist/shortcuts/mail/host.js +2 -1
- package/dist/shortcuts/meeting/host.js +2 -1
- package/dist/shortcuts/meeting/operations/eb/conflict.js +78 -12
- package/dist/shortcuts/okr/host.js +2 -1
- package/dist/shortcuts/plan/host.js +2 -1
- package/dist/shortcuts/project/host.js +2 -1
- package/dist/shortcuts/workflow/host.js +3 -5
- package/dist/shortcuts/workflow/index.js +1 -1
- package/dist/shortcuts/workflow/operations/chatscene.js +4 -22
- package/dist/shortcuts/workflow/operations/form.js +281 -166
- package/dist/shortcuts/workflow/operations/read.js +26 -2
- package/dist/shortcuts/workflow/stdout-compact.js +7 -0
- package/docs/SKILL.md +1 -1
- package/docs/_catalog.md +1 -1
- package/docs/agent-invoice.md +1 -1
- package/docs/caizhilian.md +1 -1
- package/docs/e10-auth.md +1 -1
- package/docs/fna.md +7 -3
- package/docs/invoice.md +4 -6
- package/package.json +1 -1
- package/skill-template/business-info.json +4 -1
- package/skill-template/domains/caizhilian.md +2 -1
- package/skill-template/domains/qiyecheng.md +1 -0
- package/skill-template/domains/yepiaotong.md +6 -2
- package/skill-template/skill-template.md +1 -0
- package/skills/weaver-e10-blog/SKILL.md +6 -1
- package/skills/weaver-e10-blog/references/blog-query.md +3 -1
- package/skills/weaver-e10-caizhilian/SKILL.md +18 -9
- package/skills/weaver-e10-caizhilian/references/action-flow.md +70 -0
- package/skills/weaver-e10-caizhilian/references/agent-entry.md +6 -2
- package/skills/weaver-e10-caizhilian/references/auth-and-install.md +207 -0
- package/skills/weaver-e10-caizhilian/references/file-collection.md +56 -54
- package/skills/weaver-e10-caizhilian/references/file-upload.md +4 -4
- package/skills/weaver-e10-caizhilian/references/host-executor-prompt.md +32 -0
- package/skills/weaver-e10-caizhilian/references/host-platform-integration.md +46 -0
- package/skills/weaver-e10-caizhilian/references/rule-index.md +56 -0
- package/skills/weaver-e10-caizhilian/references/setting-attach.md +5 -16
- package/skills/weaver-e10-caizhilian/references/setting-backup.md +4 -13
- package/skills/weaver-e10-caizhilian/references/setting-encrypt.md +6 -15
- package/skills/weaver-e10-caizhilian/references/setting-storage-docs-summary.md +126 -0
- package/skills/weaver-e10-caizhilian/references/setting-storage-field-map.md +57 -0
- package/skills/weaver-e10-caizhilian/references/setting-storage.md +142 -482
- package/skills/weaver-e10-caizhilian/references/source-manifest.json +7 -7
- package/skills/weaver-e10-caizhilian/references/task-workflow.md +87 -0
- package/skills/weaver-e10-caizhilian/references/withheld.md +2 -2
- package/skills/weaver-e10-caizhilian/references/write-protocol.md +7 -0
- package/skills/weaver-e10-calendar/SKILL.md +6 -1
- package/skills/weaver-e10-esb/SKILL.md +8 -0
- package/skills/weaver-e10-esb/references/input-format.md +3 -1
- package/skills/weaver-e10-esb/references/source-manifest.json +5 -5
- package/skills/weaver-e10-hrm/SKILL.md +6 -1
- package/skills/weaver-e10-hrm/references/employee.md +1 -1
- package/skills/weaver-e10-hrm/references/org.md +1 -1
- package/skills/weaver-e10-hrm/references/position.md +1 -1
- package/skills/weaver-e10-jinchengda/SKILL.md +2 -1
- package/skills/weaver-e10-jinchengda/references/contract-agent-entry.md +1 -1
- package/skills/weaver-e10-jiuchuanhui/SKILL.md +6 -1
- package/skills/weaver-e10-jucailin/SKILL.md +6 -1
- package/skills/weaver-e10-jucailin/references/hr-contact.md +1 -1
- package/skills/weaver-e10-jucailin/references/salary.md +1 -1
- package/skills/weaver-e10-mail/SKILL.md +6 -1
- package/skills/weaver-e10-meeting/SKILL.md +11 -6
- package/skills/weaver-e10-meeting/references/meeting-eb.md +7 -3
- package/skills/weaver-e10-meeting/references/meeting-queries.md +3 -1
- package/skills/weaver-e10-meeting/references/meeting-verification.md +4 -2
- package/skills/weaver-e10-okr/SKILL.md +6 -1
- package/skills/weaver-e10-okr/references/source-manifest.json +5 -5
- package/skills/weaver-e10-plan/SKILL.md +6 -1
- package/skills/weaver-e10-plan/references/plan-overview-and-routing.md +3 -1
- package/skills/weaver-e10-plan/references/plan-report-query.md +3 -1
- package/skills/weaver-e10-plan/references/source-manifest.json +7 -7
- package/skills/weaver-e10-qiyecheng/SKILL.md +16 -6
- package/skills/weaver-e10-qiyecheng/references/catalog.md +6 -3
- package/skills/weaver-e10-qiyecheng/references/expense-center.md +2 -0
- package/skills/weaver-e10-qiyecheng/references/expense-chart.md +78 -0
- package/skills/weaver-e10-qiyecheng/references/source-manifest.json +87 -33
- package/skills/weaver-e10-shared/SKILL.md +37 -14
- package/skills/weaver-e10-shared/references/e10-auth-and-session.md +11 -8
- package/skills/weaver-e10-shared/references/non-interactive-environment.md +4 -4
- package/skills/weaver-e10-shared/references/weaver-e10-installation.md +3 -1
- package/skills/weaver-e10-wenshuding/SKILL.md +6 -1
- package/skills/weaver-e10-wenshuding/references/source-manifest.json +3 -3
- package/skills/weaver-e10-workflow/references/source-manifest.json +1 -2
- package/skills/weaver-e10-workflow/references/workflow-create.md +30 -55
- package/skills/weaver-e10-yepiaotong/SKILL.md +19 -17
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-examples.md +72 -78
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-form-fill-rules.md +152 -0
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-workflow.md +210 -0
- package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +7 -7
- package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +11 -5
- package/skills/weaver-e10-yepiaotong/references/reim-examples.md +55 -33
- package/skills/weaver-e10-yepiaotong/references/reim-form-fill-rules.md +102 -23
- package/skills/weaver-e10-yepiaotong/references/reim-phone-subsidy-rules.md +1 -1
- package/skills/weaver-e10-yepiaotong/references/reim-workflow.md +53 -42
- package/skills/weaver-e10-yepiaotong/references/source-manifest.json +93 -213
- package/skills/weaver-e10-yimiaoban/SKILL.md +9 -2
- package/skills/weaver-e10-yimiaoban/references/file-user-i18n.md +1 -1
- package/skills/weaver-e10-yimiaoban/references/msg-read.md +1 -1
- package/skills/weaver-e10-yimiaoban/references/source-manifest.json +9 -9
- package/skills/weaver-e10-ziguanjia/SKILL.md +6 -1
- package/dist/shortcuts/invoice/operations/issuing.js +0 -198
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-field-rules.md +0 -161
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-qys-ledger.md +0 -66
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing.md +0 -107
|
@@ -79,7 +79,6 @@ const listProperties = {
|
|
|
79
79
|
const positiveId = { type: 'string', pattern: '^[1-9]\\d*$' };
|
|
80
80
|
const positiveIdArray = { type: 'array', minItems: 1, maxItems: 100, items: positiveId };
|
|
81
81
|
const jsonObject = { type: 'object', additionalProperties: true };
|
|
82
|
-
const requestPayload = { type: 'object', minProperties: 1 };
|
|
83
82
|
const reimFieldValue = {
|
|
84
83
|
type: 'object',
|
|
85
84
|
additionalProperties: false,
|
|
@@ -653,86 +652,36 @@ const reimAutoPrepareOutputSchema = continuationPreviewOutput(reimTemplatePrevie
|
|
|
653
652
|
labels: reimLabelsSchema,
|
|
654
653
|
warnings: arrayOf({ type: 'string' }),
|
|
655
654
|
});
|
|
656
|
-
const makeInvoicePreviewSchema = objectSchema({
|
|
657
|
-
mode: { type: 'string', enum: ['issue', 'ledger'] },
|
|
658
|
-
purchaserName: { type: 'string' },
|
|
659
|
-
purchaserTaxNo: { type: 'string' },
|
|
660
|
-
invoiceType: { type: 'string', enum: ['7', '8', '9', '10'] },
|
|
661
|
-
externalDocumentNo: { type: 'string' },
|
|
662
|
-
totalAmount: stringOrNumber,
|
|
663
|
-
taxAmount: stringOrNumber,
|
|
664
|
-
totalAmountWithTax: stringOrNumber,
|
|
665
|
-
detailCount: { type: 'integer' },
|
|
666
|
-
}, ['mode', 'purchaserName', 'invoiceType', 'externalDocumentNo', 'totalAmount', 'taxAmount', 'totalAmountWithTax', 'detailCount']);
|
|
667
|
-
const issuingPrepareOutputSchema = continuationPreviewOutput(makeInvoicePreviewSchema, { normalizedPayload: requestPayload });
|
|
668
|
-
const issuingApplyOutputSchema = objectSchema({
|
|
669
|
-
mode: { type: 'string', enum: ['issue', 'ledger'] },
|
|
670
|
-
serialNo: { type: 'string' },
|
|
671
|
-
orderNo: { type: 'string' },
|
|
672
|
-
ledgerOnly: { type: 'boolean' },
|
|
673
|
-
result: rawObject,
|
|
674
|
-
workflow: workflowSchema,
|
|
675
|
-
}, ['mode', 'ledgerOnly', 'result', 'workflow']);
|
|
676
|
-
const qysOptionValue = {
|
|
677
|
-
type: ['object', 'null'],
|
|
678
|
-
additionalProperties: false,
|
|
679
|
-
properties: { id: { type: 'string' }, name: { type: 'string' } },
|
|
680
|
-
};
|
|
681
655
|
const nullableText = { type: ['string', 'null'] };
|
|
682
|
-
const qysLedgerRowSchema = objectSchema({
|
|
683
|
-
formDataId: { type: 'string' },
|
|
684
|
-
title: nullableText,
|
|
685
|
-
dataStatus: nullableText,
|
|
686
|
-
contractNo: nullableText,
|
|
687
|
-
contractFlow: qysOptionValue,
|
|
688
|
-
invoiceType: qysOptionValue,
|
|
689
|
-
purchaserName: nullableText,
|
|
690
|
-
purchaserTaxNo: nullableText,
|
|
691
|
-
invoiceItemName: nullableText,
|
|
692
|
-
goodsName: nullableText,
|
|
693
|
-
revenueCode: nullableText,
|
|
694
|
-
taxRate: qysOptionValue,
|
|
695
|
-
quantity: nullableText,
|
|
696
|
-
unitPrice: nullableText,
|
|
697
|
-
amount: { ...nullableText, description: '开票金额(不含税)' },
|
|
698
|
-
invoiceNo: nullableText,
|
|
699
|
-
invoiceFlow: qysOptionValue,
|
|
700
|
-
discarded: qysOptionValue,
|
|
701
|
-
}, ['formDataId'], true);
|
|
702
656
|
const qysListOutputSchema = objectSchema({
|
|
703
657
|
items: arrayOf(objectSchema({
|
|
704
658
|
issuable: { type: 'boolean' },
|
|
705
659
|
blockers: arrayOf({ type: 'string' }),
|
|
706
660
|
}, ['formDataId', 'issuable', 'blockers'], true)),
|
|
661
|
+
groups: arrayOf(objectSchema({
|
|
662
|
+
contractNo: { type: 'string' },
|
|
663
|
+
contractFlowId: { type: 'string', description: '台账「合同审批流程」的流程 ID,用于填开票流程的「相关合同审批流程」' },
|
|
664
|
+
contractFlowName: { type: 'string' },
|
|
665
|
+
purchaserName: { type: 'string' },
|
|
666
|
+
purchaserTaxNo: { type: 'string' },
|
|
667
|
+
purchaserBankName: { type: 'string', description: '购方开户行名称;台账把名称写进账号列时已拆出' },
|
|
668
|
+
purchaserBankAccount: { type: 'string', description: '购方开户行账号(只含账号);台账混写时已去掉开户行名称' },
|
|
669
|
+
invoiceTypes: arrayOf({ type: 'string' }),
|
|
670
|
+
specialInvoiceWithoutTaxNo: { type: 'boolean', description: '购方无税号但台账发票类型是专票;为 true 时不能发起开票流程,需先在台账改为普票' },
|
|
671
|
+
goodsNames: arrayOf({ type: 'string' }),
|
|
672
|
+
taxRates: arrayOf({ type: 'string' }),
|
|
673
|
+
specifications: arrayOf({ type: 'string' }, { description: '可开票行“规格型号”去重(开票流程主表“所售产品版本号”取此值)' }),
|
|
674
|
+
rowCount: { type: 'integer' },
|
|
675
|
+
formDataIds: arrayOf({ type: 'string' }),
|
|
676
|
+
totalAmount: { type: 'string', description: '可开票行“开票金额”合计,按分累加(开票流程按含税金额使用)' },
|
|
677
|
+
blockedRows: { type: 'integer', description: '同组已开票、开票中或已废弃的行数' },
|
|
678
|
+
warnings: arrayOf({ type: 'string' }),
|
|
679
|
+
}, ['contractNo', 'purchaserName', 'purchaserBankName', 'purchaserBankAccount', 'rowCount', 'formDataIds', 'totalAmount', 'blockedRows', 'specialInvoiceWithoutTaxNo', 'warnings'])),
|
|
707
680
|
matched: { type: 'integer' },
|
|
708
681
|
truncated: { type: 'boolean' },
|
|
709
682
|
scanned: { type: 'integer' },
|
|
710
683
|
scanComplete: { type: 'boolean' },
|
|
711
|
-
}, ['items', 'matched', 'truncated', 'scanned', 'scanComplete']);
|
|
712
|
-
const qysPreviewSchema = objectSchema({
|
|
713
|
-
...makeInvoicePreviewSchema.properties,
|
|
714
|
-
formDataId: { type: 'string' },
|
|
715
|
-
contractNo: { type: 'string' },
|
|
716
|
-
contractFlowName: { type: 'string' },
|
|
717
|
-
invoiceTypeName: { type: 'string' },
|
|
718
|
-
goodsName: { type: 'string' },
|
|
719
|
-
taxRate: { type: 'string' },
|
|
720
|
-
}, [...makeInvoicePreviewSchema.required, 'formDataId', 'goodsName', 'taxRate']);
|
|
721
|
-
const qysPrepareOutputSchema = continuationPreviewOutput(qysPreviewSchema, {
|
|
722
|
-
warnings: arrayOf({ type: 'string' }),
|
|
723
|
-
ledgerRow: qysLedgerRowSchema,
|
|
724
|
-
normalizedPayload: requestPayload,
|
|
725
|
-
});
|
|
726
|
-
const issuingResultOutputSchema = objectSchema({
|
|
727
|
-
externalDocumentNo: { type: 'string' },
|
|
728
|
-
state: { type: 'string', enum: ['SUCCESS', 'PENDING', 'FAILED'] },
|
|
729
|
-
returnCode: { type: 'string' },
|
|
730
|
-
returnMessage: { type: 'string' },
|
|
731
|
-
invoiceNo: { type: 'string' },
|
|
732
|
-
invoiceTime: { type: 'string' },
|
|
733
|
-
serialNo: { type: 'string' },
|
|
734
|
-
result: rawObject,
|
|
735
|
-
}, ['externalDocumentNo', 'state', 'returnCode', 'returnMessage', 'invoiceNo', 'result']);
|
|
684
|
+
}, ['items', 'groups', 'matched', 'truncated', 'scanned', 'scanComplete']);
|
|
736
685
|
export const invoiceOperations = [
|
|
737
686
|
{
|
|
738
687
|
name: 'invoice.list',
|
|
@@ -1245,40 +1194,6 @@ export const invoiceOperations = [
|
|
|
1245
1194
|
},
|
|
1246
1195
|
outputSchema: reimAutoPrepareOutputSchema,
|
|
1247
1196
|
},
|
|
1248
|
-
{
|
|
1249
|
-
name: 'invoice.issuing.make.prepare',
|
|
1250
|
-
risk: 'read-before-write',
|
|
1251
|
-
fixed: {
|
|
1252
|
-
path: '/api/inc/book/open/makeInvoice',
|
|
1253
|
-
sellerName: '上海泛微网络科技股份有限公司',
|
|
1254
|
-
taxNo: '9131000070322836XD',
|
|
1255
|
-
},
|
|
1256
|
-
inputSchema: {
|
|
1257
|
-
type: 'object',
|
|
1258
|
-
additionalProperties: false,
|
|
1259
|
-
properties: {
|
|
1260
|
-
mode: { type: 'string', enum: ['issue', 'ledger'] },
|
|
1261
|
-
payload: requestPayload,
|
|
1262
|
-
},
|
|
1263
|
-
required: ['mode', 'payload'],
|
|
1264
|
-
},
|
|
1265
|
-
outputSchema: issuingPrepareOutputSchema,
|
|
1266
|
-
},
|
|
1267
|
-
{
|
|
1268
|
-
name: 'invoice.issuing.make.apply',
|
|
1269
|
-
risk: 'high-risk-write',
|
|
1270
|
-
inputSchema: {
|
|
1271
|
-
type: 'object',
|
|
1272
|
-
additionalProperties: false,
|
|
1273
|
-
properties: {
|
|
1274
|
-
payload: requestPayload,
|
|
1275
|
-
continuation: { type: 'string', minLength: 1 },
|
|
1276
|
-
confirm: { const: true },
|
|
1277
|
-
},
|
|
1278
|
-
required: ['payload', 'continuation', 'confirm'],
|
|
1279
|
-
},
|
|
1280
|
-
outputSchema: issuingApplyOutputSchema,
|
|
1281
|
-
},
|
|
1282
1197
|
{
|
|
1283
1198
|
name: 'invoice.issuing.qys.list',
|
|
1284
1199
|
risk: 'read',
|
|
@@ -1289,47 +1204,12 @@ export const invoiceOperations = [
|
|
|
1289
1204
|
properties: {
|
|
1290
1205
|
keyword: { type: 'string', description: '模糊匹配合同号、购买方名称、合同审批流程名称、商品名称或开票名称' },
|
|
1291
1206
|
contractNo: { type: 'string', description: '按合同号精确筛选' },
|
|
1292
|
-
includeIssued: { type: 'boolean', default: false, description: '是否包含已开票、开票中或已废弃的行。默认 false
|
|
1207
|
+
includeIssued: { type: 'boolean', default: false, description: '是否包含已开票、开票中或已废弃的行。默认 false 只返回可开票行;groups 始终按合同号+购方汇总,blockedRows 计不可开票行数。' },
|
|
1293
1208
|
limit: { type: 'integer', minimum: 1, maximum: 100, default: 20 },
|
|
1294
1209
|
},
|
|
1295
1210
|
},
|
|
1296
1211
|
outputSchema: qysListOutputSchema,
|
|
1297
1212
|
},
|
|
1298
|
-
{
|
|
1299
|
-
name: 'invoice.issuing.qys.prepare',
|
|
1300
|
-
risk: 'read-before-write',
|
|
1301
|
-
fixed: {
|
|
1302
|
-
path: '/api/ebuilder/form/eblist/getData',
|
|
1303
|
-
externalDocumentNo: 'QYS-{formDataId}',
|
|
1304
|
-
amountBasis: '开票金额为不含税金额,taxSign=0,税额=金额×税率四舍五入到分',
|
|
1305
|
-
applyOperation: 'invoice.issuing.make.apply',
|
|
1306
|
-
},
|
|
1307
|
-
inputSchema: {
|
|
1308
|
-
type: 'object',
|
|
1309
|
-
additionalProperties: false,
|
|
1310
|
-
properties: {
|
|
1311
|
-
formDataId: { type: 'string', pattern: '^\\d+$', description: 'invoice.issuing.qys.list 返回的台账行 formDataId' },
|
|
1312
|
-
mode: { type: 'string', enum: ['issue', 'ledger'] },
|
|
1313
|
-
},
|
|
1314
|
-
required: ['formDataId', 'mode'],
|
|
1315
|
-
},
|
|
1316
|
-
outputSchema: qysPrepareOutputSchema,
|
|
1317
|
-
},
|
|
1318
|
-
{
|
|
1319
|
-
name: 'invoice.issuing.result',
|
|
1320
|
-
risk: 'read',
|
|
1321
|
-
fixed: { path: '/api/inc/book/open/getMakeInvoiceResult', taxNo: '9131000070322836XD' },
|
|
1322
|
-
inputSchema: {
|
|
1323
|
-
type: 'object',
|
|
1324
|
-
additionalProperties: false,
|
|
1325
|
-
properties: {
|
|
1326
|
-
externalDocumentNo: { type: 'string', minLength: 1 },
|
|
1327
|
-
serialNo: { type: 'string' },
|
|
1328
|
-
},
|
|
1329
|
-
required: ['externalDocumentNo'],
|
|
1330
|
-
},
|
|
1331
|
-
outputSchema: issuingResultOutputSchema,
|
|
1332
|
-
},
|
|
1333
1213
|
];
|
|
1334
1214
|
export const invoiceManifest = {
|
|
1335
1215
|
schemaVersion: 1,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { InvoiceCliError, invoiceValidationError } from '../errors.js';
|
|
2
|
-
import {
|
|
3
|
-
import { asNonEmptyString, assertBusinessSuccess, objectFingerprint, workflow } from './shared.js';
|
|
2
|
+
import { asNonEmptyString, assertBusinessSuccess } from './shared.js';
|
|
4
3
|
const LEDGER_PATH = '/api/ebuilder/form/eblist/getData';
|
|
5
4
|
const LEDGER_PAGE_ID = '1314988320430981804';
|
|
6
5
|
const LEDGER_APP_ID = '846297243998732291';
|
|
@@ -8,7 +7,6 @@ const LEDGER_MENU_ID = '5419015526244625718';
|
|
|
8
7
|
const LEDGER_PAGE_TITLE = '5aWR57qm6ZSB5ZCI5ZCM5ZWG5ZOB5L h5oGv';
|
|
9
8
|
const LEDGER_PAGE_SIZE = 50;
|
|
10
9
|
const LEDGER_MAX_PAGES = 40;
|
|
11
|
-
const RESULT_PATH = '/api/inc/book/open/getMakeInvoiceResult';
|
|
12
10
|
/** 契约锁合同商品信息表:数据 key → 可读字段。 */
|
|
13
11
|
export const QYS_LEDGER_FIELDS = [
|
|
14
12
|
{ id: '1314988311673275798', key: 'contractNo', label: '合同号', kind: 'text' },
|
|
@@ -92,15 +90,6 @@ function toCents(value, name) {
|
|
|
92
90
|
function formatCents(cents) {
|
|
93
91
|
return `${Math.floor(cents / 100)}.${String(cents % 100).padStart(2, '0')}`;
|
|
94
92
|
}
|
|
95
|
-
/** “6.0%” → 600(万分比),只接受开票接口支持的税率。 */
|
|
96
|
-
export function parseTaxRateBasisPoints(name) {
|
|
97
|
-
const match = typeof name === 'string' ? /^\s*(\d+(?:\.\d+)?)\s*%\s*$/u.exec(name) : null;
|
|
98
|
-
const basisPoints = match ? Math.round(Number(match[1]) * 100) : Number.NaN;
|
|
99
|
-
if (![0, 100, 300, 500, 600, 900, 1300].includes(basisPoints)) {
|
|
100
|
-
throw invoiceValidationError('ledger_tax_rate_invalid', `商品税率无法识别或不在允许范围内:${name ?? '空'}`);
|
|
101
|
-
}
|
|
102
|
-
return basisPoints;
|
|
103
|
-
}
|
|
104
93
|
function isPositiveCents(value) {
|
|
105
94
|
return value !== null && /^\d+(?:\.\d+)?$/u.test(value) && Number(value) > 0;
|
|
106
95
|
}
|
|
@@ -168,6 +157,136 @@ function matchesKeyword(row, keyword) {
|
|
|
168
157
|
const haystack = [row.contractNo, row.purchaserName, row.contractFlow?.name, row.goodsName, row.invoiceItemName, row.formDataId];
|
|
169
158
|
return haystack.some((value) => typeof value === 'string' && value.includes(keyword));
|
|
170
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* 台账常把开户行名称和账号一起写进「购买方开户行账号」(如 `招商银行福田支行 8135 8668 8310 001`)。
|
|
162
|
+
* 拆成名称与账号两段:账号取末尾(或开头)连续的数字段,原样保留其中的空格和连字符。
|
|
163
|
+
*/
|
|
164
|
+
export function splitBankNameAndAccount(bankName, bankAccount) {
|
|
165
|
+
const name = (bankName ?? '').trim();
|
|
166
|
+
const account = (bankAccount ?? '').trim();
|
|
167
|
+
const trailing = /^(.*?[^\d\s-])\s*(\d[\d\s-]*\d)$/u.exec(account);
|
|
168
|
+
const leading = trailing ? null : /^(\d[\d\s-]*\d)\s*([^\d\s-].*)$/u.exec(account);
|
|
169
|
+
const rawText = trailing ? trailing[1] : leading ? leading[2] : '';
|
|
170
|
+
const textPart = rawText
|
|
171
|
+
.replace(/[\s,,;;::]*(?:银行账号|银行帐号|账号|帐号|账户|帐户)?[\s,,;;::]*$/u, '')
|
|
172
|
+
.replace(/^[\s,,;;::]*(?:开户行|开户银行)?[\s,,;;::]*/u, '')
|
|
173
|
+
.trim();
|
|
174
|
+
const digitPart = trailing ? trailing[2] : leading ? leading[1] : '';
|
|
175
|
+
if (!textPart || !digitPart)
|
|
176
|
+
return { bankName: name, bankAccount: account, split: false };
|
|
177
|
+
return { bankName: name || textPart, bankAccount: digitPart, split: true };
|
|
178
|
+
}
|
|
179
|
+
export function isSpecialInvoiceTypeName(name) {
|
|
180
|
+
return name.includes('专票') || name.includes('专用发票');
|
|
181
|
+
}
|
|
182
|
+
/** 一张开票流程对应一个“合同号 + 购方”分组;金额只累计可开票行。 */
|
|
183
|
+
export class QysLedgerGrouper {
|
|
184
|
+
groups = new Map();
|
|
185
|
+
add(row, blocked) {
|
|
186
|
+
const contractNo = row.contractNo ?? '';
|
|
187
|
+
const purchaserName = row.purchaserName ?? '';
|
|
188
|
+
const key = `${contractNo}|${purchaserName}`;
|
|
189
|
+
let group = this.groups.get(key);
|
|
190
|
+
if (!group) {
|
|
191
|
+
group = {
|
|
192
|
+
contractNo,
|
|
193
|
+
contractFlowId: row.contractFlow?.id ?? '',
|
|
194
|
+
contractFlowName: row.contractFlow?.name ?? '',
|
|
195
|
+
purchaserName,
|
|
196
|
+
purchaserTaxNos: new Set(),
|
|
197
|
+
invoiceTypes: new Set(),
|
|
198
|
+
goodsNames: new Set(),
|
|
199
|
+
taxRates: new Set(),
|
|
200
|
+
specifications: new Set(),
|
|
201
|
+
bankName: null,
|
|
202
|
+
bankAccount: null,
|
|
203
|
+
formDataIds: [],
|
|
204
|
+
amountCents: 0,
|
|
205
|
+
invalidAmountRows: [],
|
|
206
|
+
blockedRows: 0,
|
|
207
|
+
};
|
|
208
|
+
this.groups.set(key, group);
|
|
209
|
+
}
|
|
210
|
+
if (blocked) {
|
|
211
|
+
group.blockedRows += 1;
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
group.formDataIds.push(row.formDataId);
|
|
215
|
+
if (!group.contractFlowId && row.contractFlow) {
|
|
216
|
+
group.contractFlowId = row.contractFlow.id;
|
|
217
|
+
group.contractFlowName = row.contractFlow.name;
|
|
218
|
+
}
|
|
219
|
+
if (row.purchaserTaxNo)
|
|
220
|
+
group.purchaserTaxNos.add(row.purchaserTaxNo);
|
|
221
|
+
if (row.invoiceType?.name)
|
|
222
|
+
group.invoiceTypes.add(row.invoiceType.name);
|
|
223
|
+
const goodsName = row.invoiceItemName ?? row.goodsName;
|
|
224
|
+
if (goodsName)
|
|
225
|
+
group.goodsNames.add(goodsName);
|
|
226
|
+
if (row.taxRate?.name)
|
|
227
|
+
group.taxRates.add(row.taxRate.name);
|
|
228
|
+
if (row.specification)
|
|
229
|
+
group.specifications.add(row.specification);
|
|
230
|
+
if (group.bankName === null && group.bankAccount === null && (row.purchaserBankName || row.purchaserBankAccount)) {
|
|
231
|
+
group.bankName = row.purchaserBankName ?? null;
|
|
232
|
+
group.bankAccount = row.purchaserBankAccount ?? null;
|
|
233
|
+
}
|
|
234
|
+
if (row.amount !== null && /^\d+(?:\.\d{1,2})?$/u.test(row.amount)) {
|
|
235
|
+
group.amountCents += toCents(row.amount, '开票金额');
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
group.invalidAmountRows.push(row.formDataId);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
result(includeEmpty) {
|
|
242
|
+
const output = [];
|
|
243
|
+
for (const group of this.groups.values()) {
|
|
244
|
+
if (!includeEmpty && group.formDataIds.length === 0)
|
|
245
|
+
continue;
|
|
246
|
+
const warnings = [];
|
|
247
|
+
const specialTypes = [...group.invoiceTypes].filter(isSpecialInvoiceTypeName);
|
|
248
|
+
const specialInvoiceWithoutTaxNo = group.purchaserTaxNos.size === 0 && specialTypes.length > 0;
|
|
249
|
+
if (specialInvoiceWithoutTaxNo) {
|
|
250
|
+
warnings.push(`购方无税号,不能开专票(台账发票类型:${specialTypes.join('、')}),请先在台账改为普票再发起`);
|
|
251
|
+
}
|
|
252
|
+
const bank = splitBankNameAndAccount(group.bankName, group.bankAccount);
|
|
253
|
+
if (bank.split) {
|
|
254
|
+
warnings.push(`台账「购买方开户行账号」混有开户行名称,已拆分为开户行名称「${bank.bankName}」、账号「${bank.bankAccount}」`);
|
|
255
|
+
}
|
|
256
|
+
if (!group.contractNo)
|
|
257
|
+
warnings.push('台账行缺少合同号,无法按合同号发起开票流程');
|
|
258
|
+
if (group.invoiceTypes.size > 1)
|
|
259
|
+
warnings.push(`同组发票类型不一致:${[...group.invoiceTypes].join('、')}`);
|
|
260
|
+
if (group.purchaserTaxNos.size > 1)
|
|
261
|
+
warnings.push(`同组购方税号不一致:${[...group.purchaserTaxNos].join('、')}`);
|
|
262
|
+
if (group.invalidAmountRows.length)
|
|
263
|
+
warnings.push(`开票金额无法识别,未计入合计:${group.invalidAmountRows.join('、')}`);
|
|
264
|
+
if (group.blockedRows > 0) {
|
|
265
|
+
warnings.push(`同合同另有 ${group.blockedRows} 行已开票、开票中或已废弃,流程联动可能一并带出,请在 E10 核对明细`);
|
|
266
|
+
}
|
|
267
|
+
output.push({
|
|
268
|
+
contractNo: group.contractNo,
|
|
269
|
+
contractFlowId: group.contractFlowId,
|
|
270
|
+
contractFlowName: group.contractFlowName,
|
|
271
|
+
purchaserName: group.purchaserName,
|
|
272
|
+
purchaserTaxNo: [...group.purchaserTaxNos].join('、'),
|
|
273
|
+
purchaserBankName: bank.bankName,
|
|
274
|
+
purchaserBankAccount: bank.bankAccount,
|
|
275
|
+
invoiceTypes: [...group.invoiceTypes],
|
|
276
|
+
specialInvoiceWithoutTaxNo,
|
|
277
|
+
goodsNames: [...group.goodsNames],
|
|
278
|
+
taxRates: [...group.taxRates],
|
|
279
|
+
specifications: [...group.specifications],
|
|
280
|
+
rowCount: group.formDataIds.length,
|
|
281
|
+
formDataIds: group.formDataIds,
|
|
282
|
+
totalAmount: formatCents(group.amountCents),
|
|
283
|
+
blockedRows: group.blockedRows,
|
|
284
|
+
warnings,
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
return output;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
171
290
|
export class InvoiceIssuingQysListOperation {
|
|
172
291
|
name = 'invoice.issuing.qys.list';
|
|
173
292
|
async execute(input, { host }) {
|
|
@@ -178,6 +297,7 @@ export class InvoiceIssuingQysListOperation {
|
|
|
178
297
|
if (!Number.isInteger(limit) || limit < 1 || limit > 100)
|
|
179
298
|
throw invoiceValidationError('input_invalid', 'limit 必须是 1-100 的整数');
|
|
180
299
|
const items = [];
|
|
300
|
+
const grouper = new QysLedgerGrouper();
|
|
181
301
|
let matched = 0;
|
|
182
302
|
const scan = await scanLedger(host, this.name, (row) => {
|
|
183
303
|
if (contractNo && row.contractNo !== contractNo)
|
|
@@ -185,6 +305,7 @@ export class InvoiceIssuingQysListOperation {
|
|
|
185
305
|
if (keyword && !matchesKeyword(row, keyword))
|
|
186
306
|
return false;
|
|
187
307
|
const blockers = qysRowBlockers(row);
|
|
308
|
+
grouper.add(row, blockers.length > 0);
|
|
188
309
|
if (!includeIssued && blockers.length)
|
|
189
310
|
return false;
|
|
190
311
|
matched += 1;
|
|
@@ -196,6 +317,7 @@ export class InvoiceIssuingQysListOperation {
|
|
|
196
317
|
status: 'COMPLETE',
|
|
197
318
|
data: {
|
|
198
319
|
items,
|
|
320
|
+
groups: grouper.result(includeIssued),
|
|
199
321
|
matched,
|
|
200
322
|
truncated: matched > items.length,
|
|
201
323
|
scanned: scan.scanned,
|
|
@@ -204,158 +326,3 @@ export class InvoiceIssuingQysListOperation {
|
|
|
204
326
|
};
|
|
205
327
|
}
|
|
206
328
|
}
|
|
207
|
-
export function buildQysMakeInvoicePayload(row) {
|
|
208
|
-
const warnings = [];
|
|
209
|
-
const invoiceType = row.invoiceType?.id;
|
|
210
|
-
if (!invoiceType)
|
|
211
|
-
throw invoiceValidationError('ledger_field_missing', '台账行缺少发票类型');
|
|
212
|
-
const goodsName = row.invoiceItemName ?? row.goodsName;
|
|
213
|
-
if (!goodsName)
|
|
214
|
-
throw invoiceValidationError('ledger_field_missing', '台账行缺少开票名称和商品名称');
|
|
215
|
-
if (!row.purchaserName)
|
|
216
|
-
throw invoiceValidationError('ledger_field_missing', '台账行缺少购买方名称');
|
|
217
|
-
const basisPoints = parseTaxRateBasisPoints(row.taxRate?.name);
|
|
218
|
-
const amountCents = toCents(row.amount, '开票金额');
|
|
219
|
-
if (amountCents === 0)
|
|
220
|
-
throw invoiceValidationError('ledger_amount_invalid', '开票金额必须大于 0');
|
|
221
|
-
const taxCents = Math.floor((amountCents * basisPoints + 5000) / 10000);
|
|
222
|
-
const amount = formatCents(amountCents);
|
|
223
|
-
const taxAmount = formatCents(taxCents);
|
|
224
|
-
const amountWithTax = formatCents(amountCents + taxCents);
|
|
225
|
-
if (row.quantity !== null && row.unitPrice !== null) {
|
|
226
|
-
const expected = Number(row.quantity) * Number(row.unitPrice);
|
|
227
|
-
if (!Number.isFinite(expected) || Math.abs(expected * 100 - amountCents) > 1) {
|
|
228
|
-
warnings.push(`商品数量 ${row.quantity} × 商品单价 ${row.unitPrice} 与开票金额 ${row.amount} 不一致`);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
if (row.uninvoicedAmount !== null && row.uninvoicedAmount !== row.amount && Number(row.uninvoicedAmount) !== Number(row.amount)) {
|
|
232
|
-
warnings.push(`未开票金额 ${row.uninvoicedAmount} 与开票金额 ${row.amount} 不一致,本次按开票金额全额开具`);
|
|
233
|
-
}
|
|
234
|
-
if (row.dataStatus && row.dataStatus !== '提交')
|
|
235
|
-
warnings.push(`台账数据状态为“${row.dataStatus}”`);
|
|
236
|
-
const detail = {
|
|
237
|
-
goodsName,
|
|
238
|
-
taxSign: '0',
|
|
239
|
-
taxRate: basisPoints / 10000,
|
|
240
|
-
amount,
|
|
241
|
-
taxAmount,
|
|
242
|
-
amountWithTax,
|
|
243
|
-
};
|
|
244
|
-
for (const key of ['revenueCode', 'specification', 'unit', 'quantity', 'unitPrice']) {
|
|
245
|
-
if (row[key] !== null)
|
|
246
|
-
detail[key] = row[key];
|
|
247
|
-
}
|
|
248
|
-
const payload = {
|
|
249
|
-
invoiceType,
|
|
250
|
-
externalDocumentNo: `QYS-${row.formDataId}`,
|
|
251
|
-
purchaserName: row.purchaserName,
|
|
252
|
-
taxSign: '0',
|
|
253
|
-
totalAmount: amount,
|
|
254
|
-
taxAmount,
|
|
255
|
-
totalAmountWithTax: amountWithTax,
|
|
256
|
-
details: [detail],
|
|
257
|
-
};
|
|
258
|
-
for (const key of ['purchaserTaxNo', 'purchaserAddress', 'purchaserTel', 'purchaserBankName', 'purchaserBankAccount']) {
|
|
259
|
-
if (row[key] !== null)
|
|
260
|
-
payload[key] = row[key];
|
|
261
|
-
}
|
|
262
|
-
return { payload, warnings };
|
|
263
|
-
}
|
|
264
|
-
export class InvoiceIssuingQysPrepareOperation {
|
|
265
|
-
name = 'invoice.issuing.qys.prepare';
|
|
266
|
-
async execute(input, { host, continuation }) {
|
|
267
|
-
const mode = normalizeMode(input.mode);
|
|
268
|
-
const formDataId = asNonEmptyString(input.formDataId, 'formDataId');
|
|
269
|
-
if (!/^\d+$/u.test(formDataId))
|
|
270
|
-
throw invoiceValidationError('input_invalid', 'formDataId 必须是台账行的数字 ID');
|
|
271
|
-
let row;
|
|
272
|
-
const scan = await scanLedger(host, this.name, (candidate) => {
|
|
273
|
-
if (candidate.formDataId !== formDataId)
|
|
274
|
-
return false;
|
|
275
|
-
row = candidate;
|
|
276
|
-
return true;
|
|
277
|
-
});
|
|
278
|
-
if (!row) {
|
|
279
|
-
throw invoiceValidationError('ledger_row_not_found', `契约锁开票台账中未找到 formDataId=${formDataId} 的行`, {
|
|
280
|
-
scanned: scan.scanned,
|
|
281
|
-
scanComplete: scan.complete,
|
|
282
|
-
});
|
|
283
|
-
}
|
|
284
|
-
const blockers = qysRowBlockers(row);
|
|
285
|
-
if (blockers.length) {
|
|
286
|
-
throw invoiceValidationError('ledger_row_not_issuable', `该台账行不能开票:${blockers.join(';')}`, { formDataId, blockers });
|
|
287
|
-
}
|
|
288
|
-
const { payload, warnings } = buildQysMakeInvoicePayload(row);
|
|
289
|
-
const normalizedPayload = normalizeMakeInvoicePayload(payload, mode);
|
|
290
|
-
const preview = {
|
|
291
|
-
...makeInvoicePreview(normalizedPayload, mode),
|
|
292
|
-
formDataId,
|
|
293
|
-
contractNo: row.contractNo ?? '',
|
|
294
|
-
contractFlowName: row.contractFlow?.name ?? '',
|
|
295
|
-
invoiceTypeName: row.invoiceType?.name ?? '',
|
|
296
|
-
goodsName: normalizedPayload.details[0].goodsName,
|
|
297
|
-
taxRate: row.taxRate?.name ?? '',
|
|
298
|
-
};
|
|
299
|
-
const session = await host.getSession();
|
|
300
|
-
const continuationToken = await continuation.issue({
|
|
301
|
-
operation: 'invoice.issuing.make.apply',
|
|
302
|
-
workflow: workflow('invoice.issuing.make', 'AWAITING_CONFIRMATION'),
|
|
303
|
-
baseUrl: session.baseUrl,
|
|
304
|
-
profile: session.profile,
|
|
305
|
-
userId: session.userId,
|
|
306
|
-
mode,
|
|
307
|
-
fingerprint: objectFingerprint(normalizedPayload),
|
|
308
|
-
preview,
|
|
309
|
-
});
|
|
310
|
-
return {
|
|
311
|
-
status: 'AWAITING_CONFIRMATION',
|
|
312
|
-
data: {
|
|
313
|
-
preview,
|
|
314
|
-
warnings,
|
|
315
|
-
ledgerRow: row,
|
|
316
|
-
normalizedPayload,
|
|
317
|
-
continuation: continuationToken,
|
|
318
|
-
expiresInSeconds: 600,
|
|
319
|
-
workflow: workflow('invoice.issuing.make', 'AWAITING_CONFIRMATION'),
|
|
320
|
-
},
|
|
321
|
-
};
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
function resultState(returnCode) {
|
|
325
|
-
if (returnCode === '00')
|
|
326
|
-
return 'SUCCESS';
|
|
327
|
-
if (returnCode === '01')
|
|
328
|
-
return 'PENDING';
|
|
329
|
-
return 'FAILED';
|
|
330
|
-
}
|
|
331
|
-
export class InvoiceIssuingResultOperation {
|
|
332
|
-
name = 'invoice.issuing.result';
|
|
333
|
-
async execute(input, { host }) {
|
|
334
|
-
const externalDocumentNo = asNonEmptyString(input.externalDocumentNo, 'externalDocumentNo');
|
|
335
|
-
const invoiceReq = { businessNo: externalDocumentNo, taxNo: SELLER_TAX_NO };
|
|
336
|
-
if (input.serialNo !== undefined && input.serialNo !== '')
|
|
337
|
-
invoiceReq.serialNo = asNonEmptyString(input.serialNo, 'serialNo');
|
|
338
|
-
const result = await host.invoiceRequest({
|
|
339
|
-
path: RESULT_PATH,
|
|
340
|
-
method: 'POST',
|
|
341
|
-
body: { invoiceReq },
|
|
342
|
-
operation: this.name,
|
|
343
|
-
timeoutMs: 60_000,
|
|
344
|
-
});
|
|
345
|
-
assertBusinessSuccess(result, 'issuing_result_failed', '查询开票结果失败');
|
|
346
|
-
const data = result?.data || {};
|
|
347
|
-
return {
|
|
348
|
-
status: 'COMPLETE',
|
|
349
|
-
data: {
|
|
350
|
-
externalDocumentNo,
|
|
351
|
-
state: resultState(data.returnCode),
|
|
352
|
-
returnCode: data.returnCode ?? '',
|
|
353
|
-
returnMessage: data.returnMessage ?? '',
|
|
354
|
-
invoiceNo: data.digitInvoiceNo || data.invoiceNo || '',
|
|
355
|
-
invoiceTime: data.invoiceTime ?? '',
|
|
356
|
-
serialNo: data.serialNo ?? '',
|
|
357
|
-
result,
|
|
358
|
-
},
|
|
359
|
-
};
|
|
360
|
-
}
|
|
361
|
-
}
|
|
@@ -6,8 +6,7 @@ import { InvoiceDeleteApplyOperation, InvoiceDeletePrepareOperation } from './de
|
|
|
6
6
|
import { InvoiceDownloadOperation } from './download.js';
|
|
7
7
|
import { InvoiceGetOperation } from './get.js';
|
|
8
8
|
import { InvoiceImportApplyOperation, InvoiceImportPrepareOperation } from './import.js';
|
|
9
|
-
import {
|
|
10
|
-
import { InvoiceIssuingQysListOperation, InvoiceIssuingQysPrepareOperation, InvoiceIssuingResultOperation, } from './issuing-qys.js';
|
|
9
|
+
import { InvoiceIssuingQysListOperation } from './issuing-qys.js';
|
|
11
10
|
import { InvoiceListOperation } from './list.js';
|
|
12
11
|
import { InvoiceOcrPreviewOperation } from './ocr-preview.js';
|
|
13
12
|
import { InvoiceReimEmployeeSuperiorsOperation, InvoiceReimFieldSearchOperation, InvoiceReimFileOcrPreviewOperation, InvoiceReimFlowCreateApplyOperation, InvoiceReimFlowCreatePrepareOperation, InvoiceReimFlowUpdateApplyOperation, InvoiceReimFlowUpdatePrepareOperation, InvoiceReimFormStructureOperation, InvoiceReimRequestsListOperation, InvoiceReimRowInfoBatchOperation, InvoiceReimRowInfoOperation, InvoiceReimWorkflowResolveOperation, } from './reim.js';
|
|
@@ -51,11 +50,7 @@ function buildRegistry() {
|
|
|
51
50
|
new InvoiceReimFlowCreateApplyOperation(),
|
|
52
51
|
new InvoiceReimFlowUpdatePrepareOperation(),
|
|
53
52
|
new InvoiceReimFlowUpdateApplyOperation(),
|
|
54
|
-
new InvoiceIssuingMakePrepareOperation(),
|
|
55
|
-
new InvoiceIssuingMakeApplyOperation(),
|
|
56
53
|
new InvoiceIssuingQysListOperation(),
|
|
57
|
-
new InvoiceIssuingQysPrepareOperation(),
|
|
58
|
-
new InvoiceIssuingResultOperation(),
|
|
59
54
|
];
|
|
60
55
|
for (const handler of handlers) {
|
|
61
56
|
if (registry.has(handler.name))
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { E10_SESSION_EXPIRED_MESSAGE } from '../../internal/e10/auth/messages.js';
|
|
1
2
|
import { requireE10Session } from '../../internal/e10/context.js';
|
|
2
3
|
import { getActiveProfile } from '../../internal/e10/auth/session.js';
|
|
3
4
|
import { E10ApiError, createE10RequestRuntime } from '../../internal/e10/request-runtime.js';
|
|
@@ -127,7 +128,7 @@ export function createJiuchuanhuiHost(ctx, dependencies = {}) {
|
|
|
127
128
|
mapRuntimeNetworkError(error);
|
|
128
129
|
}
|
|
129
130
|
if (response.status === 401 || response.status === 302) {
|
|
130
|
-
throw jiuchuanhuiAuthError('session_expired',
|
|
131
|
+
throw jiuchuanhuiAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
131
132
|
}
|
|
132
133
|
if (response.parseError) {
|
|
133
134
|
if (response.status < 200 || response.status >= 300) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { randomBytes } from 'node:crypto';
|
|
2
|
+
import { E10_SESSION_EXPIRED_MESSAGE } from '../../internal/e10/auth/messages.js';
|
|
2
3
|
import { requireE10Session } from '../../internal/e10/context.js';
|
|
3
4
|
import { getActiveProfile } from '../../internal/e10/auth/session.js';
|
|
4
5
|
import { E10ApiError, createE10RequestRuntime } from '../../internal/e10/request-runtime.js';
|
|
@@ -149,7 +150,7 @@ export function createMailHost(ctx, dependencies = {}) {
|
|
|
149
150
|
throw error;
|
|
150
151
|
}
|
|
151
152
|
if (response.status === 401 || response.status === 302) {
|
|
152
|
-
throw mailAuthError('session_expired',
|
|
153
|
+
throw mailAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
153
154
|
}
|
|
154
155
|
if (response.parseError) {
|
|
155
156
|
if (response.status < 200 || response.status >= 300) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { E10_SESSION_EXPIRED_MESSAGE } from '../../internal/e10/auth/messages.js';
|
|
1
2
|
import { requireE10Session } from '../../internal/e10/context.js';
|
|
2
3
|
import { getActiveProfile } from '../../internal/e10/auth/session.js';
|
|
3
4
|
import { E10ApiError, createE10RequestRuntime } from '../../internal/e10/request-runtime.js';
|
|
@@ -142,7 +143,7 @@ export function createMeetingHost(ctx, dependencies = {}) {
|
|
|
142
143
|
mapRuntimeNetworkError(error);
|
|
143
144
|
}
|
|
144
145
|
if (response.status === 401 || response.status === 302) {
|
|
145
|
-
throw meetingAuthError('session_expired',
|
|
146
|
+
throw meetingAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
146
147
|
}
|
|
147
148
|
if (response.parseError) {
|
|
148
149
|
if (response.status < 200 || response.status >= 300) {
|