Skip to content

Commit

Permalink
[15.0][ADD] stock_delivery_sale_section_and_note
Browse files Browse the repository at this point in the history
  • Loading branch information
StephaneMangin committed Oct 17, 2023
1 parent 80d4dcd commit 9110822
Show file tree
Hide file tree
Showing 15 changed files with 575 additions and 0 deletions.
6 changes: 6 additions & 0 deletions setup/stock_delivery_sale_section_and_note/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import setuptools

setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)
89 changes: 89 additions & 0 deletions stock_delivery_sale_section_and_note/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
====================================
Stock Delivery Sale Section and Note
====================================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:117e560ba1a33402e2ec5aa947ffdd9b27331c9e3d26436bfe0f301c8336663f
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png
:target: https://odoo-community.org/page/development-status
:alt: Production/Stable
.. |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%2Fstock--logistics--workflow-lightgray.png?logo=github
:target: https://github.com/OCA/stock-logistics-workflow/tree/15.0/stock_delivery_sale_section_and_note
:alt: OCA/stock-logistics-workflow
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/stock-logistics-workflow-15-0/stock-logistics-workflow-15-0-stock_delivery_sale_section_and_note
: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/stock-logistics-workflow&target_branch=15.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module provides the propagation of sale order sections/notes lines to
the delivery slip reports.

**Table of contents**

.. contents::
:local:

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/stock-logistics-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/stock-logistics-workflow/issues/new?body=module:%20stock_delivery_sale_section_and_note%0Aversion:%2015.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
~~~~~~~

* Camptocamp

Contributors
~~~~~~~~~~~~

* Stéphane Mangin <stephane.mangin@camptocamp.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.

.. |maintainer-carlosdauden| image:: https://github.com/carlosdauden.png?size=40px
:target: https://github.com/carlosdauden
:alt: carlosdauden
.. |maintainer-sergio-teruel| image:: https://github.com/sergio-teruel.png?size=40px
:target: https://github.com/sergio-teruel
:alt: sergio-teruel

Current `maintainers <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-carlosdauden| |maintainer-sergio-teruel|

This module is part of the `OCA/stock-logistics-workflow <https://github.com/OCA/stock-logistics-workflow/tree/15.0/stock_delivery_sale_section_and_note>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions stock_delivery_sale_section_and_note/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
20 changes: 20 additions & 0 deletions stock_delivery_sale_section_and_note/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "Stock Delivery Sale Section and Note",
"version": "15.0.1.0.0",
"author": "Camptocamp, Odoo Community Association (OCA)",
"license": "AGPL-3",
"category": "Delivery",
"depends": [
"delivery",
"sale_section_and_note_revamp",
"sale_stock",
"stock",
],
"website": "https://github.com/OCA/stock-logistics-reporting",
"data": [
"reports/report_deliveryslip.xml",
],
"installable": True,
"auto_install": False,
"application": False,
}
2 changes: 2 additions & 0 deletions stock_delivery_sale_section_and_note/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import stock_move
from . import stock_move_line
37 changes: 37 additions & 0 deletions stock_delivery_sale_section_and_note/models/stock_move.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Copyright 2023 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
import datetime

from odoo import fields, models


class StockMove(models.Model):
_name = "stock.move"
_inherit = ["stock.move", "display.line.mixin"]

sequence = fields.Integer(related="sale_line_id.sequence", store=True)
previous_line_id = fields.Many2one(related="sale_line_id.previous_line_id")
next_line_id = fields.Many2one(related="sale_line_id.next_line_id")

def prepare_section_or_note_values(self, order_line):
"""This method is intended to be used to `convert` a display line to
the current model
It is mainly used for display lines injection to delivery reports
"""
self.ensure_one()
assert self.is_section_or_note()
related_order_line = self.sale_line_id
return {
"sequence": order_line.sequence,
"display_type": order_line.display_type,
"name": order_line.name,
"date": datetime.datetime.now(),
"company_id": order_line.company_id.id,
"product_id": related_order_line.product_id.id,
"product_uom_qty": 0,
"product_uom": related_order_line.product_uom.id,
"location_id": False,
"location_dest_id": False,
"procure_method": False,
}
162 changes: 162 additions & 0 deletions stock_delivery_sale_section_and_note/models/stock_move_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# Copyright 2023 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)

from collections import OrderedDict

from odoo import fields, models
from odoo.tools.float_utils import float_is_zero


def get_aggregated_properties(move_line=False, move=False):
"""Taken from stock.models.stock_move_line._get_aggregated_product_quantities"""
move = move or move_line.move_id
uom = move.product_uom or move_line.product_uom_id
name = move.product_id.display_name
description = move.description_picking
if description == name or description == move.product_id.name:
description = False
product = move.product_id
line_key = f"{product.id}_{product.display_name}_{description or ''}_{uom.id}"
return (line_key, name, description, uom)


class StockMoveLine(models.Model):
_name = "stock.move.line"
_inherit = ["stock.move.line", "display.line.mixin"]

sequence = fields.Integer(related="move_id.sequence", store=True)
previous_line_id = fields.Many2one(related="move_id.previous_line_id")
next_line_id = fields.Many2one(related="move_id.next_line_id")

def prepare_section_or_note_values(self, order_line):
"""This method is intended to be used to `convert` a display line to
the current model
It is mainly used for display lines injection to delivery reports
"""
self.ensure_one()
assert self.is_section_or_note()
related_order_line = self.move_id.sale_line_id
return {
"sequence": order_line.sequence,
"display_type": order_line.display_type,
"display_class": order_line.get_section_or_note_class(),
"name": order_line.name,
"description": order_line.name,
"qty_done": 0,
"qty_ordered": 0,
"product_uom_id": related_order_line.product_uom.id,
"product_id": related_order_line.product_id.id,
}

def _aggregate_sections_and_notes(self, aggregated_move_lines, done_line_keys):
"""Insert at the right position any sections or notes related
to a move_line
:param aggregated_move_lines: the aggregated dict of lines
:param done_line_keys: a list of line keys to avoid to process twice
"""
line_key, name, description, uom = get_aggregated_properties(move_line=self)
if line_key in done_line_keys:
return done_line_keys, aggregated_move_lines
done_line_keys.add(line_key)

total_lines = len(aggregated_move_lines)
# Manage positionning and itemization
pos = list(aggregated_move_lines.keys()).index(line_key)
items = list(aggregated_move_lines.items())
previous_record = self.previous_line_id
while previous_record:
line_key = f"{previous_record.id}_{previous_record.display_type}"
if line_key not in done_line_keys:
if previous_record.is_section_or_note():
values = self.prepare_section_or_note_values(previous_record)
items.insert(pos, (line_key, values))
done_line_keys.add(line_key)
previous_record = previous_record.previous_line_id

# Then we manage the last line to include any remaining section/notes
if (pos + 1) == total_lines:
next_record = self.next_line_id
while next_record:
line_key = f"{next_record.id}_{next_record.display_type}"
if line_key not in done_line_keys:
if next_record.is_section_or_note():
values = self.prepare_section_or_note_values(next_record)
items.append((line_key, values))
done_line_keys.add(line_key)
next_record = next_record.next_line_id

# Reconstuction
return done_line_keys, dict(items)

def _reordered_aggregated_product_quantities(self, **kwargs):
"""Regain the sequence ordering from sale order lines
Needed for proper section and notes positioning
Beware ! this method calls super()._get_aggregated_product_quantities
which is overriden below
"""
super_aggregated_move_lines = super()._get_aggregated_product_quantities(
**kwargs
)
new_aggregated_move_lines = OrderedDict()
for move_line in self.sorted("sequence"):
line_key, name, description, uom = get_aggregated_properties(
move_line=move_line
)
agg_move_value = super_aggregated_move_lines.get(line_key)
new_aggregated_move_lines[line_key] = agg_move_value
return new_aggregated_move_lines

def _get_aggregated_product_quantities(self, **kwargs):
"""This code partially take the content of the super method
Especially for behaviors:
- get_aggregated_properties subfonction
- except_package context option
- canceled or null quantity picking move lines
"""
aggregated_move_lines = self._reordered_aggregated_product_quantities(**kwargs)

# Keep track of section to be shown only once
done_line_keys = set()
for move_line in self.sorted("sequence"):
if kwargs.get("except_package") and move_line.result_package_id:
continue
(
done_line_keys,
aggregated_move_lines,
) = move_line._aggregate_sections_and_notes(
aggregated_move_lines, done_line_keys
)

if kwargs.get("strict"):
return aggregated_move_lines

# Loops to get backorders, backorders" backorders, and so and so...
backorders = self.env["stock.picking"]
pickings = self.picking_id
while pickings.backorder_ids:
backorders |= pickings.backorder_ids
pickings = pickings.backorder_ids

pickings = self.picking_id | backorders
for empty_move in pickings.move_lines.sorted("sequence"):
if not (
empty_move.state == "cancel"
and empty_move.product_uom_qty
and float_is_zero(
empty_move.quantity_done,
precision_rounding=empty_move.product_uom.rounding,
)
):
continue
(
done_line_keys,
aggregated_move_lines,
) = empty_move._aggregate_sections_and_notes(
aggregated_move_lines, done_line_keys
)

return aggregated_move_lines
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Stéphane Mangin <stephane.mangin@camptocamp.com>
2 changes: 2 additions & 0 deletions stock_delivery_sale_section_and_note/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This module provides the propagation of sale order sections/notes lines to
the delivery slip reports.
Loading

0 comments on commit 9110822

Please sign in to comment.