Автор Тема: Детальный подсчёт рабочих часов  (Прочитано 682 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн CreatoR [?]

  • Администратор
  • *
  • Сообщений: 7827
  • Репутация: 2288
  • Пол: Мужской
  • AutoIt is simple, subtle, elegant
    • CreatoR's Lab
    • Награды
  • Версия AutoIt: 3.3.10.2
Версия AutoIt: 3.3.10.2

Описание:
Требуется разработать функцию, которая смогла бы детально подсчитать процентное соотношение рабочих часов.
Известно что на многих предприятиях и фирмах (так по крайней мере у нас в Израиле), за дополнительные часы работы есть доплата, также доплата полагается и за работу в выходные и праздники, вот собственно это и следует подсчитать по определённому алгоритму.
Я уже сделал набросок того как я это вижу, и что нужно учитывать при подсчёте.
В наброске ниже есть уже рабочие вспомогательные функции, которые мне помогли написать в моей же теме "Подсчёт разницы времени с учётом захода солнца", за что ребятам большое спасибо.

Пытался сделать сам, честно, но мозг видимо уже не тот, заржавел я немного :whistle:...

Вот несколько примеров, где показано наглядно при каком раскладе какой должен быть результат (обратите также внимание, что параметр $bHolidayIn иногда меняется, вместе с ним меняется и параметр $sHolidayInOutTime):

№1
Код: AutoIt [Выделить]
;Тут "Total hours" должно быть 16 (всего часов)
;100% должно быть 8
;125% должно быть 2
;150% это 0, поскольку $vExtraPaymentAbove150 = True, свыше 10-ти часов идёт надбавка в 50%, а к этому времени идёт работа в праздничные часы, поэтому по сути остальные часы это 200%.
;175 это 0, см. выше
;200% должно быть 6
$bHolidayIn = True ;Это значит что праздник заходит (начинается)
_PrecentCalc('07:00', '23:00', $bHolidayIn, $sHolidayInOutTime, $vExtraPaymentAbove150)


№2
Код: AutoIt [Выделить]
;Тут "Total hours" должно быть 10 (всего часов)
;100% должно быть 4
;125% должно быть 0 (от 13:00 до 17:00 (время захода праздника) 4 часа, поэтому остальное уже надбавка в 50%)
;150% это 4, поскольку в остальные часы идёт надбавка в 25%, как часы переработки (свыше 8-и).
;175 должно быть 2 (те самые часы переработки, где 25% добавляются к 50% т.к уже пошло время работы в праздничные часы)
;200% это 0, надбавки уже нет
$bHolidayIn = True ;Это значит что праздник заходит (начинается)
_PrecentCalc('13:00', '23:00', $bHolidayIn, $sHolidayInOutTime, $vExtraPaymentAbove150)


№3
Код: AutoIt [Выделить]
;Тут "Total hours" должно быть 16 (всего часов)
;100% должно быть 0
;125% должно быть 0
;150% это 16, т.е все часы, т.к от 07:00 (начало работы) и до 17:00 (время "выхода" праздника), это часы в 150%, а дальше уже свыше 10-ти часов, т.е это часы переработки где идёт надбавка в 50%, т.е тоже 150%
;175 должно быть 0
;200% должно быть 0
$bHolidayIn = False ;Это значит что праздник выходит (заканчивается)
_PrecentCalc('07:00', '23:00', $bHolidayIn, $sHolidayInOutTime, $vExtraPaymentAbove150)


Вот собственно сам набросок скрипта для тестирования и построения функции подсчёта:
Код: AutoIt [Выделить]
Global $vExtraPayment125 = 9 ;Оплата в 125% если число раб. часов достигло этого значения
Global $vExtraPayment150 = 10 ;Оплата в 150% если число раб. часов достигло этого значения
Global $vHolidayInTime = '17:00' ;Время "захода" (начало) праздника (время захода солнца)
Global $vHolidayOutTime = '17:00' ;Время "выхода" (конец) праздника (время захода солнца)

Global $vExtraPaymentAbove150 = True ;Учитывать подсчёт экстра-часов (свыше 150%), в некоторых случаях это не нужно учитывать
Global $bHolidayIn = True ;Указывает на то, начинается или нет время с которого следует считать часы работы как праздн. часы (время указывается в след. параметре)
Global $sHolidayInOutTime = $bHolidayIn ? $vHolidayInTime : $vHolidayOutTime

$aPrecentCalc = _PrecentCalc('07:00', '23:00', $bHolidayIn, $sHolidayInOutTime, $vExtraPaymentAbove150)
   
MsgBox(64, @ScriptName, _
    'Total hours: ' & $aPrecentCalc[0] & @CRLF & @CRLF & _
    '100%: ' & $aPrecentCalc[1] & @CRLF & _
    '125%: ' & $aPrecentCalc[2] & @CRLF & _
    '150%: ' & $aPrecentCalc[3] & @CRLF & _
    '175%: ' & $aPrecentCalc[4] & @CRLF & _
    '200%: ' & $aPrecentCalc[5] _
    )

;Функция должна вернуть расчёт часов разделённые на 100%, 125%, и т.д., с учётом начала праздника (по часам) или его завершения (выход)
;Параметры:
;$sTimeStart - время начала работы
;$sTimeEnd - время завершения работы
;$bHolidayIn - указывает на то, начинается или нет время с которого следует считать часы работы как праздн. часы (время указывается в след. параметре)
;$sHolidayTime - время начала или завершения праздничных часов, если 0 то все часы должны считаться обычно (в соот-вий с таблицей часов переработки)
;$bAbove150 - указывает на то, следует ли считать часы переработки (или праздн. часы) свыше 150%.
Func _PrecentCalc($sTimeStart, $sTimeEnd, $bHolidayIn, $sHolidayTime, $bAbove150 = True)
    Local $iTotalHours = 0
    Local $i100 = 0, $i125 = 0, $i150 = 0, $i175 = 0, $i200 = 0
   
    ;???
   
    Local $aRet[6] = [$iTotalHours, $i100, $i125, $i150, $i175, $i200]
    Return $aRet
EndFunc

;Функция возвращает:
;$aArr[0] - всего часов между $sTimeStart и $sTimeEnd
;$aArr[1] - время ДО заката ($sTimeSunset), т.е это по сути время начала или завершения праздника
;$aArr[2] - время ПОСЛЕ заката ($sTimeSunset), "..."
Func _TimeCalc($sTimeStart, $sTimeEnd, $sTimeSunset)
    Local $mTimeStart, $mTimeEnd, $iTotalMinutes, $iTotalHours, $mTimeSunset, $iTimeInMinutes
    Local $iTimeBeforeSunsetMinutes, $iTimeAfterSunsetMinutes, $iTimeBeforeSunset, $iTimeAfterSunset
   
    $mTimeStart = _TimeInMinutes($sTimeStart)
    $mTimeEnd = _TimeInMinutes($sTimeEnd)
   
    If $mTimeEnd < $mTimeStart Then
        $mTimeEnd += 1440
    EndIf
   
    $iTotalMinutes = $mTimeEnd - $mTimeStart
    $iTimeInMinutes = _TimeInMinutes($sTimeSunset)
   
    If $iTimeInMinutes Then
        $mTimeSunset = $iTimeInMinutes
        $iTimeBeforeSunsetMinutes = _TimeBetween($mTimeStart, $mTimeSunset) - _TimeBetween($mTimeEnd, $mTimeSunset)
        $iTimeAfterSunsetMinutes = $iTotalMinutes - $iTimeBeforeSunsetMinutes
        $iTimeBeforeSunset = Round(Round($iTimeBeforeSunsetMinutes / 30, 1) / 2, 2)
        $iTimeAfterSunset = Round(Round($iTimeAfterSunsetMinutes / 30, 1) / 2, 2)
    Else
        $iTimeBeforeSunset = 0
        $iTimeAfterSunset = 0
    EndIf
   
    $iTotalHours = Round(Round($iTotalMinutes / 30, 1) / 2, 2)
   
    Local $aRet[3] = [$iTotalHours, $iTimeBeforeSunset, $iTimeAfterSunset]
    Return $aRet
EndFunc

;Функция переводит время в минуты
Func _TimeInMinutes($sTimeParam)
    Return Execute(StringReplace($sTimeParam, ':', '*60+'))
EndFunc

;Функция возвращает разницу между минутами времени
Func _TimeBetween($iTime1, $iTime2)
    Return($iTime1 < $iTime2 ? $iTime2 - $iTime1 : 0)
EndFunc


Примечания:
Если $sHolidayInOutTime не указан (0), то считать все часы нужно без учёта захода или выхода праздника, т.е по обычной схеме подсчёта часов и часов переработки.
В наброске нужно доделать (точнее проработать) функцию _PrecentCalc.

Задача очень интересная, и я уверен что есть несложное решение, но мозг кипел пока я сам пытался это решить.
Спасибо за внимание.


Правила, Поиск, Супер тема


AutoIt is simple, subtle, elegant.


«Не оказываю тех. поддержку через ПМ/ICQ, и по электронной почте - для этого есть форум. (C)»
«Законы Мэрфи неоспоримы!»


Мои работы

Русское сообщество AutoIt

Детальный подсчёт рабочих часов
« Отправлен: Март 05, 2018, 06:17:24 »

Оффлайн ra4o [?]

  • Скриптер
  • ****
  • Сообщений: 800
  • Репутация: 140
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: Детальный подсчёт рабочих часов
« Ответ #1, Отправлен: Март 11, 2018, 12:35:35 »
Позвольте уточнить :
- Какая дискретность отсчета часов (кратно часу, пол-часа, по минутно) ?
- Исходя из предыдущего вопроса - может ли быть время задано с минутами ?
- Может ли начало и конец рабочей смены находится в разных сутках ( например начало в 21-00, окончание в 6-00 следующего дня) ?
- Какая максимальная продолжительнось смены ? (Возможно ли более суток ? )

Оффлайн CreatoR [?]

  • Администратор
  • *
  • Сообщений: 7827

  • Автор темы
  • Репутация: 2288
  • Пол: Мужской
  • AutoIt is simple, subtle, elegant
    • CreatoR's Lab
    • Награды
  • Версия AutoIt: 3.3.10.2
Re: Детальный подсчёт рабочих часов
« Ответ #2, Отправлен: Март 12, 2018, 05:38:08 »
ra4o  [?]
Цитировать
Какая дискретность отсчета часов (кратно часу, пол-часа, по минутно) ?
Поминутно.

Цитировать
Исходя из предыдущего вопроса - может ли быть время задано с минутами ?
Да.

Цитировать
Может ли начало и конец рабочей смены находится в разных сутках ( например начало в 21-00, окончание в 6-00 следующего дня) ?
Может.

Цитировать
Какая максимальная продолжительнось смены ? (Возможно ли более суток ? )
Максимально это 23:59, хотя и это уже считается незаконным )), у нас столько нельзя работать.

Обратите внимание на функцию _TimeCalc, которая во многом должна упростить задачу, она возвращает время до и после заката, а также общее число часов, с учётом минут естественно.
И ещё, если время начала работы указано такое же как и время завершения (допустим 08:00 и 08:00), то это считается как 0 (для всех параметров), т.е тут как бы и нечего считать.

Оффлайн ra4o [?]

  • Скриптер
  • ****
  • Сообщений: 800
  • Репутация: 140
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: Детальный подсчёт рабочих часов
« Ответ #3, Отправлен: Март 13, 2018, 22:05:57 »
Ещё уточнение:
- Переработка от 8 до 10 часов +25% вне праздика, в праздник 25+50=75% ?
- Переработка свыше 10 часов при $vExtraPaymentAbove150 = false : +25% , true: +50% (вне праздника ) и 75% и 200% соответственно в праздник ?
« Последнее редактирование: Март 13, 2018, 22:14:16 от ra4o »

Русское сообщество AutoIt

Re: Детальный подсчёт рабочих часов
« Ответ #3 Отправлен: Март 13, 2018, 22:05:57 »

Оффлайн CreatoR [?]

  • Администратор
  • *
  • Сообщений: 7827

  • Автор темы
  • Репутация: 2288
  • Пол: Мужской
  • AutoIt is simple, subtle, elegant
    • CreatoR's Lab
    • Награды
  • Версия AutoIt: 3.3.10.2
Re: Детальный подсчёт рабочих часов
« Ответ #4, Отправлен: Март 14, 2018, 01:55:24 »
ra4o  [?]
Цитировать
Переработка от 8 до 10 часов +25% вне праздика, в праздник 25+50=75% ?
Не совсем, от 8 до 10 и в праздник это +25, просто если "эти" от 8 до 10 приходятся на время праздника, то считается как 175% всего.
Т.е прибавлять к текущему уровню оплаты.

Цитировать
Переработка свыше 10 часов при $vExtraPaymentAbove150 = false : +25% , true: +50% (вне праздника ) и 75% и 200% соответственно в праздник ?
Не уверен что понял, но если $vExtraPaymentAbove150 = false, то значений в 175% и 200% быть не может, они все считаются как 150%.

Оффлайн CreatoR [?]

  • Администратор
  • *
  • Сообщений: 7827

  • Автор темы
  • Репутация: 2288
  • Пол: Мужской
  • AutoIt is simple, subtle, elegant
    • CreatoR's Lab
    • Награды
  • Версия AutoIt: 3.3.10.2
Re: Детальный подсчёт рабочих часов
« Ответ #5, Отправлен: Март 16, 2018, 04:39:19 »
Вроде получилось:

Код: AutoIt [Выделить]
Global $vExtraPayment125 = 8 ;Оплата в 125% если число раб. часов достигло этого значения
Global $vExtraPayment150 = 10 ;Оплата в 150% если число раб. часов достигло этого значения

Global $vHolidayInTime = '17:00' ;Время "захода" (начало) праздника (время захода солнца)
Global $vHolidayOutTime = '17:00' ;Время "выхода" (конец) праздника (время захода солнца) ; Совпадает с предыдущим параметром чтобы не путаться

Global $vExtraPaymentAbove150 = True ;Учитывать подсчёт экстра-часов (свыше 150%), в некоторых случаях это не нужно учитывать
Global $bHolidayIn = True ;Указывает на то, начинается или нет время с которого следует считать часы работы как праздн. часы (время указывается в след. параметре)
Global $sHolidayInOutTime = $bHolidayIn ? $vHolidayInTime : $vHolidayOutTime

$sTimeStart = '07:00'
$sTimeEnd = '23:00'

$aPrecentCalc = _PrecentCalc($sTimeStart, $sTimeEnd, $bHolidayIn, $sHolidayInOutTime, $vExtraPaymentAbove150)

$sRes = _
    'Holiday ' & ($bHolidayIn ? 'in' : 'out') & ' time: ' & $sHolidayInOutTime & @CRLF & _
    'From ' & $sTimeStart & ' to ' & $sTimeEnd & @CRLF & @CRLF & _
    'Total: ' & $aPrecentCalc[0] & @CRLF & _
    'Before sunset: ' & $aPrecentCalc[6] & @CRLF & _
    'After sunset: ' & $aPrecentCalc[7] & @CRLF & @CRLF & _
    '100%: ' & $aPrecentCalc[1] & @CRLF & _
    '125%: ' & $aPrecentCalc[2] & @CRLF & _
    '150%: ' & $aPrecentCalc[3] & @CRLF & _
    '175%: ' & $aPrecentCalc[4] & @CRLF & _
    '200%: ' & $aPrecentCalc[5]

;MsgBox(64, @ScriptName, $sRes)
ConsoleWrite($sRes & @CRLF)

;Функция должна вернуть расчёт часов разделённые на 100%, 125%, и т.д., с учётом начала праздника (по часам) или его завершения (выход)
;Параметры:
;$sTimeStart - время начала работы
;$sTimeEnd - время завершения работы
;$bHolidayIn - указывает на то, начинается или нет время с которого следует считать часы работы как праздн. часы (время указывается в след. параметре)
;$sHolidayTime - время начала или завершения праздничных часов, если 0 то все часы должны считаться обычно (в соот-вий с таблицей часов переработки)
;$bAbove150 - указывает на то, следует ли считать часы переработки (или праздн. часы) свыше 150%.
Func _PrecentCalc($sTimeStart, $sTimeEnd, $bHolidayIn, $sHolidayTime, $bAbove150 = True)
    Local $aTimeCalc = _TimeCalc($sTimeStart, $sTimeEnd, $sHolidayTime)
    Local $i100 = 0, $i125 = 0, $i150 = 0, $i175 = 0, $i200 = 0, $i100To150 = 0
   
    Local $iTotalHours = $aTimeCalc[0]
    Local $iBeforeSunsetHours = $aTimeCalc[1]
    Local $iAfterSunsetHours = $aTimeCalc[2]
   
    Local Const $iExtraDiff = ($vExtraPayment150 - $vExtraPayment125)
   
    If $sHolidayTime == '0' Or $sHolidayTime == '' Then
        $i100 = (($iTotalHours >= $vExtraPayment125) ? $vExtraPayment125 : $iTotalHours)
        $i125 = (($iTotalHours >= ($i100 + $iExtraDiff)) ? $iExtraDiff : ($iTotalHours - $i100))
        $i150 = ($iTotalHours - $i125 - $i100)
    Else
        Switch $bHolidayIn
            Case True
                $i100 = (($iBeforeSunsetHours > $vExtraPayment125) ? $vExtraPayment125 : $iBeforeSunsetHours)
                $i125 = ((($iBeforeSunsetHours - $i100) > $iExtraDiff) ? $iExtraDiff : ($iBeforeSunsetHours - $i100))
               
                $i150 = ((($i100 + $i125) < $iBeforeSunsetHours) ? ($iBeforeSunsetHours - ($i100 + $i125)) : 0)
                $i150 += ((($i100 + $i125) < $vExtraPayment125) ? ($vExtraPayment125 - ($i100 + $i125)) : 0)
                $i150 = ((($i150 + $i100 + $i125) > $iTotalHours) ? ($iTotalHours - ($i100 + $i125)) : $i150)
               
                $i100To150 = ($i100 + $i125 + $i150)
               
                $i175 = ($iTotalHours - $i100To150)
                $i175 = (($i175 + $i100To150) > $iTotalHours ? $iTotalHours - $i100To150 : ($i175 > $iExtraDiff ? $iExtraDiff : $i175))
                $i175 -= ((($i175 + $i125) > $iExtraDiff) ? ((($i175 - $i125) < 0) ? $i175 : $i125) : 0)
               
                $i200 = ($iTotalHours - ($i100To150 + $i175))
            Case Else
                $i100 = (($iBeforeSunsetHours < $vExtraPayment125) ? ((($vExtraPayment125 > $iTotalHours) ? $iTotalHours : $vExtraPayment125) - $iBeforeSunsetHours) : 0)
               
                $i125 = (($iBeforeSunsetHours < $vExtraPayment150) ? ((($vExtraPayment150 > $iTotalHours) ? $iTotalHours : $vExtraPayment150) - $iBeforeSunsetHours) : 0)
                $i125 = (($i125 > $iExtraDiff) ? $iExtraDiff : $i125)
                $i125 = ((($i125 + $i100) > $iTotalHours) ? ($iTotalHours - $i100) : $i125)
                $i125 = ((($i125 + $i100 + $iBeforeSunsetHours) > $iTotalHours) ? ($iAfterSunsetHours - $i100) : $i125)
               
                $i150 = (($iTotalHours - $i100 - $i125) - (($iBeforeSunsetHours > $vExtraPayment125) ? ($iBeforeSunsetHours - $vExtraPayment125) : 0))
               
                $i100To150 = ($i100 + $i125 + $i150)
               
                $i175 = ($iTotalHours - $i100To150)
                $i175 = (($i175 + $i100To150) > $iTotalHours ? $iTotalHours - $i100To150 : ($i175 > $iExtraDiff ? $iExtraDiff : $i175))
               
                $i200 = ($iTotalHours - ($i100To150 + $i175))
        EndSwitch
       
        If Not $bAbove150 Then
            $i150 += $i175 + $i200
            $i175 = 0
            $i200 = 0
        EndIf
    EndIf
   
    Local $aRet[8] = [$iTotalHours, Round($i100, 2), Round($i125, 2), Round($i150, 2), Round($i175, 2), Round($i200, 2), $iBeforeSunsetHours, $iAfterSunsetHours]
    Return $aRet
EndFunc

;Функция возвращает:
;$aArr[0] - всего часов между $sTimeStart и $sTimeEnd
;$aArr[1] - время ДО заката ($sTimeSunset), т.е это по сути время начала или завершения праздника
;$aArr[2] - время ПОСЛЕ заката ($sTimeSunset), "..."
Func _TimeCalc($sTimeStart, $sTimeEnd, $sTimeSunset)
    Local $mTimeStart, $mTimeEnd, $iTotalMinutes, $iTotalHours, $mTimeSunset, $iTimeInMinutes
    Local $iTimeBeforeSunsetMinutes, $iTimeAfterSunsetMinutes, $iTimeBeforeSunset, $iTimeAfterSunset
   
    $mTimeStart = _TimeInMinutes($sTimeStart)
    $mTimeEnd = _TimeInMinutes($sTimeEnd)
   
    If $mTimeEnd < $mTimeStart Then
        $mTimeEnd += 1440
    EndIf
   
    $iTotalMinutes = $mTimeEnd - $mTimeStart
    $iTimeInMinutes = _TimeInMinutes($sTimeSunset)
   
    If $iTimeInMinutes Then
        $mTimeSunset = $iTimeInMinutes
        $iTimeBeforeSunsetMinutes = _TimeBetween($mTimeStart, $mTimeSunset) - _TimeBetween($mTimeEnd, $mTimeSunset)
        $iTimeAfterSunsetMinutes = $iTotalMinutes - $iTimeBeforeSunsetMinutes
        $iTimeBeforeSunset = Round(Round($iTimeBeforeSunsetMinutes / 30, 1) / 2, 2)
        $iTimeAfterSunset = Round(Round($iTimeAfterSunsetMinutes / 30, 1) / 2, 2)
    Else
        $iTimeBeforeSunset = 0
        $iTimeAfterSunset = 0
    EndIf
   
    $iTotalHours = Round(Round($iTotalMinutes / 30, 1) / 2, 2)
   
    Local $aRet[3] = [$iTotalHours, $iTimeBeforeSunset, $iTimeAfterSunset]
    Return $aRet
EndFunc

;Функция переводит время в минуты
Func _TimeInMinutes($sTimeParam)
    Return Execute(StringReplace($sTimeParam, ':', '*60+'))
EndFunc

;Функция возвращает разницу между минутами времени
Func _TimeBetween($iTime1, $iTime2)
    Return($iTime1 < $iTime2 ? $iTime2 - $iTime1 : 0)
EndFunc


Мозг конечно придётся восстанавливать, но ничего, хорошая утилита получится :laugh:.
« Последнее редактирование: Март 19, 2018, 16:31:58 от CreatoR »

Русское сообщество AutoIt

Re: Детальный подсчёт рабочих часов
« Ответ #5 Отправлен: Март 16, 2018, 04:39:19 »

 

Похожие темы

  Тема / Автор Ответов Последний ответ
10 Ответов
5889 Просмотров
Последний ответ Ноябрь 07, 2010, 00:23:54
от Kaster
7 Ответов
5808 Просмотров
Последний ответ Ноябрь 18, 2010, 09:20:30
от akoulev
1 Ответов
3859 Просмотров
Последний ответ Август 07, 2013, 10:35:31
от millgan
0 Ответов
2725 Просмотров
Последний ответ Февраль 12, 2013, 20:56:50
от damien2008
17 Ответов
4256 Просмотров
Последний ответ Март 16, 2014, 09:49:41
от madmasles
1 Ответов
1535 Просмотров
Последний ответ Март 03, 2015, 15:15:51
от InnI
6 Ответов
2297 Просмотров
Последний ответ Сентябрь 02, 2015, 21:36:49
от spayn626
15 Ответов
2794 Просмотров
Последний ответ Май 27, 2016, 16:39:47
от CreatoR
4 Ответов
1174 Просмотров
Последний ответ Июль 05, 2016, 18:37:08
от Dessan
6 Ответов
1013 Просмотров
Последний ответ Апрель 21, 2017, 15:21:08
от Dellroc