Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[14.0][IMP] add delivery_nfe volumes #3091

Merged
merged 4 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions l10n_br_delivery_nfe/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ Authors
~~~~~~~

* Akretion
* KMEE

Contributors
~~~~~~~~~~~~
Expand All @@ -84,6 +85,10 @@ Contributors

* Magno Costa <[email protected]>

* `KMEE <https://www.kmee.com.br>`_:

* Diego Paradeda <[email protected]>

Maintainers
~~~~~~~~~~~

Expand Down
1 change: 1 addition & 0 deletions l10n_br_delivery_nfe/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from . import models
from . import wizards
20 changes: 17 additions & 3 deletions l10n_br_delivery_nfe/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,28 @@
"name": "Brazilian Localization Delivery NFe",
"category": "Localisation",
"license": "AGPL-3",
"author": "Akretion, Odoo Community Association (OCA)",
"author": "Akretion, KMEE, Odoo Community Association (OCA)",
"maintainers": ["mbcosta"],
"website": "https://github.com/OCA/l10n-brazil",
"version": "14.0.1.1.0",
"depends": ["l10n_br_nfe", "l10n_br_account", "l10n_br_delivery"],
"depends": [
"l10n_br_nfe",
"l10n_br_account",
"l10n_br_delivery",
"product_net_weight",
DiegoParadeda marked this conversation as resolved.
Show resolved Hide resolved
"product_brand",
],
"data": [
# Security
"security/ir.model.access.csv",
# Wizards
"wizards/stock_invoice_onshipping_view.xml",
"wizards/stock_generate_volumes_view.xml",
# Views
"views/nfe_document_view.xml"
"views/nfe_document_view.xml",
"views/product_product_view.xml",
"views/product_template_view.xml",
"views/stock_picking_view.xml",
],
"installable": True,
"auto_install": True,
Expand Down
5 changes: 5 additions & 0 deletions l10n_br_delivery_nfe/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
from . import document
from . import product_product
from . import product_template
from . import stock_picking_vol
from . import stock_picking_lacres
from . import stock_picking
13 changes: 13 additions & 0 deletions l10n_br_delivery_nfe/models/product_product.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright (C) 2024 Diego Paradeda - KMEE
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html

from odoo import fields, models


class ProductProduct(models.Model):
_inherit = "product.product"

product_volume_type = fields.Char(
string="Volume Type",
help="Type of transported volumes: Mapped onto 'nfe40_esp'",
)
35 changes: 35 additions & 0 deletions l10n_br_delivery_nfe/models/product_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Copyright (C) 2024 Diego Paradeda - KMEE
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html

from odoo import api, fields, models


class ProductTemplate(models.Model):
_inherit = "product.template"

product_volume_type = fields.Char(
string="Volume Type",
help="Type of transported volumes: Mapped onto 'nfe40_esp'",
compute="_compute_product_volume_type",
inverse="_inverse_product_volume_type",
store=True,
)

@api.depends("product_variant_ids", "product_variant_ids.product_volume_type")
def _compute_product_volume_type(self):
unique_variants = self.filtered(
lambda template: len(template.product_variant_ids) == 1
)
for template in unique_variants:
template.product_volume_type = (
template.product_variant_ids.product_volume_type
)
for template in self - unique_variants:
template.product_volume_type = ""

def _inverse_product_volume_type(self):
for template in self:
if len(template.product_variant_ids) == 1:
template.product_variant_ids.product_volume_type = (

Check warning on line 33 in l10n_br_delivery_nfe/models/product_template.py

View check run for this annotation

Codecov / codecov/patch

l10n_br_delivery_nfe/models/product_template.py#L33

Added line #L33 was not covered by tests
template.product_volume_type
)
137 changes: 137 additions & 0 deletions l10n_br_delivery_nfe/models/stock_picking.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# Copyright (C) 2024 Diego Paradeda - KMEE
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import fields, models


class StockPicking(models.Model):
_inherit = "stock.picking"

has_vol = fields.Boolean(
string="Has Vol IDs",
DiegoParadeda marked this conversation as resolved.
Show resolved Hide resolved
help="Technical Field: True if the picking has already generated Volume IDs.",
copy=False,
)

vol_ids = fields.One2many(
string="Volume Data",
comodel_name="stock.picking.vol",
inverse_name="picking_id",
copy=False,
)

number_of_volumes = fields.Integer(
string="Number of Volumes",
DiegoParadeda marked this conversation as resolved.
Show resolved Hide resolved
default=0,
copy=False,
)

def _get_volume_data_package_level(self):
"""Generate a single volume for packages"""
vols_data = []
for picking_id in self:
if picking_id.package_ids:
for package_level_id in picking_id.package_level_ids:
manual_weight = package_level_id.package_id.shipping_weight
vol_data = {
"nfe40_qVol": 1,
"nfe40_esp": "",
"nfe40_marca": "",
"nfe40_pesoL": 0,
"nfe40_pesoB": (manual_weight if manual_weight else 0),
"picking_id": picking_id.id,
}

for line in package_level_id.move_line_ids:
vol_data["nfe40_esp"] = (
vol_data["nfe40_esp"] or line.product_id.product_volume_type
)
product_nfe40_marca = (
line.product_id.product_brand_id.name
if line.product_id.product_brand_id
else ""
)
vol_data["nfe40_marca"] = (
vol_data["nfe40_marca"] or product_nfe40_marca
)
pesoL = line.qty_done * line.product_id.net_weight
pesoB = line.qty_done * line.product_id.weight
vol_data["nfe40_pesoL"] += pesoL
vol_data["nfe40_pesoB"] += 0 if manual_weight else pesoB
vols_data.append(vol_data)

return vols_data

def _get_volume_data_wo_package(self):
"""Generate a single volume for lines without package"""
vols_data = []
for picking_id in self:
# Filter out move lines with in a package
if not picking_id.move_line_ids_without_package.filtered(
lambda ml: not ml.package_level_id
):
continue

new_vol = {
"nfe40_qVol": 0,
"nfe40_esp": "",
"nfe40_marca": "",
"nfe40_pesoL": 0,
"nfe40_pesoB": 0,
"picking_id": picking_id.id,
}

for line in picking_id.move_line_ids_without_package.filtered(
lambda ml: not ml.package_level_id and not ml.result_package_id
):
new_vol["nfe40_qVol"] += line.qty_done
new_vol["nfe40_esp"] = (
new_vol["nfe40_esp"] or line.product_id.product_volume_type
)
product_nfe40_marca = (
line.product_id.product_brand_id.name
if line.product_id.product_brand_id
else ""
)
new_vol["nfe40_marca"] = new_vol["nfe40_marca"] or product_nfe40_marca
pesoL = line.qty_done * line.product_id.net_weight
pesoB = line.qty_done * line.product_id.weight
new_vol["nfe40_pesoL"] += pesoL
new_vol["nfe40_pesoB"] += pesoB

new_vol["nfe40_qVol"] = f"{new_vol['nfe40_qVol']:.0f}"
vols_data.append(new_vol)

return vols_data

def _get_pre_generated_volumes(self):
"""Retreive and convert already generated volumes that are stored on picking"""
vols_data = []
for picking_id in self:
for vol_id in picking_id.vol_ids:
vol_data = vol_id.copy_data()[0]
vols_data.append(vol_data)

Check warning on line 112 in l10n_br_delivery_nfe/models/stock_picking.py

View check run for this annotation

Codecov / codecov/patch

l10n_br_delivery_nfe/models/stock_picking.py#L111-L112

Added lines #L111 - L112 were not covered by tests
return vols_data

def prepare_vols_data_from_picking(self):
pre_generated_pickings = self.filtered(lambda p: p.has_vol)
to_generate_pickings = self.filtered(lambda p: not p.has_vol)

vols_data = []
vols_data += pre_generated_pickings._get_pre_generated_volumes()
vols_data += to_generate_pickings._get_volume_data_package_level()
vols_data += to_generate_pickings._get_volume_data_wo_package()
return vols_data

def _compute_number_of_volumes(self):
for picking in self:
if len(picking.invoice_ids) == 1:
picking.number_of_volumes = sum(
[
float(v)
for v in picking.invoice_ids.mapped(
"fiscal_document_id.nfe40_vol.nfe40_qVol"
)
]
)
else:
picking.number_of_volumes = 0

Check warning on line 137 in l10n_br_delivery_nfe/models/stock_picking.py

View check run for this annotation

Codecov / codecov/patch

l10n_br_delivery_nfe/models/stock_picking.py#L137

Added line #L137 was not covered by tests
24 changes: 24 additions & 0 deletions l10n_br_delivery_nfe/models/stock_picking_lacres.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright (C) 2024 Diego Paradeda - KMEE
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html

from odoo import fields, models


class StockPickingLacres(models.Model):
_name = "stock.picking.lacres"
DiegoParadeda marked this conversation as resolved.
Show resolved Hide resolved
_description = "lacres"
# _inherit = "nfe.40.lacres" TODO: consider using inherit in the future

"""
NFe40 fields start
##################
this section copies fields from nfe.40.vol
sadly, _name/_inherit breaks spec_model
inheriting would be better than recreating the same fields.
"""
nfe40_lacres_vol_id = fields.Many2one(comodel_name="stock.picking.vol")
nfe40_nLacre = fields.Char(string="Número dos Lacres")
"""
NFe40 fields end
################
"""
53 changes: 53 additions & 0 deletions l10n_br_delivery_nfe/models/stock_picking_vol.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Copyright (C) 2024 Diego Paradeda - KMEE
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html

from odoo import fields, models


class StockPickingVol(models.Model):
_name = "stock.picking.vol"
_description = "Volume Data"
# _inherit = "nfe.40.vol" TODO: consider using inherit in the future

"""
NFe40 fields start
##################
this section copies fields from nfe.40.vol
sadly, _name/_inherit breaks spec_model
inheriting would be better than recreating the same fields.
TODO: learn how to inherit nfe mixin (https://github.com/OCA/l10n-brazil/pull/3091)
"""
nfe40_vol_transp_id = fields.Many2one(comodel_name="nfe.40.transp")
nfe40_qVol = fields.Char(string="Quantidade de volumes transportados")
nfe40_esp = fields.Char(string="Espécie dos volumes transportados")
nfe40_marca = fields.Char(string="Marca dos volumes transportados")
nfe40_nVol = fields.Char(string="Numeração dos volumes transportados")

nfe40_pesoL = fields.Float(
string="Peso líquido (em kg)",
digits=(
12,
3,
),
)

nfe40_pesoB = fields.Float(
string="Peso bruto (em kg)",
digits=(
12,
3,
),
)

nfe40_lacres = fields.One2many(
"stock.picking.lacres", "nfe40_lacres_vol_id", string="lacres"
)
"""
NFe40 fields end
################
"""

picking_id = fields.Many2one(
comodel_name="stock.picking",
string="Stock Picking",
)
4 changes: 4 additions & 0 deletions l10n_br_delivery_nfe/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
* `Akretion <https://www.akretion.com/pt-BR>`_:

* Magno Costa <[email protected]>

* `KMEE <https://www.kmee.com.br>`_:

* Diego Paradeda <[email protected]>
6 changes: 6 additions & 0 deletions l10n_br_delivery_nfe/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
l10n_br_delivery_nfe_onshipping_vol,l10n_br_delivery_nfe.onshipping_vol,l10n_br_delivery_nfe.model_stock_invoice_onshipping_vol,stock.group_stock_user,1,1,1,1
l10n_br_delivery_nfe_onshipping_lacres,l10n_br_delivery_nfe.onshipping_lacres,l10n_br_delivery_nfe.model_stock_invoice_onshipping_lacres,stock.group_stock_user,1,1,1,1
l10n_br_delivery_nfe_stock_generate_volumes,l10n_br_delivery_nfe.stock_generate_volumes,l10n_br_delivery_nfe.model_stock_generate_volumes,stock.group_stock_user,1,1,1,1
l10n_br_delivery_nfe_stock_picking_vol,l10n_br_delivery_nfe.stock_picking_vol,l10n_br_delivery_nfe.model_stock_picking_vol,stock.group_stock_user,1,1,1,1
l10n_br_delivery_nfe_stock_picking_lacres,l10n_br_delivery_nfe.stock_picking_lacres,l10n_br_delivery_nfe.model_stock_picking_lacres,stock.group_stock_user,1,1,1,1
Loading
Loading