@zeniai/client-epic-state 5.1.51-beta0RR → 5.1.51-beta1RR
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/esm/view/transactionDetail/epics/markTransactionAsNotMiscategorizedEpic.js +4 -2
- package/lib/esm/view/transactionDetail/epics/updateTransactionDetailEpic.js +38 -4
- package/lib/view/transactionDetail/epics/markTransactionAsNotMiscategorizedEpic.js +4 -2
- package/lib/view/transactionDetail/epics/updateTransactionDetailEpic.js +38 -4
- package/package.json +1 -1
|
@@ -36,9 +36,11 @@ export const markTransactionAsNotMiscategorizedEpic = (actions$, state$, zeniAPI
|
|
|
36
36
|
actions.push(updateTransactionIsMiscategorized(transactionKey, false));
|
|
37
37
|
const { expenseAutomationViewState, expenseAutomationTransactionsViewState, } = state$.value;
|
|
38
38
|
const { transactionCategorizationView, selectedTransactionCategorizationTab, } = expenseAutomationTransactionsViewState;
|
|
39
|
-
const
|
|
39
|
+
const currentTenantId = getCurrentTenant(state$.value)?.tenantId;
|
|
40
40
|
const { selectedPeriodByTenantId } = expenseAutomationViewState;
|
|
41
|
-
const selectedPeriod =
|
|
41
|
+
const selectedPeriod = currentTenantId != null
|
|
42
|
+
? selectedPeriodByTenantId[currentTenantId]
|
|
43
|
+
: undefined;
|
|
42
44
|
const autoTabLineItems = transactionCategorizationView.autoCategorized
|
|
43
45
|
.transactionReviewLocalDataById[txnId]
|
|
44
46
|
?.transactionReviewLocalData.tabSpecificLineItems
|
|
@@ -11,6 +11,7 @@ import { injectCOTFlagsIntoTransactionPayload, toTransactionPayload, } from '../
|
|
|
11
11
|
import { toVendorTransactionPayload, toVendorTransactionWithCustomerPayload, } from '../../../entity/transaction/payloadTypes/vendorTransactionPayload';
|
|
12
12
|
import { isCustomerTransaction, } from '../../../entity/transaction/stateTypes/customerTransaction';
|
|
13
13
|
import { isTransferTransaction, } from '../../../entity/transaction/stateTypes/otherTransaction';
|
|
14
|
+
import { toJEAndDepositTransactionTypeStrict } from '../../../entity/transaction/stateTypes/transactionType';
|
|
14
15
|
import { isVendorTransaction, } from '../../../entity/transaction/stateTypes/vendorTransaction';
|
|
15
16
|
import toSupportedTransaction from '../../../entity/transaction/toSupportedTransaction';
|
|
16
17
|
import { getTransactionWithCOT } from '../../../entity/transaction/transactionHelper';
|
|
@@ -50,7 +51,7 @@ export const updateTransactionDetailEpic = (actions$, state$, zeniAPI) => action
|
|
|
50
51
|
const uncategorizedIncomeExpense = getUncategorizedAccounts(state$.value.accountState, state$.value.accountListState, 'accountList');
|
|
51
52
|
const transaction = toSupportedTransaction(response.data.transaction);
|
|
52
53
|
const isAccountingClassesEnabled = getIsAccountingClassesEnabled(state$.value);
|
|
53
|
-
const eligibleLineIds = getLineIdsEligibleForReview(transaction, uncategorizedIncomeExpense, isAccountingClassesEnabled);
|
|
54
|
+
const eligibleLineIds = getLineIdsEligibleForReview(transaction, uncategorizedIncomeExpense, isAccountingClassesEnabled, action.payload.isExpenseAutomationEnabled);
|
|
54
55
|
if (action.payload.transactionSaveUpdates.markAsMiscatUpdates ===
|
|
55
56
|
true &&
|
|
56
57
|
eligibleLineIds.length > 0) {
|
|
@@ -264,7 +265,34 @@ export const toTransactionUpdatePayload = (updates, detail, cotTransactionTracki
|
|
|
264
265
|
// Inject COT flags into the payload
|
|
265
266
|
return injectCOTFlagsIntoTransactionPayload(basePayload, transaction);
|
|
266
267
|
};
|
|
267
|
-
const getLineIdsEligibleForReview = (transaction, uncategorizedIncomeExpense, isAccountingClassesEnabled) => {
|
|
268
|
+
const getLineIdsEligibleForReview = (transaction, uncategorizedIncomeExpense, isAccountingClassesEnabled, isExpenseAutomationEnabled) => {
|
|
269
|
+
// For non-EA, any line missing a required field (class when enabled, or entity on JE/Deposit)
|
|
270
|
+
// suppresses the entire call. EA keeps the per-line model, returning only eligible line IDs.
|
|
271
|
+
if (!isExpenseAutomationEnabled) {
|
|
272
|
+
const isApplicableType = isVendorTransaction(transaction) ||
|
|
273
|
+
toJEAndDepositTransactionTypeStrict(transaction.type) != null;
|
|
274
|
+
if (isApplicableType) {
|
|
275
|
+
const lines = (transaction.lines ?? []).filter((line) => line.type === 'transaction_with_account_and_class_line' ||
|
|
276
|
+
line.type === 'journal_entry_transaction_line' ||
|
|
277
|
+
line.type === 'transaction_with_product_or_service_line');
|
|
278
|
+
if (isAccountingClassesEnabled) {
|
|
279
|
+
const anyLineMissingClass = lines.some((line) => (line.class?.classId ??
|
|
280
|
+
'') === '');
|
|
281
|
+
if (anyLineMissingClass) {
|
|
282
|
+
return [];
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
if (toJEAndDepositTransactionTypeStrict(transaction.type) != null) {
|
|
286
|
+
const anyLineMissingEntity = lines.some((line) => {
|
|
287
|
+
const tl = line;
|
|
288
|
+
return tl.vendor == null && tl.customer == null;
|
|
289
|
+
});
|
|
290
|
+
if (anyLineMissingEntity) {
|
|
291
|
+
return [];
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
268
296
|
return (transaction.lines ?? [])
|
|
269
297
|
.filter((line) => {
|
|
270
298
|
if (line.type !== 'transaction_with_account_and_class_line' &&
|
|
@@ -274,9 +302,15 @@ const getLineIdsEligibleForReview = (transaction, uncategorizedIncomeExpense, is
|
|
|
274
302
|
}
|
|
275
303
|
const typedLine = line;
|
|
276
304
|
const hasCategory = !isAccountUncategorized(uncategorizedIncomeExpense, typedLine.account?.qboId);
|
|
277
|
-
|
|
305
|
+
// class is always a ClassBase object (never null) because the payload mapper
|
|
306
|
+
// calls mapClassBasePayloadToClassBase(payload ?? {}) which returns {} with classId:''.
|
|
307
|
+
// A real class is indicated by a non-empty classId.
|
|
308
|
+
const hasClass = !isAccountingClassesEnabled || (typedLine.class?.classId ?? '') !== '';
|
|
278
309
|
const hasAmount = (typedLine.amount?.amount ?? 0) !== 0;
|
|
279
|
-
|
|
310
|
+
// JE lines and Deposit transactions require vendor or customer before being eligible for review.
|
|
311
|
+
const isJEOrDepositContext = line.type === 'journal_entry_transaction_line' ||
|
|
312
|
+
toJEAndDepositTransactionTypeStrict(transaction.type) != null;
|
|
313
|
+
const hasEntity = !isJEOrDepositContext ||
|
|
280
314
|
typedLine.vendor != null ||
|
|
281
315
|
typedLine.customer != null;
|
|
282
316
|
return hasCategory && hasClass && hasAmount && hasEntity;
|
|
@@ -39,9 +39,11 @@ const markTransactionAsNotMiscategorizedEpic = (actions$, state$, zeniAPI) => ac
|
|
|
39
39
|
actions.push((0, transactionReducer_1.updateTransactionIsMiscategorized)(transactionKey, false));
|
|
40
40
|
const { expenseAutomationViewState, expenseAutomationTransactionsViewState, } = state$.value;
|
|
41
41
|
const { transactionCategorizationView, selectedTransactionCategorizationTab, } = expenseAutomationTransactionsViewState;
|
|
42
|
-
const
|
|
42
|
+
const currentTenantId = (0, tenantSelector_1.getCurrentTenant)(state$.value)?.tenantId;
|
|
43
43
|
const { selectedPeriodByTenantId } = expenseAutomationViewState;
|
|
44
|
-
const selectedPeriod =
|
|
44
|
+
const selectedPeriod = currentTenantId != null
|
|
45
|
+
? selectedPeriodByTenantId[currentTenantId]
|
|
46
|
+
: undefined;
|
|
45
47
|
const autoTabLineItems = transactionCategorizationView.autoCategorized
|
|
46
48
|
.transactionReviewLocalDataById[txnId]
|
|
47
49
|
?.transactionReviewLocalData.tabSpecificLineItems
|
|
@@ -17,6 +17,7 @@ const transactionPayload_1 = require("../../../entity/transaction/payloadTypes/t
|
|
|
17
17
|
const vendorTransactionPayload_1 = require("../../../entity/transaction/payloadTypes/vendorTransactionPayload");
|
|
18
18
|
const customerTransaction_1 = require("../../../entity/transaction/stateTypes/customerTransaction");
|
|
19
19
|
const otherTransaction_1 = require("../../../entity/transaction/stateTypes/otherTransaction");
|
|
20
|
+
const transactionType_1 = require("../../../entity/transaction/stateTypes/transactionType");
|
|
20
21
|
const vendorTransaction_1 = require("../../../entity/transaction/stateTypes/vendorTransaction");
|
|
21
22
|
const toSupportedTransaction_1 = __importDefault(require("../../../entity/transaction/toSupportedTransaction"));
|
|
22
23
|
const transactionHelper_1 = require("../../../entity/transaction/transactionHelper");
|
|
@@ -56,7 +57,7 @@ const updateTransactionDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe
|
|
|
56
57
|
const uncategorizedIncomeExpense = (0, accountListSelector_1.getUncategorizedAccounts)(state$.value.accountState, state$.value.accountListState, 'accountList');
|
|
57
58
|
const transaction = (0, toSupportedTransaction_1.default)(response.data.transaction);
|
|
58
59
|
const isAccountingClassesEnabled = (0, tenantSelector_1.getIsAccountingClassesEnabled)(state$.value);
|
|
59
|
-
const eligibleLineIds = getLineIdsEligibleForReview(transaction, uncategorizedIncomeExpense, isAccountingClassesEnabled);
|
|
60
|
+
const eligibleLineIds = getLineIdsEligibleForReview(transaction, uncategorizedIncomeExpense, isAccountingClassesEnabled, action.payload.isExpenseAutomationEnabled);
|
|
60
61
|
if (action.payload.transactionSaveUpdates.markAsMiscatUpdates ===
|
|
61
62
|
true &&
|
|
62
63
|
eligibleLineIds.length > 0) {
|
|
@@ -272,7 +273,34 @@ const toTransactionUpdatePayload = (updates, detail, cotTransactionTracking, isA
|
|
|
272
273
|
return (0, transactionPayload_1.injectCOTFlagsIntoTransactionPayload)(basePayload, transaction);
|
|
273
274
|
};
|
|
274
275
|
exports.toTransactionUpdatePayload = toTransactionUpdatePayload;
|
|
275
|
-
const getLineIdsEligibleForReview = (transaction, uncategorizedIncomeExpense, isAccountingClassesEnabled) => {
|
|
276
|
+
const getLineIdsEligibleForReview = (transaction, uncategorizedIncomeExpense, isAccountingClassesEnabled, isExpenseAutomationEnabled) => {
|
|
277
|
+
// For non-EA, any line missing a required field (class when enabled, or entity on JE/Deposit)
|
|
278
|
+
// suppresses the entire call. EA keeps the per-line model, returning only eligible line IDs.
|
|
279
|
+
if (!isExpenseAutomationEnabled) {
|
|
280
|
+
const isApplicableType = (0, vendorTransaction_1.isVendorTransaction)(transaction) ||
|
|
281
|
+
(0, transactionType_1.toJEAndDepositTransactionTypeStrict)(transaction.type) != null;
|
|
282
|
+
if (isApplicableType) {
|
|
283
|
+
const lines = (transaction.lines ?? []).filter((line) => line.type === 'transaction_with_account_and_class_line' ||
|
|
284
|
+
line.type === 'journal_entry_transaction_line' ||
|
|
285
|
+
line.type === 'transaction_with_product_or_service_line');
|
|
286
|
+
if (isAccountingClassesEnabled) {
|
|
287
|
+
const anyLineMissingClass = lines.some((line) => (line.class?.classId ??
|
|
288
|
+
'') === '');
|
|
289
|
+
if (anyLineMissingClass) {
|
|
290
|
+
return [];
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
if ((0, transactionType_1.toJEAndDepositTransactionTypeStrict)(transaction.type) != null) {
|
|
294
|
+
const anyLineMissingEntity = lines.some((line) => {
|
|
295
|
+
const tl = line;
|
|
296
|
+
return tl.vendor == null && tl.customer == null;
|
|
297
|
+
});
|
|
298
|
+
if (anyLineMissingEntity) {
|
|
299
|
+
return [];
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
276
304
|
return (transaction.lines ?? [])
|
|
277
305
|
.filter((line) => {
|
|
278
306
|
if (line.type !== 'transaction_with_account_and_class_line' &&
|
|
@@ -282,9 +310,15 @@ const getLineIdsEligibleForReview = (transaction, uncategorizedIncomeExpense, is
|
|
|
282
310
|
}
|
|
283
311
|
const typedLine = line;
|
|
284
312
|
const hasCategory = !(0, transactionDetailLocalDataHelper_1.isAccountUncategorized)(uncategorizedIncomeExpense, typedLine.account?.qboId);
|
|
285
|
-
|
|
313
|
+
// class is always a ClassBase object (never null) because the payload mapper
|
|
314
|
+
// calls mapClassBasePayloadToClassBase(payload ?? {}) which returns {} with classId:''.
|
|
315
|
+
// A real class is indicated by a non-empty classId.
|
|
316
|
+
const hasClass = !isAccountingClassesEnabled || (typedLine.class?.classId ?? '') !== '';
|
|
286
317
|
const hasAmount = (typedLine.amount?.amount ?? 0) !== 0;
|
|
287
|
-
|
|
318
|
+
// JE lines and Deposit transactions require vendor or customer before being eligible for review.
|
|
319
|
+
const isJEOrDepositContext = line.type === 'journal_entry_transaction_line' ||
|
|
320
|
+
(0, transactionType_1.toJEAndDepositTransactionTypeStrict)(transaction.type) != null;
|
|
321
|
+
const hasEntity = !isJEOrDepositContext ||
|
|
288
322
|
typedLine.vendor != null ||
|
|
289
323
|
typedLine.customer != null;
|
|
290
324
|
return hasCategory && hasClass && hasAmount && hasEntity;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zeniai/client-epic-state",
|
|
3
|
-
"version": "5.1.51-
|
|
3
|
+
"version": "5.1.51-beta1RR",
|
|
4
4
|
"description": "Shared module between Web & Mobile containing required abstractions for state management, async network communication. ",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "lib/esm/index.js",
|