# Phase 21 : Gestion des Dépenses & Charges

**Priorité :** P2
**Complexité :** MOYENNE
**Routes :** ~6
**Entités :** 2

---

## Objectif

Suivi des dépenses opérationnelles (loyer, électricité, eau, fournitures, salaires, transport) pour obtenir un bénéfice net réel dans les rapports financiers.

---

## Entités

### `PosExpenseCategory`
Table : `pos_expense_category`

| Champ | Type | Description |
|-------|------|-------------|
| id | int PK | |
| company | FK Company CASCADE | |
| name | string 100, NotBlank | Ex: Loyer, Electricité, Fournitures |
| color | string 20, default `gray` | Pour les graphiques |
| icon | string 50 nullable | Icône FA (fa-bolt, fa-home, etc.) |
| isActive | bool default true | |
| position | int default 0 | Ordre d'affichage |

### `PosExpense`
Table : `pos_expense`

| Champ | Type | Description |
|-------|------|-------------|
| id | int PK | |
| company | FK Company CASCADE | |
| category | FK PosExpenseCategory SET NULL | |
| reference | string 30 | Auto : `DEP-{PREFIX}-{YEAR}-{SEQ}` |
| description | text | Description de la dépense |
| amount | decimal 12,2, NotBlank, Positive | Montant |
| date | date | Date de la dépense |
| paymentMethod | string 30 | `cash`, `bank_transfer`, `check`, `mobile_money`, `other` |
| receipt | FK Media SET NULL nullable | Justificatif (photo/scan) |
| isRecurring | bool default false | Dépense récurrente ? |
| recurringFrequency | string 20 nullable | `weekly`, `monthly`, `quarterly`, `yearly` |
| createdBy | FK User CASCADE | |
| TimestampableEntity | | |

**Index :** (company_id, date), (company_id, category_id)

---

## Service

### `PosExpenseService`
- `createExpense(PosExpense, Company, User): PosExpense`
- `updateExpense(PosExpense, User): PosExpense`
- `deleteExpense(PosExpense, User): void`
- `getExpensesQuery(Company, filters): Query` — search, category, dateFrom, dateTo, paymentMethod
- `getExpenseStats(Company, ?from, ?to): array` — total, par catégorie, récurrent vs ponctuel
- `getMonthlyExpenses(Company, int year): array` — total par mois pour graphique
- `generateReference(Company): string`

---

## Intégration Rapports

### `PosReportService.getFinancialReport()`
Ajouter :
- Total dépenses sur la période
- Dépenses par catégorie
- **Bénéfice net = CA - coût marchandises vendues - dépenses**
- Ratio dépenses/CA

---

## Routes Manager (~6)

| Route | Méthode | Path | Voter |
|-------|---------|------|-------|
| `manager_pos_expenses_index` | GET | `/manager/pos/expenses` | POS_MANAGE |
| `manager_pos_expenses_create` | GET/POST | `/manager/pos/expenses/create` | POS_MANAGE |
| `manager_pos_expenses_show` | GET | `/manager/pos/expenses/{id}` | POS_MANAGE |
| `manager_pos_expenses_edit` | GET/POST | `/manager/pos/expenses/{id}/edit` | POS_MANAGE |
| `manager_pos_expenses_delete` | POST | `/manager/pos/expenses/{id}/delete` | POS_MANAGE |
| `manager_pos_expenses_categories` | GET/POST | `/manager/pos/expenses/categories` | POS_MANAGE |

---

## Formulaire

### `PosExpenseFormType`
- category (EntityType filtré company)
- description (TextareaType)
- amount (MoneyType)
- date (DateType)
- paymentMethod (ChoiceType)
- isRecurring (CheckboxType)
- recurringFrequency (ChoiceType, conditionnel)
- receipt (FileType, nullable — upload justificatif)

---

## Templates (4)
- `expenses/index.html.twig` — Stats (total mois, par catégorie), filtres, table paginée, gradient rouge-orange
- `expenses/create.html.twig` — Formulaire Symfony Form
- `expenses/show.html.twig` — Détail + image justificatif
- `expenses/categories.html.twig` — Gestion catégories inline (CRUD simple sur même page)

## Menu
- Ajouter "Dépenses" après "Rapports" dans `_menu_manager.html.twig`
