Presupuestador_web/shared/lib/contexts/common/domain/entities/Quantity.ts
2024-04-23 17:29:38 +02:00

98 lines
2.4 KiB
TypeScript

import Joi from "joi";
import { NullOr } from "../../../../utilities";
import { RuleValidator } from "../RuleValidator";
import {
INullableValueObjectOptions,
NullableValueObject,
} from "./NullableValueObject";
import { Result } from "./Result";
export interface IQuantityOptions extends INullableValueObjectOptions {}
export class Quantity extends NullableValueObject<number> {
protected static validate(
value: NullOr<number | string>,
options: IQuantityOptions = {},
) {
const ruleNull = RuleValidator.RULE_ALLOW_NULL_OR_UNDEFINED.default(null);
const ruleNumber = RuleValidator.RULE_IS_TYPE_NUMBER.label(
options.label ? options.label : "quantity",
);
const ruleString = RuleValidator.RULE_IS_TYPE_STRING.regex(
/^[-]?\d+$/,
).label(options.label ? options.label : "quantity");
const rules = Joi.alternatives(ruleNull, ruleNumber, ruleString);
return RuleValidator.validate<NullOr<number>>(rules, value);
}
public static create(
value: NullOr<number | string>,
options: IQuantityOptions = {},
) {
const _options = {
label: "quantity",
...options,
};
const validationResult = Quantity.validate(value, _options);
if (validationResult.isFailure) {
return Result.fail(validationResult.error);
}
let _value: NullOr<number> = null;
if (typeof validationResult.object === "string") {
_value = parseInt(validationResult.object, 10);
} else {
_value = validationResult.object;
}
return Result.ok<Quantity>(new Quantity(_value));
}
public toNumber(): number {
return this.isNull() ? 0 : Number(this.value);
}
public toString(): string {
return this.isNull() ? "" : String(this.value);
}
public toPrimitive(): number {
return this.toNumber();
}
public increment(amount: number = 1) {
const validationResult = Quantity.validate(amount);
if (validationResult.isFailure) {
return Result.fail(validationResult.error);
}
if (this.value === null) {
return Quantity.create(amount);
}
return Quantity.create(this.value + amount);
}
public decrement(amount: number = 1) {
const validationResult = Quantity.validate(amount);
if (validationResult.isFailure) {
return Result.fail(validationResult.error);
}
if (this.value === null) {
return Quantity.create(amount);
}
return Quantity.create(this.value - amount);
}
}