User is mandatory in sync invoices, throw exception when lock is not aquired
MODIFY
package.json
package.json
"start": "npm run start:prod",
"prestart": "npm run build:prod",
"start:dev": "npm run components:export && cross-env NODE_ENV=development ts-node-dev --max-old-space-size=4096 -- src/start.ts",
- "start:dev:debug": "npm run components:export && cross-env NODE_ENV=development ts-node-dev --inspect-brk --max-old-space-size=4096 -- src/start.ts",
+ "start:dev:debug": "npm run components:export && cross-env NODE_ENV=development ts-node-dev --max-old-space-size=4096 -- src/start.ts",
"start:dev:prof": "cross-env NODE_OPTIONS=\"--max-old-space-size=4096\" NODE_ENV=development node -r source-map-support/register --prof -- dist/start.js",
"start:dev:doctorprof": "cross-env NODE_OPTIONS=\"--max-old-space-size=4096\" NODE_ENV=development clinic doctor -- node -r source-map-support/register dist/start.js",
"start:dev:flameprof": "cross-env NODE_OPTIONS=\"--max-old-space-size=4096\" NODE_ENV=development clinic flame -- node -r source-map-support/register dist/start.js",

MODIFY
src/integration/billing/BillingIntegration.ts
src/integration/billing/BillingIntegration.ts
@@ -294,6 +294,7 @@ export default abstract class BillingIntegration<T extends BillingSetting> {
// Delete in e-Mobility
if (!invoiceInBilling && invoice) {
await BillingStorage.deleteInvoiceByInvoiceID(tenantID, invoiceIDInBilling);
+ actionsDone.inSuccess++;
Logging.logDebug({
tenantID: tenantID,
user: user,
@@ -302,7 +303,6 @@ export default abstract class BillingIntegration<T extends BillingSetting> {
module: MODULE_NAME, method: 'synchronizeInvoices',
message: `Billing invoice with ID '${invoiceIDInBilling}' has been deleted in e-Mobility`
});
- actionsDone.inSuccess++;
continue;
}
// Create / Update
@@ -319,23 +319,40 @@ export default abstract class BillingIntegration<T extends BillingSetting> {
// Get user
userInInvoice = await UserStorage.getUserByBillingID(tenantID, invoiceInBilling.customerID);
}
- invoiceInBilling.user = userInInvoice ? userInInvoice : null;
+ // Check User
+ if (!userInInvoice) {
+ actionsDone.inError++;
+ Logging.logError({
+ tenantID: tenantID,
+ user: user,
+ source: Constants.CENTRAL_SERVER,
+ action: ServerAction.BILLING_SYNCHRONIZE_INVOICES,
+ module: MODULE_NAME, method: 'synchronizeInvoices',
+ message: `No user found for billing invoice with ID '${invoiceIDInBilling}'`
+ });
+ continue;
+ }
+ // Set user
+ invoiceInBilling.user = userInInvoice;
+ invoiceInBilling.userID = userInInvoice.id;
+ invoiceInBilling.downloadable = invoice ? invoice.downloadable : false;
// Save invoice
- invoiceInBilling.userID = userInInvoice ? userInInvoice.id : null;
invoiceInBilling.id = await BillingStorage.saveInvoice(tenantID, invoiceInBilling);
- // Download the document
+ // Download the invoice document
+ if (!invoice || !invoiceInBilling.downloadable || (invoice.nbrOfItems !== invoiceInBilling.nbrOfItems)) {
const invoiceDocument = await this.downloadInvoiceDocument(invoiceInBilling);
if (invoiceDocument) {
- // Save it in our DB
+ // Save it
await BillingStorage.saveInvoiceDocument(tenantID, invoiceDocument);
// Update
invoiceInBilling.downloadable = true;
await BillingStorage.saveInvoice(tenantID, invoiceInBilling);
}
- if (userInInvoice) {
+ }
+ // Save last User invoice sync
userInInvoice.billingData.invoicesLastSynchronizedOn = new Date();
await UserStorage.saveUserBillingData(tenantID, userInInvoice.id, userInInvoice.billingData);
- }
+ // Ok
actionsDone.inSuccess++;
Logging.logDebug({
tenantID: tenantID,

MODIFY
src/server/rest/service/BillingService.ts
src/server/rest/service/BillingService.ts
@@ -91,7 +91,10 @@ export default class BillingService {
});
}
// Get the lock
- let synchronizeAction: BillingUserSynchronizeAction;
+ let synchronizeAction: BillingUserSynchronizeAction = {
+ inError: 0,
+ inSuccess: 0,
+ };
const billingLock = await LockingHelper.createBillingSyncUsersLock(req.user.tenantID);
if (billingLock) {
try {
@@ -101,6 +104,15 @@ export default class BillingService {
// Release the lock
await LockingManager.release(billingLock);
}
+ } else {
+ throw new AppError({
+ source: Constants.CENTRAL_SERVER,
+ errorCode: HTTPError.GENERAL_ERROR,
+ message: 'Cannot aquire block',
+ module: MODULE_NAME, method: 'handleSynchronizeUsers',
+ action: action,
+ user: req.user
+ });
}
// Ok
res.json(Object.assign(synchronizeAction, Constants.REST_RESPONSE_SUCCESS));
@@ -145,6 +157,15 @@ export default class BillingService {
// Release the lock
await LockingManager.release(billingLock);
}
+ } else {
+ throw new AppError({
+ source: Constants.CENTRAL_SERVER,
+ errorCode: HTTPError.GENERAL_ERROR,
+ message: 'Cannot aquire block',
+ module: MODULE_NAME, method: 'handleSynchronizeUser',
+ action: action,
+ user: req.user
+ });
}
// Ok
res.json(Constants.REST_RESPONSE_SUCCESS);
@@ -188,6 +209,15 @@ export default class BillingService {
} finally {
await LockingManager.release(billingLock);
}
+ } else {
+ throw new AppError({
+ source: Constants.CENTRAL_SERVER,
+ errorCode: HTTPError.GENERAL_ERROR,
+ message: 'Cannot aquire block',
+ module: MODULE_NAME, method: 'handleSynchronizeUser',
+ action: action,
+ user: req.user
+ });
}
// Get the Invoice lock
billingLock = await LockingHelper.createBillingSyncInvoicesLock(req.user.tenantID);
@@ -198,6 +228,15 @@ export default class BillingService {
} finally {
await LockingManager.release(billingLock);
}
+ } else {
+ throw new AppError({
+ source: Constants.CENTRAL_SERVER,
+ errorCode: HTTPError.GENERAL_ERROR,
+ message: 'Cannot aquire block',
+ module: MODULE_NAME, method: 'handleSynchronizeUser',
+ action: action,
+ user: req.user
+ });
}
// Ok
res.json(Constants.REST_RESPONSE_SUCCESS);
@@ -323,15 +362,28 @@ export default class BillingService {
MODULE_NAME, 'handleSynchronizeUserInvoices', req.user);
}
// Get the Invoice lock
- let synchronizeAction: BillingUserSynchronizeAction;
+ let synchronizeAction: BillingUserSynchronizeAction = {
+ inError: 0,
+ inSuccess: 0,
+ };
const billingLock = await LockingHelper.createBillingSyncInvoicesLock(req.user.tenantID);
if (billingLock) {
try {
// Sync invoices
- await billingImpl.synchronizeInvoices(req.user.tenantID, user);
+ synchronizeAction = await billingImpl.synchronizeInvoices(req.user.tenantID, user);
} finally {
+ // Release the lock
await LockingManager.release(billingLock);
}
+ } else {
+ throw new AppError({
+ source: Constants.CENTRAL_SERVER,
+ errorCode: HTTPError.GENERAL_ERROR,
+ message: 'Cannot aquire block',
+ module: MODULE_NAME, method: 'handleSynchronizeUserInvoices',
+ action: action,
+ user: req.user
+ });
}
// Ok
res.json(Object.assign(synchronizeAction, Constants.REST_RESPONSE_SUCCESS));
@@ -367,15 +419,28 @@ export default class BillingService {
UtilsService.assertObjectExists(action, user, `User '${filteredRequest.userID}' does not exist`,
MODULE_NAME, 'handleForceSynchronizeUserInvoices', req.user);
// Get the Invoice lock
- let synchronizeAction: BillingUserSynchronizeAction;
+ let synchronizeAction: BillingUserSynchronizeAction = {
+ inError: 0,
+ inSuccess: 0,
+ };
const billingLock = await LockingHelper.createBillingSyncInvoicesLock(req.user.tenantID);
if (billingLock) {
try {
// Sync invoices
- await billingImpl.synchronizeInvoices(req.user.tenantID, user);
+ synchronizeAction = await billingImpl.synchronizeInvoices(req.user.tenantID, user);
} finally {
+ // Release the lock
await LockingManager.release(billingLock);
}
+ } else {
+ throw new AppError({
+ source: Constants.CENTRAL_SERVER,
+ errorCode: HTTPError.GENERAL_ERROR,
+ message: 'Cannot aquire block',
+ module: MODULE_NAME, method: 'handleForceSynchronizeUserInvoices',
+ action: action,
+ user: req.user
+ });
}
// Ok
res.json(Object.assign(synchronizeAction, Constants.REST_RESPONSE_SUCCESS));

MODIFY
src/storage/mongodb/BillingStorage.ts
src/storage/mongodb/BillingStorage.ts
@@ -185,7 +185,7 @@ export default class BillingStorage {
// Build Request
// Properties to save
const invoiceDocumentMDB: any = {
- _id: invoiceDocument.id,
+ _id: Utils.convertToObjectID(invoiceDocument.id),
type: invoiceDocument.type,
invoiceID: invoiceDocument.invoiceID,
encoding: invoiceDocument.encoding,

User is mandatory in sync invoices, throw exception when lock is not aquired