import at.clockwork.time.timeModel.detail.domain.* import at.clockwork.calculation.CalculationData import at.clockwork.calculation.data.* import at.clockwork.calculation.GeneralCalculationData import at.clockwork.time.service.DateTimeService import at.clockwork.calculation.RestartCalculationException import at.clockwork.common.service.GrailsToolsService import at.clockwork.singleton.SystemConfigurations import grails.util.Holders class Calc99960Service { static transactional = false SystemConfigurations systemConfigurations = SystemConfigurations.getInstance() def run(CalculationData calculationData, GeneralCalculationData generalCalculationData, boolean saving, Map parameters) throws RestartCalculationException { // Berechnung des Grundlohnes (Zeitart 6) // vor 7:00 und nach 19:00 gibt es jedenfalls Ueberstunden _addDV( "6", _getDV( "5" ) ) // steuerfreie UeStd int startTaxFreeTime1 = 0 int endTaxFreeTime1 = 6*60 int startTaxFreeTime2 = 22*60 int endTaxFreeTime2= 30*60 int minimumTaxFreeDuration = 3*60 int startBlockTime1 = 0 int endBlockTime1 = 7*60 int startBlockTime2 = 19*60 int endBlockTime2 = 31*60 // ununterbrochene Zeit Map taxFreeMap = _cd.continuouslyTime( new StartEndCalendarPair( _cd.cal, startBlockTime1, endBlockTime1 ), minimumTaxFreeDuration, true, _gcd.realTimeAbsences ) _cd.startBlockTime1 = taxFreeMap.continuouslyStartCal?.clone() _cd.endBlockTime1 = taxFreeMap.continuouslyEndCal?.clone() _cd.blockTime1Duration = taxFreeMap.continuouslyDuration // die Dauer ist maximal minimumTaxFreeDuration (3:00) _cd.blockTime1Fulfilled = taxFreeMap.continuouslyFulfilled if ( taxFreeMap.continuouslyDuration >= minimumTaxFreeDuration ) { // wenn zwischen 0:00 und 7:00 mindestens 3 Std durchgaengig gearbeitet wird, // dann endet die steuerfreie Zeit um 7:00 (und nicht um 6:00) startTaxFreeTime1 = 0 endTaxFreeTime1 = 7*60 } /* println """ taxFreeMap1 start=${_cd.startBlockTime1?.getTime()?.format("HH:mm")} end=${_cd.endBlockTime1?.getTime()?.format("HH:mm")} duration=${_cd.blockTime1Duration} fullfilled=${_cd.blockTime1Fulfilled} """*/ taxFreeMap = _cd.continuouslyTime( new StartEndCalendarPair( _cd.cal, startBlockTime2, endBlockTime2 ), minimumTaxFreeDuration, true, _gcd.realTimeAbsences ) _cd.startBlockTime2 = taxFreeMap.continuouslyStartCal?.clone() _cd.endBlockTime2 = taxFreeMap.continuouslyEndCal?.clone() _cd.blockTime2Duration = taxFreeMap.continuouslyDuration // die Dauer ist maximal minimumTaxFreeDuration (3:00) _cd.blockTime2Fulfilled = taxFreeMap.continuouslyFulfilled if ( taxFreeMap.continuouslyDuration >= minimumTaxFreeDuration ) { // wenn zwischen 19:00 und 7:00 mindestens 3 Std durchgaengig gearbeitet wird, // dann ist der steuerfreie Zeitbereich 19:00 bis 7:00 (und nicht 22:00 bis 6:00) startTaxFreeTime2 = 19*60 endTaxFreeTime2 = 31*60 endTaxFreeTime2 = 30*60 // ZGB } /* println """ taxFreeMap2 start=${_cd.startBlockTime2?.getTime()?.format("HH:mm")} end=${_cd.endBlockTime2?.getTime()?.format("HH:mm")} duration=${_cd.blockTime2Duration} fullfilled=${_cd.blockTime2Fulfilled} """ */ List plusTimePairList = _cd.getTimeModel2PlusTimes() plusTimePairList.each { if ( it.timeTimeType ) _setDV( it.timeTimeType.number, 0 ) if ( it.timeTimeType2 ) _setDV( it.timeTimeType2.number, 0 ) } List minusTimePairList = _cd.getTimeModel2MinusTimes() minusTimePairList.each { if ( it.timeTimeType ) _setDV( it.timeTimeType.number, 0 ) } double realTime = _getDV( "1" ) double planTime = _getDV( "2" ) // am einem Feiertag beginnnen die Plusstunden sofort // an normalen Arbeitstagen, muss zuerst die Sollzeit gearbeitet werden, bevor die Plusstunden beginnen // bei ZGB werden vor 7:00 und nach 19:00 jedenfalls Ueberstunden berechnet !!! planTime -= _getDV( "" + systemConfigurations.getItem( 5, "intValue" ) ) Calendar firstStartWorkingTime = _cd.getFirstStartWorkingTime() ?: _cd.cal.clone() Calendar minCal = _cd.timeBookingPairs.min{ it?.coming?.getTime() }?.coming Calendar maxCal = _cd.timeBookingPairs.max{ it?.going?.getTime() }?.going /* println "minCal=${minCal.getTime().format("HH:mm")}" println "maxCal=${maxCal.getTime().format("HH:mm")}" println "firstStartWorkingTime=${firstStartWorkingTime.getTime().format("HH:mm")}" */ Calendar cal0700 = _dts.getCalendar( _cd.cal, 7*60 ) Calendar cal1900 = _dts.getCalendar( _cd.cal, 19*60 ) //println "_gcd.realTimeAbsences" //_gcd.realTimeAbsences.each { println it } // ZGB // Calendar endOfNormCal = _cd.getNextCalendarInsideTimeBookings( firstStartWorkingTime, (int) planTime, [maxCal, cal1900].min(), true, _gcd.realTimeAbsences ) // Calendar startOfNormCal = _cd.getPreviousCalendarInsideTimeBookings( endOfNormCal, (int) planTime, [minCal, cal0700, firstStartWorkingTime].max(), true, _gcd.realTimeAbsences ) Calendar startOfNormCal = _cd.getPreviousCalendarInsideTimeBookings( [maxCal, cal1900].min(), (int) planTime, [minCal, cal0700].max(), true, _gcd.realTimeAbsences ) Calendar endOfNormCal = _cd.getNextCalendarInsideTimeBookings( startOfNormCal, (int) planTime, [maxCal, cal1900].min(), true, _gcd.realTimeAbsences ) /* println "startOfNormCal=${startOfNormCal.getTime().format("HH:mm")}" println "endOfNormCal=${endOfNormCal.getTime().format("HH:mm")}" */ _cd.startNormalWorkingTime = startOfNormCal?.clone() _cd.endNormalWorkingTime = endOfNormCal?.clone() /* println """ Normale Arbeitszeit: ${_cd.startNormalWorkingTime?.format("HH:mm")} - ${_cd.endNormalWorkingTime?.format("HH:mm")} """ */ if ( realTime <= planTime ) { minusTimePairList.each { if ( it.timeTimeType ) _addDV( it.timeTimeType.number, realTime-planTime ) } // ZGB -> auskommentiert // return } if (_cd.timeBookingPairs.size() == 0) return // bis hierher werden teilweise Variablen gesetzt, welche in anderen Tagesmodellen verwendet werden // ****************************************************************************************************************** /* // ab 50:00 in der Woche sind es 100% int ue50Bis = 40*60 Date startOfWeek = DateTimeService.getStartOfWeek(_cd.getDate()) double weekSum = _cd.getSummedDayValues("1", startOfWeek, _cd.getDate()-1) double norm = _cd.getTime(startOfNormCal, endOfNormCal) // Zeit vor der Rahmenzeit int beforeWorkingTime = _cd.getTime(minCal, startOfNormCal, _gcd.realTimeAbsences) // Zeit nach der Rahmenzeit int afterWorkingTime = _cd.getTime(endOfNormCal, maxCal, _gcd.realTimeAbsences) double sum = weekSum + norm + beforeWorkingTime + afterWorkingTime if (sum > ue50Bis) { int ueberUe50Bis = sum - ue50Bis // Stunden nach der Rahmenzeit zu 100%-UeStd. aendern int diff = [ueberUe50Bis, afterWorkingTime].min() if (diff > 0) { ueberUe50Bis -= diff zp106 = DateTimeService.getTime( _cd.cal, _cd.getPreviousCalendarInsideTimeBookings( DateTimeService.getCalendar(_cd.cal, zp106), diff, minCal ) ) } // Stunden vor der Rahmenzeit zu 100%-UeStd. aendern diff = [ueberUe50Bis, beforeWorkingTime].min() if (diff > 0) { ueberUe50Bis -= diff zp103 = DateTimeService.getTime( _cd.cal, _cd.getPreviousCalendarInsideTimeBookings( DateTimeService.getCalendar(_cd.cal, zp103), diff, minCal ) ) } } */ for ( Map plusTimePairItem in plusTimePairList ) { if ( plusTimePairItem.timeTimeType ) { List timePairList = DateTimeService.getNotOverlappingTimePairList( DateTimeService.getTime( _cd.cal, startOfNormCal ), DateTimeService.getTime( _cd.cal, endOfNormCal ), plusTimePairItem.startTime, plusTimePairItem.endTime ) for ( def timePairItem in timePairList ) { Map ue1Map = getUeStd( calculationData, generalCalculationData, timePairItem.startTime, timePairItem.endTime, startTaxFreeTime1, endTaxFreeTime1 ) _addDV( plusTimePairItem.timeTimeType.number, ue1Map.time ) // ZGB _addDV( "6", -ue1Map.time ) /* println "6=${_getDV(6)}, ue1Map.time=${-ue1Map.time}" */ if ( plusTimePairItem.timeTimeType2 ) { _addDV( plusTimePairItem.timeTimeType2.number, ue1Map.taxFreeTime ) _addDV( plusTimePairItem.timeTimeType.number, -ue1Map.taxFreeTime ) } Map ue2Map = getUeStd( calculationData, generalCalculationData, timePairItem.startTime, timePairItem.endTime, startTaxFreeTime2, endTaxFreeTime2 ) if ( plusTimePairItem.timeTimeType2 ) { _addDV( plusTimePairItem.timeTimeType2.number, ue2Map.taxFreeTime ) _addDV( plusTimePairItem.timeTimeType.number, -ue2Map.taxFreeTime ) } } } } return } Map getUeStd( CalculationData calculationData, GeneralCalculationData generalCalculationData, int startTime, int endTime, int taxFreeStartTime, int taxFreeEndTime ) { Map resultMap = [ time:0, taxFreeTime:0 ] resultMap.time = _cd.getTime( DateTimeService.getCalendar( _cd.cal, startTime ), DateTimeService.getCalendar( _cd.cal, endTime ), _gcd.realTimeAbsences ) Map overlappingMap = DateTimeService.getOverlappingTimePair( startTime, endTime, taxFreeStartTime, taxFreeEndTime ) resultMap.taxFreeTime = _cd.getTime( DateTimeService.getCalendar( _cd.cal, overlappingMap.startTime ), DateTimeService.getCalendar( _cd.cal, overlappingMap.endTime ), _gcd.realTimeAbsences ) /** println "startTime=${GrailsToolsService.getTimeStringFromMinutes(startTime, TimeFormatEnum.HHMM)}, endTime=${GrailsToolsService.getTimeStringFromMinutes(endTime, TimeFormatEnum.HHMM)}, taxFreeStartTime=${GrailsToolsService.getTimeStringFromMinutes(taxFreeStartTime, TimeFormatEnum.HHMM)}, taxFreeEndTime=${GrailsToolsService.getTimeStringFromMinutes(taxFreeEndTime, TimeFormatEnum.HHMM)}, resultMap=$resultMap" **/ resultMap } } /* ::1:: IF FUNC ZA_5 DO =_ZA_6 ; ::2:: IF FUNC ZT_0:00 DO =_ZA_9 =_ZA_10 ; ::3:: IF FUNC ZT_0:00 DO =_ZA_11 =_ZA_12 ; ::4:: IF FUNC ZT_0:00 DO =_ZA_13 =_ZA_14 ; ::5:: IF FUNC ZT_0:00 DO =_ZA_15 =_ZA_16 ; ::6:: IF FUNC ZT_0:00 DO =_ZA_17 =_ZA_18 ; ::7:: IF FUNC USTZP_0///ZA99/ DO ; ::8:: IF FUNC ZA_2 K ZA_1 DO -_ZA_&99 ; ::9:: IF ZA_1 <= ZA_2 UND NW_0 > NW_1 FUNC RETURN_ DO ; ::10:: IF FUNC VAR_ZPVArbeitszeit DO =_ZP_1 =_ZP_11 ; ::11:: IF FUNC VAR_ZPBArbeitszeit DO =_ZP_2 ; ::12:: IF FUNC ZP_ErstesKommen DO =_ZP_3 ; ::13:: IF FUNC ZP_LetztesGehen DO =_ZP_4 ; ::14:: IF FUNC ZBA_ZP1/ZP2 DO =_XVAR_99 ; ::15:: IF FUNC ZA_2 DO =_XVAR_2 ; ::16:: IF FUNC XVAR_2 MIN XVAR_99 DO =_ZA_99 ; ::17:: IF FUNC NZPA_ZP11/ZA99 DO =_ZP_12 ; ::17:: // Änderung am 2.2.2019, weil die Feiertagsberechnung nicht OK war IF ZP_12 < ZP_11 FUNC ZP_11 DO =_ZP_12 ; ::ALPHA:: IF FUNC XVAR_2 - ZBA_ZP11/ZP12 DO =_ZA_99 ; ::18:: IF FUNC ZT_0:00 DO =_XVAR_99 ; ::19:: IF ZA_99 > ZT_0:00 FUNC NUESTD_ZP11/ZP12/ZP3/ZP4/0/ZP13/ZP14/ZA98 DO =_XVAR_99 ; ::20:: IF XVAR_99 > ZT_0:00 UND ZP_13 < ZP_11 FUNC RNZPA_ZP14/ZA99 DO =_ZP_13 ; ::21:: IF XVAR_99 > ZT_0:00 UND ZP_14 > ZP_12 FUNC NZPA_ZP13/ZA99 DO =_ZP_14 ; ::22:: IF XVAR_99 > ZT_0:00 UND ZP_13 < ZP_11 FUNC ZP_11 MIN ZP_13 DO =_ZP_11 ; ::23:: IF XVAR_99 > ZT_0:00 UND ZP_14 > ZP_12 FUNC ZP_12 MAX ZP_14 DO =_ZP_12 ; ::24:: IF XVAR_99 > ZT_0:00 UND ZP_13 != ZP_14 FUNC GOTO_ALPHA DO ; ::25:: // Spezialregelung IF ZP_11 < ZP_7:00 FUNC ZP_7:00 DO =_ZP_11 ; ::26:: IF ZP_12 > ZP_19:00 FUNC ZP_19:00 DO =_ZP_12 ; ::27:: IF FUNC USTZP_1/ZP81/ZP82/ZA81/ZA82 DO ; ::28:: IF FUNC USTZP_2/ZP83/ZP84/ZA83/ZA84 DO ; ::29:: IF FUNC USTZP_3/ZP85/ZP86/ZA85/ZA86 DO ; ::30:: IF FUNC USTZP_4/ZP87/ZP88/ZA87/ZA88 DO ; ::31:: IF FUNC USTZP_5/ZP89/ZP90/ZA89/ZA90 DO ; ::32:: IF FUNC ZBMEA_ZP81/ZP82/ZP11/ZP12/1 DO +_ZA_&81 -_ZA_6 ; ::33:: IF FUNC ZBMEA_ZP83/ZP84/ZP11/ZP12/1 DO +_ZA_&83 -_ZA_6 ; ::34:: IF FUNC ZBMEA_ZP85/ZP86/ZP11/ZP12/1 DO +_ZA_&85 -_ZA_6 ; ::35:: IF FUNC ZBMEA_ZP87/ZP88/ZP11/ZP12/1 DO +_ZA_&87 -_ZA_6 ; ::36:: IF FUNC ZBMEA_ZP89/ZP90/ZP11/ZP12/1 DO +_ZA_&89 -_ZA_6 ; ::37:: IF FUNC VAR_SYSTEM-N1 MAX ZP_12 DO =_ZP_15 ; ::38:: IF FUNC VAR_SYSTEM-N2 DO =_ZP_16 ; ::39:: IF FUNC VAR_SYSTEM-N3 DO =_ZA_99 ; ::40:: IF FUNC BLA_ZP15/ZP16/ZA99/ZP17/ZP18 DO =_XVAR_99 ; ::41:: IF XVAR_99 < ZA_99 FUNC RETURN_ DO ; ::42:: IF ZA_82 > NW_0 FUNC ZBMEA_ZP81/ZP82/ZP17/ZP18/0 DO +_ZA_&82 -_ZA_&81 ; ::43:: IF ZA_84 > NW_0 FUNC ZBMEA_ZP83/ZP84/ZP17/ZP18/0 DO +_ZA_&84 -_ZA_&83 ; ::44:: IF ZA_86 > NW_0 FUNC ZBMEA_ZP85/ZP86/ZP17/ZP18/0 DO +_ZA_&86 -_ZA_&85 ; ::45:: IF ZA_88 > NW_0 FUNC ZBMEA_ZP87/ZP88/ZP17/ZP18/0 DO +_ZA_&88 -_ZA_&87 ; ::46:: IF ZA_90 > NW_0 FUNC ZBMEA_ZP89/ZP90/ZP17/ZP18/0 DO +_ZA_&90 -_ZA_&89 ; ::47:: IF FUNC RETURN_ DO ; */