74abecbe03
Auto Tag Develop / tag (push) Successful in 10s
## Fonctionnel - Calendrier MalioDate en vue Jour (écrans Heures ET Heures Conducteurs) : les jours entièrement validés par un admin sont peints en vert. - Endpoint `GET /work-hours/validation-status?from=&to=[&driver=1]` (scope conducteur inversé via `driver=1`), périmètre complet (ignore le filtre sites). - Chargement à la volée par mois (event `@month-change`), refresh après validation / saisie / absence. ## Harmonisation @malio/layer-ui 1.7.11 - `reserveMessageSpace=false` sur tous les champs (alignement). - Tous les drawers migrés sur `MalioDrawer` (titre via slot `#header`, `AppDrawer` custom supprimé). - Boutons d'action en `MalioButton` ; deux boutons côte à côte partagent l'espace. - Inputs date en `MalioDate`, sélecteur semaine en `MalioDateWeek`. - Boutons d'ajout uniformisés sur « Ajouter » + icône. ## Divers - `.env` : `EXCLUDED_PUBLIC_HOLIDAYS="null"`. - Doc : `doc/hours-validated-days.md`, `documentation-content.ts`, `CLAUDE.md`. - Tests : provider `WorkHourValidationStatus` (suite complète 236/236 OK via pre-commit hook). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed-on: #30 Co-authored-by: tristan <tristan@yuno.malio.fr> Co-committed-by: tristan <tristan@yuno.malio.fr>
161 lines
4.2 KiB
TypeScript
161 lines
4.2 KiB
TypeScript
import type {
|
|
WorkHourDayContext,
|
|
WorkHour,
|
|
WorkHourEntryPayload,
|
|
WeeklyWorkHourSummary
|
|
} from './dto/work-hour'
|
|
import { extractItems } from '~/utils/api'
|
|
|
|
export const listWorkHoursByDate = async (workDate: string) => {
|
|
const api = useApi()
|
|
const data = await api.get<WorkHour[] | { 'hydra:member'?: WorkHour[] }>(
|
|
'/work_hours',
|
|
{
|
|
'workDate[after]': workDate,
|
|
'workDate[before]': workDate
|
|
},
|
|
{ toast: false }
|
|
)
|
|
|
|
return extractItems<WorkHour>(data)
|
|
}
|
|
|
|
export const bulkUpsertWorkHours = async (payload: {
|
|
workDate: string
|
|
entries: WorkHourEntryPayload[]
|
|
}, options?: { toast?: boolean }) => {
|
|
const api = useApi()
|
|
return api.post<{
|
|
processed: number
|
|
created: number
|
|
updated: number
|
|
deleted: number
|
|
}>(
|
|
'/work-hours/bulk-upsert',
|
|
payload,
|
|
{
|
|
toast: options?.toast ?? true,
|
|
toastSuccessMessage: 'Horaires enregistrés.',
|
|
toastErrorMessage: "Impossible d'enregistrer les horaires."
|
|
}
|
|
)
|
|
}
|
|
|
|
export const updateWorkHourValidation = async (
|
|
id: number,
|
|
isValid: boolean,
|
|
options?: { toast?: boolean }
|
|
) => {
|
|
const api = useApi()
|
|
return api.patch<WorkHour>(
|
|
`/work_hours/${id}`,
|
|
{ isValid },
|
|
{
|
|
toast: options?.toast ?? true,
|
|
toastSuccessMessage: isValid ? 'Ligne validée.' : 'Validation retirée.',
|
|
toastErrorMessage: 'Impossible de mettre à jour la validation.'
|
|
}
|
|
)
|
|
}
|
|
|
|
export const bulkUpdateWorkHourValidation = async (payload: {
|
|
workDate: string
|
|
isValid: boolean
|
|
employeeIds: number[]
|
|
}, options?: { toast?: boolean }) => {
|
|
const api = useApi()
|
|
return api.post<{
|
|
requested: number
|
|
updated: number
|
|
skipped: number
|
|
updatedEmployeeIds: number[]
|
|
skippedEmployeeIds: number[]
|
|
}>(
|
|
'/work-hours/bulk-validation',
|
|
payload,
|
|
{
|
|
toast: options?.toast ?? true,
|
|
toastSuccessMessage: payload.isValid ? 'Validations enregistrées.' : 'Validations retirées.',
|
|
toastErrorMessage: "Impossible de mettre à jour les validations."
|
|
}
|
|
)
|
|
}
|
|
|
|
export const updateWorkHourSiteValidation = async (
|
|
id: number,
|
|
isSiteValid: boolean,
|
|
options?: { toast?: boolean }
|
|
) => {
|
|
const api = useApi()
|
|
return api.patch<WorkHour>(
|
|
`/work_hours/${id}/site-validation`,
|
|
{ isSiteValid },
|
|
{
|
|
toast: options?.toast ?? true,
|
|
toastSuccessMessage: isSiteValid ? 'Validation site enregistrée.' : 'Validation site retirée.',
|
|
toastErrorMessage: "Impossible de mettre à jour la validation site."
|
|
}
|
|
)
|
|
}
|
|
|
|
export const bulkUpdateWorkHourSiteValidation = async (payload: {
|
|
workDate: string
|
|
isSiteValid: boolean
|
|
employeeIds: number[]
|
|
}, options?: { toast?: boolean }) => {
|
|
const api = useApi()
|
|
return api.post<{
|
|
requested: number
|
|
updated: number
|
|
skipped: number
|
|
updatedEmployeeIds: number[]
|
|
skippedEmployeeIds: number[]
|
|
}>(
|
|
'/work-hours/site-bulk-validation',
|
|
payload,
|
|
{
|
|
toast: options?.toast ?? true,
|
|
toastSuccessMessage: payload.isSiteValid ? 'Validations site enregistrées.' : 'Validations site retirées.',
|
|
toastErrorMessage: "Impossible de mettre à jour les validations site."
|
|
}
|
|
)
|
|
}
|
|
|
|
export const getWeeklyWorkHourSummary = async (weekStart: string) => {
|
|
const api = useApi()
|
|
return api.get<WeeklyWorkHourSummary>(
|
|
'/work-hours/weekly-summary',
|
|
{ weekStart },
|
|
{ toast: false }
|
|
)
|
|
}
|
|
|
|
export const getWorkHourDayContext = async (workDate: string) => {
|
|
const api = useApi()
|
|
return api.get<WorkHourDayContext>(
|
|
'/work-hours/day-context',
|
|
{ workDate },
|
|
{ toast: false }
|
|
)
|
|
}
|
|
|
|
// Jours entièrement validés (admin) sur une plage, pour colorer le calendrier de
|
|
// la vue Jour. `validatedDays` = liste de dates Y-m-d (cf. doc/hours-validated-days).
|
|
// `driver` : true → écran Heures Conducteurs (seuls les conducteurs), false → écran Heures.
|
|
export const getWorkHourValidationStatus = async (
|
|
from: string,
|
|
to: string,
|
|
options?: { driver?: boolean }
|
|
) => {
|
|
const api = useApi()
|
|
const query: Record<string, string> = { from, to }
|
|
if (options?.driver) query.driver = '1'
|
|
const data = await api.get<{ from: string; to: string; validatedDays: string[] }>(
|
|
'/work-hours/validation-status',
|
|
query,
|
|
{ toast: false }
|
|
)
|
|
|
|
return data?.validatedDays ?? []
|
|
}
|