dev/finalFixes #81
@@ -45,3 +45,218 @@ var testBookings10hrs = []models.Booking{{
|
||||
Timestamp: time.Date(2025, 01, 01, 18, 0, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
}}
|
||||
|
||||
var testBookings6hrsBreak30min = []models.Booking{
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 1,
|
||||
Timestamp: time.Date(2025, 01, 01, 8, 0, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 2,
|
||||
Timestamp: time.Date(2025, 01, 01, 9, 0, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 1,
|
||||
Timestamp: time.Date(2025, 01, 01, 9, 30, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 2,
|
||||
Timestamp: time.Date(2025, 01, 01, 14, 30, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
}}
|
||||
|
||||
var testBookings610hrsBreak30min = []models.Booking{
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 1,
|
||||
Timestamp: time.Date(2025, 01, 01, 8, 0, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 2,
|
||||
Timestamp: time.Date(2025, 01, 01, 9, 0, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 1,
|
||||
Timestamp: time.Date(2025, 01, 01, 9, 30, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 2,
|
||||
Timestamp: time.Date(2025, 01, 01, 14, 40, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
}}
|
||||
|
||||
var testBookings9hrsBreak30min = []models.Booking{
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 1,
|
||||
Timestamp: time.Date(2025, 01, 01, 8, 0, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 2,
|
||||
Timestamp: time.Date(2025, 01, 01, 9, 0, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 1,
|
||||
Timestamp: time.Date(2025, 01, 01, 9, 30, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 2,
|
||||
Timestamp: time.Date(2025, 01, 01, 17, 30, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
}}
|
||||
|
||||
var testBookings930hrs = []models.Booking{
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 1,
|
||||
Timestamp: time.Date(2025, 01, 01, 8, 0, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 2,
|
||||
Timestamp: time.Date(2025, 01, 01, 17, 30, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
}}
|
||||
|
||||
var testBookings910hrsBreak30min = []models.Booking{
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 1,
|
||||
Timestamp: time.Date(2025, 01, 01, 8, 0, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 2,
|
||||
Timestamp: time.Date(2025, 01, 01, 9, 0, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 1,
|
||||
Timestamp: time.Date(2025, 01, 01, 9, 30, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 2,
|
||||
Timestamp: time.Date(2025, 01, 01, 17, 40, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
}
|
||||
|
||||
var testBookings910hrsBreak35min = []models.Booking{
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 1,
|
||||
Timestamp: time.Date(2025, 01, 01, 8, 0, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 2,
|
||||
Timestamp: time.Date(2025, 01, 01, 9, 0, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 1,
|
||||
Timestamp: time.Date(2025, 01, 01, 9, 35, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 2,
|
||||
Timestamp: time.Date(2025, 01, 01, 17, 45, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
}
|
||||
|
||||
var testBookings945hrs = []models.Booking{
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 1,
|
||||
Timestamp: time.Date(2025, 01, 01, 8, 0, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 2,
|
||||
Timestamp: time.Date(2025, 01, 01, 17, 45, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
}
|
||||
|
||||
var testBookings10hrsBreak45min = []models.Booking{
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 1,
|
||||
Timestamp: time.Date(2025, 01, 01, 8, 0, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 2,
|
||||
Timestamp: time.Date(2025, 01, 01, 9, 0, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 1,
|
||||
Timestamp: time.Date(2025, 01, 01, 9, 45, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 2,
|
||||
Timestamp: time.Date(2025, 01, 01, 18, 00, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
}
|
||||
|
||||
var testBookings1030hrsBreak45min = []models.Booking{
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 1,
|
||||
Timestamp: time.Date(2025, 01, 01, 8, 0, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 2,
|
||||
Timestamp: time.Date(2025, 01, 01, 9, 0, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 1,
|
||||
Timestamp: time.Date(2025, 01, 01, 9, 45, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
{
|
||||
CardUID: "aaaa-aaaa",
|
||||
CheckInOut: 2,
|
||||
Timestamp: time.Date(2025, 01, 01, 18, 30, 0, 0, time.UTC),
|
||||
BookingType: testBookingType,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -116,7 +116,8 @@ func correctWorkPause(workIn, pauseIn time.Duration) (work, pause time.Duration)
|
||||
}
|
||||
|
||||
var diff time.Duration
|
||||
if workIn <= (9*time.Hour) && pauseIn < 30*time.Minute {
|
||||
|
||||
if (workIn+pauseIn) <= (9*time.Hour+30*time.Minute) && pauseIn <= 30*time.Minute {
|
||||
diff = 30*time.Minute - pauseIn
|
||||
} else if pauseIn < 45*time.Minute {
|
||||
diff = 45*time.Minute - pauseIn
|
||||
|
||||
@@ -30,18 +30,63 @@ func TestWorkdayWorktimeDay(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
testName: "Bookings6hrs",
|
||||
bookings: testBookings6hrs,
|
||||
expectedTime: time.Hour * 6,
|
||||
bookings: testBookings6hrs, //work 6h
|
||||
expectedTime: time.Hour * 6, //pause 0
|
||||
},
|
||||
{
|
||||
testName: "Bookings8hrs",
|
||||
bookings: testBookings8hrs,
|
||||
expectedTime: time.Hour*7 + time.Minute*30,
|
||||
bookings: testBookings8hrs, //work 8 pause 0
|
||||
expectedTime: time.Hour*7 + time.Minute*30, //pause 30 --> corrected
|
||||
},
|
||||
{
|
||||
testName: "Bookings10hrs",
|
||||
bookings: testBookings10hrs,
|
||||
expectedTime: time.Hour*9 + time.Minute*15,
|
||||
bookings: testBookings10hrs, //work 10 pause 0
|
||||
expectedTime: time.Hour*9 + time.Minute*15, //pause 45 --> corrected
|
||||
},
|
||||
{
|
||||
testName: "Booking 6h with 30 min Break",
|
||||
bookings: testBookings6hrsBreak30min, //work 6 pause 30
|
||||
expectedTime: time.Hour * 6, //pause 30 --> bc real pause
|
||||
},
|
||||
{
|
||||
testName: "Booking 6h 10min with 30 min Break",
|
||||
bookings: testBookings610hrsBreak30min, //work 6 10 pause 30
|
||||
expectedTime: time.Hour*6 + time.Minute*10, //pause 30 --> real pause
|
||||
},
|
||||
{
|
||||
testName: "Booking 9h with 30 min Break",
|
||||
bookings: testBookings9hrsBreak30min, //work 9 pause 30
|
||||
expectedTime: time.Hour * 9, //pause 30 --> real pause
|
||||
},
|
||||
{
|
||||
testName: "Booking 9h 30min",
|
||||
bookings: testBookings930hrs, //work 9 30 pause 0
|
||||
expectedTime: time.Hour * 9, //pause 30 --> corrected
|
||||
},
|
||||
{
|
||||
testName: "Booking 9h 40min with 30min Break",
|
||||
bookings: testBookings910hrsBreak30min, //work 9 10 pause 30
|
||||
expectedTime: time.Hour*8 + time.Minute*55, //pause 45 --> real + corrected
|
||||
},
|
||||
{
|
||||
testName: "Booking 9h 40min with 35min Break",
|
||||
bookings: testBookings910hrsBreak35min, //work 9 10 pause 35
|
||||
expectedTime: time.Hour * 9, //pause 45 --> real + corrected
|
||||
},
|
||||
{
|
||||
testName: "Booking 9h 45min",
|
||||
bookings: testBookings945hrs, //work 9 45 pause 0
|
||||
expectedTime: time.Hour * 9, //pause 45 --> corrected
|
||||
},
|
||||
{
|
||||
testName: "Booking 10h Break 45min",
|
||||
bookings: testBookings10hrsBreak45min, //work 9 15 pause 45
|
||||
expectedTime: time.Hour*9 + time.Minute*15, //pause 45 --> real
|
||||
},
|
||||
{
|
||||
testName: "Booking 10h 30min Break 45min",
|
||||
bookings: testBookings1030hrsBreak45min, //work 9 45 pause 45
|
||||
expectedTime: time.Hour*9 + time.Minute*45, //pause 45 --> real
|
||||
},
|
||||
}
|
||||
|
||||
@@ -113,6 +158,51 @@ func TestWorkdayPausetimeDay(t *testing.T) {
|
||||
bookings: testBookings10hrs,
|
||||
expectedTime: time.Minute * 45,
|
||||
},
|
||||
{
|
||||
testName: "Booking 6h with 30 min Break",
|
||||
bookings: testBookings6hrsBreak30min, //work 6 pause 30
|
||||
expectedTime: time.Minute * 30, //pause 30 --> bc real pause
|
||||
},
|
||||
{
|
||||
testName: "Booking 6h 10min with 30 min Break",
|
||||
bookings: testBookings610hrsBreak30min, //work 6 10 pause 30
|
||||
expectedTime: time.Minute * 30, //pause 30 --> real pause
|
||||
},
|
||||
{
|
||||
testName: "Booking 9h with 30 min Break",
|
||||
bookings: testBookings9hrsBreak30min, //work 9 pause 30
|
||||
expectedTime: time.Minute * 30, //pause 30 --> real pause
|
||||
},
|
||||
{
|
||||
testName: "Booking 9h 30min",
|
||||
bookings: testBookings930hrs, //work 9 30 pause 0
|
||||
expectedTime: time.Minute * 30, //pause 30 --> corrected
|
||||
},
|
||||
{
|
||||
testName: "Booking 9h 40min with 30min Break",
|
||||
bookings: testBookings910hrsBreak30min, //work 9 10 pause 30
|
||||
expectedTime: time.Minute * 45, //pause 45 --> real + corrected
|
||||
},
|
||||
{
|
||||
testName: "Booking 9h 40min with 35min Break",
|
||||
bookings: testBookings910hrsBreak35min, //work 9 10 pause 35
|
||||
expectedTime: time.Minute * 45, //pause 45 --> real + corrected
|
||||
},
|
||||
{
|
||||
testName: "Booking 9h 45min",
|
||||
bookings: testBookings945hrs, //work 9 45 pause 0
|
||||
expectedTime: time.Minute * 45, //pause 45 --> corrected
|
||||
},
|
||||
{
|
||||
testName: "Booking 10h Break 45min",
|
||||
bookings: testBookings10hrsBreak45min, //work 9 15 pause 45
|
||||
expectedTime: time.Minute * 45, //pause 45 --> real
|
||||
},
|
||||
{
|
||||
testName: "Booking 10h 30min Break 45min",
|
||||
bookings: testBookings1030hrsBreak45min, //work 9 45 pause 45
|
||||
expectedTime: time.Minute * 45, //pause 45 --> real
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
|
||||
91
Readme.md
91
Readme.md
@@ -50,9 +50,100 @@ cd arbeitszeitmessung
|
||||
- `BACKUP_FOLDER` Pfad für DB Backup Datein
|
||||
- `LOG_PATH` Pfad für Audit Logs
|
||||
|
||||
## Administration:
|
||||
|
||||
### Nutzer erstellen:
|
||||
|
||||
Nutzerdaten erstellen:
|
||||
|
||||
```sql
|
||||
INSERT INTO "s_personal_daten"
|
||||
(
|
||||
"personal_nummer",
|
||||
"vorname",
|
||||
"nachname",
|
||||
"card_uid",
|
||||
"geburtsdatum",
|
||||
"geschlecht",
|
||||
"adresse",
|
||||
"plz",
|
||||
"hauptbeschaeftigungs_ort",
|
||||
"aktiv_beschaeftigt",
|
||||
"vorgesetzter_pers_nr",
|
||||
"arbeitszeit_min_start",
|
||||
"arbeitszeit_max_ende",
|
||||
"arbeitszeit_per_tag",
|
||||
"arbeitszeit_per_woche",
|
||||
)
|
||||
VALUES (
|
||||
1,
|
||||
'Max',
|
||||
'Mustermann',
|
||||
'acde-edca',
|
||||
'2003-02-01',
|
||||
1,
|
||||
'Musterstr. 42',
|
||||
'00001',
|
||||
1,
|
||||
true,
|
||||
123,
|
||||
'07:00:00',
|
||||
'20:00:00',
|
||||
8,
|
||||
40
|
||||
);
|
||||
```
|
||||
|
||||
Nutzerpasswort generieren (kann auch später als Passwort reset genutzt werden):
|
||||
|
||||
```sql
|
||||
INSERT INTO "user_password"
|
||||
("personal_nummer", "pass_hash")
|
||||
VALUES (123, crypt('password', gen_salt('bf')));
|
||||
```
|
||||
|
||||
### Buchungstypen erstellen:
|
||||
|
||||
Ohne definierte Anwesenheits und Abwesenheitstypen funktioniert die Anwendung nicht!
|
||||
|
||||
Anwesenheiten:
|
||||
|
||||
```sql
|
||||
INSERT INTO "s_anwesenheit_typen"
|
||||
("anwesenheit_id", "anwesenheit_name")
|
||||
VALUES (1, 'Büro');
|
||||
```
|
||||
|
||||
Abwesenheiten:
|
||||
|
||||
```sql
|
||||
INSERT INTO "s_abwesenheit_typen"
|
||||
("abwesenheit_id", "abwesenheit_name", "arbeitszeit_equivalent")
|
||||
VALUES (1, 'Urlaub', 100);
|
||||
```
|
||||
|
||||
### Feiertage erstellen:
|
||||
|
||||
Die gesetzlichen Feiertage für Deutschland/Sachsen werden automatisch mit der Route `auto/feiertage` für das aktuelle Kalenderjahr erzeugt. Um weitere Unternehmensspezifische Feiertage (z.B. 24.12. oder 31.12.) mit in die Liste der Feiertage aufzunehmen, müssen diese manuell erstellt werden.
|
||||
|
||||
```sql
|
||||
INSERT INTO "s_feiertage"
|
||||
("datum", "name", "arbeitszeit_equivalent", "wiederholen")
|
||||
VALUES ('2026-12-24', 'Helligabend', 50, 1);
|
||||
```
|
||||
|
||||
Wenn `wiederholen` == 1 wird der Feiertag automatisch beim Aufruf von `auto/feiertage` mit ins nächste Jahr (am selben Datum) übernommen.
|
||||
|
||||
Das Feld `arbeitszeit_equivalent` `arbeitszeit_equivalent` ist die prozentuelle Zeit am Tag welche durch diesen Eintrag eingenommen wird. (dies gilt auch für die [Buchungstypen](#buchungstypen-erstellen))
|
||||
|
||||
Alle weiteren Tabellen sollte ausschließlich über die Weboberfläche oder per API befüllt werden.
|
||||
|
||||
---
|
||||
|
||||
# Filestrukture
|
||||
|
||||
```
|
||||
|
||||
├── Backend (Webserver)
|
||||
│ ├── doc (Templates for Document Creator --> typst used to create PDF Reports)
|
||||
│ │ ├── static
|
||||
|
||||
Reference in New Issue
Block a user