Work Time
Work Time Organization (WTO) declarations inform ERGANI about employee work schedules, including work hours, breaks, leave, and days off. The system supports both daily declarations (for specific dates) and weekly schedules (recurring patterns).
Overview
The Work Time system uses a hierarchical structure:
- WorkTime: Container for a branch's work time declaration
- WorkTimeEmployee: Individual employee's schedule for a date or day of week
- WorkTimeEntry: Specific time entries (work periods, breaks, leave, etc.)
Document Types
| Class | Action Code | Description |
|---|---|---|
DailyWorkTime | WTODaily | Daily work time declaration |
WeeklyWorkTime | WTOWeek | Weekly recurring schedule |
DailyWorkTimeRetrospective | WTODailyA | Retrospective daily declaration |
DailyWorkTimeDrivers | WTODailyD | Daily declaration for drivers |
WorkTimeLeave | WTOLeave | Leave declaration |
WorkTimeLeaveCorrection | WTOLeaveC | Leave correction |
Basic Usage
Daily Work Time
use OxygenSuite\OxygenErgani\Http\Documents\WorkTime\DailyWorkTime;
use OxygenSuite\OxygenErgani\Models\WorkTime\WorkTime;
use OxygenSuite\OxygenErgani\Models\WorkTime\WorkTimeEmployee;
use OxygenSuite\OxygenErgani\Models\WorkTime\WorkTimeEntry;
use OxygenSuite\OxygenErgani\Enums\WorkTimeType;
$workTime = WorkTime::make()
->setBranchCode(0)
->addEmployee(
WorkTimeEmployee::make()
->setTin('123456789')
->setLastName('ΠΑΠΑΔΟΠΟΥΛΟΣ')
->setFirstName('ΙΩΑΝΝΗΣ')
->setDate('15/01/2025')
->addAnalytics(
WorkTimeEntry::make()
->setType(WorkTimeType::WORK)
->setFromTime('09:00')
->setToTime('17:00')
)
);
$response = (new DailyWorkTime())->handle($workTime);Weekly Work Time
use OxygenSuite\OxygenErgani\Http\Documents\WorkTime\WeeklyWorkTime;
use OxygenSuite\OxygenErgani\Models\WorkTime\WorkTime;
use OxygenSuite\OxygenErgani\Models\WorkTime\WorkTimeEmployee;
use OxygenSuite\OxygenErgani\Models\WorkTime\WorkTimeEntry;
use OxygenSuite\OxygenErgani\Enums\WorkTimeType;
use OxygenSuite\OxygenErgani\Enums\DayOfWeek;
$workTime = WorkTime::make()
->setBranchCode(0)
->setFromDate('20/01/2025')
->setToDate('26/01/2025')
->addEmployee(
WorkTimeEmployee::make()
->setTin('123456789')
->setLastName('ΠΑΠΑΔΟΠΟΥΛΟΣ')
->setFirstName('ΙΩΑΝΝΗΣ')
->setDay(DayOfWeek::MONDAY)
->addAnalytics(
WorkTimeEntry::make()
->setType(WorkTimeType::WORK)
->setFromTime('09:00')
->setToTime('17:00')
)
);
$response = (new WeeklyWorkTime())->handle($workTime);WorkTime Model
The WorkTime model is the container for work time declarations.
Fields Reference
| Method | API Field | Type | Required | Description |
|---|---|---|---|---|
setBranchCode() | f_aa_pararthmatos | int|string | Yes | Branch serial number. Use 0 for main establishment |
setRelatedProtocol() | f_rel_protocol | string | No | Protocol number of related submission (for corrections) |
setRelatedDate() | f_rel_date | string | No | Date of related submission (DD/MM/YYYY) |
setComments() | f_comments | string | No | Optional comments |
setFromDate() | f_from_date | string | Weekly | Start date of period (DD/MM/YYYY) - required for weekly |
setToDate() | f_to_date | string | Weekly | End date of period (DD/MM/YYYY) - required for weekly |
addEmployee() | Ergazomenoi | array | Yes | Employee entries |
Example
use OxygenSuite\OxygenErgani\Models\WorkTime\WorkTime;
$workTime = WorkTime::make()
->setBranchCode(0)
->setComments('Weekly schedule for January')
->setFromDate('20/01/2025')
->setToDate('26/01/2025');WorkTimeEmployee Model
Each WorkTimeEmployee represents one employee's schedule.
DateTime Support
All date fields accept both DateTime objects and strings. When a DateTime is passed, it's automatically formatted to DD/MM/YYYY:
$employee->setDate('15/01/2025'); // String
$employee->setDate(new DateTime('2025-01-15')); // DateTimeFields Reference
| Method | API Field | Type | Required | Description |
|---|---|---|---|---|
setTin() | f_afm | string | Yes | Employee's Tax Identification Number (AFM), 9 digits |
setLastName() | f_eponymo | string | Yes | Employee's last name |
setFirstName() | f_onoma | string | Yes | Employee's first name |
setDate() | f_date | string | Daily | Specific date (DD/MM/YYYY) - for daily declarations |
setDay() | f_day | DayOfWeek|string | Weekly | Day of week (1-7) - for weekly declarations |
addAnalytics() | ErgazomenosAnalytics | array | Yes | Time entries for this employee |
Field Details
f_date vs f_day
- Daily declarations use
f_datewith a specific date in DD/MM/YYYY format - Weekly declarations use
f_daywith a day number (1=Monday through 7=Sunday)
You should use one or the other, not both.
Example
use OxygenSuite\OxygenErgani\Models\WorkTime\WorkTimeEmployee;
use OxygenSuite\OxygenErgani\Enums\DayOfWeek;
// For daily declaration
$dailyEmployee = WorkTimeEmployee::make()
->setTin('123456789')
->setLastName('ΠΑΠΑΔΟΠΟΥΛΟΣ')
->setFirstName('ΙΩΑΝΝΗΣ')
->setDate('15/01/2025');
// For weekly declaration
$weeklyEmployee = WorkTimeEmployee::make()
->setTin('123456789')
->setLastName('ΠΑΠΑΔΟΠΟΥΛΟΣ')
->setFirstName('ΙΩΑΝΝΗΣ')
->setDay(DayOfWeek::MONDAY);WorkTimeEntry Model
Each WorkTimeEntry represents a time period (work, break, leave, etc.).
Fields Reference
| Method | API Field | Type | Required | Description |
|---|---|---|---|---|
setType() | f_type | WorkTimeType|string | Yes | Type of time entry (work, break, leave, etc.) |
setFromTime() | f_from | string | Yes* | Start time (HH:MM format) |
setToTime() | f_to | string | Yes* | End time (HH:MM format) |
setYear() | f_year | string | Leave | Year for leave entries |
setRequestedDays() | f_req_days | string | Leave | Number of leave days requested |
*Not required for day off (ΡΕΠΟ) or certain leave types.
Example
use OxygenSuite\OxygenErgani\Models\WorkTime\WorkTimeEntry;
use OxygenSuite\OxygenErgani\Enums\WorkTimeType;
// Work period
$work = WorkTimeEntry::make()
->setType(WorkTimeType::WORK)
->setFromTime('09:00')
->setToTime('17:00');
// Day off / Rest
$dayOff = WorkTimeEntry::make()
->setType(WorkTimeType::REST);
// Leave with days
$leave = WorkTimeEntry::make()
->setType(WorkTimeType::LEAVE_REGULAR)
->setYear('2025')
->setRequestedDays('5');Work Time Types
The WorkTimeType enum defines all available time entry types. Codes are sourced from ParameterLookup::WORK_TIME_TYPE.
Work Types
| Case | Value | English | Greek |
|---|---|---|---|
WORK | ΕΡΓ | Work | Εργασία |
REMOTE_WORK | ΤΗΛ | Remote work | Τηλεργασία |
Rest/Non-Work
| Case | Value | English | Greek |
|---|---|---|---|
REST | ΑΝ | Rest/Day off | Ανάπαυση/Ρεπό |
NON_WORKING | ΜΕ | Non-working | Μη εργασία |
Leave Types (Full-Day)
| Case | Value | English | Greek |
|---|---|---|---|
LEAVE_REGULAR | ΑΔΚΑΝ | Regular leave | Κανονική άδεια |
LEAVE_BLOOD_DONATION | ΑΔΑΙΜ | Blood donation leave | Αιμοδοτική άδεια |
LEAVE_EXAMINATION | ΑΔΕΞ | Examination leave | Άδεια εξετάσεων |
LEAVE_UNPAID | ΑΔΑΑ | Unpaid leave | Άδεια άνευ αποδοχών |
LEAVE_MATERNITY | ΑΔΜΗ | Maternity leave | Άδεια μητρότητας |
LEAVE_PATERNITY | ΑΔΠΑ | Paternity leave | Άδεια πατρότητας |
LEAVE_PARENTAL | ΑΔΓΟΝ | Parental leave | Γονική άδεια |
LEAVE_CHILD_CARE | ΑΔΦΠ | Child care leave | Άδεια φροντίδας παιδιού |
LEAVE_SICK | ΑΔΑΣ | Sick leave | Άδεια ασθένειας |
LEAVE_MARRIAGE | ΑΔΓΑΜ | Marriage leave | Άδεια γάμου |
LEAVE_BEREAVEMENT | ΑΔΘΣΥΓ | Bereavement leave | Άδεια λόγω θανάτου συγγενούς |
LEAVE_OTHER | ΑΔΑΛ | Other leave | Άδεια Άλλη |
More Leave Types
The enum includes 28+ leave types. See the Enums API reference for the complete list.
Leave Types (Hourly)
| Case | Value | English | Greek |
|---|---|---|---|
HOURLY_CHILD_CARE | ΩΑΦΠ | Child care leave (hours) | Άδεια φροντίδας παιδιού (ΩΡΕΣ) |
HOURLY_PARENTAL | ΩΑΓΟΝ | Parental leave (hours) | Γονική άδεια (ΩΡΕΣ) |
HOURLY_OTHER | ΩΑΑΛ | Other leave (hours) | Άδεια Άλλη (ΩΡΕΣ) |
Overtime
| Case | Value | English | Greek |
|---|---|---|---|
OVERTIME | ΥΠ | Overtime | Υπερωρία |
NO_OVERTIME | ΧΥΠ | No overtime | Χωρίς υπερωρία |
Using Labels
use OxygenSuite\OxygenErgani\Enums\WorkTimeType;
WorkTimeType::WORK->label(); // 'Work'
WorkTimeType::WORK->labelGreek(); // 'Εργασία'
// Get all labels for dropdowns
WorkTimeType::labels(); // ['ΕΡΓ' => 'Work', ...]
WorkTimeType::labelsGreek(); // ['ΕΡΓ' => 'Εργασία', ...]Category Helpers
Get subsets of types for specific use cases:
// Get arrays of cases by category
WorkTimeType::work(); // [WORK, REMOTE_WORK]
WorkTimeType::rest(); // [REST, NON_WORKING]
WorkTimeType::schedule(); // work + rest combined
WorkTimeType::dayLeaves(); // 29 full-day leave types
WorkTimeType::hourlyLeaves(); // 7 hourly leave types
WorkTimeType::leaves(); // all 36 leave types
WorkTimeType::overtime(); // [OVERTIME, NO_OVERTIME]
// Check what category a type belongs to
WorkTimeType::WORK->isWork(); // true
WorkTimeType::LEAVE_SICK->isLeave(); // true
WorkTimeType::REST->isSchedule(); // trueCreating Filtered Dropdowns
// Greek dropdown for weekly schedule (work + rest types only)
$scheduleOptions = WorkTimeType::labelsFor(WorkTimeType::schedule(), 'greek');
// ['ΕΡΓ' => 'Εργασία', 'ΤΗΛ' => 'Τηλεργασία', 'ΑΝ' => 'Ανάπαυση/Ρεπό', 'ΜΕ' => 'Μη εργασία']
// Greek dropdown for leave types
$leaveOptions = WorkTimeType::labelsFor(WorkTimeType::leaves(), 'greek');Day of Week Enum
For weekly declarations, use the DayOfWeek enum:
| Case | Value | English | Greek |
|---|---|---|---|
MONDAY | 1 | Monday | Δευτέρα |
TUESDAY | 2 | Tuesday | Τρίτη |
WEDNESDAY | 3 | Wednesday | Τετάρτη |
THURSDAY | 4 | Thursday | Πέμπτη |
FRIDAY | 5 | Friday | Παρασκευή |
SATURDAY | 6 | Saturday | Σάββατο |
SUNDAY | 7 | Sunday | Κυριακή |
use OxygenSuite\OxygenErgani\Enums\DayOfWeek;
$employee->setDay(DayOfWeek::MONDAY);
// or
$employee->setDay('1');Complete Examples
Full Day with Break
use OxygenSuite\OxygenErgani\Http\Documents\WorkTime\DailyWorkTime;
use OxygenSuite\OxygenErgani\Models\WorkTime\WorkTime;
use OxygenSuite\OxygenErgani\Models\WorkTime\WorkTimeEmployee;
use OxygenSuite\OxygenErgani\Models\WorkTime\WorkTimeEntry;
use OxygenSuite\OxygenErgani\Enums\WorkTimeType;
$workTime = WorkTime::make()
->setBranchCode(0)
->addEmployee(
WorkTimeEmployee::make()
->setTin('123456789')
->setLastName('ΠΑΠΑΔΟΠΟΥΛΟΣ')
->setFirstName('ΙΩΑΝΝΗΣ')
->setDate('15/01/2025')
->addAnalytics(
WorkTimeEntry::make()
->setType(WorkTimeType::WORK)
->setFromTime('09:00')
->setToTime('17:00')
)
);
$response = (new DailyWorkTime())->handle($workTime);Multiple Employees
$workTime = WorkTime::make()
->setBranchCode(0)
->addEmployee(
WorkTimeEmployee::make()
->setTin('111111111')
->setLastName('ΠΑΠΑΔΟΠΟΥΛΟΣ')
->setFirstName('ΙΩΑΝΝΗΣ')
->setDate('15/01/2025')
->addAnalytics(
WorkTimeEntry::make()
->setType(WorkTimeType::WORK)
->setFromTime('08:00')
->setToTime('16:00')
)
)
->addEmployee(
WorkTimeEmployee::make()
->setTin('222222222')
->setLastName('ΓΕΩΡΓΙΟΥ')
->setFirstName('ΜΑΡΙΑ')
->setDate('15/01/2025')
->addAnalytics(
WorkTimeEntry::make()
->setType(WorkTimeType::WORK)
->setFromTime('10:00')
->setToTime('18:00')
)
)
->addEmployee(
WorkTimeEmployee::make()
->setTin('333333333')
->setLastName('ΝΙΚΟΛΑΟΥ')
->setFirstName('ΠΕΤΡΟΣ')
->setDate('15/01/2025')
->addAnalytics(
WorkTimeEntry::make()
->setType(WorkTimeType::REST)
)
);Weekly Schedule
use OxygenSuite\OxygenErgani\Http\Documents\WorkTime\WeeklyWorkTime;
use OxygenSuite\OxygenErgani\Enums\DayOfWeek;
$workTime = WorkTime::make()
->setBranchCode(0)
->setFromDate('20/01/2025')
->setToDate('26/01/2025');
// Add Monday-Friday work schedule
foreach ([DayOfWeek::MONDAY, DayOfWeek::TUESDAY, DayOfWeek::WEDNESDAY,
DayOfWeek::THURSDAY, DayOfWeek::FRIDAY] as $day) {
$workTime->addEmployee(
WorkTimeEmployee::make()
->setTin('123456789')
->setLastName('ΠΑΠΑΔΟΠΟΥΛΟΣ')
->setFirstName('ΙΩΑΝΝΗΣ')
->setDay($day)
->addAnalytics(
WorkTimeEntry::make()
->setType(WorkTimeType::WORK)
->setFromTime('09:00')
->setToTime('17:00')
)
);
}
// Add Saturday/Sunday as days off
foreach ([DayOfWeek::SATURDAY, DayOfWeek::SUNDAY] as $day) {
$workTime->addEmployee(
WorkTimeEmployee::make()
->setTin('123456789')
->setLastName('ΠΑΠΑΔΟΠΟΥΛΟΣ')
->setFirstName('ΙΩΑΝΝΗΣ')
->setDay($day)
->addAnalytics(
WorkTimeEntry::make()
->setType(WorkTimeType::REST)
)
);
}
$response = (new WeeklyWorkTime())->handle($workTime);Leave Declaration
use OxygenSuite\OxygenErgani\Http\Documents\WorkTime\WorkTimeLeave;
use OxygenSuite\OxygenErgani\Enums\WorkTimeType;
$workTime = WorkTime::make()
->setBranchCode(0)
->addEmployee(
WorkTimeEmployee::make()
->setTin('123456789')
->setLastName('ΠΑΠΑΔΟΠΟΥΛΟΣ')
->setFirstName('ΙΩΑΝΝΗΣ')
->setDate('20/01/2025')
->addAnalytics(
WorkTimeEntry::make()
->setType(WorkTimeType::LEAVE_REGULAR)
->setYear('2025')
->setRequestedDays('5')
)
);
$response = (new WorkTimeLeave())->handle($workTime);Retrospective Declaration
For late submissions or corrections:
use OxygenSuite\OxygenErgani\Http\Documents\WorkTime\DailyWorkTimeRetrospective;
$workTime = WorkTime::make()
->setBranchCode(0)
->setRelatedProtocol('ΩΡΕ123') // Original protocol
->setRelatedDate('10/01/2025') // Original submission date
->addEmployee(
WorkTimeEmployee::make()
->setTin('123456789')
->setLastName('ΠΑΠΑΔΟΠΟΥΛΟΣ')
->setFirstName('ΙΩΑΝΝΗΣ')
->setDate('10/01/2025')
->addAnalytics(
WorkTimeEntry::make()
->setType(WorkTimeType::WORK)
->setFromTime('09:00')
->setToTime('18:00') // Corrected end time
)
);
$response = (new DailyWorkTimeRetrospective())->handle($workTime);Response Handling
All work time documents return an array of WorkTimeResponse objects:
$response = (new DailyWorkTime())->handle($workTime);
foreach ($response as $result) {
echo $result->id; // Unique submission ID
echo $result->protocol; // Protocol number (e.g., 'ΩΡΕ456')
echo $result->submissionDate->format('d/m/Y H:i:s');
}Response Properties
| Property | Type | Description |
|---|---|---|
id | string | Unique identifier for the submission |
protocol | string | Official protocol number from ERGANI |
submissionDate | DateTimeInterface | When the submission was recorded |
Retrieve PDF
After a successful submission, you can retrieve the official PDF document from ERGANI:
use OxygenSuite\OxygenErgani\Http\Documents\WorkTime\DailyWorkTime;
// Submit the work time declaration
$response = (new DailyWorkTime())->handle($workTime);
// Later, retrieve the PDF
$pdfBase64 = (new DailyWorkTime())->pdf(
$response[0]->protocol,
$response[0]->submissionDate
);
// Decode and save to file
file_put_contents('work-time.pdf', base64_decode($pdfBase64));The pdf() method accepts the protocol number and submission date (as DateTime or Ymd string format like 20250115).
TIP
Always store the protocol number and submission date after each submission. These are required to retrieve the PDF later or to cancel the submission.
JSON Structure
For reference, here's the JSON structure sent to the ERGANI API:
Daily Declaration
{
"WTOS": {
"WTO": [
{
"f_aa_pararthmatos": "0",
"f_rel_protocol": "",
"f_rel_date": "",
"f_comments": "",
"f_from_date": "",
"f_to_date": "",
"Ergazomenoi": {
"ErgazomenoiWTO": [
{
"f_afm": "123456789",
"f_eponymo": "ΠΑΠΑΔΟΠΟΥΛΟΣ",
"f_onoma": "ΙΩΑΝΝΗΣ",
"f_date": "15/01/2025",
"ErgazomenosAnalytics": {
"ErgazomenosWTOAnalytics": [
{
"f_type": "ΕΡΓ",
"f_from": "09:00",
"f_to": "17:00"
}
]
}
}
]
}
}
]
}
}Weekly Declaration
{
"WTOS": {
"WTO": [
{
"f_aa_pararthmatos": "0",
"f_rel_protocol": "",
"f_rel_date": "",
"f_comments": "",
"f_from_date": "20/01/2025",
"f_to_date": "26/01/2025",
"Ergazomenoi": {
"ErgazomenoiWTO": [
{
"f_afm": "123456789",
"f_eponymo": "ΠΑΠΑΔΟΠΟΥΛΟΣ",
"f_onoma": "ΙΩΑΝΝΗΣ",
"f_day": "1",
"ErgazomenosAnalytics": {
"ErgazomenosWTOAnalytics": [
{
"f_type": "ΕΡΓ",
"f_from": "09:00",
"f_to": "17:00"
}
]
}
}
]
}
}
]
}
}Testing with Factories
WorkTimeEntry supports factory state methods for generating test data:
use OxygenSuite\OxygenErgani\Models\WorkTime\WorkTimeEntry;
// Common entry types
$entry = WorkTimeEntry::factory()->work('08:00', '16:00')->make();
$entry = WorkTimeEntry::factory()->overtime('17:00', '19:00')->make();
$entry = WorkTimeEntry::factory()->dayOff()->make();
$entry = WorkTimeEntry::factory()->leaveRegular('2025', '010')->make();
// Shift presets
$entry = WorkTimeEntry::factory()->morningShift()->make();
$entry = WorkTimeEntry::factory()->nightShift()->make();Best Practices
1. Use Appropriate Document Type
- DailyWorkTime: For declaring specific dates' schedules
- WeeklyWorkTime: For recurring weekly patterns
- DailyWorkTimeRetrospective: For late submissions or corrections
- DailyWorkTimeDrivers: Special rules apply for drivers
- WorkTimeLeave: For leave declarations specifically
2. Split Work Periods for Breaks
When an employee has a break, create separate work entries for each work period:
// Morning work (before break)
->addAnalytics(
WorkTimeEntry::make()
->setType(WorkTimeType::WORK)
->setFromTime('09:00')
->setToTime('13:00')
)
// Afternoon work (after break)
->addAnalytics(
WorkTimeEntry::make()
->setType(WorkTimeType::WORK)
->setFromTime('13:30')
->setToTime('17:30')
)3. Time Format
Always use 24-hour HH:MM format for times:
- Correct:
'09:00','17:30','23:00' - Incorrect:
'9:00','5:30 PM'
4. Date Format
Use DD/MM/YYYY format for dates:
- Correct:
'15/01/2025' - Incorrect:
'2025-01-15','01/15/2025'
5. Store Protocol Numbers
Always store the returned protocol number for corrections or cancellations:
foreach ($response as $result) {
$this->storeProtocol($employeeId, $result->protocol, $result->submissionDate);
}See Also
- Work Cards - Employee check-in/check-out tracking
- Cancel Submissions - How to cancel erroneous submissions
- Error Handling - Handling API errors and exceptions