.
This commit is contained in:
parent
0b00b84289
commit
985111af5f
@ -0,0 +1,32 @@
|
||||
import { IRepositoryManager, RepositoryManager } from "@/contexts/common/domain";
|
||||
import {
|
||||
ISequelizeAdapter,
|
||||
createSequelizeAdapter,
|
||||
} from "@/contexts/common/infrastructure/sequelize";
|
||||
|
||||
export interface ICatalogContext {
|
||||
adapter: ISequelizeAdapter;
|
||||
repositoryManager: IRepositoryManager;
|
||||
//services: IApplicationService;
|
||||
}
|
||||
|
||||
export class CatalogContext {
|
||||
private static instance: CatalogContext | null = null;
|
||||
|
||||
public static getInstance(): ICatalogContext {
|
||||
if (!CatalogContext.instance) {
|
||||
CatalogContext.instance = new CatalogContext({
|
||||
adapter: createSequelizeAdapter(),
|
||||
repositoryManager: RepositoryManager.getInstance(),
|
||||
});
|
||||
}
|
||||
|
||||
return CatalogContext.instance.context;
|
||||
}
|
||||
|
||||
private context: ICatalogContext;
|
||||
|
||||
private constructor(context: ICatalogContext) {
|
||||
this.context = context;
|
||||
}
|
||||
}
|
||||
@ -45,7 +45,7 @@ export class Article_Model extends Model<
|
||||
declare points: CreationOptional<number>;
|
||||
declare retail_price: CreationOptional<number>;
|
||||
|
||||
declare translations?: NonAttribute<ArticleTranslation_Model[]>;
|
||||
declare translations: NonAttribute<ArticleTranslation_Model[]>;
|
||||
}
|
||||
|
||||
export default (sequelize: Sequelize) => {
|
||||
|
||||
@ -43,6 +43,7 @@ export class ListQuotesUseCase implements IUseCase<IListQuotesParams, Promise<Li
|
||||
return Result.ok(Quotes);
|
||||
} catch (error: unknown) {
|
||||
const _error = error as IInfrastructureError;
|
||||
console.trace(_error.message);
|
||||
return Result.fail(
|
||||
UseCaseError.create(
|
||||
UseCaseError.REPOSITORY_ERROR,
|
||||
|
||||
@ -14,6 +14,7 @@ import {
|
||||
DomainError,
|
||||
IDomainError,
|
||||
Language,
|
||||
Note,
|
||||
Quantity,
|
||||
Result,
|
||||
UTCDateValue,
|
||||
@ -22,7 +23,7 @@ import {
|
||||
} from "@shared/contexts";
|
||||
|
||||
import { IUpdateQuote_Request_DTO } from "@shared/contexts";
|
||||
import { IQuoteRepository, Quote, QuoteItem, QuoteStatus } from "../../domain";
|
||||
import { IQuoteRepository, Quote, QuoteCustomer, QuoteItem, QuoteStatus } from "../../domain";
|
||||
|
||||
export interface IUpdateQuoteUseCaseRequest extends IUseCaseRequest {
|
||||
id: UniqueID;
|
||||
@ -119,22 +120,47 @@ export class UpdateQuoteUseCase
|
||||
return Result.fail(dateOrError.error);
|
||||
}
|
||||
|
||||
const languageOrError = Language.createFromCode(quoteDTO.language_code);
|
||||
const referenceOrError = QuoteStatus.create(quoteDTO.reference);
|
||||
if (referenceOrError.isFailure) {
|
||||
return Result.fail(referenceOrError.error);
|
||||
}
|
||||
|
||||
const languageOrError = Language.createFromCode(quoteDTO.lang_code);
|
||||
if (languageOrError.isFailure) {
|
||||
return Result.fail(languageOrError.error);
|
||||
}
|
||||
|
||||
const customerOrError = QuoteCustomer.create(quoteDTO.customer_information);
|
||||
if (customerOrError.isFailure) {
|
||||
return Result.fail(customerOrError.error);
|
||||
}
|
||||
|
||||
const currencyOrError = Currency.createFromCode(quoteDTO.currency_code);
|
||||
if (currencyOrError.isFailure) {
|
||||
return Result.fail(currencyOrError.error);
|
||||
}
|
||||
|
||||
const paymentOrError = Note.create(quoteDTO.payment_method);
|
||||
if (paymentOrError.isFailure) {
|
||||
return Result.fail(paymentOrError.error);
|
||||
}
|
||||
|
||||
const notesOrError = Note.create(quoteDTO.notes);
|
||||
if (notesOrError.isFailure) {
|
||||
return Result.fail(notesOrError.error);
|
||||
}
|
||||
|
||||
const validityOrError = Note.create(quoteDTO.validity);
|
||||
if (validityOrError.isFailure) {
|
||||
return Result.fail(validityOrError.error);
|
||||
}
|
||||
|
||||
const items = new Collection<QuoteItem>(
|
||||
quoteDTO.items?.map(
|
||||
(item) =>
|
||||
QuoteItem.create({
|
||||
description: Description.create(item.description).object,
|
||||
quantity: Quantity.create(item.quantity).object,
|
||||
quantity: Quantity.create({ amount: item.quantity, precision: 4 }).object,
|
||||
unitPrice: UnitPrice.create({
|
||||
amount: item.unit_price.amount,
|
||||
currencyCode: item.unit_price.currency,
|
||||
@ -148,8 +174,14 @@ export class UpdateQuoteUseCase
|
||||
{
|
||||
status: statusOrError.object,
|
||||
date: dateOrError.object,
|
||||
reference: referenceOrError.object,
|
||||
language: languageOrError.object,
|
||||
customer: customerOrError.object,
|
||||
currency: currencyOrError.object,
|
||||
paymentMethod: paymentOrError.object,
|
||||
notes: notesOrError.object,
|
||||
validity: validityOrError.object,
|
||||
|
||||
items,
|
||||
},
|
||||
quoteId
|
||||
|
||||
@ -26,6 +26,8 @@ export interface IQuoteProps {
|
||||
validity: Note;
|
||||
|
||||
items: ICollection<QuoteItem>;
|
||||
|
||||
dealerId: UniqueID;
|
||||
}
|
||||
|
||||
export interface IQuote {
|
||||
@ -41,6 +43,8 @@ export interface IQuote {
|
||||
notes: Note;
|
||||
validity: Note;
|
||||
items: ICollection<QuoteItem>;
|
||||
|
||||
dealerId: UniqueID;
|
||||
}
|
||||
|
||||
export class Quote extends AggregateRoot<IQuoteProps> implements IQuote {
|
||||
@ -105,4 +109,8 @@ export class Quote extends AggregateRoot<IQuoteProps> implements IQuote {
|
||||
get items() {
|
||||
return this._items;
|
||||
}
|
||||
|
||||
get dealerId() {
|
||||
return this.dealerId;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,16 @@
|
||||
import { ListQuotesUseCase } from "@/contexts/sales/application";
|
||||
import { registerQuoteRepository } from "@/contexts/sales/infrastructure/Quote.repository";
|
||||
import { ISalesContext } from "../../../../Sales.context";
|
||||
import Express from "express";
|
||||
import { ListQuotesController } from "./ListQuotes.controller";
|
||||
import { ListQuotesPresenter } from "./presenter";
|
||||
|
||||
export const listQuotesController = (context: ISalesContext) => {
|
||||
export const listQuotesController = (
|
||||
req: Express.Request,
|
||||
res: Express.Response,
|
||||
next: Express.NextFunction
|
||||
) => {
|
||||
const context = res.locals.context;
|
||||
|
||||
registerQuoteRepository(context);
|
||||
|
||||
return new ListQuotesController(
|
||||
@ -13,5 +19,5 @@ export const listQuotesController = (context: ISalesContext) => {
|
||||
presenter: ListQuotesPresenter,
|
||||
},
|
||||
context
|
||||
);
|
||||
).execute(req, res, next);
|
||||
};
|
||||
|
||||
@ -21,8 +21,11 @@ export const ListQuotesPresenter: IListQuotesPresenter = {
|
||||
id: quote.id.toString(),
|
||||
status: quote.status.toString(),
|
||||
date: quote.date.toString(),
|
||||
language_code: quote.date.toISO8601(),
|
||||
reference: quote.reference.toString(),
|
||||
customer_information: quote.customer.toString(),
|
||||
lang_code: quote.date.toISO8601(),
|
||||
currency_code: quote.currency.toString(),
|
||||
|
||||
subtotal: {
|
||||
amount: 0,
|
||||
precision: 2,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { Currency, Language, UTCDateValue, UniqueID } from "@shared/contexts";
|
||||
import { Currency, Language, Note, UTCDateValue, UniqueID } from "@shared/contexts";
|
||||
|
||||
import { ISequelizeMapper, SequelizeMapper } from "@/contexts/common/infrastructure";
|
||||
import { IQuoteProps, Quote } from "../../domain";
|
||||
import { IQuoteProps, Quote, QuoteCustomer, QuoteReference } from "../../domain";
|
||||
import { QuoteStatus } from "../../domain/entities/Quotes/QuoteStatus";
|
||||
import { ISalesContext } from "../Sales.context";
|
||||
import { QuoteCreationAttributes, Quote_Model } from "../sequelize";
|
||||
@ -34,11 +34,18 @@ class QuoteMapper
|
||||
const props: IQuoteProps = {
|
||||
status: this.mapsValue(source, "status", QuoteStatus.create),
|
||||
date: this.mapsValue(source, "issue_date", UTCDateValue.create),
|
||||
reference: this.mapsValue(source, "reference", QuoteReference.create),
|
||||
currency: this.mapsValue(source, "quote_currency", Currency.createFromCode),
|
||||
language: this.mapsValue(source, "quote_language", Language.createFromCode),
|
||||
customer: source.customer_information,
|
||||
customer: this.mapsValue(source, "customer", QuoteCustomer.create),
|
||||
|
||||
validity: this.mapsValue(source, "validity", Note.create),
|
||||
paymentMethod: this.mapsValue(source, "paymentMethod", Note.create),
|
||||
notes: this.mapsValue(source, "notes", Note.create),
|
||||
|
||||
items,
|
||||
|
||||
dealerId: this.mapsValue(source, "dealer_id", UniqueID.create),
|
||||
};
|
||||
|
||||
const quoteOrError = Quote.create(props, id);
|
||||
@ -60,12 +67,20 @@ class QuoteMapper
|
||||
id: source.id.toPrimitive(),
|
||||
status: source.status.toPrimitive(),
|
||||
date: source.date.toPrimitive(),
|
||||
reference: source.reference.toPrimitive(),
|
||||
currency_code: source.currency.toPrimitive(),
|
||||
lang_code: source.language.toPrimitive(),
|
||||
customer_information: source.customer,
|
||||
customer_information: source.customer.toPrimitive(),
|
||||
validity: source.validity.toPrimitive(),
|
||||
payment_method: source.paymentMethod.toPrimitive(),
|
||||
notes: source.notes.toPrimitive(),
|
||||
|
||||
discount: 0,
|
||||
subtotal: 0,
|
||||
total: 0,
|
||||
|
||||
items,
|
||||
dealer_id: source.dealerId.toPrimitive(),
|
||||
};
|
||||
|
||||
return quote;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { User_Model } from "@/contexts/users";
|
||||
import { UserCreationAttributes, User_Model } from "@/contexts/users";
|
||||
import {
|
||||
DataTypes,
|
||||
InferAttributes,
|
||||
@ -8,12 +8,15 @@ import {
|
||||
Op,
|
||||
Sequelize,
|
||||
} from "sequelize";
|
||||
import { Quote_Model } from "./quote.model";
|
||||
import { QuoteCreationAttributes, Quote_Model } from "./quote.model";
|
||||
|
||||
export type DealerCreationAttributes = InferCreationAttributes<
|
||||
Dealer_Model,
|
||||
{ omit: "user" | "quotes" }
|
||||
>;
|
||||
> & {
|
||||
user: UserCreationAttributes;
|
||||
quotes: QuoteCreationAttributes[];
|
||||
};
|
||||
|
||||
export class Dealer_Model extends Model<
|
||||
InferAttributes<Dealer_Model, { omit: "user" | "quotes" }>,
|
||||
@ -52,8 +55,8 @@ export class Dealer_Model extends Model<
|
||||
declare status: string;
|
||||
declare language: string;
|
||||
|
||||
declare user?: NonAttribute<User_Model>;
|
||||
declare quotes?: NonAttribute<Quote_Model>;
|
||||
declare user: NonAttribute<User_Model>;
|
||||
declare quotes: NonAttribute<Quote_Model>;
|
||||
}
|
||||
|
||||
export default (sequelize: Sequelize) => {
|
||||
|
||||
@ -9,12 +9,15 @@ import {
|
||||
Sequelize,
|
||||
} from "sequelize";
|
||||
import { Dealer_Model } from "./dealer.model";
|
||||
import { QuoteItem_Model } from "./quoteItem.model";
|
||||
import { QuoteItemCreationAttributes, QuoteItem_Model } from "./quoteItem.model";
|
||||
|
||||
export type QuoteCreationAttributes = InferCreationAttributes<
|
||||
Quote_Model,
|
||||
{ omit: "items" | "dealer" }
|
||||
>;
|
||||
> & {
|
||||
items: QuoteItemCreationAttributes[];
|
||||
dealer_id: string;
|
||||
};
|
||||
|
||||
export class Quote_Model extends Model<
|
||||
InferAttributes<Quote_Model, { omit: "items" | "dealer" }>,
|
||||
@ -51,8 +54,8 @@ export class Quote_Model extends Model<
|
||||
declare discount: CreationOptional<number>;
|
||||
declare total: CreationOptional<number>;
|
||||
|
||||
declare items?: NonAttribute<QuoteItem_Model[]>;
|
||||
declare dealer?: NonAttribute<Dealer_Model>;
|
||||
declare items: NonAttribute<QuoteItem_Model[]>;
|
||||
declare dealer: NonAttribute<Dealer_Model>;
|
||||
}
|
||||
|
||||
export default (sequelize: Sequelize) => {
|
||||
|
||||
@ -37,7 +37,7 @@ export class QuoteItem_Model extends Model<
|
||||
declare subtotal: CreationOptional<number>;
|
||||
declare total: CreationOptional<number>;
|
||||
|
||||
declare quote?: NonAttribute<Quote_Model>;
|
||||
declare quote: NonAttribute<Quote_Model>;
|
||||
}
|
||||
|
||||
export default (sequelize: Sequelize) => {
|
||||
|
||||
@ -1,3 +1,7 @@
|
||||
import { UserContext } from "@/contexts/users/infrastructure/User.context";
|
||||
import { RepositoryManager } from "@/contexts/common/domain";
|
||||
import { createSequelizeAdapter } from "@/contexts/common/infrastructure/sequelize";
|
||||
|
||||
export const createContextMiddleware = () => UserContext.getInstance();
|
||||
export const createContextMiddleware = () => ({
|
||||
adapter: createSequelizeAdapter(),
|
||||
repositoryManager: RepositoryManager.getInstance(),
|
||||
});
|
||||
|
||||
@ -8,13 +8,7 @@ import Express from "express";
|
||||
export const QuoteRouter = (appRouter: Express.Router) => {
|
||||
const quoteRoutes: Express.Router = Express.Router({ mergeParams: true });
|
||||
|
||||
quoteRoutes.get(
|
||||
"/",
|
||||
checkUser,
|
||||
(req: Express.Request, res: Express.Response, next: Express.NextFunction) =>
|
||||
listQuotesController(res.locals["context"]).execute(req, res, next)
|
||||
);
|
||||
|
||||
quoteRoutes.get("/", checkUser, listQuotesController);
|
||||
quoteRoutes.post("/", checkUser, createQuoteController);
|
||||
|
||||
//quoteRoutes.put("/:quoteId", checkUser, updateQuoteController);
|
||||
|
||||
@ -2,10 +2,10 @@ import Express from "express";
|
||||
import { createContextMiddleware } from "./context.middleware";
|
||||
import {
|
||||
DealerRouter,
|
||||
QuoteRouter,
|
||||
authRouter,
|
||||
catalogRouter,
|
||||
profileRouter,
|
||||
quoteRoutes,
|
||||
usersRouter,
|
||||
} from "./routes";
|
||||
|
||||
@ -22,6 +22,7 @@ export const v1Routes = () => {
|
||||
|
||||
return next();
|
||||
});
|
||||
|
||||
routes.use((req, res, next) => {
|
||||
console.log(`[${new Date().toLocaleTimeString()}] Incoming request to ${req.path}`);
|
||||
next();
|
||||
@ -32,7 +33,7 @@ export const v1Routes = () => {
|
||||
usersRouter(routes);
|
||||
catalogRouter(routes);
|
||||
DealerRouter(routes);
|
||||
quoteRoutes(routes);
|
||||
QuoteRouter(routes);
|
||||
|
||||
return routes;
|
||||
};
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
import { IMoney_Response_DTO } from "shared/lib/contexts/common";
|
||||
import { IMoney_Response_DTO } from "../../../../../common";
|
||||
|
||||
export interface IListQuotes_Response_DTO {
|
||||
id: string;
|
||||
|
||||
status: string;
|
||||
date: string;
|
||||
language_code: string;
|
||||
reference: string;
|
||||
customer_information: string;
|
||||
lang_code: string;
|
||||
currency_code: string;
|
||||
|
||||
subtotal: IMoney_Response_DTO;
|
||||
|
||||
@ -4,8 +4,13 @@ import { IMoney_Request_DTO, Result, RuleValidator } from "../../../../../common
|
||||
export interface IUpdateQuote_Request_DTO {
|
||||
status: string;
|
||||
date: string;
|
||||
language_code: string;
|
||||
reference: string;
|
||||
customer_information: string;
|
||||
lang_code: string;
|
||||
currency_code: string;
|
||||
payment_method: string;
|
||||
notes: string;
|
||||
validity: string;
|
||||
|
||||
items: IUpdateQuoteItem_Request_DTO[];
|
||||
}
|
||||
@ -20,8 +25,14 @@ export interface IUpdateQuoteItem_Request_DTO {
|
||||
export function ensureUpdateQuote_Request_DTOIsValid(quoteDTO: IUpdateQuote_Request_DTO) {
|
||||
const schema = Joi.object({
|
||||
date: Joi.string(),
|
||||
language: Joi.string(),
|
||||
currency: Joi.string(),
|
||||
reference: Joi.string(),
|
||||
lang_code: 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({
|
||||
description: Joi.string(),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user