Skip to content

Commit

Permalink
[MIG] fieldservice_sale: Migration to 16.0
Browse files Browse the repository at this point in the history
Co-Authored-By: Alexandre Fayolle, Stefan Ungureanu

Dependency on migration of fieldservice_account: #1042
Refactoring and fix view errors
Fix view error (obsolete XMLID)
Remove obsolete onchange
Update unit tests
  • Loading branch information
epanisset authored and stefan-tecnativa committed Jun 12, 2023
1 parent 20dc4d8 commit 1735f9c
Show file tree
Hide file tree
Showing 15 changed files with 170 additions and 184 deletions.
18 changes: 11 additions & 7 deletions fieldservice_sale/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ Field Service - Sales
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Ffield--service-lightgray.png?logo=github
:target: https://github.com/OCA/field-service/tree/15.0/fieldservice_sale
:target: https://github.com/OCA/field-service/tree/16.0/fieldservice_sale
:alt: OCA/field-service
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/field-service-15-0/field-service-15-0-fieldservice_sale
:target: https://translation.odoo-community.org/projects/field-service-16-0/field-service-16-0-fieldservice_sale
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/264/15.0
:alt: Try me on Runbot
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/webui/builds.html?repo=OCA/field-service&target_branch=16.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

Expand Down Expand Up @@ -99,7 +99,7 @@ Bug Tracker
Bugs are tracked on `GitHub Issues <https://github.com/OCA/field-service/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
`feedback <https://github.com/OCA/field-service/issues/new?body=module:%20fieldservice_sale%0Aversion:%2015.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
`feedback <https://github.com/OCA/field-service/issues/new?body=module:%20fieldservice_sale%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Expand All @@ -126,6 +126,10 @@ Contributors
* Rapha??l Reverdy <[email protected]>
* Cl??ment Mombereau <[email protected]>

* `Tecnativa <https://www.tecnativa.com>`_:

* Stefan Ungureanu

Maintainers
~~~~~~~~~~~

Expand Down Expand Up @@ -153,6 +157,6 @@ Current `maintainers <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-wolfhall| |maintainer-max3903| |maintainer-brian10048|

This module is part of the `OCA/field-service <https://github.com/OCA/field-service/tree/15.0/fieldservice_sale>`_ project on GitHub.
This module is part of the `OCA/field-service <https://github.com/OCA/field-service/tree/16.0/fieldservice_sale>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
4 changes: 2 additions & 2 deletions fieldservice_sale/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Field Service - Sales",
"version": "15.0.2.0.2",
"version": "16.0.1.0.0",
"summary": "Sell field services.",
"category": "Field Service",
"author": "Open Source Integrators, Odoo Community Association (OCA)",
Expand All @@ -14,11 +14,11 @@
],
"data": [
"security/ir.model.access.csv",
"security/res_groups.xml",
"views/fsm_location.xml",
"views/fsm_order.xml",
"views/product_template.xml",
"views/sale_order.xml",
"data/fsm_template_group.xml",
],
"license": "AGPL-3",
"development_status": "Beta",
Expand Down
12 changes: 0 additions & 12 deletions fieldservice_sale/migrations/15.0.1.0.0/pre-migration.py

This file was deleted.

4 changes: 1 addition & 3 deletions fieldservice_sale/models/product_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ class ProductTemplate(models.Model):
_inherit = "product.template"

service_type = fields.Selection(
selection_add=[
("field", "Field Service Orders"),
],
selection_add=[("field", "Field Service Orders")],
ondelete={"field": "cascade"},
)
field_service_tracking = fields.Selection(
Expand Down
49 changes: 27 additions & 22 deletions fieldservice_sale/models/sale_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ class SaleOrder(models.Model):
"fsm.location",
string="Service Location",
help="SO Lines generating a FSM order will be for this location",
compute="_compute_fsm_location_id",
precompute=True,
store=True,
readonly=False,
)
fsm_order_ids = fields.Many2many(
"fsm.order",
Expand All @@ -24,35 +28,36 @@ class SaleOrder(models.Model):

@api.depends("order_line")
def _compute_fsm_order_ids(self):
for order in self:
orders = self.env["fsm.order"]
orders |= self.env["fsm.order"].search(
[("sale_line_id", "in", order.order_line.ids)]
for sale in self:
fsm = self.env["fsm.order"].search(
[
"|",
("sale_id", "=", sale.id),
("sale_line_id", "in", sale.order_line.ids),
]
)
orders |= self.env["fsm.order"].search([("sale_id", "=", order.id)])
order.fsm_order_ids = orders
order.fsm_order_count = len(order.fsm_order_ids)
sale.fsm_order_ids = fsm
sale.fsm_order_count = len(sale.fsm_order_ids)

@api.onchange("partner_id")
def onchange_partner_id(self):
@api.depends("partner_id", "partner_shipping_id")
def _compute_fsm_location_id(self):
"""
Autofill the Sale Order's FS location with the partner_id,
the partner_shipping_id or the partner_id.commercial_partner_id if
they are FS locations.
"""
res = super(SaleOrder, self).onchange_partner_id()
domain = [
"|",
"|",
("partner_id", "=", self.partner_id.id),
("partner_id", "=", self.partner_shipping_id.id),
("partner_id", "=", self.partner_id.commercial_partner_id.id),
]
if self.partner_id.fsm_location:
domain = [("partner_id", "=", self.partner_id.id)]
location_ids = self.env["fsm.location"].search(domain)
self.fsm_location_id = location_ids and location_ids[0] or False
return res
for so in self:
if so.partner_id.fsm_location:
domain = [("partner_id", "=", so.partner_id.id)]
else:
domain = [
"|",
"|",
("partner_id", "=", so.partner_id.id),
("partner_id", "=", so.partner_shipping_id.id),
("partner_id", "=", so.partner_id.commercial_partner_id.id),
]
so.fsm_location_id = self.env["fsm.location"].search(domain, limit=1)

def _prepare_fsm_values(self, **kwargs):
self.ensure_one()
Expand Down
28 changes: 10 additions & 18 deletions fieldservice_sale/models/sale_order_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,28 @@ class SaleOrderLine(models.Model):

@api.depends("product_id.type")
def _compute_product_updatable(self):
res = super()._compute_product_updatable()
for line in self:
if line.product_id.type == "service" and line.state == "sale":
line.product_updatable = False
else:
return super(SaleOrderLine, line)._compute_product_updatable()
return res

@api.depends("product_id")
def _compute_qty_delivered_method(self):
res = super(SaleOrderLine, self)._compute_qty_delivered_method()
res = super()._compute_qty_delivered_method()
for line in self:
if not line.is_expense and line.product_id.field_service_tracking == "line":
line.qty_delivered_method = "field_service"
return res

@api.depends("fsm_order_id.stage_id")
def _compute_qty_delivered(self):
res = super(SaleOrderLine, self)._compute_qty_delivered()
lines_by_fsm = self.filtered(
lambda sol: sol.qty_delivered_method == "field_service"
)
complete = self.env.ref("fieldservice.fsm_stage_completed")
for line in lines_by_fsm:
qty = 0
if line.fsm_order_id.stage_id == complete:
qty = line.product_uom_qty
line.qty_delivered = qty
res = super()._compute_qty_delivered()
stage_complete = self.env.ref("fieldservice.fsm_stage_completed")
fsm_lines = self.filtered(lambda l: l.qty_delivered_method == "field_service")
for line in fsm_lines:
if line.fsm_order_id.stage_id == stage_complete:
line.qty_delivered = line.product_uom_qty
return res

@api.model_create_multi
Expand All @@ -60,9 +56,5 @@ def create(self, vals_list):
def _prepare_invoice_line(self, **optional_values):
res = super()._prepare_invoice_line(**optional_values)
if self.fsm_order_id:
res.update(
{
"fsm_order_ids": [(4, self.fsm_order_id.id)],
}
)
res.update({"fsm_order_ids": [(4, self.fsm_order_id.id)]})
return res
4 changes: 4 additions & 0 deletions fieldservice_sale/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@
* Brian McMaster <[email protected]>
* Rapha??l Reverdy <[email protected]>
* Cl??ment Mombereau <[email protected]>

* `Tecnativa <https://www.tecnativa.com>`_:

* Stefan Ungureanu
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- Activate the FSM Template Group by default -->
<record id="base.group_user" model="res.groups">
<field
<record id="base.group_user" model="res.groups">
<field
name="implied_ids"
eval="[(4, ref('fieldservice.group_fsm_template'))]"
/>
</record>
</record>

</odoo>
12 changes: 8 additions & 4 deletions fieldservice_sale/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.15.1: http://docutils.sourceforge.net/" />
<meta name="generator" content="Docutils: http://docutils.sourceforge.net/" />
<title>Field Service - Sales</title>
<style type="text/css">

Expand Down Expand Up @@ -367,7 +367,7 @@ <h1 class="title">Field Service - Sales</h1>
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/field-service/tree/15.0/fieldservice_sale"><img alt="OCA/field-service" src="https://img.shields.io/badge/github-OCA%2Ffield--service-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/field-service-15-0/field-service-15-0-fieldservice_sale"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/264/15.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/field-service/tree/16.0/fieldservice_sale"><img alt="OCA/field-service" src="https://img.shields.io/badge/github-OCA%2Ffield--service-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/field-service-16-0/field-service-16-0-fieldservice_sale"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runboat.odoo-community.org/webui/builds.html?repo=OCA/field-service&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>The module integrates the Field Service application with the Sales one and
allows you to sell products that generate field service orders.</p>
<p><strong>Table of contents</strong></p>
Expand Down Expand Up @@ -452,7 +452,7 @@ <h1><a class="toc-backref" href="#id5">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/field-service/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/field-service/issues/new?body=module:%20fieldservice_sale%0Aversion:%2015.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<a class="reference external" href="https://github.com/OCA/field-service/issues/new?body=module:%20fieldservice_sale%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
Expand All @@ -477,6 +477,10 @@ <h2><a class="toc-backref" href="#id8">Contributors</a></h2>
<li>Brian McMaster &lt;<a class="reference external" href="mailto:brian&#64;mcmpest.com">brian&#64;mcmpest.com</a>&gt;</li>
<li>Rapha??l Reverdy &lt;<a class="reference external" href="mailto:raphael.reverdy&#64;akretion.com">raphael.reverdy&#64;akretion.com</a>&gt;</li>
<li>Cl??ment Mombereau &lt;<a class="reference external" href="mailto:clement.mombereau&#64;akretion.com">clement.mombereau&#64;akretion.com</a>&gt;</li>
<li><a class="reference external" href="https://www.tecnativa.com">Tecnativa</a>:<ul>
<li>Stefan Ungureanu</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="maintainers">
Expand All @@ -488,7 +492,7 @@ <h2><a class="toc-backref" href="#id9">Maintainers</a></h2>
promote its widespread use.</p>
<p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainers</a>:</p>
<p><a class="reference external" href="https://github.com/wolfhall"><img alt="wolfhall" src="https://github.com/wolfhall.png?size=40px" /></a> <a class="reference external" href="https://github.com/max3903"><img alt="max3903" src="https://github.com/max3903.png?size=40px" /></a> <a class="reference external" href="https://github.com/brian10048"><img alt="brian10048" src="https://github.com/brian10048.png?size=40px" /></a></p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/field-service/tree/15.0/fieldservice_sale">OCA/field-service</a> project on GitHub.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/field-service/tree/16.0/fieldservice_sale">OCA/field-service</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion fieldservice_sale/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)

from . import (
test_fsm_sale_onchange_partner,
test_fsm_sale_autofill_location,
test_fsm_sale_common,
test_fsm_sale_order,
)
98 changes: 98 additions & 0 deletions fieldservice_sale/tests/test_fsm_sale_autofill_location.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Copyright (C) 2019 Clément Mombereau (Akretion)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
from odoo.tests.common import Form, TransactionCase


class FSMSale(TransactionCase):
@classmethod
def setUpClass(cls):
"""Create 3 related partners : a parent company, a child partner and
a child shipping partner.
For each test, a different partner is a fsm_location.
A SO is created with the child partner as customer. The test run
the SO's location autofill and check if the fsm_location_id
is the expected one.
"""
super().setUpClass()
# create a parent company
cls.commercial_partner = cls.env["res.partner"].create(
{"name": "Company Commercial Partner", "is_company": True}
)
# create a child partner
cls.partner = cls.env["res.partner"].create(
{"name": "Child Partner 1", "parent_id": cls.commercial_partner.id}
)
# create a child partner shipping address
cls.shipping_partner = cls.env["res.partner"].create(
{
"name": "Shipping Partner",
"parent_id": cls.commercial_partner.id,
"type": "delivery",
}
)
# Demo FS location
cls.location1 = cls.env.ref("fieldservice.location_1")
cls.location2 = cls.env.ref("fieldservice.location_2")
cls.location3 = cls.env.ref("fieldservice.location_3")

def test_00_autofill_so_fsm_location(self):
"""Check location autofill from SO partner
SO partner is an FSM location linked to location 2 => expect location2
(location 1 and 3 are ignored because we want only location explicitly
linked to the partner)
"""
self.partner.fsm_location = True
self.location1.partner_id = self.commercial_partner
self.location2.partner_id = self.partner
self.location3.partner_id = self.shipping_partner
with Form(self.env["sale.order"]) as so_form:
so_form.partner_id = self.partner
so = so_form.save()
self.assertEqual(so.fsm_location_id, self.location2)

def test_01_autofill_so_fsm_location(self):
"""Check location autofill from SO partner
SO partner is not an FSM location defined, but location1 is linked to
its commercial partner => expect location 1 (because of ordering)
"""
self.partner.fsm_location = False
self.location1.partner_id = self.commercial_partner
self.location2.partner_id = self.partner
self.location3.partner_id = self.shipping_partner
with Form(self.env["sale.order"]) as so_form:
so_form.partner_id = self.partner
so = so_form.save()
self.assertEqual(so.fsm_location_id, self.location1)

def test_02_autofill_so_fsm_location(self):
"""Check location autofill from SO partner
SO partner is not an FSM location defined, but location1 is linked to
the partner itself => expect location 1 (because of ordering)
"""
self.partner.fsm_location = False
self.location1.partner_id = self.partner
self.location2.partner_id = self.shipping_partner
self.location3.partner_id = self.commercial_partner
with Form(self.env["sale.order"]) as so_form:
so_form.partner_id = self.partner
so = so_form.save()
self.assertEqual(so.fsm_location_id, self.location1)

def test_03_autofill_so_fsm_location(self):
"""Check location autofill from SO partner
SO partner is not an FSM location defined, but location1 is linked to
its shipping partner => expect location 1 (because of ordering)
"""
self.partner.fsm_location = False
self.location1.partner_id = self.shipping_partner
self.location2.partner_id = self.commercial_partner
self.location3.partner_id = self.partner
with Form(self.env["sale.order"]) as so_form:
so_form.partner_id = self.partner
so = so_form.save()
self.assertEqual(so.fsm_location_id, self.location1)
Loading

0 comments on commit 1735f9c

Please sign in to comment.