mirror of
https://github.com/bringout/oca-ocb-sale.git
synced 2026-04-27 06:32:02 +02:00
19.0 vanilla
This commit is contained in:
parent
79f83631d5
commit
73afc09215
6267 changed files with 1534193 additions and 1130106 deletions
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="account_move_view_form" model="ir.ui.view">
|
||||
<field name="name">account.move.form.inherit.website_sale</field>
|
||||
<field name="model">account.move</field>
|
||||
<field name="inherit_id" ref="account.view_move_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<group name="sale_info_group" position="inside">
|
||||
<field name="website_id"
|
||||
invisible="not website_id"
|
||||
groups="website.group_multi_website"/>
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="action_invoices_ecommerce" model="ir.actions.act_window">
|
||||
<field name="name">Invoices</field>
|
||||
<field name="res_model">account.move</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[('team_id.website_ids', '!=', False)]</field>
|
||||
<field name="view_id" ref="account.view_invoice_tree"/>
|
||||
<field name="context">{'move_type':'out_invoice'}</field>
|
||||
<field name="search_view_id" ref="account.view_account_invoice_filter"/>
|
||||
</record>
|
||||
|
||||
<record id="website_product_pricelist3" model="ir.actions.act_window">
|
||||
<field name="name">Pricelists</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">product.pricelist</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[('website_id', '!=', False)]</field>
|
||||
<field name="search_view_id" ref="product.product_pricelist_view_search" />
|
||||
<field name="context">{"default_base":'list_price'}</field>
|
||||
</record>
|
||||
|
||||
<record id="account_move_view_form" model="ir.ui.view">
|
||||
<field name="name">account.move.form.inherit.website_sale</field>
|
||||
<field name="model">account.move</field>
|
||||
<field name="inherit_id" ref="account.view_move_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//group[@name='sale_info_group']" position="inside">
|
||||
<field name="website_id" groups="website.group_multi_website" attrs="{'invisible': [('website_id', '=', False)]}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="crm_team_view_kanban_dashboard" model="ir.ui.view">
|
||||
<field name="name">crm.team.view.kanban.dashboard.inherit.website.sale</field>
|
||||
<field name="model">crm.team</field>
|
||||
<field name="inherit_id" ref="sales_team.crm_team_view_kanban_dashboard"/>
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<xpath expr="//t[@name='third_options']" position="after">
|
||||
<div class="row" t-if="record.abandoned_carts_count.raw_value">
|
||||
<div class="col-8">
|
||||
<div>
|
||||
<a name="get_abandoned_carts" type="object">
|
||||
<field name="abandoned_carts_count" class="me-1"/>
|
||||
Abandoned Carts to Recover
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4 text-end">
|
||||
<field name="abandoned_carts_amount" widget="monetary"/>
|
||||
</div>
|
||||
</div>
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="view_delivery_carrier_form_website_delivery" model="ir.ui.view">
|
||||
<field name="name">delivery.carrier.website.form</field>
|
||||
<field name="model">delivery.carrier</field>
|
||||
<field name="inherit_id" ref="delivery.view_delivery_carrier_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="company_id" position="after">
|
||||
<field
|
||||
name="website_id"
|
||||
placeholder="All websites"
|
||||
groups="website.group_multi_website"
|
||||
options="{'no_open': True, 'no_create_edit': True}"
|
||||
/>
|
||||
</field>
|
||||
<field name="carrier_description" position="before">
|
||||
<field name="website_description" placeholder="Description displayed on the eCommerce and on online quotations."/>
|
||||
</field>
|
||||
<button name="toggle_prod_environment" position="before">
|
||||
<button name="website_publish_button" type="object" class="oe_stat_button" icon="fa-globe">
|
||||
<field name="is_published" widget="website_publish_button"/>
|
||||
</button>
|
||||
</button>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_delivery_carrier_tree" model="ir.ui.view">
|
||||
<field name="name">delivery.carrier.list.inherit</field>
|
||||
<field name="model">delivery.carrier</field>
|
||||
<field name="inherit_id" ref="delivery.view_delivery_carrier_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="delivery_type" position="after">
|
||||
<field name="is_published"/>
|
||||
<field name="website_id" groups="website.group_multi_website"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_delivery_carrier_search" model="ir.ui.view">
|
||||
<field name="name">delivery.carrier.search.inherit</field>
|
||||
<field name="model">delivery.carrier</field>
|
||||
<field name="inherit_id" ref="delivery.view_delivery_carrier_search"/>
|
||||
<field name="arch" type="xml">
|
||||
<filter name="inactive" position="after">
|
||||
<filter string="Published" name="is_published" domain="[('is_published', '=', True)]"/>
|
||||
</filter>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<template id="delivery_form">
|
||||
<!-- Parameters description:
|
||||
- delivery_methods: The delivery methods to display, as a `delivery.carrier` recordset.
|
||||
- selected_dm_id: The selected delivery method id.
|
||||
-->
|
||||
<form id="o_delivery_form" class="o_delivery_form">
|
||||
<h4 class="mb-3">Delivery method</h4>
|
||||
<ul t-if="delivery_methods" id="o_delivery_methods" class="list-group">
|
||||
<t t-foreach="delivery_methods" t-as="dm">
|
||||
<li name="o_delivery_method" class="list-group-item">
|
||||
<t t-call="website_sale.delivery_method">
|
||||
<t t-set="is_selected" t-value="dm.id == selected_dm_id"/>
|
||||
</t>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
<div t-else="" class="alert alert-warning">
|
||||
<strong>No suitable delivery method could be found.</strong>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<template id="delivery_method">
|
||||
<!-- Parameters description:
|
||||
- dm: The delivery method to display, as a `delivery.carrier` recordset.
|
||||
- is_selected: Whether the radio button of the delivery method should be checked.
|
||||
-->
|
||||
<t t-set="delivery_type" t-value="dm.delivery_type + '_use_locations'"/>
|
||||
<t
|
||||
t-set="is_pickup_needed"
|
||||
t-value="delivery_type in dm._fields and dm[delivery_type]"
|
||||
/>
|
||||
<div class="d-flex justify-content-between gap-3">
|
||||
<div class="form-check flex-grow-1 cursor-pointer">
|
||||
<!-- === Radio button === -->
|
||||
<input
|
||||
t-attf-id="o_delivery_{{dm.id}}"
|
||||
name="o_delivery_radio"
|
||||
type="radio"
|
||||
t-att-checked="is_selected"
|
||||
disabled="true"
|
||||
class="form-check-input position-absolute"
|
||||
t-att-data-dm-id="dm.id"
|
||||
t-att-data-delivery-type="dm.delivery_type"
|
||||
t-att-data-is-pickup-location-required="is_pickup_needed"
|
||||
/>
|
||||
<!-- === Delivery method label === -->
|
||||
<label
|
||||
name="o_delivery_method_label"
|
||||
class="form-check-label w-100"
|
||||
t-attf-for="o_delivery_{{dm.id}}"
|
||||
>
|
||||
<span name="o_delivery_method_name" t-field="dm.name"/>
|
||||
</label>
|
||||
</div>
|
||||
<!-- === Delivery price badge === -->
|
||||
<span class="o_wsale_delivery_price_badge text-muted fw-bold text-end" name="price">
|
||||
<small class="fw-normal">Select to compute delivery rate</small>
|
||||
</span>
|
||||
</div>
|
||||
<!-- === Pick up location === -->
|
||||
<div
|
||||
t-if="is_pickup_needed"
|
||||
name="o_pickup_location"
|
||||
t-attf-class="position-relative d-flex gap-2 mt-3 mb-2 {{'' if is_selected else 'd-none'}}"
|
||||
>
|
||||
<t
|
||||
t-set="pickup_location_data"
|
||||
t-value="(is_selected and order.pickup_location_data) or {}"
|
||||
/>
|
||||
<div
|
||||
name="o_pickup_location_details"
|
||||
t-attf-class="d-flex justify-items-between align-items-center gap-3 w-100 border p-3 rounded {{'' if pickup_location_data else 'd-none'}}"
|
||||
>
|
||||
<span>
|
||||
<b name="o_pickup_location_name" t-out="pickup_location_data.get('name', '')"/>
|
||||
<br/>
|
||||
<span
|
||||
name="o_pickup_location_address"
|
||||
class="text-muted"
|
||||
t-out="(pickup_location_data.get('street', ) or '')
|
||||
+ ' '
|
||||
+ (pickup_location_data.get('zip_code') or '')
|
||||
+ ' '
|
||||
+ (pickup_location_data.get('city') or '')"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
name="o_pickup_location_selector"
|
||||
class="btn btn-light fa fa-pencil ms-auto p-3"
|
||||
title="Change location"
|
||||
aria-label="Change location"
|
||||
t-att-data-location-id="pickup_location_data.get('id')"
|
||||
t-att-data-zip-code="pickup_location_data.get('zip_code')"
|
||||
t-att-data-pickup-location-data="json.dumps(pickup_location_data)"
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
t-if="not pickup_location_data"
|
||||
name="o_pickup_location_selector"
|
||||
type="button"
|
||||
class="btn btn-primary ms-4"
|
||||
t-att-data-zip-code="order.partner_shipping_id.zip"
|
||||
>
|
||||
Select a location
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
t-if="dm.website_description"
|
||||
t-field="dm.website_description"
|
||||
class="text-muted mt-1"
|
||||
/>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -1,18 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="digest_digest_view_form" model="ir.ui.view">
|
||||
<field name="name">digest.digest.view.form.inherit.website.sale.order</field>
|
||||
<field name="name">digest.digest.view.form.inherit.website_sale</field>
|
||||
<field name="model">digest.digest</field>
|
||||
<field name="priority">10</field>
|
||||
<field name="inherit_id" ref="digest.digest_digest_view_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//group[@name='kpi_sales']" position="attributes">
|
||||
<group name="kpi_sales" position="attributes">
|
||||
<attribute name="string">Sales</attribute>
|
||||
<attribute name="groups">sales_team.group_sale_salesman_all_leads</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//group[@name='kpi_sales']" position="inside">
|
||||
</group>
|
||||
<group name="kpi_sales" position="inside">
|
||||
<field name="kpi_website_sale_total"/>
|
||||
</xpath>
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<!--
|
||||
Non-website snippets need to be generated in the same way as other snippets, following the format
|
||||
module_name.configurator_{snippet_name} or module_name.configurator_{page}_{snippet_name}.
|
||||
Since these snippets are module-specific (e.g. website_sale) and do not exist in the website module
|
||||
itself, their parent_id cannot be resolved during generation until the respective module
|
||||
is installed.
|
||||
|
||||
To handle this, configurator snippet addons are declared inside their own module manifest.
|
||||
This makes the generation process independent, generic, and consistent with how themes also declare
|
||||
their configurator snippets. As a result, snippet templates are only generated when the
|
||||
corresponding module is installed, ensuring that dynamic snippets are correctly created and linked
|
||||
at the right time.
|
||||
-->
|
||||
<function model="ir.module.module" name="_generate_primary_snippet_templates">
|
||||
<value eval="[ref('base.module_website_sale')]"/>
|
||||
</function>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="gmc_xml"><t t-translation="off"><?xml version="1.0" encoding="UTF-8"?></t>
|
||||
<rss xmlns:g="http://base.google.com/ns/1.0" version="2.0">
|
||||
<channel>
|
||||
<title t-out="title"/>
|
||||
<t t-translation="off"><link><t t-out="link"/></link></t>
|
||||
<description t-out="description"/>
|
||||
<t t-foreach="items.values()" t-as="item">
|
||||
<item>
|
||||
<!-- Required -->
|
||||
<g:id t-out="item['id']"/>
|
||||
<g:title t-out="item['title']"/>
|
||||
<g:description t-out="item['description']"/>
|
||||
<g:link t-out="item['link']"/>
|
||||
<g:image_link t-out="item['image_link']"/>
|
||||
<g:availability t-out="item['availability']"/>
|
||||
<g:price t-out="item['price']"/>
|
||||
<g:identifier_exists t-out="item['identifier_exists']"/>
|
||||
<g:gtin t-if="'gtin' in item" t-out="item['gtin']"/>
|
||||
|
||||
<!-- Optional -->
|
||||
<g:sale_price t-if="'sale_price' in item" t-out="item['sale_price']"/>
|
||||
<g:sale_price_effective_date
|
||||
t-if="'sale_price_effective_date' in item"
|
||||
t-out="item['sale_price_effective_date']"
|
||||
/>
|
||||
<g:unit_pricing_measure
|
||||
t-if="'unit_pricing_measure' in item"
|
||||
t-out="item['unit_pricing_measure']"
|
||||
/>
|
||||
<g:unit_pricing_base_measure
|
||||
t-if="'unit_pricing_base_measure' in item"
|
||||
t-out="item['unit_pricing_base_measure']"
|
||||
/>
|
||||
<t t-foreach="item['custom_label']" t-as="tag_label">
|
||||
<t t-translation="off">
|
||||
<g:<t t-out="tag_label[0]"/>>
|
||||
<t t-out="tag_label[1]"/>
|
||||
</g:<t t-out="tag_label[0]"/>>
|
||||
</t>
|
||||
</t>
|
||||
<t t-foreach="item['additional_image_link']" t-as="link">
|
||||
<g:additional_image_link t-out="link"/>
|
||||
</t>
|
||||
<t t-foreach="item['product_type']" t-as="type">
|
||||
<g:product_type t-out="type"/>
|
||||
</t>
|
||||
<g:item_group_id
|
||||
t-if="'item_group_id' in item"
|
||||
t-out="item['item_group_id']"
|
||||
/>
|
||||
<g:is_bundle t-out="item['is_bundle']"/>
|
||||
<t t-foreach="item['product_detail']" t-as="name_value">
|
||||
<g:product_detail>
|
||||
<g:attribute_name t-out="name_value[0]"/>
|
||||
<g:attribute_value t-out="name_value[1]"/>
|
||||
</g:product_detail>
|
||||
</t>
|
||||
</item>
|
||||
</t>
|
||||
</channel>
|
||||
</rss>
|
||||
</template>
|
||||
</odoo>
|
||||
|
|
@ -1,17 +1,40 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="product_attribute_view_form" model="ir.ui.view">
|
||||
<field name="name">product.attribute.view.form</field>
|
||||
<field name="model">product.attribute</field>
|
||||
<field name="inherit_id" ref="product.product_attribute_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="create_variant" position="after">
|
||||
<field name="visibility" string="eCommerce Filter Visibility" widget="radio"/>
|
||||
</field>
|
||||
<group name="main_fields" position="inside">
|
||||
<group name="ecommerce_main_fields">
|
||||
<field
|
||||
name="visibility"
|
||||
string="eCommerce Filter"
|
||||
widget="radio"
|
||||
options="{'horizontal': True}"
|
||||
/>
|
||||
<field
|
||||
name="preview_variants"
|
||||
widget="radio"
|
||||
options="{'horizontal': True}"
|
||||
readonly="create_variant != 'always' or display_type == 'multi'"
|
||||
force_save="1"
|
||||
/>
|
||||
<field
|
||||
name="is_thumbnail_visible"
|
||||
widget="boolean_toggle"
|
||||
readonly="create_variant != 'always' or display_type == 'multi'"
|
||||
invisible="preview_variants == 'hidden'"
|
||||
force_save="1"
|
||||
/>
|
||||
</group>
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="attribute_tree_view" model="ir.ui.view">
|
||||
<field name="name">product.attribute.tree</field>
|
||||
<field name="name">product.attribute.list</field>
|
||||
<field name="model">product.attribute</field>
|
||||
<field name="inherit_id" ref="product.attribute_tree_view"/>
|
||||
<field name="arch" type="xml">
|
||||
|
|
@ -20,4 +43,5 @@
|
|||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="product_document_form" model="ir.ui.view">
|
||||
<field name="name">product.document.form.website_sale</field>
|
||||
<field name="model">product.document</field>
|
||||
<field name="inherit_id" ref="sale.product_document_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<sheet position="inside">
|
||||
<group name="website_sale" string="E-commerce" invisible="res_model == 'product.product'">
|
||||
<field name="shown_on_product_page"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="product_document_kanban" model="ir.ui.view">
|
||||
<field name="name">product.document.kanban.website_sale</field>
|
||||
<field name="model">product.document</field>
|
||||
<field name="inherit_id" ref="sale.product_document_kanban"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//main/div" position="inside">
|
||||
<div class="d-flex mt-2" invisible="res_model == 'product.product'">
|
||||
<span>Publish on website</span>
|
||||
<field name="shown_on_product_page" class="ms-2" widget="boolean_toggle"/>
|
||||
</div>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="product_document_list" model="ir.ui.view">
|
||||
<field name="name">product.document.list.website_sale</field>
|
||||
<field name="model">product.document</field>
|
||||
<field name="inherit_id" ref="sale.product_document_list"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="attached_on_sale" position="after">
|
||||
<field name="shown_on_product_page" invisible="res_model == 'product.product'"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="product_document_search" model="ir.ui.view">
|
||||
<field name="name">product.document.search.sale</field>
|
||||
<field name="model">product.document</field>
|
||||
<field name="inherit_id" ref="sale.product_document_search"/>
|
||||
<field name="arch" type="xml">
|
||||
<search position="inside">
|
||||
<separator/>
|
||||
<filter name="e_commerce" string="Show on Ecommerce" domain="[('shown_on_product_page', '=', True)]"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="product_feed_search" model="ir.ui.view">
|
||||
<field name="name">product.feed.view.search</field>
|
||||
<field name="model">product.feed</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="website_id" groups="website.group_multi_website"/>
|
||||
<field name="pricelist_id" groups="product.group_product_pricelist"/>
|
||||
<field name="lang_id"/>
|
||||
<field name="product_category_ids"/>
|
||||
<group>
|
||||
<filter
|
||||
name="groupby_website"
|
||||
string="Website"
|
||||
context="{'group_by': 'website_id'}"
|
||||
groups="website.group_multi_website"
|
||||
/>
|
||||
<filter
|
||||
name="groupby_pricelist"
|
||||
string="Pricelist"
|
||||
context="{'group_by': 'pricelist_id'}"
|
||||
groups="product.group_product_pricelist"
|
||||
/>
|
||||
<filter
|
||||
name="groupby_lang"
|
||||
string="Language"
|
||||
context="{'group_by': 'lang_id'}"
|
||||
/>
|
||||
<filter
|
||||
name="groupby_product_category"
|
||||
string="eCommerce Category"
|
||||
context="{'group_by': 'product_category_ids'}"
|
||||
/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="product_feed_list" model="ir.ui.view">
|
||||
<field name="name">product.feed.view.list</field>
|
||||
<field name="model">product.feed</field>
|
||||
<field name="arch" type="xml">
|
||||
<list string="Product Feeds" editable="top" multi_edit="True">
|
||||
<field name="name"/>
|
||||
<field
|
||||
name="website_id"
|
||||
column_invisible="context.get('hide_website_column')"
|
||||
groups="website.group_multi_website"
|
||||
options="{'no_create': True}"
|
||||
/>
|
||||
<field
|
||||
name="pricelist_id"
|
||||
placeholder="Default"
|
||||
options="{'no_create': True}"
|
||||
groups="product.group_product_pricelist"
|
||||
/>
|
||||
<field name="lang_id" options="{'no_create': True}"/>
|
||||
<field
|
||||
name="product_category_ids"
|
||||
placeholder="All Categories"
|
||||
widget="many2many_tags"
|
||||
options="{'no_create': True}"
|
||||
/>
|
||||
<!-- The `o_field_handle` class disables the o-text-overflow styling added by the
|
||||
list renderer, which, if not disabled, causes misalignment of the icon. -->
|
||||
<field
|
||||
name="url"
|
||||
string="Copy URL"
|
||||
widget="CopyClipboardButton"
|
||||
class="o_field_handle"
|
||||
width="100px"
|
||||
nolabel="1"
|
||||
options="{'btn_class': 'primary btn-sm'}"
|
||||
/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="product_feed_form" model="ir.ui.view">
|
||||
<field name="name">product.feed.view.form</field>
|
||||
<field name="model">product.feed</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Product Feed">
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<h1><field name="name"/></h1>
|
||||
</div>
|
||||
<div name="button_box">
|
||||
<field name="url" string="Copy URL" widget="CopyClipboardButton"/>
|
||||
</div>
|
||||
<group>
|
||||
<field name="website_id"/>
|
||||
<field name="pricelist_id" placeholder="Default" groups="product.group_product_pricelist"/>
|
||||
<field name="lang_id" options="{'no_create': True}"/>
|
||||
<field
|
||||
name="product_category_ids"
|
||||
placeholder="All Categories"
|
||||
widget="many2many_tags"
|
||||
/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_product_feeds" model="ir.actions.act_window">
|
||||
<field name="name">Product Feeds</field>
|
||||
<field name="res_model">product.feed</field>
|
||||
<field name="view_mode">list,form</field>
|
||||
</record>
|
||||
|
||||
<record id="action_invalidate_cache" model="ir.actions.server">
|
||||
<field name="name">Reset Cache</field>
|
||||
<field name="model_id" ref="model_product_feed"/>
|
||||
<field name="binding_model_id" ref="website_sale.model_product_feed"/>
|
||||
<field name="binding_view_types">list,form</field>
|
||||
<field name="state">code</field>
|
||||
<field name="code">action = records.action_invalidate_cache()</field>
|
||||
<field name="group_ids" eval="[Command.link(ref('base.group_no_one'))]"/>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- This view should only be used from the product o2m because the required field product_tmpl_id has to be automatically set. -->
|
||||
<record id="view_product_image_form" model="ir.ui.view">
|
||||
<field name="name">product.image.view.form</field>
|
||||
<field name="model">product.image</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Product Images">
|
||||
<field name="sequence" invisible="1"/>
|
||||
<div class="row o_website_sale_image_modal">
|
||||
<div class="col-md-6 col-xl-5">
|
||||
<label for="name" string="Image Name"/>
|
||||
<h2><field name="name" placeholder="Image Name"/></h2>
|
||||
<label for="video_url" string="Video URL"/><br/>
|
||||
<field name="video_url"/><br/>
|
||||
</div>
|
||||
<div class="col-md-6 col-xl-7 text-center o_website_sale_image_modal_container">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<field name="image_1920" widget="image"/>
|
||||
</div>
|
||||
<div class="col" invisible="video_url in ['', False]">
|
||||
<div class="o_video_container p-2">
|
||||
<span>Video Preview</span>
|
||||
<field name="embed_code" class="mt-2" widget="video_preview"/>
|
||||
<h4 class="o_invalid_warning text-muted text-center" invisible="embed_code">
|
||||
Please enter a valid Video URL.
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="product_image_view_kanban" model="ir.ui.view">
|
||||
<field name="name">product.image.view.kanban</field>
|
||||
<field name="model">product.image</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban string="Product Images" default_order="sequence">
|
||||
<field name="video_url" invisible="1"/>
|
||||
<field name="sequence" widget="handle"/>
|
||||
<templates>
|
||||
<t t-name="card" class="p-0 border-0">
|
||||
<div class="card">
|
||||
<div class="o_squared_image">
|
||||
<field class="card-img-top" name="image_1920" widget="x2_many_image"/>
|
||||
</div>
|
||||
<div class="p-2 m-0 bg-200" t-attf-title="#{record.name.value}">
|
||||
<field name="name" class="small fs-5 text-truncate d-block"/>
|
||||
</div>
|
||||
<!-- below 100 Kb: good -->
|
||||
<t t-if="record.image_1920.raw_value.length < 100*1000">
|
||||
<t t-set="size_status" t-value="'text-bg-success'"/>
|
||||
<t t-set="message">Acceptable file size</t>
|
||||
</t>
|
||||
<!-- below 1000 Kb: decent -->
|
||||
<t t-elif="record.image_1920.raw_value.length < 1000*1000">
|
||||
<t t-set="size_status" t-value="'text-bg-warning'" />
|
||||
<t t-set="message">Huge file size. The image should be optimized/reduced.</t>
|
||||
</t>
|
||||
<!-- above 1000 Kb: bad -->
|
||||
<t t-else="1">
|
||||
<t t-set="size_status" t-value="'text-bg-danger'"/>
|
||||
<t t-set="message">Optimization required! Reduce the image size or increase your compression settings.</t>
|
||||
</t>
|
||||
<span t-attf-class="badge #{size_status} o_product_image_size" t-att-title="message"></span>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="product_pricelist_item_form" model="ir.ui.view">
|
||||
<field name="name">product.pricelist.item.view.form.inherit</field>
|
||||
<field name="model">product.pricelist.item</field>
|
||||
<field name="inherit_id" ref="sale.product_pricelist_item_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<div id="discount_price_warning" position="after">
|
||||
<div>On the website original price is crossed out.</div>
|
||||
</div>
|
||||
<div id="formula_fixed_price_warning" position="replace">
|
||||
<div>
|
||||
For formula or fixed pricing, the original price isn’t shown in
|
||||
sale orders or checkout.
|
||||
</div>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="website_sale_pricelist_form_view" model="ir.ui.view">
|
||||
<field name="name">website_sale.pricelist.form</field>
|
||||
<field name="inherit_id" ref="product.product_pricelist_view"/>
|
||||
<field name="model">product.pricelist</field>
|
||||
<field name="arch" type="xml">
|
||||
<notebook position="inside">
|
||||
<page name="pricelist_config" string="Ecommerce">
|
||||
<group name="pricelist_website">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="website_id"
|
||||
options="{'no_create': True}"
|
||||
placeholder="Select a website"/>
|
||||
<field name="selectable"/>
|
||||
<field name="code"/>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="website_sale_pricelist_tree_view" model="ir.ui.view">
|
||||
<field name="name">product.pricelist.list.inherit.product</field>
|
||||
<field name="model">product.pricelist</field>
|
||||
<field name="inherit_id" ref="product.product_pricelist_view_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="currency_id" position="after">
|
||||
<field name="selectable"/>
|
||||
<field name="website_id" groups="website.group_multi_website"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -1,25 +1,40 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="product_product_view_form_add" model="ir.ui.view">
|
||||
<field name="name">product.product.view.form.add</field>
|
||||
<field name="model">product.product</field>
|
||||
<field name="arch" type="xml">
|
||||
<form js_class="website_new_content_form">
|
||||
<group>
|
||||
<record id="product_product_view_form_normalized_website_sale" model="ir.ui.view">
|
||||
<field name="name">product.product.view.form.normalized.website.sale.inherit</field>
|
||||
<field name="model">product.product</field>
|
||||
<field name="mode">primary</field>
|
||||
<field name="inherit_id" ref="product.product_product_view_form_normalized"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//form" position="attributes">
|
||||
<attribute name="js_class">website_new_content_form</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='company_id']" position="before">
|
||||
<field name="website_url" invisible="1"/>
|
||||
<field name="name" placeholder="e.g. Cheese Burger" string="Product Name"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<field name="website_published" invisible="1"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="product_product_action_add" model="ir.actions.act_window">
|
||||
<field name="name">New Product</field>
|
||||
<field name="res_model">product.product</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
<field name="view_id" ref="product_product_view_form_add"/>
|
||||
</record>
|
||||
<record id="product_product_view_form_normalized" model="ir.ui.view">
|
||||
<field name="name">product.product.view.form.normalized.website.sale</field>
|
||||
<field name="model">product.product</field>
|
||||
<field name="inherit_id" ref="product.product_product_view_form_normalized"/>
|
||||
<field name="arch" type="xml">
|
||||
<div name="tax_info" position="after">
|
||||
<field name="public_categ_ids" string="Website Category" class="oe_inline" widget="many2many_tags" placeholder="Unpublished"/>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="product_product_action_add" model="ir.actions.act_window">
|
||||
<field name="name">New Product</field>
|
||||
<field name="res_model">product.product</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
<field name="context" eval="{'dialog_size': 'medium'}"/>
|
||||
<field name="view_id" ref="product_product_view_form_normalized_website_sale"/>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="product_public_category_form_view" model="ir.ui.view">
|
||||
<field name="name">product.public.category.form</field>
|
||||
<field name="model">product.public.category</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Website Public Categories">
|
||||
<sheet>
|
||||
<field
|
||||
name="image_1920"
|
||||
widget="image"
|
||||
class="oe_avatar"
|
||||
options="{'convert_to_webp': True, 'preview_image': 'image_128'}"
|
||||
/>
|
||||
<div>
|
||||
<group class="col-md-4 col-lg-6 pe-3">
|
||||
<field name="name"/>
|
||||
<field name="parent_id"/>
|
||||
<field name="website_id" options="{'no_create': True}" groups="website.group_multi_website"/>
|
||||
<field name="sequence" groups="base.group_no_one"/>
|
||||
<field name="website_description"/>
|
||||
<field name="cover_image" widget="image" alt="Cover Image"/>
|
||||
</group>
|
||||
</div>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="product_public_category_tree_view" model="ir.ui.view">
|
||||
<field name="name">product.public.category.list</field>
|
||||
<field name="model">product.public.category</field>
|
||||
<field name="arch" type="xml">
|
||||
<list string="Product Public Categories">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="display_name"/>
|
||||
<field name="website_id" groups="website.group_multi_website"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="product_public_category_action" model="ir.actions.act_window">
|
||||
<field name="name">eCommerce Categories</field>
|
||||
<field name="res_model">product.public.category</field>
|
||||
<field name="path">ecommerce-categories</field>
|
||||
<field name="view_mode">list,form</field>
|
||||
<field name="view_id" eval="False"/>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Define a new category
|
||||
</p><p>
|
||||
Categories are used to browse your products through the
|
||||
touchscreen interface.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="product_ribbon_form_view" model="ir.ui.view">
|
||||
<field name="name">product.ribbon.form.view</field>
|
||||
<field name="model">product.ribbon</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<h1>
|
||||
<field name="name" placeholder="New Collection"/>
|
||||
</h1>
|
||||
</div>
|
||||
<group>
|
||||
<label for="assign"/>
|
||||
<div>
|
||||
<field name="assign" class="oe_inline"/>
|
||||
<div invisible="assign != 'new'" class="text-muted ms-2 d-inline-flex align-items-center">
|
||||
<span>for</span>
|
||||
<field name="new_period" style="width: 3rem; !important" class="ms-1 mb-0"/>
|
||||
<span>days after publication.</span>
|
||||
</div>
|
||||
</div>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Display">
|
||||
<group>
|
||||
<field name="position" widget="radio" options="{'horizontal': True}"/>
|
||||
<field name="style" widget="radio" options="{'horizontal': True}"/>
|
||||
<field name="text_color" widget="color"/>
|
||||
<field name="bg_color" widget="color"/>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="product_ribbon_view_tree" model="ir.ui.view">
|
||||
<field name="name">product.ribbon.list</field>
|
||||
<field name="model">product.ribbon</field>
|
||||
<field name="arch" type="xml">
|
||||
<list string="Product Ribbon">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="name"/>
|
||||
<field name="position"/>
|
||||
<field name="text_color" widget="color" readonly="1"/>
|
||||
<field name="bg_color" widget="color" readonly="1"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="product_ribbon_action" model="ir.actions.act_window">
|
||||
<field name="name">Product Ribbons</field>
|
||||
<field name="res_model">product.ribbon</field>
|
||||
<field name="path">product-ribbons</field>
|
||||
<field name="view_mode">list,form</field>
|
||||
<field name="context">{'create': True}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Define a new ribbon
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<!-- Product Tags -->
|
||||
<record id="product_tag_form_view_inherit_website_sale" model="ir.ui.view">
|
||||
<field name="name">product.tag.form.inherit.website.sale</field>
|
||||
<field name="model">product.tag</field>
|
||||
<field name="inherit_id" ref="product.product_tag_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="color" position="after">
|
||||
<field name="ribbon_id"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
<record id="product_tag_tree_view_inherit_website_sale" model="ir.ui.view">
|
||||
<field name="name">product.tag.tree.inherit.website.sale</field>
|
||||
<field name="model">product.tag</field>
|
||||
<field name="inherit_id" ref="product.product_tag_tree_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="name" position="after">
|
||||
<field name="ribbon_id"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
<record id="product_public_tags_action" model="ir.actions.act_window">
|
||||
<field name="name">Product Tags</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">product.tag</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" eval="False"/>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,294 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- ==== Main template ==== -->
|
||||
<!-- Product tiles. Used on the /shop page, the wishlist and the snippet. -->
|
||||
<!-- TODO: rename `products_item` to `product_tile` -->
|
||||
<template id="website_sale.products_item" name="Products item">
|
||||
<!-- Parameters:
|
||||
- show_variations: Whether to show the variant preview on the tile.
|
||||
- show_ribbons: Whether to show the ribbons.
|
||||
- product: `product.template` record.
|
||||
- product_variant: `product.product` record.
|
||||
-->
|
||||
<t t-set="show_variations" t-value="True if show_variations is None else show_variations"/>
|
||||
<t t-set="show_ribbons" t-value="True if show_ribbons is None else show_ribbons"/>
|
||||
|
||||
<!-- Variations/Attributes -->
|
||||
<t t-if="show_variations">
|
||||
<t
|
||||
t-set="product_ptavs_data"
|
||||
t-value="previewed_attribute_values[product.id]"
|
||||
/>
|
||||
<t t-if="product_ptavs_data">
|
||||
<t
|
||||
t-set="product_ptavs"
|
||||
t-value="product_ptavs_data.get('ptavs_data')"
|
||||
/>
|
||||
<t
|
||||
t-if="product_ptavs[0]['ptav'].attribute_id.preview_variants == 'hover'"
|
||||
t-set="ptavs_classes"
|
||||
t-value="'o_has_variations o_has_variations_onhover'"
|
||||
/>
|
||||
<t
|
||||
t-else=""
|
||||
t-set="ptavs_classes"
|
||||
t-value="'o_has_variations o_has_variations_static'"
|
||||
/>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
<form
|
||||
t-attf-class="oe_product_cart h-100 d-flex {{ptavs_classes}}"
|
||||
t-att-data-publish="product.website_published and 'on' or 'off'"
|
||||
role="article"
|
||||
t-att-aria-label="product.name"
|
||||
>
|
||||
<div t-attf-class="oe_product_image position-relative flex-grow-0 overflow-hidden">
|
||||
<input
|
||||
type="hidden"
|
||||
name="csrf_token"
|
||||
t-att-value="request.csrf_token()"
|
||||
/>
|
||||
|
||||
<!-- Fetch Images Data -->
|
||||
<!-- Use `variant` instead of reassigning `product_variant` beacause it's used to infer
|
||||
if variant information should be shown later. -->
|
||||
<t
|
||||
t-set="variant"
|
||||
t-value="product_variant or product_variants[product]"
|
||||
/>
|
||||
<t
|
||||
t-if="variant and variant.with_context(bin_size=True).image_128"
|
||||
t-set="all_images_list"
|
||||
t-value="variant._get_images()"
|
||||
/>
|
||||
<t
|
||||
t-else=""
|
||||
t-set="all_images_list"
|
||||
t-value="product._get_images()"
|
||||
/>
|
||||
<!--
|
||||
Image holders are records of different types (`product.template`, `product.product`
|
||||
or `product.image`) and are returned as a list.
|
||||
-->
|
||||
<t
|
||||
t-set="primary_image_holder"
|
||||
t-value="(all_images_list[:1]+[product])[0]"
|
||||
/>
|
||||
<t
|
||||
t-set="secondary_image_holder"
|
||||
t-value="(all_images_list[1:2]+[False])[0]"
|
||||
/>
|
||||
|
||||
<a
|
||||
t-att-href="product_href"
|
||||
t-attf-class="oe_product_image_link position-relative {{secondary_image_holder and 'oe_product_image_link_has_secondary'}}"
|
||||
contenteditable="false"
|
||||
t-att-title="product.name"
|
||||
>
|
||||
<!-- Primary image -->
|
||||
<span
|
||||
t-field="primary_image_holder.image_1920"
|
||||
t-options="{'widget': 'image', 'preview_image': 'image_1024', 'class': 'oe_product_image_img h-100 w-100'}"
|
||||
class="oe_product_image_img_wrapper oe_product_image_img_wrapper_primary d-flex h-100 justify-content-center align-items-center"
|
||||
/>
|
||||
|
||||
<!-- Secondary image -->
|
||||
<span
|
||||
t-if="secondary_image_holder"
|
||||
t-field="secondary_image_holder.image_1920"
|
||||
t-options="{'widget': 'image', 'preview_image': 'image_1024', 'class': 'oe_product_image_img_secondary h-100 w-100'}"
|
||||
class="oe_product_image_img_wrapper oe_product_image_img_wrapper_secondary h-100 justify-content-center align-items-center"
|
||||
/>
|
||||
|
||||
<!-- Ribbon -->
|
||||
<t t-if="show_ribbons">
|
||||
<t t-set="bg_color" t-value="ribbon.bg_color"/>
|
||||
<t t-set="text_color" t-value="ribbon.text_color"/>
|
||||
<span
|
||||
t-att-data-ribbon-id="ribbon.id"
|
||||
t-attf-class="o_ribbons o_not_editable #{ribbon._get_css_classes()}"
|
||||
t-attf-style="#{text_color and ('color: %s;' % text_color)} #{bg_color and 'background-color:' + bg_color}"
|
||||
t-out="ribbon.name or ''"
|
||||
/>
|
||||
</t>
|
||||
</a>
|
||||
</div>
|
||||
<div class="o_wsale_product_information flex-grow-1 flex-shrink-1">
|
||||
<div class="o_wsale_product_info_attributes_wrapper">
|
||||
<!-- Variations/Attributes -->
|
||||
<t
|
||||
t-if="product_ptavs_data"
|
||||
t-call="website_sale.product_variant_preview"
|
||||
/>
|
||||
|
||||
<!-- Information -->
|
||||
<div class="o_wsale_product_information_text">
|
||||
<!-- Product Name -->
|
||||
<h2 class="o_wsale_products_item_title text-break">
|
||||
<a
|
||||
class="text-decoration-none"
|
||||
t-att-href="product_href"
|
||||
>
|
||||
<span t-field="product.name"/>
|
||||
<t
|
||||
t-if="product_variant"
|
||||
t-set="combination_name"
|
||||
t-value="product_variant.product_template_attribute_value_ids._get_combination_name()"
|
||||
/>
|
||||
<span
|
||||
t-if="combination_name"
|
||||
t-out="'('+combination_name+')'"
|
||||
/>
|
||||
</a>
|
||||
<a
|
||||
t-if="not product.website_published"
|
||||
role="button"
|
||||
t-att-href="product_href"
|
||||
class="btn btn-sm btn-danger"
|
||||
title="This product is unpublished."
|
||||
>
|
||||
Unpublished
|
||||
</a>
|
||||
</h2>
|
||||
<!-- Description -->
|
||||
<t t-call="website_sale.product_tile_element_visibility">
|
||||
<t t-set="visible_element_class" t-value="'o_wsale_products_opt_has_description'"/>
|
||||
|
||||
<div class="oe_subdescription_wrapper">
|
||||
<div
|
||||
class="oe_subdescription text-muted small"
|
||||
contenteditable="false"
|
||||
>
|
||||
<div t-field="product.description_sale"/>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
<!-- Rating -->
|
||||
<t
|
||||
t-if="is_view_active('website_sale.product_comment')"
|
||||
t-call="website_sale.product_tile_element_visibility"
|
||||
>
|
||||
<t t-set="visible_element_class" t-value="'o_wsale_products_opt_has_rating'"/>
|
||||
|
||||
<div class="o_wsale_product_rating_wrapper">
|
||||
<t t-call="portal_rating.rating_widget_stars_static">
|
||||
<!-- sudo: product.product - visitor can access product average rating -->
|
||||
<t t-set="rating_avg" t-value="product.sudo().rating_avg"/>
|
||||
<t t-set="rating_count" t-value="product.rating_count"/>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
<t t-if="product_extra_information" t-out="product_extra_information"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="o_wsale_product_sub justify-content-between gap-2">
|
||||
<!-- Price(s) -->
|
||||
<t t-if="product_price" t-out="product_price"/>
|
||||
<t t-else="">
|
||||
<t t-set="template_price_vals" t-value="get_product_prices(product)"/>
|
||||
<div class="product_price" aria-label="Price information">
|
||||
<span
|
||||
class="mb-0 fw-bold"
|
||||
aria-label="Sale price"
|
||||
t-if="template_price_vals['price_reduce'] or not website.prevent_zero_price_sale"
|
||||
t-out="template_price_vals['price_reduce']"
|
||||
t-options="{'widget': 'monetary', 'display_currency': website.currency_id}"
|
||||
/>
|
||||
<t
|
||||
t-if="'base_price' in template_price_vals and (template_price_vals['base_price'] > template_price_vals['price_reduce']) and (template_price_vals['price_reduce'] or not website.prevent_zero_price_sale)"
|
||||
name="product_base_price"
|
||||
>
|
||||
<del
|
||||
aria-label="Original price"
|
||||
t-attf-class="text-muted me-1 mb-0"
|
||||
style="white-space: nowrap;"
|
||||
>
|
||||
<small
|
||||
t-esc="template_price_vals['base_price']"
|
||||
t-options="{'widget': 'monetary', 'display_currency': website.currency_id}"
|
||||
/>
|
||||
</del>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
<!-- Actions -->
|
||||
<div class="o_wsale_product_btn">
|
||||
<t t-if="product_actions" t-out="product_actions"/>
|
||||
<t t-else="" t-call="website_sale.shop_product_buttons"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Extra actions (wishlist remove, ...) -->
|
||||
<t t-if="extra_actions" t-out="extra_actions"/>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<!-- TODO: rename `shop_product_buttons` to `product_tile_actions` -->
|
||||
<template id="website_sale.shop_product_buttons" name="Products Actions">
|
||||
<t name="buttons_container">
|
||||
<div class="o_wsale_product_action_row">
|
||||
<t
|
||||
t-if="product._website_show_quick_add()"
|
||||
t-call="website_sale.product_tile_element_visibility"
|
||||
>
|
||||
<t t-set="visible_element_class" t-value="'o_wsale_products_opt_has_cta'"/>
|
||||
<input name="product_id" t-att-value="variant.id" type="hidden"/>
|
||||
<input name="product_template_id" t-att-value="product.id" type="hidden"/>
|
||||
<input name="product_type" t-att-value="product.type" type="hidden"/>
|
||||
<!-- type="button" needed as default type in a `form` is "sumbit" -->
|
||||
<button
|
||||
type="button"
|
||||
class="o_wsale_product_btn_primary a-submit btn btn-primary"
|
||||
aria-label="Add to cart"
|
||||
title="Add to cart"
|
||||
t-att-data-show-quantity="is_view_active('website_sale.product_quantity')"
|
||||
>
|
||||
<i class="fa fa-fw fa-shopping-cart o_not-animable" role="presentation"/>
|
||||
<span class="o_label small ms-1">Add to Cart</span>
|
||||
</button>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Utilities -->
|
||||
|
||||
<!-- Product Element Visibility Logic:
|
||||
|
||||
This template controls whether a product tile element (e.g., price, description)
|
||||
should be rendered in the DOM, depending on visibility settings and user role.
|
||||
|
||||
Behavior:
|
||||
- If the element's CSS class (`visible_element_class`) is NOT present in `design_field`,
|
||||
it's marked as "editor-only" (i.e., not normally visible).
|
||||
- Such elements are only injected if the current user is a website editor.
|
||||
- Otherwise, the element is always included for all users.
|
||||
|
||||
Purpose:
|
||||
- Enables a better editing experience by letting designers preview and toggle elements live.
|
||||
- Prevents rendering unused elements for visitors, reducing DOM size and improving performance.
|
||||
|
||||
Parameters:
|
||||
- visible_element_class: The CSS class identifier for the element.
|
||||
- design_field: A list of element classes currently enabled for display.
|
||||
- product: The product template record.
|
||||
- product_variant: The specific product variant record.
|
||||
-->
|
||||
<template id="website_sale.product_tile_element_visibility" name="Product tile elements visibility">
|
||||
<t
|
||||
t-set="show_only_in_editor_mode"
|
||||
t-value="visible_element_class and design_field and visible_element_class not in design_field"
|
||||
/>
|
||||
<t
|
||||
t-set="is_editor_user"
|
||||
t-value="request.env.user.has_group('website.group_website_designer')"
|
||||
/>
|
||||
|
||||
<t t-if="(show_only_in_editor_mode and is_editor_user) or not show_only_in_editor_mode">
|
||||
<t t-out="0"/>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -1,19 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="product_template_search_view_website" model="ir.ui.view">
|
||||
<field name="name">product.template.search.published</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="product.product_template_search_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//filter[@name='consumable']" position="after">
|
||||
<separator/>
|
||||
<filter name="favorites" position="after">
|
||||
<filter string="Published" name="published" domain="[('is_published', '=', True)]"/>
|
||||
</xpath>
|
||||
</filter>
|
||||
<filter name="group_by_categ_id" position="after">
|
||||
<filter
|
||||
string="eCommerce Category"
|
||||
name="groupby_public_category"
|
||||
context="{'group_by':'public_categ_ids'}"
|
||||
/>
|
||||
</filter>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="product_product_website_tree_view">
|
||||
<field name="name">product.product.website.tree</field>
|
||||
<record id="product_product_website_tree_view" model="ir.ui.view">
|
||||
<field name="name">product.product.website.list</field>
|
||||
<field name="model">product.product</field>
|
||||
<field name="inherit_id" ref="product.product_product_tree_view"/>
|
||||
<field name="arch" type="xml">
|
||||
|
|
@ -21,32 +28,46 @@
|
|||
<field name="website_id" groups="website.group_multi_website" optional="show"/>
|
||||
<field name="is_published" string="Is Published" optional="hide"/>
|
||||
</field>
|
||||
<field name="additional_product_tag_ids" position="after">
|
||||
<field
|
||||
name="website_ribbon_id"
|
||||
invisible="variant_ribbon_id"
|
||||
optional="hide"
|
||||
readonly="1"
|
||||
/>
|
||||
<field
|
||||
name="variant_ribbon_id" options="{'no_quick_create': True}" optional="hide"
|
||||
/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- We want website_id to be shown outside of website module like other models -->
|
||||
<record model="ir.ui.view" id="product_template_view_tree">
|
||||
<field name="name">product.template.view.tree.inherit.website_sale</field>
|
||||
<record id="product_template_view_tree" model="ir.ui.view">
|
||||
<field name="name">product.template.view.list.inherit.website_sale</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="product.product_template_tree_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="default_code" position="after">
|
||||
<field name="website_id" groups="website.group_multi_website" optional="hide"/>
|
||||
</field>
|
||||
<field name="product_tag_ids" position="after">
|
||||
<field name="website_ribbon_id" optional="hide"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- only website module template view should use the website_sequence -->
|
||||
<record model="ir.ui.view" id="product_template_view_tree_website_sale">
|
||||
<field name="name">product.template.view.tree.website_sale</field>
|
||||
<record id="product_template_view_tree_website_sale" model="ir.ui.view">
|
||||
<field name="name">product.template.view.list.website_sale</field>
|
||||
<field name="mode">primary</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="website_sale.product_template_view_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="/tree" position="attributes">
|
||||
<attribute name="default_order">website_sequence</attribute>
|
||||
</xpath>
|
||||
<field name="priority" position="before">
|
||||
<list position="attributes">
|
||||
<attribute name="default_order">website_sequence</attribute>
|
||||
</list>
|
||||
<field name="is_favorite" position="before">
|
||||
<field name="website_sequence" widget="handle"/>
|
||||
</field>
|
||||
<field name="website_id" position="after">
|
||||
|
|
@ -56,28 +77,30 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="product_template_view_kanban_website_sale">
|
||||
<record id="product_template_view_kanban_website_sale" model="ir.ui.view">
|
||||
<field name="name">product.template.view.kanban.website_sale</field>
|
||||
<field name="mode">primary</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="product.product_template_kanban_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="/kanban" position="attributes">
|
||||
<attribute name="default_order">website_sequence</attribute>
|
||||
</xpath>
|
||||
<field name="id" position="after">
|
||||
<field name="website_sequence"/>
|
||||
</field>
|
||||
<kanban position="attributes">
|
||||
<attribute name="default_order">website_sequence</attribute>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="product_template_action_website" model="ir.actions.act_window">
|
||||
<field name="name">Products</field>
|
||||
<field name="res_model">product.template</field>
|
||||
<field name="view_mode">kanban,tree,form,activity</field>
|
||||
<field name="path">ecommerce-products</field>
|
||||
<field name="view_mode">kanban,list,form,activity</field>
|
||||
<field name="view_id"/>
|
||||
<field name="search_view_id" ref="product_template_search_view_website"/>
|
||||
<field name="context">{'search_default_published': 1, 'tree_view_ref':'website_sale.product_template_view_tree_website_sale', 'kanban_view_ref':'website_sale.product_template_view_kanban_website_sale'}</field>
|
||||
<field name="context">{
|
||||
'search_default_published': 1,
|
||||
'list_view_ref': 'website_sale.product_template_view_tree_website_sale',
|
||||
'kanban_view_ref': 'website_sale.product_template_view_kanban_website_sale'
|
||||
}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Create a new product
|
||||
|
|
@ -87,12 +110,12 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="product_template_only_website_form_view">
|
||||
<record id="product_template_only_website_form_view" model="ir.ui.view">
|
||||
<field name="name">product.template.product.only.website.form</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="product.product_template_only_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<div name="pricing" position="after">
|
||||
<field name="categ_id" position="before">
|
||||
<label for="compare_list_price" groups="website_sale.group_product_price_comparison"/>
|
||||
<div class="o_row" groups="website_sale.group_product_price_comparison">
|
||||
<del class="oe_read_only">
|
||||
|
|
@ -100,71 +123,107 @@
|
|||
</del>
|
||||
<field name="compare_list_price" nolabel="1" widget="monetary" options="{'currency_field': 'currency_id', 'field_digits': True}" class="oe_edit_only"/>
|
||||
</div>
|
||||
</div>
|
||||
<xpath expr="//field[@name='uom_id']" position="after">
|
||||
<label for="base_unit_count" groups="website_sale.group_show_uom_price"/>
|
||||
<div name="base_unit_price" groups="website_sale.group_show_uom_price" class="d-flex flex-row">
|
||||
<field name="base_unit_count" attrs="{'invisible': [('product_variant_count', '>', 1)]}" style="width: 4rem;"/>
|
||||
<field name="base_unit_id" options="{'no_open': True}" attrs="{'invisible': [('product_variant_count', '>', 1)]}" placeholder="Specify unit" style="width: 10rem;"/>
|
||||
<div class="d-flex flex-row" attrs="{'invisible': ['|', ('base_unit_price','=', 0), ('product_variant_count', '>', 1)]}">
|
||||
<field name="base_unit_count" invisible="product_variant_count > 1" style="width: 4rem;"/>
|
||||
<field name="base_unit_id" options="{'no_open': True}" invisible="product_variant_count > 1" placeholder="Specify unit" style="width: 10rem;"/>
|
||||
<div class="d-flex flex-row" invisible="base_unit_price == 0 or product_variant_count > 1">
|
||||
(<field name="base_unit_price" class="oe_inline"/> / <field name="base_unit_name" class="oe_inline"/>)
|
||||
</div>
|
||||
<span class='text-muted' attrs="{'invisible': [('product_variant_count', '<=', 1)]}">Based on variants</span>
|
||||
<span class="text-muted" invisible="product_variant_count <= 1">Based on variants</span>
|
||||
</div>
|
||||
</xpath>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="product_product_normal_website_form_view">
|
||||
<record id="product_product_normal_website_form_view" model="ir.ui.view">
|
||||
<field name="name">product.product.normal.view.website</field>
|
||||
<field name="model">product.product</field>
|
||||
<field name="inherit_id" ref="product.product_normal_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='uom_id']" position="after">
|
||||
<field name="categ_id" position="before">
|
||||
<label for="base_unit_count" groups="website_sale.group_show_uom_price"/>
|
||||
<div name="base_unit_price" groups="website_sale.group_show_uom_price" class="d-flex flex-row">
|
||||
<field name="base_unit_count" style="width: 4rem;"/>
|
||||
<field name="base_unit_id" options="{'no_open': True}" placeholder="Specify unit" style="width: 10rem;"/>
|
||||
<div class="d-flex flex-row" attrs="{'invisible': [('base_unit_price','=', 0)]}">
|
||||
<div class="d-flex flex-row" invisible="base_unit_price == 0">
|
||||
(<field name="base_unit_price" class="oe_inline"/> / <field name="base_unit_name" class="oe_inline"/>)
|
||||
</div>
|
||||
</div>
|
||||
</xpath>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="product_template_form_view">
|
||||
<record id="product_template_form_view" model="ir.ui.view">
|
||||
<field name="name">product.template.product.website.form</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="product.product_template_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<!-- add state field in header -->
|
||||
<div name="button_box" position="inside">
|
||||
<field name="is_published" widget="website_redirect_button" attrs="{'invisible': [('sale_ok','=',False)]}"/>
|
||||
</div>
|
||||
<span id="button_website" position="before">
|
||||
<field name="is_published" widget="website_redirect_button" invisible="not sale_ok"/>
|
||||
</span>
|
||||
<group name="upsell" position="attributes">
|
||||
<attribute name="invisible">0</attribute>
|
||||
</group>
|
||||
<xpath expr="//group[@name='upsell']" position="inside">
|
||||
<field name="accessory_product_ids" widget="many2many_tags" attrs="{'invisible': [('sale_ok','=',False)]}"
|
||||
<group name="upsell" position="inside">
|
||||
<field name="accessory_product_ids" widget="many2many_tags"
|
||||
domain="[('sale_ok', '=', True)]"
|
||||
invisible="not sale_ok"
|
||||
placeholder="Suggested accessories in the eCommerce cart"/>
|
||||
<field name="alternative_product_ids" widget="many2many_tags"
|
||||
domain="[('id', '!=', active_id), '|', ('company_id', '=', company_id), ('company_id', '=', False)]"
|
||||
attrs="{'invisible': [('sale_ok','=',False)]}"
|
||||
domain="[('id', '!=', id), '|', ('company_id', '=', company_id), ('company_id', '=', False)]"
|
||||
context="{'search_product_product': True}"
|
||||
invisible="not sale_ok"
|
||||
placeholder="Displayed in bottom of product pages"/>
|
||||
</xpath>
|
||||
<field name="description_ecommerce" invisible="1" /> <!-- Adding this field as we needed in product_barcodelookup module to store value in this field -->
|
||||
</group>
|
||||
<xpath expr="//page[@name='sales']/group[@name='sale']" position="inside">
|
||||
<group string="eCommerce Shop" name="shop" attrs="{'invisible': [('sale_ok','=',False)]}">
|
||||
<field name="website_url" invisible="1"/>
|
||||
<field name="website_id" options="{'no_create': True}" groups="website.group_multi_website"/>
|
||||
<field name="website_sequence" groups="base.group_no_one"/>
|
||||
<field name="public_categ_ids" widget="many2many_tags" string="Categories"/>
|
||||
<field name="website_ribbon_id" groups="base.group_no_one" options="{'no_quick_create': True}"/>
|
||||
</group>
|
||||
<group name="product_template_images" string="Extra Product Media" attrs="{'invisible': [('sale_ok','=',False)]}">
|
||||
<field name="product_template_image_ids" class="o_website_sale_image_list" context="{'default_name': name}" mode="kanban" add-label="Add a Media" nolabel="1"/>
|
||||
<group colspan="2" name="product_template_images" string="eCommerce Media" invisible="not sale_ok">
|
||||
<field
|
||||
colspan="2"
|
||||
name="product_template_image_ids"
|
||||
class="o_website_sale_image_list"
|
||||
context="{'default_name': name}"
|
||||
mode="kanban"
|
||||
add-label="Add Media"
|
||||
nolabel="1"
|
||||
widget="x2_many_media_viewer"
|
||||
options="{'convert_to_webp': True}"
|
||||
/>
|
||||
</group>
|
||||
</xpath>
|
||||
<xpath expr="//page[@name='sales']//group[@name='description']" position="before">
|
||||
<group string="Ecommerce Description" name="ecom_description">
|
||||
<field
|
||||
colspan="2"
|
||||
name="description_ecommerce"
|
||||
nolabel="1"
|
||||
placeholder="A detailed,formatted description to promote your product on
|
||||
this page. Use '/' to discover more features."
|
||||
/>
|
||||
</group>
|
||||
</xpath>
|
||||
<xpath expr="//group[@name='extra_info']//field[@name='product_tag_ids']" position="before">
|
||||
<field
|
||||
name="website_id"
|
||||
options="{'no_create': True}"
|
||||
groups="website.group_multi_website"
|
||||
placeholder="All"
|
||||
/>
|
||||
</xpath>
|
||||
<group name="extra_info" position="inside">
|
||||
<field name="is_published" widget="boolean_toggle"/>
|
||||
<field name="website_sequence" groups="base.group_no_one"/>
|
||||
<field name="public_categ_ids" widget="many2many_tags" string="Categories"/>
|
||||
<field
|
||||
name="website_ribbon_id"
|
||||
options="{'no_quick_create': True}"
|
||||
/>
|
||||
</group>
|
||||
<group name="extra_info" position="attributes">
|
||||
<attribute name="string">Ecommerce Shop</attribute>
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
|
@ -173,211 +232,25 @@
|
|||
<field name="model">product.product</field>
|
||||
<field name="inherit_id" ref="product.product_variant_easy_edit_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//group[@name='pricing']" position="inside">
|
||||
<group name="pricing" position="inside">
|
||||
<label for="base_unit_count" groups="website_sale.group_show_uom_price"/>
|
||||
<div name="base_unit_price" groups="website_sale.group_show_uom_price" class="d-flex flex-row">
|
||||
<field name="base_unit_count" style="width: 4rem;"/>
|
||||
<field name="base_unit_id" options="{'no_open': True}" placeholder="Specify unit" style="width: 10rem;"/>
|
||||
<div class="d-flex flex-row" attrs="{'invisible': [('base_unit_price','=', 0)]}">
|
||||
<div class="d-flex flex-row" invisible="base_unit_price == 0">
|
||||
(<field name="base_unit_price" class="oe_inline"/> / <field name="base_unit_name" class="oe_inline"/>)
|
||||
</div>
|
||||
</div>
|
||||
</xpath>
|
||||
<xpath expr="//group[@name='packaging']" position="after">
|
||||
<group name="product_variant_images" string="Extra Variant Media">
|
||||
<field name="product_variant_image_ids" class="o_website_sale_image_list" context="{'default_name': name}" mode="kanban" add-label="Add a Media" nolabel="1"/>
|
||||
</group>
|
||||
<group name="sales" position="inside">
|
||||
<field name="website_ribbon_id" options="{'no_open': True}" readonly="True"/>
|
||||
<field name="variant_ribbon_id" options="{'no_quick_create': True}"/>
|
||||
</group>
|
||||
<group name="sales" position="after">
|
||||
<group colspan="2" name="product_variant_images" string="Extra Variant Media">
|
||||
<field name="product_variant_image_ids" class="o_website_sale_image_list" context="{'default_name': name}" mode="kanban" add-label="Add Media" nolabel="1" widget="x2_many_media_viewer" options="{'convert_to_webp': True}"/>
|
||||
</group>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Product ribbon -->
|
||||
<record id="product_ribbon_form_view" model="ir.ui.view">
|
||||
<field name="name">product.ribbon form view</field>
|
||||
<field name="model">product.ribbon</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<sheet>
|
||||
<group>
|
||||
<group>
|
||||
<field name="html" widget="char"/>
|
||||
<field name="text_color"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="html_class"/>
|
||||
<field name="bg_color"/>
|
||||
</group>
|
||||
</group>
|
||||
<group string="Products">
|
||||
<group>
|
||||
<field name="product_tag_ids" widget="many2many_tags" options="{'color_field': 'color', 'no_edit_color': 1}"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Product Public Categories -->
|
||||
<record id="product_public_category_form_view" model="ir.ui.view">
|
||||
<field name="name">product.public.category.form</field>
|
||||
<field name="model">product.public.category</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Website Public Categories">
|
||||
<sheet>
|
||||
<field name="image_1920" widget="image" class="oe_avatar" options="{'preview_image': 'image_128'}"/>
|
||||
<div class="oe_left">
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="parent_id"/>
|
||||
<field name="website_id" options="{'no_create': True}" groups="website.group_multi_website"/>
|
||||
<field name="sequence" groups="base.group_no_one"/>
|
||||
</group>
|
||||
</div>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="product_public_category_tree_view" model="ir.ui.view">
|
||||
<field name="name">product.public.category.tree</field>
|
||||
<field name="model">product.public.category</field>
|
||||
<field name="field_parent" eval="False"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Product Public Categories">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="display_name"/>
|
||||
<field name="website_id" groups="website.group_multi_website"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="product_public_category_action" model="ir.actions.act_window">
|
||||
<field name="name">eCommerce Categories</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">product.public.category</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" eval="False"/>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Define a new category
|
||||
</p><p>
|
||||
Categories are used to browse your products through the
|
||||
touchscreen interface.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="product_ribbon_view_tree" model="ir.ui.view">
|
||||
<field name="name">product.ribbon.tree</field>
|
||||
<field name="model">product.ribbon</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Products Ribbon">
|
||||
<field name="html" string="Name"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="website_sale_pricelist_form_view" model="ir.ui.view">
|
||||
<field name="name">website_sale.pricelist.form</field>
|
||||
<field name="inherit_id" ref="product.product_pricelist_view" />
|
||||
<field name="model">product.pricelist</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//group[@name='pricelist_availability']" position="after">
|
||||
<group name="pricelist_website" string="Website">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="website_id" options="{'no_create': True}"/>
|
||||
<field name="selectable"/>
|
||||
<field name="code"/>
|
||||
</group>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="website_sale_pricelist_tree_view" model="ir.ui.view">
|
||||
<field name="name">product.pricelist.tree.inherit.product</field>
|
||||
<field name="model">product.pricelist</field>
|
||||
<field name="inherit_id" ref="product.product_pricelist_view_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="currency_id" position="after">
|
||||
<field name="selectable" />
|
||||
<field name="website_id" groups="website.group_multi_website"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- This view should only be used from the product o2m because the required field product_tmpl_id has to be automatically set. -->
|
||||
<record id="view_product_image_form" model="ir.ui.view">
|
||||
<field name="name">product.image.view.form</field>
|
||||
<field name="model">product.image</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Product Images">
|
||||
<field name="sequence" invisible="1"/>
|
||||
<div class="row o_website_sale_image_modal">
|
||||
<div class="col-md-6 col-xl-5">
|
||||
<label for="name" string="Image Name"/>
|
||||
<h2><field name="name" placeholder="Image Name"/></h2>
|
||||
<label for="video_url" string="Video URL"/><br/>
|
||||
<field name="video_url"/><br/>
|
||||
</div>
|
||||
<div class="col-md-6 col-xl-7 text-center o_website_sale_image_modal_container">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<field name="image_1920" widget="image"/>
|
||||
</div>
|
||||
<div class="col" attrs="{'invisible': [('video_url', 'in', ['', False])]}">
|
||||
<div class="o_video_container p-2">
|
||||
<span>Video Preview</span>
|
||||
<field name="embed_code" class="mt-2" widget="video_preview"/>
|
||||
<h4 class="o_invalid_warning text-muted text-center" attrs="{'invisible': [('embed_code', '!=', False)]}">
|
||||
Please enter a valid Video URL.
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="product_image_view_kanban" model="ir.ui.view">
|
||||
<field name="name">product.image.view.kanban</field>
|
||||
<field name="model">product.image</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban string="Product Images" default_order="sequence">
|
||||
<field name="id"/>
|
||||
<field name="name"/>
|
||||
<field name="image_1920"/>
|
||||
<field name="sequence" widget="handle"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div class="card oe_kanban_global_click p-0">
|
||||
<div class="o_squared_image">
|
||||
<img class="card-img-top" t-att-src="kanban_image('product.image', 'image_1920', record.id.raw_value)" t-att-alt="record.name.value"/>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<h4 class="card-title p-2 m-0 bg-200">
|
||||
<small><field name="name"/></small>
|
||||
</h4>
|
||||
</div>
|
||||
<!-- below 100 Kb: good -->
|
||||
<t t-if="record.image_1920.raw_value.length < 100*1000">
|
||||
<t t-set="size_status" t-value="'text-bg-success'"/>
|
||||
<t t-set="message">Acceptable file size</t>
|
||||
</t>
|
||||
<!-- below 1000 Kb: decent -->
|
||||
<t t-elif="record.image_1920.raw_value.length < 1000*1000">
|
||||
<t t-set="size_status" t-value="'text-bg-warning'" />
|
||||
<t t-set="message">Huge file size. The image should be optimized/reduced.</t>
|
||||
</t>
|
||||
<!-- above 1000 Kb: bad -->
|
||||
<t t-else="1">
|
||||
<t t-set="size_status" t-value="'text-bg-danger'"/>
|
||||
<t t-set="message">Optimization required! Reduce the image size or increase your compression settings.</t>
|
||||
</t>
|
||||
<span t-attf-class="badge #{size_status} o_product_image_size" t-esc="record.image_1920.value" t-att-title="message"/>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="res_config_settings_view_form_web_terms" model="ir.ui.view">
|
||||
<field name="name">res.config.settings.view.form.inherit.account.web.terms</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="inherit_id" ref="account.res_config_settings_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//button[@name='action_update_terms']" position="after">
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="res_config_settings_view_form_inherit_sale" model="ir.ui.view">
|
||||
<field name="name">res.config.settings.view.form.inherit.sale</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
|
|
@ -19,437 +9,258 @@
|
|||
<!-- Remove customer accounts setting from sales settings tab -->
|
||||
<!-- It must not be in the view at all to make sure settings can be saved
|
||||
(because auth_signup_uninvited is specified as required) -->
|
||||
<xpath expr="//div[@id='auth_signup_documents']" position="replace"></xpath>
|
||||
<setting id="auth_signup_documents" position="replace"/>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="res_config_settings_view_form" model="ir.ui.view">
|
||||
<field name="name">res.config.settings.view.form.inherit.website.sale</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="inherit_id" ref="website.res_config_settings_view_form"/>
|
||||
<field name="inherit_id" ref="website_payment.res_config_settings_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<div id="website_info_settings" position="after">
|
||||
<h2>Shop - Checkout Process</h2>
|
||||
<div class="row mt16 o_settings_container" id="website_shop_checkout">
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="cart_redirect_setting">
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="add_to_cart_action" string="Add to Cart"/>
|
||||
<div class="text-muted">
|
||||
What should be done on "Add to Cart"?
|
||||
</div>
|
||||
<div class="content-group">
|
||||
<div class="row mt16 ms-4">
|
||||
<field name="add_to_cart_action" widget="radio"/>
|
||||
</div>
|
||||
<setting id="shared_user_account_setting" position="after">
|
||||
<setting
|
||||
id="autocomplete_googleplaces_setting"
|
||||
string="Google Address Validation"
|
||||
help="Use Google Places API to validate addresses"
|
||||
documentation="/applications/websites/website/configuration/address_autocomplete.html"
|
||||
>
|
||||
<field name="module_website_sale_autocomplete"/>
|
||||
</setting>
|
||||
</setting>
|
||||
<block id="website_payment_block" position="attributes">
|
||||
<attribute name="title">eCommerce</attribute>
|
||||
</block>
|
||||
<block id="website_payment_block" position="inside">
|
||||
<setting
|
||||
string="Configure Delivery Methods"
|
||||
id="website_delivery_setting"
|
||||
help="Configure delivery methods or work with delivery providers using existing integrations."
|
||||
documentation="/applications/inventory_and_mrp/inventory/shipping/setup/third_party_shipper.html"
|
||||
>
|
||||
<button
|
||||
string="Configure Methods"
|
||||
type="action"
|
||||
name="%(delivery.action_delivery_carrier_form)d"
|
||||
class="btn btn-primary"
|
||||
/>
|
||||
<button
|
||||
string="Find a Delivery Provider"
|
||||
type="object"
|
||||
name="action_view_delivery_provider_modules"
|
||||
class="btn btn-link"
|
||||
icon="oi-arrow-right"
|
||||
/>
|
||||
</setting>
|
||||
<setting string="Display Product Prices" id="website_tax_inclusion_setting">
|
||||
<field
|
||||
name="show_line_subtotals_tax_selection"
|
||||
widget="radio"
|
||||
class="o_light_label"
|
||||
/>
|
||||
</setting>
|
||||
<setting
|
||||
id="ecommerce_access_setting"
|
||||
title="Shop, products, cart and wishlist visibility"
|
||||
>
|
||||
<field name="ecommerce_access" widget="radio" class="o_light_label"/>
|
||||
</setting>
|
||||
<setting
|
||||
string="Sign in/up at checkout"
|
||||
id="checkout_registration_setting"
|
||||
title="To send invitations in B2B mode, open a contact or select several ones
|
||||
in list view and click on 'Portal Access Management' option in the
|
||||
dropdown menu *Action*."
|
||||
>
|
||||
<field name="account_on_checkout" widget="radio"/>
|
||||
</setting>
|
||||
<setting
|
||||
string="Add to Cart"
|
||||
id="cart_redirect_setting"
|
||||
help="What should be done on "Add to Cart"?"
|
||||
>
|
||||
<field name="add_to_cart_action" widget="radio"/>
|
||||
</setting>
|
||||
<setting
|
||||
string="Invoicing Policy"
|
||||
id="invoicing_policy_setting"
|
||||
title="The mode selected here applies as invoicing policy of any new product
|
||||
created but not of products already existing."
|
||||
info="This setting is common to all websites."
|
||||
>
|
||||
<field name="default_invoice_policy" widget="radio" class="o_light_label"/>
|
||||
</setting>
|
||||
<setting
|
||||
id="automatic_invoice_generation_setting"
|
||||
help="Invoice automatically on payment."
|
||||
invisible="default_invoice_policy == 'delivery'"
|
||||
>
|
||||
<field name="automatic_invoice"/>
|
||||
<div invisible="not automatic_invoice">
|
||||
<label for="invoice_mail_template_id" class="o_light_label me-2"/>
|
||||
<field name="invoice_mail_template_id" class="oe_inline"/>
|
||||
</div>
|
||||
</setting>
|
||||
<setting
|
||||
help="Add a strikethrough price, as a comparison"
|
||||
info="This setting is common to all websites."
|
||||
>
|
||||
<field name="group_product_price_comparison"/>
|
||||
</setting>
|
||||
<setting
|
||||
string="Product Reference Price"
|
||||
id="ecom_uom_price_option_setting"
|
||||
help="Add a reference price per UoM on products (i.e $/kg), in addition to the
|
||||
sale price"
|
||||
info="This setting is common to all websites."
|
||||
>
|
||||
<field name="group_show_uom_price"/>
|
||||
</setting>
|
||||
<setting
|
||||
string="Product Variants"
|
||||
id="product_attributes_setting"
|
||||
help="One product might have different attributes (size, color, etc.)"
|
||||
documentation="/applications/websites/ecommerce/managing_products/variants.html"
|
||||
>
|
||||
<field name="group_product_variant"/>
|
||||
<button
|
||||
string="Attributes"
|
||||
type="action"
|
||||
name="%(product.attribute_action)d"
|
||||
invisible="not group_product_variant"
|
||||
class="btn-link"
|
||||
icon="oi-arrow-right"
|
||||
/>
|
||||
</setting>
|
||||
<setting
|
||||
string="Discounts, Loyalty & Gift Card"
|
||||
id="wsale_loyalty_setting"
|
||||
title="Boost your sales with multiple kinds of programs: Coupons, Promotions,
|
||||
Gift Card, Loyalty. Specific conditions can be set (products, customers,
|
||||
minimum purchase amount, period). Rewards can be discounts (% or amount)
|
||||
or free products."
|
||||
help="Promotions, coupons, loyalty cards, gift cards & eWallet"
|
||||
documentation="/applications/sales/sales/products_prices/loyalty_discount.html"
|
||||
>
|
||||
<field name="module_loyalty" />
|
||||
</setting>
|
||||
<setting
|
||||
id="pricelists_setting"
|
||||
help="Apply specific prices or currency per country, customer, products, etc."
|
||||
documentation="/applications/sales/sales/products_prices/prices/pricing.html"
|
||||
>
|
||||
<field name="group_product_pricelist"/>
|
||||
<button
|
||||
string="Pricelists"
|
||||
type="action"
|
||||
name="%(product.product_pricelist_action2)d"
|
||||
groups="product.group_product_pricelist"
|
||||
invisible="not group_product_pricelist"
|
||||
class="btn-link"
|
||||
icon="oi-arrow-right"
|
||||
/>
|
||||
</setting>
|
||||
<setting
|
||||
id="hide_add_to_cart_setting"
|
||||
help="If product price equals 0, replace 'Add to Cart' by 'Contact us'."
|
||||
>
|
||||
<field name="website_sale_prevent_zero_price_sale"/>
|
||||
<div class="content-group" invisible="not website_sale_prevent_zero_price_sale">
|
||||
<div class="row mt16">
|
||||
<label
|
||||
string="Button URL"
|
||||
for="website_sale_contact_us_button_url"
|
||||
class="o_light_label col-lg-3"
|
||||
/>
|
||||
<field name="website_sale_contact_us_button_url"/>
|
||||
</div>
|
||||
</div>
|
||||
</setting>
|
||||
<setting string="Order Confirmation" id="order_confirmation_setting">
|
||||
<div class="content-group">
|
||||
<div class="row mt16">
|
||||
<label
|
||||
string="Email"
|
||||
for="confirmation_email_template_id"
|
||||
class="o_light_label col-lg-3"
|
||||
/>
|
||||
<field name="confirmation_email_template_id"/>
|
||||
</div>
|
||||
</div>
|
||||
</setting>
|
||||
<setting
|
||||
string="Follow up abandoned carts"
|
||||
id="abandoned_carts_setting"
|
||||
help="Automate abandoned checkout emails"
|
||||
documentation="/applications/websites/ecommerce/ecommerce_management/order_handling.html#abandoned-cart"
|
||||
>
|
||||
<field name="send_abandoned_cart_email"/>
|
||||
<div invisible="not send_abandoned_cart_email" class="content-group">
|
||||
<div class="row mt16">
|
||||
<div class="col-12">
|
||||
<label
|
||||
string="Send after"
|
||||
for="cart_abandoned_delay"
|
||||
class="o_light_label"
|
||||
/>
|
||||
<field
|
||||
name="cart_abandoned_delay"
|
||||
widget="float_time"
|
||||
class="ms-1"
|
||||
style="width: 50px;"
|
||||
/> hours.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="enabled_buy_now_button"/>
|
||||
<div invisible="not send_abandoned_cart_email" class="mt8">
|
||||
<button type="object" name="action_open_abandoned_cart_mail_template" string="Customize Abandoned Email Template" class="btn-link" icon="oi-arrow-right"/>
|
||||
</div>
|
||||
</setting>
|
||||
<setting string="Orders Assignment" help="Assignment of online orders">
|
||||
<div class="content-group">
|
||||
<div class="row mt16">
|
||||
<label
|
||||
string="Sales Team"
|
||||
for="salesteam_id"
|
||||
class="o_light_label col-lg-3"
|
||||
/>
|
||||
<field
|
||||
name="salesteam_id"
|
||||
context="{'kanban_view_ref': 'sales_team.crm_team_view_kanban'}"
|
||||
/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="enabled_buy_now_button"/>
|
||||
<div class="text-muted">
|
||||
Instant checkout, instead of adding to cart
|
||||
</div>
|
||||
<div class="row">
|
||||
<label for="salesperson_id" class="o_light_label col-lg-3"/>
|
||||
<field name="salesperson_id"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="enabled_extra_checkout_step"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="enabled_extra_checkout_step"/>
|
||||
<div class="text-muted">
|
||||
Add a customizable form during checkout (after address)
|
||||
</div>
|
||||
<div class="row mt8 ms-4" attrs="{'invisible': [('enabled_extra_checkout_step', '=', False)]}">
|
||||
<button type="object" name="action_open_extra_info" string="Configure Form " class="btn-link" icon="fa-arrow-right"/>
|
||||
</div>
|
||||
</div>
|
||||
</setting>
|
||||
<setting
|
||||
id="click_and_collect_setting"
|
||||
help="Allow customers to pick up their online purchases at your store and pay in person"
|
||||
documentation="/applications/websites/ecommerce/shipping.html#click-collect"
|
||||
>
|
||||
<field name="module_website_sale_collect"/>
|
||||
</setting>
|
||||
</block>
|
||||
<setting id="google_analytics_setting" position="after">
|
||||
<setting
|
||||
id="google_merchant_center_setting"
|
||||
help="Connect your eCommerce via a product file."
|
||||
documentation="/applications/websites/ecommerce/google_merchant_center.html"
|
||||
>
|
||||
<field name="group_gmc_feed"/>
|
||||
<div class="mt8" invisible="not group_gmc_feed">
|
||||
<button
|
||||
type="object"
|
||||
name="action_open_product_feeds"
|
||||
string="Manage feeds"
|
||||
class="btn-link"
|
||||
icon="oi-arrow-right"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="digital_content_setting" title="Provide customers with product-specific links or downloadable content in the confirmation page of the checkout process if the payment gets through. To do so, attach some files to a product using the new Files button and publish them.">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="module_website_sale_digital"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="module_website_sale_digital"/>
|
||||
<div class="text-muted">
|
||||
Add download link for customers at the end of checkout
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box">
|
||||
<div class="o_setting_right_pane">
|
||||
<span class="o_form_label">Assignment</span>
|
||||
<div class="text-muted">
|
||||
Assignment of online orders
|
||||
</div>
|
||||
<div class="content-group">
|
||||
<div class="row mt16">
|
||||
<label class="o_light_label col-lg-3" string="Sales Team" for="salesteam_id"/>
|
||||
<field name="salesteam_id" kanban_view_ref="%(sales_team.crm_team_view_kanban)s" />
|
||||
</div>
|
||||
<div class="row">
|
||||
<label class="o_light_label col-lg-3" for="salesperson_id"/>
|
||||
<field name="salesperson_id"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="website_sale_enabled_portal_reorder_button"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="website_sale_enabled_portal_reorder_button"/>
|
||||
<div class="text-muted">
|
||||
Allow your customer to add products from previous order in their cart.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>Shop - Products</h2>
|
||||
<div class="row mt16 o_settings_container" id="sale_product_catalog_settings">
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="website_tax_inclusion_setting">
|
||||
<div class="o_setting_right_pane">
|
||||
<label string="Display Product Prices" for="show_line_subtotals_tax_selection"/>
|
||||
<div class="text-muted">
|
||||
Prices displayed on your eCommerce
|
||||
</div>
|
||||
<div class="content-group">
|
||||
<div class="mt16">
|
||||
<field name="show_line_subtotals_tax_selection" class="o_light_label" widget="radio"/>
|
||||
<field name="group_show_line_subtotals_tax_included" invisible="1"/>
|
||||
<field name="group_show_line_subtotals_tax_excluded" invisible="1"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="pricelists_setting" title="With the first mode you can set several prices in the product config form (from Sales tab). With the second one, you set prices and computation rules from Pricelists.">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="group_product_pricelist"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="group_product_pricelist"/>
|
||||
<div class="text-muted">
|
||||
Manage pricelists to apply specific prices per country, customer, products, etc
|
||||
</div>
|
||||
<div class="content-group mt16" attrs="{'invisible': [('group_product_pricelist', '=', False)]}">
|
||||
<field name="group_sale_pricelist" invisible="1"/>
|
||||
<field name="group_product_pricelist" invisible="1"/>
|
||||
<field name="product_pricelist_setting" class="o_light_label w-75" widget="radio"/>
|
||||
</div>
|
||||
<div attrs="{'invisible': [('group_product_pricelist', '=', False)]}">
|
||||
<button type="action" name="%(product.product_pricelist_action2)d" string="Pricelists" class="btn-link" icon="fa-arrow-right"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="group_product_price_comparison"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="group_product_price_comparison"/>
|
||||
<div class="text-muted">
|
||||
Add a strikethrough price, as a comparison
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="ecom_uom_price_option_setting">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="group_show_uom_price"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="group_show_uom_price" string="Product Reference Price"/>
|
||||
<div class="text-muted">
|
||||
Add a reference price per UoM on products (i.e $/kg), in addition to the sale price
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="product_attributes_setting">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="group_product_variant"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="group_product_variant" string="Product Variants"/>
|
||||
<div class="text-muted">
|
||||
One product might have different attributes (size, color, ...)
|
||||
</div>
|
||||
<div class="content-group" attrs="{'invisible': [('group_product_variant', '=', False)]}">
|
||||
<div class="mt8">
|
||||
<button type="action" name="%(product.attribute_action)d" string="Attributes" class="btn-link" icon="fa-arrow-right"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box"
|
||||
id="promotion_coupon_programs"
|
||||
title="Boost your sales with multiple kinds of programs: Coupons, Promotions, Gift Card, Loyalty. Specific conditions can be set (products, customers, minimum purchase amount, period). Rewards can be discounts (% or amount) or free products.">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="module_loyalty" />
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="module_loyalty" string="Discounts, Loyalty & Gift Card"/>
|
||||
<div class="text-muted" id="website_sale_loyalty">
|
||||
Manage Promotions, coupons, loyalty cards, Gift cards & eWallet
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="wishlist_option_setting">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="module_website_sale_wishlist"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="module_website_sale_wishlist"/>
|
||||
<div class="text-muted">
|
||||
Allow signed-in users to save product in a wishlist
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="comparator_option_setting">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="module_website_sale_comparison"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="module_website_sale_comparison" string="Product Comparison Tool"/>
|
||||
<div class="text-muted">
|
||||
Allow shoppers to compare products based on their attributes
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="hide_add_to_cart_setting">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="website_sale_prevent_zero_price_sale"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="website_sale_prevent_zero_price_sale"/>
|
||||
<div class="text-muted">
|
||||
If product price equals 0, replace 'Add to Cart' by 'Contact us'.
|
||||
</div>
|
||||
<div class="content-group" attrs="{'invisible': [('website_sale_prevent_zero_price_sale', '=', False)]}">
|
||||
<div class="row mt16">
|
||||
<label class="o_light_label col-lg-3" string="Button url" for="website_sale_contact_us_button_url"/>
|
||||
<field name="website_sale_contact_us_button_url"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>Shipping</h2>
|
||||
<div class="row mt16 o_settings_container" id="sale_shipping_settings">
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="shipping_address_setting">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="group_delivery_invoice_address"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="group_delivery_invoice_address"/>
|
||||
<div class="text-muted">
|
||||
Let the customer enter a shipping address
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="delivery_method_setting">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="module_website_sale_delivery"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label string="Shipping Costs" for="module_website_sale_delivery"/>
|
||||
<div class="text-muted" id="msg_delivery_method_setting">
|
||||
Compute shipping costs on orders
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="ups_provider_setting">
|
||||
<div class="o_setting_left_pane">
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<div class="o_form_label">UPS</div>
|
||||
<div class="text-muted" id="website_delivery_ups">
|
||||
Compute shipping costs and ship with UPS<br/>
|
||||
<strong>(please go to Home>Apps to install)</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="shipping_provider_dhl_setting">
|
||||
<div class="o_setting_left_pane">
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<div class="o_form_label">DHL</div>
|
||||
<div class="text-muted" id="website_delivery_dhl">
|
||||
Compute shipping costs and ship with DHL<br/>
|
||||
<strong>(please go to Home>Apps to install)</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="shipping_provider_fedex_setting">
|
||||
<div class="o_setting_left_pane">
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<div class="o_form_label">FedEx</div>
|
||||
<div class="text-muted" id="website_delivery_fedex">
|
||||
Compute shipping costs and ship with FedEx<br/>
|
||||
<strong>(please go to Home>Apps to install)</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="shipping_provider_usps_setting">
|
||||
<div class="o_setting_left_pane">
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<div class="o_form_label">USPS</div>
|
||||
<div class="text-muted" id="website_delivery_usps">
|
||||
Compute shipping costs and ship with USPS<br/>
|
||||
<strong>(please go to Home>Apps to install)</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="shipping_provider_bpost_setting">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="module_delivery_bpost" widget="upgrade_boolean"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label string="bpost" for="module_delivery_bpost"/>
|
||||
<div class="text-muted" id="website_delivery_bpost">
|
||||
Compute shipping costs and ship with bpost
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="shipping_provider_easypost_setting">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="module_delivery_easypost" widget="upgrade_boolean"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label string="Easypost" for="module_delivery_easypost"/>
|
||||
<div class="text-muted" id="website_delivery_easypost">
|
||||
Compute shipping cost and ship with Easypost
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="shipping_provider_mondialrelay_setting">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="module_delivery_mondialrelay"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label string="Mondial Relay" for="module_delivery_mondialrelay"/>
|
||||
<div class="text-muted" id="website_delivery_mondialrelay">
|
||||
Let the customer select a Mondial Relay shipping point
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="onsite_payment_setting">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="module_website_sale_picking"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="module_website_sale_picking"/>
|
||||
<div class="text-muted">
|
||||
Allow customers to pay in person at your stores
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<field name='module_account' invisible="1"/>
|
||||
<div attrs="{'invisible': [('module_account', '=', False)]}">
|
||||
<h2>Invoicing</h2>
|
||||
<div class="row mt16 o_settings_container" id="sale_invoicing_settings">
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="invoicing_policy_setting" title="The mode selected here applies as invoicing policy of any new product created but not of products already existing.">
|
||||
<div class="o_setting_right_pane">
|
||||
<span class="o_form_label">Invoicing Policy</span>
|
||||
<div class="text-muted">
|
||||
Issue invoices to customers
|
||||
</div>
|
||||
<div class="content-group">
|
||||
<div class="mt16">
|
||||
<field name="default_invoice_policy" class="o_light_label" widget="radio"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box"
|
||||
id="automatic_invoice_generation"
|
||||
attrs="{'invisible': [('default_invoice_policy', '=', 'delivery')]}">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="automatic_invoice" nolabel="1"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="automatic_invoice"/>
|
||||
<div class="text-muted">
|
||||
Generate the invoice automatically when the online payment is confirmed
|
||||
</div>
|
||||
<div attrs="{'invisible': [('automatic_invoice','=',False)]}">
|
||||
<label for="invoice_mail_template_id" class="o_light_label me-2"/>
|
||||
<field name="invoice_mail_template_id" class="oe_inline"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="cart_redirect_setting" position="after">
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="website_checkout_registration">
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="account_on_checkout" string="Sign in/up at checkout"/>
|
||||
<div class="text-muted">
|
||||
"Optional" allows guests to register from the order confirmation email to track their order.
|
||||
</div>
|
||||
<div class="mt8 ms-4">
|
||||
<field name="account_on_checkout" class="w-75" widget="radio"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="website_marketing_automation" position="after">
|
||||
<div class="col-xs-12 col-lg-6 o_setting_box" id="abandoned_carts_setting" title="Customer needs to be signed in otherwise the mail address is not known.
|
||||
- If a potential customer creates one or more abandoned checkouts and then completes a sale before the recovery email gets sent, then the email won't be sent.
|
||||
- If user has manually sent a recovery email, the mail will not be sent a second time
|
||||
- If a payment processing error occurred when the customer tried to complete their checkout, then the email won't be sent.
|
||||
- If your shop does not support shipping to the customer's address, then the email won't be sent.
|
||||
- If none of the products in the checkout are available for purchase (empty inventory, for example), then the email won't be sent.
|
||||
- If all the products in the checkout are free, and the customer does not visit the shipping page to add a shipping fee or the shipping fee is also free, then the email won't be sent.">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="send_abandoned_cart_email"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<span class="o_form_label">Automatically send abandoned checkout emails</span>
|
||||
<div class="text-muted">
|
||||
Mail only sent to signed in customers with items available for sale in their cart.
|
||||
</div>
|
||||
|
||||
<div attrs="{'invisible': [('send_abandoned_cart_email', '=', False)]}" class="content-group" title="Carts are flagged as abandoned after this delay.">
|
||||
<div class="row mt16">
|
||||
<div class="col-12">
|
||||
<label for="cart_abandoned_delay" string="Send after" class="o_light_label"/>
|
||||
<field class="col-2" name="cart_abandoned_delay" widget="float_time" /> Hours.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div attrs="{'invisible': [('send_abandoned_cart_email', '=', False)]}" class="mt8">
|
||||
<button type="object" name="action_open_abandoned_cart_mail_template" string="Customize Abandoned Email Template" class="btn-link" icon="fa-arrow-right"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<xpath expr="//div[@id='google_analytics_setting']" position="after">
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="autocomplete_googleplaces_setting">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="module_website_sale_autocomplete"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="module_website_sale_autocomplete"/>
|
||||
<div class="text-muted">
|
||||
Use Google Places API to validate addresses entered by your visitors
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</xpath>
|
||||
</setting>
|
||||
</setting>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
<field name="inherit_id" ref="sale.view_sales_order_filter"/>
|
||||
<field name="mode">primary</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//filter[@name='my_sale_orders_filter']" position="before">
|
||||
<filter string="Confirmed" name="order_confirmed" domain="[('state', 'in', ('sale', 'done'))]"/>
|
||||
<filter name="my_sale_orders_filter" position="before">
|
||||
<filter string="Confirmed" name="order_confirmed" domain="[('state', '=', 'sale')]"/>
|
||||
<filter string="Unpaid" name="order_unpaid" domain="[('state', '=', 'sent')]"/>
|
||||
<filter string="Abandoned" name="order_abandoned" domain="[('is_abandoned_cart', '=', True)]"/>
|
||||
<separator/>
|
||||
|
|
@ -16,10 +16,10 @@
|
|||
<filter string="From Website" name="from_website" domain="[('website_id', '!=', False)]"/>
|
||||
<separator/>
|
||||
<!-- Dashboard filter - used by context -->
|
||||
<filter string="Last Week" invisible="1" name="week" domain="[('date_order','>', (context_today() - datetime.timedelta(days=7)).strftime('%Y-%m-%d'))]"/>
|
||||
<filter string="Last Month" invisible="1" name="month" domain="[('date_order','>', (context_today() - datetime.timedelta(days=30)).strftime('%Y-%m-%d'))]"/>
|
||||
<filter string="Last Year" invisible="1" name="year" domain="[('date_order','>', (context_today() - datetime.timedelta(days=365)).strftime('%Y-%m-%d'))]"/>
|
||||
</xpath>
|
||||
<filter string="Last Week" invisible="1" name="week" domain="[('date_order', '>', 'today -7d')]"/>
|
||||
<filter string="Last Month" invisible="1" name="month" domain="[('date_order', '>', 'today -30d')]"/>
|
||||
<filter string="Last Year" invisible="1" name="year" domain="[('date_order', '>', 'today -365d')]"/>
|
||||
</filter>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
|
@ -30,43 +30,21 @@
|
|||
<field name="mode">primary</field>
|
||||
<field name="priority">32</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//filter[@name='my_sale_orders_filter']" position="attributes">
|
||||
<filter name="my_sale_orders_filter" position="attributes">
|
||||
<attribute name="invisible">1</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//filter[@name='my_sale_orders_filter']" position="before">
|
||||
</filter>
|
||||
<filter name="my_sale_orders_filter" position="before">
|
||||
<filter string="Order Date" name="order_date" date="date_order"/>
|
||||
<separator/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="sale_order_view_form_cart_recovery" model="ir.ui.view">
|
||||
<field name="name">sale.order.form.abandoned.cart</field>
|
||||
<field name="model">sale.order</field>
|
||||
<field name="inherit_id" ref="sale.view_order_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='team_id']" position="after">
|
||||
<field name="is_abandoned_cart" invisible="1"/>
|
||||
<field name="cart_recovery_email_sent" invisible="1"/>
|
||||
</xpath>
|
||||
<xpath expr="//button[@name='action_quotation_send' and @states='draft']" position="attributes">
|
||||
<!-- The '| and the '&' opertors are necessary because draft state of the parent concatenate the domain -->
|
||||
<attribute name="attrs">{'invisible': ['|','&',('is_abandoned_cart', '=', True), ('cart_recovery_email_sent', '=', False)]}</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//button[@name='action_quotation_send']" position="after">
|
||||
<button name="action_recovery_email_send" data-hotkey="l"
|
||||
string="Send a Recovery Email"
|
||||
type="object"
|
||||
class="btn-primary"
|
||||
attrs="{'invisible': ['|', ('is_abandoned_cart', '=', False), ('cart_recovery_email_sent', '=', True)]}"/>
|
||||
</xpath>
|
||||
</filter>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_orders_ecommerce" model="ir.actions.act_window">
|
||||
<field name="name">Orders</field>
|
||||
<field name="res_model">sale.order</field>
|
||||
<field name="view_mode">tree,form,kanban,activity</field>
|
||||
<field name="path">ecommerce-orders</field>
|
||||
<field name="view_mode">list,form,kanban,activity</field>
|
||||
<field name="domain">[]</field>
|
||||
<field name="context">{'show_sale': True, 'search_default_order_confirmed': 1, 'search_default_from_website': 1}</field>
|
||||
<field name="search_view_id" ref="view_sales_order_filter_ecommerce"/>
|
||||
|
|
@ -81,7 +59,7 @@
|
|||
<record id="action_unpaid_orders_ecommerce" model="ir.actions.act_window">
|
||||
<field name="name">Unpaid Orders</field>
|
||||
<field name="res_model">sale.order</field>
|
||||
<field name="view_mode">tree,form,kanban,activity</field>
|
||||
<field name="view_mode">list,form,kanban,activity</field>
|
||||
<field name="domain">[('state', '=', 'sent'), ('website_id', '!=', False)]</field>
|
||||
<field name="context">{'show_sale': True, 'create': False}</field>
|
||||
<field name="search_view_id" ref="view_sales_order_filter_ecommerce"/>
|
||||
|
|
@ -95,7 +73,7 @@
|
|||
</record>
|
||||
|
||||
<record id="view_sales_order_filter_ecommerce_abondand" model="ir.ui.view">
|
||||
<field name="name">sale.order.ecommerce.abondand.view</field>
|
||||
<field name="name">sale.order.ecommerce.abandonned.view</field>
|
||||
<field name="model">sale.order</field>
|
||||
<field name="priority">32</field>
|
||||
<field name="arch" type="xml">
|
||||
|
|
@ -105,13 +83,13 @@
|
|||
<separator/>
|
||||
<filter string="Recovery Email to Send" name="recovery_email" domain="[('cart_recovery_email_sent', '=', False)]" />
|
||||
<filter string="Recovery Email Sent" name="recovery_email_set" domain="[('cart_recovery_email_sent', '=', True)]" />
|
||||
<group expand="0" string="Group By">
|
||||
<filter string="Order Date" name="order_date" domain="[]" context="{'group_by':'date_order'}"/>
|
||||
<group>
|
||||
<filter string="Order Date" name="order_date" context="{'group_by':'date_order'}"/>
|
||||
</group>
|
||||
<!-- Dashboard filter - used by context -->
|
||||
<filter string="Last Week" invisible="1" name="week" domain="[('date_order','>', (context_today() - datetime.timedelta(days=7)).strftime('%Y-%m-%d'))]"/>
|
||||
<filter string="Last Month" invisible="1" name="month" domain="[('date_order','>', (context_today() - datetime.timedelta(days=30)).strftime('%Y-%m-%d'))]"/>
|
||||
<filter string="Last Year" invisible="1" name="year" domain="[('date_order','>', (context_today() - datetime.timedelta(days=365)).strftime('%Y-%m-%d'))]"/>
|
||||
<filter string="Last Week" invisible="1" name="week" domain="[('date_order','>', 'today -7d')]"/>
|
||||
<filter string="Last Month" invisible="1" name="month" domain="[('date_order','>', 'today -30d')]"/>
|
||||
<filter string="Last Year" invisible="1" name="year" domain="[('date_order','>', 'today -365d')]"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
|
@ -120,8 +98,8 @@
|
|||
<record id="sale_order_action_to_invoice" model="ir.actions.act_window">
|
||||
<field name="name">Orders To Invoice</field>
|
||||
<field name="res_model">sale.order</field>
|
||||
<field name="view_mode">tree,form,kanban</field>
|
||||
<field name="domain">[('state', 'in', ('sale', 'done')), ('order_line', '!=', False), ('invoice_status', '=', 'to invoice'), ('website_id', '!=', False)]</field>
|
||||
<field name="view_mode">list,form,kanban</field>
|
||||
<field name="domain">[('state', '=', 'sale'), ('order_line', '!=', False), ('invoice_status', '=', 'to invoice'), ('website_id', '!=', False)]</field>
|
||||
<field name="context">{'show_sale': True, 'search_default_order_confirmed': 1, 'create': False}</field>
|
||||
<field name="search_view_id" ref="view_sales_order_filter_ecommerce"/>
|
||||
<field name="help" type="html">
|
||||
|
|
@ -132,25 +110,14 @@
|
|||
</record>
|
||||
|
||||
<!-- Server action to send multiple recovery email-->
|
||||
<record id="ir_actions_server_sale_cart_recovery_email" model="ir.actions.server">
|
||||
<field name="name">Send a Cart Recovery Email</field>
|
||||
<field name="type">ir.actions.server</field>
|
||||
<field name="model_id" ref="model_sale_order"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">
|
||||
if records:
|
||||
action = records.action_recovery_email_send()
|
||||
</field>
|
||||
<field name="binding_model_id" ref="sale.model_sale_order"/>
|
||||
<field name="binding_view_types">list,form</field>
|
||||
</record>
|
||||
|
||||
<record id="action_view_unpaid_quotation_tree" model="ir.actions.act_window">
|
||||
<field name="name">Unpaid Orders</field>
|
||||
<field name="res_model">sale.order</field>
|
||||
<field name="view_mode">tree,kanban,form,activity</field>
|
||||
<field name="path">ecommerce-unpaid-orders</field>
|
||||
<field name="view_mode">list,kanban,form,activity</field>
|
||||
<field name="domain">[('state', '=', 'sent'), ('website_id', '!=', False)]</field>
|
||||
<field name="context" eval="{'show_sale': True, 'create': False}"/>
|
||||
<field name="context">{'show_sale': True, 'create': False}</field>
|
||||
<field name="view_id" ref="sale.view_quotation_tree"/>
|
||||
<field name="search_view_id" ref="view_sales_order_filter_ecommerce_unpaid"/>
|
||||
<field name="help" type="html">
|
||||
|
|
@ -165,7 +132,8 @@
|
|||
<record id="action_view_abandoned_tree" model="ir.actions.act_window">
|
||||
<field name="name">Abandoned Carts</field>
|
||||
<field name="res_model">sale.order</field>
|
||||
<field name="view_mode">tree,kanban,form,activity</field>
|
||||
<field name="path">ecommerce-abandoned-carts</field>
|
||||
<field name="view_mode">list,kanban,form,activity</field>
|
||||
<field name="domain">[('is_abandoned_cart', '=', 1)]</field>
|
||||
<field name="context" eval="{'show_sale': True, 'create': False, 'public_partner_id': ref('base.public_partner'), 'search_default_recovery_email': True}"/>
|
||||
<field name="view_id" ref="sale.view_quotation_tree"/>
|
||||
|
|
@ -182,83 +150,31 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Main website sale menu items -->
|
||||
<menuitem id="menu_ecommerce" name="eCommerce"
|
||||
parent="website.menu_website_configuration" sequence="20"
|
||||
groups="sales_team.group_sale_salesman"/>
|
||||
<menuitem id="menu_orders" name="Orders"
|
||||
parent="menu_ecommerce" sequence="2"
|
||||
groups="sales_team.group_sale_salesman"/>
|
||||
<menuitem id="menu_catalog" name="Products"
|
||||
parent="menu_ecommerce" sequence="3"
|
||||
groups="sales_team.group_sale_salesman"/>
|
||||
|
||||
<menuitem id="menu_ecommerce_settings" name="eCommerce" sequence="50"
|
||||
parent="website.menu_website_global_configuration"/>
|
||||
|
||||
<!-- Orders sub-menus -->
|
||||
<menuitem id="menu_orders_orders" name="Orders"
|
||||
action="action_orders_ecommerce"
|
||||
parent="menu_orders" sequence="1"/>
|
||||
<menuitem id="menu_orders_unpaid_orders" name="Unpaid Orders"
|
||||
action="action_view_unpaid_quotation_tree"
|
||||
parent="menu_orders" sequence="2"/>
|
||||
<menuitem id="menu_orders_abandoned_orders" name="Abandoned Carts"
|
||||
action="action_view_abandoned_tree"
|
||||
parent="menu_orders" sequence="3"/>
|
||||
<menuitem id="menu_orders_customers" name="Customers"
|
||||
action="base.action_partner_customer_form"
|
||||
parent="menu_orders" sequence="4"/>
|
||||
|
||||
|
||||
<!-- Catalog sub-menus -->
|
||||
<menuitem id="menu_catalog_products" name="Products"
|
||||
action="product_template_action_website"
|
||||
parent="menu_catalog" sequence="1"/>
|
||||
<menuitem id="menu_catalog_pricelists" name="Pricelists"
|
||||
action="product.product_pricelist_action2"
|
||||
parent="menu_catalog" groups="product.group_product_pricelist" sequence="3"/>
|
||||
<menuitem id="menu_catalog_categories"
|
||||
action="product_public_category_action"
|
||||
parent="menu_catalog" sequence="4"/>
|
||||
<menuitem id="menu_product_attribute_action"
|
||||
action="product.attribute_action"
|
||||
parent="menu_catalog" groups="product.group_product_variant" sequence="5"/>
|
||||
<menuitem id="product_catalog_product_tags"
|
||||
name="Product Tags"
|
||||
action="product_public_tags_action"
|
||||
parent="menu_catalog"
|
||||
groups="base.group_no_one"
|
||||
/>
|
||||
|
||||
<!-- Reporting sub-menus -->
|
||||
<menuitem id="menu_report_sales" name="Online Sales"
|
||||
action="sale_report_action_dashboard"
|
||||
parent="website.menu_reporting" sequence="30"
|
||||
groups="sales_team.group_sale_manager"/>
|
||||
|
||||
<!-- Configuration sub-menus -->
|
||||
<menuitem id="menu_ecommerce_payment_providers"
|
||||
action="payment.action_payment_provider"
|
||||
parent="menu_ecommerce_settings" name="Payment Providers"/>
|
||||
<menuitem id="menu_ecommerce_payment_tokens"
|
||||
action="payment.action_payment_token"
|
||||
groups="base.group_no_one"
|
||||
parent="menu_ecommerce_settings"/>
|
||||
<menuitem id="menu_ecommerce_payment_icons"
|
||||
action="payment.action_payment_icon"
|
||||
groups="base.group_no_one"
|
||||
parent="menu_ecommerce_settings"/>
|
||||
<menuitem id="menu_ecommerce_payment_transactions"
|
||||
action="payment.action_payment_transaction"
|
||||
groups="base.group_no_one"
|
||||
parent="menu_ecommerce_settings"/>
|
||||
|
||||
<record id="sale_order_view_form" model="ir.ui.view">
|
||||
<field name="name">sale.order.form</field>
|
||||
<field name="model">sale.order</field>
|
||||
<field name="inherit_id" ref="sale.view_order_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<button name="action_quotation_send" id="quotation_send_primary" position="attributes">
|
||||
<attribute name="invisible" separator="or" add="is_abandoned_cart and not cart_recovery_email_sent"/>
|
||||
</button>
|
||||
<button name="action_quotation_send" position="after">
|
||||
<button
|
||||
name="action_recovery_email_send"
|
||||
type="object"
|
||||
string="Send a Recovery Email"
|
||||
class="btn-primary"
|
||||
data-hotkey="l"
|
||||
invisible="not is_abandoned_cart or cart_recovery_email_sent"/>
|
||||
</button>
|
||||
<button name="action_quotation_send" id="quotation_send" position="after">
|
||||
<button
|
||||
name="action_quotation_send"
|
||||
id="send_by_email_bis"
|
||||
string="Send by Email"
|
||||
type="object"
|
||||
invisible="not is_abandoned_cart or cart_recovery_email_sent or state != 'draft'"/>
|
||||
</button>
|
||||
<field name="partner_id" position="attributes">
|
||||
<attribute name="context">{
|
||||
'display_website': True,
|
||||
|
|
@ -268,30 +184,19 @@
|
|||
}</attribute>
|
||||
</field>
|
||||
<field name="team_id" position="after">
|
||||
<field name="website_id" attrs="{'invisible': [('website_id', '=', False)]}" groups="website.group_multi_website"/>
|
||||
<field name="website_id" invisible="not website_id" groups="website.group_multi_website"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_quotation_tree" model="ir.ui.view">
|
||||
<field name="name">sale.order.tree.inherit.website.sale</field>
|
||||
<record id="sale_order_tree" model="ir.ui.view">
|
||||
<field name="name">sale.order.list.inherit.website.sale</field>
|
||||
<field name="model">sale.order</field>
|
||||
<field name="inherit_id" ref="sale.view_quotation_tree"/>
|
||||
<field name="inherit_id" ref="sale.sale_order_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='user_id']" position="before">
|
||||
<field name="website_id" optional="hide"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_order_tree" model="ir.ui.view">
|
||||
<field name="name">sale.order.tree.inherit.website.sale</field>
|
||||
<field name="model">sale.order</field>
|
||||
<field name="inherit_id" ref="sale.view_order_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='partner_id']" position="before">
|
||||
<field name="website_id" optional="show"/>
|
||||
</xpath>
|
||||
<field name="user_id" position="before">
|
||||
<field name="website_id" groups="website.group_multi_website" optional="show"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
|
||||
<template id="sale_order_portal_content_inherit_website_sale" name="Orders Followup Products Links" inherit_id="sale.sale_order_portal_content">
|
||||
<div name="sol_table" position="attributes">
|
||||
<attribute name="class" remove="table-responsive" separator=" "/>
|
||||
</div>
|
||||
<span name="span_product_name" position="replace">
|
||||
<a t-if="line.product_id.website_published" t-att-href="line.product_id.website_url" class="d-block text-wrap" style="max-width: 35vw">
|
||||
<span t-field="line.name" />
|
||||
</a>
|
||||
<t t-if="not line.product_id.website_published">
|
||||
<span t-field="line.name" class="d-block text-wrap" style="max-width: 35vw"/>
|
||||
</t>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<template id="sale_order_re_order_btn" inherit_id="sale.sale_order_portal_template" name="Sale Order Order Again">
|
||||
<div id="print_invoice_sidebar_button" position="after">
|
||||
<t t-if="sale_order.with_user(request.env.user).sudo()._is_reorder_allowed()">
|
||||
<button
|
||||
id="reorder_sidebar_button"
|
||||
class="btn btn-secondary o_wsale_reorder_button oe_website_sale"
|
||||
t-att-data-sale-order-id="sale_order.id"
|
||||
>
|
||||
<i class="fa fa-rotate-right me-1"/>
|
||||
Order Again
|
||||
</button>
|
||||
</t>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="sale_report_view_search_website" model="ir.ui.view">
|
||||
<field name="name">sale.report.search</field>
|
||||
<field name="model">sale.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Sales">
|
||||
<field name="website_id" groups="website.group_multi_website"/>
|
||||
<field name="product_id"/>
|
||||
<field name="categ_id"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="country_id"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
<filter string="Confirmed Orders" name="confirmed" domain="[('state', 'in', ['sale', 'done'])]"/>
|
||||
<separator/>
|
||||
<filter name="filter_date" date="date" default_period="this_month"/>
|
||||
<group expand="0" string="Group By">
|
||||
<filter string="Website" name="groupby_website" context="{'group_by':'website_id'}" groups="website.group_multi_website"/>
|
||||
<filter string="Product" name="groupby_product" context="{'group_by':'product_id'}"/>
|
||||
<filter string="Product Category" name="groupby_product_category" context="{'group_by':'categ_id'}"/>
|
||||
<filter string="Customer" name="groupby_customer" context="{'group_by':'partner_id'}"/>
|
||||
<filter string="Customer Country" name="groupby_country" context="{'group_by':'country_id'}"/>
|
||||
<filter string="Status" name="groupby_status" context="{'group_by':'state'}"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter string="Order Date" name="groupby_order_date" context="{'group_by':'date'}"/>
|
||||
<!-- Dashboard filter - used by context -->
|
||||
<filter string="Last Week" invisible="1" name="week" domain="[('date','>=', (context_today() - datetime.timedelta(days=7)).strftime('%Y-%m-%d'))]"/>
|
||||
<filter string="Last Month" invisible="1" name="month" domain="[('date','>=', (context_today() - datetime.timedelta(days=30)).strftime('%Y-%m-%d'))]"/>
|
||||
<filter string="Last Year" invisible="1" name="year" domain="[('date','>=', (context_today() - datetime.timedelta(days=365)).strftime('%Y-%m-%d'))]"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="sale_report_view_pivot_website" model="ir.ui.view">
|
||||
<field name="name">sale.report.view.pivot.website</field>
|
||||
<field name="model">sale.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<pivot string="Sales Analysis" sample="1">
|
||||
<field name="date" type="row"/>
|
||||
<field name="state" type="col"/>
|
||||
<field name="price_subtotal" type="measure"/>
|
||||
</pivot>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="sale_report_view_graph_website" model="ir.ui.view">
|
||||
<field name="name">sale.report.view.graph.website</field>
|
||||
<field name="model">sale.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Sale Analysis" sample="1">
|
||||
<field name="date"/>
|
||||
<field name="price_subtotal" type='measure'/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="sale_report_view_tree" model="ir.ui.view">
|
||||
<field name="name">sale.report.view.tree.inherit.website.sale</field>
|
||||
<field name="model">sale.report</field>
|
||||
<field name="inherit_id" ref="sale.sale_report_view_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="order_id" position="after">
|
||||
<field name="website_id" optional="hide"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="sale_report_action_dashboard" model="ir.actions.act_window">
|
||||
<field name="name">Online Sales Analysis</field>
|
||||
<field name="res_model">sale.report</field>
|
||||
<field name="view_mode">pivot,graph</field>
|
||||
<field name="domain">[('website_id', '!=', False)]</field>
|
||||
<field name="context">{'search_default_confirmed': 1}</field>
|
||||
<field name="search_view_id" ref="sale_report_view_search_website"/>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_empty_folder">
|
||||
You don't have any order from the website
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="sale_report_action_view_pivot_website" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="view_mode">pivot</field>
|
||||
<field name="view_id" ref="sale_report_view_pivot_website"/>
|
||||
<field name="act_window_id" ref="sale_report_action_dashboard"/>
|
||||
</record>
|
||||
|
||||
<record id="sale_report_action_view_graph_website" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="view_mode">graph</field>
|
||||
<field name="view_id" ref="sale_report_view_graph_website"/>
|
||||
<field name="act_window_id" ref="sale_report_action_dashboard"/>
|
||||
</record>
|
||||
|
||||
<record id="sale_report_action_carts" model="ir.actions.act_window">
|
||||
<field name="name">Sales</field>
|
||||
<field name="res_model">sale.report</field>
|
||||
<field name="view_mode">pivot,graph</field>
|
||||
<field name="domain">[('website_id', '!=', False)]</field>
|
||||
<field name="search_view_id" ref="sale_report_view_search_website"/>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_empty_folder">
|
||||
You don't have any order from the website
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="sale_report_action_view_pivot_carts" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="view_mode">pivot</field>
|
||||
<field name="view_id" ref="sale_report_view_pivot_website"/>
|
||||
<field name="act_window_id" ref="sale_report_action_carts"/>
|
||||
</record>
|
||||
|
||||
<record id="sale_report_action_view_graph_carts" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="view_mode">graph</field>
|
||||
<field name="view_id" ref="sale_report_view_graph_website"/>
|
||||
<field name="act_window_id" ref="sale_report_action_carts"/>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
@ -1,50 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template name="Add to Cart Button" id="s_add_to_cart">
|
||||
<div class="s_add_to_cart">
|
||||
<button class="s_add_to_cart_btn disabled btn btn-secondary mb-2">
|
||||
<!--
|
||||
TODO: `.oe_website_sale` is used as a selector in `tracking.js`. This
|
||||
is a temporary solution to load the tracking utilities and will be removed once
|
||||
tracking utilities will be fully integrated into a service.
|
||||
-->
|
||||
<div class="s_add_to_cart oe_website_sale" data-action="add_to_cart">
|
||||
<button type="button" class="s_add_to_cart_btn disabled btn btn-secondary mb-2" data-action="add_to_cart">
|
||||
<i class="fa fa-cart-plus me-2"/>Add to Cart
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<template id="s_add_to_cart_options" inherit_id="website.snippet_options">
|
||||
<xpath expr="." position="inside">
|
||||
<div data-js="AddToCart"
|
||||
data-selector=".s_add_to_cart">
|
||||
<we-row>
|
||||
<we-many2one string="Product"
|
||||
data-model="product.template"
|
||||
data-set-product-template=""
|
||||
data-name="product_template_picker_opt"
|
||||
data-no-preview="true"
|
||||
data-domain='[["is_published", "=", true], ["sale_ok", "=", true]]'
|
||||
/>
|
||||
<we-button data-name="product_template_reset_opt"
|
||||
class="reset-product-picker align-self-end fa fa-fw fa-times">
|
||||
</we-button>
|
||||
</we-row>
|
||||
<we-row>
|
||||
<we-many2one-default-message string="Variant" class="o_we_sublevel_1"
|
||||
data-model="product.product"
|
||||
data-set-product-variant=""
|
||||
data-name="product_variant_picker_opt"
|
||||
data-no-preview="true"
|
||||
data-default-message="Visitor's Choice"
|
||||
/>
|
||||
<we-button data-name="product_variant_reset_opt"
|
||||
class="reset-variant-picker align-self-end fa fa-fw fa-times">
|
||||
</we-button>
|
||||
</we-row>
|
||||
<we-select data-name="action_picker_opt" string="Action" data-no-preview="true">
|
||||
<we-button data-set-action="add_to_cart">Add to Cart</we-button>
|
||||
<we-button data-set-action="buy_now">Buy Now</we-button>
|
||||
</we-select>
|
||||
</div>
|
||||
</xpath>
|
||||
</template>
|
||||
<record id="website_sale.s_add_to_cart_000_js" model="ir.asset">
|
||||
<field name="name">Add to Cart 000 JS</field>
|
||||
<field name="bundle">web.assets_frontend</field>
|
||||
<field name="path">website_sale/static/src/snippets/s_add_to_cart/000.js</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<template
|
||||
id="website_sale.s_dynamic_snippet_category_template"
|
||||
inherit_id="website.s_dynamic_snippet_template"
|
||||
primary="True"
|
||||
>
|
||||
<xpath expr="//section[contains(@t-attf-class, 's_dynamic_snippet_title')]/*" position="replace">
|
||||
<div>
|
||||
<h2 class="h3">Crafting Beautiful Spaces</h2>
|
||||
<p class="lead">Designing elegant, inviting environments that inspire and delight.</p>
|
||||
</div>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="s_dynamic_snippet_category_list" name="Category List">
|
||||
<t t-call="website_sale.s_dynamic_snippet_category_template">
|
||||
<t t-set="snippet_name" t-value="'s_dynamic_snippet_category_list'"/>
|
||||
<t
|
||||
t-set="snippet_classes"
|
||||
t-value="'oe_website_sale s_dynamic_category_clickable_items
|
||||
s_dynamic_snippet_category s_dynamic_category_no_arrows'"
|
||||
/>
|
||||
<t t-set="main_page_url" t-value="'/shop'"/>
|
||||
<t t-call="website_sale.s_dynamic_snippet_category_preview_data"/>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<template id="s_dynamic_snippet_category_preview_data" name="Category List Preview Data">
|
||||
<div
|
||||
class="o_category_container d-grid gap-2 rounded-2"
|
||||
contenteditable="false"
|
||||
style="--DynamicCategory-columns: 4; grid-auto-rows: minmax(5vh, auto);"
|
||||
>
|
||||
<div class="d-contents o_not_editable" contenteditable="false">
|
||||
<div
|
||||
class="s_dynamic_category_item bg-black position-relative overflow-hidden"
|
||||
role="article"
|
||||
style="grid-row: span 2;"
|
||||
>
|
||||
<img
|
||||
name="category_image"
|
||||
alt="Desks"
|
||||
class="o_category_image img-fluid position-absolute w-100 h-100 object-fit-cover"
|
||||
src="/website_sale/static/src/img/categories/desks.jpg"
|
||||
/>
|
||||
<div
|
||||
class="position-relative w-100 h-100 p-3 bg-black-25"
|
||||
>
|
||||
<h4 class="position-absolute start-50 top-50 translate-middle">Desks</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="s_dynamic_category_item bg-black position-relative overflow-hidden"
|
||||
role="article"
|
||||
style="grid-row: span 2;"
|
||||
>
|
||||
<img
|
||||
name="category_image"
|
||||
alt="Furnitures"
|
||||
class="o_category_image img-fluid position-absolute w-100 h-100 object-fit-cover"
|
||||
src="/website_sale/static/src/img/categories/furnitures.jpg"
|
||||
/>
|
||||
<div class="position-relative w-100 h-100 p-3 bg-black-25">
|
||||
<h4 class="position-absolute start-50 top-50 translate-middle">Furnitures</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="s_dynamic_category_item bg-black position-relative overflow-hidden"
|
||||
role="article"
|
||||
style="grid-row: span 2;"
|
||||
>
|
||||
<img
|
||||
name="category_image"
|
||||
alt="Boxes"
|
||||
class="o_category_image img-fluid position-absolute w-100 h-100 object-fit-cover"
|
||||
src="/website_sale/static/src/img/categories/boxes.jpg"
|
||||
/>
|
||||
<div class="position-relative w-100 h-100 p-3 bg-black-25">
|
||||
<h4 class="position-absolute start-50 top-50 translate-middle">Boxes</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="s_dynamic_category_item bg-black position-relative overflow-hidden"
|
||||
role="article"
|
||||
style="grid-row: span 2;"
|
||||
>
|
||||
<img
|
||||
name="category_image"
|
||||
alt="Drawers"
|
||||
class="o_category_image img-fluid position-absolute w-100 h-100 object-fit-cover"
|
||||
src="/website_sale/static/src/img/categories/drawers.jpg"
|
||||
/>
|
||||
<div class="position-relative w-100 h-100 p-3 bg-black-25">
|
||||
<h4 class="position-absolute start-50 top-50 translate-middle">Drawers</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="s_dynamic_category_item position-relative bg-black overflow-hidden"
|
||||
role="article"
|
||||
style="grid-row: span 2;"
|
||||
>
|
||||
<img
|
||||
name="category_image"
|
||||
alt="Cabinets"
|
||||
class="o_category_image img-fluid position-absolute w-100 h-100 object-fit-cover"
|
||||
src="/website_sale/static/src/img/categories/cabinets.jpg"
|
||||
/>
|
||||
<div class="position-relative w-100 h-100 p-3 bg-black-25">
|
||||
<h4 class="position-absolute start-50 top-50 translate-middle">Cabinets</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="s_dynamic_category_item position-relative bg-black overflow-hidden"
|
||||
role="article"
|
||||
style="grid-row: span 2;"
|
||||
>
|
||||
<img
|
||||
name="category_image"
|
||||
alt="Bins"
|
||||
class="o_category_image img-fluid position-absolute w-100 h-100 object-fit-cover"
|
||||
src="/website_sale/static/src/img/categories/bins.jpg"
|
||||
/>
|
||||
<div class="position-relative w-100 h-100 p-3 bg-black-25">
|
||||
<h4 class="position-absolute start-50 top-50 translate-middle">Bins</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="s_dynamic_category_item position-relative bg-black overflow-hidden"
|
||||
role="article"
|
||||
style="grid-row: span 2;"
|
||||
>
|
||||
<img
|
||||
name="category_image"
|
||||
alt="Lamps"
|
||||
class="o_category_image img-fluid position-absolute w-100 h-100 object-fit-cover"
|
||||
src="/website_sale/static/src/img/categories/lamps.jpg"
|
||||
/>
|
||||
<div class="position-relative w-100 h-100 p-3 bg-black-25">
|
||||
<h4 class="position-absolute start-50 top-50 translate-middle">Lamps</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="s_dynamic_category_item position-relative bg-black overflow-hidden"
|
||||
role="article"
|
||||
style="grid-row: span 2;"
|
||||
>
|
||||
<img
|
||||
name="category_image"
|
||||
alt="Services"
|
||||
class="o_category_image img-fluid position-absolute w-100 h-100 object-fit-cover"
|
||||
src="/website_sale/static/src/img/categories/services.jpg"
|
||||
/>
|
||||
<div class="position-relative w-100 h-100 p-3 bg-black-25">
|
||||
<h4 class="position-absolute start-50 top-50 translate-middle">Services</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</odoo>
|
||||
|
|
@ -1,46 +1,40 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<!-- Snippet -->
|
||||
<template id="s_dynamic_snippet_products" name="Products">
|
||||
<t t-call="website.s_dynamic_snippet_template">
|
||||
<t t-set="snippet_name" t-value="'s_dynamic_snippet_products'"/>
|
||||
|
||||
<t
|
||||
t-set="default_design_classes"
|
||||
t-value="request and request.env['website'].get_current_website().shop_opt_products_design_classes or ''"
|
||||
/>
|
||||
<t
|
||||
t-if="'o_wsale_products_opt_layout_catalog' not in default_design_classes"
|
||||
t-set="default_design_classes"
|
||||
t-value="'o_wsale_products_opt_name_color_regular
|
||||
o_wsale_products_opt_thumb_cover o_wsale_products_opt_img_secondary_show
|
||||
o_wsale_products_opt_img_hover_zoom_out_light o_wsale_products_opt_cc1
|
||||
o_wsale_products_opt_rounded_2 o_wsale_products_opt_layout_catalog
|
||||
o_wsale_products_opt_design_thumbs o_wsale_products_opt_has_description
|
||||
o_wsale_products_opt_name_size_body o_wsale_products_opt_actions_onhover
|
||||
o_wsale_products_opt_wishlist_fixed o_wsale_products_opt_actions_theme
|
||||
o_wsale_products_opt_has_cta'"
|
||||
/>
|
||||
<!--
|
||||
TODO: `.oe_website_sale` is used as a selector in `tracking.js`. This
|
||||
is a temporary solution to load the tracking utilities and will be removed once
|
||||
tracking utilities will be fully integrated into a service.
|
||||
-->
|
||||
<t
|
||||
t-set="snippet_classes"
|
||||
t-value="'oe_website_sale ' + default_design_classes"
|
||||
/>
|
||||
<t t-set="main_page_url" t-value="'/shop'"/>
|
||||
<t t-call="website_sale.s_dynamic_snippet_products_preview_data"/>
|
||||
</t>
|
||||
</template>
|
||||
<template id="s_dynamic_snippet_products_options" inherit_id="website.snippet_options">
|
||||
<xpath expr="." position="inside">
|
||||
<t t-call="website.dynamic_snippet_carousel_options_template">
|
||||
<t t-set="snippet_name" t-value="'dynamic_snippet_products'"/>
|
||||
<t t-set="snippet_selector" t-value="'.s_dynamic_snippet_products'"/>
|
||||
</t>
|
||||
</xpath>
|
||||
</template>
|
||||
<template id="s_dynamic_snippet_products_template_options" inherit_id="website.s_dynamic_snippet_options_template">
|
||||
<xpath expr="//we-select[@data-name='filter_opt']" position="after">
|
||||
<t t-if="snippet_name == 'dynamic_snippet_products'">
|
||||
<we-select string="Category" data-name="product_category_opt" data-attribute-name="productCategoryId" data-no-preview="true">
|
||||
<we-button data-select-data-attribute="all">All Products</we-button>
|
||||
<we-button data-select-data-attribute="current">Current Category or All</we-button>
|
||||
</we-select>
|
||||
<t t-set="domain" t-translation="off">["|", ["website_id", "=", false], ["website_id", "=", <t t-out="current_website.id"/>]]</t>
|
||||
<we-many2many string="Tags"
|
||||
data-name="product_tag_opt"
|
||||
data-attribute-name="productTagIds"
|
||||
data-no-preview="true"
|
||||
data-model="product.tag"
|
||||
t-att-data-domain="domain"
|
||||
data-allow-delete="true"
|
||||
data-fakem2m="true"
|
||||
data-select-data-attribute=""/>
|
||||
<we-input string="Product names" class="o_we_large" data-name="product_names_opt"
|
||||
data-attribute-name="productNames" data-no-preview="true" data-select-data-attribute=""
|
||||
placeholder="e.g. lamp,bin" title="Comma-separated list of parts of product names, barcodes or internal reference"/>
|
||||
</t>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<record id="website_sale.s_dynamic_snippet_products_000_js" model="ir.asset">
|
||||
<field name="name">Dynamic snippet products 000 JS</field>
|
||||
<field name="bundle">web.assets_frontend</field>
|
||||
<field name="path">website_sale/static/src/snippets/s_dynamic_snippet_products/000.js</field>
|
||||
</record>
|
||||
<!-- Multi record snippets (coming soon...) -->
|
||||
<!-- Single record snippets (coming soon...) -->
|
||||
|
||||
</odoo>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,95 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="s_dynamic_snippet_products_preview_data" name="Products Preview Data">
|
||||
<div class="carousel slide s_dialog_preview">
|
||||
<div class="carousel-inner row w-100 mx-auto">
|
||||
<div role="option" class="carousel-item active" style="min-height: 357.875px;">
|
||||
<div class="row">
|
||||
<div class="d-flex flex-grow-0 flex-shrink-0 col-3">
|
||||
<div class="o_carousel_product_card bg-transparent w-100 card border-0">
|
||||
<a class="o_carousel_product_img_link o_dynamic_product_hovered stretched-link" href="#">
|
||||
<div class="overflow-hidden rounded">
|
||||
<img class="card-img-top o_img_product_square o_img_product_cover h-auto" loading="lazy" src="/website_sale/static/src/img/product_previews/product_1.jpg"/>
|
||||
</div>
|
||||
</a>
|
||||
<div class="o_carousel_product_card_body d-flex flex-wrap flex-column justify-content-between h-100 p-3">
|
||||
<div class="h6 card-title">Three-Seat Sofa</div>
|
||||
<div>
|
||||
<div class="mt-2">
|
||||
<span class="fw-bold" name="product_price" data-oe-type="monetary" data-oe-expression="data['price']">
|
||||
<span class="oe_currency_value">1,500.00</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-grow-0 flex-shrink-0 col-3">
|
||||
<div class="o_carousel_product_card bg-transparent w-100 card border-0">
|
||||
<a class="o_carousel_product_img_link o_dynamic_product_hovered stretched-link" href="#">
|
||||
<div class="overflow-hidden rounded">
|
||||
<img class="card-img-top o_img_product_square o_img_product_cover h-auto" loading="lazy" src="/website_sale/static/src/img/product_previews/product_2.jpg" alt="Warranty (2 year)"/>
|
||||
</div>
|
||||
</a>
|
||||
<div class="o_carousel_product_card_body d-flex flex-wrap flex-column justify-content-between h-100 p-3">
|
||||
<div class="h6 card-title">Customizable Desk</div>
|
||||
<div>
|
||||
<div class="mt-2">
|
||||
<span class="fw-bold" name="product_price" data-oe-type="monetary" data-oe-expression="data['price']">
|
||||
<span class="oe_currency_value">750.00</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-grow-0 flex-shrink-0 col-3">
|
||||
<div class="o_carousel_product_card bg-transparent w-100 card border-0">
|
||||
<a class="o_carousel_product_img_link o_dynamic_product_hovered stretched-link" href="#">
|
||||
<div class="overflow-hidden rounded">
|
||||
<img class="card-img-top o_img_product_square o_img_product_cover h-auto" loading="lazy" src="/website_sale/static/src/img/product_previews/product_3.jpg" alt="Warranty (2 year)"/>
|
||||
</div>
|
||||
</a>
|
||||
<div class="o_carousel_product_card_body d-flex flex-wrap flex-column justify-content-between h-100 p-3">
|
||||
<div class="h6 card-title">Conference Chair</div>
|
||||
<div>
|
||||
<div class="mt-2">
|
||||
<span class="fw-bold" name="product_price" data-oe-type="monetary" data-oe-expression="data['price']">
|
||||
<span class="oe_currency_value">33.00</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-grow-0 flex-shrink-0 col-3">
|
||||
<div class="o_carousel_product_card bg-transparent w-100 card border-0">
|
||||
<a class="o_carousel_product_img_link o_dynamic_product_hovered stretched-link" href="#">
|
||||
<div class="overflow-hidden rounded">
|
||||
<img class="card-img-top o_img_product_square o_img_product_cover h-auto" loading="lazy" src="/website_sale/static/src/img/product_previews/product_4.jpg" alt="Warranty (2 year)"/>
|
||||
</div>
|
||||
</a>
|
||||
<div class="o_carousel_product_card_body d-flex flex-wrap flex-column justify-content-between h-100 p-3">
|
||||
<div class="h6 card-title">Cabinet with Doors</div>
|
||||
<div>
|
||||
<div class="mt-2">
|
||||
<span class="fw-bold" name="product_price" data-oe-type="monetary" data-oe-expression="data['price']">
|
||||
<span class="oe_currency_value">140.00</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a class="carousel-control-prev" data-bs-slide="prev" role="button" aria-label="Previous" title="Previous" href="#s_dynamic_snippet_1">
|
||||
<span class="fa fa-chevron-circle-left fa-2x"></span>
|
||||
</a>
|
||||
<a class="carousel-control-next" data-bs-slide="next" role="button" aria-label="Next" title="Next" href="#s_dynamic_snippet_1">
|
||||
<span class="fa fa-chevron-circle-right fa-2x"></span>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<template
|
||||
id="website_sale.s_mega_menu_big_icons_subtitles"
|
||||
name="eCommerce: Menu - Big icons & subtitles"
|
||||
groups="base.group_user"
|
||||
>
|
||||
<section
|
||||
class="s_mega_menu_big_icons_subtitles pt24 pb24 o_colored_level o_cc o_cc1"
|
||||
data-oe-shape-data="{'shape':'html_builder/Grids/07','colors':{'c5':'o-color-3'},'flip':[]}"
|
||||
>
|
||||
<div class="o_we_shape o_html_builder_Grids_07" style="background-image: url('/html_editor/shape/html_builder/Grids/07.svg?c5=o-color-3');"/>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<t
|
||||
t-foreach="request.env['product.public.category'].search([
|
||||
('parent_id', '=', False), ('has_published_products', '=', True),
|
||||
], limit=9)"
|
||||
t-as="category"
|
||||
>
|
||||
<div class="col-12 col-lg-4">
|
||||
<nav class="nav flex-column w-100">
|
||||
<a
|
||||
t-att-href="'/shop/category/%s' % category.id"
|
||||
class="col-lg-4 nav-link px-2 my-2 rounded text-wrap"
|
||||
>
|
||||
<div class="d-flex align-items-center">
|
||||
<img
|
||||
t-if="category.image_1920"
|
||||
t-att-src="image_data_uri(category.image_1920)"
|
||||
class="fa rounded rounded-circle shadow me-3"
|
||||
alt=""
|
||||
/>
|
||||
<div class="flex-grow-1">
|
||||
<h4 class="mt-0 mb-0" t-esc="category.name"/>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<template
|
||||
id="website_sale.s_mega_menu_cards"
|
||||
name="eCommerce: Menu - Cards"
|
||||
groups="base.group_user"
|
||||
>
|
||||
<section class="s_mega_menu_cards pt16 pb16 o_colored_level o_cc o_cc1">
|
||||
<div class="container">
|
||||
<nav class="row">
|
||||
<t
|
||||
t-foreach="request.env['product.public.category'].search([
|
||||
('parent_id', '=', False), ('has_published_products', '=', True),
|
||||
], limit=8)"
|
||||
t-as="category"
|
||||
>
|
||||
<div class="col-12 col-lg-3">
|
||||
<a
|
||||
t-att-href="'/shop/category/%s' % category.id"
|
||||
class="nav-link rounded text-wrap text-center p-3"
|
||||
>
|
||||
<div class="mb-3 rounded shadow" style="height:80px">
|
||||
<img
|
||||
t-if="category.image_1920"
|
||||
t-att-src="image_data_uri(category.image_1920)"
|
||||
class="img-fluid w-100 h-100 object-fit-cover"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
<h4 t-esc="category.name"/>
|
||||
</a>
|
||||
</div>
|
||||
</t>
|
||||
</nav>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<template
|
||||
id="website_sale.s_mega_menu_menu_image_menu"
|
||||
name="eCommerce: Menu - Image - Menu"
|
||||
groups="base.group_user"
|
||||
>
|
||||
<section class="s_mega_menu_menu_image_menu py-4 o_colored_level o_cc o_cc1">
|
||||
<div class="container">
|
||||
<div class="row align-items-center">
|
||||
<t
|
||||
t-foreach="request.env['product.public.category'].search(
|
||||
[('parent_id', '=', False), ('has_published_products', '=', True)],
|
||||
limit=2,
|
||||
)"
|
||||
t-as="category"
|
||||
>
|
||||
<div class="col-12 col-lg-4 py-2 text-center">
|
||||
<h4>
|
||||
<a
|
||||
t-att-href="'/shop/category/%s' % category.id"
|
||||
class="nav-link p-0 text-black"
|
||||
t-esc="category.name"
|
||||
/>
|
||||
</h4>
|
||||
<nav class="nav flex-column">
|
||||
<t t-foreach="category.child_id.filtered('has_published_products')"
|
||||
t-as="sub_category">
|
||||
<a
|
||||
t-att-href="'/shop/category/%s' % sub_category.id"
|
||||
class="nav-link"
|
||||
t-esc="sub_category.name"
|
||||
/>
|
||||
</t>
|
||||
</nav>
|
||||
</div>
|
||||
<div t-if="not category_last" class="col-12 col-lg-4 py-2 text-center">
|
||||
<img
|
||||
class="img-fluid"
|
||||
src="/web/image/website.s_mega_menu_menu_image_menu_default_image"
|
||||
alt="Mega menu default image"
|
||||
/>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<template
|
||||
id="website_sale.s_mega_menu_images_subtitles"
|
||||
name="eCommerce: Menu - images & subtitles"
|
||||
groups="base.group_user"
|
||||
>
|
||||
<section class="s_mega_menu_images_subtitles pt16 pb16 o_colored_level o_cc o_cc1">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-8">
|
||||
<nav class="nav d-flex">
|
||||
<t
|
||||
t-foreach="request.env['product.public.category'].search([
|
||||
('parent_id', '=', False), ('has_published_products', '=', True)
|
||||
], limit=8)"
|
||||
t-as="category"
|
||||
>
|
||||
<a
|
||||
t-att-href="'/shop/category/%s' % category.id"
|
||||
class="col-lg-6 nav-link px-2 rounded text-wrap"
|
||||
>
|
||||
<div class="d-flex">
|
||||
<img
|
||||
t-if="category.image_1920"
|
||||
t-att-src="image_data_uri(category.image_1920)"
|
||||
class="me-3 rounded shadow"
|
||||
alt=""
|
||||
/>
|
||||
<div class="flex-grow-1 align-content-center">
|
||||
<h4 class="mt-0 mb-0" t-esc="category.name"/>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</t>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="col-12 col-lg-4 py-2">
|
||||
<img src="/web/image/website.s_mega_menu_images_subtitles_default_image_7" class="mb-3 rounded shadow img-fluid" alt=""/>
|
||||
<h4>The team</h4>
|
||||
<p class="text-muted small">
|
||||
Created in 2021, the company is young and dynamic. Discover the composition of the team and their skills.
|
||||
</p>
|
||||
<a href="#" class="btn btn-primary">Discover our team</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<template
|
||||
id="website_sale.s_mega_menu_little_icons"
|
||||
name="eCommerce: Menu - Little icons"
|
||||
groups="base.group_user"
|
||||
>
|
||||
<section class="s_mega_menu_little_icons overflow-hidden o_colored_level o_cc o_cc1">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-9 py-2 align-content-center">
|
||||
<nav class="nav col-12 d-flex">
|
||||
<t
|
||||
t-foreach="request.env['product.public.category'].search([
|
||||
('parent_id', '=', False), ('has_published_products', '=', True)
|
||||
], limit=9)"
|
||||
t-as="category"
|
||||
>
|
||||
<a
|
||||
t-att-href="'/shop/category/%s' % category.id"
|
||||
class="col-lg-4 nav-link px-2 rounded text-wrap"
|
||||
>
|
||||
<img
|
||||
t-if="category.image_1920"
|
||||
t-att-src="image_data_uri(category.image_1920)"
|
||||
class="fa fa-fw me-2"
|
||||
alt=""
|
||||
/>
|
||||
<b t-esc="category.name"/>
|
||||
</a>
|
||||
</t>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="col-lg-3 p-4 s_mega_menu_gray_area">
|
||||
<h4>The team</h4>
|
||||
<p class="text-muted small">
|
||||
Created in 2021, the company is young and dynamic. Discover the composition of the team and their skills.
|
||||
</p>
|
||||
<a href="#" class="btn btn-primary">Discover our team</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<template
|
||||
id="website_sale.s_mega_menu_menus_logos"
|
||||
name="eCommerce: Menus & logos"
|
||||
groups="base.group_user"
|
||||
>
|
||||
<section class="s_mega_menu_menus_logos overflow-hidden o_colored_level o_cc o_cc1">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-8">
|
||||
<div class="row py-3 h-100">
|
||||
<t
|
||||
t-foreach="request.env['product.public.category'].search([
|
||||
('parent_id', '=', False), ('has_published_products', '=', True)
|
||||
], limit=6)"
|
||||
t-as="category"
|
||||
>
|
||||
<div class="col-12 col-lg-4 py-2">
|
||||
<h4>
|
||||
<a
|
||||
t-att-href="'/shop/category/%s' % category.id"
|
||||
class="col-lg-4 nav-link text-black p-0"
|
||||
t-esc="category.name"
|
||||
/>
|
||||
</h4>
|
||||
<nav class="nav flex-column">
|
||||
<t t-foreach="category.child_id.filtered('has_published_products')"
|
||||
t-as="sub_category">
|
||||
<a
|
||||
t-att-href="'/shop/category/%s' % sub_category.id"
|
||||
class="nav-link px-0"
|
||||
t-esc="sub_category.name"
|
||||
/>
|
||||
</t>
|
||||
</nav>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-4 py-4 d-flex align-items-center justify-content-center s_mega_menu_gray_area">
|
||||
<a href="#" class="nav-link text-center px-0" data-name="Menu Item">
|
||||
<img src="/web/image/website.s_mega_menu_menus_logos_default_image" class="mb-3 rounded shadow img-fluid" alt=""/>
|
||||
<h4>Spring collection has arrived!</h4>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="s_mega_menu_menus_logos_wrapper border-top">
|
||||
<div class="container">
|
||||
<div class="row py-3">
|
||||
<div class="col-4 col-lg-2">
|
||||
<img
|
||||
src="/web/image/website.s_mega_menu_menus_logos_default_logo_1"
|
||||
class="img-fluid"
|
||||
alt=""/>
|
||||
</div>
|
||||
<div class="col-4 col-lg-2">
|
||||
<img
|
||||
src="/web/image/website.s_mega_menu_menus_logos_default_logo_2"
|
||||
class="img-fluid"
|
||||
alt=""/>
|
||||
</div>
|
||||
<div class="col-4 col-lg-2">
|
||||
<img
|
||||
src="/web/image/website.s_mega_menu_menus_logos_default_logo_3"
|
||||
class="img-fluid"
|
||||
alt=""/>
|
||||
</div>
|
||||
<div class="col-4 col-lg-2">
|
||||
<img
|
||||
src="/web/image/website.s_mega_menu_menus_logos_default_logo_4"
|
||||
class="img-fluid"
|
||||
alt=""/>
|
||||
</div>
|
||||
<div class="col-4 col-lg-2">
|
||||
<img
|
||||
src="/web/image/website.s_mega_menu_menus_logos_default_logo_5"
|
||||
class="img-fluid"
|
||||
alt=""/>
|
||||
</div>
|
||||
<div class="col-4 col-lg-2">
|
||||
<img
|
||||
src="/web/image/website.s_mega_menu_menus_logos_default_logo_6"
|
||||
class="img-fluid"
|
||||
alt=""/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<template
|
||||
id="website_sale.s_mega_menu_multi_menus"
|
||||
name="eCommerce: Multi-Menus"
|
||||
groups="base.group_user"
|
||||
>
|
||||
<section class="s_mega_menu_multi_menus py-4 o_colored_level o_cc o_cc1">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<t
|
||||
t-foreach="request.env['product.public.category'].search([
|
||||
('parent_id', '=', False), ('has_published_products', '=', True),
|
||||
], limit=4)"
|
||||
t-as="category"
|
||||
>
|
||||
<div class="col-12 col-sm py-2 text-center">
|
||||
<h4>
|
||||
<a
|
||||
t-att-href="'/shop/category/%s' % category.id"
|
||||
class="nav-link p-0 text-black"
|
||||
t-esc="category.name"
|
||||
/>
|
||||
</h4>
|
||||
<nav class="nav flex-column">
|
||||
<t t-foreach="category.child_id.filtered('has_published_products')"
|
||||
t-as="sub_category">
|
||||
<a
|
||||
t-att-href="'/shop/category/%s' % sub_category.id"
|
||||
class="nav-link"
|
||||
t-esc="sub_category.name"
|
||||
/>
|
||||
</t>
|
||||
</nav>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<template
|
||||
id="website_sale.s_mega_menu_odoo_menu"
|
||||
name="eCommerce: Odoo Menu"
|
||||
groups="base.group_user"
|
||||
>
|
||||
<section class="s_mega_menu_odoo_menu pt16 o_colored_level o_cc o_cc1">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<t
|
||||
t-foreach="request.env['product.public.category'].search([
|
||||
('parent_id', '=', False), ('has_published_products', '=', True),
|
||||
], limit=4)"
|
||||
t-as="category"
|
||||
>
|
||||
<div class="col-12 col-lg-3 pt16 pb24">
|
||||
<h4 class="h5 fw-bold mt-0">
|
||||
<a
|
||||
t-att-href="'/shop/category/%s' % category.id"
|
||||
class="nav-link p-0 text-black"
|
||||
t-esc="category.name"
|
||||
/>
|
||||
</h4>
|
||||
<div class="s_hr pt4 pb16">
|
||||
<hr class="w-100 mx-auto"
|
||||
style="border-top-width: 2px; border-top-color: var(--primary);"
|
||||
/>
|
||||
</div>
|
||||
<nav class="nav flex-column">
|
||||
<t t-foreach="category.child_id.filtered('has_published_products')"
|
||||
t-as="sub_category">
|
||||
<a
|
||||
t-att-href="'/shop/category/%s' % sub_category.id"
|
||||
class="nav-link px-0"
|
||||
t-esc="sub_category.name"/>
|
||||
</t>
|
||||
</nav>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<template
|
||||
id="website_sale.s_mega_menu_thumbnails"
|
||||
name="eCommerce: Menu - Thumbnails"
|
||||
groups="base.group_user"
|
||||
>
|
||||
<section class="s_mega_menu_thumbnails pt24 o_colored_level o_cc o_cc1">
|
||||
<div class="container">
|
||||
<div class="row ustify-content-center">
|
||||
<t t-set="counter" t-value="0"/>
|
||||
<t
|
||||
t-foreach="request.env['product.public.category'].search([
|
||||
('parent_id', '=', False), ('has_published_products', '=', True),
|
||||
], limit=10)"
|
||||
t-as="category"
|
||||
>
|
||||
<t t-set="counter" t-value="counter + 1"/>
|
||||
<t t-if="(counter - 1) % 5 == 0 and counter != 1">
|
||||
<div class="w-100 d-none d-lg-block"></div>
|
||||
</t>
|
||||
<div class="col-6 col-lg-2 text-center py-2">
|
||||
<a
|
||||
t-att-href="'/shop/category/%s' % category.id"
|
||||
class="nav-link p-0"
|
||||
>
|
||||
<img
|
||||
t-if="category.image_1920"
|
||||
t-att-src="image_data_uri(category.image_1920)"
|
||||
class="img-fluid rounded shadow"
|
||||
alt=""
|
||||
/>
|
||||
<br/>
|
||||
<span class="d-block p-2 small">
|
||||
<b>
|
||||
<t t-esc="category.name"/>
|
||||
</b>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -3,346 +3,11 @@
|
|||
|
||||
<template id="snippets" inherit_id="website.snippets" name="e-commerce snippets">
|
||||
<xpath expr="//t[@id='sale_products_hook']" position="replace">
|
||||
<t t-snippet="website_sale.s_dynamic_snippet_products" string="Products" t-thumbnail="/website_sale/static/src/img/snippets_thumbs/s_dynamic_products.svg"/>
|
||||
<t t-snippet="website_sale.s_dynamic_snippet_products" string="Products" label="Dynamic Content" group="catalog"/>
|
||||
<t t-snippet="website_sale.s_dynamic_snippet_category_list" string="Category List" label="Dynamic Content" group="catalog"/>
|
||||
</xpath>
|
||||
<xpath expr="//t[@id='snippet_add_to_cart_hook']" position="replace">
|
||||
<t t-snippet="website_sale.s_add_to_cart" string="Add to Cart Button" t-thumbnail="/website/static/src/img/snippets_thumbs/s_add_to_cart.svg"/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="snippet_options" inherit_id="website.snippet_options" name="e-commerce snippet options">
|
||||
<xpath expr="." position="inside">
|
||||
<!-- All products page -->
|
||||
<div data-js="WebsiteSaleGridLayout" data-page-options="true" groups="website.group_website_designer" data-selector="main:has(.o_wsale_products_page)" data-no-check="true"
|
||||
string="Products Page" data-target="#products_grid .o_wsale_products_grid_table_wrapper > table">
|
||||
<we-select string="Layout" data-no-preview="true" data-reload="/">
|
||||
<we-button data-customize-website-views="" data-name="grid_view_opt">Grid</we-button>
|
||||
<we-button data-customize-website-views="website_sale.products_list_view">List</we-button>
|
||||
</we-select>
|
||||
<we-row string="Size" class="o_we_sublevel_1">
|
||||
<we-input data-set-ppg="" data-no-preview="true" data-reload="/"/>
|
||||
<span class="mx-2 o_wsale_ppr_by">by</span>
|
||||
<we-select class="o_wsale_ppr_submenu" data-dependencies="grid_view_opt" data-no-preview="true" data-reload="/">
|
||||
<we-button data-set-ppr="2">2</we-button>
|
||||
<we-button data-set-ppr="3">3</we-button>
|
||||
<we-button data-set-ppr="4">4</we-button>
|
||||
</we-select>
|
||||
</we-row>
|
||||
<we-select string="Style" class="o_we_sublevel_1">
|
||||
<we-button data-select-class=""
|
||||
data-customize-website-views="">
|
||||
Default
|
||||
</we-button>
|
||||
<we-button data-select-class="o_wsale_design_cards"
|
||||
data-customize-website-views="website_sale.products_design_card">
|
||||
Cards
|
||||
</we-button>
|
||||
<we-button data-select-class="o_wsale_design_thumbs"
|
||||
data-customize-website-views="website_sale.products_design_thumbs">
|
||||
Thumbnails
|
||||
</we-button>
|
||||
<we-button data-select-class="o_wsale_design_grid"
|
||||
data-customize-website-views="website_sale.products_design_grid">
|
||||
Grid
|
||||
</we-button>
|
||||
</we-select>
|
||||
<we-select string="Images Size" class="o_we_sublevel_1">
|
||||
<we-button data-select-class="o_wsale_context_thumb_4_3"
|
||||
data-customize-website-views="website_sale.products_thumb_4_3">
|
||||
Landscape (4/3)
|
||||
</we-button>
|
||||
<we-button data-select-class=""
|
||||
data-customize-website-views="">
|
||||
Default (1/1)
|
||||
</we-button>
|
||||
<we-button data-select-class="o_wsale_context_thumb_4_5"
|
||||
data-customize-website-views="website_sale.products_thumb_4_5">
|
||||
Portrait (4/5)
|
||||
</we-button>
|
||||
<we-button data-select-class="o_wsale_context_thumb_2_3"
|
||||
data-customize-website-views="website_sale.products_thumb_2_3">
|
||||
Vertical (2/3)
|
||||
</we-button>
|
||||
</we-select>
|
||||
<we-button-group string="Fill" class="o_we_sublevel_2" data-variable="thumb_size">
|
||||
<we-button data-select-class=""
|
||||
data-img="/website/static/src/img/snippets_options/content_width_normal.svg"
|
||||
data-customize-website-views="">
|
||||
</we-button>
|
||||
<we-button data-select-class="o_wsale_context_thumb_cover"
|
||||
data-name="thumb_cover"
|
||||
data-variable="thumb_cover"
|
||||
data-img="/website/static/src/img/snippets_options/content_width_full.svg"
|
||||
data-customize-website-views="website_sale.products_thumb_cover">
|
||||
</we-button>
|
||||
</we-button-group>
|
||||
<we-checkbox string="Prod. Desc."
|
||||
data-customize-website-views="website_sale.products_description"
|
||||
data-no-preview="true"
|
||||
data-reload="/"/>
|
||||
<we-row id="o_wsale_grid_left_panel" string="Categories" data-variable="filmstrip">
|
||||
<we-button string="Left"
|
||||
data-customize-website-views="website_sale.products_categories"
|
||||
data-name="categories_opt"
|
||||
data-no-preview="true"
|
||||
data-reload="/"/>
|
||||
<we-button string="Top"
|
||||
data-customize-website-views="website_sale.products_categories_top"
|
||||
data-name="categories_opt_top"
|
||||
data-no-preview="true"
|
||||
data-reload="/"/>
|
||||
</we-row>
|
||||
<we-checkbox id="collapse_category_recursive" string="Collapse Category Recursive"
|
||||
class="o_we_sublevel_1"
|
||||
data-customize-website-views="website_sale.option_collapse_products_categories"
|
||||
data-dependencies="categories_opt"
|
||||
data-no-preview="true"
|
||||
data-reload="/"/>
|
||||
<we-row string="Attributes" class="o_we_full_row">
|
||||
<we-button string="Left"
|
||||
data-customize-website-views="website_sale.products_attributes"
|
||||
data-name="attributes_opt"
|
||||
data-no-preview="true"
|
||||
data-reload="/"/>
|
||||
<we-button string="Top"
|
||||
data-customize-website-views="website_sale.products_attributes_top"
|
||||
data-name="attributes_opt_top"
|
||||
data-no-preview="true"
|
||||
data-reload="/"/>
|
||||
</we-row>
|
||||
<we-checkbox string="Price Filter"
|
||||
class="o_we_sublevel_1"
|
||||
data-customize-website-views="website_sale.filter_products_price"
|
||||
data-dependencies="attributes_opt, attributes_opt_top"
|
||||
data-no-preview="true"
|
||||
data-reload="/"/>
|
||||
<we-row string="Top Bar" class="o_we_full_row">
|
||||
<we-button string="Sort by"
|
||||
data-customize-website-views="website_sale.sort"
|
||||
data-no-preview="true"
|
||||
data-reload="/"/>
|
||||
<we-button string="Layout"
|
||||
data-customize-website-views="website_sale.add_grid_or_list_option"
|
||||
data-no-preview="true"
|
||||
data-reload="/"/>
|
||||
</we-row>
|
||||
<we-select string="Default Sort" class="o_wsale_sort_submenu" data-no-preview="true" data-reload="/">
|
||||
<t t-foreach="request.env['website']._get_product_sort_mapping()" t-as="query_and_label">
|
||||
<we-button t-att-data-set-default-sort="query_and_label[0]"><t t-esc="query_and_label[1]"/></we-button>
|
||||
</t>
|
||||
</we-select>
|
||||
<we-row string="Buttons" class="o_we_full_row">
|
||||
<we-button title="Add to Cart" class="fa fa-fw fa-shopping-cart o_we_add_to_cart_btn"
|
||||
data-customize-website-views="website_sale.products_add_to_cart"
|
||||
data-no-preview="true"
|
||||
data-reload="/"/>
|
||||
</we-row>
|
||||
</div>
|
||||
<!-- Product -->
|
||||
<div data-js="WebsiteSaleProductsItem"
|
||||
data-selector="#products_grid .oe_product"
|
||||
data-no-check="true">
|
||||
<div class="o_wsale_soptions_menu_sizes">
|
||||
<we-row string="Size">
|
||||
<table>
|
||||
<tr>
|
||||
<td/><td/><td/><td/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td/><td/><td/><td/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td/><td/><td/><td/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td/><td/><td/><td/>
|
||||
</tr>
|
||||
</table>
|
||||
</we-row>
|
||||
</div>
|
||||
|
||||
<we-row string="Re-order" data-no-preview="true">
|
||||
<we-button title="Push to top" data-change-sequence="top" class="fa fa-fw fa-angle-double-left"/>
|
||||
<we-button title="Push up" data-change-sequence="up" class="fa fa-fw fa-angle-left"/>
|
||||
<we-button title="Push down" data-change-sequence="down" class="fa fa-fw fa-angle-right"/>
|
||||
<we-button title="Push to bottom" data-change-sequence="bottom" class="fa fa-fw fa-angle-double-right"/>
|
||||
</we-row>
|
||||
|
||||
<we-row>
|
||||
<we-select string="Badge" class="o_wsale_ribbon_select">
|
||||
<we-button data-set-ribbon="" data-name="no_ribbon_opt">None</we-button>
|
||||
<!-- Ribbons are filled in JS -->
|
||||
</we-select>
|
||||
<we-button data-edit-ribbon="" title="Edit" class="fa fa-edit" data-no-preview="true" data-dependencies="!no_ribbon_opt"/>
|
||||
<we-button data-create-ribbon="" data-name="create_ribbon_opt" title="Create" class="fa fa-plus text-success" data-no-preview="true"/>
|
||||
</we-row>
|
||||
<div class="d-none" data-name="ribbon_customize_opt">
|
||||
<we-input string="Content" class="o_we_sublevel_1 o_we_large"
|
||||
data-set-ribbon-html="Badge Text" data-apply-to=".o_ribbon"/>
|
||||
<we-colorpicker string="Background" class="o_we_sublevel_1"
|
||||
title="" data-select-style="" data-css-property="background-color" data-color-prefix="bg-" data-apply-to=".o_ribbon"/>
|
||||
<we-colorpicker string="Text" class="o_we_sublevel_1"
|
||||
title="" data-select-style="" data-css-property="color" data-apply-to=".o_ribbon"/>
|
||||
<we-select string="Style" class="o_we_sublevel_1">
|
||||
<we-button data-set-ribbon-mode="ribbon">Slanted</we-button>
|
||||
<we-button data-set-ribbon-mode="tag">Tag</we-button>
|
||||
</we-select>
|
||||
<we-select string="Position" class="o_we_sublevel_1">
|
||||
<we-button data-set-ribbon-position="left">Left</we-button>
|
||||
<we-button data-set-ribbon-position="right">Right</we-button>
|
||||
</we-select>
|
||||
<we-row string=" ">
|
||||
<we-button class="o_we_bg_danger" data-delete-ribbon="" data-no-preview="true">Delete Badge</we-button>
|
||||
</we-row>
|
||||
</div>
|
||||
</div>
|
||||
<div data-selector="#wrapwrap > header"
|
||||
data-no-check="true"
|
||||
groups="website.group_website_designer">
|
||||
<we-checkbox string="Show Empty Cart"
|
||||
data-customize-website-views="website_sale.header_hide_empty_cart_link|"
|
||||
data-no-preview="true"
|
||||
data-reload="/"/>
|
||||
</div>
|
||||
<!-- Product image -->
|
||||
<div data-js="WebsiteSaleProductAttribute" data-selector="#product_detail .o_wsale_product_attribute" data-no-check="true">
|
||||
<we-select string="Display Type" data-no-preview="true">
|
||||
<we-button data-set-display-type="radio">Radio</we-button>
|
||||
<we-button data-set-display-type="pills">Pills</we-button>
|
||||
<we-button data-set-display-type="select">Select</we-button>
|
||||
<we-button data-set-display-type="color">Color</we-button>
|
||||
</we-select>
|
||||
</div>
|
||||
<!-- Product page -->
|
||||
<div data-js="WebsiteSaleProductPage" data-selector="main:has(.o_wsale_product_page)" data-page-options="true" groups="website.group_website_designer" data-no-check="true" string="Product Page">
|
||||
<we-row string="Customers" class="o_we_full_row">
|
||||
<we-button string="Rating"
|
||||
data-customize-website-views="website_sale.product_comment"
|
||||
data-no-preview="true"
|
||||
data-reload="/"/>
|
||||
<we-button string="Share"
|
||||
data-name="attributes_opt"
|
||||
data-customize-website-views="website_sale.product_share_buttons"
|
||||
data-no-preview="true"
|
||||
data-reload="/"/>
|
||||
</we-row>
|
||||
<we-checkbox string="Select Quantity"
|
||||
data-customize-website-views="website_sale.product_quantity"
|
||||
data-no-preview="true"
|
||||
data-reload="/"/>
|
||||
<we-checkbox string="Tax Indication"
|
||||
data-customize-website-views="website_sale.tax_indication"
|
||||
data-no-preview="true"
|
||||
data-reload="/"/>
|
||||
<we-select data-name="variants_opt" groups="product.group_product_variant" string="Variants" data-no-preview="true" data-reload="/">
|
||||
<we-button data-name="variants_options_opt" data-customize-website-views="">Options</we-button>
|
||||
<we-button data-name="variants_products_list_opt" data-customize-website-views="website_sale.product_variants">Products List</we-button>
|
||||
</we-select>
|
||||
<we-row string="Cart" class="o_we_full_row" data-name="o_wsale_buy_now_opt">
|
||||
<we-button title="Buy Now" class="o_we_buy_now_btn"
|
||||
data-customize-website-views="website_sale.product_buy_now"
|
||||
data-no-preview="true"
|
||||
data-reload="/">
|
||||
<i class="fa fa-fw fa-bolt"/>
|
||||
Buy Now
|
||||
</we-button>
|
||||
</we-row>
|
||||
<!-- Image config -->
|
||||
<we-button-group string="Images Width" data-no-preview="true" data-reload="/">
|
||||
<we-button data-set-image-width="none" data-img="/website_sale/static/src/img/snippet_options/image-width-none.svg" title="None"/>
|
||||
<we-button data-set-image-width="50_pc" data-img="/website_sale/static/src/img/snippet_options/image-width-50.svg" title="50 percent"/>
|
||||
<we-button data-set-image-width="66_pc" data-img="/website_sale/static/src/img/snippet_options/image-width-66.svg" title="66 percent"/>
|
||||
<we-button data-set-image-width="100_pc" data-img="/website_sale/static/src/img/snippet_options/image-width-100.svg" title="100 percent"/>
|
||||
</we-button-group>
|
||||
<we-select string="Layout" data-name="o_wsale_image_layout" data-no-preview="true" data-reload="/">
|
||||
<we-button data-set-image-layout="carousel">Carousel</we-button>
|
||||
<we-button data-set-image-layout="grid">Grid</we-button>
|
||||
</we-select>
|
||||
<we-select string="Image Zoom" class="o_we_sublevel_1" data-name="o_wsale_zoom_mode" data-no-preview="true" data-reload="/">
|
||||
<we-button data-name="o_wsale_zoom_hover" data-customize-website-views="website_sale.product_picture_magnify_hover">Magnifier on hover</we-button>
|
||||
<we-button data-name="o_wsale_zoom_click" data-customize-website-views="website_sale.product_picture_magnify_click">Pop-up on Click</we-button>
|
||||
<we-button data-name="o_wsale_zoom_both" data-customize-website-views="website_sale.product_picture_magnify_both">Both</we-button>
|
||||
<we-button data-name="o_wsale_zoom_none" data-customize-website-views="">None</we-button>
|
||||
</we-select>
|
||||
<!-- Carousel config -->
|
||||
<we-button-group string="Thumbnails" class="o_we_sublevel_1" data-name="o_wsale_thumbnail_pos" data-no-preview="true" data-reload="/">
|
||||
<we-button class="fa fa-fw fa-long-arrow-left" title="Left" data-customize-website-views="website_sale.carousel_product_indicators_left"/>
|
||||
<we-button class="fa fa-fw fa-long-arrow-down" title="Bottom" data-customize-website-views="website_sale.carousel_product_indicators_bottom"/>
|
||||
</we-button-group>
|
||||
<!-- Grid config -->
|
||||
<we-range string="Image Spacing" class="o_we_sublevel_1" data-name="o_wsale_grid_spacing" data-no-preview="true" data-reload="/" data-max="3" data-step="1" data-set-spacing=""/>
|
||||
<we-select string="Columns" class="o_we_sublevel_1" data-name="o_wsale_grid_columns" data-no-preview="true" data-reload="/">
|
||||
<we-button data-set-columns="1">1</we-button>
|
||||
<we-button data-set-columns="2">2</we-button>
|
||||
<we-button data-set-columns="3">3</we-button>
|
||||
</we-select>
|
||||
<we-row string="Main image">
|
||||
<we-button class="o_we_bg_brand_primary" data-name="o_wsale_replace_main_image" data-replace-main-image="true" data-no-preview="true">Replace</we-button>
|
||||
</we-row>
|
||||
<we-row string="Extra Images">
|
||||
<we-button class="o_we_bg_success" data-name="o_wsale_add_extra_images" data-add-images="true" data-no-preview="true">Add</we-button>
|
||||
<we-button class="o_we_bg_danger" data-name="o_wsale_clear_extra_images" data-clear-images="true" data-no-preview="true">Remove all</we-button>
|
||||
</we-row>
|
||||
</div>
|
||||
<!-- Checkout page -->
|
||||
<div data-selector="main:has(.oe_website_sale .wizard)" data-page-options="true" groups="website.group_website_designer" data-no-check="true" string="Checkout Pages">
|
||||
<we-checkbox string="Extra Step Option"
|
||||
data-customize-website-views="website_sale.extra_info_option"
|
||||
data-no-preview="true"
|
||||
data-reload="/"/>
|
||||
<we-checkbox string="Suggested Accessories"
|
||||
data-customize-website-views="website_sale.suggested_products_list"
|
||||
data-no-preview="true"
|
||||
data-reload="/"/>
|
||||
<we-checkbox string="Promo Code"
|
||||
data-customize-website-views="website_sale.reduction_code"
|
||||
data-no-preview="true"
|
||||
data-reload="/"/>
|
||||
<we-checkbox string="Accept Terms & Conditions"
|
||||
data-customize-website-views="website_sale.payment_sale_note"
|
||||
data-no-preview="true"
|
||||
data-reload="/"/>
|
||||
<we-checkbox string="Show b2b Fields"
|
||||
data-customize-website-views="website_sale.address_b2b"
|
||||
data-no-preview="true"
|
||||
data-reload="/"/>
|
||||
</div>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="snippets_options_web_editor" inherit_id="web_editor.snippet_options" name="e-commerce base snippet options">
|
||||
<xpath expr="//div[@data-js='ReplaceMedia']" position="inside">
|
||||
<we-row string="Re-order">
|
||||
<we-button class="fa fa-fw fa-angle-double-left" data-no-preview="true" title="Move to first" data-set-position="first" data-name="media_wsale_resequence"/>
|
||||
<we-button class="fa fa-fw fa-angle-left" data-no-preview="true" title="Move to previous" data-set-position="left" data-name="media_wsale_resequence"/>
|
||||
<we-button class="fa fa-fw fa-angle-right" data-no-preview="true" title="Move to next" data-set-position="right" data-name="media_wsale_resequence"/>
|
||||
<we-button class="fa fa-fw fa-angle-double-right" data-no-preview="true" title="Move to last" data-set-position="last" data-name="media_wsale_resequence"/>
|
||||
</we-row>
|
||||
</xpath>
|
||||
<xpath expr="//div[@data-js='ReplaceMedia']/we-row" position="inside">
|
||||
<we-button class="o_we_bg_danger" data-remove-media="true" data-no-preview="true" data-name="media_wsale_remove">Remove</we-button>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="product_searchbar_input_snippet_options" inherit_id="website.searchbar_input_snippet_options" name="product search bar snippet options">
|
||||
<xpath expr="//div[@data-js='SearchBar']/we-select[@data-name='scope_opt']" position="inside">
|
||||
<we-button data-set-search-type="products" data-select-data-attribute="products" data-name="search_products_opt" data-form-action="/shop">Products</we-button>
|
||||
</xpath>
|
||||
<xpath expr="//div[@data-js='SearchBar']/we-select[@data-name='order_opt']" position="inside">
|
||||
<t t-foreach="request.env['website']._get_product_sort_mapping()" t-as="query_and_label">
|
||||
<!-- name asc is already part of the general sorting methods of this snippet. -->
|
||||
<we-button t-if="query_and_label[0] != 'name asc'" t-att-data-set-order-by="query_and_label[0]" t-att-data-select-data-attribute="query_and_label[0]" data-dependencies="search_products_opt"><t t-out="query_and_label[1]"/></we-button>
|
||||
</t>
|
||||
</xpath>
|
||||
<xpath expr="//div[@data-js='SearchBar']/div[@data-dependencies='limit_opt']" position="inside">
|
||||
<we-checkbox string="Description" data-dependencies="search_products_opt" data-select-data-attribute="true" data-attribute-name="displayDescription"
|
||||
data-apply-to=".search-query"/>
|
||||
<we-checkbox string="Category" data-dependencies="search_products_opt" data-select-data-attribute="true" data-attribute-name="displayExtraLink"
|
||||
data-apply-to=".search-query"/>
|
||||
<we-checkbox string="Price" data-dependencies="search_products_opt" data-select-data-attribute="true" data-attribute-name="displayDetail"
|
||||
data-apply-to=".search-query"/>
|
||||
<we-checkbox string="Image" data-dependencies="search_products_opt" data-select-data-attribute="true" data-attribute-name="displayImage"
|
||||
data-apply-to=".search-query"/>
|
||||
<t t-snippet="website_sale.s_add_to_cart" string="Add to Cart Button" t-thumbnail="/website/static/src/img/snippets_thumbs/s_add_to_cart.svg" t-grid-column-span="3"/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,54 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="website_sale.empty_cart_svg">
|
||||
<svg width="100%" height="100" viewBox="0 0 100 92" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<style>
|
||||
.heartBeat {
|
||||
animation: heartBeat 1.3s ease-in-out forwards;
|
||||
animation-delay: 0.75s;
|
||||
transform-origin: 80.5px 28.5px;
|
||||
}
|
||||
.tilt {
|
||||
animation: tilt 1s ease forwards;
|
||||
animation-delay: 0.75s;
|
||||
transform-origin: bottom left;
|
||||
}
|
||||
@keyframes heartBeat {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
14% {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
28% {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
42% {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
70% {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
@keyframes tilt {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
50% {
|
||||
transform: rotate(-7deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<path class="tilt" d="M40.3846 71.8461C40.3846 73.2211 39.8822 74.411 38.8774 75.4158C37.8726 76.4207 36.6827 76.9231 35.3077 76.9231C33.9327 76.9231 32.7428 76.4207 31.738 75.4158C30.7332 74.411 30.2308 73.2211 30.2308 71.8461C30.2308 70.4711 30.7332 69.2812 31.738 68.2764C32.7428 67.2716 33.9327 66.7692 35.3077 66.7692C36.6827 66.7692 37.8726 67.2716 38.8774 68.2764C39.8822 69.2812 40.3846 70.4711 40.3846 71.8461ZM75.9231 71.8461C75.9231 73.2211 75.4207 74.411 74.4159 75.4158C73.4111 76.4207 72.2212 76.9231 70.8462 76.9231C69.4712 76.9231 68.2812 76.4207 67.2764 75.4158C66.2716 74.411 65.7692 73.2211 65.7692 71.8461C65.7692 70.4711 66.2716 69.2812 67.2764 68.2764C68.2812 67.2716 69.4712 66.7692 70.8462 66.7692C72.2212 66.7692 73.4111 67.2716 74.4159 68.2764C75.4207 69.2812 75.9231 70.4711 75.9231 71.8461ZM81 28.6923V49C81 49.6346 80.7818 50.1965 80.3456 50.6857C79.9093 51.1749 79.3738 51.4591 78.7392 51.5384L37.3305 56.3774C37.6743 57.9639 37.8462 58.8894 37.8462 59.1538C37.8462 59.5769 37.5288 60.4231 36.8942 61.6923H73.3846C74.0721 61.6923 74.6671 61.9435 75.1695 62.4459C75.6719 62.9483 75.9231 63.5432 75.9231 64.2307C75.9231 64.9182 75.6719 65.5132 75.1695 66.0156C74.6671 66.518 74.0721 66.7692 73.3846 66.7692H32.7692C32.0817 66.7692 31.4868 66.518 30.9844 66.0156C30.482 65.5132 30.2308 64.9182 30.2308 64.2307C30.2308 63.9399 30.3365 63.5234 30.5481 62.9813C30.7596 62.4393 30.9712 61.9633 31.1827 61.5535C31.3942 61.1436 31.6785 60.6148 32.0355 59.9669C32.3924 59.3191 32.5974 58.9291 32.6502 58.7969L25.6298 26.1538H17.5385C16.851 26.1538 16.256 25.9026 15.7536 25.4002C15.2512 24.8978 15 24.3029 15 23.6154C15 22.9279 15.2512 22.3329 15.7536 21.8305C16.256 21.3281 16.851 21.0769 17.5385 21.0769H27.6923C28.1154 21.0769 28.4922 21.1628 28.8227 21.3347C29.1532 21.5066 29.4111 21.7115 29.5962 21.9495C29.7812 22.1875 29.9531 22.5114 30.1118 22.9213C30.2704 23.3311 30.3762 23.6749 30.4291 23.9525C30.482 24.2301 30.5547 24.6202 30.6472 25.1226C30.7398 25.625 30.7993 25.9687 30.8257 26.1538H78.4615C79.149 26.1538 79.744 26.405 80.2464 26.9074C80.7488 27.4098 81 28.0048 81 28.6923Z" fill="currentColor"/>
|
||||
<circle class="heartBeat" cx="80.5" cy="28.5" r="11.5" fill="var(--o-color-1, #D9D9D9)" stroke="var(--body-bg, #F5F5F5)" stroke-width="3"/>
|
||||
<path class="heartBeat" d="M81.0014 33.1662C80.2997 33.1662 79.6974 32.9886 79.1946 32.6335C78.6946 32.2756 78.3097 31.7599 78.0398 31.0866C77.7727 30.4105 77.6392 29.5966 77.6392 28.6449C77.642 27.6932 77.777 26.8835 78.044 26.2159C78.3139 25.5455 78.6989 25.0341 79.1989 24.6818C79.7017 24.3295 80.3026 24.1534 81.0014 24.1534C81.7003 24.1534 82.3011 24.3295 82.804 24.6818C83.3068 25.0341 83.6918 25.5455 83.9588 26.2159C84.2287 26.8864 84.3636 27.696 84.3636 28.6449C84.3636 29.5994 84.2287 30.4148 83.9588 31.0909C83.6918 31.7642 83.3068 32.2784 82.804 32.6335C82.304 32.9886 81.7031 33.1662 81.0014 33.1662ZM81.0014 31.8324C81.5469 31.8324 81.9773 31.5639 82.2926 31.027C82.6108 30.4872 82.7699 29.6932 82.7699 28.6449C82.7699 27.9517 82.6974 27.3693 82.5526 26.8977C82.4077 26.4261 82.2031 26.071 81.9389 25.8324C81.6747 25.5909 81.3622 25.4702 81.0014 25.4702C80.4588 25.4702 80.0298 25.7401 79.7145 26.2798C79.3991 26.8168 79.2401 27.6051 79.2372 28.6449C79.2344 29.3409 79.304 29.9261 79.446 30.4006C79.5909 30.875 79.7955 31.233 80.0597 31.4744C80.3239 31.7131 80.6378 31.8324 81.0014 31.8324Z" fill="var(--o-color-3, #000)"/>
|
||||
</svg>
|
||||
</template>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,245 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="variants">
|
||||
<t t-set="attribute_exclusions" t-value="product._get_attribute_exclusions(parent_combination)"/>
|
||||
<t
|
||||
t-set="has_configurable_attribute_line"
|
||||
t-value="any(ptal._is_configurable() for ptal in product.attribute_line_ids)"
|
||||
/>
|
||||
<ul
|
||||
t-attf-class="o_wsale_product_page_variants d-flex flex-column gap-4 list-unstyled js_add_cart_variants #{ul_class} #{'d-none' if not has_configurable_attribute_line else '' }"
|
||||
t-att-data-attribute-exclusions="json.dumps(attribute_exclusions)"
|
||||
>
|
||||
<t t-foreach="product.valid_product_template_attribute_line_ids" t-as="ptal">
|
||||
<t t-set="attribute" t-value="ptal.attribute_id"/>
|
||||
<t t-set="ptavs" t-value="ptal.product_template_value_ids._only_active()"/>
|
||||
<t t-set="single" t-value="len(ptavs) == 1"/>
|
||||
|
||||
<!-- Attributes selection is hidden if there is only one value available and it's not a custom value -->
|
||||
<li name="variant_attribute"
|
||||
t-att-data-attribute-id="attribute.id"
|
||||
t-att-data-attribute-name="attribute.name"
|
||||
t-att-data-attribute-display-type="attribute.display_type"
|
||||
t-attf-class="variant_attribute #{
|
||||
'd-none' if single
|
||||
and not ptavs[0].is_custom
|
||||
and not attribute.display_type == 'multi' else ''
|
||||
}">
|
||||
|
||||
<!-- Used to customize layout if the only available attribute value is custom -->
|
||||
<t t-set="single_and_custom" t-value="single and ptavs[0].is_custom"/>
|
||||
<h6 class="attribute_name mb-2">
|
||||
<span t-field="ptal.attribute_id.name"/>
|
||||
<span t-if="attribute.display_type in ['color', 'image']" class="text-muted">
|
||||
-
|
||||
<t
|
||||
t-set="active_ptavs"
|
||||
t-value="[ptav for ptav in ptavs if ptav in combination]"
|
||||
/>
|
||||
<t t-foreach="active_ptavs" t-as="ptav">
|
||||
<span class="attribute_value" name="attribute_value" t-field="ptav.name"/>
|
||||
</t>
|
||||
</span>
|
||||
</h6>
|
||||
|
||||
<t t-if="attribute.display_type == 'select'">
|
||||
<select
|
||||
t-att-data-attribute-id="attribute.id"
|
||||
t-attf-class="form-select css_attribute_select o_wsale_product_attribute js_variant_change #{attribute.create_variant} #{'d-none' if single_and_custom else ''}"
|
||||
t-att-name="'ptal-%s' % ptal.id">
|
||||
<t t-foreach="ptavs" t-as="ptav">
|
||||
<option t-att-value="ptav.id"
|
||||
t-att-data-attribute-value-id="ptav.product_attribute_value_id.id"
|
||||
t-att-data-value-id="ptav.id"
|
||||
t-att-data-value-name="ptav.name"
|
||||
t-att-data-attribute-name="attribute.name"
|
||||
t-att-data-is-custom="ptav.is_custom"
|
||||
t-att-selected="ptav in combination">
|
||||
<span t-field="ptav.name"/>
|
||||
<t t-call="website_sale.badge_extra_price"/>
|
||||
</option>
|
||||
</t>
|
||||
</select>
|
||||
</t>
|
||||
|
||||
<t t-elif="attribute.display_type in ('radio', 'multi')">
|
||||
<ul
|
||||
t-att-data-attribute-id="attribute.id"
|
||||
t-attf-class="o_wsale_product_attribute d-flex flex-wrap gap-3 list-unstyled #{'d-none' if single_and_custom else ''}"
|
||||
>
|
||||
<t t-foreach="ptavs" t-as="ptav">
|
||||
<li class="js_attribute_value">
|
||||
<label class="col-form-label p-0">
|
||||
<div class="form-check cursor-pointer">
|
||||
<input t-att-type="'radio' if attribute.display_type == 'radio' else 'checkbox'"
|
||||
t-attf-class="form-check-input js_variant_change #{attribute.create_variant}"
|
||||
t-att-checked="ptav in combination"
|
||||
t-att-title="ptav.name"
|
||||
t-att-name="'ptal-%s' % ptal.id"
|
||||
t-att-value="ptav.id"
|
||||
t-att-data-attribute-value-id="ptav.product_attribute_value_id.id"
|
||||
t-att-data-value-id="ptav.id"
|
||||
t-att-data-value-name="ptav.name"
|
||||
t-att-data-attribute-name="attribute.name"
|
||||
t-att-data-is-custom="ptav.is_custom"/>
|
||||
<div class="radio_input_value form-check-label">
|
||||
<span t-field="ptav.name"/>
|
||||
<t t-call="website_sale.badge_extra_price"/>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
</t>
|
||||
|
||||
<t t-elif="attribute.display_type == 'pills'">
|
||||
<ul
|
||||
t-att-data-attribute-id="attribute.id"
|
||||
t-attf-class="o_wsale_product_attribute d-flex flex-wrap list-unstyled gap-2 #{'d-none' if single_and_custom else ''}"
|
||||
data-bs-toggle="buttons"
|
||||
>
|
||||
<t t-foreach="ptavs" t-as="ptav">
|
||||
<li t-attf-class="o_variant_pills js_attribute_value border btn m-0 cursor-pointer #{'active border-primary text-primary-emphasis bg-primary-subtle' if ptav in combination else ''}">
|
||||
<input type="radio"
|
||||
t-attf-class="js_variant_change position-absolute #{attribute.create_variant} opacity-0 cursor-pointer"
|
||||
t-att-checked="ptav in combination"
|
||||
t-att-name="'ptal-%s' % ptal.id"
|
||||
t-att-value="ptav.id"
|
||||
t-att-data-value-id="ptav.id"
|
||||
t-att-id="ptav.id"
|
||||
t-att-data-attribute-value-id="ptav.product_attribute_value_id.id"
|
||||
t-att-data-value-name="ptav.name"
|
||||
t-att-data-attribute-name="attribute.name"
|
||||
t-att-data-is-custom="ptav.is_custom"
|
||||
t-att-autocomplete="off"/>
|
||||
<label class="radio_input_value o_variant_pills_input_value cursor-pointer"
|
||||
t-att-for="ptav.id">
|
||||
<span t-field="ptav.name"/>
|
||||
<t t-call="website_sale.badge_extra_price"/>
|
||||
</label>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
</t>
|
||||
|
||||
<t t-elif="attribute.display_type == 'color'">
|
||||
<ul
|
||||
t-att-data-attribute-id="attribute.id"
|
||||
t-attf-class="o_wsale_product_attribute d-flex flex-wrap gap-2 list-unstyled #{'d-none' if single_and_custom else ''}"
|
||||
>
|
||||
<li t-foreach="ptavs" t-as="ptav">
|
||||
<t t-set="img_style"
|
||||
t-value="'background: url(/web/image/product.template.attribute.value/%s/image); background-size: cover; ' % ptav.id if ptav.image else ''"
|
||||
/>
|
||||
<t t-set="color_style"
|
||||
t-value="'background:' + str(ptav.html_color or ptav.name if not ptav.is_custom else '')"
|
||||
/>
|
||||
<label t-attf-style="#{img_style or color_style}"
|
||||
t-attf-class="css_attribute_color cursor-pointer #{'active' if ptav in combination else ''} #{'custom_value' if ptav.is_custom else ''} #{'transparent' if (not ptav.is_custom and not ptav.html_color) else ''}"
|
||||
>
|
||||
<input type="radio"
|
||||
t-attf-class="js_variant_change cursor-pointer #{attribute.create_variant}"
|
||||
t-att-checked="ptav in combination"
|
||||
t-att-name="'ptal-%s' % ptal.id"
|
||||
t-att-value="ptav.id"
|
||||
t-att-title="ptav.name"
|
||||
t-att-data-attribute-value-id="ptav.product_attribute_value_id.id"
|
||||
t-att-data-value-id="ptav.id"
|
||||
t-att-data-value-name="ptav.name"
|
||||
t-att-data-attribute-name="attribute.name"
|
||||
t-att-data-is-custom="ptav.is_custom"/>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</t>
|
||||
|
||||
<t t-elif="attribute.display_type == 'image'">
|
||||
<ul
|
||||
t-att-data-attribute-id="attribute.id"
|
||||
t-attf-class="list-inline o_wsale_product_attribute #{'d-none' if single_and_custom else ''}"
|
||||
>
|
||||
<li t-foreach="ptavs" t-as="ptav" class="list-inline-item me-2 mb-2">
|
||||
<label
|
||||
name="o_wsale_attribute_image_selector"
|
||||
t-attf-style="#{'background-image: url(/web/image/product.template.attribute.value/%s/image); background-size:cover;' % ptav.id if ptav.image else ''}"
|
||||
t-attf-class="css_attribute_image oe_img_bg o_bg_img_center position-relative d-inline-block rounded-3 bg-body text-center cursor-pointer #{'active' if ptav in combination else ''} #{'custom_value' if ptav.is_custom else ''} #{'transparent' if (not ptav.is_custom and not ptav.html_color) else ''}"
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
t-attf-class="js_variant_change w-100 h-100 opacity-0 cursor-pointer #{attribute.create_variant}"
|
||||
t-att-checked="ptav in combination"
|
||||
t-att-name="'ptal-%s' % ptal.id"
|
||||
t-att-value="ptav.id"
|
||||
t-att-title="ptav.name"
|
||||
t-att-data-attribute-value-id="ptav.product_attribute_value_id.id"
|
||||
t-att-data-value-id="ptav.id"
|
||||
t-att-data-value-name="ptav.name"
|
||||
t-att-data-attribute-name="attribute.name"
|
||||
t-att-data-is-custom="ptav.is_custom"
|
||||
/>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</t>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
<ul
|
||||
t-if="product._has_multiple_uoms()"
|
||||
t-attf-class="o_wsale_product_page_variants d-flex flex-column gap-4 list-unstyled js_add_cart_variants mt-4 #{ul_class}"
|
||||
t-att-data-attribute-exclusions="json.dumps(attribute_exclusions)"
|
||||
>
|
||||
<!-- NOTE: the t-att-data-attribute-exclusions is only there to match existing events selectors -->
|
||||
<li>
|
||||
<!-- Separate template to reduce views duplication -->
|
||||
<t t-call="website_sale.packaging_title"/>
|
||||
<ul class="btn-group-toggle list-inline list-unstyled" data-bs-toggle="buttons">
|
||||
<t t-set="product_uoms" t-value="product._get_available_uoms()"/>
|
||||
<t t-foreach="product_uoms" t-as="uom">
|
||||
<t t-set="is_main_uom" t-value="uom.id == product.uom_id.id"/>
|
||||
<li t-attf-class="o_variant_pills border btn m-0 cursor-pointer #{'active border-primary text-primary-emphasis bg-primary-subtle' if is_main_uom else ''}">
|
||||
<input
|
||||
class="position-absolute opacity-0 cursor-pointer"
|
||||
type="radio"
|
||||
t-att-checked="is_main_uom"
|
||||
name="uom_id"
|
||||
t-att-value="uom.id"
|
||||
t-attf-id="uom-{{uom.id}}"
|
||||
t-att-autocomplete="off"/>
|
||||
<label class="radio_input_value cursor-pointer" t-attf-for="uom-{{uom.id}}">
|
||||
<span t-field="uom.name"/>
|
||||
</label>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
<template id="badge_extra_price" name="Badge Extra Price">
|
||||
<t t-set="price_extra" t-value="ptav._get_extra_price(combination_info)"/>
|
||||
<span t-if="price_extra" t-attf-class="{{'badge text-bg-primary' if attribute.display_type != 'pills' else 'small text-muted'}}">
|
||||
<!--
|
||||
price_extra is displayed as catalog price instead of
|
||||
price after pricelist because it is impossible to
|
||||
compute. Indeed, the pricelist rule might depend on the
|
||||
selected variant, so the price_extra will be different
|
||||
depending on the selected combination. The price of an
|
||||
attribute is therefore variable and it's not very
|
||||
accurate to display it.
|
||||
-->
|
||||
<t t-if="attribute.display_type in ['pills', 'select']">(</t><span class="sign_badge_price_extra"><t t-out="price_extra > 0 and '+' or '-'"/></span>
|
||||
<span
|
||||
t-out="abs(price_extra)"
|
||||
class="variant_price_extra"
|
||||
style="white-space: nowrap;"
|
||||
t-options='{
|
||||
"widget": "monetary",
|
||||
"display_currency": website.currency_id
|
||||
}'/><t t-if="attribute.display_type in ['pills', 'select']">)</t>
|
||||
</span>
|
||||
</template>
|
||||
<template id="website_sale.packaging_title" name="Packaging title">
|
||||
<h6 class="attribute_name mb-2">Packaging</h6>
|
||||
</template>
|
||||
</odoo>
|
||||
|
|
@ -1,9 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id='base_unit_action' model='ir.actions.act_window'>
|
||||
|
||||
<record id="base_unit_action" model="ir.actions.act_window">
|
||||
<field name="name">Base Units</field>
|
||||
<field name="res_model">website.base.unit</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_mode">list,form</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -1,93 +1,86 @@
|
|||
<?xml version="1.0"?>
|
||||
<odoo>
|
||||
|
||||
<record id="product_pages_tree_view" model="ir.ui.view">
|
||||
<field name="name">Product Pages Tree</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="priority">99</field>
|
||||
<field name="mode">primary</field>
|
||||
<field name="inherit_id" ref="product_template_view_tree_website_sale"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//tree" position="attributes">
|
||||
<attribute name="js_class">website_pages_list</attribute>
|
||||
<attribute name="type">object</attribute>
|
||||
<attribute name="action">open_website_url</attribute>
|
||||
</xpath>
|
||||
<record id="product_pages_tree_view" model="ir.ui.view">
|
||||
<field name="name">Product Pages List</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="priority">99</field>
|
||||
<field name="mode">primary</field>
|
||||
<field name="inherit_id" ref="product_template_view_tree_website_sale"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//list" position="attributes">
|
||||
<attribute name="js_class">website_pages_list</attribute>
|
||||
<attribute name="type">object</attribute>
|
||||
<attribute name="action">open_website_url</attribute>
|
||||
</xpath>
|
||||
|
||||
<field name="is_published" position="replace"/>
|
||||
<field name="is_published" position="replace"/>
|
||||
|
||||
<field name="default_code" position="attributes">
|
||||
<attribute name="optional">hide</attribute>
|
||||
</field>
|
||||
<field name="product_tag_ids" position="attributes">
|
||||
<attribute name="optional">hide</attribute>
|
||||
</field>
|
||||
<field name="standard_price" position="attributes">
|
||||
<attribute name="optional">hide</attribute>
|
||||
<field name="default_code" position="attributes">
|
||||
<attribute name="optional">hide</attribute>
|
||||
</field>
|
||||
<field name="product_tag_ids" position="attributes">
|
||||
<attribute name="optional">hide</attribute>
|
||||
</field>
|
||||
<field name="standard_price" position="attributes">
|
||||
<attribute name="optional">hide</attribute>
|
||||
</field>
|
||||
|
||||
<field name="name" position="after">
|
||||
<field name="website_url"/>
|
||||
</field>
|
||||
<xpath expr="//list">
|
||||
<field name="is_seo_optimized"/>
|
||||
<field name="is_published"/>
|
||||
|
||||
<field name="website_id" position="move"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<field name="name" position="after">
|
||||
<field name="website_url"/>
|
||||
</field>
|
||||
<xpath expr="//tree">
|
||||
<field name="is_seo_optimized"/>
|
||||
<field name="is_published"/>
|
||||
|
||||
<field name="website_id" position="move"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="product_pages_kanban_view" model="ir.ui.view">
|
||||
<field name="name">Product Pages Kanban</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="priority">99</field>
|
||||
<field name="mode">primary</field>
|
||||
<field name="inherit_id" ref="product_template_view_kanban_website_sale"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//kanban" position="attributes">
|
||||
<attribute name="js_class">website_pages_kanban</attribute>
|
||||
<attribute name="type">object</attribute>
|
||||
<attribute name="action">open_website_url</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//kanban" position="inside">
|
||||
<field name="website_url"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='name']" position="after">
|
||||
<div class="text-muted" t-if="record.website_id.value" groups="website.group_multi_website">
|
||||
<i class="fa fa-globe me-1" title="Website"/>
|
||||
<field name="website_id"/>
|
||||
</div>
|
||||
<div class="text-primary" t-esc="record.website_url.value"/>
|
||||
</xpath>
|
||||
<xpath expr="//div[hasclass('oe_kanban_details')]" position="inside">
|
||||
<div class="o_kanban_footer">
|
||||
<div class="position-absolute bottom-0 end-0 m-1">
|
||||
<t t-if="record.is_published.raw_value">Published </t>
|
||||
<t t-else="">Not Published </t>
|
||||
<field name="is_published" widget="boolean_toggle"/>
|
||||
<record id="product_pages_kanban_view" model="ir.ui.view">
|
||||
<field name="name">Product Pages Kanban</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="priority">99</field>
|
||||
<field name="mode">primary</field>
|
||||
<field name="inherit_id" ref="product_template_view_kanban_website_sale"/>
|
||||
<field name="arch" type="xml">
|
||||
<kanban position="attributes">
|
||||
<attribute name="js_class">website_pages_kanban</attribute>
|
||||
<attribute name="class" add="o_wsale_products_kanban" separator=" "/>
|
||||
<attribute name="type">object</attribute>
|
||||
<attribute name="action">open_website_url</attribute>
|
||||
</kanban>
|
||||
<xpath expr="//main/div/div" position="after">
|
||||
<div class="d-flex flex-column mb-1">
|
||||
<div class="text-muted" t-if="record.website_id.value" groups="website.group_multi_website">
|
||||
<i class="fa fa-globe me-1" title="Website"/>
|
||||
<field name="website_id"/>
|
||||
</div>
|
||||
<field class="text-primary" name="website_url"/>
|
||||
</div>
|
||||
</div>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</xpath>
|
||||
<xpath expr="//aside" position="after">
|
||||
<footer class="justify-content-end flex-grow-1">
|
||||
<field name="is_published" widget="boolean_toggle"/>
|
||||
<span t-if="record.is_published.raw_value">Published</span>
|
||||
<span t-else="">Not Published</span>
|
||||
</footer>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_product_pages_list" model="ir.actions.act_window">
|
||||
<field name="name">Product Pages</field>
|
||||
<field name="res_model">product.template</field>
|
||||
<field name="view_mode">tree,kanban</field>
|
||||
<field name="view_id" ref="product_pages_tree_view"/>
|
||||
<field name="view_ids" eval="[(5, 0, 0),
|
||||
(0, 0, {'view_mode': 'tree', 'sequence': 1, 'view_id': ref('product_pages_tree_view')}),
|
||||
(0, 0, {'view_mode': 'kanban', 'sequence': 2, 'view_id': ref('product_pages_kanban_view')}),
|
||||
]"/>
|
||||
<field name="context">{'create_action': 'website_sale.product_product_action_add'}</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_product_pages"
|
||||
parent="website.menu_content"
|
||||
sequence="30"
|
||||
name="Products"
|
||||
action="action_product_pages_list"/>
|
||||
<record id="action_product_pages_list" model="ir.actions.act_window">
|
||||
<field name="name">Product Pages</field>
|
||||
<field name="res_model">product.template</field>
|
||||
<field name="path">product-pages</field>
|
||||
<field name="view_mode">list,kanban</field>
|
||||
<field name="view_id" ref="product_pages_tree_view"/>
|
||||
<field name="view_ids" eval="[Command.clear(),
|
||||
Command.create({'view_mode': 'list', 'sequence': 1, 'view_id': ref('product_pages_tree_view')}),
|
||||
Command.create({'view_mode': 'kanban', 'sequence': 2, 'view_id': ref('product_pages_kanban_view')}),
|
||||
]"/>
|
||||
<field name="context">{'create_action': 'website_sale.product_product_action_add'}</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,128 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
|
||||
<menuitem id="menu_ecommerce"
|
||||
name="eCommerce"
|
||||
parent="website.menu_website_configuration"
|
||||
groups="sales_team.group_sale_salesman"
|
||||
sequence="20">
|
||||
|
||||
<menuitem id="menu_orders"
|
||||
name="Orders"
|
||||
sequence="2">
|
||||
|
||||
<menuitem id="menu_orders_orders"
|
||||
name="Orders"
|
||||
action="action_orders_ecommerce"
|
||||
sequence="1"/>
|
||||
<menuitem id="menu_orders_unpaid_orders"
|
||||
name="Unpaid Orders"
|
||||
action="action_view_unpaid_quotation_tree"
|
||||
sequence="2"/>
|
||||
<menuitem id="menu_orders_abandoned_orders"
|
||||
name="Abandoned Carts"
|
||||
action="action_view_abandoned_tree"
|
||||
sequence="3"/>
|
||||
<menuitem id="menu_orders_customers"
|
||||
name="Customers"
|
||||
action="base.action_partner_customer_form"
|
||||
sequence="4"/>
|
||||
|
||||
</menuitem>
|
||||
|
||||
<menuitem id="menu_catalog"
|
||||
name="Products"
|
||||
sequence="3">
|
||||
|
||||
<menuitem id="menu_catalog_products"
|
||||
name="Products"
|
||||
action="product_template_action_website"
|
||||
sequence="1"/>
|
||||
<menuitem id="menu_catalog_pricelists"
|
||||
name="Pricelists"
|
||||
action="product.product_pricelist_action2"
|
||||
groups="product.group_product_pricelist"
|
||||
sequence="3"/>
|
||||
<menuitem id="menu_catalog_categories"
|
||||
action="product_public_category_action"
|
||||
sequence="4"/>
|
||||
<menuitem id="menu_product_attribute_action"
|
||||
action="product.attribute_action"
|
||||
groups="product.group_product_variant"
|
||||
sequence="5"/>
|
||||
<menuitem
|
||||
id="menu_product_combos"
|
||||
name="Combo Choices"
|
||||
action="product.product_combo_action"
|
||||
sequence="6"
|
||||
/>
|
||||
<menuitem id="product_catalog_product_tags"
|
||||
name="Product Tags"
|
||||
action="product.product_tag_action"/>
|
||||
<menuitem
|
||||
id="product_catalog_product_ribbons"
|
||||
name="Product Ribbons"
|
||||
action="website_sale.product_ribbon_action"
|
||||
/>
|
||||
</menuitem>
|
||||
</menuitem>
|
||||
|
||||
<menuitem id="menu_ecommerce_settings"
|
||||
name="eCommerce"
|
||||
parent="website.menu_website_global_configuration"
|
||||
sequence="50">
|
||||
|
||||
<menuitem id="menu_ecommerce_payment_providers"
|
||||
name="Payment Providers"
|
||||
action="payment.action_payment_provider"
|
||||
sequence="10"
|
||||
/>
|
||||
<menuitem id="menu_ecommerce_payment_methods"
|
||||
action="payment.action_payment_method"
|
||||
name="Payment Methods"
|
||||
sequence="20"
|
||||
/>
|
||||
<menuitem id="menu_ecommerce_payment_tokens"
|
||||
action="payment.action_payment_token"
|
||||
groups="base.group_no_one"
|
||||
sequence="30"
|
||||
/>
|
||||
<menuitem id="menu_ecommerce_payment_transactions"
|
||||
action="payment.action_payment_transaction"
|
||||
groups="base.group_no_one"
|
||||
sequence="40"
|
||||
/>
|
||||
<menuitem id="menu_ecommerce_delivery"
|
||||
action="delivery.action_delivery_carrier_form"
|
||||
sequence="90"
|
||||
/>
|
||||
<menuitem id="menu_delivery_zip_prefix"
|
||||
action="delivery.action_delivery_zip_prefix_list"
|
||||
groups="base.group_no_one"
|
||||
sequence="100"
|
||||
/>
|
||||
<menuitem id="menu_product_feeds"
|
||||
action="website_sale.action_product_feeds"
|
||||
groups="website_sale.group_product_feed"
|
||||
sequence="150"
|
||||
/>
|
||||
|
||||
</menuitem>
|
||||
|
||||
<!-- Reporting sub-menus -->
|
||||
<menuitem id="menu_report_sales" name="Online Sales"
|
||||
action="sale_report_action_dashboard"
|
||||
parent="website.menu_reporting"
|
||||
groups="sales_team.group_sale_manager"
|
||||
sequence="30"/>
|
||||
|
||||
<menuitem id="menu_product_pages"
|
||||
name="Products"
|
||||
action="action_product_pages_list"
|
||||
parent="website.menu_content"
|
||||
sequence="30"/>
|
||||
|
||||
<record id="website.menu_website_dashboard" model="ir.ui.menu">
|
||||
<field name="group_ids" eval="[Command.link(ref('sales_team.group_sale_salesman'))]"/>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
@ -1,15 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!--product history-->
|
||||
<record id="website_sale_visitor_page_view_tree" model="ir.ui.view">
|
||||
<field name="name">website.track.view.tree</field>
|
||||
<field name="name">website.track.view.list</field>
|
||||
<field name="model">website.track</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Visitor Product Views History" create="0">
|
||||
<list string="Visitor Product Views History" create="0">
|
||||
<field name="visitor_id"/>
|
||||
<field name="product_id"/>
|
||||
<field name="visit_datetime"/>
|
||||
</tree>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
|
@ -26,9 +27,9 @@
|
|||
<record id="website_sale_visitor_product_action" model="ir.actions.act_window">
|
||||
<field name="name">Product Views History</field>
|
||||
<field name="res_model">website.track</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_mode">list</field>
|
||||
<field name="view_ids" eval="[(5, 0, 0),
|
||||
(0, 0, {'view_mode': 'tree', 'view_id': ref('website_sale_visitor_page_view_tree')}),
|
||||
(0, 0, {'view_mode': 'list', 'view_id': ref('website_sale_visitor_page_view_tree')}),
|
||||
(0, 0, {'view_mode': 'graph', 'view_id': ref('website_sale_visitor_page_view_graph')}),
|
||||
]"/>
|
||||
<field name="domain">[('visitor_id', '=', active_id), ('product_id', '!=', False)]</field>
|
||||
|
|
@ -44,15 +45,15 @@
|
|||
<field name="model">website.track</field>
|
||||
<field name="inherit_id" ref="website.website_visitor_page_view_search"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='url']" position="after">
|
||||
<field name="url" position="after">
|
||||
<field name="product_id"/>
|
||||
</xpath>
|
||||
<xpath expr="//filter[@name='type_url']" position="after">
|
||||
</field>
|
||||
<filter name="type_url" position="after">
|
||||
<filter string="Products" name="type_product" domain="[('product_id', '!=', False)]"/>
|
||||
</xpath>
|
||||
<xpath expr="//filter[@name='group_by_url']" position="after">
|
||||
</filter>
|
||||
<filter name="group_by_url" position="after">
|
||||
<filter string="Product" name="group_by_product" domain="[]" context="{'group_by': 'product_id'}"/>
|
||||
</xpath>
|
||||
</filter>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
|
@ -76,13 +77,13 @@
|
|||
</record>
|
||||
|
||||
<record id="website_sale_visitor_view_tree" model="ir.ui.view">
|
||||
<field name="name">website.visitor.view.tree</field>
|
||||
<field name="name">website.visitor.view.list</field>
|
||||
<field name="model">website.visitor</field>
|
||||
<field name="inherit_id" ref="website.website_visitor_view_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='page_ids']" position="after">
|
||||
<field name="page_ids" position="after">
|
||||
<field name="product_ids" widget="many2many_tags" string="Products"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
|
@ -91,24 +92,21 @@
|
|||
<field name="model">website.visitor</field>
|
||||
<field name="inherit_id" ref="website.website_visitor_view_kanban"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='page_ids']" position="after">
|
||||
<field name="country_id" position="after">
|
||||
<field name="product_ids"/>
|
||||
</xpath>
|
||||
<xpath expr="//div[@id='o_page_count']" position="after">
|
||||
<div id="o_product_count">Visited Products<span class="float-end fw-bold"><field name="product_count"/></span></div>
|
||||
</xpath>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- website track views -->
|
||||
<record id="website_sale_visitor_track_view_tree" model="ir.ui.view">
|
||||
<field name="name">website.track.view.tree</field>
|
||||
<field name="name">website.track.view.list</field>
|
||||
<field name="model">website.track</field>
|
||||
<field name="inherit_id" ref="website.website_visitor_track_view_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='url']" position="after">
|
||||
<field name="url" position="after">
|
||||
<field name="product_id"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
|
@ -117,9 +115,10 @@
|
|||
<field name="model">website.track</field>
|
||||
<field name="inherit_id" ref="website.website_visitor_track_view_graph"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='url']" position="after">
|
||||
<field name="url" position="after">
|
||||
<field name="product_id"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
|
|||
|
|
@ -1,20 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="view_website_sale_website_form" model="ir.ui.view">
|
||||
<field name="name">website_sale.website.form</field>
|
||||
<field name="model">website</field>
|
||||
<field name="inherit_id" ref="website.view_website_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//notebook" position="inside">
|
||||
<page string="Product Page Extra Fields" groups="base.group_no_one">
|
||||
<field name="shop_extra_field_ids" context="{'default_website_id': active_id}">
|
||||
<tree editable="bottom">
|
||||
<notebook position="inside">
|
||||
<page string="Product Page Extra Fields" name="page_product_page_extra_fields" groups="base.group_no_one">
|
||||
<field name="shop_extra_field_ids" context="{'default_website_id': id}">
|
||||
<list editable="bottom">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="field_id" required="1" options="{'no_create': True}"/>
|
||||
</tree>
|
||||
</list>
|
||||
</field>
|
||||
</page>
|
||||
</xpath>
|
||||
</notebook>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue