bp - e2e test invoice to transfer - 1 drfat
MODIFY
src/integration/billing/BillingIntegration.ts
src/integration/billing/BillingIntegration.ts
@@ -819,7 +819,8 @@ export default abstract class BillingIntegration {
private computeAccountSessionFee(session: BillingSessionData, sessionTotalAmount: number): BillingAccountSessionFee {
const { percentage, flatFeePerSession } = session.accountData.platformFeeStrategy;
- const feeAmount = Utils.createDecimal(sessionTotalAmount).mul(percentage).div(100).plus(flatFeePerSession).toNumber();
+ const feeAmountAsDecimal = Utils.createDecimal(sessionTotalAmount).mul(percentage).div(100).plus(flatFeePerSession);
+ const feeAmount = Utils.roundTo(feeAmountAsDecimal, 2);
return {
percentage,
flatFeePerSession,

MODIFY
src/integration/billing/stripe/StripeBillingIntegration.ts
src/integration/billing/stripe/StripeBillingIntegration.ts
@@ -1761,7 +1761,7 @@ export default class StripeBillingIntegration extends BillingIntegration {
currency: billingTransfer.currency,
tax_rates,
description,
- amount: session.accountSessionFee.feeAmount,
+ amount: session.accountSessionFee.feeAmount * 100, // Stripe expects cents !!!
metadata: {
userID: user.id,
transferID: billingTransfer.id,
@@ -1822,14 +1822,15 @@ export default class StripeBillingIntegration extends BillingIntegration {
public convertToBillingPlatformInvoice(stripeInvoice: Stripe.Invoice): BillingPlatformInvoice {
// eslint-disable-next-line id-blacklist, max-len
- const { id: invoiceID, customer, number: invoiceNumber, livemode: liveMode, amount_due: amount, status, currency: invoiceCurrency, metadata } = stripeInvoice;
+ const { id: invoiceID, customer, number: invoiceNumber, livemode: liveMode, amount_due: amountCents, status, currency: invoiceCurrency, metadata } = stripeInvoice;
const customerID = customer as string;
const currency = invoiceCurrency?.toUpperCase();
const epoch = stripeInvoice.status_transitions?.finalized_at || stripeInvoice.created;
const createdOn = moment.unix(epoch).toDate(); // epoch to Date!
const userID = metadata.userID;
// Amount is in cents!
- const totalAmount = amount * 100;
+ const amount = amountCents ;
+ const totalAmount = Utils.createDecimal(amountCents).div(100).toNumber();
const invoice: BillingPlatformInvoice = {
invoiceID, invoiceNumber, liveMode, userID,
status: status as BillingInvoiceStatus,

MODIFY
src/types/Billing.ts
src/types/Billing.ts
@@ -231,7 +231,7 @@ export interface BillingPlatformInvoice {
userID: string;
invoiceNumber: string;
status: BillingInvoiceStatus;
- amount: number;
+ amount: number; // This one is in cents
totalAmount: number;
currency: string;
customerID: string;

MODIFY
test/api/BillingPlatformTest.ts
test/api/BillingPlatformTest.ts
@@ -39,20 +39,20 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
await global.database.start();
});
- describe('Billing Service (utbillingplatform)', () => {
+ describe('Where the admin user', () => {
beforeAll(async () => {
await stripeTestHelper.initialize(ContextDefinition.TENANT_CONTEXTS.TENANT_BILLING_PLATFORM);
// TODO - This is ugly and confusing - rethink that part (merge BillingTestHelper and StripeTestHelper methods)
await billingTestHelper.initialize(ContextDefinition.TENANT_CONTEXTS.TENANT_BILLING_PLATFORM);
// Initialize the Billing module
await billingTestHelper.setBillingSystemValidCredentials(true, false /* immediateBillingAllowed OFF, so periodicBilling ON */);
-
+ // Set the admin as the current user context
+ billingTestHelper.setCurrentUserContextAsAdmin();
});
describe('Connected Accounts', () => {
// eslint-disable-next-line @typescript-eslint/require-await
beforeAll(async () => {
- billingTestHelper.initUserContextAsAdmin();
});
it('should create an account in an IDLE state and list it', async () => {
@@ -94,9 +94,9 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
expect(companyResponse.data.accountData.platformFeeStrategy).to.deep.eq(platformFeeStrategy);
});
- it('should update a company to assign a account', async () => {
+ // Already tested
+ xit('should update a company to assign a account', async () => {
const billingAccount = await billingTestHelper.getActivatedAccount();
-
let companyResponse = await billingTestHelper.userService.companyApi.create(CompanyFactory.build());
expect(companyResponse.status).to.be.eq(StatusCodes.OK);
const companyID = companyResponse.data.id;
@@ -110,7 +110,6 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
}
});
expect(companyResponse.status).to.be.eq(StatusCodes.OK);
-
companyResponse = await billingTestHelper.userService.companyApi.readById(companyID);
expect(companyResponse.data.accountData.accountID).to.eq(billingAccount.id);
expect(companyResponse.data.accountData.platformFeeStrategy).to.deep.eq(platformFeeStrategy);
@@ -190,9 +189,8 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
describe('Transfers', () => {
// eslint-disable-next-line @typescript-eslint/require-await
beforeAll(async () => {
- billingTestHelper.initUserContextAsAdmin();
// Initialize the charging station context
- await billingTestHelper.initChargingStationContext2TestChargingTime();
+ // await billingTestHelper.initChargingStationContext2TestChargingTime();
});
it('should list transfers', async () => {
@@ -245,12 +243,10 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
});
});
- describe('Where admin user', () => {
- // eslint-disable-next-line @typescript-eslint/require-await
+ describe('Invoicing', () => {
beforeAll(async () => {
- billingTestHelper.initUserContextAsAdmin();
// Initialize the charging station context
- await billingTestHelper.initChargingStationContext2TestChargingTime();
+ await billingTestHelper.initContext2TestConnectedAccounts();
});
it('should create an invoice, and get transfers generated', async () => {
@@ -271,9 +267,8 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
// - finalize the transfers!!!!
// - send the transfers to STRIPE to generate the real transfer of funds
// -------------------------------------------------------------------------------------------------------------
- await billingTestHelper.userService.billingApi.forceSynchronizeUser({ id: billingTestHelper.userContext.id });
- const userWithBillingData = await billingTestHelper.billingImpl.getUser(billingTestHelper.userContext);
- await billingTestHelper.assignPaymentMethod(userWithBillingData, 'tok_fr');
+ // Create a account
+ await billingTestHelper.makeCurrentUserContextReadyForBilling();
const transactionID = await billingTestHelper.generateTransaction(billingTestHelper.userContext);
assert(transactionID, 'transactionID should not be null');
// Check that we have a new invoice with an invoiceID and but no invoiceNumber yet

MODIFY
test/api/BillingTest.ts
test/api/BillingTest.ts
@@ -127,7 +127,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
describe('As an admin - with transaction billing OFF', () => {
// eslint-disable-next-line @typescript-eslint/require-await
beforeAll(async () => {
- billingTestHelper.initUserContextAsAdmin();
+ billingTestHelper.setCurrentUserContextAsAdmin();
// Initialize the Billing module with transaction billing ON
await billingTestHelper.setBillingSystemValidCredentials(false);
});
@@ -193,7 +193,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
describe('As an admin - with transaction billing ON', () => {
// eslint-disable-next-line @typescript-eslint/require-await
beforeAll(async () => {
- billingTestHelper.initUserContextAsAdmin();
+ billingTestHelper.setCurrentUserContextAsAdmin();
// Initialize the Billing module with transaction billing ON
await billingTestHelper.setBillingSystemValidCredentials();
});
@@ -287,7 +287,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
xdescribe('Tune user profiles', () => {
// eslint-disable-next-line @typescript-eslint/require-await
beforeAll(async () => {
- billingTestHelper.initUserContextAsAdmin();
+ billingTestHelper.setCurrentUserContextAsAdmin();
});
it('Should change admin user locale to fr_FR', async () => {
@@ -306,13 +306,11 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
describe('Where admin user (essential)', () => {
// eslint-disable-next-line @typescript-eslint/require-await
beforeAll(async () => {
- billingTestHelper.initUserContextAsAdmin();
+ billingTestHelper.setCurrentUserContextAsAdmin();
});
it('should add an item to a DRAFT invoice after a transaction', async () => {
- await billingTestHelper.userService.billingApi.forceSynchronizeUser({ id: billingTestHelper.userContext.id });
- const userWithBillingData = await billingTestHelper.billingImpl.getUser(billingTestHelper.userContext);
- await billingTestHelper.assignPaymentMethod(userWithBillingData, 'tok_fr');
+ await billingTestHelper.makeCurrentUserContextReadyForBilling();
const itemsBefore = await billingTestHelper.getNumberOfSessions(billingTestHelper.userContext.id);
const transactionID = await billingTestHelper.generateTransaction(billingTestHelper.userContext);
assert(transactionID, 'transactionID should not be null');
@@ -324,7 +322,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
describe('Where admin user', () => {
// eslint-disable-next-line @typescript-eslint/require-await
beforeAll(async () => {
- billingTestHelper.initUserContextAsAdmin();
+ billingTestHelper.setCurrentUserContextAsAdmin();
});
it('Should connect to Billing Provider', async () => {
@@ -451,7 +449,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
describe('Negative tests as an admin user', () => {
// eslint-disable-next-line @typescript-eslint/require-await
beforeAll(async () => {
- billingTestHelper.initUserContextAsAdmin();
+ billingTestHelper.setCurrentUserContextAsAdmin();
});
it('should not delete a transaction linked to an invoice', async () => {
@@ -466,7 +464,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
describe('Recovery Scenarios', () => {
// eslint-disable-next-line @typescript-eslint/require-await
beforeAll(async () => {
- billingTestHelper.initUserContextAsAdmin();
+ billingTestHelper.setCurrentUserContextAsAdmin();
});
afterAll(async () => {
@@ -497,7 +495,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
describe('Negative tests - Wrong Billing Settings', () => {
// eslint-disable-next-line @typescript-eslint/require-await
beforeAll(async () => {
- billingTestHelper.initUserContextAsAdmin();
+ billingTestHelper.setCurrentUserContextAsAdmin();
// Force INVALID STRIPE credentials
await billingTestHelper.setBillingSystemInvalidCredentials();
assert(billingTestHelper.billingImpl, 'Billing implementation should not be null');
@@ -518,7 +516,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
describe('Negative tests', () => {
// eslint-disable-next-line @typescript-eslint/require-await
beforeAll(async () => {
- billingTestHelper.initUserContextAsAdmin();
+ billingTestHelper.setCurrentUserContextAsAdmin();
// Set STRIPE credentials
await billingTestHelper.setBillingSystemInvalidCredentials();
});
@@ -547,19 +545,16 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
describe('Where admin user', () => {
// eslint-disable-next-line @typescript-eslint/require-await
beforeAll(async () => {
- billingTestHelper.initUserContextAsAdmin();
+ billingTestHelper.setCurrentUserContextAsAdmin();
});
it(
'should NOT add an item to a DRAFT invoice after a transaction',
async () => {
await billingTestHelper.userService.billingApi.forceSynchronizeUser({ id: billingTestHelper.userContext.id });
- // const userWithBillingData = await testData.billingImpl.getUser(testData.userContext);
- // await testData.assignPaymentMethod(userWithBillingData, 'tok_fr');
const itemsBefore = await billingTestHelper.getNumberOfSessions(billingTestHelper.userContext.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(billingTestHelper.userContext.id);
expect(itemsAfter).to.be.eq(itemsBefore);
}
@@ -571,7 +566,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
describe('with Pricing + Billing', () => {
beforeAll(async () => {
- billingTestHelper.initUserContextAsAdmin();
+ billingTestHelper.setCurrentUserContextAsAdmin();
// Initialize the Billing module
await billingTestHelper.setBillingSystemValidCredentials(true, true /* immediateBillingAllowed ON */);
});
@@ -584,9 +579,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
});
it('should create and bill an invoice with FF + CT', async () => {
- await billingTestHelper.userService.billingApi.forceSynchronizeUser({ id: billingTestHelper.userContext.id });
- const userWithBillingData = await billingTestHelper.billingImpl.getUser(billingTestHelper.userContext);
- await billingTestHelper.assignPaymentMethod(userWithBillingData, 'tok_fr');
+ await billingTestHelper.makeCurrentUserContextReadyForBilling();
const transactionID = await billingTestHelper.generateTransaction(billingTestHelper.userContext);
assert(transactionID, 'transactionID should not be null');
// Check that we have a new invoice with an invoiceID and an invoiceNumber
@@ -602,9 +595,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
it('should create and bill an invoice with FF + ENERGY', async () => {
await billingTestHelper.initChargingStationContext2TestCS3Phased();
- await billingTestHelper.userService.billingApi.forceSynchronizeUser({ id: billingTestHelper.userContext.id });
- const userWithBillingData = await billingTestHelper.billingImpl.getUser(billingTestHelper.userContext);
- await billingTestHelper.assignPaymentMethod(userWithBillingData, 'tok_fr');
+ await billingTestHelper.makeCurrentUserContextReadyForBilling();
const transactionID = await billingTestHelper.generateTransaction(billingTestHelper.userContext);
assert(transactionID, 'transactionID should not be null');
// Check that we have a new invoice with an invoiceID and an invoiceNumber
@@ -613,9 +604,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
it('should create and bill an invoice with FF+ENERGY(STEP)', async () => {
await billingTestHelper.initChargingStationContext2TestCS3Phased('FF+E(STEP)');
- await billingTestHelper.userService.billingApi.forceSynchronizeUser({ id: billingTestHelper.userContext.id });
- const userWithBillingData = await billingTestHelper.billingImpl.getUser(billingTestHelper.userContext);
- await billingTestHelper.assignPaymentMethod(userWithBillingData, 'tok_fr');
+ await billingTestHelper.makeCurrentUserContextReadyForBilling();
const transactionID = await billingTestHelper.generateTransaction(billingTestHelper.userContext);
assert(transactionID, 'transactionID should not be null');
// Check that we have a new invoice with an invoiceID and an invoiceNumber
@@ -630,9 +619,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
it('should bill the Energy on COMBO CCS - DC', async () => {
await billingTestHelper.initChargingStationContext2TestFastCharger();
- await billingTestHelper.userService.billingApi.forceSynchronizeUser({ id: billingTestHelper.userContext.id });
- const userWithBillingData = await billingTestHelper.billingImpl.getUser(billingTestHelper.userContext);
- await billingTestHelper.assignPaymentMethod(userWithBillingData, 'tok_fr');
+ await billingTestHelper.makeCurrentUserContextReadyForBilling();
const transactionID = await billingTestHelper.generateTransaction(billingTestHelper.userContext);
assert(transactionID, 'transactionID should not be null');
// Check that we have a new invoice with an invoiceID and an invoiceNumber
@@ -641,9 +628,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
it('should bill the FF+CT+PT on COMBO CCS - DC', async () => {
await billingTestHelper.initChargingStationContext2TestFastCharger('FF+CT+PT');
- await billingTestHelper.userService.billingApi.forceSynchronizeUser({ id: billingTestHelper.userContext.id });
- const userWithBillingData = await billingTestHelper.billingImpl.getUser(billingTestHelper.userContext);
- await billingTestHelper.assignPaymentMethod(userWithBillingData, 'tok_fr');
+ await billingTestHelper.makeCurrentUserContextReadyForBilling();
const transactionID = await billingTestHelper.generateTransaction(billingTestHelper.userContext);
assert(transactionID, 'transactionID should not be null');
// Check that we have a new invoice with an invoiceID and an invoiceNumber
@@ -652,9 +637,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
it('should bill the CT(STEP)+PT(STEP) on COMBO CCS - DC', async () => {
await billingTestHelper.initChargingStationContext2TestFastCharger('CT(STEP)+PT(STEP)');
- await billingTestHelper.userService.billingApi.forceSynchronizeUser({ id: billingTestHelper.userContext.id });
- const userWithBillingData = await billingTestHelper.billingImpl.getUser(billingTestHelper.userContext);
- await billingTestHelper.assignPaymentMethod(userWithBillingData, 'tok_fr');
+ await billingTestHelper.makeCurrentUserContextReadyForBilling();
const transactionID = await billingTestHelper.generateTransaction(billingTestHelper.userContext);
assert(transactionID, 'transactionID should not be null');
// Check that we have a new invoice with an invoiceID and an invoiceNumber
@@ -663,9 +646,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
it('should bill the ENERGY + PT(STEP) on COMBO CCS - DC', async () => {
await billingTestHelper.initChargingStationContext2TestFastCharger('E+PT(STEP)');
- await billingTestHelper.userService.billingApi.forceSynchronizeUser({ id: billingTestHelper.userContext.id });
- const userWithBillingData = await billingTestHelper.billingImpl.getUser(billingTestHelper.userContext);
- await billingTestHelper.assignPaymentMethod(userWithBillingData, 'tok_fr');
+ await billingTestHelper.makeCurrentUserContextReadyForBilling();
const transactionID = await billingTestHelper.generateTransaction(billingTestHelper.userContext);
assert(transactionID, 'transactionID should not be null');
// Check that we have a new invoice with an invoiceID and an invoiceNumber
@@ -674,9 +655,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
it('should bill the ENERGY + CT(STEP80S) on COMBO CCS - DC', async () => {
await billingTestHelper.initChargingStationContext2TestFastCharger('E+CT(STEP80S)');
- await billingTestHelper.userService.billingApi.forceSynchronizeUser({ id: billingTestHelper.userContext.id });
- const userWithBillingData = await billingTestHelper.billingImpl.getUser(billingTestHelper.userContext);
- await billingTestHelper.assignPaymentMethod(userWithBillingData, 'tok_fr');
+ await billingTestHelper.makeCurrentUserContextReadyForBilling();
const transactionID = await billingTestHelper.generateTransaction(billingTestHelper.userContext);
assert(transactionID, 'transactionID should not be null');
// Check that we have a new invoice with an invoiceID and an invoiceNumber
@@ -689,9 +668,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
// A second Tariff applied after 30 mins!
await billingTestHelper.initChargingStationContext2TestFastCharger('E-After30mins+PT');
// A tariff applied immediately
- await billingTestHelper.userService.billingApi.forceSynchronizeUser({ id: billingTestHelper.userContext.id });
- const userWithBillingData = await billingTestHelper.billingImpl.getUser(billingTestHelper.userContext);
- await billingTestHelper.assignPaymentMethod(userWithBillingData, 'tok_fr');
+ await billingTestHelper.makeCurrentUserContextReadyForBilling();
const transactionID = await billingTestHelper.generateTransaction(billingTestHelper.userContext);
assert(transactionID, 'transactionID should not be null');
// Check that we have a new invoice with an invoiceID and an invoiceNumber
@@ -706,9 +683,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
// A second Tariff applied after 30 mins!
await billingTestHelper.initChargingStationContext2TestFastCharger('E(STEP)-After30mins');
// A tariff applied immediately
- await billingTestHelper.userService.billingApi.forceSynchronizeUser({ id: billingTestHelper.userContext.id });
- const userWithBillingData = await billingTestHelper.billingImpl.getUser(billingTestHelper.userContext);
- await billingTestHelper.assignPaymentMethod(userWithBillingData, 'tok_fr');
+ await billingTestHelper.makeCurrentUserContextReadyForBilling();
const transactionID = await billingTestHelper.generateTransaction(billingTestHelper.userContext);
assert(transactionID, 'transactionID should not be null');
// Check that we have a new invoice with an invoiceID and an invoiceNumber
@@ -724,9 +699,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
// A second Tariff applied after 30 mins!
await billingTestHelper.initChargingStationContext2TestFastCharger('E(STEP)-After30mins');
// A tariff applied immediately
- await billingTestHelper.userService.billingApi.forceSynchronizeUser({ id: billingTestHelper.userContext.id });
- const userWithBillingData = await billingTestHelper.billingImpl.getUser(billingTestHelper.userContext);
- await billingTestHelper.assignPaymentMethod(userWithBillingData, 'tok_fr');
+ await billingTestHelper.makeCurrentUserContextReadyForBilling();
const transactionID = await billingTestHelper.generateTransaction(billingTestHelper.userContext);
assert(transactionID, 'transactionID should not be null');
// Check that we have a new invoice with an invoiceID and an invoiceNumber
@@ -748,9 +721,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
// Check the charging station timezone
billingTestHelper.checkTimezone();
// A tariff applied immediately
- await billingTestHelper.userService.billingApi.forceSynchronizeUser({ id: billingTestHelper.userContext.id });
- const userWithBillingData = await billingTestHelper.billingImpl.getUser(billingTestHelper.userContext);
- await billingTestHelper.assignPaymentMethod(userWithBillingData, 'tok_fr');
+ await billingTestHelper.makeCurrentUserContextReadyForBilling();
const transactionID = await billingTestHelper.generateTransaction(billingTestHelper.userContext);
assert(transactionID, 'transactionID should not be null');
// Check that we have a new invoice with an invoiceID and an invoiceNumber
@@ -766,9 +737,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
// Check the charging station timezone
billingTestHelper.checkTimezone();
// A tariff applied immediately
- await billingTestHelper.userService.billingApi.forceSynchronizeUser({ id: billingTestHelper.userContext.id });
- const userWithBillingData = await billingTestHelper.billingImpl.getUser(billingTestHelper.userContext);
- await billingTestHelper.assignPaymentMethod(userWithBillingData, 'tok_fr');
+ await billingTestHelper.makeCurrentUserContextReadyForBilling();
const transactionID = await billingTestHelper.generateTransaction(billingTestHelper.userContext);
assert(transactionID, 'transactionID should not be null');
// Check that we have a new invoice with an invoiceID and an invoiceNumber
@@ -784,9 +753,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
// Check the charging station timezone
billingTestHelper.checkTimezone();
// A tariff applied immediately
- await billingTestHelper.userService.billingApi.forceSynchronizeUser({ id: billingTestHelper.userContext.id });
- const userWithBillingData = await billingTestHelper.billingImpl.getUser(billingTestHelper.userContext);
- await billingTestHelper.assignPaymentMethod(userWithBillingData, 'tok_fr');
+ await billingTestHelper.makeCurrentUserContextReadyForBilling();
const transactionID = await billingTestHelper.generateTransaction(billingTestHelper.userContext);
assert(transactionID, 'transactionID should not be null');
// Check that we have a new invoice with an invoiceID and an invoiceNumber
@@ -824,9 +791,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
it(
'should NOT add an item to a DRAFT invoice after a transaction',
async () => {
- await billingTestHelper.userService.billingApi.forceSynchronizeUser({ id: billingTestHelper.userContext.id });
- const userWithBillingData = await billingTestHelper.billingImpl.getUser(billingTestHelper.userContext);
- await billingTestHelper.assignPaymentMethod(userWithBillingData, 'tok_fr');
+ await billingTestHelper.makeCurrentUserContextReadyForBilling();
const itemsBefore = await billingTestHelper.getNumberOfSessions(billingTestHelper.userContext.id);
const transactionID = await billingTestHelper.generateTransaction(billingTestHelper.userContext);
assert(transactionID, 'transactionID should not be null');
@@ -865,8 +830,6 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
it('should add an item to a DRAFT invoice after a transaction', async () => {
await billingTestHelper.userService.billingApi.forceSynchronizeUser({ id: billingTestHelper.userContext.id });
- // const userWithBillingData = await testData.billingImpl.getUser(testData.userContext);
- // await testData.assignPaymentMethod(userWithBillingData, 'tok_fr');
const itemsBefore = await billingTestHelper.getNumberOfSessions(billingTestHelper.userContext.id);
const transactionID = await billingTestHelper.generateTransaction(billingTestHelper.userContext);
assert(transactionID, 'transactionID should not be null');
@@ -881,7 +844,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
describe('with Transaction Billing + Periodic Billing ON', () => {
beforeAll(async () => {
- billingTestHelper.initUserContextAsAdmin();
+ billingTestHelper.setCurrentUserContextAsAdmin();
// Initialize the Billing module
await billingTestHelper.setBillingSystemValidCredentials(true, false /* immediateBillingAllowed OFF, so periodicBilling ON */);
});
@@ -894,9 +857,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
});
it('should create a DRAFT invoice, Finalize it and Pay it', async () => {
- await billingTestHelper.userService.billingApi.forceSynchronizeUser({ id: billingTestHelper.userContext.id });
- const userWithBillingData = await billingTestHelper.billingImpl.getUser(billingTestHelper.userContext);
- await billingTestHelper.assignPaymentMethod(userWithBillingData, 'tok_fr');
+ await billingTestHelper.makeCurrentUserContextReadyForBilling();
const transactionID = await billingTestHelper.generateTransaction(billingTestHelper.userContext);
assert(transactionID, 'transactionID should not be null');
// Check that we have a new invoice with an invoiceID and but no invoiceNumber yet
@@ -933,7 +894,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
describe('Transaction Inconsistency Recovery', () => {
beforeAll(async () => {
- billingTestHelper.initUserContextAsAdmin();
+ billingTestHelper.setCurrentUserContextAsAdmin();
// Initialize the Billing module
await billingTestHelper.setBillingSystemValidCredentials(true, true /* immediateBillingAllowed ON */);
await billingTestHelper.initChargingStationContext2TestChargingTime();
@@ -945,9 +906,7 @@ describeif(isBillingProperlyConfigured)('Billing', () => {
it('check Soft Stop Transaction', async () => {
const dateInThePast = moment().add(-5, 'hours').toDate();
await billingTestHelper.initChargingStationContext2TestFastCharger('E+PT(STEP)', dateInThePast);
- await billingTestHelper.userService.billingApi.forceSynchronizeUser({ id: billingTestHelper.userContext.id });
- const userWithBillingData = await billingTestHelper.billingImpl.getUser(billingTestHelper.userContext);
- await billingTestHelper.assignPaymentMethod(userWithBillingData, 'tok_fr');
+ await billingTestHelper.makeCurrentUserContextReadyForBilling();
const transactionID = await billingTestHelper.generateTransaction(billingTestHelper.userContext, 'Accepted', dateInThePast, true);
assert(transactionID, 'transactionID should not be null');
// Check that we have a new invoice with an invoiceID and an invoiceNumber

MODIFY
test/api/BillingTestHelper.ts
test/api/BillingTestHelper.ts
@@ -9,8 +9,10 @@ import chai, { expect } from 'chai';
import AsyncTaskStorage from '../../src/storage/mongodb/AsyncTaskStorage';
import BillingFacade from '../../src/integration/billing/BillingFacade';
+import { BillingPlatformFeeStrategyFactory } from '../factories/BillingFactory';
import CentralServerService from './client/CentralServerService';
import ChargingStationContext from './context/ChargingStationContext';
+import Company from '../../src/types/Company';
import Constants from '../../src/utils/Constants';
import ContextDefinition from './context/ContextDefinition';
import ContextProvider from './context/ContextProvider';
@@ -68,6 +70,19 @@ export default class BillingTestHelper {
);
}
+ public getCurrentUserContext(): User {
+ // TODO - wrong type? UserContext vs User???
+ return this.userContext;
+ }
+
+ public async makeCurrentUserContextReadyForBilling(forceSynchronization = true) : Promise<void> {
+ if (forceSynchronization) {
+ await this.userService.billingApi.forceSynchronizeUser({ id: this.getCurrentUserContext().id });
+ }
+ const userWithBillingData = await this.billingImpl.getUser(this.getCurrentUserContext());
+ await this.assignPaymentMethod(userWithBillingData, 'tok_fr');
+ }
+
public async assignPaymentMethod(user: BillingUser, stripe_test_token: string) : Promise<Stripe.CustomerSource> {
// Assign a source using test tokens (instead of test card numbers)
// c.f.: https://stripe.com/docs/testing#cards
@@ -88,12 +103,37 @@ export default class BillingTestHelper {
return source;
}
- public initUserContextAsAdmin() : void {
- expect(this.userContext).to.not.be.null;
+ public setCurrentUserContextAsAdmin() : void {
+ // TODO - rethink this old logic
this.userContext = this.adminUserContext;
- assert(this.userContext, 'User context cannot be null');
this.userService = this.adminUserService;
- assert(!!this.userService, 'User service cannot be null');
+ }
+
+ public async initContext2TestConnectedAccounts() : Promise<void> {
+ // Assign a tariff the the charger
+ const chargingStationContext = await this.initChargingStationContext2TestChargingTime();
+ // Get an active account (create it if necessary)
+ const billingAccount = await this.getActivatedAccount();
+ const chargingStation = chargingStationContext.getChargingStation();
+ let response = await this.userService.chargingStationApi.readById(chargingStation.id);
+ expect(response.status).to.be.eq(StatusCodes.OK);
+ const companyID = response.data.companyID;
+ response = await this.userService.companyApi.readById(companyID);
+ expect(response.status).to.be.eq(StatusCodes.OK);
+ const company = response.data as Company;
+ const platformFeeStrategy = BillingPlatformFeeStrategyFactory.build();
+ response = await this.userService.companyApi.update({
+ id: companyID,
+ ...company,
+ accountData: {
+ accountID: billingAccount.id,
+ platformFeeStrategy
+ }
+ });
+ expect(response.status).to.be.eq(StatusCodes.OK);
+ response = await this.userService.companyApi.readById(companyID);
+ expect(response.data.accountData.accountID).to.eq(billingAccount.id);
+ expect(response.data.accountData.platformFeeStrategy).to.deep.eq(platformFeeStrategy);
}
public async initChargingStationContext() : Promise<ChargingStationContext> {
@@ -546,7 +586,6 @@ export default class BillingTestHelper {
const meterValueHighConsumption = Utils.createDecimal(meterStop).divToInt(30).toNumber();
const meterValuePoorConsumption = 0; // Simulate a gap in the energy provisioning
const meterValuePhaseOut = Utils.createDecimal(meterStop).divToInt(60).toNumber();
- // const user:any = this.userContext;
const connectorId = 1;
assert((user.tags && user.tags.length), 'User must have a valid tag');
const tagId = user.tags[0].id;

MODIFY
test/api/context/ChargingStationContext.ts
test/api/context/ChargingStationContext.ts
@@ -38,7 +38,7 @@ export default class ChargingStationContext {
private transactionsStarted: Map<number, OCPPStartTransactionResponse> = new Map();
private transactionsStopped: Map<number, OCPPStopTransactionResponse> = new Map();
- constructor(chargingStation: ChargingStation, tenantContext: TenantContext) {
+ public constructor(chargingStation: ChargingStation, tenantContext: TenantContext) {
this.chargingStation = chargingStation;
this.tenantContext = tenantContext;
}

bp - e2e test invoice to transfer - 1 drfat