2025-05-14 21:45:16 +02:00

275 lines
11 KiB
TypeScript

import _ from 'lodash';
import { ApolloError } from 'apollo-server-lambda';
import { Resolver, Authorized, Ctx, Query } from 'type-graphql';
import { Mutation, Arg } from 'type-graphql';
import { ApolloContext } from '@seed/interfaces/context';
import { updatePaymentIntent } from '@services/module-payments/helpers/payments.helpers';
import OrderEngineModel from '../../order.model';
import PromoModel, { validatePromo } from '@services/module-payments/functions/promos/promo.model';
import { PaymentIntentInfo } from '@services/module-payments/components/components.payments';
import { addToCart, getCurrentCartOrder } from '@services/module-payments/functions/orders/services/CartService';
import { LineItemBaseSchema } from '@src/orders/components/line.schema';
import { OrderEngineSchema } from '../../schemas/order.schema';
import {
CartEngineAddCountryCodeSchema,
CartEngineAddPromoSchema,
CartEngineUpdateOrDeleteSchema,
CartEngineUpdateSchema,
} from '../schemas/cart.schema.inputs';
import { OrderNewInputSchema } from '@src/orders/components/components.cart';
@Resolver(OrderEngineSchema)
export default class CartEngineResolver {
/*
██████╗ ██╗ ██╗███████╗██████╗ ██╗ ██╗
██╔═══██╗██║ ██║██╔════╝██╔══██╗╚██╗ ██╔╝
██║ ██║██║ ██║█████╗ ██████╔╝ ╚████╔╝
██║▄▄ ██║██║ ██║██╔══╝ ██╔══██╗ ╚██╔╝
╚██████╔╝╚██████╔╝███████╗██║ ██║ ██║
╚══▀▀═╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═╝
*/
@Query(() => OrderEngineSchema)
@Authorized()
async cartsGetMe(@Ctx() ctx: ApolloContext, @Arg('input', { nullable: true }) input?: OrderNewInputSchema): Promise<OrderEngineSchema> {
try {
return await getCurrentCartOrder(ctx, input);
} catch (error) {
throw error;
}
}
/*
███╗ ███╗██╗ ██╗████████╗ █████╗ ████████╗ ██████╗ ██████╗ ███████╗
████╗ ████║██║ ██║╚══██╔══╝██╔══██╗╚══██╔══╝██╔═══██╗██╔══██╗██╔════╝
██╔████╔██║██║ ██║ ██║ ███████║ ██║ ██║ ██║██████╔╝███████╗
██║╚██╔╝██║██║ ██║ ██║ ██╔══██║ ██║ ██║ ██║██╔══██╗╚════██║
██║ ╚═╝ ██║╚██████╔╝ ██║ ██║ ██║ ██║ ╚██████╔╝██║ ██║███████║
╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝
*/
@Mutation(() => OrderEngineSchema)
@Authorized()
async cartsAddOneItem(@Arg('input') input: LineItemBaseSchema, @Ctx() ctx: ApolloContext): Promise<OrderEngineSchema> {
return await addToCart(input, ctx);
}
@Mutation(() => OrderEngineSchema)
@Authorized()
async cartsUpdateOneItem(@Arg('input') input: CartEngineUpdateSchema, @Ctx() ctx: ApolloContext): Promise<OrderEngineSchema> {
const account = ctx.ctx.user;
const orderModel = new OrderEngineModel();
try {
const currentCartOrder = await getCurrentCartOrder(ctx);
// Check the lines
const lineIndex = _.findIndex(currentCartOrder.lines, function(o) {
if (o.productId == input.productId && _.isEqual(JSON.parse(JSON.stringify(o.options)), JSON.parse(JSON.stringify(o.options))))
return true;
else return false;
});
if (lineIndex === -1) throw new ApolloError('cart.item.notFound', '404', { productId: input.productId });
if (input.newQuantity == 0) currentCartOrder.lines.splice(lineIndex, 1);
else {
// Update the quantity
currentCartOrder.lines[lineIndex].quantity = input.newQuantity;
}
const paymentIntentUpdated: PaymentIntentInfo = await updatePaymentIntent(currentCartOrder.paymentIntent, {
amount: await currentCartOrder.finalPrice(ctx),
currency: currentCartOrder.currency,
account,
});
return await orderModel.updateOneCustom({
query: { _id: currentCartOrder._id },
updateRequest: {
$set: {
paymentIntent: paymentIntentUpdated,
lines: currentCartOrder.lines,
},
},
ctx,
});
} catch (error) {
throw error;
}
}
@Mutation(() => OrderEngineSchema)
@Authorized()
async cartsUpdateOrDeleteOneItem(@Arg('input') input: CartEngineUpdateOrDeleteSchema, @Ctx() ctx: ApolloContext): Promise<OrderEngineSchema> {
const account = ctx.ctx.user;
const orderModel = new OrderEngineModel();
const { lineId, newQuantity } = input;
try {
const currentCartOrder = await getCurrentCartOrder(ctx);
// Check the lines
const lineIndex = _.findIndex(currentCartOrder.lines, { _id: lineId });
if (lineIndex === -1) throw new ApolloError('cart.line.notFound', '404', { lineId: input.lineId });
if (newQuantity == 0) currentCartOrder.lines.splice(lineIndex, 1);
else {
// Update the quantity
currentCartOrder.lines[lineIndex].quantity = newQuantity;
}
const paymentIntentUpdated: PaymentIntentInfo = await updatePaymentIntent(currentCartOrder.paymentIntent, {
amount: await currentCartOrder.finalPrice(ctx),
currency: currentCartOrder.currency,
account,
});
return await orderModel.updateOneCustom({
query: { _id: currentCartOrder._id },
updateRequest: {
$set: {
paymentIntent: paymentIntentUpdated,
lines: currentCartOrder.lines,
},
},
ctx,
});
} catch (error) {
throw error;
}
}
@Mutation(() => OrderEngineSchema)
@Authorized()
async cartsEmpty(@Ctx() ctx: ApolloContext): Promise<OrderEngineSchema> {
const orderModel = new OrderEngineModel();
try {
const currentCartOrder = await getCurrentCartOrder(ctx);
return await orderModel.updateOneCustom({
query: { _id: currentCartOrder._id },
updateRequest: {
$set: {
lines: [],
},
$unset: {
promoId: '',
countryCode: '',
locale: '',
},
},
ctx,
});
} catch (error) {
throw error;
}
}
@Mutation(() => OrderEngineSchema)
@Authorized()
async cartAddCountryCode(@Arg('input') input: CartEngineAddCountryCodeSchema, @Ctx() ctx: ApolloContext): Promise<OrderEngineSchema> {
const orderModel = new OrderEngineModel();
try {
const currentCartOrder = await getCurrentCartOrder(ctx);
if (!currentCartOrder) throw new ApolloError('cart.notFound', '404');
const lines = currentCartOrder.lines;
lines.map((line) => {
if (line.localeInfo) return (line.localeInfo.countryCode = input.countryCode);
return (line.localeInfo = { countryCode: input.countryCode });
});
return await orderModel.updateOneCustom({
query: { _id: currentCartOrder._id },
updateRequest: {
$set: { countryCode: input.countryCode, lines },
},
ctx,
});
} catch (error) {
throw error;
}
}
@Mutation(() => OrderEngineSchema)
@Authorized()
async cartAddPromo(@Arg('input') input: CartEngineAddPromoSchema, @Ctx() ctx: ApolloContext): Promise<OrderEngineSchema> {
const orderModel = new OrderEngineModel();
const promoModel = new PromoModel();
try {
const currentCartOrder = await getCurrentCartOrder(ctx);
if (!currentCartOrder) throw new ApolloError('cart.notFound', '404');
await promoModel.getOne({ code: input.promoCode }, ctx);
await validatePromo(input.promoCode, ctx);
const lines = currentCartOrder.lines;
lines.map((line) => {
return (line.promoId = promoModel._id);
});
const paymentIntentUpdated: PaymentIntentInfo = await updatePaymentIntent(currentCartOrder.paymentIntent, {
amount: await currentCartOrder.finalPrice(ctx),
currency: currentCartOrder.currency,
account: ctx.ctx.user,
});
return await orderModel.updateOneCustom({
query: { _id: currentCartOrder._id },
updateRequest: {
// finalPrice: currentCart.finalPrice,
$set: { promoId: promoModel._id, lines, paymentIntent: paymentIntentUpdated },
},
ctx,
});
} catch (error) {
throw error;
}
}
@Mutation(() => OrderEngineSchema)
@Authorized()
async cartRemovePromo(@Ctx() ctx: ApolloContext): Promise<OrderEngineSchema> {
const orderModel = new OrderEngineModel();
try {
const currentCartOrder = await getCurrentCartOrder(ctx);
if (!currentCartOrder) throw new ApolloError('cart.notFound', '404');
const lines = currentCartOrder.lines;
lines.forEach((line) => {
delete line.promoId;
});
const paymentIntentUpdated: PaymentIntentInfo = await updatePaymentIntent(currentCartOrder.paymentIntent, {
amount: await currentCartOrder.finalPrice(ctx),
currency: currentCartOrder.currency,
account: ctx.ctx.user,
});
return await orderModel.updateOneCustom({
query: { _id: currentCartOrder._id },
updateRequest: {
$unset: {
promoId: '',
},
$set: {
lines,
paymentIntent: paymentIntentUpdated,
},
},
ctx,
});
} catch (error) {
throw error;
}
}
}