Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions resources/js/package.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ function init() {
this.scrollLock = bool
}
},

resizedPath(imagePath, size, store = null) {
if (!store) {
store = window.config.store
Expand All @@ -135,6 +136,10 @@ function init() {
hasCart() {
return this.cart?.id && this.cart.items.length
},

canOrder() {
return this.cart.items.every((item) => item.is_available)
},
},
watch: {
loadingCount: function (count) {
Expand Down
22 changes: 22 additions & 0 deletions resources/js/stores/useCart.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,21 @@ export const getAttributeValues = async function () {
return await fetchAttributeValuesMemo(window.config.cart_attributes)
}

export const checkAvailability = function (cartItem) {
// Here we polyfill the is_available field. We need to do this
// because the default is_available field supported by Magento
// always returns true, even when a product is out of stock. This
// should be fixed in the next Magento release, reference: https://github.com/magento/magento2/blame/2.4-develop/app/code/Magento/QuoteGraphQl/Model/CartItem/ProductStock.php#L61
if ('stock_item' in cartItem.product && 'in_stock' in cartItem.product.stock_item && cartItem.product.stock_item.in_stock !== null) {
return cartItem.product.stock_item.in_stock
}

// Without the use of compadre the in stock check can't be
// done. We will need to always allow users to go on to
// the checkout.
return true
}

export const cart = computed({
get() {
if (!cartStorage.value?.id && mask.value) {
Expand All @@ -107,6 +122,12 @@ export const cart = computed({
getAttributeValues()
.then((response) => {
if (!response?.data?.customAttributeMetadata?.items) {
value.items = value.items.map((item) => {
item.is_available = checkAvailability(item)

return item
})

return
}

Expand All @@ -118,6 +139,7 @@ export const cart = computed({
)

value.items = value.items.map((cartItem) => {
cartItem.is_available = checkAvailability(item)
cartItem.product.attribute_values = {}

for (const key in mapping) {
Expand Down
3 changes: 3 additions & 0 deletions resources/views/cart/item.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ class="mx-auto"
<div class="flex flex-col items-start">
<a :href="item.product.url_key + item.product.url_suffix | url" class="font-bold" dusk="cart-item-name">
@{{ item.product.name }}
<div class="text-red-600" v-if="!item.is_available">
@lang('This product is out of stock, remove it to continue your order.')
</div>
</a>
<div v-for="option in item.configurable_options">
@{{ option.option_label }}: @{{ option.value_label }}
Expand Down
1 change: 1 addition & 0 deletions resources/views/cart/queries/cart.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ items {
}
@if (Rapidez::checkCompadreVersion('0.0.1'))
stock_item {
in_stock
max_sale_qty
min_sale_qty
qty_increments
Expand Down
13 changes: 10 additions & 3 deletions resources/views/cart/sidebar.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@
</div>
</dl>

<x-rapidez::button href="{{ route('checkout') }}" dusk="checkout" class="w-full text-center">
@lang('Checkout')
</x-rapidez::button>
<div class="w-full" :class="{ 'cursor-not-allowed': !canOrder }">
<x-rapidez::button
dusk="checkout"
href="{{ route('checkout') }}"
class="w-full text-center"
v-bind:class="{ 'pointer-events-none': !canOrder }"
>
@lang('Checkout')
</x-rapidez::button>
</div>
16 changes: 12 additions & 4 deletions resources/views/layouts/partials/header/minicart.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@
<div v-if="isOpen" class="absolute right-0 bg-white border shadow rounded-xl p-5 {{ config('rapidez.frontend.z-indexes.header-dropdowns') }}">
<table class="w-full mb-3">
<tr v-for="item in cart.items" class="[&>*]:pb-3">
<td class="block w-48 truncate overflow-hidden">@{{ item.product.name }}</td>
<td class="block w-48 truncate overflow-hidden">
@{{ item.product.name }}
<div class="text-red-600" v-if="!item.is_available">
@lang('Out of stock')
</div>
</td>
<td class="text-right px-4">@{{ item.quantity }}</td>
<td class="text-right">@{{ item.prices.row_total.value | price }}</td>
</tr>
Expand All @@ -20,9 +25,12 @@
<x-rapidez::button.outline href="{{ route('cart') }}" class="mr-5">
@lang('Show cart')
</x-rapidez::button.outline>
<x-rapidez::button href="{{ route('checkout') }}">
@lang('Checkout')
</x-rapidez::button>

<div class="w-full" :class="{ 'cursor-not-allowed': !canOrder }">
<x-rapidez::button href="{{ route('checkout') }}" v-bind:class="{ 'pointer-events-none': !canOrder }">
@lang('Checkout')
</x-rapidez::button>
</div>
</div>
</div>
</div>
Expand Down
Loading