@zeniai/client-epic-state 4.19.77-betaAK8 → 4.19.77-betaAS2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/lib/entity/company/companyPayload.d.ts +1 -0
  2. package/lib/entity/company/companyPayload.js +1 -0
  3. package/lib/entity/company/companyStateTypes.d.ts +1 -0
  4. package/lib/esm/entity/company/companyPayload.js +1 -0
  5. package/lib/esm/index.js +2 -0
  6. package/lib/esm/view/companyView/epic/companyPassport/updateCompanyDetailsEpic.js +3 -0
  7. package/lib/esm/view/companyView/types/companyPassport/companyPassportLocalData.js +1 -0
  8. package/lib/esm/view/spendManagement/commonSetup/epic/setup/updateBusinessVerificationDetailsEpic.js +4 -1
  9. package/lib/esm/view/spendManagement/commonSetup/epic/setup/updateSetupViewLocalStoreDataEpic.js +2 -1
  10. package/lib/esm/view/spendManagement/commonSetup/setupViewSelector.js +2 -1
  11. package/lib/esm/view/spendManagement/commonSetup/types/businessVerification.js +141 -1
  12. package/lib/esm/view/transactionDetail/epics/initializeTransactionDetailLocalDataEpic.js +3 -1
  13. package/lib/esm/view/transactionDetail/epics/markTransactionAsNotMiscategorizedEpic.js +6 -6
  14. package/lib/esm/view/transactionDetail/epics/saveTransactionDetailEpic.js +2 -4
  15. package/lib/esm/view/transactionDetail/epics/transactionDetailEpic.js +8 -34
  16. package/lib/esm/view/transactionDetail/epics/updateTransactionDetailEpic.js +7 -12
  17. package/lib/esm/view/transactionDetail/epics/uploadMissingAttachmentSuccessEpic.js +3 -2
  18. package/lib/esm/view/transactionDetail/transactionDetailSelector.js +3 -5
  19. package/lib/esm/view/transactionDetail/transactionDetailState.js +2 -14
  20. package/lib/index.d.ts +3 -0
  21. package/lib/index.js +27 -20
  22. package/lib/view/companyView/epic/companyPassport/updateCompanyDetailsEpic.js +3 -0
  23. package/lib/view/companyView/types/companyPassport/companyDetailsLocalData.d.ts +1 -0
  24. package/lib/view/companyView/types/companyPassport/companyPassportLocalData.js +1 -0
  25. package/lib/view/spendManagement/commonSetup/epic/setup/updateBusinessVerificationDetailsEpic.js +4 -1
  26. package/lib/view/spendManagement/commonSetup/epic/setup/updateSetupViewLocalStoreDataEpic.js +2 -1
  27. package/lib/view/spendManagement/commonSetup/setupViewSelector.d.ts +1 -0
  28. package/lib/view/spendManagement/commonSetup/setupViewSelector.js +2 -1
  29. package/lib/view/spendManagement/commonSetup/setupViewState.d.ts +1 -0
  30. package/lib/view/spendManagement/commonSetup/types/businessVerification.d.ts +30 -3
  31. package/lib/view/spendManagement/commonSetup/types/businessVerification.js +143 -0
  32. package/lib/view/transactionDetail/epics/initializeTransactionDetailLocalDataEpic.js +3 -1
  33. package/lib/view/transactionDetail/epics/markTransactionAsNotMiscategorizedEpic.d.ts +2 -2
  34. package/lib/view/transactionDetail/epics/markTransactionAsNotMiscategorizedEpic.js +5 -5
  35. package/lib/view/transactionDetail/epics/saveTransactionDetailEpic.js +2 -4
  36. package/lib/view/transactionDetail/epics/transactionDetailEpic.js +8 -34
  37. package/lib/view/transactionDetail/epics/updateTransactionDetailEpic.d.ts +2 -2
  38. package/lib/view/transactionDetail/epics/updateTransactionDetailEpic.js +6 -11
  39. package/lib/view/transactionDetail/epics/uploadMissingAttachmentSuccessEpic.js +3 -2
  40. package/lib/view/transactionDetail/transactionDetailSelector.js +3 -5
  41. package/lib/view/transactionDetail/transactionDetailState.d.ts +1 -1
  42. package/lib/view/transactionDetail/transactionDetailState.js +2 -14
  43. package/package.json +1 -1
  44. package/lib/tsconfig.typecheck.tsbuildinfo +0 -1
@@ -27,7 +27,7 @@ const fetchTransactionDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe(
27
27
  const detailKey = (0, transactionDetailState_1.getTransactionDetailKey)(transactionId);
28
28
  const transactionActions = [];
29
29
  if (cacheOverride === true) {
30
- const transaction = (0, transactionSelector_1.getSupportedTransactionById)(state$.value.transactionState, transactionId.id);
30
+ const transaction = (0, transactionSelector_1.getSupportedTransactionById)(state$.value.transactionState, detailKey);
31
31
  transactionActions.push(...removeCompleteTransaction(transactionId, transaction));
32
32
  }
33
33
  const transactionDetail = (0, get_1.default)(state$.value.transactionDetailState.transactionDetailById, detailKey, undefined);
@@ -46,27 +46,6 @@ const fetchTransactionDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe(
46
46
  transactionActions.push((0, classListReducer_1.fetchClassList)());
47
47
  }
48
48
  transactionActions.push((0, transactionDetailReducer_1.updateTransactionDetailFetchState)(transactionId, 'In-Progress'));
49
- // If the transaction already exists in the entity store (e.g. fetched by the
50
- // list page), initialize local data immediately so the UI can render whatever
51
- // data is available while the full detail fetch completes in parallel.
52
- //
53
- // The entity store canonical key is the full zeni ID (transactionId.id),
54
- // which is the same key used by all list-fetch epics.
55
- //
56
- // DEPENDENCY: The web-components TransactionDetailPage sets effectiveIsDisabled
57
- // to "disabled" while fetchState !== "Completed". This prevents any user edits
58
- // between this early init and the second init dispatched on API response (below).
59
- // If that guard is ever removed, user edits made against partial list data will
60
- // be silently overwritten when the full detail response arrives.
61
- if (cacheOverride !== true) {
62
- const existingTransaction = (0, transactionSelector_1.getSupportedTransactionById)(state$.value.transactionState, transactionId.id);
63
- if (existingTransaction != null) {
64
- transactionActions.push((0, transactionDetailReducer_1.initializeTransactionDetailLocalData)({
65
- transactionId,
66
- vendorId: existingTransaction.vendorId,
67
- }));
68
- }
69
- }
70
49
  const query = { transaction_type: transactionId.type };
71
50
  const getTransactionDetail$ = zeniAPI
72
51
  .getJSON(`${zeniAPI.apiEndPoints.accountMicroServiceBaseUrl}/1.0/transactions/${transactionId.id}?query=${encodeURIComponent(JSON.stringify(query))}`)
@@ -74,7 +53,7 @@ const fetchTransactionDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe(
74
53
  if ((0, responsePayload_1.isSuccessResponse)(response) &&
75
54
  response.data?.transaction?.transaction_id != null) {
76
55
  const updateActions = [];
77
- const responseTransactionId = (0, transactionIDPayload_1.toTransactionID)(response.data.transaction);
56
+ const transcationId = (0, transactionIDPayload_1.toTransactionID)(response.data.transaction);
78
57
  const responseData = {
79
58
  ...response.data,
80
59
  vendors: response.data.vendors?.map((vendor) => ({
@@ -85,15 +64,13 @@ const fetchTransactionDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe(
85
64
  if (responseData.vendors.length > 0) {
86
65
  updateActions.push((0, vendorReducer_1.updateVendors)(responseData.vendors, 'merge'));
87
66
  }
88
- // Use the full zeni ID as the entity store key so it matches
89
- // how all list-fetch epics save transactions, avoiding
90
- // duplicate entries under different key formats.
91
- updateActions.push((0, transactionReducer_1.updateTransaction)(responseTransactionId.id, responseData.transaction));
67
+ const transactionDetailKeyForResponse = (0, transactionDetailState_1.getTransactionDetailKey)(transcationId);
68
+ updateActions.push((0, transactionReducer_1.updateTransaction)(transactionDetailKeyForResponse, responseData.transaction));
92
69
  updateActions.push((0, transactionDetailReducer_1.initializeTransactionDetailLocalData)({
93
- transactionId: responseTransactionId,
70
+ transactionId: transcationId,
94
71
  vendorId: responseData.vendors[0]?.vendor_id,
95
72
  }));
96
- updateActions.push((0, transactionDetailReducer_1.updateTransactionDetailFetchState)(responseTransactionId, 'Completed'));
73
+ updateActions.push((0, transactionDetailReducer_1.updateTransactionDetailFetchState)(transcationId, 'Completed'));
97
74
  // IMPORTANT: Fetch linked transactions..
98
75
  updateActions.push(...getAllFetchLinkedTransactionDetailActions(responseData.transaction, state$.value));
99
76
  if (responseData.vendors.length > 0) {
@@ -129,15 +106,12 @@ function removeCompleteTransaction(transactionId, transaction) {
129
106
  const actions = [];
130
107
  actions.push((0, transactionDetailReducer_1.removeTransactionDetail)(transactionId));
131
108
  if (transaction != null) {
132
- // Use transactionId.id (full zeni ID) — the canonical entity store key.
133
- // getTransactionDetailKey produces a different composite key used only by
134
- // transactionDetailState, not the entity store.
135
- actions.push((0, transactionReducer_1.removeTransaction)(transactionId.id));
109
+ actions.push((0, transactionReducer_1.removeTransaction)((0, transactionDetailState_1.getTransactionDetailKey)(transactionId)));
136
110
  // remove all the linked transactions too..
137
111
  const linkedTransactions = (0, transactionDetailState_1.getAllLinkedTransactions)(transaction);
138
112
  linkedTransactions.forEach((linkedTransaction) => {
139
113
  actions.push((0, transactionDetailReducer_1.removeTransactionDetail)(linkedTransaction));
140
- actions.push((0, transactionReducer_1.removeTransaction)(linkedTransaction.id));
114
+ actions.push((0, transactionReducer_1.removeTransaction)((0, transactionDetailState_1.getTransactionDetailKey)(linkedTransaction)));
141
115
  });
142
116
  }
143
117
  return actions;
@@ -1,10 +1,10 @@
1
1
  import { ActionsObservable, StateObservable } from 'redux-observable';
2
2
  import { openSnackbar } from '../../../entity/snackbar/snackbarReducer';
3
- import { updateTransaction } from '../../../entity/transaction/transactionReducer';
3
+ import { updateTransaction, updateTransactions } from '../../../entity/transaction/transactionReducer';
4
4
  import { updateVendors } from '../../../entity/vendor/vendorReducer';
5
5
  import { RootState } from '../../../reducer';
6
6
  import { ZeniAPI } from '../../../zeniAPI';
7
7
  import { syncTransactionCategorizationFromDetailSave } from '../../expenseAutomationView/reducers/transactionsViewReducer';
8
8
  import { initializeTransactionDetailLocalData, markTransactionAsNotMiscategorized, updateStatusConsolidatedSaveTransactionDetail, updateTransactionDetail, updateTransactionDetailSaveStatus, updateTransactionStateIfUpdateActionNotAllowed } from '../transactionDetailReducer';
9
- export type ActionType = ReturnType<typeof updateTransactionDetail> | ReturnType<typeof updateTransaction> | ReturnType<typeof updateTransactionStateIfUpdateActionNotAllowed> | ReturnType<typeof openSnackbar> | ReturnType<typeof updateTransactionDetailSaveStatus> | ReturnType<typeof updateStatusConsolidatedSaveTransactionDetail> | ReturnType<typeof initializeTransactionDetailLocalData> | ReturnType<typeof updateVendors> | ReturnType<typeof markTransactionAsNotMiscategorized> | ReturnType<typeof syncTransactionCategorizationFromDetailSave>;
9
+ export type ActionType = ReturnType<typeof updateTransactionDetail> | ReturnType<typeof updateTransaction> | ReturnType<typeof updateTransactions> | ReturnType<typeof updateTransactionStateIfUpdateActionNotAllowed> | ReturnType<typeof openSnackbar> | ReturnType<typeof updateTransactionDetailSaveStatus> | ReturnType<typeof updateStatusConsolidatedSaveTransactionDetail> | ReturnType<typeof initializeTransactionDetailLocalData> | ReturnType<typeof updateVendors> | ReturnType<typeof markTransactionAsNotMiscategorized> | ReturnType<typeof syncTransactionCategorizationFromDetailSave>;
10
10
  export declare const updateTransactionDetailEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => import("rxjs").Observable<ActionType>;
@@ -40,8 +40,7 @@ const updateTransactionDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe
40
40
  if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
41
41
  const transactionIdResp = (0, transactionIDPayload_1.toTransactionID)(response.data.transaction);
42
42
  const transactionDetailKeyForResponse = (0, transactionDetailState_1.getTransactionDetailKey)(transactionIdResp);
43
- const tranDetail = (0, get_1.default)(transactionDetailState.transactionDetailById, transactionDetailKeyForResponse, // detail key is correct for transactionDetailState
44
- undefined);
43
+ const tranDetail = (0, get_1.default)(transactionDetailState.transactionDetailById, transactionDetailKeyForResponse, undefined);
45
44
  const tranVendorUpdates = tranDetail?.transactionDetailLocalData.vendorUpdates;
46
45
  let vendorUpdates = undefined;
47
46
  if (tranVendorUpdates?.qboId != null) {
@@ -63,7 +62,7 @@ const updateTransactionDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe
63
62
  if (response.data.vendors != null) {
64
63
  actions.push((0, vendorReducer_1.updateVendors)(response.data.vendors, 'merge'));
65
64
  }
66
- actions.push((0, transactionReducer_1.updateTransaction)(transactionIdResp.id, response.data.transaction));
65
+ actions.push((0, transactionReducer_1.updateTransaction)(transactionDetailKeyForResponse, response.data.transaction));
67
66
  actions.push((0, transactionDetailReducer_1.initializeTransactionDetailLocalData)({
68
67
  transactionId: transactionIdResp,
69
68
  vendorId: response.data.vendors?.[0]?.vendor_id,
@@ -112,12 +111,9 @@ const updateTransactionDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe
112
111
  }));
113
112
  }
114
113
  }
115
- // No separate updateTransactions call needed: updateTransaction above
116
- // writes under transactionIdResp.id (the full zeni ID). This is the same
117
- // key all list-fetch epics use, so list selectors will read fresh data.
118
- // ASSUMPTION: toTransactionID(response).id === the transaction_id value
119
- // that list-fetch epics pass to updateTransactions. If these ever diverge,
120
- // list rows will go stale after a detail save.
114
+ // Sync transaction categorization list state from detail save
115
+ // Updates list-keyed canonical entity so the list selector reads fresh data
116
+ actions.push((0, transactionReducer_1.updateTransactions)([response.data.transaction], (value) => value.transaction_id, 'merge'));
121
117
  const transactionWithCOT = (0, transactionHelper_1.getTransactionWithCOT)(transaction);
122
118
  const pendingReviewLineIds = (0, transactionCategorizationLocalDataHelper_1.getPendingReviewLineIdsFromTransaction)(transactionWithCOT);
123
119
  actions.push((0, transactionsViewReducer_1.syncTransactionCategorizationFromDetailSave)(transactionIdResp, transactionWithCOT, pendingReviewLineIds, uncategorizedIncomeExpense, isUncategorizedExpenseCategoryEnabled));
@@ -136,8 +132,7 @@ const updateTransactionDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe
136
132
  exports.updateTransactionDetailEpic = updateTransactionDetailEpic;
137
133
  function preparePayload(transactionState, vendorState, transactionDetailState, transactionId, saveUpdates, cotTransactionTracking) {
138
134
  const transactionDetailKey = (0, transactionDetailState_1.getTransactionDetailKey)(transactionId);
139
- const detail = (0, transactionSelector_1.getSupportedTransactionById)(transactionState, transactionId.id // entity store uses full zeni ID as canonical key
140
- );
135
+ const detail = (0, transactionSelector_1.getSupportedTransactionById)(transactionState, transactionDetailKey);
141
136
  const tranDetail = (0, get_1.default)(transactionDetailState.transactionDetailById, transactionDetailKey, undefined);
142
137
  const tranVendorUpdates = tranDetail?.transactionDetailLocalData.vendorUpdates;
143
138
  const tranCustomerUpdates = tranDetail?.transactionDetailLocalData.customerUpdates;
@@ -7,13 +7,14 @@ const snackbarReducer_1 = require("../../../entity/snackbar/snackbarReducer");
7
7
  const transactionIDPayload_1 = require("../../../entity/transaction/payloadTypes/transactionIDPayload");
8
8
  const transactionReducer_1 = require("../../../entity/transaction/transactionReducer");
9
9
  const transactionDetailReducer_1 = require("../transactionDetailReducer");
10
+ const transactionDetailState_1 = require("../transactionDetailState");
10
11
  const uploadMissingAttachmentSuccessEpic = (actions$) => actions$.pipe((0, operators_1.filter)(transactionDetailReducer_1.uploadMissingAttachmentSuccess.match), (0, operators_1.switchMap)((action) => {
11
12
  const transactionId = (0, transactionIDPayload_1.toTransactionID)(action.payload.payload);
13
+ const transactionDetailKeyForResponse = (0, transactionDetailState_1.getTransactionDetailKey)(transactionId);
12
14
  return (0, rxjs_1.of)((0, snackbarReducer_1.openSnackbar)({
13
15
  messageSection: 'receipts_upload',
14
16
  messageText: 'success',
15
17
  type: 'success',
16
- }), (0, transactionReducer_1.updateTransaction)(transactionId.id, // entity store uses full zeni ID as canonical key
17
- action.payload.payload));
18
+ }), (0, transactionReducer_1.updateTransaction)(transactionDetailKeyForResponse, action.payload.payload));
18
19
  }));
19
20
  exports.uploadMissingAttachmentSuccessEpic = uploadMissingAttachmentSuccessEpic;
@@ -23,8 +23,7 @@ const getTransactionDetail = (state, transactionId, fetchLinkedTransactions = tr
23
23
  fetchState: transactionDetail?.fetchState ?? 'Not-Started',
24
24
  error: transactionDetail?.error,
25
25
  };
26
- const transaction = (0, transactionSelector_1.getSupportedTransactionById)(transactionState, transactionId.id // entity store uses full zeni ID as canonical key
27
- );
26
+ const transaction = (0, transactionSelector_1.getSupportedTransactionById)(transactionState, detailKey);
28
27
  let linkedTransactions = [];
29
28
  if (transactionDetail?.fetchState === 'Completed' && transaction != null) {
30
29
  // IMPORTANT: filtering out unsupported linked transactions
@@ -44,9 +43,8 @@ const getTransactionDetail = (state, transactionId, fetchLinkedTransactions = tr
44
43
  linkedTransactionsFetchState.fetchState === 'Completed') {
45
44
  linkedTransactions = linkedTransactionDetails
46
45
  .map((linkedTranDetail) => {
47
- const linkedTranId = linkedTranDetail.transactionId; // eslint-disable-line @typescript-eslint/no-non-null-assertion
48
- return (0, transactionSelector_1.getSupportedTransactionById)(transactionState, linkedTranId.id // entity store uses full zeni ID as canonical key
49
- );
46
+ const key = (0, transactionDetailState_1.getTransactionDetailKey)(linkedTranDetail.transactionId); // eslint-disable-line @typescript-eslint/no-non-null-assertion
47
+ return (0, transactionSelector_1.getSupportedTransactionById)(transactionState, key);
50
48
  })
51
49
  .filter((value) => {
52
50
  if (value == null) {
@@ -11,7 +11,7 @@ import { TransactionDetailLocalData } from './transactionDetailTypes';
11
11
  export declare const getTransactionDetailKey: (transactionId: TransactionID) => `${string}_bill` | `${string}_expense` | `${string}_check` | `${string}_refund` | `${string}_invoice` | `${string}_payment` | `${string}_credit_memo` | `${string}_sales_receipt` | `${string}_delayed_credit` | `${string}_delayed_charge` | `${string}_bill_payment` | `${string}_bill_payment_check` | `${string}_bill_payment_credit_card` | `${string}_vendor_credit` | `${string}_credit_card_credit` | `${string}_transfer` | `${string}_credit_card_payment` | `${string}_deposit` | `${string}_journal_entry`;
12
12
  export type TransactionDetailKey = ReturnType<typeof getTransactionDetailKey>;
13
13
  export declare const getZeniTransactionDetailKey: (transactionId: TransactionID) => `${string}_bill` | `${string}_expense` | `${string}_check` | `${string}_refund` | `${string}_invoice` | `${string}_payment` | `${string}_credit_memo` | `${string}_sales_receipt` | `${string}_delayed_credit` | `${string}_delayed_charge` | `${string}_bill_payment` | `${string}_bill_payment_check` | `${string}_bill_payment_credit_card` | `${string}_vendor_credit` | `${string}_credit_card_credit` | `${string}_transfer` | `${string}_credit_card_payment` | `${string}_deposit` | `${string}_journal_entry`;
14
- export type ZeniTransactionDetailKey = ReturnType<typeof getZeniTransactionDetailKey>;
14
+ export type ZeniTransactionDetailKey = ReturnType<typeof getTransactionDetailKey>;
15
15
  export declare const getThirdPartyIdFromTransactionId: (transactionId: TransactionID) => string;
16
16
  /**
17
17
  * Returns actual QBO transaction ID.
@@ -2,22 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.initialSupportedTransactionDetail = exports.getActualTransactionID = exports.getThirdPartyIdFromTransactionId = exports.getZeniTransactionDetailKey = exports.getTransactionDetailKey = void 0;
4
4
  exports.getAllLinkedTransactions = getAllLinkedTransactions;
5
- // TWO-KEY SYSTEM — read before touching transaction lookups:
6
- //
7
- // 1. transactionDetailState.transactionDetailById → keyed by getTransactionDetailKey()
8
- // Format: "<qbo_id>_<type>" (strips the "tran_<uuid>:" prefix)
9
- // Used by: all transactionDetail epics/selectors for detail metadata (fetch state, local data, etc.)
10
- //
11
- // 2. transactionState.transactionById → keyed by transactionId.id (full zeni ID, e.g. "tran_<uuid>:<qbo_id>")
12
- // Used by: all list-fetch epics, getSupportedTransactionById, and all entity store reads/writes
13
- //
14
- // IMPORTANT: Never use getTransactionDetailKey() to look up or remove from transactionState.
15
- // Always use transactionId.id for the entity store.
16
- // Produces the transactionDetailState key: "<qbo_id>_<type>"
5
+ // This transaction key only extracts the third party ID and uses that
6
+ // for the ID
17
7
  const getTransactionDetailKey = (transactionId) => `${(0, exports.getActualTransactionID)(transactionId.id)}_${transactionId.type}`;
18
8
  exports.getTransactionDetailKey = getTransactionDetailKey;
19
- // Produces the full-zeni-ID-based key: "<tran_uuid:qbo_id>_<type>"
20
- // Note: this key format is not used by the entity store (which uses transactionId.id directly).
21
9
  const getZeniTransactionDetailKey = (transactionId) => `${transactionId.id}_${transactionId.type}`;
22
10
  exports.getZeniTransactionDetailKey = getZeniTransactionDetailKey;
23
11
  const getThirdPartyIdFromTransactionId = (transactionId) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeniai/client-epic-state",
3
- "version": "4.19.77-betaAK8",
3
+ "version": "4.19.77-betaAS2",
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",