diff --git a/Backend/template.typ b/Backend/template.typ deleted file mode 100644 index ade04ab..0000000 --- a/Backend/template.typ +++ /dev/null @@ -1,92 +0,0 @@ -#let table-header(..headers) = { - table.header( - ..headers.pos().map(h => strong(h)) - ) -} - - -#let abrechnung(meta, days) = { - set page(paper: "a4", margin: (x:1.5cm, y:2.25cm), - footer:[#grid( - columns: (3fr, .65fr), - align: left + horizon, - inset: .5em, - [#meta.EmployeeName -- #meta.TimeRange], grid.cell(rowspan: 2)[#image("static/logo.png")], - [Arbeitszeitrechnung maschinell erstellt am #meta.CurrentTimestamp], - ) - ]) - set text(font: "Noto Sans", size:10pt, fill: luma(10%)) - set table( - stroke: 0.5pt + luma(10%), - inset: .5em, - align: center + horizon, - ) - show text: it => { - if it.text == "0min"{ - text(oklch(70.8%, 0, 0deg))[#it] - }else if it.text.starts-with("-"){ - text(red)[#it] - }else{ - it - } - } - - - [= Abrechnung Arbeitszeit -- #meta.EmployeeName] - - [Zeitraum: #meta.TimeRange] - - table( - columns: (1fr, 1fr, 1fr, 1fr, 1fr, 1fr, 1.25fr), - fill: (x, y) => - if y == 0 { oklch(87%, 0, 0deg) }, - table-header( - [Datum], [Kommen], [Gehen], [Arbeitsart], [Stunden], [Pause], [Überstunden] - ), - .. for day in days { - ( - [#day.Date], - if day.DayParts.len() == 0{ - table.cell(colspan: 3)[Keine Buchungen] - }else if not day.DayParts.first().IsWorkDay{ - table.cell(colspan: 3)[#day.DayParts.first().WorkType] - } - else { - - table.cell(colspan: 3, inset: 0em)[ - - #table( - columns: (1fr, 1fr, 1fr), - .. for Zeit in day.DayParts { - ( - [#Zeit.BookingFrom], - [#Zeit.BookingTo], - [#Zeit.WorkType], - ) - }, - ) - ] - }, - [#day.Worktime], - [#day.Pausetime], - [#day.Overtime], - ) - if day.IsFriday { - ( table.cell(colspan: 7, fill: oklch(87%, 0, 0deg))[Wochenende], ) // note the trailing comma - } - } - ) - - table( - columns: (3fr, 1fr), - align: right, - inset: (x: .25em, y:.75em), - stroke: none, - table.hline(start: 0, end: 2, stroke: stroke(dash:"dashed", thickness:.5pt)), - [Arbeitszeit :], table.cell(align: left)[#meta.WorkTime], - [Überstunden :], table.cell(align: left)[#meta.Overtime], - [Überstunden :],table.cell(align: left)[#meta.OvertimeTotal], - table.hline(start: 0, end: 2), - -) -} diff --git a/Readme.md b/Readme.md index c058ab8..eb15764 100644 --- a/Readme.md +++ b/Readme.md @@ -2,124 +2,53 @@ [![Quality Gate Status](https://sonar.letsstein.de/api/project_badges/measure?project=arbeitszeitmessung&metric=alert_status&token=sqb_253028eff30aff24f32b437cd6c484c511b5c33f)](https://sonar.letsstein.de/dashboard?id=arbeitszeitmessung) -bis jetzt ein einfaches Backend mit PostgreSQL Datenbank und GO Webserver um Arbeitszeitbuchungen per HTTP PUT einzufügen +--- + +Eine open-source Software zur Arbeitszeitmessung + +## Features + +- manuelle Korrektur von einzelnen Buchungen +- Buchung von benutzerdefinierten Abwesenheiten +- automatische gesetzlicher Feiertage +- Pflege eigener Feiertage + +- wöchentliches Abrechnungssystem +- Kontrolle der Arbeitszeiten durch direkte Führungskraft + +- Ausgabe der Arbeitszeiten je Monat in PDF Format + +- Anwesenheitsübersicht ## Installation ```bash git clone https://git.letsstein.de/tom/arbeitszeitmessung arbeitszeitmessung -cd arbeitszeitmessung/Docker -# .env Datei anpassen -docker compose up -d +cd arbeitszeitmessung + +./install.sh ``` -## PREVIEW +### Konfiguration: -Zeitverwaltungsansicht (/time): - -![time](docs/images/time.png) - -Ansicht der Führungskraft (/team): - -![team](docs/images/team.png) - -Nutzeransicht (/user): - -![user](docs/images/user.png) - -## Buchungstypen - -1 - Kommen -2 - Gehen -3 - Kommen Manuell -4 - Gehen Manuell -254 - Automatisch abgemeldet - -## API - -Nutzung der API -wenn die `dev-docker-compose.yml` Datei gestartet wird, ist direkt ein SwaggerUI Server mit entsprechender Datei inbegriffen. - -### Buchungen [/time] - -#### [GET] Anfrage - -Parameter: cardID (string) -Antwort: `200` - -```json -[ - { - "cradID": "test_card", - "readerID": "test_reader", - "bookingTyp": 2, - "loggedTime": "2024-09-05T08:37:53.117641Z", - "id": 5 - }, - { - "cradID": "test_card", - "readerID": "mytest", - "bookingTyp": 1, - "loggedTime": "2024-09-05T08:51:12.670827Z", - "id": 6 - } -] -``` - -Antwort `500` -Serverfehler - -#### [PUT] Anfrage - -Parameter: id (int) -Body: (veränderte Parameter) - -```json -{ - "cradID": "test_card", - "readerID": "mytest", - "bookingTyp": 1, - "loggedTime": "2024-09-05T08:51:12.670827Z" -} -``` - -Antwort `200` - -```json -{ - "cradID": "test_card", - "readerID": "mytest", - "bookingTyp": 1, - "loggedTime": "2024-09-05T08:51:12.670827Z", - "id": 6 -} -``` - -### Neue Buchung [/time/new] - -#### [PUT] Anfrage - -Parameter: - -- cardID (string) -- readerID (string) -- bookingType (string) - -Antwort `202` Akzeptiert und eingefügt - -```json -{ - "cradID": "test_card", - "readerID": "mytest", - "bookingTyp": 1, - "loggedTime": "2024-09-05T08:51:12.670827Z", - "id": 6 -} -``` - -Antwort `409` Konflikt -Die vorherige Buchung am selben Tag hat den gleichen Buchungstyp +- Datenbank + - `POSTGRES_USER` Postgres ADMIN Nutzername + - `POSTGRES_PASSWORD` Postgres ADMIN Passwort + - `POSTGRES_API_USER` Postgres API Nutzername für Webanwendung + - `POSTGRES_API_PASS` Postgres API Passwort für Webanwendung + - `POSTGRES_PATH` Datebank Pfad + - `POSTGRES_DB` Postgres Datenbank Name + - `POSTGRES_PORT` Postgres Port für administration +- System + - `TZ` Zeitzone + - `LOG_LEVEL` Welche Log-Nachrichten werden in der Konsole erscheinen +- Web/API + - `API_TOKEN` API Token für ESP Endpoints + - `WEB_PORT` Port unter welchem Webserver erreichbar ist +- Ordnerstruktur + - `BACKUP_FOLDER` Pfad für DB Backup Datein + - `LOG_PATH` Pfad für Audit Logs # Filestrukture