@accounter/server 0.0.9-alpha-20251216161545-668306e40cf3aed663f444e0004246489fbec6d4 → 0.0.9-alpha-20251217093036-7168648b507d62946aa287af4ea690b73b077b2d

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 (55) hide show
  1. package/CHANGELOG.md +34 -5
  2. package/dist/green-invoice-graphql/src/mesh-artifacts/index.d.ts +1 -1
  3. package/dist/server/src/__generated__/types.d.ts +282 -301
  4. package/dist/server/src/__generated__/types.js.map +1 -1
  5. package/dist/server/src/modules/app-providers/green-invoice-client.d.ts +3 -3
  6. package/dist/server/src/modules/contracts/helpers/contracts.helper.d.ts +2 -0
  7. package/dist/server/src/modules/contracts/helpers/contracts.helper.js +20 -0
  8. package/dist/server/src/modules/contracts/helpers/contracts.helper.js.map +1 -1
  9. package/dist/server/src/modules/documents/__generated__/types.d.ts +121 -7
  10. package/dist/server/src/modules/documents/__generated__/types.js.map +1 -1
  11. package/dist/server/src/modules/documents/helpers/common.helper.d.ts +2 -0
  12. package/dist/server/src/modules/documents/helpers/common.helper.js +20 -0
  13. package/dist/server/src/modules/documents/helpers/common.helper.js.map +1 -1
  14. package/dist/server/src/modules/documents/helpers/issue-document.helper.d.ts +21 -0
  15. package/dist/server/src/modules/{green-invoice → documents}/helpers/issue-document.helper.js +61 -11
  16. package/dist/server/src/modules/documents/helpers/issue-document.helper.js.map +1 -0
  17. package/dist/server/src/modules/documents/index.js +9 -2
  18. package/dist/server/src/modules/documents/index.js.map +1 -1
  19. package/dist/server/src/modules/documents/resolvers/documents-issuing.resolver.d.ts +2 -0
  20. package/dist/server/src/modules/documents/resolvers/documents-issuing.resolver.js +357 -0
  21. package/dist/server/src/modules/documents/resolvers/documents-issuing.resolver.js.map +1 -0
  22. package/dist/server/src/modules/documents/typeDefs/documents-issuing.graphql.d.ts +2 -0
  23. package/dist/server/src/modules/documents/typeDefs/documents-issuing.graphql.js +228 -0
  24. package/dist/server/src/modules/documents/typeDefs/documents-issuing.graphql.js.map +1 -0
  25. package/dist/server/src/modules/green-invoice/__generated__/types.d.ts +6 -135
  26. package/dist/server/src/modules/green-invoice/__generated__/types.js +0 -2
  27. package/dist/server/src/modules/green-invoice/__generated__/types.js.map +1 -1
  28. package/dist/server/src/modules/green-invoice/helpers/green-invoice.helper.d.ts +21 -27
  29. package/dist/server/src/modules/green-invoice/helpers/green-invoice.helper.js +160 -151
  30. package/dist/server/src/modules/green-invoice/helpers/green-invoice.helper.js.map +1 -1
  31. package/dist/server/src/modules/green-invoice/resolvers/green-invoice.resolvers.js +4 -347
  32. package/dist/server/src/modules/green-invoice/resolvers/green-invoice.resolvers.js.map +1 -1
  33. package/dist/server/src/modules/green-invoice/typeDefs/green-invoice.graphql.js +4 -512
  34. package/dist/server/src/modules/green-invoice/typeDefs/green-invoice.graphql.js.map +1 -1
  35. package/dist/shaam-uniform-format-generator/src/generator/records/b110.d.ts +35 -35
  36. package/dist/shaam-uniform-format-generator/src/types/enums.d.ts +71 -71
  37. package/package.json +2 -2
  38. package/src/__generated__/types.ts +327 -620
  39. package/src/modules/contracts/helpers/contracts.helper.ts +22 -0
  40. package/src/modules/documents/__generated__/types.ts +121 -7
  41. package/src/modules/documents/helpers/common.helper.ts +21 -0
  42. package/src/modules/{green-invoice → documents}/helpers/issue-document.helper.ts +104 -44
  43. package/src/modules/documents/index.ts +9 -2
  44. package/src/modules/documents/resolvers/documents-issuing.resolver.ts +554 -0
  45. package/src/modules/documents/typeDefs/documents-issuing.graphql.ts +228 -0
  46. package/src/modules/green-invoice/__generated__/types.ts +6 -137
  47. package/src/modules/green-invoice/helpers/green-invoice.helper.ts +195 -201
  48. package/src/modules/green-invoice/resolvers/green-invoice.resolvers.ts +5 -520
  49. package/src/modules/green-invoice/typeDefs/green-invoice.graphql.ts +4 -512
  50. package/dist/server/src/modules/green-invoice/helpers/contract-to-draft.helper.d.ts +0 -7
  51. package/dist/server/src/modules/green-invoice/helpers/contract-to-draft.helper.js +0 -53
  52. package/dist/server/src/modules/green-invoice/helpers/contract-to-draft.helper.js.map +0 -1
  53. package/dist/server/src/modules/green-invoice/helpers/issue-document.helper.d.ts +0 -19
  54. package/dist/server/src/modules/green-invoice/helpers/issue-document.helper.js.map +0 -1
  55. package/src/modules/green-invoice/helpers/contract-to-draft.helper.ts +0 -69
@@ -14,6 +14,17 @@ export function normalizeSubscriptionPlan(raw?: string | null): SubscriptionPlan
14
14
  }
15
15
  }
16
16
 
17
+ export function getSubscriptionPlanName(plan: SubscriptionPlan): string {
18
+ switch (plan) {
19
+ case 'ENTERPRISE':
20
+ return 'Enterprise License';
21
+ case 'PRO':
22
+ return 'Pro Plan';
23
+ default:
24
+ throw new Error(`Unknown subscription plan: ${plan}`);
25
+ }
26
+ }
27
+
17
28
  export function normalizeProduct(raw?: string | null): Product | null {
18
29
  if (!raw) {
19
30
  return null;
@@ -28,6 +39,17 @@ export function normalizeProduct(raw?: string | null): Product | null {
28
39
  }
29
40
  }
30
41
 
42
+ export function getProductName(product: Product): string {
43
+ switch (product) {
44
+ case 'HIVE':
45
+ return 'GraphQL Hive';
46
+ case 'STELLATE':
47
+ return 'Stellate';
48
+ default:
49
+ throw new Error(`Unknown product: ${product}`);
50
+ }
51
+ }
52
+
31
53
  export function normalizeBillingCycle(raw: string): BillingCycle {
32
54
  switch (raw.toLocaleLowerCase()) {
33
55
  case 'monthly':
@@ -3,8 +3,13 @@ import * as gm from "graphql-modules";
3
3
  export namespace DocumentsModule {
4
4
  interface DefinedFields {
5
5
  DocumentSuggestions: 'owner' | 'counterparty' | 'amount' | 'isIncome';
6
- Query: 'documents' | 'documentsByFilters' | 'documentById' | 'recentDocumentsByBusiness' | 'recentDocumentsByClient' | 'recentIssuedDocumentsByType';
7
- Mutation: 'insertDocument' | 'updateDocument' | 'deleteDocument' | 'uploadDocument' | 'batchUploadDocuments' | 'batchUploadDocumentsFromGoogleDrive' | 'closeDocument';
6
+ Query: 'newDocumentDraftByCharge' | 'newDocumentDraftByDocument' | 'periodicalDocumentDrafts' | 'periodicalDocumentDraftsByContracts' | 'clientMonthlyChargeDraft' | 'documents' | 'documentsByFilters' | 'documentById' | 'recentDocumentsByBusiness' | 'recentDocumentsByClient' | 'recentIssuedDocumentsByType';
7
+ Mutation: 'issueGreenInvoiceDocuments' | 'issueGreenInvoiceDocument' | 'previewDocument' | 'insertDocument' | 'updateDocument' | 'deleteDocument' | 'uploadDocument' | 'batchUploadDocuments' | 'batchUploadDocumentsFromGoogleDrive' | 'closeDocument';
8
+ GenerateDocumentsResult: 'success' | 'errors';
9
+ DocumentDraft: 'description' | 'remarks' | 'footer' | 'type' | 'date' | 'dueDate' | 'language' | 'currency' | 'vatType' | 'discount' | 'rounding' | 'signed' | 'maxPayments' | 'client' | 'income' | 'payment' | 'linkedDocumentIds' | 'linkedPaymentId' | 'linkType';
10
+ DocumentIncomeRecord: 'currency' | 'currencyRate' | 'description' | 'itemId' | 'price' | 'quantity' | 'vatRate' | 'vatType';
11
+ DocumentPaymentRecord: 'currency' | 'currencyRate' | 'date' | 'price' | 'type' | 'bankName' | 'bankBranch' | 'bankAccount' | 'chequeNum' | 'accountId' | 'transactionId' | 'cardType' | 'cardNum' | 'numPayments' | 'firstPayment';
12
+ DocumentDiscount: 'amount' | 'type';
8
13
  Unprocessed: 'id' | 'image' | 'file' | 'documentType' | 'isReviewed';
9
14
  OtherDocument: 'id' | 'image' | 'file' | 'documentType' | 'isReviewed';
10
15
  Invoice: 'missingInfoSuggestions' | 'id' | 'image' | 'file' | 'vat' | 'documentType' | 'isReviewed' | 'serialNumber' | 'date' | 'amount' | 'vatReportDateOverride' | 'noVatAmount' | 'allocationNumber' | 'exchangeRateOverride' | 'issuedDocumentInfo';
@@ -34,11 +39,22 @@ export namespace DocumentsModule {
34
39
  };
35
40
 
36
41
  interface DefinedEnumValues {
42
+ DocumentLanguage: 'ENGLISH' | 'HEBREW';
43
+ DocumentVatType: 'DEFAULT' | 'EXEMPT' | 'MIXED';
44
+ DocumentDiscountType: 'SUM' | 'PERCENTAGE';
45
+ PaymentType: 'TAX_DEDUCTION' | 'CASH' | 'CHEQUE' | 'CREDIT_CARD' | 'WIRE_TRANSFER' | 'PAYPAL' | 'OTHER_DEDUCTION' | 'PAYMENT_APP' | 'OTHER';
46
+ DocumentLinkType: 'LINK' | 'CANCEL';
47
+ DocumentPaymentRecordCardType: 'UNKNOWN' | 'ISRACARD' | 'VISA' | 'MASTERCARD' | 'AMERICAN_EXPRESS' | 'DINERS';
37
48
  DocumentType: 'INVOICE' | 'RECEIPT' | 'INVOICE_RECEIPT' | 'CREDIT_INVOICE' | 'PROFORMA' | 'UNPROCESSED' | 'OTHER';
38
49
  DocumentStatus: 'OPEN' | 'CLOSED' | 'MANUALLY_CLOSED' | 'CANCELLED_BY_OTHER_DOC' | 'CANCELLED';
39
50
  };
40
51
 
41
52
  interface DefinedInputFields {
53
+ DocumentIssueInput: 'description' | 'remarks' | 'footer' | 'type' | 'date' | 'dueDate' | 'language' | 'currency' | 'vatType' | 'discount' | 'rounding' | 'signed' | 'maxPayments' | 'client' | 'income' | 'payment' | 'linkedDocumentIds' | 'linkedPaymentId' | 'linkType';
54
+ DocumentDiscountInput: 'amount' | 'type';
55
+ DocumentClientInput: 'country' | 'emails' | 'id' | 'name' | 'phone' | 'taxId' | 'self' | 'address' | 'city' | 'zip' | 'fax' | 'mobile' | 'add';
56
+ DocumentIncomeRecordInput: 'amount' | 'amountTotal' | 'catalogNum' | 'currency' | 'currencyRate' | 'description' | 'itemId' | 'price' | 'quantity' | 'vat' | 'vatRate' | 'vatType';
57
+ DocumentPaymentRecordInput: 'currency' | 'currencyRate' | 'date' | 'price' | 'type' | 'bankName' | 'bankBranch' | 'bankAccount' | 'chequeNum' | 'accountId' | 'transactionId' | 'cardType' | 'cardNum' | 'numPayments' | 'firstPayment';
42
58
  DocumentsFilters: 'businessIDs' | 'ownerIDs' | 'fromDate' | 'toDate' | 'unmatched';
43
59
  UpdateDocumentFieldsInput: 'vat' | 'serialNumber' | 'date' | 'amount' | 'documentType' | 'image' | 'file' | 'chargeId' | 'creditorId' | 'debtorId' | 'vatReportDateOverride' | 'noVatAmount' | 'allocationNumber' | 'exchangeRateOverride';
44
60
  InsertDocumentInput: 'image' | 'file' | 'vat' | 'documentType' | 'serialNumber' | 'date' | 'amount' | 'chargeId' | 'creditorId' | 'debtorId' | 'vatReportDateOverride' | 'noVatAmount' | 'allocationNumber' | 'exchangeRateOverride';
@@ -54,18 +70,38 @@ export namespace DocumentsModule {
54
70
  export type FinancialEntity = Types.FinancialEntity;
55
71
  export type FinancialAmount = Types.FinancialAmount;
56
72
  export type Query = Pick<Types.Query, DefinedFields['Query']>;
57
- export type Document = Pick<Types.Document, DefinedFields['Document']>;
58
- export type DocumentsFilters = Pick<Types.DocumentsFilters, DefinedInputFields['DocumentsFilters']>;
73
+ export type DocumentDraft = Pick<Types.DocumentDraft, DefinedFields['DocumentDraft']>;
59
74
  export type UUID = Types.Uuid;
60
- export type DocumentType = DefinedEnumValues['DocumentType'];
61
75
  export type TimelessDate = Types.TimelessDate;
62
76
  export type Mutation = Pick<Types.Mutation, DefinedFields['Mutation']>;
77
+ export type GenerateDocumentsResult = Pick<Types.GenerateDocumentsResult, DefinedFields['GenerateDocumentsResult']>;
78
+ export type DocumentIssueInput = Pick<Types.DocumentIssueInput, DefinedInputFields['DocumentIssueInput']>;
79
+ export type Charge = Types.Charge;
80
+ export type FileScalar = Types.FileScalar;
81
+ export type DocumentType = DefinedEnumValues['DocumentType'];
82
+ export type DocumentLanguage = DefinedEnumValues['DocumentLanguage'];
83
+ export type Currency = Types.Currency;
84
+ export type DocumentVatType = DefinedEnumValues['DocumentVatType'];
85
+ export type DocumentDiscount = Pick<Types.DocumentDiscount, DefinedFields['DocumentDiscount']>;
86
+ export type Client = Types.Client;
87
+ export type DocumentIncomeRecord = Pick<Types.DocumentIncomeRecord, DefinedFields['DocumentIncomeRecord']>;
88
+ export type DocumentPaymentRecord = Pick<Types.DocumentPaymentRecord, DefinedFields['DocumentPaymentRecord']>;
89
+ export type DocumentLinkType = DefinedEnumValues['DocumentLinkType'];
90
+ export type PaymentType = DefinedEnumValues['PaymentType'];
91
+ export type DocumentPaymentRecordCardType = DefinedEnumValues['DocumentPaymentRecordCardType'];
92
+ export type DocumentDiscountType = DefinedEnumValues['DocumentDiscountType'];
93
+ export type DocumentDiscountInput = Pick<Types.DocumentDiscountInput, DefinedInputFields['DocumentDiscountInput']>;
94
+ export type DocumentClientInput = Pick<Types.DocumentClientInput, DefinedInputFields['DocumentClientInput']>;
95
+ export type DocumentIncomeRecordInput = Pick<Types.DocumentIncomeRecordInput, DefinedInputFields['DocumentIncomeRecordInput']>;
96
+ export type DocumentPaymentRecordInput = Pick<Types.DocumentPaymentRecordInput, DefinedInputFields['DocumentPaymentRecordInput']>;
97
+ export type CountryCode = Types.CountryCode;
98
+ export type Document = Pick<Types.Document, DefinedFields['Document']>;
99
+ export type DocumentsFilters = Pick<Types.DocumentsFilters, DefinedInputFields['DocumentsFilters']>;
63
100
  export type InsertDocumentResult = Types.InsertDocumentResult;
64
101
  export type InsertDocumentInput = Pick<Types.InsertDocumentInput, DefinedInputFields['InsertDocumentInput']>;
65
102
  export type UpdateDocumentResult = Types.UpdateDocumentResult;
66
103
  export type UpdateDocumentFieldsInput = Pick<Types.UpdateDocumentFieldsInput, DefinedInputFields['UpdateDocumentFieldsInput']>;
67
104
  export type UploadDocumentResult = Types.UploadDocumentResult;
68
- export type FileScalar = Types.FileScalar;
69
105
  export type Linkable = Pick<Types.Linkable, DefinedFields['Linkable']>;
70
106
  export type URL = Types.Url;
71
107
  export type Unprocessed = Pick<Types.Unprocessed, DefinedFields['Unprocessed']>;
@@ -75,7 +111,6 @@ export namespace DocumentsModule {
75
111
  export type CommonError = Types.CommonError;
76
112
  export type InsertDocumentSuccessfulResult = Pick<Types.InsertDocumentSuccessfulResult, DefinedFields['InsertDocumentSuccessfulResult']>;
77
113
  export type UploadDocumentSuccessfulResult = Pick<Types.UploadDocumentSuccessfulResult, DefinedFields['UploadDocumentSuccessfulResult']>;
78
- export type Charge = Types.Charge;
79
114
  export type CommonCharge = Types.CommonCharge;
80
115
  export type FinancialCharge = Types.FinancialCharge;
81
116
  export type ConversionCharge = Types.ConversionCharge;
@@ -93,6 +128,11 @@ export namespace DocumentsModule {
93
128
  export type DocumentSuggestionsResolvers = Pick<Types.DocumentSuggestionsResolvers, DefinedFields['DocumentSuggestions']>;
94
129
  export type QueryResolvers = Pick<Types.QueryResolvers, DefinedFields['Query']>;
95
130
  export type MutationResolvers = Pick<Types.MutationResolvers, DefinedFields['Mutation']>;
131
+ export type GenerateDocumentsResultResolvers = Pick<Types.GenerateDocumentsResultResolvers, DefinedFields['GenerateDocumentsResult']>;
132
+ export type DocumentDraftResolvers = Pick<Types.DocumentDraftResolvers, DefinedFields['DocumentDraft']>;
133
+ export type DocumentIncomeRecordResolvers = Pick<Types.DocumentIncomeRecordResolvers, DefinedFields['DocumentIncomeRecord']>;
134
+ export type DocumentPaymentRecordResolvers = Pick<Types.DocumentPaymentRecordResolvers, DefinedFields['DocumentPaymentRecord']>;
135
+ export type DocumentDiscountResolvers = Pick<Types.DocumentDiscountResolvers, DefinedFields['DocumentDiscount']>;
96
136
  export type UnprocessedResolvers = Pick<Types.UnprocessedResolvers, DefinedFields['Unprocessed'] | '__isTypeOf'>;
97
137
  export type OtherDocumentResolvers = Pick<Types.OtherDocumentResolvers, DefinedFields['OtherDocument'] | '__isTypeOf'>;
98
138
  export type InvoiceResolvers = Pick<Types.InvoiceResolvers, DefinedFields['Invoice'] | '__isTypeOf'>;
@@ -124,6 +164,11 @@ export namespace DocumentsModule {
124
164
  DocumentSuggestions?: DocumentSuggestionsResolvers;
125
165
  Query?: QueryResolvers;
126
166
  Mutation?: MutationResolvers;
167
+ GenerateDocumentsResult?: GenerateDocumentsResultResolvers;
168
+ DocumentDraft?: DocumentDraftResolvers;
169
+ DocumentIncomeRecord?: DocumentIncomeRecordResolvers;
170
+ DocumentPaymentRecord?: DocumentPaymentRecordResolvers;
171
+ DocumentDiscount?: DocumentDiscountResolvers;
127
172
  Unprocessed?: UnprocessedResolvers;
128
173
  OtherDocument?: OtherDocumentResolvers;
129
174
  Invoice?: InvoiceResolvers;
@@ -251,6 +296,11 @@ export namespace DocumentsModule {
251
296
  };
252
297
  Query?: {
253
298
  '*'?: gm.Middleware[];
299
+ newDocumentDraftByCharge?: gm.Middleware[];
300
+ newDocumentDraftByDocument?: gm.Middleware[];
301
+ periodicalDocumentDrafts?: gm.Middleware[];
302
+ periodicalDocumentDraftsByContracts?: gm.Middleware[];
303
+ clientMonthlyChargeDraft?: gm.Middleware[];
254
304
  documents?: gm.Middleware[];
255
305
  documentsByFilters?: gm.Middleware[];
256
306
  documentById?: gm.Middleware[];
@@ -260,6 +310,9 @@ export namespace DocumentsModule {
260
310
  };
261
311
  Mutation?: {
262
312
  '*'?: gm.Middleware[];
313
+ issueGreenInvoiceDocuments?: gm.Middleware[];
314
+ issueGreenInvoiceDocument?: gm.Middleware[];
315
+ previewDocument?: gm.Middleware[];
263
316
  insertDocument?: gm.Middleware[];
264
317
  updateDocument?: gm.Middleware[];
265
318
  deleteDocument?: gm.Middleware[];
@@ -268,6 +321,67 @@ export namespace DocumentsModule {
268
321
  batchUploadDocumentsFromGoogleDrive?: gm.Middleware[];
269
322
  closeDocument?: gm.Middleware[];
270
323
  };
324
+ GenerateDocumentsResult?: {
325
+ '*'?: gm.Middleware[];
326
+ success?: gm.Middleware[];
327
+ errors?: gm.Middleware[];
328
+ };
329
+ DocumentDraft?: {
330
+ '*'?: gm.Middleware[];
331
+ description?: gm.Middleware[];
332
+ remarks?: gm.Middleware[];
333
+ footer?: gm.Middleware[];
334
+ type?: gm.Middleware[];
335
+ date?: gm.Middleware[];
336
+ dueDate?: gm.Middleware[];
337
+ language?: gm.Middleware[];
338
+ currency?: gm.Middleware[];
339
+ vatType?: gm.Middleware[];
340
+ discount?: gm.Middleware[];
341
+ rounding?: gm.Middleware[];
342
+ signed?: gm.Middleware[];
343
+ maxPayments?: gm.Middleware[];
344
+ client?: gm.Middleware[];
345
+ income?: gm.Middleware[];
346
+ payment?: gm.Middleware[];
347
+ linkedDocumentIds?: gm.Middleware[];
348
+ linkedPaymentId?: gm.Middleware[];
349
+ linkType?: gm.Middleware[];
350
+ };
351
+ DocumentIncomeRecord?: {
352
+ '*'?: gm.Middleware[];
353
+ currency?: gm.Middleware[];
354
+ currencyRate?: gm.Middleware[];
355
+ description?: gm.Middleware[];
356
+ itemId?: gm.Middleware[];
357
+ price?: gm.Middleware[];
358
+ quantity?: gm.Middleware[];
359
+ vatRate?: gm.Middleware[];
360
+ vatType?: gm.Middleware[];
361
+ };
362
+ DocumentPaymentRecord?: {
363
+ '*'?: gm.Middleware[];
364
+ currency?: gm.Middleware[];
365
+ currencyRate?: gm.Middleware[];
366
+ date?: gm.Middleware[];
367
+ price?: gm.Middleware[];
368
+ type?: gm.Middleware[];
369
+ bankName?: gm.Middleware[];
370
+ bankBranch?: gm.Middleware[];
371
+ bankAccount?: gm.Middleware[];
372
+ chequeNum?: gm.Middleware[];
373
+ accountId?: gm.Middleware[];
374
+ transactionId?: gm.Middleware[];
375
+ cardType?: gm.Middleware[];
376
+ cardNum?: gm.Middleware[];
377
+ numPayments?: gm.Middleware[];
378
+ firstPayment?: gm.Middleware[];
379
+ };
380
+ DocumentDiscount?: {
381
+ '*'?: gm.Middleware[];
382
+ amount?: gm.Middleware[];
383
+ type?: gm.Middleware[];
384
+ };
271
385
  Unprocessed?: {
272
386
  '*'?: gm.Middleware[];
273
387
  id?: gm.Middleware[];
@@ -12,3 +12,24 @@ export function isInvoice(type: document_type): boolean {
12
12
  export function isReceipt(type: document_type): boolean {
13
13
  return type === DocumentType.Receipt || type === DocumentType.InvoiceReceipt;
14
14
  }
15
+
16
+ export function getDocumentNameFromType(documentType: DocumentType): string {
17
+ switch (documentType) {
18
+ case DocumentType.Invoice:
19
+ return 'Tax Invoice';
20
+ case DocumentType.Proforma:
21
+ return 'Proforma Invoice';
22
+ case DocumentType.InvoiceReceipt:
23
+ return 'Invoice / Receipt';
24
+ case DocumentType.CreditInvoice:
25
+ return 'Credit Note';
26
+ case DocumentType.Receipt:
27
+ return 'Receipt';
28
+ case DocumentType.Other:
29
+ return 'Misc Document';
30
+ case DocumentType.Unprocessed:
31
+ return 'Unprocessed Document';
32
+ default:
33
+ throw new Error(`Unsupported document type: ${documentType}`);
34
+ }
35
+ }
@@ -1,42 +1,50 @@
1
+ import { addMonths, endOfMonth, format, startOfMonth, subMonths } from 'date-fns';
1
2
  import { GraphQLError } from 'graphql';
2
- import { Injector } from 'graphql-modules';
3
+ import type { Injector } from 'graphql-modules';
3
4
  import type { _DOLLAR_defs_Document } from '@accounter/green-invoice-graphql';
4
5
  import type {
5
- GreenInvoiceIncome,
6
- GreenInvoiceLinkType,
7
- GreenInvoicePayment,
8
- GreenInvoicePaymentType,
9
- GreenInvoiceVatType,
10
- NewDocumentInfo,
11
- NewDocumentInput,
6
+ DocumentDraft,
7
+ DocumentIncomeRecord,
8
+ DocumentIssueInput,
9
+ DocumentLinkType,
10
+ DocumentPaymentRecord,
11
+ DocumentVatType,
12
+ PaymentType,
13
+ ResolversTypes,
12
14
  } from '../../../__generated__/types.js';
13
15
  import { Currency, DocumentType } from '../../../shared/enums.js';
14
16
  import { dateToTimelessDateString } from '../../../shared/helpers/index.js';
15
- import { TimelessDateString } from '../../../shared/types/index.js';
17
+ import type { TimelessDateString } from '../../../shared/types/index.js';
16
18
  import { GreenInvoiceClientProvider } from '../../app-providers/green-invoice-client.js';
17
19
  import { ChargesProvider } from '../../charges/providers/charges.provider.js';
18
- import { IssuedDocumentsProvider } from '../../documents/providers/issued-documents.provider.js';
19
- import type {
20
- IGetDocumentsByChargeIdResult,
21
- IGetIssuedDocumentsByIdsResult,
22
- } from '../../documents/types.js';
20
+ import {
21
+ getProductName,
22
+ getSubscriptionPlanName,
23
+ normalizeProduct,
24
+ normalizeSubscriptionPlan,
25
+ } from '../../contracts/helpers/contracts.helper.js';
26
+ import type { IGetContractsByIdsResult } from '../../contracts/types.js';
23
27
  import { FinancialAccountsProvider } from '../../financial-accounts/providers/financial-accounts.provider.js';
24
28
  import { FinancialBankAccountsProvider } from '../../financial-accounts/providers/financial-bank-accounts.provider.js';
25
29
  import type { IGetFinancialBankAccountsByIdsResult } from '../../financial-accounts/types.js';
30
+ import { validateClientIntegrations } from '../../financial-entities/helpers/clients.helper.js';
26
31
  import { BusinessesProvider } from '../../financial-entities/providers/businesses.provider.js';
27
- import type { IGetTransactionsByChargeIdsResult } from '../../transactions/types.js';
32
+ import { ClientsProvider } from '../../financial-entities/providers/clients.provider.js';
28
33
  import {
29
34
  convertDocumentInputIntoGreenInvoiceInput,
30
- getGreenInvoiceDocumentType,
35
+ getTypeFromGreenInvoiceDocument,
31
36
  getVatTypeFromGreenInvoiceDocument,
32
37
  insertNewDocumentFromGreenInvoice,
33
- normalizeDocumentType,
34
- } from './green-invoice.helper.js';
38
+ } from '../../green-invoice/helpers/green-invoice.helper.js';
39
+ import type { IGetTransactionsByChargeIdsResult } from '../../transactions/types.js';
40
+ import { IssuedDocumentsProvider } from '../providers/issued-documents.provider.js';
41
+ import { normalizeDocumentType } from '../resolvers/common.js';
42
+ import type { IGetIssuedDocumentsByIdsResult } from '../types.js';
35
43
 
36
44
  export async function getPaymentsFromTransactions(
37
45
  injector: Injector,
38
46
  transactions: IGetTransactionsByChargeIdsResult[],
39
- ): Promise<GreenInvoicePayment[]> {
47
+ ): Promise<DocumentPaymentRecord[]> {
40
48
  const payments = await Promise.all(
41
49
  transactions.map(async transaction => {
42
50
  // get account
@@ -48,7 +56,7 @@ export async function getPaymentsFromTransactions(
48
56
  }
49
57
 
50
58
  // get account type
51
- let type: GreenInvoicePaymentType = 'OTHER';
59
+ let type: PaymentType = 'OTHER';
52
60
  switch (account.type) {
53
61
  case 'BANK_ACCOUNT':
54
62
  type = 'WIRE_TRANSFER';
@@ -71,7 +79,7 @@ export async function getPaymentsFromTransactions(
71
79
  }
72
80
 
73
81
  // get further fields
74
- let paymentTypeSpecificAttributes: Partial<GreenInvoicePayment> = {};
82
+ let paymentTypeSpecificAttributes: Partial<DocumentPaymentRecord> = {};
75
83
  switch (type as string) {
76
84
  case 'CHEQUE':
77
85
  paymentTypeSpecificAttributes = {
@@ -82,7 +90,6 @@ export async function getPaymentsFromTransactions(
82
90
  paymentTypeSpecificAttributes = {
83
91
  cardType: 'MASTERCARD', // TODO: add logic to support other card types
84
92
  cardNum: account.account_number,
85
- dealType: 'STANDARD', // TODO: add logic to support other deal types
86
93
  numPayments: 1,
87
94
  firstPayment: transaction.event_date.getTime() / 1000, // assuming first payment is the transaction date
88
95
  };
@@ -120,7 +127,7 @@ export async function getPaymentsFromTransactions(
120
127
  break;
121
128
  }
122
129
 
123
- const payment: GreenInvoicePayment = {
130
+ const payment: DocumentPaymentRecord = {
124
131
  currency: transaction.currency as Currency,
125
132
  currencyRate: undefined,
126
133
  date: dateToTimelessDateString(transaction.debit_date ?? transaction.event_date),
@@ -136,20 +143,16 @@ export async function getPaymentsFromTransactions(
136
143
  return payments;
137
144
  }
138
145
 
139
- export function getIncomeFromDocuments(
140
- documents: {
141
- document: IGetDocumentsByChargeIdResult;
142
- issuedDocument: IGetIssuedDocumentsByIdsResult;
143
- greenInvoiceDocument: _DOLLAR_defs_Document;
144
- }[],
145
- ): GreenInvoiceIncome[] {
146
- const incomes = documents
147
- .map(({ greenInvoiceDocument }) => {
146
+ export function getIncomeRecordsFromDocuments(
147
+ greenInvoiceDocuments: _DOLLAR_defs_Document[],
148
+ ): DocumentIncomeRecord[] {
149
+ const incomes = greenInvoiceDocuments
150
+ .map(greenInvoiceDocument => {
148
151
  return greenInvoiceDocument.income.filter(Boolean).map(originIncome => {
149
152
  if (!originIncome?.currency) {
150
153
  throw new Error('Income currency is missing');
151
154
  }
152
- const income: GreenInvoiceIncome = {
155
+ const income: DocumentIncomeRecord = {
153
156
  description: originIncome.description,
154
157
  quantity: originIncome.quantity,
155
158
  price: originIncome.price,
@@ -167,19 +170,17 @@ export function getIncomeFromDocuments(
167
170
  }
168
171
 
169
172
  export function getTypeFromDocumentsAndTransactions(
170
- greenInvoiceDocuments: _DOLLAR_defs_Document[],
173
+ documents: { type: DocumentType }[],
171
174
  transactions: IGetTransactionsByChargeIdsResult[],
172
175
  ): DocumentType {
173
- if (!greenInvoiceDocuments.length) {
176
+ if (!documents.length) {
174
177
  if (transactions.length) {
175
178
  return DocumentType.InvoiceReceipt;
176
179
  }
177
180
  return DocumentType.Proforma;
178
181
  }
179
182
 
180
- const documentsTypes = new Set<DocumentType>(
181
- greenInvoiceDocuments.map(doc => normalizeDocumentType(doc.type)),
182
- );
183
+ const documentsTypes = new Set<DocumentType>(documents.map(doc => doc.type));
183
184
 
184
185
  if (documentsTypes.size === 1) {
185
186
  switch (Array.from(documentsTypes)[0]) {
@@ -230,9 +231,9 @@ export function filterAndHandleSwiftTransactions(
230
231
  export function getLinkedDocumentsAttributes(
231
232
  issuedDocuments: IGetIssuedDocumentsByIdsResult[],
232
233
  shouldCancel: boolean = false,
233
- ): Pick<NewDocumentInfo, 'linkedDocumentIds' | 'linkType'> {
234
+ ): Pick<DocumentDraft, 'linkedDocumentIds' | 'linkType'> {
234
235
  const linkedDocumentIds = issuedDocuments.map(doc => doc.external_id);
235
- let linkType: GreenInvoiceLinkType | undefined = undefined;
236
+ let linkType: DocumentLinkType | undefined = undefined;
236
237
  if (linkedDocumentIds.length) {
237
238
  if (shouldCancel) {
238
239
  linkType = 'CANCEL';
@@ -266,24 +267,83 @@ export async function deduceVatTypeFromBusiness(
266
267
  injector: Injector,
267
268
  locality: string,
268
269
  businessId?: string | null,
269
- ): Promise<GreenInvoiceVatType> {
270
+ ): Promise<DocumentVatType> {
270
271
  if (!businessId) return 'DEFAULT';
271
272
 
272
273
  const business = await injector.get(BusinessesProvider).getBusinessByIdLoader.load(businessId);
273
274
  if (!business) return 'DEFAULT';
274
275
 
275
276
  // Deduce VAT type based on business information
276
- if (business.country === locality) {
277
+ if (business.country === locality && !business.exempt_dealer) {
277
278
  return 'MIXED';
278
279
  }
279
280
 
280
281
  return 'EXEMPT';
281
282
  }
282
283
 
284
+ export const convertContractToDraft = async (
285
+ contract: IGetContractsByIdsResult,
286
+ injector: Injector,
287
+ issueMonth: TimelessDateString,
288
+ ) => {
289
+ const businessPromise = injector
290
+ .get(BusinessesProvider)
291
+ .getBusinessByIdLoader.load(contract.client_id);
292
+ const clientPromise = injector.get(ClientsProvider).getClientByIdLoader.load(contract.client_id);
293
+ const [business, client] = await Promise.all([businessPromise, clientPromise]);
294
+
295
+ if (!business) {
296
+ throw new GraphQLError(`Business ID="${contract.client_id}" not found`);
297
+ }
298
+
299
+ if (!client) {
300
+ throw new GraphQLError(`Client not found for business ID="${contract.client_id}"`);
301
+ }
302
+
303
+ const greenInvoiceId = validateClientIntegrations(client.integrations)?.greenInvoiceId;
304
+
305
+ if (!greenInvoiceId) {
306
+ throw new GraphQLError(`Green invoice match not found for business ID="${contract.client_id}"`);
307
+ }
308
+
309
+ const today = issueMonth ? addMonths(new Date(issueMonth), 1) : new Date();
310
+ const monthStart = dateToTimelessDateString(startOfMonth(today));
311
+ const monthEnd = dateToTimelessDateString(endOfMonth(today));
312
+ const year = today.getFullYear() + (today.getMonth() === 0 ? -1 : 0);
313
+ const month = format(subMonths(today, 1), 'MMMM');
314
+
315
+ const vatType = await deduceVatTypeFromBusiness(injector, business.country, contract.client_id);
316
+
317
+ const documentInput: ResolversTypes['DocumentDraft'] = {
318
+ remarks: `${contract.purchase_orders[0] ? `PO: ${contract.purchase_orders[0]}${contract.remarks ? ', ' : ''}` : ''}${contract.remarks ?? ''}`,
319
+ description: `${getProductName(normalizeProduct(contract.product ?? '')!)} ${getSubscriptionPlanName(normalizeSubscriptionPlan(contract.plan ?? '')!)} - ${month} ${year}`,
320
+ type: normalizeDocumentType(contract.document_type),
321
+ date: monthStart,
322
+ dueDate: monthEnd,
323
+ language: 'ENGLISH',
324
+ currency: contract.currency as Currency,
325
+ vatType,
326
+ rounding: false,
327
+ signed: true,
328
+ client,
329
+ income: [
330
+ {
331
+ description: `${getProductName(normalizeProduct(contract.product ?? '')!)} ${getSubscriptionPlanName(normalizeSubscriptionPlan(contract.plan ?? '')!)} - ${month} ${year}`,
332
+ quantity: 1,
333
+ price: contract.amount,
334
+ currency: contract.currency as Currency,
335
+ vatType: 'EXEMPT',
336
+ },
337
+ ],
338
+ };
339
+
340
+ return documentInput;
341
+ };
342
+
283
343
  export async function executeDocumentIssue(
284
344
  injector: Injector,
285
345
  adminBusinessId: string,
286
- initialInput: NewDocumentInput,
346
+ initialInput: DocumentIssueInput,
287
347
  emailContent?: string,
288
348
  attachment = true,
289
349
  chargeId?: string,
@@ -365,7 +425,7 @@ export async function executeDocumentIssue(
365
425
  }),
366
426
  );
367
427
  }
368
- if (coreInput.type === getGreenInvoiceDocumentType(DocumentType.CreditInvoice)) {
428
+ if (getTypeFromGreenInvoiceDocument(coreInput.type) === DocumentType.CreditInvoice) {
369
429
  // Close origin
370
430
  }
371
431
 
@@ -2,9 +2,11 @@ import { createModule } from 'graphql-modules';
2
2
  import { DocumentsProvider } from './providers/documents.provider.js';
3
3
  import { IssuedDocumentsProvider } from './providers/issued-documents.provider.js';
4
4
  import { documentSuggestionsResolvers } from './resolvers/document-suggestions.resolver.js';
5
+ import { documentsIssuingResolvers } from './resolvers/documents-issuing.resolver.js';
5
6
  import { documentsResolvers } from './resolvers/documents.resolver.js';
6
7
  import { issuedDocumentsResolvers } from './resolvers/issued-documents.resolver.js';
7
8
  import documentSuggestions from './typeDefs/document-suggestions.graphql.js';
9
+ import DocumentsIssuing from './typeDefs/documents-issuing.graphql.js';
8
10
  import documents from './typeDefs/documents.graphql.js';
9
11
  import issuedDocuments from './typeDefs/issued-documents.graphql.js';
10
12
 
@@ -13,8 +15,13 @@ const __dirname = new URL('.', import.meta.url).pathname;
13
15
  export const documentsModule = createModule({
14
16
  id: 'documents',
15
17
  dirname: __dirname,
16
- typeDefs: [documents, documentSuggestions, issuedDocuments],
17
- resolvers: [documentsResolvers, documentSuggestionsResolvers, issuedDocumentsResolvers],
18
+ typeDefs: [documents, documentSuggestions, DocumentsIssuing, issuedDocuments],
19
+ resolvers: [
20
+ documentsResolvers,
21
+ documentSuggestionsResolvers,
22
+ documentsIssuingResolvers,
23
+ issuedDocumentsResolvers,
24
+ ],
18
25
  providers: () => [DocumentsProvider, IssuedDocumentsProvider],
19
26
  });
20
27