Initial commit: Sale packages

This commit is contained in:
Ernad Husremovic 2025-08-29 15:20:49 +02:00
commit 14e3d26998
6469 changed files with 2479670 additions and 0 deletions

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="snippet_options" inherit_id="website.snippet_options" name="Comparison Snippet Options">
<xpath expr="//div[@data-js='WebsiteSaleProductPage']//we-row[@data-name='o_wsale_buy_now_opt']" position="after">
<we-select string="Specification" data-no-preview="true" data-reload="/">
<we-button data-customize-website-views="">None</we-button>
<we-button data-customize-website-views="website_sale_comparison.product_attributes_body">Bottom of Page</we-button>
</we-select>
</xpath>
<xpath expr="//we-button[hasclass('o_we_add_to_cart_btn')]" position="after">
<we-button title="Compare" class="fa fa-fw fa-exchange"
data-customize-website-views="website_sale_comparison.add_to_compare"
data-no-preview="true"
data-reload="/"/>
</xpath>
<xpath expr="//we-button[hasclass('o_we_buy_now_btn')]" position="after">
<we-button title="Compare" class="fa fa-fw fa-exchange"
data-customize-website-views="website_sale_comparison.product_add_to_compare"
data-no-preview="true"
data-reload="/"/>
</xpath>
</template>
</odoo>

View file

@ -0,0 +1,187 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="add_to_compare" inherit_id="website_sale.products_item" name="Comparison List" priority="22">
<xpath expr="//div[hasclass('o_wsale_product_btn')]" position="inside">
<t t-set="categories" t-value="product.valid_product_template_attribute_line_ids._prepare_categories_for_display()"/>
<t t-set="product_variant_id" t-value="product._get_first_possible_variant_id()"/>
<button t-if="product_variant_id and categories" type="button" role="button" class="d-none d-md-inline-block btn btn-outline-primary bg-white o_add_compare" title="Compare" aria-label="Compare" t-att-data-product-product-id="product_variant_id" data-action="o_comparelist"><span class="fa fa-exchange"></span></button>
</xpath>
</template>
<template id="product_add_to_compare" name='Add to comparison in product page' inherit_id="website_sale.product" priority="8">
<xpath expr="//div[@id='o_wsale_cta_wrapper']" position="after">
<t t-set="categories" t-value="product.valid_product_template_attribute_line_ids._prepare_categories_for_display()"/>
<t t-set="product_variant_id" t-value="product._get_first_possible_variant_id()"/>
<button t-if="product_variant_id and categories"
type="button"
role="button"
class="d-none d-md-block btn btn-link px-0 o_add_compare_dyn"
aria-label="Compare"
t-att-data-product-product-id="product_variant_id"
data-action="o_comparelist">
<span class="fa fa-exchange me-2"/>Compare
</button>
</xpath>
</template>
<template id="product_attributes_body" inherit_id="website_sale.product" name="Product attributes table">
<xpath expr="//div[@id='product_attributes_simple']" position="replace"/>
<xpath expr="//div[@id='product_full_description']" position="after">
<t t-set="categories" t-value="product.valid_product_template_attribute_line_ids._prepare_categories_for_display()"/>
<t t-if="categories">
<section class="pt32 pb32" id="product_full_spec">
<div class="container">
<div class="d-flex justify-content-between align-items-center mb-4">
<h3 class="m-0">Specifications</h3>
</div>
<div id="product_specifications">
<div class="row">
<t t-foreach="categories" t-as="category">
<div class="col-lg-6">
<table class="table">
<t t-if="len(categories) > 1">
<tr>
<th class="text-start" t-att-colspan="2">
<span t-if="category" t-field="category.name"/>
<span t-else="">Uncategorized</span>
</th>
</tr>
</t>
<tr t-foreach="categories[category].filtered(lambda l: len(l.value_ids) > 1)" t-as="ptal">
<td class="w-25"><span t-field="ptal.attribute_id.name"/></td>
<td class="w-75 text-muted">
<t t-foreach="ptal.value_ids" t-as="pav">
<span t-field="pav.name"/><t t-if="not pav_last"> or</t>
</t>
</td>
</tr>
<t t-set="single_value_attributes" t-value="categories[category]._prepare_single_value_for_display()"/>
<tr t-foreach="single_value_attributes" t-as="attribute">
<td class="w-25"><span t-field="attribute.name"/></td>
<td class="w-75 text-muted">
<t t-foreach="single_value_attributes[attribute]" t-as="ptal">
<span t-field="ptal.product_template_value_ids._only_active().name"/><t t-if="not ptal_last">, </t>
</t>
</td>
</tr>
</table>
</div>
</t>
</div>
</div>
</div>
</section>
</t>
</xpath>
</template>
<template id="product_compare" name="Comparator Page">
<t t-call="website.layout">
<t t-set="additional_title">Shop Comparator</t>
<div id="wrap" class="js_sale">
<div class="oe_structure oe_empty" id="oe_structure_website_sale_comparison_product_compare_1"/>
<div class="container oe_website_sale pt-3">
<section class="container">
<h3>Compare Products</h3>
<table class="table table-bordered table-hover text-center mt16 table-comparator" id="o_comparelist_table">
<t t-set="categories" t-value="products._prepare_categories_for_display()"/>
<thead>
<tr>
<td t-if="len(categories)" class='o_ws_compare_image td-top-left border-bottom-0'/>
<td t-foreach="products" t-as="product" class="o_ws_compare_image position-relative border-bottom-0">
<a href="#" t-att-data-product_product_id="product.id" class="o_comparelist_remove" t-if="len(products) &gt; 2">
<strong>x</strong>
</a>
<a t-att-href="product.website_url">
<img t-attf-src="/web/image/product.product/#{product.id}/image_256" class="img img-fluid" style="margin:auto;" alt="Product image"/>
</a>
</td>
</tr>
<tr>
<td t-if="len(categories)" class='td-top-left border-top-0'/>
<td t-foreach="products" t-as="product" class="border-top-0">
<t t-set="combination_info" t-value="product._get_combination_info_variant()"/>
<div class='product_summary'>
<a class="o_product_comparison_table" t-att-href="product.website_url">
<span t-esc="combination_info['display_name']"></span><br/>
</a>
<span class="o_comparison_price" t-if="combination_info['prevent_zero_price_sale']">
<strong t-field="website.prevent_zero_price_sale_text"/>
</span>
<span class="o_comparison_price" t-else="">
<strong>Price:</strong>
<del t-attf-class="text-danger mr8 {{'' if combination_info['has_discounted_price'] else 'd-none'}}"
style="white-space: nowrap;" t-esc="combination_info['list_price']"
t-options="{'widget': 'monetary', 'display_currency': website.currency_id}"/>
<span t-esc="combination_info['price']"
t-options="{'widget': 'monetary', 'display_currency': website.currency_id}"/>
<small class="d-block text-muted" groups="website_sale.group_show_uom_price" t-if="combination_info['base_unit_price']">
<t t-call='website_sale.base_unit_price'/>
</small>
</span>
<form action="/shop/cart/update" method="post" class="text-center o_add_cart_form_compare">
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
<input name="product_id" t-att-value="product.id" type="hidden"
t-att-data-product-tracking-info="json.dumps(request.env['product.template'].get_google_analytics_data(combination_info))"/>
<a t-if="combination_info['prevent_zero_price_sale']" t-att-href="website.contact_us_button_url" class="btn btn-primary btn_cta">Contact Us</a>
<a t-else="" role="button" class="btn btn-primary a-submit" href="#">
<i class="fa fa-shopping-cart me-2"/>Add to Cart
</a>
</form>
</div>
</td>
</tr>
</thead>
<tbody>
<t t-foreach="categories" t-as="category">
<t t-if="len(categories) &gt; 1">
<tr class="clickable" data-bs-toggle="collapse" t-att-data-bs-target="'.o_ws_category_%d' % category.id">
<th class="text-start" t-att-colspan="len(products) + 1"><i class="fa fa-chevron-circle-down o_product_comparison_collpase" role="img" aria-label="Collapse" title="Collapse"></i><span t-if="category" t-field="category.name"/><span t-else="">Uncategorized</span></th>
</tr>
</t>
<tr t-foreach="categories[category]" t-as="attribute" t-att-class="'collapse show o_ws_category_%d' % category.id">
<td><span t-field="attribute.name"/></td>
<td t-foreach="categories[category][attribute]" t-as="product">
<t t-foreach="categories[category][attribute][product]" t-as="ptav">
<span t-field="ptav.name"/><t t-if="not ptav_last">, </t>
</t>
</td>
</tr>
</t>
</tbody>
</table>
</section>
</div>
<div class="oe_structure" id="oe_structure_website_sale_comparison_product_compare_2"/>
</div>
</t>
</template>
<template id="product_product" name="Comparator - Product row in comparator popover">
<t t-set="combination_info" t-value="product._get_combination_info_variant()"/>
<div class="row g-0 align-items-center my-1 o_product_row" t-att-data-category_ids="product.public_categ_ids.ids">
<div class="col-3 text-center">
<img class="img o_image_64_max" t-att-src="website.image_url(product, 'image_128')" alt="Product image"/>
</div>
<div class="col-8 ps-2">
<h6>
<a t-att-href="product.website_url"><t t-esc="combination_info['display_name']" /></a><br/>
<div t-attf-class="{{'d-none' if combination_info['prevent_zero_price_sale'] else ''}}">
<del t-attf-class="text-danger mr8 {{'' if combination_info['has_discounted_price'] else 'd-none'}}" style="white-space: nowrap;" t-esc="combination_info['list_price']" t-options="{'widget': 'monetary', 'display_currency': website.currency_id}" />
<span t-esc="combination_info['price']" t-options="{'widget': 'monetary', 'display_currency': website.currency_id}"/>
</div>
<div t-attf-class="{{'' if combination_info['prevent_zero_price_sale'] else 'd-none'}}" t-field="website.prevent_zero_price_sale_text"/>
</h6>
</div>
<div class="col-1 text-end">
<a href='#' class="o_remove" title="Remove" t-att-data-product_product_id="product.id">
<i class="fa fa-trash" role="img" aria-label="Remove"></i>
</a>
</div>
</div>
</template>
</odoo>

View file

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="product_attribute_category_tree_view" model="ir.ui.view">
<field name="name">product.attribute.category.tree</field>
<field name="model">product.attribute.category</field>
<field name="arch" type="xml">
<tree string="Product Attribute Category" editable="bottom">
<field name="sequence" widget="handle"/>
<field name="name"/>
<field name="attribute_ids" widget="many2many_tags" options="{'no_create': True}"/>
</tree>
</field>
</record>
<record id="product_attribute_category_action" model="ir.actions.act_window">
<field name="name">Attribute Categories</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">product.attribute.category</field>
<field name="view_mode">tree</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create a new attribute category
</p><p>
Group attributes by category that will appear in the specification
part of a product page.
</p>
</field>
</record>
<menuitem action="product_attribute_category_action"
id="menu_attribute_category_action"
parent="website_sale.menu_catalog" groups="base.group_no_one" sequence="11"/>
<record id="product_attribute_tree_view_inherit" model="ir.ui.view">
<field name="name">product.attribute.tree.inherit</field>
<field name="model">product.attribute</field>
<field name="inherit_id" ref="product.attribute_tree_view"/>
<field name="arch" type="xml">
<field name="name" position="after">
<field name="category_id"/>
</field>
</field>
</record>
<record id="product_attribute_view_form" model="ir.ui.view">
<field name="name">product.attribute.form.inherit</field>
<field name="model">product.attribute</field>
<field name="inherit_id" ref="product.product_attribute_view_form"/>
<field name="priority" eval="8"/>
<field name="arch" type="xml">
<field name='name' position='after'>
<field name="category_id"/>
</field>
</field>
</record>
</odoo>