Merge pull request #14 from bakeupboys/39-16.0-add_credit_to_webshop
[imp] add nfu_ecommerce module, add balance to cart
This commit is contained in:
commit
b8bb1e3596
46 changed files with 250 additions and 479 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
==========================
|
=============
|
||||||
NFU Sale Min Max Quantitiy
|
NFU eCommerce
|
||||||
==========================
|
=============
|
||||||
|
|
||||||
..
|
..
|
||||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
@ -17,12 +17,15 @@ NFU Sale Min Max Quantitiy
|
||||||
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
|
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
|
||||||
:alt: License: LGPL-3
|
:alt: License: LGPL-3
|
||||||
.. |badge3| image:: https://img.shields.io/badge/github-bruecksen%2Fife_nfu-lightgray.png?logo=github
|
.. |badge3| image:: https://img.shields.io/badge/github-bruecksen%2Fife_nfu-lightgray.png?logo=github
|
||||||
:target: https://github.com/bruecksen/ife_nfu/tree/16.0/nfu_sale_product_min_max_qty
|
:target: https://github.com/bruecksen/ife_nfu/tree/16.0/nfu_ecommerce
|
||||||
:alt: bruecksen/ife_nfu
|
:alt: bruecksen/ife_nfu
|
||||||
|
|
||||||
|badge1| |badge2| |badge3|
|
|badge1| |badge2| |badge3|
|
||||||
|
|
||||||
This module adds a minium and a maximum order quantity field to Sale Orders and adds it to checkout of the website shop.
|
This module adds a maximum order quantity field to Website Sale Orders. It also adds
|
||||||
|
an ordered qantitiy field to store the original ordered quantity in case a manager
|
||||||
|
adjustes the uom quantitiy. In webshop checkout it adds the customer balance to before
|
||||||
|
and after the current order.
|
||||||
|
|
||||||
**Table of contents**
|
**Table of contents**
|
||||||
|
|
||||||
|
|
@ -32,7 +35,7 @@ This module adds a minium and a maximum order quantity field to Sale Orders and
|
||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
:1.0.0: Initial module.
|
:0.0.1: Initial module.
|
||||||
|
|
||||||
Bug Tracker
|
Bug Tracker
|
||||||
===========
|
===========
|
||||||
|
|
@ -40,7 +43,7 @@ Bug Tracker
|
||||||
Bugs are tracked on `GitHub Issues <https://github.com/bruecksen/ife_nfu/issues>`_.
|
Bugs are tracked on `GitHub Issues <https://github.com/bruecksen/ife_nfu/issues>`_.
|
||||||
In case of trouble, please check there if your issue has already been reported.
|
In case of trouble, please check there if your issue has already been reported.
|
||||||
If you spotted it first, help us to smash it by providing a detailed and welcomed
|
If you spotted it first, help us to smash it by providing a detailed and welcomed
|
||||||
`feedback <https://github.com/bruecksen/ife_nfu/issues/new?body=module:%20nfu_sale_product_min_max_qty%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
|
`feedback <https://github.com/bruecksen/ife_nfu/issues/new?body=module:%20nfu_ecommerce%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
|
||||||
|
|
||||||
Do not contact contributors directly about support or help with technical issues.
|
Do not contact contributors directly about support or help with technical issues.
|
||||||
|
|
||||||
|
|
@ -61,6 +64,6 @@ Contributors
|
||||||
Maintainers
|
Maintainers
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
|
|
||||||
This module is part of the `bruecksen/ife_nfu <https://github.com/bruecksen/ife_nfu/tree/16.0/nfu_sale_product_min_max_qty>`_ project on GitHub.
|
This module is part of the `bruecksen/ife_nfu <https://github.com/bruecksen/ife_nfu/tree/16.0/nfu_ecommerce>`_ project on GitHub.
|
||||||
|
|
||||||
You are welcome to contribute.
|
You are welcome to contribute.
|
||||||
|
|
@ -1,3 +1,2 @@
|
||||||
from . import models
|
from . import models
|
||||||
from . import controllers
|
from . import controllers
|
||||||
from . import wizard
|
|
||||||
12
nfu_ecommerce/__manifest__.py
Normal file
12
nfu_ecommerce/__manifest__.py
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"name": "NFU eCommerce",
|
||||||
|
"summary": "Qty ranges, packagings and credit in webshop",
|
||||||
|
"author": "BAKEUP",
|
||||||
|
"website": "https://www.bakeup.org",
|
||||||
|
"category": "website",
|
||||||
|
"version": "16.0.0.0.1",
|
||||||
|
"depends": ["website_sale", "nfu_sale_order_batch_packaging"],
|
||||||
|
"data": ["views/templates.xml"],
|
||||||
|
"assets": {"web.assets_frontend": ["nfu_ecommerce/static/src/js/website_sale.js"]},
|
||||||
|
"license": "LGPL-3",
|
||||||
|
}
|
||||||
1
nfu_ecommerce/controllers/__init__.py
Normal file
1
nfu_ecommerce/controllers/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
from . import main
|
||||||
12
nfu_ecommerce/controllers/main.py
Normal file
12
nfu_ecommerce/controllers/main.py
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
from odoo import fields, http
|
||||||
|
|
||||||
|
from odoo.addons.website_sale.controllers.main import WebsiteSale
|
||||||
|
|
||||||
|
|
||||||
|
class WebsiteSaleMinMax(WebsiteSale):
|
||||||
|
@http.route()
|
||||||
|
def cart_update(self, *args, ordered_qty=None, max_qty=None, **kw):
|
||||||
|
"""Override to get ordered_qty and max_qty from the product."""
|
||||||
|
product_uom_ordered_qty = fields.Float(ordered_qty)
|
||||||
|
product_uom_max_qty = fields.Float(max_qty)
|
||||||
|
return super().cart_update(*args, ordered_qty=product_uom_ordered_qty, max_qty=product_uom_max_qty, **kw)
|
||||||
1
nfu_ecommerce/models/__init__.py
Normal file
1
nfu_ecommerce/models/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
from . import sale_order
|
||||||
49
nfu_ecommerce/models/sale_order.py
Normal file
49
nfu_ecommerce/models/sale_order.py
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
from odoo import api, fields, models
|
||||||
|
|
||||||
|
|
||||||
|
class SaleOrder(models.Model):
|
||||||
|
_inherit = "sale.order"
|
||||||
|
|
||||||
|
balance = fields.Monetary(compute="_compute_balance")
|
||||||
|
updated_balance = fields.Monetary(compute="_compute_updated_balance")
|
||||||
|
|
||||||
|
def _compute_balance(self):
|
||||||
|
for order in self:
|
||||||
|
order.balance = -order.partner_id.commercial_partner_id.credit
|
||||||
|
|
||||||
|
@api.depends("amount_total")
|
||||||
|
def _compute_updated_balance(self):
|
||||||
|
for order in self:
|
||||||
|
order.updated_balance = order.balance - (order.amount_total / order.currency_rate)
|
||||||
|
|
||||||
|
def _prepare_order_line_values(
|
||||||
|
self,
|
||||||
|
product_id,
|
||||||
|
quantity,
|
||||||
|
linked_line_id=False,
|
||||||
|
no_variant_attribute_values=None,
|
||||||
|
product_custom_attribute_values=None,
|
||||||
|
**kwargs
|
||||||
|
):
|
||||||
|
values = super()._prepare_order_line_values(
|
||||||
|
product_id,
|
||||||
|
quantity,
|
||||||
|
linked_line_id=linked_line_id,
|
||||||
|
no_variant_attribute_values=no_variant_attribute_values,
|
||||||
|
product_custom_attribute_values=product_custom_attribute_values,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
values.update({"product_uom_ordered_qty": quantity, "product_uom_max_qty": kwargs.get("max_qty", quantity)})
|
||||||
|
return values
|
||||||
|
|
||||||
|
def _prepare_order_line_update_values(self, order_line, quantity, linked_line_id=False, **kwargs):
|
||||||
|
values = super()._prepare_order_line_update_values(
|
||||||
|
order_line, quantity, linked_line_id=linked_line_id, **kwargs
|
||||||
|
)
|
||||||
|
max_qty = kwargs.get("max_qty", quantity)
|
||||||
|
if quantity != order_line.product_uom_ordered_qty:
|
||||||
|
values["product_uom_ordered_qty"] = quantity
|
||||||
|
if max_qty and max_qty != order_line.product_uom_max_qty:
|
||||||
|
values["product_uom_max_qty"] = max_qty
|
||||||
|
|
||||||
|
return values
|
||||||
4
nfu_ecommerce/readme/DESCRIPTION.rst
Normal file
4
nfu_ecommerce/readme/DESCRIPTION.rst
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
This module adds a maximum order quantity field to Website Sale Orders. It also adds
|
||||||
|
an ordered qantitiy field to store the original ordered quantity in case a manager
|
||||||
|
adjustes the uom quantitiy. In webshop checkout it adds the customer balance to before
|
||||||
|
and after the current order.
|
||||||
1
nfu_ecommerce/readme/HISTORY.rst
Normal file
1
nfu_ecommerce/readme/HISTORY.rst
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
:0.0.1: Initial module.
|
||||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
|
@ -3,7 +3,7 @@
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
|
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
|
||||||
<title>NFU Sale Min Max Quantitiy</title>
|
<title>NFU eCommerce</title>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -360,8 +360,8 @@ ul.auto-toc {
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="document" id="nfu-sale-min-max-quantitiy">
|
<div class="document" id="nfu-ecommerce">
|
||||||
<h1 class="title">NFU Sale Min Max Quantitiy</h1>
|
<h1 class="title">NFU eCommerce</h1>
|
||||||
|
|
||||||
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
!! This file is generated by oca-gen-addon-readme !!
|
!! This file is generated by oca-gen-addon-readme !!
|
||||||
|
|
@ -369,8 +369,11 @@ ul.auto-toc {
|
||||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
!! source digest: sha256:4dfaea54e4d01502b433eb5c0dcca409a5fbe2c3f175e29382a19230343183c9
|
!! source digest: sha256:4dfaea54e4d01502b433eb5c0dcca409a5fbe2c3f175e29382a19230343183c9
|
||||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
||||||
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/lgpl-3.0-standalone.html"><img alt="License: LGPL-3" src="https://img.shields.io/badge/licence-LGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/bruecksen/ife_nfu/tree/16.0/nfu_sale_product_min_max_qty"><img alt="bruecksen/ife_nfu" src="https://img.shields.io/badge/github-bruecksen%2Fife_nfu-lightgray.png?logo=github" /></a></p>
|
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/lgpl-3.0-standalone.html"><img alt="License: LGPL-3" src="https://img.shields.io/badge/licence-LGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/bruecksen/ife_nfu/tree/16.0/nfu_ecommerce"><img alt="bruecksen/ife_nfu" src="https://img.shields.io/badge/github-bruecksen%2Fife_nfu-lightgray.png?logo=github" /></a></p>
|
||||||
<p>This module adds a minium and a maximum order quantity field to Sale Orders and adds it to checkout of the website shop.</p>
|
<p>This module adds a maximum order quantity field to Website Sale Orders. It also adds
|
||||||
|
an ordered qantitiy field to store the original ordered quantity in case a manager
|
||||||
|
adjustes the uom quantitiy. In webshop checkout it adds the customer balance to before
|
||||||
|
and after the current order.</p>
|
||||||
<p><strong>Table of contents</strong></p>
|
<p><strong>Table of contents</strong></p>
|
||||||
<div class="contents local topic" id="contents">
|
<div class="contents local topic" id="contents">
|
||||||
<ul class="simple">
|
<ul class="simple">
|
||||||
|
|
@ -390,7 +393,7 @@ ul.auto-toc {
|
||||||
<col class="field-name" />
|
<col class="field-name" />
|
||||||
<col class="field-body" />
|
<col class="field-body" />
|
||||||
<tbody valign="top">
|
<tbody valign="top">
|
||||||
<tr class="field"><th class="field-name">1.0.0:</th><td class="field-body">Initial module.</td>
|
<tr class="field"><th class="field-name">0.0.1:</th><td class="field-body">Initial module.</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
@ -400,7 +403,7 @@ ul.auto-toc {
|
||||||
<p>Bugs are tracked on <a class="reference external" href="https://github.com/bruecksen/ife_nfu/issues">GitHub Issues</a>.
|
<p>Bugs are tracked on <a class="reference external" href="https://github.com/bruecksen/ife_nfu/issues">GitHub Issues</a>.
|
||||||
In case of trouble, please check there if your issue has already been reported.
|
In case of trouble, please check there if your issue has already been reported.
|
||||||
If you spotted it first, help us to smash it by providing a detailed and welcomed
|
If you spotted it first, help us to smash it by providing a detailed and welcomed
|
||||||
<a class="reference external" href="https://github.com/bruecksen/ife_nfu/issues/new?body=module:%20nfu_sale_product_min_max_qty%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
|
<a class="reference external" href="https://github.com/bruecksen/ife_nfu/issues/new?body=module:%20nfu_ecommerce%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
|
||||||
<p>Do not contact contributors directly about support or help with technical issues.</p>
|
<p>Do not contact contributors directly about support or help with technical issues.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="credits">
|
<div class="section" id="credits">
|
||||||
|
|
@ -420,7 +423,7 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="maintainers">
|
<div class="section" id="maintainers">
|
||||||
<h2><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h2>
|
<h2><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h2>
|
||||||
<p>This module is part of the <a class="reference external" href="https://github.com/bruecksen/ife_nfu/tree/16.0/nfu_sale_product_min_max_qty">bruecksen/ife_nfu</a> project on GitHub.</p>
|
<p>This module is part of the <a class="reference external" href="https://github.com/bruecksen/ife_nfu/tree/16.0/nfu_ecommerce">bruecksen/ife_nfu</a> project on GitHub.</p>
|
||||||
<p>You are welcome to contribute.</p>
|
<p>You are welcome to contribute.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1,36 +1,10 @@
|
||||||
odoo.define("nfu_sale_product_min_max_qty.website_min_max_qty", function (require) {
|
odoo.define("nfu_ecommerce.website_max_qty", function (require) {
|
||||||
"use strict";
|
"use strict";
|
||||||
var core = require("web.core");
|
var core = require("web.core");
|
||||||
var _t = core._t;
|
|
||||||
var wSaleUtils = require("website_sale.utils");
|
var wSaleUtils = require("website_sale.utils");
|
||||||
var publicWidget = require("web.public.widget");
|
var publicWidget = require("web.public.widget");
|
||||||
require("website_sale.website_sale");
|
require("website_sale.website_sale");
|
||||||
publicWidget.registry.WebsiteSale.include({
|
publicWidget.registry.WebsiteSale.include({
|
||||||
onClickAddCartJSON: function (ev) {
|
|
||||||
ev.preventDefault();
|
|
||||||
$(".css_quantity").popover("dispose");
|
|
||||||
var $link = $(ev.currentTarget);
|
|
||||||
var $input = $link.closest(".input-group").find("input");
|
|
||||||
var min = parseFloat($input.data("min") || 0);
|
|
||||||
var previousQty = parseFloat($input.val() || 0, 10);
|
|
||||||
var quantity = ($link.has(".fa-minus").length ? -1 : 1) + previousQty;
|
|
||||||
if (quantity < min) {
|
|
||||||
$input.closest(".css_quantity").popover({
|
|
||||||
content: _t(`Minimum Quantity is ${min}.`),
|
|
||||||
title: _t("Warning"),
|
|
||||||
placement: "left",
|
|
||||||
trigger: "focus",
|
|
||||||
html: true,
|
|
||||||
});
|
|
||||||
$input.closest(".css_quantity").popover("show");
|
|
||||||
|
|
||||||
setTimeout(function () {
|
|
||||||
$(".css_quantity").popover("dispose");
|
|
||||||
}, 3000);
|
|
||||||
}
|
|
||||||
this._super(ev);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the max qty to the POST request when adding a product to the cart.
|
* Adds the max qty to the POST request when adding a product to the cart.
|
||||||
* @override
|
* @override
|
||||||
125
nfu_ecommerce/views/templates.xml
Normal file
125
nfu_ecommerce/views/templates.xml
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<template id="cart_lines_max_qty" inherit_id="website_sale.cart_lines" name="Shopping Cart Lines">
|
||||||
|
<xpath expr="//th[hasclass('td-qty')]" position="after">
|
||||||
|
<th class="text-center td-qty">
|
||||||
|
<t t-if="show_qty">
|
||||||
|
<span>Max Qty</span>
|
||||||
|
</t>
|
||||||
|
</th>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//td[hasclass('td-qty')]" position="after">
|
||||||
|
<td class="text-center td-qty">
|
||||||
|
<div class="css_quantity input-group mx-auto justify-content-center">
|
||||||
|
<t t-if="not line._is_not_sellable_line()">
|
||||||
|
<t t-if="show_qty">
|
||||||
|
<a
|
||||||
|
t-attf-href="#"
|
||||||
|
class="btn btn-link js_add_cart_json d-none d-md-inline-block"
|
||||||
|
aria-label="Remove one"
|
||||||
|
title="Remove one"
|
||||||
|
>
|
||||||
|
<i class="fa fa-minus"/>
|
||||||
|
</a>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="max-qty"
|
||||||
|
class="js_quantity form-control quantity"
|
||||||
|
t-att-data-line-id="line.id"
|
||||||
|
t-att-data-product-id="line.product_id.id"
|
||||||
|
t-att-value="line.product_uom_max_qty and int(line.product_uom_max_qty) or int(line.product_uom_qty)"
|
||||||
|
t-att-data-min="int(line.product_uom_qty)"
|
||||||
|
/>
|
||||||
|
<t t-if="line._get_shop_warning(clear=False)">
|
||||||
|
<a t-attf-href="#" class="btn btn-link">
|
||||||
|
<i
|
||||||
|
class='fa fa-warning text-warning'
|
||||||
|
t-att-title="line._get_shop_warning()"
|
||||||
|
role="img"
|
||||||
|
aria-label="Warning"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</t>
|
||||||
|
<a
|
||||||
|
t-else=''
|
||||||
|
t-attf-href="#"
|
||||||
|
class="btn btn-link float_left js_add_cart_json d-none d-md-inline-block"
|
||||||
|
aria-label="Add one"
|
||||||
|
title="Add one"
|
||||||
|
>
|
||||||
|
<i class="fa fa-plus"/>
|
||||||
|
</a>
|
||||||
|
</t>
|
||||||
|
<t t-else="">
|
||||||
|
<input
|
||||||
|
type="hidden"
|
||||||
|
class="js_quantity form-control quantity"
|
||||||
|
t-att-data-line-id="line.id"
|
||||||
|
t-att-data-product-id="line.product_id.id"
|
||||||
|
t-att-value="int(line.product_uom_qty) == line.product_uom_qty and int(line.product_uom_qty) or line.product_uom_qty"
|
||||||
|
/>
|
||||||
|
</t>
|
||||||
|
</t>
|
||||||
|
<t t-else="">
|
||||||
|
<span class="text-muted w-100" t-esc="int(line.product_uom_qty)"/>
|
||||||
|
<input
|
||||||
|
type="hidden"
|
||||||
|
class="js_quantity form-control quantity"
|
||||||
|
t-att-data-line-id="line.id"
|
||||||
|
t-att-data-product-id="line.product_id.id"
|
||||||
|
t-att-value="line.product_uom_qty"
|
||||||
|
/>
|
||||||
|
</t>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</xpath>
|
||||||
|
</template>
|
||||||
|
<template id="cart_summary_max_qty" inherit_id="website_sale.cart_summary" name="Cart right column">
|
||||||
|
<xpath expr="//th[hasclass('td-qty')]" position="after">
|
||||||
|
<th class="border-top-0 td-qty">Max Qty</th>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//td[hasclass('td-qty')]" position="after">
|
||||||
|
<td class='td-qty'>
|
||||||
|
<div t-esc="line.product_uom_max_qty"/>
|
||||||
|
</td>
|
||||||
|
</xpath>
|
||||||
|
</template>
|
||||||
|
<template id="total" inherit_id="website_sale.total">
|
||||||
|
<xpath expr="//tr[@id='empty']" position="after">
|
||||||
|
<tr id="balance">
|
||||||
|
<td class="text-end border-0">Balance:</td>
|
||||||
|
<td class="text-xl-end border-0">
|
||||||
|
<span
|
||||||
|
t-field="website_sale_order.balance"
|
||||||
|
class="monetary_field"
|
||||||
|
style="white-space: nowrap;"
|
||||||
|
t-options="{'widget': 'monetary', 'display_currency': website_sale_order.currency_id}"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//tr[@id='order_total']" position="after">
|
||||||
|
<tr id="updated_balance">
|
||||||
|
<td class="text-end border-0">New balance:</td>
|
||||||
|
<td class="text-xl-end border-0">
|
||||||
|
<t t-if="website_sale_order.updated_balance < 0">
|
||||||
|
<span
|
||||||
|
t-field="website_sale_order.updated_balance"
|
||||||
|
class="monetary_field text-danger"
|
||||||
|
style="white-space: nowrap;"
|
||||||
|
t-options="{'widget': 'monetary', 'display_currency': website_sale_order.currency_id}"
|
||||||
|
/>
|
||||||
|
</t>
|
||||||
|
<t t-else="">
|
||||||
|
<span
|
||||||
|
t-field="website_sale_order.updated_balance"
|
||||||
|
t-att-class="monetary_field"
|
||||||
|
style="white-space: nowrap;"
|
||||||
|
t-options="{'widget': 'monetary', 'display_currency': website_sale_order.currency_id}"
|
||||||
|
/>
|
||||||
|
</t>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</xpath>
|
||||||
|
</template>
|
||||||
|
</odoo>
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
========================
|
==============================
|
||||||
NFU Sale Order Packaging
|
NFU Sale Order Batch Packaging
|
||||||
========================
|
==============================
|
||||||
|
|
||||||
..
|
..
|
||||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
@ -17,7 +17,7 @@ NFU Sale Order Packaging
|
||||||
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
|
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
|
||||||
:alt: License: LGPL-3
|
:alt: License: LGPL-3
|
||||||
.. |badge3| image:: https://img.shields.io/badge/github-bruecksen%2Fife_nfu-lightgray.png?logo=github
|
.. |badge3| image:: https://img.shields.io/badge/github-bruecksen%2Fife_nfu-lightgray.png?logo=github
|
||||||
:target: https://github.com/bruecksen/ife_nfu/tree/16.0/nfu_sale_order_packaging
|
:target: https://github.com/bruecksen/ife_nfu/tree/16.0/nfu_sale_order_batch_packaging
|
||||||
:alt: bruecksen/ife_nfu
|
:alt: bruecksen/ife_nfu
|
||||||
|
|
||||||
|badge1| |badge2| |badge3|
|
|badge1| |badge2| |badge3|
|
||||||
|
|
@ -33,7 +33,8 @@ and adds a packaging default to sale order batch.
|
||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
:1.0.0: Initial module.
|
:0.0.1: Initial module.
|
||||||
|
:1.0.0: rename to nfu_sale_order_batch_packaging
|
||||||
|
|
||||||
Bug Tracker
|
Bug Tracker
|
||||||
===========
|
===========
|
||||||
|
|
@ -41,7 +42,7 @@ Bug Tracker
|
||||||
Bugs are tracked on `GitHub Issues <https://github.com/bruecksen/ife_nfu/issues>`_.
|
Bugs are tracked on `GitHub Issues <https://github.com/bruecksen/ife_nfu/issues>`_.
|
||||||
In case of trouble, please check there if your issue has already been reported.
|
In case of trouble, please check there if your issue has already been reported.
|
||||||
If you spotted it first, help us to smash it by providing a detailed and welcomed
|
If you spotted it first, help us to smash it by providing a detailed and welcomed
|
||||||
`feedback <https://github.com/bruecksen/ife_nfu/issues/new?body=module:%20nfu_sale_order_packaging%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
|
`feedback <https://github.com/bruecksen/ife_nfu/issues/new?body=module:%20nfu_sale_order_batch_packaging%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
|
||||||
|
|
||||||
Do not contact contributors directly about support or help with technical issues.
|
Do not contact contributors directly about support or help with technical issues.
|
||||||
|
|
||||||
|
|
@ -62,6 +63,6 @@ Contributors
|
||||||
Maintainers
|
Maintainers
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
|
|
||||||
This module is part of the `bruecksen/ife_nfu <https://github.com/bruecksen/ife_nfu/tree/16.0/nfu_sale_order_packaging>`_ project on GitHub.
|
This module is part of the `bruecksen/ife_nfu <https://github.com/bruecksen/ife_nfu/tree/16.0/nfu_sale_order_batch_packaging>`_ project on GitHub.
|
||||||
|
|
||||||
You are welcome to contribute.
|
You are welcome to contribute.
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
{
|
{
|
||||||
"name": "NFU Sale Order Packaging",
|
"name": "NFU Sale Order Batch Packaging",
|
||||||
"summary": "Add minimum and maximum order quantities to sale orders and use default packaging",
|
"summary": "Add minimum and maximum order quantities to sale orders and batches and use default packaging",
|
||||||
"author": "BAKEUP",
|
"author": "BAKEUP",
|
||||||
"website": "https://www.bakeup.org",
|
"website": "https://www.bakeup.org",
|
||||||
"category": "Sale",
|
"category": "Sale",
|
||||||
"version": "16.0.0.0.1",
|
"version": "16.0.1.0.0",
|
||||||
"depends": ["sale", "sale_order_batch"],
|
"depends": ["sale", "sale_order_batch"],
|
||||||
"data": [
|
"data": [
|
||||||
"views/sale_order_views.xml",
|
"views/sale_order_views.xml",
|
||||||
2
nfu_sale_order_batch_packaging/readme/HISTORY.rst
Normal file
2
nfu_sale_order_batch_packaging/readme/HISTORY.rst
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
:0.0.1: Initial module.
|
||||||
|
:1.0.0: rename to nfu_sale_order_batch_packaging
|
||||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
|
@ -3,7 +3,7 @@
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
|
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
|
||||||
<title>NFU Sale Order Packaging</title>
|
<title>NFU Sale Order Batch Packaging</title>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -360,8 +360,8 @@ ul.auto-toc {
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="document" id="nfu-sale-order-packaging">
|
<div class="document" id="nfu-sale-order-batch-packaging">
|
||||||
<h1 class="title">NFU Sale Order Packaging</h1>
|
<h1 class="title">NFU Sale Order Batch Packaging</h1>
|
||||||
|
|
||||||
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
!! This file is generated by oca-gen-addon-readme !!
|
!! This file is generated by oca-gen-addon-readme !!
|
||||||
|
|
@ -369,7 +369,7 @@ ul.auto-toc {
|
||||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
!! source digest: sha256:cf35c3a80aa0718148099036cd6a3dd60afb61acdb420573b1bd129be3ea2cf1
|
!! source digest: sha256:cf35c3a80aa0718148099036cd6a3dd60afb61acdb420573b1bd129be3ea2cf1
|
||||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
||||||
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/lgpl-3.0-standalone.html"><img alt="License: LGPL-3" src="https://img.shields.io/badge/licence-LGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/bruecksen/ife_nfu/tree/16.0/nfu_sale_order_packaging"><img alt="bruecksen/ife_nfu" src="https://img.shields.io/badge/github-bruecksen%2Fife_nfu-lightgray.png?logo=github" /></a></p>
|
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/lgpl-3.0-standalone.html"><img alt="License: LGPL-3" src="https://img.shields.io/badge/licence-LGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/bruecksen/ife_nfu/tree/16.0/nfu_sale_order_batch_packaging"><img alt="bruecksen/ife_nfu" src="https://img.shields.io/badge/github-bruecksen%2Fife_nfu-lightgray.png?logo=github" /></a></p>
|
||||||
<p>This module adds a minium and a maximum order quantity field to Sale Orders
|
<p>This module adds a minium and a maximum order quantity field to Sale Orders
|
||||||
and adds a packaging default to sale order batch.</p>
|
and adds a packaging default to sale order batch.</p>
|
||||||
<p><strong>Table of contents</strong></p>
|
<p><strong>Table of contents</strong></p>
|
||||||
|
|
@ -391,7 +391,9 @@ and adds a packaging default to sale order batch.</p>
|
||||||
<col class="field-name" />
|
<col class="field-name" />
|
||||||
<col class="field-body" />
|
<col class="field-body" />
|
||||||
<tbody valign="top">
|
<tbody valign="top">
|
||||||
<tr class="field"><th class="field-name">1.0.0:</th><td class="field-body">Initial module.</td>
|
<tr class="field"><th class="field-name">0.0.1:</th><td class="field-body">Initial module.</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="field"><th class="field-name">1.0.0:</th><td class="field-body">rename to nfu_sale_order_batch_packaging</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
@ -401,7 +403,7 @@ and adds a packaging default to sale order batch.</p>
|
||||||
<p>Bugs are tracked on <a class="reference external" href="https://github.com/bruecksen/ife_nfu/issues">GitHub Issues</a>.
|
<p>Bugs are tracked on <a class="reference external" href="https://github.com/bruecksen/ife_nfu/issues">GitHub Issues</a>.
|
||||||
In case of trouble, please check there if your issue has already been reported.
|
In case of trouble, please check there if your issue has already been reported.
|
||||||
If you spotted it first, help us to smash it by providing a detailed and welcomed
|
If you spotted it first, help us to smash it by providing a detailed and welcomed
|
||||||
<a class="reference external" href="https://github.com/bruecksen/ife_nfu/issues/new?body=module:%20nfu_sale_order_packaging%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
|
<a class="reference external" href="https://github.com/bruecksen/ife_nfu/issues/new?body=module:%20nfu_sale_order_batch_packaging%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
|
||||||
<p>Do not contact contributors directly about support or help with technical issues.</p>
|
<p>Do not contact contributors directly about support or help with technical issues.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="credits">
|
<div class="section" id="credits">
|
||||||
|
|
@ -421,7 +423,7 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="maintainers">
|
<div class="section" id="maintainers">
|
||||||
<h2><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h2>
|
<h2><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h2>
|
||||||
<p>This module is part of the <a class="reference external" href="https://github.com/bruecksen/ife_nfu/tree/16.0/nfu_sale_order_packaging">bruecksen/ife_nfu</a> project on GitHub.</p>
|
<p>This module is part of the <a class="reference external" href="https://github.com/bruecksen/ife_nfu/tree/16.0/nfu_sale_order_batch_packaging">bruecksen/ife_nfu</a> project on GitHub.</p>
|
||||||
<p>You are welcome to contribute.</p>
|
<p>You are welcome to contribute.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
:1.0.0: Initial module.
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
{
|
|
||||||
"name": "NFU Sale Min Max Quantitiy",
|
|
||||||
"summary": "Add minimum and maximum order quantities to sale orders",
|
|
||||||
"author": "BAKEUP",
|
|
||||||
"website": "https://www.bakeup.org",
|
|
||||||
"category": "Stock",
|
|
||||||
"version": "16.0.0.0.1",
|
|
||||||
"depends": ["sale_management", "website_sale"],
|
|
||||||
"data": [
|
|
||||||
"views/sale_order_views.xml",
|
|
||||||
"views/sale_order_line_views.xml",
|
|
||||||
"wizard/sale_max_qty_line_views.xml",
|
|
||||||
"wizard/sale_max_qty_chooser_views.xml",
|
|
||||||
"views/templates.xml",
|
|
||||||
"security/ir.model.access.csv",
|
|
||||||
],
|
|
||||||
"assets": {"web.assets_frontend": ["nfu_sale_product_min_max_qty/static/src/js/website_sale.js"]},
|
|
||||||
"license": "LGPL-3",
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
from . import main
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from odoo.http import request
|
|
||||||
from odoo import fields, http
|
|
||||||
|
|
||||||
from odoo.addons.website_sale.controllers.main import WebsiteSale
|
|
||||||
|
|
||||||
|
|
||||||
class WebsiteSaleMinMax(WebsiteSale):
|
|
||||||
|
|
||||||
@http.route()
|
|
||||||
def cart_update(self, *args, min_qty=None, max_qty=None, **kw):
|
|
||||||
""" Override to get min_qty and max_qty from the product.
|
|
||||||
"""
|
|
||||||
product_uom_min_qty = fields.Float(min_qty)
|
|
||||||
product_uom_max_qty = fields.Float(max_qty)
|
|
||||||
return super().cart_update(*args, min_qty=product_uom_min_qty, max_qty=product_uom_max_qty, **kw)
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
from . import sale_order_line
|
|
||||||
from . import sale_order
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
||||||
from odoo import _, models
|
|
||||||
|
|
||||||
|
|
||||||
class SaleOrder(models.Model):
|
|
||||||
_inherit = "sale.order"
|
|
||||||
|
|
||||||
def action_min_max_qty_wizard(self):
|
|
||||||
"""
|
|
||||||
Here you need to create the wizzard objects first and then call the wizzard with the newly created id
|
|
||||||
"""
|
|
||||||
sale_max_qty_chooser = self.env["sale.max.qty.chooser"].create({})
|
|
||||||
draft_sale_orders = self.filtered(lambda x: x.state == "draft")
|
|
||||||
for sale_order in draft_sale_orders:
|
|
||||||
sale_max_qty_chooser.sale_order_ids += sale_order
|
|
||||||
for line in sale_order.order_line.filtered(lambda x: not x.display_type):
|
|
||||||
self.env["sale.max.qty.line"].create(
|
|
||||||
{
|
|
||||||
"sale_line_id": line.id,
|
|
||||||
"sale_max_qty_chooser": sale_max_qty_chooser.id,
|
|
||||||
"qty": line.product_uom_qty,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
action = {
|
|
||||||
"name": _("Min max qty wizard"),
|
|
||||||
"type": "ir.actions.act_window",
|
|
||||||
"res_model": "sale.max.qty.line",
|
|
||||||
"view_mode": "tree",
|
|
||||||
"target": "current",
|
|
||||||
"editable": True,
|
|
||||||
"context": {"search_default_group_by_product": 1},
|
|
||||||
"domain": [("id", "in", sale_max_qty_chooser.sale_max_qty_ids.ids)],
|
|
||||||
}
|
|
||||||
return action
|
|
||||||
|
|
||||||
def action_sale_order_lines(self):
|
|
||||||
"""
|
|
||||||
Here you need to create the wizzard objects first and then call the wizzard with the newly created id
|
|
||||||
"""
|
|
||||||
return {
|
|
||||||
"name": _("Min max qty wizard"),
|
|
||||||
"type": "ir.actions.act_window",
|
|
||||||
"res_model": "sale.order.line",
|
|
||||||
"view_mode": "tree,form",
|
|
||||||
"target": "current",
|
|
||||||
"context": {"group_by": "product_id"},
|
|
||||||
"domain": [("id", "in", self.order_line.ids)],
|
|
||||||
}
|
|
||||||
|
|
||||||
def _prepare_order_line_values(
|
|
||||||
self,
|
|
||||||
product_id,
|
|
||||||
quantity,
|
|
||||||
linked_line_id=False,
|
|
||||||
no_variant_attribute_values=None,
|
|
||||||
product_custom_attribute_values=None,
|
|
||||||
**kwargs
|
|
||||||
):
|
|
||||||
values = super()._prepare_order_line_values(
|
|
||||||
product_id,
|
|
||||||
quantity,
|
|
||||||
linked_line_id=linked_line_id,
|
|
||||||
no_variant_attribute_values=no_variant_attribute_values,
|
|
||||||
product_custom_attribute_values=product_custom_attribute_values,
|
|
||||||
**kwargs
|
|
||||||
)
|
|
||||||
values.update({"product_uom_min_qty": quantity, "product_uom_max_qty": kwargs.get("max_qty", quantity)})
|
|
||||||
return values
|
|
||||||
|
|
||||||
def _prepare_order_line_update_values(self, order_line, quantity, linked_line_id=False, **kwargs):
|
|
||||||
values = super()._prepare_order_line_update_values(
|
|
||||||
order_line, quantity, linked_line_id=linked_line_id, **kwargs
|
|
||||||
)
|
|
||||||
max_qty = kwargs.get("max_qty", quantity)
|
|
||||||
if quantity != order_line.product_uom_min_qty:
|
|
||||||
values["product_uom_min_qty"] = quantity
|
|
||||||
if max_qty and max_qty != order_line.product_uom_max_qty:
|
|
||||||
values["product_uom_max_qty"] = max_qty
|
|
||||||
|
|
||||||
return values
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
from odoo import _, api, fields, models
|
|
||||||
from odoo.exceptions import UserError
|
|
||||||
|
|
||||||
|
|
||||||
class SaleOrderLine(models.Model):
|
|
||||||
_inherit = "sale.order.line"
|
|
||||||
|
|
||||||
product_uom_min_qty = fields.Float(string="Min qty.", digits="Product Unit of Measure")
|
|
||||||
product_uom_max_qty = fields.Float(string="Max qty.", digits="Product Unit of Measure")
|
|
||||||
|
|
||||||
@api.constrains("product_uom_qty", "product_uom_max_qty")
|
|
||||||
def _check_product_uom_qty(self):
|
|
||||||
for record in self:
|
|
||||||
if record.product_uom_max_qty != 0 and record.product_uom_qty > record.product_uom_max_qty:
|
|
||||||
raise UserError(_("The quantity must be less than or equal to the maximum quantity."))
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
This module adds a minium and a maximum order quantity field to Sale Orders and adds it to checkout of the website shop.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
:1.0.0: Initial module.
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
|
||||||
access_sale_max_qty_chooser,sale.max.qty.chooser,model_sale_max_qty_chooser,sales_team.group_sale_salesman,1,1,1,1
|
|
||||||
access_sale_max_qty_line,sale.max.qty.line,model_sale_max_qty_line,sales_team.group_sale_salesman,1,1,1,1
|
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<odoo>
|
|
||||||
<record id="view_order_line_tree" model="ir.ui.view">
|
|
||||||
<field name="name">sale.order.line.tree</field>
|
|
||||||
<field name="model">sale.order.line</field>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<tree create="false" expand="1">
|
|
||||||
<field name="order_id"/>
|
|
||||||
<field name="order_partner_id"/>
|
|
||||||
<field name="name"/>
|
|
||||||
<field name="salesman_id"/>
|
|
||||||
<field name="product_uom_qty" string="Qty"/>
|
|
||||||
<field name="product_uom_min_qty" optional="hide"/>
|
|
||||||
<field name="product_uom_max_qty"/>
|
|
||||||
<field name="qty_delivered"/>
|
|
||||||
<field name="qty_invoiced"/>
|
|
||||||
<field name="qty_to_invoice"/>
|
|
||||||
<field name="product_uom" string="Unit of Measure" groups="uom.group_uom"/>
|
|
||||||
<field name="price_subtotal" sum="Total" widget="monetary"/>
|
|
||||||
<field name="currency_id" invisible="1"/>
|
|
||||||
</tree>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
</odoo>
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<odoo>
|
|
||||||
<record id="view_order_form_inherit_product_min_max_qty" model="ir.ui.view">
|
|
||||||
<field name="name">sale.order.form.product.min_max_qty</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='order_line']/tree/field[@name='product_uom_qty']" position="after">
|
|
||||||
<field name="product_uom_min_qty" optional="hide"/>
|
|
||||||
<field name="product_uom_max_qty"/>
|
|
||||||
</xpath>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
<record id="view_order_list_inherit_product_min_max_qty" model="ir.ui.view">
|
|
||||||
<field name="name">sale.order.list.view.inherited</field>
|
|
||||||
<field name="model">sale.order</field>
|
|
||||||
<field name="inherit_id" ref="sale.view_quotation_tree"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<xpath expr="//tree" position="inside">
|
|
||||||
<header>
|
|
||||||
<button type="object" name="action_min_max_qty_wizard" string="Min/Max Wizard"/>
|
|
||||||
<button type="object" name="action_sale_order_lines" string="Sale order lines"/>
|
|
||||||
</header>
|
|
||||||
</xpath>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
</odoo>
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<odoo>
|
|
||||||
<template id="cart_lines_min_max_qty" inherit_id="website_sale.cart_lines" name="Shopping Cart Lines">
|
|
||||||
<xpath expr="//th[hasclass('td-qty')]" position="after">
|
|
||||||
<th class="text-center td-qty">
|
|
||||||
<t t-if="show_qty">
|
|
||||||
<span>Max qty.</span>
|
|
||||||
</t>
|
|
||||||
</th>
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="//td[hasclass('td-qty')]" position="after">
|
|
||||||
<td class="text-center td-qty">
|
|
||||||
<div class="css_quantity input-group mx-auto justify-content-center">
|
|
||||||
<t t-if="not line._is_not_sellable_line()">
|
|
||||||
<t t-if="show_qty">
|
|
||||||
<a t-attf-href="#" class="btn btn-link js_add_cart_json d-none d-md-inline-block" aria-label="Remove one" title="Remove one">
|
|
||||||
<i class="fa fa-minus"></i>
|
|
||||||
</a>
|
|
||||||
<input type="text" name="max-qty" class="js_quantity form-control quantity" t-att-data-line-id="line.id" t-att-data-product-id="line.product_id.id" t-att-value="line.product_uom_max_qty and int(line.product_uom_max_qty) or int(line.product_uom_qty)" t-att-data-min="int(line.product_uom_qty)" />
|
|
||||||
<t t-if="line._get_shop_warning(clear=False)">
|
|
||||||
<a t-attf-href="#" class="btn btn-link">
|
|
||||||
<i class='fa fa-warning text-warning' t-att-title="line._get_shop_warning()" role="img" aria-label="Warning"/>
|
|
||||||
</a>
|
|
||||||
</t>
|
|
||||||
<a t-else='' t-attf-href="#" class="btn btn-link float_left js_add_cart_json d-none d-md-inline-block" aria-label="Add one" title="Add one">
|
|
||||||
<i class="fa fa-plus"></i>
|
|
||||||
</a>
|
|
||||||
</t>
|
|
||||||
<t t-else="">
|
|
||||||
<input type="hidden" class="js_quantity form-control quantity" t-att-data-line-id="line.id" t-att-data-product-id="line.product_id.id" t-att-value="int(line.product_uom_qty) == line.product_uom_qty and int(line.product_uom_qty) or line.product_uom_qty" />
|
|
||||||
</t>
|
|
||||||
</t>
|
|
||||||
<t t-else="">
|
|
||||||
<span class="text-muted w-100" t-esc="int(line.product_uom_qty)"/>
|
|
||||||
<input type="hidden" class="js_quantity form-control quantity" t-att-data-line-id="line.id" t-att-data-product-id="line.product_id.id" t-att-value="line.product_uom_qty" />
|
|
||||||
</t>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</xpath>
|
|
||||||
</template>
|
|
||||||
<template id="cart_summary_min_max_qty" inherit_id="website_sale.cart_summary" name="Cart right column">
|
|
||||||
<xpath expr="//th[hasclass('td-qty')]" position="after">
|
|
||||||
<th class="border-top-0 td-qty">Max qty.</th>
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="//td[hasclass('td-qty')]" position="after">
|
|
||||||
<td class='td-qty'>
|
|
||||||
<div t-esc="line.product_uom_max_qty" />
|
|
||||||
</td>
|
|
||||||
</xpath>
|
|
||||||
</template>
|
|
||||||
</odoo>
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
from . import sale_max_qty_chooser
|
|
||||||
from . import sale_max_qty_line
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
from odoo import fields, models
|
|
||||||
|
|
||||||
|
|
||||||
class SaleMaxQtyChooser(models.TransientModel):
|
|
||||||
"""Wizard to Allow user to adjust the sale order amout to fit to a packaging size"""
|
|
||||||
|
|
||||||
_name = "sale.max.qty.chooser"
|
|
||||||
_description = "Sale Max Quantity Chhooser"
|
|
||||||
|
|
||||||
# fill from init or compute from given sale order lines
|
|
||||||
sale_order_ids = fields.Many2many("sale.order")
|
|
||||||
sale_max_qty_ids = fields.One2many("sale.max.qty.line", "sale_max_qty_chooser")
|
|
||||||
|
|
||||||
def update_and_confirm_sale_order(self):
|
|
||||||
"""
|
|
||||||
Confirm sale orders where the quantity is fine. Create new Sale Orders for SO Lines with reset to draft
|
|
||||||
Through user error when total order amount of a product is not equal to packaging size (first package in the
|
|
||||||
list or smalles package sale_order_line.product_id.product.packaging_ids.qty)
|
|
||||||
we can use write({'key':'value'}) to update all sale order lines and action_confirm() to validate all sale
|
|
||||||
orders
|
|
||||||
|
|
||||||
Also see this methode on how to create new records. It creates a invoice with invoice lines. we need to do the
|
|
||||||
same for sale orders
|
|
||||||
|
|
||||||
def action_sold(self):
|
|
||||||
res = super().action_sold()
|
|
||||||
self.env["account.move"].create(
|
|
||||||
{
|
|
||||||
"property_id": self.id,
|
|
||||||
"partner_id": self.buyer_id.id,
|
|
||||||
"move_type": "out_invoice",
|
|
||||||
"line_ids": [
|
|
||||||
fields.Command.create(
|
|
||||||
{
|
|
||||||
"name": f"Property {self.name} - 10% Tax",
|
|
||||||
"quantity": 1,
|
|
||||||
"price_unit": self.selling_price * 1.1,
|
|
||||||
}
|
|
||||||
),
|
|
||||||
fields.Command.create({"name": "Administration Fees", "quantity": 1, "price_unit": 1000}),
|
|
||||||
],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return res
|
|
||||||
"""
|
|
||||||
|
|
||||||
for sale_order in self.sale_order_ids:
|
|
||||||
can_confirm = True
|
|
||||||
for line in self.sale_max_qty_ids.filtered(lambda line: line.sale_line_id.order_id == sale_order):
|
|
||||||
line.sale_line_id.write({"product_uom_qty": line.qty})
|
|
||||||
if not line.quantity_fits_packaging:
|
|
||||||
can_confirm = False
|
|
||||||
if can_confirm:
|
|
||||||
sale_order.action_confirm()
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<odoo>
|
|
||||||
<record id="view_sale_max_qty_chooser_form" model="ir.ui.view">
|
|
||||||
<field name="name">Sale Max Quantity Chhooser</field>
|
|
||||||
<field name="model">sale.max.qty.chooser</field>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<form>
|
|
||||||
<div class="oe_grey">
|
|
||||||
<p>Sale Orders</p>
|
|
||||||
<field name="sale_order_ids" widget="many2many_tags"/>
|
|
||||||
</div>
|
|
||||||
<field name="sale_max_qty_ids" context="{'search_default_group_by_qty': 1}">
|
|
||||||
<!-- <tree create="0" editable="1" default_order="product_id">
|
|
||||||
<field name="product_id" context="{'group_by': 'product_id'}" />
|
|
||||||
<field name="qty"/>
|
|
||||||
<field name="max_qty"/>
|
|
||||||
<field name="packaging_size"/>
|
|
||||||
<field name="quantity_fits_packaging" widget="boolean"/>
|
|
||||||
<field name="reset_to_draft"/>
|
|
||||||
</tree> -->
|
|
||||||
</field>
|
|
||||||
<footer>
|
|
||||||
<button
|
|
||||||
name="update_and_confirm_sale_order"
|
|
||||||
string="Confirm Sale Orders"
|
|
||||||
type="object"
|
|
||||||
class="btn-primary"
|
|
||||||
data-hotkey="q"
|
|
||||||
/>
|
|
||||||
<button string="Cancel" class="btn-secondary" special="cancel" data-hotkey="z"/>
|
|
||||||
</footer>
|
|
||||||
</form>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="action_sale_max_qty" model="ir.actions.act_window">
|
|
||||||
<field name="name">Set Quantities</field>
|
|
||||||
<field name="res_model">sale.max.qty.chooser</field>
|
|
||||||
<field name="view_mode">form</field>
|
|
||||||
<field name="target">current</field>
|
|
||||||
<field name="context">
|
|
||||||
{
|
|
||||||
'search_default_group_by_product': 1,
|
|
||||||
}
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
</odoo>
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
from odoo import _, api, fields, models
|
|
||||||
from odoo.exceptions import UserError
|
|
||||||
|
|
||||||
|
|
||||||
class SaleMaxQtyLine(models.TransientModel):
|
|
||||||
"""
|
|
||||||
Lines to shown in Wizard
|
|
||||||
"""
|
|
||||||
|
|
||||||
_name = "sale.max.qty.line"
|
|
||||||
_description = "Max qty Sale Order Lines"
|
|
||||||
|
|
||||||
name = fields.Char()
|
|
||||||
sale_max_qty_chooser = fields.Many2one("sale.max.qty.chooser")
|
|
||||||
qty = fields.Float()
|
|
||||||
max_qty = fields.Float(related="sale_line_id.product_uom_max_qty")
|
|
||||||
packaging_size = fields.Float(compute="_compute_packaging_size")
|
|
||||||
quantity_fits_packaging = fields.Boolean(compute="_compute_quantity_fits_packaging")
|
|
||||||
total_quantity = fields.Float(compute="_compute_quantity_fits_packaging")
|
|
||||||
|
|
||||||
sale_line_id = fields.Many2one("sale.order.line")
|
|
||||||
product_id = fields.Many2one(related="sale_line_id.product_id", store=True)
|
|
||||||
reset_to_draft = fields.Boolean()
|
|
||||||
|
|
||||||
def _compute_packaging_size(self):
|
|
||||||
for max_qty_line in self:
|
|
||||||
max_qty_line.packaging_size = min(
|
|
||||||
max_qty_line.sale_line_id.product_id.packaging_ids.mapped("qty"), default=1.0
|
|
||||||
)
|
|
||||||
|
|
||||||
@api.onchange("qty")
|
|
||||||
def _compute_quantity_fits_packaging(self):
|
|
||||||
for max_qty_line in self:
|
|
||||||
order_lines = max_qty_line.sale_max_qty_chooser.sale_max_qty_ids.filtered(
|
|
||||||
lambda line: line.sale_line_id.product_id == max_qty_line.product_id
|
|
||||||
)
|
|
||||||
max_qty_line.total_quantity = sum(order_lines.mapped("qty"))
|
|
||||||
max_qty_line.quantity_fits_packaging = max_qty_line.total_quantity % max_qty_line.packaging_size == 0
|
|
||||||
# for order_line in order_lines:
|
|
||||||
# order_line.quantity_fits_packaging = max_qty_line.quantity_fits_packaging
|
|
||||||
|
|
||||||
@api.constrains("qty")
|
|
||||||
def _check_product_uom_qty(self):
|
|
||||||
for max_qty_line in self:
|
|
||||||
if max_qty_line.max_qty != 0 and max_qty_line.qty > max_qty_line.max_qty:
|
|
||||||
raise UserError(_("The quantity must be less than or equal to the maximum quantity."))
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<odoo>
|
|
||||||
<record id="view_sale_max_qty_line_search" model="ir.ui.view">
|
|
||||||
<field name="name">sale.max.qty.line.search</field>
|
|
||||||
<field name="model">sale.max.qty.line</field>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<search>
|
|
||||||
<filter string="Product" name="group_by_product" context="{'group_by':'product_id'}"/>
|
|
||||||
</search>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="viw_sale_max_qty_line_tree" model="ir.ui.view">
|
|
||||||
<field name="name">sale.max.qty.line.tree</field>
|
|
||||||
<field name="model">sale.max.qty.line</field>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<tree editable="bottom" create="0" expand="1">
|
|
||||||
<field name="product_id"/>
|
|
||||||
<field name="qty"/>
|
|
||||||
<field name="max_qty"/>
|
|
||||||
<field name="packaging_size"/>
|
|
||||||
<field name="quantity_fits_packaging" widget="boolean"/>
|
|
||||||
<field name="reset_to_draft"/>
|
|
||||||
</tree>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
</odoo>
|
|
||||||
Loading…
Reference in a new issue