Skip to content

Commit

Permalink
fix: discount transactions GL entries
Browse files Browse the repository at this point in the history
  • Loading branch information
abouolia committed Dec 8, 2024
1 parent 14ae978 commit 46719ef
Show file tree
Hide file tree
Showing 17 changed files with 375 additions and 58 deletions.
60 changes: 47 additions & 13 deletions packages/server/src/database/seeds/data/accounts.js
Original file line number Diff line number Diff line change
@@ -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',
Expand Down Expand Up @@ -39,8 +50,38 @@ export const StripeClearingAccount = {
code: '100020',
active: true,
index: 1,
predefined: true,
}
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 default [
{
Expand Down Expand Up @@ -231,17 +272,7 @@ export default [
},

// Expenses
{
name: 'Other Expenses',
slug: 'other-expenses',
account_type: 'other-expense',
parent_account_id: null,
code: '40001',
description: '',
active: 1,
index: 1,
predefined: 1,
},
OtherExpensesAccount,
{
name: 'Cost of Goods Sold',
slug: 'cost-of-goods-sold',
Expand Down Expand Up @@ -358,4 +389,7 @@ export default [
},
UnearnedRevenueAccount,
PrepardExpenses,
DiscountExpenseAccount,
PurchaseDiscountAccount,
OtherChargesAccount,
];
5 changes: 5 additions & 0 deletions packages/server/src/interfaces/SaleInvoice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ export interface ISaleInvoice {
pdfTemplateId?: number;

paymentMethods?: Array<PaymentIntegrationTransactionLink>;

adjustment?: number;

discount?: number;
discountAmount?: number;
}

export enum DiscountType {
Expand Down
12 changes: 6 additions & 6 deletions packages/server/src/models/Bill.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Model, raw, mixin } from 'objection';
import { castArray, defaultTo, difference } from 'lodash';
import moment from 'moment';
import * as R from 'ramda';
import TenantModel from 'models/TenantModel';
import BillSettings from './Bill.Settings';
import ModelSetting from './ModelSetting';
Expand Down Expand Up @@ -133,12 +134,11 @@ export default class Bill extends mixin(TenantModel, [
get total() {
const adjustmentAmount = defaultTo(this.adjustment, 0);

return this.isInclusiveTax
? this.subtotal - this.discountAmount - adjustmentAmount
: this.subtotal +
this.taxAmountWithheld -
this.discountAmount -
adjustmentAmount;
return R.compose(
R.add(adjustmentAmount),
R.subtract(this.discountAmount),
R.when(R.always(this.isInclusiveTax), R.add(this.taxAmountWithheld))
)(this.subtotal);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/server/src/models/CreditNote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export default class CreditNote extends mixin(TenantModel, [
* @returns {number}
*/
get total() {
return this.subtotal - this.discountAmount - this.adjustment;
return this.subtotal - this.discountAmount + this.adjustment;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/server/src/models/SaleEstimate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export default class SaleEstimate extends mixin(TenantModel, [
get total() {
const adjustmentAmount = defaultTo(this.adjustment, 0);

return this.subtotal - this.discountAmount - adjustmentAmount;
return this.subtotal - this.discountAmount + adjustmentAmount;
}

/**
Expand Down
14 changes: 7 additions & 7 deletions packages/server/src/models/SaleInvoice.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { mixin, Model, raw } from 'objection';
import * as R from 'ramda';
import { castArray, defaultTo, takeWhile } from 'lodash';
import moment from 'moment';
import TenantModel from 'models/TenantModel';
Expand Down Expand Up @@ -147,9 +148,7 @@ export default class SaleInvoice extends mixin(TenantModel, [
* @returns {number | null}
*/
get discountPercentage(): number | null {
return this.discountType === DiscountType.Percentage
? this.discount
: null;
return this.discountType === DiscountType.Percentage ? this.discount : null;
}

/**
Expand All @@ -158,11 +157,12 @@ export default class SaleInvoice extends mixin(TenantModel, [
*/
get total() {
const adjustmentAmount = defaultTo(this.adjustment, 0);
const differencies = this.discountAmount + adjustmentAmount;

return this.isInclusiveTax
? this.subtotal - differencies
: this.subtotal + this.taxAmountWithheld - differencies;
return R.compose(
R.add(adjustmentAmount),
R.subtract(R.__, this.discountAmount),
R.when(R.always(this.isInclusiveTax), R.add(this.taxAmountWithheld))
)(this.subtotal);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/server/src/models/SaleReceipt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export default class SaleReceipt extends mixin(TenantModel, [
get total() {
const adjustmentAmount = defaultTo(this.adjustment, 0);

return this.subtotal - this.discountAmount - adjustmentAmount;
return this.subtotal - this.discountAmount + adjustmentAmount;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/server/src/models/VendorCredit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export default class VendorCredit extends mixin(TenantModel, [
* @returns {number}
*/
get total() {
return this.subtotal - this.discountAmount - this.adjustment;
return this.subtotal - this.discountAmount + this.adjustment;
}

/**
Expand Down
133 changes: 123 additions & 10 deletions packages/server/src/repositories/AccountRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import TenantRepository from '@/repositories/TenantRepository';
import { IAccount } from '@/interfaces';
import { Knex } from 'knex';
import {
DiscountExpenseAccount,
OtherChargesAccount,
OtherExpensesAccount,
PrepardExpenses,
PurchaseDiscountAccount,
StripeClearingAccount,
TaxPayableAccount,
UnearnedRevenueAccount,
Expand Down Expand Up @@ -188,9 +192,9 @@ export default class AccountRepository extends TenantRepository {

/**
* Finds or creates the unearned revenue.
* @param {Record<string, string>} extraAttrs
* @param {Knex.Transaction} trx
* @returns
* @param {Record<string, string>} extraAttrs
* @param {Knex.Transaction} trx
* @returns
*/
public async findOrCreateUnearnedRevenue(
extraAttrs: Record<string, string> = {},
Expand Down Expand Up @@ -219,9 +223,9 @@ export default class AccountRepository extends TenantRepository {

/**
* Finds or creates the prepard expenses account.
* @param {Record<string, string>} extraAttrs
* @param {Knex.Transaction} trx
* @returns
* @param {Record<string, string>} extraAttrs
* @param {Knex.Transaction} trx
* @returns
*/
public async findOrCreatePrepardExpenses(
extraAttrs: Record<string, string> = {},
Expand Down Expand Up @@ -249,12 +253,11 @@ export default class AccountRepository extends TenantRepository {
return result;
}


/**
* Finds or creates the stripe clearing account.
* @param {Record<string, string>} extraAttrs
* @param {Knex.Transaction} trx
* @returns
* @param {Record<string, string>} extraAttrs
* @param {Knex.Transaction} trx
* @returns
*/
public async findOrCreateStripeClearing(
extraAttrs: Record<string, string> = {},
Expand All @@ -281,4 +284,114 @@ export default class AccountRepository extends TenantRepository {
}
return result;
}

/**
* Finds or creates the discount expense account.
* @param {Record<string, string>} extraAttrs
* @param {Knex.Transaction} trx
* @returns
*/
public async findOrCreateDiscountAccount(
extraAttrs: Record<string, string> = {},
trx?: Knex.Transaction
) {
// Retrieves the given tenant metadata.
const tenantMeta = await TenantMetadata.query().findOne({
tenantId: this.tenantId,
});
const _extraAttrs = {
currencyCode: tenantMeta.baseCurrency,
...extraAttrs,
};

let result = await this.model
.query(trx)
.findOne({ slug: DiscountExpenseAccount.slug, ..._extraAttrs });

if (!result) {
result = await this.model.query(trx).insertAndFetch({
...DiscountExpenseAccount,
..._extraAttrs,
});
}
return result;
}

public async findOrCreatePurchaseDiscountAccount(
extraAttrs: Record<string, string> = {},
trx?: Knex.Transaction
) {
// Retrieves the given tenant metadata.
const tenantMeta = await TenantMetadata.query().findOne({
tenantId: this.tenantId,
});
const _extraAttrs = {
currencyCode: tenantMeta.baseCurrency,
...extraAttrs,
};

let result = await this.model
.query(trx)
.findOne({ slug: PurchaseDiscountAccount.slug, ..._extraAttrs });

if (!result) {
result = await this.model.query(trx).insertAndFetch({
...PurchaseDiscountAccount,
..._extraAttrs,
});
}
return result;
}

public async findOrCreateOtherChargesAccount(
extraAttrs: Record<string, string> = {},
trx?: Knex.Transaction
) {
// Retrieves the given tenant metadata.
const tenantMeta = await TenantMetadata.query().findOne({
tenantId: this.tenantId,
});
const _extraAttrs = {
currencyCode: tenantMeta.baseCurrency,
...extraAttrs,
};

let result = await this.model
.query(trx)
.findOne({ slug: OtherChargesAccount.slug, ..._extraAttrs });

if (!result) {
result = await this.model.query(trx).insertAndFetch({
...OtherChargesAccount,
..._extraAttrs,
});
}
return result;
}

public async findOrCreateOtherExpensesAccount(
extraAttrs: Record<string, string> = {},
trx?: Knex.Transaction
) {
// Retrieves the given tenant metadata.
const tenantMeta = await TenantMetadata.query().findOne({
tenantId: this.tenantId,
});
const _extraAttrs = {
currencyCode: tenantMeta.baseCurrency,
...extraAttrs,
};

let result = await this.model
.query(trx)
.findOne({ slug: OtherExpensesAccount.slug, ..._extraAttrs });

if (!result) {
result = await this.model.query(trx).insertAndFetch({
...OtherExpensesAccount,
..._extraAttrs,
});
}
return result;
}
}
Loading

0 comments on commit 46719ef

Please sign in to comment.