# Flujo de Negocio: Purchase (Compras) **Modulo:** purchase **Modelo Principal:** purchase.order **Aplica Workflow:** Si --- ## 1. Estados de Orden de Compra (state) | Estado | Nombre UI | Descripcion | Siguiente | |--------|-----------|-------------|-----------| | draft | RFQ | Solicitud de cotizacion inicial | sent, to approve, purchase | | sent | RFQ Sent | RFQ enviada al proveedor | to approve, purchase | | to approve | To Approve | Pendiente de aprobacion | purchase, cancel | | purchase | Purchase Order | Orden confirmada | (cancel via unlock) | | cancel | Cancelled | Orden cancelada | draft | --- ## 2. Diagrama de Transiciones ``` ┌──────────────────┐ │ DRAFT │ │ (RFQ) │ └────────┬─────────┘ │ ┌──────────────────┼──────────────────┐ │ │ │ action_rfq_send() button_confirm() button_confirm() │ (sin aprobacion) (con aprobacion) ▼ │ │ ┌──────────────────┐ │ │ │ SENT │ │ │ │ (RFQ Sent) │ │ │ └────────┬─────────┘ │ │ │ │ │ │ button_confirm() │ │ │ │ │ └───────────────────┼──────────────────┤ │ │ ▼ ▼ (monto < limite) (monto >= limite) │ │ │ ┌────────┴────────┐ │ │ TO APPROVE │ │ │ (Pendiente) │ │ └────────┬────────┘ │ │ │ button_approve() │ │ └────────┬─────────┘ │ ▼ ┌──────────────────────────────┐ │ PURCHASE │ │ (Purchase Order) │ │ │ │ - Genera recepciones (stock)│ │ - Habilita facturacion │ │ - locked = True (opcional) │ └──────────────┬───────────────┘ │ button_cancel() (requiere unlock) │ ▼ ┌──────────────────┐ │ CANCEL │ │ (Cancelled) │ └────────┬─────────┘ │ button_draft() │ ▼ ┌──────────────────┐ │ DRAFT │ │ (Reabierta) │ └──────────────────┘ ``` --- ## 3. Flujo Completo de Compra ``` 1. CREACION (draft) └─ Usuario crea purchase.order └─ Selecciona proveedor (partner_id) └─ Agrega lineas con productos y cantidades └─ state = 'draft' 2. ENVIO RFQ (opcional) └─ action_rfq_send() └─ Envia correo al proveedor └─ state = 'sent' 3. CONFIRMACION └─ button_confirm() llamado 3a. SIN DOBLE VALIDACION: └─ _approval_allowed() = True └─ button_approve() ejecutado automatico └─ state = 'purchase' 3b. CON DOBLE VALIDACION (monto > limite): └─ _approval_allowed() = False └─ state = 'to approve' └─ Requiere gerente 4. APROBACION (si aplica) └─ button_approve() └─ Verifica permisos └─ state = 'purchase' └─ date_approve = now() 5. RECEPCION (integracion stock) └─ Genera stock.picking automaticamente └─ Operario recibe productos └─ qty_received actualizado en lineas 6. FACTURACION └─ Proveedor envia factura └─ Vincula factura con PO └─ qty_invoiced actualizado └─ invoice_status = 'invoiced' ``` --- ## 4. Metodos de Transicion | Metodo | De Estado | A Estado | Descripcion | |--------|-----------|----------|-------------| | button_confirm() | draft/sent | to approve/purchase | Confirma orden | | button_approve() | to approve | purchase | Aprueba orden | | button_cancel() | * (no purchase locked) | cancel | Cancela | | button_draft() | cancel | draft | Vuelve a borrador | | action_rfq_send() | draft | sent | Envia RFQ | | button_unlock() | purchase | purchase (unlocked) | Desbloquea | --- ## 5. Reglas de Negocio | ID | Regla | Validacion | Mensaje | |----|-------|------------|---------| | R1 | Proveedor requerido | partner_id presente | Proveedor requerido | | R2 | Lineas requeridas | order_line no vacio | Agregue al menos una linea | | R3 | Producto valido | product_id empresa compatible | Producto de otra empresa | | R4 | Cantidad positiva | product_qty > 0 | Cantidad debe ser positiva | | R5 | Aprobacion limite | amount_total vs limite | Requiere aprobacion | --- ## 6. Flujo de Doble Validacion ``` CONFIGURACION (res.config.settings) │ ├─ po_lock = 'lock' | 'edit' ├─ po_double_validation = 'one_step' | 'two_step' └─ po_double_validation_amount = monto_limite │ │ EVALUACION EN button_confirm() │ ├─ _approval_allowed(): │ │ │ ├─ Si po_double_validation == 'one_step': │ │ └─ return True (sin aprobacion) │ │ │ └─ Si po_double_validation == 'two_step': │ └─ return amount_total < limite │ OR user tiene permiso manager │ └─ Resultado: ├─ True → state = 'purchase' └─ False → state = 'to approve' ``` --- ## 7. Integracion con Stock ``` CONFIRMACION (state → purchase) │ ├─ Genera stock.picking automaticamente │ └─ picking_type_id = Recepciones │ └─ partner_id = Proveedor │ └─ location_dest_id = Stock │ ├─ Por cada purchase.order.line: │ └─ Crea stock.move │ └─ product_id │ └─ product_uom_qty = product_qty │ └─ purchase_line_id = line.id │ RECEPCION (en stock) │ ├─ Operario valida picking ├─ stock.move → done └─ purchase.order.line.qty_received actualizado ``` --- ## 8. Integracion con Facturacion ``` CREACION DE FACTURA │ ├─ Desde PO: action_create_invoice() │ └─ Crea account.move tipo 'in_invoice' │ └─ Vincula lineas de factura con POL │ ├─ Desde Factura entrante: │ └─ purchase.bill.line.match │ └─ Matching automatico o manual │ ACTUALIZACION │ ├─ qty_invoiced calculado de lineas factura ├─ invoice_status recalculado: │ ├─ 'no' = nada que facturar │ ├─ 'to invoice' = pendiente │ └─ 'invoiced' = todo facturado ``` --- ## 9. Acciones Automaticas | Trigger | Accion | Condicion | |---------|--------|-----------| | button_confirm | Generar nombre secuencial | Si name = 'New' | | button_approve | Establecer date_approve | Siempre | | button_approve | Crear recepciones stock | Si integracion activa | | Linea modificada | Recalcular totales | Siempre | | Recepcion stock | Actualizar qty_received | Automatico | --- ## 10. Permisos por Estado | Estado | Editable | Grupos | |--------|----------|--------| | draft | Si | purchase.group_purchase_user | | sent | Si | purchase.group_purchase_user | | to approve | Parcial | purchase.group_purchase_manager | | purchase | No (locked) | purchase.group_purchase_manager (unlock) | | cancel | No | purchase.group_purchase_user (reopen) | --- ## 11. Flujo de Estados de Facturacion ``` PO CONFIRMADA (state = purchase) │ ├─ invoice_status = 'no' │ └─ Nada recibido aun │ ├─ Recepcion parcial: │ └─ qty_received > 0 │ └─ invoice_status = 'to invoice' │ ├─ Factura parcial: │ └─ qty_invoiced < qty_received │ └─ invoice_status = 'to invoice' │ └─ Todo facturado: └─ qty_invoiced >= qty_received └─ invoice_status = 'invoiced' ``` --- **Referencias:** - purchase_order.py: button_confirm, button_approve, button_cancel - Integracion stock: purchase_stock/ - Integracion account: account_move.py