Use Selection field for purchase request state
issue6153 review30951002
This commit is contained in:
+37
-2
@@ -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
@@ -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'
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user