Skip to content

Commit

Permalink
[REF] repair, *_repair: Separate Repair from Sales/Invoicing scopes
Browse files Browse the repository at this point in the history
Main changes include :
 - Separate Repair and Sales/Invoicing functionalities
 - Possible binding between a Sale Order and many Repair Orders
 - Specific 'repair.line' model is now replaced by a 'stock.move' inheritance
 - Added a new 'Repairs' Operation Type to warehouse(s)

Task : 3046560

Enterprise : odoo/enterprise#36088
Upgrade : odoo/upgrade#4391

closes #106911

Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
  • Loading branch information
mama-odoo committed Jul 20, 2023
1 parent f11e84b commit eaa6e1a
Show file tree
Hide file tree
Showing 38 changed files with 1,703 additions and 1,570 deletions.
25 changes: 7 additions & 18 deletions addons/mrp_repair/models/repair.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def write(self, vals):
def action_explode(self):
lines_to_unlink_ids = set()
line_vals_list = []
for op in self.operations:
for op in self.move_ids:
bom = self.env['mrp.bom'].sudo()._bom_find(op.product_id, company_id=op.company_id.id, bom_type='phantom')[op.product_id]
if not bom:
continue
Expand All @@ -31,35 +31,24 @@ def action_explode(self):
line_vals_list.append(op._prepare_phantom_line_vals(bom_line, line_data['qty']))
lines_to_unlink_ids.add(op.id)

self.env['repair.line'].browse(lines_to_unlink_ids).sudo().unlink()
self.env['stock.move'].browse(lines_to_unlink_ids).sudo().unlink()
if line_vals_list:
self.env['repair.line'].create(line_vals_list)
self.env['stock.move'].create(line_vals_list)


class RepairLine(models.Model):
_inherit = 'repair.line'
class StockMove(models.Model):
_inherit = 'stock.move'

def _prepare_phantom_line_vals(self, bom_line, qty):
self.ensure_one()
product = bom_line.product_id
uom = bom_line.product_uom_id
partner = self.repair_id.partner_id
price = self.repair_id.pricelist_id._get_product_price(product, qty, uom=uom)
tax = self.env['account.tax']
if partner:
partner_invoice = self.repair_id.partner_invoice_id or partner
fpos = self.env['account.fiscal.position']._get_fiscal_position(partner_invoice, delivery=self.repair_id.address_id)
taxes = self.product_id.taxes_id.filtered(lambda x: x.company_id == self.repair_id.company_id)
tax = fpos.map_tax(taxes)
return {
'name': self.name,
'repair_id': self.repair_id.id,
'type': self.type,
'repair_line_type': self.repair_line_type,
'product_id': product.id,
'price_unit': price,
'tax_id': [(4, t.id) for t in tax],
'price_unit': self.price_unit,
'product_uom_qty': qty,
'product_uom': uom.id,
'location_id': self.location_id.id,
'location_dest_id': self.location_dest_id.id,
'state': 'draft',
Expand Down
14 changes: 6 additions & 8 deletions addons/mrp_repair/tests/test_tracability.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ def test_tracking_repair_production(self):
with Form(self.env['repair.order']) as ro_form:
ro_form.product_id = product_to_repair
ro_form.lot_id = ptrepair_lot # Repair product Serial A1
with ro_form.operations.new() as operation:
operation.type = 'remove'
with ro_form.move_ids.new() as operation:
operation.repair_line_type = 'remove'
operation.product_id = product_to_remove
operation.lot_id = ptremove_lot # Remove product Serial B2 from the product
ro = ro_form.save()
ro.action_validate()
ro.move_ids[0].lot_ids = ptremove_lot # Remove product Serial B2 from the product.
ro.action_repair_start()
ro.action_repair_end()

Expand Down Expand Up @@ -119,16 +119,14 @@ def produce_one(product, component):
mo = produce_one(finished, component)
self.assertEqual(mo.state, 'done')
self.assertEqual(mo.move_raw_ids.lot_ids, sn_lot)

ro_form = Form(self.env['repair.order'])
ro_form.product_id = finished
with ro_form.operations.new() as ro_line:
ro_line.type = 'remove'
with ro_form.move_ids.new() as ro_line:
ro_line.repair_line_type = 'recycle'
ro_line.product_id = component
ro_line.lot_id = sn_lot
ro_line.location_dest_id = stock_location
ro = ro_form.save()
ro.action_validate()
ro.move_ids[0].lot_ids = sn_lot
ro.action_repair_start()
ro.action_repair_end()

Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_subcontracting_portal_repair_line,subcontracting.portal.repair_line,repair.model_repair_line,base.group_portal,1,0,0,0
access_subcontracting_portal_repair_move,subcontracting.portal.repair_move,repair.model_stock_move,base.group_portal,1,0,0,0
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<record id="repair_line_subcontracting_rule" model="ir.rule">
<field name="name">Repair Line Subcontractor</field>
<field name="model_id" ref="repair.model_repair_line"/>
<field name="model_id" ref="repair.model_stock_move"/>
<field name="domain_force">[
'|',
'|',
Expand Down
13 changes: 13 additions & 0 deletions addons/repair/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,16 @@

from . import models
from . import wizard
from . import report

from odoo import api, SUPERUSER_ID

def _create_warehouse_data(env):
""" This hook is used to add default repair picking types on every warehouse.
It is necessary if the repair module is installed after some warehouses were already created.
"""
warehouses = env['stock.warehouse'].search([('repair_type_id', '=', False)])
for warehouse in warehouses:
picking_type_vals = warehouse._create_or_update_sequences_and_picking_types()
if picking_type_vals:
warehouse.write(picking_type_vals)
12 changes: 7 additions & 5 deletions addons/repair/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,29 @@
------------------------------------------------------
* Add/remove products in the reparation
* Impact for stocks
* Invoicing (products and/or services)
* Warranty concept
* Repair quotation report
* Notes for the technician and for the final customer
""",
'depends': ['stock', 'sale_management', 'account'],
'depends': ['stock', 'sale_management'],
'data': [
'security/ir.model.access.csv',
'security/repair_security.xml',
'wizard/repair_make_invoice_views.xml',
'wizard/stock_warn_insufficient_qty_views.xml',
'wizard/repair_warn_uncomplete_move.xml',
'views/product_views.xml',
'views/stock_move_views.xml',
'views/repair_views.xml',
'views/sale_order_views.xml',
'views/stock_lot_views.xml',
'views/stock_picking_views.xml',
'views/stock_warehouse_views.xml',
'report/repair_reports.xml',
'report/repair_templates_repair_order.xml',
'data/ir_sequence_data.xml',
'data/mail_template_data.xml',
'data/repair_data.xml',
],
'demo': ['data/repair_demo.xml'],
'post_init_hook': '_create_warehouse_data',
'installable': True,
'application': True,
'license': 'LGPL-3',
Expand Down
12 changes: 0 additions & 12 deletions addons/repair/data/ir_sequence_data.xml

This file was deleted.

36 changes: 0 additions & 36 deletions addons/repair/data/mail_template_data.xml

This file was deleted.

24 changes: 24 additions & 0 deletions addons/repair/data/repair_data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo noupdate="1">
<!--
Given that data are loaded before update of warehouses through the post_init_hook,
we manually create the 'Repairs' Operation Type in warehouse0 here such that it's available
when the initialization of data triggers the default method of the required field 'picking_type_id'.
-->

<record id="picking_type_warehouse0_repair" model="stock.picking.type" forcecreate="0">
<field name="name">Repairs</field>
<field name="code">repair_operation</field>
<field name="company_id" ref="base.main_company"/>
<field name="default_location_src_id" ref="stock.stock_location_stock"/>
<field name="default_location_dest_id" model="stock.location" search="[('usage', '=', 'production'), ('company_id', '=', obj().env.ref('base.main_company').id)]"/>
<field name="default_remove_location_dest_id" model="stock.location" search="[('scrap_location', '=', True), ('company_id', '=', obj().env.ref('base.main_company').id)]"/>
<field name="default_recycle_location_dest_id" ref="stock.stock_location_stock"/>
<field name="sequence_code">RO</field>
<field name="warehouse_id" ref="stock.warehouse0"/>
</record>

<record id='stock.warehouse0' model='stock.warehouse'>
<field name='repair_type_id' ref='repair.picking_type_warehouse0_repair'/>
</record>
</odoo>
58 changes: 10 additions & 48 deletions addons/repair/data/repair_demo.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,69 +6,44 @@
<field name="standard_price">20.5</field>
<field name="list_price">30.75</field>
<field name="type">service</field>
<field name="create_repair">True</field>
</record>

<record id="repair_r1" model="repair.order">
<field name="schedule_date" eval="DateTime.today()"/>
<field name="address_id" ref="base.res_partner_address_1"/>
<field name="guarantee_limit" eval="datetime.today().strftime('%Y-%m-%d')"/>
<field name="invoice_method">none</field>
<field name="user_id"/>
<field name="product_id" ref="product.product_product_3"/>
<field name="product_uom" ref="uom.product_uom_unit"/>
<field name="partner_invoice_id" ref="base.res_partner_address_1"/>
<field name="location_id" ref="stock.stock_location_stock"/>
<field name="operations" model="repair.line" eval="[(5, 0, 0), (0, 0, {
<field name="picking_type_id" ref="picking_type_warehouse0_repair"/>
<field name="move_ids" model="stock.move" eval="[(5, 0, 0), (0, 0, {
'location_dest_id': obj().env.ref('product.product_product_11').property_stock_production.id,
'location_id': obj().env.ref('stock.stock_location_stock').id,
'name': obj().env.ref('product.product_product_11').get_product_multiline_description_sale(),
'product_id': obj().env.ref('product.product_product_11').id,
'product_uom': obj().env.ref('uom.product_uom_unit').id,
'product_uom_qty': '1.0',
'price_unit': 50.0,
'state': 'draft',
'type': 'add',
'repair_line_type': 'add',
'company_id': obj().env.ref('base.main_company').id,
})]"/>
<field name="fees_lines" model="repair.fee" eval="[(5, 0, 0), (0, 0, {
'name': obj().env.ref('repair.product_service_order_repair').get_product_multiline_description_sale(),
'product_id': obj().env.ref('repair.product_service_order_repair').id,
'product_uom_qty': 1.0,
'product_uom': obj().env.ref('uom.product_uom_unit').id,
'company_id': obj().env.ref('base.main_company').id,
'price_unit': 50.0,
})]"/>
<field name="partner_id" ref="base.res_partner_12"/>
</record>

<record id="repair_r0" model="repair.order">
<field name="schedule_date" eval="DateTime.today()"/>
<field name="product_id" ref="product.product_product_5"/>
<field name="product_uom" ref="uom.product_uom_unit"/>
<field name="address_id" ref="base.res_partner_address_1"/>
<field name="guarantee_limit" eval="datetime.today().strftime('%Y-%m-%d')"/>
<field name="invoice_method">after_repair</field>
<field name="user_id"/>
<field name="partner_invoice_id" ref="base.res_partner_address_1"/>
<field name="location_id" ref="stock.stock_location_stock"/>
<field name="operations" model="repair.line" eval="[(5, 0, 0), (0, 0, {
<field name="picking_type_id" ref="picking_type_warehouse0_repair"/>
<field name="move_ids" model="stock.move" eval="[(5, 0, 0), (0, 0, {
'location_dest_id': obj().env.ref('product.product_product_12').property_stock_production.id,
'location_id': obj().env.ref('stock.stock_location_stock').id,
'name': obj().env.ref('product.product_product_12').get_product_multiline_description_sale(),
'price_unit': 50.0,
'product_id': obj().env.ref('product.product_product_12').id,
'product_uom': obj().env.ref('uom.product_uom_unit').id,
'product_uom_qty': 1.0,
'state': 'draft',
'type': 'add',
'company_id': obj().env.ref('base.main_company').id,
})]"/>
<field name="fees_lines" model="repair.fee" eval="[(5, 0, 0), (0, 0, {
'name': obj().env.ref('repair.product_service_order_repair').get_product_multiline_description_sale(),
'product_id': obj().env.ref('repair.product_service_order_repair').id,
'product_uom_qty': 1.0,
'product_uom': obj().env.ref('uom.product_uom_unit').id,
'price_unit': 50.0,
'repair_line_type': 'add',
'company_id': obj().env.ref('base.main_company').id,
})]"/>
<field name="partner_id" ref="base.res_partner_12"/>
Expand All @@ -79,30 +54,17 @@
<field name="schedule_date" eval="DateTime.today() + relativedelta(days=-5)"/>
<field name="product_id" ref="product.product_product_6"/>
<field name="product_uom" ref="uom.product_uom_unit"/>
<field name="address_id" ref="base.res_partner_address_1"/>
<field name="guarantee_limit" eval="datetime.today().strftime('%Y-%m-%d')"/>
<field name="invoice_method">b4repair</field>
<field name="user_id"/>
<field name="partner_invoice_id" ref="base.res_partner_address_1"/>
<field name="location_id" ref="stock.stock_location_14"/>
<field name="operations" model="repair.line" eval="[(5, 0, 0), (0, 0, {
<field name="picking_type_id" ref="picking_type_warehouse0_repair"/>
<field name="move_ids" model="stock.move" eval="[(5, 0, 0), (0, 0, {
'location_dest_id': obj().env.ref('product.product_product_13').property_stock_production.id,
'location_id': obj().env.ref('stock.stock_location_stock').id,
'name': obj().env.ref('product.product_product_13').get_product_multiline_description_sale(),
'price_unit': 50.0,
'product_id': obj().env.ref('product.product_product_13').id,
'product_uom': obj().env.ref('uom.product_uom_unit').id,
'product_uom_qty': 1.0,
'state': 'draft',
'type': 'add',
'company_id': obj().env.ref('base.main_company').id,
})]"/>
<field name="fees_lines" model="repair.fee" eval="[(5, 0, 0), (0, 0, {
'name': obj().env.ref('repair.product_service_order_repair').get_product_multiline_description_sale(),
'product_id': obj().env.ref('repair.product_service_order_repair').id,
'product_uom_qty': 1.0,
'product_uom': obj().env.ref('uom.product_uom_unit').id,
'price_unit': 50.0,
'repair_line_type': 'add',
'company_id': obj().env.ref('base.main_company').id,
})]"/>
<field name="partner_id" ref="base.res_partner_12"/>
Expand Down
5 changes: 3 additions & 2 deletions addons/repair/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from . import repair
from . import stock_move
from . import stock_picking
from . import stock_traceability
from . import stock_lot
from . import account_move
from . import product
from . import mail_compose_message
from . import sale_order
from . import stock_warehouse
22 changes: 0 additions & 22 deletions addons/repair/models/account_move.py

This file was deleted.

0 comments on commit eaa6e1a

Please sign in to comment.