mirror of
https://github.com/frappe/books.git
synced 2024-12-23 11:29:03 +00:00
193 lines
4.9 KiB
TypeScript
193 lines
4.9 KiB
TypeScript
import { DocValue } from 'fyo/core/types';
|
|
import { Doc } from 'fyo/model/doc';
|
|
import {
|
|
FiltersMap,
|
|
FormulaMap,
|
|
ListViewSettings,
|
|
ValidationMap,
|
|
} from 'fyo/model/types';
|
|
import { ValidationError } from 'fyo/utils/errors';
|
|
import { t } from 'fyo';
|
|
import { Money } from 'pesa';
|
|
import { ModelNameEnum } from 'models/types';
|
|
import { SalesInvoice } from '../SalesInvoice/SalesInvoice';
|
|
import { ApplicableCouponCodes } from '../Invoice/types';
|
|
|
|
export class CouponCode extends Doc {
|
|
name?: string;
|
|
couponName?: string;
|
|
pricingRule?: string;
|
|
|
|
validFrom?: Date;
|
|
validTo?: Date;
|
|
|
|
minAmount?: Money;
|
|
maxAmount?: Money;
|
|
|
|
removeUnusedCoupons(coupons: ApplicableCouponCodes[], sinvDoc: SalesInvoice) {
|
|
if (!coupons.length) {
|
|
sinvDoc.coupons = [];
|
|
|
|
return;
|
|
}
|
|
|
|
sinvDoc.coupons = sinvDoc.coupons!.filter((coupon) => {
|
|
return coupons.find((c: ApplicableCouponCodes) =>
|
|
coupon?.coupons?.includes(c?.coupon)
|
|
);
|
|
});
|
|
}
|
|
|
|
formulas: FormulaMap = {
|
|
name: {
|
|
formula: () => {
|
|
return this.couponName?.replace(/\s+/g, '').toUpperCase().slice(0, 8);
|
|
},
|
|
dependsOn: ['couponName'],
|
|
},
|
|
};
|
|
|
|
async pricingRuleData() {
|
|
return await this.fyo.db.getAll(ModelNameEnum.PricingRule, {
|
|
fields: ['minAmount', 'maxAmount', 'validFrom', 'validTo'],
|
|
filters: {
|
|
name: this.pricingRule as string,
|
|
},
|
|
});
|
|
}
|
|
|
|
validations: ValidationMap = {
|
|
minAmount: async (value: DocValue) => {
|
|
if (!value || !this.maxAmount || !this.pricingRule) {
|
|
return;
|
|
}
|
|
|
|
const [pricingRuleData] = await this.pricingRuleData();
|
|
|
|
if (
|
|
(pricingRuleData?.minAmount as Money).isZero() &&
|
|
(pricingRuleData.maxAmount as Money).isZero()
|
|
) {
|
|
return;
|
|
}
|
|
|
|
const { minAmount } = pricingRuleData;
|
|
|
|
if ((value as Money).isZero() && this.maxAmount.isZero()) {
|
|
return;
|
|
}
|
|
|
|
if ((value as Money).lt(minAmount as Money)) {
|
|
throw new ValidationError(
|
|
t`Minimum Amount should be greather than the Pricing Rule's Minimum Amount.`
|
|
);
|
|
}
|
|
|
|
if ((value as Money).gte(this.maxAmount)) {
|
|
throw new ValidationError(
|
|
t`Minimum Amount should be less than the Maximum Amount.`
|
|
);
|
|
}
|
|
},
|
|
maxAmount: async (value: DocValue) => {
|
|
if (!this.minAmount || !value || !this.pricingRule) {
|
|
return;
|
|
}
|
|
|
|
const [pricingRuleData] = await this.pricingRuleData();
|
|
|
|
if (
|
|
(pricingRuleData?.minAmount as Money).isZero() &&
|
|
(pricingRuleData.maxAmount as Money).isZero()
|
|
) {
|
|
return;
|
|
}
|
|
|
|
const { maxAmount } = pricingRuleData;
|
|
|
|
if (this.minAmount.isZero() && (value as Money).isZero()) {
|
|
return;
|
|
}
|
|
|
|
if ((value as Money).gt(maxAmount as Money)) {
|
|
throw new ValidationError(
|
|
t`Maximum Amount should be lesser than Pricing Rule's Maximum Amount`
|
|
);
|
|
}
|
|
|
|
if ((value as Money).lte(this.minAmount)) {
|
|
throw new ValidationError(
|
|
t`Maximum Amount should be greater than the Minimum Amount.`
|
|
);
|
|
}
|
|
},
|
|
validFrom: async (value: DocValue) => {
|
|
if (!value || !this.validTo || !this.pricingRule) {
|
|
return;
|
|
}
|
|
|
|
const [pricingRuleData] = await this.pricingRuleData();
|
|
|
|
if (!pricingRuleData?.validFrom && !pricingRuleData.validTo) {
|
|
return;
|
|
}
|
|
|
|
const { validFrom } = pricingRuleData;
|
|
if (
|
|
validFrom &&
|
|
(value as Date).toISOString() < (validFrom as Date).toISOString()
|
|
) {
|
|
throw new ValidationError(
|
|
t`Valid From Date should be greather than Pricing Rule's Valid From Date.`
|
|
);
|
|
}
|
|
|
|
if ((value as Date).toISOString() >= this.validTo.toISOString()) {
|
|
throw new ValidationError(
|
|
t`Valid From Date should be less than Valid To Date.`
|
|
);
|
|
}
|
|
},
|
|
validTo: async (value: DocValue) => {
|
|
if (!this.validFrom || !value || !this.pricingRule) {
|
|
return;
|
|
}
|
|
|
|
const [pricingRuleData] = await this.pricingRuleData();
|
|
|
|
if (!pricingRuleData?.validFrom && !pricingRuleData.validTo) {
|
|
return;
|
|
}
|
|
|
|
const { validTo } = pricingRuleData;
|
|
|
|
if (
|
|
validTo &&
|
|
(value as Date).toISOString() > (validTo as Date).toISOString()
|
|
) {
|
|
throw new ValidationError(
|
|
t`Valid To Date should be lesser than Pricing Rule's Valid To Date.`
|
|
);
|
|
}
|
|
|
|
if ((value as Date).toISOString() <= this.validFrom.toISOString()) {
|
|
throw new ValidationError(
|
|
t`Valid To Date should be greater than Valid From Date.`
|
|
);
|
|
}
|
|
},
|
|
};
|
|
|
|
static filters: FiltersMap = {
|
|
pricingRule: () => ({
|
|
isCouponCodeBased: true,
|
|
}),
|
|
};
|
|
|
|
static getListViewSettings(): ListViewSettings {
|
|
return {
|
|
columns: ['name', 'couponName', 'pricingRule', 'maximumUse', 'used'],
|
|
};
|
|
}
|
|
}
|