Propagate exception handling from sale to purchase
issue4071 review5491002
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
* Propagate exception handling from sale to purchase
|
||||
|
||||
Version 3.2.0 - 2014-04-21
|
||||
* Bug fixes (see mercurial logs for details)
|
||||
|
||||
|
||||
@@ -21,4 +21,6 @@ def register():
|
||||
module='sale_supply_drop_shipment', type_='model')
|
||||
Pool.register(
|
||||
CreatePurchase,
|
||||
PurchaseHandleShipmentException,
|
||||
SaleHandleShipmentException,
|
||||
module='sale_supply_drop_shipment', type_='wizard')
|
||||
|
||||
+44
-1
@@ -3,10 +3,11 @@
|
||||
from trytond.model import fields
|
||||
from trytond.pyson import Eval
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
|
||||
__all__ = ['PurchaseRequest', 'Purchase', 'PurchaseLine', 'ProductSupplier',
|
||||
'CreatePurchase']
|
||||
'CreatePurchase', 'PurchaseHandleShipmentException']
|
||||
__metaclass__ = PoolMeta
|
||||
|
||||
|
||||
@@ -119,3 +120,45 @@ class CreatePurchase:
|
||||
if request.delivery_address else None),
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
class PurchaseHandleShipmentException:
|
||||
__name__ = 'purchase.handle.shipment.exception'
|
||||
|
||||
def transition_handle(self):
|
||||
pool = Pool()
|
||||
Sale = pool.get('sale.sale')
|
||||
SaleLine = pool.get('sale.line')
|
||||
|
||||
super(PurchaseHandleShipmentException, self).transition_handle()
|
||||
|
||||
to_recreate = self.ask.recreate_moves
|
||||
domain_moves = self.ask.domain_moves
|
||||
sales, saleline_write = set(), []
|
||||
sale_lines = SaleLine.search([
|
||||
('purchase_request.purchase_line.purchase', '=',
|
||||
Transaction().context['active_id']),
|
||||
])
|
||||
saleline_write = []
|
||||
for sale_line in sale_lines:
|
||||
moves_ignored = []
|
||||
moves_recreated = []
|
||||
skip = set(sale_line.moves_ignored)
|
||||
skip.update(sale_line.moves_recreated)
|
||||
for move in sale_line.moves:
|
||||
if move not in domain_moves or move in skip:
|
||||
continue
|
||||
if move in to_recreate:
|
||||
moves_recreated.append(move.id)
|
||||
else:
|
||||
moves_ignored.append(move.id)
|
||||
sales.add(sale_line.sale)
|
||||
saleline_write.append([sale_line])
|
||||
saleline_write.append({
|
||||
'moves_ignored': [('add', moves_ignored)],
|
||||
'moves_recreated': [('add', moves_recreated)],
|
||||
})
|
||||
|
||||
SaleLine.write(*saleline_write)
|
||||
Sale.process(list(sales))
|
||||
return 'end'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#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 itertools import groupby
|
||||
from itertools import groupby, chain
|
||||
from functools import partial
|
||||
from trytond.model import fields
|
||||
from trytond.pyson import Eval
|
||||
@@ -8,7 +8,7 @@ from trytond.pool import Pool, PoolMeta
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.const import OPERATORS
|
||||
|
||||
__all__ = ['Sale', 'SaleLine']
|
||||
__all__ = ['Sale', 'SaleLine', 'SaleHandleShipmentException']
|
||||
__metaclass__ = PoolMeta
|
||||
|
||||
|
||||
@@ -181,3 +181,47 @@ class SaleLine:
|
||||
i += 1
|
||||
return domain
|
||||
return super(SaleLine, cls).search(process(domain), *args, **kwargs)
|
||||
|
||||
|
||||
class SaleHandleShipmentException:
|
||||
__name__ = 'sale.handle.shipment.exception'
|
||||
|
||||
def transition_handle(self):
|
||||
pool = Pool()
|
||||
Purchase = pool.get('purchase.purchase')
|
||||
PurchaseLine = pool.get('purchase.line')
|
||||
Sale = pool.get('sale.sale')
|
||||
|
||||
super(SaleHandleShipmentException, self).transition_handle()
|
||||
|
||||
to_recreate = self.ask.recreate_moves
|
||||
domain_moves = self.ask.domain_moves
|
||||
purchases, purchaseline_write = set(), []
|
||||
sale = Sale(Transaction().context['active_id'])
|
||||
for line in sale.lines:
|
||||
if not line.purchase_request:
|
||||
continue
|
||||
purchase_line = line.purchase_request.purchase_line
|
||||
if not purchase_line:
|
||||
continue
|
||||
|
||||
moves_ignored = []
|
||||
moves_recreated = []
|
||||
skip = set(purchase_line.moves_ignored)
|
||||
skip.update(purchase_line.moves_recreated)
|
||||
for move in purchase_line.moves:
|
||||
if move not in domain_moves or move in skip:
|
||||
continue
|
||||
if move in to_recreate:
|
||||
moves_recreated.append(move.id)
|
||||
else:
|
||||
moves_ignored.append(move.id)
|
||||
purchases.add(purchase_line.purchase)
|
||||
purchaseline_write.append(([purchase_line], {
|
||||
'moves_ignored': [('add', moves_ignored)],
|
||||
'moves_recreated': [('add', moves_recreated)],
|
||||
}))
|
||||
|
||||
PurchaseLine.write(*chain(*purchaseline_write))
|
||||
Purchase.process(list(purchases))
|
||||
return 'end'
|
||||
|
||||
@@ -288,7 +288,8 @@ The purchase is now waiting for this new drop shipment::
|
||||
>>> purchase.shipment_state
|
||||
u'waiting'
|
||||
|
||||
Let's cancel it and handle the problem from the sale order::
|
||||
Let's cancel the shipment and handle the issue from the purchase.
|
||||
As a consequence the sale order is over::
|
||||
|
||||
>>> config.user = stock_user.id
|
||||
>>> shipment.click('cancel')
|
||||
@@ -306,20 +307,9 @@ Let's cancel it and handle the problem from the sale order::
|
||||
u'received'
|
||||
|
||||
>>> config.user = sale_user.id
|
||||
>>> sale.shipment_state
|
||||
u'exception'
|
||||
>>> handle_exception = Wizard('sale.handle.shipment.exception', [sale])
|
||||
>>> handle_exception.execute('handle')
|
||||
>>> sale.reload()
|
||||
>>> sale.shipment_state
|
||||
u'waiting'
|
||||
|
||||
The sale has created a new outgoing shipment::
|
||||
|
||||
>>> shipment, = sale.shipments
|
||||
>>> move, = shipment.outgoing_moves
|
||||
>>> move.quantity
|
||||
150.0
|
||||
u'sent'
|
||||
|
||||
Cancelling the workflow on the purchase step::
|
||||
|
||||
@@ -403,3 +393,51 @@ If we opt not to cancel the shipment and deliver from stock::
|
||||
>>> config.user = sale_user.id
|
||||
>>> sale.shipment_state
|
||||
u'sent'
|
||||
|
||||
Now let's handle the exception on the sale side::
|
||||
|
||||
>>> config.user = sale_user.id
|
||||
>>> sale = Sale()
|
||||
>>> sale.party = customer
|
||||
>>> sale.payment_term = payment_term
|
||||
>>> sale_line = sale.lines.new()
|
||||
>>> sale_line.product = product
|
||||
>>> sale_line.quantity = 375
|
||||
>>> sale.save()
|
||||
>>> sale.click('quote')
|
||||
>>> sale.click('confirm')
|
||||
>>> sale.click('process')
|
||||
|
||||
>>> config.user = purchase_user.id
|
||||
>>> purchase_request, = PurchaseRequest.find([('purchase_line', '=', None)])
|
||||
>>> purchase_request.quantity
|
||||
375.0
|
||||
>>> create_purchase = Wizard('purchase.request.create_purchase',
|
||||
... [purchase_request])
|
||||
>>> purchase, = Purchase.find([('state', '=', 'draft')])
|
||||
>>> purchase.payment_term = payment_term
|
||||
>>> purchase.click('quote')
|
||||
>>> purchase.click('confirm')
|
||||
>>> purchase.click('process')
|
||||
>>> purchase.shipment_state
|
||||
u'waiting'
|
||||
>>> config.user = sale_user.id
|
||||
>>> sale.reload()
|
||||
>>> shipment, = sale.drop_shipments
|
||||
>>> config.user = stock_user.id
|
||||
>>> shipment.click('cancel')
|
||||
|
||||
>>> config.user = sale_user.id
|
||||
>>> sale.shipment_state
|
||||
u'exception'
|
||||
>>> handle_exception = Wizard('sale.handle.shipment.exception', [sale])
|
||||
>>> _ = handle_exception.form.recreate_moves.pop()
|
||||
>>> handle_exception.execute('handle')
|
||||
>>> sale.reload()
|
||||
>>> sale.shipment_state
|
||||
u'sent'
|
||||
|
||||
>>> config.user = purchase_user.id
|
||||
>>> purchase.reload()
|
||||
>>> purchase.shipment_state
|
||||
u'received'
|
||||
|
||||
Reference in New Issue
Block a user