@zeniai/client-epic-state 5.1.91 → 5.1.92-beta0NB
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/lib/entity/accountRecon/accountReconReducer.js +4 -0
- package/lib/entity/accountRecon/accountReconState.d.ts +4 -1
- package/lib/entity/accountRecon/accountReconState.js +1 -0
- package/lib/entity/snackbar/snackbarApiError.d.ts +8 -0
- package/lib/entity/snackbar/snackbarApiError.js +15 -0
- package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
- package/lib/entity/snackbar/snackbarTypes.js +1 -0
- package/lib/epic.d.ts +4 -1
- package/lib/epic.js +4 -1
- package/lib/esm/entity/accountRecon/accountReconReducer.js +4 -0
- package/lib/esm/entity/accountRecon/accountReconState.js +1 -0
- package/lib/esm/entity/snackbar/snackbarApiError.js +11 -0
- package/lib/esm/entity/snackbar/snackbarTypes.js +1 -0
- package/lib/esm/epic.js +4 -1
- package/lib/esm/index.js +4 -4
- package/lib/esm/view/expenseAutomationView/epics/accountRecon/confirmStatementMappingEpic.js +43 -0
- package/lib/esm/view/expenseAutomationView/epics/accountRecon/parseCombinedStatementEpic.js +31 -0
- package/lib/esm/view/expenseAutomationView/epics/accountRecon/parseStatementEpic.js +15 -18
- package/lib/esm/view/expenseAutomationView/epics/accountRecon/updateCombinedStatementInfoEpic.js +68 -0
- package/lib/esm/view/expenseAutomationView/epics/accountRecon/updateStatementInfoEpic.js +10 -10
- package/lib/esm/view/expenseAutomationView/epics/accountRecon/uploadAccountStatementDocumentAIHelper.js +12 -4
- package/lib/esm/view/expenseAutomationView/epics/accountRecon/uploadAccountStatementEpic.js +8 -2
- package/lib/esm/view/expenseAutomationView/helpers/mapStatementUpdateLocalDataToRequestBody.js +20 -5
- package/lib/esm/view/expenseAutomationView/payload/reconciliationPayload.js +135 -0
- package/lib/esm/view/expenseAutomationView/reducers/reconciliationViewReducer.js +119 -16
- package/lib/esm/view/expenseAutomationView/selectors/reconciliationViewSelector.js +28 -7
- package/lib/esm/view/expenseAutomationView/selectors/statementParseViewSelector.js +43 -10
- package/lib/esm/view/expenseAutomationView/types/reconciliationViewState.js +15 -1
- package/lib/esm/view/invoicing/createCreditNote/createCreditNoteEpic.js +2 -0
- package/lib/esm/view/invoicing/createInvoice/createInvoiceEpic.js +2 -0
- package/lib/esm/view/invoicing/discountAction/discountActionEpic.js +6 -3
- package/lib/esm/view/invoicing/dunningAction/dunningActionEpic.js +6 -3
- package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewPayload.js +5 -4
- package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +3 -0
- package/lib/esm/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.js +2 -0
- package/lib/esm/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.js +2 -0
- package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +2 -0
- package/lib/esm/view/invoicing/invoiceAction/invoiceActionEpic.js +7 -3
- package/lib/esm/view/invoicing/invoicingQboView/epics/retryInvoicingQboSyncTaskEpic.js +2 -0
- package/lib/esm/view/invoicing/invoicingQboView/epics/startInvoicingQboBackfillEpic.js +2 -0
- package/lib/esm/view/invoicing/issueCreditNote/issueCreditNoteEpic.js +2 -0
- package/lib/esm/view/invoicing/recordPayment/recordPaymentEpic.js +3 -0
- package/lib/esm/view/invoicing/settingsView/settingsViewEpics.js +6 -3
- package/lib/esm/view/invoicing/settingsView/settingsViewSelector.js +52 -0
- package/lib/esm/view/invoicing/subscriptionAction/subscriptionActionEpic.js +6 -3
- package/lib/esm/view/vendorTabView/vendorTabViewReducer.js +1 -1
- package/lib/index.d.ts +7 -7
- package/lib/index.js +51 -46
- package/lib/view/expenseAutomationView/epics/accountRecon/confirmStatementMappingEpic.d.ts +34 -0
- package/lib/view/expenseAutomationView/epics/accountRecon/confirmStatementMappingEpic.js +47 -0
- package/lib/view/expenseAutomationView/epics/accountRecon/parseCombinedStatementEpic.d.ts +26 -0
- package/lib/view/expenseAutomationView/epics/accountRecon/parseCombinedStatementEpic.js +35 -0
- package/lib/view/expenseAutomationView/epics/accountRecon/parseStatementEpic.d.ts +21 -1
- package/lib/view/expenseAutomationView/epics/accountRecon/parseStatementEpic.js +15 -18
- package/lib/view/expenseAutomationView/epics/accountRecon/updateCombinedStatementInfoEpic.d.ts +27 -0
- package/lib/view/expenseAutomationView/epics/accountRecon/updateCombinedStatementInfoEpic.js +72 -0
- package/lib/view/expenseAutomationView/epics/accountRecon/updateStatementInfoEpic.js +10 -10
- package/lib/view/expenseAutomationView/epics/accountRecon/uploadAccountStatementDocumentAIHelper.d.ts +1 -1
- package/lib/view/expenseAutomationView/epics/accountRecon/uploadAccountStatementDocumentAIHelper.js +12 -4
- package/lib/view/expenseAutomationView/epics/accountRecon/uploadAccountStatementEpic.js +7 -1
- package/lib/view/expenseAutomationView/helpers/mapStatementUpdateLocalDataToRequestBody.d.ts +1 -0
- package/lib/view/expenseAutomationView/helpers/mapStatementUpdateLocalDataToRequestBody.js +20 -4
- package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
- package/lib/view/expenseAutomationView/payload/reconciliationPayload.d.ts +109 -4
- package/lib/view/expenseAutomationView/payload/reconciliationPayload.js +143 -0
- package/lib/view/expenseAutomationView/reducers/reconciliationViewReducer.d.ts +32 -4
- package/lib/view/expenseAutomationView/reducers/reconciliationViewReducer.js +121 -18
- package/lib/view/expenseAutomationView/selectorTypes/reconciliationViewSelectorTypes.d.ts +5 -1
- package/lib/view/expenseAutomationView/selectors/reconciliationViewSelector.d.ts +3 -1
- package/lib/view/expenseAutomationView/selectors/reconciliationViewSelector.js +29 -7
- package/lib/view/expenseAutomationView/selectors/statementParseViewSelector.d.ts +3 -2
- package/lib/view/expenseAutomationView/selectors/statementParseViewSelector.js +44 -10
- package/lib/view/expenseAutomationView/types/reconciliationViewState.d.ts +74 -1
- package/lib/view/expenseAutomationView/types/reconciliationViewState.js +19 -1
- package/lib/view/invoicing/createCreditNote/createCreditNoteEpic.js +2 -0
- package/lib/view/invoicing/createInvoice/createInvoiceEpic.js +2 -0
- package/lib/view/invoicing/discountAction/discountActionEpic.js +5 -2
- package/lib/view/invoicing/dunningAction/dunningActionEpic.js +5 -2
- package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewPayload.js +5 -4
- package/lib/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +3 -0
- package/lib/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.js +2 -0
- package/lib/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.js +2 -0
- package/lib/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +2 -0
- package/lib/view/invoicing/invoiceAction/invoiceActionEpic.js +6 -2
- package/lib/view/invoicing/invoicingQboView/epics/retryInvoicingQboSyncTaskEpic.js +2 -0
- package/lib/view/invoicing/invoicingQboView/epics/startInvoicingQboBackfillEpic.js +2 -0
- package/lib/view/invoicing/issueCreditNote/issueCreditNoteEpic.js +2 -0
- package/lib/view/invoicing/recordPayment/recordPaymentEpic.js +3 -0
- package/lib/view/invoicing/settingsView/settingsViewEpics.js +5 -2
- package/lib/view/invoicing/settingsView/settingsViewSelector.d.ts +41 -1
- package/lib/view/invoicing/settingsView/settingsViewSelector.js +55 -1
- package/lib/view/invoicing/subscriptionAction/subscriptionActionEpic.js +5 -2
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { convertToPeriod, } from '../../../commonStateTypes/timePeriod';
|
|
2
2
|
import { toTransactionsToReviewPayload, } from '../../../entity/accountRecon/accountReconPayload';
|
|
3
3
|
import { toMatchedTransactionPayload, } from '../../../entity/transaction/payloadTypes/reconciliationTransactionPayloads';
|
|
4
|
+
import { toStatementBalanceSourceStrict, } from '../types/reconciliationViewState';
|
|
4
5
|
export function createSaveReconciliationPayloadBasedOnActionAndMethod(state, selectedPeriod, localData, accountReconciliationEntity, action, method) {
|
|
5
6
|
const { balance, initialClearedBalance } = accountReconciliationEntity;
|
|
6
7
|
const { expenseAutomationReconciliationViewState: { selectedAccountId, reconTabsState: { reconcile: { localData: { selectedTransactionIds }, }, }, }, } = state;
|
|
@@ -67,10 +68,60 @@ function createReviewTransactionPayload(accountReconciliationEntity) {
|
|
|
67
68
|
});
|
|
68
69
|
return reviewTransactionsPayload;
|
|
69
70
|
}
|
|
71
|
+
export function isParseStatementCombinedResponsePayload(payload) {
|
|
72
|
+
return ('statement_uploads' in payload &&
|
|
73
|
+
Array.isArray(payload.statement_uploads) &&
|
|
74
|
+
payload.statement_uploads.length > 0 &&
|
|
75
|
+
// Batch group GET nests each upload under statement_upload — exclude that shape.
|
|
76
|
+
'statement_upload' in (payload.statement_uploads[0] ?? {}) === false);
|
|
77
|
+
}
|
|
78
|
+
export function isUpdateStatementInfoCombinedResponsePayload(payload) {
|
|
79
|
+
return ('statement_uploads' in payload &&
|
|
80
|
+
Array.isArray(payload.statement_uploads) &&
|
|
81
|
+
payload.statement_uploads.length > 0);
|
|
82
|
+
}
|
|
70
83
|
export function isStatementDateConflictResponse(response) {
|
|
71
84
|
return response.status.code === 409 && response.error_code != null;
|
|
72
85
|
}
|
|
86
|
+
function transformConfirmedCombinedStatementUploadsToState(statementUploads) {
|
|
87
|
+
return (statementUploads ?? []).map((statementUpload) => ({
|
|
88
|
+
accountId: statementUpload.account_id,
|
|
89
|
+
isCombinedStatementAnchor: statementUpload.is_combined_statement_anchor,
|
|
90
|
+
ledgerIdentifiers: statementUpload.ledger_identifiers ?? [],
|
|
91
|
+
statementUploadId: statementUpload.statement_upload_id,
|
|
92
|
+
}));
|
|
93
|
+
}
|
|
94
|
+
function transformCombinedStatementDetailsToState(details) {
|
|
95
|
+
if (details == null) {
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
combinedStatementGroupId: details.combined_statement_group_id,
|
|
100
|
+
isMappingConfirmed: details.is_mapping_confirmed,
|
|
101
|
+
accounts: (details.accounts ?? []).map((account) => ({
|
|
102
|
+
ledgerIdentifier: account.ledger_identifier,
|
|
103
|
+
accountName: account.account_name,
|
|
104
|
+
accountType: account.account_type,
|
|
105
|
+
maskedAccountNumber: account.masked_account_number,
|
|
106
|
+
openingBalance: account.opening_balance,
|
|
107
|
+
closingBalance: account.closing_balance,
|
|
108
|
+
transactionCount: account.transaction_count,
|
|
109
|
+
isUploadContext: account.is_upload_context,
|
|
110
|
+
existingStatementStatus: account.existing_statement_status ?? null,
|
|
111
|
+
suggestion: account.suggestion != null
|
|
112
|
+
? {
|
|
113
|
+
accountId: account.suggestion.account_id,
|
|
114
|
+
accountName: account.suggestion.account_name,
|
|
115
|
+
matchedBy: account.suggestion.matched_by,
|
|
116
|
+
matchConfidence: account.suggestion.match_confidence,
|
|
117
|
+
}
|
|
118
|
+
: null,
|
|
119
|
+
})),
|
|
120
|
+
statementUploads: transformConfirmedCombinedStatementUploadsToState(details.statement_uploads),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
73
123
|
function transformStatementUploadPayloadToState(statementUploadPayload) {
|
|
124
|
+
const balanceSource = toStatementBalanceSourceStrict(statementUploadPayload.statement_meta.balance_source);
|
|
74
125
|
return {
|
|
75
126
|
account: {
|
|
76
127
|
accountId: statementUploadPayload.account.account_id,
|
|
@@ -96,6 +147,13 @@ function transformStatementUploadPayloadToState(statementUploadPayload) {
|
|
|
96
147
|
statementUploadId: statementUploadPayload.statement_meta.statement_upload_id,
|
|
97
148
|
totalDeposits: statementUploadPayload.statement_meta.total_deposits,
|
|
98
149
|
totalPayments: statementUploadPayload.statement_meta.total_payments,
|
|
150
|
+
isCombinedStatement: statementUploadPayload.statement_meta.is_combined_statement ??
|
|
151
|
+
undefined,
|
|
152
|
+
isCombinedStatementAnchor: statementUploadPayload.statement_meta.is_combined_statement_anchor ??
|
|
153
|
+
undefined,
|
|
154
|
+
combinedStatementGroupId: statementUploadPayload.statement_meta.combined_statement_group_id ??
|
|
155
|
+
undefined,
|
|
156
|
+
...(balanceSource != null ? { balanceSource } : {}),
|
|
99
157
|
},
|
|
100
158
|
statementTransactions: (statementUploadPayload.statement_transactions ?? []).map((txn) => ({
|
|
101
159
|
amount: txn.amount,
|
|
@@ -117,6 +175,7 @@ function transformStatementUploadPayloadToState(statementUploadPayload) {
|
|
|
117
175
|
transactionMemo: txn.transaction_memo,
|
|
118
176
|
})),
|
|
119
177
|
aiSummary: transformAiSummaryPayloadToState(statementUploadPayload.ai_summary),
|
|
178
|
+
combinedStatementDetails: transformCombinedStatementDetailsToState(statementUploadPayload.combined_statement_details),
|
|
120
179
|
};
|
|
121
180
|
}
|
|
122
181
|
function transformPreviousReconciliationInfoToState(payload) {
|
|
@@ -177,11 +236,71 @@ export function transformStatementDateConflictToState(response) {
|
|
|
177
236
|
};
|
|
178
237
|
}
|
|
179
238
|
export function transformParseStatementPayloadToState(payload) {
|
|
239
|
+
if (isParseStatementCombinedResponsePayload(payload) === true) {
|
|
240
|
+
const statementUploads = payload.statement_uploads.map(transformStatementUploadPayloadToState);
|
|
241
|
+
const anchorUpload = statementUploads.find((upload) => upload.statementMeta.isCombinedStatementAnchor === true) ?? statementUploads[0];
|
|
242
|
+
return {
|
|
243
|
+
statementUpload: anchorUpload,
|
|
244
|
+
statementUploads,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
180
247
|
return {
|
|
181
248
|
statementUpload: transformStatementUploadPayloadToState(payload.statement_upload),
|
|
182
249
|
};
|
|
183
250
|
}
|
|
251
|
+
export function transformCombinedStatementGroupPayloadToState(payload) {
|
|
252
|
+
const groupId = payload.combined_statement_group_id;
|
|
253
|
+
const statementUploads = (payload.statement_uploads ?? []).map((entry) => {
|
|
254
|
+
const upload = transformStatementUploadPayloadToState(entry.statement_upload);
|
|
255
|
+
if ((upload.statementMeta.combinedStatementGroupId == null ||
|
|
256
|
+
upload.statementMeta.combinedStatementGroupId === '') &&
|
|
257
|
+
groupId !== '') {
|
|
258
|
+
return {
|
|
259
|
+
...upload,
|
|
260
|
+
statementMeta: {
|
|
261
|
+
...upload.statementMeta,
|
|
262
|
+
combinedStatementGroupId: groupId,
|
|
263
|
+
},
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
return upload;
|
|
267
|
+
});
|
|
268
|
+
if (statementUploads.length === 0) {
|
|
269
|
+
throw new Error('Combined statement response has no statement uploads');
|
|
270
|
+
}
|
|
271
|
+
const anchorUpload = statementUploads.find((upload) => upload.statementMeta.isCombinedStatementAnchor === true) ?? statementUploads[0];
|
|
272
|
+
return {
|
|
273
|
+
statementUpload: anchorUpload,
|
|
274
|
+
statementUploads,
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
export function isConfirmStatementMappingConflictResponse(response) {
|
|
278
|
+
return response.status.code === 409;
|
|
279
|
+
}
|
|
280
|
+
export function transformConfirmStatementMappingPayloadToState(payload) {
|
|
281
|
+
return transformConfirmedCombinedStatementUploadsToState(payload.statement_uploads);
|
|
282
|
+
}
|
|
283
|
+
export function transformConfirmStatementMappingConflictToState(response) {
|
|
284
|
+
if (isConfirmStatementMappingConflictResponse(response) === false) {
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
return {
|
|
288
|
+
collidingAccountId: response.colliding_account_id != null
|
|
289
|
+
? response.colliding_account_id
|
|
290
|
+
: undefined,
|
|
291
|
+
collidingLedgerIdentifiers: response.colliding_ledger_identifiers ?? [],
|
|
292
|
+
previousReconciliationInfo: transformPreviousReconciliationInfoToState(response.previous_reconciliation_info),
|
|
293
|
+
};
|
|
294
|
+
}
|
|
184
295
|
export function transformUpdateStatementInfoPayloadToState(payload) {
|
|
296
|
+
if (isUpdateStatementInfoCombinedResponsePayload(payload) === true) {
|
|
297
|
+
const statementUploads = payload.statement_uploads.map(transformStatementUploadPayloadToState);
|
|
298
|
+
const anchorUpload = statementUploads.find((upload) => upload.statementMeta.isCombinedStatementAnchor === true) ?? statementUploads[0];
|
|
299
|
+
return {
|
|
300
|
+
statementUpload: anchorUpload,
|
|
301
|
+
statementUploads,
|
|
302
|
+
};
|
|
303
|
+
}
|
|
185
304
|
return {
|
|
186
305
|
statementUpload: transformStatementUploadPayloadToState(payload.statement_upload),
|
|
187
306
|
};
|
|
@@ -221,3 +340,19 @@ export function transformStatementUpdateStateToPayload(localData) {
|
|
|
221
340
|
export function toStatementUpdateRequestBody(localData) {
|
|
222
341
|
return transformStatementUpdateStateToPayload(localData);
|
|
223
342
|
}
|
|
343
|
+
export function transformBulkStatementUpdateStateToPayload(updates) {
|
|
344
|
+
return {
|
|
345
|
+
statement_uploads: updates.map(({ localData, statementUploadId }) => {
|
|
346
|
+
const body = transformStatementUpdateStateToPayload(localData);
|
|
347
|
+
return {
|
|
348
|
+
statement_upload_id: statementUploadId,
|
|
349
|
+
statement_meta: body.statement_meta,
|
|
350
|
+
statement_transactions: body.statement_transactions,
|
|
351
|
+
};
|
|
352
|
+
}),
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
/** Bulk PUT body for combined multi-account Confirm & Save. */
|
|
356
|
+
export function toBulkStatementUpdateRequestBody(updates) {
|
|
357
|
+
return transformBulkStatementUpdateStateToPayload(updates);
|
|
358
|
+
}
|
|
@@ -430,7 +430,7 @@ const expenseAutomationReconciliationView = createSlice({
|
|
|
430
430
|
}
|
|
431
431
|
},
|
|
432
432
|
uploadAccountStatement: (draft, action) => {
|
|
433
|
-
const { accountId, selectedPeriod } = action.payload;
|
|
433
|
+
const { accountId, selectedPeriod, statementAccountScope } = action.payload;
|
|
434
434
|
const accountRecon = draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(selectedPeriod)]?.reconciliationByAccountID[accountId];
|
|
435
435
|
if (accountRecon != null) {
|
|
436
436
|
accountRecon.statementUploadStatus = {
|
|
@@ -455,6 +455,22 @@ const expenseAutomationReconciliationView = createSlice({
|
|
|
455
455
|
fetchState: 'Not-Started',
|
|
456
456
|
error: undefined,
|
|
457
457
|
};
|
|
458
|
+
accountRecon.combinedStatementGroupId = undefined;
|
|
459
|
+
accountRecon.confirmedCombinedStatementUploads = undefined;
|
|
460
|
+
accountRecon.confirmStatementMappingStatus = {
|
|
461
|
+
fetchState: 'Not-Started',
|
|
462
|
+
error: undefined,
|
|
463
|
+
};
|
|
464
|
+
accountRecon.confirmStatementMappingConflict = null;
|
|
465
|
+
if (accountRecon.localData != null) {
|
|
466
|
+
accountRecon.localData.statementUpdateLocalDataByUploadId = undefined;
|
|
467
|
+
}
|
|
468
|
+
if (statementAccountScope != null) {
|
|
469
|
+
accountRecon.localData = {
|
|
470
|
+
...accountRecon.localData,
|
|
471
|
+
statementAccountScope,
|
|
472
|
+
};
|
|
473
|
+
}
|
|
458
474
|
}
|
|
459
475
|
},
|
|
460
476
|
uploadAccountStatementSuccess: (draft, action) => {
|
|
@@ -517,8 +533,15 @@ const expenseAutomationReconciliationView = createSlice({
|
|
|
517
533
|
fetchState: 'Not-Started',
|
|
518
534
|
error: undefined,
|
|
519
535
|
};
|
|
536
|
+
accountRecon.combinedStatementGroupId = undefined;
|
|
537
|
+
accountRecon.confirmedCombinedStatementUploads = undefined;
|
|
538
|
+
accountRecon.confirmStatementMappingStatus = {
|
|
539
|
+
fetchState: 'Not-Started',
|
|
540
|
+
error: undefined,
|
|
541
|
+
};
|
|
542
|
+
accountRecon.confirmStatementMappingConflict = null;
|
|
520
543
|
if (accountRecon.localData != null) {
|
|
521
|
-
accountRecon.localData.
|
|
544
|
+
accountRecon.localData.statementUpdateLocalDataByUploadId = undefined;
|
|
522
545
|
}
|
|
523
546
|
}
|
|
524
547
|
},
|
|
@@ -544,6 +567,17 @@ const expenseAutomationReconciliationView = createSlice({
|
|
|
544
567
|
};
|
|
545
568
|
}
|
|
546
569
|
},
|
|
570
|
+
parseCombinedStatement: (draft, action) => {
|
|
571
|
+
const { accountId, selectedPeriod } = action.payload;
|
|
572
|
+
const accountRecon = draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(selectedPeriod)]?.reconciliationByAccountID[accountId];
|
|
573
|
+
if (accountRecon != null) {
|
|
574
|
+
accountRecon.parsedStatementData = undefined;
|
|
575
|
+
accountRecon.statementParseStatus = {
|
|
576
|
+
fetchState: 'In-Progress',
|
|
577
|
+
error: undefined,
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
},
|
|
547
581
|
parseStatementSuccess: (draft, action) => {
|
|
548
582
|
const { accountId, selectedPeriod } = action.payload;
|
|
549
583
|
const accountRecon = draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(selectedPeriod)]?.reconciliationByAccountID[accountId];
|
|
@@ -598,7 +632,7 @@ const expenseAutomationReconciliationView = createSlice({
|
|
|
598
632
|
accountRecon.statementProcessingFailed = false;
|
|
599
633
|
accountRecon.statementParseInProgress = true;
|
|
600
634
|
if (accountRecon.localData != null) {
|
|
601
|
-
accountRecon.localData.
|
|
635
|
+
accountRecon.localData.statementUpdateLocalDataByUploadId = undefined;
|
|
602
636
|
}
|
|
603
637
|
}
|
|
604
638
|
},
|
|
@@ -644,19 +678,18 @@ const expenseAutomationReconciliationView = createSlice({
|
|
|
644
678
|
parsedStatementData;
|
|
645
679
|
},
|
|
646
680
|
updateStatementUpdateLocalData: (draft, action) => {
|
|
647
|
-
const { accountId, selectedPeriod, statementUpdateLocalData } = action.payload;
|
|
681
|
+
const { accountId, selectedPeriod, statementUpdateLocalData, statementUploadId, } = action.payload;
|
|
648
682
|
const accountRecon = draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(selectedPeriod)]?.reconciliationByAccountID[accountId];
|
|
649
|
-
if (accountRecon
|
|
650
|
-
|
|
651
|
-
accountRecon.localData = {
|
|
652
|
-
statementUpdateLocalData,
|
|
653
|
-
};
|
|
654
|
-
}
|
|
655
|
-
else {
|
|
656
|
-
accountRecon.localData.statementUpdateLocalData =
|
|
657
|
-
statementUpdateLocalData;
|
|
658
|
-
}
|
|
683
|
+
if (accountRecon == null || statementUploadId === '') {
|
|
684
|
+
return;
|
|
659
685
|
}
|
|
686
|
+
if (accountRecon.localData == null) {
|
|
687
|
+
accountRecon.localData = {};
|
|
688
|
+
}
|
|
689
|
+
accountRecon.localData.statementUpdateLocalDataByUploadId = {
|
|
690
|
+
...accountRecon.localData.statementUpdateLocalDataByUploadId,
|
|
691
|
+
[statementUploadId]: statementUpdateLocalData,
|
|
692
|
+
};
|
|
660
693
|
},
|
|
661
694
|
submitStatementUpdate: (draft, action) => {
|
|
662
695
|
const { accountId, selectedPeriod } = action.payload;
|
|
@@ -670,6 +703,17 @@ const expenseAutomationReconciliationView = createSlice({
|
|
|
670
703
|
accountRecon.statementDateConflict = null;
|
|
671
704
|
}
|
|
672
705
|
},
|
|
706
|
+
submitCombinedStatementUpdate: (draft, action) => {
|
|
707
|
+
const { accountId, selectedPeriod } = action.payload;
|
|
708
|
+
const accountRecon = draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(selectedPeriod)]?.reconciliationByAccountID[accountId];
|
|
709
|
+
if (accountRecon != null) {
|
|
710
|
+
accountRecon.statementUpdateStatus = {
|
|
711
|
+
fetchState: 'In-Progress',
|
|
712
|
+
error: undefined,
|
|
713
|
+
};
|
|
714
|
+
accountRecon.statementDateConflict = null;
|
|
715
|
+
}
|
|
716
|
+
},
|
|
673
717
|
submitStatementUpdateSuccess: (draft, action) => {
|
|
674
718
|
const { accountId, selectedPeriod } = action.payload;
|
|
675
719
|
const accountRecon = draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(selectedPeriod)]?.reconciliationByAccountID[accountId];
|
|
@@ -684,7 +728,7 @@ const expenseAutomationReconciliationView = createSlice({
|
|
|
684
728
|
accountRecon.statementProcessingStartedAtMs = undefined;
|
|
685
729
|
accountRecon.statementProcessingTotalDurationSeconds = undefined;
|
|
686
730
|
if (accountRecon.localData != null) {
|
|
687
|
-
accountRecon.localData.
|
|
731
|
+
accountRecon.localData.statementUpdateLocalDataByUploadId = undefined;
|
|
688
732
|
}
|
|
689
733
|
}
|
|
690
734
|
},
|
|
@@ -706,6 +750,52 @@ const expenseAutomationReconciliationView = createSlice({
|
|
|
706
750
|
accountRecon.statementDateConflict = null;
|
|
707
751
|
}
|
|
708
752
|
},
|
|
753
|
+
confirmStatementMapping: (draft, action) => {
|
|
754
|
+
const { accountId, selectedPeriod } = action.payload;
|
|
755
|
+
const accountRecon = draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(selectedPeriod)]?.reconciliationByAccountID[accountId];
|
|
756
|
+
if (accountRecon != null) {
|
|
757
|
+
accountRecon.confirmStatementMappingStatus = {
|
|
758
|
+
fetchState: 'In-Progress',
|
|
759
|
+
error: undefined,
|
|
760
|
+
};
|
|
761
|
+
accountRecon.confirmStatementMappingConflict = null;
|
|
762
|
+
}
|
|
763
|
+
},
|
|
764
|
+
confirmStatementMappingSuccess: (draft, action) => {
|
|
765
|
+
const { accountId, selectedPeriod, statementUploads } = action.payload;
|
|
766
|
+
const accountRecon = draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(selectedPeriod)]?.reconciliationByAccountID[accountId];
|
|
767
|
+
if (accountRecon != null) {
|
|
768
|
+
accountRecon.confirmStatementMappingStatus = {
|
|
769
|
+
fetchState: 'Completed',
|
|
770
|
+
error: undefined,
|
|
771
|
+
};
|
|
772
|
+
accountRecon.confirmStatementMappingConflict = null;
|
|
773
|
+
accountRecon.confirmedCombinedStatementUploads = statementUploads;
|
|
774
|
+
const combinedStatementDetails = accountRecon.parsedStatementData?.statementUpload
|
|
775
|
+
.combinedStatementDetails;
|
|
776
|
+
if (combinedStatementDetails != null) {
|
|
777
|
+
combinedStatementDetails.isMappingConfirmed = true;
|
|
778
|
+
}
|
|
779
|
+
const combinedStatementGroupId = combinedStatementDetails?.combinedStatementGroupId ??
|
|
780
|
+
accountRecon.parsedStatementData?.statementUpload.statementMeta
|
|
781
|
+
.combinedStatementGroupId;
|
|
782
|
+
if (combinedStatementGroupId != null &&
|
|
783
|
+
combinedStatementGroupId !== '') {
|
|
784
|
+
accountRecon.combinedStatementGroupId = combinedStatementGroupId;
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
},
|
|
788
|
+
confirmStatementMappingFailure: (draft, action) => {
|
|
789
|
+
const { accountId, selectedPeriod, mappingConflict } = action.payload;
|
|
790
|
+
const accountRecon = draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(selectedPeriod)]?.reconciliationByAccountID[accountId];
|
|
791
|
+
if (accountRecon != null) {
|
|
792
|
+
accountRecon.confirmStatementMappingStatus = {
|
|
793
|
+
fetchState: 'Error',
|
|
794
|
+
error: action.payload.error,
|
|
795
|
+
};
|
|
796
|
+
accountRecon.confirmStatementMappingConflict = mappingConflict ?? null;
|
|
797
|
+
}
|
|
798
|
+
},
|
|
709
799
|
updateAccountReconciliationLocalData: (draft, action) => {
|
|
710
800
|
const { accountId, selectedPeriod, localData } = action.payload;
|
|
711
801
|
const oldLocalData = draft.accountReconciliationRecordsBySelectedPeriod[toMonthYearPeriodId(selectedPeriod)].reconciliationByAccountID[accountId].localData;
|
|
@@ -816,7 +906,7 @@ const expenseAutomationReconciliationView = createSlice({
|
|
|
816
906
|
},
|
|
817
907
|
});
|
|
818
908
|
// Export actions
|
|
819
|
-
export const { fetchReconciliation, fetchReconciliationFailure, fetchReconciliationSuccess, saveReconciliationDetail, saveReconciliationDetailFailure, updateSelectedAccountId, setConnectionInProgressForAccount, setStatementParseInProgress, setStatementProcessingDismissedToBackground, updateStatementProcessingBackgroundCompletedSteps, updateReconcileTabLocalData, updateReconcileTabListSortState, updateReconcileTabListScrollState, saveReconciliationDetailSuccess, updateSelectedTab, updateBalancesLocalData, initialiseLocalDataForSelectedAccountId, clearExpenseAutomationReconciliationView, updateSelectedDrawerAccountId, updateStatementProcessingFailed, updateReviewTabSortState, initializeReconciliationReviewTabLocalData, updateReviewTabLocalData, saveReconciliationReview, updateSaveReconciliationReviewFetchStatus, updateReconListScrollPosition, updateAccountReconciliationLocalData, deleteAccountStatement, deleteAccountStatementSuccess, deleteAccountStatementFailure, excludeAccountFromReconciliation, excludeAccountFromReconciliationSuccess, excludeAccountFromReconciliationFailure, includeAccountInReconciliation, includeAccountInReconciliationSuccess, includeAccountInReconciliationFailure, uploadAccountStatement, uploadAccountStatementSuccess, uploadAccountStatementFailure, parseStatement, parseStatementSuccess, parseStatementFailure, reparseStatement, reparseStatementSuccess, reparseStatementFailure, resetReparseStatementStatus, updateParsedStatementData, updateStatementUpdateLocalData, submitStatementUpdate, submitStatementUpdateSuccess, submitStatementUpdateFailure, clearStatementDateConflict, updateStatementUploadChosen, updateNodeCollapseState, } = expenseAutomationReconciliationView.actions;
|
|
909
|
+
export const { fetchReconciliation, fetchReconciliationFailure, fetchReconciliationSuccess, saveReconciliationDetail, saveReconciliationDetailFailure, updateSelectedAccountId, setConnectionInProgressForAccount, setStatementParseInProgress, setStatementProcessingDismissedToBackground, updateStatementProcessingBackgroundCompletedSteps, updateReconcileTabLocalData, updateReconcileTabListSortState, updateReconcileTabListScrollState, saveReconciliationDetailSuccess, updateSelectedTab, updateBalancesLocalData, initialiseLocalDataForSelectedAccountId, clearExpenseAutomationReconciliationView, updateSelectedDrawerAccountId, updateStatementProcessingFailed, updateReviewTabSortState, initializeReconciliationReviewTabLocalData, updateReviewTabLocalData, saveReconciliationReview, updateSaveReconciliationReviewFetchStatus, updateReconListScrollPosition, updateAccountReconciliationLocalData, deleteAccountStatement, deleteAccountStatementSuccess, deleteAccountStatementFailure, excludeAccountFromReconciliation, excludeAccountFromReconciliationSuccess, excludeAccountFromReconciliationFailure, includeAccountInReconciliation, includeAccountInReconciliationSuccess, includeAccountInReconciliationFailure, uploadAccountStatement, uploadAccountStatementSuccess, uploadAccountStatementFailure, parseStatement, parseCombinedStatement, parseStatementSuccess, parseStatementFailure, reparseStatement, reparseStatementSuccess, reparseStatementFailure, resetReparseStatementStatus, updateParsedStatementData, updateStatementUpdateLocalData, submitStatementUpdate, submitCombinedStatementUpdate, submitStatementUpdateSuccess, submitStatementUpdateFailure, clearStatementDateConflict, confirmStatementMapping, confirmStatementMappingSuccess, confirmStatementMappingFailure, updateStatementUploadChosen, updateNodeCollapseState, } = expenseAutomationReconciliationView.actions;
|
|
820
910
|
// Export reducer
|
|
821
911
|
export default expenseAutomationReconciliationView.reducer;
|
|
822
912
|
function isEntityStatementParsing(reconciliation) {
|
|
@@ -830,6 +920,7 @@ function isEntityStatementParseTerminal(reconciliation) {
|
|
|
830
920
|
statusCode === 'parsing_failed' ||
|
|
831
921
|
statusCode === 'validation_failed' ||
|
|
832
922
|
statusCode === 'processing_failed' ||
|
|
923
|
+
statusCode === 'parsed_awaiting_mapping' ||
|
|
833
924
|
statusCode === 'deleting' ||
|
|
834
925
|
statusCode === 'deleted');
|
|
835
926
|
}
|
|
@@ -965,6 +1056,13 @@ function updateAllReconciliation(draft, accounts, selectedPeriod, reconciliation
|
|
|
965
1056
|
error: undefined,
|
|
966
1057
|
},
|
|
967
1058
|
statementDateConflict: oldRecord?.statementDateConflict ?? null,
|
|
1059
|
+
confirmStatementMappingStatus: oldRecord?.confirmStatementMappingStatus ?? {
|
|
1060
|
+
fetchState: 'Not-Started',
|
|
1061
|
+
error: undefined,
|
|
1062
|
+
},
|
|
1063
|
+
confirmStatementMappingConflict: oldRecord?.confirmStatementMappingConflict ?? null,
|
|
1064
|
+
confirmedCombinedStatementUploads: oldRecord?.confirmedCombinedStatementUploads,
|
|
1065
|
+
combinedStatementGroupId: oldRecord?.combinedStatementGroupId,
|
|
968
1066
|
localData: {
|
|
969
1067
|
...oldRecord?.localData,
|
|
970
1068
|
accountSource: account?.reconciliation_source != null
|
|
@@ -1063,6 +1161,11 @@ const updateReconciliationByAccountIDOnIncludeAccount = (draft, accountId, recon
|
|
|
1063
1161
|
statementParseStatus: { fetchState: 'Not-Started', error: undefined },
|
|
1064
1162
|
reparseStatementStatus: { fetchState: 'Not-Started', error: undefined },
|
|
1065
1163
|
statementDateConflict: null,
|
|
1164
|
+
confirmStatementMappingStatus: {
|
|
1165
|
+
fetchState: 'Not-Started',
|
|
1166
|
+
error: undefined,
|
|
1167
|
+
},
|
|
1168
|
+
confirmStatementMappingConflict: null,
|
|
1066
1169
|
localData: {},
|
|
1067
1170
|
accountDetectionReason: undefined,
|
|
1068
1171
|
};
|
|
@@ -245,8 +245,23 @@ export const getExpenseAutomationReconciliationView = createSelector((state) =>
|
|
|
245
245
|
}
|
|
246
246
|
const accountReconState = accountReconForMonthYearPeriod.reconciliationByAccountID[accountID];
|
|
247
247
|
const rawParsedStatementData = accountReconState.parsedStatementData;
|
|
248
|
-
const
|
|
249
|
-
const
|
|
248
|
+
const statementUpdateLocalDataByUploadId = accountReconState.localData?.statementUpdateLocalDataByUploadId;
|
|
249
|
+
const statementAccountScope = accountReconState.localData?.statementAccountScope;
|
|
250
|
+
const parsedStatementDataForView = getParsedStatementDataForView(rawParsedStatementData, statementUpdateLocalDataByUploadId, statementAccountScope);
|
|
251
|
+
const rawStatementUploads = rawParsedStatementData?.statementUploads != null &&
|
|
252
|
+
rawParsedStatementData.statementUploads.length > 0
|
|
253
|
+
? rawParsedStatementData.statementUploads
|
|
254
|
+
: rawParsedStatementData?.statementUpload != null
|
|
255
|
+
? [rawParsedStatementData.statementUpload]
|
|
256
|
+
: [];
|
|
257
|
+
const allCitationTransactions = rawStatementUploads.flatMap((statementUpload) => statementUpload.statementTransactions);
|
|
258
|
+
const statementTransactionPeriodById = rawStatementUploads.length > 0
|
|
259
|
+
? Object.assign({}, ...rawStatementUploads.map((statementUpload) => {
|
|
260
|
+
const uploadId = statementUpload.statementMeta.statementUploadId;
|
|
261
|
+
const localMeta = statementUpdateLocalDataByUploadId?.[uploadId]?.statementMeta;
|
|
262
|
+
return getStatementTransactionPeriodById(statementUpload.statementTransactions, statementUpload.statementMeta, localMeta);
|
|
263
|
+
}))
|
|
264
|
+
: undefined;
|
|
250
265
|
reconList[accountID] = {
|
|
251
266
|
accountConnectionStatus: accountConnectionStatus.status,
|
|
252
267
|
paymentAccountId: accountConnectionStatus.paymentAccountId,
|
|
@@ -257,6 +272,10 @@ export const getExpenseAutomationReconciliationView = createSelector((state) =>
|
|
|
257
272
|
statementParseStatus: accountReconState.statementParseStatus,
|
|
258
273
|
reparseStatementStatus: accountReconState.reparseStatementStatus,
|
|
259
274
|
statementDateConflict: accountReconState.statementDateConflict,
|
|
275
|
+
confirmStatementMappingStatus: accountReconState.confirmStatementMappingStatus,
|
|
276
|
+
confirmStatementMappingConflict: accountReconState.confirmStatementMappingConflict,
|
|
277
|
+
confirmedCombinedStatementUploads: accountReconState.confirmedCombinedStatementUploads,
|
|
278
|
+
combinedStatementGroupId: accountReconState.combinedStatementGroupId,
|
|
260
279
|
statementUpdateStatus: accountReconState.statementUpdateStatus,
|
|
261
280
|
statementUploadStatus: accountReconState.statementUploadStatus,
|
|
262
281
|
localData: accountReconState.localData,
|
|
@@ -267,11 +286,8 @@ export const getExpenseAutomationReconciliationView = createSelector((state) =>
|
|
|
267
286
|
statementProcessingTotalDurationSeconds: accountReconState.statementProcessingTotalDurationSeconds,
|
|
268
287
|
statementProcessingFailed: accountReconState.statementProcessingFailed,
|
|
269
288
|
parsedStatementData: parsedStatementDataForView,
|
|
270
|
-
allCitationTransactions
|
|
271
|
-
statementTransactionPeriodById
|
|
272
|
-
? getStatementTransactionPeriodById(rawParsedStatementData.statementUpload.statementTransactions, rawParsedStatementData.statementUpload.statementMeta, accountReconState.localData?.statementUpdateLocalData
|
|
273
|
-
?.statementMeta)
|
|
274
|
-
: undefined,
|
|
289
|
+
allCitationTransactions,
|
|
290
|
+
statementTransactionPeriodById,
|
|
275
291
|
transactionFetchState: reduceAnyFetchState([
|
|
276
292
|
accountReconState.transactionFetchState,
|
|
277
293
|
accountListState.byReportId.accountList,
|
|
@@ -341,6 +357,8 @@ export const getExpenseAutomationReconciliationView = createSelector((state) =>
|
|
|
341
357
|
statementParseStatus: { fetchState: 'Not-Started' },
|
|
342
358
|
reparseStatementStatus: { fetchState: 'Not-Started' },
|
|
343
359
|
statementDateConflict: null,
|
|
360
|
+
confirmStatementMappingStatus: { fetchState: 'Not-Started' },
|
|
361
|
+
confirmStatementMappingConflict: null,
|
|
344
362
|
localData: {},
|
|
345
363
|
connectionInProgress: false,
|
|
346
364
|
statementParseInProgress: false,
|
|
@@ -457,6 +475,9 @@ export const getExpenseAutomationReconciliationView = createSelector((state) =>
|
|
|
457
475
|
});
|
|
458
476
|
export const getReparseStatementStatusByAccountId = (state, accountId) => getExpenseAutomationReconciliationView(state)
|
|
459
477
|
.accountReconciliationsByAccountID[accountId]?.reparseStatementStatus;
|
|
478
|
+
export function getLedgerAccountsForCombinedStatementMapping(accountReconciliationsByAccountID) {
|
|
479
|
+
return Object.values(accountReconciliationsByAccountID).map((accountReconciliation) => accountReconciliation.accountReconEntity.account);
|
|
480
|
+
}
|
|
460
481
|
export const isAccountReconReport = (reportId) => {
|
|
461
482
|
return reportId.endsWith('reconciliation');
|
|
462
483
|
};
|
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
import { date } from '../../../zeniDayJS';
|
|
2
|
+
export function getStatementUploadsFromParsedData(parsedStatementData) {
|
|
3
|
+
if (parsedStatementData == null) {
|
|
4
|
+
return [];
|
|
5
|
+
}
|
|
6
|
+
if (parsedStatementData.statementUploads != null &&
|
|
7
|
+
parsedStatementData.statementUploads.length > 0) {
|
|
8
|
+
return parsedStatementData.statementUploads;
|
|
9
|
+
}
|
|
10
|
+
if (parsedStatementData.statementUpload != null) {
|
|
11
|
+
return [parsedStatementData.statementUpload];
|
|
12
|
+
}
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
2
15
|
export const getEffectiveStatementPeriod = (parsedMeta, localMeta) => ({
|
|
3
16
|
statementStartDate: localMeta?.statementStartDate != null && localMeta.statementStartDate !== ''
|
|
4
17
|
? localMeta.statementStartDate
|
|
@@ -25,24 +38,44 @@ export const filterStatementTransactionsByPeriod = (transactions, statementPerio
|
|
|
25
38
|
}
|
|
26
39
|
return transactions.filter((transaction) => isStatementTransactionInPeriod(transaction.transactionDate, statementStartDate, statementEndDate));
|
|
27
40
|
};
|
|
28
|
-
|
|
41
|
+
const getStatementUploadForView = (statementUpload, statementUpdateLocalData) => {
|
|
42
|
+
const parsedMeta = statementUpload.statementMeta;
|
|
43
|
+
const localMeta = statementUpdateLocalData?.statementMeta;
|
|
44
|
+
const effectiveMeta = localMeta ?? parsedMeta;
|
|
45
|
+
const statementPeriod = getEffectiveStatementPeriod(parsedMeta, localMeta);
|
|
46
|
+
return {
|
|
47
|
+
...statementUpload,
|
|
48
|
+
statementMeta: effectiveMeta,
|
|
49
|
+
statementTransactions: filterStatementTransactionsByPeriod(statementUpload.statementTransactions, statementPeriod),
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
export const getParsedStatementDataForView = (parsedStatementData, statementUpdateLocalDataByUploadId, statementAccountScope) => {
|
|
29
53
|
if (parsedStatementData == null) {
|
|
30
54
|
return undefined;
|
|
31
55
|
}
|
|
56
|
+
const statementUploads = getStatementUploadsFromParsedData(parsedStatementData);
|
|
57
|
+
if (statementUploads.length === 0) {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
if (statementAccountScope === 'multi_account') {
|
|
61
|
+
const viewedUploads = statementUploads.map((statementUpload) => {
|
|
62
|
+
const uploadId = statementUpload.statementMeta.statementUploadId;
|
|
63
|
+
return getStatementUploadForView(statementUpload, statementUpdateLocalDataByUploadId?.[uploadId]);
|
|
64
|
+
});
|
|
65
|
+
const anchorUploadId = parsedStatementData.statementUpload.statementMeta.statementUploadId;
|
|
66
|
+
const viewedAnchor = viewedUploads.find((upload) => upload.statementMeta.statementUploadId === anchorUploadId) ?? viewedUploads[0];
|
|
67
|
+
return {
|
|
68
|
+
statementUpload: viewedAnchor,
|
|
69
|
+
statementUploads: viewedUploads,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
32
72
|
const statementUpload = parsedStatementData.statementUpload;
|
|
33
73
|
if (statementUpload == null) {
|
|
34
74
|
return undefined;
|
|
35
75
|
}
|
|
36
|
-
const
|
|
37
|
-
const localMeta = statementUpdateLocalData?.statementMeta;
|
|
38
|
-
const effectiveMeta = localMeta ?? parsedMeta;
|
|
39
|
-
const statementPeriod = getEffectiveStatementPeriod(parsedMeta, localMeta);
|
|
76
|
+
const uploadId = statementUpload.statementMeta.statementUploadId;
|
|
40
77
|
return {
|
|
41
|
-
statementUpload:
|
|
42
|
-
...statementUpload,
|
|
43
|
-
statementMeta: effectiveMeta,
|
|
44
|
-
statementTransactions: filterStatementTransactionsByPeriod(statementUpload.statementTransactions, statementPeriod),
|
|
45
|
-
},
|
|
78
|
+
statementUpload: getStatementUploadForView(statementUpload, statementUpdateLocalDataByUploadId?.[uploadId]),
|
|
46
79
|
};
|
|
47
80
|
};
|
|
48
81
|
export const getStatementTransactionPeriodById = (allParsedTransactions, parsedMeta, localMeta) => {
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import { stringToUnion } from '../../../commonStateTypes/stringToUnion';
|
|
1
|
+
import { stringToUnion, stringToUnionStrict, } from '../../../commonStateTypes/stringToUnion';
|
|
2
|
+
const ALL_STATEMENT_BALANCE_SOURCES = [
|
|
3
|
+
'ocr',
|
|
4
|
+
'prior_recon',
|
|
5
|
+
'default_zero',
|
|
6
|
+
];
|
|
7
|
+
export const toStatementBalanceSource = (v) => stringToUnion(v, ALL_STATEMENT_BALANCE_SOURCES);
|
|
8
|
+
export const toStatementBalanceSourceStrict = (v) => stringToUnionStrict(v ?? '', ALL_STATEMENT_BALANCE_SOURCES);
|
|
2
9
|
export function toReconciliationViewSummary(payload) {
|
|
3
10
|
return {
|
|
4
11
|
accounts: {
|
|
@@ -59,3 +66,10 @@ const RECON_REVIEW_SORT_KEYS = [
|
|
|
59
66
|
];
|
|
60
67
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
61
68
|
const toReconReviewSortKey = (v) => stringToUnion(v, RECON_REVIEW_SORT_KEYS);
|
|
69
|
+
const ALL_STATEMENT_ACCOUNT_SCOPES = [
|
|
70
|
+
'single_account',
|
|
71
|
+
'multi_account',
|
|
72
|
+
];
|
|
73
|
+
export const toStatementAccountScope = (v) => stringToUnion(v, ALL_STATEMENT_ACCOUNT_SCOPES);
|
|
74
|
+
export const toStatementAccountScopeStrict = (v) => stringToUnionStrict(v ?? '', ALL_STATEMENT_ACCOUNT_SCOPES);
|
|
75
|
+
export const STATEMENT_ACCOUNT_SCOPES = ALL_STATEMENT_ACCOUNT_SCOPES;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { from } from 'rxjs';
|
|
2
2
|
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
3
3
|
import { updateInvoicingCreditNotes } from '../../../entity/invoicing/creditNote/creditNoteReducer';
|
|
4
|
+
import { apiErrorSnackbarVariables } from '../../../entity/snackbar/snackbarApiError';
|
|
4
5
|
import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
|
|
5
6
|
import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
|
|
6
7
|
import { localDataToCreateCreditNotePayload, } from './createCreditNotePayload';
|
|
@@ -29,6 +30,7 @@ export const createCreditNoteEpic = (actions$, state$, zeniAPI) => actions$.pipe
|
|
|
29
30
|
messageSection: 'invoicing_credit_note_saved',
|
|
30
31
|
messageText: 'failed',
|
|
31
32
|
type: 'error',
|
|
33
|
+
variables: apiErrorSnackbarVariables(response.status),
|
|
32
34
|
}),
|
|
33
35
|
]);
|
|
34
36
|
}), catchError((error) => from([
|
|
@@ -3,6 +3,7 @@ import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
|
3
3
|
import { updateAddresses } from '../../../entity/address/addressReducer';
|
|
4
4
|
import { extractInvoicingInvoiceAddresses } from '../../../entity/invoicing/invoice/invoicePayload';
|
|
5
5
|
import { updateInvoices } from '../../../entity/invoicing/invoice/invoiceReducer';
|
|
6
|
+
import { apiErrorSnackbarVariables } from '../../../entity/snackbar/snackbarApiError';
|
|
6
7
|
import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
|
|
7
8
|
import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
|
|
8
9
|
import { addInvoiceToList } from '../invoiceList/invoiceListReducer';
|
|
@@ -36,6 +37,7 @@ export const createInvoiceEpic = (actions$, _state$, zeniAPI) => actions$.pipe(f
|
|
|
36
37
|
messageSection: 'invoicing_invoice_saved',
|
|
37
38
|
messageText: 'failed',
|
|
38
39
|
type: 'error',
|
|
40
|
+
variables: apiErrorSnackbarVariables(response.status),
|
|
39
41
|
}),
|
|
40
42
|
]);
|
|
41
43
|
}), catchError((error) => from([
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { from } from 'rxjs';
|
|
2
2
|
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
3
3
|
import { updateInvoicingCoupons } from '../../../entity/invoicing/coupon/couponReducer';
|
|
4
|
+
import { apiErrorSnackbarVariables } from '../../../entity/snackbar/snackbarApiError';
|
|
4
5
|
import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
|
|
5
|
-
import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
|
|
6
|
+
import { createZeniAPIStatus, isSuccessResponse, } from '../../../responsePayload';
|
|
6
7
|
import { runInvoicingDiscountAction, runInvoicingDiscountActionFailure, runInvoicingDiscountActionSuccess, } from './discountActionReducer';
|
|
7
8
|
/** Snackbar copy per action kind; unlisted kinds run without one. */
|
|
8
9
|
const SNACKBAR_SECTION_BY_KIND = {
|
|
@@ -14,13 +15,15 @@ export const runInvoicingDiscountActionEpic = (actions$, _state$, zeniAPI) => ac
|
|
|
14
15
|
const { action: kind, id } = action.payload;
|
|
15
16
|
const requestBody = { action: kind };
|
|
16
17
|
const snackbarSection = SNACKBAR_SECTION_BY_KIND[kind];
|
|
17
|
-
|
|
18
|
+
/** `status` surfaces the platform's error text; omit it to keep the generic copy. */
|
|
19
|
+
const snackbar = (messageText, status) => snackbarSection == null
|
|
18
20
|
? []
|
|
19
21
|
: [
|
|
20
22
|
openSnackbar({
|
|
21
23
|
messageSection: snackbarSection,
|
|
22
24
|
messageText,
|
|
23
25
|
type: messageText === 'success' ? 'success' : 'error',
|
|
26
|
+
variables: apiErrorSnackbarVariables(status),
|
|
24
27
|
}),
|
|
25
28
|
];
|
|
26
29
|
const apiUrl = `${zeniAPI.apiEndPoints.invoicingMicroServiceBaseUrl}/1.0/discounts/${encodeURIComponent(id)}/actions`;
|
|
@@ -39,7 +42,7 @@ export const runInvoicingDiscountActionEpic = (actions$, _state$, zeniAPI) => ac
|
|
|
39
42
|
error: response.status,
|
|
40
43
|
id,
|
|
41
44
|
}),
|
|
42
|
-
...snackbar('failed'),
|
|
45
|
+
...snackbar('failed', response.status),
|
|
43
46
|
]);
|
|
44
47
|
}), catchError((error) => from([
|
|
45
48
|
runInvoicingDiscountActionFailure({
|