# Flujo de Negocio: Sale (Ventas) **Modulo:** sale **Modelo Principal:** sale.order **Aplica Workflow:** Si --- ## 1. Estados de Orden de Venta (state) | Estado | Nombre UI | Descripcion | Siguiente | |--------|-----------|-------------|-----------| | draft | Quotation | Cotizacion inicial | sent, sale | | sent | Quotation Sent | Cotizacion enviada al cliente | sale, cancel | | sale | Sales Order | Orden confirmada | cancel | | cancel | Cancelled | Orden cancelada | draft | --- ## 2. Diagrama de Transiciones ``` ┌──────────────────┐ │ DRAFT │ │ (Quotation) │ └────────┬─────────┘ │ ┌──────────────────┼──────────────────┐ │ │ │ action_quotation_send() │ action_confirm() │ │ │ ▼ │ │ ┌──────────────────┐ │ │ │ SENT │ │ │ │ (Quotation Sent) │ │ │ └────────┬─────────┘ │ │ │ │ │ │ action_confirm() │ │ │ (firma/pago opt) │ │ │ │ │ └───────────────────┴──────────────────┘ │ ▼ ┌───────────────────────────────────────┐ │ │ │ SALE │ │ (Sales Order) │ │ │ │ - Genera entregas (sale_stock) │ │ - Habilita facturacion │ │ - locked = True (opcional) │ │ │ └───────────────────┬───────────────────┘ │ action_cancel() (requiere unlock) │ ▼ ┌──────────────────┐ │ CANCEL │ │ (Cancelled) │ └────────┬─────────┘ │ action_draft() │ ▼ ┌──────────────────┐ │ DRAFT │ │ (Reabierta) │ └──────────────────┘ ``` --- ## 3. Flujo Completo de Venta ``` 1. CREACION (draft) └─ Usuario crea sale.order └─ Selecciona cliente (partner_id) └─ Sistema calcula direcciones (invoice/shipping) └─ Agrega lineas con productos └─ state = 'draft' 2. ENVIO COTIZACION (opcional) └─ action_quotation_send() └─ Envia correo al cliente └─ state = 'sent' └─ Cliente puede ver en portal 3. VALIDACION PRE-CONFIRMACION (si configurado) 3a. FIRMA ONLINE (require_signature = True): └─ Cliente firma en portal └─ signature, signed_by, signed_on guardados 3b. PAGO ONLINE (require_payment = True): └─ Cliente paga anticipo (prepayment_percent) └─ payment.transaction creada └─ amount_paid actualizado 4. CONFIRMACION └─ action_confirm() └─ _action_confirm() ejecutado └─ state = 'sale' └─ date_order = now() (si era draft) └─ name genera secuencia si 'New' 5. ENTREGA (integracion sale_stock) └─ Genera stock.picking automaticamente └─ Operario prepara y envia └─ qty_delivered actualizado en lineas 6. FACTURACION └─ _create_invoices() └─ account.move creado tipo 'out_invoice' └─ invoice_status actualizado ``` --- ## 4. Metodos de Transicion | Metodo | De Estado | A Estado | Descripcion | |--------|-----------|----------|-------------| | action_confirm() | draft/sent | sale | Confirma orden | | action_cancel() | * | cancel | Cancela orden | | action_draft() | cancel | draft | Vuelve a borrador | | action_quotation_send() | draft | sent | Envia cotizacion | | action_lock() | sale | sale (locked) | Bloquea | | action_unlock() | sale (locked) | sale | Desbloquea | --- ## 5. Reglas de Negocio | ID | Regla | Validacion | Mensaje | |----|-------|------------|---------| | R1 | Cliente requerido | partner_id presente | Cliente requerido | | R2 | Lineas requeridas | order_line no vacio | Agregue productos | | R3 | Fecha confirmacion | date_order si state='sale' | Fecha requerida | | R4 | Productos activos | Sin productos archivados | Producto archivado | | R5 | Firma requerida | signature si require_signature | Firma pendiente | | R6 | Pago requerido | amount_paid >= prepayment si require_payment | Pago pendiente | --- ## 6. Flujo de Firma y Pago Online ``` COTIZACION ENVIADA (state = sent) │ ├─ require_signature = True? │ │ │ ├─ SI: Cliente debe firmar en portal │ │ └─ /my/orders//accept │ │ └─ POST con firma en base64 │ │ └─ sale.order.signature = firma │ │ │ └─ NO: Continua sin firma │ ├─ require_payment = True? │ │ │ ├─ SI: Cliente debe pagar anticipo │ │ └─ /my/orders//transaction │ │ └─ prepayment_percent del total │ │ └─ payment.transaction creada │ │ └─ Estado: done/authorized │ │ │ └─ NO: Continua sin pago │ └─ Condiciones cumplidas: └─ action_confirm() disponible └─ O confirmacion automatica ``` --- ## 7. Integracion con Inventario (sale_stock) ``` CONFIRMACION (state → sale) │ ├─ sale_stock genera stock.picking │ └─ picking_type_id = Envios │ └─ partner_id = Cliente │ └─ location_dest_id = Customer Location │ ├─ Por cada sale.order.line: │ └─ Crea stock.move │ └─ product_id │ └─ product_uom_qty │ └─ sale_line_id = line.id │ ENVIO (en stock) │ ├─ Operario prepara picking ├─ stock.move → done └─ sale.order.line.qty_delivered actualizado ``` --- ## 8. Flujo de Facturacion ``` CREAR FACTURA │ ├─ Wizard: sale.advance.payment.inv │ │ │ ├─ advance_payment_method = 'delivered': │ │ └─ Factura por cantidades entregadas │ │ └─ qty_to_invoice = qty_delivered - qty_invoiced │ │ │ ├─ advance_payment_method = 'percentage': │ │ └─ Factura anticipo (% del total) │ │ └─ Linea tipo downpayment │ │ │ └─ advance_payment_method = 'fixed': │ └─ Factura anticipo (monto fijo) │ └─ Linea tipo downpayment │ ├─ _create_invoices() │ └─ account.move tipo 'out_invoice' │ └─ Lineas vinculadas a sale.order.line │ ACTUALIZACION ESTADO │ ├─ invoice_status recalculado: │ ├─ 'no' = nada que facturar │ ├─ 'to invoice' = pendiente │ ├─ 'invoiced' = todo facturado │ └─ 'upselling' = oportunidad upselling ``` --- ## 9. Acciones Automaticas | Trigger | Accion | Condicion | |---------|--------|-----------| | action_confirm | Generar nombre secuencial | Si name = 'New' | | action_confirm | Establecer date_order | Si era draft | | action_confirm | Crear entregas | Si sale_stock instalado | | Linea modificada | Recalcular totales | Siempre | | Entrega completada | Actualizar qty_delivered | Automatico | | Pago autorizado | Confirmar orden | Si autoconfirm | --- ## 10. Permisos por Estado | Estado | Editable | Grupos | |--------|----------|--------| | draft | Si | sales_team.group_sale_salesman | | sent | Si | sales_team.group_sale_salesman | | sale | No (locked) | sales_team.group_sale_manager (unlock) | | cancel | No | sales_team.group_sale_salesman (reopen) | --- ## 11. Flujo de Estados de Facturacion ``` SO CONFIRMADA (state = sale) │ ├─ invoice_status = 'no' │ └─ Nada entregado aun │ └─ O productos sin factura (service invoice='manual') │ ├─ Entrega realizada: │ └─ qty_delivered > 0 │ └─ invoice_status = 'to invoice' │ ├─ Upselling detectado: │ └─ qty_delivered > qty_invoiced │ └─ Politica = 'order' │ └─ invoice_status = 'upselling' │ ├─ Factura parcial: │ └─ qty_invoiced < qty_delivered │ └─ invoice_status = 'to invoice' │ └─ Todo facturado: └─ qty_invoiced >= qty_to_invoice └─ invoice_status = 'invoiced' ``` --- ## 12. Constraint de Base de Datos ```sql -- Orden confirmada requiere fecha CHECK( (state = 'sale' AND date_order IS NOT NULL) OR state != 'sale' ) ``` --- **Referencias:** - sale_order.py: action_confirm, action_cancel, _create_invoices - Integracion stock: sale_stock/ - Wizard factura: sale_make_invoice_advance.py