34dc52d92b
- Calendrier MalioDate en vue Jour (Heures + Heures Conducteurs) : jours entièrement validés (admin) peints en vert. Endpoint GET /work-hours/validation-status?from=&to=[&driver=1] (scope conducteur inversé), chargement à la volée par mois, refresh après validation/saisie/absence. - Suite à @malio/layer-ui 1.7.11 : reserveMessageSpace=false sur les champs ; tous les drawers migrés sur MalioDrawer (titre via slot #header, AppDrawer custom supprimé) ; boutons d'action en MalioButton (deux boutons partagent l'espace) ; inputs date en MalioDate ; MalioDateWeek en vue Semaine. - Boutons d'ajout uniformisés sur « Ajouter » + icône. - .env : EXCLUDED_PUBLIC_HOLIDAYS="null". - Doc : doc/hours-validated-days.md, documentation-content.ts, CLAUDE.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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 ?? []
|
|
}
|