feat: discount sale and purchase transactions

This commit is contained in:
Ahmed Bouhuolia
2024-11-28 11:14:16 +02:00
parent aa4aaeb612
commit df8391201f
19 changed files with 377 additions and 10 deletions

View File

@@ -1,5 +1,5 @@
import { Model, raw, mixin } from 'objection';
import { castArray, difference } from 'lodash';
import { castArray, defaultTo, difference } from 'lodash';
import moment from 'moment';
import TenantModel from 'models/TenantModel';
import BillSettings from './Bill.Settings';
@@ -7,6 +7,7 @@ import ModelSetting from './ModelSetting';
import CustomViewBaseModel from './CustomViewBaseModel';
import { DEFAULT_VIEWS } from '@/services/Purchases/Bills/constants';
import ModelSearchable from './ModelSearchable';
import { DiscountType } from '@/interfaces';
export default class Bill extends mixin(TenantModel, [
ModelSetting,
@@ -21,6 +22,11 @@ export default class Bill extends mixin(TenantModel, [
public taxAmountWithheld: number;
public exchangeRate: number;
public discount: number;
public discountType: DiscountType;
public adjustment: number;
/**
* Timestamps columns.
*/
@@ -103,9 +109,15 @@ export default class Bill extends mixin(TenantModel, [
* @returns {number}
*/
get total() {
const discountAmount = this.discountType === DiscountType.Amount
? this.discount
: this.subtotal * (this.discount / 100);
const adjustmentAmount = defaultTo(this.adjustment, 0);
return this.isInclusiveTax
? this.subtotal
: this.subtotal + this.taxAmountWithheld;
? this.subtotal - discountAmount - adjustmentAmount
: this.subtotal + this.taxAmountWithheld - discountAmount - adjustmentAmount;
}
/**

View File

@@ -5,12 +5,20 @@ import CustomViewBaseModel from './CustomViewBaseModel';
import { DEFAULT_VIEWS } from '@/services/CreditNotes/constants';
import ModelSearchable from './ModelSearchable';
import CreditNoteMeta from './CreditNote.Meta';
import { DiscountType } from '@/interfaces';
export default class CreditNote extends mixin(TenantModel, [
ModelSetting,
CustomViewBaseModel,
ModelSearchable,
]) {
public amount: number;
public exchangeRate: number;
public openedAt: Date;
public discount: number;
public discountType: DiscountType;
public adjustment: number;
/**
* Table name
*/
@@ -48,6 +56,42 @@ export default class CreditNote extends mixin(TenantModel, [
return this.amount * this.exchangeRate;
}
/**
* Credit note subtotal.
* @returns {number}
*/
get subtotal() {
return this.amount;
}
/**
* Credit note subtotal in local currency.
* @returns {number}
*/
get subtotalLocal() {
return this.subtotal * this.exchangeRate;
}
/**
* Credit note total.
* @returns {number}
*/
get total() {
const discountAmount = this.discountType === DiscountType.Amount
? this.discount
: this.subtotal * (this.discount / 100);
return this.subtotal - discountAmount - this.adjustment;
}
/**
* Credit note total in local currency.
* @returns {number}
*/
get totalLocal() {
return this.total * this.exchangeRate;
}
/**
* Detarmines whether the credit note is draft.
* @returns {boolean}

View File

@@ -7,12 +7,22 @@ import ModelSetting from './ModelSetting';
import CustomViewBaseModel from './CustomViewBaseModel';
import { DEFAULT_VIEWS } from '@/services/Sales/Estimates/constants';
import ModelSearchable from './ModelSearchable';
import { DiscountType } from '@/interfaces';
import { defaultTo } from 'lodash';
export default class SaleEstimate extends mixin(TenantModel, [
ModelSetting,
CustomViewBaseModel,
ModelSearchable,
]) {
public amount: number;
public exchangeRate: number;
public discount: number;
public discountType: DiscountType;
public adjustment: number;
/**
* Table name
*/
@@ -49,6 +59,44 @@ export default class SaleEstimate extends mixin(TenantModel, [
return this.amount * this.exchangeRate;
}
/**
* Estimate subtotal.
* @returns {number}
*/
get subtotal() {
return this.amount;;
}
/**
* Estimate subtotal in local currency.
* @returns {number}
*/
get subtotalLocal() {
return this.localAmount;
}
/**
* Estimate total.
* @returns {number}
*/
get total() {
const discountAmount = this.discountType === DiscountType.Amount
? this.discount
: this.subtotal * (this.discount / 100);
const adjustmentAmount = defaultTo(this.adjustment, 0);
return this.subtotal - discountAmount - adjustmentAmount;
}
/**
* Estimate total in local currency.
* @returns {number}
*/
get totalLocal() {
return this.total * this.exchangeRate;
}
/**
* Detarmines whether the sale estimate converted to sale invoice.
* @return {boolean}

View File

@@ -1,5 +1,5 @@
import { mixin, Model, raw } from 'objection';
import { castArray, takeWhile } from 'lodash';
import { castArray, defaultTo, takeWhile } from 'lodash';
import moment from 'moment';
import TenantModel from 'models/TenantModel';
import ModelSetting from './ModelSetting';
@@ -7,6 +7,7 @@ import SaleInvoiceMeta from './SaleInvoice.Settings';
import CustomViewBaseModel from './CustomViewBaseModel';
import { DEFAULT_VIEWS } from '@/services/Sales/Invoices/constants';
import ModelSearchable from './ModelSearchable';
import { DiscountType } from '@/interfaces';
export default class SaleInvoice extends mixin(TenantModel, [
ModelSetting,
@@ -23,6 +24,10 @@ export default class SaleInvoice extends mixin(TenantModel, [
public writtenoffAt: Date;
public dueDate: Date;
public deliveredAt: Date;
public discount: number;
public discountType: DiscountType;
public adjustments: number;
/**
* Table name
@@ -130,9 +135,16 @@ export default class SaleInvoice extends mixin(TenantModel, [
* @returns {number}
*/
get total() {
const discountAmount = this.discountType === DiscountType.Amount
? this.discount
: this.subtotal * (this.discount / 100);
const adjustmentAmount = defaultTo(this.adjustments, 0);
const differencies = discountAmount + adjustmentAmount;
return this.isInclusiveTax
? this.subtotal
: this.subtotal + this.taxAmountWithheld;
? this.subtotal - differencies
: this.subtotal + this.taxAmountWithheld - differencies;
}
/**

View File

@@ -5,12 +5,23 @@ import SaleReceiptSettings from './SaleReceipt.Settings';
import CustomViewBaseModel from './CustomViewBaseModel';
import { DEFAULT_VIEWS } from '@/services/Sales/Receipts/constants';
import ModelSearchable from './ModelSearchable';
import { DiscountType } from '@/interfaces';
import { defaultTo } from 'lodash';
export default class SaleReceipt extends mixin(TenantModel, [
ModelSetting,
CustomViewBaseModel,
ModelSearchable,
]) {
public amount: number;
public exchangeRate: number;
public closedAt: Date;
public discount: number;
public discountType: DiscountType;
public adjustment: number;
/**
* Table name
*/
@@ -40,6 +51,44 @@ export default class SaleReceipt extends mixin(TenantModel, [
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;
}
/**
* Receipt total.
* @returns {number}
*/
get total() {
const discountAmount = this.discountType === DiscountType.Amount
? this.discount
: this.subtotal * (this.discount / 100);
const adjustmentAmount = defaultTo(this.adjustment, 0);
return this.subtotal - discountAmount - adjustmentAmount;
}
/**
* Receipt total in local currency.
* @returns {number}
*/
get totalLocal() {
return this.total * this.exchangeRate;
}
/**
* Detarmine whether the sale receipt closed.
* @return {boolean}

View File

@@ -6,12 +6,20 @@ import CustomViewBaseModel from './CustomViewBaseModel';
import { DEFAULT_VIEWS } from '@/services/Purchases/VendorCredits/constants';
import ModelSearchable from './ModelSearchable';
import VendorCreditMeta from './VendorCredit.Meta';
import { DiscountType } from '@/interfaces';
export default class VendorCredit extends mixin(TenantModel, [
ModelSetting,
CustomViewBaseModel,
ModelSearchable,
]) {
public amount: number;
public exchangeRate: number;
public openedAt: Date;
public discount: number;
public discountType: DiscountType;
public adjustment: number;
/**
* Table name
*/
@@ -34,6 +42,42 @@ export default class VendorCredit extends mixin(TenantModel, [
return this.amount * this.exchangeRate;
}
/**
* Vendor credit subtotal.
* @returns {number}
*/
get subtotal() {
return this.amount;
}
/**
* Vendor credit subtotal in local currency.
* @returns {number}
*/
get subtotalLocal() {
return this.subtotal * this.exchangeRate;
}
/**
* Vendor credit total.
* @returns {number}
*/
get total() {
const discountAmount = this.discountType === DiscountType.Amount
? this.discount
: this.subtotal * (this.discount / 100);
return this.subtotal - discountAmount - this.adjustment;
}
/**
* Vendor credit total in local currency.
* @returns {number}
*/
get totalLocal() {
return this.total * this.exchangeRate;
}
/**
* Model modifiers.
*/