mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-21 15:20:34 +00:00
fix: writing the bill journal entries.
This commit is contained in:
@@ -197,8 +197,8 @@ export default class BillsController extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
*/
|
*/
|
||||||
async editBill(req: Request, res: Response, next: NextFunction) {
|
async editBill(req: Request, res: Response, next: NextFunction) {
|
||||||
const { id: billId, user } = req.params;
|
const { id: billId } = req.params;
|
||||||
const { tenantId } = req;
|
const { tenantId, user } = req;
|
||||||
const billDTO: IBillEditDTO = this.matchedBodyData(req);
|
const billDTO: IBillEditDTO = this.matchedBodyData(req);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ export interface IBill {
|
|||||||
openedAt: Date | string,
|
openedAt: Date | string,
|
||||||
|
|
||||||
entries: IItemEntry[],
|
entries: IItemEntry[],
|
||||||
|
userId: number,
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface IBillsFilter extends IDynamicListFilterDTO {
|
export interface IBillsFilter extends IDynamicListFilterDTO {
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ interface IJournalTransactionsFilter {
|
|||||||
toAmount: number,
|
toAmount: number,
|
||||||
contactsIds?: number[],
|
contactsIds?: number[],
|
||||||
contactType?: string,
|
contactType?: string,
|
||||||
|
referenceType?: string[],
|
||||||
|
referenceId?: number[],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class AccountTransactionsRepository extends TenantRepository {
|
export default class AccountTransactionsRepository extends TenantRepository {
|
||||||
@@ -42,6 +44,12 @@ export default class AccountTransactionsRepository extends TenantRepository {
|
|||||||
if (filter.contactType) {
|
if (filter.contactType) {
|
||||||
query.where('contact_type', filter.contactType);
|
query.where('contact_type', filter.contactType);
|
||||||
}
|
}
|
||||||
|
if (filter.referenceType && filter.referenceType.length > 0) {
|
||||||
|
query.whereIn('reference_type', filter.referenceType);
|
||||||
|
}
|
||||||
|
if (filter.referenceId && filter.referenceId.length > 0) {
|
||||||
|
query.whereIn('reference_id', filter.referenceId);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -177,7 +177,20 @@ export default class CachableRepository extends EntityRepository{
|
|||||||
*
|
*
|
||||||
* @param {string|number[]} values -
|
* @param {string|number[]} values -
|
||||||
*/
|
*/
|
||||||
async deleteWhereIn(values: string | number[]) {
|
async deleteWhereIn(field: string, values: string | number[]) {
|
||||||
|
const result = await super.deleteWhereIn(field, values);
|
||||||
|
|
||||||
|
// Flushes the repository cache after delete operation.
|
||||||
|
this.flushCache();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string|number[]} values
|
||||||
|
*/
|
||||||
|
async deleteWhereIdIn(values: string | number[]) {
|
||||||
const result = await super.deleteWhereIdIn(values);
|
const result = await super.deleteWhereIdIn(values);
|
||||||
|
|
||||||
// Flushes the repository cache after delete operation.
|
// Flushes the repository cache after delete operation.
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ export default class EntityRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Deletes the given entries in the array on the specific field.
|
||||||
* @param {string} field -
|
* @param {string} field -
|
||||||
* @param {number|string} values -
|
* @param {number|string} values -
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import { sumBy, chain } from 'lodash';
|
import { sumBy, chain } from 'lodash';
|
||||||
|
import moment from 'moment';
|
||||||
|
import { IBill } from 'interfaces';
|
||||||
import JournalPoster from "./JournalPoster";
|
import JournalPoster from "./JournalPoster";
|
||||||
import JournalEntry from "./JournalEntry";
|
import JournalEntry from "./JournalEntry";
|
||||||
import { AccountTransaction } from 'models';
|
import { AccountTransaction } from 'models';
|
||||||
@@ -7,6 +9,7 @@ import {
|
|||||||
IManualJournal,
|
IManualJournal,
|
||||||
IExpense,
|
IExpense,
|
||||||
IExpenseCategory,
|
IExpenseCategory,
|
||||||
|
IItem,
|
||||||
} from 'interfaces';
|
} from 'interfaces';
|
||||||
|
|
||||||
interface IInventoryCostEntity {
|
interface IInventoryCostEntity {
|
||||||
@@ -57,6 +60,68 @@ export default class JournalCommands{
|
|||||||
this.models = this.journal.models;
|
this.models = this.journal.models;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Records the bill journal entries.
|
||||||
|
* @param {IBill} bill
|
||||||
|
* @param {boolean} override - Override the old bill entries.
|
||||||
|
*/
|
||||||
|
async bill(bill: IBill, override: boolean = false): Promise<void> {
|
||||||
|
const { transactionsRepository, accountRepository } = this.repositories;
|
||||||
|
const { Item, ItemEntry } = this.models;
|
||||||
|
|
||||||
|
const entriesItemsIds = bill.entries.map((entry) => entry.itemId);
|
||||||
|
|
||||||
|
// Retrieve the bill transaction items.
|
||||||
|
const storedItems = await Item.query().whereIn('id', entriesItemsIds);
|
||||||
|
|
||||||
|
const storedItemsMap = new Map(storedItems.map((item) => [item.id, item]));
|
||||||
|
const payableAccount = await accountRepository.findOne({ slug: 'accounts-payable' });
|
||||||
|
const formattedDate = moment(bill.billDate).format('YYYY-MM-DD');
|
||||||
|
|
||||||
|
const commonJournalMeta = {
|
||||||
|
debit: 0,
|
||||||
|
credit: 0,
|
||||||
|
referenceId: bill.id,
|
||||||
|
referenceType: 'Bill',
|
||||||
|
date: formattedDate,
|
||||||
|
userId: bill.userId,
|
||||||
|
};
|
||||||
|
// Overrides the old bill entries.
|
||||||
|
if (override) {
|
||||||
|
const entries = await transactionsRepository.journal({
|
||||||
|
referenceType: ['Bill'],
|
||||||
|
referenceId: [bill.id],
|
||||||
|
});
|
||||||
|
this.journal.fromTransactions(entries);
|
||||||
|
this.journal.removeEntries();
|
||||||
|
}
|
||||||
|
const payableEntry = new JournalEntry({
|
||||||
|
...commonJournalMeta,
|
||||||
|
credit: bill.amount,
|
||||||
|
account: payableAccount.id,
|
||||||
|
contactId: bill.vendorId,
|
||||||
|
contactType: 'Vendor',
|
||||||
|
index: 1,
|
||||||
|
});
|
||||||
|
this.journal.credit(payableEntry);
|
||||||
|
|
||||||
|
bill.entries.forEach((entry, index) => {
|
||||||
|
const item: IItem = storedItemsMap.get(entry.itemId);
|
||||||
|
const amount = ItemEntry.calcAmount(entry);
|
||||||
|
|
||||||
|
const debitEntry = new JournalEntry({
|
||||||
|
...commonJournalMeta,
|
||||||
|
debit: amount,
|
||||||
|
account:
|
||||||
|
['inventory'].indexOf(item.type) !== -1
|
||||||
|
? item.inventoryAccountId
|
||||||
|
: item.costAccountId,
|
||||||
|
index: index + 2,
|
||||||
|
});
|
||||||
|
this.journal.debit(debitEntry);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Customer opening balance journals.
|
* Customer opening balance journals.
|
||||||
* @param {number} customerId
|
* @param {number} customerId
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export default class JournalPoster implements IJournalPoster {
|
|||||||
deletedEntriesIds: number[] = [];
|
deletedEntriesIds: number[] = [];
|
||||||
entries: IJournalEntry[] = [];
|
entries: IJournalEntry[] = [];
|
||||||
balancesChange: IAccountsChange = {};
|
balancesChange: IAccountsChange = {};
|
||||||
accountsDepGraph: IAccountsChange = {};
|
accountsDepGraph: IAccountsChange;
|
||||||
|
|
||||||
accountsBalanceTable: { [key: number]: number; } = {};
|
accountsBalanceTable: { [key: number]: number; } = {};
|
||||||
|
|
||||||
@@ -250,12 +250,12 @@ export default class JournalPoster implements IJournalPoster {
|
|||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
public async saveEntries() {
|
public async saveEntries() {
|
||||||
const { AccountTransaction } = this.models;
|
const { transactionsRepository } = this.repositories;
|
||||||
const saveOperations: Promise<void>[] = [];
|
const saveOperations: Promise<void>[] = [];
|
||||||
|
|
||||||
this.entries.forEach((entry) => {
|
this.entries.forEach((entry) => {
|
||||||
const oper = AccountTransaction.query()
|
const oper = transactionsRepository
|
||||||
.insert({
|
.create({
|
||||||
accountId: entry.account,
|
accountId: entry.account,
|
||||||
...omit(entry, ['account']),
|
...omit(entry, ['account']),
|
||||||
});
|
});
|
||||||
@@ -309,12 +309,10 @@ export default class JournalPoster implements IJournalPoster {
|
|||||||
* @return {Promise<void>}
|
* @return {Promise<void>}
|
||||||
*/
|
*/
|
||||||
public async deleteEntries() {
|
public async deleteEntries() {
|
||||||
const { AccountTransaction } = this.models;
|
const { transactionsRepository } = this.repositories;
|
||||||
|
|
||||||
if (this.deletedEntriesIds.length > 0) {
|
if (this.deletedEntriesIds.length > 0) {
|
||||||
await AccountTransaction.query()
|
await transactionsRepository.deleteWhereIdIn(this.deletedEntriesIds);
|
||||||
.whereIn('id', this.deletedEntriesIds)
|
|
||||||
.delete();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,7 +330,6 @@ export default class JournalPoster implements IJournalPoster {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the entries balance change.
|
* Calculates the entries balance change.
|
||||||
* @public
|
* @public
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import {
|
|||||||
import { ServiceError } from 'exceptions';
|
import { ServiceError } from 'exceptions';
|
||||||
import ItemsService from 'services/Items/ItemsService';
|
import ItemsService from 'services/Items/ItemsService';
|
||||||
import ItemsEntriesService from 'services/Items/ItemsEntriesService';
|
import ItemsEntriesService from 'services/Items/ItemsEntriesService';
|
||||||
|
import JournalCommands from 'services/Accounting/JournalCommands';
|
||||||
|
|
||||||
const ERRORS = {
|
const ERRORS = {
|
||||||
BILL_NOT_FOUND: 'BILL_NOT_FOUND',
|
BILL_NOT_FOUND: 'BILL_NOT_FOUND',
|
||||||
@@ -139,8 +140,8 @@ export default class BillsService extends SalesInvoicesCost {
|
|||||||
private async billDTOToModel(
|
private async billDTOToModel(
|
||||||
tenantId: number,
|
tenantId: number,
|
||||||
billDTO: IBillDTO | IBillEditDTO,
|
billDTO: IBillDTO | IBillEditDTO,
|
||||||
oldBill?: IBill,
|
|
||||||
authorizedUser: ISystemUser,
|
authorizedUser: ISystemUser,
|
||||||
|
oldBill?: IBill,
|
||||||
) {
|
) {
|
||||||
const { ItemEntry } = this.tenancy.models(tenantId);
|
const { ItemEntry } = this.tenancy.models(tenantId);
|
||||||
let invLotNumber = oldBill?.invLotNumber;
|
let invLotNumber = oldBill?.invLotNumber;
|
||||||
@@ -156,7 +157,7 @@ export default class BillsService extends SalesInvoicesCost {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
...formatDateFields(
|
...formatDateFields(
|
||||||
omit(billDTO, ['open']),
|
omit(billDTO, ['open', 'entries']),
|
||||||
['billDate', 'dueDate']
|
['billDate', 'dueDate']
|
||||||
),
|
),
|
||||||
amount,
|
amount,
|
||||||
@@ -165,7 +166,6 @@ export default class BillsService extends SalesInvoicesCost {
|
|||||||
reference_type: 'Bill',
|
reference_type: 'Bill',
|
||||||
...omit(entry, ['amount', 'id']),
|
...omit(entry, ['amount', 'id']),
|
||||||
})),
|
})),
|
||||||
|
|
||||||
// Avoid rewrite the open date in edit mode when already opened.
|
// Avoid rewrite the open date in edit mode when already opened.
|
||||||
...(billDTO.open && (!oldBill?.openedAt)) && ({
|
...(billDTO.open && (!oldBill?.openedAt)) && ({
|
||||||
openedAt: moment().toMySqlDateTime(),
|
openedAt: moment().toMySqlDateTime(),
|
||||||
@@ -197,7 +197,7 @@ export default class BillsService extends SalesInvoicesCost {
|
|||||||
const { Bill } = this.tenancy.models(tenantId);
|
const { Bill } = this.tenancy.models(tenantId);
|
||||||
|
|
||||||
this.logger.info('[bill] trying to create a new bill', { tenantId, billDTO });
|
this.logger.info('[bill] trying to create a new bill', { tenantId, billDTO });
|
||||||
const billObj = await this.billDTOToModel(tenantId, billDTO, null, authorizedUser);
|
const billObj = await this.billDTOToModel(tenantId, billDTO, authorizedUser, null);
|
||||||
|
|
||||||
// Retrieve vendor or throw not found service error.
|
// Retrieve vendor or throw not found service error.
|
||||||
await this.getVendorOrThrowError(tenantId, billDTO.vendorId);
|
await this.getVendorOrThrowError(tenantId, billDTO.vendorId);
|
||||||
@@ -253,7 +253,7 @@ export default class BillsService extends SalesInvoicesCost {
|
|||||||
const oldBill = await this.getBillOrThrowError(tenantId, billId);
|
const oldBill = await this.getBillOrThrowError(tenantId, billId);
|
||||||
|
|
||||||
// Transforms the bill DTO object to model object.
|
// Transforms the bill DTO object to model object.
|
||||||
const billObj = await this.billDTOToModel(tenantId, billDTO, oldBill, authorizedUser);
|
const billObj = await this.billDTOToModel(tenantId, billDTO, authorizedUser, oldBill);
|
||||||
|
|
||||||
// Retrieve vendor details or throw not found service error.
|
// Retrieve vendor details or throw not found service error.
|
||||||
await this.getVendorOrThrowError(tenantId, billDTO.vendorId);
|
await this.getVendorOrThrowError(tenantId, billDTO.vendorId);
|
||||||
@@ -342,62 +342,16 @@ export default class BillsService extends SalesInvoicesCost {
|
|||||||
* @param {IBill} bill
|
* @param {IBill} bill
|
||||||
* @param {Integer} billId
|
* @param {Integer} billId
|
||||||
*/
|
*/
|
||||||
public async recordJournalTransactions(tenantId: number, bill: IBill, billId?: number) {
|
public async recordJournalTransactions(
|
||||||
const { AccountTransaction, Item, ItemEntry } = this.tenancy.models(tenantId);
|
tenantId: number,
|
||||||
const { accountRepository } = this.tenancy.repositories(tenantId);
|
bill: IBill,
|
||||||
|
override: boolean = false,
|
||||||
const entriesItemsIds = bill.entries.map((entry) => entry.itemId);
|
) {
|
||||||
const formattedDate = moment(bill.billDate).format('YYYY-MM-DD');
|
|
||||||
|
|
||||||
const storedItems = await Item.query().whereIn('id', entriesItemsIds);
|
|
||||||
|
|
||||||
const storedItemsMap = new Map(storedItems.map((item) => [item.id, item]));
|
|
||||||
const payableAccount = await accountRepository.find({ slug: 'accounts-payable' });
|
|
||||||
|
|
||||||
const journal = new JournalPoster(tenantId);
|
const journal = new JournalPoster(tenantId);
|
||||||
|
const journalCommands = new JournalCommands(journal);
|
||||||
|
|
||||||
const commonJournalMeta = {
|
await journalCommands.bill(bill, override)
|
||||||
debit: 0,
|
|
||||||
credit: 0,
|
|
||||||
referenceId: bill.id,
|
|
||||||
referenceType: 'Bill',
|
|
||||||
date: formattedDate,
|
|
||||||
userId: bill.userId,
|
|
||||||
};
|
|
||||||
if (billId) {
|
|
||||||
const transactions = await AccountTransaction.query()
|
|
||||||
.whereIn('reference_type', ['Bill'])
|
|
||||||
.whereIn('reference_id', [billId])
|
|
||||||
.withGraphFetched('account.type');
|
|
||||||
|
|
||||||
journal.loadEntries(transactions);
|
|
||||||
journal.removeEntries();
|
|
||||||
}
|
|
||||||
const payableEntry = new JournalEntry({
|
|
||||||
...commonJournalMeta,
|
|
||||||
credit: bill.amount,
|
|
||||||
account: payableAccount.id,
|
|
||||||
contactId: bill.vendorId,
|
|
||||||
contactType: 'Vendor',
|
|
||||||
index: 1,
|
|
||||||
});
|
|
||||||
journal.credit(payableEntry);
|
|
||||||
|
|
||||||
bill.entries.forEach((entry, index) => {
|
|
||||||
const item: IItem = storedItemsMap.get(entry.itemId);
|
|
||||||
const amount = ItemEntry.calcAmount(entry);
|
|
||||||
|
|
||||||
const debitEntry = new JournalEntry({
|
|
||||||
...commonJournalMeta,
|
|
||||||
debit: amount,
|
|
||||||
account:
|
|
||||||
['inventory'].indexOf(item.type) !== -1
|
|
||||||
? item.inventoryAccountId
|
|
||||||
: item.costAccountId,
|
|
||||||
index: index + 2,
|
|
||||||
});
|
|
||||||
journal.debit(debitEntry);
|
|
||||||
});
|
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
journal.deleteEntries(),
|
journal.deleteEntries(),
|
||||||
journal.saveEntries(),
|
journal.saveEntries(),
|
||||||
|
|||||||
@@ -37,11 +37,20 @@ export default class BillSubscriber {
|
|||||||
* Handles writing journal entries once bill created.
|
* Handles writing journal entries once bill created.
|
||||||
*/
|
*/
|
||||||
@On(events.bill.onCreated)
|
@On(events.bill.onCreated)
|
||||||
@On(events.bill.onEdited)
|
async handlerWriteJournalEntriesOnCreate({ tenantId, bill }) {
|
||||||
async handlerWriteJournalEntries({ tenantId, billId, bill }) {
|
|
||||||
// Writes the journal entries for the given bill transaction.
|
// Writes the journal entries for the given bill transaction.
|
||||||
this.logger.info('[bill] writing bill journal entries.', { tenantId });
|
this.logger.info('[bill] writing bill journal entries.', { tenantId });
|
||||||
await this.billsService.recordJournalTransactions(tenantId, bill, billId);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { Container } from 'typedi';
|
import { Container } from 'typedi';
|
||||||
import { On, EventSubscriber } from "event-dispatch";
|
import { On, EventSubscriber } from 'event-dispatch';
|
||||||
import events from 'subscribers/events';
|
import events from 'subscribers/events';
|
||||||
import TenancyService from 'services/Tenancy/TenancyService';
|
import TenancyService from 'services/Tenancy/TenancyService';
|
||||||
import SettingsService from 'services/Settings/SettingsService';
|
import SettingsService from 'services/Settings/SettingsService';
|
||||||
import SaleEstimateService from 'services/Sales/SalesEstimate';
|
import SaleEstimateService from 'services/Sales/SalesEstimate';
|
||||||
|
|
||||||
@EventSubscriber()
|
@EventSubscriber()
|
||||||
export default class SaleInvoiceSubscriber {
|
export default class SaleInvoiceSubscriber {
|
||||||
logger: any;
|
logger: any;
|
||||||
@@ -22,23 +23,36 @@ export default class SaleInvoiceSubscriber {
|
|||||||
* Handles customer balance increment once sale invoice created.
|
* Handles customer balance increment once sale invoice created.
|
||||||
*/
|
*/
|
||||||
@On(events.saleInvoice.onCreated)
|
@On(events.saleInvoice.onCreated)
|
||||||
public async handleCustomerBalanceIncrement({ tenantId, saleInvoice, saleInvoiceId }) {
|
public async handleCustomerBalanceIncrement({
|
||||||
|
tenantId,
|
||||||
|
saleInvoice,
|
||||||
|
saleInvoiceId,
|
||||||
|
}) {
|
||||||
const { customerRepository } = this.tenancy.repositories(tenantId);
|
const { customerRepository } = this.tenancy.repositories(tenantId);
|
||||||
|
|
||||||
this.logger.info('[sale_invoice] trying to increment customer balance.', { tenantId });
|
this.logger.info('[sale_invoice] trying to increment customer balance.', {
|
||||||
await customerRepository.changeBalance(saleInvoice.customerId, saleInvoice.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)
|
@On(events.saleInvoice.onCreated)
|
||||||
public async handleMarkEstimateConvert({ tenantId, saleInvoice, saleInvoiceId }) {
|
public async handleMarkEstimateConvert({
|
||||||
if (saleInvoice.fromEstiamteId) {
|
tenantId,
|
||||||
|
saleInvoice,
|
||||||
|
saleInvoiceId,
|
||||||
|
}) {
|
||||||
|
if (saleInvoice.fromEstimateId) {
|
||||||
this.saleEstimatesService.convertEstimateToInvoice(
|
this.saleEstimatesService.convertEstimateToInvoice(
|
||||||
tenantId,
|
tenantId,
|
||||||
saleInvoice.fromEstiamteId,
|
saleInvoice.fromEstiamteId,
|
||||||
saleInvoiceId,
|
saleInvoiceId
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,29 +61,42 @@ export default class SaleInvoiceSubscriber {
|
|||||||
* Handles customer balance diff balnace change once sale invoice edited.
|
* Handles customer balance diff balnace change once sale invoice edited.
|
||||||
*/
|
*/
|
||||||
@On(events.saleInvoice.onEdited)
|
@On(events.saleInvoice.onEdited)
|
||||||
public async onSaleInvoiceEdited({ tenantId, saleInvoice, oldSaleInvoice, saleInvoiceId }) {
|
public async onSaleInvoiceEdited({
|
||||||
|
tenantId,
|
||||||
|
saleInvoice,
|
||||||
|
oldSaleInvoice,
|
||||||
|
saleInvoiceId,
|
||||||
|
}) {
|
||||||
const { customerRepository } = this.tenancy.repositories(tenantId);
|
const { customerRepository } = this.tenancy.repositories(tenantId);
|
||||||
|
|
||||||
this.logger.info('[sale_invoice] trying to change diff customer balance.', { tenantId });
|
this.logger.info('[sale_invoice] trying to change diff customer balance.', {
|
||||||
|
tenantId,
|
||||||
|
});
|
||||||
await customerRepository.changeDiffBalance(
|
await customerRepository.changeDiffBalance(
|
||||||
saleInvoice.customerId,
|
saleInvoice.customerId,
|
||||||
saleInvoice.balance,
|
saleInvoice.balance,
|
||||||
oldSaleInvoice.balance,
|
oldSaleInvoice.balance,
|
||||||
oldSaleInvoice.customerId,
|
oldSaleInvoice.customerId
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles customer balance decrement once sale invoice deleted.
|
* Handles customer balance decrement once sale invoice deleted.
|
||||||
*/
|
*/
|
||||||
@On(events.saleInvoice.onDeleted)
|
@On(events.saleInvoice.onDeleted)
|
||||||
public async handleCustomerBalanceDecrement({ tenantId, saleInvoiceId, oldSaleInvoice }) {
|
public async handleCustomerBalanceDecrement({
|
||||||
|
tenantId,
|
||||||
|
saleInvoiceId,
|
||||||
|
oldSaleInvoice,
|
||||||
|
}) {
|
||||||
const { customerRepository } = this.tenancy.repositories(tenantId);
|
const { customerRepository } = this.tenancy.repositories(tenantId);
|
||||||
|
|
||||||
this.logger.info('[sale_invoice] trying to decrement customer balance.', { tenantId });
|
this.logger.info('[sale_invoice] trying to decrement customer balance.', {
|
||||||
await customerRepository.changeBalance(
|
tenantId,
|
||||||
|
});
|
||||||
|
await customerRepository.changeBalance(
|
||||||
oldSaleInvoice.customerId,
|
oldSaleInvoice.customerId,
|
||||||
oldSaleInvoice.balance * -1,
|
oldSaleInvoice.balance * -1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,10 +104,14 @@ export default class SaleInvoiceSubscriber {
|
|||||||
* Handles sale invoice next number increment once invoice created.
|
* Handles sale invoice next number increment once invoice created.
|
||||||
*/
|
*/
|
||||||
@On(events.saleInvoice.onCreated)
|
@On(events.saleInvoice.onCreated)
|
||||||
public async handleInvoiceNextNumberIncrement({ tenantId, saleInvoiceId, saleInvoice }) {
|
public async handleInvoiceNextNumberIncrement({
|
||||||
|
tenantId,
|
||||||
|
saleInvoiceId,
|
||||||
|
saleInvoice,
|
||||||
|
}) {
|
||||||
await this.settingsService.incrementNextNumber(tenantId, {
|
await this.settingsService.incrementNextNumber(tenantId, {
|
||||||
key: 'next_number',
|
key: 'next_number',
|
||||||
group: 'sales_invoices',
|
group: 'sales_invoices',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user