fix: refactoring invoice calc cost service.

This commit is contained in:
a.bouhuolia
2021-01-05 17:06:42 +02:00
parent d25360d279
commit df85c9b295
41 changed files with 1684 additions and 1085 deletions

View File

@@ -0,0 +1,59 @@
import { Container } from 'typedi';
import { EventSubscriber, On } from 'event-dispatch';
import events from 'subscribers/events';
import TenancyService from 'services/Tenancy/TenancyService';
import ItemsEntriesService from 'services/Items/ItemsEntriesService';
@EventSubscriber()
export default class BillSubscriber {
tenancy: TenancyService;
logger: any;
itemsEntriesService: ItemsEntriesService;
/**
* Constructor method.
*/
constructor() {
this.tenancy = Container.get(TenancyService);
this.logger = Container.get('logger');
this.itemsEntriesService = Container.get(ItemsEntriesService);
}
/**
* Increments the sale invoice items once the invoice created.
*/
@On(events.bill.onCreated)
public async handleDecrementSaleInvoiceItemsQuantity({ tenantId, bill }) {
await this.itemsEntriesService.incrementItemsEntries(
tenantId,
bill.entries
);
}
/**
* Decrements the sale invoice items once the invoice deleted.
*/
@On(events.bill.onDeleted)
public async handleIncrementSaleInvoiceItemsQuantity({ tenantId, oldBill }) {
await this.itemsEntriesService.decrementItemsQuantity(
tenantId,
oldBill.entries
);
}
/**
* Handle increment/decrement the different items quantity once the sale invoice be edited.
*/
@On(events.bill.onEdited)
public async handleChangeSaleInvoiceItemsQuantityOnEdit({
tenantId,
bill,
oldBill,
}) {
await this.itemsEntriesService.changeItemsQuantity(
tenantId,
bill.entries,
oldBill.entries
);
}
}

View File

@@ -0,0 +1,68 @@
import { Container } from 'typedi';
import { EventSubscriber, On } from 'event-dispatch';
import events from 'subscribers/events';
import TenancyService from 'services/Tenancy/TenancyService';
@EventSubscriber()
export default class BillSubscriber {
tenancy: TenancyService;
logger: any;
/**
* Constructor method.
*/
constructor() {
this.tenancy = Container.get(TenancyService);
this.logger = Container.get('logger');
}
/**
* Handles vendor balance increment once bill created.
*/
@On(events.bill.onCreated)
async handleVendorBalanceIncrement({ tenantId, billId, bill }) {
const { vendorRepository } = this.tenancy.repositories(tenantId);
// Increments vendor balance.
this.logger.info('[bill] trying to increment vendor balance.', {
tenantId,
billId,
});
await vendorRepository.changeBalance(bill.vendorId, bill.amount);
}
/**
* Handles vendor balance decrement once bill deleted.
*/
@On(events.bill.onDeleted)
async handleVendorBalanceDecrement({ tenantId, billId, oldBill }) {
const { vendorRepository } = this.tenancy.repositories(tenantId);
// Decrements vendor balance.
this.logger.info('[bill] trying to decrement vendor balance.', {
tenantId,
billId,
});
await vendorRepository.changeBalance(oldBill.vendorId, oldBill.amount * -1);
}
/**
* Handles vendor balance difference change.
*/
@On(events.bill.onEdited)
async handleVendorBalanceDiffChange({ tenantId, billId, oldBill, bill }) {
const { vendorRepository } = this.tenancy.repositories(tenantId);
// Changes the diff vendor balance between old and new amount.
this.logger.info('[bill[ change vendor the different balance.', {
tenantId,
billId,
});
await vendorRepository.changeDiffBalance(
bill.vendorId,
bill.amount,
oldBill.amount,
oldBill.vendorId
);
}
}

View File

@@ -0,0 +1,60 @@
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');
}
/**
* Handles writing the inventory transactions once bill created.
*/
@On(events.bill.onCreated)
async handleWritingInventoryTransactions({ tenantId, bill }) {
this.logger.info('[bill] writing the inventory transactions', { tenantId });
this.billsService.recordInventoryTransactions(
tenantId,
bill
);
}
/**
* Handles the overwriting the inventory transactions once bill edited.
*/
@On(events.bill.onEdited)
async handleOverwritingInventoryTransactions({ tenantId, bill }) {
this.logger.info('[bill] overwriting the inventory transactions.', {
tenantId,
});
this.billsService.recordInventoryTransactions(
tenantId,
bill,
true
);
}
/**
* Handles the reverting the inventory transactions once the bill deleted.
*/
@On(events.bill.onDeleted)
async handleRevertInventoryTransactions({ tenantId, billId }) {
this.logger.info('[bill] reverting the bill inventory transactions', {
tenantId,
billId,
});
this.billsService.revertInventoryTransactions(tenantId, billId);
}
}

View File

@@ -0,0 +1,54 @@
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');
}
/**
* Handles writing journal entries once bill created.
*/
@On(events.bill.onCreated)
async handlerWriteJournalEntriesOnCreate({ tenantId, bill }) {
// Writes the journal entries for the given bill transaction.
this.logger.info('[bill] writing bill journal entries.', { tenantId });
await this.billsService.recordJournalTransactions(tenantId, bill);
}
/**
* Handles the overwriting journal entries once bill edited.
*/
@On(events.bill.onEdited)
async handleOverwriteJournalEntriesOnEdit({ tenantId, bill }) {
// Overwrite the journal entries for the given bill transaction.
this.logger.info('[bill] overwriting bill journal entries.', { tenantId });
await this.billsService.recordJournalTransactions(tenantId, bill, true);
}
/**
* Handles revert journal entries on bill deleted.
*/
@On(events.bill.onDeleted)
async handlerDeleteJournalEntries({ tenantId, billId }) {
// Delete associated bill journal transactions.
this.logger.info('[bill] trying to delete journal entries.', {
tenantId,
billId,
});
await this.billsService.revertJournalEntries(tenantId, billId);
}
}

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,82 @@
import { Container } from 'typedi';
import { On, EventSubscriber } from 'event-dispatch';
import events from 'subscribers/events';
import TenancyService from 'services/Tenancy/TenancyService';
@EventSubscriber()
export default class SaleInvoiceSubscriber {
logger: any;
tenancy: TenancyService;
/**
* Constructor method.
*/
constructor() {
this.logger = Container.get('logger');
this.tenancy = Container.get(TenancyService);
}
/**
* Handles customer balance increment once sale invoice created.
*/
@On(events.saleInvoice.onCreated)
public async handleCustomerBalanceIncrement({
tenantId,
saleInvoice,
saleInvoiceId,
}) {
const { customerRepository } = this.tenancy.repositories(tenantId);
this.logger.info('[sale_invoice] trying to increment customer balance.', {
tenantId,
});
await customerRepository.changeBalance(
saleInvoice.customerId,
saleInvoice.balance
);
}
/**
* Handles customer balance diff balnace change once sale invoice edited.
*/
@On(events.saleInvoice.onEdited)
public async onSaleInvoiceEdited({
tenantId,
saleInvoice,
oldSaleInvoice,
saleInvoiceId,
}) {
const { customerRepository } = this.tenancy.repositories(tenantId);
this.logger.info('[sale_invoice] trying to change diff customer balance.', {
tenantId,
});
await customerRepository.changeDiffBalance(
saleInvoice.customerId,
saleInvoice.balance,
oldSaleInvoice.balance,
oldSaleInvoice.customerId
);
}
/**
* Handles customer balance decrement once sale invoice deleted.
*/
@On(events.saleInvoice.onDeleted)
public async handleCustomerBalanceDecrement({
tenantId,
saleInvoiceId,
oldSaleInvoice,
}) {
const { customerRepository } = this.tenancy.repositories(tenantId);
this.logger.info('[sale_invoice] trying to decrement customer balance.', {
tenantId,
});
await customerRepository.changeBalance(
oldSaleInvoice.customerId,
oldSaleInvoice.balance * -1
);
}
}

View File

@@ -0,0 +1,71 @@
import { Container } from 'typedi';
import { On, EventSubscriber } from 'event-dispatch';
import events from 'subscribers/events';
import TenancyService from 'services/Tenancy/TenancyService';
import ItemsEntriesService from 'services/Items/ItemsEntriesService';
@EventSubscriber()
export default class SyncItemsQuantityWithInvoices {
logger: any;
tenancy: TenancyService;
itemsEntriesService: ItemsEntriesService;
/**
* Constructor method.
*/
constructor() {
this.logger = Container.get('logger');
this.tenancy = Container.get(TenancyService);
this.itemsEntriesService = Container.get(ItemsEntriesService);
}
/**
* Increments the sale invoice items once the invoice created.
*/
@On(events.saleInvoice.onCreated)
public async handleDecrementSaleInvoiceItemsQuantity({
tenantId,
saleInvoice,
}) {
await this.itemsEntriesService.decrementItemsQuantity(
tenantId,
saleInvoice.entries
);
}
/**
* Decrements the sale invoice items once the invoice deleted.
*/
@On(events.saleInvoice.onDeleted)
public async handleIncrementSaleInvoiceItemsQuantity({
tenantId,
oldSaleInvoice,
}) {
await this.itemsEntriesService.incrementItemsEntries(
tenantId,
oldSaleInvoice.entries
);
}
/**
* Handle increment/decrement the different items quantity once the sale invoice be edited.
*/
@On(events.saleInvoice.onEdited)
public async handleChangeSaleInvoiceItemsQuantityOnEdit({
tenantId,
saleInvoice,
oldSaleInvoice,
}) {
await this.itemsEntriesService.changeItemsQuantity(
tenantId,
saleInvoice.entries.map((entry) => ({
...entry,
quantity: entry.quantity * -1,
})),
oldSaleInvoice.entries.map((entry) => ({
...entry,
quantity: entry.quantity * -1,
}))
);
}
}

View File

@@ -0,0 +1,72 @@
import { Container } from 'typedi';
import { On, EventSubscriber } from 'event-dispatch';
import events from 'subscribers/events';
import TenancyService from 'services/Tenancy/TenancyService';
import SaleInvoicesService from 'services/Sales/SalesInvoices';
@EventSubscriber()
export default class WriteInventoryTransactions {
logger: any;
tenancy: TenancyService;
saleInvoicesService: SaleInvoicesService;
/**
* Constructor method.
*/
constructor() {
this.logger = Container.get('logger');
this.tenancy = Container.get(TenancyService);
this.saleInvoicesService = Container.get(SaleInvoicesService);
}
/**
* Handles the writing inventory transactions once the invoice created.
*/
@On(events.saleInvoice.onCreated)
public async handleWritingInventoryTransactions({ tenantId, saleInvoice }) {
this.logger.info('[sale_invoice] trying to write inventory transactions.', {
tenantId,
});
await this.saleInvoicesService.recordInventoryTranscactions(
tenantId,
saleInvoice
);
}
/**
* Rewriting the inventory transactions once the sale invoice be edited.
*/
@On(events.saleInvoice.onEdited)
public async handleRewritingInventoryTransactions({ tenantId, saleInvoice }) {
this.logger.info('[sale_invoice] trying to write inventory transactions.', {
tenantId,
});
await this.saleInvoicesService.recordInventoryTranscactions(
tenantId,
saleInvoice,
true
);
}
/**
* Handles deleting the inventory transactions once the invoice deleted.
*/
@On(events.saleInvoice.onDeleted)
public async handleDeletingInventoryTransactions({
tenantId,
saleInvoiceId,
oldSaleInvoice,
}) {
this.logger.info(
'[sale_invoice] trying to revert inventory transactions.',
{
tenantId,
saleInvoiceId,
}
);
await this.saleInvoicesService.revertInventoryTransactions(
tenantId,
saleInvoiceId
);
}
}

View File

@@ -0,0 +1,80 @@
import { Container } from 'typedi';
import { On, EventSubscriber } from 'event-dispatch';
import events from 'subscribers/events';
import TenancyService from 'services/Tenancy/TenancyService';
import SaleInvoicesService from 'services/Sales/SalesInvoices';
@EventSubscriber()
export default class SaleInvoiceSubscriber {
logger: any;
tenancy: TenancyService;
saleInvoicesService: SaleInvoicesService;
/**
* Constructor method.
*/
constructor() {
this.logger = Container.get('logger');
this.tenancy = Container.get(TenancyService);
this.saleInvoicesService = Container.get(SaleInvoicesService);
}
/**
* Records journal entries of the non-inventory invoice.
*/
@On(events.saleInvoice.onCreated)
public async handleWriteJournalEntriesOnInvoiceCreated({
tenantId,
saleInvoiceId,
saleInvoice,
authorizedUser,
}) {
const { saleInvoiceRepository } = this.tenancy.repositories(tenantId);
const saleInvoiceWithItems = await saleInvoiceRepository.findOneById(
saleInvoiceId,
'entries.item'
);
await this.saleInvoicesService.writesIncomeJournalEntries(
tenantId,
saleInvoiceWithItems
);
}
/**
* Records journal entries of the non-inventory invoice.
*/
@On(events.saleInvoice.onEdited)
public async handleRewriteJournalEntriesOnceInvoiceEdit({
tenantId,
saleInvoiceId,
saleInvoice,
authorizedUser,
}) {
const { saleInvoiceRepository } = this.tenancy.repositories(tenantId);
const saleInvoiceWithItems = await saleInvoiceRepository.findOneById(
saleInvoiceId,
'entries.item'
);
await this.saleInvoicesService.writesIncomeJournalEntries(
tenantId,
saleInvoiceWithItems,
true
);
}
/**
* Handle reverting journal entries once sale invoice delete.
*/
@On(events.saleInvoice.onDeleted)
public async handleRevertingInvoiceJournalEntriesOnDelete({
tenantId,
saleInvoiceId,
}) {
await this.saleInvoicesService.revertInvoiceJournalEntries(
tenantId,
saleInvoiceId,
);
}
}

View File

@@ -0,0 +1,57 @@
import { Container } from 'typedi';
import { On, EventSubscriber } from 'event-dispatch';
import events from 'subscribers/events';
import TenancyService from 'services/Tenancy/TenancyService';
import SettingsService from 'services/Settings/SettingsService';
import SaleEstimateService from 'services/Sales/SalesEstimate';
@EventSubscriber()
export default class SaleInvoiceSubscriber {
logger: any;
tenancy: TenancyService;
settingsService: SettingsService;
saleEstimatesService: SaleEstimateService;
/**
* Constructor method.
*/
constructor() {
this.logger = Container.get('logger');
this.tenancy = Container.get(TenancyService);
this.settingsService = Container.get(SettingsService);
this.saleEstimatesService = Container.get(SaleEstimateService);
}
/**
* Marks the sale estimate as converted from the sale invoice once created.
*/
@On(events.saleInvoice.onCreated)
public async handleMarkEstimateConvert({
tenantId,
saleInvoice,
saleInvoiceId,
}) {
if (saleInvoice.fromEstimateId) {
this.saleEstimatesService.convertEstimateToInvoice(
tenantId,
saleInvoice.fromEstiamteId,
saleInvoiceId
);
}
}
/**
* Handles sale invoice next number increment once invoice created.
*/
@On(events.saleInvoice.onCreated)
public async handleInvoiceNextNumberIncrement({
tenantId,
saleInvoiceId,
saleInvoice,
}) {
await this.settingsService.incrementNextNumber(tenantId, {
key: 'next_number',
group: 'sales_invoices',
});
}
}

View File

@@ -0,0 +1,67 @@
import { Container } from 'typedi';
import { On, EventSubscriber } from 'event-dispatch';
import events from 'subscribers/events';
import TenancyService from 'services/Tenancy/TenancyService';
import ItemsEntriesService from 'services/Items/ItemsEntriesService';
import SalesInvoicesCost from 'services/Sales/SalesInvoicesCost';
@EventSubscriber()
export default class SaleReceiptSubscriber {
logger: any;
tenancy: TenancyService;
itemsEntriesService: ItemsEntriesService;
constructor() {
this.logger = Container.get('logger');
this.tenancy = Container.get(TenancyService);
this.itemsEntriesService = Container.get(ItemsEntriesService);
}
/**
* Increments the sale receipt items once be created.
*/
@On(events.saleReceipt.onCreated)
public async handleDecremenReceiptItemsQuantity({ tenantId, saleReceipt }) {
await this.itemsEntriesService.decrementItemsQuantity(
tenantId,
saleReceipt.entries
);
}
/**
* Decrements the sale receipt items once be deleted.
*/
@On(events.saleReceipt.onDeleted)
public async handleIncrementReceiptItemsQuantity({
tenantId,
oldSaleReceipt,
}) {
await this.itemsEntriesService.incrementItemsEntries(
tenantId,
oldSaleReceipt.entries
);
}
/**
* Handle increment/decrement the different items quantity once
* the sale receipt be edited.
*/
@On(events.saleReceipt.onEdited)
public async handleChangeSaleInvoiceItemsQuantityOnEdit({
tenantId,
saleReceipt,
oldSaleReceipt,
}) {
await this.itemsEntriesService.changeItemsQuantity(
tenantId,
saleReceipt.entries.map((entry) => ({
...entry,
quantity: entry.quantity * -1,
})),
oldSaleReceipt.entries.map((entry) => ({
...entry,
quantity: entry.quantity * -1,
}))
);
}
}

View File

@@ -0,0 +1,68 @@
import { Container } from 'typedi';
import { On, EventSubscriber } from 'event-dispatch';
import events from 'subscribers/events';
import TenancyService from 'services/Tenancy/TenancyService';
import SalesReceiptService from 'services/Sales/SalesReceipts';
@EventSubscriber()
export default class SaleReceiptSubscriber {
logger: any;
tenancy: TenancyService;
saleReceiptsService: SalesReceiptService;
constructor() {
this.logger = Container.get('logger');
this.tenancy = Container.get(TenancyService);
this.saleReceiptsService = Container.get(SalesReceiptService);
}
/**
* Handles the writing inventory transactions once the receipt created.
*/
@On(events.saleReceipt.onCreated)
public async handleWritingInventoryTransactions({ tenantId, saleReceipt }) {
this.logger.info('[sale_receipt] trying to write inventory transactions.', {
tenantId,
});
await this.saleReceiptsService.recordInventoryTransactions(
tenantId,
saleReceipt
);
}
/**
* Rewriting the inventory transactions once the sale invoice be edited.
*/
@On(events.saleReceipt.onEdited)
public async handleRewritingInventoryTransactions({ tenantId, saleReceipt }) {
this.logger.info('[sale_invoice] trying to write inventory transactions.', {
tenantId,
});
await this.saleReceiptsService.recordInventoryTransactions(
tenantId,
saleReceipt,
true
);
}
/**
* Handles deleting the inventory transactions once the receipt deleted.
*/
@On(events.saleReceipt.onDeleted)
public async handleDeletingInventoryTransactions({
tenantId,
saleReceiptId,
}) {
this.logger.info(
'[sale_invoice] trying to revert inventory transactions.',
{
tenantId,
saleReceiptId,
}
);
await this.saleReceiptsService.revertInventoryTransactions(
tenantId,
saleReceiptId
);
}
}

View File

@@ -0,0 +1,75 @@
import { Container } from 'typedi';
import { On, EventSubscriber } from 'event-dispatch';
import events from 'subscribers/events';
import TenancyService from 'services/Tenancy/TenancyService';
import SalesReceiptService from 'services/Sales/SalesReceipts';
@EventSubscriber()
export default class SaleReceiptSubscriber {
logger: any;
tenancy: TenancyService;
saleReceiptsService: SalesReceiptService;
constructor() {
this.logger = Container.get('logger');
this.tenancy = Container.get(TenancyService);
this.saleReceiptsService = Container.get(SalesReceiptService);
}
/**
* Handles writing sale receipt income journal entries once created.
*/
@On(events.saleReceipt.onCreated)
public async handleWriteReceiptIncomeJournalEntrieOnCreate({
tenantId,
saleReceiptId,
}) {
const { SaleReceipt } = this.tenancy.models(tenantId);
const saleReceiptWithItems = await SaleReceipt.query()
.findById(saleReceiptId)
.withGraphFetched('entries.item');
// Writes the sale receipt income journal entries.
await this.saleReceiptsService.writesIncomeJournalEntries(
tenantId,
saleReceiptWithItems
);
}
/**
* Handles sale receipt revert jouranl entries once be deleted.
*/
@On(events.saleReceipt.onDeleted)
public async handleRevertReceiptJournalEntriesOnDeleted({
tenantId,
saleReceiptId,
}) {
await this.saleReceiptsService.revertReceiptJournalEntries(
tenantId,
saleReceiptId
);
}
/**
* Handles writing sale receipt income journal entries once be edited.
*/
@On(events.saleReceipt.onEdited)
public async handleWriteReceiptIncomeJournalEntrieOnEdited({
tenantId,
saleReceiptId,
}) {
const { SaleReceipt } = this.tenancy.models(tenantId);
const saleReceiptWithItems = await SaleReceipt.query()
.findById(saleReceiptId)
.withGraphFetched('entries.item');
// Writes the sale receipt income journal entries.
await this.saleReceiptsService.writesIncomeJournalEntries(
tenantId,
saleReceiptWithItems,
true
);
}
}

View File

@@ -1,5 +1,5 @@
import { Container } from 'typedi';
import { On, EventSubscriber } from "event-dispatch";
import { On, EventSubscriber } from 'event-dispatch';
import events from 'subscribers/events';
import TenancyService from 'services/Tenancy/TenancyService';
import SettingsService from 'services/Settings/SettingsService';
@@ -15,7 +15,7 @@ export default class SaleReceiptSubscriber {
this.tenancy = Container.get(TenancyService);
this.settingsService = Container.get(SettingsService);
}
/**
* Handle sale receipt increment next number once be created.
*/
@@ -26,4 +26,4 @@ export default class SaleReceiptSubscriber {
group: 'sales_receipts',
});
}
}
}

View File

@@ -1,227 +0,0 @@
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 BillsService from 'services/Purchases/Bills';
import JournalPosterService from 'services/Sales/JournalPosterService';
import ItemsEntriesService from 'services/Items/ItemsEntriesService';
@EventSubscriber()
export default class BillSubscriber {
tenancy: TenancyService;
billsService: BillsService;
logger: any;
journalPosterService: JournalPosterService;
itemsEntriesService: ItemsEntriesService;
/**
* Constructor method.
*/
constructor() {
this.tenancy = Container.get(TenancyService);
this.billsService = Container.get(BillsService);
this.logger = Container.get('logger');
this.journalPosterService = Container.get(JournalPosterService);
this.itemsEntriesService = Container.get(ItemsEntriesService);
}
/**
* Handles vendor balance increment once bill created.
*/
@On(events.bill.onCreated)
async handleVendorBalanceIncrement({ tenantId, billId, bill }) {
const { vendorRepository } = this.tenancy.repositories(tenantId);
// Increments vendor balance.
this.logger.info('[bill] trying to increment vendor balance.', {
tenantId,
billId,
});
await vendorRepository.changeBalance(bill.vendorId, bill.amount);
}
/**
* Handles writing journal entries once bill created.
*/
@On(events.bill.onCreated)
async handlerWriteJournalEntriesOnCreate({ tenantId, bill }) {
// Writes the journal entries for the given bill transaction.
this.logger.info('[bill] writing bill journal entries.', { tenantId });
await this.billsService.recordJournalTransactions(tenantId, bill);
}
/**
* Handles the overwriting journal entries once bill edited.
*/
@On(events.bill.onEdited)
async handleOverwriteJournalEntriesOnEdit({ tenantId, bill }) {
// Overwrite the journal entries for the given bill transaction.
this.logger.info('[bill] overwriting bill journal entries.', { tenantId });
await this.billsService.recordJournalTransactions(tenantId, bill, true);
}
/**
* Handles vendor balance decrement once bill deleted.
*/
@On(events.bill.onDeleted)
async handleVendorBalanceDecrement({ tenantId, billId, oldBill }) {
const { vendorRepository } = this.tenancy.repositories(tenantId);
// Decrements vendor balance.
this.logger.info('[bill] trying to decrement vendor balance.', {
tenantId,
billId,
});
await vendorRepository.changeBalance(oldBill.vendorId, oldBill.amount * -1);
}
/**
* Handles revert journal entries on bill deleted.
*/
@On(events.bill.onDeleted)
async handlerDeleteJournalEntries({ tenantId, billId }) {
// Delete associated bill journal transactions.
this.logger.info('[bill] trying to delete journal entries.', {
tenantId,
billId,
});
await this.journalPosterService.revertJournalTransactions(
tenantId,
billId,
'Bill'
);
}
/**
* Handles vendor balance difference change.
*/
@On(events.bill.onEdited)
async handleVendorBalanceDiffChange({ tenantId, billId, oldBill, bill }) {
const { vendorRepository } = this.tenancy.repositories(tenantId);
// Changes the diff vendor balance between old and new amount.
this.logger.info('[bill[ change vendor the different balance.', {
tenantId,
billId,
});
await vendorRepository.changeDiffBalance(
bill.vendorId,
bill.amount,
oldBill.amount,
oldBill.vendorId
);
}
/**
* Handles writing the inventory transactions once bill created.
*/
@On(events.bill.onCreated)
async handleWritingInventoryTransactions({ tenantId, bill }) {
this.logger.info('[bill] writing the inventory transactions', { tenantId });
this.billsService.recordInventoryTransactions(
tenantId,
bill.id,
bill.billDate
);
}
/**
* Handles the overwriting the inventory transactions once bill edited.
*/
@On(events.bill.onEdited)
async handleOverwritingInventoryTransactions({ tenantId, bill }) {
this.logger.info('[bill] overwriting the inventory transactions.', {
tenantId,
});
this.billsService.recordInventoryTransactions(
tenantId,
bill.id,
bill.billDate,
true
);
}
/**
* Handles the reverting the inventory transactions once the bill deleted.
*/
@On(events.bill.onDeleted)
async handleRevertInventoryTransactions({ tenantId, billId }) {
this.logger.info('[bill] reverting the bill inventory transactions', {
tenantId,
billId,
});
this.billsService.revertInventoryTransactions(tenantId, billId);
}
/**
* Schedules items cost compute jobs once the inventory transactions created
* of the bill transaction.
*/
@On(events.bill.onInventoryTransactionsCreated)
public async handleComputeItemsCosts({ tenantId, billId }) {
this.logger.info('[bill] trying to compute the bill items cost.', {
tenantId,
billId,
});
await this.billsService.scheduleComputeCostByBillId(tenantId, billId);
}
/**
* Handles computes items costs once the inventory transactions deleted.
*/
@On(events.bill.onInventoryTransactionsDeleted)
public async handleComputeCostsOnInventoryTransactionsDeleted({
tenantId,
billId,
oldInventoryTransactions,
}) {
const inventoryItemsIds = map(oldInventoryTransactions, 'itemId');
const startingDates = map(oldInventoryTransactions, 'date');
const startingDate = head(startingDates);
await this.billsService.scheduleComputeCostByItemsIds(
tenantId,
inventoryItemsIds,
startingDate
);
}
/**
* Increments the sale invoice items once the invoice created.
*/
@On(events.bill.onCreated)
public async handleDecrementSaleInvoiceItemsQuantity({ tenantId, bill }) {
await this.itemsEntriesService.incrementItemsEntries(
tenantId,
bill.entries
);
}
/**
* Decrements the sale invoice items once the invoice deleted.
*/
@On(events.bill.onDeleted)
public async handleIncrementSaleInvoiceItemsQuantity({ tenantId, oldBill }) {
await this.itemsEntriesService.decrementItemsQuantity(
tenantId,
oldBill.entries
);
}
/**
* Handle increment/decrement the different items quantity once the sale invoice be edited.
*/
@On(events.bill.onEdited)
public async handleChangeSaleInvoiceItemsQuantityOnEdit({
tenantId,
bill,
oldBill,
}) {
await this.itemsEntriesService.changeItemsQuantity(
tenantId,
bill.entries,
oldBill.entries
);
}
}

View File

@@ -83,8 +83,6 @@ export default {
onDelivered: 'onSaleInvoiceDelivered',
onBulkDelete: 'onSaleInvoiceBulkDeleted',
onPublished: 'onSaleInvoicePublished',
onInventoryTransactionsCreated: 'onInvoiceInventoryTransactionsCreated',
onInventoryTransactionsDeleted: 'onInvoiceInventoryTransactionsDeleted',
},
/**
@@ -128,8 +126,6 @@ export default {
onDeleted: 'onBillDeleted',
onBulkDeleted: 'onBillBulkDeleted',
onPublished: 'onBillPublished',
onInventoryTransactionsCreated: 'onBillInventoryTransactionsCreated',
onInventoryTransactionsDeleted: 'onBillInventoryTransactionsDeleted'
},
/**
@@ -189,6 +185,9 @@ export default {
* Inventory service.
*/
inventory: {
onInventoryTransactionsCreated: 'onInventoryTransactionsCreated',
onInventoryTransactionsDeleted: 'onInventoryTransactionsDeleted',
onComputeItemCostJobScheduled: 'onComputeItemCostJobScheduled',
onComputeItemCostJobStarted: 'onComputeItemCostJobStarted',
onComputeItemCostJobCompleted: 'onComputeItemCostJobCompleted'

View File

@@ -1,5 +1,6 @@
import { Container } from 'typedi';
import { EventSubscriber, On } from 'event-dispatch';
import { map, head } from 'lodash';
import events from 'subscribers/events';
import SaleInvoicesCost from 'services/Sales/SalesInvoicesCost';
@@ -7,16 +8,20 @@ import SaleInvoicesCost from 'services/Sales/SalesInvoicesCost';
export class InventorySubscriber {
depends: number = 0;
startingDate: Date;
saleInvoicesCost: SaleInvoicesCost;
agenda: any;
constructor() {
this.saleInvoicesCost = Container.get(SaleInvoicesCost);
this.agenda = Container.get('agenda');
}
/**
* Handle run writing the journal entries once the compute items jobs completed.
*/
@On(events.inventory.onComputeItemCostJobCompleted)
async onComputeItemCostJobFinished({ itemId, tenantId, startingDate }) {
const saleInvoicesCost = Container.get(SaleInvoicesCost);
const agenda = Container.get('agenda');
const dependsComputeJobs = await agenda.jobs({
const dependsComputeJobs = await this.agenda.jobs({
name: 'compute-item-cost',
nextRunAt: { $ne: null },
'data.tenantId': tenantId,
@@ -25,10 +30,53 @@ export class InventorySubscriber {
if (dependsComputeJobs.length === 0) {
this.startingDate = null;
await saleInvoicesCost.scheduleWriteJournalEntries(
await this.saleInvoicesCost.scheduleWriteJournalEntries(
tenantId,
startingDate
);
}
}
/**
*
*/
@On(events.inventory.onInventoryTransactionsCreated)
async handleScheduleItemsCostOnInventoryTransactionsCreated({
tenantId,
inventoryEntries,
transactionId,
transactionType,
transactionDate,
transactionDirection,
override
}) {
const inventoryItemsIds = map(inventoryEntries, 'itemId');
await this.saleInvoicesCost.scheduleComputeCostByItemsIds(
tenantId,
inventoryItemsIds,
transactionDate,
);
}
/**
* Schedules compute items cost once the inventory transactions deleted.
*/
@On(events.inventory.onInventoryTransactionsDeleted)
async handleScheduleItemsCostOnInventoryTransactionsDeleted({
tenantId,
transactionType,
transactionId,
oldInventoryTransactions
}) {
const inventoryItemsIds = map(oldInventoryTransactions, 'itemId');
const startingDates = map(oldInventoryTransactions, 'date');
const startingDate = head(startingDates);
await this.saleInvoicesCost.scheduleComputeCostByItemsIds(
tenantId,
inventoryItemsIds,
startingDate
);
}
}

View File

@@ -1,330 +0,0 @@
import { Container } from 'typedi';
import { head, map } from 'lodash';
import { On, EventSubscriber } from 'event-dispatch';
import events from 'subscribers/events';
import TenancyService from 'services/Tenancy/TenancyService';
import SettingsService from 'services/Settings/SettingsService';
import SaleEstimateService from 'services/Sales/SalesEstimate';
import SaleInvoicesService from 'services/Sales/SalesInvoices';
import ItemsEntriesService from 'services/Items/ItemsEntriesService';
import SalesInvoicesCost from 'services/Sales/SalesInvoicesCost';
@EventSubscriber()
export default class SaleInvoiceSubscriber {
logger: any;
tenancy: TenancyService;
settingsService: SettingsService;
saleEstimatesService: SaleEstimateService;
saleInvoicesService: SaleInvoicesService;
itemsEntriesService: ItemsEntriesService;
salesInvoicesCost: SalesInvoicesCost;
constructor() {
this.logger = Container.get('logger');
this.tenancy = Container.get(TenancyService);
this.settingsService = Container.get(SettingsService);
this.saleEstimatesService = Container.get(SaleEstimateService);
this.saleInvoicesService = Container.get(SaleInvoicesService);
this.itemsEntriesService = Container.get(ItemsEntriesService);
this.salesInvoicesCost = Container.get(SalesInvoicesCost);
}
/**
* Handles customer balance increment once sale invoice created.
*/
@On(events.saleInvoice.onCreated)
public async handleCustomerBalanceIncrement({
tenantId,
saleInvoice,
saleInvoiceId,
}) {
const { customerRepository } = this.tenancy.repositories(tenantId);
this.logger.info('[sale_invoice] trying to increment customer balance.', {
tenantId,
});
await customerRepository.changeBalance(
saleInvoice.customerId,
saleInvoice.balance
);
}
/**
* Marks the sale estimate as converted from the sale invoice once created.
*/
@On(events.saleInvoice.onCreated)
public async handleMarkEstimateConvert({
tenantId,
saleInvoice,
saleInvoiceId,
}) {
if (saleInvoice.fromEstimateId) {
this.saleEstimatesService.convertEstimateToInvoice(
tenantId,
saleInvoice.fromEstiamteId,
saleInvoiceId
);
}
}
/**
* Handles sale invoice next number increment once invoice created.
*/
@On(events.saleInvoice.onCreated)
public async handleInvoiceNextNumberIncrement({
tenantId,
saleInvoiceId,
saleInvoice,
}) {
await this.settingsService.incrementNextNumber(tenantId, {
key: 'next_number',
group: 'sales_invoices',
});
}
/**
* Handles the writing inventory transactions once the invoice created.
*/
@On(events.saleInvoice.onCreated)
public async handleWritingInventoryTransactions({ tenantId, saleInvoice }) {
this.logger.info('[sale_invoice] trying to write inventory transactions.', {
tenantId,
});
await this.saleInvoicesService.recordInventoryTranscactions(
tenantId,
saleInvoice.id,
saleInvoice.invoiceDate
);
}
/**
* Handles handle write income journal entries of sale invoice.
*/
@On(events.saleInvoice.onCreated)
public async handleWriteInvoiceIncomeJournalEntries({
tenantId,
saleInvoiceId,
saleInvoice,
authorizedUser,
}) {
const { saleInvoiceRepository } = this.tenancy.repositories(tenantId);
const saleInvoiceWithItems = await saleInvoiceRepository.findOneById(
saleInvoiceId,
'entries.item'
);
await this.saleInvoicesService.writesIncomeJournalEntries(
tenantId,
saleInvoiceWithItems
);
}
/**
* Increments the sale invoice items once the invoice created.
*/
@On(events.saleInvoice.onCreated)
public async handleDecrementSaleInvoiceItemsQuantity({
tenantId,
saleInvoice,
}) {
await this.itemsEntriesService.decrementItemsQuantity(
tenantId,
saleInvoice.entries
);
}
/**
* Rewriting the inventory transactions once the sale invoice be edited.
*/
@On(events.saleInvoice.onEdited)
public async handleRewritingInventoryTransactions({ tenantId, saleInvoice }) {
this.logger.info('[sale_invoice] trying to write inventory transactions.', {
tenantId,
});
await this.saleInvoicesService.recordInventoryTranscactions(
tenantId,
saleInvoice.id,
saleInvoice.invoiceDate,
true
);
}
/**
* Handles customer balance diff balnace change once sale invoice edited.
*/
@On(events.saleInvoice.onEdited)
public async onSaleInvoiceEdited({
tenantId,
saleInvoice,
oldSaleInvoice,
saleInvoiceId,
}) {
const { customerRepository } = this.tenancy.repositories(tenantId);
this.logger.info('[sale_invoice] trying to change diff customer balance.', {
tenantId,
});
await customerRepository.changeDiffBalance(
saleInvoice.customerId,
saleInvoice.balance,
oldSaleInvoice.balance,
oldSaleInvoice.customerId
);
}
/**
* Records journal entries of the non-inventory invoice.
*/
@On(events.saleInvoice.onEdited)
public async handleRewriteJournalEntriesOnceInvoiceEdit({
tenantId,
saleInvoiceId,
saleInvoice,
authorizedUser,
}) {
const { saleInvoiceRepository } = this.tenancy.repositories(tenantId);
const saleInvoiceWithItems = await saleInvoiceRepository.findOneById(
saleInvoiceId,
'entries.item'
);
await this.saleInvoicesService.writesIncomeJournalEntries(
tenantId,
saleInvoiceWithItems,
true
);
}
/**
* Handles customer balance decrement once sale invoice deleted.
*/
@On(events.saleInvoice.onDeleted)
public async handleCustomerBalanceDecrement({
tenantId,
saleInvoiceId,
oldSaleInvoice,
}) {
const { customerRepository } = this.tenancy.repositories(tenantId);
this.logger.info('[sale_invoice] trying to decrement customer balance.', {
tenantId,
});
await customerRepository.changeBalance(
oldSaleInvoice.customerId,
oldSaleInvoice.balance * -1
);
}
/**
* Handle reverting journal entries once sale invoice delete.
*/
@On(events.saleInvoice.onDelete)
public async handleRevertingInvoiceJournalEntriesOnDelete({
tenantId,
saleInvoiceId,
}) {
await this.saleInvoicesService.revertInvoiceJournalEntries(
tenantId,
saleInvoiceId,
);
}
/**
* Handles deleting the inventory transactions once the invoice deleted.
*/
@On(events.saleInvoice.onDelete)
public async handleDeletingInventoryTransactions({
tenantId,
saleInvoiceId,
oldSaleInvoice,
}) {
this.logger.info(
'[sale_invoice] trying to revert inventory transactions.',
{
tenantId,
saleInvoiceId,
}
);
await this.saleInvoicesService.revertInventoryTransactions(
tenantId,
saleInvoiceId
);
}
/**
* Schedules compute invoice items cost job.
*/
@On(events.saleInvoice.onInventoryTransactionsCreated)
public async handleComputeCostsOnInventoryTransactionsCreated({
tenantId,
saleInvoiceId,
}) {
this.logger.info(
'[sale_invoice] trying to compute the invoice items cost.',
{
tenantId,
saleInvoiceId,
}
);
await this.salesInvoicesCost.scheduleComputeCostByInvoiceId(
tenantId,
saleInvoiceId
);
}
/**
* Schedules compute items cost once the inventory transactions deleted.
*/
@On(events.saleInvoice.onInventoryTransactionsDeleted)
public async handleComputeCostsOnInventoryTransactionsDeleted({
tenantId,
saleInvoiceId,
oldInventoryTransactions,
}) {
const inventoryItemsIds = map(oldInventoryTransactions, 'itemId');
const startingDates = map(oldInventoryTransactions, 'date');
const startingDate = head(startingDates);
await this.salesInvoicesCost.scheduleComputeCostByItemsIds(
tenantId,
inventoryItemsIds,
startingDate
);
}
/**
* Decrements the sale invoice items once the invoice deleted.
*/
@On(events.saleInvoice.onDeleted)
public async handleIncrementSaleInvoiceItemsQuantity({
tenantId,
oldSaleInvoice,
}) {
await this.itemsEntriesService.incrementItemsEntries(
tenantId,
oldSaleInvoice.entries
);
}
/**
* Handle increment/decrement the different items quantity once the sale invoice be edited.
*/
@On(events.saleInvoice.onEdited)
public async handleChangeSaleInvoiceItemsQuantityOnEdit({
tenantId,
saleInvoice,
oldSaleInvoice,
}) {
await this.itemsEntriesService.changeItemsQuantity(
tenantId,
saleInvoice.entries.map((entry) => ({
...entry,
quantity: entry.quantity * -1,
})),
oldSaleInvoice.entries.map((entry) => ({
...entry,
quantity: entry.quantity * -1,
}))
);
}
}