@accounter/server 0.0.8-alpha-20251105180132-1c81096625a160ce926416f8206cb74fcf4f769f → 0.0.8-alpha-20251105183654-b3147b83bfda6ce62d09073ce81342ceadf5160c

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/CHANGELOG.md +25 -15
  2. package/dist/green-invoice-graphql/src/mesh-artifacts/index.js +2 -2
  3. package/dist/green-invoice-graphql/src/mesh-artifacts/index.js.map +1 -1
  4. package/dist/server/src/__generated__/types.d.ts +39 -10
  5. package/dist/server/src/__generated__/types.js.map +1 -1
  6. package/dist/server/src/modules/financial-entities/__generated__/clients.types.d.ts +11 -4
  7. package/dist/server/src/modules/financial-entities/__generated__/types.d.ts +19 -7
  8. package/dist/server/src/modules/financial-entities/__generated__/types.js.map +1 -1
  9. package/dist/server/src/modules/financial-entities/helpers/clients.helper.d.ts +11 -0
  10. package/dist/server/src/modules/financial-entities/helpers/clients.helper.js +26 -0
  11. package/dist/server/src/modules/financial-entities/helpers/clients.helper.js.map +1 -0
  12. package/dist/server/src/modules/financial-entities/providers/businesses.provider.js +1 -1
  13. package/dist/server/src/modules/financial-entities/providers/clients.provider.js +18 -16
  14. package/dist/server/src/modules/financial-entities/providers/clients.provider.js.map +1 -1
  15. package/dist/server/src/modules/financial-entities/resolvers/clients.resolvers.js +26 -24
  16. package/dist/server/src/modules/financial-entities/resolvers/clients.resolvers.js.map +1 -1
  17. package/dist/server/src/modules/financial-entities/typeDefs/clients.graphql.js +24 -8
  18. package/dist/server/src/modules/financial-entities/typeDefs/clients.graphql.js.map +1 -1
  19. package/dist/server/src/modules/green-invoice/__generated__/types.d.ts +8 -0
  20. package/dist/server/src/modules/green-invoice/__generated__/types.js.map +1 -1
  21. package/dist/server/src/modules/green-invoice/helpers/contract-to-draft.helper.d.ts +3 -1
  22. package/dist/server/src/modules/green-invoice/helpers/contract-to-draft.helper.js +5 -12
  23. package/dist/server/src/modules/green-invoice/helpers/contract-to-draft.helper.js.map +1 -1
  24. package/dist/server/src/modules/green-invoice/helpers/green-invoice-clients.helper.d.ts +1 -2
  25. package/dist/server/src/modules/green-invoice/helpers/green-invoice-clients.helper.js +17 -31
  26. package/dist/server/src/modules/green-invoice/helpers/green-invoice-clients.helper.js.map +1 -1
  27. package/dist/server/src/modules/green-invoice/helpers/green-invoice.helper.d.ts +2 -2
  28. package/dist/server/src/modules/green-invoice/helpers/green-invoice.helper.js +16 -14
  29. package/dist/server/src/modules/green-invoice/helpers/green-invoice.helper.js.map +1 -1
  30. package/dist/server/src/modules/green-invoice/resolvers/green-invoice.resolvers.js +89 -28
  31. package/dist/server/src/modules/green-invoice/resolvers/green-invoice.resolvers.js.map +1 -1
  32. package/dist/server/src/modules/green-invoice/typeDefs/green-invoice.graphql.js +4 -0
  33. package/dist/server/src/modules/green-invoice/typeDefs/green-invoice.graphql.js.map +1 -1
  34. package/package.json +6 -6
  35. package/src/__generated__/types.ts +42 -10
  36. package/src/modules/financial-entities/__generated__/clients.types.ts +10 -4
  37. package/src/modules/financial-entities/__generated__/types.ts +19 -7
  38. package/src/modules/financial-entities/helpers/clients.helper.ts +28 -0
  39. package/src/modules/financial-entities/providers/businesses.provider.ts +1 -1
  40. package/src/modules/financial-entities/providers/clients.provider.ts +19 -16
  41. package/src/modules/financial-entities/resolvers/clients.resolvers.ts +30 -27
  42. package/src/modules/financial-entities/typeDefs/clients.graphql.ts +24 -8
  43. package/src/modules/green-invoice/__generated__/types.ts +8 -0
  44. package/src/modules/green-invoice/helpers/contract-to-draft.helper.ts +7 -13
  45. package/src/modules/green-invoice/helpers/green-invoice-clients.helper.ts +19 -40
  46. package/src/modules/green-invoice/helpers/green-invoice.helper.ts +17 -18
  47. package/src/modules/green-invoice/resolvers/green-invoice.resolvers.ts +99 -34
  48. package/src/modules/green-invoice/typeDefs/green-invoice.graphql.ts +4 -0
@@ -942,10 +942,8 @@ export type Client = {
942
942
  readonly __typename?: 'Client';
943
943
  readonly emails: ReadonlyArray<Scalars['String']['output']>;
944
944
  readonly generatedDocumentType: DocumentType;
945
- readonly greenInvoiceId?: Maybe<Scalars['UUID']['output']>;
946
- readonly greenInvoiceInfo?: Maybe<GreenInvoiceClient>;
947
- readonly hiveId?: Maybe<Scalars['String']['output']>;
948
945
  readonly id: Scalars['UUID']['output'];
946
+ readonly integrations: ClientIntegrations;
949
947
  readonly originalBusiness: LtdFinancialEntity;
950
948
  };
951
949
 
@@ -954,16 +952,36 @@ export type ClientInsertInput = {
954
952
  readonly businessId: Scalars['UUID']['input'];
955
953
  readonly emails?: InputMaybe<ReadonlyArray<Scalars['String']['input']>>;
956
954
  readonly generatedDocumentType: DocumentType;
955
+ readonly integrations?: InputMaybe<ClientIntegrationsInput>;
956
+ };
957
+
958
+ /** integrations associated with a client */
959
+ export type ClientIntegrations = {
960
+ readonly __typename?: 'ClientIntegrations';
961
+ readonly greenInvoiceInfo?: Maybe<GreenInvoiceClient>;
962
+ readonly hiveId?: Maybe<Scalars['String']['output']>;
963
+ readonly id: Scalars['ID']['output'];
964
+ readonly linearId?: Maybe<Scalars['String']['output']>;
965
+ readonly notionId?: Maybe<Scalars['String']['output']>;
966
+ readonly slackChannelKey?: Maybe<Scalars['String']['output']>;
967
+ readonly workflowyUrl?: Maybe<Scalars['String']['output']>;
968
+ };
969
+
970
+ /** integrations input for client insert/update */
971
+ export type ClientIntegrationsInput = {
957
972
  readonly greenInvoiceId?: InputMaybe<Scalars['UUID']['input']>;
958
973
  readonly hiveId?: InputMaybe<Scalars['String']['input']>;
974
+ readonly linearId?: InputMaybe<Scalars['String']['input']>;
975
+ readonly notionId?: InputMaybe<Scalars['String']['input']>;
976
+ readonly slackChannelKey?: InputMaybe<Scalars['String']['input']>;
977
+ readonly workflowyUrl?: InputMaybe<Scalars['String']['input']>;
959
978
  };
960
979
 
961
980
  /** fields for updating an existing client */
962
981
  export type ClientUpdateInput = {
963
982
  readonly emails?: InputMaybe<ReadonlyArray<Scalars['String']['input']>>;
964
983
  readonly generatedDocumentType?: InputMaybe<DocumentType>;
965
- readonly greenInvoiceId?: InputMaybe<Scalars['UUID']['input']>;
966
- readonly hiveId?: InputMaybe<Scalars['String']['input']>;
984
+ readonly integrations?: InputMaybe<ClientIntegrationsInput>;
967
985
  readonly newBusinessId?: InputMaybe<Scalars['UUID']['input']>;
968
986
  };
969
987
 
@@ -5162,6 +5180,8 @@ export type ResolversTypes = {
5162
5180
  ChargesWithLedgerChangesResult: ResolverTypeWrapper<Omit<ChargesWithLedgerChangesResult, 'charge'> & { charge?: Maybe<ResolversTypes['Charge']> }>;
5163
5181
  Client: ResolverTypeWrapper<IGetAllClientsResult>;
5164
5182
  ClientInsertInput: ClientInsertInput;
5183
+ ClientIntegrations: ResolverTypeWrapper<IGetAllClientsResult>;
5184
+ ClientIntegrationsInput: ClientIntegrationsInput;
5165
5185
  ClientUpdateInput: ClientUpdateInput;
5166
5186
  CommonCharge: ResolverTypeWrapper<IGetChargesByIdsResult>;
5167
5187
  CommonError: ResolverTypeWrapper<CommonError>;
@@ -5228,7 +5248,7 @@ export type ResolversTypes = {
5228
5248
  Fund: ResolverTypeWrapper<ResolversInterfaceTypes<ResolversTypes>['Fund']>;
5229
5249
  GenerateMonthlyClientDocumentsResult: ResolverTypeWrapper<GenerateMonthlyClientDocumentsResult>;
5230
5250
  GeneratedLedgerRecords: ResolverTypeWrapper<ResolversUnionTypes<ResolversTypes>['GeneratedLedgerRecords']>;
5231
- GreenInvoiceClient: ResolverTypeWrapper<GreenInvoiceClient>;
5251
+ GreenInvoiceClient: ResolverTypeWrapper<string>;
5232
5252
  GreenInvoiceClientInput: GreenInvoiceClientInput;
5233
5253
  GreenInvoiceCountry: GreenInvoiceCountry;
5234
5254
  GreenInvoiceDiscount: ResolverTypeWrapper<GreenInvoiceDiscount>;
@@ -5451,6 +5471,8 @@ export type ResolversParentTypes = {
5451
5471
  ChargesWithLedgerChangesResult: Omit<ChargesWithLedgerChangesResult, 'charge'> & { charge?: Maybe<ResolversParentTypes['Charge']> };
5452
5472
  Client: IGetAllClientsResult;
5453
5473
  ClientInsertInput: ClientInsertInput;
5474
+ ClientIntegrations: IGetAllClientsResult;
5475
+ ClientIntegrationsInput: ClientIntegrationsInput;
5454
5476
  ClientUpdateInput: ClientUpdateInput;
5455
5477
  CommonCharge: IGetChargesByIdsResult;
5456
5478
  CommonError: CommonError;
@@ -5508,7 +5530,7 @@ export type ResolversParentTypes = {
5508
5530
  Fund: ResolversInterfaceTypes<ResolversParentTypes>['Fund'];
5509
5531
  GenerateMonthlyClientDocumentsResult: GenerateMonthlyClientDocumentsResult;
5510
5532
  GeneratedLedgerRecords: ResolversUnionTypes<ResolversParentTypes>['GeneratedLedgerRecords'];
5511
- GreenInvoiceClient: GreenInvoiceClient;
5533
+ GreenInvoiceClient: string;
5512
5534
  GreenInvoiceClientInput: GreenInvoiceClientInput;
5513
5535
  GreenInvoiceDiscount: GreenInvoiceDiscount;
5514
5536
  GreenInvoiceDiscountInput: GreenInvoiceDiscountInput;
@@ -6165,14 +6187,23 @@ export type ChargesWithLedgerChangesResultResolvers<ContextType = GraphQLModules
6165
6187
  export type ClientResolvers<ContextType = GraphQLModules.Context, ParentType extends ResolversParentTypes['Client'] = ResolversParentTypes['Client']> = {
6166
6188
  emails?: Resolver<ReadonlyArray<ResolversTypes['String']>, ParentType, ContextType>;
6167
6189
  generatedDocumentType?: Resolver<ResolversTypes['DocumentType'], ParentType, ContextType>;
6168
- greenInvoiceId?: Resolver<Maybe<ResolversTypes['UUID']>, ParentType, ContextType>;
6169
- greenInvoiceInfo?: Resolver<Maybe<ResolversTypes['GreenInvoiceClient']>, ParentType, ContextType>;
6170
- hiveId?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
6171
6190
  id?: Resolver<ResolversTypes['UUID'], ParentType, ContextType>;
6191
+ integrations?: Resolver<ResolversTypes['ClientIntegrations'], ParentType, ContextType>;
6172
6192
  originalBusiness?: Resolver<ResolversTypes['LtdFinancialEntity'], ParentType, ContextType>;
6173
6193
  __isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
6174
6194
  };
6175
6195
 
6196
+ export type ClientIntegrationsResolvers<ContextType = GraphQLModules.Context, ParentType extends ResolversParentTypes['ClientIntegrations'] = ResolversParentTypes['ClientIntegrations']> = {
6197
+ greenInvoiceInfo?: Resolver<Maybe<ResolversTypes['GreenInvoiceClient']>, ParentType, ContextType>;
6198
+ hiveId?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
6199
+ id?: Resolver<ResolversTypes['ID'], ParentType, ContextType>;
6200
+ linearId?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
6201
+ notionId?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
6202
+ slackChannelKey?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
6203
+ workflowyUrl?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
6204
+ __isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
6205
+ };
6206
+
6176
6207
  export type CommonChargeResolvers<ContextType = GraphQLModules.Context, ParentType extends ResolversParentTypes['CommonCharge'] = ResolversParentTypes['CommonCharge']> = {
6177
6208
  accountantApproval?: Resolver<ResolversTypes['AccountantStatus'], ParentType, ContextType>;
6178
6209
  additionalDocuments?: Resolver<ReadonlyArray<ResolversTypes['Document']>, ParentType, ContextType>;
@@ -8010,6 +8041,7 @@ export type Resolvers<ContextType = GraphQLModules.Context> = {
8010
8041
  ChargeSuggestions?: ChargeSuggestionsResolvers<ContextType>;
8011
8042
  ChargesWithLedgerChangesResult?: ChargesWithLedgerChangesResultResolvers<ContextType>;
8012
8043
  Client?: ClientResolvers<ContextType>;
8044
+ ClientIntegrations?: ClientIntegrationsResolvers<ContextType>;
8013
8045
  CommonCharge?: CommonChargeResolvers<ContextType>;
8014
8046
  CommonError?: CommonErrorResolvers<ContextType>;
8015
8047
  CommonTransaction?: CommonTransactionResolvers<ContextType>;
@@ -1,6 +1,8 @@
1
1
  /** Types generated for queries found in "src/modules/financial-entities/providers/clients.provider.ts" */
2
2
  export type document_type = 'CREDIT_INVOICE' | 'INVOICE' | 'INVOICE_RECEIPT' | 'OTHER' | 'PROFORMA' | 'RECEIPT' | 'UNPROCESSED';
3
3
 
4
+ export type Json = null | boolean | number | string | Json[] | { [key: string]: Json };
5
+
4
6
  export type stringArray = (string)[];
5
7
 
6
8
  /** 'GetAllClients' parameters type */
@@ -13,6 +15,7 @@ export interface IGetAllClientsResult {
13
15
  emails: stringArray | null;
14
16
  green_invoice_id: string;
15
17
  hive_id: string | null;
18
+ integrations: Json | null;
16
19
  remark: string | null;
17
20
  }
18
21
 
@@ -34,6 +37,7 @@ export interface IGetClientsByIdsResult {
34
37
  emails: stringArray | null;
35
38
  green_invoice_id: string;
36
39
  hive_id: string | null;
40
+ integrations: Json | null;
37
41
  remark: string | null;
38
42
  }
39
43
 
@@ -53,8 +57,10 @@ export interface IGetClientsByGreenInvoiceIdsResult {
53
57
  business_id: string;
54
58
  document_type: document_type;
55
59
  emails: stringArray | null;
60
+ green_invoice_business_id: string | null;
56
61
  green_invoice_id: string;
57
62
  hive_id: string | null;
63
+ integrations: Json | null;
58
64
  remark: string | null;
59
65
  }
60
66
 
@@ -68,8 +74,7 @@ export interface IGetClientsByGreenInvoiceIdsQuery {
68
74
  export interface IUpdateClientParams {
69
75
  businessId?: string | null | void;
70
76
  emails?: stringArray | null | void;
71
- greenInvoiceId?: string | null | void;
72
- hiveId?: string | null | void;
77
+ integrations?: Json | null | void;
73
78
  newBusinessId?: string | null | void;
74
79
  }
75
80
 
@@ -80,6 +85,7 @@ export interface IUpdateClientResult {
80
85
  emails: stringArray | null;
81
86
  green_invoice_id: string;
82
87
  hive_id: string | null;
88
+ integrations: Json | null;
83
89
  remark: string | null;
84
90
  }
85
91
 
@@ -109,8 +115,7 @@ export interface IDeleteClientQuery {
109
115
  export interface IInsertClientParams {
110
116
  businessId?: string | null | void;
111
117
  emails?: stringArray | null | void;
112
- greenInvoiceId?: string | null | void;
113
- hiveId?: string | null | void;
118
+ integrations?: Json | null | void;
114
119
  }
115
120
 
116
121
  /** 'InsertClient' return type */
@@ -120,6 +125,7 @@ export interface IInsertClientResult {
120
125
  emails: stringArray | null;
121
126
  green_invoice_id: string;
122
127
  hive_id: string | null;
128
+ integrations: Json | null;
123
129
  remark: string | null;
124
130
  }
125
131
 
@@ -17,7 +17,8 @@ export namespace FinancialEntitiesModule {
17
17
  Suggestions: 'phrases' | 'tags' | 'description' | 'emails' | 'emailListener' | 'priority';
18
18
  SuggestionsEmailListenerConfig: 'internalEmailLinks' | 'emailBody' | 'attachments';
19
19
  PersonalFinancialEntity: 'id' | 'name' | 'email' | 'pcn874RecordType' | 'irsCode' | 'isActive' | 'createdAt' | 'updatedAt';
20
- Client: 'id' | 'originalBusiness' | 'greenInvoiceId' | 'hiveId' | 'emails' | 'generatedDocumentType' | 'greenInvoiceInfo';
20
+ Client: 'id' | 'originalBusiness' | 'emails' | 'generatedDocumentType' | 'integrations';
21
+ ClientIntegrations: 'id' | 'hiveId' | 'linearId' | 'slackChannelKey' | 'notionId' | 'workflowyUrl';
21
22
  PaginatedFinancialEntities: 'nodes' | 'pageInfo';
22
23
  TaxCategory: 'id' | 'name' | 'irsCode' | 'createdAt' | 'updatedAt' | 'isActive';
23
24
  CommonCharge: 'owner' | 'counterparty' | 'taxCategory';
@@ -61,8 +62,9 @@ export namespace FinancialEntitiesModule {
61
62
  InsertNewBusinessInput: 'name' | 'sortCode' | 'country' | 'hebrewName' | 'address' | 'email' | 'website' | 'phoneNumber' | 'governmentId' | 'taxCategory' | 'exemptDealer' | 'suggestions' | 'optionalVAT' | 'isReceiptEnough' | 'isDocumentsOptional' | 'pcn874RecordType' | 'irsCode' | 'isActive';
62
63
  SuggestionsInput: 'phrases' | 'tags' | 'description' | 'emails' | 'emailListener' | 'priority';
63
64
  SuggestionsEmailListenerConfigInput: 'internalEmailLinks' | 'emailBody' | 'attachments';
64
- ClientInsertInput: 'businessId' | 'greenInvoiceId' | 'hiveId' | 'emails' | 'generatedDocumentType';
65
- ClientUpdateInput: 'greenInvoiceId' | 'hiveId' | 'emails' | 'generatedDocumentType' | 'newBusinessId';
65
+ ClientInsertInput: 'businessId' | 'emails' | 'generatedDocumentType' | 'integrations';
66
+ ClientUpdateInput: 'newBusinessId' | 'emails' | 'generatedDocumentType' | 'integrations';
67
+ ClientIntegrationsInput: 'greenInvoiceId' | 'hiveId' | 'linearId' | 'slackChannelKey' | 'notionId' | 'workflowyUrl';
66
68
  UpdateTaxCategoryInput: 'name' | 'sortCode' | 'irsCode' | 'isActive' | 'hashavshevetName' | 'taxExcluded';
67
69
  InsertTaxCategoryInput: 'name' | 'sortCode' | 'irsCode' | 'hashavshevetName' | 'taxExcluded' | 'isActive';
68
70
  UpdateChargeInput: 'counterpartyId' | 'ownerId';
@@ -126,7 +128,8 @@ export namespace FinancialEntitiesModule {
126
128
  export type ClientUpdateInput = Pick<Types.ClientUpdateInput, DefinedInputFields['ClientUpdateInput']>;
127
129
  export type ClientInsertInput = Pick<Types.ClientInsertInput, DefinedInputFields['ClientInsertInput']>;
128
130
  export type DocumentType = Types.DocumentType;
129
- export type GreenInvoiceClient = Types.GreenInvoiceClient;
131
+ export type ClientIntegrations = Pick<Types.ClientIntegrations, DefinedFields['ClientIntegrations']>;
132
+ export type ClientIntegrationsInput = Pick<Types.ClientIntegrationsInput, DefinedInputFields['ClientIntegrationsInput']>;
130
133
  export type PaginatedFinancialEntities = Pick<Types.PaginatedFinancialEntities, DefinedFields['PaginatedFinancialEntities']>;
131
134
  export type UpdateChargeInput = Types.UpdateChargeInput;
132
135
  export type Transaction = Types.Transaction;
@@ -160,6 +163,7 @@ export namespace FinancialEntitiesModule {
160
163
  export type SuggestionsEmailListenerConfigResolvers = Pick<Types.SuggestionsEmailListenerConfigResolvers, DefinedFields['SuggestionsEmailListenerConfig']>;
161
164
  export type PersonalFinancialEntityResolvers = Pick<Types.PersonalFinancialEntityResolvers, DefinedFields['PersonalFinancialEntity'] | '__isTypeOf'>;
162
165
  export type ClientResolvers = Pick<Types.ClientResolvers, DefinedFields['Client'] | '__isTypeOf'>;
166
+ export type ClientIntegrationsResolvers = Pick<Types.ClientIntegrationsResolvers, DefinedFields['ClientIntegrations']>;
163
167
  export type PaginatedFinancialEntitiesResolvers = Pick<Types.PaginatedFinancialEntitiesResolvers, DefinedFields['PaginatedFinancialEntities']>;
164
168
  export type TaxCategoryResolvers = Pick<Types.TaxCategoryResolvers, DefinedFields['TaxCategory'] | '__isTypeOf'>;
165
169
  export type CommonChargeResolvers = Pick<Types.CommonChargeResolvers, DefinedFields['CommonCharge']>;
@@ -204,6 +208,7 @@ export namespace FinancialEntitiesModule {
204
208
  SuggestionsEmailListenerConfig?: SuggestionsEmailListenerConfigResolvers;
205
209
  PersonalFinancialEntity?: PersonalFinancialEntityResolvers;
206
210
  Client?: ClientResolvers;
211
+ ClientIntegrations?: ClientIntegrationsResolvers;
207
212
  PaginatedFinancialEntities?: PaginatedFinancialEntitiesResolvers;
208
213
  TaxCategory?: TaxCategoryResolvers;
209
214
  CommonCharge?: CommonChargeResolvers;
@@ -446,11 +451,18 @@ export namespace FinancialEntitiesModule {
446
451
  '*'?: gm.Middleware[];
447
452
  id?: gm.Middleware[];
448
453
  originalBusiness?: gm.Middleware[];
449
- greenInvoiceId?: gm.Middleware[];
450
- hiveId?: gm.Middleware[];
451
454
  emails?: gm.Middleware[];
452
455
  generatedDocumentType?: gm.Middleware[];
453
- greenInvoiceInfo?: gm.Middleware[];
456
+ integrations?: gm.Middleware[];
457
+ };
458
+ ClientIntegrations?: {
459
+ '*'?: gm.Middleware[];
460
+ id?: gm.Middleware[];
461
+ hiveId?: gm.Middleware[];
462
+ linearId?: gm.Middleware[];
463
+ slackChannelKey?: gm.Middleware[];
464
+ notionId?: gm.Middleware[];
465
+ workflowyUrl?: gm.Middleware[];
454
466
  };
455
467
  PaginatedFinancialEntities?: {
456
468
  '*'?: gm.Middleware[];
@@ -0,0 +1,28 @@
1
+ import { GraphQLError } from 'graphql';
2
+ import { z } from 'zod';
3
+
4
+ // Zod schema matching the GraphQL `ClientIntegrations` type
5
+ export const ClientIntegrationsSchema = z
6
+ .object({
7
+ greenInvoiceId: z.uuid().optional().nullable(),
8
+ hiveId: z.string().optional().nullable(),
9
+ linearId: z.string().optional().nullable(),
10
+ slackChannelKey: z.string().optional().nullable(),
11
+ notionId: z.string().optional().nullable(),
12
+ workflowyUrl: z.string().optional().nullable(),
13
+ })
14
+ .strict();
15
+
16
+ export type ClientIntegrations = z.infer<typeof ClientIntegrationsSchema>;
17
+
18
+ export function validateClientIntegrations(input: unknown): ClientIntegrations {
19
+ try {
20
+ const { data, success, error } = ClientIntegrationsSchema.safeParse(input);
21
+ if (!success) {
22
+ throw new Error(`Parsing error: ${error}`);
23
+ }
24
+ return data;
25
+ } catch (error) {
26
+ throw new GraphQLError(`Failed to validate client integrations: ${error}`);
27
+ }
28
+ }
@@ -281,7 +281,7 @@ const replaceBusinesses = sql<IReplaceBusinessesQuery>`
281
281
  UPDATE accounter_schema.clients
282
282
  SET business_id = $targetBusinessId
283
283
  WHERE business_id = $businessIdToReplace
284
- RETURNING green_invoice_id
284
+ RETURNING (integrations->>'greenInvoiceId')::uuid
285
285
  )
286
286
  UPDATE accounter_schema.transactions
287
287
  SET business_id = $targetBusinessId
@@ -3,6 +3,7 @@ import { Injectable, Scope } from 'graphql-modules';
3
3
  import { DBProvider } from '@modules/app-providers/db.provider.js';
4
4
  import { sql } from '@pgtyped/runtime';
5
5
  import { getCacheInstance } from '@shared/helpers';
6
+ import { validateClientIntegrations } from '../helpers/clients.helper.js';
6
7
  import type {
7
8
  IDeleteClientQuery,
8
9
  IGetAllClientsQuery,
@@ -27,24 +28,14 @@ const getClientsByIds = sql<IGetClientsByIdsQuery>`
27
28
  `;
28
29
 
29
30
  const getClientsByGreenInvoiceIds = sql<IGetClientsByGreenInvoiceIdsQuery>`
30
- SELECT *
31
+ SELECT *, (integrations->>'greenInvoiceId')::uuid as green_invoice_business_id
31
32
  FROM accounter_schema.clients
32
- WHERE green_invoice_id IN $$greenInvoiceBusinessIds;
33
+ WHERE (integrations->>'greenInvoiceId')::uuid in $$greenInvoiceBusinessIds;
33
34
  `;
34
35
 
35
36
  const updateClient = sql<IUpdateClientQuery>`
36
37
  UPDATE accounter_schema.clients
37
38
  SET
38
- green_invoice_id = COALESCE(
39
- $greenInvoiceId,
40
- green_invoice_id,
41
- NULL
42
- ),
43
- hive_id = COALESCE(
44
- $hiveId,
45
- hive_id,
46
- NULL
47
- ),
48
39
  emails = COALESCE(
49
40
  $emails,
50
41
  emails,
@@ -54,6 +45,11 @@ const updateClient = sql<IUpdateClientQuery>`
54
45
  $newBusinessId,
55
46
  business_id,
56
47
  NULL
48
+ ),
49
+ integrations = COALESCE(
50
+ $integrations,
51
+ integrations,
52
+ NULL
57
53
  )
58
54
  WHERE
59
55
  business_id = $businessId
@@ -67,8 +63,8 @@ const deleteClient = sql<IDeleteClientQuery>`
67
63
  `;
68
64
 
69
65
  const insertClient = sql<IInsertClientQuery>`
70
- INSERT INTO accounter_schema.clients (business_id, green_invoice_id, hive_id, emails)
71
- VALUES ($businessId, $greenInvoiceId, $hiveId, $emails)
66
+ INSERT INTO accounter_schema.clients (business_id, emails, integrations)
67
+ VALUES ($businessId, $emails, $integrations)
72
68
  RETURNING *;`;
73
69
 
74
70
  @Injectable({
@@ -91,7 +87,12 @@ export class ClientsProvider {
91
87
  this.cache.set('all-clients', data);
92
88
  data.map(client => {
93
89
  this.cache.set(`client-id-${client.business_id}`, client);
94
- this.cache.set(`client-green-invoice-id-${client.green_invoice_id}`, client);
90
+ try {
91
+ const { greenInvoiceId } = validateClientIntegrations(client.integrations ?? {});
92
+ this.cache.set(`client-green-invoice-id-${greenInvoiceId}`, client);
93
+ } catch {
94
+ // swallow errors
95
+ }
95
96
  });
96
97
  return data;
97
98
  });
@@ -123,7 +124,9 @@ export class ClientsProvider {
123
124
  this.dbProvider,
124
125
  );
125
126
 
126
- return greenInvoiceIds.map(id => matches.find(match => match.green_invoice_id === id));
127
+ return greenInvoiceIds.map(id =>
128
+ matches.find(match => match.green_invoice_business_id === id),
129
+ );
127
130
  } catch (e) {
128
131
  console.error(e);
129
132
  return greenInvoiceIds.map(() => undefined);
@@ -1,11 +1,11 @@
1
1
  import { GraphQLError } from 'graphql';
2
- import { GreenInvoiceClientProvider } from '@modules/app-providers/green-invoice-client.js';
3
2
  import { BusinessesProvider } from '@modules/financial-entities/providers/businesses.provider.js';
4
3
  import {
5
4
  addGreenInvoiceClient,
6
5
  updateGreenInvoiceClient,
7
6
  } from '@modules/green-invoice/helpers/green-invoice-clients.helper.js';
8
- import { Resolvers } from '@shared/gql-types';
7
+ import { ClientIntegrationsInput, Resolvers } from '@shared/gql-types';
8
+ import { validateClientIntegrations } from '../helpers/clients.helper.js';
9
9
  import { ClientsProvider } from '../providers/clients.provider.js';
10
10
  import type {
11
11
  FinancialEntitiesModule,
@@ -45,12 +45,26 @@ export const clientsResolvers: FinancialEntitiesModule.Resolvers &
45
45
  },
46
46
  Mutation: {
47
47
  updateClient: async (_, { businessId, fields }, { injector }) => {
48
+ let updatedIntegrations: ClientIntegrationsInput | undefined =
49
+ fields.integrations ?? undefined;
50
+ if (updatedIntegrations) {
51
+ const currentClient = await injector
52
+ .get(ClientsProvider)
53
+ .getClientByIdLoader.load(businessId);
54
+ if (!currentClient) {
55
+ throw new GraphQLError(`Client with ID="${businessId}" not found`);
56
+ }
57
+ const currentIntegrations = validateClientIntegrations(currentClient.integrations);
58
+ updatedIntegrations = {
59
+ ...currentIntegrations,
60
+ ...updatedIntegrations,
61
+ };
62
+ }
48
63
  const adjustedFields: IUpdateClientParams = {
49
64
  businessId,
50
65
  emails: fields.emails ? [...fields.emails] : undefined,
51
- greenInvoiceId: fields.greenInvoiceId,
52
- hiveId: fields.hiveId,
53
66
  newBusinessId: fields.newBusinessId,
67
+ integrations: updatedIntegrations,
54
68
  };
55
69
  try {
56
70
  const [updatedClient] = await injector
@@ -81,8 +95,7 @@ export const clientsResolvers: FinancialEntitiesModule.Resolvers &
81
95
  const newClient: IInsertClientParams = {
82
96
  businessId: fields.businessId,
83
97
  emails: fields.emails ? [...fields.emails] : [],
84
- greenInvoiceId: fields.greenInvoiceId,
85
- hiveId: fields.hiveId,
98
+ integrations: fields.integrations,
86
99
  };
87
100
  const [insertClient] = await injector.get(ClientsProvider).insertClient(newClient);
88
101
 
@@ -116,28 +129,18 @@ export const clientsResolvers: FinancialEntitiesModule.Resolvers &
116
129
 
117
130
  return businessMatch;
118
131
  },
119
- greenInvoiceId: business => business.green_invoice_id,
120
- hiveId: business => business.hive_id,
121
132
  emails: business => business.emails ?? [],
122
- greenInvoiceInfo: async (business, _, { injector }) => {
123
- if (!business.green_invoice_id) {
124
- return null;
125
- }
126
- const client = await injector
127
- .get(GreenInvoiceClientProvider)
128
- .clientLoader.load(business.green_invoice_id);
129
- if (!client) {
130
- throw new GraphQLError(
131
- `Green Invoice client with ID "${business.green_invoice_id}" not found`,
132
- );
133
- }
134
- const emails = client.emails ? (client.emails.filter(Boolean) as string[]) : [];
135
- return {
136
- ...client,
137
- emails,
138
- id: business.green_invoice_id,
139
- };
140
- },
133
+ integrations: business => business,
134
+ },
135
+ ClientIntegrations: {
136
+ id: business => `${business.business_id}-integrations`,
137
+ hiveId: business => validateClientIntegrations(business.integrations).hiveId ?? null,
138
+ linearId: business => validateClientIntegrations(business.integrations).linearId ?? null,
139
+ slackChannelKey: business =>
140
+ validateClientIntegrations(business.integrations).slackChannelKey ?? null,
141
+ notionId: business => validateClientIntegrations(business.integrations).notionId ?? null,
142
+ workflowyUrl: business =>
143
+ validateClientIntegrations(business.integrations).workflowyUrl ?? null,
141
144
  },
142
145
  LtdFinancialEntity: {
143
146
  clientInfo: async (business, _, { injector }) => {
@@ -16,29 +16,45 @@ export default gql`
16
16
  type Client {
17
17
  id: UUID!
18
18
  originalBusiness: LtdFinancialEntity!
19
- greenInvoiceId: UUID
20
- hiveId: String
21
19
  emails: [String!]!
22
20
  generatedDocumentType: DocumentType!
23
- greenInvoiceInfo: GreenInvoiceClient
21
+ integrations: ClientIntegrations!
22
+ }
23
+
24
+ " integrations associated with a client "
25
+ type ClientIntegrations {
26
+ id: ID!
27
+ hiveId: String
28
+ linearId: String
29
+ slackChannelKey: String
30
+ notionId: String
31
+ workflowyUrl: String
24
32
  }
25
33
 
26
34
  " fields for inserting a new client "
27
35
  input ClientInsertInput {
28
36
  businessId: UUID!
29
- greenInvoiceId: UUID
30
- hiveId: String
31
37
  emails: [String!]
32
38
  generatedDocumentType: DocumentType!
39
+ integrations: ClientIntegrationsInput
33
40
  }
34
41
 
35
42
  " fields for updating an existing client "
36
43
  input ClientUpdateInput {
37
- greenInvoiceId: UUID
38
- hiveId: String
44
+ newBusinessId: UUID
39
45
  emails: [String!]
40
46
  generatedDocumentType: DocumentType
41
- newBusinessId: UUID
47
+ integrations: ClientIntegrationsInput
48
+ }
49
+
50
+ " integrations input for client insert/update "
51
+ input ClientIntegrationsInput {
52
+ greenInvoiceId: UUID
53
+ hiveId: String
54
+ linearId: String
55
+ slackChannelKey: String
56
+ notionId: String
57
+ workflowyUrl: String
42
58
  }
43
59
 
44
60
  " result type for updateClient "
@@ -11,6 +11,7 @@ export namespace GreenInvoiceModule {
11
11
  GreenInvoiceIncome: 'currency' | 'currencyRate' | 'description' | 'itemId' | 'price' | 'quantity' | 'vatRate' | 'vatType';
12
12
  GreenInvoicePayment: 'currency' | 'currencyRate' | 'date' | 'price' | 'type' | 'subType' | 'bankName' | 'bankBranch' | 'bankAccount' | 'chequeNum' | 'accountId' | 'transactionId' | 'appType' | 'cardType' | 'cardNum' | 'dealType' | 'numPayments' | 'firstPayment';
13
13
  IssuedDocumentInfo: 'originalDocument';
14
+ ClientIntegrations: 'greenInvoiceInfo';
14
15
  };
15
16
 
16
17
  interface DefinedEnumValues {
@@ -46,6 +47,7 @@ export namespace GreenInvoiceModule {
46
47
  export type FileScalar = Types.FileScalar;
47
48
  export type Charge = Types.Charge;
48
49
  export type IssuedDocumentInfo = Types.IssuedDocumentInfo;
50
+ export type ClientIntegrations = Types.ClientIntegrations;
49
51
  export type DocumentType = Types.DocumentType;
50
52
  export type GreenInvoiceDocumentLang = DefinedEnumValues['GreenInvoiceDocumentLang'];
51
53
  export type Currency = Types.Currency;
@@ -75,6 +77,7 @@ export namespace GreenInvoiceModule {
75
77
  export type GreenInvoiceIncomeResolvers = Pick<Types.GreenInvoiceIncomeResolvers, DefinedFields['GreenInvoiceIncome']>;
76
78
  export type GreenInvoicePaymentResolvers = Pick<Types.GreenInvoicePaymentResolvers, DefinedFields['GreenInvoicePayment']>;
77
79
  export type IssuedDocumentInfoResolvers = Pick<Types.IssuedDocumentInfoResolvers, DefinedFields['IssuedDocumentInfo']>;
80
+ export type ClientIntegrationsResolvers = Pick<Types.ClientIntegrationsResolvers, DefinedFields['ClientIntegrations']>;
78
81
 
79
82
  export interface Resolvers {
80
83
  Query?: QueryResolvers;
@@ -86,6 +89,7 @@ export namespace GreenInvoiceModule {
86
89
  GreenInvoiceIncome?: GreenInvoiceIncomeResolvers;
87
90
  GreenInvoicePayment?: GreenInvoicePaymentResolvers;
88
91
  IssuedDocumentInfo?: IssuedDocumentInfoResolvers;
92
+ ClientIntegrations?: ClientIntegrationsResolvers;
89
93
  };
90
94
 
91
95
  export interface MiddlewareMap {
@@ -112,6 +116,10 @@ export namespace GreenInvoiceModule {
112
116
  '*'?: gm.Middleware[];
113
117
  originalDocument?: gm.Middleware[];
114
118
  };
119
+ ClientIntegrations?: {
120
+ '*'?: gm.Middleware[];
121
+ greenInvoiceInfo?: gm.Middleware[];
122
+ };
115
123
  GenerateMonthlyClientDocumentsResult?: {
116
124
  '*'?: gm.Middleware[];
117
125
  success?: gm.Middleware[];
@@ -3,13 +3,13 @@ import { GraphQLError } from 'graphql';
3
3
  import { Injector } from 'graphql-modules';
4
4
  import type { IGetContractsByIdsResult } from '@modules/contracts/types.js';
5
5
  import { normalizeDocumentType } from '@modules/documents/resolvers/common.js';
6
+ import { validateClientIntegrations } from '@modules/financial-entities/helpers/clients.helper.js';
6
7
  import { BusinessesProvider } from '@modules/financial-entities/providers/businesses.provider.js';
7
8
  import { ClientsProvider } from '@modules/financial-entities/providers/clients.provider.js';
8
9
  import { Currency } from '@shared/enums';
9
10
  import { NewDocumentInfo } from '@shared/gql-types';
10
11
  import { dateToTimelessDateString } from '@shared/helpers';
11
12
  import { TimelessDateString } from '@shared/types';
12
- import { getClientFromGreenInvoiceClient } from './green-invoice-clients.helper.js';
13
13
 
14
14
  export const convertContractToDraft = async (
15
15
  contract: IGetContractsByIdsResult,
@@ -20,12 +20,7 @@ export const convertContractToDraft = async (
20
20
  .get(BusinessesProvider)
21
21
  .getBusinessByIdLoader.load(contract.client_id);
22
22
  const clientPromise = injector.get(ClientsProvider).getClientByIdLoader.load(contract.client_id);
23
- const greenInvoiceClientPromise = getClientFromGreenInvoiceClient(injector, contract.client_id);
24
- const [business, client, greenInvoiceClient] = await Promise.all([
25
- businessPromise,
26
- clientPromise,
27
- greenInvoiceClientPromise,
28
- ]);
23
+ const [business, client] = await Promise.all([businessPromise, clientPromise]);
29
24
 
30
25
  if (!business) {
31
26
  throw new GraphQLError(`Business ID="${contract.client_id}" not found`);
@@ -35,7 +30,9 @@ export const convertContractToDraft = async (
35
30
  throw new GraphQLError(`Client not found for business ID="${contract.client_id}"`);
36
31
  }
37
32
 
38
- if (!greenInvoiceClient) {
33
+ const greenInvoiceId = validateClientIntegrations(client.integrations)?.greenInvoiceId;
34
+
35
+ if (!greenInvoiceId) {
39
36
  throw new GraphQLError(`Green invoice match not found for business ID="${contract.client_id}"`);
40
37
  }
41
38
 
@@ -45,7 +42,7 @@ export const convertContractToDraft = async (
45
42
  const year = today.getFullYear() + (today.getMonth() === 0 ? -1 : 0);
46
43
  const month = format(subMonths(today, 1), 'MMMM');
47
44
 
48
- const documentInput: NewDocumentInfo = {
45
+ const documentInput: Omit<NewDocumentInfo, 'client'> & { client: string | undefined } = {
49
46
  remarks: `${contract.purchase_orders[0] ? `PO: ${contract.purchase_orders[0]}${contract.remarks ? ', ' : ''}` : ''}${contract.remarks ?? ''}`,
50
47
  description: `GraphQL Hive Enterprise License - ${month} ${year}`,
51
48
  type: normalizeDocumentType(contract.document_type),
@@ -56,10 +53,7 @@ export const convertContractToDraft = async (
56
53
  vatType: 'EXEMPT',
57
54
  rounding: false,
58
55
  signed: true,
59
- client: {
60
- ...greenInvoiceClient,
61
- emails: [...((client.emails?.filter(Boolean) as string[]) ?? [])],
62
- },
56
+ client: greenInvoiceId,
63
57
  income: [
64
58
  {
65
59
  description: `GraphQL Hive Enterprise License - ${month} ${year}`,