diff --git a/delivery_stamps/models/delivery_stamps.py b/delivery_stamps/models/delivery_stamps.py index 8f346f55..6a489fa4 100644 --- a/delivery_stamps/models/delivery_stamps.py +++ b/delivery_stamps/models/delivery_stamps.py @@ -109,36 +109,17 @@ class ProviderStamps(models.Model): ret_val = service.create_shipping() ret_val.ShipDate = date_planned.split()[0] if date_planned else date.today().isoformat() - ret_val.FromZIPCode = order.warehouse_id.partner_id.zip + ret_val.FromZIPCode = self.get_shipper_warehouse(order=order).zip ret_val.ToZIPCode = order.partner_shipping_id.zip ret_val.PackageType = self._stamps_package_type() ret_val.ServiceType = self.stamps_service_type ret_val.WeightLb = weight return ret_val - def _get_order_for_picking(self, picking): - if picking.sale_id: - return picking.sale_id - return None - - def _get_company_for_order(self, order): - company = order.company_id - if order.team_id and order.team_id.subcompany_id: - company = order.team_id.subcompany_id.company_id - elif order.analytic_account_id and order.analytic_account_id.subcompany_id: - company = order.analytic_account_id.subcompany_id.company_id - return company - - def _get_company_for_picking(self, picking): - order = self._get_order_for_picking(picking) - if order: - return self._get_company_for_order(order) - return picking.company_id - def _stamps_get_addresses_for_picking(self, picking): - company = self._get_company_for_picking(picking) - from_ = picking.picking_type_id.warehouse_id.partner_id - to = picking.partner_id + company = self.get_shipper_company(picking=picking) + from_ = self.get_shipper_warehouse(picking=picking) + to = self.get_recipient(picking=picking) return company, from_, to def _stamps_get_shippings_for_picking(self, service, picking): @@ -251,7 +232,7 @@ class ProviderStamps(models.Model): company, from_partner, to_partner = self._stamps_get_addresses_for_picking(picking) from_address = service.create_address() - from_address.FullName = company.partner_id.name + from_address.FullName = company.name from_address.Address1 = from_partner.street if from_partner.street2: from_address.Address2 = from_partner.street2 diff --git a/external/hibou-oca/connector-magento b/external/hibou-oca/connector-magento index 8cce7538..802fe38d 160000 --- a/external/hibou-oca/connector-magento +++ b/external/hibou-oca/connector-magento @@ -1 +1 @@ -Subproject commit 8cce7538e6f81adc8411288430a350e98ef1349a +Subproject commit 802fe38dc14025410960072b881a68fcc00cc7bb diff --git a/product_catch_weight/models/account_invoice.py b/product_catch_weight/models/account_invoice.py index ee8c9f92..11879f5b 100644 --- a/product_catch_weight/models/account_invoice.py +++ b/product_catch_weight/models/account_invoice.py @@ -25,10 +25,14 @@ class AccountInvoiceLine(models.Model): move_lines = self.sale_line_ids.mapped('move_ids.move_line_ids') else: move_lines = self.purchase_line_id.mapped('move_ids.move_line_ids') - for move_line in move_lines: + for move_line in move_lines.filtered(lambda l: l.lot_id): qty_done = move_line.qty_done + current_qty_done = qty_done + qty_done_total r = move_line.lot_id.catch_weight_ratio - ratio = ((ratio * qty_done_total) + (qty_done * r)) / (qty_done + qty_done_total) + if current_qty_done == 0: + ratio = 0 + else: + ratio = ((ratio * qty_done_total) + (qty_done * r)) / current_qty_done qty_done_total += qty_done catch_weight += move_line.lot_id.catch_weight price = price * ratio diff --git a/product_catch_weight/models/stock.py b/product_catch_weight/models/stock.py index 1ad5d3b6..c5cc9363 100644 --- a/product_catch_weight/models/stock.py +++ b/product_catch_weight/models/stock.py @@ -8,7 +8,6 @@ class StockProductionLot(models.Model): catch_weight = fields.Float(string='Catch Weight', digits=(10, 4)) catch_weight_uom_id = fields.Many2one('product.uom', related='product_id.catch_weight_uom_id') - @api.depends('catch_weight') def _compute_catch_weight_ratio(self): for lot in self: @@ -44,3 +43,14 @@ class StockMoveLine(models.Model): catch_weight_uom_id = fields.Many2one('product.uom', string='Catch Weight UOM') lot_catch_weight = fields.Float(related='lot_id.catch_weight') lot_catch_weight_uom_id = fields.Many2one('product.uom', related='product_id.catch_weight_uom_id') + + +class StockPicking(models.Model): + _inherit = 'stock.picking' + + has_catch_weight = fields.Boolean(string="Has Catch Weight", compute='_compute_has_catch_weight', store=True) + + @api.depends('move_lines.product_catch_weight_uom_id') + def _compute_has_catch_weight(self): + for picking in self: + picking.has_catch_weight = any(picking.mapped('move_lines.product_catch_weight_uom_id')) diff --git a/product_catch_weight/tests/test_catch_weight.py b/product_catch_weight/tests/test_catch_weight.py index 1b13cb55..48821d7a 100644 --- a/product_catch_weight/tests/test_catch_weight.py +++ b/product_catch_weight/tests/test_catch_weight.py @@ -30,6 +30,7 @@ class TestPicking(TransactionCase): 'uom_po_id': self.product_uom_id.id, 'catch_weight_uom_id': self.ref_uom_id.id, }) + self.pricelist = self.env.ref('product.list0') # def test_creation(self): @@ -69,6 +70,7 @@ class TestPicking(TransactionCase): 'partner_invoice_id': self.partner1.id, 'partner_shipping_id': self.partner1.id, 'order_line': [(0, 0, {'product_id': self.product1.id})], + 'pricelist_id': self.pricelist.id, }) so.action_confirm() self.assertTrue(so.state in ('sale', 'done')) @@ -104,6 +106,7 @@ class TestPicking(TransactionCase): 'partner_invoice_id': self.partner1.id, 'partner_shipping_id': self.partner1.id, 'order_line': [(0, 0, {'product_id': self.product1.id, 'product_uom_qty': 2.0})], + 'pricelist_id': self.pricelist.id, }) so.action_confirm() self.assertTrue(so.state in ('sale', 'done')) diff --git a/product_catch_weight/views/stock_views.xml b/product_catch_weight/views/stock_views.xml index 40e2d9dd..3ce9015d 100644 --- a/product_catch_weight/views/stock_views.xml +++ b/product_catch_weight/views/stock_views.xml @@ -13,16 +13,6 @@ - - - - - - - - - - stock.move.operations.form.inherit stock.move @@ -36,6 +26,7 @@ + stock.move.line.operations.tree.inherit stock.move.line @@ -49,6 +40,7 @@ + product.template.common.form.inherit product.template @@ -59,4 +51,18 @@ + + + stock.view.picking.internal.search.inherit + stock.picking + + + + + + + + + + \ No newline at end of file diff --git a/rma/wizard/rma_lines_views.xml b/rma/wizard/rma_lines_views.xml index 9515fd03..934c8f71 100644 --- a/rma/wizard/rma_lines_views.xml +++ b/rma/wizard/rma_lines_views.xml @@ -7,7 +7,7 @@
- + diff --git a/rma_sale/wizard/rma_lines_views.xml b/rma_sale/wizard/rma_lines_views.xml index e6486124..dd7a8e03 100644 --- a/rma_sale/wizard/rma_lines_views.xml +++ b/rma_sale/wizard/rma_lines_views.xml @@ -7,7 +7,7 @@ - + diff --git a/sale_line_change/__init__.py b/sale_line_change/__init__.py new file mode 100644 index 00000000..40272379 --- /dev/null +++ b/sale_line_change/__init__.py @@ -0,0 +1 @@ +from . import wizard diff --git a/sale_line_change/__manifest__.py b/sale_line_change/__manifest__.py new file mode 100644 index 00000000..02a5d98b --- /dev/null +++ b/sale_line_change/__manifest__.py @@ -0,0 +1,25 @@ +{ + 'name': 'Sale Line Change', + 'summary': 'Change Confirmed Sale Lines Routes or Warehouses.', + 'version': '11.0.1.0.0', + 'author': "Hibou Corp.", + 'category': 'Sale', + 'license': 'AGPL-3', + 'complexity': 'expert', + 'images': [], + 'website': "https://hibou.io", + 'description': """ +""", + 'depends': [ + 'sale_sourced_by_line', + 'sale_stock', + 'stock_dropshipping', + ], + 'demo': [], + 'data': [ + 'wizard/sale_line_change_views.xml', + 'views/sale_views.xml', + ], + 'auto_install': False, + 'installable': True, +} diff --git a/sale_line_change/tests/__init__.py b/sale_line_change/tests/__init__.py new file mode 100644 index 00000000..27bc6136 --- /dev/null +++ b/sale_line_change/tests/__init__.py @@ -0,0 +1 @@ +from . import test_sale_line_change diff --git a/sale_line_change/tests/test_sale_line_change.py b/sale_line_change/tests/test_sale_line_change.py new file mode 100644 index 00000000..7409446b --- /dev/null +++ b/sale_line_change/tests/test_sale_line_change.py @@ -0,0 +1,99 @@ +from odoo.tests import common +from odoo.exceptions import ValidationError + + +class TestSaleLineChange(common.TransactionCase): + def setUp(self): + super(TestSaleLineChange, self).setUp() + self.warehouse0 = self.env.ref('stock.warehouse0') + self.warehouse1 = self.env['stock.warehouse'].create({ + 'company_id': self.env.user.company_id.id, + # 'partner_id': self.env.user.company_id.partner_id.id, + 'name': 'TWH1', + 'code': 'TWH1', + }) + self.product1 = self.env.ref('product.product_product_24') + self.partner1 = self.env.ref('base.res_partner_12') + self.so1 = self.env['sale.order'].create({ + 'partner_id': self.partner1.id, + 'partner_invoice_id': self.partner1.id, + 'partner_shipping_id': self.partner1.id, + 'order_line': [(0, 0, { + 'product_id': self.product1.id, + 'name': 'N/A', + 'product_uom_qty': 1.0, + 'price_unit': 100.0, + })] + }) + self.dropship_route = self.env.ref('stock_dropshipping.route_drop_shipping') + self.warehouse0_route = self.warehouse0.route_ids.filtered(lambda r: r.name.find('Ship') >= 0) + + def test_00_sale_change_warehouse(self): + so = self.so1 + + so.action_confirm() + self.assertTrue(so.state in ('sale', 'done')) + self.assertTrue(so.picking_ids) + org_picking = so.picking_ids + self.assertEqual(org_picking.picking_type_id.warehouse_id, self.warehouse0) + + wiz = self.env['sale.line.change.order'].with_context(default_order_id=so.id).create({}) + self.assertTrue(wiz.line_ids) + wiz.line_ids.line_warehouse_id = self.warehouse1 + wiz.line_ids.line_date_planned = '2018-01-01 00:00:00' + wiz.apply() + + self.assertTrue(len(so.picking_ids) == 2) + self.assertTrue(org_picking.state == 'cancel') + new_picking = so.picking_ids - org_picking + self.assertTrue(new_picking) + self.assertEqual(new_picking.picking_type_id.warehouse_id, self.warehouse1) + self.assertEqual(new_picking.scheduled_date, '2018-01-01 00:00:00') + + def test_01_sale_change_route(self): + so = self.so1 + + so.action_confirm() + self.assertTrue(so.state in ('sale', 'done')) + self.assertTrue(so.picking_ids) + org_picking = so.picking_ids + self.assertEqual(org_picking.picking_type_id.warehouse_id, self.warehouse0) + + # Change route on wizard line + wiz = self.env['sale.line.change.order'].with_context(default_order_id=so.id).create({}) + self.assertTrue(wiz.line_ids) + wiz.line_ids.line_route_id = self.dropship_route + wiz.apply() + + # Check that RFQ/PO was created. + self.assertTrue(org_picking.state == 'cancel') + po_line = self.env['purchase.order.line'].search([('sale_line_id', '=', so.order_line.id)]) + self.assertTrue(po_line) + + def test_02_sale_dropshipping_to_warehouse(self): + self.assertTrue(self.warehouse0_route) + self.product1.route_ids += self.dropship_route + so = self.so1 + + so.action_confirm() + self.assertTrue(so.state in ('sale', 'done')) + self.assertFalse(so.picking_ids) + + # Change route on wizard line + wiz = self.env['sale.line.change.order'].with_context(default_order_id=so.id).create({}) + self.assertTrue(wiz.line_ids) + wiz.line_ids.line_route_id = self.warehouse0_route + wiz.line_ids.line_date_planned = '2018-01-01 00:00:00' + + # Wizard cannot complete because of non-cancelled Purchase Order. + with self.assertRaises(ValidationError): + wiz.apply() + + po_line = self.env['purchase.order.line'].search([('sale_line_id', '=', so.order_line.id)]) + po_line.order_id.button_cancel() + wiz.apply() + + # Check parameters on new picking + self.assertTrue(so.picking_ids) + self.assertEqual(so.picking_ids.picking_type_id.warehouse_id, self.warehouse0) + self.assertEqual(so.picking_ids.scheduled_date, '2018-01-01 00:00:00') diff --git a/sale_line_change/views/sale_views.xml b/sale_line_change/views/sale_views.xml new file mode 100644 index 00000000..57dafe2c --- /dev/null +++ b/sale_line_change/views/sale_views.xml @@ -0,0 +1,19 @@ + + + + sale.order.form.inherit + sale.order + + + +