de periferica: actualizar stock y precios dinamicamente

This commit is contained in:
f 2021-10-27 15:47:58 -03:00
parent bb485918bc
commit 8cdc6d44ec
3 changed files with 51 additions and 25 deletions

View file

@ -1,5 +1,6 @@
data-controller="cart" data-controller="cart"
data-target="stock.product" data-target="stock.product"
data-sku="{{ include.product.sku }}"
data-cart-url="{{ include.product.url }}" data-cart-url="{{ include.product.url }}"
data-cart-variant-id="{{ include.product.variant_id }}" data-cart-variant-id="{{ include.product.variant_id }}"
data-cart-image="{{ include.product.image.path | thumbnail: 212, 300 }}" data-cart-image="{{ include.product.image.path | thumbnail: 212, 300 }}"

View file

@ -52,7 +52,7 @@
{%- include_cached menu.html active_cache_key=page.layout %} {%- include_cached menu.html active_cache_key=page.layout %}
<main data-controller="scroll"> <main data-controller="scroll stock" data-per-page="100">
{{ content }} {{ content }}
</main> </main>

View file

@ -12,13 +12,26 @@ export default class extends Controller {
static targets = [ 'product' ] static targets = [ 'product' ]
async connect () { async connect () {
if (this.variant_ids.length === 0) return const all_skus = this.skus
const ids = this.variant_ids.join(',') if (all_skus.length === 0) return
const filter = { ids }
// El paginado es para prevenir que la petición se haga muy grande y
// falle entera.
const pages = Math.ceil(all_skus.length / this.per_page)
let start = 0
let end = this.per_page
for (let local_page = 1; local_page <= pages; local_page++) {
const skus = all_skus.slice(start, end).join(',')
start = this.per_page * local_page
end = start + this.per_page
const filter = { skus }
let response = await window.spree.products.list({ filter }) let response = await window.spree.products.list({ filter })
// TODO: Gestionar errores
if (response.isFail()) { if (response.isFail()) {
console.error(response.fail()) console.error(response.fail())
return return
@ -32,7 +45,6 @@ export default class extends Controller {
for (let page = 2; page <= response.success().meta.total_pages; page++) { for (let page = 2; page <= response.success().meta.total_pages; page++) {
response = await window.spree.products.list({ filter, page }) response = await window.spree.products.list({ filter, page })
// TODO: Gestionar errores
if (response.isFail()) { if (response.isFail()) {
console.error(response.fail()) console.error(response.fail())
continue continue
@ -41,30 +53,43 @@ export default class extends Controller {
this.update_local_products(response.success().data) this.update_local_products(response.success().data)
} }
} }
}
/* /*
* La lista de todas las variantes incluidas en el controlador que no * La lista de todas las variantes incluidas en el controlador que no
* estén vacías. * estén vacías. Usamos los SKUs porque no tenemos forma de filtrar
* por ID.
* *
* @return [Array] * @return [Array]
*/ */
get variant_ids () { get skus () {
if (!this._variant_ids) this._variant_ids = [...new Set(this.productTargets.map(p=> p.dataset.cartVariantId).filter(x => x.length > 0))] return [...new Set(this.productTargets.map(p=> p.dataset.sku).filter(x => x.length > 0))]
}
return this._variant_ids /*
* La cantidad de productos por página que vamos a pedir
*/
get per_page () {
if (!this._per_page) {
this._per_page = parseInt(this.element.dataset.perPage)
if (isNaN(this._per_page)) this._per_page = 100
}
return this._per_page
} }
/* /*
* Los productos pueden estar duplicados así que buscamos todos. * Los productos pueden estar duplicados así que buscamos todos.
*/ */
update_local_products (products) { update_local_products (products) {
for (const product of products) { for (const local of this.productTargets) {
for (const local of this.productTargets.filter(local => local.dataset.cartVariantId === product.id)) { for (const product of products.filter(p => local.dataset.cartVariantId === p.relationships.default_variant.data.id)) {
local.dataset.cartInStock = product.attributes.in_stock local.dataset.cartInStock = product.attributes.in_stock
local.dataset.cartPrice = product.attributes.price local.dataset.cartPrice = product.attributes.price
local.querySelectorAll('[data-stock-add]').forEach(button => button.disabled = !product.attributes.in_stock) local.querySelectorAll('[data-stock-add]').forEach(button => button.disabled = !product.attributes.in_stock)
local.querySelectorAll('[data-stock-price]').forEach(price => price.innerText = product.attributes.display_price) local.querySelectorAll('[data-stock-price]').forEach(price => price.innerText = parseInt(product.attributes.price))
local.querySelectorAll('[data-stock-currency]').forEach(currency => currency.innerText = product.attributes.currency)
} }
} }
} }