File size: 2,049 Bytes
c14ceee
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
"""Vendor module — per-vendor rollup + the multiple-vendor / cheapest-price view.

PURE: it takes the procurement recs (which already merge the curated supplier map + live Odoo
demand/stock + Odoo's alternative vendors via product.supplierinfo) and groups them by vendor, so
there is NO extra Odoo round-trip — the Procurement page and this page share one cached pull. Vendor
master-data edits (country / lead) persist through the procurement overrides store, applied to every
SKU of that vendor (the UI does the bulk write). READ-ONLY on Odoo.
"""


def rollup(recs):
    """[{vendor, country, lead, n_skus, n_buy, demand_units, buy_value, lines}], by SKU count desc."""
    out = {}
    for r in recs:
        v = r.get('vendor') or '(no supplier)'
        g = out.setdefault(v, {'vendor': v, 'country': r.get('country', ''), 'lead': r.get('lead', 0),
                               'n_skus': 0, 'n_buy': 0, 'demand_units': 0.0, 'buy_value': 0.0, 'lines': []})
        g['n_skus'] += 1
        if r.get('buy'):
            g['n_buy'] += 1
        g['demand_units'] += (r.get('demand_8m') or 0)
        g['buy_value'] += (r.get('reorder_trend') or 0) * (r.get('unit_cost') or 0)
        g['lines'].append(r)
        if not g['country'] and r.get('country'):
            g['country'] = r['country']
        if not g['lead'] and r.get('lead'):
            g['lead'] = r['lead']
    return sorted(out.values(), key=lambda x: (-x['n_skus'], x['vendor'] or '~'))


def multi_vendor(recs):
    """SKUs Odoo lists with >1 vendor — current vendor/cost vs the cheapest alternative (price-shop)."""
    out = []
    for r in recs:
        if (r.get('n_vendors') or 0) <= 1:
            continue
        cur = r.get('unit_cost') or 0
        cheapest = r.get('cheapest_price')
        cheaper = bool(cheapest is not None and cur > 0 and cheapest < cur - 1e-9)
        out.append({**r, 'current_cost': cur,
                    'savings': (cur - cheapest) if cheaper else 0.0, 'cheaper': cheaper})
    out.sort(key=lambda r: -r['savings'])
    return out