billing - feature toggle cleanup - lazy user sync
MODIFY
src/integration/billing/BillingIntegration.ts
src/integration/billing/BillingIntegration.ts
@@ -36,55 +36,6 @@ export default abstract class BillingIntegration {
this.settings = settings;
}
- public async synchronizeUsers(): Promise<BillingUserSynchronizeAction> {
- await this.checkConnection();
- const actionsDone: BillingUserSynchronizeAction = {
- inSuccess: 0,
- inError: 0
- };
- if (FeatureToggles.isFeatureActive(Feature.BILLING_SYNC_USERS)) {
- // Sync e-Mobility Users with no billing data
- const users = await this._getUsersWithNoBillingData();
- if (!Utils.isEmptyArray(users)) {
- // Process them
- await Logging.logInfo({
- tenantID: this.tenant.id,
- action: ServerAction.BILLING_SYNCHRONIZE_USERS,
- module: MODULE_NAME, method: 'synchronizeUsers',
- message: `${users.length} new user(s) are going to be synchronized`
- });
- for (const user of users) {
- // Synchronize user
- if (await this.synchronizeUser(user)) {
- actionsDone.inSuccess++;
- } else {
- actionsDone.inError++;
- }
- }
- }
- } else {
- await Logging.logWarning({
- tenantID: this.tenant.id,
- action: ServerAction.BILLING_SYNCHRONIZE_USERS,
- module: MODULE_NAME, method: 'synchronizeUsers',
- message: 'Feature is switched OFF - operation has been aborted'
- });
- }
- // Log
- await Logging.logActionsResponse(this.tenant.id, ServerAction.BILLING_SYNCHRONIZE_USERS,
- MODULE_NAME, 'synchronizeUsers', actionsDone,
- '{{inSuccess}} user(s) were successfully synchronized',
- '{{inError}} user(s) failed to be synchronized',
- '{{inSuccess}} user(s) were successfully synchronized and {{inError}} failed to be synchronized',
- 'All the users are up to date'
- );
- // Update last synchronization
- this.settings.billing.usersLastSynchronizedOn = new Date();
- await SettingStorage.saveBillingSetting(this.tenant, this.settings);
- // Result
- return actionsDone;
- }
-
public async synchronizeUser(user: User): Promise<BillingUser> {
let billingUser: BillingUser = null;
try {
@@ -142,21 +93,6 @@ export default abstract class BillingIntegration {
return billingUser;
}
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- public async synchronizeInvoices(user?: User): Promise<BillingUserSynchronizeAction> {
- const actionsDone: BillingUserSynchronizeAction = {
- inSuccess: 0,
- inError: 0
- };
- await Logging.logWarning({
- tenantID: this.tenant.id,
- action: ServerAction.BILLING_SYNCHRONIZE_INVOICES,
- module: MODULE_NAME, method: 'synchronizeInvoices',
- message: 'Method is deprecated - operation skipped'
- });
- return actionsDone;
- }
-
public async chargeInvoices(forceOperation = false): Promise<BillingChargeInvoiceAction> {
const actionsDone: BillingChargeInvoiceAction = {
inSuccess: 0,

MODIFY
src/scheduler/SchedulerManager.ts
src/scheduler/SchedulerManager.ts
@@ -27,8 +27,6 @@ import OICPPushEvseDataTask from './tasks/oicp/OICPPushEvseDataTask';
import OICPPushEvseStatusTask from './tasks/oicp/OICPPushEvseStatusTask';
import SchedulerTask from './SchedulerTask';
import { ServerAction } from '../types/Server';
-import SynchronizeBillingInvoicesTask from './tasks/SynchronizeBillingInvoicesTask';
-import SynchronizeBillingUsersTask from './tasks/SynchronizeBillingUsersTask';
import SynchronizeCarsTask from './tasks/SynchronizeCarsTask';
import SynchronizeRefundTransactionsTask from './tasks/SynchronizeRefundTransactionsTask';
import cron from 'node-cron';
@@ -122,10 +120,6 @@ export default class SchedulerManager {
return new OCPIPushCdrsTask();
case 'SynchronizeRefundTransactionsTask':
return new SynchronizeRefundTransactionsTask();
- case 'SynchronizeBillingUsersTask':
- return new SynchronizeBillingUsersTask();
- case 'SynchronizeBillingInvoicesTask':
- return new SynchronizeBillingInvoicesTask();
case 'BillingPeriodicOperationTask':
return new BillingPeriodicOperationTask();
case 'BillPendingTransactionTask':

DELETE
src/scheduler/tasks/SynchronizeBillingInvoicesTask.ts
-import BillingFactory from '../../integration/billing/BillingFactory';
-import { BillingInvoiceSynchronizationTaskConfig } from '../../types/TaskConfig';
-import LockingHelper from '../../locking/LockingHelper';
-import LockingManager from '../../locking/LockingManager';
-import Logging from '../../utils/Logging';
-import NotificationHandler from '../../notification/NotificationHandler';
-import { ServerAction } from '../../types/Server';
-import Tenant from '../../types/Tenant';
-import TenantSchedulerTask from '../TenantSchedulerTask';
-import Utils from '../../utils/Utils';
-
-export default class SynchronizeBillingInvoicesTask extends TenantSchedulerTask {
- public async processTenant(tenant: Tenant, taskConfig: BillingInvoiceSynchronizationTaskConfig): Promise<void> {
- // Get the lock
- const billingLock = await LockingHelper.acquireBillingSyncInvoicesLock(tenant.id);
- if (billingLock) {
- try {
- const billingImpl = await BillingFactory.getBillingImpl(tenant);
- if (billingImpl) {
- // Synchronize new Invoices and Invoices changes
- const synchronizeActionResults = await billingImpl.synchronizeInvoices();
- if (synchronizeActionResults.inError > 0) {
- void NotificationHandler.sendBillingInvoicesSynchronizationFailed(
- tenant,
- {
- nbrInvoicesInError: synchronizeActionResults.inError,
- evseDashboardURL: Utils.buildEvseURL(tenant.subdomain),
- evseDashboardBillingURL: Utils.buildEvseBillingSettingsURL(tenant.subdomain)
- }
- );
- }
- }
- } catch (error) {
- // Log error
- await Logging.logActionExceptionMessage(tenant.id, ServerAction.BILLING_SYNCHRONIZE_INVOICES, error);
- } finally {
- // Release the lock
- await LockingManager.release(billingLock);
- }
- }
- }
-}

DELETE
src/scheduler/tasks/SynchronizeBillingUsersTask.ts
-import BillingFactory from '../../integration/billing/BillingFactory';
-import LockingHelper from '../../locking/LockingHelper';
-import LockingManager from '../../locking/LockingManager';
-import Logging from '../../utils/Logging';
-import NotificationHandler from '../../notification/NotificationHandler';
-import { ServerAction } from '../../types/Server';
-import { TaskConfig } from '../../types/TaskConfig';
-import Tenant from '../../types/Tenant';
-import TenantSchedulerTask from '../TenantSchedulerTask';
-import Utils from '../../utils/Utils';
-
-export default class SynchronizeBillingUsersTask extends TenantSchedulerTask {
- public async processTenant(tenant: Tenant, config: TaskConfig): Promise<void> {
- // Get the lock
- const billingLock = await LockingHelper.acquireBillingSyncUsersLock(tenant.id);
- if (billingLock) {
- try {
- const billingImpl = await BillingFactory.getBillingImpl(tenant);
- if (billingImpl) {
- const synchronizeAction = await billingImpl.synchronizeUsers();
- if (synchronizeAction.inError > 0) {
- void NotificationHandler.sendBillingSynchronizationFailed(
- tenant,
- {
- nbrUsersInError: synchronizeAction.inError,
- evseDashboardURL: Utils.buildEvseURL(tenant.subdomain),
- evseDashboardBillingURL: Utils.buildEvseBillingSettingsURL(tenant.subdomain)
- }
- );
- }
- }
- } catch (error) {
- // Log error
- await Logging.logActionExceptionMessage(tenant.id, ServerAction.BILLING_SYNCHRONIZE_USERS, error);
- } finally {
- // Release the lock
- await LockingManager.release(billingLock);
- }
- }
- }
-}

MODIFY
src/server/rest/CentralRestServerService.ts
src/server/rest/CentralRestServerService.ts
@@ -51,11 +51,7 @@ class RequestMapper {
[ServerAction.TRANSACTION_PUSH_CDR]: TransactionService.handlePushTransactionCdr.bind(this),
[ServerAction.SYNCHRONIZE_REFUNDED_TRANSACTIONS]: TransactionService.handleSynchronizeRefundedTransactions.bind(this),
[ServerAction.SETTING_CREATE]: SettingService.handleCreateSetting.bind(this),
- [ServerAction.BILLING_SYNCHRONIZE_USERS]: BillingService.handleSynchronizeUsers.bind(this),
- [ServerAction.BILLING_SYNCHRONIZE_USER]: BillingService.handleSynchronizeUser.bind(this),
[ServerAction.BILLING_FORCE_SYNCHRONIZE_USER]: BillingService.handleForceSynchronizeUser.bind(this),
- [ServerAction.BILLING_SYNCHRONIZE_INVOICES]: BillingService.handleSynchronizeInvoices.bind(this),
- [ServerAction.BILLING_FORCE_SYNCHRONIZE_USER_INVOICES]: BillingService.handleForceSynchronizeUserInvoices.bind(this),
[ServerAction.BILLING_SETUP_PAYMENT_METHOD]: BillingService.handleBillingSetupPaymentMethod.bind(this),
[ServerAction.OCPI_ENDPOINT_CREATE]: OCPIEndpointService.handleCreateOcpiEndpoint.bind(this),
[ServerAction.OCPI_ENDPOINT_PING]: OCPIEndpointService.handlePingOcpiEndpoint.bind(this),

MODIFY
src/server/rest/v1/service/BillingService.ts
src/server/rest/v1/service/BillingService.ts
import { Action, Entity } from '../../../../types/Authorization';
-import { BillingInvoiceStatus, BillingOperationResult, BillingPaymentMethod, BillingUserSynchronizeAction } from '../../../../types/Billing';
+import { BillingInvoiceStatus, BillingOperationResult, BillingPaymentMethod } from '../../../../types/Billing';
import { HTTPAuthError, HTTPError } from '../../../../types/HTTPError';
import { NextFunction, Request, Response } from 'express';
@@ -20,7 +20,6 @@ import { ServerAction } from '../../../../types/Server';
import SettingStorage from '../../../../storage/mongodb/SettingStorage';
import { StatusCodes } from 'http-status-codes';
import { TenantComponents } from '../../../../types/Tenant';
-import TenantStorage from '../../../../storage/mongodb/TenantStorage';
import User from '../../../../types/User';
import UserStorage from '../../../../storage/mongodb/UserStorage';
import Utils from '../../../../utils/Utils';
@@ -123,105 +122,6 @@ export default class BillingService {
next();
}
- public static async handleSynchronizeUsers(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
- if (!(await Authorizations.canSynchronizeUsersBilling(req.user)).authorized) {
- throw new AppAuthError({
- errorCode: HTTPAuthError.FORBIDDEN,
- user: req.user,
- entity: Entity.USER, action: Action.SYNCHRONIZE_BILLING_USERS,
- module: MODULE_NAME, method: 'handleSynchronizeUsers',
- });
- }
- // Check if component is active
- UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.BILLING,
- Action.SYNCHRONIZE_BILLING_USERS, Entity.USER, MODULE_NAME, 'handleSynchronizeUsers');
- const billingImpl = await BillingFactory.getBillingImpl(req.tenant);
- if (!billingImpl) {
- throw new AppError({
- errorCode: HTTPError.GENERAL_ERROR,
- message: 'Billing service is not configured',
- module: MODULE_NAME, method: 'handleSynchronizeUsers',
- action: action,
- user: req.user
- });
- }
- // Get the lock
- let synchronizeAction: BillingUserSynchronizeAction = {
- inError: 0,
- inSuccess: 0,
- };
- const billingLock = await LockingHelper.acquireBillingSyncUsersLock(req.user.tenantID);
- if (billingLock) {
- try {
- // Sync users
- synchronizeAction = await billingImpl.synchronizeUsers();
- } finally {
- // Release the lock
- await LockingManager.release(billingLock);
- }
- } else {
- throw new AppError({
- errorCode: HTTPError.GENERAL_ERROR,
- message: 'Cannot acquire lock',
- module: MODULE_NAME, method: 'handleSynchronizeUsers',
- action: action,
- user: req.user
- });
- }
- res.json(Object.assign(synchronizeAction, Constants.REST_RESPONSE_SUCCESS));
- next();
- }
-
- public static async handleSynchronizeUser(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
- const filteredRequest = BillingSecurity.filterSynchronizeUserRequest(req.body);
- if (!(await Authorizations.canSynchronizeUserBilling(req.user)).authorized) {
- throw new AppAuthError({
- errorCode: HTTPAuthError.FORBIDDEN,
- user: req.user,
- entity: Entity.USER, action: Action.SYNCHRONIZE_BILLING_USER,
- module: MODULE_NAME, method: 'handleSynchronizeUser',
- });
- }
- // Check if component is active
- UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.BILLING,
- Action.SYNCHRONIZE_BILLING_USERS, Entity.USER, MODULE_NAME, 'handleSynchronizeUser');
- const billingImpl = await BillingFactory.getBillingImpl(req.tenant);
- if (!billingImpl) {
- throw new AppError({
- errorCode: HTTPError.GENERAL_ERROR,
- message: 'Billing service is not configured',
- module: MODULE_NAME, method: 'handleSynchronizeUser',
- action: action,
- user: req.user
- });
- }
- // Get user
- const userToSynchronize = await UserStorage.getUser(req.tenant, filteredRequest.id);
- UtilsService.assertObjectExists(action, userToSynchronize, `User ID '${filteredRequest.id}' does not exist`,
- MODULE_NAME, 'handleSynchronizeUser', req.user);
- // Get the lock
- const billingLock = await LockingHelper.acquireBillingSyncUsersLock(req.user.tenantID);
- if (billingLock) {
- try {
- // Sync user
- await billingImpl.synchronizeUser(userToSynchronize);
- } finally {
- // Release the lock
- await LockingManager.release(billingLock);
- }
- } else {
- throw new AppError({
- errorCode: HTTPError.GENERAL_ERROR,
- message: 'Cannot acquire lock',
- module: MODULE_NAME, method: 'handleSynchronizeUser',
- action: action,
- user: req.user
- });
- }
- res.json(Constants.REST_RESPONSE_SUCCESS);
- next();
- }
-
public static async handleForceSynchronizeUser(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
const filteredRequest = BillingSecurity.filterSynchronizeUserRequest(req.body);
if (!(await Authorizations.canSynchronizeUserBilling(req.user)).authorized) {
@@ -374,118 +274,6 @@ export default class BillingService {
next();
}
- public static async handleSynchronizeInvoices(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
- if (!await Authorizations.canSynchronizeInvoicesBilling(req.user)) {
- throw new AppAuthError({
- errorCode: HTTPAuthError.FORBIDDEN,
- user: req.user,
- entity: Entity.INVOICE, action: Action.SYNCHRONIZE,
- module: MODULE_NAME, method: 'handleSynchronizeInvoices',
- });
- }
- // Check if component is active
- UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.BILLING,
- Action.SYNCHRONIZE, Entity.INVOICE, MODULE_NAME, 'handleSynchronizeInvoices');
- // Check user
- let user: User;
- if (!Authorizations.isAdmin(req.user)) {
- // Get the User
- user = await UserStorage.getUser(req.tenant, req.user.id);
- UtilsService.assertObjectExists(action, user, `User ID '${req.user.id}' does not exist`,
- MODULE_NAME, 'handleSynchronizeUserInvoices', req.user);
- }
- // Get the billing impl
- const billingImpl = await BillingFactory.getBillingImpl(req.tenant);
- if (!billingImpl) {
- throw new AppError({
- errorCode: HTTPError.GENERAL_ERROR,
- message: 'Billing service is not configured',
- module: MODULE_NAME, method: 'handleSynchronizeInvoices',
- action: action,
- user: req.user
- });
- }
- let synchronizeAction: BillingUserSynchronizeAction = {
- inError: 0,
- inSuccess: 0,
- };
- // Get the Invoice lock
- const billingLock = await LockingHelper.acquireBillingSyncInvoicesLock(req.user.tenantID);
- if (billingLock) {
- try {
- // Sync invoices
- synchronizeAction = await billingImpl.synchronizeInvoices(user);
- } finally {
- // Release the lock
- await LockingManager.release(billingLock);
- }
- } else {
- throw new AppError({
- errorCode: HTTPError.GENERAL_ERROR,
- message: 'Cannot acquire lock',
- module: MODULE_NAME, method: 'handleSynchronizeUserInvoices',
- action: action,
- user: req.user
- });
- }
- res.json(Object.assign(synchronizeAction, Constants.REST_RESPONSE_SUCCESS));
- next();
- }
-
- public static async handleForceSynchronizeUserInvoices(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
- if (!await Authorizations.canSynchronizeInvoicesBilling(req.user)) {
- throw new AppAuthError({
- errorCode: HTTPAuthError.FORBIDDEN,
- user: req.user,
- entity: Entity.INVOICE, action: Action.SYNCHRONIZE,
- module: MODULE_NAME, method: 'handleForceSynchronizeUserInvoices',
- });
- }
- // Check if component is active
- UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.BILLING,
- Action.SYNCHRONIZE, Entity.INVOICE, MODULE_NAME, 'handleForceSynchronizeUserInvoices');
- const billingImpl = await BillingFactory.getBillingImpl(req.tenant);
- if (!billingImpl) {
- throw new AppError({
- errorCode: HTTPError.GENERAL_ERROR,
- message: 'Billing service is not configured',
- module: MODULE_NAME, method: 'handleForceSynchronizeUserInvoices',
- action: action,
- user: req.user
- });
- }
- const filteredRequest = BillingSecurity.filterForceSynchronizeUserInvoicesRequest(req.body);
- // Get the User
- const user = await UserStorage.getUser(req.tenant, filteredRequest.userID);
- UtilsService.assertObjectExists(action, user, `User ID '${filteredRequest.userID}' does not exist`,
- MODULE_NAME, 'handleForceSynchronizeUserInvoices', req.user);
- // Get the Invoice lock
- let synchronizeAction: BillingUserSynchronizeAction = {
- inError: 0,
- inSuccess: 0,
- };
- const billingLock = await LockingHelper.acquireBillingSyncInvoicesLock(req.user.tenantID);
- if (billingLock) {
- try {
- // Sync invoices
- synchronizeAction = await billingImpl.synchronizeInvoices(user);
- } finally {
- // Release the lock
- await LockingManager.release(billingLock);
- }
- } else {
- throw new AppError({
- errorCode: HTTPError.GENERAL_ERROR,
- message: 'Cannot acquire lock',
- module: MODULE_NAME, method: 'handleForceSynchronizeUserInvoices',
- action: action,
- user: req.user
- });
- }
- res.json(Object.assign(synchronizeAction, Constants.REST_RESPONSE_SUCCESS));
- next();
- }
-
public static async handleBillingSetupPaymentMethod(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.BILLING,

MODIFY
src/storage/mongodb/UserStorage.ts
src/storage/mongodb/UserStorage.ts
-import FeatureToggles, { Feature } from '../../utils/FeatureToggles';
import Tenant, { TenantComponents } from '../../types/Tenant';
import User, { ImportedUser, UserRole, UserStatus } from '../../types/User';
import { UserInError, UserInErrorType } from '../../types/InError';
@@ -825,11 +824,7 @@ export default class UserStorage {
const array = [];
for (const type of params.errorTypes) {
if ((type === UserInErrorType.NOT_ASSIGNED && !Utils.isTenantComponentActive(tenant, TenantComponents.ORGANIZATION)) ||
- ((type === UserInErrorType.NO_BILLING_DATA || type === UserInErrorType.FAILED_BILLING_SYNCHRO) && !Utils.isTenantComponentActive(tenant, TenantComponents.BILLING))) {
- continue;
- }
- if (type === UserInErrorType.NO_BILLING_DATA && !FeatureToggles.isFeatureActive(Feature.BILLING_SYNC_USERS)) {
- // LAZY User Synchronization - no BillingData is not an Error anymore
+ (type === UserInErrorType.FAILED_BILLING_SYNCHRO && !Utils.isTenantComponentActive(tenant, TenantComponents.BILLING))) {
continue;
}
array.push(`$${type}`);
@@ -1083,11 +1078,6 @@ export default class UserStorage {
{ $match: { $or: [{ 'billingData.hasSynchroError': { $eq: true } }, { $and: [{ billingData: { $exists: true } }, { 'billingData.hasSynchroError': { $exists: false } }] }] } },
{ $addFields: { 'errorCode': UserInErrorType.FAILED_BILLING_SYNCHRO } }
];
- case UserInErrorType.NO_BILLING_DATA:
- return [
- { $match: { $and: [{ 'status': { $eq: UserStatus.ACTIVE } }, { 'billingData': { $exists: false } }] } },
- { $addFields: { 'errorCode': UserInErrorType.NO_BILLING_DATA } }
- ];
default:
return [];
}

MODIFY
src/types/InError.ts
src/types/InError.ts
@@ -53,7 +53,6 @@ export enum UserInErrorType {
NOT_ASSIGNED = 'unassigned_user',
INACTIVE_USER_ACCOUNT = 'inactive_user_account',
FAILED_BILLING_SYNCHRO = 'failed_billing_synchro',
- NO_BILLING_DATA = 'no_billing_data'
}
export enum AssetInErrorType {

MODIFY
src/types/Server.ts
src/types/Server.ts
@@ -419,16 +419,13 @@ export enum ServerAction {
BILLING = 'Billing',
BILLING_TRANSACTION = 'BillingTransaction',
- BILLING_SYNCHRONIZE_USERS = 'BillingSynchronizeUsers',
BILLING_SYNCHRONIZE_USER = 'BillingSynchronizeUser',
BILLING_FORCE_SYNCHRONIZE_USER = 'BillingForceSynchronizeUser',
CHECK_BILLING_CONNECTION = 'CheckBillingConnection',
BILLING_TAXES = 'BillingTaxes',
BILLING_INVOICES = 'BillingInvoices',
BILLING_INVOICE = 'BillingInvoice',
- BILLING_SYNCHRONIZE_INVOICES = 'BillingSynchronizeInvoices',
BILLING_PERFORM_OPERATIONS = 'BillingPeriodicOperations',
- BILLING_FORCE_SYNCHRONIZE_USER_INVOICES = 'BillingForceSynchronizeUserInvoices',
BILLING_DOWNLOAD_INVOICE = 'BillingDownloadInvoice',
BILLING_NEW_INVOICE = 'BillingNewInvoice',
BILLING_SETUP_PAYMENT_METHOD = 'BillingSetupPaymentMethod',

MODIFY
src/utils/FeatureToggles.ts
src/utils/FeatureToggles.ts
// Declare here the list of features
export enum Feature {
- BILLING_SYNC_USERS,
BILLING_PREVENT_CUSTOMER_DELETION,
BILLING_SHOW_PRICING_DETAIL,
}
export default class FeatureToggles {
// Comment out the features that you want to switch OFF
- static activeFeatures: Feature[] = [
- // Feature.BILLING_SYNC_USERS, - When switched OFF the sync of the user should be implicit (LAZY mode)
+ private static activeFeatures: Feature[] = [
Feature.BILLING_PREVENT_CUSTOMER_DELETION,
// Feature.BILLING_SHOW_PRICING_DETAIL,
];

MODIFY
test/api/BillingTest.ts
test/api/BillingTest.ts
@@ -437,8 +437,10 @@ describe('Billing', function() {
const fakeUser = {
...Factory.user.build(),
} as User;
- const response = await billingTestHelper.userService.billingApi.synchronizeUser({ id: fakeUser.id });
- expect(response.status).to.be.eq(StatusCodes.FORBIDDEN);
+ const billingUser = await billingTestHelper.billingImpl.synchronizeUser(fakeUser);
+ expect(billingUser).to.be.not.null;
+ // const response = await billingTestHelper.userService.billingApi.synchronizeUser({ id: fakeUser.id });
+ // expect(response.status).to.be.eq(StatusCodes.FORBIDDEN);
});
it('Should not force synchronization of a user', async () => {
@@ -465,13 +467,11 @@ describe('Billing', function() {
billingTestHelper.tenantContext.getTenant().subdomain,
billingTestHelper.userContext
);
- // await testData.userService.billingApi.synchronizeInvoices({});
const userWithBillingData = await billingTestHelper.billingImpl.getUser(billingTestHelper.userContext);
await billingTestHelper.assignPaymentMethod(userWithBillingData, 'tok_fr');
const itemsBefore = await billingTestHelper.getNumberOfSessions(basicUser.id);
const transactionID = await billingTestHelper.generateTransaction(billingTestHelper.userContext);
assert(transactionID, 'transactionID should not be null');
- // await testData.userService.billingApi.synchronizeInvoices({});
const itemsAfter = await billingTestHelper.getNumberOfSessions(basicUser.id);
expect(itemsAfter).to.be.eq(itemsBefore + 1);
});
@@ -516,7 +516,9 @@ describe('Billing', function() {
);
billingTestHelper.createdUsers.push(fakeUser);
billingTestHelper.billingImpl = await billingTestHelper.setBillingSystemValidCredentials();
- await billingTestHelper.userService.billingApi.synchronizeUser({ id: fakeUser.id });
+ // await billingTestHelper.userService.billingApi.synchronizeUser({ id: fakeUser.id });
+ const billingUser = await billingTestHelper.billingImpl.synchronizeUser(fakeUser);
+ expect(billingUser).to.be.not.null;
const userExists = await billingTestHelper.billingImpl.isUserSynchronized(fakeUser);
expect(userExists).to.be.true;
});
@@ -541,37 +543,6 @@ describe('Billing', function() {
assert(!transactionID, 'Transaction ID should not be set');
});
- it('Should set in error users without Billing data', async () => {
- const fakeUser = {
- ...Factory.user.build()
- } as User;
- fakeUser.issuer = true;
- // Creates user without billing data
- await billingTestHelper.userService.createEntity(
- billingTestHelper.userService.userApi,
- fakeUser
- );
- billingTestHelper.createdUsers.push(fakeUser);
- // Check if user is in Users In Error
- const response = await billingTestHelper.userService.userApi.readAllInError({ ErrorType: UserInErrorType.NO_BILLING_DATA }, {
- limit: 100,
- skip: 0
- });
- let userFound = false;
- for (const user of response.data.result) {
- if (user.id === fakeUser.id) {
- userFound = true;
- break;
- }
- }
- if (FeatureToggles.isFeatureActive(Feature.BILLING_SYNC_USERS)) {
- assert(userFound, 'User with no billing data should be listed as a User In Error');
- } else {
- // LAZY User Sync - The billing data will be created on demand (i.e.: when entering a payment method)
- assert(!userFound, 'User with no billing data should not be listed as a User In Error');
- }
- });
-
});
describe('Negative tests', () => {

billing - feature toggle cleanup - lazy user sync