@silexpert/core 1.1.306 → 1.1.308
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/cjs/api/resources/Commercial.d.ts +4 -1
- package/dist/cjs/api/resources/Commercial.d.ts.map +1 -1
- package/dist/cjs/api/resources/Commercial.js +3 -0
- package/dist/cjs/api/resources/Commercial.js.map +1 -1
- package/dist/cjs/types/Enum/Card.d.ts +24 -2
- package/dist/cjs/types/Enum/Card.d.ts.map +1 -1
- package/dist/cjs/types/Enum/Card.js +26 -0
- package/dist/cjs/types/Enum/Card.js.map +1 -1
- package/dist/cjs/types/Enum/PriceGridClementine.d.ts +22 -0
- package/dist/cjs/types/Enum/PriceGridClementine.d.ts.map +1 -1
- package/dist/cjs/types/Enum/PriceGridClementine.js +27 -1
- package/dist/cjs/types/Enum/PriceGridClementine.js.map +1 -1
- package/dist/cjs/types/Enum/PriceGridLegalstart.d.ts +8 -0
- package/dist/cjs/types/Enum/PriceGridLegalstart.d.ts.map +1 -1
- package/dist/cjs/types/Enum/PriceGridLegalstart.js +8 -0
- package/dist/cjs/types/Enum/PriceGridLegalstart.js.map +1 -1
- package/dist/cjs/types/Enum/PriceGridPourcentage.d.ts +10 -0
- package/dist/cjs/types/Enum/PriceGridPourcentage.d.ts.map +1 -1
- package/dist/cjs/types/Enum/PriceGridPourcentage.js +84 -0
- package/dist/cjs/types/Enum/PriceGridPourcentage.js.map +1 -1
- package/dist/cjs/types/Enum/StatisticType.d.ts +2 -1
- package/dist/cjs/types/Enum/StatisticType.d.ts.map +1 -1
- package/dist/cjs/types/Enum/StatisticType.js +1 -0
- package/dist/cjs/types/Enum/StatisticType.js.map +1 -1
- package/dist/cjs/types/Interface/api/commercial/QueryGetStatsHistory.d.ts +7 -0
- package/dist/cjs/types/Interface/api/commercial/QueryGetStatsHistory.d.ts.map +1 -0
- package/dist/cjs/types/Interface/api/commercial/QueryGetStatsHistory.js +42 -0
- package/dist/cjs/types/Interface/api/commercial/QueryGetStatsHistory.js.map +1 -0
- package/dist/cjs/types/Interface/api/payment/Util.d.ts +3 -0
- package/dist/cjs/types/Interface/api/payment/Util.d.ts.map +1 -1
- package/dist/cjs/types/Interface/api/payment/Util.js.map +1 -1
- package/dist/cjs/types/Interface/api/statistic/QueryInternal.d.ts +1 -1
- package/dist/cjs/types/Interface/api/statistic/QueryInternal.d.ts.map +1 -1
- package/dist/cjs/types/Interface/api/statistic/QueryInternal.js +5 -5
- package/dist/cjs/types/Interface/api/statistic/QueryInternal.js.map +1 -1
- package/dist/cjs/types/index.d.ts +1 -0
- package/dist/cjs/types/index.d.ts.map +1 -1
- package/dist/cjs/types/index.js +1 -0
- package/dist/cjs/types/index.js.map +1 -1
- package/dist/cjs/utils/payment.d.ts +1 -0
- package/dist/cjs/utils/payment.d.ts.map +1 -1
- package/dist/cjs/utils/payment.js +68 -59
- package/dist/cjs/utils/payment.js.map +1 -1
- package/dist/cjs/utils/prestation.d.ts +60 -0
- package/dist/cjs/utils/prestation.d.ts.map +1 -1
- package/dist/cjs/utils/prestation.js +4 -3
- package/dist/cjs/utils/prestation.js.map +1 -1
- package/dist/cjs/utils/tests/payment.spec.js +72 -36
- package/dist/cjs/utils/tests/payment.spec.js.map +1 -1
- package/dist/mjs/api/resources/Commercial.d.ts +4 -1
- package/dist/mjs/api/resources/Commercial.d.ts.map +1 -1
- package/dist/mjs/api/resources/Commercial.js +7 -0
- package/dist/mjs/api/resources/Commercial.js.map +1 -1
- package/dist/mjs/types/Enum/Card.d.ts +24 -2
- package/dist/mjs/types/Enum/Card.d.ts.map +1 -1
- package/dist/mjs/types/Enum/Card.js +26 -0
- package/dist/mjs/types/Enum/Card.js.map +1 -1
- package/dist/mjs/types/Enum/PriceGridClementine.d.ts +22 -0
- package/dist/mjs/types/Enum/PriceGridClementine.d.ts.map +1 -1
- package/dist/mjs/types/Enum/PriceGridClementine.js +27 -1
- package/dist/mjs/types/Enum/PriceGridClementine.js.map +1 -1
- package/dist/mjs/types/Enum/PriceGridLegalstart.d.ts +8 -0
- package/dist/mjs/types/Enum/PriceGridLegalstart.d.ts.map +1 -1
- package/dist/mjs/types/Enum/PriceGridLegalstart.js +8 -0
- package/dist/mjs/types/Enum/PriceGridLegalstart.js.map +1 -1
- package/dist/mjs/types/Enum/PriceGridPourcentage.d.ts +10 -0
- package/dist/mjs/types/Enum/PriceGridPourcentage.d.ts.map +1 -1
- package/dist/mjs/types/Enum/PriceGridPourcentage.js +84 -0
- package/dist/mjs/types/Enum/PriceGridPourcentage.js.map +1 -1
- package/dist/mjs/types/Enum/StatisticType.d.ts +2 -1
- package/dist/mjs/types/Enum/StatisticType.d.ts.map +1 -1
- package/dist/mjs/types/Enum/StatisticType.js +1 -0
- package/dist/mjs/types/Enum/StatisticType.js.map +1 -1
- package/dist/mjs/types/Interface/api/commercial/QueryGetStatsHistory.d.ts +7 -0
- package/dist/mjs/types/Interface/api/commercial/QueryGetStatsHistory.d.ts.map +1 -0
- package/dist/mjs/types/Interface/api/commercial/QueryGetStatsHistory.js +42 -0
- package/dist/mjs/types/Interface/api/commercial/QueryGetStatsHistory.js.map +1 -0
- package/dist/mjs/types/Interface/api/payment/Util.d.ts +3 -0
- package/dist/mjs/types/Interface/api/payment/Util.d.ts.map +1 -1
- package/dist/mjs/types/Interface/api/payment/Util.js.map +1 -1
- package/dist/mjs/types/Interface/api/statistic/QueryInternal.d.ts +1 -1
- package/dist/mjs/types/Interface/api/statistic/QueryInternal.d.ts.map +1 -1
- package/dist/mjs/types/Interface/api/statistic/QueryInternal.js +3 -3
- package/dist/mjs/types/Interface/api/statistic/QueryInternal.js.map +1 -1
- package/dist/mjs/types/index.d.ts +1 -0
- package/dist/mjs/types/index.d.ts.map +1 -1
- package/dist/mjs/types/index.js +1 -0
- package/dist/mjs/types/index.js.map +1 -1
- package/dist/mjs/utils/payment.d.ts +1 -0
- package/dist/mjs/utils/payment.d.ts.map +1 -1
- package/dist/mjs/utils/payment.js +68 -59
- package/dist/mjs/utils/payment.js.map +1 -1
- package/dist/mjs/utils/prestation.d.ts +60 -0
- package/dist/mjs/utils/prestation.d.ts.map +1 -1
- package/dist/mjs/utils/prestation.js +1 -1
- package/dist/mjs/utils/prestation.js.map +1 -1
- package/dist/mjs/utils/tests/payment.spec.js +72 -36
- package/dist/mjs/utils/tests/payment.spec.js.map +1 -1
- package/package.json +1 -1
- package/ts/api/resources/Commercial.ts +8 -0
- package/ts/types/Enum/Card.ts +27 -0
- package/ts/types/Enum/PriceGridClementine.ts +27 -1
- package/ts/types/Enum/PriceGridLegalstart.ts +8 -0
- package/ts/types/Enum/PriceGridPourcentage.ts +84 -0
- package/ts/types/Enum/StatisticType.ts +1 -0
- package/ts/types/Interface/api/commercial/QueryGetStatsHistory.ts +26 -0
- package/ts/types/Interface/api/payment/Util.ts +3 -0
- package/ts/types/Interface/api/statistic/QueryInternal.ts +1 -1
- package/ts/types/index.ts +1 -0
- package/ts/utils/payment.ts +70 -63
- package/ts/utils/prestation.ts +3 -1
- package/ts/utils/tests/payment.spec.ts +72 -36
package/ts/utils/payment.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { IPayment, IRegulation, ParamsForPaymentsAuto, PaymentMethod, PaymentAuto, getTaxesIncludedAmount } from '../types';
|
|
4
4
|
import * as dayjs from 'dayjs';
|
|
5
5
|
import { PartialExercicePrestationExpress } from '../types/Interface/api/payment/Util';
|
|
6
|
+
import { getPriceGrid } from './prestation';
|
|
6
7
|
|
|
7
8
|
interface PaymentsWithList extends IPayment {
|
|
8
9
|
type: 'isComptable' | 'isJuridique' | 'isSocial' | 'isOther',
|
|
@@ -57,9 +58,8 @@ const groupPaymentsByServiceType = (payments: IPayment[], types: ('isComptable'
|
|
|
57
58
|
return societyPayment;
|
|
58
59
|
};
|
|
59
60
|
|
|
60
|
-
const calculateFees = (amount: number, goToClient: Date, paymentDate: Date
|
|
61
|
+
const calculateFees = (amount: number, goToClient: Date, paymentDate: Date):number => {
|
|
61
62
|
const yearlyPriceIncreasing = 1.0275;
|
|
62
|
-
const appCost = getTaxesIncludedAmount(14.9, idVat);
|
|
63
63
|
|
|
64
64
|
const oneYearLessIfIn3LastMonthsOfYear = dayjs(goToClient).month() >= 9 ? 1 : 0;
|
|
65
65
|
|
|
@@ -71,12 +71,7 @@ const calculateFees = (amount: number, goToClient: Date, paymentDate: Date, nbEx
|
|
|
71
71
|
// soit amount * yearlyPriceIncreasing ^ nbYearsMore
|
|
72
72
|
amount = amount * Math.pow(yearlyPriceIncreasing, nbYearsMore);
|
|
73
73
|
}
|
|
74
|
-
|
|
75
|
-
// À partir du second exercice non express, on applique le coût de l'application (14,9€ HT)
|
|
76
|
-
if (nbExoNonExpressGenerated >= 2) {
|
|
77
|
-
amount += appCost;
|
|
78
|
-
}
|
|
79
|
-
return Math.round(100 * amount) / 100;
|
|
74
|
+
return amount;
|
|
80
75
|
};
|
|
81
76
|
|
|
82
77
|
/**
|
|
@@ -86,15 +81,25 @@ const calculateFees = (amount: number, goToClient: Date, paymentDate: Date, nbEx
|
|
|
86
81
|
* @param {IPrestationList} prestationList - type of prestation (hidden: 0, isCatalog: 1, isComptable: 1)
|
|
87
82
|
* @param {number} idVat - vat id of society linked
|
|
88
83
|
* @param {number} yearlyAmountNonExpress - yearly amount of non express prestation (HT)
|
|
84
|
+
* @param {number} nextYearlyAmountNonExpress - yearly amount of non express prestation for next years (HT)
|
|
89
85
|
* @param {PartialExercicePrestationExpress[]} listPartialExercicePrestationExpress - list of exercicePrestation linked to idPrestation -> used to get express
|
|
90
86
|
* @param {IRegulation[]} listRegulations - list of regulations linked to idPrestation (TTC)
|
|
91
87
|
* @returns { IPayment[] } list of payment to create for billing auto, after each presta go to onBoarding
|
|
92
88
|
*/
|
|
93
89
|
const calculatePaymentsAuto = (params: ParamsForPaymentsAuto):PaymentAuto[] => {
|
|
94
|
-
const { goToClient, firstExerciceNonExpresssEndDate, idPrestation, prestationList, idVat, yearlyAmountNonExpress, listPartialExercicePrestationExpress, listRegulations } = params;
|
|
90
|
+
const { idTypeBrand, goToClient, firstExerciceNonExpresssEndDate, idPrestation, prestationList, idVat, yearlyAmountNonExpress, nextYearlyAmountNonExpress, listPartialExercicePrestationExpress, listRegulations } = params;
|
|
95
91
|
const initializedPaymentDate = dayjs().endOf('month').diff(dayjs(), 'day') < 3/* || dayjs().date() >= 15 */
|
|
96
92
|
? dayjs().add(2, 'month').startOf('month').toDate()
|
|
97
93
|
: dayjs().add(1, 'month').startOf('month').toDate();
|
|
94
|
+
let isApplicationAlreadyPaid = false;
|
|
95
|
+
|
|
96
|
+
// On récupère la grille tarifaire pour savoir si les tarifs sont HT ou TTC
|
|
97
|
+
// et pour connaitre le montant du coût de l'app
|
|
98
|
+
if (!prestationList.id) throw new Error('idPrestationList manquant');
|
|
99
|
+
const priceGrid = getPriceGrid(idTypeBrand, prestationList.id);
|
|
100
|
+
if (!priceGrid) throw new Error('Impossible de trouver la grille tarifaire correspondante');
|
|
101
|
+
const { applicationCost, priceWithTaxesIncluded } = priceGrid;
|
|
102
|
+
const applicationCostTotalTTC = (priceWithTaxesIncluded ? applicationCost : getTaxesIncludedAmount(applicationCost, idVat)) * 12;
|
|
98
103
|
|
|
99
104
|
if (prestationList?.isCatalog || !prestationList?.isComptable) throw new Error('Ce type de prestation ne correspond pas aux conditions attendues.');
|
|
100
105
|
// if (!listRegulations?.length) throw new Error('List of regulations can not be empty');
|
|
@@ -120,6 +125,7 @@ const calculatePaymentsAuto = (params: ParamsForPaymentsAuto):PaymentAuto[] => {
|
|
|
120
125
|
if (sumRegulations) {
|
|
121
126
|
listPayments.push({
|
|
122
127
|
amount:sumRegulations, //TTC
|
|
128
|
+
isPaid: true,
|
|
123
129
|
datePayment: dayjs().toDate(),
|
|
124
130
|
idPrestation,
|
|
125
131
|
idPaymentMethod: PaymentMethod.DIRECT_DEBIT.id,
|
|
@@ -130,31 +136,33 @@ const calculatePaymentsAuto = (params: ParamsForPaymentsAuto):PaymentAuto[] => {
|
|
|
130
136
|
// =========================
|
|
131
137
|
// EXPRESS
|
|
132
138
|
// =========================
|
|
133
|
-
listPartialExercicePrestationExpress.forEach((exercicePrestation:PartialExercicePrestationExpress) => {
|
|
134
|
-
remainingAmount +=
|
|
139
|
+
listPartialExercicePrestationExpress.forEach((exercicePrestation:PartialExercicePrestationExpress, indexEP: number) => {
|
|
140
|
+
remainingAmount += !priceWithTaxesIncluded
|
|
141
|
+
? getTaxesIncludedAmount(exercicePrestation.totalAmount, idVat)
|
|
142
|
+
: exercicePrestation.totalAmount; //TTC
|
|
135
143
|
//Si le premier règlement couvre le coût de cet exercicePrestation, on passe au suivant
|
|
136
144
|
if (remainingAmount <= 0) return;
|
|
137
145
|
|
|
138
146
|
//express : on étale en countExpressMonthlyPayment (nb de mensualités)
|
|
139
147
|
let remainingAmountByExercicePrestation = remainingAmount; //TTC
|
|
140
148
|
let countExpressMonthlyPayment = exercicePrestation?.countExpressMonthlyPayment ?? 3; //TTC
|
|
141
|
-
|
|
149
|
+
//Si un premier règlement est généré avec le montant des regulations, on le considère comme une mensualité (unioquement pour le premier express et la première mensualité)
|
|
150
|
+
if (indexEP === 0 && sumRegulations > 0) countExpressMonthlyPayment -= 1;
|
|
151
|
+
|
|
152
|
+
const monthlyAmount = remainingAmountByExercicePrestation / countExpressMonthlyPayment; //TTC
|
|
142
153
|
for (let index = 1; index <= countExpressMonthlyPayment; index++) {
|
|
143
|
-
//Si un premier règlement est généré avec le montant des regulations, on le considère comme une mensualité
|
|
144
|
-
if (index === 1 && sumRegulations) countExpressMonthlyPayment -= 1;
|
|
145
|
-
|
|
146
154
|
// On arrondis les 11 premières mensualités, mais on récupère le reste pour la dernière mensualité, pour éviter les centimes perdus en arrondis
|
|
147
155
|
// et on applique le taux de tva de la société
|
|
148
|
-
const amount = index < countExpressMonthlyPayment ?
|
|
156
|
+
const amount = index < countExpressMonthlyPayment ? monthlyAmount : remainingAmountByExercicePrestation; //TTC
|
|
149
157
|
|
|
150
158
|
listPayments.push({
|
|
151
|
-
amount,
|
|
159
|
+
amount: Math.round(100 * amount) / 100,
|
|
152
160
|
datePayment: paymentDate,
|
|
153
161
|
idPrestation,
|
|
154
162
|
idPaymentMethod: PaymentMethod.DIRECT_DEBIT.id,
|
|
155
163
|
closingDate: exercicePrestation.endDate,
|
|
156
164
|
});
|
|
157
|
-
remainingAmountByExercicePrestation -=
|
|
165
|
+
remainingAmountByExercicePrestation -= monthlyAmount;
|
|
158
166
|
paymentDate = dayjs(paymentDate).add(1, 'month').startOf('month').toDate();
|
|
159
167
|
}
|
|
160
168
|
remainingAmount = 0;
|
|
@@ -167,79 +175,78 @@ const calculatePaymentsAuto = (params: ParamsForPaymentsAuto):PaymentAuto[] => {
|
|
|
167
175
|
// Si un seul exo express, alors on met les paiements de l'exo actuel en parallèle
|
|
168
176
|
// sinon, ils sont à la suite des express
|
|
169
177
|
if (nbExoExpress <= 1) paymentDate = initializedPaymentDate;
|
|
170
|
-
let nbExoNonExpressGenerated = 1;
|
|
171
178
|
let exerciceEndDate = dayjs(firstExerciceNonExpresssEndDate).toDate();
|
|
172
179
|
|
|
173
|
-
//On génère
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
+
//On génère un seul exercices plein, non express
|
|
181
|
+
//On compte le nb de mois restants entre la date à laquelle le paiement va être créé et la date de fin d'exercice
|
|
182
|
+
let countMonthsBeforeExerciceEnd = Math.ceil(dayjs(exerciceEndDate).diff(paymentDate, 'months', true));
|
|
183
|
+
if (countMonthsBeforeExerciceEnd < 3) countMonthsBeforeExerciceEnd = 3;
|
|
184
|
+
|
|
185
|
+
const exoAmount = yearlyAmountNonExpress;
|
|
186
|
+
remainingAmount += priceWithTaxesIncluded ? exoAmount : getTaxesIncludedAmount(exoAmount, idVat);
|
|
180
187
|
|
|
181
|
-
|
|
182
|
-
|
|
188
|
+
let remainingAmountByExercicePrestation = remainingAmount;
|
|
189
|
+
let monthlyAmount = remainingAmountByExercicePrestation / countMonthsBeforeExerciceEnd; //TTC
|
|
183
190
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
191
|
+
if (monthlyAmount > 0) {
|
|
192
|
+
for (let index = 1; index <= countMonthsBeforeExerciceEnd; index++) {
|
|
193
|
+
let amount = index < countMonthsBeforeExerciceEnd ? monthlyAmount : remainingAmountByExercicePrestation;
|
|
187
194
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
amount = calculateFees(amount, goToClient, paymentDate, nbExoNonExpressGenerated, idVat);
|
|
195
|
+
// Si besoin, on applique les frais nécessaires :
|
|
196
|
+
// - 2,75% d'augmentation chaque année, sauf si souscriptiuon dans les 3 derniers mois de l'année civile)
|
|
197
|
+
amount = calculateFees(amount, goToClient, paymentDate);
|
|
192
198
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
}
|
|
203
|
-
exerciceEndDate = dayjs(exerciceEndDate).startOf('month').add(1, 'year').endOf('month').toDate();
|
|
199
|
+
listPayments.push({
|
|
200
|
+
amount: Math.round(100 * amount) / 100,
|
|
201
|
+
datePayment: paymentDate,
|
|
202
|
+
idPrestation,
|
|
203
|
+
idPaymentMethod: PaymentMethod.DIRECT_DEBIT.id,
|
|
204
|
+
closingDate: exerciceEndDate,
|
|
205
|
+
});
|
|
206
|
+
remainingAmountByExercicePrestation -= monthlyAmount;
|
|
207
|
+
paymentDate = dayjs(paymentDate).add(1, 'month').startOf('month').toDate();
|
|
204
208
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
remainingAmount = 0;
|
|
209
|
+
exerciceEndDate = dayjs(exerciceEndDate).startOf('month').add(1, 'year').endOf('month').toDate();
|
|
208
210
|
}
|
|
209
211
|
|
|
212
|
+
remainingAmount = 0;
|
|
213
|
+
|
|
210
214
|
// =========================
|
|
211
215
|
// JUSQU'EN DECEMBRE
|
|
212
216
|
// =========================
|
|
213
|
-
//On
|
|
214
|
-
|
|
215
|
-
// if (countMonthsBeforeExerciceEnd < 3) countMonthsBeforeExerciceEnd = 3;
|
|
217
|
+
// On applique le taux de tva de la société, si besoin, selon la grille tarifaire
|
|
218
|
+
remainingAmount += priceWithTaxesIncluded ? nextYearlyAmountNonExpress : getTaxesIncludedAmount(nextYearlyAmountNonExpress, idVat);
|
|
216
219
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
+
remainingAmountByExercicePrestation = remainingAmount;
|
|
221
|
+
//On compte le nb de mois restants entre la date à laquelle le paiement va être créé et la date de fin d'exercice
|
|
222
|
+
countMonthsBeforeExerciceEnd = Math.ceil(dayjs(exerciceEndDate).diff(paymentDate, 'months', true));
|
|
223
|
+
if (countMonthsBeforeExerciceEnd < 3) countMonthsBeforeExerciceEnd = 3;
|
|
224
|
+
|
|
225
|
+
// - frais d'application dès les second exo non express
|
|
226
|
+
remainingAmountByExercicePrestation += applicationCostTotalTTC;
|
|
227
|
+
|
|
228
|
+
monthlyAmount = remainingAmountByExercicePrestation / countMonthsBeforeExerciceEnd;
|
|
220
229
|
|
|
221
230
|
// Si aucun paiement généré, on stoppe là
|
|
222
231
|
if (!listPayments.length) return [];
|
|
223
232
|
|
|
224
|
-
while (dayjs(listPayments.slice(-1)[0].datePayment).month() < 11) {
|
|
225
|
-
let amount =
|
|
226
|
-
|
|
233
|
+
while (dayjs(listPayments.slice(-1)[0].datePayment).month() < 11 || !isApplicationAlreadyPaid) {
|
|
234
|
+
let amount = monthlyAmount;
|
|
235
|
+
|
|
227
236
|
// Si besoin, on applique les frais nécessaires :
|
|
228
237
|
// - 2,75% d'augmentation chaque année, sauf si souscriptiuon dans les 3 derniers mois de l'année civile)
|
|
229
238
|
// - frais d'application dès les second exo non express
|
|
230
|
-
amount = calculateFees(amount, goToClient, paymentDate
|
|
231
|
-
|
|
232
|
-
// On applique le taux de tva de la société
|
|
233
|
-
amount = getTaxesIncludedAmount(amount, idVat);
|
|
239
|
+
amount = calculateFees(amount, goToClient, paymentDate);
|
|
234
240
|
|
|
235
241
|
listPayments.push({
|
|
236
|
-
amount,
|
|
242
|
+
amount: Math.round(100 * amount) / 100,
|
|
237
243
|
datePayment: paymentDate,
|
|
238
244
|
idPrestation,
|
|
239
245
|
idPaymentMethod: PaymentMethod.DIRECT_DEBIT.id,
|
|
240
246
|
closingDate: exerciceEndDate,
|
|
241
247
|
});
|
|
242
248
|
paymentDate = dayjs(paymentDate).add(1, 'month').startOf('month').toDate();
|
|
249
|
+
isApplicationAlreadyPaid = true;
|
|
243
250
|
}
|
|
244
251
|
|
|
245
252
|
return listPayments;
|
package/ts/utils/prestation.ts
CHANGED
|
@@ -19,6 +19,8 @@ type priceGridBrand = {
|
|
|
19
19
|
|
|
20
20
|
type priceGrid = {
|
|
21
21
|
idPrestationList: number[],
|
|
22
|
+
priceWithTaxesIncluded: boolean,
|
|
23
|
+
applicationCost: number,
|
|
22
24
|
monthlyNbr?: monthlyNbr[],
|
|
23
25
|
exerciceNbr?: exerciceNbr[],
|
|
24
26
|
turnoverCreatedYear?: turnover[],
|
|
@@ -136,7 +138,7 @@ const calculateScoringOfPrestation = (idPrestationType: PrestationType, prestati
|
|
|
136
138
|
return numberPoint;
|
|
137
139
|
};
|
|
138
140
|
|
|
139
|
-
const getPriceGrid = (idTypeBrand: number, idPrestationList: number): priceGrid | undefined => {
|
|
141
|
+
export const getPriceGrid = (idTypeBrand: number, idPrestationList: number): priceGrid | undefined => {
|
|
140
142
|
let currentBrandPriceGrid: priceGridBrand | undefined;
|
|
141
143
|
let currentPriceGrid: priceGrid | undefined;
|
|
142
144
|
|
|
@@ -10,6 +10,7 @@ describe('Payment', () => {
|
|
|
10
10
|
const idPrestation = 1;
|
|
11
11
|
const idSociety = 1;
|
|
12
12
|
const yearlyAmountNonExpress = 1800;
|
|
13
|
+
const nextYearlyAmountNonExpress = 1800;
|
|
13
14
|
const appCost = 14.9;
|
|
14
15
|
|
|
15
16
|
const firstExerciceNonExpresssEndDate = dayjs().add(11, 'month').endOf('month').toDate();
|
|
@@ -78,7 +79,8 @@ describe('Payment', () => {
|
|
|
78
79
|
try {
|
|
79
80
|
prestationList.hidden = true;
|
|
80
81
|
calculatePaymentsAuto({
|
|
81
|
-
|
|
82
|
+
idTypeBrand: 1,
|
|
83
|
+
goToClient: dayjs('2024-06-06').toDate(),
|
|
82
84
|
firstExerciceNonExpresssEndDate,
|
|
83
85
|
idPrestation,
|
|
84
86
|
prestationList: {
|
|
@@ -88,7 +90,8 @@ describe('Payment', () => {
|
|
|
88
90
|
idVat,
|
|
89
91
|
listPartialExercicePrestationExpress,
|
|
90
92
|
listRegulations,
|
|
91
|
-
yearlyAmountNonExpress
|
|
93
|
+
yearlyAmountNonExpress,
|
|
94
|
+
nextYearlyAmountNonExpress });
|
|
92
95
|
} catch (error) {
|
|
93
96
|
expect(error).toBeInstanceOf(Error);
|
|
94
97
|
// @ts-ignore
|
|
@@ -99,14 +102,16 @@ describe('Payment', () => {
|
|
|
99
102
|
expect.assertions(2);
|
|
100
103
|
try {
|
|
101
104
|
calculatePaymentsAuto({
|
|
102
|
-
|
|
105
|
+
idTypeBrand: 1,
|
|
106
|
+
goToClient: dayjs('2024-06-06').toDate(),
|
|
103
107
|
firstExerciceNonExpresssEndDate,
|
|
104
108
|
idPrestation,
|
|
105
109
|
prestationList,
|
|
106
110
|
idVat,
|
|
107
111
|
listPartialExercicePrestationExpress,
|
|
108
112
|
listRegulations: [],
|
|
109
|
-
yearlyAmountNonExpress
|
|
113
|
+
yearlyAmountNonExpress,
|
|
114
|
+
nextYearlyAmountNonExpress });
|
|
110
115
|
} catch (error) {
|
|
111
116
|
expect(error).toBeInstanceOf(Error);
|
|
112
117
|
// @ts-ignore
|
|
@@ -117,14 +122,16 @@ describe('Payment', () => {
|
|
|
117
122
|
expect.assertions(2);
|
|
118
123
|
try {
|
|
119
124
|
calculatePaymentsAuto({
|
|
120
|
-
|
|
125
|
+
idTypeBrand: 1,
|
|
126
|
+
goToClient: dayjs('2024-06-06').toDate(),
|
|
121
127
|
firstExerciceNonExpresssEndDate,
|
|
122
128
|
idPrestation,
|
|
123
129
|
prestationList,
|
|
124
130
|
idVat,
|
|
125
131
|
listPartialExercicePrestationExpress,
|
|
126
132
|
listRegulations: [{ processed: true } as IRegulation],
|
|
127
|
-
yearlyAmountNonExpress
|
|
133
|
+
yearlyAmountNonExpress,
|
|
134
|
+
nextYearlyAmountNonExpress });
|
|
128
135
|
} catch (error) {
|
|
129
136
|
expect(error).toBeInstanceOf(Error);
|
|
130
137
|
// @ts-ignore
|
|
@@ -138,14 +145,16 @@ describe('Payment', () => {
|
|
|
138
145
|
// express
|
|
139
146
|
test('if only one express, monthly payments of actual exo should be in parallel of express monthly payments, smoothed in number of remaining months (mini 3 months) (if not in 3 last month)', async () => {
|
|
140
147
|
const payments = calculatePaymentsAuto({
|
|
141
|
-
|
|
148
|
+
idTypeBrand: 1,
|
|
149
|
+
goToClient: dayjs('2024-06-06').toDate(),
|
|
142
150
|
firstExerciceNonExpresssEndDate,
|
|
143
151
|
idPrestation,
|
|
144
152
|
prestationList,
|
|
145
153
|
idVat,
|
|
146
154
|
listPartialExercicePrestationExpress: [listPartialExercicePrestationExpress[0]],
|
|
147
155
|
listRegulations,
|
|
148
|
-
yearlyAmountNonExpress
|
|
156
|
+
yearlyAmountNonExpress,
|
|
157
|
+
nextYearlyAmountNonExpress });
|
|
149
158
|
|
|
150
159
|
const firstExpressDatePayment = payments.filter(p => dayjs(p.closingDate).diff(firstExerciceNonExpresssEndDate) < 0)[0].datePayment;
|
|
151
160
|
const firstNonExpressDatePayment = payments.filter(p => dayjs(p.closingDate).diff(firstExerciceNonExpresssEndDate) === 0)[0].datePayment;
|
|
@@ -153,14 +162,16 @@ describe('Payment', () => {
|
|
|
153
162
|
});
|
|
154
163
|
test('if more than one express, monthly payments of actual exo should be in a row of express monthly payments and smoothed, smoothed in number of remaining months after express monthly payments (mini 3 months) (if in 3 last month of exercice)', async () => {
|
|
155
164
|
const payments = calculatePaymentsAuto({
|
|
156
|
-
|
|
165
|
+
idTypeBrand: 1,
|
|
166
|
+
goToClient: dayjs('2024-06-06').toDate(),
|
|
157
167
|
firstExerciceNonExpresssEndDate,
|
|
158
168
|
idPrestation,
|
|
159
169
|
prestationList,
|
|
160
170
|
idVat,
|
|
161
171
|
listPartialExercicePrestationExpress,
|
|
162
172
|
listRegulations,
|
|
163
|
-
yearlyAmountNonExpress
|
|
173
|
+
yearlyAmountNonExpress,
|
|
174
|
+
nextYearlyAmountNonExpress });
|
|
164
175
|
|
|
165
176
|
const lastExpressDatePayment = payments.filter(p => dayjs(p.closingDate).diff(firstExerciceNonExpresssEndDate) < 0).splice(-1)?.[0]?.datePayment;
|
|
166
177
|
const firstNonExpressDatePayment = payments.filter(p => dayjs(p.closingDate).diff(firstExerciceNonExpresssEndDate) === 0)?.[0]?.datePayment;
|
|
@@ -175,7 +186,8 @@ describe('Payment', () => {
|
|
|
175
186
|
const newFirstExerciceNonExpresssEndDate = dayjs().add(nbMonthDelay, 'month').endOf('month').toDate();
|
|
176
187
|
|
|
177
188
|
const payments = calculatePaymentsAuto({
|
|
178
|
-
|
|
189
|
+
idTypeBrand: 1,
|
|
190
|
+
goToClient: dayjs('2024-06-06').toDate(),
|
|
179
191
|
firstExerciceNonExpresssEndDate: newFirstExerciceNonExpresssEndDate,
|
|
180
192
|
idPrestation,
|
|
181
193
|
prestationList,
|
|
@@ -185,7 +197,8 @@ describe('Payment', () => {
|
|
|
185
197
|
amount: 50,
|
|
186
198
|
amountUsed: 0,
|
|
187
199
|
} as IRegulation],
|
|
188
|
-
yearlyAmountNonExpress
|
|
200
|
+
yearlyAmountNonExpress,
|
|
201
|
+
nextYearlyAmountNonExpress });
|
|
189
202
|
|
|
190
203
|
// const listNonExpressPayments = payments.filter(p => p.closingDate === newFirstExerciceNonExpresssEndDate);
|
|
191
204
|
const listNonExpressPayments = payments.filter(p => dayjs(p.closingDate).diff(newFirstExerciceNonExpresssEndDate) === 0);
|
|
@@ -198,7 +211,8 @@ describe('Payment', () => {
|
|
|
198
211
|
const newFirstExerciceNonExpresssEndDate = dayjs().add(nbMonthDelay, 'month').endOf('month').toDate();
|
|
199
212
|
|
|
200
213
|
const payments = calculatePaymentsAuto({
|
|
201
|
-
|
|
214
|
+
idTypeBrand: 1,
|
|
215
|
+
goToClient: dayjs('2024-06-06').toDate(),
|
|
202
216
|
firstExerciceNonExpresssEndDate: newFirstExerciceNonExpresssEndDate,
|
|
203
217
|
idPrestation,
|
|
204
218
|
prestationList,
|
|
@@ -208,7 +222,8 @@ describe('Payment', () => {
|
|
|
208
222
|
amount: 50,
|
|
209
223
|
amountUsed: 0,
|
|
210
224
|
} as IRegulation],
|
|
211
|
-
yearlyAmountNonExpress
|
|
225
|
+
yearlyAmountNonExpress,
|
|
226
|
+
nextYearlyAmountNonExpress });
|
|
212
227
|
|
|
213
228
|
const listNonExpressPayments = payments.filter(p => dayjs(p.closingDate).diff(newFirstExerciceNonExpresssEndDate) === 0);
|
|
214
229
|
expect(listNonExpressPayments.length).toStrictEqual(3);
|
|
@@ -224,14 +239,16 @@ describe('Payment', () => {
|
|
|
224
239
|
amountUsed: 0,
|
|
225
240
|
} as IRegulation];
|
|
226
241
|
const payments = calculatePaymentsAuto({
|
|
227
|
-
|
|
242
|
+
idTypeBrand: 1,
|
|
243
|
+
goToClient: dayjs('2024-06-06').toDate(),
|
|
228
244
|
firstExerciceNonExpresssEndDate: newFirstExerciceNonExpresssEndDate,
|
|
229
245
|
idPrestation,
|
|
230
246
|
prestationList,
|
|
231
247
|
idVat,
|
|
232
248
|
listPartialExercicePrestationExpress: [],
|
|
233
249
|
listRegulations: newListRegulations,
|
|
234
|
-
yearlyAmountNonExpress
|
|
250
|
+
yearlyAmountNonExpress,
|
|
251
|
+
nextYearlyAmountNonExpress });
|
|
235
252
|
|
|
236
253
|
const diff = yearlyAmountNonExpress - newListRegulations.reduce((acc, r:IRegulation) => acc + r.amount - r.amountUsed, 0);
|
|
237
254
|
const amount = Math.round(100 * diff / nbMonthDelay) / 100;
|
|
@@ -248,14 +265,16 @@ describe('Payment', () => {
|
|
|
248
265
|
amountUsed: 0,
|
|
249
266
|
} as IRegulation];
|
|
250
267
|
const payments = calculatePaymentsAuto({
|
|
251
|
-
|
|
268
|
+
idTypeBrand: 1,
|
|
269
|
+
goToClient: dayjs('2024-06-06').toDate(),
|
|
252
270
|
firstExerciceNonExpresssEndDate: newFirstExerciceNonExpresssEndDate,
|
|
253
271
|
idPrestation,
|
|
254
272
|
prestationList,
|
|
255
273
|
idVat,
|
|
256
274
|
listPartialExercicePrestationExpress: [],
|
|
257
275
|
listRegulations: newListRegulations,
|
|
258
|
-
yearlyAmountNonExpress
|
|
276
|
+
yearlyAmountNonExpress,
|
|
277
|
+
nextYearlyAmountNonExpress });
|
|
259
278
|
|
|
260
279
|
const diff = yearlyAmountNonExpress - newListRegulations.reduce((acc, r:IRegulation) => acc + r.amount - r.amountUsed, 0);
|
|
261
280
|
const amount = Math.round(100 * diff / 3) / 100;
|
|
@@ -270,7 +289,8 @@ describe('Payment', () => {
|
|
|
270
289
|
const newFirstExerciceNonExpresssEndDate = dayjs().add(11, 'month').endOf('month').toDate();
|
|
271
290
|
|
|
272
291
|
const payments = calculatePaymentsAuto({
|
|
273
|
-
|
|
292
|
+
idTypeBrand: 1,
|
|
293
|
+
goToClient: dayjs('2024-06-06').toDate(),
|
|
274
294
|
firstExerciceNonExpresssEndDate: newFirstExerciceNonExpresssEndDate,
|
|
275
295
|
idPrestation,
|
|
276
296
|
prestationList,
|
|
@@ -280,7 +300,8 @@ describe('Payment', () => {
|
|
|
280
300
|
amount: 50,
|
|
281
301
|
amountUsed: 0,
|
|
282
302
|
} as IRegulation],
|
|
283
|
-
yearlyAmountNonExpress
|
|
303
|
+
yearlyAmountNonExpress,
|
|
304
|
+
nextYearlyAmountNonExpress });
|
|
284
305
|
|
|
285
306
|
const listNonExpressPayments = payments.filter(p => dayjs(p.closingDate).diff(newFirstExerciceNonExpresssEndDate) === 0);
|
|
286
307
|
expect(Math.round(100 * listNonExpressPayments[0].amount * 1.0275) / 100).toStrictEqual(listNonExpressPayments.splice(-2)[0].amount);
|
|
@@ -294,7 +315,8 @@ describe('Payment', () => {
|
|
|
294
315
|
const newFirstExerciceNonExpresssEndDate = dayjs().add(11, 'month').endOf('month').toDate();
|
|
295
316
|
|
|
296
317
|
const payments = calculatePaymentsAuto({
|
|
297
|
-
|
|
318
|
+
idTypeBrand: 1,
|
|
319
|
+
goToClient: dayjs('2024-06-06').toDate(),
|
|
298
320
|
firstExerciceNonExpresssEndDate: newFirstExerciceNonExpresssEndDate,
|
|
299
321
|
idPrestation,
|
|
300
322
|
prestationList,
|
|
@@ -304,7 +326,8 @@ describe('Payment', () => {
|
|
|
304
326
|
amount: 50,
|
|
305
327
|
amountUsed: 0,
|
|
306
328
|
} as IRegulation],
|
|
307
|
-
yearlyAmountNonExpress
|
|
329
|
+
yearlyAmountNonExpress,
|
|
330
|
+
nextYearlyAmountNonExpress });
|
|
308
331
|
|
|
309
332
|
const listNonExpressPayments = payments.filter(p => dayjs(p.datePayment).diff(dayjs('2025-06-01')) === 0);
|
|
310
333
|
expect(listNonExpressPayments[0].amount).toStrictEqual(listNonExpressPayments.splice(-2)[0].amount);
|
|
@@ -319,7 +342,8 @@ describe('Payment', () => {
|
|
|
319
342
|
const newFirstExerciceNonExpresssEndDate = dayjs().add(12, 'month').endOf('month').toDate();
|
|
320
343
|
|
|
321
344
|
const payments = calculatePaymentsAuto({
|
|
322
|
-
|
|
345
|
+
idTypeBrand: 1,
|
|
346
|
+
goToClient: dayjs('2024-06-06').toDate(),
|
|
323
347
|
firstExerciceNonExpresssEndDate: newFirstExerciceNonExpresssEndDate,
|
|
324
348
|
idPrestation,
|
|
325
349
|
prestationList,
|
|
@@ -329,7 +353,8 @@ describe('Payment', () => {
|
|
|
329
353
|
amount: 50,
|
|
330
354
|
amountUsed: 50,
|
|
331
355
|
} as IRegulation],
|
|
332
|
-
yearlyAmountNonExpress
|
|
356
|
+
yearlyAmountNonExpress,
|
|
357
|
+
nextYearlyAmountNonExpress });
|
|
333
358
|
|
|
334
359
|
const paymentsOfFirstExo = payments.filter(p => dayjs(p.datePayment).diff(dayjs('2025-06-01')) === 0).splice(-1)[0].amount ?? 0;
|
|
335
360
|
const paymentsOfSecondExo = payments.filter(p => dayjs(p.datePayment).diff(dayjs('2025-07-01')) === 0).splice(-1)[0].amount ?? 0;
|
|
@@ -350,14 +375,16 @@ describe('Payment', () => {
|
|
|
350
375
|
startDate: dayjs().startOf('month').toDate(),
|
|
351
376
|
};
|
|
352
377
|
const payments = calculatePaymentsAuto({
|
|
353
|
-
|
|
378
|
+
idTypeBrand: 1,
|
|
379
|
+
goToClient: dayjs('2024-06-06').toDate(),
|
|
354
380
|
firstExerciceNonExpresssEndDate,
|
|
355
381
|
idPrestation,
|
|
356
382
|
prestationList,
|
|
357
383
|
idVat,
|
|
358
384
|
listPartialExercicePrestationExpress: listPartialExercicePrestationExpressCloned,
|
|
359
385
|
listRegulations,
|
|
360
|
-
yearlyAmountNonExpress
|
|
386
|
+
yearlyAmountNonExpress,
|
|
387
|
+
nextYearlyAmountNonExpress });
|
|
361
388
|
expect(payments.length).toBeGreaterThanOrEqual(4);
|
|
362
389
|
expect(dayjs(payments[payments.length - 1].datePayment).diff(dayjs(payments?.[0]?.datePayment), 'month')).toBeGreaterThan(0);
|
|
363
390
|
});
|
|
@@ -366,7 +393,8 @@ describe('Payment', () => {
|
|
|
366
393
|
MockDate.set(mockedDate);
|
|
367
394
|
|
|
368
395
|
const payments = calculatePaymentsAuto({
|
|
369
|
-
|
|
396
|
+
idTypeBrand: 1,
|
|
397
|
+
goToClient: dayjs('2024-06-06').toDate(),
|
|
370
398
|
firstExerciceNonExpresssEndDate,
|
|
371
399
|
idPrestation,
|
|
372
400
|
prestationList,
|
|
@@ -380,7 +408,8 @@ describe('Payment', () => {
|
|
|
380
408
|
idPaymentMethod: PaymentMethod.BANK_CARD.id,
|
|
381
409
|
idSociety,
|
|
382
410
|
}],
|
|
383
|
-
yearlyAmountNonExpress
|
|
411
|
+
yearlyAmountNonExpress,
|
|
412
|
+
nextYearlyAmountNonExpress });
|
|
384
413
|
expect(payments.length).toBeGreaterThanOrEqual(2);
|
|
385
414
|
expect(payments[0]).toMatchObject(
|
|
386
415
|
{
|
|
@@ -403,14 +432,16 @@ describe('Payment', () => {
|
|
|
403
432
|
MockDate.set(mockedDate);
|
|
404
433
|
|
|
405
434
|
const payments = calculatePaymentsAuto({
|
|
406
|
-
|
|
435
|
+
idTypeBrand: 1,
|
|
436
|
+
goToClient: dayjs('2024-06-06').toDate(),
|
|
407
437
|
firstExerciceNonExpresssEndDate,
|
|
408
438
|
idPrestation,
|
|
409
439
|
prestationList,
|
|
410
440
|
idVat,
|
|
411
441
|
listPartialExercicePrestationExpress,
|
|
412
442
|
listRegulations,
|
|
413
|
-
yearlyAmountNonExpress
|
|
443
|
+
yearlyAmountNonExpress,
|
|
444
|
+
nextYearlyAmountNonExpress });
|
|
414
445
|
expect(payments.length).toBeGreaterThanOrEqual(4);
|
|
415
446
|
expect(payments?.[0]?.datePayment).toStrictEqual(dayjs(mockedDate).add(2, 'month').startOf('month').toDate());
|
|
416
447
|
MockDate.reset();
|
|
@@ -420,32 +451,37 @@ describe('Payment', () => {
|
|
|
420
451
|
MockDate.set(mockedDate);
|
|
421
452
|
|
|
422
453
|
const payments = calculatePaymentsAuto({
|
|
423
|
-
|
|
454
|
+
idTypeBrand: 1,
|
|
455
|
+
goToClient: dayjs('2024-06-06').toDate(),
|
|
424
456
|
firstExerciceNonExpresssEndDate,
|
|
425
457
|
idPrestation,
|
|
426
458
|
prestationList,
|
|
427
459
|
idVat,
|
|
428
460
|
listPartialExercicePrestationExpress,
|
|
429
461
|
listRegulations,
|
|
430
|
-
yearlyAmountNonExpress
|
|
462
|
+
yearlyAmountNonExpress,
|
|
463
|
+
nextYearlyAmountNonExpress });
|
|
431
464
|
expect(payments.length).toBeGreaterThanOrEqual(4);
|
|
432
465
|
expect(dayjs(payments[payments.length - 1].datePayment).month()).toStrictEqual(11);
|
|
433
466
|
});
|
|
434
467
|
test('first payment and last payment should have at least one year difference (ex. : 23 - 24)', async () => {
|
|
435
468
|
const payments = calculatePaymentsAuto({
|
|
436
|
-
|
|
469
|
+
idTypeBrand: 1,
|
|
470
|
+
goToClient: dayjs('2024-06-06').toDate(),
|
|
437
471
|
firstExerciceNonExpresssEndDate,
|
|
438
472
|
idPrestation,
|
|
439
473
|
prestationList,
|
|
440
474
|
idVat,
|
|
441
475
|
listPartialExercicePrestationExpress: [],
|
|
442
476
|
listRegulations,
|
|
443
|
-
yearlyAmountNonExpress
|
|
477
|
+
yearlyAmountNonExpress,
|
|
478
|
+
nextYearlyAmountNonExpress });
|
|
444
479
|
expect(dayjs(payments.slice(-1)?.[0]?.datePayment).diff(dayjs(payments?.[0]?.datePayment), 'year', true)).toBeGreaterThan(1);
|
|
445
480
|
});
|
|
446
481
|
test('real case : idSociety 114440', async () => {
|
|
447
482
|
const payments = calculatePaymentsAuto({
|
|
448
|
-
|
|
483
|
+
idTypeBrand: 1,
|
|
484
|
+
goToClient: dayjs('2024-06-06').toDate(),
|
|
449
485
|
firstExerciceNonExpresssEndDate: dayjs('2024-12-31').toDate(),
|
|
450
486
|
idPrestation,
|
|
451
487
|
prestationList,
|
|
@@ -459,7 +495,7 @@ describe('Payment', () => {
|
|
|
459
495
|
idPaymentMethod: PaymentMethod.BANK_CARD.id,
|
|
460
496
|
idSociety,
|
|
461
497
|
}],
|
|
462
|
-
yearlyAmountNonExpress: 1433 });
|
|
498
|
+
yearlyAmountNonExpress: 1433, nextYearlyAmountNonExpress: 1433 });
|
|
463
499
|
expect(dayjs(payments.slice(-1)?.[0]?.datePayment).diff(dayjs(payments?.[0]?.datePayment), 'year', true)).toBeGreaterThan(1);
|
|
464
500
|
});
|
|
465
501
|
});
|