Transferring stock between two warehouses belongs to neither warehouse, and putting it on one of them makes that one special for no reason.
final class StockTransfer
{
public function transfer(
Warehouse $from,
Warehouse $to,
Sku $sku,
int $quantity,
): TransferRecord {
$from->release($sku, $quantity);
$to->receive($sku, $quantity);
return new TransferRecord(/* ... */);
}
}
This is the case a domain service is for, and it is narrower than the way the pattern usually gets used — most classes named SomethingService are a bag of procedures that should have been methods on the entity. The test is whether the operation has a natural owner: if it does, it belongs there, and if genuinely neither party owns it, a service named after the operation rather than the entity is right.