diff options
Diffstat (limited to 'addons/purchase_stock/models/res_partner.py')
| -rw-r--r-- | addons/purchase_stock/models/res_partner.py | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/addons/purchase_stock/models/res_partner.py b/addons/purchase_stock/models/res_partner.py new file mode 100644 index 00000000..89604b83 --- /dev/null +++ b/addons/purchase_stock/models/res_partner.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from datetime import timedelta, datetime, time +from collections import defaultdict + +from odoo import api, fields, models + + +class ResPartner(models.Model): + _inherit = 'res.partner' + + purchase_line_ids = fields.One2many('purchase.order.line', 'partner_id', string="Purchase Lines") + on_time_rate = fields.Float( + "On-Time Delivery Rate", compute='_compute_on_time_rate', + help="Over the past 12 months; the number of products received on time divided by the number of ordered products.") + + @api.depends('purchase_line_ids') + def _compute_on_time_rate(self): + order_lines = self.env['purchase.order.line'].search([ + ('partner_id', 'in', self.ids), + ('date_order', '>', fields.Date.today() - timedelta(365)), + ('qty_received', '!=', 0), + ('order_id.state', 'in', ['done', 'purchase']) + ]).filtered(lambda l: l.product_id.sudo().product_tmpl_id.type != 'service') + lines_qty_done = defaultdict(lambda: 0) + moves = self.env['stock.move'].search([ + ('purchase_line_id', 'in', order_lines.ids), + ('state', '=', 'done')]).filtered(lambda m: m.date.date() <= m.purchase_line_id.date_planned.date()) + for move, qty_done in zip(moves, moves.mapped('quantity_done')): + lines_qty_done[move.purchase_line_id.id] += qty_done + partner_dict = {} + for line in order_lines: + on_time, ordered = partner_dict.get(line.partner_id, (0, 0)) + ordered += line.product_uom_qty + on_time += lines_qty_done[line.id] + partner_dict[line.partner_id] = (on_time, ordered) + seen_partner = self.env['res.partner'] + for partner, numbers in partner_dict.items(): + seen_partner |= partner + on_time, ordered = numbers + partner.on_time_rate = on_time / ordered * 100 if ordered else -1 # use negative number to indicate no data + (self - seen_partner).on_time_rate = -1 |
