.,
This commit is contained in:
parent
47802ab932
commit
23cfe70578
@ -128,6 +128,7 @@ export const QuoteEdit = () => {
|
|||||||
|
|
||||||
const onSubmit: SubmitHandler<QuoteDataForm> = async (data) => {
|
const onSubmit: SubmitHandler<QuoteDataForm> = async (data) => {
|
||||||
// Transformación del form -> typo de request
|
// Transformación del form -> typo de request
|
||||||
|
console.log(data);
|
||||||
mutate(data, {
|
mutate(data, {
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
console.debug(error);
|
console.debug(error);
|
||||||
@ -163,19 +164,17 @@ export const QuoteEdit = () => {
|
|||||||
|
|
||||||
if (name === "items") {
|
if (name === "items") {
|
||||||
const { items } = value;
|
const { items } = value;
|
||||||
let quoteSubtotal = MoneyValue.create().object;
|
|
||||||
|
let quoteSubtotal = MoneyValue.create({
|
||||||
|
amount: 0,
|
||||||
|
scale: 4,
|
||||||
|
}).object;
|
||||||
|
|
||||||
// Recálculo líneas
|
// Recálculo líneas
|
||||||
items &&
|
items &&
|
||||||
items.map((item, index) => {
|
items.map((item, index) => {
|
||||||
const itemTotals = calculateItemTotals(item);
|
const itemTotals = calculateItemTotals(item);
|
||||||
|
|
||||||
if (itemTotals === null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
quoteSubtotal = quoteSubtotal.add(itemTotals.totalPrice);
|
quoteSubtotal = quoteSubtotal.add(itemTotals.totalPrice);
|
||||||
|
|
||||||
setValue(`items.${index}.subtotal_price`, itemTotals.subtotalPrice.toObject());
|
setValue(`items.${index}.subtotal_price`, itemTotals.subtotalPrice.toObject());
|
||||||
setValue(`items.${index}.total_price`, itemTotals.totalPrice.toObject());
|
setValue(`items.${index}.total_price`, itemTotals.totalPrice.toObject());
|
||||||
});
|
});
|
||||||
@ -186,15 +185,11 @@ export const QuoteEdit = () => {
|
|||||||
|
|
||||||
if (name.endsWith("quantity") || name.endsWith("unit_price") || name.endsWith("discount")) {
|
if (name.endsWith("quantity") || name.endsWith("unit_price") || name.endsWith("discount")) {
|
||||||
const { items } = value;
|
const { items } = value;
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
const [, indexString, fieldName] = String(name).split(".");
|
const [, indexString, fieldName] = String(name).split(".");
|
||||||
const index = parseInt(indexString);
|
const index = parseInt(indexString);
|
||||||
|
|
||||||
const itemTotals = calculateItemTotals(items[index]);
|
const itemTotals = calculateItemTotals(items[index]);
|
||||||
if (itemTotals === null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setValue(`items.${index}.subtotal_price`, itemTotals.subtotalPrice.toObject());
|
setValue(`items.${index}.subtotal_price`, itemTotals.subtotalPrice.toObject());
|
||||||
setValue(`items.${index}.total_price`, itemTotals.totalPrice.toObject());
|
setValue(`items.${index}.total_price`, itemTotals.totalPrice.toObject());
|
||||||
|
|
||||||
@ -206,7 +201,7 @@ export const QuoteEdit = () => {
|
|||||||
}, [watch, getValues, setValue]);
|
}, [watch, getValues, setValue]);
|
||||||
|
|
||||||
if (isSubmitting) {
|
if (isSubmitting) {
|
||||||
return <LoadingOverlay />;
|
return <LoadingOverlay title='Guardando cotización' />;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status === "error") {
|
if (status === "error") {
|
||||||
|
|||||||
@ -1,13 +1,32 @@
|
|||||||
import { MoneyValue, Percentage, Quantity } from "@shared/contexts";
|
import { MoneyValue, Percentage, Quantity } from "@shared/contexts";
|
||||||
|
|
||||||
export const calculateItemTotals = (item: any) => {
|
export const calculateItemTotals = (item: any) => {
|
||||||
console.log(item);
|
|
||||||
|
|
||||||
const { quantity: quantity_dto, unit_price: unit_price_dto, discount: discount_dto } = item;
|
const { quantity: quantity_dto, unit_price: unit_price_dto, discount: discount_dto } = item;
|
||||||
|
|
||||||
/*if (quantity_dto.amount === null || unit_price_dto.amount === null) {
|
if (quantity_dto.amount === null || unit_price_dto.amount === null) {
|
||||||
return null;
|
return {
|
||||||
}*/
|
quantity: Quantity.create({
|
||||||
|
amount: quantity_dto.amount,
|
||||||
|
scale: 0,
|
||||||
|
}).object,
|
||||||
|
unitPrice: MoneyValue.create({
|
||||||
|
amount: unit_price_dto.amount,
|
||||||
|
scale: 4,
|
||||||
|
}).object,
|
||||||
|
subtotalPrice: MoneyValue.create({
|
||||||
|
amount: null,
|
||||||
|
scale: 4,
|
||||||
|
}).object,
|
||||||
|
discount: Percentage.create({
|
||||||
|
amount: discount_dto.amount,
|
||||||
|
scale: 2,
|
||||||
|
}).object,
|
||||||
|
totalPrice: MoneyValue.create({
|
||||||
|
amount: null,
|
||||||
|
scale: 4,
|
||||||
|
}).object,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const quantityOrError = Quantity.create(quantity_dto);
|
const quantityOrError = Quantity.create(quantity_dto);
|
||||||
if (quantityOrError.isFailure) {
|
if (quantityOrError.isFailure) {
|
||||||
|
|||||||
@ -16,6 +16,8 @@ export class ArticleIdentifier extends NullableValueObject<number> {
|
|||||||
) {
|
) {
|
||||||
const ruleNull = RuleValidator.RULE_ALLOW_NULL_OR_UNDEFINED.default(null);
|
const ruleNull = RuleValidator.RULE_ALLOW_NULL_OR_UNDEFINED.default(null);
|
||||||
|
|
||||||
|
const ruleEmpty = RuleValidator.RULE_ALLOW_EMPTY.default(null);
|
||||||
|
|
||||||
const ruleNumber = RuleValidator.RULE_IS_TYPE_NUMBER.label(
|
const ruleNumber = RuleValidator.RULE_IS_TYPE_NUMBER.label(
|
||||||
options.label ? options.label : "ArticleIdentifier"
|
options.label ? options.label : "ArticleIdentifier"
|
||||||
);
|
);
|
||||||
@ -24,11 +26,15 @@ export class ArticleIdentifier extends NullableValueObject<number> {
|
|||||||
options.label ? options.label : "ArticleIdentifier"
|
options.label ? options.label : "ArticleIdentifier"
|
||||||
);
|
);
|
||||||
|
|
||||||
const rules = Joi.alternatives(ruleNull, ruleNumber, ruleString);
|
const rules = Joi.alternatives(ruleNull, ruleEmpty, ruleNumber, ruleString);
|
||||||
|
|
||||||
return RuleValidator.validate<NullOr<number>>(rules, value);
|
return RuleValidator.validate<NullOr<number>>(rules, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static sanitize(value: NullOr<number | string>): NullOr<number> {
|
||||||
|
return value ? Number(value) : null;
|
||||||
|
}
|
||||||
|
|
||||||
public static create(value: NullOr<number | string>, options: IArticleIdentifierOptions = {}) {
|
public static create(value: NullOr<number | string>, options: IArticleIdentifierOptions = {}) {
|
||||||
const _options = {
|
const _options = {
|
||||||
label: "ArticleIdentifier",
|
label: "ArticleIdentifier",
|
||||||
@ -49,7 +55,7 @@ export class ArticleIdentifier extends NullableValueObject<number> {
|
|||||||
_value = validationResult.object;
|
_value = validationResult.object;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result.ok<ArticleIdentifier>(new ArticleIdentifier(_value));
|
return Result.ok<ArticleIdentifier>(new ArticleIdentifier(ArticleIdentifier.sanitize(_value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public toNumber(): number {
|
public toNumber(): number {
|
||||||
|
|||||||
@ -117,7 +117,6 @@ export class UpdateQuoteUseCase
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await transaction.complete(async (t) => {
|
await transaction.complete(async (t) => {
|
||||||
console.log(t);
|
|
||||||
quoteRepo = quoteRepository({ transaction: t });
|
quoteRepo = quoteRepository({ transaction: t });
|
||||||
await quoteRepo.update(quote);
|
await quoteRepo.update(quote);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -53,7 +53,9 @@ export class QuoteItem extends Entity<IQuoteItemProps> implements IQuoteItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get subtotalPrice(): MoneyValue {
|
get subtotalPrice(): MoneyValue {
|
||||||
return this.unitPrice.multiply(this.quantity.toNumber());
|
return this.quantity.isNull() || this.unitPrice.isNull()
|
||||||
|
? MoneyValue.create({ amount: null, scale: 4 }).object
|
||||||
|
: this.unitPrice.multiply(this.quantity.toNumber());
|
||||||
}
|
}
|
||||||
|
|
||||||
get discount(): Percentage {
|
get discount(): Percentage {
|
||||||
@ -61,6 +63,8 @@ export class QuoteItem extends Entity<IQuoteItemProps> implements IQuoteItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get totalPrice(): MoneyValue {
|
get totalPrice(): MoneyValue {
|
||||||
return this.subtotalPrice.subtract(this.subtotalPrice.percentage(this.discount.toNumber()));
|
return this.subtotalPrice.isNull()
|
||||||
|
? MoneyValue.create({ amount: null, scale: 4 }).object
|
||||||
|
: this.subtotalPrice.subtract(this.subtotalPrice.percentage(this.discount.toNumber()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,7 +43,7 @@ const quoteItemPresenter = (
|
|||||||
): IGetQuote_QuoteItem_Response_DTO[] =>
|
): IGetQuote_QuoteItem_Response_DTO[] =>
|
||||||
items.totalCount > 0
|
items.totalCount > 0
|
||||||
? items.items.map((item: QuoteItem) => ({
|
? items.items.map((item: QuoteItem) => ({
|
||||||
article_id: item.articleId ?? "",
|
article_id: item.articleId.toString(),
|
||||||
description: item.description.toString(),
|
description: item.description.toString(),
|
||||||
quantity: item.quantity.toObject(),
|
quantity: item.quantity.toObject(),
|
||||||
unit_price: item.unitPrice.toObject(),
|
unit_price: item.unitPrice.toObject(),
|
||||||
|
|||||||
@ -36,7 +36,7 @@ export const UpdateQuotePresenter: IUpdateQuotePresenter = {
|
|||||||
const quoteItemPresenter = (items: ICollection<QuoteItem>, context: ISalesContext) =>
|
const quoteItemPresenter = (items: ICollection<QuoteItem>, context: ISalesContext) =>
|
||||||
items.totalCount > 0
|
items.totalCount > 0
|
||||||
? items.items.map((item: QuoteItem) => ({
|
? items.items.map((item: QuoteItem) => ({
|
||||||
article_id: item.articleId ?? "",
|
article_id: item.articleId.toString(),
|
||||||
description: item.description.toString(),
|
description: item.description.toString(),
|
||||||
quantity: item.quantity.toObject(),
|
quantity: item.quantity.toObject(),
|
||||||
unit_price: item.unitPrice.toObject(),
|
unit_price: item.unitPrice.toObject(),
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import DineroFactory, { Currency, Dinero } from "dinero.js";
|
|||||||
|
|
||||||
import Joi from "joi";
|
import Joi from "joi";
|
||||||
import { isNull } from "lodash";
|
import { isNull } from "lodash";
|
||||||
import { NullOr, UndefinedOr } from "../../../../utilities";
|
import { NullOr } from "../../../../utilities";
|
||||||
import { DomainError, handleDomainError } from "../errors";
|
import { DomainError, handleDomainError } from "../errors";
|
||||||
import { RuleValidator } from "../RuleValidator";
|
import { RuleValidator } from "../RuleValidator";
|
||||||
import { CurrencyData } from "./CurrencyData";
|
import { CurrencyData } from "./CurrencyData";
|
||||||
@ -11,12 +11,10 @@ import { Result } from "./Result";
|
|||||||
import { IValueObjectOptions, ValueObject } from "./ValueObject";
|
import { IValueObjectOptions, ValueObject } from "./ValueObject";
|
||||||
|
|
||||||
export interface IMoneyValueOptions extends IValueObjectOptions {
|
export interface IMoneyValueOptions extends IValueObjectOptions {
|
||||||
defaultValue?: number;
|
|
||||||
locale: string;
|
locale: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const defaultMoneyValueOptions: IMoneyValueOptions = {
|
export const defaultMoneyValueOptions: IMoneyValueOptions = {
|
||||||
defaultValue: 0,
|
|
||||||
locale: "es-ES",
|
locale: "es-ES",
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -50,7 +48,7 @@ const defaultMoneyValueProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
interface IMoneyValue {
|
interface IMoneyValue {
|
||||||
toPrimitive(): UndefinedOr<number>;
|
toPrimitive(): NullOr<number>;
|
||||||
toPrimitives(): MoneyValueObject;
|
toPrimitives(): MoneyValueObject;
|
||||||
isEmpty(): boolean;
|
isEmpty(): boolean;
|
||||||
toString(): string;
|
toString(): string;
|
||||||
@ -92,9 +90,6 @@ export class MoneyValue extends ValueObject<Dinero> implements IMoneyValue {
|
|||||||
public static readonly DEFAULT_SCALE = defaultMoneyValueProps.scale;
|
public static readonly DEFAULT_SCALE = defaultMoneyValueProps.scale;
|
||||||
public static readonly DEFAULT_CURRENCY_CODE = defaultMoneyValueProps.currencyCode;
|
public static readonly DEFAULT_CURRENCY_CODE = defaultMoneyValueProps.currencyCode;
|
||||||
|
|
||||||
private static readonly MIN_VALUE = Number.MIN_VALUE;
|
|
||||||
private static readonly MAX_VALUE = Number.MAX_VALUE;
|
|
||||||
|
|
||||||
private readonly _isNull: boolean;
|
private readonly _isNull: boolean;
|
||||||
private readonly _options: IMoneyValueOptions;
|
private readonly _options: IMoneyValueOptions;
|
||||||
|
|
||||||
@ -103,12 +98,7 @@ export class MoneyValue extends ValueObject<Dinero> implements IMoneyValue {
|
|||||||
.optional() // <- undefined
|
.optional() // <- undefined
|
||||||
.valid(null); // <- null
|
.valid(null); // <- null
|
||||||
|
|
||||||
const ruleNumber = Joi.number()
|
const ruleNumber = Joi.number().label(options.label ? options.label : "amount");
|
||||||
.optional()
|
|
||||||
.default(0)
|
|
||||||
.min(-1000)
|
|
||||||
.max(this.MAX_VALUE)
|
|
||||||
.label(options.label ? options.label : "amount");
|
|
||||||
|
|
||||||
const rules = Joi.alternatives(ruleNull, ruleNumber);
|
const rules = Joi.alternatives(ruleNull, ruleNumber);
|
||||||
|
|
||||||
@ -154,7 +144,7 @@ export class MoneyValue extends ValueObject<Dinero> implements IMoneyValue {
|
|||||||
const _currency = CurrencyData.createFromCode(currencyCode).object.code;
|
const _currency = CurrencyData.createFromCode(currencyCode).object.code;
|
||||||
|
|
||||||
const prop = DineroFactory({
|
const prop = DineroFactory({
|
||||||
amount: !isNull(_amount) ? Number(_amount) : options.defaultValue,
|
amount: Number(_amount),
|
||||||
currency: _currency as Currency,
|
currency: _currency as Currency,
|
||||||
precision: scale,
|
precision: scale,
|
||||||
}).setLocale(options.locale);
|
}).setLocale(options.locale);
|
||||||
@ -287,8 +277,8 @@ export class MoneyValue extends ValueObject<Dinero> implements IMoneyValue {
|
|||||||
return this._isNull ? {} : this.props?.toJSON();
|
return this._isNull ? {} : this.props?.toJSON();
|
||||||
}
|
}
|
||||||
|
|
||||||
public toPrimitive(): UndefinedOr<number> {
|
public toPrimitive(): NullOr<number> {
|
||||||
return this._isNull ? undefined : Number(this.props?.getAmount());
|
return this._isNull ? null : Number(this.props?.getAmount());
|
||||||
}
|
}
|
||||||
|
|
||||||
public toPrimitives(): MoneyValueObject {
|
public toPrimitives(): MoneyValueObject {
|
||||||
@ -308,7 +298,16 @@ export class MoneyValue extends ValueObject<Dinero> implements IMoneyValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public convertScale(newScale: number, roundingMode: RoundingMode = "HALF_UP"): MoneyValue {
|
public convertScale(newScale: number, roundingMode: RoundingMode = "HALF_UP"): MoneyValue {
|
||||||
return MoneyValue.createFromDinero(this.props.convertPrecision(newScale, roundingMode)).object;
|
if (this._isNull) {
|
||||||
|
return MoneyValue.create({
|
||||||
|
amount: null,
|
||||||
|
scale: newScale,
|
||||||
|
currencyCode: this.getCurrency().code,
|
||||||
|
}).object;
|
||||||
|
} else {
|
||||||
|
return MoneyValue.createFromDinero(this.props.convertPrecision(newScale, roundingMode))
|
||||||
|
.object;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public getCurrency(): CurrencyData {
|
public getCurrency(): CurrencyData {
|
||||||
|
|||||||
@ -22,7 +22,7 @@ interface IPercentage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface PercentageObject {
|
export interface PercentageObject {
|
||||||
amount: number;
|
amount: number | null;
|
||||||
scale: number;
|
scale: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,7 +259,7 @@ export class Percentage extends NullableValueObject<IPercentage> {
|
|||||||
|
|
||||||
public toObject(): PercentageObject {
|
public toObject(): PercentageObject {
|
||||||
return {
|
return {
|
||||||
amount: this.isNull() ? 0 : Number(this.amount),
|
amount: this.amount,
|
||||||
scale: this.scale,
|
scale: this.scale,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -195,7 +195,7 @@ export class Quantity extends NullableValueObject<IQuantity> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get scale(): number {
|
get scale(): number {
|
||||||
return this.isNull() ? 0 : Number(this.props?.scale);
|
return Number(this.props?.scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getAmount(): NullOr<number> {
|
public getAmount(): NullOr<number> {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user