Use Selection field for purchase request state

issue6153
review30951002
This commit is contained in:
Cédric Krier
2017-01-10 11:47:28 +01:00
parent b286e85406
commit 188fae0ec1
3 changed files with 104 additions and 56 deletions
+37 -2
View File
@@ -1,14 +1,26 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from functools import wraps
from trytond.pool import PoolMeta
from trytond.model import fields
from trytond.pool import PoolMeta, Pool
from trytond.model import ModelView, Workflow, fields
from trytond.transaction import Transaction
from trytond.pyson import Eval
__all__ = ['Purchase', 'PurchaseLine']
def process_request(func):
@wraps(func)
def wrapper(cls, purchases):
pool = Pool()
Request = pool.get('purchase.request')
func(cls, purchases)
requests = [r for p in purchases for l in p.lines for r in l.requests]
Request.update_state(requests)
return wrapper
class Purchase:
__name__ = 'purchase.purchase'
__metaclass__ = PoolMeta
@@ -37,6 +49,19 @@ class Purchase:
'purchase': purchase.rec_name,
})
@classmethod
@ModelView.button
@Workflow.transition('cancel')
@process_request
def cancel(cls, purchases):
super(Purchase, cls).cancel(purchases)
@classmethod
@Workflow.transition('done')
@process_request
def do(cls, purchases):
super(Purchase, cls).do(purchases)
class PurchaseLine:
__metaclass__ = PoolMeta
@@ -47,3 +72,13 @@ class PurchaseLine:
states={
'invisible': ~Eval('requests'),
})
@classmethod
def delete(cls, lines):
pool = Pool()
Request = pool.get('purchase.request')
with Transaction().set_context(_check_access=False):
requests = [r for l in cls.browse(lines) for r in l.requests]
super(PurchaseLine, cls).delete(lines)
with Transaction().set_context(_check_access=False):
Request.update_state(requests)
+59 -46
View File
@@ -5,9 +5,6 @@ from decimal import Decimal
from itertools import groupby
from functools import partial
from sql import Null
from sql.conditionals import Case
from trytond import backend
from trytond.model import ModelView, ModelSQL, fields
from trytond.wizard import Wizard, StateView, StateTransition, Button
@@ -82,13 +79,13 @@ class PurchaseRequest(ModelSQL, ModelView):
origin = fields.Reference('Origin', selection='get_origin', readonly=True,
required=True)
exception_ignored = fields.Boolean('Ignored Exception')
state = fields.Function(fields.Selection([
('purchased', 'Purchased'),
('done', 'Done'),
('draft', 'Draft'),
('cancel', 'Cancel'),
('exception', 'Exception'),
], 'State'), 'get_state', searcher='search_state')
state = fields.Selection([
('purchased', "Purchased"),
('done', "Done"),
('draft', "Draft"),
('cancel', "Cancel"),
('exception', "Exception"),
], "State", required=True, select=True)
@classmethod
def __setup__(cls):
@@ -110,8 +107,17 @@ class PurchaseRequest(ModelSQL, ModelView):
def __register__(cls, module_name):
pool = Pool()
ModelData = pool.get('ir.model.data')
Purchase = pool.get('purchase.purchase')
PurchaseLine = pool.get('purchase.line')
TableHandler = backend.get('TableHandler')
model_data = ModelData.__table__()
purchase = Purchase.__table__()
purchase_line = PurchaseLine.__table__()
request = cls.__table__()
tablehandler = TableHandler(cls, module_name)
state_exist = tablehandler.column_exist('state')
super(PurchaseRequest, cls).__register__(module_name)
# Migration from 3.6: removing the constraint on the quantity
@@ -130,6 +136,31 @@ class PurchaseRequest(ModelSQL, ModelView):
tablehandler.not_null_action('product', action='remove')
tablehandler.not_null_action('uom', action='remove')
# Migration from 4.2: add state
if not state_exist:
cursor = Transaction().connection.cursor()
update = Transaction().connection.cursor()
query = request.join(purchase_line, type_='INNER',
condition=request.purchase_line == purchase_line.id
).join(purchase, type_='INNER',
condition=purchase_line.purchase == purchase.id
).select(
request.id, purchase.state, request.exception_ignored)
cursor.execute(*query)
for request_id, purchase_state, exception_ignored in cursor:
if purchase_state == 'cancel' and not exception_ignored:
state = 'exception'
elif purchase_state == 'cancel':
state = 'cancel'
elif purchase_state == 'done':
state = 'done'
else:
state = 'purchased'
update.execute(*request.update(
[request.state],
[state],
where=request.id == request_id))
def get_rec_name(self, name):
product_name = (self.product.name if self.product else
self.description.splitlines()[0])
@@ -169,7 +200,11 @@ class PurchaseRequest(ModelSQL, ModelView):
def currency(self):
return self.company.currency
def get_state(self, name):
@classmethod
def default_state(cls):
return 'draft'
def get_state(self):
if self.purchase_line:
if (self.purchase_line.purchase.state == 'cancel'
and not self.exception_ignored):
@@ -183,35 +218,12 @@ class PurchaseRequest(ModelSQL, ModelView):
return 'draft'
@classmethod
def search_state(cls, name, clause):
pool = Pool()
Purchase = pool.get('purchase.purchase')
PurchaseLine = pool.get('purchase.line')
request = cls.__table__()
purchase_line = PurchaseLine.__table__()
purchase = Purchase.__table__()
_, operator_, state = clause
Operator = fields.SQL_OPERATORS[operator_]
state_case = Case(
((purchase.state == 'cancel')
& (request.exception_ignored == False), 'exception'),
((purchase.state == 'cancel')
& (request.exception_ignored == True), 'cancel'),
(purchase.state == 'done', 'done'),
(request.purchase_line != Null, 'purchased'),
else_='draft')
state_query = request.join(
purchase_line, type_='LEFT',
condition=request.purchase_line == purchase_line.id
).join(purchase, type_='LEFT',
condition=purchase_line.purchase == purchase.id
).select(
request.id,
where=Operator(state_case, state))
return [('id', 'in', state_query)]
def update_state(cls, requests):
for request in requests:
state = request.get_state()
if state != request.state:
request.state = state
cls.save(requests)
def get_warehouse_required(self, name):
return self.product and self.product.type in ('goods', 'assets')
@@ -423,6 +435,7 @@ class CreatePurchase(Wizard):
lines.append(line)
Purchase.save(purchases)
Line.save(lines)
Request.update_state(requests)
return 'end'
@staticmethod
@@ -492,9 +505,9 @@ class HandlePurchaseCancellationException(Wizard):
PurchaseRequest = pool.get('purchase.request')
requests = PurchaseRequest.browse(Transaction().context['active_ids'])
PurchaseRequest.write(requests, {
'purchase_line': None,
})
for request in requests:
request.purchase_line = None
PurchaseRequest.update_state(requests)
return 'end'
def transition_cancel_request(self):
@@ -502,9 +515,9 @@ class HandlePurchaseCancellationException(Wizard):
PurchaseRequest = pool.get('purchase.request')
requests = PurchaseRequest.browse(Transaction().context['active_ids'])
PurchaseRequest.write(requests, {
'exception_ignored': True,
})
for request in requests:
request.exception_ignored = True
PurchaseRequest.update_state(requests)
return 'end'
+8 -8
View File
@@ -162,14 +162,14 @@ Create the purchase then cancel it::
>>> create_purchase.form.party = supplier
>>> create_purchase.execute('start')
>>> pr.state
'purchased'
u'purchased'
>>> Purchase = Model.get('purchase.purchase')
>>> purchase, = Purchase.find()
>>> purchase.click('cancel')
>>> pr.reload()
>>> pr.state
'exception'
u'exception'
Handle the exception::
@@ -177,20 +177,20 @@ Handle the exception::
... 'purchase.request.handle.purchase.cancellation', [pr])
>>> handle_exception.execute('reset')
>>> pr.state
'draft'
u'draft'
Recreate a purchase and cancel it again::
>>> create_purchase = Wizard('purchase.request.create_purchase',
... [pr])
>>> pr.state
'purchased'
u'purchased'
>>> purchase, = Purchase.find([('state', '=', 'draft')])
>>> purchase.click('cancel')
>>> pr.reload()
>>> pr.state
'exception'
u'exception'
Handle again the exception::
@@ -198,7 +198,7 @@ Handle again the exception::
... 'purchase.request.handle.purchase.cancellation', [pr])
>>> handle_exception.execute('cancel_request')
>>> pr.state
'cancel'
u'cancel'
Re-create the purchase request::
@@ -229,7 +229,7 @@ Create the purchase with a unique line::
>>> create_purchase.form.party = supplier
>>> create_purchase.execute('start')
>>> pr.state
'purchased'
u'purchased'
>>> Purchase = Model.get('purchase.purchase')
>>> purchase, = Purchase.find([('state', '=', 'draft')])
@@ -258,7 +258,7 @@ Create the purchase without product::
>>> create_purchase.form.party = supplier
>>> create_purchase.execute('start')
>>> pr.state
'purchased'
u'purchased'
>>> pr.purchase_line.product
>>> pr.purchase_line.description