Initial commit: Sale packages

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

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="website_sale.FieldVideoPreview" owl="1">
<div class="ratio ratio-16x9 mt-2" t-if="props.value">
<t t-out="props.value"/>
</div>
</t>
</templates>

View file

@ -0,0 +1,169 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates>
<t t-extend="website.dashboard_header">
<t t-jquery="div.o_dashboard_common" t-operation="append">
<div class="col-12 o_box" t-if="widget.dashboards_data.sales.summary.order_unpaid_count || widget.dashboards_data.sales.summary.order_to_invoice_count || widget.dashboards_data.sales.summary.payment_to_capture_count || widget.dashboards_data.sales.summary.order_carts_abandoned_count">
<div t-if="widget.dashboards_data.sales.summary.order_unpaid_count" class="o_inner_box o_dashboard_action" title="Confirm orders when you get paid." name="website_sale.action_unpaid_orders_ecommerce">
<div class="o_highlight"><t t-esc="widget.dashboards_data.sales.summary.order_unpaid_count"/></div>
Unpaid Orders
</div>
<div t-if="widget.dashboards_data.sales.summary.order_to_invoice_count" class="o_inner_box o_dashboard_action" title="Generate an invoice from orders ready for invoicing." name="website_sale.sale_order_action_to_invoice">
<div class="o_highlight"><t t-esc="widget.dashboards_data.sales.summary.order_to_invoice_count"/></div>
Orders to Invoice
</div>
<div t-if="widget.dashboards_data.sales.summary.payment_to_capture_count" class="o_inner_box o_dashboard_action" title="Capture order payments when the delivery is completed." name="website_sale.payment_transaction_action_payments_to_capture">
<div class="o_highlight"><t t-esc="widget.dashboards_data.sales.summary.payment_to_capture_count"/></div>
Payments to Capture
</div>
<div t-if="widget.dashboards_data.sales.summary.order_carts_abandoned_count" class="o_inner_box o_dashboard_action" title="Send a recovery email to visitors who haven't completed their order." name="website_sale.action_view_abandoned_tree">
<div class="o_highlight"><t t-esc="widget.dashboards_data.sales.summary.order_carts_abandoned_count"/></div>
Abandoned Carts
</div>
</div>
</t>
</t>
<t t-name="website_sale.dashboard_content" t-inherit="website.dashboard_content" t-inherit-mode="extension">
<xpath expr="//div[hasclass('o_website_dashboard_content')]/*[1]" position="before">
<div t-if="widget.groups.sale_salesman" class="row o_dashboard_sales">
<div class="col-12 row o_box">
<t t-if="widget.dashboards_data.sales.summary.order_count">
<h2 class="col-lg-7 col-12">
<t t-if="widget.date_range=='week'">
Sales Since Last Week
</t>
<t t-elif="widget.date_range=='month'">
Sales Since Last Month
</t>
<t t-elif="widget.date_range=='year'">
Sales Since Last Year
</t>
<t t-else="">Sales</t>
</h2>
<h4 class='col-lg-5 col-12'>AT A GLANCE</h4>
<div class="col-lg-7 col-12">
<div class="o_graph_sales" data-type="sales"/>
</div>
<div class="col-lg-5 col-12">
<t t-call="website_sale.products_table"/>
</div>
</t>
<t t-if="! widget.dashboards_data.sales.summary.order_count">
<t t-if="widget.date_range=='week'">
<h2>Sales Since Last Week</h2>
</t>
<t t-elif="widget.date_range=='month'">
<h2>Sales Since Last Month</h2>
</t>
<t t-elif="widget.date_range=='year'">
<h2>Sales Since Last Year</h2>
</t>
<t t-else=""><h2>Sales</h2></t>
<div class="col-lg-12 col-12">
<div class="o_demo_background">
</div>
<div class="o_demo_message">
<h3>There is no recent confirmed order.</h3>
</div>
</div>
</t>
</div>
</div>
</xpath>
</t>
<t t-name="website_sale.products_table">
<div class="row">
<a href="#" class="col-md-4 o_dashboard_action" name="website_sale.sale_report_action_dashboard">
<div class="o_link_enable" title="Orders">
<div class="o_highlight">
<t t-esc="widget.dashboards_data.sales.summary.order_count"/>
</div>
Orders
</div>
</a>
<a href="#" class="col-md-4 o_dashboard_action" name="website_sale.sale_report_action_dashboard">
<div class="o_link_enable" title="Untaxed Total Sold">
<div class="o_highlight">
<t t-esc="widget.render_monetary_field(widget.dashboards_data.sales.summary.total_sold, widget.data.currency)"/>
</div>
Sold
</div>
</a>
<a href="#" class="col-md-4 o_dashboard_action" name="website_sale.sale_report_action_carts">
<div class="o_link_enable o_invisible_border" title="Carts">
<div class="o_highlight"><t t-esc="widget.dashboards_data.sales.summary.order_carts_count"/></div>
Carts
</div>
</a>
<div class="col-md-4 o_link_disable" title="Orders/Day">
<div class="o_highlight"><t t-esc="widget.dashboards_data.sales.summary.order_per_day_ratio"/></div>
Orders/Day
</div>
<div class="col-md-4 o_link_disable" title="Average Order">
<div class="o_highlight"><t t-esc="widget.render_monetary_field(widget.dashboards_data.sales.summary.order_sold_ratio, widget.data.currency)"/></div>
Average Order
</div>
<div class="col-md-4 o_link_disable o_invisible_border" title="Conversion">
<div class="o_highlight"><t t-esc="widget.format_number(widget.dashboards_data.sales.summary.order_convertion_pctg, 'float', [3, 2], '%')"/></div>
Conversion
</div>
</div>
<div class="col-lg-12 col-12 o_top_margin">
<div class="row">
<div class="col-lg-12 col-12">
<h4>Best Sellers</h4>
<table class="table table-responsive table-hover">
<tr>
<th>Product</th>
<th>Quantity</th>
<th>Sold</th>
</tr>
<tr class="o_product_template" t-foreach="widget.dashboards_data.sales.best_sellers" t-as="product" t-att-data-product-id="product.id">
<td><t t-esc="product.name"/></td>
<td><t t-esc="product.qty"/></td>
<td><t t-esc="widget.render_monetary_field(product.sales, widget.data.currency)"/></td>
</tr>
</table>
</div>
</div>
</div>
</t>
<t t-extend="website_sale.products_table">
<t t-jquery=".o_top_margin .row .col-12" t-operation="attributes">
<attribute name="class" value="col-lg-6 col-12" />
</t>
<t t-jquery=".o_top_margin .row" t-operation="append">
<div class="col-lg-6 col-12 o_dashboard_utms">
<div>
<h4 class="float-start">REVENUE BY</h4>
<t t-call="website_sale.LinkTrackersDropDown"/>
</div>
<div class="o_utm_no_data_img">
<img src="website_sale/static/src/img/website_sale_chart_demo.png" alt="There isn't any UTM tag detected in orders" class="utm_chart_image image-responsive mt8"/>
</div>
<div class="o_utm_data_graph"/>
</div>
</t>
</t>
<t t-name="website_sale.LinkTrackersDropDown">
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle utm_dropdown ml4" type="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="true"><span class="utm_button_name">Campaigns</span>
</button>
<div class="dropdown-menu" role="menu" aria-labelledby="utm_dropdown">
<a name="campaign_id" class="dropdown-item js_utm_selector" role="menuitem">Campaigns</a>
<a name="medium_id" class="dropdown-item js_utm_selector" role="menuitem">Medium</a>
<a name="source_id" class="dropdown-item js_utm_selector" role="menuitem">Sources</a>
</div>
</div>
</t>
<!-- Show the date range buttons related to the 'community' Sales Dashboard -->
<t t-extend="website.DateRangeButtons">
<t t-jquery="t[t-set='show_range_buttons']" t-operation="attributes">
<attribute name="t-value" value="1" />
</t>
</t>
</templates>

View file

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates>
<t t-name="website_sale.ProductImageViewer" owl="1">
<div class="o_dialog" t-att-id="id" t-att-class="{ o_inactive_modal: !data.isActive }">
<div role="dialog" class="modal" t-ref="modalRef">
<div class="o_wsale_image_viewer flex-column align-items-center d-flex w-100 h-100" t-on-mousemove="onGlobalMousemove">
<!-- Header -->
<div class="o_wsale_image_viewer_header d-flex w-100 text-white">
<div class="flex-grow-1"/>
<div class="d-flex align-items-center mb-0 px-3 h4 text-reset cursor-pointer">
<span class="fa fa-times" t-on-click="data.close"/>
</div>
</div>
<!-- Content -->
<div class="o_wsale_image_viewer_image position-absolute top-0 bottom-0 start-0 end-0 align-items-center justify-content-center d-flex o_with_img overflow-hidden">
<div class="o_wsale_image_viewer_void position-absolute align-items-center justify-content-center d-flex w-100 h-100" t-ref="imageContainer" t-att-style="imageContainerStyle">
<img class="mw-100 mh-100 bg-black transition-base" t-att-src="selectedImage.src" draggable="false" alt="Viewer" t-att-style="imageStyle" t-on-wheel.stop="onWheelImage" t-on-mousedown="onMousedownImage"/>
</div>
</div>
<t t-if="images.length > 1">
<!-- Footer -->
<div class="o_wsale_image_viewer_carousel position-absolute bottom-0 d-flex" role="toolbar">
<ol class="d-flex justify-content-start ps-0 pt-2 pt-lg-0 mx-auto my-0 text-start">
<t t-foreach="images" t-as="image" t-key="image.thumbnailSrc">
<li t-attf-class="align-top position-relative px-1 pb-1 {{image === selectedImage ? 'active' : ''}}" t-on-click="() => this.selectedImage = image">
<div>
<img t-att-src="image.thumbnailSrc" t-attf-class="img o_wsale_image_viewer_thumbnail {{image === selectedImage ? 'active' : ''}}" t-att-alt="props.title" loading="lazy"/>
</div>
</li>
</t>
</ol>
</div>
<!-- Controls -->
<div class="o_wsale_image_viewer_control o_wsale_image_viewer_previous btn btn-dark position-absolute top-0 bottom-0 start-0 align-items-center justify-content-center d-flex my-auto ms-3 rounded-circle" t-on-click="previousImage" title="Previous (Left-Arrow)" role="button">
<span class="fa fa-chevron-left" role="img"/>
</div>
<div class="o_wsale_image_viewer_control o_wsale_image_viewer_next btn btn-dark position-absolute top-0 bottom-0 end-0 align-items-center justify-content-center d-flex my-auto me-3 rounded-circle" t-on-click="nextImage" title="Next (Right-Arrow)" role="button">
<span class="fa fa-chevron-right" role="img"/>
</div>
</t>
</div>
</div>
</div>
</t>
</templates>

View file

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates>
<t t-name="website_sale.ReorderModal" owl="1">
<Dialog title="env._t('Re-Order')">
<table id="o_wsale_reorder_table" class="table table-sm">
<thead class="bg-100">
<tr id="o_wsale_reorder_header">
<!-- Product Image -->
<th class="text-start td-img">Product</th>
<!-- Product name + description -->
<th/>
<!-- Product Quantity Selector -->
<th class="text-center td-qty">Quantity</th>
<!-- Product price (per unit) -->
<th class="text-end td-price">Price</th>
</tr>
</thead>
<tbody id="o_wsale_reorder_body" class="sale_tbody">
<t t-foreach="content.products" t-as="product" t-key="product_index">
<tr class="js_product">
<td t-if="product.has_image" class="td-img">
<img class="product_detail_img" t-att-alt="product.name" t-attf-src="/web/image/product.product/{{product.product_id}}/image_128"/>
</td>
<td t-att-colspan="product.has_image ? '1' : '2'">
<h5><t t-esc="product.name"/></h5>
<span class="text-muted d-none d-md-inline-block" t-if="product.description_sale" t-out="product.description_sale"/>
</td>
<t t-if="product.add_to_cart_allowed">
<td class="text-center td-qty">
<div class="css_quantity input-group input-group-sm justify-content-center">
<a href="#" class="btn btn-link d-none d-md-inline-block" aria-label="Remove one" title="Remove one" t-on-click.stop.prevent="() => this.changeProductQty(product, product.qty - 1)">
<i class="fa fa-minus"/>
</a>
<input type="text" class="js_quantity text-center form-control quantity" t-on-change="(ev) => this.onChangeProductQtyInput(ev, product)"
t-att-value="product.qty"/>
<a href="#" class="btn btn-link d-none d-md-inline-block" aria-label="Add one" title="Add one" t-on-click.stop.prevent="() => this.changeProductQty(product, product.qty + 1)">
<i class="fa fa-plus"/>
</a>
</div>
<div t-if="product.qty_warning and product.qty_warning !== ''" class="text-warning fw-bold">
<i class="fa fa-exclamation-triangle"/>
<span t-esc="product.qty_warning"/>
</div>
</td>
<td class="text-end td-price">
<span t-esc="formatMonetary(product.combinationInfo.price, content.currency)"/>
</td>
</t>
<t t-else="">
<td class="text-center" colspan="2">
<div class="text-warning fw-bold">
<i class="fa fa-exclamation-triangle"/>
<span t-esc="getWarningForProduct(product)"/>
</div>
</td>
</t>
</tr>
</t>
</tbody>
</table>
<div id="o_wsale_reorder_total" class="row" name="total" style="page-break-inside: avoid;">
<div class="col-sm-7 col-md-6 ms-auto">
<table class="table table-sm">
<tr class="border-black o_total">
<td>
<strong>Total</strong>
</td>
<td class="text-end">
<span t-out="formatMonetary(total, content.currency)"/>
</td>
</tr>
</table>
</div>
</div>
<t t-set-slot="footer">
<button class="btn btn-primary o_wsale_reorder_confirm" t-att-disabled="!hasBuyableProducts" t-on-click="confirmReorder">
Add To Cart
</button>
<button class="btn btn-secondary o_wsale_reorder_cancel" t-on-click.stop.prevent="props.close">
Discard
</button>
</t>
</Dialog>
</t>
<t t-name="website_sale.ReorderConfirmationDialog" t-inherit="web.ConfirmationDialog" t-inherit-mode="primary" owl="1">
<xpath expr="//button[1]" position="replace">
<button class="btn btn-primary" t-on-click="_confirm">
Yes
</button>
</xpath>
<xpath expr="//button[2]" position="replace">
<button class="btn btn-secondary" t-on-click="_cancel">
No
</button>
</xpath>
</t>
</templates>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<!-- Products Search Bar autocomplete item -->
<we-button t-name="website_sale.ribbonSelectItem" t-att-data-set-ribbon="ribbon.id">
<t t-out="ribbon.html"/>
<span t-attf-class="fa fa-#{isTag ? 'tag' : 'bookmark'} ms-auto"></span>
<span t-attf-class="fa fa-arrow-#{isLeft ? 'left' : 'right'} ms-1"></span>
<span t-attf-class="o_wsale_color_preview #{colorClasses} ms-1" t-attf-style="background-color: #{ribbon.bg_color}"></span>
<span t-attf-class="o_wsale_color_preview #{colorClasses} ms-1" t-attf-style="background-color: #{textColor} !important;"></span>
</we-button>
</templates>