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

[REF] delivery: put_in_pack cleaning #30324

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
68 changes: 26 additions & 42 deletions addons/delivery/models/stock_picking.py
Expand Up @@ -37,28 +37,6 @@ def _compute_weight_uom_name(self):
shipping_weight = fields.Float(string='Shipping Weight', help="Total weight of the package.")


class StockMoveLine(models.Model):
arbaes marked this conversation as resolved.
Show resolved Hide resolved
_inherit = 'stock.move.line'

@api.multi
def manage_package_type(self):
self.ensure_one()
view_id = self.env.ref('delivery.choose_delivery_package_view_form').id
return {
'name': _('Package Details'),
'type': 'ir.actions.act_window',
'view_mode': 'form',
'res_model': 'choose.delivery.package',
'view_id': view_id,
'views': [(view_id, 'form')],
'target': 'new',
'context': {
'default_stock_quant_package_id': self.result_package_id.id,
'current_package_carrier_type': self.picking_id.carrier_id.delivery_type if self.picking_id.carrier_id.delivery_type not in ['base_on_rule', 'fixed'] else 'none',
}
}


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

Expand Down Expand Up @@ -135,29 +113,35 @@ def action_done(self):
return res

@api.multi
def put_in_pack(self):
res = super(StockPicking, self).put_in_pack()
if isinstance(res, dict) and res.get('type'):
return res
if self.carrier_id and self.carrier_id.delivery_type not in ['base_on_rule', 'fixed']:
view_id = self.env.ref('delivery.choose_delivery_package_view_form').id
return {
'name': _('Package Details'),
'type': 'ir.actions.act_window',
'view_mode': 'form',
'res_model': 'choose.delivery.package',
'view_id': view_id,
'views': [(view_id, 'form')],
'target': 'new',
'context': dict(
self.env.context,
current_package_carrier_type=self.carrier_id.delivery_type,
default_stock_quant_package_id=res.id
),
}
def _pre_put_in_pack_hook(self, move_line_ids):
res = super(StockPicking, self)._pre_put_in_pack_hook(move_line_ids)
if not res:
if self.carrier_id:
return self._set_delivery_packaging()
else:
return res

def _set_delivery_packaging(self):
sle-odoo marked this conversation as resolved.
Show resolved Hide resolved
""" This method returns an action allowing to set the product packaging and the shipping weight
on the stock.quant.package.
"""
self.ensure_one()
view_id = self.env.ref('delivery.choose_delivery_package_view_form').id
return {
'name': _('Package Details'),
'type': 'ir.actions.act_window',
'view_mode': 'form',
'res_model': 'choose.delivery.package',
'view_id': view_id,
'views': [(view_id, 'form')],
'target': 'new',
'context': dict(
self.env.context,
current_package_carrier_type=self.carrier_id.delivery_type,
default_picking_id=self.id
),
}

@api.multi
def action_send_confirmation_email(self):
self.ensure_one()
Expand Down
1 change: 1 addition & 0 deletions addons/delivery/tests/__init__.py
Expand Up @@ -2,3 +2,4 @@
# Part of Odoo. See LICENSE file for full copyright and licensing detailsself.

from . import test_delivery_cost, test_delivery_stock_move
from . import test_packing_delivery
74 changes: 74 additions & 0 deletions addons/delivery/tests/test_packing_delivery.py
@@ -0,0 +1,74 @@
from odoo.addons.stock.tests.test_packing import TestPacking


class TestPacking(TestPacking):

def setUp(self):
super(TestPacking, self).setUp()
self.uom_kg = self.env.ref('uom.product_uom_kgm')
self.product_aw = self.env['product.product'].create({
'name': 'Product AW',
'type': 'product',
'weight': 2.4,
'uom_id': self.uom_kg.id,
'uom_po_id': self.uom_kg.id
})
self.product_bw = self.env['product.product'].create({
'name': 'Product BW',
'type': 'product',
'weight': 0.3,
'uom_id': self.uom_kg.id,
'uom_po_id': self.uom_kg.id
})
test_carrier_product = self.env['product.product'].create({
'name': 'Test carrier product',
'type': 'service',
})
self.test_carrier = self.env['delivery.carrier'].create({
'name': 'Test carrier',
'delivery_type': 'fixed',
'product_id': test_carrier_product.id,
})

def test_put_in_pack_weight_wizard(self):
""" Check that de default weight is correctly set by default when using the 'choose.delivery.package' wizard.
This purpose of this wizard is
"""
self.env['stock.quant']._update_available_quantity(self.product_aw, self.stock_location, 20.0)
self.env['stock.quant']._update_available_quantity(self.product_bw, self.stock_location, 20.0)

picking_ship = self.env['stock.picking'].create({
'partner_id': self.env.ref('base.res_partner_2').id,
'picking_type_id': self.warehouse.out_type_id.id,
'location_id': self.stock_location.id,
'location_dest_id': self.customer_location.id,
'carrier_id': self.test_carrier.id
})
move_line_paw = self.env['stock.move.line'].create({
'product_id': self.product_aw.id,
'product_uom_id': self.uom_kg.id,
'picking_id': picking_ship.id,
'qty_done': 5,
'location_id': self.stock_location.id,
'location_dest_id': self.customer_location.id
})
move_line_pbw = self.env['stock.move.line'].create({
'product_id': self.product_bw.id,
'product_uom_id': self.uom_kg.id,
'picking_id': picking_ship.id,
'qty_done': 5,
'location_id': self.stock_location.id,
'location_dest_id': self.customer_location.id
})
picking_ship.action_confirm()
pack_action = picking_ship.put_in_pack()
pack_action_ctx = pack_action['context']
pack_action_model = pack_action['res_model']

# We make sure the correct action was returned
self.assertEquals(pack_action_model, 'choose.delivery.package')

# We instanciate the wizard with the context of the action and check that the
# default weight was set.
pack_wiz = self.env['choose.delivery.package'].with_context(pack_action_ctx).create({})
self.assertEquals(pack_wiz.shipping_weight, 13.5)
63 changes: 24 additions & 39 deletions addons/delivery/wizard/choose_delivery_package.py
Expand Up @@ -2,51 +2,31 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from odoo import api, fields, models, _
from odoo.tools.float_utils import float_compare


class ChooseDeliveryPackage(models.TransientModel):
_name = 'choose.delivery.package'
_description = 'Delivery Package Selection Wizard'

stock_quant_package_id = fields.Many2one(
'stock.quant.package',
string="Physical Package",
default=lambda self: self._default_stock_quant_package_id()
)
arbaes marked this conversation as resolved.
Show resolved Hide resolved
delivery_packaging_id = fields.Many2one(
'product.packaging',
default=lambda self: self._default_delivery_packaging_id()
)
shipping_weight = fields.Float(
string='Shipping Weight',
default=lambda self: self._default_shipping_weight()
)
weight_uom_name = fields.Char(string='Weight unit of measure label', compute='_compute_weight_uom_name')

def _default_stock_quant_package_id(self):
if self.env.context.get('default_stock_quant_package_id'):
return self.env['stock.quant.package'].browse(self.env.context['stock_quant_package_id'])

def _default_delivery_packaging_id(self):
res = None
if self.env.context.get('default_delivery_packaging_id'):
res = self.env['product.packaging'].browse(self.env.context['default_delivery_packaging_id'])
if self.env.context.get('default_stock_quant_package_id'):
stock_quant_package = self.env['stock.quant.package'].browse(self.env.context['default_stock_quant_package_id'])
res = stock_quant_package.packaging_id
return res

def _default_shipping_weight(self):
if self.env.context.get('default_stock_quant_package_id'):
stock_quant_package = self.env['stock.quant.package'].browse(self.env.context['default_stock_quant_package_id'])
return stock_quant_package.shipping_weight
else:
picking_id = self.env['stock.picking'].browse(self.env.context['active_id'])
move_line_ids = [po for po in picking_id.move_line_ids if po.qty_done > 0 and not po.result_package_id]
total_weight = sum([po.qty_done * po.product_id.weight for po in move_line_ids])
return total_weight
picking = self.env['stock.picking'].browse(self.env.context.get('default_picking_id'))
move_line_ids = picking.move_line_ids.filtered(lambda m:
float_compare(m.qty_done, 0.0, precision_rounding=m.product_uom_id.rounding) > 0
and not m.result_package_id
)
total_weight = 0.0
for ml in move_line_ids:
qty = ml.product_uom_id._compute_quantity(ml.qty_done, ml.product_id.uom_id)
total_weight += qty * ml.product_id.weight
return total_weight

picking_id = fields.Many2one('stock.picking', 'Picking')
delivery_packaging_id = fields.Many2one('product.packaging', 'Delivery Packaging')
shipping_weight = fields.Float('Shipping Weight', default=_default_shipping_weight)
weight_uom_name = fields.Char(string='Weight unit of measure label', compute='_compute_weight_uom_name')

@api.depends('stock_quant_package_id', 'delivery_packaging_id')
@api.depends('delivery_packaging_id')
def _compute_weight_uom_name(self):
weight_uom_id = self.env['product.template']._get_weight_uom_id_from_ir_config_parameter()
for package in self:
Expand All @@ -62,8 +42,13 @@ def _onchange_packaging_weight(self):
return {'warning': warning_mess}

def put_in_pack(self):
move_line_ids = self.picking_id.move_line_ids.filtered(lambda ml:
float_compare(ml.qty_done, 0.0, precision_rounding=ml.product_uom_id.rounding) > 0
and not ml.result_package_id
)
delivery_package = self.picking_id._put_in_pack(move_line_ids)
# write shipping weight and product_packaging on 'stock_quant_package' if needed
if self.delivery_packaging_id:
self.stock_quant_package_id.packaging_id = self.delivery_packaging_id
delivery_package.packaging_id = self.delivery_packaging_id
if self.shipping_weight:
self.stock_quant_package_id.shipping_weight = self.shipping_weight
delivery_package.shipping_weight = self.shipping_weight
89 changes: 48 additions & 41 deletions addons/stock/models/stock_picking.py
Expand Up @@ -1023,12 +1023,15 @@ def _explore(impacted_pickings, explored_moves, moves_to_explore):

return _explore(self.env['stock.picking'], self.env['stock.move'], moves)

def check_destinations(self):
if len(self.move_line_ids.filtered(lambda l: l.qty_done > 0 and not l.result_package_id).mapped('location_dest_id')) > 1:
def _pre_put_in_pack_hook(self, move_line_ids):
return self._check_destinations(move_line_ids)

def _check_destinations(self, move_line_ids):
if len(move_line_ids.mapped('location_dest_id')) > 1:
view_id = self.env.ref('stock.stock_package_destination_form_view').id
wiz = self.env['stock.package.destination'].create({
'picking_id': self.id,
'location_dest_id': self.move_line_ids[0].location_dest_id.id,
'location_dest_id': move_line_ids[0].location_dest_id.id,
})
return {
'name': _('Choose destination location'),
Expand All @@ -1044,48 +1047,52 @@ def check_destinations(self):
else:
return {}

def _put_in_pack(self):
def _put_in_pack(self, move_line_ids):
package = False
for pick in self.filtered(lambda p: p.state not in ('done', 'cancel')):
move_line_ids = pick.move_line_ids.filtered(lambda o: o.qty_done > 0 and not o.result_package_id)
if move_line_ids:
move_lines_to_pack = self.env['stock.move.line']
package = self.env['stock.quant.package'].create({})
for ml in move_line_ids:
if float_compare(ml.qty_done, ml.product_uom_qty,
precision_rounding=ml.product_uom_id.rounding) >= 0:
move_lines_to_pack |= ml
else:
quantity_left_todo = float_round(
ml.product_uom_qty - ml.qty_done,
precision_rounding=ml.product_uom_id.rounding,
rounding_method='UP')
done_to_keep = ml.qty_done
new_move_line = ml.copy(
default={'product_uom_qty': 0, 'qty_done': ml.qty_done})
ml.write({'product_uom_qty': quantity_left_todo, 'qty_done': 0.0})
new_move_line.write({'product_uom_qty': done_to_keep})
move_lines_to_pack |= new_move_line

package_level = self.env['stock.package_level'].create({
'package_id': package.id,
'picking_id': pick.id,
'location_id': False,
'location_dest_id': move_line_ids.mapped('location_dest_id').id,
'move_line_ids': [(6, 0, move_lines_to_pack.ids)]
})
move_lines_to_pack.write({
'result_package_id': package.id,
})
else:
raise UserError(_('You must first set the quantity you will put in the pack.'))
for pick in self:
move_lines_to_pack = self.env['stock.move.line']
package = self.env['stock.quant.package'].create({})
for ml in move_line_ids:
if float_compare(ml.qty_done, ml.product_uom_qty,
precision_rounding=ml.product_uom_id.rounding) >= 0:
move_lines_to_pack |= ml
else:
quantity_left_todo = float_round(
ml.product_uom_qty - ml.qty_done,
precision_rounding=ml.product_uom_id.rounding,
rounding_method='UP')
done_to_keep = ml.qty_done
new_move_line = ml.copy(
default={'product_uom_qty': 0, 'qty_done': ml.qty_done})
ml.write({'product_uom_qty': quantity_left_todo, 'qty_done': 0.0})
new_move_line.write({'product_uom_qty': done_to_keep})
move_lines_to_pack |= new_move_line
package_level = self.env['stock.package_level'].create({
'package_id': package.id,
'picking_id': pick.id,
'location_id': False,
'location_dest_id': move_line_ids.mapped('location_dest_id').id,
'move_line_ids': [(6, 0, move_lines_to_pack.ids)]
})
move_lines_to_pack.write({
'result_package_id': package.id,
})
return package

def put_in_pack(self):
res = self.check_destinations()
if res.get('type'):
return res
return self._put_in_pack()
self.ensure_one()
if self.state not in ('done', 'cancel'):
move_line_ids = self.move_line_ids.filtered(lambda ml:
float_compare(ml.qty_done, 0.0, precision_rounding=ml.product_uom_id.rounding) > 0
and not ml.result_package_id
)
if move_line_ids:
res = self._pre_put_in_pack_hook(move_line_ids)
if not res:
res = self._put_in_pack(move_line_ids)
return res
else:
raise UserError(_('You must first set the quantity you will put in the pack.'))
sle-odoo marked this conversation as resolved.
Show resolved Hide resolved

def button_scrap(self):
self.ensure_one()
Expand Down