# Documentation Technique - Modèles de données StockTransfer

## Vue d'ensemble

Cette documentation décrit l'architecture des modèles de données de l'application **StockTransfer**, une solution de gestion de stock et de transferts entre magasins. Les modèles ont été conçus à partir des modules présents dans la sidebar de l'application.

---

## Schéma relationnel global

```
┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│  Magasin    │────<│   Stock     │>────│  Produit    │
└──────┬──────┘     └─────────────┘     └──────┬──────┘
       │                                       │
       │     ┌─────────────┐                   │
       └────>│  Transfert  │<──────────────────┘
       │     └─────────────┘
       │
       ├────>│   Vente     │<────┐
       │     └─────────────┘     │
       │                          │
       ├────>│  Personnel  │     ┌┴──────┐
       │     └─────────────┘     │Client │
       │                          └───┬───┘
       ├────>│  Mouvement  │          │
       │     └─────────────┘          │
       │                               │
       └────>│ Inventaire  │     ┌─────┴─────┐
             └─────────────┘     │  Caution  │
                                 └───────────┘

┌──────────────┐     ┌─────────────┐
│ Fournisseur  │────<│   Achat     │
└──────────────┘     └─────────────┘

┌─────────────┐     ┌─────────────┐
│  Depense    │     │   Audit     │
└─────────────┘     └─────────────┘
```

---

## 1. Module Gestion

### 1.1 Magasin

**Table :** `magasins`

| Champ      | Type         | Description                    |
|------------|--------------|--------------------------------|
| id         | bigint       | Clé primaire                   |
| nom        | string       | Nom du magasin                 |
| adresse    | string       | Adresse (nullable)             |
| telephone  | string       | Numéro de téléphone (nullable)  |
| timestamps |              | created_at, updated_at         |

**Relations :**
- `stock()` : HasMany → Stock
- `transfertsOrigine()` : HasMany → Transfert (magasin_origine_id)
- `transfertsDestination()` : HasMany → Transfert (magasin_destination_id)
- `ventes()` : HasMany → Vente
- `personnel()` : HasMany → Personnel
- `mouvements()` : HasMany → Mouvement
- `inventaires()` : HasMany → Inventaire
- `produits()` : BelongsToMany → Produit (via table pivot stock)

---

### 1.2 Produit

**Table :** `produits`

| Champ       | Type         | Description                          |
|-------------|--------------|--------------------------------------|
| id          | bigint       | Clé primaire                         |
| reference   | string       | Référence unique (ex: PRD-001)        |
| designation | string       | Désignation du produit                |
| prix        | decimal(12,0)| Prix unitaire en FCFA                 |
| unite       | string       | Unité (pièce, kg, L, carton, sachet)  |
| timestamps  |              | created_at, updated_at                |

**Relations :**
- `stock()` : HasMany → Stock
- `transferts()` : HasMany → Transfert
- `ventes()` : HasMany → Vente
- `achats()` : HasMany → Achat
- `mouvements()` : HasMany → Mouvement
- `magasins()` : BelongsToMany → Magasin (via table pivot stock)

---

### 1.3 Stock

**Table :** `stock`

| Champ         | Type    | Description                          |
|---------------|---------|--------------------------------------|
| id            | bigint  | Clé primaire                         |
| magasin_id    | bigint  | FK → magasins                         |
| produit_id    | bigint  | FK → produits                         |
| quantite      | integer | Quantité en stock                    |
| seuil_alerte  | integer | Seuil déclenchant une alerte         |
| timestamps    |         | created_at, updated_at               |

**Contrainte unique :** (magasin_id, produit_id)

**Méthodes utilitaires :**
- `isEnAlerte()` : Retourne true si quantite ≤ seuil_alerte
- `getStatutAttribute()` : Retourne 'ok', 'alerte' ou 'critique'

---

### 1.4 Transfert

**Table :** `transferts`

| Champ                   | Type    | Description                    |
|-------------------------|---------|--------------------------------|
| id                      | bigint  | Clé primaire                   |
| reference               | string  | Référence unique (ex: TRF-001)  |
| magasin_origine_id      | bigint  | FK → magasins                   |
| magasin_destination_id   | bigint  | FK → magasins                   |
| produit_id              | bigint  | FK → produits                   |
| quantite                | integer | Quantité transférée            |
| date_transfert          | date    | Date du transfert              |
| timestamps              |         | created_at, updated_at         |

**Relations :**
- `magasinOrigine()` : BelongsTo → Magasin
- `magasinDestination()` : BelongsTo → Magasin
- `produit()` : BelongsTo → Produit

---

## 2. Module Ventes & Clients

### 2.1 Client

**Table :** `clients`

| Champ      | Type         | Description                    |
|------------|--------------|--------------------------------|
| id         | bigint       | Clé primaire                   |
| nom        | string       | Nom complet                    |
| telephone  | string       | Numéro de téléphone            |
| adresse    | string       | Adresse (nullable)              |
| caution    | decimal(12,0)| Montant caution actuel (FCFA)   |
| timestamps |              | created_at, updated_at         |

**Relations :**
- `ventes()` : HasMany → Vente
- `cautions()` : HasMany → Caution

---

### 2.2 Vente (et Facture)

**Table :** `ventes`

> **Note :** Dans l'application, les ventes et factures sont fusionnées. Une vente génère une facture (référence VNT-xxx). Le champ `paye` indique le statut de paiement.

| Champ       | Type         | Description                    |
|-------------|--------------|--------------------------------|
| id          | bigint       | Clé primaire                   |
| reference   | string       | Référence unique (ex: VNT-001)  |
| client_id   | bigint       | FK → clients                   |
| produit_id  | bigint       | FK → produits (nullable)       |
| magasin_id  | bigint       | FK → magasins                  |
| montant     | decimal(12,0)| Montant total en FCFA          |
| date_vente  | date         | Date de la vente               |
| paye        | boolean      | Statut de paiement             |
| timestamps  |              | created_at, updated_at          |

**Relations :**
- `client()` : BelongsTo → Client
- `produit()` : BelongsTo → Produit
- `magasin()` : BelongsTo → Magasin

---

### 2.3 Caution

**Table :** `cautions`

| Champ             | Type         | Description                    |
|-------------------|--------------|--------------------------------|
| id                | bigint       | Clé primaire                   |
| client_id         | bigint       | FK → clients                   |
| montant           | decimal(12,0)| Montant déposé (FCFA)          |
| date_depot        | date         | Date du dépôt                  |
| date_restitution  | date         | Date de restitution (nullable) |
| statut            | string       | 'active' ou 'restituée'         |
| timestamps        |              | created_at, updated_at          |

**Constantes :**
- `STATUT_ACTIVE` : 'active'
- `STATUT_RESTITUEE` : 'restituée'

**Relations :**
- `client()` : BelongsTo → Client

---

## 3. Module Approvisionnement

### 3.1 Fournisseur

**Table :** `fournisseurs`

| Champ      | Type   | Description                    |
|------------|--------|--------------------------------|
| id         | bigint | Clé primaire                   |
| nom        | string | Nom / Entreprise               |
| contact    | string | Téléphone de contact           |
| email      | string | Email (nullable)               |
| adresse    | string | Adresse (nullable)              |
| timestamps |        | created_at, updated_at          |

**Relations :**
- `achats()` : HasMany → Achat

---

### 3.2 Achat

**Table :** `achats`

| Champ             | Type         | Description                          |
|-------------------|--------------|--------------------------------------|
| id                | bigint       | Clé primaire                         |
| reference         | string       | Référence (ACH-xxx ou RET-xxx)        |
| type              | string       | 'achat' ou 'retour'                   |
| fournisseur_id    | bigint       | FK → fournisseurs                     |
| produit_id        | bigint       | FK → produits                         |
| quantite          | integer      | Quantité                              |
| montant           | decimal(12,0)| Montant en FCFA                       |
| achat_origine_id  | bigint       | FK → achats (pour les retours)        |
| motif             | string       | Motif du retour (nullable)            |
| date_achat        | date         | Date de l'achat                       |
| timestamps        |              | created_at, updated_at                |

**Constantes :**
- `TYPE_ACHAT` : 'achat'
- `TYPE_RETOUR` : 'retour'

**Relations :**
- `fournisseur()` : BelongsTo → Fournisseur
- `produit()` : BelongsTo → Produit
- `achatOrigine()` : BelongsTo → Achat (pour les retours)
- `retours()` : HasMany → Achat

---

### 3.3 Dépense

**Table :** `depenses`

| Champ        | Type         | Description                    |
|--------------|--------------|--------------------------------|
| id           | bigint       | Clé primaire                   |
| reference    | string       | Référence unique (ex: DEP-001) |
| libelle      | string       | Description de la dépense      |
| categorie    | string       | Catégorie (Loyer, Électricité…)|
| montant      | decimal(12,0)| Montant en FCFA                |
| date_depense | date         | Date de la dépense             |
| timestamps   |              | created_at, updated_at          |

---

### 3.4 Mouvement

**Table :** `mouvements`

| Champ       | Type    | Description                              |
|-------------|---------|------------------------------------------|
| id          | bigint  | Clé primaire                             |
| type        | string  | 'entree', 'sortie', 'transfert'          |
| magasin_id  | bigint  | FK → magasins                            |
| produit_id  | bigint  | FK → produits                            |
| quantite    | integer | Quantité (positif=entrée, négatif=sortie) |
| reference   | string  | Réf. document source (TRF-001, VNT-156…)  |
| timestamps  |         | created_at, updated_at                   |

**Constantes :**
- `TYPE_ENTREE` : 'entree'
- `TYPE_SORTIE` : 'sortie'
- `TYPE_TRANSFERT` : 'transfert'

**Relations :**
- `magasin()` : BelongsTo → Magasin
- `produit()` : BelongsTo → Produit

---

## 4. Module Administration

### 4.1 Personnel

**Table :** `personnel`

| Champ       | Type   | Description                    |
|-------------|--------|--------------------------------|
| id          | bigint | Clé primaire                   |
| nom         | string | Nom complet                    |
| poste       | string | Poste (Gérant, Vendeur…)       |
| magasin_id  | bigint | FK → magasins                  |
| telephone   | string | Numéro de téléphone            |
| timestamps  |        | created_at, updated_at          |

**Relations :**
- `magasin()` : BelongsTo → Magasin

---

### 4.2 Inventaire

**Table :** `inventaires`

| Champ           | Type   | Description                    |
|-----------------|--------|--------------------------------|
| id              | bigint | Clé primaire                   |
| reference       | string | Référence unique (ex: INV-001) |
| magasin_id      | bigint | FK → magasins                  |
| date_inventaire | date   | Date de l'inventaire           |
| statut          | string | 'en_cours' ou 'termine'        |
| timestamps      |        | created_at, updated_at          |

**Constantes :**
- `STATUT_EN_COURS` : 'en_cours'
- `STATUT_TERMINE` : 'termine'

**Relations :**
- `magasin()` : BelongsTo → Magasin
- `lignes()` : HasMany → InventaireLigne

---

### 4.3 InventaireLigne

**Table :** `inventaire_lignes`

| Champ             | Type    | Description                    |
|-------------------|---------|--------------------------------|
| id                | bigint  | Clé primaire                   |
| inventaire_id     | bigint  | FK → inventaires               |
| produit_id        | bigint  | FK → produits                  |
| quantite_systeme  | integer | Quantité système               |
| quantite_reelle   | integer | Quantité physique (nullable)    |
| ecart             | integer | quantite_reelle - quantite_systeme |
| timestamps        |         | created_at, updated_at          |

**Contrainte unique :** (inventaire_id, produit_id)

**Relations :**
- `inventaire()` : BelongsTo → Inventaire
- `produit()` : BelongsTo → Produit

---

### 4.4 Audit

**Table :** `audits`

| Champ            | Type   | Description                    |
|------------------|--------|--------------------------------|
| id               | bigint | Clé primaire                   |
| action           | string | create, update, delete         |
| model_type       | string | Classe du modèle               |
| model_id         | bigint | ID de l'enregistrement          |
| anciennes_valeurs| json   | Valeurs avant modification      |
| nouvelles_valeurs| json  | Valeurs après modification     |
| user_id          | bigint | FK → users (nullable)          |
| ip_address       | string | Adresse IP                      |
| timestamps       |        | created_at, updated_at          |

**Relations :**
- `user()` : BelongsTo → User

---

## 5. Rapports

Le module **Rapports** ne possède pas de modèle dédié. Les rapports sont générés à partir des données des modèles existants (Vente, Achat, Stock, Dépense, etc.) via des requêtes agrégées et des vues.

---

## 6. Ordre des migrations

Les migrations doivent être exécutées dans l'ordre suivant (dépendances respectées) :

1. `create_magasins_table`
2. `create_produits_table`
3. `create_fournisseurs_table`
4. `create_clients_table`
5. `create_stock_table`
6. `create_transferts_table`
7. `create_ventes_table`
8. `create_cautions_table`
9. `create_achats_table`
10. `add_achat_origine_foreign_key`
11. `create_depenses_table`
12. `create_mouvements_table`
13. `create_personnel_table`
14. `create_inventaires_table`
15. `create_inventaire_lignes_table`
16. `create_audits_table`

---

## 7. Exécution des migrations

```bash
php artisan migrate
```

---

## 8. Conventions de nommage

- **Références :**
  - Magasins : pas de préfixe
  - Produits : `PRD-001`, `PRD-002`…
  - Transferts : `TRF-001`, `TRF-002`…
  - Ventes/Factures : `VNT-001`, `VNT-002`…
  - Achats : `ACH-001`, `ACH-002`…
  - Retours : `RET-001`, `RET-002`…
  - Dépenses : `DEP-001`, `DEP-002`…
  - Inventaires : `INV-001`, `INV-002`…

- **Devise :** FCFA (Franc CFA)
- **Unités produits :** pièce, kg, L, carton, sachet

---

*Document généré le 23 février 2026 - Application StockTransfer*
