From 5b6b7a57fdde7e63dd99c63e9cfdf0bcc55ec792 Mon Sep 17 00:00:00 2001 From: mkucmus Date: Mon, 24 Apr 2023 14:19:40 +0200 Subject: [PATCH 1/4] feat(composables): new total price property for useCartItem composable --- .changeset/cyan-yaks-return.md | 5 ++ .changeset/warm-snakes-sort.md | 5 ++ packages/composables/src/useCartItem.ts | 69 ++++++++++++--- .../components/checkout/CheckoutCartItem.vue | 88 ++++++++----------- 4 files changed, 104 insertions(+), 63 deletions(-) create mode 100644 .changeset/cyan-yaks-return.md create mode 100644 .changeset/warm-snakes-sort.md diff --git a/.changeset/cyan-yaks-return.md b/.changeset/cyan-yaks-return.md new file mode 100644 index 000000000..e9b34cdcf --- /dev/null +++ b/.changeset/cyan-yaks-return.md @@ -0,0 +1,5 @@ +--- +"vue-demo-store": minor +--- + +Display cart item total price instead of unit price diff --git a/.changeset/warm-snakes-sort.md b/.changeset/warm-snakes-sort.md new file mode 100644 index 000000000..9739070fd --- /dev/null +++ b/.changeset/warm-snakes-sort.md @@ -0,0 +1,5 @@ +--- +"@shopware-pwa/composables-next": patch +--- + +Add item total price property for useCartItem composable diff --git a/packages/composables/src/useCartItem.ts b/packages/composables/src/useCartItem.ts index b7d067e72..c9af57b51 100644 --- a/packages/composables/src/useCartItem.ts +++ b/packages/composables/src/useCartItem.ts @@ -1,6 +1,6 @@ -import { computed, ComputedRef, Ref, unref } from "vue"; +import { computed, ComputedRef, Ref } from "vue"; import { removeCartItem, getProduct } from "@shopware-pwa/api-client"; -import { +import type { LineItem, LineItemType, ClientApiError, @@ -13,14 +13,45 @@ import { getMainImageUrl } from "@shopware-pwa/helpers-next"; import { useShopwareContext, useCart } from "."; export type UseCartItemReturn = { + /** + * Calculated price {number} for the current item + */ itemRegularPrice: ComputedRef; + /** + * Calculated price {number} for the current item if list price is set + */ itemSpecialPrice: ComputedRef; + /** + * Total price for the current item of given quantity in the cart + */ + itemTotalPrice: ComputedRef; + /** + * Thumbnail url for the current item's entity + */ itemImageThumbnailUrl: ComputedRef; + /** + * Options (of variation) for the current item + */ itemOptions: ComputedRef; + /** + * Type of the current item: "product" or "promotion" + */ itemType: ComputedRef; + /** + * Determines if the current item is a product + */ isProduct: ComputedRef; + /** + * Determines if the current item is a promotion + */ isPromotion: ComputedRef; + /** + * Stock information for the current item + */ itemStock: ComputedRef; + /** + * Quantity of the current item in the cart + */ itemQuantity: ComputedRef; /** * Changes the current item quantity in the cart @@ -32,6 +63,8 @@ export type UseCartItemReturn = { removeItem(): Promise; /** * Get SEO data for the current item + * + * @deprecated */ getProductItemSeoUrlData(): Promise; }; @@ -52,19 +85,25 @@ export function useCartItem(cartItem: Ref): UseCartItemReturn { const itemQuantity = computed(() => cartItem.value.quantity); const itemImageThumbnailUrl = computed(() => getMainImageUrl(cartItem.value)); - // TODO: use helper instead - - const itemRegularPrice = computed(() => cartItem.value.price?.unitPrice); + const itemRegularPrice = computed( + () => + cartItem.value?.price?.listPrice?.price || + cartItem.value?.price?.unitPrice, + ); const itemSpecialPrice = computed( - () => cartItem.value.price?.listPrice && cartItem.value.price.unitPrice + () => + cartItem.value?.price?.listPrice?.price && + cartItem.value?.price?.unitPrice, ); + const itemTotalPrice = computed(() => cartItem.value.price?.totalPrice); + const itemOptions = computed( () => (cartItem.value.type === "product" && (cartItem.value.payload as CartProductItem)?.options) || - [] + [], ); const itemStock = computed(() => cartItem.value.deliveryInformation?.stock); @@ -76,19 +115,20 @@ export function useCartItem(cartItem: Ref): UseCartItemReturn { const isPromotion = computed(() => cartItem.value.type === "promotion"); async function removeItem() { - const result = await removeCartItem(cartItem.value.id, apiInstance); - // broadcastUpcomingErrors(result); - await refreshCart(); + await removeCartItem(cartItem.value.id, apiInstance); + refreshCart(); } async function changeItemQuantity(quantity: number): Promise { - await changeProductQuantity({ + changeProductQuantity({ id: cartItem.value.id, quantity: quantity, }); - // broadcastUpcomingErrors(result); } + /** + * @deprecated Method is not used anymore and the case should be solved on project level instead due to performance reasons. + */ async function getProductItemSeoUrlData(): Promise< ProductResponse | undefined > { @@ -104,13 +144,13 @@ export function useCartItem(cartItem: Ref): UseCartItemReturn { // associations: (getDefaults() as any).getProductItemsSeoUrlsData // .associations, }, - apiInstance + apiInstance, ); return result.product as unknown as ProductResponse; } catch (error) { console.error( "[useCart][getProductItemsSeoUrlsData]", - (error as ClientApiError).messages + (error as ClientApiError).messages, ); } @@ -123,6 +163,7 @@ export function useCartItem(cartItem: Ref): UseCartItemReturn { getProductItemSeoUrlData, itemRegularPrice, itemSpecialPrice, + itemTotalPrice, itemOptions, itemStock, itemQuantity, diff --git a/templates/vue-demo-store/components/checkout/CheckoutCartItem.vue b/templates/vue-demo-store/components/checkout/CheckoutCartItem.vue index 80df6058a..5e878624a 100644 --- a/templates/vue-demo-store/components/checkout/CheckoutCartItem.vue +++ b/templates/vue-demo-store/components/checkout/CheckoutCartItem.vue @@ -1,51 +1,51 @@