Files
fastapi-vue-odoo/frontend/src/utils/utils.js

261 lines
6.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const polishMonths = {
styczeń: 1,
luty: 2,
marzec: 3,
kwiecień: 4,
maj: 5,
czerwiec: 6,
lipiec: 7,
sierpień: 8,
wrzesień: 9,
październik: 10,
listopad: 11,
grudzień: 12,
}
const months = [
'styczeń',
'luty',
'marzec',
'kwiecień',
'maj',
'czerwiec',
'lipiec',
'sierpień',
'wrzesień',
'październik',
'listopad',
'grudzień',
]
const daysOfWeek = ['Nd', 'Pn', 'Wt', 'Śr', 'Cz', 'Pt', 'So']
// function getLastThreeMonth(monthName) {
// const months = Object.keys(polishMonths) // ["styczeń", "luty", ..., "grudzień"]
// const index = months.indexOf(monthName)
// if (index === -1) return [] // jeśli nie znaleziono miesiąca
// return [months[(index - 2 + 12) % 12], months[(index - 1 + 12) % 12], months[index]]
// }
// function getLastThreeMonth(monthName) {
// const index = months.indexOf(monthName)
// if (index === -1) return [] // jeśli nie znaleziono miesiąca
// return [months[(index - 2 + 12) % 12], months[(index - 1 + 12) % 12], months[index]]
// }
function getLastMonths(startMonth, count) {
const result = []
for (let i = 0; i < count; i++) {
// Obliczamy numer miesiąca (112), uwzględniając cofanie się w roku
let month = ((startMonth - i - 1 + 12) % 12) + 1
result.push(month)
}
return result
}
function getLastThreeMonth(month) {
if (!month || typeof month !== 'number' || month < 1 || month > 12) {
return null
}
return [((month - 3 + 12) % 12) + 1, ((month - 2 + 12) % 12) + 1, month]
}
function getMonthName(month) {
if (!month || typeof month !== 'number' || month < 1 || month > 12) {
return null
}
return months[month - 1]
}
function getMonthNumber(monthName) {
const monthNum = polishMonths[monthName.toLowerCase()]
if (!monthNum) {
console.error('❌ Unknown month:', monthName)
return null
}
return String(monthNum).padStart(2, '0')
}
function getDayOfWeek(dateStr) {
const date = new Date(dateStr)
return daysOfWeek[date.getDay()]
}
function extractTimeFromDateString(isoString) {
if (!isoString || typeof isoString !== 'string') return ''
const date = new Date(isoString + 'Z')
if (isNaN(date.getTime())) return ''
return date.toTimeString().slice(0, 5) // 'HH:MM:SS'
}
function isValidWorkDay(day) {
if (!day || typeof day !== 'object') return false
if (!('dayOfWeek' in day) || !('isPublicHoliday' in day)) return false
return day.dayOfWeek !== 'So' && day.dayOfWeek !== 'Nd' && !day.isPublicHoliday
}
function calculateWorkedTime(entryTimes, exitTimes) {
if (
!entryTimes ||
!exitTimes ||
!Array.isArray(entryTimes) ||
!Array.isArray(exitTimes) ||
entryTimes.length === 0
) {
return 0
}
let totalWorkedMinutes = 0
for (let i = 0; i < entryTimes.length; i++) {
const entryTime = entryTimes[i]
// Use the corresponding exit time, or skip if it doesn't exist
const exitTime = exitTimes[i]
if (!entryTime || !exitTime || typeof entryTime !== 'string' || typeof exitTime !== 'string') {
continue
}
const [eh, em] = entryTime.split(':').map(Number)
const [xh, xm] = exitTime.split(':').map(Number)
if ([eh, em, xh, xm].some((v) => typeof v !== 'number' || isNaN(v))) {
continue
}
const start = eh * 60 + em
const end = xh * 60 + xm
totalWorkedMinutes += end - start
}
const worked = totalWorkedMinutes / 60
return parseFloat(worked.toFixed(9))
}
function floatHoursToHHMM(decimalHours) {
if (typeof decimalHours !== 'number' || isNaN(decimalHours)) return ''
// if (decimalHours === 0) return ''
const negative = decimalHours < 0
const abs = Math.abs(decimalHours)
const m_total = Math.round(abs * 60)
const h = Math.floor(m_total / 60)
const m = m_total % 60
const hh = String(h).padStart(2, '0')
const mm = String(m).padStart(2, '0')
return `${negative ? '-' : ''}${hh}:${mm}`
}
function calculateDay(day) {
// Create a mutable copy of exit times to potentially add the current time.
// const exitTimes = [...day.exitTime]
// If there's one more entry than exits, it means the user is currently clocked in.
if (day.entryTime.length > 0 && day.entryTime.length === day.exitTime.length + 1) {
const now = new Date()
const hh = String(now.getHours()).padStart(2, '0')
const mm = String(now.getMinutes()).padStart(2, '0')
const ss = String(now.getSeconds()).padStart(2, '0')
// Add the current time as the "exit" for the last entry.
day.exitTime.push(`${hh}:${mm}:${ss}`)
}
if (day.entryTime.length === 0) {
day.workedHours = 0
} else {
// The -0.25 for a 15-minute break seems to be a business rule.
// It should probably only be subtracted once per day, not per interval.
// Let's subtract it from the total.
let totalHours = calculateWorkedTime(day.entryTime, day.exitTime)
if (totalHours > 0) {
totalHours -= 0.25
}
day.workedHours = parseFloat(totalHours.toFixed(9))
}
if (isValidWorkDay(day) && !day.isHolidayLeave && !day.isSickLeave) {
day.overtime = day.workedHours - 8
} else {
day.overtime = day.workedHours
}
day.overtime = parseFloat(day.overtime.toFixed(9))
let sumHours = day.workedHours
if (day.isHolidayLeave) {
sumHours += 8
}
if (day.isSickLeave) {
sumHours += 6.4
}
return parseFloat(sumHours.toFixed(9))
}
function calculateMonth(days) {
let accumulated = 0
let workingDaysCount = 0
let balance = 0
for (let i = 0; i < days.length; i++) {
const day = days[i]
const workedHours = calculateDay(day)
accumulated += workedHours
if (isValidWorkDay(day)) {
workingDaysCount++
}
balance = parseFloat((accumulated - workingDaysCount * 8).toFixed(9))
day.accumulatedHours = parseFloat(accumulated.toFixed(9))
day.balanceHours = balance
}
}
function calculateMonthFromDay(startDay, days) {
let startIndex = days.indexOf(startDay)
if (startIndex === -1) return
let accumulated = 0
let workingDaysCount = 0
let balance = 0
if (startIndex > 0) {
const previousDay = days[startIndex - 1]
accumulated = previousDay.accumulatedHours || 0
balance = previousDay.balanceHours || 0
workingDaysCount = days.slice(0, startIndex).filter(isValidWorkDay).length
}
for (let i = startIndex; i < days.length; i++) {
const day = days[i]
const workedHours = calculateDay(day)
accumulated += workedHours
if (isValidWorkDay(day)) {
workingDaysCount++
}
balance = parseFloat((accumulated - workingDaysCount * 8).toFixed(9))
day.accumulatedHours = parseFloat(accumulated.toFixed(9))
day.balanceHours = balance
}
}
export default {
getDayOfWeek,
extractTimeFromDateString,
isValidWorkDay,
calculateWorkedTime,
floatHoursToHHMM,
calculateDay,
calculateMonth,
calculateMonthFromDay,
getLastThreeMonth,
getLastMonths,
getMonthNumber,
getMonthName,
daysOfWeek,
}