diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
index 95572a5c443..ef87b5f5081 100644
--- a/htdocs/core/class/html.form.class.php
+++ b/htdocs/core/class/html.form.class.php
@@ -246,7 +246,7 @@ class Form
if (empty($notabletag)) {
$ret .= '
| ';
}
- if (preg_match('/^(string|safehtmlstring|email)/', $typeofdata)) {
+ if (preg_match('/^(string|safehtmlstring|email|url)/', $typeofdata)) {
$tmp = explode(':', $typeofdata);
$ret .= '';
} elseif (preg_match('/^(integer)/', $typeofdata)) {
@@ -320,6 +320,8 @@ class Form
} else {
if (preg_match('/^(email)/', $typeofdata)) {
$ret .= dol_print_email($value, 0, 0, 0, 0, 1);
+ } elseif (preg_match('/^url/', $typeofdata)) {
+ $ret .= dol_print_url($value, '_blank', 32, 1);
} elseif (preg_match('/^(amount|numeric)/', $typeofdata)) {
$ret .= ($value != '' ? price($value, '', $langs, 0, -1, -1, $conf->currency) : '');
} elseif (preg_match('/^(checkbox)/', $typeofdata)) {
diff --git a/htdocs/loan/payment/card.php b/htdocs/loan/payment/card.php
index 309e0d99f4a..b291b313e43 100644
--- a/htdocs/loan/payment/card.php
+++ b/htdocs/loan/payment/card.php
@@ -223,7 +223,7 @@ print ' ';
if (empty($action) && !empty($user->rights->loan->delete)) {
if (!$disable_delete) {
- print dolGetButtonAction($langs->trans("Delete"), '', 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), 'delete', 1);
+ print dolGetButtonAction($langs->trans("Delete"), '', 'delete', $_SERVER["PHP_SELF"].'?id='.$id.'&action=delete&token='.newToken(), 'delete', 1);
} else {
print dolGetButtonAction($langs->trans("CantRemovePaymentWithOneInvoicePaid"), $langs->trans("Delete"), 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), 'delete', 0);
}
diff --git a/htdocs/projet/class/api_tasks.class.php b/htdocs/projet/class/api_tasks.class.php
index 64690f90950..80fede57563 100644
--- a/htdocs/projet/class/api_tasks.class.php
+++ b/htdocs/projet/class/api_tasks.class.php
@@ -516,6 +516,7 @@ class Tasks extends DolibarrApi
* @param string $note Note
*
* @url POST {id}/addtimespent
+ * NOTE: Should be "POST {id}/timespent", since POST already implies "add"
*
* @return array
*/
@@ -562,6 +563,110 @@ class Tasks extends DolibarrApi
);
}
+ /**
+ * Update time spent for a task of a project.
+ * You can test this API with the following input message
+ * { "date": "2016-12-31 23:15:00", "duration": 1800, "user_id": 1, "note": "My time test" }
+ *
+ * @param int $id Task ID
+ * @param int $timespent_id Time spent ID (llx_projet_task_time.rowid)
+ * @param datetime $date Date (YYYY-MM-DD HH:MI:SS in GMT)
+ * @param int $duration Duration in seconds (3600 = 1h)
+ * @param int $user_id User (Use 0 for connected user)
+ * @param string $note Note
+ *
+ * @url PUT {id}/timespent/{timespent_id}
+ *
+ * @return array
+ */
+ public function putTimeSpent($id, $timespent_id, $date, $duration, $user_id = 0, $note = '')
+ {
+ if (!DolibarrApiAccess::$user->rights->projet->creer) {
+ throw new RestException(401);
+ }
+ $this->timespentRecordChecks($id, $timespent_id);
+
+ if (!DolibarrApi::_checkAccessToResource('task', $this->task->id)) {
+ throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+ }
+
+ $newdate = dol_stringtotime($date, 1);
+ $this->task->timespent_date = $newdate;
+ $this->task->timespent_datehour = $newdate;
+ $this->task->timespent_withhour = 1;
+ $this->task->timespent_duration = $duration;
+ $this->task->timespent_fk_user = $user_id ?? DolibarrApiAccess::$user->id;
+ $this->task->timespent_note = $note;
+
+ $result = $this->task->updateTimeSpent(DolibarrApiAccess::$user, 0);
+ if ($result == 0) {
+ throw new RestException(304, 'Error nothing done.');
+ }
+ if ($result < 0) {
+ throw new RestException(500, 'Error when updating time spent: '.$this->task->error);
+ }
+
+ return array(
+ 'success' => array(
+ 'code' => 200,
+ 'message' => 'Time spent updated'
+ )
+ );
+ }
+
+ /**
+ * Delete time spent for a task of a project.
+ *
+ * @param int $id Task ID
+ * @param int $timespent_id Time spent ID (llx_projet_task_time.rowid)
+ *
+ * @url DELETE {id}/timespent/{timespent_id}
+ *
+ * @return array
+ */
+ public function deleteTimeSpent($id, $timespent_id)
+ {
+ if (!DolibarrApiAccess::$user->rights->projet->supprimer) {
+ throw new RestException(401);
+ }
+ $this->timespentRecordChecks($id, $timespent_id);
+
+ if (!DolibarrApi::_checkAccessToResource('task', $this->task->id)) {
+ throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+ }
+
+ if ($this->task->delTimeSpent(DolibarrApiAccess::$user, 0) < 0) {
+ throw new RestException(500, 'Error when deleting time spent: '.$this->task->error);
+ }
+
+ return array(
+ 'success' => array(
+ 'code' => 200,
+ 'message' => 'Time spent deleted'
+ )
+ );
+ }
+
+ /**
+ * Validate task & timespent IDs for timespent API methods.
+ * Loads the selected task & timespent records.
+ *
+ * @param int $id Task ID
+ * @param int $timespent_id Time spent ID (llx_projet_task_time.rowid)
+ *
+ * @return void
+ */
+ protected function timespentRecordChecks($id, $timespent_id)
+ {
+ if ($this->task->fetch($id) <= 0) {
+ throw new RestException(404, 'Task not found');
+ }
+ if ($this->task->fetchTimeSpent($timespent_id) <= 0) {
+ throw new RestException(404, 'Timespent not found');
+ } elseif ($this->task->id != $id) {
+ throw new RestException(404, 'Timespent not found in selected task');
+ }
+ }
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
/**
|