diff --git a/service_line_qty_update_purchase/models/purchase_order.py b/service_line_qty_update_purchase/models/purchase_order.py index 89b09be..9cb17cd 100644 --- a/service_line_qty_update_purchase/models/purchase_order.py +++ b/service_line_qty_update_purchase/models/purchase_order.py @@ -2,7 +2,7 @@ # @author Alexis de Lattre # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import fields, models +from odoo import api, fields, models class PurchaseOrder(models.Model): @@ -10,6 +10,7 @@ class PurchaseOrder(models.Model): has_service = fields.Boolean(compute='_compute_has_service') + @api.depends('order_line.product_id.type') def _compute_has_service(self): for order in self: has_service = False diff --git a/service_line_qty_update_sale/__init__.py b/service_line_qty_update_sale/__init__.py new file mode 100644 index 0000000..9b42961 --- /dev/null +++ b/service_line_qty_update_sale/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import wizard diff --git a/service_line_qty_update_sale/__manifest__.py b/service_line_qty_update_sale/__manifest__.py new file mode 100644 index 0000000..45c850d --- /dev/null +++ b/service_line_qty_update_sale/__manifest__.py @@ -0,0 +1,22 @@ +# Copyright 2020 Akretion France (http://www.akretion.com) +# @author Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + 'name': 'Service Line Qty Update Sale', + 'version': '12.0.1.0.0', + 'category': 'Tools', + 'license': 'AGPL-3', + 'summary': 'Update delivery qty on service lines - Sale module', + 'author': 'Akretion', + 'website': 'http://www.akretion.com', + 'depends': [ + 'sale', + 'service_line_qty_update_base', + # 'purchase_reception_status', + ], + 'data': [ + 'views/sale_order.xml', + ], + 'installable': True, +} diff --git a/service_line_qty_update_sale/models/__init__.py b/service_line_qty_update_sale/models/__init__.py new file mode 100644 index 0000000..6aacb75 --- /dev/null +++ b/service_line_qty_update_sale/models/__init__.py @@ -0,0 +1 @@ +from . import sale_order diff --git a/service_line_qty_update_sale/models/sale_order.py b/service_line_qty_update_sale/models/sale_order.py new file mode 100644 index 0000000..802625f --- /dev/null +++ b/service_line_qty_update_sale/models/sale_order.py @@ -0,0 +1,21 @@ +# Copyright 2020 Akretion France (http://www.akretion.com) +# @author Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class SaleOrder(models.Model): + _inherit = 'sale.order' + + has_service = fields.Boolean(compute='_compute_has_service') + + @api.depends('order_line.product_id.type') + def _compute_has_service(self): + for order in self: + has_service = False + for l in order.order_line: + if l.product_id.type == 'service': + has_service = True + break + order.has_service = has_service diff --git a/service_line_qty_update_sale/views/sale_order.xml b/service_line_qty_update_sale/views/sale_order.xml new file mode 100644 index 0000000..04ebf16 --- /dev/null +++ b/service_line_qty_update_sale/views/sale_order.xml @@ -0,0 +1,26 @@ + + + + + + + + sale.order + + + + + 1 + + + + + + diff --git a/service_line_qty_update_sale/wizard/__init__.py b/service_line_qty_update_sale/wizard/__init__.py new file mode 100644 index 0000000..c0ac3f4 --- /dev/null +++ b/service_line_qty_update_sale/wizard/__init__.py @@ -0,0 +1 @@ +from . import service_qty_update diff --git a/service_line_qty_update_sale/wizard/service_qty_update.py b/service_line_qty_update_sale/wizard/service_qty_update.py new file mode 100644 index 0000000..8be21ec --- /dev/null +++ b/service_line_qty_update_sale/wizard/service_qty_update.py @@ -0,0 +1,62 @@ +# Copyright 2020 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + + +from odoo import _, api, fields, models +from odoo.tools import float_compare +from odoo.exceptions import UserError + + +class ServiceQtyUpdate(models.TransientModel): + _inherit = 'service.qty.update' + + @api.model + def default_get(self, fields_list): + res = super().default_get(fields_list) + prec = self.env['decimal.precision'].precision_get('Product Unit of Measure') + if self._context.get('active_model') == 'sale.order' and self._context.get('active_id'): + lines = [] + order = self.env['sale.order'].browse(self._context['active_id']) + for l in order.order_line.filtered(lambda x: x.product_id.type == 'service'): + if float_compare(l.product_qty, l.qty_delivered, precision_digits=prec) > 0: + lines.append((0, 0, { + 'sale_line_id': l.id, + 'product_id': l.product_id.id, + 'name': l.name, + 'name_readonly': l.name, + 'order_qty': l.product_uom_qty, + 'order_qty_readonly': l.product_uom_qty, + 'pre_delivered_qty': l.qty_delivered, + 'pre_delivered_qty_readonly': l.qty_delivered, + 'uom_id': l.product_uom.id, + })) + if lines: + res['line_ids'] = lines + else: + raise UserError(_( + "All service lines are fully delivered.")) + return res + + +class ServiceQtyUpdateLine(models.TransientModel): + _inherit = 'service.qty.update.line' + + sale_line_id = fields.Many2one('sale.order.line', string='Sale Line', readonly=True) + + def process_line(self): + so_line = self.sale_line_id + if so_line: + new_qty = so_line.qty_delivered + self.added_delivered_qty + so_line.write({'qty_delivered': new_qty}) + body = """ +

Delivered qty updated on service line %s: +

    +
  • Added delivered qty: %s
  • +
  • Total delivered qty: %s
  • +

+ """ % (self.name, self.added_delivered_qty, new_qty) + if self.comment: + body += '

Comment: %s

' % self.comment + so_line.order_id.message_post(body=body) + return super().process_line()