diff --git a/README.md b/README.md index 0f71678..da32a9e 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ There is a [Transifex project](https://transifex.com/projects/p/dolibarr-module- ## Installation -Prerequisites: You must have Dolibarr ERP & CRM software installed. You can download it from [Dolistore.org](https://www.dolibarr.org). +Prerequisites: You must have Dolibarr ERP & CRM software installed. You can download it from [Dolibarr.org](https://www.dolibarr.org). You can also get a ready-to-use instance in the cloud from https://saas.dolibarr.org diff --git a/class/timesheetweek.class.php b/class/timesheetweek.class.php index f4443e6..ee9180b 100644 --- a/class/timesheetweek.class.php +++ b/class/timesheetweek.class.php @@ -49,7 +49,7 @@ class TimesheetWeek extends CommonObject public $table_element = 'timesheet_week'; /** - * @var string If permission must be checkec with hasRight('timesheetweek', 'read') and not hasright('mymodyle', 'timesheetweek', 'read'), you can uncomment this line + * @var string If permission must be checked with hasRight('timesheetweek', 'read') and not hasRight('mymodule', 'timesheetweek', 'read'), you can uncomment this line */ //public $element_for_permission = 'timesheetweek'; @@ -135,13 +135,13 @@ class TimesheetWeek extends CommonObject public $fields = array( "rowid" => array("type" => "int", "label" => "TechnicalID", "enabled" => "1", 'position' => 10, 'notnull' => 1, "visible" => "0",), "ref" => array("type" => "varchar(50)", "label" => "Ref", "enabled" => "1", 'position' => 15, 'notnull' => 1, "visible" => "1", "csslist" => "tdoverflowmax150", "showoncombobox" => "1",), - "fk_user" => array("type" => "integer:User:user/class/user.class.php", "label" => "Fkuser", "picto" => "user", "enabled" => "1", 'position' => 20, 'notnull' => 1, "visible" => "-1", "css" => "maxwidth500 widthcentpercentminusxx", "csslist" => "tdoverflowmax150",), + "fk_user" => array("type" => "integer:User:user/class/user.class.php", "label" => "User", "picto" => "user", "enabled" => "1", 'position' => 20, 'notnull' => 1, "visible" => "-1", "css" => "maxwidth500 widthcentpercentminusxx", "csslist" => "tdoverflowmax150",), "year" => array("type" => "smallint", "label" => "Year", "enabled" => "1", 'position' => 25, 'notnull' => 1, "visible" => "-1",), "week" => array("type" => "smallint", "label" => "Week", "enabled" => "1", 'position' => 30, 'notnull' => 1, "visible" => "-1",), "status" => array("type" => "smallint", "label" => "Status", "enabled" => "1", 'position' => 500, 'notnull' => 1, "visible" => "-1", "default" => "0",), "note" => array("type" => "text", "label" => "Note", "enabled" => "1", 'position' => 45, 'notnull' => 0, "visible" => "-1",), "date_creation" => array("type" => "datetime", "label" => "DateCreation", "enabled" => "1", 'position' => 50, 'notnull' => 0, "visible" => "-1",), - "date_validation" => array("type" => "datetime", "label" => "Datevalidation", "enabled" => "1", 'position' => 55, 'notnull' => 0, "visible" => "-1",), + "date_validation" => array("type" => "datetime", "label" => "DateValidation", "enabled" => "1", 'position' => 55, 'notnull' => 0, "visible" => "-1",), "fk_user_valid" => array("type" => "integer:User:user/class/user.class.php", "label" => "UserValidation", "picto" => "user", "enabled" => "1", 'position' => 60, 'notnull' => 0, "visible" => "-1", "css" => "maxwidth500 widthcentpercentminusxx", "csslist" => "tdoverflowmax150",), "tms" => array("type" => "timestamp", "label" => "DateModification", "enabled" => "1", 'position' => 65, 'notnull' => 0, "visible" => "-1",), ); diff --git a/class/timesheetweekline.class.php b/class/timesheetweekline.class.php index 09e94ff..9eb0ab1 100644 --- a/class/timesheetweekline.class.php +++ b/class/timesheetweekline.class.php @@ -13,10 +13,12 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php'; -class TimesheetWeekLine extends CommonObject +class TimesheetWeekLine extends CommonObjectLine { public $element = 'timesheetweekline'; public $table_element = 'timesheet_week_line'; + public $fk_element = 'fk_timesheet_week'; + public $parent_element = 'timesheetweek'; public $fk_timesheet_week; public $fk_task; diff --git a/lib/timesheetweek.lib.php b/lib/timesheetweek.lib.php index 37677ed..22c09eb 100644 --- a/lib/timesheetweek.lib.php +++ b/lib/timesheetweek.lib.php @@ -321,7 +321,14 @@ function timesheetweekShowPerWeek($db, $userId, $year, $week) */ function formatHours($hoursDecimal) { - $h = floor($hoursDecimal); - $m = round(($hoursDecimal - $h) * 60); - return sprintf("%02d:%02d", $h, $m); + $hoursDecimal = (float) $hoursDecimal; + $hours = (int) floor($hoursDecimal); + $minutes = (int) round(($hoursDecimal - $hours) * 60); + + if ($minutes >= 60) { + $hours += (int) floor($minutes / 60); + $minutes = $minutes % 60; + } + + return sprintf("%02d:%02d", $hours, $minutes); } diff --git a/tests/FormatHoursTest.php b/tests/FormatHoursTest.php new file mode 100644 index 0000000..a6c3ecb --- /dev/null +++ b/tests/FormatHoursTest.php @@ -0,0 +1,27 @@ + [0, '00:00'], + 'quarter hour' => [1.25, '01:15'], + 'round up minutes' => [1.999, '02:00'], + 'fifty nine point five minutes' => [59.5 / 60, '01:00'], + 'half hour' => [2.5, '02:30'], + 'over twenty four hours' => [24.5, '24:30'], + 'string input' => ['3.1', '03:06'], +]; + +$errors = []; +foreach ($cases as $label => [$input, $expected]) { + $actual = formatHours($input); + if ($actual !== $expected) { + $errors[] = sprintf('%s: expected %s, got %s', $label, $expected, $actual); + } +} + +if ($errors) { + fwrite(STDERR, "formatHours tests failed:\n".implode("\n", $errors)."\n"); + exit(1); +} + +echo "All formatHours tests passed.\n";