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
|
||||
:alt: License: LGPL-3
|
||||
.. |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
|
||||
|
||||
|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**
|
||||
|
||||
|
|
@ -32,7 +35,7 @@ This module adds a minium and a maximum order quantity field to Sale Orders and
|
|||
Changelog
|
||||
=========
|
||||
|
||||
:1.0.0: Initial module.
|
||||
:0.0.1: Initial module.
|
||||
|
||||
Bug Tracker
|
||||
===========
|
||||
|
|
@ -40,7 +43,7 @@ Bug Tracker
|
|||
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.
|
||||
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.
|
||||
|
||||
|
|
@ -61,6 +64,6 @@ Contributors
|
|||
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.
|
||||
|
|
@ -1,3 +1,2 @@
|
|||
from . import models
|
||||
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>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
|
||||
<title>NFU Sale Min Max Quantitiy</title>
|
||||
<title>NFU eCommerce</title>
|
||||
<style type="text/css">
|
||||
|
||||
/*
|
||||
|
|
@ -360,8 +360,8 @@ ul.auto-toc {
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="document" id="nfu-sale-min-max-quantitiy">
|
||||
<h1 class="title">NFU Sale Min Max Quantitiy</h1>
|
||||
<div class="document" id="nfu-ecommerce">
|
||||
<h1 class="title">NFU eCommerce</h1>
|
||||
|
||||
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! This file is generated by oca-gen-addon-readme !!
|
||||
|
|
@ -369,8 +369,11 @@ ul.auto-toc {
|
|||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! 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>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><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 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>
|
||||
<div class="contents local topic" id="contents">
|
||||
<ul class="simple">
|
||||
|
|
@ -390,7 +393,7 @@ ul.auto-toc {
|
|||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<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>
|
||||
</tbody>
|
||||
</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>.
|
||||
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
|
||||
<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>
|
||||
</div>
|
||||
<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 class="section" id="maintainers">
|
||||
<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>
|
||||
</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";
|
||||
var core = require("web.core");
|
||||
var _t = core._t;
|
||||
var wSaleUtils = require("website_sale.utils");
|
||||
var publicWidget = require("web.public.widget");
|
||||
require("website_sale.website_sale");
|
||||
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.
|
||||
* @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
|
||||
:alt: License: LGPL-3
|
||||
.. |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
|
||||
|
||||
|badge1| |badge2| |badge3|
|
||||
|
|
@ -33,7 +33,8 @@ and adds a packaging default to sale order batch.
|
|||
Changelog
|
||||
=========
|
||||
|
||||
:1.0.0: Initial module.
|
||||
:0.0.1: Initial module.
|
||||
:1.0.0: rename to nfu_sale_order_batch_packaging
|
||||
|
||||
Bug Tracker
|
||||
===========
|
||||
|
|
@ -41,7 +42,7 @@ Bug Tracker
|
|||
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.
|
||||
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.
|
||||
|
||||
|
|
@ -62,6 +63,6 @@ Contributors
|
|||
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.
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
{
|
||||
"name": "NFU Sale Order Packaging",
|
||||
"summary": "Add minimum and maximum order quantities to sale orders and use default packaging",
|
||||
"name": "NFU Sale Order Batch Packaging",
|
||||
"summary": "Add minimum and maximum order quantities to sale orders and batches and use default packaging",
|
||||
"author": "BAKEUP",
|
||||
"website": "https://www.bakeup.org",
|
||||
"category": "Sale",
|
||||
"version": "16.0.0.0.1",
|
||||
"version": "16.0.1.0.0",
|
||||
"depends": ["sale", "sale_order_batch"],
|
||||
"data": [
|
||||
"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>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<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">
|
||||
|
||||
/*
|
||||
|
|
@ -360,8 +360,8 @@ ul.auto-toc {
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="document" id="nfu-sale-order-packaging">
|
||||
<h1 class="title">NFU Sale Order Packaging</h1>
|
||||
<div class="document" id="nfu-sale-order-batch-packaging">
|
||||
<h1 class="title">NFU Sale Order Batch Packaging</h1>
|
||||
|
||||
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! This file is generated by oca-gen-addon-readme !!
|
||||
|
|
@ -369,7 +369,7 @@ ul.auto-toc {
|
|||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! 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
|
||||
and adds a packaging default to sale order batch.</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-body" />
|
||||
<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>
|
||||
</tbody>
|
||||
</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>.
|
||||
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
|
||||
<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>
|
||||
</div>
|
||||
<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 class="section" id="maintainers">
|
||||
<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>
|
||||
</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