trytond-purchase_request_pe.../purchase_request.py

120 lines
4.2 KiB
Python

#The COPYRIGHT file at the top level of this repository contains the full
# copyright notices and license terms.
import datetime
import operator
from trytond.model import ModelView, fields
from trytond.transaction import Transaction
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval, And
__all__ = ['PurchaseRequest']
_STATES = {
'readonly': ~Eval('state').in_(['draft', 'pending']),
}
class PurchaseRequest(metaclass=PoolMeta):
__name__ = 'purchase.request'
pending = fields.Boolean('Pending', readonly=True)
@classmethod
def __setup__(cls):
super(PurchaseRequest, cls).__setup__()
pending = ('pending', 'Pending')
if pending not in cls.state.selection:
cls.state.selection.append(pending)
# set new attributes at all purchase request fields
for fname in dir(cls):
field = getattr(cls, fname)
if hasattr(field, 'states'):
if field.states.get('readonly'):
field.states['readonly'] = And(field.states['readonly'],
_STATES['readonly'])
else:
field.states['readonly'] = _STATES['readonly']
field.depends.add('state')
cls._buttons.update({
'draft': {
'invisible': Eval('state') != 'pending',
'icon': 'tryton-back',
},
'to_pending': {
'invisible': Eval('state') != 'draft',
'icon': 'tryton-forward',
},
})
@staticmethod
def default_pending():
return False
@classmethod
@ModelView.button
def draft(cls, requests):
cls.write(requests, {'pending': False})
cls.update_state(requests)
@classmethod
@ModelView.button
def to_pending(cls, requests):
cls.write(requests, {'pending': True})
cls.update_state(requests)
def get_state(self):
if self.pending and not self.purchase_line:
return 'pending'
return super(PurchaseRequest, self).get_state()
@classmethod
def generate_requests(cls, products=None, warehouses=None):
with Transaction().set_context(generate_requests=True):
return super(PurchaseRequest, cls).generate_requests(products,
warehouses)
@classmethod
def compare_requests(cls, new_requests, company):
pool = Pool()
Uom = pool.get('product.uom')
Request = pool.get('purchase.request')
requests = Request.search([
('purchase_line', '=', None),
('pending', '=', True),
('product', '!=', None),
])
# Fetch data from existing requests
existing_req = {}
for request in requests:
existing_req.setdefault(
(request.product.id, request.warehouse.id),
[]).append({
'supply_date': (
request.supply_date or datetime.date.max),
'quantity': request.quantity,
'unit': request.unit,
})
new_requests = super(PurchaseRequest, cls).compare_requests(
new_requests, company)
new_requests.sort(key=operator.attrgetter('supply_date'))
for new_req in new_requests:
for old_req in existing_req.get(
(new_req.product.id, new_req.warehouse.id), []):
if old_req['supply_date'] <= new_req.supply_date:
quantity = Uom.compute_qty(old_req['unit'],
old_req['quantity'], new_req.unit)
new_req.quantity = max(0.0, new_req.quantity - quantity)
new_req.computed_quantity = new_req.quantity
old_req['quantity'] = Uom.compute_qty(new_req.unit,
max(0.0, quantity - new_req.quantity), old_req['unit'])
else:
break
return new_requests
@classmethod
def delete(cls, requests):
if Transaction().context.get('generate_requests', False):
requests = [r for r in requests if not r.pending]
super(PurchaseRequest, cls).delete(requests)