mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-15 04:10:32 +00:00
Merge branch 'develop' into migrate-server-nestjs
This commit is contained in:
@@ -1,12 +1,14 @@
|
||||
import { Model, raw, mixin } from 'objection';
|
||||
import { castArray, difference } from 'lodash';
|
||||
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';
|
||||
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 +23,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.
|
||||
*/
|
||||
@@ -47,6 +54,13 @@ export default class Bill extends mixin(TenantModel, [
|
||||
'localAllocatedCostAmount',
|
||||
'billableAmount',
|
||||
'amountLocal',
|
||||
|
||||
'discountAmount',
|
||||
'discountAmountLocal',
|
||||
'discountPercentage',
|
||||
|
||||
'adjustmentLocal',
|
||||
|
||||
'subtotal',
|
||||
'subtotalLocal',
|
||||
'subtotalExludingTax',
|
||||
@@ -98,14 +112,53 @@ export default class Bill extends mixin(TenantModel, [
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
@@ -35,8 +43,21 @@ export default class CreditNote extends mixin(TenantModel, [
|
||||
'isPublished',
|
||||
'isOpen',
|
||||
'isClosed',
|
||||
|
||||
'creditsRemaining',
|
||||
'creditsUsed',
|
||||
|
||||
'subtotal',
|
||||
'subtotalLocal',
|
||||
|
||||
'discountAmount',
|
||||
'discountAmountLocal',
|
||||
'discountPercentage',
|
||||
|
||||
'total',
|
||||
'totalLocal',
|
||||
|
||||
'adjustmentLocal',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -48,6 +69,72 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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}
|
||||
*/
|
||||
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}
|
||||
*/
|
||||
get adjustmentLocal() {
|
||||
return this.adjustment ? this.adjustment * this.exchangeRate : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Credit note total.
|
||||
* @returns {number}
|
||||
*/
|
||||
get total() {
|
||||
return this.subtotal - this.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}
|
||||
@@ -176,6 +263,7 @@ export default class CreditNote extends mixin(TenantModel, [
|
||||
const Branch = require('models/Branch');
|
||||
const Document = require('models/Document');
|
||||
const Warehouse = require('models/Warehouse');
|
||||
const { PdfTemplate } = require('models/PdfTemplate');
|
||||
|
||||
return {
|
||||
/**
|
||||
@@ -266,6 +354,18 @@ export default class CreditNote extends mixin(TenantModel, [
|
||||
query.where('model_ref', 'CreditNote');
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Credit note may belongs to pdf branding template.
|
||||
*/
|
||||
pdfTemplate: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
modelClass: PdfTemplate,
|
||||
join: {
|
||||
from: 'credit_notes.pdfTemplateId',
|
||||
to: 'pdf_templates.id',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import { Model } from 'objection';
|
||||
import TenantModel from 'models/TenantModel';
|
||||
import { getExlusiveTaxAmount, getInclusiveTaxAmount } from '@/utils/taxRate';
|
||||
import { DiscountType } from '@/interfaces';
|
||||
|
||||
// Subtotal (qty * rate) (tax inclusive)
|
||||
// Subtotal Tax Exclusive (Subtotal - Tax Amount)
|
||||
// Discount (Is percentage ? amount * discount : discount)
|
||||
// Total (Subtotal - Discount)
|
||||
|
||||
export default class ItemEntry extends TenantModel {
|
||||
public taxRate: number;
|
||||
@@ -8,7 +14,7 @@ export default class ItemEntry extends TenantModel {
|
||||
public quantity: number;
|
||||
public rate: number;
|
||||
public isInclusiveTax: number;
|
||||
|
||||
public discountType: DiscountType;
|
||||
/**
|
||||
* Table name.
|
||||
* @returns {string}
|
||||
@@ -31,10 +37,24 @@ export default class ItemEntry extends TenantModel {
|
||||
*/
|
||||
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',
|
||||
];
|
||||
}
|
||||
@@ -45,7 +65,15 @@ export default class ItemEntry extends TenantModel {
|
||||
* @returns {number}
|
||||
*/
|
||||
get total() {
|
||||
return this.amountInclusingTax;
|
||||
return this.subtotal - this.discountAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Total (excluding tax).
|
||||
* @returns {number}
|
||||
*/
|
||||
get totalExcludingTax() {
|
||||
return this.subtotalExcludingTax - this.discountAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,19 +85,27 @@ export default class ItemEntry extends TenantModel {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -78,7 +114,9 @@ export default class ItemEntry extends TenantModel {
|
||||
* @returns {number}
|
||||
*/
|
||||
get discountAmount() {
|
||||
return this.amount * (this.discount / 100);
|
||||
return this.discountType === DiscountType.Percentage
|
||||
? this.amount * (this.discount / 100)
|
||||
: this.discount;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,6 +11,10 @@ export default class PaymentReceive extends mixin(TenantModel, [
|
||||
CustomViewBaseModel,
|
||||
ModelSearchable,
|
||||
]) {
|
||||
amount!: number;
|
||||
paymentAmount!: number;
|
||||
exchangeRate!: number;
|
||||
|
||||
/**
|
||||
* Table name.
|
||||
*/
|
||||
@@ -29,7 +33,7 @@ export default class PaymentReceive extends mixin(TenantModel, [
|
||||
* Virtual attributes.
|
||||
*/
|
||||
static get virtualAttributes() {
|
||||
return ['localAmount'];
|
||||
return ['localAmount', 'total'];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -40,6 +44,14 @@ export default class PaymentReceive extends mixin(TenantModel, [
|
||||
return this.amount * this.exchangeRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Payment receive total.
|
||||
* @returns {number}
|
||||
*/
|
||||
get total() {
|
||||
return this.paymentAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resourcable model.
|
||||
*/
|
||||
@@ -57,6 +69,7 @@ export default class PaymentReceive extends mixin(TenantModel, [
|
||||
const Account = require('models/Account');
|
||||
const Branch = require('models/Branch');
|
||||
const Document = require('models/Document');
|
||||
const { PdfTemplate } = require('models/PdfTemplate');
|
||||
|
||||
return {
|
||||
customer: {
|
||||
@@ -131,6 +144,18 @@ export default class PaymentReceive extends mixin(TenantModel, [
|
||||
query.where('model_ref', 'PaymentReceive');
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Payment received may belongs to pdf branding template.
|
||||
*/
|
||||
pdfTemplate: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
modelClass: PdfTemplate,
|
||||
join: {
|
||||
from: 'payment_receives.pdfTemplateId',
|
||||
to: 'pdf_templates.id',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -7,12 +7,30 @@ 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;
|
||||
|
||||
public expirationDate!: string;
|
||||
public deliveredAt!: string | null;
|
||||
public approvedAt!: string | null;
|
||||
public rejectedAt!: string | null;
|
||||
|
||||
public convertedToInvoiceId!: number | null;
|
||||
public convertedToInvoiceAt!: string | null;
|
||||
|
||||
/**
|
||||
* Table name
|
||||
*/
|
||||
@@ -33,6 +51,12 @@ export default class SaleEstimate extends mixin(TenantModel, [
|
||||
static get virtualAttributes() {
|
||||
return [
|
||||
'localAmount',
|
||||
'discountAmount',
|
||||
'discountPercentage',
|
||||
'total',
|
||||
'totalLocal',
|
||||
'subtotal',
|
||||
'subtotalLocal',
|
||||
'isDelivered',
|
||||
'isExpired',
|
||||
'isConvertedToInvoice',
|
||||
@@ -49,6 +73,60 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Discount amount.
|
||||
* @returns {number}
|
||||
*/
|
||||
get discountAmount() {
|
||||
return this.discountType === DiscountType.Amount
|
||||
? this.discount
|
||||
: this.subtotal * (this.discount / 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Discount percentage.
|
||||
* @returns {number | null}
|
||||
*/
|
||||
get discountPercentage(): number | null {
|
||||
return this.discountType === DiscountType.Percentage
|
||||
? this.discount
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate total.
|
||||
* @returns {number}
|
||||
*/
|
||||
get total() {
|
||||
const adjustmentAmount = defaultTo(this.adjustment, 0);
|
||||
|
||||
return this.subtotal - this.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}
|
||||
@@ -184,6 +262,7 @@ export default class SaleEstimate extends mixin(TenantModel, [
|
||||
const Branch = require('models/Branch');
|
||||
const Warehouse = require('models/Warehouse');
|
||||
const Document = require('models/Document');
|
||||
const { PdfTemplate } = require('models/PdfTemplate');
|
||||
|
||||
return {
|
||||
customer: {
|
||||
@@ -252,6 +331,18 @@ export default class SaleEstimate extends mixin(TenantModel, [
|
||||
query.where('model_ref', 'SaleEstimate');
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Sale estimate may belongs to pdf branding template.
|
||||
*/
|
||||
pdfTemplate: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
modelClass: PdfTemplate,
|
||||
join: {
|
||||
from: 'sales_estimates.pdfTemplateId',
|
||||
to: 'pdf_templates.id',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { mixin, Model, raw } from 'objection';
|
||||
import { castArray, takeWhile } from 'lodash';
|
||||
import * as R from 'ramda';
|
||||
import { castArray, defaultTo, takeWhile } from 'lodash';
|
||||
import moment from 'moment';
|
||||
import TenantModel from 'models/TenantModel';
|
||||
import ModelSetting from './ModelSetting';
|
||||
@@ -7,6 +8,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,
|
||||
@@ -24,6 +26,9 @@ export default class SaleInvoice extends mixin(TenantModel, [
|
||||
public dueDate: Date;
|
||||
public deliveredAt: Date;
|
||||
public pdfTemplateId: number;
|
||||
public discount: number;
|
||||
public discountType: DiscountType;
|
||||
public adjustment: number | null;
|
||||
|
||||
/**
|
||||
* Table name
|
||||
@@ -68,10 +73,15 @@ export default class SaleInvoice extends mixin(TenantModel, [
|
||||
'subtotalExludingTax',
|
||||
|
||||
'taxAmountWithheldLocal',
|
||||
'discountAmount',
|
||||
'discountAmountLocal',
|
||||
'discountPercentage',
|
||||
|
||||
'total',
|
||||
'totalLocal',
|
||||
|
||||
'writtenoffAmountLocal',
|
||||
'adjustmentLocal',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -126,14 +136,52 @@ export default class SaleInvoice extends mixin(TenantModel, [
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -605,7 +653,7 @@ export default class SaleInvoice extends mixin(TenantModel, [
|
||||
join: {
|
||||
from: 'sales_invoices.pdfTemplateId',
|
||||
to: 'pdf_templates.id',
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
@@ -29,7 +40,28 @@ export default class SaleReceipt extends mixin(TenantModel, [
|
||||
* Virtual attributes.
|
||||
*/
|
||||
static get virtualAttributes() {
|
||||
return ['localAmount', 'isClosed', 'isDraft'];
|
||||
return [
|
||||
'localAmount',
|
||||
|
||||
'subtotal',
|
||||
'subtotalLocal',
|
||||
|
||||
'total',
|
||||
'totalLocal',
|
||||
|
||||
'adjustment',
|
||||
'adjustmentLocal',
|
||||
|
||||
'discountAmount',
|
||||
'discountAmountLocal',
|
||||
'discountPercentage',
|
||||
|
||||
'paid',
|
||||
'paidLocal',
|
||||
|
||||
'isClosed',
|
||||
'isDraft',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -40,6 +72,90 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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}
|
||||
|
||||
@@ -6,26 +6,26 @@ 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
|
||||
*/
|
||||
static get tableName() {
|
||||
return 'vendor_credits';
|
||||
}
|
||||
|
||||
/**
|
||||
* Virtual attributes.
|
||||
*/
|
||||
static get virtualAttributes() {
|
||||
return ['localAmount'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Vendor credit amount in local currency.
|
||||
* @returns {number}
|
||||
@@ -34,6 +34,72 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vendor credit total.
|
||||
* @returns {number}
|
||||
*/
|
||||
get total() {
|
||||
return this.subtotal - this.discountAmount + this.adjustment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vendor credit total in local currency.
|
||||
* @returns {number}
|
||||
*/
|
||||
get totalLocal() {
|
||||
return this.total * this.exchangeRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Model modifiers.
|
||||
*/
|
||||
@@ -120,7 +186,24 @@ export default class VendorCredit extends mixin(TenantModel, [
|
||||
* Virtual attributes.
|
||||
*/
|
||||
static get virtualAttributes() {
|
||||
return ['isDraft', 'isPublished', 'isOpen', 'isClosed', 'creditsRemaining'];
|
||||
return [
|
||||
'isDraft',
|
||||
'isPublished',
|
||||
'isOpen',
|
||||
'isClosed',
|
||||
|
||||
'creditsRemaining',
|
||||
'localAmount',
|
||||
|
||||
'discountAmount',
|
||||
'discountAmountLocal',
|
||||
'discountPercentage',
|
||||
|
||||
'adjustmentLocal',
|
||||
|
||||
'total',
|
||||
'totalLocal',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user