bp - assign account to company
MODIFY
src/assets/charging-station-templates
src/assets/charging-station-templates
-Subproject commit bc9cf2530c7c12e42a80c7531f8aff1a9bac89f2
+Subproject commit 2b5f0123b4aaa6ec28c180ce929356101d64450d

MODIFY
src/assets/server/rest/v1/schemas/company/company-create.json
src/assets/server/rest/v1/schemas/company/company-create.json
"platformFeeStrategy": {
"$ref": "billing-account#/definitions/platformFeeStrategy"
}
- },
- "required": [
- "accountID",
- "platformFeeStrategy"
- ]
+ }
}
},
"required": [

MODIFY
src/assets/server/rest/v1/schemas/company/company-update.json
src/assets/server/rest/v1/schemas/company/company-update.json
"platformFeeStrategy": {
"$ref": "billing-account#/definitions/platformFeeStrategy"
}
- },
- "required": [
- "accountID",
- "platformFeeStrategy"
- ]
+ }
}
},
"required": [

MODIFY
src/server/rest/v1/router/api/BillingRouter.ts
src/server/rest/v1/router/api/BillingRouter.ts
@@ -41,7 +41,7 @@ export default class BillingRouter {
// -----------------------------------
this.buildRouteBillingGetTaxes();
// -----------------------------------
- // ROUTES for SUB-ACCOUNTS
+ // ROUTES for Connected Accounts
// -----------------------------------
this.buildRouteBillingCreateAccount();
this.buildRouteBillingGetAccounts();

MODIFY
src/server/rest/v1/service/CompanyService.ts
src/server/rest/v1/service/CompanyService.ts
@@ -150,12 +150,14 @@ export default class CompanyService {
createdBy: { id: req.user.id },
createdOn: new Date()
} as Company;
- // If the company is assigned to a billing account, check if the billing is active
+ // Connected Account
if (filteredRequest.accountData) {
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.BILLING_PLATFORM,
Action.CREATE, Entity.COMPANY, MODULE_NAME, 'handleCreateCompany');
+ if (filteredRequest.accountData.accountID) {
const billingAccount = await BillingStorage.getAccountByID(req.tenant, filteredRequest.accountData.accountID);
- UtilsService.assertObjectExists(action, billingAccount, `Billing Sub-Account ID '${filteredRequest.accountData.accountID}' does not exist`, MODULE_NAME, 'handleCreateCompany', req.user);
+ UtilsService.assertObjectExists(action, billingAccount, `Billing Account ID '${filteredRequest.accountData.accountID}' does not exist`, MODULE_NAME, 'handleCreateCompany', req.user);
+ }
}
// Save
newCompany.id = await CompanyStorage.saveCompany(req.tenant, newCompany);
@@ -185,19 +187,18 @@ export default class CompanyService {
if (Utils.objectHasProperty(filteredRequest, 'logo')) {
company.logo = filteredRequest.logo;
}
- company.lastChangedBy = { 'id': req.user.id };
- company.lastChangedOn = new Date();
- // If the company is assigned to a billing account, check if the billing is active
+ // Connected Account
if (filteredRequest.accountData) {
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.BILLING_PLATFORM,
- Action.CREATE, Entity.COMPANY, MODULE_NAME, 'handleUpdateCompany');
+ Action.UPDATE, Entity.COMPANY, MODULE_NAME, 'handleUpdateCompany');
+ if (filteredRequest.accountData.accountID) {
const billingAccount = await BillingStorage.getAccountByID(req.tenant, filteredRequest.accountData.accountID);
- UtilsService.assertObjectExists(action, billingAccount, `Billing Sub-Account ID '${filteredRequest.accountData.accountID}' does not exist`, MODULE_NAME, 'handleUpdateCompany', req.user);
- company.accountData = {
- accountID: billingAccount.id,
- platformFeeStrategy: filteredRequest.accountData.platformFeeStrategy,
- };
+ UtilsService.assertObjectExists(action, billingAccount, `Billing Account ID '${filteredRequest.accountData.accountID}' does not exist`, MODULE_NAME, 'handleUpdateCompany', req.user);
}
+ company.accountData = filteredRequest.accountData;
+ }
+ company.lastChangedBy = { 'id': req.user.id };
+ company.lastChangedOn = new Date();
// Update Company
await CompanyStorage.saveCompany(req.tenant, company, Utils.objectHasProperty(filteredRequest, 'logo') ? true : false);
await Logging.logInfo({

MODIFY
src/server/rest/v1/service/SiteService.ts
src/server/rest/v1/service/SiteService.ts
@@ -305,7 +305,7 @@ export default class SiteService {
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.BILLING_PLATFORM,
Action.CREATE, Entity.SITE, MODULE_NAME, 'handleCreateSite');
const billingAccount = await BillingStorage.getAccountByID(req.tenant, filteredRequest.accountData.accountID);
- UtilsService.assertObjectExists(action, billingAccount, `Billing Sub-Account ID '${filteredRequest.accountData.accountID}' does not exist`, MODULE_NAME, 'handleCreateSite', req.user);
+ UtilsService.assertObjectExists(action, billingAccount, `Billing Account ID '${filteredRequest.accountData.accountID}' does not exist`, MODULE_NAME, 'handleCreateSite', req.user);
}
// Save
site.id = await SiteStorage.saveSite(req.tenant, site, Utils.objectHasProperty(filteredRequest, 'image'));
@@ -376,7 +376,7 @@ export default class SiteService {
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.BILLING_PLATFORM,
Action.CREATE, Entity.SITE, MODULE_NAME, 'handleUpdateSite');
const billingAccount = await BillingStorage.getAccountByID(req.tenant, filteredRequest.accountData.accountID);
- UtilsService.assertObjectExists(action, billingAccount, `Billing Sub-Account ID '${filteredRequest.accountData.accountID}' does not exist`, MODULE_NAME, 'handleUpdateSite', req.user);
+ UtilsService.assertObjectExists(action, billingAccount, `Billing Account ID '${filteredRequest.accountData.accountID}' does not exist`, MODULE_NAME, 'handleUpdateSite', req.user);
site.accountData = {
accountID: billingAccount.id,
platformFeeStrategy: filteredRequest.accountData.platformFeeStrategy,

MODIFY
src/storage/mongodb/BillingStorage.ts
src/storage/mongodb/BillingStorage.ts
@@ -480,7 +480,7 @@ export default class BillingStorage {
aggregation.push({
$limit: dbParams.limit
});
- // Add Sub-account
+ // Add connected account information
DatabaseUtils.pushAccountLookupInAggregation({
tenantID: tenant.id, aggregation: aggregation, asField: 'account', localField: 'accountID',
foreignField: '_id', oneToOneCardinality: true, oneToOneCardinalityNotNull: false

MODIFY
src/storage/mongodb/CompanyStorage.ts
src/storage/mongodb/CompanyStorage.ts
@@ -61,11 +61,18 @@ export default class CompanyStorage {
(coordinate) => Utils.convertToFloat(coordinate)) : [],
};
}
- if (companyToSave.accountData && Utils.isTenantComponentActive(tenant, TenantComponents.BILLING_PLATFORM)) {
+ if (Utils.isTenantComponentActive(tenant, TenantComponents.BILLING_PLATFORM)) {
+ if (companyToSave.accountData) {
companyMDB.accountData = {
accountID: DatabaseUtils.convertToObjectID(companyToSave.accountData.accountID),
- platformFeeStrategy: companyToSave.accountData.platformFeeStrategy,
+ platformFeeStrategy: {
+ flatFeePerSession: companyToSave.accountData.platformFeeStrategy?.flatFeePerSession || 0,
+ percentage: companyToSave.accountData.platformFeeStrategy?.percentage || 0,
+ }
};
+ } else {
+ companyToSave.accountData = null;
+ }
}
// Add Last Changed/Created props
DatabaseUtils.addLastChangedCreatedProps(companyMDB, companyToSave);

MODIFY
test/api/BillingPlatformTest.ts
test/api/BillingPlatformTest.ts
@@ -237,20 +237,6 @@ describeif(isBillingProperlyConfigured)('Billing Platform (utbillingplatform)',
await billingTestHelper.setBillingSystemValidCredentials(true, false /* immediateBillingAllowed OFF */);
});
- // -------------------------------------------------------------------------------------------------------------
- // TO DO - GENERATE SEVERAL TRANSACTIONS
- // -------------------------------------------------------------------------------------------------------------
- // - create and onboard two accounts
- // - assign a account at a company level (with a platform fee strategy)
- // - Override the account at a site level (with a distinct platform fee strategy)
- // - Generate several transactions
- // - Make sure to select the periodic billing mode and generate DRAFT invoices
- // - Make sure to have several sessions per invoices
- // - Make sure each invoices targets SEVERAL SUB-ACCOUNTS
- // - force the periodic billing and thus GENERATE SEVERAL TRANSFERS
- // - finalize the transfers!!!!
- // - send the transfers to STRIPE to generate the real transfer of funds
- // -------------------------------------------------------------------------------------------------------------
it('should create an invoice, and get transfers generated', async () => {
// Create a account
await billingTestHelper.makeCurrentUserContextReadyForBilling();

bp - assign account to company