Skip to content

Commit

Permalink
fix: handle item maximum stock
Browse files Browse the repository at this point in the history
  • Loading branch information
csandru-plenty committed Oct 24, 2024
1 parent 1c9682b commit 8a846e0
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 11 deletions.
51 changes: 43 additions & 8 deletions apps/web/components/ui/CartProductCard/CartProductCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,12 @@
{{ n(currentFullPrice || 0, 'currency') }}
</span>
<UiQuantitySelector
ref="quantitySelectorReference"
:disabled="disabled"
@change-quantity="debounceQuantity"
:value="cartGetters.getItemQty(cartItem)"
:value="itemQuantitySelector"
:min-value="productGetters.getMinimumOrderQuantity(cartItem.variation || ({} as Product))"
:max-value="maximumOrderQuantity"
class="mt-4 sm:mt-0"
/>
</div>
Expand All @@ -125,21 +127,25 @@
<script setup lang="ts">
import { productGetters, productBundleGetters, cartGetters } from '@plentymarkets/shop-api';
import { SfLink, SfLoaderCircular, SfIconClose } from '@storefront-ui/vue';
import _ from 'lodash';
import type { CartProductCardProps } from '~/components/ui/CartProductCard/types';
import type { Product } from '@plentymarkets/shop-api';
import _ from 'lodash';
const { cartItem, disabled = false } = defineProps<CartProductCardProps>();
const emit = defineEmits(['load']);
const { addModernImageExtension, getImageForViewport } = useModernImage();
const { setCartItemQuantity, deleteCartItem } = useCart();
const { data: cartData, setCartItemQuantity, deleteCartItem } = useCart();
const { send } = useNotification();
const { t, n } = useI18n();
const localePath = useLocalePath();
const imageLoaded = ref(false);
const img = ref();
const deleteLoading = ref(false);
const emit = defineEmits(['load']);
const { cartItem, disabled = false } = defineProps<CartProductCardProps>();
const quantitySelectorReference = ref(null as any);
const itemQuantitySelector = ref(cartGetters.getItemQty(cartItem));
const maximumOrderQuantity = ref();
onMounted(() => {
const imgElement = (img.value?.$el as HTMLImageElement) || null;
Expand All @@ -156,13 +162,41 @@ onMounted(() => {
}
});
const changeQuantity = async (quantity: string) => {
const handleMaximumQuantityCheck = async (quantityCast: number) => {
if (!cartData.value?.itemQuantity || quantityCast <= cartData.value.itemQuantity) {
maximumOrderQuantity.value = undefined;
return;
}
maximumOrderQuantity.value = cartData.value.itemQuantity;
if (quantitySelectorReference.value) {
const event = new Event('input');
Object.defineProperty(event, 'target', {
value: { value: maximumOrderQuantity.value },
writable: true,
});
quantitySelectorReference.value.handleOnChange(event);
}
await setCartItemQuantity({
quantity: Number(quantity),
quantity: maximumOrderQuantity.value,
cartItemId: cartItem.id,
productId: cartItem.variationId,
});
};
const changeQuantity = async (quantity: string) => {
const quantityCast = Number(quantity);
if (Number.isNaN(quantityCast) || quantityCast === cartData.value.itemQuantity) return;
await setCartItemQuantity({
quantity: quantityCast,
cartItemId: cartItem.id,
productId: cartItem.variationId,
}).then(async () => await handleMaximumQuantityCheck(quantityCast));
};
const deleteItem = async () => {
deleteLoading.value = true;
await deleteCartItem({
Expand All @@ -175,6 +209,7 @@ const deleteItem = async () => {
const currentFullPrice = computed(() => {
return cartGetters.getCartItemPrice(cartItem) * cartGetters.getItemQty(cartItem);
});
const cartItemImage = computed(() => {
if (cartItem && cartItem.variation) {
return getImageForViewport(cartItem.variation, 'CartProductCard');
Expand Down
2 changes: 2 additions & 0 deletions apps/web/components/ui/QuantitySelector/QuantitySelector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,6 @@ const handleOnChange = (event: Event) => {
const nextValue = Number.parseFloat(currentValue);
set(clamp(nextValue, minValue, maxValue));
};
defineExpose({ handleOnChange });
</script>
22 changes: 21 additions & 1 deletion apps/web/composables/useCart/useCart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
SetCartItemQuantityParams,
DeleteCartItemParams,
CartItem,
CartItemError,
} from '@plentymarkets/shop-api';
import {
type UseCartReturn,
Expand Down Expand Up @@ -38,6 +39,10 @@ const migrateVariationData = (oldCart: Cart, nextCart: Cart = {} as Cart): Cart
return nextCart;
};

const isCartItemError = (data: Cart | CartItemError): data is CartItemError => {
return 'availableStock' in data;
};

/**
* @description Composable for managing cart.
* @returns UseCartReturn
Expand Down Expand Up @@ -186,9 +191,24 @@ export const useCart: UseCartReturn = () => {
cartItemId: params.cartItemId,
}),
);

useHandleError(error.value);

state.value.data = migrateVariationData(state.value.data, data?.value?.data) ?? state.value.data;
if (isCartItemError(data.value?.data as unknown as Cart | CartItemError)) {
const { $i18n } = useNuxtApp();
const { send } = useNotification();
const responseData = data?.value?.data as CartItemError;
state.value.data.itemQuantity = responseData.availableStock;

send({
message: $i18n.t('storefrontError.cart.reachedMaximumQuantity', {
maximumQuantity: responseData.availableStock,
}),
type: 'warning',
});
} else {
state.value.data = migrateVariationData(state.value.data, data?.value?.data as Cart) ?? state.value.data;
}

return state.value.data;
} catch (error) {
Expand Down
3 changes: 2 additions & 1 deletion apps/web/lang/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -883,7 +883,8 @@
"validationFailed": "Die Adresse ist ungültig."
},
"cart": {
"failedToRemoveItem": "Der Artikel konnte nicht entfernt werden."
"failedToRemoveItem": "Der Artikel konnte nicht entfernt werden.",
"reachedMaximumQuantity": "Dieser Artikel ist in einer maximalen Menge von {maximumQuantity} Stück verfügbar"
},
"contact": {
"emailAlreadyExists": "Die E-Mail Adresse existiert bereits.",
Expand Down
3 changes: 2 additions & 1 deletion apps/web/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -883,7 +883,8 @@
"validationFailed": "The address is invalid."
},
"cart": {
"failedToRemoveItem": "The item could not be removed."
"failedToRemoveItem": "The item could not be removed.",
"reachedMaximumQuantity": "This item is available in a maximum quantity of {maximumQuantity}"
},
"contact": {
"emailAlreadyExists": "The e-mail address already exists.",
Expand Down

0 comments on commit 8a846e0

Please sign in to comment.