diff --git a/modules/sale_supply_drop_shipment/CHANGELOG b/modules/sale_supply_drop_shipment/CHANGELOG
index 002c18f450..4843ef59ee 100644
--- a/modules/sale_supply_drop_shipment/CHANGELOG
+++ b/modules/sale_supply_drop_shipment/CHANGELOG
@@ -1,3 +1,4 @@
+* Support splitting drop shipment
* Split customer moves when splitting supplier moves
* Rename 'done' button to 'do'
diff --git a/modules/sale_supply_drop_shipment/__init__.py b/modules/sale_supply_drop_shipment/__init__.py
index ac66c3782f..f5eea42949 100644
--- a/modules/sale_supply_drop_shipment/__init__.py
+++ b/modules/sale_supply_drop_shipment/__init__.py
@@ -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'])
diff --git a/modules/sale_supply_drop_shipment/stock.py b/modules/sale_supply_drop_shipment/stock.py
index c19d46cbcd..6b844477e2 100644
--- a/modules/sale_supply_drop_shipment/stock.py
+++ b/modules/sale_supply_drop_shipment/stock.py
@@ -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'
diff --git a/modules/sale_supply_drop_shipment/stock.xml b/modules/sale_supply_drop_shipment/stock.xml
index 6eae621e83..dfe26dce03 100644
--- a/modules/sale_supply_drop_shipment/stock.xml
+++ b/modules/sale_supply_drop_shipment/stock.xml
@@ -264,6 +264,20 @@ this repository contains the full copyright notices and license terms. -->
+
+
+ stock.shipment.drop
+
+ shipment_drop_split_form
+
+
+
+ stock.shipment.drop
+ split_wizard
+ Split
+
+
+
diff --git a/modules/sale_supply_drop_shipment/tests/scenario_sale_supply_drop_shipment_split.rst b/modules/sale_supply_drop_shipment/tests/scenario_sale_supply_drop_shipment_split.rst
new file mode 100644
index 0000000000..bd8b83b8b8
--- /dev/null
+++ b/modules/sale_supply_drop_shipment/tests/scenario_sale_supply_drop_shipment_split.rst
@@ -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))
diff --git a/modules/sale_supply_drop_shipment/view/shipment_drop_split_form.xml b/modules/sale_supply_drop_shipment/view/shipment_drop_split_form.xml
new file mode 100644
index 0000000000..be65c958f3
--- /dev/null
+++ b/modules/sale_supply_drop_shipment/view/shipment_drop_split_form.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+