workspace-v1/shared/knowledge-base/reference/odoo/docs/04-logica-negocio/FLUJO-project.md
rckrdmrd cb4c0681d3 feat(workspace): Add new projects and update architecture
New projects created:
- michangarrito (marketplace mobile)
- template-saas (SaaS template)
- clinica-dental (dental ERP)
- clinica-veterinaria (veterinary ERP)

Architecture updates:
- Move catalog from core/ to shared/
- Add MCP servers structure and templates
- Add git management scripts
- Update SUBREPOSITORIOS.md with 15 new repos
- Update .gitignore for new projects

Repository infrastructure:
- 4 main repositories
- 11 subrepositorios
- Gitea remotes configured

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 04:43:28 -06:00

9.5 KiB

Flujo de Negocio: Project (Proyectos)

Modulo: project Modelo Principal: project.task Aplica Workflow: Si (basado en state + stage_id)


1. Estados de Tarea (state)

Estado Nombre UI Tipo Descripcion
01_in_progress In Progress OPEN Trabajo activo
02_changes_requested Changes Requested OPEN Requiere modificaciones
03_approved Approved OPEN Aprobada
04_waiting_normal Waiting OPEN Bloqueada por dependencias
1_done Done CLOSED Completada
1_canceled Cancelled CLOSED Cancelada

2. Diagrama de Estados

                    ┌──────────────────┐
                    │   CREAR TAREA    │
                    │  state=in_progress│
                    └────────┬─────────┘
                             │
          ┌──────────────────┼──────────────────┐
          │                  │                  │
          ▼                  ▼                  ▼
┌──────────────────┐  ┌──────────────┐  ┌──────────────────┐
│   IN_PROGRESS    │  │  WAITING     │  │    APPROVED      │
│   01_in_progress │  │04_waiting_   │  │   03_approved    │
│                  │  │    normal    │  │                  │
└────────┬─────────┘  └──────┬───────┘  └────────┬─────────┘
         │                   │                   │
         │    ┌──────────────┘                   │
         │    │ (dependencias resueltas)         │
         │    ▼                                  │
         │  ┌─────────────────┐                  │
         │  │CHANGES_REQUESTED│                  │
         │  │02_changes_      │                  │
         │  │    requested    │                  │
         │  └────────┬────────┘                  │
         │           │                           │
         └───────────┼───────────────────────────┘
                     │
          ┌──────────┴──────────┐
          │                     │
          ▼                     ▼
┌──────────────────┐   ┌──────────────────┐
│       DONE       │   │    CANCELED      │
│     1_done       │   │   1_canceled     │
│  (is_closed=True)│   │  (is_closed=True)│
└──────────────────┘   └──────────────────┘

3. Etapas Kanban (stage_id)

ETAPAS POR PROYECTO:

project.type_ids = [Stage1, Stage2, Stage3, ...]

ASIGNACION:
- Al crear tarea: stage_id = primera etapa del proyecto
- Al mover en kanban: stage_id actualizado
- stage.fold = True indica etapa final

ETAPA PERSONAL:
- Cada usuario puede tener diferente etapa
- personal_stage_id computed por usuario
- Sincronizado via project.task.stage.personal

4. Flujo de Dependencias

TAREA A depende de TAREA B:

A.depend_on_ids = [B]
B.dependent_ids = [A]

LOGICA _compute_state:
┌─────────────────────────────────────────────────┐
│ Para cada tarea:                                │
│   Si state en CLOSED_STATES:                    │
│     → mantener (ya cerrada)                     │
│   Si depend_on_ids tiene tareas no cerradas:    │
│     → state = '04_waiting_normal'               │
│   Si no:                                        │
│     → mantener state actual                     │
└─────────────────────────────────────────────────┘

EFECTO:
- Tarea A automaticamente en "Waiting"
- Al cerrar B, A sale de "Waiting"

5. Flujo de Subtareas

ESTRUCTURA:
Tarea Padre
├── Subtarea 1 (child_ids)
│   └── Subtarea 1.1
├── Subtarea 2
└── Subtarea 3

HERENCIA:
- Subtareas heredan project_id del padre
- Subtareas pueden heredar milestone_id
- Tags se copian del padre al crear

CONTEO:
subtask_count = len(child_ids)

6. Flujo de Recurrencia

CONFIGURACION:
┌─────────────────────────────────────────────────┐
│ recurring_task = True                           │
│ repeat_interval = 1                             │
│ repeat_unit = 'week'                            │
│ repeat_type = 'forever' | 'until'               │
│ repeat_until = Date (si type='until')           │
└─────────────────────────────────────────────────┘

AL CERRAR TAREA:
1. _inverse_state detecta cierre
2. Si recurring_task y recurrence_id:
   - Crea siguiente ocurrencia
   - Nueva tarea con fecha + repeat_interval
3. Nueva tarea en estado inicial

7. Flujo de Milestones

ESTRUCTURA:
project.milestone
├── deadline: Fecha objetivo
├── is_reached: Marcado como alcanzado
└── task_ids: Tareas vinculadas

ASIGNACION:
- Tarea.milestone_id = hito seleccionado
- Subtareas heredan milestone del padre
- Validacion: milestone debe estar en mismo proyecto

TRACKING:
- task_count: Total tareas en hito
- done_task_count: Tareas cerradas
- Progreso = done_task_count / task_count

8. Metodos de Transicion

_compute_state()

@api.depends('stage_id', 'depend_on_ids.state')
def _compute_state(self):
    for task in self:
        # No cambiar si ya cerrada
        if task.state in CLOSED_STATES:
            continue

        # Verificar dependencias bloqueadas
        has_blocking = any(
            dep.state not in CLOSED_STATES
            for dep in task.depend_on_ids
        )

        if has_blocking:
            task.state = '04_waiting_normal'

_inverse_state()

def _inverse_state(self):
    # Maneja recurrencia al cerrar
    for task in self:
        if task.state in CLOSED_STATES and task.recurring_task:
            task._create_next_recurrence()

update_date_end(stage_id)

def update_date_end(self, stage_id):
    stage = self.env['project.task.type'].browse(stage_id)
    if stage.fold:  # Etapa final
        self.write({'date_end': fields.Datetime.now()})
    else:
        self.write({'date_end': False})

stage_find(section_id, domain, order)

def stage_find(self, section_id, domain=[], order='sequence, id'):
    # Buscar etapa valida para el proyecto
    # Considera etapas del proyecto o por defecto
    return stage_id

9. Reglas de Negocio

ID Regla Validacion Mensaje
R1 Proyecto requerido project_id presente Seleccione proyecto
R2 Milestone mismo proyecto milestone.project_id = project_id Milestone invalido
R3 No auto-dependencia task not in depend_on_ids No puede depender de si misma
R4 No ciclo dependencias Validar DAG Dependencia circular

10. Acciones Automaticas

Trigger Accion Condicion
stage_id change update_date_end Si stage.fold = True
stage_id change date_last_stage_update Siempre
user_ids change date_assign Primera asignacion
Cierre tarea recurrente Crear siguiente Si recurring_task
depend_on_ids change Recalcular state Siempre

11. Permisos por Portal

Campos Leibles

PROJECT_TASK_READABLE_FIELDS = {
    'id', 'active', 'priority', 'project_id',
    'user_ids', 'date_deadline', 'date_assign',
    'subtask_count', 'milestone_id', 'stage_id',
    'tag_ids', 'partner_id', 'display_name',
    'recurring_task', ...
}

Campos Escribibles

PROJECT_TASK_WRITABLE_FIELDS = {
    'name', 'description', 'partner_id',
    'date_deadline', 'tag_ids', 'sequence',
    'stage_id', 'child_ids', 'parent_id',
    'priority', 'state', 'is_closed', ...
}

12. Flujo Completo de Tarea

1. CREAR TAREA
   └─ state = '01_in_progress'
   └─ stage_id = primera etapa proyecto
   └─ date_create = ahora

2. ASIGNACION
   └─ user_ids asignados
   └─ date_assign = ahora (primera vez)

3. TRABAJO
   └─ Cambios de stage_id (kanban)
   └─ date_last_stage_update actualizado
   └─ Si tiene dependencias → puede ir a 'waiting'

4. REVISION (opcional)
   └─ state = '02_changes_requested'
   └─ state = '03_approved'

5. CIERRE
   └─ state = '1_done' o '1_canceled'
   └─ is_closed = True
   └─ date_end = ahora (si stage.fold)
   └─ Si recurrente → crea siguiente

6. RECURRENCIA (si aplica)
   └─ Nueva tarea creada
   └─ Fechas ajustadas segun interval
   └─ state = inicial

Referencias:

  • project_task.py: _compute_state, _inverse_state, update_date_end
  • project_task_type.py: fold, sequence
  • project_milestone.py: is_reached, task_count