11<?php
2- /* Copyright (C) 2025 Pierre ARDOIN
3- *
4- * This program is free software; you can redistribute it and/or modify
5- * it under the terms of the GNU General Public License.
6- */
2+ /* Copyright (C) 2025 Pierre Ardoin <[email protected] > 3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; either version 3 of the License, or
7+ * (at your option) any later version.
8+ *
9+ * This program is distributed in the hope that it will be useful,
10+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+ * GNU General Public License for more details.
13+ *
14+ * You should have received a copy of the GNU General Public License
15+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
16+ */
717
818/**
9- * \file timesheetweek/class/timesheetweekline.class.php
10- * \ingroup timesheetweek
11- * \brief TimesheetWeekLine class file
12- */
19+ * \file timesheetweek/class/timesheetweekline.class.php
20+ * \ingroup timesheetweek
21+ * \brief TimesheetWeekLine class file
22+ */
1323
1424require_once DOL_DOCUMENT_ROOT .'/core/class/commonobjectline.class.php ' ;
1525
1626class TimesheetWeekLine extends CommonObjectLine
1727{
18- public $ element = 'timesheetweekline ' ;
19- public $ table_element = 'timesheet_week_line ' ;
20- public $ fk_element = 'fk_timesheet_week ' ;
21- public $ parent_element = 'timesheetweek ' ;
28+ public $ element = 'timesheetweekline ' ;
29+ public $ table_element = 'timesheet_week_line ' ;
30+ public $ fk_element = 'fk_timesheet_week ' ;
31+ public $ parent_element = 'timesheetweek ' ;
2232
23- // EN: Entity identifier bound to the line.
24- // FR: Identifiant d'entité lié à la ligne.
25- public $ entity ;
26- public $ fk_timesheet_week ;
27- public $ fk_task ;
28- public $ day_date ;
29- public $ hours ;
30- public $ zone ;
31- public $ meal ;
33+ // EN: Entity identifier bound to the line.
34+ // FR: Identifiant d'entité lié à la ligne.
35+ public $ entity ;
36+ public $ fk_timesheet_week ;
37+ public $ fk_task ;
38+ public $ day_date ;
39+ public $ hours ;
40+ // EN: Stores the selected daily rate value linked to forfait-jour entries.
41+ // FR: Stocke la valeur de forfait-jour sélectionnée pour les saisies concernées.
42+ public $ daily_rate ;
43+ public $ zone ;
44+ public $ meal ;
3245
33- /**
34- * Fetches a timesheet line by its rowid.
35- * Récupère une ligne de feuille de temps via son rowid.
36- *
37- * @param int $id Row identifier / Identifiant de ligne
38- * @return int >0 success, <=0 error / >0 succès, <=0 erreur
39- */
40- public function fetch ($ id )
41- {
42- if (empty ($ id )) {
43- return 0 ;
44- }
46+ /**
47+ * Fetches a timesheet line by its rowid.
48+ * Récupère une ligne de feuille de temps via son rowid.
49+ *
50+ * @param int $id Row identifier / Identifiant de ligne
51+ * @return int >0 success, <=0 error / >0 succès, <=0 erreur
52+ */
53+ public function fetch ($ id )
54+ {
55+ if (empty ($ id )) {
56+ return 0 ;
57+ }
4558
46- // Build the query for the line / Construit la requête pour la ligne
47- $ sql = "SELECT rowid, entity, fk_timesheet_week, fk_task, day_date, hours, zone, meal " ;
48- $ sql .= " FROM " .MAIN_DB_PREFIX ."timesheet_week_line " ;
49- $ sql .= " WHERE rowid= " .(int ) $ id ;
50- // EN: Respect module entity permissions during line fetch.
51- // FR: Respecte les permissions d'entité du module lors du chargement de la ligne.
52- $ sql .= " AND entity IN ( " .getEntity ('timesheetweek ' ).") " ;
59+ // Build the query for the line / Construit la requête pour la ligne
60+ $ sql = "SELECT rowid, entity, fk_timesheet_week, fk_task, day_date, hours, daily_rate , zone, meal " ;
61+ $ sql .= " FROM " .MAIN_DB_PREFIX ."timesheet_week_line " ;
62+ $ sql .= " WHERE rowid= " .(int ) $ id ;
63+ // EN: Respect module entity permissions during line fetch.
64+ // FR: Respecte les permissions d'entité du module lors du chargement de la ligne.
65+ $ sql .= " AND entity IN ( " .getEntity ('timesheetweek ' ).") " ;
5366
54- $ resql = $ this ->db ->query ($ sql );
55- if (!$ resql ) {
56- $ this ->error = $ this ->db ->lasterror ();
57- return -1 ;
58- }
67+ $ resql = $ this ->db ->query ($ sql );
68+ if (!$ resql ) {
69+ $ this ->error = $ this ->db ->lasterror ();
70+ return -1 ;
71+ }
5972
60- $ obj = $ this ->db ->fetch_object ($ resql );
61- $ this ->db ->free ($ resql );
62- if (!$ obj ) {
63- return 0 ;
64- }
73+ $ obj = $ this ->db ->fetch_object ($ resql );
74+ $ this ->db ->free ($ resql );
75+ if (!$ obj ) {
76+ return 0 ;
77+ }
6578
66- // Map database values to object / Mappe les valeurs de la base vers l'objet
67- $ this ->id = (int ) $ obj ->rowid ;
68- $ this ->rowid = (int ) $ obj ->rowid ;
69- $ this ->entity = (int ) $ obj ->entity ;
70- $ this ->fk_timesheet_week = (int ) $ obj ->fk_timesheet_week ;
71- $ this ->fk_task = (int ) $ obj ->fk_task ;
72- $ this ->day_date = $ obj ->day_date ;
73- $ this ->hours = (float ) $ obj ->hours ;
74- $ this ->zone = (int ) $ obj ->zone ;
75- $ this ->meal = (int ) $ obj ->meal ;
79+ // Map database values to object / Mappe les valeurs de la base vers l'objet
80+ $ this ->id = (int ) $ obj ->rowid ;
81+ $ this ->rowid = (int ) $ obj ->rowid ;
82+ $ this ->entity = (int ) $ obj ->entity ;
83+ $ this ->fk_timesheet_week = (int ) $ obj ->fk_timesheet_week ;
84+ $ this ->fk_task = (int ) $ obj ->fk_task ;
85+ $ this ->day_date = $ obj ->day_date ;
86+ $ this ->hours = (float ) $ obj ->hours ;
87+ $ this ->daily_rate = (int ) $ obj ->daily_rate ;
88+ $ this ->zone = (int ) $ obj ->zone ;
89+ $ this ->meal = (int ) $ obj ->meal ;
7690
77- return 1 ;
78- }
91+ return 1 ;
92+ }
7993
80- /**
81- * Crée ou met à jour la ligne si elle existe déjà
82- */
83- public function save ($ user )
84- {
85- // EN: Resolve the entity from the parent sheet when not provided.
86- // FR: Récupère l'entité depuis la feuille parente lorsqu'elle n'est pas fournie.
87- if (empty ($ this ->entity ) && !empty ($ this ->fk_timesheet_week )) {
88- $ sqlEntity = "SELECT entity FROM " .MAIN_DB_PREFIX ."timesheet_week WHERE rowid= " .(int ) $ this ->fk_timesheet_week ;
89- $ sqlEntity .= " AND entity IN ( " .getEntity ('timesheetweek ' ).") " ;
90- $ resEntity = $ this ->db ->query ($ sqlEntity );
91- if ($ resEntity ) {
92- $ objEntity = $ this ->db ->fetch_object ($ resEntity );
93- if ($ objEntity ) {
94- $ this ->entity = (int ) $ objEntity ->entity ;
95- }
96- }
97- }
98- if (empty ($ this ->entity )) {
99- global $ conf ;
100- // EN: Fall back to the current context entity as a last resort.
101- // FR: Revient en dernier recours à l'entité du contexte courant.
102- $ this ->entity = isset ($ conf ->entity ) ? (int ) $ conf ->entity : 1 ;
103- }
94+ /**
95+ * Saves the line or updates it when already stored.
96+ * Crée ou met à jour la ligne si elle existe déjà.
97+ */
98+ public function save ($ user )
99+ {
100+ // EN: Resolve the entity from the parent sheet when not provided.
101+ // FR: Récupère l'entité depuis la feuille parente lorsqu'elle n'est pas fournie.
102+ if (empty ($ this ->entity ) && !empty ($ this ->fk_timesheet_week )) {
103+ $ sqlEntity = "SELECT entity FROM " .MAIN_DB_PREFIX ."timesheet_week WHERE rowid= " .(int ) $ this ->fk_timesheet_week ;
104+ $ sqlEntity .= " AND entity IN ( " .getEntity ('timesheetweek ' ).") " ;
105+ $ resEntity = $ this ->db ->query ($ sqlEntity );
106+ if ($ resEntity ) {
107+ $ objEntity = $ this ->db ->fetch_object ($ resEntity );
108+ if ($ objEntity ) {
109+ $ this ->entity = (int ) $ objEntity ->entity ;
110+ }
111+ }
112+ }
113+ if (empty ($ this ->entity )) {
114+ global $ conf ;
115+ // EN: Fall back to the current context entity as a last resort.
116+ // FR: Revient en dernier recours à l'entité du contexte courant.
117+ $ this ->entity = isset ($ conf ->entity ) ? (int ) $ conf ->entity : 1 ;
118+ }
119+
120+ // EN: Normalize the stored daily rate to avoid null values reaching SQL.
121+ // FR: Normalise la valeur de forfait-jour pour éviter d'envoyer des NULL en SQL.
122+ if ($ this ->daily_rate === null ) {
123+ $ this ->daily_rate = 0 ;
124+ }
104125
105- // Vérifie si une ligne existe déjà pour cette tâche et ce jour
106- $ sql = "SELECT rowid FROM " .MAIN_DB_PREFIX ."timesheet_week_line " ;
107- $ sql .= " WHERE fk_timesheet_week = " .((int )$ this ->fk_timesheet_week );
108- $ sql .= " AND fk_task = " .((int )$ this ->fk_task );
109- $ sql .= " AND day_date = ' " .$ this ->db ->escape ($ this ->day_date )."' " ;
110- // EN: Keep lookups limited to lines inside allowed entities.
111- // FR: Limite les recherches aux lignes situées dans les entités autorisées.
112- $ sql .= " AND entity IN ( " .getEntity ('timesheetweek ' ).") " ;
126+ // EN: Check whether a line already exists for this task and day.
127+ // FR: Vérifie si une ligne existe déjà pour cette tâche et ce jour.
128+ $ sql = "SELECT rowid FROM " .MAIN_DB_PREFIX ."timesheet_week_line " ;
129+ $ sql .= " WHERE fk_timesheet_week = " .((int )$ this ->fk_timesheet_week );
130+ $ sql .= " AND fk_task = " .((int )$ this ->fk_task );
131+ $ sql .= " AND day_date = ' " .$ this ->db ->escape ($ this ->day_date )."' " ;
132+ // EN: Keep lookups limited to lines inside allowed entities.
133+ // FR: Limite les recherches aux lignes situées dans les entités autorisées.
134+ $ sql .= " AND entity IN ( " .getEntity ('timesheetweek ' ).") " ;
113135
114- $ resql = $ this ->db ->query ($ sql );
115- if ($ resql && $ this ->db ->num_rows ($ resql ) > 0 ) {
116- // ---- UPDATE ----
117- $ obj = $ this ->db ->fetch_object ($ resql );
118- $ sqlu = "UPDATE " .MAIN_DB_PREFIX ."timesheet_week_line SET " ;
119- $ sqlu .= " hours = " .((float )$ this ->hours ).", " ;
120- $ sqlu .= " zone = " .((int )$ this ->zone ).", " ;
121- $ sqlu .= " meal = " .((int )$ this ->meal );
122- $ sqlu .= " WHERE rowid = " .((int )$ obj ->rowid );
123- // EN: Ensure updates stay within the permitted entity scope.
124- // FR: Assure que les mises à jour restent dans le périmètre d'entité autorisé.
125- $ sqlu .= " AND entity IN ( " .getEntity ('timesheetweek ' ).") " ;
126- return $ this ->db ->query ($ sqlu ) ? 1 : -1 ;
127- }
128- else {
129- // ---- INSERT ----
130- // EN: Persist the entity alongside the usual line fields for consistency.
131- // FR: Enregistre l'entité avec les champs habituels de la ligne pour rester cohérent.
132- $ sqli = "INSERT INTO " .MAIN_DB_PREFIX ."timesheet_week_line( " ;
133- $ sqli .= " entity, fk_timesheet_week, fk_task, day_date, hours, zone, meal) " ;
134- $ sqli .= " VALUES( " ;
135- $ sqli .= (int )$ this ->entity .", " ;
136- $ sqli .= (int )$ this ->fk_timesheet_week .", " ;
137- $ sqli .= (int )$ this ->fk_task .", " ;
138- $ sqli .= "' " .$ this ->db ->escape ($ this ->day_date )."', " ;
139- $ sqli .= (float )$ this ->hours .", " ;
140- $ sqli .= (int )$ this ->zone .", " ;
141- $ sqli .= (int )$ this ->meal .") " ;
142- return $ this ->db ->query ($ sqli ) ? 1 : -1 ;
143- }
144- }
145- }
136+ $ resql = $ this ->db ->query ($ sql );
137+ if ($ resql && $ this ->db ->num_rows ($ resql ) > 0 ) {
138+ // ---- UPDATE ----
139+ $ obj = $ this ->db ->fetch_object ($ resql );
140+ $ sqlu = "UPDATE " .MAIN_DB_PREFIX ."timesheet_week_line SET " ;
141+ $ sqlu .= " hours = " .((float )$ this ->hours ).", " ;
142+ $ sqlu .= " daily_rate = " .((int )$ this ->daily_rate ).", " ;
143+ $ sqlu .= " zone = " .((int )$ this ->zone ).", " ;
144+ $ sqlu .= " meal = " .((int )$ this ->meal );
145+ $ sqlu .= " WHERE rowid = " .((int )$ obj ->rowid );
146+ // EN: Ensure updates stay within the permitted entity scope.
147+ // FR: Assure que les mises à jour restent dans le périmètre d'entité autorisé.
148+ $ sqlu .= " AND entity IN ( " .getEntity ('timesheetweek ' ).") " ;
149+ return $ this ->db ->query ($ sqlu ) ? 1 : -1 ;
150+ }
151+ else {
152+ // ---- INSERT ----
153+ // EN: Persist the entity alongside the usual line fields for consistency.
154+ // FR: Enregistre l'entité avec les champs habituels de la ligne pour rester cohérent.
155+ $ sqli = "INSERT INTO " .MAIN_DB_PREFIX ."timesheet_week_line( " ;
156+ $ sqli .= " entity, fk_timesheet_week, fk_task, day_date, hours, daily_rate, zone, meal) " ;
157+ $ sqli .= " VALUES( " ;
158+ $ sqli .= (int )$ this ->entity .", " ;
159+ $ sqli .= (int )$ this ->fk_timesheet_week .", " ;
160+ $ sqli .= (int )$ this ->fk_task .", " ;
161+ $ sqli .= "' " .$ this ->db ->escape ($ this ->day_date )."', " ;
162+ $ sqli .= (float )$ this ->hours .", " ;
163+ $ sqli .= (int )$ this ->daily_rate .", " ;
164+ $ sqli .= (int )$ this ->zone .", " ;
165+ $ sqli .= (int )$ this ->meal .") " ;
166+ return $ this ->db ->query ($ sqli ) ? 1 : -1 ;
167+ }
168+ }
169+ }
0 commit comments