mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 12:50:38 +00:00
refactor: migrate ledger writer to nestjs
This commit is contained in:
@@ -1,3 +1,14 @@
|
||||
export const OtherExpensesAccount = {
|
||||
name: 'Other Expenses',
|
||||
slug: 'other-expenses',
|
||||
account_type: 'other-expense',
|
||||
code: '40011',
|
||||
description: '',
|
||||
active: 1,
|
||||
index: 1,
|
||||
predefined: 1,
|
||||
};
|
||||
|
||||
export const TaxPayableAccount = {
|
||||
name: 'Tax Payable',
|
||||
slug: 'tax-payable',
|
||||
@@ -42,6 +53,36 @@ export const StripeClearingAccount = {
|
||||
predefined: true,
|
||||
};
|
||||
|
||||
export const DiscountExpenseAccount = {
|
||||
name: 'Discount',
|
||||
slug: 'discount',
|
||||
account_type: 'other-income',
|
||||
code: '40008',
|
||||
active: true,
|
||||
index: 1,
|
||||
predefined: true,
|
||||
};
|
||||
|
||||
export const PurchaseDiscountAccount = {
|
||||
name: 'Purchase Discount',
|
||||
slug: 'purchase-discount',
|
||||
account_type: 'other-expense',
|
||||
code: '40009',
|
||||
active: true,
|
||||
index: 1,
|
||||
predefined: true,
|
||||
};
|
||||
|
||||
export const OtherChargesAccount = {
|
||||
name: 'Other Charges',
|
||||
slug: 'other-charges',
|
||||
account_type: 'other-income',
|
||||
code: '40010',
|
||||
active: true,
|
||||
index: 1,
|
||||
predefined: true,
|
||||
};
|
||||
|
||||
export const SeedAccounts = [
|
||||
{
|
||||
name: 'Bank Account',
|
||||
@@ -231,6 +272,7 @@ export const SeedAccounts = [
|
||||
},
|
||||
|
||||
// Expenses
|
||||
OtherExpensesAccount,
|
||||
{
|
||||
name: 'Other Expenses',
|
||||
slug: 'other-expenses',
|
||||
@@ -358,6 +400,9 @@ export const SeedAccounts = [
|
||||
},
|
||||
UnearnedRevenueAccount,
|
||||
PrepardExpenses,
|
||||
DiscountExpenseAccount,
|
||||
PurchaseDiscountAccount,
|
||||
OtherChargesAccount,
|
||||
];
|
||||
|
||||
export const ACCOUNT_TYPE = {
|
||||
|
||||
@@ -13,7 +13,6 @@ import { TransformerInjectable } from '../Transformer/TransformerInjectable.serv
|
||||
import { ActivateAccount } from './ActivateAccount.service';
|
||||
import { GetAccountTypesService } from './GetAccountTypes.service';
|
||||
import { GetAccountTransactionsService } from './GetAccountTransactions.service';
|
||||
// import { EditAccount } from './EditAccount.service';
|
||||
// import { GetAccountsService } from './GetAccounts.service';
|
||||
|
||||
@Module({
|
||||
|
||||
@@ -6,7 +6,11 @@ import { Account } from '../models/Account.model';
|
||||
import { I18nService } from 'nestjs-i18n';
|
||||
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
|
||||
import {
|
||||
DiscountExpenseAccount,
|
||||
OtherChargesAccount,
|
||||
OtherExpensesAccount,
|
||||
PrepardExpenses,
|
||||
PurchaseDiscountAccount,
|
||||
StripeClearingAccount,
|
||||
TaxPayableAccount,
|
||||
UnearnedRevenueAccount,
|
||||
@@ -371,7 +375,6 @@ export class AccountRepository extends TenantRepository {
|
||||
currencyCode: tenantMeta.baseCurrency,
|
||||
...extraAttrs,
|
||||
};
|
||||
|
||||
let result = await this.model
|
||||
.query(trx)
|
||||
.findOne({ slug: OtherExpensesAccount.slug, ..._extraAttrs });
|
||||
|
||||
@@ -12,8 +12,13 @@ import { TenancyContext } from '../Tenancy/TenancyContext.service';
|
||||
import { BranchTransactionDTOTransformer } from '../Branches/integrations/BranchTransactionDTOTransform';
|
||||
import { BranchesSettingsService } from '../Branches/BranchesSettings';
|
||||
import { BillPaymentsController } from './BillPayments.controller';
|
||||
import { BillPaymentGLEntries } from './commands/BillPaymentGLEntries';
|
||||
import { BillPaymentGLEntriesSubscriber } from './subscribers/BillPaymentGLEntriesSubscriber';
|
||||
import { LedgerModule } from '../Ledger/Ledger.module';
|
||||
import { AccountsModule } from '../Accounts/Accounts.module';
|
||||
|
||||
@Module({
|
||||
imports: [LedgerModule, AccountsModule],
|
||||
providers: [
|
||||
BillPaymentsApplication,
|
||||
CreateBillPaymentService,
|
||||
@@ -27,6 +32,8 @@ import { BillPaymentsController } from './BillPayments.controller';
|
||||
BranchTransactionDTOTransformer,
|
||||
BranchesSettingsService,
|
||||
TenancyContext,
|
||||
BillPaymentGLEntries,
|
||||
BillPaymentGLEntriesSubscriber,
|
||||
],
|
||||
exports: [BillPaymentValidators],
|
||||
controllers: [BillPaymentsController],
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
import { sumBy } from 'lodash';
|
||||
import { BillPayment } from '../models/BillPayment';
|
||||
import { AccountNormal } from '@/interfaces/Account';
|
||||
import { ILedgerEntry } from '@/modules/Ledger/types/Ledger.types';
|
||||
import { Ledger } from '@/modules/Ledger/Ledger';
|
||||
|
||||
export class BillPaymentGL {
|
||||
private billPayment: BillPayment;
|
||||
private APAccountId: number;
|
||||
private gainLossAccountId: number;
|
||||
private baseCurrency: string;
|
||||
|
||||
constructor(billPayment: BillPayment) {
|
||||
this.billPayment = billPayment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the A/P account ID.
|
||||
* @param {number} APAccountId -
|
||||
* @returns {BillPaymentGL}
|
||||
*/
|
||||
setAPAccountId(APAccountId: number) {
|
||||
this.APAccountId = APAccountId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the gain/loss account ID.
|
||||
* @param {number} gainLossAccountId -
|
||||
* @returns {BillPaymentGL}
|
||||
*/
|
||||
setGainLossAccountId(gainLossAccountId: number) {
|
||||
this.gainLossAccountId = gainLossAccountId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the base currency.
|
||||
* @param {string} baseCurrency -
|
||||
* @returns {BillPaymentGL}
|
||||
*/
|
||||
setBaseCurrency(baseCurrency: string) {
|
||||
this.baseCurrency = baseCurrency;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the payment common entry.
|
||||
*/
|
||||
private get paymentCommonEntry() {
|
||||
const formattedDate = moment(this.billPayment.paymentDate).format(
|
||||
'YYYY-MM-DD',
|
||||
);
|
||||
|
||||
return {
|
||||
debit: 0,
|
||||
credit: 0,
|
||||
|
||||
exchangeRate: this.billPayment.exchangeRate,
|
||||
currencyCode: this.billPayment.currencyCode,
|
||||
|
||||
transactionId: this.billPayment.id,
|
||||
transactionType: 'BillPayment',
|
||||
|
||||
transactionNumber: this.billPayment.paymentNumber,
|
||||
referenceNumber: this.billPayment.reference,
|
||||
|
||||
date: formattedDate,
|
||||
createdAt: this.billPayment.createdAt,
|
||||
|
||||
branchId: this.billPayment.branchId,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the payment total exchange gain/loss.
|
||||
* @param {IBillPayment} paymentReceive - Payment receive with entries.
|
||||
* @returns {number}
|
||||
*/
|
||||
private get paymentExGainOrLoss(): number {
|
||||
return sumBy(this.billPayment.entries, (entry) => {
|
||||
const paymentLocalAmount =
|
||||
entry.paymentAmount * this.billPayment.exchangeRate;
|
||||
const invoicePayment = entry.paymentAmount * entry.bill.exchangeRate;
|
||||
|
||||
return invoicePayment - paymentLocalAmount;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the payment exchange gain/loss entries.
|
||||
* @returns {ILedgerEntry[]}
|
||||
*/
|
||||
private get paymentExGainOrLossEntries(): ILedgerEntry[] {
|
||||
const commonEntry = this.paymentCommonEntry;
|
||||
const totalExGainOrLoss = this.paymentExGainOrLoss;
|
||||
const absExGainOrLoss = Math.abs(totalExGainOrLoss);
|
||||
|
||||
return totalExGainOrLoss
|
||||
? [
|
||||
{
|
||||
...commonEntry,
|
||||
currencyCode: this.baseCurrency,
|
||||
exchangeRate: 1,
|
||||
credit: totalExGainOrLoss > 0 ? absExGainOrLoss : 0,
|
||||
debit: totalExGainOrLoss < 0 ? absExGainOrLoss : 0,
|
||||
accountId: this.gainLossAccountId,
|
||||
index: 2,
|
||||
indexGroup: 20,
|
||||
accountNormal: AccountNormal.DEBIT,
|
||||
},
|
||||
{
|
||||
...commonEntry,
|
||||
currencyCode: this.baseCurrency,
|
||||
exchangeRate: 1,
|
||||
debit: totalExGainOrLoss > 0 ? absExGainOrLoss : 0,
|
||||
credit: totalExGainOrLoss < 0 ? absExGainOrLoss : 0,
|
||||
accountId: this.APAccountId,
|
||||
index: 3,
|
||||
accountNormal: AccountNormal.DEBIT,
|
||||
},
|
||||
]
|
||||
: [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the payment deposit GL entry.
|
||||
* @param {IBillPayment} billPayment
|
||||
* @returns {ILedgerEntry}
|
||||
*/
|
||||
private get paymentGLEntry(): ILedgerEntry {
|
||||
const commonEntry = this.paymentCommonEntry;
|
||||
|
||||
return {
|
||||
...commonEntry,
|
||||
credit: this.billPayment.localAmount,
|
||||
accountId: this.billPayment.paymentAccountId,
|
||||
accountNormal: AccountNormal.DEBIT,
|
||||
index: 2,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the payment GL payable entry.
|
||||
* @returns {ILedgerEntry}
|
||||
*/
|
||||
private get paymentGLPayableEntry(): ILedgerEntry {
|
||||
const commonEntry = this.paymentCommonEntry;
|
||||
|
||||
return {
|
||||
...commonEntry,
|
||||
exchangeRate: this.billPayment.exchangeRate,
|
||||
debit: this.billPayment.localAmount,
|
||||
contactId: this.billPayment.vendorId,
|
||||
accountId: this.APAccountId,
|
||||
accountNormal: AccountNormal.CREDIT,
|
||||
index: 1,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the payment GL entries.
|
||||
* @param {IBillPayment} billPayment
|
||||
* @param {number} APAccountId
|
||||
* @returns {ILedgerEntry[]}
|
||||
*/
|
||||
private get paymentGLEntries(): ILedgerEntry[] {
|
||||
// Retrieves the payment deposit entry.
|
||||
const paymentEntry = this.paymentGLEntry;
|
||||
|
||||
// Retrieves the payment debit A/R entry.
|
||||
const payableEntry = this.paymentGLPayableEntry;
|
||||
|
||||
// Retrieves the exchange gain/loss entries.
|
||||
const exGainLossEntries = this.paymentExGainOrLossEntries;
|
||||
|
||||
return [paymentEntry, payableEntry, ...exGainLossEntries];
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the bill payment ledger.
|
||||
* @param {IBillPayment} billPayment
|
||||
* @param {number} APAccountId
|
||||
* @returns {Ledger}
|
||||
*/
|
||||
public getBillPaymentLedger(): Ledger {
|
||||
const entries = this.paymentGLEntries;
|
||||
|
||||
return new Ledger(entries);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,277 +1,99 @@
|
||||
// import moment from 'moment';
|
||||
// import { sumBy } from 'lodash';
|
||||
// import { Service, Inject } from 'typedi';
|
||||
// import { Knex } from 'knex';
|
||||
// import { AccountNormal, IBillPayment, ILedgerEntry } from '@/interfaces';
|
||||
// import Ledger from '@/services/Accounting/Ledger';
|
||||
// import LedgerStorageService from '@/services/Accounting/LedgerStorageService';
|
||||
// import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||
// import { TenantMetadata } from '@/system/models';
|
||||
import { Knex } from 'knex';
|
||||
import { BillPaymentGL } from './BillPaymentGL';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { LedgerStorageService } from '@/modules/Ledger/LedgerStorage.service';
|
||||
import { Account } from '@/modules/Accounts/models/Account.model';
|
||||
import { BillPayment } from '../models/BillPayment';
|
||||
import { AccountRepository } from '@/modules/Accounts/repositories/Account.repository';
|
||||
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
|
||||
|
||||
// @Service()
|
||||
// export class BillPaymentGLEntries {
|
||||
// @Inject()
|
||||
// private tenancy: HasTenancyService;
|
||||
@Injectable()
|
||||
export class BillPaymentGLEntries {
|
||||
constructor(
|
||||
private readonly ledgerStorage: LedgerStorageService,
|
||||
private readonly accountRepository: AccountRepository,
|
||||
private readonly tenancyContext: TenancyContext,
|
||||
|
||||
// @Inject()
|
||||
// private ledgerStorage: LedgerStorageService;
|
||||
@Inject(BillPayment.name)
|
||||
private readonly billPaymentModel: typeof BillPayment,
|
||||
|
||||
// /**
|
||||
// * Creates a bill payment GL entries.
|
||||
// * @param {number} tenantId
|
||||
// * @param {number} billPaymentId
|
||||
// * @param {Knex.Transaction} trx
|
||||
// */
|
||||
// public writePaymentGLEntries = async (
|
||||
// tenantId: number,
|
||||
// billPaymentId: number,
|
||||
// trx?: Knex.Transaction
|
||||
// ): Promise<void> => {
|
||||
// const { accountRepository } = this.tenancy.repositories(tenantId);
|
||||
// const { BillPayment, Account } = this.tenancy.models(tenantId);
|
||||
@Inject(Account.name)
|
||||
private readonly accountModel: typeof Account,
|
||||
) {}
|
||||
|
||||
// // Retrieves the bill payment details with associated entries.
|
||||
// const payment = await BillPayment.query(trx)
|
||||
// .findById(billPaymentId)
|
||||
// .withGraphFetched('entries.bill');
|
||||
/**
|
||||
* Creates a bill payment GL entries.
|
||||
* @param {number} tenantId
|
||||
* @param {number} billPaymentId
|
||||
* @param {Knex.Transaction} trx
|
||||
*/
|
||||
public writePaymentGLEntries = async (
|
||||
billPaymentId: number,
|
||||
trx?: Knex.Transaction,
|
||||
): Promise<void> => {
|
||||
// Retrieves the bill payment details with associated entries.
|
||||
const payment = await this.billPaymentModel
|
||||
.query(trx)
|
||||
.findById(billPaymentId)
|
||||
.withGraphFetched('entries.bill');
|
||||
|
||||
// // Retrieves the given tenant metadata.
|
||||
// const tenantMeta = await TenantMetadata.query().findOne({ tenantId });
|
||||
// Retrieves the given tenant metadata.
|
||||
const tenantMeta = await this.tenancyContext.getTenantMetadata();
|
||||
|
||||
// // Finds or creates a new A/P account of the given currency.
|
||||
// const APAccount = await accountRepository.findOrCreateAccountsPayable(
|
||||
// payment.currencyCode,
|
||||
// {},
|
||||
// trx
|
||||
// );
|
||||
// // Exchange gain or loss account.
|
||||
// const EXGainLossAccount = await Account.query(trx).modify(
|
||||
// 'findBySlug',
|
||||
// 'exchange-grain-loss'
|
||||
// );
|
||||
// // Retrieves the bill payment ledger.
|
||||
// const ledger = this.getBillPaymentLedger(
|
||||
// payment,
|
||||
// APAccount.id,
|
||||
// EXGainLossAccount.id,
|
||||
// tenantMeta.baseCurrency
|
||||
// );
|
||||
// // Commits the ledger on the storage.
|
||||
// await this.ledgerStorage.commit(tenantId, ledger, trx);
|
||||
// };
|
||||
// Finds or creates a new A/P account of the given currency.
|
||||
const APAccount = await this.accountRepository.findOrCreateAccountsPayable(
|
||||
payment.currencyCode,
|
||||
{},
|
||||
trx,
|
||||
);
|
||||
// Exchange gain or loss account.
|
||||
const EXGainLossAccount = await this.accountModel
|
||||
.query(trx)
|
||||
.modify('findBySlug', 'exchange-grain-loss')
|
||||
.first();
|
||||
|
||||
// /**
|
||||
// * Rewrites the bill payment GL entries.
|
||||
// * @param {number} tenantId
|
||||
// * @param {number} billPaymentId
|
||||
// * @param {Knex.Transaction} trx
|
||||
// */
|
||||
// public rewritePaymentGLEntries = async (
|
||||
// tenantId: number,
|
||||
// billPaymentId: number,
|
||||
// trx?: Knex.Transaction
|
||||
// ): Promise<void> => {
|
||||
// // Revert payment GL entries.
|
||||
// await this.revertPaymentGLEntries(tenantId, billPaymentId, trx);
|
||||
// Retrieves the bill payment ledger.
|
||||
const ledger = new BillPaymentGL(payment)
|
||||
.setAPAccountId(APAccount.id)
|
||||
.setGainLossAccountId(EXGainLossAccount.id)
|
||||
.setBaseCurrency(tenantMeta.baseCurrency)
|
||||
.getBillPaymentLedger();
|
||||
|
||||
// // Write payment GL entries.
|
||||
// await this.writePaymentGLEntries(tenantId, billPaymentId, trx);
|
||||
// };
|
||||
// Commits the ledger on the storage.
|
||||
await this.ledgerStorage.commit(ledger, trx);
|
||||
};
|
||||
|
||||
// /**
|
||||
// * Reverts the bill payment GL entries.
|
||||
// * @param {number} tenantId
|
||||
// * @param {number} billPaymentId
|
||||
// * @param {Knex.Transaction} trx
|
||||
// */
|
||||
// public revertPaymentGLEntries = async (
|
||||
// tenantId: number,
|
||||
// billPaymentId: number,
|
||||
// trx?: Knex.Transaction
|
||||
// ): Promise<void> => {
|
||||
// await this.ledgerStorage.deleteByReference(
|
||||
// tenantId,
|
||||
// billPaymentId,
|
||||
// 'BillPayment',
|
||||
// trx
|
||||
// );
|
||||
// };
|
||||
/**
|
||||
* Rewrites the bill payment GL entries.
|
||||
* @param {number} tenantId
|
||||
* @param {number} billPaymentId
|
||||
* @param {Knex.Transaction} trx
|
||||
*/
|
||||
public rewritePaymentGLEntries = async (
|
||||
billPaymentId: number,
|
||||
trx?: Knex.Transaction,
|
||||
): Promise<void> => {
|
||||
// Revert payment GL entries.
|
||||
await this.revertPaymentGLEntries(billPaymentId, trx);
|
||||
|
||||
// /**
|
||||
// * Retrieves the payment common entry.
|
||||
// * @param {IBillPayment} billPayment
|
||||
// * @returns {}
|
||||
// */
|
||||
// private getPaymentCommonEntry = (billPayment: IBillPayment) => {
|
||||
// const formattedDate = moment(billPayment.paymentDate).format('YYYY-MM-DD');
|
||||
// Write payment GL entries.
|
||||
await this.writePaymentGLEntries(billPaymentId, trx);
|
||||
};
|
||||
|
||||
// return {
|
||||
// debit: 0,
|
||||
// credit: 0,
|
||||
|
||||
// exchangeRate: billPayment.exchangeRate,
|
||||
// currencyCode: billPayment.currencyCode,
|
||||
|
||||
// transactionId: billPayment.id,
|
||||
// transactionType: 'BillPayment',
|
||||
|
||||
// transactionNumber: billPayment.paymentNumber,
|
||||
// referenceNumber: billPayment.reference,
|
||||
|
||||
// date: formattedDate,
|
||||
// createdAt: billPayment.createdAt,
|
||||
|
||||
// branchId: billPayment.branchId,
|
||||
// };
|
||||
// };
|
||||
|
||||
// /**
|
||||
// * Calculates the payment total exchange gain/loss.
|
||||
// * @param {IBillPayment} paymentReceive - Payment receive with entries.
|
||||
// * @returns {number}
|
||||
// */
|
||||
// private getPaymentExGainOrLoss = (billPayment: IBillPayment): number => {
|
||||
// return sumBy(billPayment.entries, (entry) => {
|
||||
// const paymentLocalAmount = entry.paymentAmount * billPayment.exchangeRate;
|
||||
// const invoicePayment = entry.paymentAmount * entry.bill.exchangeRate;
|
||||
|
||||
// return invoicePayment - paymentLocalAmount;
|
||||
// });
|
||||
// };
|
||||
|
||||
// /**
|
||||
// * Retrieves the payment exchange gain/loss entries.
|
||||
// * @param {IBillPayment} billPayment -
|
||||
// * @param {number} APAccountId -
|
||||
// * @param {number} gainLossAccountId -
|
||||
// * @param {string} baseCurrency -
|
||||
// * @returns {ILedgerEntry[]}
|
||||
// */
|
||||
// private getPaymentExGainOrLossEntries = (
|
||||
// billPayment: IBillPayment,
|
||||
// APAccountId: number,
|
||||
// gainLossAccountId: number,
|
||||
// baseCurrency: string
|
||||
// ): ILedgerEntry[] => {
|
||||
// const commonEntry = this.getPaymentCommonEntry(billPayment);
|
||||
// const totalExGainOrLoss = this.getPaymentExGainOrLoss(billPayment);
|
||||
// const absExGainOrLoss = Math.abs(totalExGainOrLoss);
|
||||
|
||||
// return totalExGainOrLoss
|
||||
// ? [
|
||||
// {
|
||||
// ...commonEntry,
|
||||
// currencyCode: baseCurrency,
|
||||
// exchangeRate: 1,
|
||||
// credit: totalExGainOrLoss > 0 ? absExGainOrLoss : 0,
|
||||
// debit: totalExGainOrLoss < 0 ? absExGainOrLoss : 0,
|
||||
// accountId: gainLossAccountId,
|
||||
// index: 2,
|
||||
// indexGroup: 20,
|
||||
// accountNormal: AccountNormal.DEBIT,
|
||||
// },
|
||||
// {
|
||||
// ...commonEntry,
|
||||
// currencyCode: baseCurrency,
|
||||
// exchangeRate: 1,
|
||||
// debit: totalExGainOrLoss > 0 ? absExGainOrLoss : 0,
|
||||
// credit: totalExGainOrLoss < 0 ? absExGainOrLoss : 0,
|
||||
// accountId: APAccountId,
|
||||
// index: 3,
|
||||
// accountNormal: AccountNormal.DEBIT,
|
||||
// },
|
||||
// ]
|
||||
// : [];
|
||||
// };
|
||||
|
||||
// /**
|
||||
// * Retrieves the payment deposit GL entry.
|
||||
// * @param {IBillPayment} billPayment
|
||||
// * @returns {ILedgerEntry}
|
||||
// */
|
||||
// private getPaymentGLEntry = (billPayment: IBillPayment): ILedgerEntry => {
|
||||
// const commonEntry = this.getPaymentCommonEntry(billPayment);
|
||||
|
||||
// return {
|
||||
// ...commonEntry,
|
||||
// credit: billPayment.localAmount,
|
||||
// accountId: billPayment.paymentAccountId,
|
||||
// accountNormal: AccountNormal.DEBIT,
|
||||
// index: 2,
|
||||
// };
|
||||
// };
|
||||
|
||||
// /**
|
||||
// * Retrieves the payment GL payable entry.
|
||||
// * @param {IBillPayment} billPayment
|
||||
// * @param {number} APAccountId
|
||||
// * @returns {ILedgerEntry}
|
||||
// */
|
||||
// private getPaymentGLPayableEntry = (
|
||||
// billPayment: IBillPayment,
|
||||
// APAccountId: number
|
||||
// ): ILedgerEntry => {
|
||||
// const commonEntry = this.getPaymentCommonEntry(billPayment);
|
||||
|
||||
// return {
|
||||
// ...commonEntry,
|
||||
// exchangeRate: billPayment.exchangeRate,
|
||||
// debit: billPayment.localAmount,
|
||||
// contactId: billPayment.vendorId,
|
||||
// accountId: APAccountId,
|
||||
// accountNormal: AccountNormal.CREDIT,
|
||||
// index: 1,
|
||||
// };
|
||||
// };
|
||||
|
||||
// /**
|
||||
// * Retrieves the payment GL entries.
|
||||
// * @param {IBillPayment} billPayment
|
||||
// * @param {number} APAccountId
|
||||
// * @returns {ILedgerEntry[]}
|
||||
// */
|
||||
// private getPaymentGLEntries = (
|
||||
// billPayment: IBillPayment,
|
||||
// APAccountId: number,
|
||||
// gainLossAccountId: number,
|
||||
// baseCurrency: string
|
||||
// ): ILedgerEntry[] => {
|
||||
// // Retrieves the payment deposit entry.
|
||||
// const paymentEntry = this.getPaymentGLEntry(billPayment);
|
||||
|
||||
// // Retrieves the payment debit A/R entry.
|
||||
// const payableEntry = this.getPaymentGLPayableEntry(
|
||||
// billPayment,
|
||||
// APAccountId
|
||||
// );
|
||||
// // Retrieves the exchange gain/loss entries.
|
||||
// const exGainLossEntries = this.getPaymentExGainOrLossEntries(
|
||||
// billPayment,
|
||||
// APAccountId,
|
||||
// gainLossAccountId,
|
||||
// baseCurrency
|
||||
// );
|
||||
// return [paymentEntry, payableEntry, ...exGainLossEntries];
|
||||
// };
|
||||
|
||||
// /**
|
||||
// * Retrieves the bill payment ledger.
|
||||
// * @param {IBillPayment} billPayment
|
||||
// * @param {number} APAccountId
|
||||
// * @returns {Ledger}
|
||||
// */
|
||||
// private getBillPaymentLedger = (
|
||||
// billPayment: IBillPayment,
|
||||
// APAccountId: number,
|
||||
// gainLossAccountId: number,
|
||||
// baseCurrency: string
|
||||
// ): Ledger => {
|
||||
// const entries = this.getPaymentGLEntries(
|
||||
// billPayment,
|
||||
// APAccountId,
|
||||
// gainLossAccountId,
|
||||
// baseCurrency
|
||||
// );
|
||||
// return new Ledger(entries);
|
||||
// };
|
||||
// }
|
||||
/**
|
||||
* Reverts the bill payment GL entries.
|
||||
* @param {number} tenantId
|
||||
* @param {number} billPaymentId
|
||||
* @param {Knex.Transaction} trx
|
||||
*/
|
||||
public revertPaymentGLEntries = async (
|
||||
billPaymentId: number,
|
||||
trx?: Knex.Transaction,
|
||||
): Promise<void> => {
|
||||
await this.ledgerStorage.deleteByReference(
|
||||
billPaymentId,
|
||||
'BillPayment',
|
||||
trx,
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
// import { Inject, Service } from 'typedi';
|
||||
// import events from '@/subscribers/events';
|
||||
// import {
|
||||
// IBillPaymentEventCreatedPayload,
|
||||
// IBillPaymentEventDeletedPayload,
|
||||
// IBillPaymentEventEditedPayload,
|
||||
// } from '@/interfaces';
|
||||
// import { BillPaymentGLEntries } from './BillPaymentGLEntries';
|
||||
|
||||
// @Service()
|
||||
// export class PaymentWriteGLEntriesSubscriber {
|
||||
// @Inject()
|
||||
// private billPaymentGLEntries: BillPaymentGLEntries;
|
||||
|
||||
// /**
|
||||
// * Attaches events with handles.
|
||||
// */
|
||||
// public attach(bus) {
|
||||
// bus.subscribe(events.billPayment.onCreated, this.handleWriteJournalEntries);
|
||||
// bus.subscribe(
|
||||
// events.billPayment.onEdited,
|
||||
// this.handleRewriteJournalEntriesOncePaymentEdited
|
||||
// );
|
||||
// bus.subscribe(
|
||||
// events.billPayment.onDeleted,
|
||||
// this.handleRevertJournalEntries
|
||||
// );
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Handle bill payment writing journal entries once created.
|
||||
// */
|
||||
// private handleWriteJournalEntries = async ({
|
||||
// tenantId,
|
||||
// billPayment,
|
||||
// trx,
|
||||
// }: IBillPaymentEventCreatedPayload) => {
|
||||
// // Records the journal transactions after bills payment
|
||||
// // and change diff account balance.
|
||||
// await this.billPaymentGLEntries.writePaymentGLEntries(
|
||||
// tenantId,
|
||||
// billPayment.id,
|
||||
// trx
|
||||
// );
|
||||
// };
|
||||
|
||||
// /**
|
||||
// * Handle bill payment re-writing journal entries once the payment transaction be edited.
|
||||
// */
|
||||
// private handleRewriteJournalEntriesOncePaymentEdited = async ({
|
||||
// tenantId,
|
||||
// billPayment,
|
||||
// trx,
|
||||
// }: IBillPaymentEventEditedPayload) => {
|
||||
// await this.billPaymentGLEntries.rewritePaymentGLEntries(
|
||||
// tenantId,
|
||||
// billPayment.id,
|
||||
// trx
|
||||
// );
|
||||
// };
|
||||
|
||||
// /**
|
||||
// * Reverts journal entries once bill payment deleted.
|
||||
// */
|
||||
// private handleRevertJournalEntries = async ({
|
||||
// tenantId,
|
||||
// billPaymentId,
|
||||
// trx,
|
||||
// }: IBillPaymentEventDeletedPayload) => {
|
||||
// await this.billPaymentGLEntries.revertPaymentGLEntries(
|
||||
// tenantId,
|
||||
// billPaymentId,
|
||||
// trx
|
||||
// );
|
||||
// };
|
||||
// }
|
||||
@@ -0,0 +1,60 @@
|
||||
import {
|
||||
IBillPaymentEventCreatedPayload,
|
||||
IBillPaymentEventDeletedPayload,
|
||||
IBillPaymentEventEditedPayload,
|
||||
} from '../types/BillPayments.types';
|
||||
import { BillPaymentGLEntries } from '../commands/BillPaymentGLEntries';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { OnEvent } from '@nestjs/event-emitter';
|
||||
import { events } from '@/common/events/events';
|
||||
|
||||
@Injectable()
|
||||
export class BillPaymentGLEntriesSubscriber {
|
||||
constructor(
|
||||
private readonly billPaymentGLEntries: BillPaymentGLEntries,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Handle bill payment writing journal entries once created.
|
||||
*/
|
||||
@OnEvent(events.billPayment.onCreated)
|
||||
private async handleWriteJournalEntries({
|
||||
billPayment,
|
||||
trx,
|
||||
}: IBillPaymentEventCreatedPayload) {
|
||||
// Records the journal transactions after bills payment
|
||||
// and change diff account balance.
|
||||
await this.billPaymentGLEntries.writePaymentGLEntries(
|
||||
billPayment.id,
|
||||
trx
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle bill payment re-writing journal entries once the payment transaction be edited.
|
||||
*/
|
||||
@OnEvent(events.billPayment.onEdited)
|
||||
private async handleRewriteJournalEntriesOncePaymentEdited({
|
||||
billPayment,
|
||||
trx,
|
||||
}: IBillPaymentEventEditedPayload) {
|
||||
await this.billPaymentGLEntries.rewritePaymentGLEntries(
|
||||
billPayment.id,
|
||||
trx
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Reverts journal entries once bill payment deleted.
|
||||
*/
|
||||
@OnEvent(events.billPayment.onDeleted)
|
||||
private async handleRevertJournalEntries({
|
||||
billPaymentId,
|
||||
trx,
|
||||
}: IBillPaymentEventDeletedPayload) {
|
||||
await this.billPaymentGLEntries.revertPaymentGLEntries(
|
||||
billPaymentId,
|
||||
trx
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -19,10 +19,10 @@ export class BillsApplication {
|
||||
private createBillService: CreateBill,
|
||||
private editBillService: EditBillService,
|
||||
private getBillService: GetBill,
|
||||
// private getBillsService: GetBills,
|
||||
private deleteBillService: DeleteBill,
|
||||
private getDueBillsService: GetDueBills,
|
||||
private openBillService: OpenBillService,
|
||||
// private getBillsService: GetBills,
|
||||
// private getBillPaymentsService: GetBillPayments,
|
||||
) {}
|
||||
|
||||
|
||||
@@ -18,9 +18,12 @@ import { TenancyContext } from '../Tenancy/TenancyContext.service';
|
||||
import { BillsController } from './Bills.controller';
|
||||
import { BillLandedCostsModule } from '../BillLandedCosts/BillLandedCosts.module';
|
||||
import { BillGLEntriesSubscriber } from './subscribers/BillGLEntriesSubscriber';
|
||||
import { BillGLEntries } from './commands/BillsGLEntries';
|
||||
import { LedgerModule } from '../Ledger/Ledger.module';
|
||||
import { AccountsModule } from '../Accounts/Accounts.module';
|
||||
|
||||
@Module({
|
||||
imports: [BillLandedCostsModule],
|
||||
imports: [BillLandedCostsModule, LedgerModule, AccountsModule],
|
||||
providers: [
|
||||
TenancyContext,
|
||||
BillsApplication,
|
||||
@@ -37,8 +40,9 @@ import { BillGLEntriesSubscriber } from './subscribers/BillGLEntriesSubscriber';
|
||||
DeleteBill,
|
||||
BillDTOTransformer,
|
||||
BillsValidators,
|
||||
BillGLEntries,
|
||||
ItemsEntriesService,
|
||||
BillGLEntriesSubscriber
|
||||
BillGLEntriesSubscriber,
|
||||
],
|
||||
controllers: [BillsController],
|
||||
})
|
||||
|
||||
@@ -6,7 +6,7 @@ import * as composeAsync from 'async/compose';
|
||||
import { formatDateFields } from '@/utils/format-date-fields';
|
||||
import { BranchTransactionDTOTransformer } from '@/modules/Branches/integrations/BranchTransactionDTOTransform';
|
||||
import { WarehouseTransactionDTOTransform } from '@/modules/Warehouses/Integrations/WarehouseTransactionDTOTransform';
|
||||
import { ItemEntry } from '@/modules/Items/models/ItemEntry';
|
||||
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
|
||||
import { Item } from '@/modules/Items/models/Item';
|
||||
import { Vendor } from '@/modules/Vendors/models/Vendor';
|
||||
import { ItemEntriesTaxTransactions } from '@/modules/TaxRates/ItemEntriesTaxTransactions.service';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { sumBy } from 'lodash';
|
||||
import { ILedgerEntry } from '@/modules/Ledger/types/Ledger.types';
|
||||
import { ItemEntry } from '@/modules/Items/models/ItemEntry';
|
||||
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
|
||||
import { Bill } from '../models/Bill';
|
||||
import { AccountNormal } from '@/modules/Accounts/Accounts.types';
|
||||
import { Ledger } from '@/modules/Ledger/Ledger';
|
||||
@@ -85,7 +85,6 @@ export class BillGL {
|
||||
index: index + 1,
|
||||
indexGroup: 10,
|
||||
itemId: entry.itemId,
|
||||
itemQuantity: entry.quantity,
|
||||
accountNormal: AccountNormal.DEBIT,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Knex } from 'knex';
|
||||
import { LedgerStorageService } from '@/modules/Ledger/LedgerStorage.service';
|
||||
import { AccountRepository } from '@/modules/Accounts/repositories/Account.repository';
|
||||
import { Bill } from '../models/Bill';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { BillGL } from './BillsGL';
|
||||
|
||||
@Injectable()
|
||||
@@ -15,6 +15,8 @@ export class BillGLEntries {
|
||||
constructor(
|
||||
private readonly ledgerStorage: LedgerStorageService,
|
||||
private readonly accountRepository: AccountRepository,
|
||||
|
||||
@Inject(Bill.name)
|
||||
private readonly billModel: typeof Bill,
|
||||
) {}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
import { BillsValidators } from './BillsValidators.service';
|
||||
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { ItemEntry } from '@/modules/Items/models/ItemEntry';
|
||||
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
|
||||
import { Bill } from '../models/Bill';
|
||||
|
||||
@Injectable()
|
||||
|
||||
@@ -24,6 +24,7 @@ export class EditBillService {
|
||||
private eventPublisher: EventEmitter2,
|
||||
private transactionLandedCostEntries: TransactionLandedCostEntriesService,
|
||||
private transformerDTO: BillDTOTransformer,
|
||||
|
||||
@Inject(Bill.name) private billModel: typeof Bill,
|
||||
@Inject(Vendor.name) private contactModel: typeof Vendor,
|
||||
) {}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Model, raw, mixin } from 'objection';
|
||||
import { castArray, difference } from 'lodash';
|
||||
import moment from 'moment';
|
||||
import { castArray, difference, defaultTo } from 'lodash';
|
||||
import * as moment from 'moment';
|
||||
import * as R from 'ramda';
|
||||
// import TenantModel from 'models/TenantModel';
|
||||
// import BillSettings from './Bill.Settings';
|
||||
// import ModelSetting from './ModelSetting';
|
||||
@@ -8,10 +9,11 @@ import moment from 'moment';
|
||||
// import { DEFAULT_VIEWS } from '@/services/Purchases/Bills/constants';
|
||||
// import ModelSearchable from './ModelSearchable';
|
||||
import { BaseModel } from '@/models/Model';
|
||||
import { ItemEntry } from '@/modules/Items/models/ItemEntry';
|
||||
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
|
||||
import { BillLandedCost } from '@/modules/BillLandedCosts/models/BillLandedCost';
|
||||
import { DiscountType } from '@/common/types/Discount';
|
||||
|
||||
export class Bill extends BaseModel{
|
||||
export class Bill extends BaseModel {
|
||||
public amount: number;
|
||||
public paymentAmount: number;
|
||||
public landedCostAmount: number;
|
||||
@@ -33,6 +35,10 @@ export class Bill extends BaseModel{
|
||||
public openedAt: Date | string;
|
||||
public userId: number;
|
||||
|
||||
public discountType: DiscountType;
|
||||
public discount: number;
|
||||
public adjustment: number;
|
||||
|
||||
public branchId: number;
|
||||
public warehouseId: number;
|
||||
public projectId: number;
|
||||
@@ -68,9 +74,16 @@ export class Bill extends BaseModel{
|
||||
'localAllocatedCostAmount',
|
||||
'billableAmount',
|
||||
'amountLocal',
|
||||
|
||||
'discountAmount',
|
||||
'discountAmountLocal',
|
||||
'discountPercentage',
|
||||
|
||||
'adjustmentLocal',
|
||||
|
||||
'subtotal',
|
||||
'subtotalLocal',
|
||||
'subtotalExcludingTax',
|
||||
'subtotalExludingTax',
|
||||
'taxAmountWithheldLocal',
|
||||
'total',
|
||||
'totalLocal',
|
||||
@@ -119,14 +132,53 @@ export class Bill extends BaseModel{
|
||||
return this.taxAmountWithheld * this.exchangeRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Discount amount.
|
||||
* @returns {number}
|
||||
*/
|
||||
get discountAmount() {
|
||||
return this.discountType === DiscountType.Amount
|
||||
? this.discount
|
||||
: this.subtotal * (this.discount / 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Discount amount in local currency.
|
||||
* @returns {number | null}
|
||||
*/
|
||||
get discountAmountLocal() {
|
||||
return this.discountAmount ? this.discountAmount * this.exchangeRate : null;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Discount percentage.
|
||||
* @returns {number | null}
|
||||
*/
|
||||
get discountPercentage(): number | null {
|
||||
return this.discountType === DiscountType.Percentage ? this.discount : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjustment amount in local currency.
|
||||
* @returns {number | null}
|
||||
*/
|
||||
get adjustmentLocal() {
|
||||
return this.adjustment ? this.adjustment * this.exchangeRate : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoice total. (Tax included)
|
||||
* @returns {number}
|
||||
*/
|
||||
get total() {
|
||||
return this.isInclusiveTax
|
||||
? this.subtotal
|
||||
: this.subtotal + this.taxAmountWithheld;
|
||||
const adjustmentAmount = defaultTo(this.adjustment, 0);
|
||||
|
||||
return R.compose(
|
||||
R.add(adjustmentAmount),
|
||||
R.subtract(R.__, this.discountAmount),
|
||||
R.when(R.always(this.isInclusiveTax), R.add(this.taxAmountWithheld)),
|
||||
)(this.subtotal);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -183,7 +235,7 @@ export class Bill extends BaseModel{
|
||||
raw(`COALESCE(AMOUNT, 0) -
|
||||
COALESCE(PAYMENT_AMOUNT, 0) -
|
||||
COALESCE(CREDITED_AMOUNT, 0) > 0
|
||||
`)
|
||||
`),
|
||||
);
|
||||
},
|
||||
/**
|
||||
|
||||
@@ -8,6 +8,7 @@ import { TransformerInjectable } from '@/modules/Transformer/TransformerInjectab
|
||||
export class GetBill {
|
||||
constructor(
|
||||
@Inject(Bill.name) private billModel: typeof Bill,
|
||||
|
||||
private transformer: TransformerInjectable,
|
||||
private validators: BillsValidators,
|
||||
) {}
|
||||
|
||||
@@ -20,6 +20,8 @@ import { CreditNoteBrandingTemplate } from './queries/CreditNoteBrandingTemplate
|
||||
import { AutoIncrementOrdersModule } from '../AutoIncrementOrders/AutoIncrementOrders.module';
|
||||
import { CreditNoteGLEntries } from './commands/CreditNoteGLEntries';
|
||||
import { CreditNoteGLEntriesSubscriber } from './subscribers/CreditNoteGLEntriesSubscriber';
|
||||
import { LedgerModule } from '../Ledger/Ledger.module';
|
||||
import { AccountsModule } from '../Accounts/Accounts.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -30,6 +32,8 @@ import { CreditNoteGLEntriesSubscriber } from './subscribers/CreditNoteGLEntries
|
||||
ChromiumlyTenancyModule,
|
||||
TemplateInjectableModule,
|
||||
AutoIncrementOrdersModule,
|
||||
LedgerModule,
|
||||
AccountsModule
|
||||
],
|
||||
providers: [
|
||||
CreateCreditNoteService,
|
||||
|
||||
@@ -2,7 +2,7 @@ import { ILedgerEntry } from '@/modules/Ledger/types/Ledger.types';
|
||||
import { CreditNote } from '../models/CreditNote';
|
||||
import { AccountNormal } from '@/interfaces/Account';
|
||||
import { Ledger } from '@/modules/Ledger/Ledger';
|
||||
import { ItemEntry } from '@/modules/Items/models/ItemEntry';
|
||||
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
|
||||
|
||||
export class CreditNoteGL {
|
||||
creditNoteModel: CreditNote;
|
||||
@@ -111,7 +111,6 @@ export class CreditNoteGL {
|
||||
note: entry.description,
|
||||
index: index + 2,
|
||||
itemId: entry.itemId,
|
||||
itemQuantity: entry.quantity,
|
||||
accountNormal: AccountNormal.CREDIT,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
} from '../../CreditNoteRefunds/models/RefundCreditNote';
|
||||
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { ItemEntry } from '@/modules/Items/models/ItemEntry';
|
||||
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
|
||||
import { ServiceError } from '@/modules/Items/ServiceError';
|
||||
import { events } from '@/common/events/events';
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { DiscountType } from '@/common/types/Discount';
|
||||
import { BaseModel } from '@/models/Model';
|
||||
import { Branch } from '@/modules/Branches/models/Branch.model';
|
||||
import { Customer } from '@/modules/Customers/models/Customer';
|
||||
import { ItemEntry } from '@/modules/Items/models/ItemEntry';
|
||||
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
|
||||
import { Warehouse } from '@/modules/Warehouses/models/Warehouse.model';
|
||||
import { mixin, Model, raw } from 'objection';
|
||||
// import TenantModel from 'models/TenantModel';
|
||||
@@ -28,6 +28,8 @@ export class CreditNote extends BaseModel {
|
||||
public currencyCode: string;
|
||||
public customerId: number;
|
||||
|
||||
public userId: number;
|
||||
|
||||
public branchId: number;
|
||||
public warehouseId: number;
|
||||
|
||||
@@ -37,7 +39,8 @@ export class CreditNote extends BaseModel {
|
||||
public branch!: Branch;
|
||||
public warehouse!: Warehouse;
|
||||
|
||||
|
||||
public createdAt!: Date | string;
|
||||
public updatedAt!: Date | string;
|
||||
|
||||
/**
|
||||
* Table name
|
||||
|
||||
@@ -4,7 +4,7 @@ import { ItemEstimateTransactionTransformer } from './ItemEstimatesTransaction.t
|
||||
import { ItemBillTransactionTransformer } from './ItemBillsTransactions.transformer';
|
||||
import { ItemReceiptTransactionTransformer } from './ItemReceiptsTransactions.transformer';
|
||||
import { TransformerInjectable } from '../Transformer/TransformerInjectable.service';
|
||||
import { ItemEntry } from './models/ItemEntry';
|
||||
import { ItemEntry } from '../TransactionItemEntry/models/ItemEntry';
|
||||
|
||||
@Injectable()
|
||||
export class ItemTransactionsService {
|
||||
|
||||
@@ -1,242 +0,0 @@
|
||||
import { Model } from 'objection';
|
||||
// import TenantModel from 'models/TenantModel';
|
||||
// import { getExlusiveTaxAmount, getInclusiveTaxAmount } from '@/utils/taxRate';
|
||||
import { BaseModel } from '@/models/Model';
|
||||
import { Item } from './Item';
|
||||
|
||||
export class ItemEntry extends BaseModel {
|
||||
public taxRate: number;
|
||||
public discount: number;
|
||||
public quantity: number;
|
||||
public rate: number;
|
||||
public isInclusiveTax: number;
|
||||
public itemId: number;
|
||||
public costAccountId: number;
|
||||
public taxRateId: number;
|
||||
public sellAccountId: number;
|
||||
public description: string;
|
||||
|
||||
public landedCost!: boolean;
|
||||
public allocatedCostAmount!: number;
|
||||
|
||||
public item!: Item;
|
||||
|
||||
/**
|
||||
* Table name.
|
||||
* @returns {string}
|
||||
*/
|
||||
static get tableName() {
|
||||
return 'items_entries';
|
||||
}
|
||||
|
||||
/**
|
||||
* Timestamps columns.
|
||||
* @returns {string[]}
|
||||
*/
|
||||
get timestamps() {
|
||||
return ['created_at', 'updated_at'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Virtual attributes.
|
||||
* @returns {string[]}
|
||||
*/
|
||||
static get virtualAttributes() {
|
||||
return [
|
||||
'amount',
|
||||
'taxAmount',
|
||||
'amountExludingTax',
|
||||
'amountInclusingTax',
|
||||
'total',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Item entry total.
|
||||
* Amount of item entry includes tax and subtracted discount amount.
|
||||
* @returns {number}
|
||||
*/
|
||||
get total() {
|
||||
return this.amountInclusingTax;
|
||||
}
|
||||
|
||||
/**
|
||||
* Item entry amount.
|
||||
* Amount of item entry that may include or exclude tax.
|
||||
* @returns {number}
|
||||
*/
|
||||
get amount() {
|
||||
return this.quantity * this.rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Item entry amount including tax.
|
||||
* @returns {number}
|
||||
*/
|
||||
get amountInclusingTax() {
|
||||
return this.isInclusiveTax ? this.amount : this.amount + this.taxAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Item entry amount excluding tax.
|
||||
* @returns {number}
|
||||
*/
|
||||
get amountExludingTax() {
|
||||
return this.isInclusiveTax ? this.amount - this.taxAmount : this.amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Discount amount.
|
||||
* @returns {number}
|
||||
*/
|
||||
get discountAmount() {
|
||||
return this.amount * (this.discount / 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tag rate fraction.
|
||||
* @returns {number}
|
||||
*/
|
||||
get tagRateFraction() {
|
||||
return this.taxRate / 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tax amount withheld.
|
||||
* @returns {number}
|
||||
*/
|
||||
get taxAmount() {
|
||||
return 0;
|
||||
// return this.isInclusiveTax
|
||||
// ? getInclusiveTaxAmount(this.amount, this.taxRate)
|
||||
// : getExlusiveTaxAmount(this.amount, this.taxRate);
|
||||
}
|
||||
|
||||
static calcAmount(itemEntry) {
|
||||
const { discount, quantity, rate } = itemEntry;
|
||||
const total = quantity * rate;
|
||||
|
||||
return discount ? total - total * discount * 0.01 : total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Item entry relations.
|
||||
*/
|
||||
static get relationMappings() {
|
||||
const { Item } = require('../../Items/models/Item');
|
||||
// const BillLandedCostEntry = require('models/BillLandedCostEntry');
|
||||
const { SaleInvoice } = require('../../SaleInvoices/models/SaleInvoice');
|
||||
const { Bill } = require('../../Bills/models/Bill');
|
||||
const { SaleReceipt } = require('../../SaleReceipts/models/SaleReceipt');
|
||||
const { SaleEstimate } = require('../../SaleEstimates/models/SaleEstimate');
|
||||
// const ProjectTask = require('models/Task');
|
||||
const { Expense } = require('../../Expenses/models/Expense.model');
|
||||
const { TaxRateModel } = require('../../TaxRates/models/TaxRate.model');
|
||||
|
||||
return {
|
||||
item: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
modelClass: Item,
|
||||
join: {
|
||||
from: 'items_entries.itemId',
|
||||
to: 'items.id',
|
||||
},
|
||||
},
|
||||
// allocatedCostEntries: {
|
||||
// relation: Model.HasManyRelation,
|
||||
// modelClass: BillLandedCostEntry,
|
||||
// join: {
|
||||
// from: 'items_entries.referenceId',
|
||||
// to: 'bill_located_cost_entries.entryId',
|
||||
// },
|
||||
// },
|
||||
|
||||
invoice: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
modelClass: SaleInvoice,
|
||||
join: {
|
||||
from: 'items_entries.referenceId',
|
||||
to: 'sales_invoices.id',
|
||||
},
|
||||
},
|
||||
|
||||
bill: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
modelClass: Bill,
|
||||
join: {
|
||||
from: 'items_entries.referenceId',
|
||||
to: 'bills.id',
|
||||
},
|
||||
},
|
||||
|
||||
estimate: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
modelClass: SaleEstimate,
|
||||
join: {
|
||||
from: 'items_entries.referenceId',
|
||||
to: 'sales_estimates.id',
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Sale receipt reference.
|
||||
*/
|
||||
receipt: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
modelClass: SaleReceipt,
|
||||
join: {
|
||||
from: 'items_entries.referenceId',
|
||||
to: 'sales_receipts.id',
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Project task reference.
|
||||
*/
|
||||
// projectTaskRef: {
|
||||
// relation: Model.HasManyRelation,
|
||||
// modelClass: ProjectTask.default,
|
||||
// join: {
|
||||
// from: 'items_entries.projectRefId',
|
||||
// to: 'tasks.id',
|
||||
// },
|
||||
// },
|
||||
|
||||
/**
|
||||
* Project expense reference.
|
||||
*/
|
||||
// projectExpenseRef: {
|
||||
// relation: Model.HasManyRelation,
|
||||
// modelClass: Expense.default,
|
||||
// join: {
|
||||
// from: 'items_entries.projectRefId',
|
||||
// to: 'expenses_transactions.id',
|
||||
// },
|
||||
// },
|
||||
|
||||
/**
|
||||
* Project bill reference.
|
||||
*/
|
||||
// projectBillRef: {
|
||||
// relation: Model.HasManyRelation,
|
||||
// modelClass: Bill.default,
|
||||
// join: {
|
||||
// from: 'items_entries.projectRefId',
|
||||
// to: 'bills.id',
|
||||
// },
|
||||
// },
|
||||
|
||||
/**
|
||||
* Tax rate reference.
|
||||
*/
|
||||
tax: {
|
||||
relation: Model.HasOneRelation,
|
||||
modelClass: TaxRateModel,
|
||||
join: {
|
||||
from: 'items_entries.taxRateId',
|
||||
to: 'tax_rates.id',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -18,12 +18,10 @@ export class LedegrAccountsStorage {
|
||||
*/
|
||||
constructor(
|
||||
private tenancyContext: TenancyContext,
|
||||
private accountRepository: AccountRepository,
|
||||
|
||||
@Inject(Account.name)
|
||||
private accountModel: typeof Account,
|
||||
|
||||
@Inject(AccountRepository)
|
||||
private accountRepository: AccountRepository,
|
||||
) {}
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,7 +14,7 @@ import { DeletePaymentReceivedService } from './commands/DeletePaymentReceived.s
|
||||
import { GetPaymentReceivedService } from './queries/GetPaymentReceived.service';
|
||||
import { GetPaymentReceivedInvoices } from './queries/GetPaymentReceivedInvoices.service';
|
||||
// import { PaymentReceiveNotifyBySms } from './PaymentReceivedSmsNotify';
|
||||
import GetPaymentReceivedPdf from './queries/GetPaymentReceivedPdf.service';
|
||||
import { GetPaymentReceivedPdfService } from './queries/GetPaymentReceivedPdf.service';
|
||||
// import { SendPaymentReceiveMailNotification } from './PaymentReceivedMailNotification';
|
||||
import { GetPaymentReceivedStateService } from './queries/GetPaymentReceivedState.service';
|
||||
|
||||
@@ -29,7 +29,7 @@ export class PaymentReceivesApplication {
|
||||
private getPaymentReceiveInvoicesService: GetPaymentReceivedInvoices,
|
||||
// private paymentSmsNotify: PaymentReceiveNotifyBySms,
|
||||
// private paymentMailNotify: SendPaymentReceiveMailNotification,
|
||||
private getPaymentReceivePdfService: GetPaymentReceivedPdf,
|
||||
private getPaymentReceivePdfService: GetPaymentReceivedPdfService,
|
||||
private getPaymentReceivedStateService: GetPaymentReceivedStateService,
|
||||
) {}
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@ import { PaymentReceivedGLEntriesSubscriber } from './subscribers/PaymentReceive
|
||||
import { PaymentReceivedGLEntries } from './commands/PaymentReceivedGLEntries';
|
||||
import { PaymentReceivedSyncInvoicesSubscriber } from './subscribers/PaymentReceivedSyncInvoices';
|
||||
import { PaymentReceivedInvoiceSync } from './commands/PaymentReceivedInvoiceSync.service';
|
||||
import { LedgerModule } from '../Ledger/Ledger.module';
|
||||
import { AccountsModule } from '../Accounts/Accounts.module';
|
||||
|
||||
@Module({
|
||||
controllers: [PaymentReceivesController],
|
||||
@@ -55,6 +57,8 @@ import { PaymentReceivedInvoiceSync } from './commands/PaymentReceivedInvoiceSyn
|
||||
WarehousesModule,
|
||||
PdfTemplatesModule,
|
||||
AutoIncrementOrdersModule,
|
||||
LedgerModule,
|
||||
AccountsModule
|
||||
],
|
||||
})
|
||||
export class PaymentsReceivedModule {}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { AccountRepository } from '@/modules/Accounts/repositories/Account.repos
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Inject } from '@nestjs/common';
|
||||
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
|
||||
import { Account } from '@/modules/Accounts/models/Account.model';
|
||||
|
||||
@Injectable()
|
||||
export class PaymentReceivedGLEntries {
|
||||
@@ -98,7 +99,8 @@ export class PaymentReceivedGLEntries {
|
||||
// Exchange gain/loss account.
|
||||
const exGainLossAccount = await this.accountRepository.findBySlug(
|
||||
'exchange-grain-loss'
|
||||
);
|
||||
) as Account;
|
||||
|
||||
const paymentReceivedGL = new PaymentReceivedGL(paymentReceive)
|
||||
.setARAccountId(receivableAccount.id)
|
||||
.setExchangeGainOrLossAccountId(exGainLossAccount.id)
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { defaultPaymentReceivedPdfTemplateAttributes } from '../constants';
|
||||
import { GetPdfTemplateService } from '../../PdfTemplate/queries/GetPdfTemplate.service';
|
||||
import { GetOrganizationBrandingAttributesService } from '../../PdfTemplate/queries/GetOrganizationBrandingAttributes.service';
|
||||
import { PdfTemplateModel } from '../../PdfTemplate/models/PdfTemplate';
|
||||
import { mergePdfTemplateWithDefaultAttributes } from '../../SaleInvoices/utils';
|
||||
|
||||
@Injectable()
|
||||
@@ -10,9 +9,6 @@ export class PaymentReceivedBrandingTemplate {
|
||||
constructor(
|
||||
private readonly getPdfTemplateService: GetPdfTemplateService,
|
||||
private readonly getOrgBrandingAttributes: GetOrganizationBrandingAttributesService,
|
||||
|
||||
@Inject(PdfTemplateModel.name)
|
||||
private readonly pdfTemplateModel: typeof PdfTemplateModel,
|
||||
) {}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { BaseModel } from '@/models/Model';
|
||||
import moment from 'moment';
|
||||
import { Model } from 'objection';
|
||||
import { ItemEntry } from '../../Items/models/ItemEntry';
|
||||
import { ItemEntry } from '../../TransactionItemEntry/models/ItemEntry';
|
||||
import { Customer } from '../../Customers/models/Customer';
|
||||
import { Branch } from '../../Branches/models/Branch.model';
|
||||
import { Warehouse } from '../../Warehouses/models/Warehouse.model';
|
||||
|
||||
@@ -33,6 +33,8 @@ import { TaxRatesModule } from '../TaxRates/TaxRate.module';
|
||||
import { SaleInvoicesController } from './SaleInvoices.controller';
|
||||
import { InvoiceGLEntriesSubscriber } from './subscribers/InvoiceGLEntriesSubscriber';
|
||||
import { SaleInvoiceGLEntries } from './ledger/InvoiceGLEntries';
|
||||
import { LedgerModule } from '../Ledger/Ledger.module';
|
||||
import { AccountsModule } from '../Accounts/Accounts.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -43,6 +45,8 @@ import { SaleInvoiceGLEntries } from './ledger/InvoiceGLEntries';
|
||||
BranchesModule,
|
||||
WarehousesModule,
|
||||
TaxRatesModule,
|
||||
LedgerModule,
|
||||
AccountsModule
|
||||
],
|
||||
controllers: [SaleInvoicesController],
|
||||
providers: [
|
||||
|
||||
@@ -12,7 +12,7 @@ import { Customer } from '@/modules/Customers/models/Customer';
|
||||
import { BranchTransactionDTOTransformer } from '@/modules/Branches/integrations/BranchTransactionDTOTransform';
|
||||
import { WarehouseTransactionDTOTransform } from '@/modules/Warehouses/Integrations/WarehouseTransactionDTOTransform';
|
||||
import { ItemsEntriesService } from '@/modules/Items/ItemsEntries.service';
|
||||
import { ItemEntry } from '@/modules/Items/models/ItemEntry';
|
||||
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
|
||||
import { CommandSaleInvoiceValidators } from './CommandSaleInvoiceValidators.service';
|
||||
import { SaleInvoiceIncrement } from './SaleInvoiceIncrement.service';
|
||||
import { BrandingTemplateDTOTransformer } from '@/modules/PdfTemplate/BrandingTemplateDTOTransformer';
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
ISaleInvoiceDeletedPayload,
|
||||
ISaleInvoiceDeletingPayload,
|
||||
} from '../SaleInvoice.types';
|
||||
import { ItemEntry } from '@/modules/Items/models/ItemEntry';
|
||||
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
|
||||
import { SaleInvoice } from '../models/SaleInvoice';
|
||||
import { UnlinkConvertedSaleEstimate } from '@/modules/SaleEstimates/commands/UnlinkConvertedSaleEstimate.service';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
|
||||
@@ -2,7 +2,7 @@ import * as R from 'ramda';
|
||||
import { ILedger } from '@/modules/Ledger/types/Ledger.types';
|
||||
import { AccountNormal } from '@/modules/Accounts/Accounts.types';
|
||||
import { ILedgerEntry } from '@/modules/Ledger/types/Ledger.types';
|
||||
import { ItemEntry } from '@/modules/Items/models/ItemEntry';
|
||||
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
|
||||
import { Ledger } from '@/modules/Ledger/Ledger';
|
||||
import { SaleInvoice } from '../models/SaleInvoice';
|
||||
|
||||
@@ -116,7 +116,6 @@ export class InvoiceGL {
|
||||
note: entry.description,
|
||||
index: index + 2,
|
||||
itemId: entry.itemId,
|
||||
itemQuantity: entry.quantity,
|
||||
accountNormal: AccountNormal.CREDIT,
|
||||
taxRateId: entry.taxRateId,
|
||||
taxRate: entry.taxRate,
|
||||
@@ -149,7 +148,7 @@ export class InvoiceGL {
|
||||
* Retrieves the invoice discount GL entry.
|
||||
* @returns {ILedgerEntry}
|
||||
*/
|
||||
private getInvoiceDiscountEntry = (): ILedgerEntry => {
|
||||
private get invoiceDiscountEntry(): ILedgerEntry {
|
||||
const commonEntry = this.invoiceGLCommonEntry;
|
||||
|
||||
return {
|
||||
@@ -165,7 +164,7 @@ export class InvoiceGL {
|
||||
* Retrieves the invoice adjustment GL entry.
|
||||
* @returns {ILedgerEntry}
|
||||
*/
|
||||
private getAdjustmentEntry = (): ILedgerEntry => {
|
||||
private get adjustmentEntry(): ILedgerEntry {
|
||||
const commonEntry = this.invoiceGLCommonEntry;
|
||||
const adjustmentAmount = Math.abs(this.saleInvoice.adjustmentLocal);
|
||||
|
||||
@@ -184,24 +183,19 @@ export class InvoiceGL {
|
||||
* @returns {ILedgerEntry[]}
|
||||
*/
|
||||
public getInvoiceGLEntries = (): ILedgerEntry[] => {
|
||||
const receivableEntry = this.invoiceReceivableEntry;
|
||||
const creditEntries = this.saleInvoice.entries.map(
|
||||
this.getInvoiceItemEntry,
|
||||
(entry, index) => this.getInvoiceItemEntry(entry, index),
|
||||
);
|
||||
|
||||
const taxEntries = this.saleInvoice.entries
|
||||
.filter((entry) => entry.taxAmount > 0)
|
||||
.map(this.getInvoiceTaxEntry);
|
||||
|
||||
const discountEntry = this.getInvoiceDiscountEntry();
|
||||
const adjustmentEntry = this.getAdjustmentEntry();
|
||||
.map((entry, index) => this.getInvoiceTaxEntry(entry, index));
|
||||
|
||||
return [
|
||||
this.invoiceReceivableEntry,
|
||||
...creditEntries,
|
||||
...taxEntries,
|
||||
discountEntry,
|
||||
adjustmentEntry,
|
||||
this.invoiceDiscountEntry,
|
||||
this.adjustmentEntry,
|
||||
];
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { mixin, Model, raw } from 'objection';
|
||||
import { castArray, takeWhile } from 'lodash';
|
||||
import { Model, raw } from 'objection';
|
||||
import { castArray } from 'lodash';
|
||||
import * as moment from 'moment';
|
||||
import * as R from 'ramda';
|
||||
import { MomentInput, unitOfTime } from 'moment';
|
||||
import { defaultTo } from 'ramda';
|
||||
// import TenantModel from 'models/TenantModel';
|
||||
// import ModelSetting from './ModelSetting';
|
||||
// import SaleInvoiceMeta from './SaleInvoice.Settings';
|
||||
@@ -10,8 +12,9 @@ import { MomentInput, unitOfTime } from 'moment';
|
||||
// import ModelSearchable from './ModelSearchable';
|
||||
import { BaseModel } from '@/models/Model';
|
||||
import { TaxRateTransaction } from '@/modules/TaxRates/models/TaxRateTransaction.model';
|
||||
import { ItemEntry } from '@/modules/Items/models/ItemEntry';
|
||||
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
|
||||
import { Document } from '@/modules/ChromiumlyTenancy/models/Document';
|
||||
import { DiscountType } from '@/common/types/Discount';
|
||||
|
||||
export class SaleInvoice extends BaseModel {
|
||||
public taxAmountWithheld: number;
|
||||
@@ -34,6 +37,10 @@ export class SaleInvoice extends BaseModel {
|
||||
public writtenoffAmount: number;
|
||||
public writtenoffAt: Date;
|
||||
|
||||
public discountType: DiscountType;
|
||||
public discount: number;
|
||||
public adjustment: number;
|
||||
|
||||
public customerId: number;
|
||||
public invoiceNo: string;
|
||||
public referenceNo: string;
|
||||
@@ -91,10 +98,15 @@ export class SaleInvoice extends BaseModel {
|
||||
'subtotalExludingTax',
|
||||
|
||||
'taxAmountWithheldLocal',
|
||||
'discountAmount',
|
||||
'discountAmountLocal',
|
||||
'discountPercentage',
|
||||
|
||||
'total',
|
||||
'totalLocal',
|
||||
|
||||
'writtenoffAmountLocal',
|
||||
'adjustmentLocal',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -149,14 +161,52 @@ export class SaleInvoice extends BaseModel {
|
||||
return this.taxAmountWithheld * this.exchangeRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Discount amount.
|
||||
* @returns {number}
|
||||
*/
|
||||
get discountAmount() {
|
||||
return this.discountType === DiscountType.Amount
|
||||
? this.discount
|
||||
: this.subtotal * (this.discount / 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Local discount amount.
|
||||
* @returns {number | null}
|
||||
*/
|
||||
get discountAmountLocal() {
|
||||
return this.discountAmount ? this.discountAmount * this.exchangeRate : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Discount percentage.
|
||||
* @returns {number | null}
|
||||
*/
|
||||
get discountPercentage(): number | null {
|
||||
return this.discountType === DiscountType.Percentage ? this.discount : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjustment amount in local currency.
|
||||
* @returns {number | null}
|
||||
*/
|
||||
get adjustmentLocal(): number | null {
|
||||
return this.adjustment ? this.adjustment * this.exchangeRate : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoice total. (Tax included)
|
||||
* @returns {number}
|
||||
*/
|
||||
get total() {
|
||||
return this.isInclusiveTax
|
||||
? this.subtotal
|
||||
: this.subtotal + this.taxAmountWithheld;
|
||||
const adjustmentAmount = defaultTo(this.adjustment, 0);
|
||||
|
||||
return R.compose(
|
||||
R.add(adjustmentAmount),
|
||||
R.subtract(R.__, this.discountAmount),
|
||||
R.when(R.always(this.isInclusiveTax), R.add(this.taxAmountWithheld)),
|
||||
)(this.subtotal);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -445,7 +495,9 @@ export class SaleInvoice extends BaseModel {
|
||||
const { Branch } = require('../../Branches/models/Branch.model');
|
||||
const { Warehouse } = require('../../Warehouses/models/Warehouse.model');
|
||||
const { Account } = require('../../Accounts/models/Account.model');
|
||||
const { TaxRateTransaction } = require('../../TaxRates/models/TaxRateTransaction.model');
|
||||
const {
|
||||
TaxRateTransaction,
|
||||
} = require('../../TaxRates/models/TaxRateTransaction.model');
|
||||
const { Document } = require('../../ChromiumlyTenancy/models/Document');
|
||||
// const { MatchedBankTransaction } = require('models/MatchedBankTransaction');
|
||||
const {
|
||||
|
||||
@@ -22,6 +22,8 @@ import { AutoIncrementOrdersModule } from '../AutoIncrementOrders/AutoIncrementO
|
||||
import { SaleReceiptsController } from './SaleReceipts.controller';
|
||||
import { SaleReceiptGLEntriesSubscriber } from './subscribers/SaleReceiptGLEntriesSubscriber';
|
||||
import { SaleReceiptGLEntries } from './ledger/SaleReceiptGLEntries';
|
||||
import { LedgerModule } from '../Ledger/Ledger.module';
|
||||
import { AccountsModule } from '../Accounts/Accounts.module';
|
||||
|
||||
@Module({
|
||||
controllers: [SaleReceiptsController],
|
||||
@@ -32,7 +34,9 @@ import { SaleReceiptGLEntries } from './ledger/SaleReceiptGLEntries';
|
||||
BranchesModule,
|
||||
WarehousesModule,
|
||||
PdfTemplatesModule,
|
||||
AutoIncrementOrdersModule
|
||||
AutoIncrementOrdersModule,
|
||||
LedgerModule,
|
||||
AccountsModule
|
||||
],
|
||||
providers: [
|
||||
TenancyContext,
|
||||
|
||||
@@ -8,7 +8,7 @@ import { SaleReceiptValidators } from './SaleReceiptValidators.service';
|
||||
import { SaleReceipt } from '../models/SaleReceipt';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
|
||||
import { ItemEntry } from '@/modules/Items/models/ItemEntry';
|
||||
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
|
||||
import { events } from '@/common/events/events';
|
||||
|
||||
@Injectable()
|
||||
|
||||
@@ -9,7 +9,7 @@ import { BranchTransactionDTOTransformer } from '@/modules/Branches/integrations
|
||||
import { WarehouseTransactionDTOTransform } from '@/modules/Warehouses/Integrations/WarehouseTransactionDTOTransform';
|
||||
import { SaleReceiptValidators } from './SaleReceiptValidators.service';
|
||||
import { BrandingTemplateDTOTransformer } from '@/modules/PdfTemplate/BrandingTemplateDTOTransformer';
|
||||
import { ItemEntry } from '@/modules/Items/models/ItemEntry';
|
||||
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
|
||||
import { formatDateFields } from '@/utils/format-date-fields';
|
||||
import { assocItemEntriesDefaultIndex } from '@/utils/associate-item-entries-index';
|
||||
import { SaleReceipt } from '../models/SaleReceipt';
|
||||
|
||||
@@ -4,7 +4,7 @@ import { AccountNormal } from '@/modules/Accounts/Accounts.types';
|
||||
import { ILedgerEntry } from '@/modules/Ledger/types/Ledger.types';
|
||||
import { Ledger } from '@/modules/Ledger/Ledger';
|
||||
import { SaleReceipt } from '../models/SaleReceipt';
|
||||
import { ItemEntry } from '@/modules/Items/models/ItemEntry';
|
||||
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
|
||||
|
||||
export class SaleReceiptGL {
|
||||
private saleReceipt: SaleReceipt;
|
||||
@@ -82,7 +82,7 @@ export class SaleReceiptGL {
|
||||
note: entry.description,
|
||||
index: index + 2,
|
||||
itemId: entry.itemId,
|
||||
itemQuantity: entry.quantity,
|
||||
// itemQuantity: entry.quantity,
|
||||
accountNormal: AccountNormal.CREDIT,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Model, mixin } from 'objection';
|
||||
import { defaultTo } from 'ramda';
|
||||
// import TenantModel from 'models/TenantModel';
|
||||
// import ModelSetting from './ModelSetting';
|
||||
// import SaleReceiptSettings from './SaleReceipt.Settings';
|
||||
@@ -6,11 +7,12 @@ import { Model, mixin } from 'objection';
|
||||
// import { DEFAULT_VIEWS } from '@/services/Sales/Receipts/constants';
|
||||
// import ModelSearchable from './ModelSearchable';
|
||||
import { BaseModel } from '@/models/Model';
|
||||
import { ItemEntry } from '@/modules/Items/models/ItemEntry';
|
||||
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
|
||||
import { Customer } from '@/modules/Customers/models/Customer';
|
||||
import { AccountTransaction } from '@/modules/Accounts/models/AccountTransaction.model';
|
||||
import { Branch } from '@/modules/Branches/models/Branch.model';
|
||||
import { Warehouse } from '@/modules/Warehouses/models/Warehouse.model';
|
||||
import { DiscountType } from '@/common/types/Discount';
|
||||
|
||||
export class SaleReceipt extends BaseModel {
|
||||
amount: number;
|
||||
@@ -26,9 +28,15 @@ export class SaleReceipt extends BaseModel {
|
||||
statement: string;
|
||||
closedAt: Date | string;
|
||||
|
||||
discountType: DiscountType;
|
||||
discount: number;
|
||||
adjustment: number;
|
||||
|
||||
branchId: number;
|
||||
warehouseId: number;
|
||||
|
||||
userId: number;
|
||||
|
||||
createdAt: Date;
|
||||
updatedAt: Date | null;
|
||||
|
||||
@@ -37,7 +45,7 @@ export class SaleReceipt extends BaseModel {
|
||||
transactions!: AccountTransaction[];
|
||||
branch!: Branch;
|
||||
warehouse!: Warehouse;
|
||||
|
||||
|
||||
/**
|
||||
* Table name
|
||||
*/
|
||||
@@ -56,7 +64,28 @@ export class SaleReceipt extends BaseModel {
|
||||
* Virtual attributes.
|
||||
*/
|
||||
static get virtualAttributes() {
|
||||
return ['localAmount', 'isClosed', 'isDraft'];
|
||||
return [
|
||||
'localAmount',
|
||||
|
||||
'subtotal',
|
||||
'subtotalLocal',
|
||||
|
||||
'total',
|
||||
'totalLocal',
|
||||
|
||||
'adjustment',
|
||||
'adjustmentLocal',
|
||||
|
||||
'discountAmount',
|
||||
'discountAmountLocal',
|
||||
'discountPercentage',
|
||||
|
||||
'paid',
|
||||
'paidLocal',
|
||||
|
||||
'isClosed',
|
||||
'isDraft',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,6 +96,90 @@ export class SaleReceipt extends BaseModel {
|
||||
return this.amount * this.exchangeRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Receipt subtotal.
|
||||
* @returns {number}
|
||||
*/
|
||||
get subtotal() {
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Receipt subtotal in local currency.
|
||||
* @returns {number}
|
||||
*/
|
||||
get subtotalLocal() {
|
||||
return this.localAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Discount amount.
|
||||
* @returns {number}
|
||||
*/
|
||||
get discountAmount() {
|
||||
return this.discountType === DiscountType.Amount
|
||||
? this.discount
|
||||
: this.subtotal * (this.discount / 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Discount amount in local currency.
|
||||
* @returns {number | null}
|
||||
*/
|
||||
get discountAmountLocal() {
|
||||
return this.discountAmount ? this.discountAmount * this.exchangeRate : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Discount percentage.
|
||||
* @returns {number | null}
|
||||
*/
|
||||
get discountPercentage(): number | null {
|
||||
return this.discountType === DiscountType.Percentage ? this.discount : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Receipt total.
|
||||
* @returns {number}
|
||||
*/
|
||||
get total() {
|
||||
const adjustmentAmount = defaultTo(this.adjustment, 0);
|
||||
|
||||
return this.subtotal - this.discountAmount + adjustmentAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Receipt total in local currency.
|
||||
* @returns {number}
|
||||
*/
|
||||
get totalLocal() {
|
||||
return this.total * this.exchangeRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjustment amount in local currency.
|
||||
* @returns {number}
|
||||
*/
|
||||
get adjustmentLocal() {
|
||||
return this.adjustment * this.exchangeRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Receipt paid amount.
|
||||
* @returns {number}
|
||||
*/
|
||||
get paid() {
|
||||
return this.total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Receipt paid amount in local currency.
|
||||
* @returns {number}
|
||||
*/
|
||||
get paidLocal() {
|
||||
return this.paid * this.exchangeRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detarmine whether the sale receipt closed.
|
||||
* @return {boolean}
|
||||
@@ -132,8 +245,12 @@ export class SaleReceipt extends BaseModel {
|
||||
static get relationMappings() {
|
||||
const { Customer } = require('../../Customers/models/Customer');
|
||||
const { Account } = require('../../Accounts/models/Account.model');
|
||||
const { AccountTransaction } = require('../../Accounts/models/AccountTransaction.model');
|
||||
const { ItemEntry } = require('../../TransactionItemEntry/models/ItemEntry');
|
||||
const {
|
||||
AccountTransaction,
|
||||
} = require('../../Accounts/models/AccountTransaction.model');
|
||||
const {
|
||||
ItemEntry,
|
||||
} = require('../../TransactionItemEntry/models/ItemEntry');
|
||||
const { Branch } = require('../../Branches/models/Branch.model');
|
||||
const { Document } = require('../../ChromiumlyTenancy/models/Document');
|
||||
const { Warehouse } = require('../../Warehouses/models/Warehouse.model');
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { keyBy, sumBy } from 'lodash';
|
||||
import { ItemEntry } from '@/modules/Items/models/ItemEntry';
|
||||
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
|
||||
import { TaxRateModel } from './models/TaxRate.model';
|
||||
|
||||
@Injectable()
|
||||
|
||||
@@ -4,7 +4,7 @@ import { TENANCY_DB_CONNECTION } from '../TenancyDB/TenancyDB.constants';
|
||||
|
||||
import { Item } from '../../../modules/Items/models/Item';
|
||||
import { Account } from '@/modules/Accounts/models/Account.model';
|
||||
import { ItemEntry } from '@/modules/Items/models/ItemEntry';
|
||||
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
|
||||
import { AccountTransaction } from '@/modules/Accounts/models/AccountTransaction.model';
|
||||
import { Expense } from '@/modules/Expenses/models/Expense.model';
|
||||
import { ExpenseCategory } from '@/modules/Expenses/models/ExpenseCategory.model';
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import { DiscountType } from '@/common/types/Discount';
|
||||
import { BaseModel } from '@/models/Model';
|
||||
import { BillLandedCostEntry } from '@/modules/BillLandedCosts/models/BillLandedCostEntry';
|
||||
import { Item } from '@/modules/Items/models/Item';
|
||||
import {
|
||||
getExlusiveTaxAmount,
|
||||
getInclusiveTaxAmount,
|
||||
} from '@/modules/TaxRates/utils';
|
||||
import { Model } from 'objection';
|
||||
|
||||
export class ItemEntry extends BaseModel {
|
||||
public referenceType: string;
|
||||
@@ -15,14 +19,26 @@ export class ItemEntry extends BaseModel {
|
||||
public sellAccountId: number;
|
||||
public costAccountId: number;
|
||||
|
||||
public landedCost: boolean;
|
||||
public allocatedCostAmount: number;
|
||||
public taxRate: number;
|
||||
public discount: number;
|
||||
public quantity: number;
|
||||
public rate: number;
|
||||
|
||||
public taxRate: number;
|
||||
public isInclusiveTax: number;
|
||||
|
||||
public landedCost: boolean;
|
||||
public allocatedCostAmount: number;
|
||||
|
||||
public discountType: DiscountType;
|
||||
public discount: number;
|
||||
|
||||
public adjustment: number;
|
||||
|
||||
public taxRateId: number;
|
||||
|
||||
item: Item;
|
||||
allocatedCostEntries: BillLandedCostEntry[];
|
||||
|
||||
|
||||
/**
|
||||
* Table name.
|
||||
* @returns {string}
|
||||
@@ -45,10 +61,24 @@ export class ItemEntry extends BaseModel {
|
||||
*/
|
||||
static get virtualAttributes() {
|
||||
return [
|
||||
// Amount (qty * rate)
|
||||
'amount',
|
||||
|
||||
'taxAmount',
|
||||
'amountExludingTax',
|
||||
'amountInclusingTax',
|
||||
|
||||
// Subtotal (qty * rate) + (tax inclusive)
|
||||
'subtotalInclusingTax',
|
||||
|
||||
// Subtotal Tax Exclusive (Subtotal - Tax Amount)
|
||||
'subtotalExcludingTax',
|
||||
|
||||
// Subtotal (qty * rate) + (tax inclusive)
|
||||
'subtotal',
|
||||
|
||||
// Discount (Is percentage ? amount * discount : discount)
|
||||
'discountAmount',
|
||||
|
||||
// Total (Subtotal - Discount)
|
||||
'total',
|
||||
];
|
||||
}
|
||||
@@ -59,7 +89,15 @@ export class ItemEntry extends BaseModel {
|
||||
* @returns {number}
|
||||
*/
|
||||
get total() {
|
||||
return this.amountInclusingTax;
|
||||
return this.subtotal - this.discountAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Total (excluding tax).
|
||||
* @returns {number}
|
||||
*/
|
||||
get totalExcludingTax() {
|
||||
return this.subtotalExcludingTax - this.discountAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,19 +109,27 @@ export class ItemEntry extends BaseModel {
|
||||
return this.quantity * this.rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtotal amount (tax inclusive).
|
||||
* @returns {number}
|
||||
*/
|
||||
get subtotal() {
|
||||
return this.subtotalInclusingTax;
|
||||
}
|
||||
|
||||
/**
|
||||
* Item entry amount including tax.
|
||||
* @returns {number}
|
||||
*/
|
||||
get amountInclusingTax() {
|
||||
get subtotalInclusingTax() {
|
||||
return this.isInclusiveTax ? this.amount : this.amount + this.taxAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Item entry amount excluding tax.
|
||||
* Subtotal amount (tax exclusive).
|
||||
* @returns {number}
|
||||
*/
|
||||
get amountExludingTax() {
|
||||
get subtotalExcludingTax() {
|
||||
return this.isInclusiveTax ? this.amount - this.taxAmount : this.amount;
|
||||
}
|
||||
|
||||
@@ -92,7 +138,9 @@ export class ItemEntry extends BaseModel {
|
||||
* @returns {number}
|
||||
*/
|
||||
get discountAmount() {
|
||||
return this.amount * (this.discount / 100);
|
||||
return this.discountType === DiscountType.Percentage
|
||||
? this.amount * (this.discount / 100)
|
||||
: this.discount;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,121 +171,123 @@ export class ItemEntry extends BaseModel {
|
||||
/**
|
||||
* Item entry relations.
|
||||
*/
|
||||
// static get relationMappings() {
|
||||
// const Item = require('models/Item');
|
||||
// const BillLandedCostEntry = require('models/BillLandedCostEntry');
|
||||
// const SaleInvoice = require('models/SaleInvoice');
|
||||
// const Bill = require('models/Bill');
|
||||
// const SaleReceipt = require('models/SaleReceipt');
|
||||
// const SaleEstimate = require('models/SaleEstimate');
|
||||
// const ProjectTask = require('models/Task');
|
||||
// const Expense = require('models/Expense');
|
||||
// const TaxRate = require('models/TaxRate');
|
||||
static get relationMappings() {
|
||||
const { Item } = require('../../Items/models/Item');
|
||||
const { SaleInvoice } = require('../../SaleInvoices/models/SaleInvoice');
|
||||
const {
|
||||
BillLandedCostEntry,
|
||||
} = require('../../BillLandedCosts/models/BillLandedCostEntry');
|
||||
const { Bill } = require('../../Bills/models/Bill');
|
||||
const { SaleReceipt } = require('../../SaleReceipts/models/SaleReceipt');
|
||||
const { SaleEstimate } = require('../../SaleEstimates/models/SaleEstimate');
|
||||
const { Expense } = require('../../Expenses/models/Expense.model');
|
||||
const { TaxRate } = require('../../TaxRates/models/TaxRate.model');
|
||||
// const ProjectTask = require('models/Task');
|
||||
|
||||
// return {
|
||||
// item: {
|
||||
// relation: Model.BelongsToOneRelation,
|
||||
// modelClass: Item.default,
|
||||
// join: {
|
||||
// from: 'items_entries.itemId',
|
||||
// to: 'items.id',
|
||||
// },
|
||||
// },
|
||||
// allocatedCostEntries: {
|
||||
// relation: Model.HasManyRelation,
|
||||
// modelClass: BillLandedCostEntry.default,
|
||||
// join: {
|
||||
// from: 'items_entries.referenceId',
|
||||
// to: 'bill_located_cost_entries.entryId',
|
||||
// },
|
||||
// },
|
||||
return {
|
||||
item: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
modelClass: Item,
|
||||
join: {
|
||||
from: 'items_entries.itemId',
|
||||
to: 'items.id',
|
||||
},
|
||||
},
|
||||
allocatedCostEntries: {
|
||||
relation: Model.HasManyRelation,
|
||||
modelClass: BillLandedCostEntry,
|
||||
join: {
|
||||
from: 'items_entries.referenceId',
|
||||
to: 'bill_located_cost_entries.entryId',
|
||||
},
|
||||
},
|
||||
|
||||
// invoice: {
|
||||
// relation: Model.BelongsToOneRelation,
|
||||
// modelClass: SaleInvoice.default,
|
||||
// join: {
|
||||
// from: 'items_entries.referenceId',
|
||||
// to: 'sales_invoices.id',
|
||||
// },
|
||||
// },
|
||||
invoice: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
modelClass: SaleInvoice,
|
||||
join: {
|
||||
from: 'items_entries.referenceId',
|
||||
to: 'sales_invoices.id',
|
||||
},
|
||||
},
|
||||
|
||||
// bill: {
|
||||
// relation: Model.BelongsToOneRelation,
|
||||
// modelClass: Bill.default,
|
||||
// join: {
|
||||
// from: 'items_entries.referenceId',
|
||||
// to: 'bills.id',
|
||||
// },
|
||||
// },
|
||||
bill: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
modelClass: Bill,
|
||||
join: {
|
||||
from: 'items_entries.referenceId',
|
||||
to: 'bills.id',
|
||||
},
|
||||
},
|
||||
|
||||
// estimate: {
|
||||
// relation: Model.BelongsToOneRelation,
|
||||
// modelClass: SaleEstimate.default,
|
||||
// join: {
|
||||
// from: 'items_entries.referenceId',
|
||||
// to: 'sales_estimates.id',
|
||||
// },
|
||||
// },
|
||||
estimate: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
modelClass: SaleEstimate,
|
||||
join: {
|
||||
from: 'items_entries.referenceId',
|
||||
to: 'sales_estimates.id',
|
||||
},
|
||||
},
|
||||
|
||||
// /**
|
||||
// * Sale receipt reference.
|
||||
// */
|
||||
// receipt: {
|
||||
// relation: Model.BelongsToOneRelation,
|
||||
// modelClass: SaleReceipt.default,
|
||||
// join: {
|
||||
// from: 'items_entries.referenceId',
|
||||
// to: 'sales_receipts.id',
|
||||
// },
|
||||
// },
|
||||
/**
|
||||
* Sale receipt reference.
|
||||
*/
|
||||
receipt: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
modelClass: SaleReceipt,
|
||||
join: {
|
||||
from: 'items_entries.referenceId',
|
||||
to: 'sales_receipts.id',
|
||||
},
|
||||
},
|
||||
|
||||
// /**
|
||||
// * Project task reference.
|
||||
// */
|
||||
// projectTaskRef: {
|
||||
// relation: Model.HasManyRelation,
|
||||
// modelClass: ProjectTask.default,
|
||||
// join: {
|
||||
// from: 'items_entries.projectRefId',
|
||||
// to: 'tasks.id',
|
||||
// },
|
||||
// },
|
||||
/**
|
||||
* Project task reference.
|
||||
*/
|
||||
// projectTaskRef: {
|
||||
// relation: Model.HasManyRelation,
|
||||
// modelClass: ProjectTask.default,
|
||||
// join: {
|
||||
// from: 'items_entries.projectRefId',
|
||||
// to: 'tasks.id',
|
||||
// },
|
||||
// },
|
||||
|
||||
// /**
|
||||
// * Project expense reference.
|
||||
// */
|
||||
// projectExpenseRef: {
|
||||
// relation: Model.HasManyRelation,
|
||||
// modelClass: Expense.default,
|
||||
// join: {
|
||||
// from: 'items_entries.projectRefId',
|
||||
// to: 'expenses_transactions.id',
|
||||
// },
|
||||
// },
|
||||
/**
|
||||
* Project expense reference.
|
||||
*/
|
||||
// projectExpenseRef: {
|
||||
// relation: Model.HasManyRelation,
|
||||
// modelClass: Expense.default,
|
||||
// join: {
|
||||
// from: 'items_entries.projectRefId',
|
||||
// to: 'expenses_transactions.id',
|
||||
// },
|
||||
// },
|
||||
|
||||
// /**
|
||||
// * Project bill reference.
|
||||
// */
|
||||
// projectBillRef: {
|
||||
// relation: Model.HasManyRelation,
|
||||
// modelClass: Bill.default,
|
||||
// join: {
|
||||
// from: 'items_entries.projectRefId',
|
||||
// to: 'bills.id',
|
||||
// },
|
||||
// },
|
||||
/**
|
||||
* Project bill reference.
|
||||
*/
|
||||
// projectBillRef: {
|
||||
// relation: Model.HasManyRelation,
|
||||
// modelClass: Bill,
|
||||
// join: {
|
||||
// from: 'items_entries.projectRefId',
|
||||
// to: 'bills.id',
|
||||
// },
|
||||
// },
|
||||
|
||||
// /**
|
||||
// * Tax rate reference.
|
||||
// */
|
||||
// tax: {
|
||||
// relation: Model.HasOneRelation,
|
||||
// modelClass: TaxRate.default,
|
||||
// join: {
|
||||
// from: 'items_entries.taxRateId',
|
||||
// to: 'tax_rates.id',
|
||||
// },
|
||||
// },
|
||||
// };
|
||||
// }
|
||||
/**
|
||||
* Tax rate reference.
|
||||
*/
|
||||
tax: {
|
||||
relation: Model.HasOneRelation,
|
||||
modelClass: TaxRate,
|
||||
join: {
|
||||
from: 'items_entries.taxRateId',
|
||||
to: 'tax_rates.id',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ import { VendorCreditsApplicationService } from './VendorCreditsApplication.serv
|
||||
import { OpenVendorCreditService } from './commands/OpenVendorCredit.service';
|
||||
import { VendorCreditGlEntriesSubscriber } from './subscribers/VendorCreditGLEntriesSubscriber';
|
||||
import { VendorCreditGLEntries } from './commands/VendorCreditGLEntries';
|
||||
import { LedgerModule } from '../Ledger/Ledger.module';
|
||||
import { AccountsModule } from '../Accounts/Accounts.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -28,6 +30,8 @@ import { VendorCreditGLEntries } from './commands/VendorCreditGLEntries';
|
||||
AutoIncrementOrdersModule,
|
||||
BranchesModule,
|
||||
WarehousesModule,
|
||||
LedgerModule,
|
||||
AccountsModule
|
||||
],
|
||||
providers: [
|
||||
CreateVendorCreditService,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ItemEntry } from '@/modules/Items/models/ItemEntry';
|
||||
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
|
||||
import { VendorCredit } from '../models/VendorCredit';
|
||||
import { ILedgerEntry } from '@/modules/Ledger/types/Ledger.types';
|
||||
import { AccountNormal } from '@/interfaces/Account';
|
||||
@@ -96,7 +96,7 @@ export class VendorCreditGL {
|
||||
credit: totalLocal,
|
||||
index: index + 2,
|
||||
itemId: entry.itemId,
|
||||
itemQuantity: entry.quantity,
|
||||
// itemQuantity: entry.quantity,
|
||||
accountId:
|
||||
'inventory' === entry.item.type
|
||||
? entry.item.inventoryAccountId
|
||||
@@ -156,6 +156,10 @@ export class VendorCreditGL {
|
||||
return [payableEntry, discountEntry, adjustmentEntry, ...itemsEntries];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the vendor credit ledger.
|
||||
* @returns {Ledger}
|
||||
*/
|
||||
public getVendorCreditLedger(): Ledger {
|
||||
const entries = this.getVendorCreditGLEntries();
|
||||
return new Ledger(entries);
|
||||
|
||||
@@ -10,7 +10,7 @@ import { Model, raw, mixin } from 'objection';
|
||||
import { Vendor } from '@/modules/Vendors/models/Vendor';
|
||||
import { Warehouse } from '@/modules/Warehouses/models/Warehouse.model';
|
||||
import { Branch } from '@/modules/Branches/models/Branch.model';
|
||||
import { ItemEntry } from '@/modules/Items/models/ItemEntry';
|
||||
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
|
||||
import { BaseModel } from '@/models/Model';
|
||||
import { DiscountType } from '@/common/types/Discount';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user