# --- Block D: Optional split ---
if split_qty is not None:
if split_qty <= 0 or split_qty >= batch.quantity:
raise HTTPException(status_code=400, ...)
remainder = batch.quantity - split_qty
new_batch = Batch(
id=str(uuid.uuid4()),
quantity=remainder,
current_owner_id=batch.current_owner_id, # aun es from_actor_id
origin_batch_id=batch.id,
...
)
db_session.add(new_batch)
batch.quantity = split_qty
Que hace
Divide el lote original: el fragmento de split_qty se transfiere; el remanente queda en manos del propietario actual como nuevo lote hijo.
Invariantes establecidas
batch.quantity + new_batch.quantity = original
new_batch hereda current_owner_id de from_actor (correcto)
split_qty es Float β posible precision de punto flotante
5 Hows β ΒΏComo podria perderse cantidad total?
1split_qty=0.1, batch.quantity=0.3 β remainder=0.19999... (float imprecision).
2El Transfer de Block E registra quantity=batch.quantity post-split = 0.1 (correcto visualmente).
3new_batch.quantity=0.19999... en DB β discrepancia acumulativa en multiples splits.
4Los certificados del lote original NO se replican al new_batch automaticamente.
5El lote hijo queda sin certificado valido β cualquier transferencia futura de new_batch requiere override_cert=True.