Merge branch 'mig/18.0/stock_delivery_route' into '18.0-test'

mig/18.0/stock_delivery_route into 18.0-test

See merge request hibou-io/hibou-odoo/suite!1736
This commit is contained in:
Jared Kipe
2024-10-24 13:01:34 +00:00
14 changed files with 385 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
********************************
Hibou - Warehouse Delivery Route
********************************
Define delivery routes per warehouse. Pick the delivery route on the sale order or delivery order.
Optionally define warehouse routes on the Customer or Customer's Delivery address to pre-select
the delivery route.
For more information and add-ons, visit `Hibou.io <https://hibou.io/>`_.
=======
License
=======
Please see `LICENSE <https://github.com/hibou-io/hibou-odoo-suite/blob/master/LICENSE>`_.
Copyright Hibou Corp. 2024

View File

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

View File

@@ -0,0 +1,32 @@
{
'name': 'Warehouse Delivery Routes',
'summary': 'Assign a delivery route to a sale order or picking.',
'version': '18.0.1.0.0',
'author': "Hibou Corp.",
'category': 'Warehouse',
'license': 'LGPL-3',
'complexity': 'expert',
'images': [],
'website': "https://hibou.io",
'description': """
Warehouse Delivery Routes
=========================
Assign a delivery route at the time of sale order.
Additionally, set a default route on the customer level.
""",
'depends': [
'sale_stock',
'stock_picking_batch',
],
'demo': [],
'data': [
'views/partner_views.xml',
'views/sale_views.xml',
'views/stock_views.xml',
'security/ir.model.access.csv',
],
'auto_install': False,
'installable': True,
}

View File

@@ -0,0 +1,114 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_delivery_route
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 15.0+e\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-10-12 01:49+0000\n"
"PO-Revision-Date: 2021-10-12 01:49+0000\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: stock_delivery_route
#: model:ir.model.fields,field_description:stock_delivery_route.field_stock_picking__partner_address
msgid "Address"
msgstr "Dirección"
#. module: stock_delivery_route
#: model:ir.model,name:stock_delivery_route.model_res_partner
msgid "Contact"
msgstr "Contacto"
#. module: stock_delivery_route
#: model:ir.model.fields,field_description:stock_delivery_route.field_stock_warehouse_delivery_route__create_uid
msgid "Created by"
msgstr "Creado por"
#. module: stock_delivery_route
#: model:ir.model.fields,field_description:stock_delivery_route.field_stock_warehouse_delivery_route__create_date
msgid "Created on"
msgstr "Creado en"
#. module: stock_delivery_route
#: model:ir.model.fields,field_description:stock_delivery_route.field_sale_order__delivery_route_id
#: model:ir.model.fields,field_description:stock_delivery_route.field_stock_picking__delivery_route_id
#: model_terms:ir.ui.view,arch_db:stock_delivery_route.view_picking_internal_search_inherit
msgid "Delivery Route"
msgstr "Ruta de Envío"
#. module: stock_delivery_route
#: model:ir.model.fields,field_description:stock_delivery_route.field_res_partner__delivery_route_ids
#: model:ir.model.fields,field_description:stock_delivery_route.field_res_users__delivery_route_ids
#: model:ir.model.fields,field_description:stock_delivery_route.field_stock_warehouse__delivery_route_ids
#: model_terms:ir.ui.view,arch_db:stock_delivery_route.view_partner_form_inherit
#: model_terms:ir.ui.view,arch_db:stock_delivery_route.view_warehouse_inherit
msgid "Delivery Routes"
msgstr "Rutas de Envío"
#. module: stock_delivery_route
#: model:ir.model.fields,field_description:stock_delivery_route.field_stock_warehouse_delivery_route__display_name
msgid "Display Name"
msgstr "Nombre para mostrar"
#. module: stock_delivery_route
#: model:ir.model.fields,field_description:stock_delivery_route.field_stock_warehouse_delivery_route__id
msgid "ID"
msgstr "ID"
#. module: stock_delivery_route
#: model:ir.model.fields,field_description:stock_delivery_route.field_stock_warehouse_delivery_route____last_update
msgid "Last Modified on"
msgstr "Última Modificación el"
#. module: stock_delivery_route
#: model:ir.model.fields,field_description:stock_delivery_route.field_stock_warehouse_delivery_route__write_uid
msgid "Last Updated by"
msgstr "Última Actualización por"
#. module: stock_delivery_route
#: model:ir.model.fields,field_description:stock_delivery_route.field_stock_warehouse_delivery_route__write_date
msgid "Last Updated on"
msgstr "Última Actualización el"
#. module: stock_delivery_route
#: model:ir.model.fields,field_description:stock_delivery_route.field_stock_warehouse_delivery_route__name
msgid "Name"
msgstr "Nombre"
#. module: stock_delivery_route
#: model:ir.model.fields,field_description:stock_delivery_route.field_stock_warehouse_delivery_route__note
msgid "Note"
msgstr "Nota"
#. module: stock_delivery_route
#: model:ir.model,name:stock_delivery_route.model_sale_order
msgid "Sales Order"
msgstr "Pedido de venta"
#. module: stock_delivery_route
#: model:ir.model.fields,field_description:stock_delivery_route.field_stock_picking__sequence
msgid "Sequence"
msgstr "Secuencia"
#. module: stock_delivery_route
#: model:ir.model,name:stock_delivery_route.model_stock_picking
msgid "Transfer"
msgstr "Transferir"
#. module: stock_delivery_route
#: model:ir.model,name:stock_delivery_route.model_stock_warehouse
#: model:ir.model.fields,field_description:stock_delivery_route.field_stock_picking__warehouse_id
#: model:ir.model.fields,field_description:stock_delivery_route.field_stock_warehouse_delivery_route__warehouse_id
msgid "Warehouse"
msgstr "Almacén"
#. module: stock_delivery_route
#: model:ir.model,name:stock_delivery_route.model_stock_warehouse_delivery_route
msgid "stock.warehouse.delivery.route"
msgstr "stock.warehouse.delivery.route"

View File

@@ -0,0 +1,3 @@
from . import stock
from . import partner
from . import sale

View File

@@ -0,0 +1,7 @@
from odoo import fields, models
class Partner(models.Model):
_inherit = 'res.partner'
delivery_route_ids = fields.Many2many('stock.warehouse.delivery.route', string="Delivery Routes")

View File

@@ -0,0 +1,30 @@
from odoo import api, fields, models
class SaleOrder(models.Model):
_inherit = 'sale.order'
delivery_route_id = fields.Many2one('stock.warehouse.delivery.route', string='Delivery Route')
@api.onchange('partner_id', 'partner_shipping_id', 'warehouse_id')
def _prefill_delivery_route(self):
for so in self:
if so.warehouse_id:
for route in so.partner_shipping_id.delivery_route_ids.filtered(lambda d: d.warehouse_id == so.warehouse_id):
so.delivery_route_id = route
break
else:
for route in so.partner_id.delivery_route_ids.filtered(lambda d: d.warehouse_id == so.warehouse_id):
so.delivery_route_id = route
break
else:
so.delivery_route_id = False
else:
so.delivery_route_id = False
def action_confirm(self):
val = super(SaleOrder, self).action_confirm()
for so in self:
if so.delivery_route_id and so.picking_ids:
so.picking_ids.write({'delivery_route_id': so.delivery_route_id.id})
return val

View File

@@ -0,0 +1,38 @@
from odoo import api, fields, models
class Warehouse(models.Model):
_inherit = 'stock.warehouse'
delivery_route_ids = fields.One2many('stock.warehouse.delivery.route', 'warehouse_id', string='Delivery Routes')
class Picking(models.Model):
_inherit = 'stock.picking'
_order = 'sequence asc, priority desc, date asc, id desc'
sequence = fields.Integer(string='Sequence')
warehouse_id = fields.Many2one('stock.warehouse', related='picking_type_id.warehouse_id')
delivery_route_id = fields.Many2one('stock.warehouse.delivery.route', string='Delivery Route')
partner_address = fields.Char(string='Address', compute='_compute_partner_address')
def _compute_partner_address(self):
for pick in self:
if pick.partner_id:
pick.partner_address = '%s: %s, %s' % (pick.partner_id.name or '', pick.partner_id.street or '', pick.partner_id.city or '')
else:
pick.partner_address = ''
class WarehouseDeliveryRoute(models.Model):
_name = 'stock.warehouse.delivery.route'
name = fields.Char(string='Name')
warehouse_id = fields.Many2one('stock.warehouse', string='Warehouse')
note = fields.Text(string='Note')
def name_get(self):
res = []
for route in self:
res.append((route.id, '[%s] %s' % (route.warehouse_id.code, route.name)))
return res

View File

@@ -0,0 +1,2 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"user_stock_warehouse_delivery_route","user stock_warehouse_delivery_route","model_stock_warehouse_delivery_route","base.group_user",1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 user_stock_warehouse_delivery_route user stock_warehouse_delivery_route model_stock_warehouse_delivery_route base.group_user 1 1 1 1

View File

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

View File

@@ -0,0 +1,22 @@
from odoo.tests import common
class TestSaleRoutes(common.TransactionCase):
def test_plan_two_warehouses(self):
partner = self.env.ref('base.res_partner_2')
product_1 = self.env.ref('product.product_product_24_product_template')
wh_1 = self.env.ref('stock.warehouse0')
delivery_route = self.env['stock.warehouse.delivery.route'].create({
'name': 'Test',
'warehouse_id': wh_1.id,
})
so = self.env['sale.order'].create({
'warehouse_id': wh_1.id,
'partner_id': partner.id,
'order_line': [(0, 0, {'product_id': product_1.product_variant_id.id})],
'delivery_route_id': delivery_route.id,
})
so.action_confirm()
self.assertTrue(so.state in ('sale', 'done'))
self.assertEqual(so.picking_ids[0].delivery_route_id, delivery_route)

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record id="view_partner_form_inherit" model="ir.ui.view">
<field name="name">res.partner.form.inherit</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form" />
<field name="arch" type="xml">
<xpath expr="//group[@name='container_row_2']" position="after">
<group name="container_row_delivery_routes">
<group string="Delivery Routes" name="delivery_routes">
<field name="delivery_route_ids" widget="many2many_tags" colspan="2" nolabel="1" options="{'no_create': True}"/>
</group>
</group>
</xpath>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record id="view_order_form_inherit_sale_stock_inherit" model="ir.ui.view">
<field name="name">sale.order.form.sale.stock.inherit</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale_stock.view_order_form_inherit_sale_stock" />
<field name="arch" type="xml">
<xpath expr="//field[@name='warehouse_id']" position="after">
<field name="delivery_route_id" context="{'default_warehouse_id': warehouse_id}" domain="[('warehouse_id', '=', warehouse_id)]" options="{'no_create': True}"/>
</xpath>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<!-- Warehouse -->
<record id="view_warehouse_inherit" model="ir.ui.view">
<field name="name">stock.warehouse.inherit</field>
<field name="model">stock.warehouse</field>
<field name="inherit_id" ref="stock.view_warehouse" />
<field name="arch" type="xml">
<xpath expr="//page[1]" position="after">
<page string="Delivery Routes">
<group>
<field name="id" invisible="1"/>
<field name="delivery_route_ids" context="{'default_warehouse_id': id}" colspan="2" nolabel="1">
<list>
<field name="name"/>
</list>
<form>
<group>
<group>
<field name="name" required="1"/>
<field name="warehouse_id"/>
</group>
<group>
<field name="note"/>
</group>
</group>
</form>
</field>
</group>
</page>
</xpath>
</field>
</record>
<!-- Picking -->
<record id="view_picking_internal_search_inherit" model="ir.ui.view">
<field name="name">stock.picking.internal.search.inherit</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_internal_search"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='name']" position="after">
<field name="delivery_route_id"/>
</xpath>
<xpath expr="//filter[@name='picking_type']" position="after">
<filter name="delivery_route_id" string="Delivery Route" context="{'group_by':'delivery_route_id'}"/>
</xpath>
</field>
</record>
<record id="vpicktree_inherit" model="ir.ui.view">
<field name="name">stock.picking.tree.search.inherit</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.vpicktree"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='name']" position="before">
<field name="sequence" widget="handle"/>
</xpath>
<xpath expr="//field[@name='partner_id']" position="after">
<field name="delivery_route_id"/>
</xpath>
</field>
</record>
<record id="view_picking_form_inherit" model="ir.ui.view">
<field name="name">stock.picking.form.inherit</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='partner_id']" position="after">
<field name="warehouse_id" invisible="1"/>
<field name="delivery_route_id" context="{'default_warehouse_id': warehouse_id}" domain="[('warehouse_id', '=', warehouse_id)]" options="{'no_create': True}"/>
</xpath>
</field>
</record>
<!-- Picking Batch -->
<!-- <record id="view_picking_tree_batch_inherit" model="ir.ui.view">
<field name="name">stock_picking_batch.picking.tree.batch.inherit</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock_picking_batch.view_picking_tree_batch"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='name']" position="before">
<field name="sequence" widget="handle"/>
<field name="partner_address" />
</xpath>
</field>
</record> -->
</odoo>