[IMP] {website_}sale, delivery: add local delivery option
This commit does a couple of small related improvements: - adds new delivery options: "Local Delivery". We replace the existing "Normal Delivery Charges" with the new "Local Delivery" since it is now redundant. - Originally a "Local Pickup" demo option was going to be added, but this appeared redundant with the "[On Site Pick]" added in odoo/odoo#87636 . Regardless, an additional `carrier_description` field has been added so users can include extra instructions (e.g. address to pick up from, when pickup can occur, etc) to sales orders/ confirmation emails (emails only via ecommerce sales). - adds option to filter based on zip prefix rather than the previous zip "range" option, which was too restrictive in some cases (e.g. in the UK where zips can have letters in them). Note that users can view/edit zip prefixes in menu under settings when debug mode is active. Note: - prefixes are ordered by name so its easier to read large numbers prefixes - prefixes are always capitalized to avoid duplicate prefixes that differ by case + avoid capitalizing all prefixes every time the `_match_address` logic is called Task: 2706451 Upgrade PR: odoo/upgrade#3384 closes odoo/odoo#84620 Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
This commit is contained in:
committed by
ticodoo
parent
9accece7d3
commit
22fa7f90e4
@@ -32,6 +32,7 @@ invoices from picking, the system is able to add and compute the shipping line.
|
||||
'views/stock_picking_type_views.xml',
|
||||
'views/stock_rule_views.xml',
|
||||
'views/stock_move_line_views.xml',
|
||||
'report/ir_actions_report_templates.xml',
|
||||
],
|
||||
'demo': ['data/delivery_demo.xml'],
|
||||
'installable': True,
|
||||
|
||||
@@ -23,22 +23,25 @@
|
||||
<field name="product_id" ref="delivery.product_product_delivery_poste"/>
|
||||
</record>
|
||||
|
||||
<record id="product_product_delivery_normal" model="product.product">
|
||||
<field name="name">Normal Delivery Charges</field>
|
||||
<field name="default_code">Delivery_008</field>
|
||||
<!-- Local Delivery -->
|
||||
<record id="product_product_local_delivery" model="product.product">
|
||||
<field name="name">Local Delivery</field>
|
||||
<field name="default_code">Delivery_010</field>
|
||||
<field name="type">service</field>
|
||||
<field name="categ_id" ref="delivery.product_category_deliveries"/>
|
||||
<field name="sale_ok" eval="False"/>
|
||||
<field name="purchase_ok" eval="False"/>
|
||||
<field name="list_price">10.0</field>
|
||||
<field name="invoice_policy">order</field>
|
||||
</record>
|
||||
|
||||
<record id="normal_delivery_carrier" model="delivery.carrier">
|
||||
<field name="name">Normal Delivery Charges</field>
|
||||
<field name="fixed_price">10.0</field>
|
||||
<field name="sequence">3</field>
|
||||
<record id="delivery_local_delivery" model="delivery.carrier">
|
||||
<field name="name">Local Delivery</field>
|
||||
<field name="fixed_price">5.0</field>
|
||||
<field name="free_over" eval="True"/>
|
||||
<field name="amount">50</field>
|
||||
<field name="sequence">4</field>
|
||||
<field name="delivery_type">fixed</field>
|
||||
<field name="product_id" ref="delivery.product_product_delivery_normal"/>
|
||||
<field name="product_id" ref="delivery.product_product_local_delivery"/>
|
||||
</record>
|
||||
|
||||
<record id="delivery_price_rule1" model="delivery.price.rule">
|
||||
@@ -66,7 +69,7 @@
|
||||
<record forcecreate="True" id="property_delivery_carrier" model="ir.property">
|
||||
<field name="name">property_delivery_carrier_id</field>
|
||||
<field name="fields_id" search="[('model','=','res.partner'),('name','=','property_delivery_carrier_id')]"/>
|
||||
<field name="value" eval="'delivery.carrier,'+str(ref('normal_delivery_carrier'))"/>
|
||||
<field name="value" eval="'delivery.carrier,'+str(ref('delivery_local_delivery'))"/>
|
||||
</record>
|
||||
|
||||
<!--Sample sale orders with carrier defined-->
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
from . import delivery_carrier
|
||||
from . import delivery_grid
|
||||
from . import delivery_zip_prefix
|
||||
from . import product_template
|
||||
from . import sale_order
|
||||
from . import partner
|
||||
|
||||
@@ -53,8 +53,12 @@ class DeliveryCarrier(models.Model):
|
||||
|
||||
country_ids = fields.Many2many('res.country', 'delivery_carrier_country_rel', 'carrier_id', 'country_id', 'Countries')
|
||||
state_ids = fields.Many2many('res.country.state', 'delivery_carrier_state_rel', 'carrier_id', 'state_id', 'States')
|
||||
zip_from = fields.Char('Zip From')
|
||||
zip_to = fields.Char('Zip To')
|
||||
zip_prefix_ids = fields.Many2many(
|
||||
'delivery.zip.prefix', 'delivery_zip_prefix_rel', 'carrier_id', 'zip_prefix_id', 'Zip Prefixes')
|
||||
carrier_description = fields.Text(
|
||||
'Carrier Description', translate=True,
|
||||
help="A description of the delivery method that you want to communicate to your customers on the Sales Order and sales confirmation email."
|
||||
"E.g. instructions for customers to follow.")
|
||||
|
||||
margin = fields.Float(help='This percentage will be added to the shipping price.')
|
||||
free_over = fields.Boolean('Free if order amount is above', help="If the order total amount (shipping excluded) is above or equal to this value, the customer benefits from a free shipping", default=False)
|
||||
@@ -115,9 +119,7 @@ class DeliveryCarrier(models.Model):
|
||||
return False
|
||||
if self.state_ids and partner.state_id not in self.state_ids:
|
||||
return False
|
||||
if self.zip_from and (partner.zip or '').upper() < self.zip_from.upper():
|
||||
return False
|
||||
if self.zip_to and (partner.zip or '').upper() > self.zip_to.upper():
|
||||
if self.zip_prefix_ids and not partner.zip.upper().startswith(tuple(self.zip_prefix_ids.mapped('name'))):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class DeliveryZipPrefix(models.Model):
|
||||
""" Zip prefix that a delivery.carrier will deliver to. """
|
||||
_name = 'delivery.zip.prefix'
|
||||
_description = 'Delivery Zip Prefix'
|
||||
_order = 'name, id'
|
||||
|
||||
name = fields.Char('Prefix', required=True)
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
for vals in vals_list:
|
||||
# we cannot easily convert a list of prefix names into upper to compare with partner zips
|
||||
# later on, so let's ensure they are always upper
|
||||
vals['name'] = vals['name'].upper()
|
||||
return super(DeliveryZipPrefix, self).create(vals_list)
|
||||
|
||||
def write(self, vals):
|
||||
vals['name'] = vals['name'].upper()
|
||||
return super().write(vals)
|
||||
|
||||
_sql_constraints = [
|
||||
('name_uniq', 'unique (name)', "Prefix already exists!"),
|
||||
]
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="delivery_report_saleorder_document" inherit_id="sale.report_saleorder_document">
|
||||
<xpath expr="//p[@name='order_note']" position="before">
|
||||
<p t-if="doc.carrier_id.carrier_description" id="carrier_description">
|
||||
<strong>Shipping Description:</strong>
|
||||
<span t-out="doc.carrier_id.carrier_description"/>
|
||||
</p>
|
||||
</xpath>
|
||||
</template>
|
||||
</odoo>
|
||||
@@ -1,12 +1,14 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_delivery_carrier,delivery.carrier,model_delivery_carrier,sales_team.group_sale_salesman,1,0,0,0
|
||||
access_delivery_carrier_system,delivery.carrier,model_delivery_carrier,base.group_system,1,0,0,0
|
||||
access_delivery_zip_prefix,delivery.zip.prefix,model_delivery_zip_prefix,sales_team.group_sale_salesman,1,0,0,0
|
||||
access_delivery_price_rule,delivery.price.rule,model_delivery_price_rule,sales_team.group_sale_salesman,1,0,0,0
|
||||
access_delivery_carrier_manager,delivery.carrier,model_delivery_carrier,sales_team.group_sale_manager,1,1,1,1
|
||||
access_delivery_price_rule_manager,delivery.price.rule,model_delivery_price_rule,sales_team.group_sale_manager,1,1,1,1
|
||||
access_delivery_carrier_partner_manager,delivery.carrier partner_manager,model_delivery_carrier,base.group_partner_manager,1,0,0,0
|
||||
access_delivery_carrier_stock_user,delivery.carrier stock_user,model_delivery_carrier,stock.group_stock_user,1,0,0,0
|
||||
access_delivery_carrier_stock_manager,delivery.carrier,model_delivery_carrier,stock.group_stock_manager,1,1,1,1
|
||||
access_delivery_zip_prefix_stock_manager,delivery.zip.prefix,model_delivery_zip_prefix,stock.group_stock_manager,1,1,1,1
|
||||
access_delivery_price_rule_stock_manager,delivery.price.rule,model_delivery_price_rule,stock.group_stock_manager,1,1,1,1
|
||||
access_choose_delivery_package,access.choose.delivery.package,model_choose_delivery_package,stock.group_stock_user,1,1,1,0
|
||||
access_choose_delivery_carrier,access.choose.delivery.carrier,model_choose_delivery_carrier,stock.group_stock_user,1,1,1,0
|
||||
|
||||
|
@@ -130,16 +130,13 @@
|
||||
<group name="country_details">
|
||||
<field name="country_ids" widget="many2many_tags" options="{'no_open': True, 'no_create': True}"/>
|
||||
<field name="state_ids" widget="many2many_tags"/>
|
||||
</group>
|
||||
<group></group>
|
||||
<group name="zip_from">
|
||||
<field name="zip_from"/>
|
||||
</group>
|
||||
<group name="zip_to">
|
||||
<field name="zip_to"/>
|
||||
<field name="zip_prefix_ids" widget="many2many_tags"/>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Description" name="description">
|
||||
<field name="carrier_description" placeholder="Shipping method details to be included at bottom sales orders and their confirmation emails. E.g. Instructions for customers to follow."/>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</form>
|
||||
@@ -167,8 +164,24 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_delivery_zip_prefix_list" model="ir.actions.act_window">
|
||||
<field name="name">Zip Prefix</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">delivery.zip.prefix</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Manage delivery zip prefixes
|
||||
</p><p>
|
||||
Delivery zip prefixes are assigned to delivery carriers to restrict
|
||||
which zips it is available to.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem action="action_delivery_carrier_form" id="menu_action_delivery_carrier_form" parent="stock.menu_delivery" sequence="1"/>
|
||||
<menuitem action="action_delivery_carrier_form" id="sale_menu_action_delivery_carrier_form" parent="sale.menu_sales_config" sequence="4"/>
|
||||
<menuitem action="action_delivery_zip_prefix_list" id="menu_delivery_zip_prefix" parent="stock.menu_delivery" groups="base.group_no_one" sequence="100"/>
|
||||
|
||||
<record id="view_delivery_price_rule_form" model="ir.ui.view">
|
||||
<field name="name">delivery.price.rule.form</field>
|
||||
|
||||
@@ -222,6 +222,12 @@
|
||||
</t>
|
||||
</td>
|
||||
</tr>
|
||||
<tr t-if="object.carrier_id.carrier_description">
|
||||
<td>
|
||||
<strong>Shipping Description:</strong>
|
||||
<t t-out="object.carrier_id.carrier_description"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
@@ -166,7 +166,7 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p t-field="doc.note" />
|
||||
<p t-field="doc.note" name="order_note"/>
|
||||
<p t-if="not is_html_empty(doc.payment_term_id.note)">
|
||||
<span t-field="doc.payment_term_id.note"/>
|
||||
</p>
|
||||
|
||||
@@ -6,9 +6,5 @@
|
||||
<field name="is_published" eval="False" />
|
||||
</record>
|
||||
|
||||
<record id="delivery.normal_delivery_carrier" model="delivery.carrier">
|
||||
<field name="is_published" eval="False" />
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
@@ -9,11 +9,9 @@
|
||||
<field name="company_id" position='after'>
|
||||
<field name="website_id" groups="website.group_multi_website" options="{'no_open': True, 'no_create_edit': True}"/>
|
||||
</field>
|
||||
<xpath expr="//page[@name='destination']" position='after'>
|
||||
<page string="Description" name="description">
|
||||
<field name="website_description" placeholder="Description displayed on the eCommerce and on online quotations."/>
|
||||
</page>
|
||||
</xpath>
|
||||
<field name="carrier_description" position='before'>
|
||||
<field name="website_description" placeholder="Description displayed on the eCommerce and on online quotations."/>
|
||||
</field>
|
||||
<xpath expr="//button[@name='toggle_prod_environment']" position='before'>
|
||||
<button name="website_publish_button" type="object" class="oe_stat_button" icon="fa-globe">
|
||||
<field name="is_published" widget="website_publish_button"/>
|
||||
|
||||
Reference in New Issue
Block a user