.
This commit is contained in:
parent
981d70cffe
commit
54dc76534a
@ -54,21 +54,21 @@ export const QuoteDetailsCardEditor = () => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
id: "retail_price" as const,
|
id: "unit_price" as const,
|
||||||
accessorKey: "retail_price",
|
accessorKey: "unit_price",
|
||||||
header: "retail_price",
|
header: "unit_price",
|
||||||
size: 10,
|
size: 10,
|
||||||
cell: ({ row: { index }, column: { id } }) => {
|
cell: ({ row: { index }, column: { id } }) => {
|
||||||
return <FormMoneyField {...register(`items.${index}.retail_price`)} />;
|
return <FormMoneyField {...register(`items.${index}.unit_price`)} />;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "price" as const,
|
id: "subtotal_price" as const,
|
||||||
accessorKey: "price",
|
accessorKey: "subtotal_price",
|
||||||
header: "price",
|
header: "subtotal_price",
|
||||||
size: 10,
|
size: 10,
|
||||||
cell: ({ row: { index }, column: { id } }) => {
|
cell: ({ row: { index }, column: { id } }) => {
|
||||||
return <FormMoneyField {...register(`items.${index}.price`)} />;
|
return <FormMoneyField {...register(`items.${index}.subtotal_price`)} />;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -81,12 +81,12 @@ export const QuoteDetailsCardEditor = () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "total" as const,
|
id: "total_price" as const,
|
||||||
accessorKey: "total",
|
accessorKey: "total_price",
|
||||||
header: "total",
|
header: "total_price",
|
||||||
size: 10,
|
size: 10,
|
||||||
cell: ({ row: { index }, column: { id } }) => {
|
cell: ({ row: { index }, column: { id } }) => {
|
||||||
return <FormMoneyField {...register(`items.${index}.total`)} />;
|
return <FormMoneyField {...register(`items.${index}.total_price`)} />;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@ -33,7 +33,7 @@ interface QuoteDataForm extends IUpdateQuote_Request_DTO {
|
|||||||
items: {
|
items: {
|
||||||
quantity: IQuantity;
|
quantity: IQuantity;
|
||||||
description: string;
|
description: string;
|
||||||
retail_price: IMoney;
|
unit_price: IMoney;
|
||||||
price: IMoney;
|
price: IMoney;
|
||||||
discount: IPercentage;
|
discount: IPercentage;
|
||||||
total: IMoney;
|
total: IMoney;
|
||||||
@ -105,10 +105,10 @@ export const QuoteEdit = () => {
|
|||||||
// Recálculo líneas
|
// Recálculo líneas
|
||||||
items.map((item, index) => {
|
items.map((item, index) => {
|
||||||
const itemTotals = calculateItemTotals(item);
|
const itemTotals = calculateItemTotals(item);
|
||||||
quoteSubtotal = quoteSubtotal.add(itemTotals.total);
|
quoteSubtotal = quoteSubtotal.add(itemTotals.totalPrice);
|
||||||
|
|
||||||
setValue(`items.${index}.price`, itemTotals.price.toObject());
|
setValue(`items.${index}.subtotal_price`, itemTotals.subtotalPrice.toObject());
|
||||||
setValue(`items.${index}.total`, itemTotals.total.toObject());
|
setValue(`items.${index}.total_price`, itemTotals.totalPrice.toObject());
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(quoteSubtotal.toFormat());
|
console.log(quoteSubtotal.toFormat());
|
||||||
@ -128,8 +128,8 @@ export const QuoteEdit = () => {
|
|||||||
|
|
||||||
const itemTotals = calculateItemTotals(items[index]);
|
const itemTotals = calculateItemTotals(items[index]);
|
||||||
|
|
||||||
setValue(`items.${index}.price`, itemTotals.price.toObject());
|
setValue(`items.${index}.subtotal_price`, itemTotals.subtotalPrice.toObject());
|
||||||
setValue(`items.${index}.total`, itemTotals.total.toObject());
|
setValue(`items.${index}.total_price`, itemTotals.totalPrice.toObject());
|
||||||
|
|
||||||
// Recálculo completo
|
// Recálculo completo
|
||||||
}
|
}
|
||||||
@ -168,9 +168,9 @@ export const QuoteEdit = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<FormMoneyField
|
<FormMoneyField
|
||||||
label={"subtotal"}
|
label={"subtotal_price"}
|
||||||
disabled={form.formState.disabled}
|
disabled={form.formState.disabled}
|
||||||
{...form.register("subtotal")}
|
{...form.register("subtotal_price")}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Tabs defaultValue='items' className='space-y-4'>
|
<Tabs defaultValue='items' className='space-y-4'>
|
||||||
|
|||||||
@ -3,57 +3,43 @@ import { IMoney, IPercentage, IQuantity } from "./types";
|
|||||||
|
|
||||||
export const calculateItemTotals = (item: {
|
export const calculateItemTotals = (item: {
|
||||||
quantity?: IQuantity;
|
quantity?: IQuantity;
|
||||||
retail_price?: IMoney;
|
unit_price?: IMoney;
|
||||||
discount?: IPercentage;
|
discount?: IPercentage;
|
||||||
}): {
|
}): {
|
||||||
quantity: Quantity;
|
quantity: Quantity;
|
||||||
retailPrice: MoneyValue;
|
unitPrice: MoneyValue;
|
||||||
price: MoneyValue;
|
subtotalPrice: MoneyValue;
|
||||||
discount: Percentage;
|
discount: Percentage;
|
||||||
total: MoneyValue;
|
totalPrice: MoneyValue;
|
||||||
} => {
|
} => {
|
||||||
const { quantity: quantityValue, retail_price: retailPriceValue, discount: discountValue } = item;
|
const { quantity: quantity_value, unit_price: unit_price_value, discount: discount_value } = item;
|
||||||
|
|
||||||
console.log({
|
const quantityOrError = Quantity.create(quantity_value);
|
||||||
quantityValue,
|
|
||||||
retailPriceValue,
|
|
||||||
discountValue,
|
|
||||||
});
|
|
||||||
|
|
||||||
const quantityOrError = Quantity.create(quantityValue);
|
|
||||||
if (quantityOrError.isFailure) {
|
if (quantityOrError.isFailure) {
|
||||||
throw quantityOrError.error;
|
throw quantityOrError.error;
|
||||||
}
|
}
|
||||||
const quantity = quantityOrError.object;
|
const quantity = quantityOrError.object;
|
||||||
|
|
||||||
const retailPriceOrError = MoneyValue.create(retailPriceValue);
|
const unitPriceOrError = MoneyValue.create(unit_price_value);
|
||||||
if (retailPriceOrError.isFailure) {
|
if (unitPriceOrError.isFailure) {
|
||||||
throw retailPriceOrError.error;
|
throw unitPriceOrError.error;
|
||||||
}
|
}
|
||||||
const retailPrice = retailPriceOrError.object;
|
const unitPrice = unitPriceOrError.object;
|
||||||
|
|
||||||
const discountOrError = Percentage.create(discountValue);
|
const discountOrError = Percentage.create(discount_value);
|
||||||
if (discountOrError.isFailure) {
|
if (discountOrError.isFailure) {
|
||||||
throw discountOrError.error;
|
throw discountOrError.error;
|
||||||
}
|
}
|
||||||
const discount = discountOrError.object;
|
const discount = discountOrError.object;
|
||||||
|
|
||||||
const price = retailPrice.multiply(quantity.toNumber());
|
const subtotalPrice = unitPrice.multiply(quantity.toNumber());
|
||||||
const total = price.subtract(price.percentage(discount.toNumber()));
|
const totalPrice = subtotalPrice.subtract(subtotalPrice.percentage(discount.toNumber()));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
quantity,
|
quantity,
|
||||||
retailPrice,
|
unitPrice,
|
||||||
price,
|
subtotalPrice,
|
||||||
discount,
|
discount,
|
||||||
total,
|
totalPrice,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*return {
|
|
||||||
quantity: quantity.toObject(),
|
|
||||||
retail_price: retailPrice.toObject(),
|
|
||||||
price: price.toObject(),
|
|
||||||
discount: discount.toObject(),
|
|
||||||
total: total.toObject(),
|
|
||||||
};*/
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -158,7 +158,6 @@ export abstract class SequelizeRepository<T> implements IRepository<T> {
|
|||||||
},
|
},
|
||||||
transaction: this._transaction,
|
transaction: this._transaction,
|
||||||
force,
|
force,
|
||||||
logging: console.log,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -144,7 +144,9 @@ export class CreateQuoteUseCase
|
|||||||
return Result.fail(referenceOrError.error);
|
return Result.fail(referenceOrError.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
const languageOrError = Language.createFromCode(quoteDTO.lang_code);
|
const languageOrError = Language.createFromCode(
|
||||||
|
quoteDTO.lang_code ?? this._dealer?.language.code
|
||||||
|
);
|
||||||
if (languageOrError.isFailure) {
|
if (languageOrError.isFailure) {
|
||||||
return Result.fail(languageOrError.error);
|
return Result.fail(languageOrError.error);
|
||||||
}
|
}
|
||||||
@ -154,7 +156,9 @@ export class CreateQuoteUseCase
|
|||||||
return Result.fail(customerOrError.error);
|
return Result.fail(customerOrError.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
const currencyOrError = CurrencyData.createFromCode(quoteDTO.currency_code);
|
const currencyOrError = CurrencyData.createFromCode(
|
||||||
|
quoteDTO.currency_code ?? CurrencyData.DEFAULT_CURRENCY_CODE
|
||||||
|
);
|
||||||
if (currencyOrError.isFailure) {
|
if (currencyOrError.isFailure) {
|
||||||
return Result.fail(currencyOrError.error);
|
return Result.fail(currencyOrError.error);
|
||||||
}
|
}
|
||||||
@ -174,6 +178,11 @@ export class CreateQuoteUseCase
|
|||||||
return Result.fail(validityOrError.error);
|
return Result.fail(validityOrError.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const discountOrError = Percentage.create(quoteDTO.discount);
|
||||||
|
if (discountOrError.isFailure) {
|
||||||
|
return Result.fail(discountOrError.error);
|
||||||
|
}
|
||||||
|
|
||||||
const items = new Collection<QuoteItem>(
|
const items = new Collection<QuoteItem>(
|
||||||
quoteDTO.items?.map(
|
quoteDTO.items?.map(
|
||||||
(item) =>
|
(item) =>
|
||||||
@ -182,11 +191,14 @@ export class CreateQuoteUseCase
|
|||||||
description: Description.create(item.description).object,
|
description: Description.create(item.description).object,
|
||||||
quantity: Quantity.create(item.quantity).object,
|
quantity: Quantity.create(item.quantity).object,
|
||||||
unitPrice: UnitPrice.create({
|
unitPrice: UnitPrice.create({
|
||||||
amount: item.unit_price.amount,
|
amount: item.unit_price?.amount,
|
||||||
currencyCode: item.unit_price.currency_code,
|
currencyCode: item.unit_price?.currency_code,
|
||||||
precision: item.unit_price.precision,
|
precision: item.unit_price?.precision,
|
||||||
|
}).object,
|
||||||
|
discount: Percentage.create({
|
||||||
|
amount: item.discount?.amount,
|
||||||
|
precision: item.discount?.precision,
|
||||||
}).object,
|
}).object,
|
||||||
discount: Percentage.create(item.discount.amount).object,
|
|
||||||
}).object
|
}).object
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -203,6 +215,8 @@ export class CreateQuoteUseCase
|
|||||||
notes: notesOrError.object,
|
notes: notesOrError.object,
|
||||||
validity: validityOrError.object,
|
validity: validityOrError.object,
|
||||||
|
|
||||||
|
discount: discountOrError.object,
|
||||||
|
|
||||||
items,
|
items,
|
||||||
|
|
||||||
dealerId,
|
dealerId,
|
||||||
|
|||||||
@ -9,12 +9,13 @@ import { IInfrastructureError } from "@/contexts/common/infrastructure";
|
|||||||
import { ISequelizeAdapter } from "@/contexts/common/infrastructure/sequelize";
|
import { ISequelizeAdapter } from "@/contexts/common/infrastructure/sequelize";
|
||||||
import {
|
import {
|
||||||
Collection,
|
Collection,
|
||||||
Currency,
|
CurrencyData,
|
||||||
Description,
|
Description,
|
||||||
DomainError,
|
DomainError,
|
||||||
IDomainError,
|
IDomainError,
|
||||||
Language,
|
Language,
|
||||||
Note,
|
Note,
|
||||||
|
Percentage,
|
||||||
Quantity,
|
Quantity,
|
||||||
Result,
|
Result,
|
||||||
UTCDateValue,
|
UTCDateValue,
|
||||||
@ -23,11 +24,20 @@ import {
|
|||||||
} from "@shared/contexts";
|
} from "@shared/contexts";
|
||||||
|
|
||||||
import { IUpdateQuote_Request_DTO } from "@shared/contexts";
|
import { IUpdateQuote_Request_DTO } from "@shared/contexts";
|
||||||
import { IQuoteRepository, Quote, QuoteCustomer, QuoteItem, QuoteStatus } from "../../domain";
|
import {
|
||||||
|
Dealer,
|
||||||
|
IQuoteRepository,
|
||||||
|
Quote,
|
||||||
|
QuoteCustomer,
|
||||||
|
QuoteItem,
|
||||||
|
QuoteReference,
|
||||||
|
QuoteStatus,
|
||||||
|
} from "../../domain";
|
||||||
|
import { ISalesContext } from "../../infrastructure";
|
||||||
|
|
||||||
export interface IUpdateQuoteUseCaseRequest extends IUseCaseRequest {
|
export interface IUpdateQuoteUseCaseRequest extends IUseCaseRequest {
|
||||||
id: UniqueID;
|
id: UniqueID;
|
||||||
QuoteDTO: IUpdateQuote_Request_DTO;
|
quoteDTO: IUpdateQuote_Request_DTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type UpdateQuoteResponseOrError =
|
export type UpdateQuoteResponseOrError =
|
||||||
@ -39,16 +49,26 @@ export class UpdateQuoteUseCase
|
|||||||
{
|
{
|
||||||
private _adapter: ISequelizeAdapter;
|
private _adapter: ISequelizeAdapter;
|
||||||
private _repositoryManager: IRepositoryManager;
|
private _repositoryManager: IRepositoryManager;
|
||||||
|
private _dealer?: Dealer;
|
||||||
|
|
||||||
constructor(props: { adapter: ISequelizeAdapter; repositoryManager: IRepositoryManager }) {
|
constructor(context: ISalesContext) {
|
||||||
this._adapter = props.adapter;
|
this._adapter = context.adapter;
|
||||||
this._repositoryManager = props.repositoryManager;
|
this._repositoryManager = context.repositoryManager;
|
||||||
|
this._dealer = context.dealer;
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute(request: IUpdateQuoteUseCaseRequest): Promise<UpdateQuoteResponseOrError> {
|
async execute(request: IUpdateQuoteUseCaseRequest): Promise<UpdateQuoteResponseOrError> {
|
||||||
const { id, QuoteDTO } = request;
|
const { id, quoteDTO } = request;
|
||||||
const QuoteRepository = this._getQuoteRepository();
|
const QuoteRepository = this._getQuoteRepository();
|
||||||
|
|
||||||
|
// Validaciones de datos
|
||||||
|
if (!this._dealer) {
|
||||||
|
const message = "Error. Missing Dealer";
|
||||||
|
return Result.fail(UseCaseError.create(UseCaseError.INVALID_INPUT_DATA, message));
|
||||||
|
}
|
||||||
|
|
||||||
|
const dealerId = this._dealer.id;
|
||||||
|
|
||||||
// Comprobar que existe el Quote
|
// Comprobar que existe el Quote
|
||||||
const idExists = await QuoteRepository().exists(id);
|
const idExists = await QuoteRepository().exists(id);
|
||||||
if (!idExists) {
|
if (!idExists) {
|
||||||
@ -61,10 +81,10 @@ export class UpdateQuoteUseCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Crear usuario
|
// Crear usuario
|
||||||
const QuoteOrError = this._tryCreateQuoteInstance(QuoteDTO, id);
|
const quoteOrError = this._tryCreateQuoteInstance(quoteDTO, id, dealerId);
|
||||||
|
|
||||||
if (QuoteOrError.isFailure) {
|
if (quoteOrError.isFailure) {
|
||||||
const { error: domainError } = QuoteOrError;
|
const { error: domainError } = quoteOrError;
|
||||||
let errorCode = "";
|
let errorCode = "";
|
||||||
let message = "";
|
let message = "";
|
||||||
|
|
||||||
@ -84,22 +104,23 @@ export class UpdateQuoteUseCase
|
|||||||
return Result.fail(UseCaseError.create(errorCode, message, domainError));
|
return Result.fail(UseCaseError.create(errorCode, message, domainError));
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._updateQuote(QuoteOrError.object);
|
return this._updateQuote(quoteOrError.object);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _updateQuote(Quote: Quote) {
|
private async _updateQuote(quote: Quote) {
|
||||||
// Guardar el contacto
|
// Guardar el contacto
|
||||||
const transaction = this._adapter.startTransaction();
|
const transaction = this._adapter.startTransaction();
|
||||||
const QuoteRepository = this._getQuoteRepository();
|
const quoteRepository = this._getQuoteRepository();
|
||||||
let QuoteRepo: IQuoteRepository;
|
let quoteRepo: IQuoteRepository;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await transaction.complete(async (t) => {
|
await transaction.complete(async (t) => {
|
||||||
QuoteRepo = QuoteRepository({ transaction: t });
|
console.log(t);
|
||||||
await QuoteRepo.update(Quote);
|
quoteRepo = quoteRepository({ transaction: t });
|
||||||
|
await quoteRepo.update(quote);
|
||||||
});
|
});
|
||||||
|
|
||||||
return Result.ok<Quote>(Quote);
|
return Result.ok<Quote>(quote);
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
const _error = error as IInfrastructureError;
|
const _error = error as IInfrastructureError;
|
||||||
return Result.fail(UseCaseError.create(UseCaseError.REPOSITORY_ERROR, _error.message));
|
return Result.fail(UseCaseError.create(UseCaseError.REPOSITORY_ERROR, _error.message));
|
||||||
@ -108,7 +129,8 @@ export class UpdateQuoteUseCase
|
|||||||
|
|
||||||
private _tryCreateQuoteInstance(
|
private _tryCreateQuoteInstance(
|
||||||
quoteDTO: IUpdateQuote_Request_DTO,
|
quoteDTO: IUpdateQuote_Request_DTO,
|
||||||
quoteId: UniqueID
|
quoteId: UniqueID,
|
||||||
|
dealerId: UniqueID
|
||||||
): Result<Quote, IDomainError> {
|
): Result<Quote, IDomainError> {
|
||||||
const statusOrError = QuoteStatus.create(quoteDTO.status);
|
const statusOrError = QuoteStatus.create(quoteDTO.status);
|
||||||
if (statusOrError.isFailure) {
|
if (statusOrError.isFailure) {
|
||||||
@ -120,7 +142,7 @@ export class UpdateQuoteUseCase
|
|||||||
return Result.fail(dateOrError.error);
|
return Result.fail(dateOrError.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
const referenceOrError = QuoteStatus.create(quoteDTO.reference);
|
const referenceOrError = QuoteReference.create(quoteDTO.reference);
|
||||||
if (referenceOrError.isFailure) {
|
if (referenceOrError.isFailure) {
|
||||||
return Result.fail(referenceOrError.error);
|
return Result.fail(referenceOrError.error);
|
||||||
}
|
}
|
||||||
@ -135,7 +157,7 @@ export class UpdateQuoteUseCase
|
|||||||
return Result.fail(customerOrError.error);
|
return Result.fail(customerOrError.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
const currencyOrError = Currency.createFromCode(quoteDTO.currency_code);
|
const currencyOrError = CurrencyData.createFromCode(quoteDTO.currency_code);
|
||||||
if (currencyOrError.isFailure) {
|
if (currencyOrError.isFailure) {
|
||||||
return Result.fail(currencyOrError.error);
|
return Result.fail(currencyOrError.error);
|
||||||
}
|
}
|
||||||
@ -155,16 +177,26 @@ export class UpdateQuoteUseCase
|
|||||||
return Result.fail(validityOrError.error);
|
return Result.fail(validityOrError.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const discountOrError = Percentage.create(quoteDTO.discount);
|
||||||
|
if (discountOrError.isFailure) {
|
||||||
|
return Result.fail(discountOrError.error);
|
||||||
|
}
|
||||||
|
|
||||||
const items = new Collection<QuoteItem>(
|
const items = new Collection<QuoteItem>(
|
||||||
quoteDTO.items?.map(
|
quoteDTO.items?.map(
|
||||||
(item) =>
|
(item) =>
|
||||||
QuoteItem.create({
|
QuoteItem.create({
|
||||||
|
articleId: item.article_id,
|
||||||
description: Description.create(item.description).object,
|
description: Description.create(item.description).object,
|
||||||
quantity: Quantity.create({ amount: item.quantity, precision: 4 }).object,
|
quantity: Quantity.create(item.quantity).object,
|
||||||
unitPrice: UnitPrice.create({
|
unitPrice: UnitPrice.create({
|
||||||
amount: item.unit_price.amount,
|
amount: item.unit_price?.amount,
|
||||||
currencyCode: item.unit_price.currency,
|
currencyCode: item.unit_price?.currency_code,
|
||||||
precision: item.unit_price.precision,
|
precision: item.unit_price?.precision,
|
||||||
|
}).object,
|
||||||
|
discount: Percentage.create({
|
||||||
|
amount: item.discount?.amount,
|
||||||
|
precision: item.discount?.precision,
|
||||||
}).object,
|
}).object,
|
||||||
}).object
|
}).object
|
||||||
)
|
)
|
||||||
@ -182,7 +214,11 @@ export class UpdateQuoteUseCase
|
|||||||
notes: notesOrError.object,
|
notes: notesOrError.object,
|
||||||
validity: validityOrError.object,
|
validity: validityOrError.object,
|
||||||
|
|
||||||
|
discount: discountOrError.object,
|
||||||
|
|
||||||
items,
|
items,
|
||||||
|
|
||||||
|
dealerId,
|
||||||
},
|
},
|
||||||
quoteId
|
quoteId
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { ISequelizeAdapter, SequelizeRepository } from "@/contexts/common/infrastructure/sequelize";
|
import { ISequelizeAdapter, SequelizeRepository } from "@/contexts/common/infrastructure/sequelize";
|
||||||
import { ICollection, IQueryCriteria, UniqueID } from "@shared/contexts";
|
import { ICollection, IQueryCriteria, UniqueID } from "@shared/contexts";
|
||||||
import { Transaction } from "sequelize";
|
import { ModelDefined, Transaction } from "sequelize";
|
||||||
|
|
||||||
import { IQuoteRepository } from "../domain";
|
import { IQuoteRepository } from "../domain";
|
||||||
import { Quote } from "../domain/entities";
|
import { Quote } from "../domain/entities";
|
||||||
@ -35,11 +35,27 @@ export class QuoteRepository extends SequelizeRepository<Quote> implements IQuot
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async update(user: Quote): Promise<void> {
|
public async update(user: Quote): Promise<void> {
|
||||||
|
console.time("update");
|
||||||
const userData = this.mapper.mapToPersistence(user);
|
const userData = this.mapper.mapToPersistence(user);
|
||||||
|
|
||||||
// borrando y luego creando
|
const QuoteItem_Model: ModelDefined<any, any> = this._adapter.getModel("QuoteItem_Model");
|
||||||
// await this.removeById(user.id, true);
|
|
||||||
await this._save("Quote_Model", user.id, userData, {});
|
await Promise.all([
|
||||||
|
this._save("Quote_Model", user.id, userData, {}),
|
||||||
|
QuoteItem_Model.destroy({
|
||||||
|
where: {
|
||||||
|
quote_id: userData.id,
|
||||||
|
},
|
||||||
|
transaction: this._transaction,
|
||||||
|
force: true,
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
|
await QuoteItem_Model.bulkCreate(userData.items, {
|
||||||
|
transaction: this._transaction,
|
||||||
|
});
|
||||||
|
|
||||||
|
console.timeEnd("update");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getById(id: UniqueID): Promise<Quote | null> {
|
public async getById(id: UniqueID): Promise<Quote | null> {
|
||||||
|
|||||||
@ -55,7 +55,7 @@ export default (sequelize: Sequelize) => {
|
|||||||
},
|
},
|
||||||
id_article: {
|
id_article: {
|
||||||
type: DataTypes.BIGINT().UNSIGNED,
|
type: DataTypes.BIGINT().UNSIGNED,
|
||||||
allowNull: false,
|
allowNull: true,
|
||||||
},
|
},
|
||||||
position: {
|
position: {
|
||||||
type: new DataTypes.MEDIUMINT(),
|
type: new DataTypes.MEDIUMINT(),
|
||||||
|
|||||||
@ -14,12 +14,12 @@ export const QuoteRouter = (appRouter: Express.Router) => {
|
|||||||
quoteRoutes.get("/", checkUser, getDealerMiddleware, listQuotesController);
|
quoteRoutes.get("/", checkUser, getDealerMiddleware, listQuotesController);
|
||||||
quoteRoutes.get("/:quoteId", checkUser, getDealerMiddleware, getQuoteController);
|
quoteRoutes.get("/:quoteId", checkUser, getDealerMiddleware, getQuoteController);
|
||||||
quoteRoutes.post("/", checkUser, getDealerMiddleware, createQuoteController);
|
quoteRoutes.post("/", checkUser, getDealerMiddleware, createQuoteController);
|
||||||
quoteRoutes.put("/:quoteId", checkUser, updateQuoteController);
|
quoteRoutes.put("/:quoteId", checkUser, getDealerMiddleware, updateQuoteController);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
quoteRoutes.post("/", isAdmin, createQuoteController);
|
quoteRoutes.post("/", isAdmin, createQuoteController);
|
||||||
|
|
||||||
quoteRoutes.delete("/:quoteId", isAdmin, deleteQuoteController);*/
|
quoteRoutes.delete("/:quoteId", isAdmin, getDealerMiddleware, deleteQuoteController);*/
|
||||||
|
|
||||||
appRouter.use("/quotes", quoteRoutes);
|
appRouter.use("/quotes", quoteRoutes);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import Joi from "joi";
|
import Joi from "joi";
|
||||||
import { isNull } from "lodash";
|
import { isNull } from "lodash";
|
||||||
import { NullOr } from "../../../../utilities";
|
import { NullOr } from "../../../../utilities";
|
||||||
|
import { DomainError, handleDomainError } from "../errors";
|
||||||
import { RuleValidator } from "../RuleValidator";
|
import { RuleValidator } from "../RuleValidator";
|
||||||
import { INullableValueObjectOptions, NullableValueObject } from "./NullableValueObject";
|
import { INullableValueObjectOptions, NullableValueObject } from "./NullableValueObject";
|
||||||
import { Result } from "./Result";
|
import { Result } from "./Result";
|
||||||
@ -70,7 +71,9 @@ export class Percentage extends NullableValueObject<IPercentage> {
|
|||||||
const validationResult = Percentage.validate(amount, _options);
|
const validationResult = Percentage.validate(amount, _options);
|
||||||
|
|
||||||
if (validationResult.isFailure) {
|
if (validationResult.isFailure) {
|
||||||
return Result.fail(validationResult.error);
|
return Result.fail(
|
||||||
|
handleDomainError(DomainError.INVALID_INPUT_DATA, validationResult.error.message, _options)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let _amount: NullOr<number> = Percentage.sanitize(validationResult.object);
|
let _amount: NullOr<number> = Percentage.sanitize(validationResult.object);
|
||||||
|
|||||||
@ -74,7 +74,6 @@ export class Quantity extends NullableValueObject<IQuantity> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let _amount: NullOr<number> = Quantity.sanitize(validationResult.object);
|
let _amount: NullOr<number> = Quantity.sanitize(validationResult.object);
|
||||||
|
|
||||||
const _props = {
|
const _props = {
|
||||||
amount: isNull(_amount) ? 0 : _amount,
|
amount: isNull(_amount) ? 0 : _amount,
|
||||||
precision,
|
precision,
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { NullOr } from '../../../../utilities';
|
import { NullOr } from "../../../../utilities";
|
||||||
import { MoneyValue } from './MoneyValue';
|
import { MoneyValue } from "./MoneyValue";
|
||||||
import { Result } from './Result';
|
import { Result } from "./Result";
|
||||||
|
|
||||||
export interface IUnitPriceProps {
|
export interface IUnitPriceProps {
|
||||||
amount: NullOr<number | string>;
|
amount: NullOr<number | string>;
|
||||||
@ -10,8 +10,7 @@ export interface IUnitPriceProps {
|
|||||||
|
|
||||||
export class UnitPrice extends MoneyValue {
|
export class UnitPrice extends MoneyValue {
|
||||||
public static create(props: IUnitPriceProps) {
|
public static create(props: IUnitPriceProps) {
|
||||||
const {amount, currencyCode, precision = 4} = props;
|
const { amount, currencyCode, precision = 4 } = props;
|
||||||
|
|
||||||
const _unitPriceOrError = MoneyValue.create({
|
const _unitPriceOrError = MoneyValue.create({
|
||||||
amount,
|
amount,
|
||||||
currencyCode,
|
currencyCode,
|
||||||
|
|||||||
@ -22,7 +22,7 @@ export * from "./StringValueObject";
|
|||||||
export * from "./TextValueObject";
|
export * from "./TextValueObject";
|
||||||
export * from "./TINNumber";
|
export * from "./TINNumber";
|
||||||
export * from "./UniqueID";
|
export * from "./UniqueID";
|
||||||
//export * from "./UnitPrice";
|
export * from "./UnitPrice";
|
||||||
export * from "./UTCDateValue";
|
export * from "./UTCDateValue";
|
||||||
export * from "./ValueObject";
|
export * from "./ValueObject";
|
||||||
|
|
||||||
|
|||||||
@ -41,34 +41,10 @@ export interface ICreateQuoteItem_Request_DTO {
|
|||||||
export function ensureCreateQuote_Request_DTOIsValid(quoteDTO: ICreateQuote_Request_DTO) {
|
export function ensureCreateQuote_Request_DTOIsValid(quoteDTO: ICreateQuote_Request_DTO) {
|
||||||
const schema = Joi.object({
|
const schema = Joi.object({
|
||||||
id: Joi.string(),
|
id: Joi.string(),
|
||||||
|
status: Joi.string(),
|
||||||
date: Joi.string(),
|
date: Joi.string(),
|
||||||
reference: Joi.string(),
|
reference: Joi.string(),
|
||||||
lang_code: Joi.string(),
|
|
||||||
customer_information: Joi.string(),
|
customer_information: Joi.string(),
|
||||||
currency_code: Joi.string(),
|
|
||||||
payment_method: Joi.string(),
|
|
||||||
notes: Joi.string(),
|
|
||||||
validity: Joi.string(),
|
|
||||||
|
|
||||||
items: Joi.array().items(
|
|
||||||
Joi.object({
|
|
||||||
article_id: Joi.string(),
|
|
||||||
description: Joi.string(),
|
|
||||||
quantity: {
|
|
||||||
amount: Joi.number(),
|
|
||||||
precision: Joi.number(),
|
|
||||||
},
|
|
||||||
unit_price: Joi.object({
|
|
||||||
amount: Joi.number(),
|
|
||||||
precision: Joi.number(),
|
|
||||||
currency: Joi.string(),
|
|
||||||
}),
|
|
||||||
discount: Joi.object({
|
|
||||||
amount: Joi.number(),
|
|
||||||
precision: Joi.number(),
|
|
||||||
}),
|
|
||||||
}).unknown(true)
|
|
||||||
),
|
|
||||||
}).unknown(true);
|
}).unknown(true);
|
||||||
|
|
||||||
const result = RuleValidator.validate<ICreateQuote_Request_DTO>(schema, quoteDTO);
|
const result = RuleValidator.validate<ICreateQuote_Request_DTO>(schema, quoteDTO);
|
||||||
|
|||||||
@ -43,14 +43,14 @@ export function ensureUpdateQuote_Request_DTOIsValid(quoteDTO: IUpdateQuote_Requ
|
|||||||
customer_information: Joi.string(),
|
customer_information: Joi.string(),
|
||||||
lang_code: Joi.string(),
|
lang_code: Joi.string(),
|
||||||
currency_code: Joi.string(),
|
currency_code: Joi.string(),
|
||||||
payment_method: Joi.string(),
|
payment_method: Joi.string().optional().allow(null).allow("").default(""),
|
||||||
notes: Joi.string(),
|
notes: Joi.string().optional().allow(null).allow("").default(""),
|
||||||
validity: Joi.string(),
|
validity: Joi.string().optional().allow(null).allow("").default(""),
|
||||||
|
|
||||||
subtotal: Joi.object({
|
subtotal: Joi.object({
|
||||||
amount: Joi.number(),
|
amount: Joi.number(),
|
||||||
precision: Joi.number(),
|
precision: Joi.number(),
|
||||||
currency: Joi.string(),
|
currency_code: Joi.string(),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
discount: Joi.object({
|
discount: Joi.object({
|
||||||
@ -69,12 +69,12 @@ export function ensureUpdateQuote_Request_DTOIsValid(quoteDTO: IUpdateQuote_Requ
|
|||||||
unit_price: Joi.object({
|
unit_price: Joi.object({
|
||||||
amount: Joi.number(),
|
amount: Joi.number(),
|
||||||
precision: Joi.number(),
|
precision: Joi.number(),
|
||||||
currency: Joi.string(),
|
currency_code: Joi.string(),
|
||||||
}),
|
}),
|
||||||
subtotal_price: Joi.object({
|
subtotal_price: Joi.object({
|
||||||
amount: Joi.number(),
|
amount: Joi.number(),
|
||||||
precision: Joi.number(),
|
precision: Joi.number(),
|
||||||
currency: Joi.string(),
|
currency_code: Joi.string(),
|
||||||
}),
|
}),
|
||||||
discount: Joi.object({
|
discount: Joi.object({
|
||||||
amount: Joi.number(),
|
amount: Joi.number(),
|
||||||
@ -83,7 +83,7 @@ export function ensureUpdateQuote_Request_DTOIsValid(quoteDTO: IUpdateQuote_Requ
|
|||||||
total_price: Joi.object({
|
total_price: Joi.object({
|
||||||
amount: Joi.number(),
|
amount: Joi.number(),
|
||||||
precision: Joi.number(),
|
precision: Joi.number(),
|
||||||
currency: Joi.string(),
|
currency_code: Joi.string(),
|
||||||
}),
|
}),
|
||||||
}).unknown(true)
|
}).unknown(true)
|
||||||
),
|
),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user