Congés Spectacles auto déclaration
This commit is contained in:
parent
10802e8ccb
commit
01aa804396
4 changed files with 301 additions and 2 deletions
108
FIX_CONGES_SPECTACLES_AUTO_DECLARATION.md
Normal file
108
FIX_CONGES_SPECTACLES_AUTO_DECLARATION.md
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
# Fix : Numéro Congés Spectacles - Page Auto-déclaration
|
||||||
|
|
||||||
|
## Problème identifié
|
||||||
|
|
||||||
|
Le champ "Numéro de Congés Spectacles" n'était **pas présent** dans le formulaire de la page d'auto-déclaration (`/auto-declaration`), alors que :
|
||||||
|
- ✅ Le champ existe dans la base de données (`salaries.conges_spectacles`)
|
||||||
|
- ✅ L'API backend gère correctement ce champ (`/api/auto-declaration/route.ts`)
|
||||||
|
- ✅ Le champ était pré-rempli depuis la base de données
|
||||||
|
|
||||||
|
**Conséquence** : Les salariés ne pouvaient pas saisir ou modifier leur numéro de Congés Spectacles via l'auto-déclaration.
|
||||||
|
|
||||||
|
## Solution appliquée
|
||||||
|
|
||||||
|
### 1. Modification de l'interface FormData
|
||||||
|
Ajout du champ `conges_spectacles` dans l'interface TypeScript :
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface FormData {
|
||||||
|
// ... autres champs
|
||||||
|
// État civil
|
||||||
|
date_naissance: string;
|
||||||
|
lieu_naissance: string;
|
||||||
|
numero_secu: string;
|
||||||
|
conges_spectacles: string; // ← AJOUTÉ
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Initialisation de l'état
|
||||||
|
Ajout de `conges_spectacles: ''` dans l'état initial du formulaire.
|
||||||
|
|
||||||
|
### 3. Pré-remplissage depuis la base de données
|
||||||
|
Ajout de la ligne pour pré-remplir le champ depuis les données du salarié :
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
setFormData(prev => ({
|
||||||
|
...prev,
|
||||||
|
// ...
|
||||||
|
conges_spectacles: data.conges_spectacles || '',
|
||||||
|
// ...
|
||||||
|
}));
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Envoi vers l'API
|
||||||
|
Ajout du champ dans les données envoyées lors de la sauvegarde :
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const updateData = {
|
||||||
|
// ...
|
||||||
|
conges_spectacles: formData.conges_spectacles || null,
|
||||||
|
// ...
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Ajout du champ HTML dans le formulaire
|
||||||
|
Nouveau champ ajouté dans la section "État civil", après le numéro de Sécurité Sociale :
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<div>
|
||||||
|
<LabelComponent>Votre numéro de Congés Spectacles</LabelComponent>
|
||||||
|
<input
|
||||||
|
value={formData.conges_spectacles}
|
||||||
|
onChange={(e) => setFormData(prev => ({
|
||||||
|
...prev,
|
||||||
|
conges_spectacles: e.target.value
|
||||||
|
}))}
|
||||||
|
className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
|
||||||
|
placeholder="Numéro d'objet (si intermittent)"
|
||||||
|
/>
|
||||||
|
<p className="text-[11px] text-slate-500 mt-1">
|
||||||
|
Ce champ est facultatif. Il concerne uniquement les intermittents du spectacle.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Fichiers modifiés
|
||||||
|
|
||||||
|
- ✅ `/app/auto-declaration/page.tsx` - Ajout du champ dans le formulaire
|
||||||
|
- ℹ️ `/app/api/auto-declaration/route.ts` - Aucune modification (déjà fonctionnel)
|
||||||
|
|
||||||
|
## Emplacement du champ
|
||||||
|
|
||||||
|
Le champ a été placé dans la section **"État civil"**, juste après le numéro de Sécurité Sociale, car :
|
||||||
|
- Il concerne l'état administratif du salarié
|
||||||
|
- C'est un numéro d'identification professionnel (comme le NIR)
|
||||||
|
- Position logique pour les intermittents du spectacle
|
||||||
|
|
||||||
|
## Caractéristiques du champ
|
||||||
|
|
||||||
|
- **Type** : Input texte
|
||||||
|
- **Obligatoire** : Non (facultatif)
|
||||||
|
- **Public cible** : Intermittents du spectacle
|
||||||
|
- **Placeholder** : "Numéro d'objet (si intermittent)"
|
||||||
|
- **Aide** : Message explicatif précisant que c'est facultatif
|
||||||
|
|
||||||
|
## Tests recommandés
|
||||||
|
|
||||||
|
1. ✅ Vérifier que le champ s'affiche correctement
|
||||||
|
2. ✅ Tester la saisie d'un numéro Congés Spectacles
|
||||||
|
3. ✅ Vérifier la sauvegarde en base de données
|
||||||
|
4. ✅ Tester le pré-remplissage si un numéro existe déjà
|
||||||
|
5. ✅ Vérifier que le champ reste facultatif (pas d'erreur si vide)
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- Le champ n'a pas de validation spécifique (format libre)
|
||||||
|
- Il n'est pas obligatoire
|
||||||
|
- Accepte n'importe quel texte/format
|
||||||
158
SYNC_NOTES_AUTO_DECLARATION_STAFF.md
Normal file
158
SYNC_NOTES_AUTO_DECLARATION_STAFF.md
Normal file
|
|
@ -0,0 +1,158 @@
|
||||||
|
# Synchronisation des notes : Auto-déclaration → Staff/Salariés
|
||||||
|
|
||||||
|
## Problème résolu
|
||||||
|
|
||||||
|
Les notes saisies par les salariés dans le formulaire d'auto-déclaration n'étaient **pas visibles** dans la section "Notes" de la page staff/salaries.
|
||||||
|
|
||||||
|
### Situation avant correction
|
||||||
|
|
||||||
|
- ✅ Les notes étaient sauvegardées dans `justificatifs_personnels` (format JSON)
|
||||||
|
- ❌ Les notes n'étaient PAS enregistrées dans le champ `notes`
|
||||||
|
- ❌ Le staff ne pouvait pas voir ces notes dans l'interface staff/salaries
|
||||||
|
|
||||||
|
**Conséquence** : Les informations importantes communiquées par les salariés restaient invisibles pour le staff.
|
||||||
|
|
||||||
|
## Solution appliquée
|
||||||
|
|
||||||
|
### Modifications dans `/app/api/auto-declaration/route.ts`
|
||||||
|
|
||||||
|
La logique d'enregistrement des notes a été améliorée pour :
|
||||||
|
|
||||||
|
1. **Récupérer les notes existantes** avant d'ajouter les nouvelles
|
||||||
|
2. **Ajouter la nouvelle note avec horodatage** au champ `notes` visible par le staff
|
||||||
|
3. **Préserver l'historique** dans `justificatifs_personnels` (format JSON)
|
||||||
|
|
||||||
|
### Code modifié
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
if (updateData.notes) {
|
||||||
|
// Récupérer les notes existantes pour les préserver
|
||||||
|
const { data: currentSalarie } = await sb
|
||||||
|
.from('salaries')
|
||||||
|
.select('notes, justificatifs_personnels')
|
||||||
|
.eq('id', tokenData.salarie_id)
|
||||||
|
.single();
|
||||||
|
|
||||||
|
// Préparer la nouvelle note avec horodatage
|
||||||
|
const currentDate = new Date().toISOString().split('T')[0];
|
||||||
|
const currentTime = new Date().toLocaleString('fr-FR');
|
||||||
|
const newNote = `[${currentTime} - Auto-déclaration]\n${updateData.notes}`;
|
||||||
|
|
||||||
|
// Ajouter aux notes existantes ou créer une nouvelle note
|
||||||
|
if (currentSalarie?.notes) {
|
||||||
|
dataToUpdate.notes = `${currentSalarie.notes}\n\n${newNote}`;
|
||||||
|
} else {
|
||||||
|
dataToUpdate.notes = newNote;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Également ajouter aux justificatifs personnels (format JSON) pour historique
|
||||||
|
const noteEntry = {
|
||||||
|
date: currentDate,
|
||||||
|
source: 'auto-declaration',
|
||||||
|
notes: updateData.notes
|
||||||
|
};
|
||||||
|
|
||||||
|
dataToUpdate.justificatifs_personnels = JSON.stringify([noteEntry]);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Fonctionnement
|
||||||
|
|
||||||
|
### 1. Horodatage automatique
|
||||||
|
Chaque note de l'auto-déclaration est précédée de :
|
||||||
|
```
|
||||||
|
[17/10/2025 à 14:30:25 - Auto-déclaration]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Préservation des notes existantes
|
||||||
|
- Si le salarié avait déjà des notes (ajoutées par le staff), elles sont conservées
|
||||||
|
- La nouvelle note est ajoutée à la suite avec une double ligne de séparation (`\n\n`)
|
||||||
|
|
||||||
|
### 3. Double sauvegarde
|
||||||
|
- **Champ `notes`** : Visible immédiatement par le staff sur staff/salaries
|
||||||
|
- **Champ `justificatifs_personnels`** : Historique structuré au format JSON
|
||||||
|
|
||||||
|
## Format des notes
|
||||||
|
|
||||||
|
### Exemple avec première note
|
||||||
|
```
|
||||||
|
[17/10/2025 à 14:30:25 - Auto-déclaration]
|
||||||
|
Je suis disponible pour commencer le contrat dès le 20 octobre.
|
||||||
|
J'ai déjà travaillé sur des productions similaires.
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exemple avec notes multiples
|
||||||
|
```
|
||||||
|
[15/10/2025 à 10:00:00 - Staff]
|
||||||
|
Candidat intéressant pour le projet XYZ
|
||||||
|
|
||||||
|
[17/10/2025 à 14:30:25 - Auto-déclaration]
|
||||||
|
Je suis disponible pour commencer le contrat dès le 20 octobre.
|
||||||
|
J'ai déjà travaillé sur des productions similaires.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Avantages
|
||||||
|
|
||||||
|
### ✅ Visibilité immédiate
|
||||||
|
- Les notes des salariés apparaissent instantanément dans l'interface staff
|
||||||
|
- Pas besoin de chercher dans les justificatifs personnels
|
||||||
|
|
||||||
|
### ✅ Traçabilité
|
||||||
|
- Horodatage précis de chaque note
|
||||||
|
- Source clairement identifiée (Auto-déclaration vs Staff)
|
||||||
|
- Historique complet préservé
|
||||||
|
|
||||||
|
### ✅ Communication améliorée
|
||||||
|
- Le staff peut voir les informations importantes des salariés
|
||||||
|
- Facilite le suivi et la coordination
|
||||||
|
- Évite les oublis ou pertes d'information
|
||||||
|
|
||||||
|
## Interface utilisateur
|
||||||
|
|
||||||
|
### Page auto-déclaration
|
||||||
|
Le salarié voit :
|
||||||
|
```
|
||||||
|
Section "Notes"
|
||||||
|
┌─────────────────────────────────────────────┐
|
||||||
|
│ Informations complémentaires │
|
||||||
|
│ ┌─────────────────────────────────────────┐ │
|
||||||
|
│ │ [Zone de texte libre] │ │
|
||||||
|
│ │ │ │
|
||||||
|
│ │ │ │
|
||||||
|
│ └─────────────────────────────────────────┘ │
|
||||||
|
│ Utilisez ce champ libre si vous devez │
|
||||||
|
│ mentionner toutes les informations │
|
||||||
|
│ complémentaires. │
|
||||||
|
└─────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### Page staff/salaries
|
||||||
|
Le staff voit la note dans le panneau latéral :
|
||||||
|
```
|
||||||
|
Section "Notes"
|
||||||
|
┌─────────────────────────────────────────────┐
|
||||||
|
│ [17/10/2025 à 14:30:25 - Auto-déclaration] │
|
||||||
|
│ Je suis disponible pour commencer le │
|
||||||
|
│ contrat dès le 20 octobre. │
|
||||||
|
└─────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tests recommandés
|
||||||
|
|
||||||
|
1. ✅ Saisir une note sur l'auto-déclaration
|
||||||
|
2. ✅ Vérifier qu'elle apparaît dans staff/salaries
|
||||||
|
3. ✅ Vérifier l'horodatage et la source
|
||||||
|
4. ✅ Ajouter une deuxième note et vérifier la concaténation
|
||||||
|
5. ✅ Vérifier que les notes staff existantes sont préservées
|
||||||
|
6. ✅ Tester avec un salarié sans note existante
|
||||||
|
7. ✅ Tester avec un salarié ayant déjà des notes staff
|
||||||
|
|
||||||
|
## Fichiers modifiés
|
||||||
|
|
||||||
|
- ✅ `/app/api/auto-declaration/route.ts` - Logique d'enregistrement des notes
|
||||||
|
|
||||||
|
## Rétrocompatibilité
|
||||||
|
|
||||||
|
- ✅ Les anciennes notes (si existantes) sont préservées
|
||||||
|
- ✅ Le format JSON dans `justificatifs_personnels` reste fonctionnel
|
||||||
|
- ✅ Aucune migration de données nécessaire
|
||||||
|
|
@ -148,8 +148,26 @@ export async function PATCH(request: NextRequest) {
|
||||||
if (updateData.bic !== undefined) dataToUpdate.bic = updateData.bic;
|
if (updateData.bic !== undefined) dataToUpdate.bic = updateData.bic;
|
||||||
if (updateData.derniere_profession !== undefined) dataToUpdate.derniere_profession = updateData.derniere_profession;
|
if (updateData.derniere_profession !== undefined) dataToUpdate.derniere_profession = updateData.derniere_profession;
|
||||||
if (updateData.notes) {
|
if (updateData.notes) {
|
||||||
// Ajouter les notes aux justificatifs personnels (format JSON)
|
// Récupérer les notes existantes pour les préserver
|
||||||
|
const { data: currentSalarie } = await sb
|
||||||
|
.from('salaries')
|
||||||
|
.select('notes, justificatifs_personnels')
|
||||||
|
.eq('id', tokenData.salarie_id)
|
||||||
|
.single();
|
||||||
|
|
||||||
|
// Préparer la nouvelle note avec horodatage
|
||||||
const currentDate = new Date().toISOString().split('T')[0];
|
const currentDate = new Date().toISOString().split('T')[0];
|
||||||
|
const currentTime = new Date().toLocaleString('fr-FR');
|
||||||
|
const newNote = `[${currentTime} - Auto-déclaration]\n${updateData.notes}`;
|
||||||
|
|
||||||
|
// Ajouter aux notes existantes ou créer une nouvelle note
|
||||||
|
if (currentSalarie?.notes) {
|
||||||
|
dataToUpdate.notes = `${currentSalarie.notes}\n\n${newNote}`;
|
||||||
|
} else {
|
||||||
|
dataToUpdate.notes = newNote;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Également ajouter aux justificatifs personnels (format JSON) pour historique
|
||||||
const noteEntry = {
|
const noteEntry = {
|
||||||
date: currentDate,
|
date: currentDate,
|
||||||
source: 'auto-declaration',
|
source: 'auto-declaration',
|
||||||
|
|
|
||||||
|
|
@ -133,6 +133,7 @@ interface FormData {
|
||||||
date_naissance: string;
|
date_naissance: string;
|
||||||
lieu_naissance: string;
|
lieu_naissance: string;
|
||||||
numero_secu: string;
|
numero_secu: string;
|
||||||
|
conges_spectacles: string;
|
||||||
|
|
||||||
// Bancaire
|
// Bancaire
|
||||||
iban: string;
|
iban: string;
|
||||||
|
|
@ -191,6 +192,7 @@ export default function AutoDeclarationPage() {
|
||||||
date_naissance: '',
|
date_naissance: '',
|
||||||
lieu_naissance: '',
|
lieu_naissance: '',
|
||||||
numero_secu: '',
|
numero_secu: '',
|
||||||
|
conges_spectacles: '',
|
||||||
|
|
||||||
// Bancaire
|
// Bancaire
|
||||||
iban: '',
|
iban: '',
|
||||||
|
|
@ -240,6 +242,7 @@ export default function AutoDeclarationPage() {
|
||||||
date_naissance: data.date_naissance || '',
|
date_naissance: data.date_naissance || '',
|
||||||
lieu_naissance: data.lieu_de_naissance || '',
|
lieu_naissance: data.lieu_de_naissance || '',
|
||||||
numero_secu: data.nir || '',
|
numero_secu: data.nir || '',
|
||||||
|
conges_spectacles: data.conges_spectacles || '',
|
||||||
iban: data.iban || '',
|
iban: data.iban || '',
|
||||||
bic: data.bic || '',
|
bic: data.bic || '',
|
||||||
employeur: data.organizations?.name || ''
|
employeur: data.organizations?.name || ''
|
||||||
|
|
@ -425,6 +428,7 @@ export default function AutoDeclarationPage() {
|
||||||
date_naissance: formData.date_naissance || null,
|
date_naissance: formData.date_naissance || null,
|
||||||
lieu_de_naissance: formData.lieu_naissance || null,
|
lieu_de_naissance: formData.lieu_naissance || null,
|
||||||
nir: formData.numero_secu || null,
|
nir: formData.numero_secu || null,
|
||||||
|
conges_spectacles: formData.conges_spectacles || null,
|
||||||
iban: formData.iban || null,
|
iban: formData.iban || null,
|
||||||
bic: formData.bic || null,
|
bic: formData.bic || null,
|
||||||
notes: formData.notes
|
notes: formData.notes
|
||||||
|
|
@ -840,6 +844,17 @@ export default function AutoDeclarationPage() {
|
||||||
/>
|
/>
|
||||||
<p className="text-[11px] text-slate-500 mt-1">Indiquez le NIR complet ou provisoire si pas encore définitif.</p>
|
<p className="text-[11px] text-slate-500 mt-1">Indiquez le NIR complet ou provisoire si pas encore définitif.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<LabelComponent>Votre numéro de Congés Spectacles</LabelComponent>
|
||||||
|
<input
|
||||||
|
value={formData.conges_spectacles}
|
||||||
|
onChange={(e) => setFormData(prev => ({ ...prev, conges_spectacles: e.target.value }))}
|
||||||
|
className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
|
||||||
|
placeholder="Numéro d'objet (si intermittent)"
|
||||||
|
/>
|
||||||
|
<p className="text-[11px] text-slate-500 mt-1">Ce champ est facultatif. Il concerne uniquement les intermittents du spectacle.</p>
|
||||||
|
</div>
|
||||||
</Section>
|
</Section>
|
||||||
|
|
||||||
{/* Section Coordonnées bancaires */}
|
{/* Section Coordonnées bancaires */}
|
||||||
|
|
@ -930,7 +945,7 @@ export default function AutoDeclarationPage() {
|
||||||
<textarea
|
<textarea
|
||||||
value={formData.notes}
|
value={formData.notes}
|
||||||
onChange={(e) => setFormData(prev => ({ ...prev, notes: e.target.value }))}
|
onChange={(e) => setFormData(prev => ({ ...prev, notes: e.target.value }))}
|
||||||
placeholder="Utilisez ce champ libre si vous devez mentionner toutes les informations complémentaires."
|
placeholder="Utilisez ce champ libre pour nous communiquer toute information complémentaire que vous jugez utile."
|
||||||
rows={4}
|
rows={4}
|
||||||
className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
|
className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue