coupon save on order

This commit is contained in:
2025-12-20 12:08:34 +03:30
parent cc3192e3ee
commit 172ceee4ff
2 changed files with 25 additions and 16 deletions
+24 -16
View File
@@ -18,12 +18,13 @@ import { Delivery } from '../../delivery/entities/delivery.entity';
import { DeliveryMethodEnum } from '../../delivery/interface/delivery'; import { DeliveryMethodEnum } from '../../delivery/interface/delivery';
import { Cart, CartItem } from '../interfaces/cart.interface'; import { Cart, CartItem } from '../interfaces/cart.interface';
import { CouponService } from 'src/modules/coupons/providers/coupon.service'; import { CouponService } from 'src/modules/coupons/providers/coupon.service';
import { OrderCouponDetail } from 'src/modules/orders/interface/order.interface'; import { OrderCouponDetail, OrderStatus } from 'src/modules/orders/interface/order.interface';
import { CouponType } from 'src/modules/coupons/interface/coupon'; import { CouponType } from 'src/modules/coupons/interface/coupon';
import { UserWallet } from 'src/modules/users/entities/user-wallet.entity'; import { UserWallet } from 'src/modules/users/entities/user-wallet.entity';
import { PaymentMethodEnum } from 'src/modules/payments/interface/payment'; import { PaymentMethodEnum } from 'src/modules/payments/interface/payment';
import { SetAllCartParmsDto } from '../dto/set-all-cart-params.dto'; import { SetAllCartParmsDto } from '../dto/set-all-cart-params.dto';
import { Order } from 'src/modules/orders/entities/order.entity';
@Injectable() @Injectable()
export class CartService { export class CartService {
private readonly CART_TTL = 3600; // 1 hour in seconds private readonly CART_TTL = 3600; // 1 hour in seconds
@@ -319,7 +320,7 @@ export class CartService {
latitude?: number | null, latitude?: number | null,
longitude?: number | null, longitude?: number | null,
): Promise<void> { ): Promise<void> {
if (latitude === undefined || latitude === null || longitude === undefined || longitude === null) { if (latitude === undefined || latitude === null || longitude === undefined || longitude === null) {
throw new BadRequestException('Address does not have coordinates'); throw new BadRequestException('Address does not have coordinates');
} }
@@ -343,7 +344,7 @@ export class CartService {
const polygon: [number, number][] = ring.map( const polygon: [number, number][] = ring.map(
coord => [Number(coord[0] ?? 0), Number(coord[1] ?? 0)] as [number, number], coord => [Number(coord[0] ?? 0), Number(coord[1] ?? 0)] as [number, number],
); );
if (!this.isPointInPolygon(point, polygon)) { if (!this.isPointInPolygon(point, polygon)) {
throw new BadRequestException('Address is outside the restaurant service area'); throw new BadRequestException('Address is outside the restaurant service area');
} }
} }
@@ -817,18 +818,25 @@ export class CartService {
private async assertCouponUsageLimit(userId: string, couponId: string, maxUsesPerUser?: number): Promise<void> { private async assertCouponUsageLimit(userId: string, couponId: string, maxUsesPerUser?: number): Promise<void> {
if (!maxUsesPerUser) return; if (!maxUsesPerUser) return;
const knex = this.em.getKnex(); // const knex = this.em.getKnex();
const result = await knex.raw( // const result = await knex.raw(
`SELECT COUNT(*)::int as count // `SELECT COUNT(*)::int as count
FROM orders // FROM orders
WHERE user_id = ? // WHERE user_id = ?
AND coupon_detail IS NOT NULL // AND coupon_detail IS NOT NULL
AND coupon_detail->>'couponId' = ? // AND coupon_detail->>'couponId' = ?
AND deleted_at IS NULL`, // AND deleted_at IS NULL`,
[userId, couponId], // [userId, couponId],
); // );
const userCouponUsageCount = result.rows?.[0]?.count ?? result[0]?.count ?? 0; const ordersThatUSedTheCouponCount = await this.em.count(Order, {
if (userCouponUsageCount >= maxUsesPerUser) { user: { id: userId },
couponDetail: { couponId: couponId },
status: { $ne: OrderStatus.CANCELED },
deletedAt: null,
});
console.log('ordersThatUSedTheCouponCount', ordersThatUSedTheCouponCount);
if (ordersThatUSedTheCouponCount >= maxUsesPerUser) {
throw new BadRequestException(`You have reached the maximum number of uses (${maxUsesPerUser}) for this coupon`); throw new BadRequestException(`You have reached the maximum number of uses (${maxUsesPerUser}) for this coupon`);
} }
} }
@@ -71,6 +71,7 @@ export class OrdersService {
carAddress: validated.carAddress, carAddress: validated.carAddress,
paymentMethod: validated.paymentMethod, paymentMethod: validated.paymentMethod,
couponDiscount: cart.couponDiscount || 0, couponDiscount: cart.couponDiscount || 0,
couponDetail: cart.coupon,
itemsDiscount: cart.itemsDiscount || 0, itemsDiscount: cart.itemsDiscount || 0,
totalDiscount: cart.totalDiscount || 0, totalDiscount: cart.totalDiscount || 0,
subTotal: cart.subTotal || 0, subTotal: cart.subTotal || 0,