Skip to content

Commit 1bf4cd9

Browse files
committed
feat: update cart schema and service to use attribute_value_id instead of product_id
1 parent 0a915da commit 1bf4cd9

File tree

4 files changed

+99
-52
lines changed

4 files changed

+99
-52
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
Warnings:
3+
4+
- You are about to drop the column `product_id` on the `cart_items` table. All the data in the column will be lost.
5+
- A unique constraint covering the columns `[cart_id,attribute_value_id]` on the table `cart_items` will be added. If there are existing duplicate values, this will fail.
6+
- Added the required column `attribute_value_id` to the `cart_items` table without a default value. This is not possible if the table is not empty.
7+
8+
*/
9+
-- DropForeignKey
10+
ALTER TABLE "cart_items" DROP CONSTRAINT "cart_items_product_id_fkey";
11+
12+
-- DropIndex
13+
DROP INDEX "cart_items_cart_id_product_id_key";
14+
15+
-- AlterTable
16+
ALTER TABLE "cart_items" DROP COLUMN "product_id",
17+
ADD COLUMN "attribute_value_id" INTEGER NOT NULL;
18+
19+
-- CreateIndex
20+
CREATE UNIQUE INDEX "cart_items_cart_id_attribute_value_id_key" ON "cart_items"("cart_id", "attribute_value_id");
21+
22+
-- AddForeignKey
23+
ALTER TABLE "cart_items" ADD CONSTRAINT "cart_items_attribute_value_id_fkey" FOREIGN KEY ("attribute_value_id") REFERENCES "variants_attributes_values"("id") ON DELETE CASCADE ON UPDATE CASCADE;

prisma/schema.prisma

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ model Product {
6363
updatedAt DateTime @default(now()) @map("updated_at") @db.Timestamp(0)
6464
6565
category Category? @relation(fields: [categoryId], references: [id], onDelete: SetNull)
66-
cartItems CartItem[]
66+
6767
orderItems OrderItem[]
6868
variantAttributeValues VariantAttributeValue[]
6969
@@ -92,6 +92,8 @@ model VariantAttributeValue {
9292
9393
variantAttribute VariantAttribute @relation(fields: [attributeId], references: [id])
9494
product Product @relation(fields: [productId], references: [id])
95+
96+
CartItem CartItem[]
9597
9698
@@unique([attributeId, productId, value], name: "unique_attribute_product_value")
9799
@@map("variants_attributes_values")
@@ -113,15 +115,15 @@ model Cart {
113115
model CartItem {
114116
id Int @id @default(autoincrement())
115117
cartId Int @map("cart_id")
116-
productId Int @map("product_id")
118+
attributeValueId Int @map("attribute_value_id")
117119
quantity Int
118120
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(0)
119121
updatedAt DateTime @default(now()) @map("updated_at") @db.Timestamp(0)
120122
121123
cart Cart @relation(fields: [cartId], references: [id], onDelete: Cascade)
122-
product Product @relation(fields: [productId], references: [id], onDelete: Cascade)
124+
variantAttributeValue VariantAttributeValue @relation(fields: [attributeValueId], references: [id], onDelete: Cascade)
123125
124-
@@unique([cartId, productId], name: "unique_cart_item")
126+
@@unique([cartId, attributeValueId], name: "unique_cart_item")
125127
@@map("cart_items")
126128
}
127129

src/models/cart.model.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export type CartProductInfo = Pick<
3333
export type CartItemWithProduct = {
3434
product: CartProductInfo;
3535
quantity: number;
36+
attributeId: number;
3637
};
3738

3839
// Tipo para el carrito con items y productos incluidos

src/services/cart.service.ts

Lines changed: 69 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,22 @@ async function getCart(
2020
if (!whereCondition) return null;
2121

2222
const data = await prisma.cart.findFirst({
23+
// se modifico esta funcion
2324
where: whereCondition,
2425
include: {
2526
items: {
2627
include: {
27-
product: {
28-
select: {
29-
id: true,
30-
title: true,
31-
imgSrc: true,
32-
alt: true,
33-
price: true,
34-
isOnSale: true,
28+
variantAttributeValue: {
29+
include: {
30+
product: {
31+
select: {
32+
id: true,
33+
title: true,
34+
imgSrc: true,
35+
alt: true,
36+
isOnSale: true,
37+
},
38+
},
3539
},
3640
},
3741
},
@@ -49,9 +53,10 @@ async function getCart(
4953
items: data.items.map((item) => ({
5054
...item,
5155
product: {
52-
...item.product,
53-
price: item.product.price.toNumber(),
56+
...item.variantAttributeValue.product,
57+
price: item.variantAttributeValue.price.toNumber(),
5458
},
59+
variantAttributeValue: item.variantAttributeValue,
5560
})),
5661
};
5762
}
@@ -82,14 +87,17 @@ export async function getOrCreateCart(
8287
include: {
8388
items: {
8489
include: {
85-
product: {
86-
select: {
87-
id: true,
88-
title: true,
89-
imgSrc: true,
90-
alt: true,
91-
price: true,
92-
isOnSale: true,
90+
variantAttributeValue: {
91+
include: {
92+
product: {
93+
select: {
94+
id: true,
95+
title: true,
96+
imgSrc: true,
97+
alt: true,
98+
isOnSale: true,
99+
},
100+
},
93101
},
94102
},
95103
},
@@ -104,9 +112,10 @@ export async function getOrCreateCart(
104112
items: newCart.items.map((item) => ({
105113
...item,
106114
product: {
107-
...item.product,
108-
price: item.product.price.toNumber(),
115+
...item.variantAttributeValue.product,
116+
price: item.variantAttributeValue.price.toNumber(),
109117
},
118+
variantAttributeValue: item.variantAttributeValue,
110119
})),
111120
};
112121
}
@@ -130,7 +139,7 @@ export async function createRemoteItems(
130139
await prisma.cartItem.createMany({
131140
data: items.map((item) => ({
132141
cartId: cart.id,
133-
productId: item.product.id,
142+
attributeValueId: item.attributeId, // modificar
134143
quantity: item.quantity,
135144
})),
136145
});
@@ -146,12 +155,14 @@ export async function createRemoteItems(
146155
export async function alterQuantityCartItem(
147156
userId: User["id"] | undefined,
148157
sessionCartId: string | undefined,
149-
productId: number,
158+
attributeId: number,
150159
quantity: number = 1
151160
): Promise<CartWithItems> {
152161
const cart = await getOrCreateCart(userId, sessionCartId);
153162

154-
const existingItem = cart.items.find((item) => item.product.id === productId);
163+
const existingItem = cart.items.find(
164+
(item) => item.attributeValueId === attributeId
165+
);
155166

156167
if (existingItem) {
157168
const newQuantity = existingItem.quantity + quantity;
@@ -170,7 +181,7 @@ export async function alterQuantityCartItem(
170181
await prisma.cartItem.create({
171182
data: {
172183
cartId: cart.id,
173-
productId,
184+
attributeValueId: attributeId,
174185
quantity,
175186
},
176187
});
@@ -236,14 +247,17 @@ export async function linkCartToUser(
236247
include: {
237248
items: {
238249
include: {
239-
product: {
240-
select: {
241-
id: true,
242-
title: true,
243-
imgSrc: true,
244-
alt: true,
245-
price: true,
246-
isOnSale: true,
250+
variantAttributeValue: {
251+
include: {
252+
product: {
253+
select: {
254+
id: true,
255+
title: true,
256+
imgSrc: true,
257+
alt: true,
258+
isOnSale: true,
259+
},
260+
},
247261
},
248262
},
249263
},
@@ -258,9 +272,10 @@ export async function linkCartToUser(
258272
items: updatedCart.items.map((item) => ({
259273
...item,
260274
product: {
261-
...item.product,
262-
price: item.product.price.toNumber(),
275+
...item.variantAttributeValue.product,
276+
price: item.variantAttributeValue.price.toNumber(),
263277
},
278+
variantAttributeValue: item.variantAttributeValue,
264279
})),
265280
};
266281
}
@@ -285,41 +300,46 @@ export async function mergeGuestCartWithUserCart(
285300
include: {
286301
items: {
287302
include: {
288-
product: {
289-
select: {
290-
id: true,
291-
title: true,
292-
imgSrc: true,
293-
alt: true,
294-
price: true,
295-
isOnSale: true,
303+
variantAttributeValue: {
304+
include: {
305+
product: {
306+
select: {
307+
id: true,
308+
title: true,
309+
imgSrc: true,
310+
alt: true,
311+
isOnSale: true,
312+
},
313+
},
296314
},
297315
},
298316
},
299317
},
300318
},
301319
});
320+
302321
return {
303322
...updatedCart,
304323
items: updatedCart.items.map((item) => ({
305324
...item,
306325
product: {
307-
...item.product,
308-
price: item.product.price.toNumber(),
326+
...item.variantAttributeValue.product,
327+
price: item.variantAttributeValue.price.toNumber(),
309328
},
329+
variantAttributeValue: item.variantAttributeValue,
310330
})),
311331
};
312332
}
313333

314334
// Obtener productos duplicados para eliminarlos del carrito del usuario
315-
const guestProductIds = guestCart.items.map((item) => item.productId);
335+
const guestAttributeValueIds = guestCart.items.map((item) => item.attributeValueId);
316336

317337
// Eliminar productos del carrito usuario que también existan en el carrito invitado
318338
await prisma.cartItem.deleteMany({
319339
where: {
320340
cartId: userCart.id,
321-
productId: {
322-
in: guestProductIds,
341+
attributeValueId: {
342+
in: guestAttributeValueIds,
323343
},
324344
},
325345
});
@@ -328,7 +348,7 @@ export async function mergeGuestCartWithUserCart(
328348
await prisma.cartItem.createMany({
329349
data: guestCart.items.map((item) => ({
330350
cartId: userCart.id,
331-
productId: item.productId,
351+
attributeValueId: item.attributeValueId,
332352
quantity: item.quantity,
333353
})),
334354
});
@@ -341,3 +361,4 @@ export async function mergeGuestCartWithUserCart(
341361
// Devolver el carrito actualizado del usuario
342362
return await getCart(userId);
343363
}
364+

0 commit comments

Comments
 (0)