Start feature

This commit is contained in:
Florian HENRY 2022-01-07 12:17:39 +01:00
parent aa64b9c524
commit 5329028d6a
4 changed files with 93 additions and 1 deletions

View File

@ -0,0 +1,34 @@
--
-- Be carefull to requests order.
-- This file must be loaded by calling /install/index.php page
-- when current version is 14.0.0 or higher.
--
-- To restrict request to Mysql version x.y minimum use -- VMYSQLx.y
-- To restrict request to Pgsql version x.y minimum use -- VPGSQLx.y
-- To rename a table: ALTER TABLE llx_table RENAME TO llx_table_new;
-- To add a column: ALTER TABLE llx_table ADD COLUMN newcol varchar(60) NOT NULL DEFAULT '0' AFTER existingcol;
-- To rename a column: ALTER TABLE llx_table CHANGE COLUMN oldname newname varchar(60);
-- To drop a column: ALTER TABLE llx_table DROP COLUMN oldname;
-- To change type of field: ALTER TABLE llx_table MODIFY COLUMN name varchar(60);
-- To drop a foreign key: ALTER TABLE llx_table DROP FOREIGN KEY fk_name;
-- To create a unique index ALTER TABLE llx_table ADD UNIQUE INDEX uk_table_field (field);
-- To drop an index: -- VMYSQL4.1 DROP INDEX nomindex on llx_table;
-- To drop an index: -- VPGSQL8.2 DROP INDEX nomindex;
-- To make pk to be auto increment (mysql): -- VMYSQL4.3 ALTER TABLE llx_table CHANGE COLUMN rowid rowid INTEGER NOT NULL AUTO_INCREMENT;
-- To make pk to be auto increment (postgres):
-- -- VPGSQL8.2 CREATE SEQUENCE llx_table_rowid_seq OWNED BY llx_table.rowid;
-- -- VPGSQL8.2 ALTER TABLE llx_table ADD PRIMARY KEY (rowid);
-- -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN rowid SET DEFAULT nextval('llx_table_rowid_seq');
-- -- VPGSQL8.2 SELECT setval('llx_table_rowid_seq', MAX(rowid)) FROM llx_table;
-- To set a field as NULL: -- VMYSQL4.3 ALTER TABLE llx_table MODIFY COLUMN name varchar(60) NULL;
-- To set a field as NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name DROP NOT NULL;
-- To set a field as NOT NULL: -- VMYSQL4.3 ALTER TABLE llx_table MODIFY COLUMN name varchar(60) NOT NULL;
-- To set a field as NOT NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name SET NOT NULL;
-- To set a field as default NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name SET DEFAULT NULL;
-- Note: fields with type BLOB/TEXT can't have default value.
-- To rebuild sequence for postgresql after insert by forcing id autoincrement fields:
-- -- VPGSQL8.2 SELECT dol_util_rebuild_sequences();
-- Missing in v14 or lower
ALTER TABLE llx_projet_task_time ADD COLUMN fk_product integer NULL;

View File

@ -24,6 +24,7 @@ create table llx_projet_task_time
task_datehour datetime, -- day + hour
task_date_withhour integer DEFAULT 0, -- 0 by default, 1 if date was entered with start hour
task_duration double,
fk_product integer NULL,
fk_user integer,
thm double(24,8),
invoice_id integer DEFAULT NULL, -- If we need to invoice each line of timespent, we can save invoice id here

View File

@ -118,6 +118,7 @@ class Task extends CommonObject
public $timespent_fk_user;
public $timespent_thm;
public $timespent_note;
public $timespent_fk_product;
public $comments = array();
@ -1201,6 +1202,7 @@ class Task extends CommonObject
$sql .= ", task_date_withhour";
$sql .= ", task_duration";
$sql .= ", fk_user";
$sql .= ", fk_product";
$sql .= ", note";
$sql .= ") VALUES (";
$sql .= ((int) $this->id);
@ -1209,6 +1211,7 @@ class Task extends CommonObject
$sql .= ", ".(empty($this->timespent_withhour) ? 0 : 1);
$sql .= ", ".((int) $this->timespent_duration);
$sql .= ", ".((int) $this->timespent_fk_user);
$sql .= ", ".((int) $this->timespent_fk_product);
$sql .= ", ".(isset($this->timespent_note) ? "'".$this->db->escape($this->timespent_note)."'" : "null");
$sql .= ")";
@ -1404,6 +1407,7 @@ class Task extends CommonObject
$sql .= " t.task_date_withhour,";
$sql .= " t.task_duration,";
$sql .= " t.fk_user,";
$sql .= " t.fk_product,";
$sql .= " t.thm,";
$sql .= " t.note";
$sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t";
@ -1422,6 +1426,7 @@ class Task extends CommonObject
$this->timespent_withhour = $obj->task_date_withhour;
$this->timespent_duration = $obj->task_duration;
$this->timespent_fk_user = $obj->fk_user;
$this->timespent_fk_product = $obj->fk_product;
$this->timespent_thm = $obj->thm; // hourly rate
$this->timespent_note = $obj->note;
}
@ -1575,6 +1580,7 @@ class Task extends CommonObject
$sql .= " task_date_withhour = ".(empty($this->timespent_withhour) ? 0 : 1).",";
$sql .= " task_duration = ".((int) $this->timespent_duration).",";
$sql .= " fk_user = ".((int) $this->timespent_fk_user).",";
$sql .= " fk_product = ".((int) $this->timespent_fk_product).",";
$sql .= " note = ".(isset($this->timespent_note) ? "'".$this->db->escape($this->timespent_note)."'" : "null");
$sql .= " WHERE rowid = ".((int) $this->timespent_id);

View File

@ -73,6 +73,7 @@ $search_task_ref = GETPOST('search_task_ref', 'alpha');
$search_task_label = GETPOST('search_task_label', 'alpha');
$search_user = GETPOST('search_user', 'int');
$search_valuebilled = GETPOST('search_valuebilled', 'int');
$search_product_ref = GETPOST('search_product_ref', 'alpha');
// Security check
$socid = 0;
@ -161,6 +162,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x'
$search_task_label = '';
$search_user = 0;
$search_valuebilled = '';
$search_product_ref = '';
$toselect = '';
$search_array_options = array();
$action = '';
@ -215,6 +217,7 @@ if ($action == 'addtimespent' && $user->rights->projet->lire) {
$object->timespent_date = dol_mktime(12, 0, 0, GETPOST("timemonth", 'int'), GETPOST("timeday", 'int'), GETPOST("timeyear", 'int'));
}
$object->timespent_fk_user = GETPOST("userid", 'int');
$object->timespent_fk_product = GETPOST("fk_product", 'int');
$result = $object->addTimeSpent($user);
if ($result >= 0) {
setEventMessages($langs->trans("RecordSaved"), null, 'mesgs');
@ -261,6 +264,7 @@ if (($action == 'updateline' || $action == 'updatesplitline') && !$cancel && $us
$object->timespent_date = dol_mktime(12, 0, 0, GETPOST("timelinemonth"), GETPOST("timelineday"), GETPOST("timelineyear"));
}
$object->timespent_fk_user = GETPOST("userid_line", 'int');
$object->timespent_fk_product = GETPOST("fk_product", 'int');
$result = $object->addTimeSpent($user);
if ($result >= 0) {
setEventMessages($langs->trans("RecordSaved"), null, 'mesgs');
@ -284,6 +288,7 @@ if (($action == 'updateline' || $action == 'updatesplitline') && !$cancel && $us
$object->timespent_date = dol_mktime(12, 0, 0, GETPOST("timelinemonth", 'int'), GETPOST("timelineday", 'int'), GETPOST("timelineyear", 'int'));
}
$object->timespent_fk_user = GETPOST("userid_line", 'int');
$object->timespent_fk_product = GETPOST("fk_product", 'int');
$result = $object->updateTimeSpent($user);
if ($result >= 0) {
@ -367,6 +372,7 @@ if ($action == 'confirm_generateinvoice') {
$fuser = new User($db);
$db->begin();
//TODO produit du temps passé ou produt id
$idprod = GETPOST('productid', 'int');
$generateinvoicemode = GETPOST('generateinvoicemode', 'string');
$invoiceToUse = GETPOST('invoiceid', 'int');
@ -1029,6 +1035,9 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser
}
$arrayfields['author'] = array('label'=>$langs->trans("By"), 'checked'=>1);
$arrayfields['t.note'] = array('label'=>$langs->trans("Note"), 'checked'=>1);
if ($conf->service->enabled && $projectstatic->thirdparty->id > 0 && $projectstatic->usage_bill_time) {
$arrayfields['t.fk_product'] = array('label' => $langs->trans("Product"), 'checked' => 1);
}
$arrayfields['t.task_duration'] = array('label'=>$langs->trans("Duration"), 'checked'=>1);
$arrayfields['value'] = array('label'=>$langs->trans("Value"), 'checked'=>1, 'enabled'=>(empty($conf->salaries->enabled) ? 0 : 1));
$arrayfields['valuebilled'] = array('label'=>$langs->trans("Billed"), 'checked'=>1, 'enabled'=>(((!empty($conf->global->PROJECT_HIDE_TASKS) || empty($conf->global->PROJECT_BILL_TIME_SPENT)) ? 0 : 1) && $projectstatic->usage_bill_time));
@ -1167,6 +1176,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser
$form->select_produits('', 'productid', '1', 0, $projectstatic->thirdparty->price_level, 1, 2, '', 0, array(), $projectstatic->thirdparty->id, 'None', 0, 'maxwidth500');
print '</td>';
print '</tr>';
//TODO : Use product of time affect
}
print '<tr>';
@ -1238,12 +1248,14 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser
$tasks = array();
$sql = "SELECT t.rowid, t.fk_task, t.task_date, t.task_datehour, t.task_date_withhour, t.task_duration, t.fk_user, t.note, t.thm,";
$sql .= " t.fk_product,";
$sql .= " pt.ref, pt.label, pt.fk_projet,";
$sql .= " u.lastname, u.firstname, u.login, u.photo, u.statut as user_status,";
$sql .= " il.fk_facture as invoice_id, inv.fk_statut";
$sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facturedet as il ON il.rowid = t.invoice_line_id";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facture as inv ON inv.rowid = il.fk_facture,";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facture as inv ON inv.rowid = il.fk_facture";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as prod ON prod.rowid = t.fk_product,";
$sql .= " ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."user as u";
$sql .= " WHERE t.fk_user = u.rowid AND t.fk_task = pt.rowid";
@ -1273,6 +1285,9 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser
if ($search_user > 0) {
$sql .= natural_search('t.fk_user', $search_user, 2);
}
if (!empty($search_product_ref)) {
$sql .= natural_search('prod.ref', $search_product_ref);
}
if ($search_valuebilled == '1') {
$sql .= ' AND t.invoice_id > 0';
}
@ -1365,6 +1380,10 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser
print '<td>'.$langs->trans("ProgressDeclared").'</td>';
if (empty($conf->global->PROJECT_HIDE_TASKS) && !empty($conf->global->PROJECT_BILL_TIME_SPENT)) {
print '<td></td>';
if ($conf->service->enabled && $projectstatic->thirdparty->id > 0 && $projectstatic->usage_bill_time) {
print '<td>'.$langs->trans("Product").'</td>';
}
}
print '<td></td>';
print "</tr>\n";
@ -1436,6 +1455,12 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser
if (empty($conf->global->PROJECT_HIDE_TASKS) && !empty($conf->global->PROJECT_BILL_TIME_SPENT)) {
print '<td>';
print '</td>';
if ($conf->service->enabled && $projectstatic->thirdparty->id > 0 && $projectstatic->usage_bill_time) {
print '<td class="nowrap">';
print $form->select_produits('', 'fk_product', '1', 0, $projectstatic->thirdparty->price_level, 1, 2, '', 0, array(), $projectstatic->thirdparty->id, 'None', 0, 'maxwidth500');
print '</td>';
}
}
print '<td class="center">';
@ -1509,6 +1534,10 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser
if (!empty($arrayfields['t.task_duration']['checked'])) {
print '<td class="liste_titre right"></td>';
}
// Product
if (!empty($arrayfields['t.fk_product']['checked'])) {
print '<td class="liste_titre right"></td>';
}
// Value in main currency
if (!empty($arrayfields['value']['checked'])) {
print '<td class="liste_titre"></td>';
@ -1557,6 +1586,10 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser
if (!empty($arrayfields['t.task_duration']['checked'])) {
print_liste_field_titre($arrayfields['t.task_duration']['label'], $_SERVER['PHP_SELF'], 't.task_duration', '', $param, '', $sortfield, $sortorder, 'right ');
}
if (!empty($arrayfields['t.fk_product']['checked'])) {
print_liste_field_titre($arrayfields['t.fk_product']['label'], $_SERVER['PHP_SELF'], 't.fk_product', '', $param, '', $sortfield, $sortorder, 'right ');
}
if (!empty($arrayfields['value']['checked'])) {
print_liste_field_titre($arrayfields['value']['label'], $_SERVER['PHP_SELF'], '', '', $param, '', $sortfield, $sortorder, 'right ');
}
@ -1732,6 +1765,24 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser
$totalarray['totalduration'] += $task_time->task_duration;
}
//Product
if (!empty($arrayfields['t.fk_product']['checked'])) {
print '<td class="nowraponall right">';
if ($action == 'editline' && $_GET['lineid'] == $task_time->rowid) {
$form->select_produits($task_time->fk_product, 'fk_product', '1', 0, $projectstatic->thirdparty->price_level, 1, 2, '', 0, array(), $projectstatic->thirdparty->id, 'None', 0, 'maxwidth500');
} elseif (!empty($task_time->fk_product)) {
$product = new Product($db);
$resultFetch = $product->fetch($task_time->fk_product);
if ($resultFetch < 0) {
setEventMessages($product->error, $product->errors, 'errors');
} else {
print $product->getNomUrl(1);
}
}
print '</td>';
}
// Value spent
if (!empty($arrayfields['value']['checked'])) {
$langs->load("salaries");