Add module service_line_qty_update_sale
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# 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):
|
class PurchaseOrder(models.Model):
|
||||||
@@ -10,6 +10,7 @@ class PurchaseOrder(models.Model):
|
|||||||
|
|
||||||
has_service = fields.Boolean(compute='_compute_has_service')
|
has_service = fields.Boolean(compute='_compute_has_service')
|
||||||
|
|
||||||
|
@api.depends('order_line.product_id.type')
|
||||||
def _compute_has_service(self):
|
def _compute_has_service(self):
|
||||||
for order in self:
|
for order in self:
|
||||||
has_service = False
|
has_service = False
|
||||||
|
|||||||
2
service_line_qty_update_sale/__init__.py
Normal file
2
service_line_qty_update_sale/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
from . import models
|
||||||
|
from . import wizard
|
||||||
22
service_line_qty_update_sale/__manifest__.py
Normal file
22
service_line_qty_update_sale/__manifest__.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# Copyright 2020 Akretion France (http://www.akretion.com)
|
||||||
|
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||||
|
# 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,
|
||||||
|
}
|
||||||
1
service_line_qty_update_sale/models/__init__.py
Normal file
1
service_line_qty_update_sale/models/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from . import sale_order
|
||||||
21
service_line_qty_update_sale/models/sale_order.py
Normal file
21
service_line_qty_update_sale/models/sale_order.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Copyright 2020 Akretion France (http://www.akretion.com)
|
||||||
|
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||||
|
# 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
|
||||||
26
service_line_qty_update_sale/views/sale_order.xml
Normal file
26
service_line_qty_update_sale/views/sale_order.xml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright 2020 Akretion France (http://www.akretion.com/)
|
||||||
|
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
-->
|
||||||
|
|
||||||
|
<odoo>
|
||||||
|
|
||||||
|
|
||||||
|
<record id="view_order_form" model="ir.ui.view">
|
||||||
|
<field name="model">sale.order</field>
|
||||||
|
<field name="inherit_id" ref="sale.view_order_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<button name="action_quotation_send" position="after">
|
||||||
|
<button name="%(service_line_qty_update_base.service_qty_update_action)d" type="action" string="Update Service Qty" attrs="{'invisible': ['|', ('state', 'not in', ('sale', 'done')), ('has_service', '=', False)]}" groups="sales_team.group_sale_salesman"/>
|
||||||
|
<field name="has_service" invisible="1"/>
|
||||||
|
</button>
|
||||||
|
<xpath expr="//field[@name='order_line']/tree/field[@name='qty_delivered']" position="attributes">
|
||||||
|
<attribute name="readonly">1</attribute>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
</odoo>
|
||||||
1
service_line_qty_update_sale/wizard/__init__.py
Normal file
1
service_line_qty_update_sale/wizard/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from . import service_qty_update
|
||||||
62
service_line_qty_update_sale/wizard/service_qty_update.py
Normal file
62
service_line_qty_update_sale/wizard/service_qty_update.py
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
# Copyright 2020 Akretion France (http://www.akretion.com/)
|
||||||
|
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||||
|
# 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 = """
|
||||||
|
<p>Delivered qty updated on service line <b>%s</b>:
|
||||||
|
<ul>
|
||||||
|
<li>Added delivered qty: <b>%s</b></li>
|
||||||
|
<li>Total delivered qty: %s</li>
|
||||||
|
</ul></p>
|
||||||
|
""" % (self.name, self.added_delivered_qty, new_qty)
|
||||||
|
if self.comment:
|
||||||
|
body += '<p>Comment: %s</p>' % self.comment
|
||||||
|
so_line.order_id.message_post(body=body)
|
||||||
|
return super().process_line()
|
||||||
Reference in New Issue
Block a user