[IMP] sale_stock: forecast widget

Add the forecast widget for the sale order line's delivered quantity.

task-2058495
This commit is contained in:
svs-odoo
2020-07-31 12:36:55 +00:00
parent f44da631f4
commit 89625df828
2 changed files with 39 additions and 0 deletions
+33
View File
@@ -8,8 +8,11 @@ from collections import defaultdict
from odoo import api, fields, models, _
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT, float_compare, float_round
from odoo.tools.float_utils import float_repr
from odoo.tools.misc import format_date
from odoo.exceptions import UserError
_logger = logging.getLogger(__name__)
@@ -267,6 +270,7 @@ class SaleOrderLine(models.Model):
qty_to_deliver = fields.Float(compute='_compute_qty_to_deliver')
is_mto = fields.Boolean(compute='_compute_is_mto')
display_qty_widget = fields.Boolean(compute='_compute_qty_to_deliver')
json_forecast = fields.Char('JSON data for the forecast widget', compute='_compute_json_forecast')
@api.depends('product_id', 'product_uom_qty', 'qty_delivered', 'state')
def _compute_qty_to_deliver(self):
@@ -354,6 +358,35 @@ class SaleOrderLine(models.Model):
else:
line.is_mto = False
@api.depends('move_ids', 'order_id.expected_date', 'qty_delivered')
def _compute_json_forecast(self):
self.json_forecast = False
if not any(self._ids):
# onchange
return
# compute
precision = self.env['decimal.precision'].precision_get('Product Unit of Measure')
for so_line in self:
if any(so_line.move_ids.filtered(lambda move: move.state in ['done'])):
qty_delivered = float_repr(so_line.qty_delivered, precision)
so_line.json_forecast = json.dumps({'reservedAvailability': qty_delivered})
else:
# For waiting deliveries, take the info from the report line.
delivery = so_line.move_ids.picking_id.filtered(lambda picking: picking.state in ['confirmed', 'waiting'])
if delivery.exists():
moves_to_process = so_line.move_ids.filtered(lambda move: move.id in delivery.move_lines.ids and move.state not in ['cancel', 'done'])
if moves_to_process.exists():
so_line.json_forecast = moves_to_process[0].json_forecast
else:
# For assigned deliveries, take the delivery's date.
delivery = so_line.move_ids.picking_id.filtered(lambda picking: picking.state == 'assigned')
if delivery.exists():
date_expected = delivery.scheduled_date
so_line.json_forecast = json.dumps({
'expectedDate': format_date(self.env, date_expected),
'isLate': date_expected > so_line.order_id.expected_date,
})
@api.depends('product_id')
def _compute_qty_delivered_method(self):
""" Stock module compute delivered qty for product [('type', 'in', ['consu', 'product'])]
@@ -53,6 +53,12 @@
<xpath expr="//field[@name='order_line']/tree/field[@name='analytic_tag_ids']" position="after">
<field name="route_id" groups="stock.group_adv_location" options="{'no_create': True}" optional="hide"/>
</xpath>
<xpath expr="//field[@name='order_line']/tree/field[@name='qty_delivered']" position="attributes">
<attribute name="attrs">{'column_invisible': [('parent.state', 'not in', ['cancel', 'done'])]}</attribute>
</xpath>
<xpath expr="//field[@name='order_line']/tree/field[@name='qty_delivered']" position="after">
<field name="json_forecast" string="Delivered" widget="forecast_widget" attrs="{'column_invisible': [('parent.state', 'in', ['cancel', 'done'])]}"/>
</xpath>
</field>
</record>