Initial commit: Odoo 18.0-20251222 extra-addons
Some checks failed
pre-commit / pre-commit (push) Has been cancelled
tests / Detect unreleased dependencies (push) Has been cancelled
tests / test with OCB (push) Has been cancelled
tests / test with Odoo (push) Has been cancelled

This commit is contained in:
tocmo0nlord
2026-03-13 20:43:25 +00:00
parent 36e847a7df
commit adbe430761
9472 changed files with 1265727 additions and 0 deletions

View File

@@ -0,0 +1,93 @@
==============================
Sale Order Line Delivery State
==============================
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:5591acba48ee389bf9b63755ce827cf25cd0381d7ffb5a2ab3110e05cc289079
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github
:target: https://github.com/OCA/sale-workflow/tree/18.0/sale_order_line_delivery_state
:alt: OCA/sale-workflow
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/sale-workflow-18-0/sale-workflow-18-0-sale_order_line_delivery_state
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/sale-workflow&target_branch=18.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
This odoo module add delivery state on the sale order line. It is based
on the module sale_delivery_state, which adds the field at sale order
level.
Delivery state is computed based on qty_delivered field on sale order
line.
The state of the sale order line can be forced to fully delivered in
case some quantities were cancelled by the customer and you consider you
have nothing more to deliver.
Sale order lines can have products or services, as long as the field
qty_delivered is set, it will trigger the computation of delivery state.
This module also works with delivery.carrier fees that are added as a
sale order line. Thoses line are special as they will never be
considered delivered. Delivery fees lines are ignored in the computation
of the delivery state.
**Table of contents**
.. contents::
:local:
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/sale-workflow/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/OCA/sale-workflow/issues/new?body=module:%20sale_order_line_delivery_state%0Aversion:%2018.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.
Credits
=======
Authors
-------
* ForgeFlow
Contributors
------------
- Jordi Masvidal <jordi.masvidal@forgeflow.com>
Maintainers
-----------
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
This module is part of the `OCA/sale-workflow <https://github.com/OCA/sale-workflow/tree/18.0/sale_order_line_delivery_state>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@@ -0,0 +1 @@
from . import models

View File

@@ -0,0 +1,16 @@
# Copyright 2021 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Sale Order Line Delivery State",
"summary": "Show the delivery state on the sale order line",
"version": "18.0.1.0.0",
"category": "Product",
"website": "https://github.com/OCA/sale-workflow",
"author": "ForgeFlow, Odoo Community Association (OCA)",
"license": "AGPL-3",
"installable": True,
"depends": ["sale"],
"data": ["views/sale_order_views.xml"],
"demo": [],
}

View File

@@ -0,0 +1,72 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_order_line_delivery_state
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2023-10-15 19:36+0000\n"
"Last-Translator: Ivorra78 <informatica@totmaterial.es>\n"
"Language-Team: none\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.17\n"
#. module: sale_order_line_delivery_state
#: model:ir.model.fields,help:sale_order_line_delivery_state.field_sale_order_line__force_delivery_state
msgid ""
"Allow to enforce done state of delivery, for instance if some quantities "
"were cancelled"
msgstr ""
"Permitir forzar estado de entrega a hecho, por ejemplo si se han cancelado "
"algunas cantidades"
#. module: sale_order_line_delivery_state
#: model:ir.model.fields,field_description:sale_order_line_delivery_state.field_sale_order_line__delivery_state
#: model_terms:ir.ui.view,arch_db:sale_order_line_delivery_state.view_order_form
msgid "Delivery State"
msgstr "Estado de entrega"
#. module: sale_order_line_delivery_state
#: model:ir.model.fields.selection,name:sale_order_line_delivery_state.selection__sale_order_line__delivery_state__done
msgid "Done"
msgstr "Hecho"
#. module: sale_order_line_delivery_state
#: model:ir.model.fields,field_description:sale_order_line_delivery_state.field_sale_order_line__force_delivery_state
msgid "Force Delivery State"
msgstr "Forzar estado de envío"
#. module: sale_order_line_delivery_state
#: model_terms:ir.ui.view,arch_db:sale_order_line_delivery_state.view_order_form
msgid "Force delivery done"
msgstr "Forzar envío realizado"
#. module: sale_order_line_delivery_state
#: model:ir.model.fields.selection,name:sale_order_line_delivery_state.selection__sale_order_line__delivery_state__no
msgid "No delivery"
msgstr "No enviado"
#. module: sale_order_line_delivery_state
#: model:ir.model.fields.selection,name:sale_order_line_delivery_state.selection__sale_order_line__delivery_state__partially
msgid "Partially processed"
msgstr "Parcialmente procesado"
#. module: sale_order_line_delivery_state
#: model:ir.model,name:sale_order_line_delivery_state.model_sale_order_line
msgid "Sales Order Line"
msgstr "Línea de Orden de Venta"
#. module: sale_order_line_delivery_state
#: model_terms:ir.ui.view,arch_db:sale_order_line_delivery_state.view_order_form
msgid "Unforce delivery done"
msgstr "No forzar envío realizado"
#. module: sale_order_line_delivery_state
#: model:ir.model.fields.selection,name:sale_order_line_delivery_state.selection__sale_order_line__delivery_state__unprocessed
msgid "Unprocessed"
msgstr "No procesado"

View File

@@ -0,0 +1,72 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_order_line_delivery_state
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2023-12-12 14:34+0000\n"
"Last-Translator: mymage <stefano.consolaro@mymage.it>\n"
"Language-Team: none\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.17\n"
#. module: sale_order_line_delivery_state
#: model:ir.model.fields,help:sale_order_line_delivery_state.field_sale_order_line__force_delivery_state
msgid ""
"Allow to enforce done state of delivery, for instance if some quantities "
"were cancelled"
msgstr ""
"Consente di forzare lo stato di consegna ad evasa, ad esempio se alcune "
"quantità sono state annullate"
#. module: sale_order_line_delivery_state
#: model:ir.model.fields,field_description:sale_order_line_delivery_state.field_sale_order_line__delivery_state
#: model_terms:ir.ui.view,arch_db:sale_order_line_delivery_state.view_order_form
msgid "Delivery State"
msgstr "Stato di consegna"
#. module: sale_order_line_delivery_state
#: model:ir.model.fields.selection,name:sale_order_line_delivery_state.selection__sale_order_line__delivery_state__done
msgid "Done"
msgstr "Evasa"
#. module: sale_order_line_delivery_state
#: model:ir.model.fields,field_description:sale_order_line_delivery_state.field_sale_order_line__force_delivery_state
msgid "Force Delivery State"
msgstr "Forza lo stato della consegna"
#. module: sale_order_line_delivery_state
#: model_terms:ir.ui.view,arch_db:sale_order_line_delivery_state.view_order_form
msgid "Force delivery done"
msgstr "Forza la consegna ad evasa"
#. module: sale_order_line_delivery_state
#: model:ir.model.fields.selection,name:sale_order_line_delivery_state.selection__sale_order_line__delivery_state__no
msgid "No delivery"
msgstr "Nessuna consegna"
#. module: sale_order_line_delivery_state
#: model:ir.model.fields.selection,name:sale_order_line_delivery_state.selection__sale_order_line__delivery_state__partially
msgid "Partially processed"
msgstr "Parzialmente processata"
#. module: sale_order_line_delivery_state
#: model:ir.model,name:sale_order_line_delivery_state.model_sale_order_line
msgid "Sales Order Line"
msgstr "Riga ordine di vendita"
#. module: sale_order_line_delivery_state
#: model_terms:ir.ui.view,arch_db:sale_order_line_delivery_state.view_order_form
msgid "Unforce delivery done"
msgstr "Annulla consegna evasa forzata"
#. module: sale_order_line_delivery_state
#: model:ir.model.fields.selection,name:sale_order_line_delivery_state.selection__sale_order_line__delivery_state__unprocessed
msgid "Unprocessed"
msgstr "Non processata"

View File

@@ -0,0 +1,68 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_order_line_delivery_state
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 18.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
"Language: pt\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
#. module: sale_order_line_delivery_state
#: model:ir.model.fields,help:sale_order_line_delivery_state.field_sale_order_line__force_delivery_state
msgid ""
"Allow to enforce done state of delivery, for instance if some quantities "
"were cancelled"
msgstr ""
#. module: sale_order_line_delivery_state
#: model:ir.model.fields,field_description:sale_order_line_delivery_state.field_sale_order_line__delivery_state
#: model_terms:ir.ui.view,arch_db:sale_order_line_delivery_state.view_order_form
msgid "Delivery State"
msgstr ""
#. module: sale_order_line_delivery_state
#: model:ir.model.fields.selection,name:sale_order_line_delivery_state.selection__sale_order_line__delivery_state__done
msgid "Done"
msgstr ""
#. module: sale_order_line_delivery_state
#: model:ir.model.fields,field_description:sale_order_line_delivery_state.field_sale_order_line__force_delivery_state
msgid "Force Delivery State"
msgstr ""
#. module: sale_order_line_delivery_state
#: model_terms:ir.ui.view,arch_db:sale_order_line_delivery_state.view_order_form
msgid "Force delivery done"
msgstr ""
#. module: sale_order_line_delivery_state
#: model:ir.model.fields.selection,name:sale_order_line_delivery_state.selection__sale_order_line__delivery_state__no
msgid "No delivery"
msgstr ""
#. module: sale_order_line_delivery_state
#: model:ir.model.fields.selection,name:sale_order_line_delivery_state.selection__sale_order_line__delivery_state__partially
msgid "Partially processed"
msgstr ""
#. module: sale_order_line_delivery_state
#: model:ir.model,name:sale_order_line_delivery_state.model_sale_order_line
msgid "Sales Order Line"
msgstr ""
#. module: sale_order_line_delivery_state
#: model_terms:ir.ui.view,arch_db:sale_order_line_delivery_state.view_order_form
msgid "Unforce delivery done"
msgstr ""
#. module: sale_order_line_delivery_state
#: model:ir.model.fields.selection,name:sale_order_line_delivery_state.selection__sale_order_line__delivery_state__unprocessed
msgid "Unprocessed"
msgstr ""

View File

@@ -0,0 +1,67 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_order_line_delivery_state
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 18.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: sale_order_line_delivery_state
#: model:ir.model.fields,help:sale_order_line_delivery_state.field_sale_order_line__force_delivery_state
msgid ""
"Allow to enforce done state of delivery, for instance if some quantities "
"were cancelled"
msgstr ""
#. module: sale_order_line_delivery_state
#: model:ir.model.fields,field_description:sale_order_line_delivery_state.field_sale_order_line__delivery_state
#: model_terms:ir.ui.view,arch_db:sale_order_line_delivery_state.view_order_form
msgid "Delivery State"
msgstr ""
#. module: sale_order_line_delivery_state
#: model:ir.model.fields.selection,name:sale_order_line_delivery_state.selection__sale_order_line__delivery_state__done
msgid "Done"
msgstr ""
#. module: sale_order_line_delivery_state
#: model:ir.model.fields,field_description:sale_order_line_delivery_state.field_sale_order_line__force_delivery_state
msgid "Force Delivery State"
msgstr ""
#. module: sale_order_line_delivery_state
#: model_terms:ir.ui.view,arch_db:sale_order_line_delivery_state.view_order_form
msgid "Force delivery done"
msgstr ""
#. module: sale_order_line_delivery_state
#: model:ir.model.fields.selection,name:sale_order_line_delivery_state.selection__sale_order_line__delivery_state__no
msgid "No delivery"
msgstr ""
#. module: sale_order_line_delivery_state
#: model:ir.model.fields.selection,name:sale_order_line_delivery_state.selection__sale_order_line__delivery_state__partially
msgid "Partially processed"
msgstr ""
#. module: sale_order_line_delivery_state
#: model:ir.model,name:sale_order_line_delivery_state.model_sale_order_line
msgid "Sales Order Line"
msgstr ""
#. module: sale_order_line_delivery_state
#: model_terms:ir.ui.view,arch_db:sale_order_line_delivery_state.view_order_form
msgid "Unforce delivery done"
msgstr ""
#. module: sale_order_line_delivery_state
#: model:ir.model.fields.selection,name:sale_order_line_delivery_state.selection__sale_order_line__delivery_state__unprocessed
msgid "Unprocessed"
msgstr ""

View File

@@ -0,0 +1 @@
from . import sale_order_line

View File

@@ -0,0 +1,79 @@
# Copyright 2021 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
from odoo.tools import float_compare, float_is_zero
class SaleOrderLine(models.Model):
_inherit = "sale.order.line"
delivery_state = fields.Selection(
[
("no", "No delivery"),
("unprocessed", "Unprocessed"),
("partially", "Partially processed"),
("done", "Done"),
],
compute="_compute_delivery_state",
store=True,
)
force_delivery_state = fields.Boolean(
help=(
"Allow to enforce done state of delivery, for instance if some"
" quantities were cancelled"
),
)
def _all_qty_delivered(self):
"""
Returns True if line has qty_delivered >= to ordered quantities
:returns: boolean
"""
self.ensure_one()
precision = self.env["decimal.precision"].precision_get(
"Product Unit of Measure"
)
return (
float_compare(
self.qty_delivered, self.product_uom_qty, precision_digits=precision
)
>= 0
)
def _partially_delivered(self):
"""
Returns True if line has qty_delivered != to 0 and < ordered
quantities.
:returns: boolean
"""
self.ensure_one()
precision = self.env["decimal.precision"].precision_get(
"Product Unit of Measure"
)
return not float_is_zero(self.qty_delivered, precision_digits=precision)
@api.depends("qty_delivered", "state", "force_delivery_state")
def _compute_delivery_state(self):
"""
If `delivery` module is installed, lines with delivery costs are marked
as 'No delivery'.
"""
for line in self:
if line.state in ("draft", "cancel") or line._is_delivery():
line.delivery_state = "no"
elif line.force_delivery_state or line._all_qty_delivered():
line.delivery_state = "done"
elif line._partially_delivered():
line.delivery_state = "partially"
else:
line.delivery_state = "unprocessed"
def action_force_delivery_state(self):
self.write({"force_delivery_state": True})
def action_unforce_delivery_state(self):
self.write({"force_delivery_state": False})

View File

@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"

View File

@@ -0,0 +1 @@
- Jordi Masvidal \<<jordi.masvidal@forgeflow.com>\>

View File

@@ -0,0 +1,18 @@
This odoo module add delivery state on the sale order line. It is based
on the module sale_delivery_state, which adds the field at sale order
level.
Delivery state is computed based on qty_delivered field on sale order
line.
The state of the sale order line can be forced to fully delivered in
case some quantities were cancelled by the customer and you consider you
have nothing more to deliver.
Sale order lines can have products or services, as long as the field
qty_delivered is set, it will trigger the computation of delivery state.
This module also works with delivery.carrier fees that are added as a
sale order line. Thoses line are special as they will never be
considered delivered. Delivery fees lines are ignored in the computation
of the delivery state.

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -0,0 +1,436 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>Sale Order Line Delivery State</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic, pre.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="sale-order-line-delivery-state">
<h1 class="title">Sale Order Line Delivery State</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:5591acba48ee389bf9b63755ce827cf25cd0381d7ffb5a2ab3110e05cc289079
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<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/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/sale-workflow/tree/18.0/sale_order_line_delivery_state"><img alt="OCA/sale-workflow" src="https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/sale-workflow-18-0/sale-workflow-18-0-sale_order_line_delivery_state"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/sale-workflow&amp;target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This odoo module add delivery state on the sale order line. It is based
on the module sale_delivery_state, which adds the field at sale order
level.</p>
<p>Delivery state is computed based on qty_delivered field on sale order
line.</p>
<p>The state of the sale order line can be forced to fully delivered in
case some quantities were cancelled by the customer and you consider you
have nothing more to deliver.</p>
<p>Sale order lines can have products or services, as long as the field
qty_delivered is set, it will trigger the computation of delivery state.</p>
<p>This module also works with delivery.carrier fees that are added as a
sale order line. Thoses line are special as they will never be
considered delivered. Delivery fees lines are ignored in the computation
of the delivery state.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-1">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-2">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-3">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-4">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-5">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-1">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/sale-workflow/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/OCA/sale-workflow/issues/new?body=module:%20sale_order_line_delivery_state%0Aversion:%2018.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">
<h1><a class="toc-backref" href="#toc-entry-2">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#toc-entry-3">Authors</a></h2>
<ul class="simple">
<li>ForgeFlow</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#toc-entry-4">Contributors</a></h2>
<ul class="simple">
<li>Jordi Masvidal &lt;<a class="reference external" href="mailto:jordi.masvidal&#64;forgeflow.com">jordi.masvidal&#64;forgeflow.com</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-5">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/sale-workflow/tree/18.0/sale_order_line_delivery_state">OCA/sale-workflow</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1 @@
from . import test_sale_line_delivery_state

View File

@@ -0,0 +1,115 @@
# Copyright 2021 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from unittest import mock
from odoo.tests import TransactionCase
class TestSaleLineDeliveryState(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
# Base data
partner = cls.env.ref("base.res_partner_2")
product = cls.env.ref("product.product_product_25")
pricelist = cls.env["product.pricelist"].create({"name": "Test Pricelist"})
cls.uom = cls.env.ref("uom.product_uom_unit")
# Create delivery product
cls.delivery_cost = cls.env["product.product"].create(
{"name": "delivery", "type": "service"}
)
# Create sales order
cls.order = cls.env["sale.order"].create(
{
"partner_id": partner.id,
"pricelist_id": pricelist.id,
"order_line": [
(
0,
0,
{
"product_id": product.id,
"product_uom": cls.uom.id,
"product_uom_qty": 3,
"price_unit": 2950.00,
"name": product.name,
},
)
],
}
)
def _mock_delivery(self, delivery_prod=None):
delivery_prod = delivery_prod or self.delivery_cost
return mock.patch.object(
type(self.env["sale.order.line"]),
"_is_delivery",
lambda self: self.product_id == delivery_prod,
)
def _add_delivery_cost_line(self):
self.env["sale.order.line"].create(
{
"order_id": self.order.id,
"name": "Delivery cost",
"product_id": self.delivery_cost.id,
"product_uom_qty": 1,
"product_uom": self.uom.id,
"price_unit": 10.0,
}
)
def test_no_delivery(self):
self.assertEqual(self.order.order_line[0].delivery_state, "no")
def test_unprocessed_delivery(self):
self.order.action_confirm()
self.assertEqual(self.order.order_line[0].delivery_state, "unprocessed")
def test_partially(self):
self.order.action_confirm()
self.order.order_line[0].qty_delivered = 2
self.assertEqual(self.order.order_line[0].delivery_state, "partially")
def test_delivery_done(self):
self.order.action_confirm()
self.order.order_line[0].qty_delivered = 3
self.assertEqual(self.order.order_line[0].delivery_state, "done")
def test_no_delivery_delivery_cost(self):
self._add_delivery_cost_line()
with self._mock_delivery():
self.assertEqual(self.order.order_line[1].delivery_state, "no")
def test_unprocessed_delivery_delivery_cost(self):
self._add_delivery_cost_line()
with self._mock_delivery():
self.order.action_confirm()
self.assertEqual(self.order.order_line[0].delivery_state, "unprocessed")
self.assertEqual(self.order.order_line[1].delivery_state, "no")
def test_partially_delivery_cost(self):
self._add_delivery_cost_line()
with self._mock_delivery():
self.order.action_confirm()
self.order.order_line[0].qty_delivered = 2
self.assertEqual(self.order.order_line[0].delivery_state, "partially")
self.assertEqual(self.order.order_line[1].delivery_state, "no")
def test_forced_delivery_cost(self):
self._add_delivery_cost_line()
with self._mock_delivery():
self.order.action_confirm()
self.order.order_line[0].qty_delivered = 2
self.order.order_line[0].force_delivery_state = True
self.assertEqual(self.order.order_line[0].delivery_state, "done")
def test_delivery_done_delivery_cost(self):
self._add_delivery_cost_line()
with self._mock_delivery():
self.order.action_confirm()
self.order.order_line[0].qty_delivered = 3
self.assertEqual(self.order.order_line[0].delivery_state, "done")
self.assertEqual(self.order.order_line[1].delivery_state, "no")

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="view_order_form" model="ir.ui.view">
<field name="name">sale.order.form - sale_order_line_delivery_state</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']/form/group/group/div[@name='delivered_qty']"
position="after"
>
<label for="delivery_state" string="Delivery State" />
<div name="delivery_state">
<field name="force_delivery_state" invisible="True" />
<field name="delivery_state" readonly="True" />
<button
name="action_force_delivery_state"
type="object"
string="Force delivery done"
invisible="force_delivery_state or state != 'done' or delivery_state == 'done'"
/>
<button
name="action_unforce_delivery_state"
type="object"
string="Unforce delivery done"
invisible="not force_delivery_state or state != 'done'"
/>
</div>
</xpath>
<xpath expr="//field[@name='order_line']/list" position="inside">
<field name="delivery_state" readonly="True" optional="hide" />
</xpath>
</field>
</record>
</odoo>