implement latest changes to employee payroll process
- Add ContractDaysWeek - Add Sickness Days to employee export sheet - Add Gesundheitsbonus value per employee - Additional fixes
This commit is contained in:
parent
156733f65a
commit
0951282f11
|
|
@ -1,3 +1,5 @@
|
|||
daten.csv
|
||||
|
||||
tmp/
|
||||
|
||||
# Binaries for programs and plugins
|
||||
|
|
|
|||
|
|
@ -1,73 +0,0 @@
|
|||
,,,Vertrag,Vertrag,Vertrag,Vertrag,Vertrag,Vertrag,Vertrag,Vertrag,"Stunden innerhalb der Soll-Stunden","Stunden innerhalb der Soll-Stunden","Stunden innerhalb der Soll-Stunden","Stunden innerhalb der Soll-Stunden","Stunden innerhalb der Soll-Stunden","Stunden innerhalb der Soll-Stunden",Ist-/Soll-Stunden,Ist-/Soll-Stunden,Ist-/Soll-Stunden,Ist-/Soll-Stunden,Berechnung,Berechnung,Berechnung,Berechnung,Berechnung,Berechnung,Berechnung,Berechnung,Berechnung,Berechnung,Berechnung,Berechnung,Berechnung,Berechnung,Berechnung,Berechnung,Berechnung,Salden,Salden,Salden,Salden,Salden,Salden,Salden,Salden,Salden,Auszahlen,Auszahlen,Auszahlen,Auszahlen,Auszahlen,Auszahlen,Auszahlen,Auszahlen,Auszahlen,Auszahlen,Auszahlen
|
||||
,,,,,,,,,,,"Gearbeitete Stunden","Gearbeitete Stunden","Urlaub nehmen","Urlaub nehmen",Krankheitsstunden,Krankheitsstunden,Gesamt,Gesamt,Vertrag,Vertrag,Plus/Min,Mehrstunden,Überstunden,"Zuschlag P-Schein","Krank ohne AU","Krank ohne AU","Nachtzuschlag 25 (25%)","Nachtzuschlag 25 (25%)","Nachtzuschlag 40 (40%)","Nachtzuschlag 40 (40%)","Sonntagszuschlag (50%)","Sonntagszuschlag (50%)","Feiertagszuschlag (125%)","Feiertagszuschlag (125%)","Verpfl.-pauschale (14%)","Samstagzuschlag (15%)","Samstagzuschlag (15%)",Zeitausgleich,Zeitausgleich,Zeitausgleich,Zeitausgleich,Zeitausgleich,Urlaub,Urlaub,Urlaub,Urlaub,Mehrstunden,"Überstunden auszahlen",Fahrtkosten,Verpflegungspauschale,"Zuschlag P-Schein",25%,40%,50%,125%,14%,15%
|
||||
Persnr.,Nachname,Vorname,Art,P-Schein,"Recht auf Zuschläge?",Start,Tage,Stunden,Max,"Urlaubstage pro Jahr",Tage,Stunden,Tage,Stunden,Tage,Stunden,Tage,Stunden,Tage,Stunden,Stunden,Stunden,Stunden,anzahl,Tage,Stunden,Tage,Stunden,Tage,Stunden,Tage,Stunden,Tage,Stunden,Tage,Tage,Stunden,Start,+/-,Änderungen,Auszahlen,Jetzt,Start,Abbau,Korrektur,Jetzt,Stunden,Stunden,km,Tage,Anzahl,Stunden,Stunden,Stunden,Stunden,Stunden,Stunden
|
||||
169,Safari,"Abdul Latif ",Fest,Ja,Ja,2025-09-01,5.00,40.00,0.00,20,20,180.4167,5,40,0,0,25,220.41666666667,21.667,173.333,47.08366666667,0.00033333332999064,47.08333333334,20,0,0,0,0,0,0,0,0,2,16.166666666667,16,2,17.35,0.334,47.08366666667,47.08366666667,47.08366666667,0.334,19,5,0,14,0.00033333332999064,47.08333333334,0.00,20,20,0,0,0,16.166666666667,18.9,17.35
|
||||
93,"Moshtagh Askari",Adel,Fest,Ja,Ja,2025-01-01,5.00,40.00,0.00,20,25,218.4167,0,0,0,0,25,218.41666666667,21.667,173.333,45.08366666667,0.00033333332999064,45.08333333334,25,0,0,0,0,0,0,0,0,2,18.65,20,3,24.95,0.007,45.08366666667,45.08366666667,45.08366666667,0.0069999999999979,31,0,0,31,0.00033333332999064,45.08333333334,0.00,25,25,0,0,0,18.65,14.816666666667,24.95
|
||||
18,Mihailescu,"Adrian Lucian",Fest,Ja,Ja,2025-09-01,5.00,40.00,0.00,20,21,177.5667,0,0,0,0,21,177.56666666667,21.667,173.333,4.23366666667,0.00033333332999064,4.23333333334,21,0,0,0,0,0,0,0,0,1,8.6333333333333,15,3,24.116666666667,0,4.23366666667,4.23366666667,4.23366666667,0,20,0,0,20,0.00033333332999064,4.23333333334,0.00,18,21,0,0,0,8.6333333333333,11.1,24.116666666667
|
||||
,"Esmaeili Dashtbayaz",Amin,Fest,Nein,Ja,2025-04-01,5.00,40.00,0.00,,20,171.2667,0,0,0,0,20,171.26666666667,21.667,173.333,-2.06633333333,0,0,,0,0,0,0,0,0,0,0,0,0,18,2,16.083333333333,0,-2.06633333333,-2.06633333333,0,-2.06633333333,-3,0,15,12,0,0,0.00,20,0,0,0,0,0,11.183333333333,16.083333333333
|
||||
,Ahmadpour,Amirhossein,Fest,Ja,Ja,2025-09-01,5.00,40.00,0.00,24,21,193.6333,2,16,0,0,23,209.63333333333,21.667,173.333,36.30033333333,0.00033333332999064,36.3,21,0,0,0,0,0,0,1,8.4666666666667,1,8.7833333333333,19,0,0,0,36.30033333333,36.30033333333,36.30033333333,0,-2,2,13,9,0.00033333332999064,36.3,0.00,21,21,0,0,8.4666666666667,8.7833333333333,24.383333333333,0
|
||||
188,"Malani Karizi",Arasch,Fest,Nein,Ja,2025-09-01,5.00,40.00,0.00,20,24,211.9833,0,0,0,0,24,211.98333333333,21.667,173.333,38.65033333333,0.00033333332999064,38.65,,0,0,6,2.6,0,0,0,0,1,8.25,20,3,24.7,-147.647,38.65033333333,38.65033333333,0,-108.99666666667,5,0,0,5,0,0,0.00,24,0,2.6,0,0,8.25,16.433333333333,24.7
|
||||
113,Ziaudin,Atiq,Fest,Ja,Ja,2025-02-24,5.00,40.00,0.00,20,23,194.3167,0,0,0,0,23,194.31666666667,21.667,173.333,20.98366666667,0.00033333332999064,20.98333333334,23,0,0,0,0,0,0,0,0,1,6.4333333333333,20,2,15.05,14.047,20.98366666667,20.98366666667,20.98366666667,14.047,9,0,0,9,0.00033333332999064,20.98333333334,0.00,21,23,0,0,0,6.4333333333333,12.833333333333,15.05
|
||||
,Rahmati,Behnam,Fest,Ja,Ja,2025-04-01,5.00,40.00,0.00,,20,176.05,0,0,0,0,20,176.05,21.667,173.333,2.717,0.00033333332999064,2.71666666667,20,1,8.5,0,0,0,0,0,0,0,0,20,0,0,0,2.717,2.717,2.717,0,-2,0,15,13,0.00033333332999064,2.71666666667,0.00,20,20,0,0,0,0,16.05,0
|
||||
,Altner,"Christian Van Manh",Fest,Ja,Ja,2025-10-01,5.00,40.00,0.00,20,22,184.0833,0,0,0,0,22,184.08333333333,21.667,173.333,10.75033333333,0.00033333332999064,10.75,22,0,0,1,0.2,0,0,0,0,1,7.9333333333333,20,1,8.0166666666667,0,10.75033333333,10.75033333333,10.75033333333,0,0,0,2,2,0.00033333332999064,10.75,0.00,21,22,0.2,0,0,7.9333333333333,7.9333333333333,8.0166666666667
|
||||
,Aba,Cuan,Fest,Nein,Ja,2025-08-01,5.00,40.00,0.00,,8,50.25,6,39,0,0,14,89.25,21.667,173.333,-84.083,0,0,,0,0,0,0,0,0,0,0,0,0,0,0,0,-144.25,-84.083,-84.083,0,-228.333,0,6,10,4,0,0,0.00,,0,0,0,0,0,0,0
|
||||
,Haghighivand,Danial,Fest,Nein,Ja,2025-04-01,5.00,40.00,0.00,,19,166.0333,2,16,0,0,21,182.03333333333,21.667,173.333,8.70033333333,0.00033333332999064,8.7,,0,0,0,0,0,0,0,0,0,0,19,0,0,0,8.70033333333,8.70033333333,8.70033333333,0,-10,2,15,3,0.00033333332999064,8.7,0.00,19,0,0,0,0,0,14.033333333333,0
|
||||
,Mohammadi,Danial,Fest,Ja,Ja,2025-01-01,5.00,40.00,0.00,20,21,182.8667,0,0,0,0,21,182.86666666667,21.667,173.333,9.53366666667,0.00033333332999064,9.53333333334,21,0,0,0,0,0,0,0,0,1,8.3333333333333,18,2,16.616666666667,0,9.53366666667,9.53366666667,9.53366666667,0,7,0,0,7,0.00033333332999064,9.53333333334,0.00,20,21,0,0,0,8.3333333333333,13.916666666667,16.616666666667
|
||||
,Shahrasebi,Danial,Fest,,,2021-05-01,0.00,0.00,0.00,,,,0,0,0,0,0,0,0,0,0,0,0,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,5,0,0,,,0,0,0,0,0,0,0
|
||||
,Emkani,Daniel,Fest,Nein,Ja,2025-07-15,3.00,25.00,0.00,,14,118.45,0,0,0,0,14,118.45,13,108.333,10.117,10.117,0,,0,0,0,0,0,0,0,0,1,8.6833333333333,0,2,13.3,0,10.117,10.117,10.117,0,0,0,7,7,10.117,0,0.00,12,0,0,0,0,8.6833333333333,0,13.3
|
||||
,Lolies,Danny,Fest,Ja,Ja,2025-03-01,5.00,40.00,0.00,,19,158.9,0,0,1,8.5,20,167.4,21.667,173.333,-5.933,0,0,19,3,24,0,0,0,0,0,0,1,5.55,15,2,17.05,0,-5.933,-5.933,0,-5.933,10,0,0,10,0,0,0.00,17,19,0,0,0,5.55,11.05,17.05
|
||||
,Hastedt,David,Fest,Nein,Ja,2025-01-27,4.00,32.00,0.00,20,14,112.3167,0,0,4,32,18,144.31666666667,17.333,138.667,5.64966666667,5.64966666667,0,,0,0,0,0,0,0,0,0,0,0,11,0,0,0,5.64966666667,5.64966666667,5.64966666667,0,2,0,0,2,5.64966666667,0,0.00,11,0,0,0,0,0,7.4166666666667,0
|
||||
2,Shahrasebi,David,Fest,Ja,Ja,2022-10-01,5.00,40.00,0.00,20,,0,0,0,0,0,0,0,21.667,173.333,0,0,0,,1,8.5,0,0,0,0,0,0,0,0,0,0,0,151.34,0,0,0,151.34,2,0,0,2,0,0,,,0,0,0,0,0,0,0
|
||||
,Golmohammadi,"Davood ",Fest,Ja,Ja,2025-08-01,5.00,40.00,0.00,20,20,182.2167,0,0,0,0,20,182.21666666667,21.667,173.333,8.88366666667,0.00033333332999064,8.88333333334,20,1,8,0,0,0,0,0,0,0,0,20,0,0,0,8.88366666667,8.88366666667,8.88366666667,0,-6,0,8,2,0.00033333332999064,8.88333333334,0.00,20,20,0,0,0,0,22.216666666667,0
|
||||
202,Pouzesh,Esmail,Fest,Ja,Ja,2025-09-01,5.00,40.00,0.00,20,24,202.0833,0,0,0,0,24,202.08333333333,21.667,173.333,28.75033333333,0.00033333332999064,28.75,24,0,0,21,70.416666666667,9,20.6,1,9.5,4,17.816666666667,0,0,0,0,28.75033333333,28.75033333333,28.75033333333,0,12,0,0,12,0.00033333332999064,28.75,0.00,24,24,70.416666666667,20.6,9.5,17.816666666667,0,0
|
||||
187,"Sajaei Khouzestani",Farid,Fest,Ja,Ja,2025-04-07,5.00,40.00,0.00,20,22,197.4333,0,0,0,0,22,197.43333333333,21.667,173.333,24.10033333333,0.00033333332999064,24.1,22,0,0,0,0,0,0,0,0,2,17.316666666667,18,2,16.366666666667,0,24.10033333333,24.10033333333,24.10033333333,0,19,0,0,19,0.00033333332999064,24.1,0.00,22,22,0,0,0,17.316666666667,19.75,16.366666666667
|
||||
191,"Faridani Rad",Farzad,Fest,Ja,Ja,2025-02-01,5.00,40.00,0.00,20,21,174.0833,0,0,2,16,23,190.08333333333,21.667,173.333,16.75033333333,0.00033333332999064,16.75,21,0,0,14,44.5,2,5.6666666666667,0,0,3,16.15,5,0,0,0,16.75033333333,16.75033333333,16.75033333333,0,0,0,0,0,0.00033333332999064,16.75,0.00,21,21,44.5,5.6666666666667,0,16.15,1.7666666666667,0
|
||||
,Movafagh,"Farzad ",Fest,Ja,Ja,2025-02-03,5.00,40.00,0.00,20,23,202.6167,0,0,1,8,24,210.61666666667,21.667,173.333,37.28366666667,0.00033333332999064,37.28333333334,23,0,0,0,0,0,0,0,0,0,0,20,3,24.55,0,37.28366666667,37.28366666667,37.28366666667,0,17,0,0,17,0.00033333332999064,37.28333333334,0.00,23,23,0,0,0,0,18.066666666667,24.55
|
||||
89,Hashimazada,Firuz,Fest,Ja,Ja,2025-01-01,5.00,40.00,0.00,20,18,155.35,0,0,3,24,21,179.35,21.667,173.333,6.017,0.00033333332999064,6.01666666667,18,1,8,0,0,0,0,0,0,1,8.5333333333333,17,0,0,0,6.017,6.017,6.017,0,8,0,0,8,0.00033333332999064,6.01666666667,0.00,18,18,0,0,0,8.5333333333333,10.816666666667,0
|
||||
,Saeedpour,Fouad,Fest,Ja,Ja,2025-09-01,5.00,40.00,0.00,,23,203.2833,0,0,0,0,23,203.28333333333,21.667,173.333,29.95033333333,0.00033333332999064,29.95,23,0,0,2,4.25,0,0,3,26.8,1,9,16,3,25.25,0,29.95033333333,29.95033333333,29.95033333333,0,26,0,0,26,0.00033333332999064,29.95,0.00,23,23,4.25,0,26.8,9,9.9833333333333,25.25
|
||||
55,Khodayaran,Hossein,Fest,Ja,Ja,2025-01-01,5.00,40.00,0.00,20,13,105.3,10,80,0,0,23,185.3,21.667,173.333,11.967,0.00033333332999064,11.96666666667,13,0,0,11,31,2,5.6666666666667,0,0,2,8.1333333333333,0,0,0,0,11.967,11.967,11.967,0,16,10,0,6,0.00033333332999064,11.96666666667,0.00,12,13,31,5.6666666666667,0,8.1333333333333,0,0
|
||||
206,Rasulkhani,Hossein,Fest,Ja,Ja,2025-03-06,5.00,40.00,0.00,20,23,194.8667,0,0,0,0,23,194.86666666667,21.667,173.333,21.53366666667,0.00033333332999064,21.53333333334,23,0,0,4,10.433333333333,0,0,1,9.25,1,9,13,4,32.366666666667,0,21.53366666667,21.53366666667,21.53366666667,0,29,0,0,29,0.00033333332999064,21.53333333334,0.00,23,23,10.433333333333,0,9.25,9,7.8166666666667,32.366666666667
|
||||
,"Mohamed Salah","Hussin Noureldin",Fest,Ja,Ja,2025-06-06,5.00,40.00,0.00,20,22,186.5833,0,0,0,0,22,186.58333333333,21.667,173.333,13.25033333333,0.00033333332999064,13.25,22,0,0,0,0,0,0,0,0,1,8.5166666666667,18,3,24.55,0,13.25033333333,13.25033333333,13.25033333333,0,-11,0,11,0,0.00033333332999064,13.25,0.00,21,22,0,0,0,8.5166666666667,9.5166666666667,24.55
|
||||
50,"Rohany Oskoee",Iman,Fest,Nein,Ja,2025-01-01,5.00,40.00,0.00,20,22,190.3833,0,0,0,0,22,190.38333333333,21.667,173.333,17.05033333333,0.00033333332999064,17.05,,0,0,0,0,0,0,0,0,1,8.7333333333333,20,1,8.0333333333333,0,17.05033333333,17.05033333333,17.05033333333,0,36,0,0,36,0.00033333332999064,17.05,0.00,22,0,0,0,0,8.7333333333333,13.616666666667,8.0333333333333
|
||||
7,Salehi,Iman,Fest,Ja,Ja,2025-02-01,5.00,40.00,0.00,20,26,220.1,0,0,0,0,26,220.1,21.667,173.333,46.767,0.00033333332999064,46.76666666667,26,0,0,21,68.766666666667,7,13.483333333333,2,18.2,2,16.383333333333,0,1,8.0166666666667,-14.233,46.767,46.767,32.534,7.105427357601E-15,0,0,0,0,0.00033333332999064,32.53366666667,0.00,26,26,68.766666666667,13.483333333333,18.2,16.383333333333,0,8.0166666666667
|
||||
,Krüger,Julian,Fest,Ja,Ja,2025-01-15,5.00,40.00,0.00,20,23,197.35,0,0,0,0,23,197.35,21.667,173.333,24.017,0.00033333332999064,24.01666666667,23,0,0,0,0,0,0,0,0,2,14.283333333333,0,2,15.116666666667,0,24.017,24.017,24.017,0,-30,0,38,8,0.00033333332999064,24.01666666667,0.00,19,23,0,0,0,14.283333333333,0,15.116666666667
|
||||
,Hazrati,Kamyar,Fest,,Ja,2025-02-24,5.00,40.00,0.00,20,21,182.75,0,0,0,0,21,182.75,21.667,173.333,9.417,0.00033333332999064,9.41666666667,,0,0,0,0,0,0,0,0,0,0,19,2,16.616666666667,0,9.417,9.417,9.417,0,10,0,0,10,0.00033333332999064,9.41666666667,0.00,20,0,0,0,0,0,14.133333333333,16.616666666667
|
||||
,Saei,Kasra,Fest,Nein,Ja,2025-08-01,5.00,40.00,0.00,,6,37.2667,10,80,0,0,16,117.26666666667,21.667,173.333,-56.06633333333,0,0,,0,0,0,0,0,0,0,0,0,0,0,0,0,-130.782,-56.06633333333,-56.06633333333,0,-186.84833333333,0,10,10,0,0,0,0.00,,0,0,0,0,0,0,0
|
||||
182,Kalantari,Kaveh,Fest,Ja,Ja,2025-03-01,5.00,40.00,0.00,20,18,159.05,5,40,0,0,23,199.05,21.667,173.333,25.717,0.00033333332999064,25.71666666667,18,0,0,2,4.25,0,0,1,10.25,1,9.9,14,2,16.916666666667,0,25.717,25.717,25.717,0,22,5,0,17,0.00033333332999064,25.71666666667,0.00,18,18,4.25,0,10.25,9.9,5.7333333333333,16.916666666667
|
||||
,Sahem,Khalid,Fest,Ja,Ja,2025-06-16,5.00,40.00,0.00,20,24,204.35,0,0,0,0,24,204.35,21.667,173.333,31.017,0.00033333332999064,31.01666666667,24,0,0,0,0,0,0,0,0,2,16.833333333333,19,3,26.033333333333,0,31.017,31.017,31.017,0,15,0,0,15,0.00033333332999064,31.01666666667,0.00,24,24,0,0,0,16.833333333333,9.4833333333333,26.033333333333
|
||||
194,Saffarnajib,Majid,Fest,Ja,Ja,2025-04-01,3.00,21.00,0.00,16,16,133.3667,0,0,0,0,16,133.36666666667,13,91,42.36666666667,42.36666666667,0,16,0,0,0,0,0,0,0,0,0,0,16,0,0,0,42.36666666667,42.36666666667,42.36666666667,0,0,0,16,16,42.36666666667,0,0.00,16,16,0,0,0,0,5.3666666666667,0
|
||||
177,Juyande,Masoud,Fest,Nein,Ja,2025-01-01,5.00,40.00,0.00,20,22,182.9,0,0,0,0,22,182.9,21.667,173.333,9.567,0.00033333332999064,9.56666666667,,0,0,21,68.1,10,23.783333333333,0,0,2,8.5166666666667,0,0,0,0.009,9.567,9.567,9.567,0.0090000000000003,-7,0,0,-7,0.00033333332999064,9.56666666667,0.00,22,0,68.1,23.783333333333,0,8.5166666666667,0,0
|
||||
53,Eggerstedt,Matthias,Fest,Ja,Ja,2025-01-01,5.00,40.00,0.00,20,22,190.1333,0,0,0,0,22,190.13333333333,21.667,173.333,16.80033333333,0.00033333332999064,16.8,22,0,0,0,0,0,0,0,0,1,8.6333333333333,20,0,0,0,16.80033333333,16.80033333333,16.80033333333,0,8,0,2,10,0.00033333332999064,16.8,0.00,21,22,0,0,0,8.6333333333333,15.233333333333,0
|
||||
,Arabnia,Mehdi,Fest,Ja,Ja,2025-05-05,5.00,40.00,0.00,,22,194.3833,0,0,0,0,22,194.38333333333,21.667,173.333,21.05033333333,0.00033333332999064,21.05,22,0,0,0,0,0,0,0,0,0,0,20,2,15.783333333333,0,21.05033333333,21.05033333333,21.05033333333,0,-5,0,12,7,0.00033333332999064,21.05,0.00,21,22,0,0,0,0,18.6,15.783333333333
|
||||
,"Jalali Wagener",Mehdi,Fest,Ja,Ja,2025-02-01,5.00,40.00,0.00,,24,204.4833,0,0,0,0,24,204.48333333333,21.667,173.333,31.15033333333,0.00033333332999064,31.15,24,0,0,0,0,0,0,0,0,1,8.5333333333333,21,2,16.35,0,31.15033333333,31.15033333333,31.15033333333,0,-2,0,1,-1,0.00033333332999064,31.15,0.00,24,24,0,0,0,8.5333333333333,11.6,16.35
|
||||
,Taghadosi,Mehdi,Fest,Ja,Ja,2025-08-08,5.00,40.00,0.00,,22,188.9333,0,0,0,0,22,188.93333333333,21.667,173.333,15.60033333333,0.00033333332999064,15.6,22,0,0,0,0,0,0,0,0,1,6.3,19,2,16.6,0,15.60033333333,15.60033333333,15.60033333333,0,10,0,0,10,0.00033333332999064,15.6,0.00,21,22,0,0,0,6.3,14.033333333333,16.6
|
||||
,Mazidi,Mehrdad,Fest,Ja,Ja,2025-07-01,5.00,40.00,0.00,20,21,183.1667,0,0,0,0,21,183.16666666667,21.667,173.333,9.83366666667,0.00033333332999064,9.83333333334,21,0,0,0,0,0,0,0,0,1,8.1166666666667,18,2,17.033333333333,0,9.83366666667,9.83366666667,9.83366666667,0,0,0,10,10,0.00033333332999064,9.83333333334,0.00,21,21,0,0,0,8.1166666666667,14.016666666667,17.033333333333
|
||||
165,Koell,"Melanie Nadine",Fest,Nein,Ja,2025-01-01,5.00,40.00,0.00,20,,0,0,0,4,32,4,32,21.667,173.333,-141.333,0,0,,0,0,0,0,0,0,0,0,0,0,0,0,0,-165.263,-141.333,-141.333,0,-306.596,12,0,0,12,0,0,,,0,0,0,0,0,0,0
|
||||
119,Pourhossein,Milad,Fest,Ja,Ja,2025-09-01,5.00,40.00,0.00,20,15,125.6167,7,56,0,0,22,181.61666666667,21.667,173.333,8.28366666667,0.00033333332999064,8.28333333334,15,0,0,0,0,0,0,0,0,1,7.9333333333333,12,2,16.6,-57.848,8.28366666667,8.28366666667,0,-49.56433333333,-6,7,23,10,0,0,0.00,14,15,0,0,0,7.9333333333333,5.0833333333333,16.6
|
||||
144,Maleki,Mohammad,Fest,Ja,Ja,2025-09-01,3.00,24.00,0.00,20,5,41.1167,0,0,0,0,5,41.116666666667,13,104,-62.883333333333,0,0,5,2,16,0,0,0,0,0,0,0,0,3,0,0,-250.962,-62.883333333333,-62.883333333333,0,-313.84533333333,-1,0,0,-1,0,0,0.00,3,5,0,0,0,0,1.4,0
|
||||
217,"Rasul Khani",Mohammad,Fest,Ja,Ja,2025-03-03,5.00,40.00,0.00,20,24,209.4833,0,0,0,0,24,209.48333333333,21.667,173.333,36.15033333333,0.00033333332999064,36.15,24,0,0,1,2.25,0,0,2,17.45,1,8.25,20,1,8.0166666666667,0,36.15033333333,36.15033333333,36.15033333333,0,20,0,0,20,0.00033333332999064,36.15,0.00,24,24,2.25,0,17.45,8.25,13.516666666667,8.0166666666667
|
||||
96,Sabahi,Mohammad,Fest,Ja,Ja,2025-01-01,5.00,40.00,0.00,20,18,152.5833,1,8,4,32,23,192.58333333333,21.667,173.333,19.25033333333,0.00033333332999064,19.25,18,0,0,0,0,0,0,0,0,2,16.583333333333,16,0,0,0,19.25033333333,19.25033333333,19.25033333333,0,10,1,0,9,0.00033333332999064,19.25,0.00,18,18,0,0,0,16.583333333333,8,0
|
||||
78,Tajikzadeh,Mohammad,Fest,Ja,Ja,2025-01-01,5.00,40.00,0.00,20,18,152.3167,5,40,0,0,23,192.31666666667,21.667,173.333,18.98366666667,0.00033333332999064,18.98333333334,18,0,0,0,0,0,0,0,0,1,8.25,16,1,8.0833333333333,0,18.98366666667,18.98366666667,18.98366666667,0,7,5,0,2,0.00033333332999064,18.98333333334,0.00,18,18,0,0,0,8.25,7.9833333333333,8.0833333333333
|
||||
,Atrafi,"Mohammad Nasir",Fest,Ja,Ja,2025-10-01,5.00,4.00,0.00,20,19,162.9667,0,0,0,0,19,162.96666666667,21.667,17.333,145.63366666667,145.63366666667,0,19,0,0,0,0,0,0,0,0,0,0,16,3,22.5,0,145.63366666667,145.63366666667,145.63366666667,0,0,0,5,5,145.63366666667,0,0.00,17,19,0,0,0,0,12.466666666667,22.5
|
||||
,Amiri,"Mohammad Samir",Fest,Ja,Ja,2025-09-01,5.00,40.00,0.00,20,22,190.15,0,0,3,24,25,214.15,21.667,173.333,40.817,0.00033333332999064,40.81666666667,22,0,0,5,17.25,5,12.633333333333,1,10.166666666667,0,0,0,2,12.316666666667,0,40.817,40.817,40.817,0,11,0,0,11,0.00033333332999064,40.81666666667,0.00,20,22,17.25,12.633333333333,10.166666666667,0,0,12.316666666667
|
||||
,"El Moustaiqid",Najlae,Fest,,Ja,2025-09-01,5.00,40.00,0.00,,20,151.7,1,8,0,0,21,159.7,21.667,173.333,-13.633,0,0,,0,0,0,0,0,0,0,0,0,0,0,0,0,-1140.63,-13.633,-13.633,0,-1154.263,-5,1,15,9,0,0,0.00,,0,0,0,0,0,0,0
|
||||
,Jasarevic,Noel,Fest,Nein,Ja,2025-09-15,5.00,40.00,0.00,,14,116.6333,7,56,0,0,21,172.63333333333,21.667,173.333,-0.69966666667,0,0,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-0.69966666667,-0.69966666667,0,-0.69966666667,0,7,6,-1,0,0,0.00,12,0,0,0,0,0,0,0
|
||||
,"Sharh Ghaboos",Peyman,Fest,Ja,Ja,2025-03-01,5.00,40.00,0.00,,24,212.6333,0,0,0,0,24,212.63333333333,21.667,173.333,39.30033333333,0.00033333332999064,39.3,24,0,0,6,2.6,0,0,0,0,1,8.25,21,2,16.683333333333,0,39.30033333333,39.30033333333,39.30033333333,0,20,0,0,20,0.00033333332999064,39.3,0.00,24,24,2.6,0,0,8.25,17.1,16.683333333333
|
||||
227,Feilbach,"Raoul Nikolai ",Fest,Nein,Ja,2025-09-01,5.00,40.00,0.00,20,24,215.8833,0,0,0,0,24,215.88333333333,21.667,173.333,42.55033333333,0.00033333332999064,42.55,,0,0,16,55.5,16,40.75,1,8.7,4,17.483333333333,0,0,0,0.007,42.55033333333,42.55033333333,42.55033333333,0.0069999999999979,-14,0,20,6,0.00033333332999064,42.55,0.00,24,0,55.5,40.75,8.7,17.483333333333,0,0
|
||||
,Hatami,Reza,Fest,Ja,Ja,2025-09-15,5.00,40.00,0.00,20,20,173.9667,0,0,0,0,20,173.96666666667,21.667,173.333,0.63366666667,0.00033333332999064,0.63333333334,20,0,0,0,0,0,0,0,0,0,0,18,2,16.6,0,0.63366666667,0.63366666667,0.63366666666999,9.9920072216264E-15,0,0,6,6,0.00033333332999064,0.63333333334,0.00,20,20,0,0,0,0,13.366666666667,16.6
|
||||
137,Pourhossein,Reza,Fest,Ja,Ja,2025-04-01,5.00,40.00,0.00,20,21,181.55,0,0,0,0,21,181.55,21.667,173.333,8.217,0.00033333332999064,8.21666666667,21,0,0,12,36.533333333333,7,15.016666666667,0,0,2,16.316666666667,7,1,8.0166666666667,0,8.217,8.217,8.217,0,29,0,0,29,0.00033333332999064,8.21666666667,0.00,20,21,36.533333333333,15.016666666667,0,16.316666666667,4.1666666666667,8.0166666666667
|
||||
225,"Hosseini Jahed",Sajad,Fest,Ja,Ja,2025-03-03,5.00,40.00,0.00,20,21,193.3833,2,16,0,0,23,209.38333333333,21.667,173.333,36.05033333333,0.00033333332999064,36.05,21,0,0,0,0,0,0,1,8.4666666666667,1,8.7833333333333,18,0,0,0,36.05033333333,36.05033333333,36.05033333333,0,39,2,-17,20,0.00033333332999064,36.05,0.00,20,21,0,0,8.4666666666667,8.7833333333333,24.3,0
|
||||
,Saki,Sara,Fest,Ja,Ja,2025-02-01,5.00,40.00,0.00,,14,117.6333,10,80,0,0,24,197.63333333333,21.667,173.333,24.30033333333,0.00033333332999064,24.3,14,0,0,11,35.05,0,0,1,8.7,2,16.383333333333,0,0,0,0,24.30033333333,24.30033333333,24.30033333333,0,23,10,-2,11,0.00033333332999064,24.3,0.00,14,14,35.05,0,8.7,16.383333333333,0,0
|
||||
,"Perez Y Waldt",Sebastian,Fest,Nein,Ja,2024-09-23,5.00,40.00,0.00,,22,181.9,0,0,0,0,22,181.9,21.667,173.333,8.567,0.00033333332999064,8.56666666667,,0,0,4,14.1,0,0,0,0,1,8.0166666666667,11,3,24.666666666667,-756.446,8.567,8.567,0,-747.879,14,0,0,14,0,0,0.00,17,0,14.1,0,0,8.0166666666667,6.5166666666667,24.666666666667
|
||||
38,Hosseini,"Seyed Hamid",Fest,Ja,Ja,2025-03-10,5.00,40.00,0.00,20,18,153.4167,0,0,5,40,23,193.41666666667,21.667,173.333,20.08366666667,0.00033333332999064,20.08333333334,18,0,0,0,0,0,0,0,0,2,16.5,15,1,8.0833333333333,0,20.08366666667,20.08366666667,20.08366666667,0,26,0,0,26,0.00033333332999064,20.08333333334,0.00,18,18,0,0,0,16.5,8.8333333333333,8.0833333333333
|
||||
,Jabbari,Shahram,Fest,Nein,Ja,2025-04-01,5.00,40.00,0.00,,20,175.2167,0,0,0,0,20,175.21666666667,21.667,173.333,1.88366666667,0.00033333332999064,1.88333333334,,0,0,0,0,0,0,0,0,0,0,18,2,16.95,0,1.88366666667,1.88366666667,1.88366666667,0,-5,0,0,-5,0.00033333332999064,1.88333333334,0.00,20,0,0,0,0,0,14.266666666667,16.95
|
||||
124,Imanian,Shahriyar,Fest,Ja,Ja,2025-03-10,5.00,40.00,0.00,20,12,104.2833,12,96,0,0,24,200.28333333333,21.667,173.333,26.95033333333,0.00033333332999064,26.95,12,0,0,1,0.083333333333333,0,0,1,8.35,0,0,10,1,8.1666666666667,0,26.95033333333,26.95033333333,26.95033333333,0,36,12,0,24,0.00033333332999064,26.95,0.00,12,12,0.083333333333333,0,8.35,0,7.6833333333333,8.1666666666667
|
||||
164,Tokhi,Shokrollah,Fest,Ja,Ja,2025-03-04,5.00,40.00,0.00,20,18,152.6,5,40,0,0,23,192.6,21.667,173.333,19.267,0.00033333332999064,19.26666666667,18,0,0,14,47.75,9,21.483333333333,0,0,2,9.3,2,1,8.6333333333333,0,19.267,19.267,19.267,0,14,5,0,9,0.00033333332999064,19.26666666667,0.00,18,18,47.75,21.483333333333,0,9.3,0.93333333333333,8.6333333333333
|
||||
210,Rahimzadeh,Siamak,Fest,Ja,Ja,2025-03-01,5.00,40.00,0.00,20,23,197.5,0,0,0,0,23,197.5,21.667,173.333,24.167,0.00033333332999064,24.16666666667,23,0,0,0,0,0,0,0,0,2,16.25,18,3,25.016666666667,0.027,24.167,24.167,24.167,0.027000000000001,39,0,0,39,0.00033333332999064,24.16666666667,0.00,23,23,0,0,0,16.25,12.233333333333,25.016666666667
|
||||
,Florescu,Silviu-Cezar,Fest,Nein,Ja,2025-10-01,5.00,40.00,0.00,,20,173.5333,0,0,0,0,20,173.53333333333,21.667,173.333,0.20033333333001,0.00033333332999064,0.20000000000002,,0,0,2,0.28333333333333,0,0,0,0,0,0,19,1,8.35,0,0.20033333333001,0.20033333333001,0.20033333333001,0,9,0,0,9,0.00033333332999064,0.20000000000002,0.00,20,0,0.28333333333333,0,0,0,12.9,8.35
|
||||
,Vafaei,Soheil,Fest,Ja,Ja,2025-04-01,5.00,40.00,0.00,,18,155.4833,3,24,1,8,22,187.48333333333,21.667,173.333,14.15033333333,0.00033333332999064,14.15,18,0,0,0,0,0,0,0,0,0,0,17,1,8.0166666666667,0,14.15033333333,14.15033333333,14.15033333333,0,-10,3,0,-13,0.00033333332999064,14.15,0.00,18,18,0,0,0,0,11.466666666667,8.0166666666667
|
||||
,Toraman,"Tolga Can",Fest,Nein,Ja,2025-09-15,5.00,40.00,0.00,20,22,183.1333,0,0,0,0,22,183.13333333333,21.667,173.333,9.80033333333,0.00033333332999064,9.8,,0,0,0,0,0,0,1,9.5,0,0,17,2,16.3,0,9.80033333333,9.80033333333,9.80033333333,0,0,0,0,0,0.00033333332999064,9.8,0.00,20,0,0,0,9.5,0,6.3666666666667,16.3
|
||||
14,Haugg,Uwe,Fest,Ja,Ja,2025-01-01,4.00,32.00,0.00,18,6,50.6167,8,64,4,32,18,146.61666666667,17.333,138.667,7.94966666667,7.94966666667,0,6,0,0,0,0,0,0,0,0,0,0,5,1,6.9666666666667,-0.2,7.94966666667,7.94966666667,7.74966666667,0,-10,8,0,-18,7.74966666667,0,0.00,5,6,0,0,0,0,3.65,6.9666666666667
|
||||
231,Shokripour,Vahid,Fest,Ja,Ja,2025-01-01,5.00,40.00,0.00,20,24,208.1167,0,0,0,0,24,208.11666666667,21.667,173.333,34.78366666667,0.00033333332999064,34.78333333334,24,0,0,0,0,0,0,1,9.5,2,16.166666666667,18,3,25.333333333333,0,34.78366666667,34.78366666667,34.78366666667,0,35,0,0,35,0.00033333332999064,34.78333333334,0.00,24,24,0,0,9.5,16.166666666667,13.116666666667,25.333333333333
|
||||
226,Konak,Zidar,Fest,Nein,Ja,2025-05-01,5.00,40.00,0.00,20,22,183.65,0,0,0,0,22,183.65,21.667,173.333,10.317,0.00033333332999064,10.31666666667,,0,0,0,0,0,0,2,18.5,1,7,0,2,16.433333333333,0,10.317,10.317,10.317,0,16,0,0,16,0.00033333332999064,10.31666666667,0.00,15,0,0,0,18.5,7,0,16.433333333333
|
||||
,,,,,,,,,,,1293,11086.0499,101,799,32,256.5,1426,12141.55,1438.687,11344.646,970.23699999999,,,,9,73,175,515.91666666667,67,159.08333333333,20,181.8,66,479.58333333333,841,91,738.55,,970.23699999999,970.23699999999,1267.0006666666,-2939.2536666667,,101,241,709,211.53366666651,1055.4670000001,0,1209,,515.91666666667,159.08333333333,181.8,479.58333333333,607.15,738.55
|
||||
|
|
|
@ -211,7 +211,8 @@ CREATE TABLE public."DyflexisEmployee" (
|
|||
"contractHoursWeek" double precision NOT NULL,
|
||||
"contractSalaryHour" double precision NOT NULL,
|
||||
"contractTypeName" text,
|
||||
"internalId" uuid DEFAULT gen_random_uuid() NOT NULL
|
||||
"internalId" uuid DEFAULT gen_random_uuid() NOT NULL,
|
||||
"contractDaysWeek" integer DEFAULT 0 NOT NULL
|
||||
);
|
||||
|
||||
|
||||
|
|
@ -591,6 +592,23 @@ CREATE TABLE public."Tour" (
|
|||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: TourFile; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public."TourFile" (
|
||||
id uuid DEFAULT gen_random_uuid() NOT NULL,
|
||||
"tourId" text NOT NULL,
|
||||
"ticketId" text NOT NULL,
|
||||
"storagePath" text NOT NULL,
|
||||
"originalFilename" text NOT NULL,
|
||||
"mimeType" text NOT NULL,
|
||||
"fileSizeBytes" integer NOT NULL,
|
||||
"dlUploadStatus" text DEFAULT 'pending'::text NOT NULL,
|
||||
"createdAt" timestamp(3) without time zone DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: TourSource; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
|
@ -1025,6 +1043,14 @@ ALTER TABLE ONLY public."Ticket"
|
|||
ADD CONSTRAINT "Ticket_pkey" PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: TourFile TourFile_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."TourFile"
|
||||
ADD CONSTRAINT "TourFile_pkey" PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: TourSource TourSource_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
|
@ -1104,6 +1130,13 @@ ALTER TABLE ONLY public._prisma_migrations
|
|||
CREATE UNIQUE INDEX "CostType_id_key" ON public."CostType" USING btree (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: TourFile_tourId_ticketId_idx; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX "TourFile_tourId_ticketId_idx" ON public."TourFile" USING btree ("tourId", "ticketId");
|
||||
|
||||
|
||||
--
|
||||
-- Name: Tour_operationId_key; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ SELECT
|
|||
de.surname,
|
||||
de."contractStart",
|
||||
de."contractEnd",
|
||||
de."contractDaysWeek",
|
||||
de."contractHoursWeek",
|
||||
de."contractSalaryHour",
|
||||
de."contractTypeName",
|
||||
|
|
@ -119,6 +120,25 @@ SELECT
|
|||
COUNT(CASE WHEN was_punctual THEN 1 END) AS punctual_days
|
||||
FROM daily_comparison;
|
||||
|
||||
-- name: IsEmployeesDepartmentNotLeitstelle :one
|
||||
SELECT COALESCE(
|
||||
(
|
||||
(
|
||||
bool_or(department LIKE '%KTW%')
|
||||
OR bool_or(department LIKE '%BTW%')
|
||||
OR bool_or(department LIKE '%TSW%')
|
||||
)
|
||||
AND
|
||||
bool_and(department <> 'Leitstelle')
|
||||
),
|
||||
false
|
||||
)::bool as meets_requirements
|
||||
FROM "PlannedTime"
|
||||
WHERE
|
||||
"userId"::int = @employee_id::bigint
|
||||
AND "startDate" BETWEEN @start_date AND @end_date
|
||||
AND department IS NOT NULL;
|
||||
|
||||
-- name: IsEmployeesDepartmentKTW :one
|
||||
SELECT COALESCE(
|
||||
(
|
||||
|
|
@ -152,16 +172,7 @@ WITH ToursInPeriod AS (
|
|||
CASE
|
||||
WHEN "occupiedKm" <= 30 THEN 1.0
|
||||
ELSE ROUND("occupiedKm" / 30.0)
|
||||
END AS tour_value,
|
||||
CASE
|
||||
WHEN EXTRACT(ISODOW FROM "startDate") = 6 AND "occupiedKm" <= 30 THEN 0.5
|
||||
ELSE 0.0
|
||||
END AS weekend_bonus,
|
||||
"infectionName",
|
||||
CASE
|
||||
WHEN "infectionName" = 'Covid-19' THEN 0.5
|
||||
ELSE 0.0
|
||||
END AS infection_bonus
|
||||
END AS tour_value
|
||||
FROM
|
||||
"Tour"
|
||||
WHERE
|
||||
|
|
@ -193,7 +204,7 @@ WITH ToursInPeriod AS (
|
|||
DailyCounts AS (
|
||||
SELECT
|
||||
day,
|
||||
SUM(tour_value) + SUM(weekend_bonus) + SUM(infection_bonus) AS tour_amount
|
||||
SUM(tour_value) AS tour_amount
|
||||
FROM
|
||||
ToursInPeriod
|
||||
GROUP BY
|
||||
|
|
@ -215,3 +226,14 @@ TourenGeld AS (
|
|||
SELECT
|
||||
COALESCE(tourengeld, 0.0)
|
||||
FROM TourenGeld;
|
||||
|
||||
-- name: ListSickdaysForEmployee :many
|
||||
SELECT
|
||||
"start",
|
||||
"end",
|
||||
"days",
|
||||
locked
|
||||
FROM "Sickdays"
|
||||
WHERE
|
||||
"employeeId" = @employee_id
|
||||
ORDER BY start asc;
|
||||
|
|
@ -275,6 +275,7 @@ type DyflexisEmployee struct {
|
|||
ContractSalaryHour float64 `json:"contractSalaryHour"`
|
||||
ContractTypeName pgtype.Text `json:"contractTypeName"`
|
||||
InternalId pgtype.UUID `json:"internalId"`
|
||||
ContractDaysWeek int32 `json:"contractDaysWeek"`
|
||||
}
|
||||
|
||||
type Employee struct {
|
||||
|
|
@ -564,6 +565,18 @@ type Tour struct {
|
|||
Schwerlast bool `json:"schwerlast"`
|
||||
}
|
||||
|
||||
type TourFile struct {
|
||||
ID pgtype.UUID `json:"id"`
|
||||
TourId string `json:"tourId"`
|
||||
TicketId string `json:"ticketId"`
|
||||
StoragePath string `json:"storagePath"`
|
||||
OriginalFilename string `json:"originalFilename"`
|
||||
MimeType string `json:"mimeType"`
|
||||
FileSizeBytes int32 `json:"fileSizeBytes"`
|
||||
DlUploadStatus string `json:"dlUploadStatus"`
|
||||
CreatedAt *time.Time `json:"createdAt"`
|
||||
}
|
||||
|
||||
type TourSource struct {
|
||||
InternalId pgtype.UUID `json:"internalId"`
|
||||
InsertedAt time.Time `json:"insertedAt"`
|
||||
|
|
|
|||
|
|
@ -309,6 +309,39 @@ func (q *Queries) IsEmployeesDepartmentKTW(ctx context.Context, arg IsEmployeesD
|
|||
return meets_requirements, err
|
||||
}
|
||||
|
||||
const isEmployeesDepartmentNotLeitstelle = `-- name: IsEmployeesDepartmentNotLeitstelle :one
|
||||
SELECT COALESCE(
|
||||
(
|
||||
(
|
||||
bool_or(department LIKE '%KTW%')
|
||||
OR bool_or(department LIKE '%BTW%')
|
||||
OR bool_or(department LIKE '%TSW%')
|
||||
)
|
||||
AND
|
||||
bool_and(department <> 'Leitstelle')
|
||||
),
|
||||
false
|
||||
)::bool as meets_requirements
|
||||
FROM "PlannedTime"
|
||||
WHERE
|
||||
"userId"::int = $1::bigint
|
||||
AND "startDate" BETWEEN $2 AND $3
|
||||
AND department IS NOT NULL
|
||||
`
|
||||
|
||||
type IsEmployeesDepartmentNotLeitstelleParams struct {
|
||||
EmployeeID int64 `json:"employee_id"`
|
||||
StartDate *time.Time `json:"start_date"`
|
||||
EndDate *time.Time `json:"end_date"`
|
||||
}
|
||||
|
||||
func (q *Queries) IsEmployeesDepartmentNotLeitstelle(ctx context.Context, arg IsEmployeesDepartmentNotLeitstelleParams) (bool, error) {
|
||||
row := q.db.QueryRow(ctx, isEmployeesDepartmentNotLeitstelle, arg.EmployeeID, arg.StartDate, arg.EndDate)
|
||||
var meets_requirements bool
|
||||
err := row.Scan(&meets_requirements)
|
||||
return meets_requirements, err
|
||||
}
|
||||
|
||||
const listActiveEmployees = `-- name: ListActiveEmployees :many
|
||||
SELECT
|
||||
de.id,
|
||||
|
|
@ -316,6 +349,7 @@ SELECT
|
|||
de.surname,
|
||||
de."contractStart",
|
||||
de."contractEnd",
|
||||
de."contractDaysWeek",
|
||||
de."contractHoursWeek",
|
||||
de."contractSalaryHour",
|
||||
de."contractTypeName",
|
||||
|
|
@ -334,6 +368,7 @@ type ListActiveEmployeesRow struct {
|
|||
Surname string `json:"surname"`
|
||||
ContractStart time.Time `json:"contractStart"`
|
||||
ContractEnd *time.Time `json:"contractEnd"`
|
||||
ContractDaysWeek int32 `json:"contractDaysWeek"`
|
||||
ContractHoursWeek float64 `json:"contractHoursWeek"`
|
||||
ContractSalaryHour float64 `json:"contractSalaryHour"`
|
||||
ContractTypeName pgtype.Text `json:"contractTypeName"`
|
||||
|
|
@ -356,6 +391,7 @@ func (q *Queries) ListActiveEmployees(ctx context.Context) ([]ListActiveEmployee
|
|||
&i.Surname,
|
||||
&i.ContractStart,
|
||||
&i.ContractEnd,
|
||||
&i.ContractDaysWeek,
|
||||
&i.ContractHoursWeek,
|
||||
&i.ContractSalaryHour,
|
||||
&i.ContractTypeName,
|
||||
|
|
@ -371,3 +407,47 @@ func (q *Queries) ListActiveEmployees(ctx context.Context) ([]ListActiveEmployee
|
|||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listSickdaysForEmployee = `-- name: ListSickdaysForEmployee :many
|
||||
SELECT
|
||||
"start",
|
||||
"end",
|
||||
"days",
|
||||
locked
|
||||
FROM "Sickdays"
|
||||
WHERE
|
||||
"employeeId" = $1
|
||||
ORDER BY start asc
|
||||
`
|
||||
|
||||
type ListSickdaysForEmployeeRow struct {
|
||||
Start time.Time `json:"start"`
|
||||
End time.Time `json:"end"`
|
||||
Days int32 `json:"days"`
|
||||
Locked bool `json:"locked"`
|
||||
}
|
||||
|
||||
func (q *Queries) ListSickdaysForEmployee(ctx context.Context, employeeID int32) ([]ListSickdaysForEmployeeRow, error) {
|
||||
rows, err := q.db.Query(ctx, listSickdaysForEmployee, employeeID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []ListSickdaysForEmployeeRow
|
||||
for rows.Next() {
|
||||
var i ListSickdaysForEmployeeRow
|
||||
if err := rows.Scan(
|
||||
&i.Start,
|
||||
&i.End,
|
||||
&i.Days,
|
||||
&i.Locked,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package domain
|
||||
|
||||
import (
|
||||
"business-engine/internal/database"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
|
@ -12,6 +13,7 @@ type PayrollInput struct {
|
|||
HourlyRate float64
|
||||
ContractHours int64
|
||||
DepartmentIsKtw bool
|
||||
DepartmentNotLeitstelle bool
|
||||
|
||||
// Erfasste Zeiten
|
||||
WorkedHours float64
|
||||
|
|
@ -21,6 +23,8 @@ type PayrollInput struct {
|
|||
TotalHours float64
|
||||
OvertimeHours float64
|
||||
|
||||
SickdaysYear []database.ListSickdaysForEmployeeRow
|
||||
|
||||
// Zulagen und Boni
|
||||
ZulageTourengeld float64
|
||||
ZulagePassengerTransport int64
|
||||
|
|
@ -59,12 +63,15 @@ type PayrollStatement struct {
|
|||
Tourengeld float64 `json:"tourengeld" csv:"Tourengeld Anzahl"`
|
||||
TourengeldBonus float64 `json:"tourengeldBonus" csv:"Tourengeld-Bonus (Platz 1-3, EUR)"`
|
||||
GesundheitsbonusAbzug string `json:"gesundheitsbonusAbzug" csv:"Gesundheitsbonus abzuziehen? (ja/nein)"`
|
||||
Gesundheitsbonus float64 `json:"gesundheitsbonus" csv:"Gesundheitsbonus"`
|
||||
Urlaubsgeld float64 `json:"urlaubsgeld" csv:"Urlaubsgeld (44 EUR pro tag)"`
|
||||
PScheinZulage float64 `json:"pScheinZulage" csv:"P-schein Zulage"`
|
||||
Wochenendzuschlag15 float64 `json:"wochenendzuschlag15" csv:"Wochenendzuschlag 15%"`
|
||||
Sonntagszuschlag50 float64 `json:"sonntagszuschlag50" csv:"Sonntagszuschlag 50%"`
|
||||
Feiertagszuschlag125 float64 `json:"feiertagszuschlag125" csv:"Feiertagszuschlag 125%"`
|
||||
Feiertagszuschlag150 float64 `json:"feiertagszuschlag150" csv:"Feiertagszuschlag 150%"`
|
||||
Feiertagszuschlag125 float64 `json:"feiertagszuschlag125" csv:"Feiertagszuschlag 125%,omitempty"`
|
||||
Feiertagszuschlag150 float64 `json:"feiertagszuschlag150" csv:"Feiertagszuschlag 150%,omitempty"`
|
||||
Nachtzuschlag25 float64 `json:"nachtzuschlag25" csv:"Nachtzuschlag 25%"`
|
||||
Nachtzuschlag40 float64 `json:"nachtzuschlag40" csv:"Nachtzuschlag 40%"`
|
||||
|
||||
SickdaysYear []database.ListSickdaysForEmployeeRow `json:"-" csv:"-"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package genpdf
|
||||
|
||||
import (
|
||||
"business-engine/internal/database"
|
||||
domain "business-engine/internal/domain"
|
||||
"fmt"
|
||||
"slices"
|
||||
|
|
@ -77,6 +78,8 @@ func GenerateSalaryStatement(stmt domain.PayrollStatement, filename string, mont
|
|||
|
||||
drawSummary(pdf, gesamtbetrag)
|
||||
|
||||
drawSickdays(pdf, stmt.SickdaysYear)
|
||||
|
||||
if err := pdf.OutputFileAndClose(filename); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -147,12 +150,12 @@ func genLineItemsFromStatement(stmt domain.PayrollStatement) []LineItem {
|
|||
Betrag: 14.0,
|
||||
})
|
||||
}
|
||||
if stmt.GesundheitsbonusAbzug == "" {
|
||||
if stmt.Gesundheitsbonus > 0 {
|
||||
items = append(items, LineItem{
|
||||
Lohnart: "1032",
|
||||
Beschreibung: "Gesundheitsbonus",
|
||||
Anzahl: 1,
|
||||
Betrag: 200.0,
|
||||
Betrag: stmt.Gesundheitsbonus,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -295,6 +298,41 @@ func drawSummary(pdf *fpdf.Fpdf, total float64) {
|
|||
pdf.CellFormat(30, 8, formatCurrency(total), "T", 0, "R", false, 0, "")
|
||||
}
|
||||
|
||||
func drawSickdays(pdf *fpdf.Fpdf, sickdays []database.ListSickdaysForEmployeeRow) {
|
||||
// 1. Abstand und Überschrift
|
||||
pdf.Ln(10)
|
||||
|
||||
pdf.SetFont("DejaVu", "B", 11)
|
||||
// Kein Rahmen, Zeilenumbruch nach der Zelle
|
||||
pdf.CellFormat(0, 10, "Krankmeldungen", "", 1, "L", false, 0, "")
|
||||
|
||||
// 2. Fallback: Wenn keine Krankmeldungen vorhanden sind
|
||||
if len(sickdays) == 0 {
|
||||
pdf.SetFont("DejaVu", "", 10)
|
||||
text := "- Keine Einträge vorhanden"
|
||||
pdf.CellFormat(0, 6, text, "", 1, "L", false, 0, "")
|
||||
pdf.Ln(5)
|
||||
return
|
||||
}
|
||||
|
||||
// 3. Liste zeichne
|
||||
pdf.SetFont("DejaVu", "", 10)
|
||||
|
||||
for _, sick := range sickdays {
|
||||
startStr := sick.Start.Format("02.01.2006")
|
||||
endStr := sick.End.Format("02.01.2006")
|
||||
|
||||
// Formatierung: "- 01.01.2023 bis 05.01.2023: 4 Tage"
|
||||
text := fmt.Sprintf("- %s bis %s: %d Tage", startStr, endStr, sick.Days)
|
||||
|
||||
// Zeichnen der Zeile
|
||||
pdf.CellFormat(0, 6, text, "", 1, "L", false, 0, "")
|
||||
}
|
||||
|
||||
// Kleiner Abstand nach der Liste
|
||||
pdf.Ln(5)
|
||||
}
|
||||
|
||||
func formatFloat(f float64) string {
|
||||
p := message.NewPrinter(language.German)
|
||||
str := p.Sprintf("%.2f", f)
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ func NewEmployeeHandler(service Service, logger *slog.Logger) *EmployeeHandler {
|
|||
}
|
||||
|
||||
func (h *EmployeeHandler) RunPayroll(w http.ResponseWriter, r *http.Request) {
|
||||
month := time.Date(2025, time.November, 1, 0, 0, 0, 0, time.UTC)
|
||||
month := time.Date(2025, time.December, 1, 0, 0, 0, 0, time.UTC)
|
||||
|
||||
employees, err := h.service.FetchActiveEmployees(r.Context())
|
||||
if err != nil {
|
||||
|
|
@ -85,7 +85,7 @@ func (h *EmployeeHandler) RunPayroll(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
if err := json.NewEncoder(w).Encode(data); err != nil {
|
||||
if err := json.NewEncoder(w).Encode(payrollStatements); err != nil {
|
||||
h.logger.Error("failed to encode response", "error", err)
|
||||
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,10 @@ type Repository interface {
|
|||
CountTourengeldAmountInPeriod(ctx context.Context, args database.CountTourengeldAmountInPeriodParams) (float64, error)
|
||||
GetWeeklyTimeSummaryForEmployee(ctx context.Context, args database.GetWeeklyTimeSummaryForEmployeeParams) ([]database.GetWeeklyTimeSummaryForEmployeeRow, error)
|
||||
EvaluatePunctualityForEmployee(ctx context.Context, args database.EvaluatePunctualityForEmployeeParams) (int64, error)
|
||||
IsEmployeesDepartmentNotLeitstelle(ctx context.Context, args database.IsEmployeesDepartmentNotLeitstelleParams) (bool, error)
|
||||
IsEmployeesDepartmentKTW(ctx context.Context, args database.IsEmployeesDepartmentKTWParams) (bool, error)
|
||||
CountVerpflegungspauschale(ctx context.Context, args database.CountVerpflegungspauschaleParams) (int64, error)
|
||||
ListSickdaysForEmployee(ctx context.Context, employeeId int32) ([]database.ListSickdaysForEmployeeRow, error)
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
|
|
@ -55,8 +57,7 @@ func (s *Service) GeneratePayrollStatement(input domain.PayrollInput) domain.Pay
|
|||
GearbeiteteTage: float64(input.WorkedDays),
|
||||
Krankheitstage: float64(input.SickDays),
|
||||
Ueberstunden: input.OvertimeHours,
|
||||
|
||||
Verpflegungspauschale: float64(input.Verpflegungspauschale),
|
||||
SickdaysYear: input.SickdaysYear,
|
||||
|
||||
Wochenendzuschlag15: input.ZuschlagSamstag,
|
||||
Sonntagszuschlag50: input.ZuschlagSonntag,
|
||||
|
|
@ -66,10 +67,27 @@ func (s *Service) GeneratePayrollStatement(input domain.PayrollInput) domain.Pay
|
|||
Feiertagszuschlag150: input.ZuschlagFeiertag150,
|
||||
}
|
||||
|
||||
if input.DepartmentNotLeitstelle {
|
||||
statement.Verpflegungspauschale = float64(input.Verpflegungspauschale)
|
||||
}
|
||||
|
||||
if input.SickDays > 0 || !input.DepartmentIsKtw {
|
||||
statement.GesundheitsbonusAbzug = "ja"
|
||||
}
|
||||
|
||||
if input.SickDays <= 0 && input.DepartmentIsKtw {
|
||||
switch {
|
||||
case statement.Vertragsstunden > 173.0:
|
||||
statement.Gesundheitsbonus = 200.0
|
||||
case statement.Vertragsstunden > 120:
|
||||
statement.Gesundheitsbonus = 150.0
|
||||
case statement.Vertragsstunden > 100:
|
||||
statement.Gesundheitsbonus = 100.0
|
||||
default:
|
||||
statement.Gesundheitsbonus = 0.0
|
||||
}
|
||||
}
|
||||
|
||||
if input.DepartmentIsKtw {
|
||||
statement.Urlaubsgeld = float64(input.HolidayDays)
|
||||
statement.PScheinZulage = float64(input.ZulagePassengerTransport)
|
||||
|
|
@ -107,12 +125,22 @@ func (s *Service) LoadPayrollInput(ctx context.Context, month time.Time, employe
|
|||
return domain.PayrollInput{}, err
|
||||
}
|
||||
|
||||
isNotLeitstelle, err := s.isEmployeesDepartmentNotLeitstelle(ctx, month, int64(employee.ID))
|
||||
if err != nil {
|
||||
s.logger.Error("could not load employee department", "error", err)
|
||||
return domain.PayrollInput{}, err
|
||||
}
|
||||
|
||||
isKtw, err := s.isEmployeesDepartmentKTW(ctx, month, int64(employee.ID))
|
||||
if err != nil {
|
||||
s.logger.Error("could not load employee department", "error", err)
|
||||
return domain.PayrollInput{}, err
|
||||
}
|
||||
s.logger.Debug("fetched department", "isKtw", isKtw)
|
||||
|
||||
sickdays, err := s.loadSickdays(ctx, int64(employee.ID))
|
||||
if err != nil {
|
||||
s.logger.Error("could not load sickdays of employee", "employeeId", employee.ID, "error", err)
|
||||
}
|
||||
|
||||
input := domain.PayrollInput{
|
||||
Firstname: employee.Firstname,
|
||||
|
|
@ -120,6 +148,7 @@ func (s *Service) LoadPayrollInput(ctx context.Context, month time.Time, employe
|
|||
HourlyRate: employee.ContractSalaryHour,
|
||||
ContractHours: int64(employee.ContractHoursWeek),
|
||||
DepartmentIsKtw: isKtw,
|
||||
DepartmentNotLeitstelle: isNotLeitstelle,
|
||||
|
||||
WorkedHours: metrics.WorkedHours,
|
||||
WorkedDays: int64(metrics.WorkedDays),
|
||||
|
|
@ -128,6 +157,8 @@ func (s *Service) LoadPayrollInput(ctx context.Context, month time.Time, employe
|
|||
OvertimeHours: metrics.OvertimeHours,
|
||||
TotalHours: metrics.TotalHours,
|
||||
|
||||
SickdaysYear: sickdays,
|
||||
|
||||
ZulageTourengeld: tourengeld,
|
||||
ZulagePuenktlichkeit: punctuality,
|
||||
Verpflegungspauschale: verpflegungsPauschale,
|
||||
|
|
@ -150,12 +181,15 @@ func (s *Service) LoadPayrollInput(ctx context.Context, month time.Time, employe
|
|||
input.ZuschlagVerpflegung = zuschlagData.Verpflegung14
|
||||
} else {
|
||||
s.logger.Warn("Keine Zuschlag-Daten für Mitarbeiter gefunden", "key", compoundKey)
|
||||
// (Kein Fehler, der Mitarbeiter hatte vielleicht keine Zuschläge)
|
||||
}
|
||||
|
||||
return input, nil
|
||||
}
|
||||
|
||||
func (s *Service) loadSickdays(ctx context.Context, employeeId int64) ([]database.ListSickdaysForEmployeeRow, error) {
|
||||
return s.repo.ListSickdaysForEmployee(ctx, int32(employeeId))
|
||||
}
|
||||
|
||||
func (s *Service) countVerpflegungspauschale(ctx context.Context, month time.Time, employeeId int64) (int64, error) {
|
||||
startOfMonth := beginningOfMonth(month)
|
||||
endOfMonth := endOfMonth(month)
|
||||
|
|
@ -172,6 +206,22 @@ func (s *Service) countVerpflegungspauschale(ctx context.Context, month time.Tim
|
|||
return verpflegungsPauschale, nil
|
||||
}
|
||||
|
||||
func (s *Service) isEmployeesDepartmentNotLeitstelle(ctx context.Context, month time.Time, employeeId int64) (bool, error) {
|
||||
startOfMonth := beginningOfMonth(month)
|
||||
endOfMonth := endOfMonth(month)
|
||||
s.logger.Info("fetching department for employee", "employeeId", employeeId, "startDate", startOfMonth, "endDate", endOfMonth)
|
||||
|
||||
isNotLeitstelle, err := s.repo.IsEmployeesDepartmentNotLeitstelle(ctx, database.IsEmployeesDepartmentNotLeitstelleParams{
|
||||
StartDate: &startOfMonth,
|
||||
EndDate: &endOfMonth,
|
||||
EmployeeID: employeeId,
|
||||
})
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to fetch department for employee %d: %w", employeeId, err)
|
||||
}
|
||||
return isNotLeitstelle, nil
|
||||
}
|
||||
|
||||
func (s *Service) isEmployeesDepartmentKTW(ctx context.Context, month time.Time, employeeId int64) (bool, error) {
|
||||
startOfMonth := beginningOfMonth(month)
|
||||
endOfMonth := endOfMonth(month)
|
||||
|
|
@ -217,7 +267,13 @@ type payrollMetrics struct {
|
|||
func (s *Service) calculatePayrollMetrics(weeklyTimeData []domain.WeeklyTimeData, employee database.ListActiveEmployeesRow) payrollMetrics {
|
||||
var m payrollMetrics
|
||||
|
||||
employeeDailyContractHours := employee.ContractHoursWeek / 5
|
||||
employeeDailyContractHours := 0.0
|
||||
switch {
|
||||
case employee.ContractDaysWeek <= 0:
|
||||
employeeDailyContractHours = employee.ContractHoursWeek / 5
|
||||
default:
|
||||
employeeDailyContractHours = employee.ContractHoursWeek / float64(employee.ContractDaysWeek)
|
||||
}
|
||||
|
||||
for _, week := range weeklyTimeData {
|
||||
m.WorkedHours += week.WorkedHours
|
||||
|
|
@ -261,6 +317,7 @@ func (s *Service) getWeeklyTimeData(ctx context.Context, month time.Time, employ
|
|||
func (s *Service) fetchTourengeld(ctx context.Context, month time.Time, dlEmployeeId string) (float64, error) {
|
||||
startOfMonth := beginningOfMonth(month)
|
||||
endOfMonth := endOfMonth(month)
|
||||
s.logger.Info("fetching tourengeld for employee", "employeeId", dlEmployeeId, "startDate", startOfMonth, "endDate", endOfMonth)
|
||||
|
||||
tourengeld, err := s.repo.CountTourengeldAmountInPeriod(ctx, database.CountTourengeldAmountInPeriodParams{
|
||||
StartDate: startOfMonth,
|
||||
|
|
|
|||
|
|
@ -1,84 +0,0 @@
|
|||
Nachname;Vorname;Verpflegungspauschale;Vertr. Stundenlohn;Arbeitsstunden lt. Vertrag;Gearbeitet Stunden;Gearbeitet Tage;Pünktlichkeitsprämie anzahl;Krankheitstage x 8 Stunden;davon Überstunden;Tourengeld Anzahl;Tourengeld-Bonus (Platz 1-3;Gesundheitsbonus abzuziehen? (ja/nein);Urlaubsgeld (44 EUR pro tag);P-schein Zulage;Wochenendzuschlag 15%;Sonntagszuschlag 50%;Feiertagszuschlag 125%;Feiertagszuschlag 150%;Nachtzuschlag 25%;Nachtzuschlag 40%
|
||||
Malani Karizi;Arasch;24;14.42;173.32;211.98333333333332;24;24;0;38.651333333333305;41.5;500;;0;0;24.7;0;8.25;0;2.6;0
|
||||
Saeedpour;Fouad;23;14.42;173.32;203.28333333333333;23;23;0;29.951333333333316;41;400;;0;23;25.25;26.8;9;0;4.25;0
|
||||
Sharh Ghaboos;Peyman;24;14.42;173.32;212.63333333333333;24;24;0;39.30133333333331;37;300;;0;24;16.683333333333;0;8.25;0;2.6;0
|
||||
Kalantari;Kaveh;18;14.42;173.32;159.05;18;18;0;25.717999999999996;31;0;;5;18;16.916666666667;10.25;9.9;0;4.25;0
|
||||
Ahmadpour;Amirhossein;21;14.42;173.32;193.63333333333333;21;21;0;36.30133333333331;31;0;;2;21;0;8.4666666666667;8.7833333333333;0;0;0
|
||||
Hosseini Jahed;Sajad;20;14.42;173.32;193.38333333333333;21;21;0;44.05133333333331;30;0;;3;21;0;8.4666666666667;8.7833333333333;0;0;0
|
||||
Rasul Khani;Mohammad;24;14.42;173.32;209.48333333333332;24;24;0;36.151333333333305;29.5;0;;0;24;8.0166666666667;17.45;8.25;0;2.25;0
|
||||
Moshtagh Askari;Adel;25;15.58;173.32;218.41666666666666;25;23;0;45.08466666666664;29;0;;0;25;24.95;0;18.65;0;0;0
|
||||
Rasulkhani;Hossein;23;14.42;173.32;194.86666666666667;23;22;0;21.53466666666666;28;0;;0;23;32.366666666667;9.25;9;0;10.433333333333;0
|
||||
Sajaei Khouzestani;Farid;22;14.42;173.32;197.43333333333334;22;22;0;24.101333333333322;26;0;;0;22;16.366666666667;0;17.316666666667;0;0;0
|
||||
Perez Y Waldt;Sebastian;17;14.42;173.32;181.89999999999998;22;15;0;8.567999999999962;25;0;;0;0;24.666666666667;0;8.0166666666667;0;14.1;0
|
||||
Rahimzadeh;Siamak;23;14.42;173.32;197.5;23;23;0;24.167999999999985;25;0;;0;23;25.016666666667;0;16.25;0;0;0
|
||||
Shokripour;Vahid;24;15;173.32;208.11666666666667;24;24;0;34.78466666666666;23.5;0;;0;24;25.333333333333;9.5;16.166666666667;0;0;0
|
||||
Hosseini;Seyed Hamid;18;14.42;173.32;153.41666666666666;18;18;5;20.084666666666642;23;0;ja;0;18;8.0833333333333;0;16.5;0;0;0
|
||||
Safari;Abdul Latif ;20;14.42;173.32;180.41666666666669;20;20;0;47.08466666666667;23;0;;5;20;17.35;0;16.166666666667;0;0;0
|
||||
Pourhossein;Reza;20;14.42;173.32;181.55;21;21;0;8.217999999999996;20.5;0;;0;21;8.0166666666667;0;16.316666666667;0;36.533333333333;15.016666666667
|
||||
Salehi;Iman;26;17.31;173.32;220.1;26;26;0;46.76799999999998;20;0;;0;26;8.0166666666667;18.2;16.383333333333;0;68.766666666667;13.483333333333
|
||||
Rohany Oskoee;Iman;22;16.15;173.32;190.38333333333333;22;10;0;17.05133333333331;20;0;;0;0;8.0333333333333;0;8.7333333333333;0;0;0
|
||||
Sahem;Khalid;24;14.42;173.32;204.35000000000002;24;24;0;31.018000000000008;18.5;0;;0;24;26.033333333333;0;16.833333333333;0;0;0
|
||||
Toraman;Tolga Can;20;14.42;173.32;183.13333333333333;22;19;0;9.80133333333331;18;0;;0;0;16.3;9.5;0;0;0;0
|
||||
Tokhi;Shokrollah;18;14.42;173.32;152.6;18;18;0;19.26799999999998;17;0;;5;18;8.6333333333333;0;9.3;0;47.75;21.483333333333
|
||||
Eggerstedt;Matthias;21;15.58;173.32;190.13333333333333;22;22;0;16.80133333333331;16;0;;0;22;0;0;8.6333333333333;0;0;0
|
||||
Mihailescu;Adrian Lucian;18;16.73;173.32;177.56666666666666;21;4;0;4.234666666666648;14.5;0;;0;21;24.116666666667;0;8.6333333333333;0;0;0
|
||||
Hastedt;David;11;14.93;138.656;112.31666666666666;14;11;4;5.651066666666651;14;0;ja;0;0;0;0;0;0;0;0
|
||||
Faridani Rad;Farzad;21;15;173.32;174.08333333333334;21;21;2;16.751333333333328;13.5;0;ja;0;21;0;0;16.15;0;44.5;5.6666666666667
|
||||
Tajikzadeh;Mohammad;18;16.15;173.32;152.31666666666666;18;18;0;18.984666666666648;13.5;0;;5;18;8.0833333333333;0;8.25;0;0;0
|
||||
Saki;Sara;14;15;173.32;117.63333333333333;14;14;0;32.30133333333331;13;0;;11;14;0;8.7;16.383333333333;0;35.05;0
|
||||
Imanian;Shahriyar;12;14.42;173.32;104.28333333333333;12;12;0;26.951333333333316;12.5;0;;12;12;8.1666666666667;8.35;0;0;0.083333333333333;0
|
||||
Sabahi;Mohammad;18;16.15;173.32;152.58333333333334;18;17;4;19.251333333333328;11;0;ja;1;18;0;0;16.583333333333;0;0;0
|
||||
Florescu;Silviu-Cezar;20;15;173.32;173.53333333333336;20;20;0;0.2013333333333449;10.5;0;;0;0;8.35;0;0;0;0.28333333333333;0
|
||||
Florescu;Silviu-Cezar;20;15;173.32;173.53333333333336;20;20;0;0.2013333333333449;10.5;0;;0;0;8.35;0;0;0;0.28333333333333;0
|
||||
Altner;Christian Van Manh;21;15;173.32;184.08333333333334;22;22;0;10.751333333333328;9;0;;0;22;8.0166666666667;0;7.9333333333333;0;0.2;0
|
||||
Pourhossein;Milad;14;14.42;173.32;125.61666666666665;15;15;0;8.28466666666663;8.5;0;;7;15;16.6;0;7.9333333333333;0;0;0
|
||||
Pouzesh;Esmail;24;16.15;173.32;202.08333333333334;24;24;0;28.751333333333328;7;0;;0;24;0;9.5;17.816666666667;0;70.416666666667;20.6
|
||||
Khodayaran;Hossein;12;16.15;173.32;105.30000000000001;13;13;0;11.967999999999996;7;0;;10;13;0;0;8.1333333333333;0;31;5.6666666666667
|
||||
Juyande;Masoud;22;15;173.32;182.9;22;22;0;9.56799999999999;7;0;;0;0;0;0;8.5166666666667;0;68.1;23.783333333333
|
||||
Maleki;Mohammad;3;14.44;103.992;41.11666666666667;5;1;2;-46.88253333333334;3.5;0;ja;0;5;0;0;0;0;0;0
|
||||
Saffarnajib;Majid;16;15.38;90.99300000000001;133.36666666666665;16;16;0;42.36736666666664;1;0;;0;16;0;0;0;0;0;0
|
||||
Jasarevic;Noel;12;14.42;173.32;116.63333333333333;14;0;0;-0.6986666666666892;0;0;ja;0;0;0;0;0;0;0;0
|
||||
Movafagh;Farzad ;23;12.82;173.32;202.61666666666667;23;0;1;37.28466666666666;0;0;ja;0;0;24.55;0;0;0;0;0
|
||||
Haralambous;Martin;0;12.41;173.32;0;0;0;0;-173.33200000000002;0;0;ja;0;0;0;0;0;0;0;0
|
||||
Hazrati;Kamyar;20;12.82;173.32;182.75;21;0;0;9.417999999999985;0;0;ja;0;0;16.616666666667;0;0;0;0;0
|
||||
Krüger;Julian;19;22.5;173.32;197.35;23;0;0;24.01799999999998;0;0;ja;0;0;15.116666666667;0;14.283333333333;0;0;0
|
||||
Arabnia;Mehdi;21;12.82;173.32;194.38333333333333;22;0;0;21.05133333333331;0;0;ja;0;0;15.783333333333;0;0;0;0;0
|
||||
Taghadosi;Mehdi;21;12.82;173.32;188.93333333333334;22;0;0;15.601333333333322;0;0;ja;0;0;16.6;0;6.3;0;0;0
|
||||
Jalali Wagener;Mehdi;24;12.82;173.32;204.48333333333332;24;0;0;31.151333333333305;0;0;ja;0;0;16.35;0;8.5333333333333;0;0;0
|
||||
Mazidi;Mehrdad;21;12.82;173.32;183.16666666666666;21;0;0;9.834666666666642;0;0;ja;0;0;17.033333333333;0;8.1166666666667;0;0;0
|
||||
Koell;Melanie Nadine;0;15.58;173.32;0;0;0;0;-173.33200000000002;0;0;ja;0;0;0;0;0;0;0;0
|
||||
Esmaeili Miandehi;Milad;0;12.82;173.32;0;0;0;0;-173.33200000000002;0;0;ja;0;0;0;0;0;0;0;0
|
||||
Mohamed Salah;Hussin Noureldin;21;12.82;173.32;186.58333333333334;22;0;0;13.251333333333328;0;0;ja;0;0;24.55;0;8.5166666666667;0;0;0
|
||||
Tokhi;Haroun;0;14.42;173.32;0;0;0;0;-173.33200000000002;0;0;ja;0;0;0;0;0;0;0;0
|
||||
Feilbach;Raoul Nikolai ;24;19.62;173.32;215.88333333333335;24;0;0;42.55133333333334;0;0;ja;0;0;0;8.7;17.483333333333;0;55.5;40.75
|
||||
Hashimazada;Firuz;18;12.82;173.32;155.35;18;0;4;14.01799999999998;0;0;ja;0;0;0;0;8.5333333333333;0;0;0
|
||||
Esser;Detlef;0;12;121.32400000000001;0;0;0;0;-121.3324;0;0;ja;0;0;0;0;0;0;0;0
|
||||
Atrafi;Mohammad Nasir;17;12.82;17.332;162.96666666666667;19;0;0;145.63346666666666;0;0;ja;0;0;22.5;0;0;0;0;0
|
||||
Amiri;Mohammad Samir;20;19.62;173.32;190.14999999999998;22;0;0;16.817999999999962;0;0;ja;0;0;12.316666666667;10.166666666667;0;0;17.25;12.633333333333
|
||||
Babaei Dezghi;Mojtaba;0;15;160.321;0;0;0;0;-162.49875;0;0;ja;0;0;0;0;0;0;0;0
|
||||
Aydin;Muhammet Ali;0;14.51;73.661;0;0;0;0;-73.6661;0;0;ja;0;0;0;0;0;0;0;0
|
||||
El Moustaiqid;Najlae;9;12.82;173.32;151.7;20;0;0;-5.632000000000026;0;0;ja;0;0;0;0;0;0;0;0
|
||||
Heucke;Niklas;0;15;173.32;0;0;0;0;-173.33200000000002;0;0;ja;0;0;0;0;0;0;0;0
|
||||
Saei;Kasra;0;5.65;173.32;37.266666666666666;6;0;0;-56.06533333333335;0;0;ja;0;0;0;0;0;0;0;0
|
||||
Latza;Lelia Eleonore;0;6.35;173.32;0;0;0;0;-173.33200000000002;0;0;ja;0;0;0;0;0;0;0;0
|
||||
Karimloo;Hamidreza;0;12.82;173.32;0;0;0;0;-173.33200000000002;0;0;ja;0;0;0;0;0;0;0;0
|
||||
Hatami;Reza;20;12.82;173.32;173.9666666666667;20;0;0;0.634666666666682;0;0;ja;0;0;16.6;0;0;0;0;0
|
||||
Abdallah;Delshad;0;12.82;173.32;0;0;0;0;-173.33200000000002;0;0;ja;0;0;0;0;0;0;0;0
|
||||
Sidiqi;Sahel;0;14.42;173.32;0;0;0;0;-173.33200000000002;0;0;ja;0;0;0;0;0;0;0;0
|
||||
Golmohammadi;Davood ;20;12.82;173.32;182.2166666666667;20;0;0;8.884666666666682;0;0;ja;0;0;0;0;0;0;0;0
|
||||
Shahrasebi;David;0;0;173.32;0;0;0;0;-173.33200000000002;0;0;ja;0;0;0;0;0;0;0;0
|
||||
Lolies;Danny;17;12.82;173.32;158.9;19;0;4;18.06799999999999;0;0;ja;0;0;17.05;0;5.55;0;0;0
|
||||
Emkani;Daniel;12;22.48;108.325;118.45;14;0;0;10.117499999999993;0;0;ja;0;0;13.3;0;8.6833333333333;0;0;0
|
||||
Askarian Pour;Seyed Hosein;0;15.58;173.32;0;0;0;0;-173.33200000000002;0;0;ja;0;0;0;0;0;0;0;0
|
||||
Jabbari;Shahram;20;12.82;173.32;175.21666666666667;20;0;0;1.8846666666666536;0;0;ja;0;0;16.95;0;0;0;0;0
|
||||
Haghighivand;Danial;19;12.82;173.32;166.03333333333333;19;0;0;8.701333333333316;0;0;ja;0;0;0;0;0;0;0;0
|
||||
Alami;Shoaib;0;12.82;173.32;0;0;0;0;-173.33200000000002;0;0;ja;0;0;0;0;0;0;0;0
|
||||
Mohammadi;Danial;20;12.82;173.32;182.86666666666665;21;0;0;9.53466666666663;0;0;ja;0;0;16.616666666667;0;8.3333333333333;0;0;0
|
||||
Aba;Cuan;0;5.65;173.32;50.25;8;0;0;-75.08200000000002;0;0;ja;0;0;0;0;0;0;0;0
|
||||
Modrau;Cara Marleen;0;14.42;173.32;0;0;0;0;-173.33200000000002;0;0;ja;0;0;0;0;0;0;0;0
|
||||
Rahmati;Behnam;20;12.82;173.32;176.04999999999998;20;0;1;11.217999999999968;0;0;ja;0;0;0;0;0;0;0;0
|
||||
Vafaei;Soheil;18;12.82;173.32;155.48333333333332;18;0;1;14.151333333333305;0;0;ja;0;0;8.0166666666667;0;0;0;0;0
|
||||
Ziaudin;Atiq;21;12.82;173.32;194.31666666666666;23;0;0;20.984666666666648;0;0;ja;0;0;15.05;0;6.4333333333333;0;0;0
|
||||
Haugg;Uwe;5;12.82;138.656;50.616666666666674;6;0;4;-4.848933333333349;0;0;ja;0;0;6.9666666666667;0;0;0;0;0
|
||||
Esmaeili Dashtbayaz;Amin;20;12.82;173.32;171.26666666666665;20;0;0;-2.0653333333333634;0;0;ja;0;0;16.083333333333;0;0;0;0;0
|
||||
Konak;Zidar;15;22.5;173.32;183.65000000000003;22;0;0;10.31800000000002;0;0;ja;0;0;16.433333333333;18.5;7;0;0;0
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
-- AlterTable
|
||||
ALTER TABLE "DyflexisEmployee" ADD COLUMN "contractDaysWeek" INTEGER NOT NULL DEFAULT 0;
|
||||
|
|
@ -553,6 +553,7 @@ model DyflexisEmployee {
|
|||
surname String
|
||||
contractStart DateTime
|
||||
contractEnd DateTime?
|
||||
contractDaysWeek Int @default(0)
|
||||
contractHoursWeek Float
|
||||
contractSalaryHour Float
|
||||
contractTypeName String?
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ export type DyflexisEmployee = {
|
|||
surname: string;
|
||||
contractStart: Timestamp;
|
||||
contractEnd: Timestamp | null;
|
||||
contractDaysWeek: Generated<number>;
|
||||
contractHoursWeek: number;
|
||||
contractSalaryHour: number;
|
||||
contractTypeName: string | null;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { HttpService } from '@nestjs/axios';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { SourceRepository } from './source.repository';
|
||||
import { ConfigService } from 'src/core/config/config.service';
|
||||
import { format, Interval } from 'date-fns';
|
||||
import {
|
||||
catchError,
|
||||
combineLatest,
|
||||
EMPTY,
|
||||
expand,
|
||||
forkJoin,
|
||||
|
|
@ -12,11 +12,15 @@ import {
|
|||
Observable,
|
||||
of,
|
||||
reduce,
|
||||
switchMap,
|
||||
tap,
|
||||
switchMap
|
||||
} from 'rxjs';
|
||||
import { format, Interval } from 'date-fns';
|
||||
import { HolidayRaw, SickDaysRaw } from './source.interface';
|
||||
import { ConfigService } from 'src/core/config/config.service';
|
||||
import {
|
||||
EmployeeContractRaw,
|
||||
HolidayRaw,
|
||||
SickDaysRaw,
|
||||
} from './source.interface';
|
||||
import { SourceRepository } from './source.repository';
|
||||
|
||||
interface DyflexisAuthHeader {
|
||||
Cookie: string;
|
||||
|
|
@ -40,11 +44,72 @@ export class DyflexisUserAccessExtractorsService {
|
|||
) {}
|
||||
|
||||
loadData(): Observable<any> {
|
||||
// return this.extractSicknessDays({
|
||||
return combineLatest([
|
||||
// this.extractWorkdays(),
|
||||
// this.extractSicknessDays({
|
||||
// start: new Date('2025-01-01T00:00:00.000Z'),
|
||||
// end: new Date('2025-12-31T23:59:59.999Z'),
|
||||
// });
|
||||
return this.extractHolidays(new Date('2025-01-01T00:00:00.000Z'));
|
||||
// }),
|
||||
this.extractHolidays(new Date('2025-01-01T00:00:00.000Z')),
|
||||
]);
|
||||
}
|
||||
|
||||
extractWorkdays(): Observable<any> {
|
||||
return this.dyflexisLogin(
|
||||
this.config.dyflexisAppUsername(),
|
||||
this.config.dyflexisAppPassword(),
|
||||
).pipe(
|
||||
switchMap((authHeader) =>
|
||||
forkJoin({
|
||||
authHeader: of(authHeader),
|
||||
employees: this.fetchEmployees(authHeader),
|
||||
}),
|
||||
),
|
||||
switchMap(({ authHeader, employees }) =>
|
||||
forkJoin(
|
||||
employees.map((employee) =>
|
||||
this.fetchWorkdaysForEmployee(authHeader, employee.id),
|
||||
),
|
||||
),
|
||||
),
|
||||
map((workdaysPerEmployee) => workdaysPerEmployee.flat(1)),
|
||||
switchMap((workdays) => from(this.repository.createWorkdays(workdays))),
|
||||
map((res) => {
|
||||
return { count: Number(res.at(0).numUpdatedRows) };
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
private fetchWorkdaysForEmployee(
|
||||
authHeader: DyflexisAuthHeader,
|
||||
employeeId: number,
|
||||
): Observable<{ employeeId: number; daysPerWeek: number }> {
|
||||
const endpoint = (employeeId: number) =>
|
||||
`hamburg/employees/contract/data/${employeeId}`;
|
||||
|
||||
return this.http
|
||||
.get<{
|
||||
contracts: EmployeeContractRaw[];
|
||||
}>(`${this.config.dyflexisAppBaseUrl()}${endpoint(employeeId)}`, {
|
||||
headers: {
|
||||
...authHeader,
|
||||
},
|
||||
})
|
||||
.pipe(
|
||||
map((response) =>
|
||||
response.data.contracts
|
||||
.sort(
|
||||
({ startDate: dateA }, { startDate: dateB }) =>
|
||||
new Date(dateB).getTime() - new Date(dateA).getTime(),
|
||||
)
|
||||
.map(({ daysPerWeek }) => daysPerWeek)
|
||||
.at(0),
|
||||
),
|
||||
map((daysPerWeek) => ({
|
||||
employeeId,
|
||||
daysPerWeek,
|
||||
})),
|
||||
);
|
||||
}
|
||||
|
||||
extractHolidays(year: Date): Observable<any> {
|
||||
|
|
@ -101,6 +166,9 @@ export class DyflexisUserAccessExtractorsService {
|
|||
return { bookDate, isLocked, isExcludedFromPayroll, employeeId };
|
||||
}),
|
||||
),
|
||||
catchError(() => {
|
||||
return [[]];
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -115,7 +183,6 @@ export class DyflexisUserAccessExtractorsService {
|
|||
employees: this.fetchEmployees(authHeader),
|
||||
}),
|
||||
),
|
||||
tap(({ employees }) => console.log(employees.length)),
|
||||
switchMap(({ authHeader, employees }) =>
|
||||
forkJoin(
|
||||
employees.map((employee) =>
|
||||
|
|
|
|||
|
|
@ -184,7 +184,6 @@ export interface FahrzeugItemDto {
|
|||
verordnungsart: string;
|
||||
}
|
||||
|
||||
|
||||
export interface SickDaysRaw {
|
||||
startDate: string;
|
||||
endDate: string;
|
||||
|
|
@ -199,3 +198,24 @@ export interface HolidayRaw {
|
|||
isLocked: boolean;
|
||||
isExcludedFromPayroll: boolean;
|
||||
}
|
||||
|
||||
export interface EmployeeContractRaw {
|
||||
id: number;
|
||||
officeId: number;
|
||||
employeeId: number;
|
||||
typeId: number;
|
||||
serial: string;
|
||||
daysPerWeek: number;
|
||||
hoursPerWeek: number;
|
||||
upperLimit: any;
|
||||
startDate: string;
|
||||
endDate: any;
|
||||
salaryAmount: number;
|
||||
salaryPeriod: number;
|
||||
salaryType: number;
|
||||
hourlySalary: number;
|
||||
active: boolean;
|
||||
workingPattern: any;
|
||||
isSyncedWithPayroll: boolean;
|
||||
lastLockDate: string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import {
|
|||
TourRaw,
|
||||
WorkTimeRaw,
|
||||
} from './source.interface';
|
||||
import { Kysely } from 'kysely';
|
||||
import { Kysely, sql } from 'kysely';
|
||||
import { KYSELY_CLIENT_PROVIDER_TOKEN } from 'src/core/database/database.module';
|
||||
import { DB } from 'src/core/database/types';
|
||||
|
||||
|
|
@ -112,6 +112,23 @@ export class SourceRepository {
|
|||
});
|
||||
}
|
||||
|
||||
createWorkdays(workdays: { employeeId: number; daysPerWeek: number }[]) {
|
||||
const values = workdays.map(
|
||||
({ employeeId, daysPerWeek }) =>
|
||||
sql`(${employeeId}::int4, ${daysPerWeek}::int4)`,
|
||||
);
|
||||
|
||||
return this.db
|
||||
.with('v(id, days)', () => sql`(VALUES ${sql.join(values)})`)
|
||||
.updateTable('DyflexisEmployee as e')
|
||||
.set({
|
||||
contractDaysWeek: sql.ref('v.days'),
|
||||
})
|
||||
.from('v')
|
||||
.whereRef('e.id', '=', 'v.id')
|
||||
.execute();
|
||||
}
|
||||
|
||||
createPatients(
|
||||
patients: PatientRaw[],
|
||||
jobId: string,
|
||||
|
|
|
|||
Loading…
Reference in New Issue