add server to monorepo.

This commit is contained in:
a.bouhuolia
2023-02-03 11:57:50 +02:00
parent 28e309981b
commit 80b97b5fdc
1303 changed files with 137049 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
import { Container, Service } from 'typedi';
import events from '@/subscribers/events';
@Service()
export default class ResetLoginThrottleSubscriber {
/**
* Attaches events with handlers.
* @param bus
*/
public attach(bus) {
bus.subscribe(events.auth.login, this.resetLoginThrottleOnceSuccessLogin);
}
/**
* Resets the login throttle once the login success.
*/
private async resetLoginThrottleOnceSuccessLogin(payload) {
const { emailOrPhone, password, user } = payload;
const loginThrottler = Container.get('rateLimiter.login');
// Reset the login throttle by the given email and phone number.
await loginThrottler.reset(user.email);
await loginThrottler.reset(user.phoneNumber);
await loginThrottler.reset(emailOrPhone);
}
}

View File

@@ -0,0 +1,25 @@
import { Service, Inject } from 'typedi';
import events from '@/subscribers/events';
@Service()
export default class AuthenticationSubscriber {
@Inject('agenda')
agenda: any;
/**
* Attaches events with handlers.
*/
public attach(bus) {
bus.subscribe(events.auth.sendResetPassword, this.sendPasswordMail);
}
/**
* Sends reset password mail once the reset password success.
*/
public sendPasswordMail = (payload) => {
const { user, token } = payload;
// Send reset password mail.
this.agenda.now('reset-password-mail', { user, token });
};
}

View File

@@ -0,0 +1,28 @@
import { Service, Inject } from 'typedi';
import events from '@/subscribers/events';
@Service()
export default class AuthSendWelcomeMailSubscriber {
@Inject('agenda')
agenda: any;
/**
* Attaches events with handlers.
*/
public attach(bus) {
bus.subscribe(events.auth.register, this.sendWelcomeEmailOnceUserRegister);
}
/**
* Sends welcome email once the user register.
*/
private sendWelcomeEmailOnceUserRegister = async (payload) => {
const { registerDTO, tenant, user } = payload;
// Send welcome mail to the user.
await this.agenda.now('welcome-email', {
organizationId: tenant.organizationId,
user,
});
};
}

View File

@@ -0,0 +1,79 @@
import { Service, Inject } from 'typedi';
import events from '@/subscribers/events';
import TenancyService from '@/services/Tenancy/TenancyService';
import BillsService from '@/services/Purchases/Bills';
import {
IBillCreatedPayload,
IBillEditedPayload,
IBIllEventDeletedPayload,
} from '@/interfaces';
@Service()
export default class BillWriteInventoryTransactionsSubscriber {
@Inject()
tenancy: TenancyService;
@Inject()
billsService: BillsService;
/**
* Attaches events with handles.
*/
public attach(bus) {
bus.subscribe(
events.bill.onCreated,
this.handleWritingInventoryTransactions
);
bus.subscribe(
events.bill.onEdited,
this.handleOverwritingInventoryTransactions
);
bus.subscribe(
events.bill.onDeleted,
this.handleRevertInventoryTransactions
);
}
/**
* Handles writing the inventory transactions once bill created.
*/
private handleWritingInventoryTransactions = async ({
tenantId,
billId,
trx,
}: IBillCreatedPayload) => {
await this.billsService.recordInventoryTransactions(
tenantId,
billId,
false,
trx
);
};
/**
* Handles the overwriting the inventory transactions once bill edited.
*/
private handleOverwritingInventoryTransactions = async ({
tenantId,
billId,
trx,
}: IBillEditedPayload) => {
await this.billsService.recordInventoryTransactions(
tenantId,
billId,
true,
trx
);
};
/**
* Handles the reverting the inventory transactions once the bill deleted.
*/
private handleRevertInventoryTransactions = async ({
tenantId,
billId,
trx,
}: IBIllEventDeletedPayload) => {
await this.billsService.revertInventoryTransactions(tenantId, billId, trx);
};
}

View File

@@ -0,0 +1,79 @@
import { Inject, Service } from 'typedi';
import events from '@/subscribers/events';
import TenancyService from '@/services/Tenancy/TenancyService';
import BillsService from '@/services/Purchases/Bills';
import {
IBillCreatedPayload,
IBillEditedPayload,
IBIllEventDeletedPayload,
} from '@/interfaces';
@Service()
export default class BillWriteGLEntriesSubscriber {
@Inject()
tenancy: TenancyService;
@Inject()
billsService: BillsService;
/**
* Attachs events with handles.
*/
attach(bus) {
bus.subscribe(
events.bill.onCreated,
this.handlerWriteJournalEntriesOnCreate
);
bus.subscribe(
events.bill.onEdited,
this.handleOverwriteJournalEntriesOnEdit
);
bus.subscribe(events.bill.onDeleted, this.handlerDeleteJournalEntries);
}
/**
* Handles writing journal entries once bill created.
* @param {IBillCreatedPayload} payload -
*/
private handlerWriteJournalEntriesOnCreate = async ({
tenantId,
billId,
trx,
}: IBillCreatedPayload) => {
await this.billsService.recordJournalTransactions(
tenantId,
billId,
false,
trx
);
};
/**
* Handles the overwriting journal entries once bill edited.
* @param {IBillEditedPayload} payload -
*/
private handleOverwriteJournalEntriesOnEdit = async ({
tenantId,
billId,
trx,
}: IBillEditedPayload) => {
await this.billsService.recordJournalTransactions(
tenantId,
billId,
true,
trx
);
};
/**
* Handles revert journal entries on bill deleted.
* @param {IBIllEventDeletedPayload} payload -
*/
private handlerDeleteJournalEntries = async ({
tenantId,
billId,
trx,
}: IBIllEventDeletedPayload) => {
await this.billsService.revertJournalEntries(tenantId, billId, trx);
};
}

View File

@@ -0,0 +1,22 @@
import { Container } from 'typedi';
import { EventSubscriber, On } from 'event-dispatch';
import events from '@/subscribers/events';
import TenancyService from '@/services/Tenancy/TenancyService';
import BillsService from '@/services/Purchases/Bills';
@EventSubscriber()
export default class BillSubscriber {
tenancy: TenancyService;
billsService: BillsService;
logger: any;
/**
* Constructor method.
*/
constructor() {
this.tenancy = Container.get(TenancyService);
this.billsService = Container.get(BillsService);
this.logger = Container.get('logger');
}
}

View File

@@ -0,0 +1,37 @@
import { Container } from 'typedi';
import { EventSubscriber, On } from 'event-dispatch';
import { map, head } from 'lodash';
import events from '@/subscribers/events';
import TenancyService from '@/services/Tenancy/TenancyService';
import SaleInvoicesCost from '@/services/Sales/SalesInvoicesCost';
import InventoryItemsQuantitySync from '@/services/Inventory/InventoryItemsQuantitySync';
import InventoryService from '@/services/Inventory/Inventory';
@EventSubscriber()
export class OwnerContributionCashflowSubscriber {
depends: number = 0;
startingDate: Date;
saleInvoicesCost: SaleInvoicesCost;
tenancy: TenancyService;
itemsQuantitySync: InventoryItemsQuantitySync;
inventoryService: InventoryService;
agenda: any;
/**
* Constructor method.
*/
constructor() {
this.tenancy = Container.get(TenancyService);
}
/**
* Marks items cost compute running state.
*/
@On(events.cashflow.onOwnerContributionCreate)
async writeOwnerContributionJournalEntries({
}) {
}
}

View File

@@ -0,0 +1,197 @@
import { Inject, Service } from 'typedi';
import { map, head } from 'lodash';
import events from '@/subscribers/events';
import TenancyService from '@/services/Tenancy/TenancyService';
import SaleInvoicesCost from '@/services/Sales/SalesInvoicesCost';
import InventoryItemsQuantitySync from '@/services/Inventory/InventoryItemsQuantitySync';
import InventoryService from '@/services/Inventory/Inventory';
import {
IComputeItemCostJobCompletedPayload,
IInventoryTransactionsCreatedPayload,
IInventoryTransactionsDeletedPayload,
} from '@/interfaces';
import { runAfterTransaction } from '@/services/UnitOfWork/TransactionsHooks';
@Service()
export default class InventorySubscriber {
@Inject()
saleInvoicesCost: SaleInvoicesCost;
@Inject()
tenancy: TenancyService;
@Inject()
itemsQuantitySync: InventoryItemsQuantitySync;
@Inject()
inventoryService: InventoryService;
@Inject('agenda')
agenda: any;
/**
* Attaches events with handlers.
*/
public attach(bus) {
bus.subscribe(
events.inventory.onInventoryTransactionsCreated,
this.handleScheduleItemsCostOnInventoryTransactionsCreated
);
bus.subscribe(
events.inventory.onInventoryTransactionsCreated,
this.syncItemsQuantityOnceInventoryTransactionsCreated
);
bus.subscribe(
events.inventory.onComputeItemCostJobScheduled,
this.markGlobalSettingsComputeItems
);
bus.subscribe(
events.inventory.onInventoryCostEntriesWritten,
this.markGlobalSettingsComputeItemsCompeted
);
bus.subscribe(
events.inventory.onComputeItemCostJobCompleted,
this.onComputeItemCostJobFinished
);
bus.subscribe(
events.inventory.onInventoryTransactionsDeleted,
this.handleScheduleItemsCostOnInventoryTransactionsDeleted
);
bus.subscribe(
events.inventory.onInventoryTransactionsDeleted,
this.syncItemsQuantityOnceInventoryTransactionsDeleted
);
}
/**
* Sync inventory items quantity once inventory transactions created.
* @param {IInventoryTransactionsCreatedPayload} payload -
*/
private syncItemsQuantityOnceInventoryTransactionsCreated = async ({
tenantId,
inventoryTransactions,
trx,
}: IInventoryTransactionsCreatedPayload) => {
const itemsQuantityChanges = this.itemsQuantitySync.getItemsQuantityChanges(
inventoryTransactions
);
await this.itemsQuantitySync.changeItemsQuantity(
tenantId,
itemsQuantityChanges,
trx
);
};
/**
* Handles schedule compute inventory items cost once inventory transactions created.
* @param {IInventoryTransactionsCreatedPayload} payload -
*/
private handleScheduleItemsCostOnInventoryTransactionsCreated = async ({
tenantId,
inventoryTransactions,
trx
}: IInventoryTransactionsCreatedPayload) => {
const inventoryItemsIds = map(inventoryTransactions, 'itemId');
runAfterTransaction(trx, async () => {
try {
await this.saleInvoicesCost.computeItemsCostByInventoryTransactions(
tenantId,
inventoryTransactions
);
} catch (error) {
console.error(error);
}
});
};
/**
* Marks items cost compute running state.
*/
private markGlobalSettingsComputeItems = async ({ tenantId }) => {
await this.inventoryService.markItemsCostComputeRunning(tenantId, true);
};
/**
* Marks items cost compute as completed.
*/
private markGlobalSettingsComputeItemsCompeted = async ({ tenantId }) => {
await this.inventoryService.markItemsCostComputeRunning(tenantId, false);
};
/**
* Handle run writing the journal entries once the compute items jobs completed.
*/
private onComputeItemCostJobFinished = async ({
itemId,
tenantId,
startingDate,
}: IComputeItemCostJobCompletedPayload) => {
const dependsComputeJobs = await this.agenda.jobs({
name: 'compute-item-cost',
nextRunAt: { $ne: null },
'data.tenantId': tenantId,
});
// There is no scheduled compute jobs waiting.
if (dependsComputeJobs.length === 0) {
await this.saleInvoicesCost.scheduleWriteJournalEntries(
tenantId,
startingDate
);
}
};
/**
* Sync inventory items quantity once inventory transactions deleted.
*/
private syncItemsQuantityOnceInventoryTransactionsDeleted = async ({
tenantId,
oldInventoryTransactions,
trx,
}: IInventoryTransactionsDeletedPayload) => {
const itemsQuantityChanges =
this.itemsQuantitySync.getReverseItemsQuantityChanges(
oldInventoryTransactions
);
await this.itemsQuantitySync.changeItemsQuantity(
tenantId,
itemsQuantityChanges,
trx
);
};
/**
* Schedules compute items cost once the inventory transactions deleted.
*/
private handleScheduleItemsCostOnInventoryTransactionsDeleted = async ({
tenantId,
transactionType,
transactionId,
oldInventoryTransactions,
trx,
}: IInventoryTransactionsDeletedPayload) => {
// Ignore compute item cost with theses transaction types.
const ignoreWithTransactionTypes = ['OpeningItem'];
if (ignoreWithTransactionTypes.indexOf(transactionType) !== -1) {
return;
}
const inventoryItemsIds = map(oldInventoryTransactions, 'itemId');
const startingDates = map(oldInventoryTransactions, 'date');
const startingDate: Date = head(startingDates);
runAfterTransaction(trx, async () => {
try {
await this.saleInvoicesCost.scheduleComputeCostByItemsIds(
tenantId,
inventoryItemsIds,
startingDate
);
} catch (error) {
console.error(error);
}
});
};
}

View File

@@ -0,0 +1,134 @@
import { Inject, Service } from 'typedi';
import events from '@/subscribers/events';
import InventoryAdjustmentService from '@/services/Inventory/InventoryAdjustmentService';
import InventoryAdjustmentsGL from '@/services/Inventory/InventoryAdjustmentGL';
import {
IInventoryAdjustmentEventCreatedPayload,
IInventoryAdjustmentEventDeletedPayload,
IInventoryAdjustmentEventPublishedPayload,
} from '@/interfaces';
@Service()
export default class InventoryAdjustmentsSubscriber {
@Inject()
private inventoryAdjustment: InventoryAdjustmentService;
@Inject()
private inventoryAdjustmentGL: InventoryAdjustmentsGL;
/**
* Attaches events with handles.
* @param bus
*/
public attach(bus) {
bus.subscribe(
events.inventoryAdjustment.onQuickCreated,
this.handleWriteInventoryTransactionsOncePublished
);
bus.subscribe(
events.inventoryAdjustment.onQuickCreated,
this.handleGLEntriesOnceIncrementAdjustmentCreated
);
bus.subscribe(
events.inventoryAdjustment.onPublished,
this.handleGLEntriesOnceIncrementAdjustmentCreated
);
bus.subscribe(
events.inventoryAdjustment.onPublished,
this.handleWriteInventoryTransactionsOncePublished
);
bus.subscribe(
events.inventoryAdjustment.onDeleted,
this.handleRevertInventoryTransactionsOnceDeleted
);
bus.subscribe(
events.inventoryAdjustment.onDeleted,
this.revertAdjustmentGLEntriesOnceDeleted
);
}
/**
* Handles writing increment inventory adjustment GL entries.
*/
private handleGLEntriesOnceIncrementAdjustmentCreated = async ({
tenantId,
inventoryAdjustmentId,
inventoryAdjustment,
trx,
}: IInventoryAdjustmentEventCreatedPayload) => {
// Can't continue if the inventory adjustment is not published.
if (!inventoryAdjustment.isPublished) {
return;
}
// Can't continue if the inventory adjustment direction is not `IN`.
if (inventoryAdjustment.type !== 'increment') {
return;
}
await this.inventoryAdjustmentGL.writeAdjustmentGLEntries(
tenantId,
inventoryAdjustmentId,
trx
);
};
/**
* Handles writing inventory transactions once the quick adjustment created.
* @param {IInventoryAdjustmentEventPublishedPayload} payload
* @param {IInventoryAdjustmentEventCreatedPayload} payload -
*/
private handleWriteInventoryTransactionsOncePublished = async ({
tenantId,
inventoryAdjustment,
trx,
}:
| IInventoryAdjustmentEventPublishedPayload
| IInventoryAdjustmentEventCreatedPayload) => {
await this.inventoryAdjustment.writeInventoryTransactions(
tenantId,
inventoryAdjustment,
false,
trx
);
};
/**
* Handles reverting invetory transactions once the inventory adjustment deleted.
* @param {IInventoryAdjustmentEventDeletedPayload} payload -
*/
private handleRevertInventoryTransactionsOnceDeleted = async ({
tenantId,
inventoryAdjustmentId,
oldInventoryAdjustment,
trx,
}: IInventoryAdjustmentEventDeletedPayload) => {
// Can't continue if the inventory adjustment is not published.
if (!oldInventoryAdjustment.isPublished) {
return;
}
// Reverts the inventory transactions of adjustment transaction.
await this.inventoryAdjustment.revertInventoryTransactions(
tenantId,
inventoryAdjustmentId,
trx
);
};
/**
* Reverts the inventory adjustment GL entries once the transaction deleted.
* @param {IInventoryAdjustmentEventDeletedPayload} payload -
*/
private revertAdjustmentGLEntriesOnceDeleted = async ({
tenantId,
inventoryAdjustmentId,
oldInventoryAdjustment,
}: IInventoryAdjustmentEventDeletedPayload) => {
// Can't continue if the inventory adjustment is not published.
if (!oldInventoryAdjustment.isPublished) {
return;
}
await this.inventoryAdjustmentGL.revertAdjustmentGLEntries(
tenantId,
inventoryAdjustmentId
);
};
}

View File

@@ -0,0 +1,18 @@
import events from '@/subscribers/events';
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
import { Service } from 'typedi';
@Service()
export default class ItemSubscriber extends EventSubscriber {
/**
* Attaches the events with handles.
* @param bus
*/
attach(bus) {
bus.subscribe(events.item.onCreated, this.handleItemCreated);
}
handleItemCreated() {
}
}

View File

@@ -0,0 +1,37 @@
import { Container } from 'typedi';
import { On, EventSubscriber } from 'event-dispatch';
import events from '@/subscribers/events';
import TenancyService from '@/services/Tenancy/TenancyService';
import BillsService from '@/services/Purchases/Bills';
@EventSubscriber()
export default class BillLandedCostSubscriber {
logger: any;
tenancy: TenancyService;
billsService: BillsService;
/**
* Constructor method.
*/
constructor() {
this.logger = Container.get('logger');
this.tenancy = Container.get(TenancyService);
this.billsService = Container.get(BillsService);
}
/**
* Marks the rewrite bill journal entries once the landed cost transaction
* be deleted or created.
*/
@On(events.billLandedCost.onCreated)
@On(events.billLandedCost.onDeleted)
public async handleRewriteBillJournalEntries({
tenantId,
billId,
bilLandedCostId,
}) {
// Overwrite the journal entries for the given bill transaction.
this.logger.info('[bill] overwriting bill journal entries.', { tenantId });
await this.billsService.recordJournalTransactions(tenantId, billId, true);
}
}

View File

@@ -0,0 +1,26 @@
import { Service, Inject } from 'typedi';
import events from '@/subscribers/events';
import { IOrganizationBuildEventPayload } from '@/interfaces';
@Service()
export default class OrgBuildSmsNotificationSubscriber {
@Inject('agenda')
agenda: any;
/**
* Attaches events with handlers.
*/
public attach(bus) {
bus.subscribe(events.organization.build, this.sendWelcomeSmsNotification);
}
/**
* Sends welcome SMS once the organization build completed.
*/
public sendWelcomeSmsNotification = async ({
tenantId,
systemUser,
}: IOrganizationBuildEventPayload) => {
// await this.agenda.now('welcome-sms', { tenant, user });
};
}

View File

@@ -0,0 +1,27 @@
import { Inject, Service } from 'typedi';
import events from '@/subscribers/events';
import OrganizationService from '@/services/Organization/OrganizationService';
import { IOrganizationBuildEventPayload } from '@/interfaces';
@Service()
export default class OrgSyncTenantAdminUserSubscriber {
@Inject()
organizationService: OrganizationService;
/**
* Attaches events with handlers.
*/
public attach(bus) {
bus.subscribe(events.organization.build, this.assignSystemUserAsAdminRole);
}
/**
* Assign the autorized system user as admin role.
*/
public assignSystemUserAsAdminRole = async ({
tenantId,
systemUser,
}: IOrganizationBuildEventPayload) => {
await this.organizationService.syncSystemUserToTenant(tenantId, systemUser);
};
}

View File

@@ -0,0 +1,71 @@
import { Inject, Service } from 'typedi';
import events from '@/subscribers/events';
import BillPaymentsService from '@/services/Purchases/BillPayments/BillPayments';
import TenancyService from '@/services/Tenancy/TenancyService';
import {
IBillPaymentEventCreatedPayload,
IBillPaymentEventDeletedPayload,
IBillPaymentEventEditedPayload,
} from '@/interfaces';
@Service()
export default class PaymentSyncBillBalance {
@Inject()
tenancy: TenancyService;
@Inject()
billPaymentsService: BillPaymentsService;
/**
*
* @param bus
*/
attach(bus) {
bus.subscribe(
events.billPayment.onCreated,
this.handleBillsIncrementPaymentAmount
);
bus.subscribe(
events.billPayment.onEdited,
this.handleBillsIncrementPaymentAmount
);
bus.subscribe(
events.billPayment.onDeleted,
this.handleBillDecrementPaymentAmount
);
}
/**
* Handle bill payment amount increment/decrement once bill payment created or edited.
*/
private handleBillsIncrementPaymentAmount = async ({
tenantId,
billPayment,
oldBillPayment,
billPaymentId,
trx,
}: IBillPaymentEventCreatedPayload | IBillPaymentEventEditedPayload) => {
this.billPaymentsService.saveChangeBillsPaymentAmount(
tenantId,
billPayment.entries,
oldBillPayment?.entries || null,
trx
);
};
/**
* Handle revert bill payment amount once bill payment deleted.
*/
private handleBillDecrementPaymentAmount = async ({
tenantId,
billPaymentId,
oldBillPayment,
trx,
}: IBillPaymentEventDeletedPayload) => {
this.billPaymentsService.saveChangeBillsPaymentAmount(
tenantId,
oldBillPayment.entries.map((entry) => ({ ...entry, paymentAmount: 0 })),
oldBillPayment.entries,
trx
);
};
}

View File

@@ -0,0 +1,36 @@
import { Service, Inject } from 'typedi';
import events from '@/subscribers/events';
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
import PaymentReceiveService from '@/services/Sales/PaymentReceives/PaymentsReceives';
import { IPaymentReceiveCreatedPayload } from '@/interfaces';
@Service()
export default class PaymentReceiveAutoSerialSubscriber extends EventSubscriber {
@Inject()
paymentReceivesService: PaymentReceiveService;
/**
* Attaches the events with handles.
* @param bus
*/
public attach(bus) {
bus.subscribe(
events.paymentReceive.onCreated,
this.handlePaymentNextNumberIncrement
);
}
/**
* Handles increment next number of payment receive once be created.
* @param {IPaymentReceiveCreatedPayload} payload -
*/
private handlePaymentNextNumberIncrement = async ({
tenantId,
paymentReceiveId,
trx,
}: IPaymentReceiveCreatedPayload) => {
await this.paymentReceivesService.incrementNextPaymentReceiveNumber(
tenantId
);
};
}

View File

@@ -0,0 +1,89 @@
import { Inject, Service } from 'typedi';
import events from '@/subscribers/events';
import PaymentReceiveService from '@/services/Sales/PaymentReceives/PaymentsReceives';
import {
IPaymentReceiveCreatedPayload,
IPaymentReceiveDeletedPayload,
IPaymentReceiveEditedPayload,
} from '@/interfaces';
@Service()
export default class PaymentReceiveSyncInvoices {
@Inject()
paymentReceivesService: PaymentReceiveService;
/**
* Attaches the events to handles.
* @param bus
*/
attach(bus) {
bus.subscribe(
events.paymentReceive.onCreated,
this.handleInvoiceIncrementPaymentOnceCreated
);
bus.subscribe(
events.paymentReceive.onEdited,
this.handleInvoiceIncrementPaymentOnceEdited
);
bus.subscribe(
events.paymentReceive.onDeleted,
this.handleInvoiceDecrementPaymentAmount
);
}
/**
* Handle sale invoice increment/decrement payment amount
* once created, edited or deleted.
*/
private handleInvoiceIncrementPaymentOnceCreated = async ({
tenantId,
paymentReceiveId,
paymentReceive,
trx,
}: IPaymentReceiveCreatedPayload) => {
await this.paymentReceivesService.saveChangeInvoicePaymentAmount(
tenantId,
paymentReceive.entries,
null,
trx
);
};
/**
* Handle sale invoice increment/decrement payment amount once edited.
*/
private handleInvoiceIncrementPaymentOnceEdited = async ({
tenantId,
paymentReceiveId,
paymentReceive,
oldPaymentReceive,
trx,
}: IPaymentReceiveEditedPayload) => {
await this.paymentReceivesService.saveChangeInvoicePaymentAmount(
tenantId,
paymentReceive.entries,
oldPaymentReceive?.entries || null,
trx
);
};
/**
* Handle revert invoices payment amount once payment receive deleted.
*/
private handleInvoiceDecrementPaymentAmount = async ({
tenantId,
paymentReceiveId,
oldPaymentReceive,
trx,
}: IPaymentReceiveDeletedPayload) => {
await this.paymentReceivesService.saveChangeInvoicePaymentAmount(
tenantId,
oldPaymentReceive.entries.map((entry) => ({
...entry,
paymentAmount: 0,
})),
oldPaymentReceive.entries,
trx
);
};
}

View File

@@ -0,0 +1,40 @@
import { Service, Inject } from 'typedi';
import events from '@/subscribers/events';
import PaymentReceiveNotifyBySms from '@/services/Sales/PaymentReceives/PaymentReceiveSmsNotify';
import { IPaymentReceiveCreatedPayload } from '@/interfaces';
import { runAfterTransaction } from '@/services/UnitOfWork/TransactionsHooks';
@Service()
export default class SendSmsNotificationPaymentReceive {
@Inject()
paymentReceiveSmsNotify: PaymentReceiveNotifyBySms;
/**
* Attach events.
*/
public attach(bus) {
bus.subscribe(
events.paymentReceive.onCreated,
this.handleNotifyViaSmsOncePaymentPublish
);
}
/**
* Handles send SMS notification after payment transaction creation.
*/
private handleNotifyViaSmsOncePaymentPublish = ({
tenantId,
paymentReceiveId,
trx,
}: IPaymentReceiveCreatedPayload) => {
// Notify via Sms after transactions complete running.
runAfterTransaction(trx, async () => {
try {
await this.paymentReceiveSmsNotify.notifyViaSmsNotificationAfterCreation(
tenantId,
paymentReceiveId
);
} catch (error) {}
});
};
}

View File

@@ -0,0 +1,77 @@
import { Inject, Service } from 'typedi';
import {
IPaymentReceiveCreatedPayload,
IPaymentReceiveDeletedPayload,
IPaymentReceiveEditedPayload,
} from '@/interfaces';
import events from '@/subscribers/events';
import { PaymentReceiveGLEntries } from '@/services/Sales/PaymentReceives/PaymentReceiveGLEntries';
@Service()
export default class PaymentReceivesWriteGLEntriesSubscriber {
@Inject()
private paymentReceiveGLEntries: PaymentReceiveGLEntries;
/**
* Attaches events with handlers.
*/
public attach(bus) {
bus.subscribe(
events.paymentReceive.onCreated,
this.handleWriteJournalEntriesOnceCreated
);
bus.subscribe(
events.paymentReceive.onEdited,
this.handleOverwriteJournalEntriesOnceEdited
);
bus.subscribe(
events.paymentReceive.onDeleted,
this.handleRevertJournalEntriesOnceDeleted
);
}
/**
* Handle journal entries writing once the payment receive created.
*/
private handleWriteJournalEntriesOnceCreated = async ({
tenantId,
paymentReceiveId,
trx,
}: IPaymentReceiveCreatedPayload) => {
await this.paymentReceiveGLEntries.writePaymentGLEntries(
tenantId,
paymentReceiveId,
trx
);
};
/**
* Handle journal entries writing once the payment receive edited.
*/
private handleOverwriteJournalEntriesOnceEdited = async ({
tenantId,
paymentReceive,
trx,
}: IPaymentReceiveEditedPayload) => {
await this.paymentReceiveGLEntries.rewritePaymentGLEntries(
tenantId,
paymentReceive.id,
trx
);
};
/**
* Handles revert journal entries once deleted.
*/
private handleRevertJournalEntriesOnceDeleted = async ({
tenantId,
paymentReceiveId,
trx,
}: IPaymentReceiveDeletedPayload) => {
await this.paymentReceiveGLEntries.revertPaymentGLEntries(
tenantId,
paymentReceiveId,
trx
);
};
}

View File

@@ -0,0 +1,38 @@
import { Inject, Service } from 'typedi';
import events from '@/subscribers/events';
import TenancyService from '@/services/Tenancy/TenancyService';
import SettingsService from '@/services/Settings/SettingsService';
import { ISaleEstimateCreatedPayload } from '@/interfaces';
@Service()
export default class SaleEstimateAutoSerialSubscriber {
@Inject()
tenancy: TenancyService;
@Inject()
settingsService: SettingsService;
/**
* Attaches events to handles.events.saleEstimate.onCreated
*/
public attach(bus) {
bus.subscribe(
events.saleEstimate.onCreated,
this.handleEstimateNextNumberIncrement
);
}
/**
* Handle sale estimate increment next number once be created.
*/
private handleEstimateNextNumberIncrement = async ({
tenantId,
saleEstimateId,
trx,
}: ISaleEstimateCreatedPayload) => {
await this.settingsService.incrementNextNumber(tenantId, {
key: 'next_number',
group: 'sales_estimates',
});
};
}

View File

@@ -0,0 +1,43 @@
import { Inject, Service } from 'typedi';
import events from '@/subscribers/events';
import SaleEstimateNotifyBySms from '@/services/Sales/Estimates/SaleEstimateSmsNotify';
import { ISaleEstimateCreatedPayload } from '@/interfaces';
import { runAfterTransaction } from '@/services/UnitOfWork/TransactionsHooks';
@Service()
export default class SaleEstimateSmsNotificationSubscriber {
@Inject()
saleEstimateNotifyBySms: SaleEstimateNotifyBySms;
/**
* Attaches events to handles.events.saleEstimate.onCreated
*/
public attach(bus) {
bus.subscribe(
events.saleEstimate.onCreated,
this.handleNotifySmSNotificationAfterCreation
);
}
/**
* Notify via SMS notification after sale estimate creation.
*/
private handleNotifySmSNotificationAfterCreation = async ({
tenantId,
saleEstimateId,
saleEstimate,
trx,
}: ISaleEstimateCreatedPayload) => {
// Can't continue if estimate is not delivered.
if (!saleEstimate.isDelivered) return;
runAfterTransaction(trx, async () => {
try {
await this.saleEstimateNotifyBySms.notifyViaSmsNotificationAfterCreation(
tenantId,
saleEstimateId
);
} catch (error) {}
});
};
}

View File

@@ -0,0 +1,31 @@
import { Inject, Service } from 'typedi';
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
import events from '@/subscribers/events';
import SaleInvoicesService from '@/services/Sales/SalesInvoices';
import { ISaleInvoiceCreatedPayload } from '@/interfaces';
@Service()
export default class SaleInvoiceAutoIncrementSubscriber extends EventSubscriber {
@Inject()
saleInvoicesService: SaleInvoicesService;
/**
* Constructor method.
*/
public attach(bus) {
bus.subscribe(
events.saleInvoice.onCreated,
this.handleInvoiceNextNumberIncrement
);
}
/**
* Handles sale invoice next number increment once invoice created.
* @param {ISaleInvoiceCreatedPayload} payload -
*/
private handleInvoiceNextNumberIncrement = async ({
tenantId,
}: ISaleInvoiceCreatedPayload) => {
await this.saleInvoicesService.incrementNextInvoiceNumber(tenantId);
};
}

View File

@@ -0,0 +1,41 @@
import { Inject, Service } from 'typedi';
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
import events from '@/subscribers/events';
import SaleEstimateService from '@/services/Sales/SalesEstimate';
import { ISaleInvoiceCreatedPayload } from '@/interfaces';
@Service()
export default class SaleInvoiceConvertFromEstimateSubscriber extends EventSubscriber {
@Inject()
saleEstimatesService: SaleEstimateService;
/**
* Constructor method.
*/
public attach(bus) {
bus.subscribe(
events.saleInvoice.onCreated,
this.handleMarkEstimateConvertOnceInvoiceCreated
);
}
/**
* Marks the sale estimate as converted from the sale invoice once created.
*/
private handleMarkEstimateConvertOnceInvoiceCreated = async ({
tenantId,
saleInvoice,
saleInvoiceDTO,
saleInvoiceId,
trx,
}: ISaleInvoiceCreatedPayload) => {
if (saleInvoiceDTO.fromEstimateId) {
await this.saleEstimatesService.convertEstimateToInvoice(
tenantId,
saleInvoiceDTO.fromEstimateId,
saleInvoiceId,
trx
);
}
};
}

View File

@@ -0,0 +1,44 @@
import { Inject, Service } from 'typedi';
import events from '@/subscribers/events';
import SaleInvoiceNotifyBySms from '@/services/Sales/SaleInvoiceNotifyBySms';
import { ISaleInvoiceCreatedPayload } from '@/interfaces';
import { runAfterTransaction } from '@/services/UnitOfWork/TransactionsHooks';
@Service()
export default class SendSmsNotificationToCustomer {
@Inject()
saleInvoiceNotifyBySms: SaleInvoiceNotifyBySms;
/**
* Attaches events with handlers.
*/
public attach(bus) {
bus.subscribe(
events.saleInvoice.onCreated,
this.sendSmsNotificationAfterInvoiceCreation
);
}
/**
* Hnadle sending SMS notification after invoice transaction creation.
*/
private sendSmsNotificationAfterInvoiceCreation = async ({
tenantId,
saleInvoiceId,
saleInvoice,
trx,
}: ISaleInvoiceCreatedPayload) => {
// Can't continue if the sale invoice is not marked as delivered.
if (!saleInvoice.deliveredAt) return;
// Notify via sms after transactions complete running.
runAfterTransaction(trx, async () => {
try {
await this.saleInvoiceNotifyBySms.notifyDetailsBySmsAfterCreation(
tenantId,
saleInvoiceId
);
} catch (error) {}
});
};
}

View File

@@ -0,0 +1,87 @@
import { Service, Inject } from 'typedi';
import events from '@/subscribers/events';
import TenancyService from '@/services/Tenancy/TenancyService';
import SaleInvoicesService from '@/services/Sales/SalesInvoices';
import {
ISaleInvoiceCreatedPayload,
ISaleInvoiceDeletedPayload,
ISaleInvoiceEditedPayload,
} from '@/interfaces';
@Service()
export default class WriteInventoryTransactions {
@Inject()
tenancy: TenancyService;
@Inject()
saleInvoicesService: SaleInvoicesService;
/**
* Attaches events with handles
*/
public attach(bus) {
bus.subscribe(
events.saleInvoice.onCreated,
this.handleWritingInventoryTransactions
);
bus.subscribe(
events.saleInvoice.onEdited,
this.handleRewritingInventoryTransactions
);
bus.subscribe(
events.saleInvoice.onDeleted,
this.handleDeletingInventoryTransactions
);
}
/**
* Handles the writing inventory transactions once the invoice created.
* @param {ISaleInvoiceCreatedPayload} payload
*/
private handleWritingInventoryTransactions = async ({
tenantId,
saleInvoice,
trx,
}: ISaleInvoiceCreatedPayload) => {
await this.saleInvoicesService.recordInventoryTranscactions(
tenantId,
saleInvoice,
false,
trx
);
};
/**
* Rewriting the inventory transactions once the sale invoice be edited.
* @param {ISaleInvoiceEditPayload} payload -
*/
private handleRewritingInventoryTransactions = async ({
tenantId,
saleInvoice,
trx,
}: ISaleInvoiceEditedPayload) => {
await this.saleInvoicesService.recordInventoryTranscactions(
tenantId,
saleInvoice,
true,
trx
);
};
/**
* Handles deleting the inventory transactions once the invoice deleted.
* @param {ISaleInvoiceDeletedPayload} payload -
*/
private handleDeletingInventoryTransactions = async ({
tenantId,
saleInvoiceId,
oldSaleInvoice,
trx,
}: ISaleInvoiceDeletedPayload) => {
await this.saleInvoicesService.revertInventoryTransactions(
tenantId,
saleInvoiceId,
trx
);
};
}

View File

@@ -0,0 +1,77 @@
import { Service, Inject } from 'typedi';
import events from '@/subscribers/events';
import {
ISaleInvoiceCreatedPayload,
ISaleInvoiceDeletePayload,
ISaleInvoiceEditedPayload,
} from '@/interfaces';
import { SaleInvoiceGLEntries } from '@/services/Sales/Invoices/InvoiceGLEntries';
@Service()
export default class SaleInvoiceWriteGLEntriesSubscriber {
@Inject()
private saleInvoiceGLEntries: SaleInvoiceGLEntries;
/**
* Constructor method.
*/
attach(bus) {
bus.subscribe(
events.saleInvoice.onCreated,
this.handleWriteJournalEntriesOnInvoiceCreated
);
bus.subscribe(
events.saleInvoice.onEdited,
this.handleRewriteJournalEntriesOnceInvoiceEdit
);
bus.subscribe(
events.saleInvoice.onDeleted,
this.handleRevertingInvoiceJournalEntriesOnDelete
);
}
/**
* Records journal entries of the non-inventory invoice.
*/
private handleWriteJournalEntriesOnInvoiceCreated = async ({
tenantId,
saleInvoiceId,
trx,
}: ISaleInvoiceCreatedPayload) => {
await this.saleInvoiceGLEntries.writeInvoiceGLEntries(
tenantId,
saleInvoiceId,
trx
);
};
/**
* Records journal entries of the non-inventory invoice.
*/
private handleRewriteJournalEntriesOnceInvoiceEdit = async ({
tenantId,
saleInvoice,
trx,
}: ISaleInvoiceEditedPayload) => {
await this.saleInvoiceGLEntries.rewritesInvoiceGLEntries(
tenantId,
saleInvoice.id,
trx
);
};
/**
* Handle reverting journal entries once sale invoice delete.
*/
private handleRevertingInvoiceJournalEntriesOnDelete = async ({
tenantId,
saleInvoiceId,
trx,
}: ISaleInvoiceDeletePayload) => {
await this.saleInvoiceGLEntries.revertInvoiceGLEntries(
tenantId,
saleInvoiceId,
trx
);
};
}

View File

@@ -0,0 +1,31 @@
import { Service, Inject } from 'typedi';
import events from '@/subscribers/events';
import SalesReceiptService from '@/services/Sales/SalesReceipts';
import { ISaleReceiptCreatedPayload } from '@/interfaces';
@Service()
export default class SaleReceiptAutoSerialSubscriber {
@Inject()
saleReceiptsService: SalesReceiptService;
/**
*
* @param bus
*/
public attach(bus) {
bus.subscribe(
events.saleReceipt.onCreated,
this.handleReceiptNextNumberIncrement
);
}
/**
* Handle sale receipt increment next number once be created.
*/
private handleReceiptNextNumberIncrement = async ({
tenantId,
saleReceiptId,
}: ISaleReceiptCreatedPayload) => {
await this.saleReceiptsService.incrementNextReceiptNumber(tenantId);
};
}

View File

@@ -0,0 +1,45 @@
import { Inject, Service } from 'typedi';
import events from '@/subscribers/events';
import SaleReceiptNotifyBySms from '@/services/Sales/SaleReceiptNotifyBySms';
import { ISaleReceiptCreatedPayload } from '@/interfaces';
import { runAfterTransaction } from '@/services/UnitOfWork/TransactionsHooks';
@Service()
export default class SendSmsNotificationSaleReceipt {
@Inject()
saleReceiptNotifyBySms: SaleReceiptNotifyBySms;
/**
* Attaches events with handlers.
*/
public attach(bus) {
bus.subscribe(
events.saleReceipt.onCreated,
this.handleNotifyViaSmsAfterReceiptCreation
);
}
/**
* Notify via SMS message after receipt transaction creation.
* @param {ISaleReceiptCreatedPayload} payload -
*/
private handleNotifyViaSmsAfterReceiptCreation = ({
tenantId,
saleReceiptId,
saleReceipt,
trx,
}: ISaleReceiptCreatedPayload) => {
// Can't continue if the sale receipt is not closed.
if (!saleReceipt.isClosed) return;
// Notify via sms after transaction complete running.
runAfterTransaction(trx, async () => {
try {
await this.saleReceiptNotifyBySms.notifyViaSmsAfterCreation(
tenantId,
saleReceiptId
);
} catch (error) {}
});
};
}

View File

@@ -0,0 +1,87 @@
import { Inject } from 'typedi';
import { EventSubscriber } from 'event-dispatch';
import events from '@/subscribers/events';
import TenancyService from '@/services/Tenancy/TenancyService';
import SalesReceiptService from '@/services/Sales/SalesReceipts';
import {
ISaleReceiptCreatedPayload,
ISaleReceiptEditedPayload,
ISaleReceiptEventDeletedPayload,
} from '@/interfaces';
@EventSubscriber()
export default class SaleReceiptInventoryTransactionsSubscriber {
@Inject()
tenancy: TenancyService;
@Inject()
saleReceiptsService: SalesReceiptService;
/**
* Subscribe events to handles.
*/
attach(bus) {
bus.subscribe(
events.saleReceipt.onCreated,
this.handleWritingInventoryTransactions
);
bus.subscribe(
events.saleReceipt.onEdited,
this.handleRewritingInventoryTransactions
);
bus.subscribe(
events.saleReceipt.onDeleted,
this.handleDeletingInventoryTransactions
);
}
/**
* Handles the writing inventory transactions once the receipt created.
* @param {ISaleReceiptCreatedPayload} payload -
*/
private handleWritingInventoryTransactions = async ({
tenantId,
saleReceipt,
trx,
}: ISaleReceiptCreatedPayload) => {
await this.saleReceiptsService.recordInventoryTransactions(
tenantId,
saleReceipt,
false,
trx
);
};
/**
* Rewriting the inventory transactions once the sale invoice be edited.
* @param {ISaleReceiptEditedPayload} payload -
*/
private handleRewritingInventoryTransactions = async ({
tenantId,
saleReceipt,
trx,
}: ISaleReceiptEditedPayload) => {
await this.saleReceiptsService.recordInventoryTransactions(
tenantId,
saleReceipt,
true,
trx
);
};
/**
* Handles deleting the inventory transactions once the receipt deleted.
* @param {ISaleReceiptEventDeletedPayload} payload -
*/
private handleDeletingInventoryTransactions = async ({
tenantId,
saleReceiptId,
trx,
}: ISaleReceiptEventDeletedPayload) => {
await this.saleReceiptsService.revertInventoryTransactions(
tenantId,
saleReceiptId,
trx
);
};
}

View File

@@ -0,0 +1,87 @@
import { Service, Inject } from 'typedi';
import events from '@/subscribers/events';
import TenancyService from '@/services/Tenancy/TenancyService';
import SalesReceiptService from '@/services/Sales/SalesReceipts';
import {
ISaleReceiptCreatedPayload,
ISaleReceiptEditedPayload,
ISaleReceiptEventDeletedPayload,
} from '@/interfaces';
import { SaleReceiptGLEntries } from '@/services/Sales/SaleReceiptGLEntries';
@Service()
export default class SaleReceiptWriteGLEntriesSubscriber {
@Inject()
tenancy: TenancyService;
@Inject()
saleReceiptGLEntries: SaleReceiptGLEntries;
/**
* Attaches events with handlers.
*/
public attach(bus) {
bus.subscribe(
events.saleReceipt.onCreated,
this.handleWriteReceiptIncomeJournalEntrieOnCreate
);
bus.subscribe(
events.saleReceipt.onEdited,
this.handleWriteReceiptIncomeJournalEntrieOnEdited
);
bus.subscribe(
events.saleReceipt.onDeleted,
this.handleRevertReceiptJournalEntriesOnDeleted
);
}
/**
* Handles writing sale receipt income journal entries once created.
* @param {ISaleReceiptCreatedPayload} payload -
*/
public handleWriteReceiptIncomeJournalEntrieOnCreate = async ({
tenantId,
saleReceiptId,
trx,
}: ISaleReceiptCreatedPayload) => {
// Writes the sale receipt income journal entries.
await this.saleReceiptGLEntries.writeIncomeGLEntries(
tenantId,
saleReceiptId,
trx
);
};
/**
* Handles sale receipt revert jouranl entries once be deleted.
* @param {ISaleReceiptEventDeletedPayload} payload -
*/
public handleRevertReceiptJournalEntriesOnDeleted = async ({
tenantId,
saleReceiptId,
trx,
}: ISaleReceiptEventDeletedPayload) => {
await this.saleReceiptGLEntries.revertReceiptGLEntries(
tenantId,
saleReceiptId,
trx
);
};
/**
* Handles writing sale receipt income journal entries once be edited.
* @param {ISaleReceiptEditedPayload} payload -
*/
private handleWriteReceiptIncomeJournalEntrieOnEdited = async ({
tenantId,
saleReceiptId,
trx,
}: ISaleReceiptEditedPayload) => {
// Writes the sale receipt income journal entries.
await this.saleReceiptGLEntries.rewriteReceiptGLEntries(
tenantId,
saleReceiptId,
trx
);
};
}

View File

@@ -0,0 +1,553 @@
export default {
/**
* Authentication service.
*/
auth: {
login: 'onLogin',
register: 'onRegister',
sendResetPassword: 'onSendResetPassword',
resetPassword: 'onResetPassword',
},
/**
* Invite users service.
*/
inviteUser: {
acceptInvite: 'onUserAcceptInvite',
sendInvite: 'onUserSendInvite',
resendInvite: 'onUserInviteResend',
checkInvite: 'onUserCheckInvite',
sendInviteTenantSynced: 'onUserSendInviteTenantSynced',
},
/**
* Organization managment service.
*/
organization: {
build: 'onOrganizationBuild',
seeded: 'onOrganizationSeeded',
baseCurrencyUpdated: 'onOrganizationBaseCurrencyUpdated',
},
/**
* Tenants managment service.
*/
tenantManager: {
databaseCreated: 'onDatabaseCreated',
tenantMigrated: 'onTenantMigrated',
tenantSeeded: 'onTenantSeeded',
},
/**
* Accounts service.
*/
accounts: {
onCreating: 'onAccountCreating',
onCreated: 'onAccountCreated',
onEditing: 'onAccountEditing',
onEdited: 'onAccountEdited',
onDelete: 'onAccountDelete',
onDeleted: 'onAccountDeleted',
onBulkDeleted: 'onBulkDeleted',
onBulkActivated: 'onAccountBulkActivated',
onActivated: 'onAccountActivated',
},
/**
* Manual journals service.
*/
manualJournals: {
onCreating: 'onManualJournalCreating',
onCreated: 'onManualJournalCreated',
onEditing: 'onManualJournalEditing',
onEdited: 'onManualJournalEdited',
onDeleting: 'onManualJournalDeleting',
onDeleted: 'onManualJournalDeleted',
onPublished: 'onManualJournalPublished',
onPublishing: 'onManualJournalPublishing',
},
/**
* Expenses service.
*/
expenses: {
onCreating: 'onExpenseCreating',
onCreated: 'onExpenseCreated',
onEditing: 'onExpenseEditing',
onEdited: 'onExpenseEdited',
onDeleting: 'onExpenseDeleting',
onDeleted: 'onExpenseDeleted',
onPublishing: 'onExpensePublishing',
onPublished: 'onExpensePublished',
},
/**
* Sales invoices service.
*/
saleInvoice: {
onCreate: 'onSaleInvoiceCreate',
onCreating: 'onSaleInvoiceCreating',
onCreated: 'onSaleInvoiceCreated',
onEdit: 'onSaleInvoiceEdit',
onEditing: 'onSaleInvoiceEditing',
onEdited: 'onSaleInvoiceEdited',
onDelete: 'onSaleInvoiceDelete',
onDeleting: 'onSaleInvoiceDeleting',
onDeleted: 'onSaleInvoiceDeleted',
onDelivering: 'onSaleInvoiceDelivering',
onDeliver: 'onSaleInvoiceDeliver',
onDelivered: 'onSaleInvoiceDelivered',
onPublish: 'onSaleInvoicePublish',
onPublished: 'onSaleInvoicePublished',
onWriteoff: 'onSaleInvoiceWriteoff',
onWrittenoff: 'onSaleInvoiceWrittenoff',
onWrittenoffCancel: 'onSaleInvoiceWrittenoffCancel',
onWrittenoffCanceled: 'onSaleInvoiceWrittenoffCanceled',
onNotifySms: 'onSaleInvoiceNotifySms',
onNotifiedSms: 'onSaleInvoiceNotifiedSms',
},
/**
* Sales estimates service.
*/
saleEstimate: {
onCreating: 'onSaleEstimateCreating',
onCreated: 'onSaleEstimateCreated',
onEditing: 'onSaleEstimateEditing',
onEdited: 'onSaleEstimateEdited',
onDeleting: 'onSaleEstimatedDeleting',
onDeleted: 'onSaleEstimatedDeleted',
onPublishing: 'onSaleEstimatedPublishing',
onPublished: 'onSaleEstimatedPublished',
onNotifySms: 'onSaleEstimateNotifySms',
onNotifiedSms: 'onSaleEstimateNotifiedSms',
onDelivering: 'onSaleEstimateDelivering',
onDelivered: 'onSaleEstimateDelivered',
onConvertedToInvoice: 'onSaleEstimateConvertedToInvoice',
onApproving: 'onSaleEstimateApproving',
onApproved: 'onSaleEstimateApproved',
onRejecting: 'onSaleEstimateRejecting',
onRejected: 'onSaleEstimateRejected',
},
/**
* Sales receipts service.
*/
saleReceipt: {
onCreating: 'onSaleReceiptsCreating',
onCreated: 'onSaleReceiptsCreated',
onEditing: 'onSaleReceiptsEditing',
onEdited: 'onSaleReceiptsEdited',
onDeleting: 'onSaleReceiptsDeleting',
onDeleted: 'onSaleReceiptsDeleted',
onPublishing: 'onSaleReceiptPublishing',
onPublished: 'onSaleReceiptPublished',
onClosed: 'onSaleReceiptClosed',
onClosing: 'onSaleReceiptClosing',
onNotifySms: 'onSaleReceiptNotifySms',
onNotifiedSms: 'onSaleReceiptNotifiedSms',
},
/**
* Payment receipts service.
*/
paymentReceive: {
onCreated: 'onPaymentReceiveCreated',
onCreating: 'onPaymentReceiveCreating',
onEditing: 'onPaymentReceiveEditing',
onEdited: 'onPaymentReceiveEdited',
onDeleting: 'onPaymentReceiveDeleting',
onDeleted: 'onPaymentReceiveDeleted',
onPublishing: 'onPaymentReceivePublishing',
onPublished: 'onPaymentReceivePublished',
onNotifySms: 'onPaymentReceiveNotifySms',
onNotifiedSms: 'onPaymentReceiveNotifiedSms',
},
/**
* Bills service.
*/
bill: {
onCreating: 'onBillCreating',
onCreated: 'onBillCreated',
onEditing: 'onBillEditing',
onEdited: 'onBillEdited',
onDeleting: 'onBillDeleting',
onDeleted: 'onBillDeleted',
onPublishing: 'onBillPublishing',
onPublished: 'onBillPublished',
},
/**
* Bill payments service.
*/
billPayment: {
onCreating: 'onBillPaymentCreating',
onCreated: 'onBillPaymentCreated',
onEditing: 'onBillPaymentEditing',
onEdited: 'onBillPaymentEdited',
onDeleted: 'onBillPaymentDeleted',
onDeleting: 'onBillPaymentDeleting',
onPublishing: 'onBillPaymentPublishing',
onPublished: 'onBillPaymentPublished',
},
/**
* Customers services.
*/
customers: {
onCreating: 'onCustomerCreating',
onCreated: 'onCustomerCreated',
onEdited: 'onCustomerEdited',
onEditing: 'onCustomerEditing',
onDeleted: 'onCustomerDeleted',
onDeleting: 'onCustomerDeleting',
onBulkDeleted: 'onBulkDeleted',
onOpeningBalanceChanging: 'onCustomerOpeningBalanceChanging',
onOpeningBalanceChanged: 'onCustomerOpeingBalanceChanged',
onActivating: 'onCustomerActivating',
onActivated: 'onCustomerActivated',
},
/**
* Vendors services.
*/
vendors: {
onCreated: 'onVendorCreated',
onCreating: 'onVendorCreating',
onEdited: 'onVendorEdited',
onEditing: 'onVendorEditing',
onDeleted: 'onVendorDeleted',
onDeleting: 'onVendorDeleting',
onOpeningBalanceChanging: 'onVendorOpeingBalanceChanging',
onOpeningBalanceChanged: 'onVendorOpeingBalanceChanged',
onActivating: 'onVendorActivating',
onActivated: 'onVendorActivated',
},
/**
* Items service.
*/
item: {
onCreated: 'onItemCreated',
onCreating: 'onItemCreating',
onEditing: 'onItemEditing',
onEdited: 'onItemEdited',
onDeleted: 'onItemDeleted',
onDeleting: 'onItemDeleting',
onActivating: 'onItemActivating',
onActivated: 'onItemActivated',
onInactivating: 'onInactivating',
onInactivated: 'onItemInactivated',
},
/**
* Item category service.
*/
itemCategory: {
onCreated: 'onItemCategoryCreated',
onEdited: 'onItemCategoryEdited',
onDeleted: 'onItemCategoryDeleted',
onBulkDeleted: 'onItemCategoryBulkDeleted',
},
/**
* Inventory service.
*/
inventory: {
onInventoryTransactionsCreated: 'onInventoryTransactionsCreated',
onInventoryTransactionsDeleted: 'onInventoryTransactionsDeleted',
onComputeItemCostJobScheduled: 'onComputeItemCostJobScheduled',
onComputeItemCostJobStarted: 'onComputeItemCostJobStarted',
onComputeItemCostJobCompleted: 'onComputeItemCostJobCompleted',
onInventoryCostEntriesWritten: 'onInventoryCostEntriesWritten',
onCostLotsGLEntriesBeforeWrite: 'onInventoryCostLotsGLEntriesBeforeWrite',
onCostLotsGLEntriesWrite: 'onInventoryCostLotsGLEntriesWrite',
},
/**
* Inventory adjustment service.
*/
inventoryAdjustment: {
onQuickCreating: 'onInventoryAdjustmentCreating',
onQuickCreated: 'onInventoryAdjustmentQuickCreated',
onCreated: 'onInventoryAdjustmentCreated',
onDeleting: 'onInventoryAdjustmentDeleting',
onDeleted: 'onInventoryAdjustmentDeleted',
onPublishing: 'onInventoryAdjustmentPublishing',
onPublished: 'onInventoryAdjustmentPublished',
},
/**
* Bill landed cost.
*/
billLandedCost: {
onCreate: 'onBillLandedCostCreate',
onCreated: 'onBillLandedCostCreated',
onDelete: 'onBillLandedCostDelete',
onDeleted: 'onBillLandedCostDeleted',
},
cashflow: {
onOwnerContributionCreate: 'onCashflowOwnerContributionCreate',
onOwnerContributionCreated: 'onCashflowOwnerContributionCreated',
onOtherIncomeCreate: 'onCashflowOtherIncomeCreate',
onOtherIncomeCreated: 'onCashflowOtherIncomeCreated',
onTransactionCreating: 'onCashflowTransactionCreating',
onTransactionCreated: 'onCashflowTransactionCreated',
onTransactionDeleting: 'onCashflowTransactionDeleting',
onTransactionDeleted: 'onCashflowTransactionDeleted',
},
/**
* Roles service events.
*/
roles: {
onCreate: 'onRoleCreate',
onCreated: 'onRoleCreated',
onEdit: 'onRoleEdit',
onEdited: 'onRoleEdited',
onDelete: 'onRoleDelete',
onDeleted: 'onRoleDeleted',
},
tenantUser: {
onEdited: 'onTenantUserEdited',
onDeleted: 'onTenantUserDeleted',
onActivated: 'onTenantUserActivated',
onInactivated: 'onTenantUserInactivated',
},
/**
* Credit note service.
*/
creditNote: {
onCreate: 'onCreditNoteCreate',
onCreating: 'onCreditNoteCreating',
onCreated: 'onCreditNoteCreated',
onEditing: 'onCreditNoteEditing',
onEdit: 'onCreditNoteEdit',
onEdited: 'onCreditNoteEdited',
onDelete: 'onCreditNoteDelete',
onDeleting: 'onCreditNoteDeleting',
onDeleted: 'onCreditNoteDeleted',
onOpen: 'onCreditNoteOpen',
onOpening: 'onCreditNoteOpening',
onOpened: 'onCreditNoteOpened',
onRefundCreate: 'onCreditNoteRefundCreate',
onRefundCreating: 'onCreditNoteRefundCreating',
onRefundCreated: 'onCreditNoteRefundCreated',
onRefundDelete: 'onCreditNoteRefundDelete',
onRefundDeleting: 'onCreditNoteRefundDeleting',
onRefundDeleted: 'onCreditNoteRefundDeleted',
onApplyToInvoicesCreated: 'onCreditNoteApplyToInvoiceCreated',
onApplyToInvoicesCreate: 'onCreditNoteApplyToInvoiceCreate',
onApplyToInvoicesDeleted: 'onCreditNoteApplyToInvoiceDeleted',
},
/**
* Vendor credit service.
*/
vendorCredit: {
onCreate: 'onVendorCreditCreate',
onCreating: 'onVendorCreditCreating',
onCreated: 'onVendorCreditCreated',
onEdit: 'onVendorCreditEdit',
onEditing: 'onVendorCreditEditing',
onEdited: 'onVendorCreditEdited',
onDelete: 'onVendorCreditDelete',
onDeleting: 'onVendorCreditDeleting',
onDeleted: 'onVendorCreditDeleted',
onOpen: 'onVendorCreditOpen',
onOpened: 'onVendorCreditOpened',
onRefundCreating: 'onVendorCreditRefundCreating',
onRefundCreate: 'onVendorCreditRefundCreate',
onRefundCreated: 'onVendorCreditRefundCreated',
onRefundDelete: 'onVendorCreditRefundDelete',
onRefundDeleting: 'onVendorCreditRefundDeleting',
onRefundDeleted: 'onVendorCreditRefundDeleted',
onApplyToInvoicesCreated: 'onVendorCreditApplyToInvoiceCreated',
onApplyToInvoicesCreate: 'onVendorCreditApplyToInvoiceCreate',
onApplyToInvoicesDeleted: 'onVendorCreditApplyToInvoiceDeleted',
},
transactionsLocking: {
locked: 'onTransactionLockingLocked',
lockCanceled: 'onTransactionLockingLockCanceled',
partialUnlocked: 'onTransactionLockingPartialUnlocked',
partialUnlockCanceled: 'onTransactionLockingPartialUnlockCanceled',
},
warehouse: {
onCreate: 'onWarehouseCreate',
onCreated: 'onWarehouseCreated',
onEdit: 'onWarehouseEdit',
onEdited: 'onWarehouseEdited',
onDelete: 'onWarehouseDelete',
onDeleted: 'onWarehouseDeleted',
onActivate: 'onWarehouseActivate',
onActivated: 'onWarehouseActivated',
onMarkPrimary: 'onWarehouseMarkPrimary',
onMarkedPrimary: 'onWarehouseMarkedPrimary',
},
warehouseTransfer: {
onCreate: 'onWarehouseTransferCreate',
onCreated: 'onWarehouseTransferCreated',
onEdit: 'onWarehouseTransferEdit',
onEdited: 'onWarehouseTransferEdited',
onDelete: 'onWarehouseTransferDelete',
onDeleted: 'onWarehouseTransferDeleted',
onInitiate: 'onWarehouseTransferInitiate',
onInitiated: 'onWarehouseTransferInitated',
onTransfer: 'onWarehouseTransferInitiate',
onTransferred: 'onWarehouseTransferTransferred',
},
/**
* Branches.
*/
branch: {
onActivate: 'onBranchActivate',
onActivated: 'onBranchActivated',
onMarkPrimary: 'onBranchMarkPrimary',
onMarkedPrimary: 'onBranchMarkedPrimary',
},
/**
* Projects.
*/
project: {
onCreate: 'onProjectCreate',
onCreating: 'onProjectCreating',
onCreated: 'onProjectCreated',
onEdit: 'onEditProject',
onEditing: 'onEditingProject',
onEdited: 'onEditedProject',
onEditStatus: 'onEditStatusProject',
onEditingStatus: 'onEditingStatusProject',
onEditedStatus: 'onEditedStatusProject',
onDelete: 'onDeleteProject',
onDeleting: 'onDeletingProject',
onDeleted: 'onDeletedProject',
},
/**
* Project Tasks.
*/
projectTask: {
onCreate: 'onProjectTaskCreate',
onCreating: 'onProjectTaskCreating',
onCreated: 'onProjectTaskCreated',
onEdit: 'onProjectTaskEdit',
onEditing: 'onProjectTaskEditing',
onEdited: 'onProjectTaskEdited',
onDelete: 'onProjectTaskDelete',
onDeleting: 'onProjectTaskDeleting',
onDeleted: 'onProjectTaskDeleted',
},
/**
* Project Times.
*/
projectTime: {
onCreate: 'onProjectTimeCreate',
onCreating: 'onProjectTimeCreating',
onCreated: 'onProjectTimeCreated',
onEdit: 'onProjectTimeEdit',
onEditing: 'onProjectTimeEditing',
onEdited: 'onProjectTimeEdited',
onDelete: 'onProjectTimeDelete',
onDeleting: 'onProjectTimeDeleting',
onDeleted: 'onProjectTimeDeleted',
},
};