mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-18 13:50:31 +00:00
feat: discount sale and purchase transactions
This commit is contained in:
@@ -183,6 +183,13 @@ export default class VendorCreditController extends BaseController {
|
||||
|
||||
check('attachments').isArray().optional(),
|
||||
check('attachments.*.key').exists().isString(),
|
||||
|
||||
// Discount.
|
||||
check('discount').optional({ nullable: true }).isNumeric().toFloat(),
|
||||
check('discount_type').optional({ nullable: true }).isString().trim(),
|
||||
|
||||
// Adjustment.
|
||||
check('adjustment').optional({ nullable: true }).isNumeric().toFloat(),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -244,11 +244,19 @@ export default class PaymentReceivesController extends BaseController {
|
||||
.isNumeric()
|
||||
.toInt(),
|
||||
|
||||
// Attachments.
|
||||
check('attachments').isArray().optional(),
|
||||
check('attachments.*.key').exists().isString(),
|
||||
|
||||
// Pdf template id.
|
||||
check('pdf_template_id').optional({ nullable: true }).isNumeric().toInt(),
|
||||
|
||||
// Discount.
|
||||
check('discount').optional({ nullable: true }).isNumeric().toFloat(),
|
||||
check('discount_type').optional({ nullable: true }).isString().trim(),
|
||||
|
||||
// Adjustment.
|
||||
check('adjustment').optional({ nullable: true }).isNumeric().toFloat(),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import { body, check, param, query } from 'express-validator';
|
||||
import { Inject, Service } from 'typedi';
|
||||
import {
|
||||
AbilitySubject,
|
||||
DiscountType,
|
||||
ISaleEstimateDTO,
|
||||
SaleEstimateAction,
|
||||
SaleEstimateMailOptionsDTO,
|
||||
@@ -195,11 +196,21 @@ export default class SalesEstimatesController extends BaseController {
|
||||
check('terms_conditions').optional().trim(),
|
||||
check('send_to_email').optional().trim(),
|
||||
|
||||
// # Attachments
|
||||
check('attachments').isArray().optional(),
|
||||
check('attachments.*.key').exists().isString(),
|
||||
|
||||
// Pdf template id.
|
||||
// # Pdf template id.
|
||||
check('pdf_template_id').optional({ nullable: true }).isNumeric().toInt(),
|
||||
|
||||
// # Discount
|
||||
check('discount').optional().isNumeric().toFloat(),
|
||||
check('discount_type')
|
||||
.default(DiscountType.Amount)
|
||||
.isIn([DiscountType.Amount, DiscountType.Percentage]),
|
||||
|
||||
// # Adjustment
|
||||
check('adjustment').optional().isNumeric().toFloat(),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* @param { import("knex").Knex } knex
|
||||
* @returns { Promise<void> }
|
||||
*/
|
||||
exports.up = function(knex) {
|
||||
return knex.schema.alterTable('sales_estimates', (table) => {
|
||||
table.decimal('discount', 10, 2).nullable().after('credited_amount');
|
||||
table.string('discount_type').nullable().after('discount');
|
||||
|
||||
table.decimal('adjustment', 10, 2).nullable().after('discount_type');
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param { import("knex").Knex } knex
|
||||
* @returns { Promise<void> }
|
||||
*/
|
||||
exports.down = function(knex) {
|
||||
return knex.schema.alterTable('sales_estimates', (table) => {
|
||||
table.dropColumn('discount');
|
||||
table.dropColumn('discount_type');
|
||||
table.dropColumn('adjustment');
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* @param { import("knex").Knex } knex
|
||||
* @returns { Promise<void> }
|
||||
*/
|
||||
exports.up = function(knex) {
|
||||
return knex.schema.alterTable('sales_receipts', (table) => {
|
||||
table.decimal('discount', 10, 2).nullable().after('amount');
|
||||
table.string('discount_type').nullable().after('discount');
|
||||
|
||||
table.decimal('adjustment', 10, 2).nullable().after('discount_type');
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param { import("knex").Knex } knex
|
||||
* @returns { Promise<void> }
|
||||
*/
|
||||
exports.down = function(knex) {
|
||||
return knex.schema.alterTable('sales_receipts', (table) => {
|
||||
table.dropColumn('discount');
|
||||
table.dropColumn('discount_type');
|
||||
table.dropColumn('adjustment');
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* @param { import("knex").Knex } knex
|
||||
* @returns { Promise<void> }
|
||||
*/
|
||||
exports.up = function(knex) {
|
||||
return knex.schema.alterTable('bills', (table) => {
|
||||
// Discount.
|
||||
table.decimal('discount', 10, 2).nullable().after('amount');
|
||||
table.string('discount_type').nullable().after('discount');
|
||||
|
||||
// Adjustment.
|
||||
table.decimal('adjustment', 10, 2).nullable().after('discount_type');
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param { import("knex").Knex } knex
|
||||
* @returns { Promise<void> }
|
||||
*/
|
||||
exports.down = function(knex) {
|
||||
return knex.schema.alterTable('bills', (table) => {
|
||||
table.dropColumn('discount');
|
||||
table.dropColumn('discount_type');
|
||||
table.dropColumn('adjustment');
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* @param { import("knex").Knex } knex
|
||||
* @returns { Promise<void> }
|
||||
*/
|
||||
exports.up = function(knex) {
|
||||
return knex.schema.alterTable('credit_notes', (table) => {
|
||||
table.decimal('discount', 10, 2).nullable().after('credited_amount');
|
||||
table.string('discount_type').nullable().after('discount');
|
||||
table.decimal('adjustment', 10, 2).nullable().after('discount_type');
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param { import("knex").Knex } knex
|
||||
* @returns { Promise<void> }
|
||||
*/
|
||||
exports.down = function(knex) {
|
||||
return knex.schema.alterTable('credit_notes', (table) => {
|
||||
table.dropColumn('discount');
|
||||
table.dropColumn('discount_type');
|
||||
table.dropColumn('adjustment');
|
||||
});
|
||||
};
|
||||
@@ -3,6 +3,7 @@ import { IDynamicListFilterDTO } from './DynamicFilter';
|
||||
import { IItemEntry, IItemEntryDTO } from './ItemEntry';
|
||||
import { IBillLandedCost } from './LandedCost';
|
||||
import { AttachmentLinkDTO } from './Attachments';
|
||||
import { DiscountType } from './SaleInvoice';
|
||||
|
||||
export interface IBillDTO {
|
||||
vendorId: number;
|
||||
@@ -22,6 +23,13 @@ export interface IBillDTO {
|
||||
projectId?: number;
|
||||
isInclusiveTax?: boolean;
|
||||
attachments?: AttachmentLinkDTO[];
|
||||
|
||||
// # Discount
|
||||
discount?: number;
|
||||
discountType?: DiscountType;
|
||||
|
||||
// # Adjustment
|
||||
adjustment?: number;
|
||||
}
|
||||
|
||||
export interface IBillEditDTO {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Knex } from 'knex';
|
||||
import { IDynamicListFilter, IItemEntry } from '@/interfaces';
|
||||
import { DiscountType, IDynamicListFilter, IItemEntry } from '@/interfaces';
|
||||
import { ILedgerEntry } from './Ledger';
|
||||
import { AttachmentLinkDTO } from './Attachments';
|
||||
|
||||
@@ -23,6 +23,9 @@ export interface ICreditNoteNewDTO {
|
||||
branchId?: number;
|
||||
warehouseId?: number;
|
||||
attachments?: AttachmentLinkDTO[];
|
||||
discount?: number;
|
||||
discountType?: DiscountType;
|
||||
adjustment?: number;
|
||||
}
|
||||
|
||||
export interface ICreditNoteEditDTO {
|
||||
|
||||
@@ -3,6 +3,7 @@ import { IItemEntry, IItemEntryDTO } from './ItemEntry';
|
||||
import { IDynamicListFilterDTO } from '@/interfaces/DynamicFilter';
|
||||
import { CommonMailOptions, CommonMailOptionsDTO } from './Mailable';
|
||||
import { AttachmentLinkDTO } from './Attachments';
|
||||
import { DiscountType } from './SaleInvoice';
|
||||
|
||||
export interface ISaleEstimate {
|
||||
id?: number;
|
||||
@@ -40,6 +41,13 @@ export interface ISaleEstimateDTO {
|
||||
branchId?: number;
|
||||
warehouseId?: number;
|
||||
attachments?: AttachmentLinkDTO[];
|
||||
|
||||
// # Discount
|
||||
discount?: number;
|
||||
discountType?: DiscountType;
|
||||
|
||||
// # Adjustment
|
||||
adjustment?: number;
|
||||
}
|
||||
|
||||
export interface ISalesEstimatesFilter extends IDynamicListFilterDTO {
|
||||
|
||||
@@ -82,6 +82,11 @@ export interface ISaleInvoice {
|
||||
paymentMethods?: Array<PaymentIntegrationTransactionLink>;
|
||||
}
|
||||
|
||||
export enum DiscountType {
|
||||
Percentage = 'Percentage',
|
||||
Amount = 'Amount',
|
||||
}
|
||||
|
||||
export interface ISaleInvoiceDTO {
|
||||
invoiceDate: Date;
|
||||
dueDate: Date;
|
||||
@@ -105,7 +110,7 @@ export interface ISaleInvoiceDTO {
|
||||
|
||||
// # Discount
|
||||
discount?: number;
|
||||
discountType?: string;
|
||||
discountType?: DiscountType;
|
||||
|
||||
// # Adjustments
|
||||
adjustments?: string;
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Knex } from 'knex';
|
||||
import { IItemEntry } from './ItemEntry';
|
||||
import { CommonMailOptions, CommonMailOptionsDTO } from './Mailable';
|
||||
import { AttachmentLinkDTO } from './Attachments';
|
||||
import { DiscountType } from './SaleInvoice';
|
||||
|
||||
export interface ISaleReceipt {
|
||||
id?: number;
|
||||
@@ -47,6 +48,11 @@ export interface ISaleReceiptDTO {
|
||||
entries: any[];
|
||||
branchId?: number;
|
||||
attachments?: AttachmentLinkDTO[];
|
||||
|
||||
discount?: number;
|
||||
discountType?: DiscountType;
|
||||
|
||||
adjustment?: number;
|
||||
}
|
||||
|
||||
export interface ISalesReceiptsService {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { IDynamicListFilter, IItemEntry, IItemEntryDTO } from '@/interfaces';
|
||||
import { DiscountType, IDynamicListFilter, IItemEntry, IItemEntryDTO } from '@/interfaces';
|
||||
import { Knex } from 'knex';
|
||||
import { AttachmentLinkDTO } from './Attachments';
|
||||
|
||||
@@ -63,6 +63,11 @@ export interface IVendorCreditDTO {
|
||||
branchId?: number;
|
||||
warehouseId?: number;
|
||||
attachments?: AttachmentLinkDTO[];
|
||||
|
||||
discount?: number;
|
||||
discountType?: DiscountType;
|
||||
|
||||
adjustment?: number;
|
||||
}
|
||||
|
||||
export interface IVendorCreditCreateDTO extends IVendorCreditDTO {}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user