This commit is contained in:
snt 2026-02-12 18:33:57 +01:00
parent f5a689bcc8
commit c308d538a3
3 changed files with 217 additions and 419 deletions

View file

@ -83,7 +83,7 @@ Este repositorio contiene addons personalizados y modificados de Odoo 18.0. El p
Pedir al usuario generar a través de UI, no sabemos el método correcto para exportar SÓLO las cadenas del addon sin incluir todo el sistema. Pedir al usuario generar a través de UI, no sabemos el método correcto para exportar SÓLO las cadenas del addon sin incluir todo el sistema.
``` ```
Usar sólo polib para trataer los archivos .po, msmerge corrompe los archivos. Usar sólo polib y apend cadenas en los archivos .po, msmerge corrompe los archivos.
``` ```

View file

@ -8,6 +8,7 @@
"summary": "Add default price category to suppliers and bulk update products", "summary": "Add default price category to suppliers and bulk update products",
"author": "Odoo Community Association (OCA), Criptomart", "author": "Odoo Community Association (OCA), Criptomart",
"license": "AGPL-3", "license": "AGPL-3",
"website": "https://git.criptomart.net/criptomart/addons-cm",
"depends": ["product_price_category", "sales_team", "product_main_seller"], "depends": ["product_price_category", "sales_team", "product_main_seller"],
"data": [ "data": [
"security/ir.model.access.csv", "security/ir.model.access.csv",

View file

@ -2,32 +2,22 @@
<odoo> <odoo>
<data> <data>
<!-- Template: Group Orders Page (Eskaera) --> <!-- Template: Group Orders Page (Eskaera) -->
<template id="eskaera_page" name="Eskaera Page"> <template id="eskaera_page" name="Eskaera Page">
<t t-call="website.layout"> <t t-call="website.layout">
<div <div id="wrap" class="eskaera-page oe_structure oe_empty" data-name="Eskaera Orders">
id="wrap" <div class="container">
class="eskaera-page oe_structure oe_empty" <div class="row">
data-name="Eskaera Orders" <div class="col-lg-12">
> <h1>Available Orders</h1>
<div class="container"> <p class="text-muted" role="status">Browse and select an order to view its products.</p>
<div class="row">
<div class="col-lg-12">
<h1>Available Orders</h1>
<p
class="text-muted"
role="status"
>Browse and select an order to view its products.</p>
</div> </div>
</div> </div>
<div class="row mt-4"> <div class="row mt-4">
<div class="col-lg-12"> <div class="col-lg-12">
<!-- Editable area: Above orders list --> <!-- Editable area: Above orders list -->
<div <div class="oe_structure oe_empty" data-name="Before Orders" />
class="oe_structure oe_empty"
data-name="Before Orders"
/>
<t t-if="active_orders"> <t t-if="active_orders">
<div <div
@ -315,18 +305,13 @@
</t> </t>
</div> </div>
</t> </t>
<t t-else=""> <t t-else="">
<div class="eskaera-empty-state"> <div class="eskaera-empty-state">
<div <div class="alert alert-info" role="status" aria-live="polite">
class="alert alert-info" <p>No group orders available this week.</p>
role="status" </div>
aria-live="polite" </div>
> </t>
<p
>No group orders available this week.</p>
</div>
</div>
</t>
<!-- Editable area: Below orders list --> <!-- Editable area: Below orders list -->
<div <div
@ -379,89 +364,58 @@
</t> </t>
</template> </template>
<!-- Small QWeb snippets used to render translated confirmation strings <!-- Small QWeb snippets used to render translated confirmation strings
Rendered via ir.ui.view._render_template() with lang in context Rendered via ir.ui.view._render_template() with lang in context
to ensure server-side translation regardless of call stack. --> to ensure server-side translation regardless of call stack. -->
<template id="confirm_message_snippet" name="Confirm Message Snippet"> <template id="confirm_message_snippet" name="Confirm Message Snippet">
<t t-esc="_('Thank you! Your order has been confirmed.')" /> <t t-esc="_('Thank you! Your order has been confirmed.')" />
</template> </template>
<template <template id="confirm_pickup_label_snippet" name="Confirm Pickup Label Snippet">
id="confirm_pickup_label_snippet" <t t-esc="_('Pickup Day')" />
name="Confirm Pickup Label Snippet" </template>
>
<t t-esc="_('Pickup Day')" />
</template>
<!-- Shared template: Order Header --> <!-- Shared template: Order Header -->
<template id="order_header" name="Order Header"> <template id="order_header" name="Order Header">
<div t-att-class="header_class or 'eskaera-order-header'"> <div t-att-class="header_class or 'eskaera-order-header'">
<div class="d-flex gap-5 align-items-center mb-4"> <div class="d-flex gap-5 align-items-center mb-4">
<t <t t-set="image_to_show" t-value="group_order.image or (group_order.group_ids[0].image_1920 if group_order.group_ids else False)" />
t-set="image_to_show" <t t-if="image_to_show">
t-value="group_order.image or (group_order.group_ids[0].image_1920 if group_order.group_ids else False)" <img t-att-src="image_data_uri(image_to_show)" alt="Order image" class="order-thumbnail-md" />
/> </t>
<t t-if="image_to_show"> <div class="flex-grow-1">
<img <h1 class="mb-2"><t t-esc="header_title or group_order.name" /></h1>
t-att-src="image_data_uri(image_to_show)" <t t-if="group_order.description">
alt="Order image" <p class="text-muted mb-0 order-desc-full"><t t-esc="group_order.description" /></p>
class="order-thumbnail-md" </t>
/> </div>
</t> </div>
<div class="flex-grow-1"> </div>
<h1 class="mb-2"><t </template>
t-esc="header_title or group_order.name"
/></h1> <!-- Template: Group Order Shop (Eskaera) -->
<t t-if="group_order.description"> <template id="eskaera_shop" name="Eskaera Shop">
<p class="text-muted mb-0 order-desc-full"><t <t t-call="website.layout">
t-esc="group_order.description" <div id="wrap" class="eskaera-shop-page oe_structure oe_empty" data-name="Eskaera Shop">
/></p> <div class="container">
</t> <!-- Order Header Info Panel -->
<div class="row mb-4">
<div class="col-lg-12">
<t t-call="website_sale_aplicoop.order_header">
<t t-set="header_class" t-value="'eskaera-order-header'" />
</t>
<div class="eskaera-order-header">
<div class="order-info-grid">
<div class="info-item">
<span t-att-class="'info-label'">Consumer Groups</span>
<span class="info-value"><t t-esc="', '.join(group_order.group_ids.mapped('name'))" /></span>
</div> </div>
</div> <t t-if="group_order.cutoff_day">
</div> <div class="info-item">
</template> <span t-att-class="'info-label'">Cutoff Day</span>
<span class="info-value"><t t-esc="day_names[int(group_order.cutoff_day) % 7]" /> (<t t-esc="group_order.cutoff_date.strftime('%d/%m/%Y')" />)</span>
<!-- Template: Group Order Shop (Eskaera) --> </div>
<template id="eskaera_shop" name="Eskaera Shop"> </t>
<t t-call="website.layout">
<div
id="wrap"
class="eskaera-shop-page oe_structure oe_empty"
data-name="Eskaera Shop"
>
<div class="container">
<!-- Order Header Info Panel -->
<div class="row mb-4">
<div class="col-lg-12">
<t t-call="website_sale_aplicoop.order_header">
<t
t-set="header_class"
t-value="'eskaera-order-header'"
/>
</t>
<div class="eskaera-order-header">
<div class="order-info-grid">
<div class="info-item">
<span
t-att-class="'info-label'"
>Consumer Groups</span>
<span class="info-value"><t
t-esc="', '.join(group_order.group_ids.mapped('name'))"
/></span>
</div>
<t t-if="group_order.cutoff_day">
<div class="info-item">
<span
t-att-class="'info-label'"
>Cutoff Day</span>
<span class="info-value"><t
t-esc="day_names[int(group_order.cutoff_day) % 7]"
/> (<t
t-esc="group_order.cutoff_date.strftime('%d/%m/%Y')"
/>)</span>
</div>
</t>
<t t-if="group_order.pickup_day"> <t t-if="group_order.pickup_day">
<div class="info-item"> <div class="info-item">
<span <span
@ -516,38 +470,21 @@
<!-- Search and Filter Bar (Full Width, Above Products/Cart) --> <!-- Search and Filter Bar (Full Width, Above Products/Cart) -->
<div class="mb-3" id="realtimeSearch-filters"> <div class="mb-3" id="realtimeSearch-filters">
<div class="row g-2"> <div class="row g-2">
<div class="col-md-7"> <div class="col-md-7">
<!-- CRITICAL: This input is NOT inside a form to prevent Odoo from transforming it --> <!-- CRITICAL: This input is NOT inside a form to prevent Odoo from transforming it -->
<!-- It must remain a pure HTML input element for realtime_search.js to detect value changes --> <!-- It must remain a pure HTML input element for realtime_search.js to detect value changes -->
<input <input type="text" id="realtime-search-input" class="form-control realtime-search-box search-input-styled" placeholder="Search products..." autocomplete="off" />
type="text" </div>
id="realtime-search-input" <div class="col-md-5">
class="form-control realtime-search-box search-input-styled" <select name="category" id="realtime-category-select" class="form-select">
placeholder="Search products..." <option value="">Browse Product Categories</option>
autocomplete="off" <!-- Macro para renderizar categorías recursivamente -->
/> <t t-call="website_sale_aplicoop.category_hierarchy_options">
</div> <t t-set="categories" t-value="category_hierarchy" />
<div class="col-md-5"> <t t-set="depth" t-value="0" />
<select </t>
name="category" </select>
id="realtime-category-select" </div>
class="form-select"
>
<option
value=""
>Browse Product Categories</option>
<!-- Macro para renderizar categorías recursivamente -->
<t
t-call="website_sale_aplicoop.category_hierarchy_options"
>
<t
t-set="categories"
t-value="category_hierarchy"
/>
<t t-set="depth" t-value="0" />
</t>
</select>
</div>
</div> </div>
<t t-if="available_tags"> <t t-if="available_tags">
<div class="row mt-3"> <div class="row mt-3">
@ -606,11 +543,8 @@
<div class="row g-2"> <div class="row g-2">
<!-- Products Column --> <!-- Products Column -->
<div class="col-lg-9"> <div class="col-lg-9">
<!-- Editable area: Above search/filter --> <!-- Editable area: Above search/filter -->
<div <div class="oe_structure oe_empty" data-name="Before Products Filter" />
class="oe_structure oe_empty"
data-name="Before Products Filter"
/>
<t t-if="products"> <t t-if="products">
<div class="products-grid"> <div class="products-grid">
@ -826,15 +760,11 @@
</t> </t>
</div> </div>
</t> </t>
<t t-else=""> <t t-else="">
<div <div class="alert alert-warning" role="status" aria-live="polite">
class="alert alert-warning" <p>No products available in this order.</p>
role="status" </div>
aria-live="polite" </t>
>
<p>No products available in this order.</p>
</div>
</t>
<!-- Editable area: Below products list --> <!-- Editable area: Below products list -->
<div <div
class="oe_structure oe_empty mt-4" class="oe_structure oe_empty mt-4"
@ -851,26 +781,11 @@
<div <div
class="card-header d-flex justify-content-between align-items-center gap-1" class="card-header d-flex justify-content-between align-items-center gap-1"
> >
<h6 <h6 class="mb-0 cart-title-sm" id="cart-title">My Cart</h6>
class="mb-0 cart-title-sm" <div class="btn-group cart-btn-group gap-0" role="group">
id="cart-title" <button type="button" class="btn btn-primary cart-btn-compact" id="save-cart-btn" t-attf-data-order-id="{{ group_order.id }}" data-bs-title="Save Cart" data-bs-toggle="tooltip">
>My Cart</h6> <i class="fa fa-save cart-icon-size" />
<div </button>
class="btn-group cart-btn-group gap-0"
role="group"
>
<button
type="button"
class="btn btn-primary cart-btn-compact"
id="save-cart-btn"
t-attf-data-order-id="{{ group_order.id }}"
data-bs-title="Save Cart"
data-bs-toggle="tooltip"
>
<i
class="fa fa-save cart-icon-size"
/>
</button>
<button <button
type="button" type="button"
class="btn btn-info cart-btn-compact" class="btn btn-info cart-btn-compact"
@ -897,63 +812,31 @@
</a> </a>
</div> </div>
</div> </div>
<div <div class="card-body cart-body-lg" id="cart-items-container" t-attf-data-order-id="{{ group_order.id }}" aria-labelledby="cart-title" aria-live="polite" aria-relevant="additions removals">
class="card-body cart-body-lg" <p class="text-muted">This order's cart is empty</p>
id="cart-items-container" </div>
t-attf-data-order-id="{{ group_order.id }}" <div class="card-footer bg-white text-center">
aria-labelledby="cart-title" <a t-attf-href="/eskaera/{{ group_order.id }}/checkout" class="btn btn-success checkout-btn-lg" data-bs-title="Proceed to Checkout" data-bs-toggle="tooltip">
aria-live="polite" Proceed to Checkout
aria-relevant="additions removals" </a>
> </div>
<p class="text-muted">
This order's cart is empty
</p>
</div>
<div class="card-footer bg-white text-center">
<a
t-attf-href="/eskaera/{{ group_order.id }}/checkout"
class="btn btn-success checkout-btn-lg"
data-bs-title="Proceed to Checkout"
data-bs-toggle="tooltip"
>
Proceed to Checkout
</a>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- Scripts (in dependency order) --> <!-- Scripts (in dependency order) -->
<!-- Load i18n_manager first - fetches translations from server --> <!-- Load i18n_manager first - fetches translations from server -->
<script <script type="text/javascript" src="/website_sale_aplicoop/static/src/js/i18n_manager.js" />
type="text/javascript" <!-- Keep legacy helpers for backwards compatibility -->
src="/website_sale_aplicoop/static/src/js/i18n_manager.js" <script type="text/javascript" src="/website_sale_aplicoop/static/src/js/i18n_helpers.js" />
/> <!-- Main shop functionality (depends on i18nManager) -->
<!-- Keep legacy helpers for backwards compatibility --> <script type="text/javascript" src="/website_sale_aplicoop/static/src/js/website_sale.js" />
<script <!-- UI enhancements -->
type="text/javascript" <script type="text/javascript" src="/website_sale_aplicoop/static/src/js/checkout_labels.js" />
src="/website_sale_aplicoop/static/src/js/i18n_helpers.js" <script type="text/javascript" src="/website_sale_aplicoop/static/src/js/home_delivery.js" />
/> <script type="text/javascript" src="/website_sale_aplicoop/static/src/js/realtime_search.js" />
<!-- Main shop functionality (depends on i18nManager) -->
<script
type="text/javascript"
src="/website_sale_aplicoop/static/src/js/website_sale.js"
/>
<!-- UI enhancements -->
<script
type="text/javascript"
src="/website_sale_aplicoop/static/src/js/checkout_labels.js"
/>
<script
type="text/javascript"
src="/website_sale_aplicoop/static/src/js/home_delivery.js"
/>
<script
type="text/javascript"
src="/website_sale_aplicoop/static/src/js/realtime_search.js"
/>
<!-- Initialize tooltips using native title attribute --> <!-- Initialize tooltips using native title attribute -->
<script type="text/javascript"> <script type="text/javascript">
@ -993,77 +876,51 @@
</t> </t>
</template> </template>
<!-- Sub-template: Checkout Order Summary Table with Translations --> <!-- Sub-template: Checkout Order Summary Table with Translations -->
<template id="eskaera_checkout_summary" name="Checkout Order Summary"> <template id="eskaera_checkout_summary" name="Checkout Order Summary">
<div class="checkout-summary-container"> <div class="checkout-summary-container">
<table <table class="table table-hover checkout-summary-table" id="checkout-summary-table">
class="table table-hover checkout-summary-table" <thead class="table-dark">
id="checkout-summary-table" <tr>
> <th class="col-name">Product</th>
<thead class="table-dark"> <th class="col-qty text-center">Quantity</th>
<tr> <th class="col-price text-right">Price</th>
<th class="col-name">Product</th> <th class="col-subtotal text-right">Subtotal</th>
<th class="col-qty text-center">Quantity</th> </tr>
<th class="col-price text-right">Price</th> </thead>
<th class="col-subtotal text-right">Subtotal</th> <tbody id="checkout-summary-tbody">
</tr> <tr id="checkout-empty-row" class="empty-message">
</thead> <td colspan="4" class="text-center text-muted py-4">
<tbody id="checkout-summary-tbody"> <i class="fa fa-inbox fa-2x mb-2" />
<tr id="checkout-empty-row" class="empty-message"> <p>This order's cart is empty</p>
<td colspan="4" class="text-center text-muted py-4"> </td>
<i class="fa fa-inbox fa-2x mb-2" /> </tr>
<p>This order's cart is empty</p> </tbody>
</td> </table>
</tr> <div class="checkout-total-section">
</tbody> <div class="total-row">
</table> <span class="total-label">Total</span>:
<div class="checkout-total-section"> <span class="total-amount" id="checkout-total-amount">0.00</span>
<div class="total-row"> <span class="currency"></span>
<span class="total-label">Total</span>: </div>
<span </div>
class="total-amount" </div>
id="checkout-total-amount" </template>
>0.00</span>
<span class="currency"></span>
</div>
</div>
</div>
</template>
<!-- Template: Group Order Checkout (Eskaera) --> <!-- Template: Group Order Checkout (Eskaera) -->
<template id="eskaera_checkout" name="Eskaera Checkout"> <template id="eskaera_checkout" name="Eskaera Checkout">
<t t-call="website.layout"> <t t-call="website.layout">
<div <div id="wrap" class="eskaera-checkout-page oe_structure oe_empty" data-name="Eskaera Checkout" t-attf-data-delivery-product-id="{{ delivery_product_id }}" t-attf-data-delivery-product-name="{{ delivery_product_name }}" t-attf-data-delivery-product-price="{{ delivery_product_price }}" t-attf-data-home-delivery-enabled="{{ 'true' if group_order.home_delivery else 'false' }}" t-attf-data-pickup-day="{{ group_order.pickup_day }}" t-attf-data-pickup-date="{{ group_order.pickup_date.strftime('%d/%m/%Y') if group_order.pickup_date else '' }}" t-attf-data-delivery-notice="{{ (group_order.delivery_notice or '').replace(chr(10), ' ').replace(chr(13), ' ') }}">
id="wrap" <div class="container mt-5">
class="eskaera-checkout-page oe_structure oe_empty" <div class="row">
data-name="Eskaera Checkout" <div class="col-lg-10 offset-lg-1">
t-attf-data-delivery-product-id="{{ delivery_product_id }}" <!-- Header Section -->
t-attf-data-delivery-product-name="{{ delivery_product_name }}" <div class="mb-4">
t-attf-data-delivery-product-price="{{ delivery_product_price }}" <t t-call="website_sale_aplicoop.order_header">
t-attf-data-home-delivery-enabled="{{ 'true' if group_order.home_delivery else 'false' }}" <t t-set="header_class" t-value="'checkout-header'" />
t-attf-data-pickup-day="{{ group_order.pickup_day }}" <t t-set="header_title">Confirm Order: <t t-esc="group_order.name" /></t>
t-attf-data-pickup-date="{{ group_order.pickup_date.strftime('%d/%m/%Y') if group_order.pickup_date else '' }}" </t>
t-attf-data-delivery-notice="{{ (group_order.delivery_notice or '').replace(chr(10), ' ').replace(chr(13), ' ') }}" </div>
>
<div class="container mt-5">
<div class="row">
<div class="col-lg-10 offset-lg-1">
<!-- Header Section -->
<div class="mb-4">
<t
t-call="website_sale_aplicoop.order_header"
>
<t
t-set="header_class"
t-value="'checkout-header'"
/>
<t
t-set="header_title"
>Confirm Order: <t
t-esc="group_order.name"
/></t>
</t>
</div>
<!-- Order Info Card --> <!-- Order Info Card -->
<div <div
@ -1204,21 +1061,13 @@
data-name="After Summary" data-name="After Summary"
/> />
<!-- Home Delivery Checkbox --> <!-- Home Delivery Checkbox -->
<div class="card border-0 shadow-sm mb-4"> <div class="card border-0 shadow-sm mb-4">
<div class="card-body"> <div class="card-body">
<div class="form-check"> <div class="form-check">
<input <input type="checkbox" class="form-check-input" id="home-delivery-checkbox" name="home_delivery" />
type="checkbox" <label class="form-check-label fw-bold" for="home-delivery-checkbox">Home Delivery</label>
class="form-check-input" </div>
id="home-delivery-checkbox"
name="home_delivery"
/>
<label
class="form-check-label fw-bold"
for="home-delivery-checkbox"
>Home Delivery</label>
</div>
<div <div
id="delivery-info-alert" id="delivery-info-alert"
class="alert alert-info mt-3 d-none" class="alert alert-info mt-3 d-none"
@ -1294,43 +1143,17 @@
/> />
</div> </div>
<!-- Action Buttons --> <!-- Action Buttons -->
<div <div class="checkout-actions d-grid gap-3" id="checkout-form-labels">
class="checkout-actions d-grid gap-3" <button class="btn btn-success btn-lg" id="confirm-order-btn" t-attf-data-order-id="{{ group_order.id }}" data-confirmed-label="Order confirmed" data-pickup-label="Pickup Day" aria-label="Confirm and send order" data-bs-title="Confirm Order" data-bs-toggle="tooltip">
id="checkout-form-labels" <i class="fa fa-check-circle" aria-hidden="true" t-translation="off" />
> <span>Confirm Order</span>
<button </button>
class="btn btn-success btn-lg" <a t-attf-href="/eskaera/{{ group_order.id }}" class="btn btn-outline-secondary btn-lg" aria-label="Back to cart page" data-bs-title="Back to Cart" data-bs-toggle="tooltip">
id="confirm-order-btn" <i class="fa fa-arrow-left" aria-hidden="true" t-translation="off" />
t-attf-data-order-id="{{ group_order.id }}" <span>Back to Cart</span>
data-confirmed-label="Order confirmed" </a>
data-pickup-label="Pickup Day" </div>
aria-label="Confirm and send order"
data-bs-title="Confirm Order"
data-bs-toggle="tooltip"
>
<i
class="fa fa-check-circle"
aria-hidden="true"
t-translation="off"
/>
<span>Confirm Order</span>
</button>
<a
t-attf-href="/eskaera/{{ group_order.id }}"
class="btn btn-outline-secondary btn-lg"
aria-label="Back to cart page"
data-bs-title="Back to Cart"
data-bs-toggle="tooltip"
>
<i
class="fa fa-arrow-left"
aria-hidden="true"
t-translation="off"
/>
<span>Back to Cart</span>
</a>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -1348,35 +1171,17 @@
console.log('[LABELS] Initialized from server:', window.groupOrderShop.labels); console.log('[LABELS] Initialized from server:', window.groupOrderShop.labels);
})(); })();
</script> </script>
<!-- Scripts (in dependency order) --> <!-- Scripts (in dependency order) -->
<!-- Load i18n_manager first - fetches translations from server --> <!-- Load i18n_manager first - fetches translations from server -->
<script <script type="text/javascript" src="/website_sale_aplicoop/static/src/js/i18n_manager.js" />
type="text/javascript" <!-- Keep legacy helpers for backwards compatibility -->
src="/website_sale_aplicoop/static/src/js/i18n_manager.js" <script type="text/javascript" src="/website_sale_aplicoop/static/src/js/i18n_helpers.js" />
/> <!-- Main shop functionality (depends on i18nManager) -->
<!-- Keep legacy helpers for backwards compatibility --> <script type="text/javascript" src="/website_sale_aplicoop/static/src/js/website_sale.js" />
<script <!-- UI enhancements -->
type="text/javascript" <script type="text/javascript" src="/website_sale_aplicoop/static/src/js/checkout_labels.js" />
src="/website_sale_aplicoop/static/src/js/i18n_helpers.js" <script type="text/javascript" src="/website_sale_aplicoop/static/src/js/home_delivery.js" />
/> <script type="text/javascript" src="/website_sale_aplicoop/static/src/js/checkout_summary.js" />
<!-- Main shop functionality (depends on i18nManager) -->
<script
type="text/javascript"
src="/website_sale_aplicoop/static/src/js/website_sale.js"
/>
<!-- UI enhancements -->
<script
type="text/javascript"
src="/website_sale_aplicoop/static/src/js/checkout_labels.js"
/>
<script
type="text/javascript"
src="/website_sale_aplicoop/static/src/js/home_delivery.js"
/>
<script
type="text/javascript"
src="/website_sale_aplicoop/static/src/js/checkout_summary.js"
/>
<script type="text/javascript"> <script type="text/javascript">
// Auto-load cart from localStorage when accessing checkout directly // Auto-load cart from localStorage when accessing checkout directly
(function() { (function() {
@ -1412,46 +1217,38 @@
</t> </t>
</template> </template>
<!-- Recursive macro to render category hierarchy for select dropdown --> <!-- Recursive macro to render category hierarchy for select dropdown -->
<template <template id="category_hierarchy_options" name="Category Hierarchy Options">
id="category_hierarchy_options" <!--
name="Category Hierarchy Options" Macro para renderizar recursivamente la jerarquía de categorías.
> Todas las categorías son seleccionables, indentadas por profundidad.
<!--
Macro para renderizar recursivamente la jerarquía de categorías.
Todas las categorías son seleccionables, indentadas por profundidad.
Parámetros: Parámetros:
- categories: lista de categorías a renderizar - categories: lista de categorías a renderizar
- depth: nivel de profundidad actual (para padding/indentación) - depth: nivel de profundidad actual (para padding/indentación)
--> -->
<t t-foreach="categories" t-as="cat"> <t t-foreach="categories" t-as="cat">
<!-- Calcular padding basado en profundidad: 20px por nivel --> <!-- Calcular padding basado en profundidad: 20px por nivel -->
<t t-set="padding_px" t-value="depth * 20" /> <t t-set="padding_px" t-value="depth * 20" />
<!-- Crear prefijo visual con flechas según profundidad --> <!-- Crear prefijo visual con flechas según profundidad -->
<t t-set="prefix"> <t t-set="prefix">
<t t-foreach="range(depth)" t-as="i"></t> <t t-foreach="range(depth)" t-as="i"></t>
</t> </t>
<!-- Renderizar como opción indentada y seleccionable --> <!-- Renderizar como opción indentada y seleccionable -->
<option <option t-att-value="str(cat['id'])" t-attf-style="padding-left: {{ padding_px }}px;">
t-att-value="str(cat['id'])" <t t-esc="prefix" /><t t-esc="cat['name']" />
t-attf-style="padding-left: {{ padding_px }}px;" </option>
>
<t t-esc="prefix" /><t t-esc="cat['name']" />
</option>
<!-- Renderizar hijos recursivamente si existen --> <!-- Renderizar hijos recursivamente si existen -->
<t t-if="cat['children']"> <t t-if="cat['children']">
<t <t t-call="website_sale_aplicoop.category_hierarchy_options">
t-call="website_sale_aplicoop.category_hierarchy_options" <t t-set="categories" t-value="cat['children']" />
> <t t-set="depth" t-value="depth + 1" />
<t t-set="categories" t-value="cat['children']" /> </t>
<t t-set="depth" t-value="depth + 1" /> </t>
</t> </t>
</t> </template>
</t>
</template>
</data> </data>
</odoo> </odoo>