diff --git a/htdocs/accountancy/customer/lines.php b/htdocs/accountancy/customer/lines.php
index 884de9dd232..55700fe8439 100644
--- a/htdocs/accountancy/customer/lines.php
+++ b/htdocs/accountancy/customer/lines.php
@@ -458,8 +458,8 @@ if ($result) {
$productstatic->accountancy_code_sell_export = $objp->accountancy_code_sell_export;
$accountingaccountstatic->rowid = $objp->fk_compte;
- $accountingaccountstatic->label = $objp->label;
- $accountingaccountstatic->labelshort = $objp->labelshort;
+ $accountingaccountstatic->label = $objp->label_account;
+ $accountingaccountstatic->labelshort = $objp->labelshort_account;
$accountingaccountstatic->account_number = $objp->account_number;
print '
';
diff --git a/htdocs/accountancy/supplier/lines.php b/htdocs/accountancy/supplier/lines.php
index 4a3b8cd53ac..da8bc0cd5e9 100644
--- a/htdocs/accountancy/supplier/lines.php
+++ b/htdocs/accountancy/supplier/lines.php
@@ -194,7 +194,7 @@ print '';
+ $sql .= $this->db->order('ctc.pos', 'ASC');
+ $resql = $this->db->query($sql);
+ if ($resql) {
+ $num_rows = $this->db->num_rows($resql);
+ $i = 0;
+ $arrayidused=array();
+ while ($i < $num_rows) {
+ $obj = $this->db->fetch_object($resql);
+ if ($obj) {
+ $grouprowid = $obj->rowid;
+ $groupvalue = $obj->code;
+ $grouplabel = $obj->label;
+ $isparent = $obj->isparent;
+ $fatherid = $obj->fk_parent;
+ $arrayidused[] = $grouprowid;
+ $groupcodefather = $obj->codefather;
+ if ($isparent == 'NOTPARENT') {
+ $arraycodenotparent[] = $groupvalue;
+ }
+ $iselected = $groupticketchild == $obj->code ?'selected':'';
+ $stringtoprint .= ''.dol_escape_htmltag($grouplabel).' ';
+ if (empty($tabscript[$groupcodefather])) {
+ $tabscript[$groupcodefather] = 'if($("#'.$htmlname.($levelid > 1 ?'_child_'.$levelid-1:'').'")[0].value == "'.dol_escape_js($groupcodefather).'"){
+ $(".'.$htmlname.'_'.dol_escape_htmltag($fatherid).'_child_'.$levelid.'").show()
+ console.log("We show childs tickets of '.$groupcodefather.' group ticket")
+ }else{
+ $(".'.$htmlname.'_'.dol_escape_htmltag($fatherid).'_child_'.$levelid.'").hide()
+ console.log("We hide childs tickets of '.$groupcodefather.' group ticket")
+ }';
+ }
+ }
+ $i++;
+ }
+ } else {
+ dol_print_error($this->db);
+ }
+ $stringtoprint .='';
+
+ $stringtoprint .='';
+ }
return $stringtoprint;
}
}
diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php
index d20a0348d3d..1ba9e0e3d1c 100644
--- a/htdocs/core/lib/project.lib.php
+++ b/htdocs/core/lib/project.lib.php
@@ -1306,6 +1306,13 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr
$oldprojectforbreak = (empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT) ? 0 : -1); // 0 to start break , -1 no break
}
+ $restrictBefore = null;
+
+ if (! empty($conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS)) {
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
+ $restrictBefore = dol_time_plus_duree(dol_now(), - $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS, 'm');
+ }
+
//dol_syslog('projectLinesPerDay inc='.$inc.' preselectedday='.$preselectedday.' task parent id='.$parent.' level='.$level." count(lines)=".$numlines." count(lineswithoutlevel0)=".count($lineswithoutlevel0));
for ($i = 0; $i < $numlines; $i++) {
if ($parent == 0) {
@@ -1551,6 +1558,10 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr
$disabledtask = 1;
}
+ if ($restrictBefore && $preselectedday < $restrictBefore) {
+ $disabledtask = 1;
+ }
+
// Form to add new time
print '';
$tableCell = $form->selectDate($preselectedday, $lines[$i]->id, 1, 1, 2, "addtime", 0, 0, $disabledtask);
@@ -1699,6 +1710,13 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$
$oldprojectforbreak = (empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT) ? 0 : -1); // 0 = start break, -1 = never break
}
+ $restrictBefore = null;
+
+ if (! empty($conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS)) {
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
+ $restrictBefore = dol_time_plus_duree(dol_now(), - $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS, 'm');
+ }
+
for ($i = 0; $i < $numlines; $i++) {
if ($parent == 0) {
$level = 0;
@@ -1977,6 +1995,12 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$
$cssweekend = 'weekend';
}
+ $disabledtaskday = $disabledtask;
+
+ if (! $disabledtask && $restrictBefore && $tmpday < $restrictBefore) {
+ $disabledtaskday = 1;
+ }
+
$tableCell = ' ';
//$tableCell .= 'idw='.$idw.' '.$conf->global->MAIN_START_WEEK.' '.$numstartworkingday.'-'.$numendworkingday;
$placeholder = '';
@@ -1985,7 +2009,7 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$
//$placeholder=' placeholder="00:00"';
//$tableCell.='+';
}
- $tableCell .= ' ';
@@ -2079,6 +2103,13 @@ function projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &
$oldprojectforbreak = (empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT) ? 0 : -1); // 0 = start break, -1 = never break
}
+ $restrictBefore = null;
+
+ if (! empty($conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS)) {
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
+ $restrictBefore = dol_time_plus_duree(dol_now(), - $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS, 'm');
+ }
+
for ($i = 0; $i < $numlines; $i++) {
if ($parent == 0) {
$level = 0;
@@ -2231,10 +2262,11 @@ function projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &
$modeinput = 'hours';
$TFirstDay = getFirstDayOfEachWeek($TWeek, date('Y', $firstdaytoshow));
$TFirstDay[reset($TWeek)] = 1;
- foreach ($TFirstDay as &$fday) {
- $fday--;
- }
- foreach ($TWeek as $weekNb) {
+
+ $firstdaytoshowarray = dol_getdate($firstdaytoshow);
+ $year = $firstdaytoshowarray['year'];
+ $month = $firstdaytoshowarray['mon'];
+ foreach ($TWeek as $weekIndex => $weekNb) {
$weekWorkLoad = $projectstatic->monthWorkLoadPerTask[$weekNb][$lines[$i]->id];
$totalforeachweek[$weekNb] += $weekWorkLoad;
@@ -2244,6 +2276,12 @@ function projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &
}
$alttitle = $langs->trans("AddHereTimeSpentForWeek", $weekNb);
+ $disabledtaskweek = $disabledtask;
+ $firstdayofweek = dol_mktime(0, 0, 0, $month, $TFirstDay[$weekIndex], $year);
+
+ if (! $disabledtask && $restrictBefore && $firstdayofweek < $restrictBefore) {
+ $disabledtaskweek = 1;
+ }
$tableCell = ' ';
$placeholder = '';
@@ -2253,7 +2291,7 @@ function projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &
//$tableCell.='+';
}
- $tableCell .= ' ';
diff --git a/htdocs/fourn/paiement/list.php b/htdocs/fourn/paiement/list.php
index 4da69cfc0c1..80654e9a4ae 100644
--- a/htdocs/fourn/paiement/list.php
+++ b/htdocs/fourn/paiement/list.php
@@ -8,7 +8,7 @@
* Copyright (C) 2014 Teddy Andreotti <125155@supinfo.com>
* Copyright (C) 2015 Marcos García
* Copyright (C) 2015 Juanjo Menent
- * Copyright (C) 2017 Alexandre Spangaro
+ * Copyright (C) 2017-2021 Alexandre Spangaro
* Copyright (C) 2018-2021 Frédéric France
* Copyright (C) 2020 Tobias Sekan
* Copyright (C) 2021 Ferran Marcet
@@ -36,6 +36,7 @@
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
// Load translation files required by the page
$langs->loadLangs(array('companies', 'bills', 'banks', 'compta'));
@@ -48,14 +49,19 @@ $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 've
$socid = GETPOST('socid', 'int');
$search_ref = GETPOST('search_ref', 'alpha');
-$search_day = GETPOST('search_day', 'int');
-$search_month = GETPOST('search_month', 'int');
-$search_year = GETPOST('search_year', 'int');
-$search_company = GETPOST('search_company', 'alpha');
+$search_date_startday = GETPOST('search_date_startday', 'int');
+$search_date_startmonth = GETPOST('search_date_startmonth', 'int');
+$search_date_startyear = GETPOST('search_date_startyear', 'int');
+$search_date_endday = GETPOST('search_date_endday', 'int');
+$search_date_endmonth = GETPOST('search_date_endmonth', 'int');
+$search_date_endyear = GETPOST('search_date_endyear', 'int');
+$search_date_start = dol_mktime(0, 0, 0, $search_date_startmonth, $search_date_startday, $search_date_startyear); // Use tzserver
+$search_date_end = dol_mktime(23, 59, 59, $search_date_endmonth, $search_date_endday, $search_date_endyear);
+$search_company = GETPOST('search_company', 'alpha');
$search_payment_type = GETPOST('search_payment_type');
-$search_cheque_num = GETPOST('search_cheque_num', 'alpha');
+$search_cheque_num = GETPOST('search_cheque_num', 'alpha');
$search_bank_account = GETPOST('search_bank_account', 'int');
-$search_amount = GETPOST('search_amount', 'alpha'); // alpha because we must be able to search on '< x'
+$search_amount = GETPOST('search_amount', 'alpha'); // alpha because we must be able to search on '< x'
$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST('sortfield', 'alpha');
@@ -135,9 +141,14 @@ if (empty($reshook)) {
if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
$search_ref = '';
- $search_day = '';
- $search_month = '';
- $search_year = '';
+ $search_date_startday = '';
+ $search_date_startmonth = '';
+ $search_date_startyear = '';
+ $search_date_endday = '';
+ $search_date_endmonth = '';
+ $search_date_endyear = '';
+ $search_date_start = '';
+ $search_date_end = '';
$search_company = '';
$search_payment_type = '';
$search_cheque_num = '';
@@ -187,7 +198,13 @@ if ($socid > 0) {
if ($search_ref) {
$sql .= natural_search('p.ref', $search_ref);
}
-$sql .= dolSqlDateFilter('p.datep', $search_day, $search_month, $search_year);
+if ($search_date_start) {
+ $sql .= " AND p.datep >= '" . $db->idate($search_date_start) . "'";
+}
+if ($search_date_end) {
+ $sql .=" AND p.datep <= '" . $db->idate($search_date_end) . "'";
+}
+
if ($search_company) {
$sql .= natural_search('s.nom', $search_company);
}
@@ -254,14 +271,23 @@ if ($optioncss != '') {
if ($search_ref) {
$param .= '&search_ref='.urlencode($search_ref);
}
-if ($search_day) {
- $param .= '&search_day='.urlencode($search_day);
+if ($search_date_startday) {
+ $param .= '&search_date_startday='.urlencode($search_date_startday);
}
-if ($search_month) {
- $param .= '&search_month='.urlencode($search_month);
+if ($search_date_startmonth) {
+ $param .= '&search_date_startmonth='.urlencode($search_date_startmonth);
}
-if ($search_year) {
- $param .= '&search_year='.urlencode($search_year);
+if ($search_date_startyear) {
+ $param .= '&search_date_startyear='.urlencode($search_date_startyear);
+}
+if ($search_date_endday) {
+ $param .= '&search_date_endday='.urlencode($search_date_endday);
+}
+if ($search_date_endmonth) {
+ $param .= '&search_date_endmonth='.urlencode($search_date_endmonth);
+}
+if ($search_date_endyear) {
+ $param .= '&search_date_endyear='.urlencode($search_date_endyear);
}
if ($search_company) {
$param .= '&search_company='.urlencode($search_company);
@@ -336,11 +362,12 @@ if (!empty($arrayfields['p.ref']['checked'])) {
// Filter: Date
if (!empty($arrayfields['p.datep']['checked'])) {
print '';
- if (!empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) {
- print ' ';
- }
- print ' ';
- $formother->select_year($search_year ? $search_year : -1, 'search_year', 1, 20, 5);
+ print '';
+ print $form->selectDate($search_date_start ? $search_date_start : -1, 'search_date_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
+ print '
';
+ print '';
+ print $form->selectDate($search_date_end ? $search_date_end : -1, 'search_date_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
+ print '
';
print ' ';
}
diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
index a05c9e7ea97..cc7e207ad4c 100644
--- a/htdocs/langs/en_US/admin.lang
+++ b/htdocs/langs/en_US/admin.lang
@@ -84,6 +84,7 @@ NumberOfBytes=Number of Bytes
SearchString=Search string
NotAvailableWhenAjaxDisabled=Not available when Ajax disabled
AllowToSelectProjectFromOtherCompany=On document of a third party, can choose a project linked to another third party
+TimesheetPreventAfterFollowingMonths=Prevent recording time spent after the following number of months
JavascriptDisabled=JavaScript disabled
UsePreviewTabs=Use preview tabs
ShowPreview=Show preview
diff --git a/htdocs/langs/en_US/projects.lang b/htdocs/langs/en_US/projects.lang
index 2fda7e1df0e..c5679cf5774 100644
--- a/htdocs/langs/en_US/projects.lang
+++ b/htdocs/langs/en_US/projects.lang
@@ -140,6 +140,7 @@ NoTasks=No tasks for this project
LinkedToAnotherCompany=Linked to other third party
TaskIsNotAssignedToUser=Task not assigned to user. Use button '%s ' to assign task now.
ErrorTimeSpentIsEmpty=Time spent is empty
+TimeRecordingRestrictedToNMonthsBack=Time recording is restricted to %s months back
ThisWillAlsoRemoveTasks=This action will also delete all tasks of project (%s tasks at the moment) and all inputs of time spent.
IfNeedToUseOtherObjectKeepEmpty=If some objects (invoice, order, ...), belonging to another third party, must be linked to the project to create, keep this empty to have the project being multi third parties.
CloneTasks=Clone tasks
diff --git a/htdocs/langs/nl_NL/main.lang b/htdocs/langs/nl_NL/main.lang
index 9c0fcdfa791..d730795c8c0 100644
--- a/htdocs/langs/nl_NL/main.lang
+++ b/htdocs/langs/nl_NL/main.lang
@@ -616,9 +616,9 @@ MonthVeryShort11=N
MonthVeryShort12=D
AttachedFiles=Bijgevoegde bestanden en documenten
JoinMainDoc=Word hoofddocument
-DateFormatYYYYMM=JJJJ-MM
-DateFormatYYYYMMDD=JJJJ-MM-DD
-DateFormatYYYYMMDDHHMM=JJJJ-MM-DD HH: SS
+DateFormatYYYYMM=YYYY-MM
+DateFormatYYYYMMDD=YYYY-MM-DD
+DateFormatYYYYMMDDHHMM=YYYY-MM-DD HH: SS
ReportName=Rapportnaam
ReportPeriod=Periode-analyse
ReportDescription=Omschrijving
diff --git a/htdocs/projet/admin/project.php b/htdocs/projet/admin/project.php
index 288e2282a40..eaea44dd22b 100644
--- a/htdocs/projet/admin/project.php
+++ b/htdocs/projet/admin/project.php
@@ -219,6 +219,10 @@ if ($action == 'updateMaskTask') {
$projectToSelect = GETPOST('projectToSelect', 'alpha');
dolibarr_set_const($db, 'PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY', $projectToSelect, 'chaine', 0, '', $conf->entity); //Allow to disable this configuration if empty value
}
+ if (GETPOST('PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS')) {
+ $timesheetFreezeDuration = GETPOST('timesheetFreezeDuration', 'alpha');
+ dolibarr_set_const($db, 'PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS', intval($timesheetFreezeDuration), 'chaine', 0, '', $conf->entity); //Allow to disable this configuration if empty value
+ }
} elseif (preg_match('/^(set|del)_?([A-Z_]+)$/', $action, $reg)) {
// Set boolean (on/off) constants
if (!dolibarr_set_const($db, $reg[2], ($reg[1] === 'set' ? '1' : '0'), 'chaine', 0, '', $conf->entity) > 0) {
@@ -797,6 +801,7 @@ print ' ';
print ' ';
+print ' ';
$key = 'PROJECT_CLASSIFY_CLOSED_WHEN_ALL_TASKS_DONE';
echo '