@silexpert/core 2.0.120 → 2.0.122
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{index-BvApezAZ.d.mts → index-BTRchHCY.d.mts} +1187 -1114
- package/dist/index-BTRchHCY.d.mts.map +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +6 -6
- package/dist/index.mjs.map +1 -1
- package/dist/{product-BCFrBxXc.mjs → product-B35JCiip.mjs} +2 -2
- package/dist/product-B35JCiip.mjs.map +1 -0
- package/dist/server/index.d.mts +1 -1
- package/dist/server/index.mjs +3 -3
- package/dist/server/index.mjs.map +1 -1
- package/package.json +1 -1
- package/ts/api/index.ts +19 -2
- package/ts/api/resources/Exercice.ts +5 -0
- package/ts/api/resources/TeamSystemSignature.ts +16 -0
- package/ts/api/resources.ts +16 -0
- package/ts/types/Enum/CustomerSignature.ts +1 -0
- package/ts/types/Enum/EInvoicingStatusCode.ts +15 -1
- package/ts/types/Enum/LetterType.ts +8 -0
- package/ts/types/Enum/MealExpenseThresholds.ts +4 -0
- package/ts/types/Enum/Unit.ts +7 -0
- package/ts/types/Interface/api/appointment/Appointment.ts +1 -1
- package/ts/types/Interface/api/balanceSheet/UpdateBalanceSheet.ts +5 -0
- package/ts/types/Interface/api/commercialManagement/Create.ts +6 -1
- package/ts/types/Interface/api/commercialManagement/CreateProductInvoice.ts +60 -0
- package/ts/types/Interface/api/commercialManagement/Read.ts +1 -0
- package/ts/types/Interface/api/exercice/QueryExercice.ts +8 -2
- package/ts/types/Interface/api/product/CreateProduct.ts +3 -34
- package/ts/types/Interface/api/product/ProductLineInputs.ts +37 -0
- package/ts/types/Interface/api/refund/QueryRefundPaginated.ts +5 -0
- package/ts/types/Interface/api/teamSystemSignature/ReadTeamSystemSignature.ts +18 -0
- package/ts/types/Interface/api/teamSystemSignature/SendTeamSystemSignature.ts +23 -0
- package/ts/types/Interface/api/teamSystemSignature/index.ts +2 -0
- package/ts/types/Interface/models/IBalanceSheet.ts +1 -0
- package/ts/types/Interface/models/ICustomerSignature.ts +2 -0
- package/ts/types/Interface/models/IEstimateInvoice.ts +4 -0
- package/ts/types/index.ts +3 -0
- package/ts/utils/amount.ts +7 -0
- package/ts/utils/commercialManagement/document.ts +1 -1
- package/ts/utils/commercialManagement/product.ts +7 -3
- package/ts/utils/commercialManagement/vat.ts +9 -11
- package/ts/utils/tests/document.spec.ts +95 -0
- package/ts/utils/tests/payment.spec.ts +0 -70
- package/ts/utils/validators/nestedArray.validator.ts +42 -0
- package/dist/index-BvApezAZ.d.mts.map +0 -1
- package/dist/product-BCFrBxXc.mjs.map +0 -1
package/package.json
CHANGED
package/ts/api/index.ts
CHANGED
|
@@ -41,11 +41,28 @@ export const Silex = (params: { url: string; loginWith?: any; setToken?: any })
|
|
|
41
41
|
},
|
|
42
42
|
});
|
|
43
43
|
|
|
44
|
+
const wrappedAxios = wrapAxios(axiosInstance);
|
|
45
|
+
|
|
46
|
+
const instantiateResource = (value: any): any => {
|
|
47
|
+
if (typeof value === 'function') {
|
|
48
|
+
return new value(wrappedAxios);
|
|
49
|
+
}
|
|
50
|
+
if (typeof value === 'object' && value !== null) {
|
|
51
|
+
return Object.entries(value).reduce(
|
|
52
|
+
(acc, [k, v]) => ({
|
|
53
|
+
...acc,
|
|
54
|
+
[k]: instantiateResource(v),
|
|
55
|
+
}),
|
|
56
|
+
{},
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
return value;
|
|
60
|
+
};
|
|
61
|
+
|
|
44
62
|
const _resources = Object.entries(resources).reduce(
|
|
45
63
|
(acc, [name, value]) => ({
|
|
46
64
|
...acc,
|
|
47
|
-
|
|
48
|
-
[name]: new value(wrapAxios(axiosInstance)),
|
|
65
|
+
[name]: instantiateResource(value),
|
|
49
66
|
}),
|
|
50
67
|
{},
|
|
51
68
|
);
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
GenerateProjectExercice,
|
|
11
11
|
IGedFile,
|
|
12
12
|
SendPreviewProjectExercice,
|
|
13
|
+
QuerySignUrlForProject,
|
|
13
14
|
} from '../../types/index.js';
|
|
14
15
|
import { Resource } from '../Resource.js';
|
|
15
16
|
|
|
@@ -71,6 +72,10 @@ export class Exercice extends Resource {
|
|
|
71
72
|
});
|
|
72
73
|
}
|
|
73
74
|
|
|
75
|
+
getSignUrlForProject(params: QuerySignUrlForProject): Promise<string> {
|
|
76
|
+
return this.axios.$get('exercices/project/sign-url', { params });
|
|
77
|
+
}
|
|
78
|
+
|
|
74
79
|
getProgress(idExercice: number): Promise<number> {
|
|
75
80
|
return this.axios.$get(`exercices/${idExercice}/progress`);
|
|
76
81
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { SendTeamSystemSignature, ReadTeamSystemSignature } from '../../types/index.js';
|
|
2
|
+
import { Resource } from '../Resource.js';
|
|
3
|
+
|
|
4
|
+
export class TeamSystemSignature extends Resource {
|
|
5
|
+
sendForSignature(idDocument: number, payload: SendTeamSystemSignature): Promise<ReadTeamSystemSignature> {
|
|
6
|
+
return this.axios.$post(`/connectors/team-system/signatures/documents/${idDocument}/send-for-signature`, payload);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
startSession(token: string): Promise<{ url: string }> {
|
|
10
|
+
return this.axios.$get(`/connectors/team-system/signatures/start-session/${token}`);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
getSignatureStatus(idDocument: number): Promise<ReadTeamSystemSignature> {
|
|
14
|
+
return this.axios.$get(`/connectors/team-system/signatures/documents/${idDocument}/signature-status`);
|
|
15
|
+
}
|
|
16
|
+
}
|
package/ts/api/resources.ts
CHANGED
|
@@ -118,6 +118,8 @@ import { Prestations } from './resources/Prestations.js';
|
|
|
118
118
|
import { StatisticCustomerSuccess } from './resources/statistic/CustomerSuccess.js';
|
|
119
119
|
import { CommercialImport } from './resources/CommercialImport.js';
|
|
120
120
|
import { Team } from './resources/Team.js';
|
|
121
|
+
import { TeamSystemSignature } from './resources/TeamSystemSignature.js';
|
|
122
|
+
|
|
121
123
|
import { CashAndExpense } from './resources/CashAndExpense.js';
|
|
122
124
|
import { Archive } from './resources/Archive.js';
|
|
123
125
|
import { AccountsSector } from './resources/AccountsSectors.js';
|
|
@@ -392,6 +394,9 @@ export const resources = {
|
|
|
392
394
|
docoon: Docoon,
|
|
393
395
|
usersHistory: UsersHistory,
|
|
394
396
|
acd: Acd,
|
|
397
|
+
teamSystem: {
|
|
398
|
+
signature: TeamSystemSignature,
|
|
399
|
+
},
|
|
395
400
|
zendesk: Zendesk,
|
|
396
401
|
formalism: Formalism,
|
|
397
402
|
financialProjection: FinancialProjection,
|
|
@@ -403,3 +408,14 @@ export const resources = {
|
|
|
403
408
|
};
|
|
404
409
|
|
|
405
410
|
export * from './resources/Cache.js';
|
|
411
|
+
export * from './resources/TeamSystemSignature.js';
|
|
412
|
+
|
|
413
|
+
export type SilexResourceInstance<T> = T extends new (...args: any) => infer R
|
|
414
|
+
? R
|
|
415
|
+
: T extends object
|
|
416
|
+
? { [K in keyof T]: SilexResourceInstance<T[K]> }
|
|
417
|
+
: never;
|
|
418
|
+
|
|
419
|
+
export type SilexResources = {
|
|
420
|
+
[K in keyof typeof resources]: SilexResourceInstance<(typeof resources)[K]>;
|
|
421
|
+
};
|
|
@@ -19,6 +19,7 @@ export enum SignatureType {
|
|
|
19
19
|
EQUIPMENT = 'equipment',
|
|
20
20
|
MANDAT = 'mandat', // N'est plus utilisé, permet de distinguer les mandats signés avant ajout de la signature Clementine
|
|
21
21
|
MANDAT_PA_EC = 'mandat_pa_ec',
|
|
22
|
+
COMMERCIAL_DOCUMENT = 'commercial_document',
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
export const SignatureStatusDetail = {
|
|
@@ -17,89 +17,103 @@ export enum EInvoicingStatusCode {
|
|
|
17
17
|
|
|
18
18
|
export const EInvoicingStatusCodeMetadata: Record<
|
|
19
19
|
EInvoicingStatusCode,
|
|
20
|
-
{ shortLabel: string; label: string; color: string; description?: string }
|
|
20
|
+
{ shortLabel: string; label: string; pluralLabel: string; color: string; description?: string }
|
|
21
21
|
> = {
|
|
22
22
|
[EInvoicingStatusCode.DEPOSITED]: {
|
|
23
23
|
shortLabel: 'Déposée',
|
|
24
24
|
label: 'Déposée',
|
|
25
|
+
pluralLabel: 'Déposées',
|
|
25
26
|
color: 'cerulean',
|
|
26
27
|
description: 'Facture déposée et contrôles techniques validés.',
|
|
27
28
|
},
|
|
28
29
|
[EInvoicingStatusCode.ISSUED]: {
|
|
29
30
|
shortLabel: 'Émise',
|
|
30
31
|
label: 'Émise par la plateforme',
|
|
32
|
+
pluralLabel: 'Émises',
|
|
31
33
|
color: 'success',
|
|
32
34
|
description: 'Facture transmise au réseau de facturation.',
|
|
33
35
|
},
|
|
34
36
|
[EInvoicingStatusCode.RECEIVED]: {
|
|
35
37
|
shortLabel: 'Reçue',
|
|
36
38
|
label: 'Reçue',
|
|
39
|
+
pluralLabel: 'Reçues',
|
|
37
40
|
color: 'success',
|
|
38
41
|
description: 'Facture reçue par la plateforme du destinataire.',
|
|
39
42
|
},
|
|
40
43
|
[EInvoicingStatusCode.MADE_AVAILABLE]: {
|
|
41
44
|
shortLabel: 'Mise à disposition',
|
|
42
45
|
label: 'Mise à disposition',
|
|
46
|
+
pluralLabel: 'Mises à disposition',
|
|
43
47
|
color: 'fire',
|
|
44
48
|
description: 'Facture disponible pour le destinataire.',
|
|
45
49
|
},
|
|
46
50
|
[EInvoicingStatusCode.HANDLED]: {
|
|
47
51
|
shortLabel: 'Prise en charge',
|
|
48
52
|
label: 'Prise en charge',
|
|
53
|
+
pluralLabel: 'Prises en charge',
|
|
49
54
|
color: 'fire',
|
|
50
55
|
description: 'Facture en cours de traitement par le destinataire.',
|
|
51
56
|
},
|
|
52
57
|
[EInvoicingStatusCode.APPROVED]: {
|
|
53
58
|
shortLabel: 'Approuvée',
|
|
54
59
|
label: 'Approuvée',
|
|
60
|
+
pluralLabel: 'Approuvées',
|
|
55
61
|
color: 'success',
|
|
56
62
|
description: 'Facture entièrement acceptée.',
|
|
57
63
|
},
|
|
58
64
|
[EInvoicingStatusCode.PARTIALLY_APPROVED]: {
|
|
59
65
|
shortLabel: 'Approbation partielle',
|
|
60
66
|
label: 'Approbation partielle',
|
|
67
|
+
pluralLabel: 'Approbations partielles',
|
|
61
68
|
color: 'error',
|
|
62
69
|
description: 'Facture partiellement acceptée.',
|
|
63
70
|
},
|
|
64
71
|
[EInvoicingStatusCode.IN_DISPUTE]: {
|
|
65
72
|
shortLabel: 'En litige',
|
|
66
73
|
label: 'En litige',
|
|
74
|
+
pluralLabel: 'En litige',
|
|
67
75
|
color: 'error',
|
|
68
76
|
description: 'Facture contestée par le destinataire.',
|
|
69
77
|
},
|
|
70
78
|
[EInvoicingStatusCode.SUSPENDED]: {
|
|
71
79
|
shortLabel: 'Suspendue',
|
|
72
80
|
label: 'Suspendue',
|
|
81
|
+
pluralLabel: 'Suspendues',
|
|
73
82
|
color: 'error',
|
|
74
83
|
description: 'Traitement suspendu, informations attendues.',
|
|
75
84
|
},
|
|
76
85
|
[EInvoicingStatusCode.COMPLETED]: {
|
|
77
86
|
shortLabel: 'Complétée',
|
|
78
87
|
label: 'Complétée',
|
|
88
|
+
pluralLabel: 'Complétées',
|
|
79
89
|
color: 'fire',
|
|
80
90
|
description: 'Informations complémentaires transmises.',
|
|
81
91
|
},
|
|
82
92
|
[EInvoicingStatusCode.REFUSED]: {
|
|
83
93
|
shortLabel: 'Refusée',
|
|
84
94
|
label: 'Refusée',
|
|
95
|
+
pluralLabel: 'Refusées',
|
|
85
96
|
color: 'error',
|
|
86
97
|
description: 'Facture refusée par le destinataire.',
|
|
87
98
|
},
|
|
88
99
|
[EInvoicingStatusCode.PAYMENT_TRANSMITTED]: {
|
|
89
100
|
shortLabel: 'Paiement transmis',
|
|
90
101
|
label: 'Paiement transmis',
|
|
102
|
+
pluralLabel: 'Paiements transmis',
|
|
91
103
|
color: 'success',
|
|
92
104
|
description: 'Paiement déclaré par le destinataire.',
|
|
93
105
|
},
|
|
94
106
|
[EInvoicingStatusCode.PAID]: {
|
|
95
107
|
shortLabel: 'Encaissée',
|
|
96
108
|
label: 'Encaissée',
|
|
109
|
+
pluralLabel: 'Encaissées',
|
|
97
110
|
color: 'success',
|
|
98
111
|
description: 'Paiement reçu et confirmé.',
|
|
99
112
|
},
|
|
100
113
|
[EInvoicingStatusCode.REJECTED]: {
|
|
101
114
|
shortLabel: 'Rejetée',
|
|
102
115
|
label: 'Rejetée',
|
|
116
|
+
pluralLabel: 'Rejetées',
|
|
103
117
|
color: 'error',
|
|
104
118
|
description: 'Facture rejetée, correction nécessaire.',
|
|
105
119
|
},
|
|
@@ -47,4 +47,12 @@ export const LetterType = {
|
|
|
47
47
|
id: 12,
|
|
48
48
|
name: 'Bilan avec observation',
|
|
49
49
|
},
|
|
50
|
+
RESIGNATION_OF_MISSION_LRAR: {
|
|
51
|
+
id: 13,
|
|
52
|
+
name: 'LRAR démission de la mission',
|
|
53
|
+
},
|
|
54
|
+
TERMINATION_MANDATE_ELECTRONIC_INVOICING: {
|
|
55
|
+
id: 14,
|
|
56
|
+
name: 'Résiliation mandat facturation électronique',
|
|
57
|
+
},
|
|
50
58
|
};
|
package/ts/types/Enum/Unit.ts
CHANGED
|
@@ -30,6 +30,7 @@ export enum UnitId {
|
|
|
30
30
|
HECTARE = 20,
|
|
31
31
|
MINUTE = 21,
|
|
32
32
|
GRAM = 22,
|
|
33
|
+
UNIT = 23,
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
export type IUnitList = Array<{ name: string; id: number; shortName: string; eInvoicingCode: string | null }>;
|
|
@@ -41,6 +42,12 @@ export const Unit: IUnit = {
|
|
|
41
42
|
shortName: 'art',
|
|
42
43
|
codeEN16931: 'NAR',
|
|
43
44
|
},
|
|
45
|
+
UNIT: {
|
|
46
|
+
id: UnitId.UNIT,
|
|
47
|
+
name: 'Unité',
|
|
48
|
+
shortName: 'u',
|
|
49
|
+
codeEN16931: 'NAR',
|
|
50
|
+
},
|
|
44
51
|
HOUR: {
|
|
45
52
|
id: UnitId.HOUR,
|
|
46
53
|
name: 'Heure',
|
|
@@ -24,12 +24,12 @@ export class CreateAppointmentLink {
|
|
|
24
24
|
|
|
25
25
|
export interface AppointmentContext {
|
|
26
26
|
isProspect: boolean;
|
|
27
|
-
isSoftware: boolean;
|
|
28
27
|
isInCreation: boolean;
|
|
29
28
|
hasAcceptedLab: boolean;
|
|
30
29
|
hasJuridicalPrestation: boolean;
|
|
31
30
|
hasExpertAccountantPrestation: boolean;
|
|
32
31
|
existingAppointments: Array<{ id: number; idTimeSlot: number; startDate: Date }>;
|
|
32
|
+
hasSocietyCreation: boolean;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export class QueryAppointmentAvailability {
|
|
@@ -29,6 +29,8 @@ import { IThirdParty } from '../../models/IThirdParty.js';
|
|
|
29
29
|
import { IEstimateInvoice } from '../../models/IEstimateInvoice.js';
|
|
30
30
|
import { ToBoolean } from '../../../../utils/transforms/boolean.transform.js';
|
|
31
31
|
import { ToNumericEnum } from '../../../../utils/transforms/numericEnum.transform.js';
|
|
32
|
+
import { ValidateNestedArrayOf } from '../../../../utils/validators/nestedArray.validator.js';
|
|
33
|
+
import { CreateProductInvoice } from './CreateProductInvoice.js';
|
|
32
34
|
|
|
33
35
|
export type IProductInvoiceToCreate = IProductInvoice & { save?: boolean };
|
|
34
36
|
|
|
@@ -430,8 +432,11 @@ export class CommercialDocumentInputs {
|
|
|
430
432
|
@ApiProperty({ description: 'Conditions de réglement' })
|
|
431
433
|
termsOfPayment: string | null;
|
|
432
434
|
|
|
433
|
-
@ApiProperty()
|
|
435
|
+
@ApiProperty({ type: [CreateProductInvoice] })
|
|
434
436
|
@IsArray()
|
|
437
|
+
@ValidateNestedArrayOf(CreateProductInvoice)
|
|
438
|
+
// Lines are validated as CreateProductInvoice, but stay typed as IProductInvoice because the same objects feed the
|
|
439
|
+
// document rendering helpers (ReadProductEditing) shared with the front-end apps
|
|
435
440
|
products: Array<IProductInvoiceToCreate>;
|
|
436
441
|
|
|
437
442
|
@ApiProperty({ description: 'Escompte' })
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { IsBoolean, IsEnum, IsIn, IsInt, IsNumber, IsOptional, IsString } from 'class-validator';
|
|
2
|
+
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
|
3
|
+
import { DiscountType } from '../../../Enum/CommercialManagement.js';
|
|
4
|
+
import { Vat } from '../../../Enum/Vat.js';
|
|
5
|
+
import type { VatType } from '../../../Enum/Vat.js';
|
|
6
|
+
import { ProductLineInputs } from '../product/ProductLineInputs.js';
|
|
7
|
+
|
|
8
|
+
const VAT_IDS: number[] = (Object.values(Vat) as VatType[]).map((vat) => vat.id);
|
|
9
|
+
|
|
10
|
+
export class CreateProductInvoice extends ProductLineInputs {
|
|
11
|
+
@ApiPropertyOptional({
|
|
12
|
+
description: 'Absente lorsque la société ne facture pas la TVA : la ligne est alors Hors-Taxe',
|
|
13
|
+
})
|
|
14
|
+
@IsIn(VAT_IDS)
|
|
15
|
+
@IsOptional()
|
|
16
|
+
idVat?: number | null;
|
|
17
|
+
|
|
18
|
+
@ApiProperty({ description: 'Peut être négatif (remise, avoir)' })
|
|
19
|
+
@IsNumber()
|
|
20
|
+
priceTaxExcluded: number;
|
|
21
|
+
|
|
22
|
+
@ApiProperty()
|
|
23
|
+
@IsNumber()
|
|
24
|
+
quantity: number;
|
|
25
|
+
|
|
26
|
+
@ApiPropertyOptional()
|
|
27
|
+
@IsString()
|
|
28
|
+
@IsOptional()
|
|
29
|
+
itemSaleName?: string | null;
|
|
30
|
+
|
|
31
|
+
@ApiPropertyOptional({ description: "Référence de l'article" })
|
|
32
|
+
@IsString()
|
|
33
|
+
@IsOptional()
|
|
34
|
+
itemCodeProduct?: string | null;
|
|
35
|
+
|
|
36
|
+
@ApiPropertyOptional()
|
|
37
|
+
@IsInt()
|
|
38
|
+
@IsOptional()
|
|
39
|
+
idProduct?: number | null;
|
|
40
|
+
|
|
41
|
+
@ApiPropertyOptional()
|
|
42
|
+
@IsNumber()
|
|
43
|
+
@IsOptional()
|
|
44
|
+
discount2?: number | null;
|
|
45
|
+
|
|
46
|
+
@ApiPropertyOptional({ enum: DiscountType })
|
|
47
|
+
@IsEnum(DiscountType)
|
|
48
|
+
@IsOptional()
|
|
49
|
+
discountType?: DiscountType | null;
|
|
50
|
+
|
|
51
|
+
@ApiPropertyOptional()
|
|
52
|
+
@IsInt()
|
|
53
|
+
@IsOptional()
|
|
54
|
+
reorder?: number | null;
|
|
55
|
+
|
|
56
|
+
@ApiPropertyOptional({ description: "Enregistre l'article dans le catalogue de produits" })
|
|
57
|
+
@IsBoolean()
|
|
58
|
+
@IsOptional()
|
|
59
|
+
save?: boolean;
|
|
60
|
+
}
|
|
@@ -21,6 +21,7 @@ export type ReadEstimateInvoice = IEstimateInvoice & { id: number };
|
|
|
21
21
|
|
|
22
22
|
export type ReadProductEditing = IProductInvoice & {
|
|
23
23
|
totalTaxExcluded: number;
|
|
24
|
+
totalTaxExcludedRounded: number;
|
|
24
25
|
unitFormatted: string;
|
|
25
26
|
vatFormatted: string;
|
|
26
27
|
discountFormatted: string | null;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { IsBoolean, IsDate, IsIn, IsOptional } from 'class-validator';
|
|
2
|
-
import { ApiPropertyOptional } from '@nestjs/swagger';
|
|
1
|
+
import { IsBoolean, IsDate, IsIn, IsOptional, IsString } from 'class-validator';
|
|
2
|
+
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
|
3
3
|
import { ToBoolean } from '../../../../utils/transforms/boolean.transform.js';
|
|
4
4
|
|
|
5
5
|
export class QueryExercice {
|
|
@@ -44,3 +44,9 @@ export class QueryExerciceProject {
|
|
|
44
44
|
@IsOptional()
|
|
45
45
|
type?: 'juridical' | 'default';
|
|
46
46
|
}
|
|
47
|
+
|
|
48
|
+
export class QuerySignUrlForProject {
|
|
49
|
+
@ApiProperty()
|
|
50
|
+
@IsString()
|
|
51
|
+
token: string;
|
|
52
|
+
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { IsBoolean,
|
|
2
|
-
import { ProductType, Unit } from '../../../index.js';
|
|
1
|
+
import { IsBoolean, IsNumber, IsOptional, IsString, Min } from 'class-validator';
|
|
3
2
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
|
4
3
|
import { ToBoolean } from '../../../../utils/transforms/boolean.transform.js';
|
|
5
|
-
import {
|
|
4
|
+
import { ProductLineInputs } from './ProductLineInputs.js';
|
|
6
5
|
|
|
7
|
-
export class CreateProduct {
|
|
6
|
+
export class CreateProduct extends ProductLineInputs {
|
|
8
7
|
@ApiProperty()
|
|
9
8
|
@IsString()
|
|
10
9
|
name: string;
|
|
@@ -19,44 +18,14 @@ export class CreateProduct {
|
|
|
19
18
|
@IsNumber()
|
|
20
19
|
idVat: number;
|
|
21
20
|
|
|
22
|
-
@ApiPropertyOptional()
|
|
23
|
-
@IsNumber()
|
|
24
|
-
@IsOptional()
|
|
25
|
-
marginVatType?: number;
|
|
26
|
-
|
|
27
|
-
@ApiPropertyOptional()
|
|
28
|
-
@IsNumber()
|
|
29
|
-
@IsOptional()
|
|
30
|
-
amountOfPurchase?: number;
|
|
31
|
-
|
|
32
21
|
@ApiPropertyOptional()
|
|
33
22
|
@IsBoolean()
|
|
34
23
|
@ToBoolean()
|
|
35
24
|
@IsOptional()
|
|
36
25
|
isFree?: boolean;
|
|
37
26
|
|
|
38
|
-
@ApiProperty()
|
|
39
|
-
@IsNumber()
|
|
40
|
-
@IsObjectId(Unit)
|
|
41
|
-
unit: number;
|
|
42
|
-
|
|
43
|
-
@ApiProperty()
|
|
44
|
-
@IsNumber()
|
|
45
|
-
@IsObjectId(ProductType)
|
|
46
|
-
type: number;
|
|
47
|
-
|
|
48
|
-
@ApiPropertyOptional()
|
|
49
|
-
@IsString()
|
|
50
|
-
@IsOptional()
|
|
51
|
-
comment?: string;
|
|
52
|
-
|
|
53
27
|
@ApiPropertyOptional()
|
|
54
28
|
@IsString()
|
|
55
29
|
@IsOptional()
|
|
56
30
|
codeProduct?: string;
|
|
57
|
-
|
|
58
|
-
@ApiPropertyOptional()
|
|
59
|
-
@IsInt()
|
|
60
|
-
@IsOptional()
|
|
61
|
-
idAccount?: number;
|
|
62
31
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { IsInt, IsNumber, IsOptional, IsString } from 'class-validator';
|
|
2
|
+
import { ProductType, Unit } from '../../../index.js';
|
|
3
|
+
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
|
4
|
+
import { IsObjectId } from '../../../../utils/validators/objectId.validator.js';
|
|
5
|
+
|
|
6
|
+
// Fields shared by a catalog product and a commercial document line, validated the same way in both contexts
|
|
7
|
+
export class ProductLineInputs {
|
|
8
|
+
@ApiProperty()
|
|
9
|
+
@IsNumber()
|
|
10
|
+
@IsObjectId(Unit)
|
|
11
|
+
unit: number;
|
|
12
|
+
|
|
13
|
+
@ApiProperty()
|
|
14
|
+
@IsNumber()
|
|
15
|
+
@IsObjectId(ProductType)
|
|
16
|
+
type: number;
|
|
17
|
+
|
|
18
|
+
@ApiPropertyOptional()
|
|
19
|
+
@IsNumber()
|
|
20
|
+
@IsOptional()
|
|
21
|
+
marginVatType?: number;
|
|
22
|
+
|
|
23
|
+
@ApiPropertyOptional()
|
|
24
|
+
@IsNumber()
|
|
25
|
+
@IsOptional()
|
|
26
|
+
amountOfPurchase?: number | null;
|
|
27
|
+
|
|
28
|
+
@ApiPropertyOptional()
|
|
29
|
+
@IsString()
|
|
30
|
+
@IsOptional()
|
|
31
|
+
comment?: string | null;
|
|
32
|
+
|
|
33
|
+
@ApiPropertyOptional()
|
|
34
|
+
@IsInt()
|
|
35
|
+
@IsOptional()
|
|
36
|
+
idAccount?: number | null;
|
|
37
|
+
}
|
|
@@ -14,6 +14,11 @@ export class QueryRefundPaginated extends RequiredQueryPaginate implements Order
|
|
|
14
14
|
@IsOptional()
|
|
15
15
|
motif?: number;
|
|
16
16
|
|
|
17
|
+
@ApiPropertyOptional()
|
|
18
|
+
@IsOptional()
|
|
19
|
+
@IsInt()
|
|
20
|
+
idSociety?: number;
|
|
21
|
+
|
|
17
22
|
@ApiPropertyOptional()
|
|
18
23
|
@IsOptional()
|
|
19
24
|
startDate?: Date;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ApiPropertyOptional } from '@nestjs/swagger';
|
|
2
|
+
|
|
3
|
+
export class ReadTeamSystemSignature {
|
|
4
|
+
@ApiPropertyOptional()
|
|
5
|
+
tsDocumentId?: string | null;
|
|
6
|
+
|
|
7
|
+
@ApiPropertyOptional()
|
|
8
|
+
tsSignStatus?: string | null;
|
|
9
|
+
|
|
10
|
+
@ApiPropertyOptional()
|
|
11
|
+
tsSignUrl?: string | null;
|
|
12
|
+
|
|
13
|
+
@ApiPropertyOptional()
|
|
14
|
+
tsSignedAt?: Date | null;
|
|
15
|
+
|
|
16
|
+
@ApiPropertyOptional()
|
|
17
|
+
success?: boolean;
|
|
18
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ApiProperty } from '@nestjs/swagger';
|
|
2
|
+
import { IsEmail, IsNotEmpty, IsString } from 'class-validator';
|
|
3
|
+
|
|
4
|
+
export class SendTeamSystemSignature {
|
|
5
|
+
@ApiProperty({ description: 'Prénom du signataire' })
|
|
6
|
+
@IsString()
|
|
7
|
+
@IsNotEmpty()
|
|
8
|
+
signerFirstName: string;
|
|
9
|
+
|
|
10
|
+
@ApiProperty({ description: 'Nom du signataire' })
|
|
11
|
+
@IsString()
|
|
12
|
+
@IsNotEmpty()
|
|
13
|
+
signerLastName: string;
|
|
14
|
+
|
|
15
|
+
@ApiProperty({ description: 'Email du signataire' })
|
|
16
|
+
@IsEmail()
|
|
17
|
+
signerEmail: string;
|
|
18
|
+
|
|
19
|
+
@ApiProperty({ description: 'Numéro de téléphone du signataire' })
|
|
20
|
+
@IsString()
|
|
21
|
+
@IsNotEmpty()
|
|
22
|
+
signerPhone: string;
|
|
23
|
+
}
|
|
@@ -16,6 +16,8 @@ export class ICustomerSignature {
|
|
|
16
16
|
tokenSigner?: string;
|
|
17
17
|
mailSigner: string;
|
|
18
18
|
phoneSigner: string;
|
|
19
|
+
firstNameSigner?: string | null;
|
|
20
|
+
lastNameSigner?: string | null;
|
|
19
21
|
idSendMethod: number;
|
|
20
22
|
idStatusSignature: number;
|
|
21
23
|
idPrestation?: number | null;
|
|
@@ -8,6 +8,7 @@ import { IInvoiceRecurrence } from './IInvoiceRecurrence.js';
|
|
|
8
8
|
import type { ReadEstimateInvoiceStatus } from '../api/commercialManagement/Read.js';
|
|
9
9
|
import { AccountingCategoryId, InvoiceLanguage } from '../../Enum/CommercialManagement.js';
|
|
10
10
|
import { IReminder } from './IReminder.js';
|
|
11
|
+
import { ICustomerSignature } from './ICustomerSignature.js';
|
|
11
12
|
|
|
12
13
|
// estimatesInvoices
|
|
13
14
|
export class IEstimateInvoice {
|
|
@@ -57,9 +58,12 @@ export class IEstimateInvoice {
|
|
|
57
58
|
updatedAt?: Date | null;
|
|
58
59
|
deletedAt?: Date | null;
|
|
59
60
|
|
|
61
|
+
idCustomerSignature?: number | null;
|
|
62
|
+
|
|
60
63
|
// Associations
|
|
61
64
|
products?: IProductInvoice[];
|
|
62
65
|
thirdParty?: IThirdParty;
|
|
66
|
+
signature?: ICustomerSignature | null;
|
|
63
67
|
type?: IEstimateInvoiceType;
|
|
64
68
|
customerPayment?: IPaymentExpectationCustomer;
|
|
65
69
|
society?: ISociety;
|
package/ts/types/index.ts
CHANGED
|
@@ -289,6 +289,7 @@ export * from './Interface/models/IRevenueMovement.js';
|
|
|
289
289
|
export * from './Interface/models/IRevenueSnapshot.js';
|
|
290
290
|
export * from './Interface/models/IEInvoicingEligibilityRequest.js';
|
|
291
291
|
export * from './Interface/models/IUsersHistory.js';
|
|
292
|
+
export * from './Interface/api/teamSystemSignature/index.js';
|
|
292
293
|
export * from './Interface/models/IEInvoicingKycAndMandate.js';
|
|
293
294
|
export * from './Interface/models/IConnectorTracking.js';
|
|
294
295
|
export * from './Interface/models/IEInvoicing.js';
|
|
@@ -894,6 +895,7 @@ export * from './Interface/api/vehicle/CreateSocietyVehicle.js';
|
|
|
894
895
|
export * from './Interface/api/vehicle/UpdateSocietyVehicle.js';
|
|
895
896
|
export * from './Interface/api/fecFile/QueryFecFile.js';
|
|
896
897
|
export * from './Interface/api/product/CreateProduct.js';
|
|
898
|
+
export * from './Interface/api/product/ProductLineInputs.js';
|
|
897
899
|
export * from './Interface/api/product/UpdateProduct.js';
|
|
898
900
|
export * from './Interface/api/product/QueryProduct.js';
|
|
899
901
|
export * from './Interface/api/registration/ReadRegistration.js';
|
|
@@ -983,6 +985,7 @@ export * from './Interface/api/customerActivity/CreateCustomerActivityReport.js'
|
|
|
983
985
|
export * from './Interface/api/customerActivity/Query.js';
|
|
984
986
|
export * from './Interface/api/customerActivity/Create.js';
|
|
985
987
|
export * from './Interface/api/commercialManagement/Create.js';
|
|
988
|
+
export * from './Interface/api/commercialManagement/CreateProductInvoice.js';
|
|
986
989
|
export * from './Interface/api/commercialManagement/Read.js';
|
|
987
990
|
export * from './Interface/api/commercialManagement/Query.js';
|
|
988
991
|
export * from './Interface/api/commercialManagement/Update.js';
|
package/ts/utils/amount.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { MathematicalSign } from '../types/Enum/Util.js';
|
|
2
2
|
import { FormattedAmount } from '../types/Interface/api/amount/FormattedAmount.js';
|
|
3
3
|
|
|
4
|
+
// Round the magnitude first so negative half-cent values match the formatter's symmetric rounding.
|
|
5
|
+
export function roundAmountToInteger(value: number): number {
|
|
6
|
+
const roundedAbsoluteValue = Math.round(Math.abs(value));
|
|
7
|
+
if (roundedAbsoluteValue === 0) return 0;
|
|
8
|
+
return value < 0 ? -roundedAbsoluteValue : roundedAbsoluteValue;
|
|
9
|
+
}
|
|
10
|
+
|
|
4
11
|
export function integerToFormattedAmountString(value: number): string {
|
|
5
12
|
const abs = Math.abs(value / 100);
|
|
6
13
|
let integer = Math.trunc(abs);
|
|
@@ -73,7 +73,7 @@ export function generateCommercialDocument(
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
const totalVats = sumBy(vats, (v) => round(v.amount));
|
|
76
|
-
const totalTaxExcluded = sumBy(products,
|
|
76
|
+
const totalTaxExcluded = sumBy(products, 'totalTaxExcludedRounded');
|
|
77
77
|
|
|
78
78
|
const totalTaxIncluded = totalTaxExcluded + totalVats;
|
|
79
79
|
|