@zeniai/client-epic-state 5.1.8-betaRD2 → 5.1.8-betaRR0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/entity/company/cardsVisibilityHelpers.d.ts +4 -0
- package/lib/entity/company/cardsVisibilityHelpers.js +14 -0
- package/lib/entity/tenant/tenantSelector.d.ts +1 -1
- package/lib/entity/tenant/tenantSelector.js +9 -11
- package/lib/entity/transaction/payloadTypes/transactionPayload.js +10 -0
- package/lib/esm/entity/company/cardsVisibilityHelpers.js +9 -0
- package/lib/esm/entity/tenant/tenantSelector.js +7 -9
- package/lib/esm/entity/transaction/payloadTypes/transactionPayload.js +10 -0
- package/lib/esm/index.js +2 -1
- package/lib/esm/view/dashboard/dashboardSelector.js +8 -43
- package/lib/esm/view/people/initializeEditPersonEpic.js +5 -1
- package/lib/esm/view/people/invitePeopleEpic.js +6 -3
- package/lib/esm/view/people/peopleSaveUpdatesEpic.js +7 -3
- package/lib/esm/view/settingsView/settingsViewHelpers.js +16 -10
- package/lib/esm/view/transactionDetail/epics/saveTransactionHelper.js +1 -0
- package/lib/esm/view/transactionDetail/epics/updateTransactionDetailEpic.js +6 -0
- package/lib/esm/view/transactionDetail/transactionDetailLocalDataHelper.js +7 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.js +30 -27
- package/lib/view/dashboard/dashboardSelector.js +8 -43
- package/lib/view/people/initializeEditPersonEpic.js +5 -1
- package/lib/view/people/invitePeopleEpic.js +6 -3
- package/lib/view/people/peopleSaveUpdatesEpic.js +7 -3
- package/lib/view/settingsView/settingsViewHelpers.js +15 -9
- package/lib/view/transactionDetail/epics/saveTransactionHelper.js +1 -0
- package/lib/view/transactionDetail/epics/updateTransactionDetailEpic.js +6 -0
- package/lib/view/transactionDetail/transactionDetailLocalDataHelper.js +7 -1
- package/lib/view/transactionDetail/transactionDetailState.d.ts +1 -0
- package/lib/view/transactionDetail/transactionDetailTypes.d.ts +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { UserRoleType } from '../userRole/userRoleType';
|
|
2
|
+
import { Company } from './companyStateTypes';
|
|
3
|
+
export declare const isCardsProductEnabledOnCompany: (company: Company | undefined) => boolean;
|
|
4
|
+
export declare const filterChargeCardRolesWhenProductDisabled: (roles: UserRoleType[], company: Company | undefined) => UserRoleType[];
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.filterChargeCardRolesWhenProductDisabled = exports.isCardsProductEnabledOnCompany = void 0;
|
|
4
|
+
const isCardsProductEnabledOnCompany = (company) => Boolean(company?.companyChargeCardInfo?.isChargeCardEnabled) ||
|
|
5
|
+
Boolean(company?.companyDebitCardInfo?.isDebitCardEnabled);
|
|
6
|
+
exports.isCardsProductEnabledOnCompany = isCardsProductEnabledOnCompany;
|
|
7
|
+
const CHARGE_CARD_USER_ROLES = [
|
|
8
|
+
'charge_card_admin',
|
|
9
|
+
'charge_card_user',
|
|
10
|
+
];
|
|
11
|
+
const filterChargeCardRolesWhenProductDisabled = (roles, company) => (0, exports.isCardsProductEnabledOnCompany)(company)
|
|
12
|
+
? roles
|
|
13
|
+
: roles.filter((role) => !CHARGE_CARD_USER_ROLES.includes(role));
|
|
14
|
+
exports.filterChargeCardRolesWhenProductDisabled = filterChargeCardRolesWhenProductDisabled;
|
|
@@ -85,7 +85,7 @@ export declare const getCurrentTenantExternalConnections: (tenantState: TenantSt
|
|
|
85
85
|
export declare const toTenantCoreDetailsView: (tenantsBaseView: TenantBaseView[]) => TenantCoreDetailsView[];
|
|
86
86
|
export declare const isTenantBankingOnly: (isDebitCardFlagEnabled: boolean, tenant: Tenant | undefined) => boolean;
|
|
87
87
|
export declare const isTenantCardsOnly: (tenant: Tenant | undefined) => boolean;
|
|
88
|
-
export declare const
|
|
88
|
+
export declare const isTenantAccountingServicesEnabled: (tenant: Tenant | undefined) => boolean;
|
|
89
89
|
export declare const getIsAccountingClassesEnabled: (state: RootState) => boolean;
|
|
90
90
|
export declare const getIsAccountingProjectsEnabled: (state: RootState) => boolean;
|
|
91
91
|
export declare const isTenantBookkeepingEnabled: (tenant: Tenant | undefined) => boolean;
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.isTenantTreasuryEnabled = exports.isOtherProductsEnabledForTenant = exports.isTenantBookkeepingEnabled = exports.getIsAccountingProjectsEnabled = exports.getIsAccountingClassesEnabled = exports.
|
|
6
|
+
exports.isTenantTreasuryEnabled = exports.isOtherProductsEnabledForTenant = exports.isTenantBookkeepingEnabled = exports.getIsAccountingProjectsEnabled = exports.getIsAccountingClassesEnabled = exports.isTenantAccountingServicesEnabled = exports.isTenantCardsOnly = exports.isTenantBankingOnly = exports.toTenantCoreDetailsView = exports.getCurrentTenantExternalConnections = exports.isTenantUsingZeniCOA = exports.isZeniDomainTenant = exports.getTenantBaseViewForTenantView = exports.getTenantsCoreDetailsByCheckInDateSelector = exports.getTenantsBaseByCheckInDateSelector = exports.getTenantBaseById = exports.getTenantsByCheckInDateSelector = exports.getCurrentTenant = exports.getTenantBaseViewForTenantId = void 0;
|
|
7
7
|
exports.getTenant = getTenant;
|
|
8
8
|
exports.getOnboardingTenantByTenantId = getOnboardingTenantByTenantId;
|
|
9
9
|
const toolkit_1 = require("@reduxjs/toolkit");
|
|
@@ -280,17 +280,15 @@ const isTenantCardsOnly = (tenant) => {
|
|
|
280
280
|
: false;
|
|
281
281
|
};
|
|
282
282
|
exports.isTenantCardsOnly = isTenantCardsOnly;
|
|
283
|
-
const
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
settings.isPayrollEnabled === true ||
|
|
291
|
-
settings.isBookkeepingEnabled === true);
|
|
283
|
+
const isTenantAccountingServicesEnabled = (tenant) => {
|
|
284
|
+
return tenant != null && tenant.productSettings != null
|
|
285
|
+
? tenant.productSettings.isCfoEnabled === true ||
|
|
286
|
+
tenant.productSettings.isTaxEnabled === true ||
|
|
287
|
+
tenant.productSettings.isPayrollEnabled === true ||
|
|
288
|
+
tenant.productSettings.isBookkeepingEnabled === true
|
|
289
|
+
: false;
|
|
292
290
|
};
|
|
293
|
-
exports.
|
|
291
|
+
exports.isTenantAccountingServicesEnabled = isTenantAccountingServicesEnabled;
|
|
294
292
|
const getIsAccountingClassesEnabled = (state) => {
|
|
295
293
|
const { currentTenantId, tenantsById } = state.tenantState;
|
|
296
294
|
if (currentTenantId == null) {
|
|
@@ -157,6 +157,16 @@ const toTransactionPayload = (transaction) => {
|
|
|
157
157
|
lines: transaction?.lines?.map((line) => (0, transactionLinePayload_1.toLinePayload)(line)) ?? [],
|
|
158
158
|
recommendations: toRecommendationsPayload(transaction.lines ?? [], transaction.recommendations ?? {}),
|
|
159
159
|
};
|
|
160
|
+
// Only carry `document_id` (the journal-entry title / document number) when
|
|
161
|
+
// the transaction actually has one, so transaction types that never expose
|
|
162
|
+
// the title don't start sending the key, and we never emit an empty string
|
|
163
|
+
// that the server could interpret as clearing the number.
|
|
164
|
+
if (transaction.documentId != null) {
|
|
165
|
+
transactionPayload = {
|
|
166
|
+
...transactionPayload,
|
|
167
|
+
document_id: transaction.documentId,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
160
170
|
//note: for transaction type deposit and refund account is must for put call
|
|
161
171
|
if (transaction.account != null &&
|
|
162
172
|
(transaction.type === 'deposit' || transaction.type === 'refund')) {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const isCardsProductEnabledOnCompany = (company) => Boolean(company?.companyChargeCardInfo?.isChargeCardEnabled) ||
|
|
2
|
+
Boolean(company?.companyDebitCardInfo?.isDebitCardEnabled);
|
|
3
|
+
const CHARGE_CARD_USER_ROLES = [
|
|
4
|
+
'charge_card_admin',
|
|
5
|
+
'charge_card_user',
|
|
6
|
+
];
|
|
7
|
+
export const filterChargeCardRolesWhenProductDisabled = (roles, company) => isCardsProductEnabledOnCompany(company)
|
|
8
|
+
? roles
|
|
9
|
+
: roles.filter((role) => !CHARGE_CARD_USER_ROLES.includes(role));
|
|
@@ -265,15 +265,13 @@ export const isTenantCardsOnly = (tenant) => {
|
|
|
265
265
|
tenant.productSettings.isSpendManagementEnabled === false
|
|
266
266
|
: false;
|
|
267
267
|
};
|
|
268
|
-
export const
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
settings.isPayrollEnabled === true ||
|
|
276
|
-
settings.isBookkeepingEnabled === true);
|
|
268
|
+
export const isTenantAccountingServicesEnabled = (tenant) => {
|
|
269
|
+
return tenant != null && tenant.productSettings != null
|
|
270
|
+
? tenant.productSettings.isCfoEnabled === true ||
|
|
271
|
+
tenant.productSettings.isTaxEnabled === true ||
|
|
272
|
+
tenant.productSettings.isPayrollEnabled === true ||
|
|
273
|
+
tenant.productSettings.isBookkeepingEnabled === true
|
|
274
|
+
: false;
|
|
277
275
|
};
|
|
278
276
|
export const getIsAccountingClassesEnabled = (state) => {
|
|
279
277
|
const { currentTenantId, tenantsById } = state.tenantState;
|
|
@@ -152,6 +152,16 @@ export const toTransactionPayload = (transaction) => {
|
|
|
152
152
|
lines: transaction?.lines?.map((line) => toLinePayload(line)) ?? [],
|
|
153
153
|
recommendations: toRecommendationsPayload(transaction.lines ?? [], transaction.recommendations ?? {}),
|
|
154
154
|
};
|
|
155
|
+
// Only carry `document_id` (the journal-entry title / document number) when
|
|
156
|
+
// the transaction actually has one, so transaction types that never expose
|
|
157
|
+
// the title don't start sending the key, and we never emit an empty string
|
|
158
|
+
// that the server could interpret as clearing the number.
|
|
159
|
+
if (transaction.documentId != null) {
|
|
160
|
+
transactionPayload = {
|
|
161
|
+
...transactionPayload,
|
|
162
|
+
document_id: transaction.documentId,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
155
165
|
//note: for transaction type deposit and refund account is must for put call
|
|
156
166
|
if (transaction.account != null &&
|
|
157
167
|
(transaction.type === 'deposit' || transaction.type === 'refund')) {
|
package/lib/esm/index.js
CHANGED
|
@@ -43,6 +43,7 @@ import { getChargeCardById } from './entity/chargeCard/chargeCardSelector';
|
|
|
43
43
|
import { attachmentFilePathToAttachment, } from './entity/chargeCardTransaction/chargeCardTransactionPayload';
|
|
44
44
|
import { updateChargeCardTransactionAttachments } from './entity/chargeCardTransaction/chargeCardTransactionReducer';
|
|
45
45
|
import { updateChargeCardTransactionFromPusher, updateChargeCardTransactionReceiptFromPusher, updateChargeCardTransactionStatusFromPusher, } from './entity/chargeCardTransaction/chargeCardTransactionReducer';
|
|
46
|
+
import { filterChargeCardRolesWhenProductDisabled, isCardsProductEnabledOnCompany, } from './entity/company/cardsVisibilityHelpers';
|
|
46
47
|
import { getControllersName, getFirstControllerEmail, getFirstControllerId, } from './entity/company/companyHelper';
|
|
47
48
|
import { getCompanyByCompanyId, getCompanyInfoForAllCockpitCompaniesInState, getControllersForCompany, } from './entity/company/companySelector';
|
|
48
49
|
import { ALL_ACCOUNTING_CONNECTION_CREATION_MODES, isCompanyEligibleForTreasury, } from './entity/company/companyStateTypes';
|
|
@@ -536,7 +537,7 @@ export { getEntityAutoCompleteResults };
|
|
|
536
537
|
export { updateEntities, clearAllEntities };
|
|
537
538
|
export { getEntityByEntityIDs };
|
|
538
539
|
export { getAddressByAddressId };
|
|
539
|
-
export { ALL_ACCOUNTING_CONNECTION_CREATION_MODES, isCompanyEligibleForTreasury, };
|
|
540
|
+
export { ALL_ACCOUNTING_CONNECTION_CREATION_MODES, isCompanyEligibleForTreasury, isCardsProductEnabledOnCompany, filterChargeCardRolesWhenProductDisabled, };
|
|
540
541
|
export { getCompanyByCompanyId, getControllersForCompany, getCompanyInfoForAllCockpitCompaniesInState, getFirstControllerEmail, getFirstControllerId, getControllersName, };
|
|
541
542
|
export { getCompanyManagementView, getPlanListZeniSku, getAddonListZeniSku, };
|
|
542
543
|
export { getParentSubsidiaryManagementView };
|
|
@@ -57,20 +57,13 @@ export const getDashboard = createSelector(tenantSelector, getCardBalance, getCa
|
|
|
57
57
|
const hasTasksCardAccess = tenants.currentTenant?.excludedResources?.resources?.find((resource) => resource.resource === '/reports/task_card') == null;
|
|
58
58
|
let cardsCopy = [...cards];
|
|
59
59
|
const cardsToRemove = new Set();
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
let isZeniPromoCardOn4thPosition = true;
|
|
63
|
-
const isChargeCardEnabled = chargeCardInfo?.isChargeCardEnabled ?? false;
|
|
60
|
+
// Credit-only express-interest promo; always omitted while cards are company-product-gated. Reintroduce only with an explicit show rule.
|
|
61
|
+
cardsToRemove.add('zeni_promo_card');
|
|
64
62
|
if (cardBalance != null &&
|
|
65
63
|
cardBalance.fetchState === 'Completed' &&
|
|
66
64
|
(cardBalance.accountsInOrder.length === 0 ||
|
|
67
65
|
cardBalance.status?.code !== 200)) {
|
|
68
66
|
cardsToRemove.add('card_balance');
|
|
69
|
-
isZeniPromoCardOn4thPosition = false;
|
|
70
|
-
}
|
|
71
|
-
if (isChargeCardEnabled || creditAccountLimit === -1) {
|
|
72
|
-
cardsToRemove.add('zeni_promo_card');
|
|
73
|
-
isZeniPromoCardOn4thPosition = false;
|
|
74
67
|
}
|
|
75
68
|
if (hasTopExAccess === false) {
|
|
76
69
|
cardsToRemove.add('top_expenses');
|
|
@@ -160,57 +153,29 @@ export const getDashboard = createSelector(tenantSelector, getCardBalance, getCa
|
|
|
160
153
|
cardsToRemove.add('bill_pay_card');
|
|
161
154
|
cardsToRemove.add('reimbursement_card');
|
|
162
155
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (isZeniPromoCardOn4thPosition) {
|
|
156
|
+
const showZeniAccountsPromoCard = zeniAccountsPromoCard.isShowDepositAccountsPromo === true;
|
|
157
|
+
if (showZeniAccountsPromoCard) {
|
|
166
158
|
cardsToRemove.add('bill_pay_promo_card');
|
|
167
159
|
cardsToRemove.add('reimbursement_promo_card');
|
|
168
|
-
cardsToRemove.add('zeni_accounts_promo_card');
|
|
169
160
|
}
|
|
170
161
|
else {
|
|
171
|
-
|
|
172
|
-
if (showZeniAccountsPromoCard) {
|
|
173
|
-
cardsToRemove.add('bill_pay_promo_card');
|
|
174
|
-
cardsToRemove.add('reimbursement_promo_card');
|
|
175
|
-
}
|
|
176
|
-
else {
|
|
177
|
-
cardsToRemove.add('zeni_accounts_promo_card');
|
|
178
|
-
}
|
|
162
|
+
cardsToRemove.add('zeni_accounts_promo_card');
|
|
179
163
|
}
|
|
180
164
|
// remove treasury promo card if its already enabled
|
|
181
165
|
const isTreasuryTOSAccepted = tenants.currentTenant.companyTreasuryInfo?.info?.isTreasuryTOSAccepted;
|
|
182
166
|
if (isTreasuryTOSAccepted === true || isTreasuryFeatureEnabled === false) {
|
|
183
167
|
cardsToRemove.add('treasury_promo_card');
|
|
184
168
|
}
|
|
185
|
-
// More than one promo card can't be shown
|
|
186
|
-
// There is an exception when number of card accounts connected to QBO is zero, in that case we replace card_balance tile in 2nd position with zeni_promo_card,
|
|
187
|
-
// so 3rd position tile could be any other promo card based on priority order.
|
|
169
|
+
// More than one promo card can't be shown on the dashboard (priority: Treasury > Accounts > Bill > Remi).
|
|
188
170
|
const PROMO_CARD_PRIORITY_ORDER = [
|
|
189
171
|
'treasury_promo_card',
|
|
190
|
-
'zeni_promo_card',
|
|
191
172
|
'zeni_accounts_promo_card',
|
|
192
173
|
'bill_pay_promo_card',
|
|
193
174
|
'reimbursement_promo_card',
|
|
194
175
|
];
|
|
195
|
-
const
|
|
196
|
-
const promoCardsTobeRetained = promoCards.filter((c) => !cardsToRemove.has(c));
|
|
176
|
+
const promoCardsTobeRetained = PROMO_CARD_PRIORITY_ORDER.filter((c) => !cardsToRemove.has(c));
|
|
197
177
|
if (promoCardsTobeRetained.length > 1) {
|
|
198
|
-
const cardsToKeep = new Set();
|
|
199
|
-
if (cardsToRemove.has('card_balance') &&
|
|
200
|
-
promoCardsTobeRetained.includes('zeni_promo_card')) {
|
|
201
|
-
// zeni_promo_card is the primary promo card when card_balance is removed
|
|
202
|
-
cardsToKeep.add('zeni_promo_card');
|
|
203
|
-
// Also keep the highest priority non-zeni promo card as the 2nd
|
|
204
|
-
const secondCard = promoCardsTobeRetained.find((card) => card !== 'zeni_promo_card');
|
|
205
|
-
if (secondCard != null) {
|
|
206
|
-
cardsToKeep.add(secondCard);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
else {
|
|
210
|
-
// Keep only the highest priority promo card
|
|
211
|
-
cardsToKeep.add(promoCardsTobeRetained[0]);
|
|
212
|
-
}
|
|
213
|
-
// Remove all other promo cards not in cardsToKeep
|
|
178
|
+
const cardsToKeep = new Set([promoCardsTobeRetained[0]]);
|
|
214
179
|
promoCardsTobeRetained.forEach((card) => {
|
|
215
180
|
if (!cardsToKeep.has(card)) {
|
|
216
181
|
cardsToRemove.add(card);
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { from } from 'rxjs';
|
|
2
2
|
import { filter, mergeMap } from 'rxjs/operators';
|
|
3
|
+
import { filterChargeCardRolesWhenProductDisabled } from '../../entity/company/cardsVisibilityHelpers';
|
|
4
|
+
import { getCurrentTenant } from '../../entity/tenant/tenantSelector';
|
|
3
5
|
import { getUserByUserId } from '../../entity/user/userSelector';
|
|
4
6
|
import { getUserRoleByUserId } from '../../entity/userRole/userRoleSelector';
|
|
5
7
|
import { initializeEditPerson, peopleSaveDataInLocalStore, } from './peopleReducer';
|
|
@@ -18,11 +20,13 @@ export const initializeEditPersonEpic = (actions$, state$) => actions$.pipe(filt
|
|
|
18
20
|
};
|
|
19
21
|
const email = person.user?.email;
|
|
20
22
|
const { userRoles, managerUserId: managerId, accountingClassIDs, } = person.userRole;
|
|
23
|
+
const currentTenant = getCurrentTenant(state$.value);
|
|
24
|
+
const rolesForLocalStore = filterChargeCardRolesWhenProductDisabled(userRoles, currentTenant.company);
|
|
21
25
|
fetchActions.push(peopleSaveDataInLocalStore({
|
|
22
26
|
peopleLocalData: [
|
|
23
27
|
{
|
|
24
28
|
email: email != null ? [email] : [],
|
|
25
|
-
role:
|
|
29
|
+
role: rolesForLocalStore,
|
|
26
30
|
managerId,
|
|
27
31
|
departmentId: accountingClassIDs[0],
|
|
28
32
|
},
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { of } from 'rxjs';
|
|
2
2
|
import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
|
|
3
|
+
import { filterChargeCardRolesWhenProductDisabled } from '../../entity/company/cardsVisibilityHelpers';
|
|
3
4
|
import { openSnackbar } from '../../entity/snackbar/snackbarReducer';
|
|
5
|
+
import { getCurrentTenant } from '../../entity/tenant/tenantSelector';
|
|
4
6
|
import { updateAllUsers } from '../../entity/user/userReducer';
|
|
5
7
|
import { updateUserRoles } from '../../entity/userRole/userRoleReducer';
|
|
6
8
|
import { createZeniAPIStatus, isSuccessResponse } from '../../responsePayload';
|
|
@@ -8,7 +10,8 @@ import { updateManagersListOnRoleChange, } from './helpers/updateManagersListOnR
|
|
|
8
10
|
import { invitePeople, invitePeopleFailure, invitePeopleSuccess, } from './peopleReducer';
|
|
9
11
|
export const invitePeopleEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(invitePeople.match), switchMap(() => {
|
|
10
12
|
const peopleLocalData = state$.value.peopleState.personDetails.localData;
|
|
11
|
-
const
|
|
13
|
+
const currentTenant = getCurrentTenant(state$.value);
|
|
14
|
+
const invitePayload = toInvitePayloadFromLocalData(peopleLocalData, currentTenant.company);
|
|
12
15
|
return zeniAPI
|
|
13
16
|
.postAndGetJSON(`${zeniAPI.apiEndPoints.tenantMicroServiceBaseUrl}/1.0/invites`, invitePayload)
|
|
14
17
|
.pipe(mergeMap((response) => {
|
|
@@ -31,11 +34,11 @@ export const invitePeopleEpic = (actions$, state$, zeniAPI) => actions$.pipe(fil
|
|
|
31
34
|
}
|
|
32
35
|
}), catchError((error) => of(invitePeopleFailure(createZeniAPIStatus('Unexpected error', 'User Roles REST API call errored out' + JSON.stringify(error))))));
|
|
33
36
|
}));
|
|
34
|
-
const toInvitePayloadFromLocalData = (peopleLocalData) => {
|
|
37
|
+
const toInvitePayloadFromLocalData = (peopleLocalData, company) => {
|
|
35
38
|
const invitedPeople = peopleLocalData
|
|
36
39
|
.map((local) => {
|
|
37
40
|
const rolesPayload = {};
|
|
38
|
-
local.role.forEach((role) => {
|
|
41
|
+
filterChargeCardRolesWhenProductDisabled(local.role, company).forEach((role) => {
|
|
39
42
|
rolesPayload[`is_${role}`] = true;
|
|
40
43
|
});
|
|
41
44
|
return local.email.map((mail) => {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { from, of } from 'rxjs';
|
|
2
2
|
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
3
|
+
import { filterChargeCardRolesWhenProductDisabled } from '../../entity/company/cardsVisibilityHelpers';
|
|
3
4
|
import { openSnackbar } from '../../entity/snackbar/snackbarReducer';
|
|
5
|
+
import { getCurrentTenant } from '../../entity/tenant/tenantSelector';
|
|
4
6
|
import { updateUserRoles } from '../../entity/userRole/userRoleReducer';
|
|
5
7
|
import { hasZeniRoleOrCompanyOfficerAccess } from '../../entity/userRole/userRoleType';
|
|
6
8
|
import { createZeniAPIStatus, isSuccessResponse } from '../../responsePayload';
|
|
@@ -10,7 +12,8 @@ export const peopleSaveUpdatesEpic = (actions$, state$, zeniAPI) => actions$.pip
|
|
|
10
12
|
const { localData, person } = state$.value.peopleState.personDetails;
|
|
11
13
|
const { userRole } = person;
|
|
12
14
|
const { isZeniTenant } = action.payload;
|
|
13
|
-
const
|
|
15
|
+
const currentTenant = getCurrentTenant(state$.value);
|
|
16
|
+
const updatesPayload = toPersonUpdatableInfoPayload(localData[0], isZeniTenant, person, currentTenant.company);
|
|
14
17
|
return zeniAPI
|
|
15
18
|
.putAndGetJSON(`${zeniAPI.apiEndPoints.tenantMicroServiceBaseUrl}/1.0/user-roles/${userRole.userRoleId}`, updatesPayload)
|
|
16
19
|
.pipe(mergeMap((response) => {
|
|
@@ -37,7 +40,7 @@ export const peopleSaveUpdatesEpic = (actions$, state$, zeniAPI) => actions$.pip
|
|
|
37
40
|
}
|
|
38
41
|
}), catchError((error) => of(peopleSaveUpdatesFailure(createZeniAPIStatus('Unexpected error', 'User Roles save updates errored out' + JSON.stringify(error))))));
|
|
39
42
|
}));
|
|
40
|
-
const toPersonUpdatableInfoPayload = (info, isZeniTenant, person) => {
|
|
43
|
+
const toPersonUpdatableInfoPayload = (info, isZeniTenant, person, company) => {
|
|
41
44
|
const payload = {};
|
|
42
45
|
const { accountingClassIDs, managerUserId, userRoles } = person.userRole;
|
|
43
46
|
if (info.departmentId != null &&
|
|
@@ -52,6 +55,7 @@ const toPersonUpdatableInfoPayload = (info, isZeniTenant, person) => {
|
|
|
52
55
|
info.managerId !== 'no_manager' ? info.managerId : null;
|
|
53
56
|
}
|
|
54
57
|
if (info.role != null) {
|
|
58
|
+
const rolesForUpdate = filterChargeCardRolesWhenProductDisabled(info.role, company);
|
|
55
59
|
/**
|
|
56
60
|
* Mark previously selected roles as false and new roles true
|
|
57
61
|
*/
|
|
@@ -62,7 +66,7 @@ const toPersonUpdatableInfoPayload = (info, isZeniTenant, person) => {
|
|
|
62
66
|
}
|
|
63
67
|
rolesPayload[`is_${role}`] = false;
|
|
64
68
|
});
|
|
65
|
-
|
|
69
|
+
rolesForUpdate.forEach((role) => {
|
|
66
70
|
rolesPayload[`is_${role}`] = true;
|
|
67
71
|
});
|
|
68
72
|
Object.assign(payload, rolesPayload);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isCardsProductEnabledOnCompany } from '../../entity/company/cardsVisibilityHelpers';
|
|
2
|
+
import { isTenantAccountingServicesEnabled, isTenantBankingOnly, isTenantCardsOnly, } from '../../entity/tenant/tenantSelector';
|
|
2
3
|
import { hasAnyAdminLevelAccess, hasBillPayAccessible, hasBookKeepingAdminLevelAccess, hasBookKeepingUserLevelAccess, hasChargeCardAccessible, hasFullOrAdminLevelAccess, hasInvestorBankerLevelAccess, hasReimbursementAccess, hasReimbursementAccessible, hasSuperAdminLevelAccess, hasZeniAccountsAccessible, isZeniSignedInUser, } from '../../entity/userRole/userRoleType';
|
|
3
4
|
import { isVendorsTabVisible } from '../vendorList/vendorListSelector';
|
|
4
5
|
export const isAccountingTabVisible = (userRole, isDebitCardFlagEnabled, currentTenant, userRoleMap) => {
|
|
@@ -10,8 +11,9 @@ export const isAccountingTabVisible = (userRole, isDebitCardFlagEnabled, current
|
|
|
10
11
|
hasBillPayAccessible(currentTenant, userRoleMap) ||
|
|
11
12
|
hasReimbursementAccessible(currentTenant, userRoleMap) ||
|
|
12
13
|
hasFullOrAdminLevelAccess(userRole)) &&
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
(isTenantAccountingServicesEnabled(currentTenant) ||
|
|
15
|
+
(isTenantBankingOnly(isDebitCardFlagEnabled, currentTenant) === false &&
|
|
16
|
+
isTenantCardsOnly(currentTenant) === false)));
|
|
15
17
|
}
|
|
16
18
|
else {
|
|
17
19
|
return false;
|
|
@@ -29,8 +31,9 @@ export const isApprovalRulesTabVisible = (userRole, isDebitCardFlagEnabled, curr
|
|
|
29
31
|
hasReimbursementAccessible(currentTenant, userRoleMap) ||
|
|
30
32
|
((isBillPayTOSAccepted || isReimbursementTOSAccepted) &&
|
|
31
33
|
hasFullOrAdminLevelAccess(userRole))) &&
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
(isTenantAccountingServicesEnabled(currentTenant) ||
|
|
35
|
+
(isTenantBankingOnly(isDebitCardFlagEnabled, currentTenant) === false &&
|
|
36
|
+
isTenantCardsOnly(currentTenant) === false)));
|
|
34
37
|
}
|
|
35
38
|
else {
|
|
36
39
|
return false;
|
|
@@ -55,7 +58,8 @@ export const isBankConnectionsTabVisible = (currentTenant, userRoleMap) => {
|
|
|
55
58
|
return (hasBillPayAccessible(currentTenant, userRoleMap) ||
|
|
56
59
|
hasReimbursementAccessible(currentTenant, userRoleMap) ||
|
|
57
60
|
hasZeniAccountsAccessible(currentTenant, userRoleMap) ||
|
|
58
|
-
hasChargeCardAccessible(currentTenant, userRoleMap)
|
|
61
|
+
(hasChargeCardAccessible(currentTenant, userRoleMap) &&
|
|
62
|
+
isCardsProductEnabledOnCompany(currentTenant.company)));
|
|
59
63
|
}
|
|
60
64
|
else {
|
|
61
65
|
return false;
|
|
@@ -69,7 +73,8 @@ export const isBusinessVerificationTabVisible = (currentTenant, userRoleMap) =>
|
|
|
69
73
|
return (hasBillPayAccessible(currentTenant, userRoleMap) ||
|
|
70
74
|
hasReimbursementAccessible(currentTenant, userRoleMap) ||
|
|
71
75
|
hasZeniAccountsAccessible(currentTenant, userRoleMap) ||
|
|
72
|
-
hasChargeCardAccessible(currentTenant, userRoleMap)
|
|
76
|
+
(hasChargeCardAccessible(currentTenant, userRoleMap) &&
|
|
77
|
+
isCardsProductEnabledOnCompany(currentTenant.company)));
|
|
73
78
|
}
|
|
74
79
|
else {
|
|
75
80
|
return false;
|
|
@@ -94,7 +99,7 @@ export const isIntegrationsTabVisible = (userRole, isDebitCardFlagEnabled, curre
|
|
|
94
99
|
}
|
|
95
100
|
if (isSettingsVisible(currentTenant)) {
|
|
96
101
|
return (hasFullOrAdminLevelAccess(userRole) &&
|
|
97
|
-
(
|
|
102
|
+
(isTenantAccountingServicesEnabled(currentTenant) ||
|
|
98
103
|
!(isTenantBankingOnly(isDebitCardFlagEnabled, currentTenant) ||
|
|
99
104
|
isTenantCardsOnly(currentTenant))));
|
|
100
105
|
}
|
|
@@ -147,6 +152,7 @@ export const isNotificationsTabVisible = (notificationSettings, signedInUseEmail
|
|
|
147
152
|
const { reminderNotificationSettings, monthEndInsightsNotificationSettings } = notificationSettings;
|
|
148
153
|
return ((isRemindersSectionVisibleOnSettingsPage(reminderNotificationSettings) ||
|
|
149
154
|
isMonthEndNotificationsSectionVisibleOnSettingsPage(monthEndInsightsNotificationSettings, signedInUseEmail)) &&
|
|
150
|
-
|
|
151
|
-
|
|
155
|
+
(isTenantAccountingServicesEnabled(currentTenant) ||
|
|
156
|
+
(isTenantBankingOnly(isDebitCardFlagEnabled, currentTenant) === false &&
|
|
157
|
+
isTenantCardsOnly(currentTenant) === false)));
|
|
152
158
|
};
|
|
@@ -29,6 +29,7 @@ export const toTransactionUpdatesFromTransactionDetailLocalData = (transactionDe
|
|
|
29
29
|
const entityUpdates = {};
|
|
30
30
|
const isTransactionMisCategorized = isTransactionMiscategorized(transaction, isExpenseAutomationEnabled);
|
|
31
31
|
updates.memo = transactionDetailLocalData.memo;
|
|
32
|
+
updates.documentId = transactionDetailLocalData.documentId;
|
|
32
33
|
const selectedEntity = transactionDetailLocalData.selectedEntity;
|
|
33
34
|
const updatedEntityId = transactionDetailLocalData.updatePreviousTransactionsWithUpdatedVendor ===
|
|
34
35
|
true
|
|
@@ -168,6 +168,12 @@ function preparePayload(transactionState, vendorState, transactionDetailState, t
|
|
|
168
168
|
const toTransactionUpdatePayload = (updates, detail, cotTransactionTracking, vendorUpdates, customerUpdates, tranSelectedEntity) => {
|
|
169
169
|
const transaction = Object.assign({}, detail);
|
|
170
170
|
transaction.memo = updates.memo ?? '';
|
|
171
|
+
// Unlike `memo` (always reset to '' when absent), `documentId` falls back to
|
|
172
|
+
// the existing value rather than ''. Only the journal-entry title is
|
|
173
|
+
// user-editable; for every other transaction type `updates.documentId` is
|
|
174
|
+
// either the unchanged current value or undefined, and we must not send an
|
|
175
|
+
// empty `document_id` that the server would treat as clearing the number.
|
|
176
|
+
transaction.documentId = updates.documentId ?? transaction.documentId;
|
|
171
177
|
const recommendationUpdates = {};
|
|
172
178
|
for (const key in updates.updatesByLineId) {
|
|
173
179
|
const lineUpdates = updates.updatesByLineId[key];
|
|
@@ -11,6 +11,7 @@ export const toTransactionDetailLocalData = (transaction, defaultVendorId, uncat
|
|
|
11
11
|
?.id;
|
|
12
12
|
const vendorId = defaultVendorId ?? transaction.vendor?.id;
|
|
13
13
|
transactionLocal.memo = transaction.memo;
|
|
14
|
+
transactionLocal.documentId = transaction.documentId;
|
|
14
15
|
transactionLocal.vendorUpdates =
|
|
15
16
|
isVendorTransaction(transaction) && vendorId != null
|
|
16
17
|
? {
|
|
@@ -421,6 +422,7 @@ export const toUpdateLineItemsOriginalCategoryClass = (transaction, transactionD
|
|
|
421
422
|
const newLocalData = {
|
|
422
423
|
...initialSupportedTransactionDetail.transactionDetailLocalData,
|
|
423
424
|
memo: transactionDetailLocalData.memo,
|
|
425
|
+
documentId: transactionDetailLocalData.documentId,
|
|
424
426
|
lineItemById: newLineItems,
|
|
425
427
|
vendorDetails: transactionDetailLocalData.vendorDetails,
|
|
426
428
|
vendorUpdates: transactionDetailLocalData.vendorUpdates,
|
|
@@ -524,6 +526,7 @@ export const toSetAllLineItemsToCategoryClass = (transaction, transactionDetailL
|
|
|
524
526
|
const newLocalData = {
|
|
525
527
|
...initialSupportedTransactionDetail.transactionDetailLocalData,
|
|
526
528
|
memo: transactionDetailLocalData.memo,
|
|
529
|
+
documentId: transactionDetailLocalData.documentId,
|
|
527
530
|
lineItemById: newLineItems,
|
|
528
531
|
vendorUpdates: transactionDetailLocalData.vendorUpdates,
|
|
529
532
|
vendorDetails: transactionDetailLocalData.vendorDetails,
|
|
@@ -568,6 +571,7 @@ export const toSetAllLineItemsLocalDataIsUpdateAllChecked = (transaction, transa
|
|
|
568
571
|
const newLocalData = {
|
|
569
572
|
...initialSupportedTransactionDetail.transactionDetailLocalData,
|
|
570
573
|
memo: transactionDetailLocalData.memo,
|
|
574
|
+
documentId: transactionDetailLocalData.documentId,
|
|
571
575
|
lineItemById: newLineItems,
|
|
572
576
|
vendorDetails: transactionDetailLocalData.vendorDetails,
|
|
573
577
|
vendorUpdates: transactionDetailLocalData.vendorUpdates,
|
|
@@ -724,6 +728,7 @@ export const setEntityRecommendationForLineIdInLocalData = (transaction, transac
|
|
|
724
728
|
const newLocalData = {
|
|
725
729
|
...initialSupportedTransactionDetail.transactionDetailLocalData,
|
|
726
730
|
memo: transactionDetailLocalData.memo,
|
|
731
|
+
documentId: transactionDetailLocalData.documentId,
|
|
727
732
|
lineItemById: newLineItems,
|
|
728
733
|
vendorUpdates: transactionDetailLocalData.vendorUpdates,
|
|
729
734
|
vendorDetails: transactionDetailLocalData.vendorDetails,
|
|
@@ -776,6 +781,7 @@ export const removeEntityRecommendationForLineIdInLocalData = (transaction, tran
|
|
|
776
781
|
const newLocalData = {
|
|
777
782
|
...initialSupportedTransactionDetail.transactionDetailLocalData,
|
|
778
783
|
memo: transactionDetailLocalData.memo,
|
|
784
|
+
documentId: transactionDetailLocalData.documentId,
|
|
779
785
|
lineItemById: newLineItems,
|
|
780
786
|
vendorDetails: transactionDetailLocalData.vendorDetails,
|
|
781
787
|
vendorUpdates: transactionDetailLocalData.vendorUpdates,
|
|
@@ -881,7 +887,6 @@ export const toSetAllLineItemsToVendor = (transaction, transactionDetailLocalDat
|
|
|
881
887
|
}
|
|
882
888
|
const newLocalData = {
|
|
883
889
|
...transactionDetailLocalData,
|
|
884
|
-
memo: transactionDetailLocalData.memo,
|
|
885
890
|
lineItemById: newLineItems,
|
|
886
891
|
isVendorUpdateAllChecked: true,
|
|
887
892
|
};
|
|
@@ -996,6 +1001,7 @@ export const toUpdateLineItemsToOriginalVendor = (transaction, transactionDetail
|
|
|
996
1001
|
const newLocalData = {
|
|
997
1002
|
...initialSupportedTransactionDetail.transactionDetailLocalData,
|
|
998
1003
|
memo: transactionDetailLocalData.memo,
|
|
1004
|
+
documentId: transactionDetailLocalData.documentId,
|
|
999
1005
|
lineItemById: newLineItems,
|
|
1000
1006
|
isVendorUpdateAllChecked: false,
|
|
1001
1007
|
latestUpdatedLineWithEntity: transactionDetailLocalData.latestUpdatedLineWithEntity,
|
package/lib/index.d.ts
CHANGED
|
@@ -68,6 +68,7 @@ import { ChargeCardTransaction, ChargeCardTransactionStatus, ChargeCardTransacti
|
|
|
68
68
|
import { ChargeCardTransactionPayload, TransactionReceiptsPayload, attachmentFilePathToAttachment } from './entity/chargeCardTransaction/chargeCardTransactionPayload';
|
|
69
69
|
import { updateChargeCardTransactionAttachments } from './entity/chargeCardTransaction/chargeCardTransactionReducer';
|
|
70
70
|
import { updateChargeCardTransactionFromPusher, updateChargeCardTransactionReceiptFromPusher, updateChargeCardTransactionStatusFromPusher } from './entity/chargeCardTransaction/chargeCardTransactionReducer';
|
|
71
|
+
import { filterChargeCardRolesWhenProductDisabled, isCardsProductEnabledOnCompany } from './entity/company/cardsVisibilityHelpers';
|
|
71
72
|
import { getControllersName, getFirstControllerEmail, getFirstControllerId } from './entity/company/companyHelper';
|
|
72
73
|
import { CompanyWithSchema, ControllerUserDetails, getCompanyByCompanyId, getCompanyInfoForAllCockpitCompaniesInState, getControllersForCompany } from './entity/company/companySelector';
|
|
73
74
|
import { ALL_ACCOUNTING_CONNECTION_CREATION_MODES, AccountingConnectionCreationMode, Company, CompanyBillPayInfo, CompanyChargeCardInfo, CompanyConfigInfo, CompanyDebitCardInfo, CompanyFeaturesActivationInfo, CompanyIncInfo, CompanyInfo, CompanyLocaleInfo, CompanyManagementInfo, CompanyManagementUserRole, CompanyMileageConfigInfo, CompanyOnboardingAiActivationInfo, CompanyQuestionaire, CompanyReimbursementInfo, CompanyTaxInfo, CompanyZeniAccountInfo, IdentityVerificationStatus, OnboardingIdentityVerficationStatus, OnboardingInfo, OnboardingStepInfo, OnboardingStepsInfo, ParentSubsidiaryInfo, UserReimbursementInfo, isCompanyEligibleForTreasury } from './entity/company/companyStateTypes';
|
|
@@ -768,7 +769,7 @@ export { SubscriptionAddOn, SubscriptionAddOnWithSchema, SubscriptionAddOnSchema
|
|
|
768
769
|
export { SubscriptionCoupon, SubscriptionCouponSchemaKeys };
|
|
769
770
|
export { SubscriptionPlan, SubscriptionPlanSchemaKeys };
|
|
770
771
|
export { SubscriptionSummary, SubscriptionSummarySchemaKeys };
|
|
771
|
-
export { CompanyInfo, CompanyLocaleInfo, CompanyIncInfo, CompanyTaxInfo, CompanyQuestionaire, CompanyManagementInfo, CompanyManagementUserRole, Company, ParentSubsidiaryInfo, CompanyConfigInfo, CompanyReimbursementInfo, CompanyZeniAccountInfo, CompanyBillPayInfo, CompanyChargeCardInfo, CompanyDebitCardInfo, CompanyFeaturesActivationInfo, CompanyMileageConfigInfo, CompanyOnboardingAiActivationInfo, UserReimbursementInfo, OnboardingInfo, OnboardingStepsInfo, OnboardingStepInfo, AccountingConnectionCreationMode, ALL_ACCOUNTING_CONNECTION_CREATION_MODES, OnboardingIdentityVerficationStatus, IdentityVerificationStatus, isCompanyEligibleForTreasury, };
|
|
772
|
+
export { CompanyInfo, CompanyLocaleInfo, CompanyIncInfo, CompanyTaxInfo, CompanyQuestionaire, CompanyManagementInfo, CompanyManagementUserRole, Company, ParentSubsidiaryInfo, CompanyConfigInfo, CompanyReimbursementInfo, CompanyZeniAccountInfo, CompanyBillPayInfo, CompanyChargeCardInfo, CompanyDebitCardInfo, CompanyFeaturesActivationInfo, CompanyMileageConfigInfo, CompanyOnboardingAiActivationInfo, UserReimbursementInfo, OnboardingInfo, OnboardingStepsInfo, OnboardingStepInfo, AccountingConnectionCreationMode, ALL_ACCOUNTING_CONNECTION_CREATION_MODES, OnboardingIdentityVerficationStatus, IdentityVerificationStatus, isCompanyEligibleForTreasury, isCardsProductEnabledOnCompany, filterChargeCardRolesWhenProductDisabled, };
|
|
772
773
|
export { getCompanyByCompanyId, CompanyWithSchema, getControllersForCompany, getCompanyInfoForAllCockpitCompaniesInState, ControllerUserDetails, getFirstControllerEmail, getFirstControllerId, getControllersName, };
|
|
773
774
|
export type { ZeniUsersResponse } from './view/companyView/companyViewPayload';
|
|
774
775
|
export { CompanyView };
|