@things-factory/invoice 10.1.208 → 10.1.209

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.
Files changed (48) hide show
  1. package/dist-client/document/document-form.d.ts +2 -1
  2. package/dist-client/document/document-form.js +3 -2
  3. package/dist-client/document/document-form.js.map +1 -1
  4. package/dist-client/document/document-print.d.ts +2 -1
  5. package/dist-client/document/document-print.js +2 -2
  6. package/dist-client/document/document-print.js.map +1 -1
  7. package/dist-client/entity360/invoice-360.d.ts +8 -0
  8. package/dist-client/entity360/invoice-360.js +12 -2
  9. package/dist-client/entity360/invoice-360.js.map +1 -1
  10. package/dist-client/invoice-files.d.ts +32 -0
  11. package/dist-client/invoice-files.js +249 -0
  12. package/dist-client/invoice-files.js.map +1 -0
  13. package/dist-client/pages/invoice-editor.d.ts +16 -0
  14. package/dist-client/pages/invoice-editor.js +88 -3
  15. package/dist-client/pages/invoice-editor.js.map +1 -1
  16. package/dist-client/pages/invoice-list.js +8 -4
  17. package/dist-client/pages/invoice-list.js.map +1 -1
  18. package/dist-client/tsconfig.tsbuildinfo +1 -1
  19. package/dist-server/service/index.d.ts +1 -0
  20. package/dist-server/service/index.js +1 -0
  21. package/dist-server/service/index.js.map +1 -1
  22. package/dist-server/service/invoice/index.d.ts +1 -1
  23. package/dist-server/service/invoice/invoice-files.d.ts +14 -0
  24. package/dist-server/service/invoice/invoice-files.js +43 -0
  25. package/dist-server/service/invoice/invoice-files.js.map +1 -0
  26. package/dist-server/service/invoice/invoice-mutation.d.ts +2 -0
  27. package/dist-server/service/invoice/invoice-mutation.js +18 -0
  28. package/dist-server/service/invoice/invoice-mutation.js.map +1 -1
  29. package/dist-server/service/invoice/invoice-query.d.ts +4 -0
  30. package/dist-server/service/invoice/invoice-query.js +23 -0
  31. package/dist-server/service/invoice/invoice-query.js.map +1 -1
  32. package/dist-server/service/invoice/invoice-rules.d.ts +2 -2
  33. package/dist-server/service/invoice/invoice-service.js +5 -0
  34. package/dist-server/service/invoice/invoice-service.js.map +1 -1
  35. package/dist-server/service/invoice/invoice-type.d.ts +1 -0
  36. package/dist-server/service/invoice/invoice-type.js +4 -0
  37. package/dist-server/service/invoice/invoice-type.js.map +1 -1
  38. package/dist-server/service/invoice/invoice.d.ts +3 -0
  39. package/dist-server/service/invoice/invoice.js +11 -0
  40. package/dist-server/service/invoice/invoice.js.map +1 -1
  41. package/dist-server/tsconfig.tsbuildinfo +1 -1
  42. package/package.json +8 -3
  43. package/translations/en.json +13 -1
  44. package/translations/es.json +13 -1
  45. package/translations/ja.json +13 -1
  46. package/translations/ko.json +13 -1
  47. package/translations/ms.json +13 -1
  48. package/translations/zh.json +13 -1
@@ -4,6 +4,7 @@ export * from './invoice/invoice';
4
4
  export * from './invoice/commercial-document';
5
5
  export * from './invoice/invoice-rules';
6
6
  export * from './invoice/invoice-service';
7
+ export * from './invoice/invoice-files';
7
8
  export * from './invoice/invoice-type';
8
9
  export declare const entities: any[];
9
10
  export declare const subscribers: any[];
@@ -8,6 +8,7 @@ tslib_1.__exportStar(require("./invoice/invoice"), exports);
8
8
  tslib_1.__exportStar(require("./invoice/commercial-document"), exports);
9
9
  tslib_1.__exportStar(require("./invoice/invoice-rules"), exports);
10
10
  tslib_1.__exportStar(require("./invoice/invoice-service"), exports);
11
+ tslib_1.__exportStar(require("./invoice/invoice-files"), exports);
11
12
  tslib_1.__exportStar(require("./invoice/invoice-type"), exports);
12
13
  const invoice = tslib_1.__importStar(require("./invoice"));
13
14
  const invoiceEvent = tslib_1.__importStar(require("./invoice-event"));
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/service/index.ts"],"names":[],"mappings":";;;;AAAA,wEAA6C;AAC7C,sEAA2C;AAC3C,4DAAiC;AACjC,wEAA6C;AAC7C,kEAAuC;AACvC,oEAAyC;AACzC,iEAAsC;AACtC,2DAAoC;AACpC,sEAA+C;AAC/C,oEAA6C;AAC7C,MAAM,OAAO,GAAgE,CAAC,OAAO,EAAE,WAAW,EAAE,YAAY,CAAC,CAAA;AACpG,QAAA,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;AAC/C,QAAA,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;AACrD,QAAA,MAAM,GAAG,EAAE,eAAe,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAA","sourcesContent":["export * from './invoice-event/invoice-event'\nexport * from './invoice-item/invoice-item'\nexport * from './invoice/invoice'\nexport * from './invoice/commercial-document'\nexport * from './invoice/invoice-rules'\nexport * from './invoice/invoice-service'\nexport * from './invoice/invoice-type'\nimport * as invoice from './invoice'\nimport * as invoiceEvent from './invoice-event'\nimport * as invoiceItem from './invoice-item'\nconst modules: { entities: any[]; subscribers: any[]; resolvers: any[] }[] = [invoice, invoiceItem, invoiceEvent]\nexport const entities = modules.flatMap(one => one.entities)\nexport const subscribers = modules.flatMap(one => one.subscribers)\nexport const schema = { resolverClasses: modules.flatMap(one => one.resolvers) }\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/service/index.ts"],"names":[],"mappings":";;;;AAAA,wEAA6C;AAC7C,sEAA2C;AAC3C,4DAAiC;AACjC,wEAA6C;AAC7C,kEAAuC;AACvC,oEAAyC;AACzC,kEAAuC;AACvC,iEAAsC;AACtC,2DAAoC;AACpC,sEAA+C;AAC/C,oEAA6C;AAC7C,MAAM,OAAO,GAAgE,CAAC,OAAO,EAAE,WAAW,EAAE,YAAY,CAAC,CAAA;AACpG,QAAA,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;AAC/C,QAAA,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;AACrD,QAAA,MAAM,GAAG,EAAE,eAAe,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAA","sourcesContent":["export * from './invoice-event/invoice-event'\nexport * from './invoice-item/invoice-item'\nexport * from './invoice/invoice'\nexport * from './invoice/commercial-document'\nexport * from './invoice/invoice-rules'\nexport * from './invoice/invoice-service'\nexport * from './invoice/invoice-files'\nexport * from './invoice/invoice-type'\nimport * as invoice from './invoice'\nimport * as invoiceEvent from './invoice-event'\nimport * as invoiceItem from './invoice-item'\nconst modules: { entities: any[]; subscribers: any[]; resolvers: any[] }[] = [invoice, invoiceItem, invoiceEvent]\nexport const entities = modules.flatMap(one => one.entities)\nexport const subscribers = modules.flatMap(one => one.subscribers)\nexport const schema = { resolverClasses: modules.flatMap(one => one.resolvers) }\n"]}
@@ -2,5 +2,5 @@ import { Invoice } from './invoice';
2
2
  import { InvoiceMutation } from './invoice-mutation';
3
3
  import { InvoiceQuery } from './invoice-query';
4
4
  export declare const entities: (typeof Invoice)[];
5
- export declare const resolvers: (typeof InvoiceQuery | typeof InvoiceMutation)[];
5
+ export declare const resolvers: (typeof InvoiceMutation | typeof InvoiceQuery)[];
6
6
  export declare const subscribers: any[];
@@ -0,0 +1,14 @@
1
+ import { Attachment } from '@things-factory/attachment-base';
2
+ import { Domain } from '@things-factory/shell';
3
+ import { EntityManager } from 'typeorm';
4
+ import { Invoice } from './invoice';
5
+ export declare const INVOICE_FILE_REF_TYPE = "Invoice";
6
+ /** An invoice's files, the first attached first. */
7
+ export declare function filesOf(tx: EntityManager, domain: {
8
+ id: string;
9
+ }, invoiceId: string): Promise<Attachment[]>;
10
+ /** Attach files to an invoice and take others off it, in one go - a file taken off is deleted. */
11
+ export declare function changeInvoiceFiles(tx: EntityManager, domain: Domain, id: string, change: {
12
+ attach?: any[];
13
+ remove?: string[];
14
+ }, context: ResolverContext): Promise<Invoice>;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.INVOICE_FILE_REF_TYPE = void 0;
4
+ exports.filesOf = filesOf;
5
+ exports.changeInvoiceFiles = changeInvoiceFiles;
6
+ const attachment_base_1 = require("@things-factory/attachment-base");
7
+ const auth_base_1 = require("@things-factory/auth-base");
8
+ const shell_1 = require("@things-factory/shell");
9
+ const typeorm_1 = require("typeorm");
10
+ const invoice_service_1 = require("./invoice-service");
11
+ /*
12
+ * The files an invoice keeps - the signed copy, the purchase order, the delivery note (2026-10-23). They are not the
13
+ * printed document, so they come and go on a draft, an issued and a voided invoice alike.
14
+ */
15
+ exports.INVOICE_FILE_REF_TYPE = 'Invoice';
16
+ /** An invoice's files, the first attached first. */
17
+ async function filesOf(tx, domain, invoiceId) {
18
+ return await tx.getRepository(attachment_base_1.Attachment).find({ where: { domain: { id: domain.id }, refType: exports.INVOICE_FILE_REF_TYPE, refBy: invoiceId }, order: { createdAt: 'ASC' } });
19
+ }
20
+ /** Attach files to an invoice and take others off it, in one go - a file taken off is deleted. */
21
+ async function changeInvoiceFiles(tx, domain, id, change, context) {
22
+ await (0, invoice_service_1.lockDocumentDomain)(tx, domain);
23
+ const invoice = await (0, invoice_service_1.invoiceInDomain)(tx, domain, id);
24
+ const remove = [...new Set(change.remove ?? [])];
25
+ if (remove.length) {
26
+ const own = await tx.getRepository(attachment_base_1.Attachment).find({ where: { domain: { id: domain.id }, refType: exports.INVOICE_FILE_REF_TYPE, refBy: invoice.id, id: (0, typeorm_1.In)(remove) } });
27
+ if (own.length !== remove.length)
28
+ throw new shell_1.Refusal('invoice-file-not-on-invoice', {}, 'a file is not on this invoice - reload and try again');
29
+ for (const one of own)
30
+ await (0, attachment_base_1.deleteAttachment)(null, { id: one.id }, context);
31
+ }
32
+ for (const file of change.attach ?? [])
33
+ await (0, attachment_base_1.createAttachment)(null, { attachment: { file, refType: exports.INVOICE_FILE_REF_TYPE, refBy: invoice.id, category: 'invoice' } }, context);
34
+ return invoice;
35
+ }
36
+ /** An invoice's file opens to whoever may read invoices, as the invoice doors ask it. */
37
+ (0, attachment_base_1.registerAttachmentReader)(exports.INVOICE_FILE_REF_TYPE, async (_attachment, context) => {
38
+ const { domain, user, unsafeIP, prohibitedPrivileges } = context?.state ?? {};
39
+ if (!domain || !user)
40
+ return false;
41
+ return await (0, auth_base_1.checkPermission)({ category: 'invoice', privilege: 'query', owner: true }, user, domain, unsafeIP, prohibitedPrivileges);
42
+ });
43
+ //# sourceMappingURL=invoice-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoice-files.js","sourceRoot":"","sources":["../../../server/service/invoice/invoice-files.ts"],"names":[],"mappings":";;;AAgBA,0BAEC;AAGD,gDAkBC;AAvCD,qEAA0H;AAC1H,yDAA2D;AAC3D,iDAAuD;AACvD,qCAA2C;AAG3C,uDAAuE;AAEvE;;;GAGG;AAEU,QAAA,qBAAqB,GAAG,SAAS,CAAA;AAE9C,oDAAoD;AAC7C,KAAK,UAAU,OAAO,CAAC,EAAiB,EAAE,MAAsB,EAAE,SAAiB;IACxF,OAAO,MAAM,EAAE,CAAC,aAAa,CAAC,4BAAU,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,6BAAqB,EAAE,KAAK,EAAE,SAAS,EAAS,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,KAAK,EAAS,EAAE,CAAC,CAAA;AACvL,CAAC;AAED,kGAAkG;AAC3F,KAAK,UAAU,kBAAkB,CACtC,EAAiB,EACjB,MAAc,EACd,EAAU,EACV,MAA6C,EAC7C,OAAwB;IAExB,MAAM,IAAA,oCAAkB,EAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IACpC,MAAM,OAAO,GAAG,MAAM,IAAA,iCAAe,EAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,CAAA;IAErD,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAA;IAChD,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,aAAa,CAAC,4BAAU,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,6BAAqB,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,EAAE,IAAA,YAAE,EAAC,MAAM,CAAC,EAAS,EAAE,CAAC,CAAA;QACvK,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM;YAAE,MAAM,IAAI,eAAO,CAAC,6BAA6B,EAAE,EAAE,EAAE,sDAAsD,CAAC,CAAA;QAC9I,KAAK,MAAM,GAAG,IAAI,GAAG;YAAE,MAAM,IAAA,kCAAgB,EAAC,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,CAAA;IAC9E,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,IAAI,EAAE;QAAE,MAAM,IAAA,kCAAgB,EAAC,IAAI,EAAE,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,6BAAqB,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAS,EAAE,OAAO,CAAC,CAAA;IACtL,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,yFAAyF;AACzF,IAAA,0CAAwB,EAAC,6BAAqB,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE;IAC7E,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,oBAAoB,EAAE,GAAG,OAAO,EAAE,KAAK,IAAI,EAAE,CAAA;IAC7E,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAA;IAClC,OAAO,MAAM,IAAA,2BAAe,EAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAS,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,oBAAoB,CAAC,CAAA;AAC7I,CAAC,CAAC,CAAA","sourcesContent":["import { Attachment, createAttachment, deleteAttachment, registerAttachmentReader } from '@things-factory/attachment-base'\nimport { checkPermission } from '@things-factory/auth-base'\nimport { Domain, Refusal } from '@things-factory/shell'\nimport { EntityManager, In } from 'typeorm'\n\nimport { Invoice } from './invoice'\nimport { invoiceInDomain, lockDocumentDomain } from './invoice-service'\n\n/*\n * The files an invoice keeps - the signed copy, the purchase order, the delivery note (2026-10-23). They are not the\n * printed document, so they come and go on a draft, an issued and a voided invoice alike.\n */\n\nexport const INVOICE_FILE_REF_TYPE = 'Invoice'\n\n/** An invoice's files, the first attached first. */\nexport async function filesOf(tx: EntityManager, domain: { id: string }, invoiceId: string): Promise<Attachment[]> {\n return await tx.getRepository(Attachment).find({ where: { domain: { id: domain.id }, refType: INVOICE_FILE_REF_TYPE, refBy: invoiceId } as any, order: { createdAt: 'ASC' } as any })\n}\n\n/** Attach files to an invoice and take others off it, in one go - a file taken off is deleted. */\nexport async function changeInvoiceFiles(\n tx: EntityManager,\n domain: Domain,\n id: string,\n change: { attach?: any[]; remove?: string[] },\n context: ResolverContext\n): Promise<Invoice> {\n await lockDocumentDomain(tx, domain)\n const invoice = await invoiceInDomain(tx, domain, id)\n\n const remove = [...new Set(change.remove ?? [])]\n if (remove.length) {\n const own = await tx.getRepository(Attachment).find({ where: { domain: { id: domain.id }, refType: INVOICE_FILE_REF_TYPE, refBy: invoice.id, id: In(remove) } as any })\n if (own.length !== remove.length) throw new Refusal('invoice-file-not-on-invoice', {}, 'a file is not on this invoice - reload and try again')\n for (const one of own) await deleteAttachment(null, { id: one.id }, context)\n }\n for (const file of change.attach ?? []) await createAttachment(null, { attachment: { file, refType: INVOICE_FILE_REF_TYPE, refBy: invoice.id, category: 'invoice' } } as any, context)\n return invoice\n}\n\n/** An invoice's file opens to whoever may read invoices, as the invoice doors ask it. */\nregisterAttachmentReader(INVOICE_FILE_REF_TYPE, async (_attachment, context) => {\n const { domain, user, unsafeIP, prohibitedPrivileges } = context?.state ?? {}\n if (!domain || !user) return false\n return await checkPermission({ category: 'invoice', privilege: 'query', owner: true } as any, user, domain, unsafeIP, prohibitedPrivileges)\n})\n"]}
@@ -1,8 +1,10 @@
1
+ import type { FileUpload } from 'graphql-upload/GraphQLUpload.js';
1
2
  import { Invoice } from './invoice';
2
3
  import { NewInvoice } from './invoice-type';
3
4
  export declare class InvoiceMutation {
4
5
  createInvoice(invoice: NewInvoice, context: ResolverContext): Promise<Invoice>;
5
6
  updateInvoice(id: string, invoice: NewInvoice, context: ResolverContext): Promise<Invoice>;
7
+ changeInvoiceFiles(id: string, attach: FileUpload[], remove: string[], context: ResolverContext): Promise<Invoice>;
6
8
  issueInvoice(id: string, context: ResolverContext): Promise<Invoice>;
7
9
  voidInvoice(id: string, reason: string, context: ResolverContext): Promise<Invoice>;
8
10
  }
@@ -3,8 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.InvoiceMutation = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const shell_1 = require("@things-factory/shell");
6
+ const GraphQLUpload_js_1 = tslib_1.__importDefault(require("graphql-upload/GraphQLUpload.js"));
6
7
  const type_graphql_1 = require("type-graphql");
7
8
  const invoice_1 = require("./invoice");
9
+ const invoice_files_1 = require("./invoice-files");
8
10
  const invoice_service_1 = require("./invoice-service");
9
11
  const invoice_type_1 = require("./invoice-type");
10
12
  let InvoiceMutation = class InvoiceMutation {
@@ -16,6 +18,10 @@ let InvoiceMutation = class InvoiceMutation {
16
18
  const { tx, domain, user } = context.state;
17
19
  return (0, invoice_service_1.saveInvoice)(tx, domain, user, invoice, id);
18
20
  }
21
+ async changeInvoiceFiles(id, attach, remove, context) {
22
+ const { tx, domain } = context.state;
23
+ return await (0, invoice_files_1.changeInvoiceFiles)(tx, domain, id, { attach: attach ?? [], remove: remove ?? [] }, context);
24
+ }
19
25
  issueInvoice(id, context) {
20
26
  const { tx, domain, user } = context.state;
21
27
  return (0, invoice_service_1.transitionInvoice)(tx, domain, user, id, 'ISSUED');
@@ -47,6 +53,18 @@ tslib_1.__decorate([
47
53
  tslib_1.__metadata("design:paramtypes", [String, invoice_type_1.NewInvoice, Object]),
48
54
  tslib_1.__metadata("design:returntype", void 0)
49
55
  ], InvoiceMutation.prototype, "updateInvoice", null);
56
+ tslib_1.__decorate([
57
+ (0, type_graphql_1.Directive)('@transaction'),
58
+ (0, type_graphql_1.Directive)('@privilege(category: "invoice", privilege: "mutation", domainOwnerGranted: true)'),
59
+ (0, type_graphql_1.Mutation)(type => invoice_1.Invoice, { description: 'To attach files to an invoice and take others off it - its signed copy, order or delivery note' }),
60
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('id')),
61
+ tslib_1.__param(1, (0, type_graphql_1.Arg)('attach', type => [GraphQLUpload_js_1.default], { nullable: true })),
62
+ tslib_1.__param(2, (0, type_graphql_1.Arg)('remove', type => [String], { nullable: true })),
63
+ tslib_1.__param(3, (0, type_graphql_1.Ctx)()),
64
+ tslib_1.__metadata("design:type", Function),
65
+ tslib_1.__metadata("design:paramtypes", [String, Array, Array, Object]),
66
+ tslib_1.__metadata("design:returntype", Promise)
67
+ ], InvoiceMutation.prototype, "changeInvoiceFiles", null);
50
68
  tslib_1.__decorate([
51
69
  (0, type_graphql_1.Directive)('@transaction'),
52
70
  (0, type_graphql_1.Directive)('@privilege(category: "invoice", privilege: "mutation", domainOwnerGranted: true)'),
@@ -1 +1 @@
1
- {"version":3,"file":"invoice-mutation.js","sourceRoot":"","sources":["../../../server/service/invoice/invoice-mutation.ts"],"names":[],"mappings":"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","sourcesContent":["import { SpeakRefusals } from '@things-factory/shell'\nimport { Arg, Ctx, Directive, Mutation, Resolver, UseMiddleware } from 'type-graphql'\n\nimport { Invoice } from './invoice'\nimport { saveInvoice, transitionInvoice } from './invoice-service'\nimport { NewInvoice } from './invoice-type'\n\n@UseMiddleware(SpeakRefusals)\n@Resolver(Invoice)\nexport class InvoiceMutation {\n @Directive('@transaction')\n @Directive('@privilege(category: \"invoice\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(type => Invoice, { description: 'To create an invoice draft' })\n createInvoice(@Arg('invoice') invoice: NewInvoice, @Ctx() context: ResolverContext) {\n const { tx, domain, user } = context.state\n return saveInvoice(tx, domain, user, invoice)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"invoice\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(type => Invoice, { description: 'To replace the head and lines of an invoice draft' })\n updateInvoice(@Arg('id') id: string, @Arg('invoice') invoice: NewInvoice, @Ctx() context: ResolverContext) {\n const { tx, domain, user } = context.state\n return saveInvoice(tx, domain, user, invoice, id)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"invoice\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(type => Invoice, { description: 'To issue an invoice draft; its amounts are fixed from then on' })\n issueInvoice(@Arg('id') id: string, @Ctx() context: ResolverContext) {\n const { tx, domain, user } = context.state\n return transitionInvoice(tx, domain, user, id, 'ISSUED')\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"invoice\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(type => Invoice, { description: 'To void an invoice, with the reason' })\n voidInvoice(@Arg('id') id: string, @Arg('reason') reason: string, @Ctx() context: ResolverContext) {\n const { tx, domain, user } = context.state\n return transitionInvoice(tx, domain, user, id, 'VOID', reason)\n }\n}\n"]}
1
+ {"version":3,"file":"invoice-mutation.js","sourceRoot":"","sources":["../../../server/service/invoice/invoice-mutation.ts"],"names":[],"mappings":"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","sourcesContent":["import { SpeakRefusals } from '@things-factory/shell'\nimport type { FileUpload } from 'graphql-upload/GraphQLUpload.js'\nimport GraphQLUpload from 'graphql-upload/GraphQLUpload.js'\nimport { Arg, Ctx, Directive, Mutation, Resolver, UseMiddleware } from 'type-graphql'\n\nimport { Invoice } from './invoice'\nimport { changeInvoiceFiles } from './invoice-files'\nimport { saveInvoice, transitionInvoice } from './invoice-service'\nimport { NewInvoice } from './invoice-type'\n\n@UseMiddleware(SpeakRefusals)\n@Resolver(Invoice)\nexport class InvoiceMutation {\n @Directive('@transaction')\n @Directive('@privilege(category: \"invoice\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(type => Invoice, { description: 'To create an invoice draft' })\n createInvoice(@Arg('invoice') invoice: NewInvoice, @Ctx() context: ResolverContext) {\n const { tx, domain, user } = context.state\n return saveInvoice(tx, domain, user, invoice)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"invoice\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(type => Invoice, { description: 'To replace the head and lines of an invoice draft' })\n updateInvoice(@Arg('id') id: string, @Arg('invoice') invoice: NewInvoice, @Ctx() context: ResolverContext) {\n const { tx, domain, user } = context.state\n return saveInvoice(tx, domain, user, invoice, id)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"invoice\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(type => Invoice, { description: 'To attach files to an invoice and take others off it - its signed copy, order or delivery note' })\n async changeInvoiceFiles(\n @Arg('id') id: string,\n @Arg('attach', type => [GraphQLUpload], { nullable: true }) attach: FileUpload[],\n @Arg('remove', type => [String], { nullable: true }) remove: string[],\n @Ctx() context: ResolverContext\n ) {\n const { tx, domain } = context.state\n return await changeInvoiceFiles(tx, domain, id, { attach: attach ?? [], remove: remove ?? [] }, context)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"invoice\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(type => Invoice, { description: 'To issue an invoice draft; its amounts are fixed from then on' })\n issueInvoice(@Arg('id') id: string, @Ctx() context: ResolverContext) {\n const { tx, domain, user } = context.state\n return transitionInvoice(tx, domain, user, id, 'ISSUED')\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"invoice\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(type => Invoice, { description: 'To void an invoice, with the reason' })\n voidInvoice(@Arg('id') id: string, @Arg('reason') reason: string, @Ctx() context: ResolverContext) {\n const { tx, domain, user } = context.state\n return transitionInvoice(tx, domain, user, id, 'VOID', reason)\n }\n}\n"]}
@@ -1,4 +1,6 @@
1
+ import { Attachment } from '@things-factory/attachment-base';
1
2
  import { User } from '@things-factory/auth-base';
3
+ import { Counterparty } from '@things-factory/biz-base';
2
4
  import { Domain, ListParam } from '@things-factory/shell';
3
5
  import { InvoiceEvent } from '../invoice-event/invoice-event';
4
6
  import { InvoiceItem } from '../invoice-item/invoice-item';
@@ -10,6 +12,8 @@ export declare class InvoiceQuery {
10
12
  invoiceEvents(invoiceId: string, context: ResolverContext): Promise<InvoiceEvent[]>;
11
13
  items(invoice: Invoice): Promise<InvoiceItem[]>;
12
14
  taxGroups(invoice: Invoice): Promise<import("./invoice-rules").TaxGroup[]>;
15
+ files(row: Invoice): Promise<Attachment[]>;
16
+ counterparty(row: Invoice): Counterparty | Promise<Counterparty>;
13
17
  domain(row: Invoice): Domain | Promise<Domain>;
14
18
  creator(row: Invoice): User | Promise<User>;
15
19
  updater(row: Invoice): User | Promise<User>;
@@ -2,13 +2,16 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.InvoiceQuery = void 0;
4
4
  const tslib_1 = require("tslib");
5
+ const attachment_base_1 = require("@things-factory/attachment-base");
5
6
  const auth_base_1 = require("@things-factory/auth-base");
7
+ const biz_base_1 = require("@things-factory/biz-base");
6
8
  const shell_1 = require("@things-factory/shell");
7
9
  const type_graphql_1 = require("type-graphql");
8
10
  const invoice_event_1 = require("../invoice-event/invoice-event");
9
11
  const invoice_item_1 = require("../invoice-item/invoice-item");
10
12
  const commercial_document_1 = require("./commercial-document");
11
13
  const invoice_1 = require("./invoice");
14
+ const invoice_files_1 = require("./invoice-files");
12
15
  const invoice_rules_1 = require("./invoice-rules");
13
16
  const invoice_type_1 = require("./invoice-type");
14
17
  let InvoiceQuery = class InvoiceQuery {
@@ -37,6 +40,12 @@ let InvoiceQuery = class InvoiceQuery {
37
40
  async taxGroups(invoice) {
38
41
  return (0, invoice_rules_1.taxGroupsOf)({ ...invoice, items: await this.items(invoice) });
39
42
  }
43
+ files(row) {
44
+ return (0, invoice_files_1.filesOf)((0, shell_1.getRepository)(invoice_1.Invoice).manager, { id: row.domainId }, row.id);
45
+ }
46
+ counterparty(row) {
47
+ return row.counterparty ?? (row.counterpartyId ? (0, shell_1.getRepository)(biz_base_1.Counterparty).findOneBy({ id: row.counterpartyId }) : undefined);
48
+ }
40
49
  domain(row) {
41
50
  return row.domain ?? (row.domainId ? (0, shell_1.getRepository)(shell_1.Domain).findOneBy({ id: row.domainId }) : undefined);
42
51
  }
@@ -89,6 +98,20 @@ tslib_1.__decorate([
89
98
  tslib_1.__metadata("design:paramtypes", [invoice_1.Invoice]),
90
99
  tslib_1.__metadata("design:returntype", Promise)
91
100
  ], InvoiceQuery.prototype, "taxGroups", null);
101
+ tslib_1.__decorate([
102
+ (0, type_graphql_1.FieldResolver)(type => [attachment_base_1.Attachment], { description: 'The files the invoice keeps, the first attached first' }),
103
+ tslib_1.__param(0, (0, type_graphql_1.Root)()),
104
+ tslib_1.__metadata("design:type", Function),
105
+ tslib_1.__metadata("design:paramtypes", [invoice_1.Invoice]),
106
+ tslib_1.__metadata("design:returntype", void 0)
107
+ ], InvoiceQuery.prototype, "files", null);
108
+ tslib_1.__decorate([
109
+ (0, type_graphql_1.FieldResolver)(type => biz_base_1.Counterparty, { nullable: true }),
110
+ tslib_1.__param(0, (0, type_graphql_1.Root)()),
111
+ tslib_1.__metadata("design:type", Function),
112
+ tslib_1.__metadata("design:paramtypes", [invoice_1.Invoice]),
113
+ tslib_1.__metadata("design:returntype", void 0)
114
+ ], InvoiceQuery.prototype, "counterparty", null);
92
115
  tslib_1.__decorate([
93
116
  (0, type_graphql_1.FieldResolver)(type => shell_1.Domain, { nullable: true }),
94
117
  tslib_1.__param(0, (0, type_graphql_1.Root)()),
@@ -1 +1 @@
1
- {"version":3,"file":"invoice-query.js","sourceRoot":"","sources":["../../../server/service/invoice/invoice-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { User } from '@things-factory/auth-base'\nimport { Domain, getQueryBuilderFromListParams, getRepository, ListParam, SpeakRefusals } from '@things-factory/shell'\nimport { Arg, Args, Ctx, Directive, FieldResolver, Query, Resolver, Root, UseMiddleware } from 'type-graphql'\n\nimport { InvoiceEvent } from '../invoice-event/invoice-event'\nimport { InvoiceItem } from '../invoice-item/invoice-item'\nimport { DocumentTaxGroup } from './commercial-document'\nimport { Invoice } from './invoice'\nimport { taxGroupsOf } from './invoice-rules'\nimport { InvoiceList } from './invoice-type'\n\n@UseMiddleware(SpeakRefusals)\n@Resolver(Invoice)\nexport class InvoiceQuery {\n @Directive('@privilege(category: \"invoice\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(type => Invoice, { nullable: true, description: 'To fetch an invoice' })\n invoice(@Arg('id') id: string, @Ctx() context: ResolverContext) {\n return getRepository(Invoice).findOne({ where: { id, domain: { id: context.state.domain.id } } })\n }\n\n @Directive('@privilege(category: \"invoice\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(type => InvoiceList, { description: 'To fetch a page of invoices' })\n async invoices(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext): Promise<InvoiceList> {\n const query = getQueryBuilderFromListParams({\n domain: context.state.domain,\n params,\n repository: getRepository(Invoice),\n searchables: ['number', 'supplierName', 'buyerName', 'purchaseOrder', 'notes']\n })\n const [items, total] = await query.getManyAndCount()\n return { items, total }\n }\n\n @Directive('@privilege(category: \"invoice\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(type => [InvoiceEvent], { description: 'To fetch what happened to an invoice, oldest first' })\n invoiceEvents(@Arg('invoiceId') invoiceId: string, @Ctx() context: ResolverContext) {\n return getRepository(InvoiceEvent).find({\n where: { domain: { id: context.state.domain.id }, invoice: { id: invoiceId } },\n order: { createdAt: 'ASC' }\n })\n }\n\n @FieldResolver(type => [InvoiceItem])\n async items(@Root() invoice: Invoice) {\n return invoice.items ?? getRepository(InvoiceItem).find({ where: { invoice: { id: invoice.id } }, order: { position: 'ASC' } })\n }\n\n @FieldResolver(type => [DocumentTaxGroup])\n async taxGroups(@Root() invoice: Invoice) {\n return taxGroupsOf({ ...invoice, items: await this.items(invoice) })\n }\n\n @FieldResolver(type => Domain, { nullable: true })\n domain(@Root() row: Invoice) {\n return row.domain ?? (row.domainId ? getRepository(Domain).findOneBy({ id: row.domainId }) : undefined)\n }\n\n @FieldResolver(type => User, { nullable: true })\n creator(@Root() row: Invoice) {\n return row.creator ?? (row.creatorId ? getRepository(User).findOneBy({ id: row.creatorId }) : undefined)\n }\n\n @FieldResolver(type => User, { nullable: true })\n updater(@Root() row: Invoice) {\n return row.updater ?? (row.updaterId ? getRepository(User).findOneBy({ id: row.updaterId }) : undefined)\n }\n}\n"]}
1
+ {"version":3,"file":"invoice-query.js","sourceRoot":"","sources":["../../../server/service/invoice/invoice-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { Attachment } from '@things-factory/attachment-base'\nimport { User } from '@things-factory/auth-base'\nimport { Counterparty } from '@things-factory/biz-base'\nimport { Domain, getQueryBuilderFromListParams, getRepository, ListParam, SpeakRefusals } from '@things-factory/shell'\nimport { Arg, Args, Ctx, Directive, FieldResolver, Query, Resolver, Root, UseMiddleware } from 'type-graphql'\n\nimport { InvoiceEvent } from '../invoice-event/invoice-event'\nimport { InvoiceItem } from '../invoice-item/invoice-item'\nimport { DocumentTaxGroup } from './commercial-document'\nimport { Invoice } from './invoice'\nimport { filesOf } from './invoice-files'\nimport { taxGroupsOf } from './invoice-rules'\nimport { InvoiceList } from './invoice-type'\n\n@UseMiddleware(SpeakRefusals)\n@Resolver(Invoice)\nexport class InvoiceQuery {\n @Directive('@privilege(category: \"invoice\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(type => Invoice, { nullable: true, description: 'To fetch an invoice' })\n invoice(@Arg('id') id: string, @Ctx() context: ResolverContext) {\n return getRepository(Invoice).findOne({ where: { id, domain: { id: context.state.domain.id } } })\n }\n\n @Directive('@privilege(category: \"invoice\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(type => InvoiceList, { description: 'To fetch a page of invoices' })\n async invoices(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext): Promise<InvoiceList> {\n const query = getQueryBuilderFromListParams({\n domain: context.state.domain,\n params,\n repository: getRepository(Invoice),\n searchables: ['number', 'supplierName', 'buyerName', 'purchaseOrder', 'notes']\n })\n const [items, total] = await query.getManyAndCount()\n return { items, total }\n }\n\n @Directive('@privilege(category: \"invoice\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(type => [InvoiceEvent], { description: 'To fetch what happened to an invoice, oldest first' })\n invoiceEvents(@Arg('invoiceId') invoiceId: string, @Ctx() context: ResolverContext) {\n return getRepository(InvoiceEvent).find({\n where: { domain: { id: context.state.domain.id }, invoice: { id: invoiceId } },\n order: { createdAt: 'ASC' }\n })\n }\n\n @FieldResolver(type => [InvoiceItem])\n async items(@Root() invoice: Invoice) {\n return invoice.items ?? getRepository(InvoiceItem).find({ where: { invoice: { id: invoice.id } }, order: { position: 'ASC' } })\n }\n\n @FieldResolver(type => [DocumentTaxGroup])\n async taxGroups(@Root() invoice: Invoice) {\n return taxGroupsOf({ ...invoice, items: await this.items(invoice) })\n }\n\n @FieldResolver(type => [Attachment], { description: 'The files the invoice keeps, the first attached first' })\n files(@Root() row: Invoice) {\n return filesOf(getRepository(Invoice).manager, { id: row.domainId! }, row.id)\n }\n\n @FieldResolver(type => Counterparty, { nullable: true })\n counterparty(@Root() row: Invoice) {\n return row.counterparty ?? (row.counterpartyId ? getRepository(Counterparty).findOneBy({ id: row.counterpartyId }) : undefined)\n }\n\n @FieldResolver(type => Domain, { nullable: true })\n domain(@Root() row: Invoice) {\n return row.domain ?? (row.domainId ? getRepository(Domain).findOneBy({ id: row.domainId }) : undefined)\n }\n\n @FieldResolver(type => User, { nullable: true })\n creator(@Root() row: Invoice) {\n return row.creator ?? (row.creatorId ? getRepository(User).findOneBy({ id: row.creatorId }) : undefined)\n }\n\n @FieldResolver(type => User, { nullable: true })\n updater(@Root() row: Invoice) {\n return row.updater ?? (row.updaterId ? getRepository(User).findOneBy({ id: row.updaterId }) : undefined)\n }\n}\n"]}
@@ -61,12 +61,12 @@ export declare function normalizedHeader(input: Record<string, any>): {
61
61
  direction: any;
62
62
  language: any;
63
63
  supplierName: any;
64
+ buyerName: any;
65
+ issueDate: any;
64
66
  supplierAddress: any;
65
67
  supplierRegistrationNumber: any;
66
- buyerName: any;
67
68
  buyerAddress: any;
68
69
  buyerRegistrationNumber: any;
69
- issueDate: any;
70
70
  purchaseOrder: any;
71
71
  paymentTerms: any;
72
72
  bankDetails: any;
@@ -6,6 +6,7 @@ exports.invoiceInDomain = invoiceInDomain;
6
6
  exports.saveInvoice = saveInvoice;
7
7
  exports.transitionInvoice = transitionInvoice;
8
8
  exports.snapshotOf = snapshotOf;
9
+ const biz_base_1 = require("@things-factory/biz-base");
9
10
  const shell_1 = require("@things-factory/shell");
10
11
  const invoice_event_1 = require("../invoice-event/invoice-event");
11
12
  const invoice_item_1 = require("../invoice-item/invoice-item");
@@ -46,10 +47,14 @@ async function saveInvoice(tx, domain, user, input, id) {
46
47
  const duplicate = await repository.findOne({ where: { domain: { id: domain.id }, number: header.number } });
47
48
  if (duplicate && duplicate.id !== id)
48
49
  throw new shell_1.Refusal('invoice-number-duplicate', {}, 'Invoice number already exists');
50
+ const counterparty = input.counterpartyId ? await tx.getRepository(biz_base_1.Counterparty).findOne({ where: { id: input.counterpartyId, domain: { id: domain.id } } }) : null;
51
+ if (input.counterpartyId && !counterparty)
52
+ throw new shell_1.Refusal('invoice-counterparty-not-found', {}, 'The counterparty was not found - reload and try again');
49
53
  const { items, supplyAmount, taxAmount, totalAmount } = (0, invoice_rules_1.calculateDocument)(input.items, header.currency, received);
50
54
  const invoice = await repository.save(repository.create({
51
55
  ...old,
52
56
  ...header,
57
+ counterparty,
53
58
  dueDate: input.dueDate ?? null,
54
59
  taxBasis: received ? invoice_1.InvoiceTaxBasis.RECEIVED : invoice_1.InvoiceTaxBasis.CALCULATED,
55
60
  supplyAmount,
@@ -1 +1 @@
1
- {"version":3,"file":"invoice-service.js","sourceRoot":"","sources":["../../../server/service/invoice/invoice-service.ts"],"names":[],"mappings":";;AAaA,wEAEC;AAGD,gDAGC;AAED,0CAKC;AAED,kCAuCC;AAED,8CAwBC;AAOD,gCA4BC;AAlID,iDAA2E;AAG3E,kEAA6D;AAC7D,+DAA0D;AAC1D,uCAAmE;AACnE,mDAAwI;AAIxI,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAA0B,CAAA;AAE1D,kHAAkH;AAClH,SAAgB,8BAA8B,CAAC,KAA6B;IAC1E,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;AAC7B,CAAC;AAED,gHAAgH;AACzG,KAAK,UAAU,kBAAkB,CAAC,EAAiB,EAAE,MAAc;IACxE,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,aAAa,CAAC,cAAM,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,IAAA,0BAAkB,EAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;IAC9J,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,eAAO,CAAC,wBAAwB,EAAE,EAAE,EAAE,kBAAkB,CAAC,CAAA;AACjF,CAAC;AAEM,KAAK,UAAU,eAAe,CAAC,EAAiB,EAAE,MAAc,EAAE,EAAU;IACjF,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,aAAa,CAAC,iBAAO,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC,CAAA;IACtI,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,eAAO,CAAC,mBAAmB,EAAE,EAAE,EAAE,mBAAmB,CAAC,CAAA;IAC7E,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAA;IACrD,OAAO,OAAO,CAAA;AAChB,CAAC;AAEM,KAAK,UAAU,WAAW,CAAC,EAAiB,EAAE,MAAc,EAAE,IAAS,EAAE,KAAiB,EAAE,EAAW;IAC5G,MAAM,kBAAkB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IACpC,MAAM,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAClE,IAAI,GAAG;QAAE,IAAA,4BAAY,EAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAEjC,MAAM,MAAM,GAAG,IAAA,gCAAgB,EAAC,KAAK,CAAC,CAAA;IACtC,IAAI,KAAK,CAAC,OAAO,IAAI,CAAC,IAAA,wBAAQ,EAAC,KAAK,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,eAAO,CAAC,sBAAsB,EAAE,EAAE,EAAE,6BAA6B,CAAC,CAAA;IAC3H,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,SAAS;QAAE,MAAM,IAAI,eAAO,CAAC,0BAA0B,EAAE,EAAE,EAAE,8BAA8B,CAAC,CAAA;IAC1J,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,KAAK,yBAAe,CAAC,QAAQ,CAAA;IAC5D,IAAI,QAAQ,IAAI,MAAM,CAAC,SAAS,KAAK,UAAU;QAAE,MAAM,IAAI,eAAO,CAAC,gCAAgC,EAAE,EAAE,EAAE,oDAAoD,CAAC,CAAA;IAE9J,MAAM,UAAU,GAAG,EAAE,CAAC,aAAa,CAAC,iBAAO,CAAC,CAAA;IAC5C,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IAC3G,IAAI,SAAS,IAAI,SAAS,CAAC,EAAE,KAAK,EAAE;QAAE,MAAM,IAAI,eAAO,CAAC,0BAA0B,EAAE,EAAE,EAAE,+BAA+B,CAAC,CAAA;IAExH,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,IAAA,iCAAiB,EAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;IACjH,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,IAAI,CACnC,UAAU,CAAC,MAAM,CAAC;QAChB,GAAG,GAAG;QACN,GAAG,MAAM;QACT,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,IAAI;QAC9B,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,yBAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,yBAAe,CAAC,UAAU;QAC1E,YAAY;QACZ,SAAS;QACT,WAAW;QACX,MAAM;QACN,OAAO,EAAE,GAAG,EAAE,OAAO,IAAI,IAAI;QAC7B,OAAO,EAAE,IAAI;QACb,KAAK,EAAE,SAAS;KACjB,CAAC,CACH,CAAA;IAED,MAAM,KAAK,GAAG,EAAE,CAAC,aAAa,CAAC,0BAAW,CAAC,CAAA;IAC3C,IAAI,GAAG;QAAE,MAAM,KAAK,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IAChE,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IAE7G,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAA;IAC3D,MAAM,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;IAC9E,OAAO,KAAK,CAAA;AACd,CAAC;AAEM,KAAK,UAAU,iBAAiB,CAAC,EAAiB,EAAE,MAAc,EAAE,IAAS,EAAE,EAAU,EAAE,MAAyB,EAAE,MAAe;IAC1I,MAAM,kBAAkB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IACpC,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,CAAA;IACrD,KAAK,MAAM,KAAK,IAAI,gBAAgB;QAAE,MAAM,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;IAE9E,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,IAAA,4BAAY,EAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QAC5B,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACpE,MAAM,IAAI,eAAO,CAAC,wBAAwB,EAAE,EAAE,EAAE,6CAA6C,CAAC,CAAA;QAChG,CAAC;QACD,oGAAoG;QACpG,OAAO,CAAC,WAAW,GAAG,4BAAY,CAAA;QAClC,OAAO,CAAC,cAAc,GAAG,IAAA,8BAAc,EAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;QACzD,OAAO,CAAC,MAAM,GAAG,uBAAa,CAAC,MAAM,CAAA;IACvC,CAAC;SAAM,CAAC;QACN,IAAI,OAAO,CAAC,MAAM,KAAK,uBAAa,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE;YAAE,MAAM,IAAI,eAAO,CAAC,sBAAsB,EAAE,EAAE,EAAE,sDAAsD,CAAC,CAAA;QACnK,OAAO,CAAC,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,CAAA;QAClC,OAAO,CAAC,MAAM,GAAG,uBAAa,CAAC,IAAI,CAAA;IACrC,CAAC;IACD,OAAO,CAAC,OAAO,GAAG,IAAI,CAAA;IACtB,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,CAAA;IAClC,MAAM,EAAE,CAAC,aAAa,CAAC,iBAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC1C,MAAM,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IACnE,OAAO,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,CAAA;AACxC,CAAC;AAED,SAAS,kBAAkB,CAAC,EAAiB,EAAE,MAAc,EAAE,IAAS,EAAE,OAAgB,EAAE,MAAc,EAAE,MAAe;IACzH,OAAO,EAAE,CAAC,aAAa,CAAC,4BAAY,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;AAC3J,CAAC;AAED,mGAAmG;AACnG,SAAgB,UAAU,CAAC,OAAgB;IACzC,MAAM,IAAI,GAAG;QACX,IAAI;QACJ,GAAG,2BAAW;QACd,QAAQ;QACR,SAAS;QACT,UAAU;QACV,cAAc;QACd,WAAW;QACX,aAAa;QACb,aAAa;QACb,gBAAgB;QAChB,YAAY;KACb,CAAA;IACD,OAAO;QACL,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;QACnE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,EAAE,EAAE,CAAC,CAAC;YACzI,QAAQ;YACR,WAAW;YACX,QAAQ;YACR,SAAS;YACT,QAAQ;YACR,OAAO;YACP,OAAO;YACP,YAAY;YACZ,iBAAiB,EAAE,iBAAiB,IAAI,IAAI;SAC7C,CAAC,CAAC;KACJ,CAAA;AACH,CAAC","sourcesContent":["import { Domain, Refusal, writeLockSupported } from '@things-factory/shell'\nimport { EntityManager } from 'typeorm'\n\nimport { InvoiceEvent } from '../invoice-event/invoice-event'\nimport { InvoiceItem } from '../invoice-item/invoice-item'\nimport { Invoice, InvoiceStatus, InvoiceTaxBasis } from './invoice'\nimport { calculateDocument, currencyDigits, HEADER_KEYS, normalizedHeader, requireDraft, TAX_ROUNDING, validDay } from './invoice-rules'\nimport { NewInvoice } from './invoice-type'\n\nexport type InvoiceTransitionGuard = (tx: EntityManager, domain: Domain, invoice: Invoice, action: 'ISSUED' | 'VOID') => Promise<void>\nconst transitionGuards = new Set<InvoiceTransitionGuard>()\n\n/** An application refuses a transition its own links forbid — Office keeps a linked invoice from being voided. */\nexport function registerInvoiceTransitionGuard(guard: InvoiceTransitionGuard) {\n transitionGuards.add(guard)\n}\n\n/** Serialize document writes on the domain row, where the database can hold it (shell `writeLockSupported`). */\nexport async function lockDocumentDomain(tx: EntityManager, domain: Domain) {\n const found = await tx.getRepository(Domain).findOne({ where: { id: domain.id }, ...(writeLockSupported(tx) ? { lock: { mode: 'pessimistic_write' } } : {}) })\n if (!found) throw new Refusal('invoice-domain-missing', {}, 'Domain not found')\n}\n\nexport async function invoiceInDomain(tx: EntityManager, domain: Domain, id: string) {\n const invoice = await tx.getRepository(Invoice).findOne({ where: { id, domain: { id: domain.id } }, relations: ['items', 'creator'] })\n if (!invoice) throw new Refusal('invoice-not-found', {}, 'Invoice not found')\n invoice.items.sort((a, b) => a.position - b.position)\n return invoice\n}\n\nexport async function saveInvoice(tx: EntityManager, domain: Domain, user: any, input: NewInvoice, id?: string) {\n await lockDocumentDomain(tx, domain)\n const old = id ? await invoiceInDomain(tx, domain, id) : undefined\n if (old) requireDraft(old.status)\n\n const header = normalizedHeader(input)\n if (input.dueDate && !validDay(input.dueDate)) throw new Refusal('invoice-date-invalid', {}, 'Use a valid YYYY-MM-DD date')\n if (input.issueDate && input.dueDate && input.dueDate < input.issueDate) throw new Refusal('invoice-due-before-issue', {}, 'Due date precedes issue date')\n const received = input.taxBasis === InvoiceTaxBasis.RECEIVED\n if (received && header.direction !== 'PURCHASE') throw new Refusal('invoice-received-purchase-only', {}, 'Only a received purchase invoice keeps printed tax')\n\n const repository = tx.getRepository(Invoice)\n const duplicate = await repository.findOne({ where: { domain: { id: domain.id }, number: header.number } })\n if (duplicate && duplicate.id !== id) throw new Refusal('invoice-number-duplicate', {}, 'Invoice number already exists')\n\n const { items, supplyAmount, taxAmount, totalAmount } = calculateDocument(input.items, header.currency, received)\n const invoice = await repository.save(\n repository.create({\n ...old,\n ...header,\n dueDate: input.dueDate ?? null,\n taxBasis: received ? InvoiceTaxBasis.RECEIVED : InvoiceTaxBasis.CALCULATED,\n supplyAmount,\n taxAmount,\n totalAmount,\n domain,\n creator: old?.creator ?? user,\n updater: user,\n items: undefined\n })\n )\n\n const lines = tx.getRepository(InvoiceItem)\n if (old) await lines.softDelete({ invoice: { id: invoice.id } })\n await lines.save(items.map(item => lines.create({ ...item, invoice, domain, creator: user, updater: user })))\n\n const saved = await invoiceInDomain(tx, domain, invoice.id)\n await recordInvoiceEvent(tx, domain, user, saved, old ? 'UPDATED' : 'CREATED')\n return saved\n}\n\nexport async function transitionInvoice(tx: EntityManager, domain: Domain, user: any, id: string, action: 'ISSUED' | 'VOID', reason?: string) {\n await lockDocumentDomain(tx, domain)\n const invoice = await invoiceInDomain(tx, domain, id)\n for (const guard of transitionGuards) await guard(tx, domain, invoice, action)\n\n if (action === 'ISSUED') {\n requireDraft(invoice.status)\n if (!invoice.issueDate || !invoice.dueDate || !invoice.items.length) {\n throw new Refusal('invoice-issue-required', {}, 'Issue date, due date and items are required')\n }\n /* What the amounts were reckoned with stays on the document; a later rule never recomputes them. */\n invoice.taxRounding = TAX_ROUNDING\n invoice.currencyDigits = currencyDigits(invoice.currency)\n invoice.status = InvoiceStatus.ISSUED\n } else {\n if (invoice.status === InvoiceStatus.VOID || !reason?.trim()) throw new Refusal('invoice-void-invalid', {}, 'A cancellation needs a reason and a non-void invoice')\n invoice.voidReason = reason.trim()\n invoice.status = InvoiceStatus.VOID\n }\n invoice.updater = user\n const { items, ...head } = invoice\n await tx.getRepository(Invoice).save(head)\n await recordInvoiceEvent(tx, domain, user, invoice, action, reason)\n return invoiceInDomain(tx, domain, id)\n}\n\nfunction recordInvoiceEvent(tx: EntityManager, domain: Domain, user: any, invoice: Invoice, action: string, reason?: string) {\n return tx.getRepository(InvoiceEvent).save({ domain, invoice, actor: user, action, reason, creator: user, updater: user, snapshot: snapshotOf(invoice) })\n}\n\n/** The document as printed — what an issued invoice said stays readable whatever changes later. */\nexport function snapshotOf(invoice: Invoice) {\n const keys = [\n 'id',\n ...HEADER_KEYS,\n 'status',\n 'dueDate',\n 'taxBasis',\n 'supplyAmount',\n 'taxAmount',\n 'totalAmount',\n 'taxRounding',\n 'currencyDigits',\n 'voidReason'\n ]\n return {\n ...Object.fromEntries(keys.map(key => [key, invoice[key] ?? null])),\n items: invoice.items.map(({ position, description, quantity, unitPrice, discount, taxKind, taxRate, supplyAmount, receivedTaxAmount }) => ({\n position,\n description,\n quantity,\n unitPrice,\n discount,\n taxKind,\n taxRate,\n supplyAmount,\n receivedTaxAmount: receivedTaxAmount ?? null\n }))\n }\n}\n"]}
1
+ {"version":3,"file":"invoice-service.js","sourceRoot":"","sources":["../../../server/service/invoice/invoice-service.ts"],"names":[],"mappings":";;AAcA,wEAEC;AAGD,gDAGC;AAED,0CAKC;AAED,kCA2CC;AAED,8CAwBC;AAOD,gCA4BC;AAvID,uDAAuD;AACvD,iDAA2E;AAG3E,kEAA6D;AAC7D,+DAA0D;AAC1D,uCAAmE;AACnE,mDAAwI;AAIxI,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAA0B,CAAA;AAE1D,kHAAkH;AAClH,SAAgB,8BAA8B,CAAC,KAA6B;IAC1E,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;AAC7B,CAAC;AAED,gHAAgH;AACzG,KAAK,UAAU,kBAAkB,CAAC,EAAiB,EAAE,MAAc;IACxE,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,aAAa,CAAC,cAAM,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,IAAA,0BAAkB,EAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;IAC9J,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,eAAO,CAAC,wBAAwB,EAAE,EAAE,EAAE,kBAAkB,CAAC,CAAA;AACjF,CAAC;AAEM,KAAK,UAAU,eAAe,CAAC,EAAiB,EAAE,MAAc,EAAE,EAAU;IACjF,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,aAAa,CAAC,iBAAO,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC,CAAA;IACtI,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,eAAO,CAAC,mBAAmB,EAAE,EAAE,EAAE,mBAAmB,CAAC,CAAA;IAC7E,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAA;IACrD,OAAO,OAAO,CAAA;AAChB,CAAC;AAEM,KAAK,UAAU,WAAW,CAAC,EAAiB,EAAE,MAAc,EAAE,IAAS,EAAE,KAAiB,EAAE,EAAW;IAC5G,MAAM,kBAAkB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IACpC,MAAM,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAClE,IAAI,GAAG;QAAE,IAAA,4BAAY,EAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAEjC,MAAM,MAAM,GAAG,IAAA,gCAAgB,EAAC,KAAK,CAAC,CAAA;IACtC,IAAI,KAAK,CAAC,OAAO,IAAI,CAAC,IAAA,wBAAQ,EAAC,KAAK,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,eAAO,CAAC,sBAAsB,EAAE,EAAE,EAAE,6BAA6B,CAAC,CAAA;IAC3H,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,SAAS;QAAE,MAAM,IAAI,eAAO,CAAC,0BAA0B,EAAE,EAAE,EAAE,8BAA8B,CAAC,CAAA;IAC1J,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,KAAK,yBAAe,CAAC,QAAQ,CAAA;IAC5D,IAAI,QAAQ,IAAI,MAAM,CAAC,SAAS,KAAK,UAAU;QAAE,MAAM,IAAI,eAAO,CAAC,gCAAgC,EAAE,EAAE,EAAE,oDAAoD,CAAC,CAAA;IAE9J,MAAM,UAAU,GAAG,EAAE,CAAC,aAAa,CAAC,iBAAO,CAAC,CAAA;IAC5C,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IAC3G,IAAI,SAAS,IAAI,SAAS,CAAC,EAAE,KAAK,EAAE;QAAE,MAAM,IAAI,eAAO,CAAC,0BAA0B,EAAE,EAAE,EAAE,+BAA+B,CAAC,CAAA;IAExH,MAAM,YAAY,GAAG,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,aAAa,CAAC,uBAAY,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACnK,IAAI,KAAK,CAAC,cAAc,IAAI,CAAC,YAAY;QAAE,MAAM,IAAI,eAAO,CAAC,gCAAgC,EAAE,EAAE,EAAE,uDAAuD,CAAC,CAAA;IAE3J,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,IAAA,iCAAiB,EAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;IACjH,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,IAAI,CACnC,UAAU,CAAC,MAAM,CAAC;QAChB,GAAG,GAAG;QACN,GAAG,MAAM;QACT,YAAY;QACZ,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,IAAI;QAC9B,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,yBAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,yBAAe,CAAC,UAAU;QAC1E,YAAY;QACZ,SAAS;QACT,WAAW;QACX,MAAM;QACN,OAAO,EAAE,GAAG,EAAE,OAAO,IAAI,IAAI;QAC7B,OAAO,EAAE,IAAI;QACb,KAAK,EAAE,SAAS;KACjB,CAAC,CACH,CAAA;IAED,MAAM,KAAK,GAAG,EAAE,CAAC,aAAa,CAAC,0BAAW,CAAC,CAAA;IAC3C,IAAI,GAAG;QAAE,MAAM,KAAK,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IAChE,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IAE7G,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAA;IAC3D,MAAM,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;IAC9E,OAAO,KAAK,CAAA;AACd,CAAC;AAEM,KAAK,UAAU,iBAAiB,CAAC,EAAiB,EAAE,MAAc,EAAE,IAAS,EAAE,EAAU,EAAE,MAAyB,EAAE,MAAe;IAC1I,MAAM,kBAAkB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IACpC,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,CAAA;IACrD,KAAK,MAAM,KAAK,IAAI,gBAAgB;QAAE,MAAM,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;IAE9E,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,IAAA,4BAAY,EAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QAC5B,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACpE,MAAM,IAAI,eAAO,CAAC,wBAAwB,EAAE,EAAE,EAAE,6CAA6C,CAAC,CAAA;QAChG,CAAC;QACD,oGAAoG;QACpG,OAAO,CAAC,WAAW,GAAG,4BAAY,CAAA;QAClC,OAAO,CAAC,cAAc,GAAG,IAAA,8BAAc,EAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;QACzD,OAAO,CAAC,MAAM,GAAG,uBAAa,CAAC,MAAM,CAAA;IACvC,CAAC;SAAM,CAAC;QACN,IAAI,OAAO,CAAC,MAAM,KAAK,uBAAa,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE;YAAE,MAAM,IAAI,eAAO,CAAC,sBAAsB,EAAE,EAAE,EAAE,sDAAsD,CAAC,CAAA;QACnK,OAAO,CAAC,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,CAAA;QAClC,OAAO,CAAC,MAAM,GAAG,uBAAa,CAAC,IAAI,CAAA;IACrC,CAAC;IACD,OAAO,CAAC,OAAO,GAAG,IAAI,CAAA;IACtB,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,CAAA;IAClC,MAAM,EAAE,CAAC,aAAa,CAAC,iBAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC1C,MAAM,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IACnE,OAAO,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,CAAA;AACxC,CAAC;AAED,SAAS,kBAAkB,CAAC,EAAiB,EAAE,MAAc,EAAE,IAAS,EAAE,OAAgB,EAAE,MAAc,EAAE,MAAe;IACzH,OAAO,EAAE,CAAC,aAAa,CAAC,4BAAY,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;AAC3J,CAAC;AAED,mGAAmG;AACnG,SAAgB,UAAU,CAAC,OAAgB;IACzC,MAAM,IAAI,GAAG;QACX,IAAI;QACJ,GAAG,2BAAW;QACd,QAAQ;QACR,SAAS;QACT,UAAU;QACV,cAAc;QACd,WAAW;QACX,aAAa;QACb,aAAa;QACb,gBAAgB;QAChB,YAAY;KACb,CAAA;IACD,OAAO;QACL,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;QACnE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,EAAE,EAAE,CAAC,CAAC;YACzI,QAAQ;YACR,WAAW;YACX,QAAQ;YACR,SAAS;YACT,QAAQ;YACR,OAAO;YACP,OAAO;YACP,YAAY;YACZ,iBAAiB,EAAE,iBAAiB,IAAI,IAAI;SAC7C,CAAC,CAAC;KACJ,CAAA;AACH,CAAC","sourcesContent":["import { Counterparty } from '@things-factory/biz-base'\nimport { Domain, Refusal, writeLockSupported } from '@things-factory/shell'\nimport { EntityManager } from 'typeorm'\n\nimport { InvoiceEvent } from '../invoice-event/invoice-event'\nimport { InvoiceItem } from '../invoice-item/invoice-item'\nimport { Invoice, InvoiceStatus, InvoiceTaxBasis } from './invoice'\nimport { calculateDocument, currencyDigits, HEADER_KEYS, normalizedHeader, requireDraft, TAX_ROUNDING, validDay } from './invoice-rules'\nimport { NewInvoice } from './invoice-type'\n\nexport type InvoiceTransitionGuard = (tx: EntityManager, domain: Domain, invoice: Invoice, action: 'ISSUED' | 'VOID') => Promise<void>\nconst transitionGuards = new Set<InvoiceTransitionGuard>()\n\n/** An application refuses a transition its own links forbid — Office keeps a linked invoice from being voided. */\nexport function registerInvoiceTransitionGuard(guard: InvoiceTransitionGuard) {\n transitionGuards.add(guard)\n}\n\n/** Serialize document writes on the domain row, where the database can hold it (shell `writeLockSupported`). */\nexport async function lockDocumentDomain(tx: EntityManager, domain: Domain) {\n const found = await tx.getRepository(Domain).findOne({ where: { id: domain.id }, ...(writeLockSupported(tx) ? { lock: { mode: 'pessimistic_write' } } : {}) })\n if (!found) throw new Refusal('invoice-domain-missing', {}, 'Domain not found')\n}\n\nexport async function invoiceInDomain(tx: EntityManager, domain: Domain, id: string) {\n const invoice = await tx.getRepository(Invoice).findOne({ where: { id, domain: { id: domain.id } }, relations: ['items', 'creator'] })\n if (!invoice) throw new Refusal('invoice-not-found', {}, 'Invoice not found')\n invoice.items.sort((a, b) => a.position - b.position)\n return invoice\n}\n\nexport async function saveInvoice(tx: EntityManager, domain: Domain, user: any, input: NewInvoice, id?: string) {\n await lockDocumentDomain(tx, domain)\n const old = id ? await invoiceInDomain(tx, domain, id) : undefined\n if (old) requireDraft(old.status)\n\n const header = normalizedHeader(input)\n if (input.dueDate && !validDay(input.dueDate)) throw new Refusal('invoice-date-invalid', {}, 'Use a valid YYYY-MM-DD date')\n if (input.issueDate && input.dueDate && input.dueDate < input.issueDate) throw new Refusal('invoice-due-before-issue', {}, 'Due date precedes issue date')\n const received = input.taxBasis === InvoiceTaxBasis.RECEIVED\n if (received && header.direction !== 'PURCHASE') throw new Refusal('invoice-received-purchase-only', {}, 'Only a received purchase invoice keeps printed tax')\n\n const repository = tx.getRepository(Invoice)\n const duplicate = await repository.findOne({ where: { domain: { id: domain.id }, number: header.number } })\n if (duplicate && duplicate.id !== id) throw new Refusal('invoice-number-duplicate', {}, 'Invoice number already exists')\n\n const counterparty = input.counterpartyId ? await tx.getRepository(Counterparty).findOne({ where: { id: input.counterpartyId, domain: { id: domain.id } } }) : null\n if (input.counterpartyId && !counterparty) throw new Refusal('invoice-counterparty-not-found', {}, 'The counterparty was not found - reload and try again')\n\n const { items, supplyAmount, taxAmount, totalAmount } = calculateDocument(input.items, header.currency, received)\n const invoice = await repository.save(\n repository.create({\n ...old,\n ...header,\n counterparty,\n dueDate: input.dueDate ?? null,\n taxBasis: received ? InvoiceTaxBasis.RECEIVED : InvoiceTaxBasis.CALCULATED,\n supplyAmount,\n taxAmount,\n totalAmount,\n domain,\n creator: old?.creator ?? user,\n updater: user,\n items: undefined\n })\n )\n\n const lines = tx.getRepository(InvoiceItem)\n if (old) await lines.softDelete({ invoice: { id: invoice.id } })\n await lines.save(items.map(item => lines.create({ ...item, invoice, domain, creator: user, updater: user })))\n\n const saved = await invoiceInDomain(tx, domain, invoice.id)\n await recordInvoiceEvent(tx, domain, user, saved, old ? 'UPDATED' : 'CREATED')\n return saved\n}\n\nexport async function transitionInvoice(tx: EntityManager, domain: Domain, user: any, id: string, action: 'ISSUED' | 'VOID', reason?: string) {\n await lockDocumentDomain(tx, domain)\n const invoice = await invoiceInDomain(tx, domain, id)\n for (const guard of transitionGuards) await guard(tx, domain, invoice, action)\n\n if (action === 'ISSUED') {\n requireDraft(invoice.status)\n if (!invoice.issueDate || !invoice.dueDate || !invoice.items.length) {\n throw new Refusal('invoice-issue-required', {}, 'Issue date, due date and items are required')\n }\n /* What the amounts were reckoned with stays on the document; a later rule never recomputes them. */\n invoice.taxRounding = TAX_ROUNDING\n invoice.currencyDigits = currencyDigits(invoice.currency)\n invoice.status = InvoiceStatus.ISSUED\n } else {\n if (invoice.status === InvoiceStatus.VOID || !reason?.trim()) throw new Refusal('invoice-void-invalid', {}, 'A cancellation needs a reason and a non-void invoice')\n invoice.voidReason = reason.trim()\n invoice.status = InvoiceStatus.VOID\n }\n invoice.updater = user\n const { items, ...head } = invoice\n await tx.getRepository(Invoice).save(head)\n await recordInvoiceEvent(tx, domain, user, invoice, action, reason)\n return invoiceInDomain(tx, domain, id)\n}\n\nfunction recordInvoiceEvent(tx: EntityManager, domain: Domain, user: any, invoice: Invoice, action: string, reason?: string) {\n return tx.getRepository(InvoiceEvent).save({ domain, invoice, actor: user, action, reason, creator: user, updater: user, snapshot: snapshotOf(invoice) })\n}\n\n/** The document as printed — what an issued invoice said stays readable whatever changes later. */\nexport function snapshotOf(invoice: Invoice) {\n const keys = [\n 'id',\n ...HEADER_KEYS,\n 'status',\n 'dueDate',\n 'taxBasis',\n 'supplyAmount',\n 'taxAmount',\n 'totalAmount',\n 'taxRounding',\n 'currencyDigits',\n 'voidReason'\n ]\n return {\n ...Object.fromEntries(keys.map(key => [key, invoice[key] ?? null])),\n items: invoice.items.map(({ position, description, quantity, unitPrice, discount, taxKind, taxRate, supplyAmount, receivedTaxAmount }) => ({\n position,\n description,\n quantity,\n unitPrice,\n discount,\n taxKind,\n taxRate,\n supplyAmount,\n receivedTaxAmount: receivedTaxAmount ?? null\n }))\n }\n}\n"]}
@@ -31,6 +31,7 @@ export declare abstract class DocumentInput {
31
31
  items: DocumentLineInput[];
32
32
  }
33
33
  export declare class NewInvoice extends DocumentInput {
34
+ counterpartyId?: string;
34
35
  dueDate?: string;
35
36
  taxBasis: InvoiceTaxBasis;
36
37
  }
@@ -118,6 +118,10 @@ exports.DocumentInput = DocumentInput = tslib_1.__decorate([
118
118
  let NewInvoice = class NewInvoice extends DocumentInput {
119
119
  };
120
120
  exports.NewInvoice = NewInvoice;
121
+ tslib_1.__decorate([
122
+ (0, type_graphql_1.Field)({ nullable: true, description: 'Id of the other party among the domain counterparties; empty leaves it unknown' }),
123
+ tslib_1.__metadata("design:type", String)
124
+ ], NewInvoice.prototype, "counterpartyId", void 0);
121
125
  tslib_1.__decorate([
122
126
  (0, type_graphql_1.Field)({ nullable: true, description: 'Payment due date, YYYY-MM-DD' }),
123
127
  tslib_1.__metadata("design:type", String)
@@ -1 +1 @@
1
- {"version":3,"file":"invoice-type.js","sourceRoot":"","sources":["../../../server/service/invoice/invoice-type.ts"],"names":[],"mappings":";;;;AAAA,+CAAuE;AAEvE,+DAAyD;AACzD,uCAAoD;AACpD,mDAAyC;AAGlC,IAAM,iBAAiB,GAAvB,MAAM,iBAAiB;CAQ7B,CAAA;AARY,8CAAiB;AACyB;IAApD,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,2BAA2B,EAAE,CAAC;;sDAAoB;AACrB;IAAlD,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,oBAAK,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;;mDAAiB;AACP;IAA3D,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,oBAAK,EAAE,EAAE,WAAW,EAAE,mBAAmB,EAAE,CAAC;;oDAAkB;AACoC;IAAhH,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,oBAAK,EAAE,EAAE,YAAY,EAAE,CAAC,EAAE,WAAW,EAAE,uDAAuD,EAAE,CAAC;;mDAAiB;AACxB;IAAxG,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,uBAAO,EAAE,EAAE,YAAY,EAAE,uBAAO,CAAC,OAAO,EAAE,WAAW,EAAE,+BAA+B,EAAE,CAAC;;kDAAiB;AACrB;IAAnG,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,oBAAK,EAAE,EAAE,YAAY,EAAE,CAAC,EAAE,WAAW,EAAE,0CAA0C,EAAE,CAAC;;kDAAgB;AACO;IAAzH,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,oBAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,iEAAiE,EAAE,CAAC;;4DAA2B;4BAPzI,iBAAiB;IAD7B,IAAA,wBAAS,EAAC,EAAE,WAAW,EAAE,2CAA2C,EAAE,CAAC;GAC3D,iBAAiB,CAQ7B;AAED,6GAA6G;AAEtG,IAAe,aAAa,GAA5B,MAAe,aAAa;CAkBlC,CAAA;AAlBqB,sCAAa;AACgC;IAAhE,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,uCAAuC,EAAE,CAAC;;6CAAe;AAC2C;IAAzH,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,uCAAiB,EAAE,EAAE,WAAW,EAAE,qEAAqE,EAAE,CAAC;;gDAA6B;AACpG;IAAjD,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,wBAAwB,EAAE,CAAC;;+CAAiB;AACO;IAAxE,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,+CAA+C,EAAE,CAAC;;+CAAiB;AACrC;IAAnD,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,0BAA0B,EAAE,CAAC;;mDAAqB;AACD;IAAtE,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,6BAA6B,EAAE,CAAC;;sDAAyB;AACP;IAAvF,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,8CAA8C,EAAE,CAAC;;iEAAoC;AAC1E;IAAhD,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,uBAAuB,EAAE,CAAC;;gDAAkB;AACE;IAAnE,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,0BAA0B,EAAE,CAAC;;mDAAsB;AACJ;IAApF,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,2CAA2C,EAAE,CAAC;;8DAAiC;AACnD;IAAjE,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,wBAAwB,EAAE,CAAC;;gDAAmB;AACV;IAAzE,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,gCAAgC,EAAE,CAAC;;oDAAuB;AAC5B;IAAnE,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,0BAA0B,EAAE,CAAC;;mDAAsB;AACT;IAA/E,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,sCAAsC,EAAE,CAAC;;kDAAqB;AAC3B;IAAxE,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,+BAA+B,EAAE,CAAC;;4CAAe;AACO;IAA7F,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,oDAAoD,EAAE,CAAC;;sDAAyB;AACvC;IAA9E,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,CAAC,iBAAiB,CAAC,EAAE,EAAE,WAAW,EAAE,wBAAwB,EAAE,CAAC;;4CAA2B;wBAjBrF,aAAa;IADlC,IAAA,wBAAS,EAAC,EAAE,WAAW,EAAE,qDAAqD,EAAE,CAAC;GAC5D,aAAa,CAkBlC;AAGM,IAAM,UAAU,GAAhB,MAAM,UAAW,SAAQ,aAAa;CAI5C,CAAA;AAJY,gCAAU;AACmD;IAAvE,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,8BAA8B,EAAE,CAAC;;2CAAiB;AAExF;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,yBAAe,EAAE,EAAE,YAAY,EAAE,yBAAe,CAAC,UAAU,EAAE,WAAW,EAAE,qDAAqD,EAAE,CAAC;;4CACxH;qBAHd,UAAU;IADtB,IAAA,wBAAS,EAAC,EAAE,WAAW,EAAE,uCAAuC,EAAE,CAAC;GACvD,UAAU,CAItB;AAGM,IAAM,WAAW,GAAjB,MAAM,WAAW;CAGvB,CAAA;AAHY,kCAAW;AAC6C;IAAlE,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,CAAC,iBAAO,CAAC,EAAE,EAAE,WAAW,EAAE,sBAAsB,EAAE,CAAC;;0CAAiB;AACK;IAAvF,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,kBAAG,EAAE,EAAE,WAAW,EAAE,iDAAiD,EAAE,CAAC;;0CAAc;sBAF1F,WAAW;IADvB,IAAA,yBAAU,EAAC,EAAE,WAAW,EAAE,oBAAoB,EAAE,CAAC;GACrC,WAAW,CAGvB","sourcesContent":["import { Field, Float, InputType, Int, ObjectType } from 'type-graphql'\n\nimport { DocumentDirection } from './commercial-document'\nimport { Invoice, InvoiceTaxBasis } from './invoice'\nimport { TaxKind } from './invoice-rules'\n\n@InputType({ description: 'One line of a commercial document to save' })\nexport class DocumentLineInput {\n @Field({ description: 'What the line charges for' }) description: string\n @Field(type => Float, { description: 'Quantity' }) quantity: number\n @Field(type => Float, { description: 'Price of one unit' }) unitPrice: number\n @Field(type => Float, { defaultValue: 0, description: 'Discount taken off the line, in the document currency' }) discount: number\n @Field(type => TaxKind, { defaultValue: TaxKind.TAXABLE, description: 'Taxable, zero-rated or exempt' }) taxKind: TaxKind\n @Field(type => Float, { defaultValue: 0, description: 'Tax rate in percent; zero unless taxable' }) taxRate: number\n @Field(type => Float, { nullable: true, description: 'Tax the sender printed on the line — only on a received invoice' }) receivedTaxAmount?: number\n}\n\n/** The head and lines every commercial document writes; invoice and quotation inputs add their own dates. */\n@InputType({ description: 'The printed head and lines of a commercial document' })\nexport abstract class DocumentInput {\n @Field({ description: 'Document number, unique in the domain' }) number: string\n @Field(type => DocumentDirection, { description: 'SALES for a document the domain sends, PURCHASE for one it receives' }) direction: DocumentDirection\n @Field({ description: 'ISO 4217 currency code' }) currency: string\n @Field({ description: 'Language the document is printed in: ko or en' }) language: string\n @Field({ description: 'Supplier name as printed' }) supplierName: string\n @Field({ nullable: true, description: 'Supplier address as printed' }) supplierAddress?: string\n @Field({ nullable: true, description: 'Supplier business or tax registration number' }) supplierRegistrationNumber?: string\n @Field({ description: 'Buyer name as printed' }) buyerName: string\n @Field({ nullable: true, description: 'Buyer address as printed' }) buyerAddress?: string\n @Field({ nullable: true, description: 'Buyer business or tax registration number' }) buyerRegistrationNumber?: string\n @Field({ nullable: true, description: 'Issue date, YYYY-MM-DD' }) issueDate?: string\n @Field({ nullable: true, description: 'Buyer purchase order reference' }) purchaseOrder?: string\n @Field({ nullable: true, description: 'Payment terms as printed' }) paymentTerms?: string\n @Field({ nullable: true, description: 'Bank account to pay into, as printed' }) bankDetails?: string\n @Field({ nullable: true, description: 'Notes printed on the document' }) notes?: string\n @Field({ nullable: true, description: 'Reference to the record the document was made from' }) sourceReference?: string\n @Field(type => [DocumentLineInput], { description: 'Lines in printed order' }) items: DocumentLineInput[]\n}\n\n@InputType({ description: 'An invoice draft to create or replace' })\nexport class NewInvoice extends DocumentInput {\n @Field({ nullable: true, description: 'Payment due date, YYYY-MM-DD' }) dueDate?: string\n @Field(type => InvoiceTaxBasis, { defaultValue: InvoiceTaxBasis.CALCULATED, description: 'Reckoned tax, or the tax a received invoice printed' })\n taxBasis: InvoiceTaxBasis\n}\n\n@ObjectType({ description: 'A page of invoices' })\nexport class InvoiceList {\n @Field(type => [Invoice], { description: 'Invoices on the page' }) items: Invoice[]\n @Field(type => Int, { description: 'Number of invoices matching the list parameters' }) total: number\n}\n"]}
1
+ {"version":3,"file":"invoice-type.js","sourceRoot":"","sources":["../../../server/service/invoice/invoice-type.ts"],"names":[],"mappings":"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","sourcesContent":["import { Field, Float, InputType, Int, ObjectType } from 'type-graphql'\n\nimport { DocumentDirection } from './commercial-document'\nimport { Invoice, InvoiceTaxBasis } from './invoice'\nimport { TaxKind } from './invoice-rules'\n\n@InputType({ description: 'One line of a commercial document to save' })\nexport class DocumentLineInput {\n @Field({ description: 'What the line charges for' }) description: string\n @Field(type => Float, { description: 'Quantity' }) quantity: number\n @Field(type => Float, { description: 'Price of one unit' }) unitPrice: number\n @Field(type => Float, { defaultValue: 0, description: 'Discount taken off the line, in the document currency' }) discount: number\n @Field(type => TaxKind, { defaultValue: TaxKind.TAXABLE, description: 'Taxable, zero-rated or exempt' }) taxKind: TaxKind\n @Field(type => Float, { defaultValue: 0, description: 'Tax rate in percent; zero unless taxable' }) taxRate: number\n @Field(type => Float, { nullable: true, description: 'Tax the sender printed on the line — only on a received invoice' }) receivedTaxAmount?: number\n}\n\n/** The head and lines every commercial document writes; invoice and quotation inputs add their own dates. */\n@InputType({ description: 'The printed head and lines of a commercial document' })\nexport abstract class DocumentInput {\n @Field({ description: 'Document number, unique in the domain' }) number: string\n @Field(type => DocumentDirection, { description: 'SALES for a document the domain sends, PURCHASE for one it receives' }) direction: DocumentDirection\n @Field({ description: 'ISO 4217 currency code' }) currency: string\n @Field({ description: 'Language the document is printed in: ko or en' }) language: string\n @Field({ description: 'Supplier name as printed' }) supplierName: string\n @Field({ nullable: true, description: 'Supplier address as printed' }) supplierAddress?: string\n @Field({ nullable: true, description: 'Supplier business or tax registration number' }) supplierRegistrationNumber?: string\n @Field({ description: 'Buyer name as printed' }) buyerName: string\n @Field({ nullable: true, description: 'Buyer address as printed' }) buyerAddress?: string\n @Field({ nullable: true, description: 'Buyer business or tax registration number' }) buyerRegistrationNumber?: string\n @Field({ nullable: true, description: 'Issue date, YYYY-MM-DD' }) issueDate?: string\n @Field({ nullable: true, description: 'Buyer purchase order reference' }) purchaseOrder?: string\n @Field({ nullable: true, description: 'Payment terms as printed' }) paymentTerms?: string\n @Field({ nullable: true, description: 'Bank account to pay into, as printed' }) bankDetails?: string\n @Field({ nullable: true, description: 'Notes printed on the document' }) notes?: string\n @Field({ nullable: true, description: 'Reference to the record the document was made from' }) sourceReference?: string\n @Field(type => [DocumentLineInput], { description: 'Lines in printed order' }) items: DocumentLineInput[]\n}\n\n@InputType({ description: 'An invoice draft to create or replace' })\nexport class NewInvoice extends DocumentInput {\n @Field({ nullable: true, description: 'Id of the other party among the domain counterparties; empty leaves it unknown' }) counterpartyId?: string\n @Field({ nullable: true, description: 'Payment due date, YYYY-MM-DD' }) dueDate?: string\n @Field(type => InvoiceTaxBasis, { defaultValue: InvoiceTaxBasis.CALCULATED, description: 'Reckoned tax, or the tax a received invoice printed' })\n taxBasis: InvoiceTaxBasis\n}\n\n@ObjectType({ description: 'A page of invoices' })\nexport class InvoiceList {\n @Field(type => [Invoice], { description: 'Invoices on the page' }) items: Invoice[]\n @Field(type => Int, { description: 'Number of invoices matching the list parameters' }) total: number\n}\n"]}
@@ -1,4 +1,5 @@
1
1
  import { User } from '@things-factory/auth-base';
2
+ import { Counterparty } from '@things-factory/biz-base';
2
3
  import { Domain } from '@things-factory/shell';
3
4
  import { InvoiceItem } from '../invoice-item/invoice-item';
4
5
  import { CommercialDocument } from './commercial-document';
@@ -15,6 +16,8 @@ export declare class Invoice extends CommercialDocument {
15
16
  readonly id: string;
16
17
  domain?: Domain;
17
18
  domainId?: string;
19
+ counterparty?: Counterparty;
20
+ counterpartyId?: string;
18
21
  status: InvoiceStatus;
19
22
  dueDate?: string;
20
23
  taxBasis: InvoiceTaxBasis;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Invoice = exports.InvoiceTaxBasis = exports.InvoiceStatus = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const auth_base_1 = require("@things-factory/auth-base");
6
+ const biz_base_1 = require("@things-factory/biz-base");
6
7
  const shell_1 = require("@things-factory/shell");
7
8
  const type_graphql_1 = require("type-graphql");
8
9
  const typeorm_1 = require("typeorm");
@@ -41,6 +42,16 @@ tslib_1.__decorate([
41
42
  (0, typeorm_1.RelationId)((invoice) => invoice.domain),
42
43
  tslib_1.__metadata("design:type", String)
43
44
  ], Invoice.prototype, "domainId", void 0);
45
+ tslib_1.__decorate([
46
+ (0, typeorm_1.ManyToOne)(type => biz_base_1.Counterparty, { nullable: true }),
47
+ (0, type_graphql_1.Field)(type => biz_base_1.Counterparty, { nullable: true, description: 'The other party among the domain counterparties: the buyer of a sale, the supplier of a purchase' }),
48
+ tslib_1.__metadata("design:type", biz_base_1.Counterparty)
49
+ ], Invoice.prototype, "counterparty", void 0);
50
+ tslib_1.__decorate([
51
+ (0, typeorm_1.RelationId)((invoice) => invoice.counterparty),
52
+ (0, type_graphql_1.Field)({ nullable: true, description: 'Id of the other party among the domain counterparties' }),
53
+ tslib_1.__metadata("design:type", String)
54
+ ], Invoice.prototype, "counterpartyId", void 0);
44
55
  tslib_1.__decorate([
45
56
  (0, typeorm_1.Column)({ default: InvoiceStatus.DRAFT }),
46
57
  (0, type_graphql_1.Field)(type => InvoiceStatus, { description: 'Draft, issued or void' }),
@@ -1 +1 @@
1
- {"version":3,"file":"invoice.js","sourceRoot":"","sources":["../../../server/service/invoice/invoice.ts"],"names":[],"mappings":"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","sourcesContent":["import { User } from '@things-factory/auth-base'\nimport { Domain } from '@things-factory/shell'\nimport { Field, ID, ObjectType, registerEnumType } from 'type-graphql'\nimport { Column, CreateDateColumn, DeleteDateColumn, Entity, Index, ManyToOne, OneToMany, PrimaryGeneratedColumn, RelationId, UpdateDateColumn } from 'typeorm'\n\nimport { InvoiceItem } from '../invoice-item/invoice-item'\nimport { CommercialDocument } from './commercial-document'\n\nexport enum InvoiceStatus {\n DRAFT = 'DRAFT',\n ISSUED = 'ISSUED',\n VOID = 'VOID'\n}\nregisterEnumType(InvoiceStatus, { name: 'InvoiceStatus', description: 'state of an invoice — draft, issued or void' })\n\nexport enum InvoiceTaxBasis {\n CALCULATED = 'CALCULATED',\n RECEIVED = 'RECEIVED'\n}\nregisterEnumType(InvoiceTaxBasis, {\n name: 'InvoiceTaxBasis',\n description: 'whether the tax is reckoned from the supply groups or kept as the sender printed it on each line'\n})\n\n@Entity()\n@Index('ix_invoice_0', (invoice: Invoice) => [invoice.domain, invoice.number], { unique: true, where: '\"deleted_at\" IS NULL' })\n@Index('ix_invoice_1', (invoice: Invoice) => [invoice.domain, invoice.status, invoice.dueDate])\n@ObjectType({ description: 'Entity for Invoice — a commercial invoice, domestic or international' })\nexport class Invoice extends CommercialDocument {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID)\n readonly id: string\n\n @ManyToOne(type => Domain)\n @Field(type => Domain, { nullable: true })\n domain?: Domain\n\n @RelationId((invoice: Invoice) => invoice.domain)\n domainId?: string\n\n @Column({ default: InvoiceStatus.DRAFT })\n @Field(type => InvoiceStatus, { description: 'Draft, issued or void' })\n status: InvoiceStatus\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Payment due date, YYYY-MM-DD' })\n dueDate?: string\n\n @Column({ default: InvoiceTaxBasis.CALCULATED })\n @Field(type => InvoiceTaxBasis, { description: 'Reckoned tax, or the tax a received invoice printed' })\n taxBasis: InvoiceTaxBasis\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Why the invoice was voided' })\n voidReason?: string\n\n @OneToMany(type => InvoiceItem, item => item.invoice)\n @Field(type => [InvoiceItem], { description: 'Lines in printed order' })\n items: InvoiceItem[]\n\n @CreateDateColumn()\n @Field({ nullable: true, description: 'When the invoice was created' })\n createdAt?: Date\n\n @UpdateDateColumn()\n @Field({ nullable: true, description: 'When the invoice last changed' })\n updatedAt?: Date\n\n @DeleteDateColumn()\n @Field({ nullable: true, description: 'When the invoice was deleted' })\n deletedAt?: Date\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true })\n creator?: User\n\n @RelationId((invoice: Invoice) => invoice.creator)\n creatorId?: string\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true })\n updater?: User\n\n @RelationId((invoice: Invoice) => invoice.updater)\n updaterId?: string\n}\n"]}
1
+ {"version":3,"file":"invoice.js","sourceRoot":"","sources":["../../../server/service/invoice/invoice.ts"],"names":[],"mappings":"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","sourcesContent":["import { User } from '@things-factory/auth-base'\nimport { Counterparty } from '@things-factory/biz-base'\nimport { Domain } from '@things-factory/shell'\nimport { Field, ID, ObjectType, registerEnumType } from 'type-graphql'\nimport { Column, CreateDateColumn, DeleteDateColumn, Entity, Index, ManyToOne, OneToMany, PrimaryGeneratedColumn, RelationId, UpdateDateColumn } from 'typeorm'\n\nimport { InvoiceItem } from '../invoice-item/invoice-item'\nimport { CommercialDocument } from './commercial-document'\n\nexport enum InvoiceStatus {\n DRAFT = 'DRAFT',\n ISSUED = 'ISSUED',\n VOID = 'VOID'\n}\nregisterEnumType(InvoiceStatus, { name: 'InvoiceStatus', description: 'state of an invoice — draft, issued or void' })\n\nexport enum InvoiceTaxBasis {\n CALCULATED = 'CALCULATED',\n RECEIVED = 'RECEIVED'\n}\nregisterEnumType(InvoiceTaxBasis, {\n name: 'InvoiceTaxBasis',\n description: 'whether the tax is reckoned from the supply groups or kept as the sender printed it on each line'\n})\n\n@Entity()\n@Index('ix_invoice_0', (invoice: Invoice) => [invoice.domain, invoice.number], { unique: true, where: '\"deleted_at\" IS NULL' })\n@Index('ix_invoice_1', (invoice: Invoice) => [invoice.domain, invoice.status, invoice.dueDate])\n@ObjectType({ description: 'Entity for Invoice — a commercial invoice, domestic or international' })\nexport class Invoice extends CommercialDocument {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID)\n readonly id: string\n\n @ManyToOne(type => Domain)\n @Field(type => Domain, { nullable: true })\n domain?: Domain\n\n @RelationId((invoice: Invoice) => invoice.domain)\n domainId?: string\n\n /* The printed buyer or supplier stays as printed; this is who it is among the domain's counterparties (ADR-0122). */\n @ManyToOne(type => Counterparty, { nullable: true })\n @Field(type => Counterparty, { nullable: true, description: 'The other party among the domain counterparties: the buyer of a sale, the supplier of a purchase' })\n counterparty?: Counterparty\n\n @RelationId((invoice: Invoice) => invoice.counterparty)\n @Field({ nullable: true, description: 'Id of the other party among the domain counterparties' })\n counterpartyId?: string\n\n @Column({ default: InvoiceStatus.DRAFT })\n @Field(type => InvoiceStatus, { description: 'Draft, issued or void' })\n status: InvoiceStatus\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Payment due date, YYYY-MM-DD' })\n dueDate?: string\n\n @Column({ default: InvoiceTaxBasis.CALCULATED })\n @Field(type => InvoiceTaxBasis, { description: 'Reckoned tax, or the tax a received invoice printed' })\n taxBasis: InvoiceTaxBasis\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Why the invoice was voided' })\n voidReason?: string\n\n @OneToMany(type => InvoiceItem, item => item.invoice)\n @Field(type => [InvoiceItem], { description: 'Lines in printed order' })\n items: InvoiceItem[]\n\n @CreateDateColumn()\n @Field({ nullable: true, description: 'When the invoice was created' })\n createdAt?: Date\n\n @UpdateDateColumn()\n @Field({ nullable: true, description: 'When the invoice last changed' })\n updatedAt?: Date\n\n @DeleteDateColumn()\n @Field({ nullable: true, description: 'When the invoice was deleted' })\n deletedAt?: Date\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true })\n creator?: User\n\n @RelationId((invoice: Invoice) => invoice.creator)\n creatorId?: string\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true })\n updater?: User\n\n @RelationId((invoice: Invoice) => invoice.updater)\n updaterId?: string\n}\n"]}