Skip to content

Commit 1ae5a11

Browse files
[MIG] delivery_dropoff_site: Migration to 17.0
1 parent d70a242 commit 1ae5a11

12 files changed

Lines changed: 265 additions & 41 deletions

File tree

delivery_dropoff_site/README.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ Contributors
101101
- Aymeric LECOMTE, akretion
102102
- Sébastien BEAU <sebastien.beau@akretion.com>
103103
- Sylvain LE GAL (https://twitter.com/legalsylvain)
104+
- `Heliconia Solutions Pvt. Ltd. <https://www.heliconia.io>`__
105+
106+
- Bhavesh Heliconia
104107

105108
Other credits
106109
-------------

delivery_dropoff_site/__manifest__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
{
99
"name": "Delivery Drop-off Sites",
10-
"version": "16.0.1.0.0",
10+
"version": "17.0.1.0.0",
1111
"author": "Akretion,GRAP,Odoo Community Association (OCA)",
1212
"license": "AGPL-3",
1313
"summary": "Send goods to sites in which customers come pick up package",

delivery_dropoff_site/migrations/16.0.1.0.0/pre-migrate.py

Lines changed: 0 additions & 28 deletions
This file was deleted.

delivery_dropoff_site/models/sale_order.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ class SaleOrder(models.Model):
2121
final_shipping_partner_id = fields.Many2one(
2222
comodel_name="res.partner",
2323
string="Final Recipient",
24-
states={"draft": [("readonly", False)], "sent": [("readonly", False)]},
2524
readonly=True,
2625
help="It is the partner that will pick up the parcel " "in the dropoff site.",
2726
)

delivery_dropoff_site/readme/CONTRIBUTORS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@
22
- Aymeric LECOMTE, akretion
33
- Sébastien BEAU \<<sebastien.beau@akretion.com>\>
44
- Sylvain LE GAL (<https://twitter.com/legalsylvain>)
5+
- [Heliconia Solutions Pvt. Ltd.](https://www.heliconia.io)
6+
- Bhavesh Heliconia

delivery_dropoff_site/static/description/index.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,10 @@ <h2><a class="toc-backref" href="#toc-entry-6">Contributors</a></h2>
444444
<li>Aymeric LECOMTE, akretion</li>
445445
<li>Sébastien BEAU &lt;<a class="reference external" href="mailto:sebastien.beau&#64;akretion.com">sebastien.beau&#64;akretion.com</a>&gt;</li>
446446
<li>Sylvain LE GAL (<a class="reference external" href="https://twitter.com/legalsylvain">https://twitter.com/legalsylvain</a>)</li>
447+
<li><a class="reference external" href="https://www.heliconia.io">Heliconia Solutions Pvt. Ltd.</a><ul>
448+
<li>Bhavesh Heliconia</li>
449+
</ul>
450+
</li>
447451
</ul>
448452
</div>
449453
<div class="section" id="other-credits">
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import test_delivery_dropoff_site
Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
# Copyright (C) 2018 - Today: GRAP (http://www.grap.coop)
2+
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
3+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
4+
from unittest.mock import patch
5+
6+
from odoo import Command
7+
from odoo.tests import TransactionCase
8+
9+
10+
class TestDeliveryDropoffSite(TransactionCase):
11+
@classmethod
12+
def setUpClass(cls):
13+
super().setUpClass()
14+
15+
# Create delivery product
16+
cls.delivery_product = cls.env["product.product"].create(
17+
{
18+
"name": "Delivery Product",
19+
"type": "service",
20+
"categ_id": cls.env.ref("product.product_category_all").id,
21+
"sale_ok": True,
22+
"purchase_ok": True,
23+
"list_price": 10.0,
24+
}
25+
)
26+
27+
# Create delivery carrier
28+
cls.carrier = cls.env["delivery.carrier"].create(
29+
{
30+
"name": "Test Carrier",
31+
"product_id": cls.delivery_product.id,
32+
"delivery_type": "fixed",
33+
"fixed_price": 10.0,
34+
"with_dropoff_site": True,
35+
}
36+
)
37+
38+
# Create a dropoff site
39+
cls.dropoff_site = cls.env["dropoff.site"].create(
40+
{
41+
"name": "Test Dropoff Site",
42+
"code": "TDS001",
43+
"carrier_id": cls.carrier.id,
44+
"street": "123 Test Street",
45+
"city": "Test City",
46+
"zip": "12345",
47+
"country_id": cls.env.ref("base.us").id,
48+
}
49+
)
50+
51+
# Create customer
52+
cls.customer = cls.env["res.partner"].create(
53+
{
54+
"name": "Test Customer",
55+
"street": "456 Customer Street",
56+
"city": "Customer City",
57+
"zip": "67890",
58+
"country_id": cls.env.ref("base.us").id,
59+
}
60+
)
61+
62+
# Create product
63+
cls.product = cls.env["product.product"].create(
64+
{
65+
"name": "Test Product",
66+
"type": "product",
67+
"categ_id": cls.env.ref("product.product_category_all").id,
68+
}
69+
)
70+
71+
def test_01_create_dropoff_site(self):
72+
"""Test creation of dropoff site"""
73+
self.assertTrue(self.dropoff_site.partner_id)
74+
self.assertEqual(self.dropoff_site.partner_id.is_dropoff_site, True)
75+
self.assertEqual(self.dropoff_site.partner_id.customer_rank, 0)
76+
self.assertEqual(self.dropoff_site.partner_id.supplier_rank, 0)
77+
78+
def test_02_dropoff_site_calendar(self):
79+
"""Test calendar functionality for dropoff site"""
80+
# Initially no calendar
81+
self.assertFalse(self.dropoff_site.calendar_id)
82+
83+
# Enable calendar
84+
self.dropoff_site.action_enable_calendar()
85+
self.assertTrue(self.dropoff_site.calendar_id)
86+
self.assertEqual(self.dropoff_site.calendar_id.name, self.dropoff_site.name)
87+
88+
# Disable calendar
89+
self.dropoff_site.action_disable_calendar()
90+
self.assertFalse(self.dropoff_site.calendar_id)
91+
92+
def test_03_sale_order_dropoff(self):
93+
"""Test sale order with dropoff site delivery"""
94+
# Create sale order
95+
sale_order = self.env["sale.order"].create(
96+
{
97+
"partner_id": self.customer.id,
98+
"carrier_id": self.carrier.id,
99+
"partner_shipping_id": self.dropoff_site.partner_id.id,
100+
"order_line": [
101+
Command.create(
102+
{
103+
"product_id": self.product.id,
104+
"product_uom_qty": 1,
105+
}
106+
)
107+
],
108+
}
109+
)
110+
111+
# Check dropoff site requirements
112+
self.assertTrue(sale_order.dropoff_site_required)
113+
self.assertEqual(sale_order.partner_shipping_id, self.dropoff_site.partner_id)
114+
115+
# Confirm order and check final shipping partner
116+
sale_order.action_confirm()
117+
picking = sale_order.picking_ids[0]
118+
self.assertEqual(
119+
picking.final_shipping_partner_id, sale_order.final_shipping_partner_id
120+
)
121+
122+
def test_04_carrier_change(self):
123+
"""Test changing carrier on sale order"""
124+
# Create new carrier without dropoff
125+
regular_delivery_product = self.env["product.product"].create(
126+
{
127+
"name": "Regular Delivery Product",
128+
"type": "service",
129+
"categ_id": self.env.ref("product.product_category_all").id,
130+
"sale_ok": True,
131+
"purchase_ok": True,
132+
"list_price": 10.0,
133+
}
134+
)
135+
136+
carrier_no_dropoff = self.env["delivery.carrier"].create(
137+
{
138+
"name": "Regular Carrier",
139+
"product_id": regular_delivery_product.id,
140+
"delivery_type": "fixed",
141+
"fixed_price": 10.0,
142+
"with_dropoff_site": False,
143+
}
144+
)
145+
146+
# Create sale order with dropoff
147+
sale_order = self.env["sale.order"].create(
148+
{
149+
"partner_id": self.customer.id,
150+
"carrier_id": self.carrier.id,
151+
"partner_shipping_id": self.dropoff_site.partner_id.id,
152+
}
153+
)
154+
155+
# Change carrier and check shipping address reset
156+
sale_order.carrier_id = carrier_no_dropoff
157+
sale_order.onchange_carrier_id()
158+
self.assertFalse(sale_order.partner_shipping_id)
159+
160+
def test_05_final_shipping_partner_propagation(self):
161+
"""Test propagation of final shipping partner through documents"""
162+
sale_order = self.env["sale.order"].create(
163+
{
164+
"partner_id": self.customer.id,
165+
"carrier_id": self.carrier.id,
166+
"partner_shipping_id": self.dropoff_site.partner_id.id,
167+
"final_shipping_partner_id": self.customer.id,
168+
"order_line": [
169+
Command.create(
170+
{
171+
"product_id": self.product.id,
172+
"product_uom_qty": 1,
173+
}
174+
)
175+
],
176+
}
177+
)
178+
179+
sale_order.action_confirm()
180+
181+
# Check propagation to picking
182+
picking = sale_order.picking_ids[0]
183+
self.assertEqual(picking.final_shipping_partner_id, self.customer)
184+
185+
# Check propagation to moves
186+
move = picking.move_ids[0]
187+
self.assertEqual(move.final_shipping_partner_id, self.customer)
188+
189+
def test_06_geo_localize(self):
190+
"""Test geo_localize function on Dropoff Site"""
191+
with patch.object(
192+
type(self.dropoff_site.partner_id), "geo_localize"
193+
) as mock_geo:
194+
self.dropoff_site.geo_localize()
195+
mock_geo.assert_called_once()
196+
197+
def test_07_prepare_calendar_id(self):
198+
"""Test _prepare_calendar_id method"""
199+
expected_calendar_data = {"name": self.dropoff_site.name}
200+
self.assertEqual(
201+
self.dropoff_site._prepare_calendar_id(), expected_calendar_data
202+
)
203+
204+
def test_08_partner_shipping_id_domain(self):
205+
"""Test _compute_partner_shipping_id_domain method"""
206+
self.carrier.with_dropoff_site = True
207+
self.dropoff_site.partner_id.dropoff_site_carrier_id = self.carrier
208+
209+
sale_order = self.env["sale.order"].create(
210+
{
211+
"partner_id": self.customer.id,
212+
"carrier_id": self.carrier.id,
213+
}
214+
)
215+
216+
sale_order._compute_partner_shipping_id_domain()
217+
self.assertEqual(
218+
sale_order.partner_shipping_id_domain,
219+
[("dropoff_site_carrier_id", "=", self.carrier.id)],
220+
)
221+
222+
def test_09_prepare_procurement_values(self):
223+
"""Test _prepare_procurement_values in SaleOrderLine"""
224+
sale_order = self.env["sale.order"].create(
225+
{
226+
"partner_id": self.customer.id,
227+
"carrier_id": self.carrier.id,
228+
"final_shipping_partner_id": self.customer.id,
229+
"order_line": [
230+
Command.create(
231+
{
232+
"product_id": self.product.id,
233+
"product_uom_qty": 1,
234+
}
235+
)
236+
],
237+
}
238+
)
239+
240+
sale_order.action_confirm()
241+
order_line = sale_order.order_line[0]
242+
values = order_line._prepare_procurement_values(None)
243+
244+
self.assertEqual(values.get("final_shipping_partner_id"), self.customer.id)

delivery_dropoff_site/views/view_delivery_carrier.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@
1212
<page
1313
name="dropoff_site"
1414
string="Drop-off Sites"
15-
attrs="{'invisible': [('with_dropoff_site', '=', False)]}"
15+
invisible="not with_dropoff_site"
1616
>
1717
<field name="dropoff_site_ids" nolabel="1">
1818
<tree editable="bottom">
19-
<field name="name" attrs="{'required': True}" />
19+
<field name="name" required='1' />
2020
<field name="street" />
2121
<field name="street2" />
2222
<field name="city" />

delivery_dropoff_site/views/view_dropoff_site.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@
1111
type="object"
1212
class="btn-primary"
1313
icon="fa-calendar-plus-o"
14-
attrs="{'invisible': [('calendar_id', '!=', False)]}"
14+
invisible="not calendar_id"
1515
/>
1616
<button
1717
name="action_disable_calendar"
1818
string="Disable Calendar"
1919
type="object"
2020
icon="fa-calendar-minus-o"
21-
attrs="{'invisible': [('calendar_id', '=', False)]}"
21+
invisible="not calendar_id"
2222
/>
2323
<button
2424
name="geo_localize"
@@ -128,7 +128,7 @@
128128
<page
129129
name="calendar"
130130
string="Calendar"
131-
attrs="{'invisible': [('calendar_id', '=', False)]}"
131+
invisible="not calendar_id"
132132
>
133133
<field name="calendar_id" invisible="1" />
134134
<field name="attendance_ids">

0 commit comments

Comments
 (0)