feat(overtime-contingent) : encart contingent heures supp dans le header fiche employé
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,12 +2,14 @@ import type { Employee } from '~/services/dto/employee'
|
|||||||
import { CONTRACT_TYPES } from '~/services/dto/contract'
|
import { CONTRACT_TYPES } from '~/services/dto/contract'
|
||||||
import { getEmployee } from '~/services/employees'
|
import { getEmployee } from '~/services/employees'
|
||||||
import { useEmployeeContractPhase } from '~/composables/useEmployeeContractPhase'
|
import { useEmployeeContractPhase } from '~/composables/useEmployeeContractPhase'
|
||||||
|
import { getEmployeeOvertimeContingent, type OvertimeContingent } from '~/services/employee-overtime-contingent'
|
||||||
|
|
||||||
export const useEmployeeDetailPage = () => {
|
export const useEmployeeDetailPage = () => {
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const employee = ref<Employee | null>(null)
|
const employee = ref<Employee | null>(null)
|
||||||
const isLoading = ref(false)
|
const isLoading = ref(false)
|
||||||
const activeTab = ref<'contract' | 'leave' | 'rtt' | 'mileage' | 'formation' | 'bonus' | 'observation'>('contract')
|
const activeTab = ref<'contract' | 'leave' | 'rtt' | 'mileage' | 'formation' | 'bonus' | 'observation'>('contract')
|
||||||
|
const overtimeContingent = ref<OvertimeContingent | null>(null)
|
||||||
|
|
||||||
const phase = useEmployeeContractPhase(employee)
|
const phase = useEmployeeContractPhase(employee)
|
||||||
|
|
||||||
@@ -28,6 +30,18 @@ export const useEmployeeDetailPage = () => {
|
|||||||
return contract.name || '-'
|
return contract.name || '-'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const loadOvertimeContingent = async () => {
|
||||||
|
if (!employee.value || !showRttTab.value) {
|
||||||
|
overtimeContingent.value = null
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
overtimeContingent.value = await getEmployeeOvertimeContingent(employee.value.id)
|
||||||
|
} catch {
|
||||||
|
overtimeContingent.value = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const loadEmployee = async () => {
|
const loadEmployee = async () => {
|
||||||
const idParam = Array.isArray(route.params.id) ? route.params.id[0] : route.params.id
|
const idParam = Array.isArray(route.params.id) ? route.params.id[0] : route.params.id
|
||||||
const employeeId = Number(idParam)
|
const employeeId = Number(idParam)
|
||||||
@@ -71,6 +85,7 @@ export const useEmployeeDetailPage = () => {
|
|||||||
// qui proviennent du récap congés — nécessaire même quand on ouvre un autre onglet.
|
// qui proviennent du récap congés — nécessaire même quand on ouvre un autre onglet.
|
||||||
await leave.loadLeaveData()
|
await leave.loadLeaveData()
|
||||||
}
|
}
|
||||||
|
await loadOvertimeContingent()
|
||||||
} finally {
|
} finally {
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
}
|
}
|
||||||
@@ -94,6 +109,18 @@ export const useEmployeeDetailPage = () => {
|
|||||||
if (presence === undefined || presence === null) return ''
|
if (presence === undefined || presence === null) return ''
|
||||||
return ` (${formatDays(presence)} présence)`
|
return ` (${formatDays(presence)} présence)`
|
||||||
})
|
})
|
||||||
|
const overtimeContingentLabel = computed(() => {
|
||||||
|
if (!showRttTab.value) return ''
|
||||||
|
const c = overtimeContingent.value
|
||||||
|
if (!c) return ''
|
||||||
|
const h = c.paidMinutes / 60
|
||||||
|
const hStr = Number.isInteger(h) ? String(h) : (Math.round(h * 10) / 10).toFixed(1).replace('.', ',')
|
||||||
|
return `Contingent ${c.year} : ${hStr} h / ${c.capHours} h`
|
||||||
|
})
|
||||||
|
const overtimeContingentExceeded = computed(() => {
|
||||||
|
const c = overtimeContingent.value
|
||||||
|
return c ? c.paidMinutes > c.capHours * 60 : false
|
||||||
|
})
|
||||||
const rtt = useEmployeeRtt(employee, loadEmployee, phase.selectedPhase)
|
const rtt = useEmployeeRtt(employee, loadEmployee, phase.selectedPhase)
|
||||||
const mileage = useEmployeeMileage(employee, loadEmployee)
|
const mileage = useEmployeeMileage(employee, loadEmployee)
|
||||||
const formation = useEmployeeFormation(employee, loadEmployee)
|
const formation = useEmployeeFormation(employee, loadEmployee)
|
||||||
@@ -147,6 +174,8 @@ export const useEmployeeDetailPage = () => {
|
|||||||
employeeContractWorkLabel,
|
employeeContractWorkLabel,
|
||||||
forfaitRemainingDaysLabel,
|
forfaitRemainingDaysLabel,
|
||||||
nonForfaitPresenceLabel,
|
nonForfaitPresenceLabel,
|
||||||
|
overtimeContingentLabel,
|
||||||
|
overtimeContingentExceeded,
|
||||||
...phase,
|
...phase,
|
||||||
...contract,
|
...contract,
|
||||||
...leave,
|
...leave,
|
||||||
|
|||||||
@@ -28,6 +28,11 @@
|
|||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
<p class="font-bold text-[22px]">{{ contractNatureLabel(employee.currentContractNature) }} {{ employeeContractWorkLabel }}{{ forfaitRemainingDaysLabel }}{{ nonForfaitPresenceLabel }}</p>
|
<p class="font-bold text-[22px]">{{ contractNatureLabel(employee.currentContractNature) }} {{ employeeContractWorkLabel }}{{ forfaitRemainingDaysLabel }}{{ nonForfaitPresenceLabel }}</p>
|
||||||
<p class="text-[18px]">{{ employee.site?.name ?? '-' }}</p>
|
<p class="text-[18px]">{{ employee.site?.name ?? '-' }}</p>
|
||||||
|
<p
|
||||||
|
v-if="overtimeContingentLabel"
|
||||||
|
class="text-[16px] font-semibold"
|
||||||
|
:class="overtimeContingentExceeded ? 'text-red-600' : ''"
|
||||||
|
>{{ overtimeContingentLabel }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="showPicker" class="mt-3 flex items-center gap-3">
|
<div v-if="showPicker" class="mt-3 flex items-center gap-3">
|
||||||
@@ -300,6 +305,8 @@ const {
|
|||||||
employeeContractWorkLabel,
|
employeeContractWorkLabel,
|
||||||
forfaitRemainingDaysLabel,
|
forfaitRemainingDaysLabel,
|
||||||
nonForfaitPresenceLabel,
|
nonForfaitPresenceLabel,
|
||||||
|
overtimeContingentLabel,
|
||||||
|
overtimeContingentExceeded,
|
||||||
contractForm,
|
contractForm,
|
||||||
createContractForm,
|
createContractForm,
|
||||||
isContractDrawerOpen,
|
isContractDrawerOpen,
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
export interface OvertimeContingent {
|
||||||
|
year: number
|
||||||
|
paidMinutes: number
|
||||||
|
capHours: number
|
||||||
|
isDriver: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getEmployeeOvertimeContingent = async (employeeId: number, year?: number) => {
|
||||||
|
const api = useApi()
|
||||||
|
const query: Record<string, number> = {}
|
||||||
|
if (year) query.year = year
|
||||||
|
return api.get<OvertimeContingent>(`/employees/${employeeId}/overtime-contingent`, query, { toast: false })
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user