Display invoice user + sync invoices with users
MODIFY
src/integration/billing/BillingIntegration.ts
src/integration/billing/BillingIntegration.ts
@@ -158,7 +158,7 @@ export default abstract class BillingIntegration<T extends BillingSetting> {
return actionsDone;
}
- public async synchronizeUser(user: User, tenantID) {
+ public async synchronizeUser(user: User, tenantID: string): Promise<void> {
try {
const exists = await this.userExists(user);
let newUser: BillingUser;
@@ -207,7 +207,7 @@ export default abstract class BillingIntegration<T extends BillingSetting> {
}
}
- public async forceSynchronizeUser(user: User, tenantID) {
+ public async forceSynchronizeUser(user: User, tenantID: string): Promise<void> {
try {
let billingUser = await this.getUserByEmail(user.email);
if (billingUser) {
@@ -310,7 +310,7 @@ export default abstract class BillingIntegration<T extends BillingSetting> {
// Get user
userInInvoice = await UserStorage.getUserByBillingID(tenantID, invoiceBilling.customerID);
}
- invoiceBilling.userID = userInInvoice ? userInInvoice.id : null;
+ invoiceBilling.user.id = userInInvoice ? userInInvoice.id : null;
}
await BillingStorage.saveInvoice(tenantID, invoiceBilling);
Logging.logDebug({
@@ -428,7 +428,7 @@ export default abstract class BillingIntegration<T extends BillingSetting> {
// Get user
userInInvoice = await UserStorage.getUserByBillingID(tenantID, invoiceBilling.customerID);
}
- invoiceBilling.userID = userInInvoice ? userInInvoice.id : null;
+ invoiceBilling.user = userInInvoice ? userInInvoice : null;
await BillingStorage.saveInvoice(tenantID, invoiceBilling);
Logging.logDebug({
tenantID: tenantID,
@@ -521,7 +521,7 @@ export default abstract class BillingIntegration<T extends BillingSetting> {
return billingUser;
}
- async abstract checkConnection();
+ async abstract checkConnection(): Promise<void>;
async abstract getUpdatedUserIDsInBilling(): Promise<string[]>;
@@ -547,7 +547,7 @@ export default abstract class BillingIntegration<T extends BillingSetting> {
async abstract updateUser(user: User): Promise<BillingUser>;
- async abstract deleteUser(user: User);
+ async abstract deleteUser(user: User): Promise<void>;
async abstract userExists(user: User): Promise<boolean>;

MODIFY
src/integration/billing/stripe/StripeBillingIntegration.ts
src/integration/billing/stripe/StripeBillingIntegration.ts
@@ -39,7 +39,7 @@ export default class StripeBillingIntegration extends BillingIntegration<StripeB
}
}
- public async checkConnection() {
+ public async checkConnection(): Promise<void> {
// Check Stripe
this.checkIfStripeIsInitialized();
// Check Key
@@ -813,7 +813,7 @@ export default class StripeBillingIntegration extends BillingIntegration<StripeB
return this.modifyUser(user);
}
- public async deleteUser(user: User) {
+ public async deleteUser(user: User): Promise<void> {
// Check Stripe
await this.checkConnection();
const customer = await this.getCustomerByEmail(user.email);

MODIFY
src/server/rest/service/BillingService.ts
src/server/rest/service/BillingService.ts
@@ -22,7 +22,7 @@ const MODULE_NAME = 'BillingService';
export default class BillingService {
- public static async handleCheckBillingConnection(action: ServerAction, req: Request, res: Response, next: NextFunction) {
+ public static async handleCheckBillingConnection(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
if (!Authorizations.canCheckConnectionBilling(req.user)) {
throw new AppAuthError({
errorCode: HTTPAuthError.ERROR,
@@ -65,7 +65,7 @@ export default class BillingService {
next();
}
- public static async handleSynchronizeUsers(action: ServerAction, req: Request, res: Response, next: NextFunction) {
+ public static async handleSynchronizeUsers(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
if (!Authorizations.canSynchronizeUsersBilling(req.user)) {
throw new AppAuthError({
errorCode: HTTPAuthError.ERROR,
@@ -96,7 +96,7 @@ export default class BillingService {
next();
}
- public static async handleSynchronizeUser(action: ServerAction, req: Request, res: Response, next: NextFunction) {
+ public static async handleSynchronizeUser(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
const filteredRequest = BillingSecurity.filterSynchronizeUserRequest(req.body);
if (!Authorizations.canSynchronizeUserBilling(req.user)) {
throw new AppAuthError({
@@ -132,7 +132,7 @@ export default class BillingService {
next();
}
- public static async handleForceSynchronizeUser(action: ServerAction, req: Request, res: Response, next: NextFunction) {
+ public static async handleForceSynchronizeUser(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
const filteredRequest = BillingSecurity.filterSynchronizeUserRequest(req.body);
if (!Authorizations.canSynchronizeUserBilling(req.user)) {
throw new AppAuthError({
@@ -168,7 +168,7 @@ export default class BillingService {
next();
}
- public static async handleGetBillingTaxes(action: ServerAction, req: Request, res: Response, next: NextFunction) {
+ public static async handleGetBillingTaxes(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
if (!Authorizations.canReadTaxesBilling(req.user)) {
throw new AppAuthError({
errorCode: HTTPAuthError.ERROR,
@@ -202,7 +202,7 @@ export default class BillingService {
next();
}
- public static async handleGetUserInvoices(action: ServerAction, req: Request, res: Response, next: NextFunction) {
+ public static async handleGetUserInvoices(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.BILLING,
Action.LIST, Entity.INVOICES, MODULE_NAME, 'handleGetUserInvoices');
@@ -256,7 +256,7 @@ export default class BillingService {
next();
}
- public static async handleSynchronizeInvoices(action: ServerAction, req: Request, res: Response, next: NextFunction) {
+ public static async handleSynchronizeInvoices(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
if (!Authorizations.canSynchronizeInvoicesBilling(req.user)) {
throw new AppAuthError({
errorCode: HTTPAuthError.ERROR,
@@ -295,7 +295,7 @@ export default class BillingService {
next();
}
- public static async handleForceSynchronizeUserInvoices(action: ServerAction, req: Request, res: Response, next: NextFunction) {
+ public static async handleForceSynchronizeUserInvoices(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
if (!Authorizations.canSynchronizeInvoicesBilling(req.user)) {
throw new AppAuthError({
errorCode: HTTPAuthError.ERROR,

MODIFY
src/server/rest/service/security/BillingSecurity.ts
src/server/rest/service/security/BillingSecurity.ts
@@ -63,7 +63,7 @@ export default class BillingSecurity {
// Check auth
if (Authorizations.canReadInvoicesBilling(loggedUser)) {
// Set only necessary info
- filteredInvoice.userID = invoice.userID;
+ filteredInvoice.user = invoice.user;
filteredInvoice.invoiceID = invoice.invoiceID;
filteredInvoice.number = invoice.number;
filteredInvoice.status = invoice.status;

MODIFY
src/storage/mongodb/BillingStorage.ts
src/storage/mongodb/BillingStorage.ts
@@ -6,7 +6,6 @@ import DatabaseUtils from './DatabaseUtils';
import DbParams from '../../types/database/DbParams';
import Logging from '../../utils/Logging';
import { ObjectID } from 'mongodb';
-import UserStorage from './UserStorage';
import Utils from '../../utils/Utils';
import global from '../../types/GlobalType';
@@ -130,6 +129,16 @@ export default class BillingStorage {
aggregation.push({
$limit: limit
});
+ // Add Users
+ DatabaseUtils.pushUserLookupInAggregation({
+ tenantID,
+ aggregation: aggregation,
+ asField: 'user',
+ localField: 'userID',
+ foreignField: '_id',
+ oneToOneCardinality: true,
+ oneToOneCardinalityNotNull: false
+ });
// Project
DatabaseUtils.projectFields(aggregation, projectFields);
// Read DB
@@ -151,14 +160,13 @@ export default class BillingStorage {
public static async saveInvoice(tenantId: string, invoiceToSave: Partial<BillingInvoice>): Promise<string> {
// Debug
const uniqueTimerID = Logging.traceStart(MODULE_NAME, 'saveInvoice');
- const user = await UserStorage.getUserByBillingID(tenantId, invoiceToSave.customerID);
// Build Request
// Properties to save
- const invoiceMDB: any = {
+ const invoiceMDB = {
_id: invoiceToSave.id ? Utils.convertToObjectID(invoiceToSave.id) : new ObjectID(),
invoiceID: invoiceToSave.invoiceID,
number: invoiceToSave.number,
- userID: user ? Utils.convertToObjectID(user.id) : null,
+ userID: invoiceToSave.user ? Utils.convertToObjectID(invoiceToSave.user.id) : null,
customerID: invoiceToSave.customerID,
amount: Utils.convertToFloat(invoiceToSave.amount),
status: invoiceToSave.status,

MODIFY
src/types/Billing.ts
src/types/Billing.ts
import { ActionsResponse } from './GlobalType';
+import User from './User';
export interface BillingTransactionData {
status?: string;
@@ -63,7 +64,7 @@ export interface BillingTax {
export interface BillingInvoice {
id: string;
invoiceID: string;
- userID?: string;
+ user?: User;
number?: string;
status?: BillingInvoiceStatus;
amount?: number;

Display invoice user + sync invoices with users