@zeniai/client-epic-state 5.0.96 → 5.0.97

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 (272) hide show
  1. package/lib/common/aiCfo/aiCfoSuggestedQuestionsPageContext.d.ts +1 -1
  2. package/lib/commonStateTypes/amount.d.ts +1 -0
  3. package/lib/commonStateTypes/amount.js +9 -1
  4. package/lib/commonStateTypes/workingDayHelper.d.ts +9 -0
  5. package/lib/commonStateTypes/workingDayHelper.js +28 -1
  6. package/lib/entity/aiCfo/aiCfoPayload.d.ts +63 -5
  7. package/lib/entity/aiCfo/aiCfoReducer.d.ts +23 -2
  8. package/lib/entity/aiCfo/aiCfoReducer.js +249 -9
  9. package/lib/entity/aiCfo/aiCfoSelector.d.ts +4 -1
  10. package/lib/entity/aiCfo/aiCfoSelector.js +19 -1
  11. package/lib/entity/aiCfo/aiCfoState.d.ts +97 -4
  12. package/lib/entity/aiCfo/aiCfoState.js +18 -1
  13. package/lib/entity/cardPolicy/cardPolicyPayload.d.ts +277 -0
  14. package/lib/entity/cardPolicy/cardPolicyPayload.js +143 -0
  15. package/lib/entity/cardPolicy/cardPolicyReducer.d.ts +19 -0
  16. package/lib/entity/cardPolicy/cardPolicyReducer.js +175 -0
  17. package/lib/entity/cardPolicy/cardPolicySelector.d.ts +32 -0
  18. package/lib/entity/cardPolicy/cardPolicySelector.js +99 -0
  19. package/lib/entity/cardPolicy/cardPolicyState.d.ts +205 -0
  20. package/lib/entity/cardPolicy/cardPolicyState.js +14 -0
  21. package/lib/entity/cardPolicy/extractPolicyDocumentEpic.d.ts +18 -0
  22. package/lib/entity/cardPolicy/extractPolicyDocumentEpic.js +68 -0
  23. package/lib/entity/cardPolicy/fetchCardPolicyVendorOptionsEpic.d.ts +26 -0
  24. package/lib/entity/cardPolicy/fetchCardPolicyVendorOptionsEpic.js +47 -0
  25. package/lib/entity/cardPolicy/policyDocumentExtractionToRecommendationBridgeEpic.d.ts +25 -0
  26. package/lib/entity/cardPolicy/policyDocumentExtractionToRecommendationBridgeEpic.js +39 -0
  27. package/lib/entity/cardPolicy/policyRecommendationFromUploadEpic.d.ts +24 -0
  28. package/lib/entity/cardPolicy/policyRecommendationFromUploadEpic.js +105 -0
  29. package/lib/entity/jeSchedules/jeSchedulesPayload.d.ts +1 -0
  30. package/lib/entity/jeSchedules/jeSchedulesPayload.js +7 -0
  31. package/lib/entity/jeSchedules/jeSchedulesState.d.ts +2 -0
  32. package/lib/entity/jeSchedules/jeSchedulesTypes.d.ts +1 -1
  33. package/lib/entity/monthEndCloseChecks/monthEndCloseChecksState.d.ts +1 -1
  34. package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
  35. package/lib/entity/snackbar/snackbarTypes.js +3 -0
  36. package/lib/entity/task/taskPayload.d.ts +3 -1
  37. package/lib/entity/task/taskPayload.js +2 -0
  38. package/lib/entity/task/taskState.d.ts +2 -0
  39. package/lib/entity/tenant/clearAllEpic.d.ts +8 -2
  40. package/lib/entity/tenant/clearAllEpic.js +12 -0
  41. package/lib/epic.d.ts +24 -3
  42. package/lib/epic.js +24 -3
  43. package/lib/esm/commonStateTypes/amount.js +7 -0
  44. package/lib/esm/commonStateTypes/workingDayHelper.js +26 -0
  45. package/lib/esm/entity/aiCfo/aiCfoReducer.js +249 -9
  46. package/lib/esm/entity/aiCfo/aiCfoSelector.js +17 -1
  47. package/lib/esm/entity/aiCfo/aiCfoState.js +15 -0
  48. package/lib/esm/entity/cardPolicy/cardPolicyPayload.js +130 -0
  49. package/lib/esm/entity/cardPolicy/cardPolicyReducer.js +171 -0
  50. package/lib/esm/entity/cardPolicy/cardPolicySelector.js +75 -0
  51. package/lib/esm/entity/cardPolicy/cardPolicyState.js +9 -0
  52. package/lib/esm/entity/cardPolicy/extractPolicyDocumentEpic.js +64 -0
  53. package/lib/esm/entity/cardPolicy/fetchCardPolicyVendorOptionsEpic.js +43 -0
  54. package/lib/esm/entity/cardPolicy/policyDocumentExtractionToRecommendationBridgeEpic.js +35 -0
  55. package/lib/esm/entity/cardPolicy/policyRecommendationFromUploadEpic.js +101 -0
  56. package/lib/esm/entity/jeSchedules/jeSchedulesPayload.js +7 -0
  57. package/lib/esm/entity/snackbar/snackbarTypes.js +3 -0
  58. package/lib/esm/entity/task/taskPayload.js +2 -0
  59. package/lib/esm/entity/tenant/clearAllEpic.js +12 -0
  60. package/lib/esm/epic.js +24 -3
  61. package/lib/esm/index.js +47 -12
  62. package/lib/esm/reducer.js +18 -0
  63. package/lib/esm/view/aiCfoView/aiCfoViewReducer.js +6 -3
  64. package/lib/esm/view/aiCfoView/epics/createSessionAndSubmitEpic.js +5 -2
  65. package/lib/esm/view/aiCfoView/epics/createSessionEpic.js +2 -1
  66. package/lib/esm/view/aiCfoView/epics/fetchSuggestedQuestionsEpic.js +12 -2
  67. package/lib/esm/view/companyTaskManagerView/companyTaskManagerViewReducer.js +39 -11
  68. package/lib/esm/view/companyTaskManagerView/companyTaskManagerViewSelector.js +14 -4
  69. package/lib/esm/view/companyTaskManagerView/epics/fetchCockpitContextEpic.js +38 -0
  70. package/lib/esm/view/companyTaskManagerView/epics/fetchCompanyTaskManagerViewEpic.js +37 -28
  71. package/lib/esm/view/companyTaskManagerView/epics/updateCompanyTaskManagerViewFiltersEpic.js +16 -0
  72. package/lib/esm/view/companyView/epic/fetchAllCockpitViewsEpic.js +2 -2
  73. package/lib/esm/view/spendManagement/autotransferRules/autoTransferRulesSelector.js +22 -2
  74. package/lib/esm/view/spendManagement/cashManagement/autoSweepFlow/autoSweepFlowPayload.js +29 -0
  75. package/lib/esm/view/spendManagement/cashManagement/autoSweepFlow/autoSweepFlowReducer.js +78 -0
  76. package/lib/esm/view/spendManagement/cashManagement/autoSweepFlow/autoSweepFlowSelector.js +47 -0
  77. package/lib/esm/view/spendManagement/cashManagement/autoSweepFlow/autoSweepFlowState.js +47 -0
  78. package/lib/esm/view/spendManagement/cashManagement/autoSweepFlow/epics/fetchCashManagementSettingsEpic.js +34 -0
  79. package/lib/esm/view/spendManagement/cashManagement/autoSweepFlow/epics/saveAutoSweepSettingsEpic.js +32 -0
  80. package/lib/esm/view/spendManagement/cashManagement/cashManagementOverview/cashManagementOverviewPayload.js +54 -0
  81. package/lib/esm/view/spendManagement/cashManagement/cashManagementOverview/cashManagementOverviewReducer.js +92 -0
  82. package/lib/esm/view/spendManagement/cashManagement/cashManagementOverview/cashManagementOverviewSelector.js +225 -0
  83. package/lib/esm/view/spendManagement/cashManagement/cashManagementOverview/cashManagementOverviewState.js +10 -0
  84. package/lib/esm/view/spendManagement/cashManagement/cashManagementOverview/epics/fetchCashManagementBannerEpic.js +23 -0
  85. package/lib/esm/view/spendManagement/cashManagement/cashManagementOverview/epics/fetchCashManagementOverviewPageEpic.js +36 -0
  86. package/lib/esm/view/spendManagement/cashManagement/cashManagementOverview/epics/fetchCashManagementRecommendationEpic.js +27 -0
  87. package/lib/esm/view/spendManagement/cashManagement/cashManagementOverview/epics/fetchRecentTransferEpic.js +28 -0
  88. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailReducer.js +52 -0
  89. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailSelector.js +22 -0
  90. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailState.js +1 -0
  91. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/fetchCardPolicyDetailEpic.js +36 -0
  92. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/updateCardPolicyEpic.js +39 -0
  93. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/archiveCardPolicyEpic.js +34 -0
  94. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListReducer.js +58 -0
  95. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListSelector.js +21 -0
  96. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListState.js +1 -0
  97. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/fetchCardPolicyListEpic.js +38 -0
  98. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyAiCardPolicyFormDraftUpdate.js +289 -0
  99. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyExtractedPolicyToAiCardPolicyDraft.js +109 -0
  100. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyExtractedPolicyToDraftEpic.js +44 -0
  101. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyExtractedPolicyToManualCardPolicyDraft.js +111 -0
  102. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyUploadPlanToAiCardPolicyDraft.js +25 -0
  103. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/buildAiCardPolicyFormDraftSeed.js +363 -0
  104. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/buildManualCardPolicyFormDraftSeed.js +36 -0
  105. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/cardPolicyChipIds.js +19 -0
  106. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/cardPolicyFormDraftTypes.js +6 -0
  107. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/cardPolicyRequestParts.js +119 -0
  108. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyReducer.js +154 -0
  109. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicySelector.js +22 -0
  110. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyState.js +1 -0
  111. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyTemplateEpic.js +39 -0
  112. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/deriveAiPolicyReviewRowsFromInputs.js +140 -0
  113. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/fetchCardPolicyMccCategoriesEpic.js +20 -0
  114. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/seedAiCardPolicyFormDraftEpic.js +100 -0
  115. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/toBulkCardPolicyTemplateRequestsFromDraft.js +96 -0
  116. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/toCardPolicyTemplateRequestFromDraft.js +59 -0
  117. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/toManualCardPolicyTemplateRequestFromDraft.js +24 -0
  118. package/lib/esm/view/spendManagement/chargeCards/chargeCardList/chargeCardListSelector.js +25 -0
  119. package/lib/esm/view/spendManagement/chargeCards/issueChargeCard/aiCardCreationFormDraftTypes.js +1 -0
  120. package/lib/esm/view/spendManagement/chargeCards/issueChargeCard/applyAiCardCreationFormDraftUpdate.js +34 -0
  121. package/lib/esm/view/spendManagement/chargeCards/issueChargeCard/buildAiCardCreationFormDraftSeed.js +57 -0
  122. package/lib/esm/view/spendManagement/chargeCards/issueChargeCard/deriveAiCardRowsFromTeams.js +35 -0
  123. package/lib/esm/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardEpic.js +2 -2
  124. package/lib/esm/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardReducer.js +42 -4
  125. package/lib/esm/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardSelector.js +35 -0
  126. package/lib/esm/view/spendManagement/chargeCards/issueChargeCard/seedAiCardCreationFormDraftEpic.js +62 -0
  127. package/lib/esm/view/spendManagement/chargeCards/issueChargeCard/toIssueChargeCardLocalDataFromDraft.js +44 -0
  128. package/lib/index.d.ts +59 -15
  129. package/lib/index.js +213 -22
  130. package/lib/reducer.d.ts +18 -0
  131. package/lib/reducer.js +18 -0
  132. package/lib/view/aiCfoView/aiCfoViewReducer.d.ts +11 -2
  133. package/lib/view/aiCfoView/aiCfoViewReducer.js +6 -3
  134. package/lib/view/aiCfoView/epics/createSessionAndSubmitEpic.js +5 -2
  135. package/lib/view/aiCfoView/epics/createSessionEpic.js +2 -1
  136. package/lib/view/aiCfoView/epics/fetchSuggestedQuestionsEpic.d.ts +8 -1
  137. package/lib/view/aiCfoView/epics/fetchSuggestedQuestionsEpic.js +12 -2
  138. package/lib/view/companyTaskManagerView/companyTaskManagerViewPayload.d.ts +19 -11
  139. package/lib/view/companyTaskManagerView/companyTaskManagerViewReducer.d.ts +10 -4
  140. package/lib/view/companyTaskManagerView/companyTaskManagerViewReducer.js +40 -12
  141. package/lib/view/companyTaskManagerView/companyTaskManagerViewSelector.d.ts +2 -0
  142. package/lib/view/companyTaskManagerView/companyTaskManagerViewSelector.js +13 -3
  143. package/lib/view/companyTaskManagerView/companyTaskManagerViewState.d.ts +11 -3
  144. package/lib/view/companyTaskManagerView/epics/fetchCockpitContextEpic.d.ts +10 -0
  145. package/lib/view/companyTaskManagerView/epics/fetchCockpitContextEpic.js +42 -0
  146. package/lib/view/companyTaskManagerView/epics/fetchCompanyTaskManagerViewEpic.d.ts +1 -3
  147. package/lib/view/companyTaskManagerView/epics/fetchCompanyTaskManagerViewEpic.js +37 -28
  148. package/lib/view/companyTaskManagerView/epics/updateCompanyTaskManagerViewFiltersEpic.d.ts +6 -0
  149. package/lib/view/companyTaskManagerView/epics/updateCompanyTaskManagerViewFiltersEpic.js +20 -0
  150. package/lib/view/companyView/epic/fetchAllCockpitViewsEpic.js +2 -2
  151. package/lib/view/companyView/types/cockpitTypes.d.ts +2 -1
  152. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
  153. package/lib/view/expenseAutomationView/types/reconciliationViewState.d.ts +1 -1
  154. package/lib/view/people/peopleTypes.d.ts +1 -1
  155. package/lib/view/scheduleView/scheduleListView/scheduleListTypes.d.ts +1 -1
  156. package/lib/view/spendManagement/autotransferRules/autoTransferRulesSelector.d.ts +8 -1
  157. package/lib/view/spendManagement/autotransferRules/autoTransferRulesSelector.js +21 -1
  158. package/lib/view/spendManagement/autotransferRules/autoTransferRulesState.d.ts +22 -0
  159. package/lib/view/spendManagement/cashManagement/autoSweepFlow/autoSweepFlowPayload.d.ts +47 -0
  160. package/lib/view/spendManagement/cashManagement/autoSweepFlow/autoSweepFlowPayload.js +34 -0
  161. package/lib/view/spendManagement/cashManagement/autoSweepFlow/autoSweepFlowReducer.d.ts +23 -0
  162. package/lib/view/spendManagement/cashManagement/autoSweepFlow/autoSweepFlowReducer.js +82 -0
  163. package/lib/view/spendManagement/cashManagement/autoSweepFlow/autoSweepFlowSelector.d.ts +40 -0
  164. package/lib/view/spendManagement/cashManagement/autoSweepFlow/autoSweepFlowSelector.js +51 -0
  165. package/lib/view/spendManagement/cashManagement/autoSweepFlow/autoSweepFlowState.d.ts +37 -0
  166. package/lib/view/spendManagement/cashManagement/autoSweepFlow/autoSweepFlowState.js +53 -0
  167. package/lib/view/spendManagement/cashManagement/autoSweepFlow/epics/fetchCashManagementSettingsEpic.d.ts +14 -0
  168. package/lib/view/spendManagement/cashManagement/autoSweepFlow/epics/fetchCashManagementSettingsEpic.js +38 -0
  169. package/lib/view/spendManagement/cashManagement/autoSweepFlow/epics/saveAutoSweepSettingsEpic.d.ts +7 -0
  170. package/lib/view/spendManagement/cashManagement/autoSweepFlow/epics/saveAutoSweepSettingsEpic.js +36 -0
  171. package/lib/view/spendManagement/cashManagement/cashManagementOverview/cashManagementOverviewPayload.d.ts +56 -0
  172. package/lib/view/spendManagement/cashManagement/cashManagementOverview/cashManagementOverviewPayload.js +60 -0
  173. package/lib/view/spendManagement/cashManagement/cashManagementOverview/cashManagementOverviewReducer.d.ts +22 -0
  174. package/lib/view/spendManagement/cashManagement/cashManagementOverview/cashManagementOverviewReducer.js +96 -0
  175. package/lib/view/spendManagement/cashManagement/cashManagementOverview/cashManagementOverviewSelector.d.ts +59 -0
  176. package/lib/view/spendManagement/cashManagement/cashManagementOverview/cashManagementOverviewSelector.js +230 -0
  177. package/lib/view/spendManagement/cashManagement/cashManagementOverview/cashManagementOverviewState.d.ts +122 -0
  178. package/lib/view/spendManagement/cashManagement/cashManagementOverview/cashManagementOverviewState.js +13 -0
  179. package/lib/view/spendManagement/cashManagement/cashManagementOverview/epics/fetchCashManagementBannerEpic.d.ts +7 -0
  180. package/lib/view/spendManagement/cashManagement/cashManagementOverview/epics/fetchCashManagementBannerEpic.js +27 -0
  181. package/lib/view/spendManagement/cashManagement/cashManagementOverview/epics/fetchCashManagementOverviewPageEpic.d.ts +9 -0
  182. package/lib/view/spendManagement/cashManagement/cashManagementOverview/epics/fetchCashManagementOverviewPageEpic.js +40 -0
  183. package/lib/view/spendManagement/cashManagement/cashManagementOverview/epics/fetchCashManagementRecommendationEpic.d.ts +7 -0
  184. package/lib/view/spendManagement/cashManagement/cashManagementOverview/epics/fetchCashManagementRecommendationEpic.js +31 -0
  185. package/lib/view/spendManagement/cashManagement/cashManagementOverview/epics/fetchRecentTransferEpic.d.ts +15 -0
  186. package/lib/view/spendManagement/cashManagement/cashManagementOverview/epics/fetchRecentTransferEpic.js +32 -0
  187. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailReducer.d.ts +14 -0
  188. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailReducer.js +56 -0
  189. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailSelector.d.ts +15 -0
  190. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailSelector.js +28 -0
  191. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailState.d.ts +8 -0
  192. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailState.js +2 -0
  193. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/fetchCardPolicyDetailEpic.d.ts +8 -0
  194. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/fetchCardPolicyDetailEpic.js +40 -0
  195. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/updateCardPolicyEpic.d.ts +8 -0
  196. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/updateCardPolicyEpic.js +43 -0
  197. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/archiveCardPolicyEpic.d.ts +8 -0
  198. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/archiveCardPolicyEpic.js +38 -0
  199. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListReducer.d.ts +15 -0
  200. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListReducer.js +62 -0
  201. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListSelector.d.ts +15 -0
  202. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListSelector.js +27 -0
  203. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListState.d.ts +7 -0
  204. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListState.js +2 -0
  205. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/fetchCardPolicyListEpic.d.ts +8 -0
  206. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/fetchCardPolicyListEpic.js +42 -0
  207. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyAiCardPolicyFormDraftUpdate.d.ts +8 -0
  208. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyAiCardPolicyFormDraftUpdate.js +294 -0
  209. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyExtractedPolicyToAiCardPolicyDraft.d.ts +8 -0
  210. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyExtractedPolicyToAiCardPolicyDraft.js +113 -0
  211. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyExtractedPolicyToDraftEpic.d.ts +9 -0
  212. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyExtractedPolicyToDraftEpic.js +48 -0
  213. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyExtractedPolicyToManualCardPolicyDraft.d.ts +8 -0
  214. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyExtractedPolicyToManualCardPolicyDraft.js +115 -0
  215. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyUploadPlanToAiCardPolicyDraft.d.ts +13 -0
  216. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/applyUploadPlanToAiCardPolicyDraft.js +29 -0
  217. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/buildAiCardPolicyFormDraftSeed.d.ts +14 -0
  218. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/buildAiCardPolicyFormDraftSeed.js +369 -0
  219. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/buildManualCardPolicyFormDraftSeed.d.ts +6 -0
  220. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/buildManualCardPolicyFormDraftSeed.js +40 -0
  221. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/cardPolicyChipIds.d.ts +7 -0
  222. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/cardPolicyChipIds.js +26 -0
  223. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/cardPolicyFormDraftTypes.d.ts +116 -0
  224. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/cardPolicyFormDraftTypes.js +10 -0
  225. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/cardPolicyRequestParts.d.ts +33 -0
  226. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/cardPolicyRequestParts.js +126 -0
  227. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyReducer.d.ts +52 -0
  228. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyReducer.js +158 -0
  229. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicySelector.d.ts +11 -0
  230. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicySelector.js +31 -0
  231. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyState.d.ts +12 -0
  232. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyState.js +2 -0
  233. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyTemplateEpic.d.ts +8 -0
  234. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyTemplateEpic.js +43 -0
  235. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/deriveAiPolicyReviewRowsFromInputs.d.ts +10 -0
  236. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/deriveAiPolicyReviewRowsFromInputs.js +144 -0
  237. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/fetchCardPolicyMccCategoriesEpic.d.ts +7 -0
  238. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/fetchCardPolicyMccCategoriesEpic.js +24 -0
  239. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/seedAiCardPolicyFormDraftEpic.d.ts +11 -0
  240. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/seedAiCardPolicyFormDraftEpic.js +104 -0
  241. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/toBulkCardPolicyTemplateRequestsFromDraft.d.ts +22 -0
  242. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/toBulkCardPolicyTemplateRequestsFromDraft.js +100 -0
  243. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/toCardPolicyTemplateRequestFromDraft.d.ts +8 -0
  244. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/toCardPolicyTemplateRequestFromDraft.js +63 -0
  245. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/toManualCardPolicyTemplateRequestFromDraft.d.ts +3 -0
  246. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/toManualCardPolicyTemplateRequestFromDraft.js +28 -0
  247. package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardList.d.ts +1 -1
  248. package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardListSelector.d.ts +14 -0
  249. package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardListSelector.js +27 -1
  250. package/lib/view/spendManagement/chargeCards/issueChargeCard/aiCardCreationFormDraftTypes.d.ts +34 -0
  251. package/lib/view/spendManagement/chargeCards/issueChargeCard/aiCardCreationFormDraftTypes.js +2 -0
  252. package/lib/view/spendManagement/chargeCards/issueChargeCard/applyAiCardCreationFormDraftUpdate.d.ts +7 -0
  253. package/lib/view/spendManagement/chargeCards/issueChargeCard/applyAiCardCreationFormDraftUpdate.js +38 -0
  254. package/lib/view/spendManagement/chargeCards/issueChargeCard/buildAiCardCreationFormDraftSeed.d.ts +12 -0
  255. package/lib/view/spendManagement/chargeCards/issueChargeCard/buildAiCardCreationFormDraftSeed.js +61 -0
  256. package/lib/view/spendManagement/chargeCards/issueChargeCard/deriveAiCardRowsFromTeams.d.ts +9 -0
  257. package/lib/view/spendManagement/chargeCards/issueChargeCard/deriveAiCardRowsFromTeams.js +39 -0
  258. package/lib/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardEpic.d.ts +2 -2
  259. package/lib/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardEpic.js +1 -1
  260. package/lib/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardReducer.d.ts +12 -2
  261. package/lib/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardReducer.js +43 -5
  262. package/lib/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardSelector.d.ts +7 -0
  263. package/lib/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardSelector.js +42 -1
  264. package/lib/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardState.d.ts +5 -0
  265. package/lib/view/spendManagement/chargeCards/issueChargeCard/seedAiCardCreationFormDraftEpic.d.ts +11 -0
  266. package/lib/view/spendManagement/chargeCards/issueChargeCard/seedAiCardCreationFormDraftEpic.js +66 -0
  267. package/lib/view/spendManagement/chargeCards/issueChargeCard/toIssueChargeCardLocalDataFromDraft.d.ts +3 -0
  268. package/lib/view/spendManagement/chargeCards/issueChargeCard/toIssueChargeCardLocalDataFromDraft.js +48 -0
  269. package/lib/view/taskManager/taskListView/taskListReducer.d.ts +1 -1
  270. package/lib/view/transactionDetail/journalEntryLinesViewModel.d.ts +1 -1
  271. package/lib/zeniAPI.d.ts +1 -0
  272. package/package.json +1 -1
@@ -1,9 +1,10 @@
1
1
  import { createSlice } from '@reduxjs/toolkit';
2
2
  import { date as zeniDate } from '../../zeniDayJS';
3
- import { ALL_AI_CFO_ANSWER_RESPONSE_TYPES, toAiCfoAnswerResponseType, toAiCfoAnswerResponseTypeStrict, toAiCfoAnswerStateType, toAiCfoVisualizationTypeStrict, toMessageSender, toMessageType, toYFormatScaleStrict, toYFormatTypeStrict, toYFormatUnitStrict, } from './aiCfoState';
3
+ import { ALL_AI_CFO_ANSWER_RESPONSE_TYPES, toAiCfoAnswerResponseType, toAiCfoAnswerResponseTypeStrict, toAiCfoAnswerStateType, toAiCfoVisualizationTypeStrict, toInteractiveFormTypeStrict, toMessageSender, toMessageType, toYFormatScaleStrict, toYFormatTypeStrict, toYFormatUnitStrict, } from './aiCfoState';
4
4
  export const initialAiCfoState = {
5
5
  aiCfoByChatSessionId: {},
6
6
  partialQuestionAnswers: {},
7
+ syntheticAnswersByChatSessionId: {},
7
8
  };
8
9
  // Utility: Merge two arrays of Q&A pairs, combining responses for the same question
9
10
  function mergeQuestionAnswerPairs(existing, newQAs) {
@@ -136,9 +137,171 @@ export const toAiCfoVisualization = (visualization) => {
136
137
  if (visualization.type == null || visualization.data == null) {
137
138
  return undefined;
138
139
  }
140
+ // Reject unknown viz types; `?? 'table'` used to throw in the chart/table decoder
141
+ // when interactive-form payloads (no `values`) hit it.
142
+ const normalizedType = toAiCfoVisualizationTypeStrict(visualization.type);
143
+ if (normalizedType == null) {
144
+ return undefined;
145
+ }
146
+ return {
147
+ type: normalizedType,
148
+ data: normalizedType === 'interactive_form'
149
+ ? toInteractiveFormVisualization(visualization.data)
150
+ : toAiCfoVisualizationData(visualization.data),
151
+ };
152
+ };
153
+ const toInteractiveFormVisualization = (data) => {
154
+ // When `form_type` is missing / mistyped, infer from payload shape so a malformed
155
+ // card-policy answer doesn't get decoded as cards_creation (wrong form + submit path).
156
+ const formType = toInteractiveFormTypeStrict(data.form_type) ??
157
+ inferInteractiveFormTypeFromPayload(data.payload);
158
+ if (formType === 'card_policy') {
159
+ return {
160
+ formType: 'card_policy',
161
+ payload: toCardPolicyInitialData(data.payload),
162
+ };
163
+ }
164
+ return {
165
+ formType: 'cards_creation',
166
+ payload: toCardsCreationInitialData(data.payload),
167
+ };
168
+ };
169
+ const inferInteractiveFormTypeFromPayload = (payload) => {
170
+ if (payload != null && typeof payload === 'object' && 'mode' in payload) {
171
+ const mode = payload.mode;
172
+ if (mode === 'auto' || mode === 'guided' || mode === 'upload') {
173
+ return 'card_policy';
174
+ }
175
+ }
176
+ return 'cards_creation';
177
+ };
178
+ const toCardsCreationInitialData = (payload) => {
179
+ const suggestedCards = payload.suggested_cards ?? [];
180
+ const ordered = [...suggestedCards].sort((a, b) => KIND_RANK[a.card_type] - KIND_RANK[b.card_type]);
181
+ const withUniqueIds = withSynthesizedIds(ordered);
182
+ const suggestedOnly = withUniqueIds.filter(({ card }) => card.is_suggested);
183
+ const cardNameOptions = withUniqueIds.map(({ card, uniqueId }) => ({
184
+ id: uniqueId,
185
+ kind: toCardKind(card.card_type),
186
+ label: card.card_name,
187
+ }));
188
+ const suggestedOwnerUserIdByTeamId = Object.fromEntries(suggestedOnly.map(({ card, uniqueId }) => [
189
+ uniqueId,
190
+ normalizeOwnerId(card.owner_id),
191
+ ]));
192
+ const common = {
193
+ cardNameOptions,
194
+ suggestedOwnerUserIdByTeamId,
195
+ };
196
+ if (payload.mode === 'create') {
197
+ return {
198
+ ...common,
199
+ mode: 'create',
200
+ cardRows: suggestedOnly.map(({ card, uniqueId }) => ({
201
+ cardKind: toCardKind(card.card_type),
202
+ id: uniqueId,
203
+ label: card.card_name,
204
+ recommendedLimit: card.credit_limit > 0 ? card.credit_limit : undefined,
205
+ suggestedOwnerUserId: normalizeOwnerId(card.owner_id),
206
+ })),
207
+ };
208
+ }
139
209
  return {
140
- type: toAiCfoVisualizationTypeStrict(visualization.type) ?? 'table',
141
- data: toAiCfoVisualizationData(visualization.data),
210
+ ...common,
211
+ mode: 'review',
212
+ teamRows: suggestedOnly.map(({ card, uniqueId }) => ({
213
+ avgMonthlySpend: CURRENCY_FORMATTER.format(card.avg_spend),
214
+ cardKind: toCardKind(card.card_type),
215
+ id: uniqueId,
216
+ label: card.card_name,
217
+ recommendedLimit: CURRENCY_FORMATTER.format(card.credit_limit),
218
+ recommendedLimitCadence: 'Monthly',
219
+ })),
220
+ };
221
+ };
222
+ const CURRENCY_FORMATTER = new Intl.NumberFormat('en-US', {
223
+ style: 'currency',
224
+ currency: 'USD',
225
+ maximumFractionDigits: 0,
226
+ });
227
+ // BE emits `null` or `""` for "no owner picked"; collapse both to `undefined`.
228
+ const normalizeOwnerId = (ownerId) => (ownerId != null && ownerId !== '' ? ownerId : undefined);
229
+ const KIND_RANK = {
230
+ vendor: 0,
231
+ category: 1,
232
+ department: 2,
233
+ };
234
+ const toCardKind = (cardType) => {
235
+ if (cardType === 'department') {
236
+ return 'class';
237
+ }
238
+ if (cardType === 'category') {
239
+ return 'category';
240
+ }
241
+ return 'vendor';
242
+ };
243
+ // Falls back to `${kind}__${card_name_id}__${index}` when `card_name_id` collides
244
+ // (sample payloads ship the literal `"vendor_uuid"`), to keep RHF row keys unique.
245
+ const withSynthesizedIds = (cards) => {
246
+ const seen = new Set();
247
+ return cards.map((card, index) => {
248
+ const preferred = card.card_name_id;
249
+ if (preferred != null && preferred !== '' && !seen.has(preferred)) {
250
+ seen.add(preferred);
251
+ return { card, uniqueId: preferred };
252
+ }
253
+ const synthesized = `${card.card_type}__${preferred ?? 'unknown'}__${index}`;
254
+ seen.add(synthesized);
255
+ return { card, uniqueId: synthesized };
256
+ });
257
+ };
258
+ const toCardPolicyDraftPolicy = (payload, index) => ({
259
+ id: `draft-${index}`,
260
+ name: payload.name,
261
+ description: payload.description ?? '',
262
+ mode: payload.mode,
263
+ allowedEntity: {
264
+ categoryCodes: payload.allowed_entity?.category_codes ?? [],
265
+ merchantNames: payload.allowed_entity?.merchant_names ?? [],
266
+ },
267
+ blockedEntity: {
268
+ categoryCodes: payload.blocked_entity?.category_codes ?? [],
269
+ merchantNames: payload.blocked_entity?.merchant_names ?? [],
270
+ },
271
+ applyToCards: payload.apply_to_cards ?? [],
272
+ requiredReceiptThreshold: payload.required_receipt_threshold ?? 0,
273
+ spendLimits: {
274
+ transaction: payload.spend_limits?.transaction ?? 0,
275
+ },
276
+ });
277
+ const toCardPolicyStep5Review = (payload) => ({
278
+ draftPolicies: (payload.draft_policies ?? []).map(toCardPolicyDraftPolicy),
279
+ groupingSource: payload.grouping_source ?? 'none',
280
+ prompt: payload.prompt ?? '',
281
+ });
282
+ const toCardPolicyWizardPlan = (payload) => ({
283
+ step5Review: toCardPolicyStep5Review(payload.step_5_review),
284
+ });
285
+ const toCardPolicyUploadSource = (payload) => ({
286
+ confidenceScore: payload.confidence_score,
287
+ fileName: payload.file_name,
288
+ lowConfidenceFields: payload.low_confidence_fields ?? [],
289
+ });
290
+ const toCardPolicyInitialData = (payload) => {
291
+ if (payload.mode === 'upload') {
292
+ return {
293
+ policyKind: 'upload',
294
+ wizardPlan: payload.wizard_plan != null
295
+ ? toCardPolicyWizardPlan(payload.wizard_plan)
296
+ : undefined,
297
+ source: payload.source != null
298
+ ? toCardPolicyUploadSource(payload.source)
299
+ : undefined,
300
+ };
301
+ }
302
+ return {
303
+ policyKind: payload.mode,
304
+ wizardPlan: toCardPolicyWizardPlan(payload.wizard_plan),
142
305
  };
143
306
  };
144
307
  const toAiCfoVisualizationData = (data) => {
@@ -375,10 +538,8 @@ const aiCfo = createSlice({
375
538
  // Update state - append new complete Q&As to existing ones
376
539
  session.questionAnswers = mergeQuestionAnswerPairs(session.questionAnswers, completeQAs);
377
540
  },
378
- /**
379
- * Upsert a Q/A pair: if the questionAnswerId exists, upsert the response block; if not, add a new Q/A entry.
380
- * Used for push notification payloads that may introduce a new question.
381
- */
541
+ // Upserts the response block when `questionAnswerId` exists; otherwise adds the Q/A
542
+ // entry. Used for push notification payloads that may introduce a new question.
382
543
  upsertOrAddQuestionAnswerPayload(draft, action) {
383
544
  const { chatSessionId, questionAnswerId, question: { questionId, createdAt, text }, answerPayload, userId, insertQuestionAnswer, } = action.payload;
384
545
  const session = draft.aiCfoByChatSessionId[chatSessionId];
@@ -455,10 +616,82 @@ const aiCfo = createSlice({
455
616
  session.questionAnswers.push(qa);
456
617
  }
457
618
  },
619
+ // Patches an upload-mode card-policy answer with the wizard plan + source returned
620
+ // by `policy-recommendation-from-upload`. No-op for non-upload / missing targets.
621
+ updateAiCfoAnswerCardPolicyWizardPlan(draft, action) {
622
+ const { answerId, chatSessionId, source, wizardPlan } = action.payload;
623
+ const session = draft.aiCfoByChatSessionId[chatSessionId];
624
+ if (session == null) {
625
+ return;
626
+ }
627
+ const qa = session.questionAnswers.find((entry) => entry.questionAnswerId === answerId);
628
+ if (qa == null) {
629
+ return;
630
+ }
631
+ for (const response of Object.values(qa.responses)) {
632
+ const visualization = response?.content.visualization;
633
+ if (visualization == null ||
634
+ visualization.type !== 'interactive_form') {
635
+ continue;
636
+ }
637
+ const data = visualization.data;
638
+ if (data.formType !== 'card_policy' ||
639
+ data.payload.policyKind !== 'upload') {
640
+ continue;
641
+ }
642
+ data.payload = {
643
+ ...data.payload,
644
+ wizardPlan,
645
+ source: source ?? data.payload.source,
646
+ };
647
+ }
648
+ },
649
+ // Renders a "Creating…" placeholder while the cards/policy create mutation runs.
650
+ // Caller supplies a stable `id` (updated in place by `updateSyntheticAiCfoAnswer`).
651
+ appendSyntheticAiCfoAnswer(draft, action) {
652
+ const { chatSessionId, id, kind, createdAt, entityIds, sourceQuestionAnswerId, } = action.payload;
653
+ if (draft.syntheticAnswersByChatSessionId[chatSessionId] == null) {
654
+ draft.syntheticAnswersByChatSessionId[chatSessionId] = [];
655
+ }
656
+ draft.syntheticAnswersByChatSessionId[chatSessionId].push({
657
+ id,
658
+ kind,
659
+ entityIds: entityIds ?? [],
660
+ createdAt,
661
+ sourceQuestionAnswerId,
662
+ });
663
+ },
664
+ // Transitions a bubble from `creating_*` to `created_*` once the mutation completes.
665
+ updateSyntheticAiCfoAnswer(draft, action) {
666
+ const { chatSessionId, id, kind, entityIds } = action.payload;
667
+ const list = draft.syntheticAnswersByChatSessionId[chatSessionId];
668
+ if (list == null) {
669
+ return;
670
+ }
671
+ const entry = list.find((item) => item.id === id);
672
+ if (entry == null) {
673
+ return;
674
+ }
675
+ entry.kind = kind;
676
+ if (entityIds != null) {
677
+ entry.entityIds = entityIds;
678
+ }
679
+ },
680
+ removeSyntheticAiCfoAnswer(draft, action) {
681
+ const { chatSessionId, id } = action.payload;
682
+ const list = draft.syntheticAnswersByChatSessionId[chatSessionId];
683
+ if (list == null) {
684
+ return;
685
+ }
686
+ draft.syntheticAnswersByChatSessionId[chatSessionId] = list.filter((item) => item.id !== id);
687
+ },
688
+ clearSyntheticAiCfoAnswers(draft, action) {
689
+ delete draft.syntheticAnswersByChatSessionId[action.payload];
690
+ },
458
691
  clearSession(draft, action) {
459
692
  const sessionId = action.payload;
460
693
  delete draft.aiCfoByChatSessionId[sessionId];
461
- // Clear partial Q&A if it belongs to the cleared session
694
+ delete draft.syntheticAnswersByChatSessionId[sessionId];
462
695
  if (draft.partialQuestionAnswers?.[sessionId] != null) {
463
696
  draft.partialQuestionAnswers[sessionId] = undefined;
464
697
  }
@@ -466,6 +699,7 @@ const aiCfo = createSlice({
466
699
  clearAiCfo(draft) {
467
700
  draft.aiCfoByChatSessionId = {};
468
701
  draft.partialQuestionAnswers = {};
702
+ draft.syntheticAnswersByChatSessionId = {};
469
703
  },
470
704
  deleteQuestion(draft, action) {
471
705
  const { chatSessionId, questionAnswerId } = action.payload;
@@ -478,6 +712,12 @@ const aiCfo = createSlice({
478
712
  if (idx !== -1) {
479
713
  session.questionAnswers.splice(idx, 1);
480
714
  }
715
+ // Drop synthetic bubbles whose sourceQuestionAnswerId is the deleted Q/A; otherwise "Creating…" / "Created" tiles outlive their Q/A.
716
+ const syntheticAnswers = draft.syntheticAnswersByChatSessionId[chatSessionId];
717
+ if (syntheticAnswers != null) {
718
+ draft.syntheticAnswersByChatSessionId[chatSessionId] =
719
+ syntheticAnswers.filter((answer) => answer.sourceQuestionAnswerId !== questionAnswerId);
720
+ }
481
721
  },
482
722
  },
483
723
  });
@@ -490,5 +730,5 @@ const toChatSession = (chatSessionPayload) => {
490
730
  createdAt: zeniDate(created_at),
491
731
  };
492
732
  };
493
- export const { setNewSession, clearSession, setSessions, setChatHistory, upsertAnswerPayload, upsertOrAddQuestionAnswerPayload, addQuestionPayload, clearAiCfo, deleteQuestion, } = aiCfo.actions;
733
+ export const { setNewSession, clearSession, setSessions, setChatHistory, upsertAnswerPayload, upsertOrAddQuestionAnswerPayload, addQuestionPayload, clearAiCfo, deleteQuestion, updateAiCfoAnswerCardPolicyWizardPlan, appendSyntheticAiCfoAnswer, updateSyntheticAiCfoAnswer, removeSyntheticAiCfoAnswer, clearSyntheticAiCfoAnswers, } = aiCfo.actions;
494
734
  export default aiCfo.reducer;
@@ -32,5 +32,21 @@ export function getAiCfoSelectorView(state) {
32
32
  : [],
33
33
  }))
34
34
  .sort((a, b) => b.chatSession.createdAt.valueOf() - a.chatSession.createdAt.valueOf());
35
- return { allSessionsWithOrderedQuestionAnswers };
35
+ return {
36
+ allSessionsWithOrderedQuestionAnswers,
37
+ syntheticAnswersByChatSessionId: state.syntheticAnswersByChatSessionId ?? {},
38
+ };
39
+ }
40
+ export function getSyntheticAiCfoAnswersForChatSession(state, chatSessionId) {
41
+ const arr = state.syntheticAnswersByChatSessionId?.[chatSessionId] ?? [];
42
+ return arr
43
+ .slice()
44
+ .sort((a, b) => a.createdAt.valueOf() - b.createdAt.valueOf());
45
+ }
46
+ export function getSyntheticAiCfoAnswerByQuestionAnswerId(state, chatSessionId, questionAnswerId) {
47
+ const arr = state.syntheticAnswersByChatSessionId?.[chatSessionId];
48
+ if (arr == null) {
49
+ return undefined;
50
+ }
51
+ return arr.find((answer) => answer.sourceQuestionAnswerId === questionAnswerId);
36
52
  }
@@ -7,7 +7,14 @@ export const ALL_AI_CFO_CHARTS_TYPES = [
7
7
  export const ALL_AI_CFO_VISUALIZATION_TYPES = [
8
8
  ...ALL_AI_CFO_CHARTS_TYPES,
9
9
  'table',
10
+ 'interactive_form',
10
11
  ];
12
+ export const ALL_INTERACTIVE_FORM_TYPES = [
13
+ 'cards_creation',
14
+ 'card_policy',
15
+ ];
16
+ export const toInteractiveFormType = (v) => stringToUnion(v, ALL_INTERACTIVE_FORM_TYPES);
17
+ export const toInteractiveFormTypeStrict = (v) => stringToUnionStrict(v, ALL_INTERACTIVE_FORM_TYPES);
11
18
  export const toAiCfoVisualizationType = (v) => stringToUnion(v, ALL_AI_CFO_VISUALIZATION_TYPES);
12
19
  export const toAiCfoVisualizationTypeStrict = (v) => stringToUnionStrict(v, ALL_AI_CFO_VISUALIZATION_TYPES);
13
20
  export const toAiCfoChartType = (v) => stringToUnion(v, ALL_AI_CFO_CHARTS_TYPES);
@@ -58,3 +65,11 @@ export const toMessageSender = (v) => stringToUnion(v, ALL_MESSAGE_SENDERS);
58
65
  export const toMessageType = (v) => stringToUnion(v, ALL_MESSAGE_TYPES);
59
66
  export const toMessageSenderStrict = (v) => stringToUnionStrict(v, ALL_MESSAGE_SENDERS);
60
67
  export const toMessageTypeStrict = (v) => stringToUnionStrict(v, ALL_MESSAGE_TYPES);
68
+ // Client-synthesized AI CFO answer bubbles (Creating…/Created) pushed when the user
69
+ // submits an interactive form; not streamed from the backend.
70
+ export const ALL_SYNTHETIC_AI_CFO_ANSWER_KINDS = [
71
+ 'creating_cards',
72
+ 'creating_policy',
73
+ 'created_cards',
74
+ 'created_policy',
75
+ ];
@@ -0,0 +1,130 @@
1
+ import { date } from '../../zeniDayJS';
2
+ import { toCardPolicyTemplateMode, toCardPolicyTemplateStatus, } from './cardPolicyState';
3
+ export const toMccCategory = (payload) => ({
4
+ count: payload.count,
5
+ mccCodes: payload.mcc_codes ?? [],
6
+ name: payload.name,
7
+ });
8
+ export const toCardPolicyVendorSearchOption = (payload) => ({
9
+ vendorId: payload.vendor_id,
10
+ name: payload.vendor_name,
11
+ });
12
+ export const toCardPolicyStats = (payload) => ({
13
+ activePolicies: payload.active_policies,
14
+ totalCards: payload.total_cards,
15
+ totalTemplates: payload.total_templates,
16
+ });
17
+ export const toCardPolicyTemplateList = (data) => (data.templates ?? []).map((row) => toCardPolicyTemplate(row.data.template));
18
+ const toCardPolicyTemplateEntityList = (payload) => ({
19
+ categoryCodes: payload.category_codes ?? [],
20
+ merchantNames: payload.merchant_names ?? [],
21
+ });
22
+ export const toCardPolicyTemplate = (payload) => ({
23
+ allowedEntity: toCardPolicyTemplateEntityList(payload.allowed_entity),
24
+ appliedCards: payload.applied_cards ?? [],
25
+ blockedEntity: toCardPolicyTemplateEntityList(payload.blocked_entity),
26
+ cardsCount: payload.cards_count,
27
+ categoryRestrictions: payload.category_restrictions ?? [],
28
+ createdAt: date(payload.created_at),
29
+ createdBy: payload.created_by,
30
+ description: payload.description,
31
+ mode: toCardPolicyTemplateMode(payload.mode),
32
+ name: payload.name,
33
+ requiredReceiptThreshold: payload.required_receipt_threshold,
34
+ spendLimits: {
35
+ transaction: payload.spend_limits.transaction,
36
+ },
37
+ status: toCardPolicyTemplateStatus(payload.status),
38
+ templateId: payload.template_id,
39
+ tenantId: payload.tenant_id,
40
+ updatedAt: date(payload.updated_at),
41
+ });
42
+ /**
43
+ * Re-shape a single camelCase create request into the snake_case wire
44
+ * body. Used by the bulk-create mapper to build each entry of the
45
+ * `templates` array, and directly by the update epic (PUT) since the
46
+ * update endpoint still consumes a single object.
47
+ */
48
+ export const toCreateCardPolicyTemplateRequestBody = (request) => ({
49
+ allowed_entity: {
50
+ category_codes: request.allowedEntity.categoryCodes,
51
+ merchant_names: request.allowedEntity.merchantNames,
52
+ },
53
+ apply_to_cards: request.applyToCards,
54
+ blocked_entity: {
55
+ category_codes: request.blockedEntity.categoryCodes,
56
+ merchant_names: request.blockedEntity.merchantNames,
57
+ },
58
+ description: request.description,
59
+ mode: request.mode ?? 'strict',
60
+ name: request.name,
61
+ required_receipt_threshold: request.requiredReceiptThreshold,
62
+ spend_limits: {
63
+ transaction: request.spendLimits.transaction,
64
+ },
65
+ });
66
+ /**
67
+ * Re-shape a bulk create request into the snake_case wire body for
68
+ * `POST /cards/1.0/policy-templates`. Maps each entry through
69
+ * `toCreateCardPolicyTemplateRequestBody` and only emits
70
+ * `source_chat_session_id` when the camelCase counterpart is defined,
71
+ * so manual-create callers don't ship a stray `undefined` over the wire.
72
+ */
73
+ export const toCreateCardPolicyTemplatesRequestBody = (request) => {
74
+ const body = {
75
+ templates: request.templates.map(toCreateCardPolicyTemplateRequestBody),
76
+ };
77
+ if (request.sourceChatSessionId != null) {
78
+ body.source_chat_session_id = request.sourceChatSessionId;
79
+ }
80
+ return body;
81
+ };
82
+ /**
83
+ * Map a single bulk-response error payload to its camelCased view shape.
84
+ * Defensive against missing optional fields (see `BulkCreateCardPolicyTemplateErrorPayload`
85
+ * docstring — the BE contract isn't fully locked yet).
86
+ */
87
+ export const toBulkCreateCardPolicyTemplateError = (payload) => ({
88
+ message: payload.message,
89
+ code: payload.code,
90
+ index: payload.index,
91
+ name: payload.name,
92
+ });
93
+ // Update body uses the exact same wire shape as create — the PUT
94
+ // endpoint is a full replace and was not affected by the bulk migration.
95
+ export const toUpdateCardPolicyTemplateRequestBody = toCreateCardPolicyTemplateRequestBody;
96
+ /**
97
+ * Seed an edit-form draft (`CreateCardPolicyTemplateRequest`) from an
98
+ * existing camelCased `CardPolicyTemplate`. Used by the detail-fetch
99
+ * epic so the edit page can render with the saved values pre-populated.
100
+ */
101
+ export const toCardPolicyEditFormDraft = (template) => ({
102
+ allowedEntity: {
103
+ categoryCodes: [...template.allowedEntity.categoryCodes],
104
+ merchantNames: [...template.allowedEntity.merchantNames],
105
+ },
106
+ applyToCards: [...template.appliedCards],
107
+ blockedEntity: {
108
+ categoryCodes: [...template.blockedEntity.categoryCodes],
109
+ merchantNames: [...template.blockedEntity.merchantNames],
110
+ },
111
+ description: template.description,
112
+ mode: template.mode,
113
+ name: template.name,
114
+ requiredReceiptThreshold: template.requiredReceiptThreshold,
115
+ spendLimits: { transaction: template.spendLimits.transaction },
116
+ });
117
+ export const toExtractedCardPolicyRules = (payload) => ({
118
+ allowedEntity: {
119
+ categoryCodes: payload.allowed_entity?.category_codes ?? [],
120
+ merchantNames: payload.allowed_entity?.merchant_names ?? [],
121
+ },
122
+ blockedEntity: {
123
+ categoryCodes: payload.blocked_entity?.category_codes ?? [],
124
+ merchantNames: payload.blocked_entity?.merchant_names ?? [],
125
+ },
126
+ confidenceScore: payload.confidence_score,
127
+ policyName: payload.policy_name,
128
+ requiredReceiptThreshold: payload.required_receipt_threshold,
129
+ transactionLimit: payload.transaction_limit,
130
+ });
@@ -0,0 +1,171 @@
1
+ import { createSlice } from '@reduxjs/toolkit';
2
+ import { toCardPolicyTemplate, toCardPolicyVendorSearchOption, toExtractedCardPolicyRules, toMccCategory, } from './cardPolicyPayload';
3
+ // `buildVendorChipId(name)` calls `name.trim().toLowerCase()`; empty/whitespace names would crash or collapse into one colliding chip-id.
4
+ const isUsableMerchantName = (name) => typeof name === 'string' && name.trim() !== '';
5
+ const initialPolicyDocumentExtractionState = {
6
+ fetchState: 'Not-Started',
7
+ error: undefined,
8
+ extractedRules: undefined,
9
+ uploadedFileName: undefined,
10
+ };
11
+ const initialPolicyRecommendationFromUploadState = {
12
+ fetchState: 'Not-Started',
13
+ answerId: undefined,
14
+ chatSessionId: undefined,
15
+ error: undefined,
16
+ };
17
+ const initialVendorSearchState = {
18
+ fetchState: 'Not-Started',
19
+ searchString: '',
20
+ vendors: [],
21
+ error: undefined,
22
+ };
23
+ export const initialState = {
24
+ cardPolicyTemplateById: {},
25
+ mccCategories: [],
26
+ mccCategoriesError: undefined,
27
+ mccCategoriesFetchState: 'Not-Started',
28
+ policyDocumentExtraction: initialPolicyDocumentExtractionState,
29
+ policyRecommendationFromUpload: initialPolicyRecommendationFromUploadState,
30
+ suggestedAllowCategories: [],
31
+ suggestedAllowMerchants: [],
32
+ suggestedBlockCategories: [],
33
+ suggestedBlockMerchants: [],
34
+ vendorSearch: initialVendorSearchState,
35
+ cardPolicyStats: undefined,
36
+ };
37
+ const cardPolicy = createSlice({
38
+ name: 'cardPolicy',
39
+ initialState,
40
+ reducers: {
41
+ fetchCardPolicyMccCategories(draft) {
42
+ draft.mccCategoriesFetchState = 'In-Progress';
43
+ draft.mccCategoriesError = undefined;
44
+ },
45
+ updateCardPolicyMccCategories(draft, action) {
46
+ draft.mccCategories = (action.payload.categories ?? []).map(toMccCategory);
47
+ // BE-suggested seeds pre-populate the chip cloud; `isUsableMerchantName` drops names that would break `buildVendorChipId`.
48
+ draft.suggestedAllowMerchants = (action.payload.suggested_allow_merchants ?? []).filter(isUsableMerchantName);
49
+ draft.suggestedBlockMerchants = (action.payload.suggested_block_merchants ?? []).filter(isUsableMerchantName);
50
+ draft.suggestedAllowCategories = (action.payload.suggested_allow_catagories ?? []).map(toMccCategory);
51
+ draft.suggestedBlockCategories = (action.payload.suggested_block_catagories ?? []).map(toMccCategory);
52
+ draft.mccCategoriesFetchState = 'Completed';
53
+ draft.mccCategoriesError = undefined;
54
+ },
55
+ updateCardPolicyMccCategoriesFailure(draft, action) {
56
+ draft.mccCategoriesFetchState = 'Error';
57
+ draft.mccCategoriesError = action.payload;
58
+ },
59
+ updateCreatedCardPolicyTemplate(draft, action) {
60
+ const template = toCardPolicyTemplate(action.payload);
61
+ draft.cardPolicyTemplateById[template.templateId] = template;
62
+ },
63
+ // Full replace so server-side deletes evict locally too; the view slice owns the ordered ID list.
64
+ updateCardPolicyTemplates(draft, action) {
65
+ const byId = {};
66
+ for (const template of action.payload) {
67
+ byId[template.templateId] = template;
68
+ }
69
+ draft.cardPolicyTemplateById = byId;
70
+ },
71
+ removeCardPolicyTemplate(draft, action) {
72
+ delete draft.cardPolicyTemplateById[action.payload];
73
+ },
74
+ updateCardPolicyStats(draft, action) {
75
+ draft.cardPolicyStats = action.payload;
76
+ },
77
+ // Captures the first file name so the upload pill can render without callers retaining a File ref.
78
+ extractPolicyDocument: {
79
+ reducer(draft, action) {
80
+ draft.policyDocumentExtraction.fetchState = 'In-Progress';
81
+ draft.policyDocumentExtraction.error = undefined;
82
+ draft.policyDocumentExtraction.extractedRules = undefined;
83
+ draft.policyDocumentExtraction.uploadedFileName =
84
+ action.meta.uploadedFileName;
85
+ draft.policyDocumentExtraction.aiCfoAnswerId =
86
+ action.payload.aiCfoAnswerId;
87
+ draft.policyDocumentExtraction.aiCfoChatSessionId =
88
+ action.payload.aiCfoChatSessionId;
89
+ // Extraction + recommendation model one upload lifecycle; reset together so a re-upload doesn't read stale lifecycle from the prior chain.
90
+ draft.policyRecommendationFromUpload = {
91
+ ...initialPolicyRecommendationFromUploadState,
92
+ };
93
+ },
94
+ prepare(files, aiCfoAnswerId, aiCfoChatSessionId) {
95
+ return {
96
+ payload: { files, aiCfoAnswerId, aiCfoChatSessionId },
97
+ meta: { uploadedFileName: files[0]?.name },
98
+ };
99
+ },
100
+ },
101
+ updatePolicyDocumentExtractionSuccess(draft, action) {
102
+ draft.policyDocumentExtraction.fetchState = 'Completed';
103
+ draft.policyDocumentExtraction.error = undefined;
104
+ draft.policyDocumentExtraction.extractedRules =
105
+ toExtractedCardPolicyRules(action.payload);
106
+ },
107
+ updatePolicyDocumentExtractionFailure(draft, action) {
108
+ draft.policyDocumentExtraction.fetchState = 'Error';
109
+ draft.policyDocumentExtraction.error = action.payload;
110
+ draft.policyDocumentExtraction.extractedRules = undefined;
111
+ },
112
+ clearPolicyDocumentExtraction(draft) {
113
+ draft.policyDocumentExtraction = {
114
+ ...initialPolicyDocumentExtractionState,
115
+ };
116
+ // Pair with extractPolicyDocument: the two sub-slices reset and advance together.
117
+ draft.policyRecommendationFromUpload = {
118
+ ...initialPolicyRecommendationFromUploadState,
119
+ };
120
+ },
121
+ // Chained after extractPolicyDocument; epic merges the returned wizard plan into the AI CFO answer identified by answerId + chatSessionId.
122
+ fetchCardPolicyRecommendationFromUpload: {
123
+ reducer(draft, action) {
124
+ draft.policyRecommendationFromUpload.fetchState = 'In-Progress';
125
+ draft.policyRecommendationFromUpload.answerId = action.payload.answerId;
126
+ draft.policyRecommendationFromUpload.chatSessionId =
127
+ action.payload.chatSessionId;
128
+ draft.policyRecommendationFromUpload.error = undefined;
129
+ },
130
+ prepare(answerId, chatSessionId, extractedRules) {
131
+ return { payload: { answerId, chatSessionId, extractedRules } };
132
+ },
133
+ },
134
+ updatePolicyRecommendationFromUploadSuccess(draft) {
135
+ draft.policyRecommendationFromUpload.fetchState = 'Completed';
136
+ draft.policyRecommendationFromUpload.error = undefined;
137
+ },
138
+ updatePolicyRecommendationFromUploadFailure(draft, action) {
139
+ draft.policyRecommendationFromUpload.fetchState = 'Error';
140
+ draft.policyRecommendationFromUpload.error = action.payload;
141
+ },
142
+ // Empty searchString = top vendors by YTD spend; non-empty filters server-side.
143
+ fetchCardPolicyVendorOptions: {
144
+ reducer(draft, action) {
145
+ draft.vendorSearch.fetchState = 'In-Progress';
146
+ draft.vendorSearch.searchString = action.payload.searchString;
147
+ draft.vendorSearch.error = undefined;
148
+ },
149
+ prepare(searchString) {
150
+ return { payload: { searchString: searchString ?? '' } };
151
+ },
152
+ },
153
+ updateCardPolicyVendorOptions(draft, action) {
154
+ // Same `buildVendorChipId` guard as the suggested-merchants seeds above.
155
+ draft.vendorSearch.vendors = (action.payload.vendors ?? [])
156
+ .map(toCardPolicyVendorSearchOption)
157
+ .filter((vendor) => isUsableMerchantName(vendor.name));
158
+ draft.vendorSearch.fetchState = 'Completed';
159
+ draft.vendorSearch.error = undefined;
160
+ },
161
+ updateCardPolicyVendorOptionsFailure(draft, action) {
162
+ draft.vendorSearch.fetchState = 'Error';
163
+ draft.vendorSearch.error = action.payload;
164
+ },
165
+ clearCardPolicy(draft) {
166
+ Object.assign(draft, initialState);
167
+ },
168
+ },
169
+ });
170
+ export const { fetchCardPolicyMccCategories, fetchCardPolicyVendorOptions, updateCardPolicyMccCategories, updateCardPolicyMccCategoriesFailure, updateCardPolicyVendorOptions, updateCardPolicyVendorOptionsFailure, updateCreatedCardPolicyTemplate, updateCardPolicyTemplates, removeCardPolicyTemplate, updateCardPolicyStats, extractPolicyDocument, updatePolicyDocumentExtractionSuccess, updatePolicyDocumentExtractionFailure, clearPolicyDocumentExtraction, fetchCardPolicyRecommendationFromUpload, updatePolicyRecommendationFromUploadSuccess, updatePolicyRecommendationFromUploadFailure, clearCardPolicy, } = cardPolicy.actions;
171
+ export default cardPolicy.reducer;