Support splitting drop shipment
This commit is contained in:
1 parent
e052849c3d
commit
9be2860eb7
6 files changed
+209
No files matched your search
@@ -1,3 +1,4 @@
|
||||
* Support splitting drop shipment
|
||||
* Split customer moves when splitting supplier moves
|
||||
* Rename 'done' button to 'do'
|
||||
|
||||
|
||||
@@ -31,6 +31,11 @@ def register():
|
||||
party.Erase,
|
||||
module='sale_supply_drop_shipment', type_='wizard')
|
||||
Pool.register(
|
||||
stock.ShipmentDropSplit,
|
||||
stock.MoveSplit,
|
||||
module='sale_supply_drop_shipment', type_='model',
|
||||
depends=['stock_split'])
|
||||
Pool.register(
|
||||
stock.SplitShipment,
|
||||
module='sale_supply_drop_shipment', type_='wizard',
|
||||
depends=['stock_split'])
|
||||
@@ -535,6 +535,47 @@ class ShipmentDrop(
|
||||
return self.customer_moves
|
||||
|
||||
|
||||
class ShipmentDropSplit(metaclass=PoolMeta):
|
||||
__name__ = 'stock.shipment.drop'
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super().__setup__()
|
||||
cls._buttons.update({
|
||||
'split_wizard': {
|
||||
'readonly': Eval('state') != 'draft',
|
||||
'invisible': Eval('state') != 'draft',
|
||||
'depends': ['state'],
|
||||
},
|
||||
})
|
||||
|
||||
@classmethod
|
||||
@ModelView.button_action('stock_split.wizard_split_shipment')
|
||||
def split_wizard(cls, shipments):
|
||||
pass
|
||||
|
||||
|
||||
class SplitShipment(metaclass=PoolMeta):
|
||||
__name__ = 'stock.shipment.split'
|
||||
|
||||
def get_moves(self, shipment):
|
||||
moves = super().get_moves(shipment)
|
||||
if shipment.__name__ == 'stock.shipment.drop':
|
||||
moves = shipment.supplier_moves
|
||||
return moves
|
||||
|
||||
def transition_split(self):
|
||||
shipment = self.record
|
||||
if shipment.__name__ == 'stock.shipment.drop':
|
||||
customer_moves = []
|
||||
for move in self.start.moves:
|
||||
customer_moves.extend(move.moves_drop)
|
||||
self.start.moves = [*self.start.moves, *customer_moves]
|
||||
self.start.domain_moves = [
|
||||
*self.start.domain_moves, *customer_moves]
|
||||
return super().transition_split()
|
||||
|
||||
|
||||
class Move(metaclass=PoolMeta):
|
||||
__name__ = 'stock.move'
|
||||
|
||||
|
||||
@@ -264,6 +264,20 @@ this repository contains the full copyright notices and license terms. -->
|
||||
</record>
|
||||
</data>
|
||||
|
||||
<data depends="stock_split">
|
||||
<record model="ir.ui.view" id="shipment_drop_view_form_split">
|
||||
<field name="model">stock.shipment.drop</field>
|
||||
<field name="inherit" ref="shipment_drop_view_form"/>
|
||||
<field name="name">shipment_drop_split_form</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.model.button" id="shipment_drop_split_wizard_button">
|
||||
<field name="model">stock.shipment.drop</field>
|
||||
<field name="name">split_wizard</field>
|
||||
<field name="string">Split</field>
|
||||
</record>
|
||||
</data>
|
||||
|
||||
<data noupdate="1">
|
||||
|
||||
<!-- Default locations -->
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
========================================
|
||||
Sale Supply Drop Shipment Split Scenario
|
||||
========================================
|
||||
|
||||
Imports::
|
||||
|
||||
>>> from decimal import Decimal
|
||||
|
||||
>>> from proteus import Model, Wizard
|
||||
>>> from trytond.modules.account.tests.tools import create_chart, get_accounts
|
||||
>>> from trytond.modules.company.tests.tools import create_company
|
||||
>>> from trytond.tests.tools import activate_modules, assertEqual
|
||||
|
||||
Activate modules::
|
||||
|
||||
>>> config = activate_modules([
|
||||
... 'sale_supply_drop_shipment',
|
||||
... 'stock_split',
|
||||
... ])
|
||||
|
||||
>>> Move = Model.get('stock.move')
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> ProductCategory = Model.get('product.category')
|
||||
>>> ProductSupplier = Model.get('purchase.product_supplier')
|
||||
>>> ProductTemplate = Model.get('product.template')
|
||||
>>> ProductUom = Model.get('product.uom')
|
||||
>>> Purchase = Model.get('purchase.purchase')
|
||||
>>> PurchaseRequest = Model.get('purchase.request')
|
||||
>>> Sale = Model.get('sale.sale')
|
||||
>>> Shipment = Model.get('stock.shipment.drop')
|
||||
|
||||
Create company::
|
||||
|
||||
>>> _ = create_company()
|
||||
|
||||
Create chart of account::
|
||||
|
||||
>>> _ = create_chart()
|
||||
>>> accounts = get_accounts()
|
||||
|
||||
Create parties::
|
||||
|
||||
>>> supplier = Party(name="Supplier")
|
||||
>>> supplier.save()
|
||||
>>> customer = Party(name="Customer")
|
||||
>>> customer.save()
|
||||
|
||||
Create account category::
|
||||
|
||||
>>> account_category = ProductCategory(name="Account Category")
|
||||
>>> account_category.accounting = True
|
||||
>>> account_category.account_expense = accounts['expense']
|
||||
>>> account_category.account_revenue = accounts['revenue']
|
||||
>>> account_category.save()
|
||||
|
||||
Create product::
|
||||
|
||||
>>> unit, = ProductUom.find([('name', '=', "Unit")])
|
||||
|
||||
>>> template = ProductTemplate()
|
||||
>>> template.name = "Product"
|
||||
>>> template.default_uom = unit
|
||||
>>> template.type = 'goods'
|
||||
>>> template.purchasable = True
|
||||
>>> template.salable = True
|
||||
>>> template.list_price = Decimal('10.000')
|
||||
>>> template.supply_on_sale = 'always'
|
||||
>>> template.account_category = account_category
|
||||
>>> product_supplier = template.product_suppliers.new()
|
||||
>>> product_supplier.party = supplier
|
||||
>>> product_supplier.drop_shipment = True
|
||||
>>> template.save()
|
||||
>>> product, = template.products
|
||||
>>> product_supplier.save()
|
||||
|
||||
Sale 5 products::
|
||||
|
||||
>>> sale = Sale(party=customer)
|
||||
>>> line = sale.lines.new()
|
||||
>>> line.product = product
|
||||
>>> line.quantity = 5
|
||||
>>> sale.click('quote')
|
||||
>>> sale.click('confirm')
|
||||
>>> sale.state
|
||||
'processing'
|
||||
|
||||
Create purchase request::
|
||||
|
||||
>>> purchase_request, = PurchaseRequest.find()
|
||||
>>> create_purchase = Wizard(
|
||||
... 'purchase.request.create_purchase', [purchase_request])
|
||||
>>> purchase, = Purchase.find()
|
||||
>>> purchase.click('quote')
|
||||
>>> purchase.click('confirm')
|
||||
>>> purchase.state
|
||||
'processing'
|
||||
|
||||
Split supplier move of drop shipment::
|
||||
|
||||
>>> shipment, = Shipment.find()
|
||||
>>> move, = shipment.supplier_moves
|
||||
>>> split = move.click('split_wizard')
|
||||
>>> split.form.quantity = 2
|
||||
>>> split.form.count = 1
|
||||
>>> split.execute('split')
|
||||
|
||||
>>> shipment.reload()
|
||||
>>> len(shipment.supplier_moves)
|
||||
2
|
||||
>>> len(shipment.customer_moves)
|
||||
2
|
||||
>>> for move in shipment.supplier_moves:
|
||||
... assertEqual(move.quantity, sum(m.quantity for m in move.moves_drop))
|
||||
|
||||
Split drop shipment::
|
||||
|
||||
>>> shipment.click('draft')
|
||||
>>> split = shipment.click('split_wizard')
|
||||
>>> split.form.moves.append(Move(shipment.supplier_moves[0].id))
|
||||
>>> split.execute('split')
|
||||
|
||||
>>> shipment2, = Shipment.find([('id', '!=', shipment.id)])
|
||||
|
||||
>>> Shipment.click([shipment, shipment2], 'wait')
|
||||
|
||||
>>> len(shipment.supplier_moves)
|
||||
1
|
||||
>>> len(shipment.customer_moves)
|
||||
1
|
||||
>>> assertEqual(
|
||||
... sum(m.quantity for m in shipment.supplier_moves),
|
||||
... sum(m.quantity for m in shipment.customer_moves))
|
||||
|
||||
>>> len(shipment2.supplier_moves)
|
||||
1
|
||||
>>> len(shipment2.customer_moves)
|
||||
1
|
||||
>>> assertEqual(
|
||||
... sum(m.quantity for m in shipment2.supplier_moves),
|
||||
... sum(m.quantity for m in shipment2.customer_moves))
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<data>
|
||||
<xpath expr="//group[@id='buttons']" position="inside">
|
||||
<button name="split_wizard"/>
|
||||
</xpath>
|
||||
</data>
|
||||
Reference in new issue
Block a user