Merge branch '14.0' of git@github.com:Dolibarr/dolibarr.git into develop

Conflicts:
	htdocs/accountancy/admin/productaccount.php
	htdocs/core/class/html.form.class.php
	htdocs/langs/en_US/main.lang
This commit is contained in:
Laurent Destailleur 2021-10-04 14:53:44 +02:00
commit 6060f0bfb0
12 changed files with 68 additions and 31 deletions

View File

@ -179,14 +179,11 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog)
- Multi-Users and groups with finely grained rights - Multi-Users and groups with finely grained rights
- Multi-Currency - Multi-Currency
- Multi-Company (by adding of an external module) - Multi-Company (by adding of an external module)
- Very user friendly and easy to use - Very user friendly and easy to use
- customizable Dashboard - customizable Dashboard
- Highly customizable: enable only the modules you need, add user personalized fields, choose your skin, several menu managers (can be used by internal users as a back-office with a particular menu, or by external users as a front-office with another one) - Highly customizable: enable only the modules you need, add user personalized fields, choose your skin, several menu managers (can be used by internal users as a back-office with a particular menu, or by external users as a front-office with another one)
- APIs (REST, SOAP) - APIs (REST, SOAP)
- Code that is easy to understand, maintain and develop (PHP with no heavy framework; trigger and hook architecture) - Code that is easy to understand, maintain and develop (PHP with no heavy framework; trigger and hook architecture)
- Support a lot of country specific features: - Support a lot of country specific features:
- Spanish Tax RE and ISPF - Spanish Tax RE and ISPF
- French NPR VAT rate (VAT called "Non Perçue Récupérable" for DOM-TOM) - French NPR VAT rate (VAT called "Non Perçue Récupérable" for DOM-TOM)
@ -197,7 +194,7 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog)
- Compatible with European GDPR rules - Compatible with European GDPR rules
- ... - ...
- Flexible PDF & ODT generation for invoices, proposals, orders... - Flexible PDF & ODT generation for invoices, proposals, orders...
- … - ...
### System Environment / Requirements ### System Environment / Requirements

View File

@ -186,12 +186,28 @@ if ($action == 'update') {
$msg .= '<div><span style="color:red">'.$langs->trans("ErrorDB").' : '.$langs->trans("Product").' '.$productid.' '.$langs->trans("NotVentilatedinAccount").' : id='.$accounting_account_id.'<br> <pre>'.$sql.'</pre></span></div>'; $msg .= '<div><span style="color:red">'.$langs->trans("ErrorDB").' : '.$langs->trans("Product").' '.$productid.' '.$langs->trans("NotVentilatedinAccount").' : id='.$accounting_account_id.'<br> <pre>'.$sql.'</pre></span></div>';
$ko++; $ko++;
} else { } else {
$db->begin(); $sql = '';
if (!empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) { if (!empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) {
$sql = "INSERT INTO ".MAIN_DB_PREFIX."product_perentity (fk_product, entity, '".$db->escape($accountancy_field_name)."')"; $sql_exists = "SELECT rowid FROM " . MAIN_DB_PREFIX . "product_perentity";
$sql .= " VALUES (".((int) $productid).", ".((int) $conf->entity).", '".$db->escape($accounting->account_number)."')"; $sql_exists .= " WHERE fk_product = " . ((int) $productid) . " AND entity = " . ((int) $conf->entity);
$sql .= " ON DUPLICATE KEY UPDATE ".$accountancy_field_name." = '".$db->escape($accounting->account_number)."'"; $resql_exists = $db->query($sql_exists);
if (!$resql_exists) {
$msg .= '<div><span style="color:red">'.$langs->trans("ErrorDB").' : '.$langs->trans("Product").' '.$productid.' '.$langs->trans("NotVentilatedinAccount").' : id='.$accounting_account_id.'<br> <pre>'.$resql_exists.'</pre></span></div>';
$ko++;
} else {
$nb_exists = $db->num_rows($resql_exists);
if ($nb_exists <= 0) {
// insert
$sql = "INSERT INTO " . MAIN_DB_PREFIX . "product_perentity (fk_product, entity, '" . $db->escape($accountancy_field_name) . "')";
$sql .= " VALUES (" . ((int) $productid) . ", " . ((int) $conf->entity) . ", '" . $db->escape($accounting->account_number) . "')";
} else {
$obj_exists = $db->fetch_object($resql_exists);
// update
$sql = "UPDATE " . MAIN_DB_PREFIX . "product_perentity";
$sql .= " SET " . $accountancy_field_name . " = '" . $db->escape($accounting->account_number) . "'";
$sql .= " WHERE rowid = " . ((int) $obj_exists->rowid);
}
}
} else { } else {
$sql = " UPDATE ".MAIN_DB_PREFIX."product"; $sql = " UPDATE ".MAIN_DB_PREFIX."product";
$sql .= " SET ".$accountancy_field_name." = '".$db->escape($accounting->account_number)."'"; $sql .= " SET ".$accountancy_field_name." = '".$db->escape($accounting->account_number)."'";
@ -199,6 +215,9 @@ if ($action == 'update') {
} }
dol_syslog("/accountancy/admin/productaccount.php", LOG_DEBUG); dol_syslog("/accountancy/admin/productaccount.php", LOG_DEBUG);
$db->begin();
if ($db->query($sql)) { if ($db->query($sql)) {
$ok++; $ok++;
$db->commit(); $db->commit();

View File

@ -1680,11 +1680,6 @@ class Form
if ($resql) { if ($resql) {
$num = $this->db->num_rows($resql); $num = $this->db->num_rows($resql);
if ($conf->use_javascript_ajax && !$forcecombo && !$options_only) {
include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
$out .= ajax_combobox($htmlid, $events, getDolGlobalString("CONTACT_USE_SEARCH_TO_SELECT"));
}
if ($htmlname != 'none' && !$options_only) { if ($htmlname != 'none' && !$options_only) {
$out .= '<select class="flat'.($moreclass ? ' '.$moreclass : '').'" id="'.$htmlid.'" name="'.$htmlname.(($num || empty($disableifempty)) ? '' : ' disabled').($multiple ? '[]' : '').'" '.($multiple ? 'multiple' : '').' '.(!empty($moreparam) ? $moreparam : '').'>'; $out .= '<select class="flat'.($moreclass ? ' '.$moreclass : '').'" id="'.$htmlid.'" name="'.$htmlname.(($num || empty($disableifempty)) ? '' : ' disabled').($multiple ? '[]' : '').'" '.($multiple ? 'multiple' : '').' '.(!empty($moreparam) ? $moreparam : '').'>';
} }
@ -1815,6 +1810,11 @@ class Form
$out .= '</select>'; $out .= '</select>';
} }
if ($conf->use_javascript_ajax && !$forcecombo && !$options_only) {
include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
$out .= ajax_combobox($htmlid, $events, getDolGlobalString("CONTACT_USE_SEARCH_TO_SELECT"));
}
$this->num = $num; $this->num = $num;
return $out; return $out;
} else { } else {
@ -8789,8 +8789,8 @@ class Form
public function showFilterButtons() public function showFilterButtons()
{ {
$out = '<div class="nowraponall">'; $out = '<div class="nowraponall">';
$out .= '<button type="submit" class="liste_titre button_search" name="button_search_x" value="x"><span class="fa fa-search"></span></button>'; $out .= '<button type="submit" class="liste_titre button_search reposition" name="button_search_x" value="x"><span class="fa fa-search"></span></button>';
$out .= '<button type="submit" class="liste_titre button_removefilter" name="button_removefilter_x" value="x"><span class="fa fa-remove"></span></button>'; $out .= '<button type="submit" class="liste_titre button_removefilter reposition" name="button_removefilter_x" value="x"><span class="fa fa-remove"></span></button>';
$out .= '</div>'; $out .= '</div>';
return $out; return $out;

View File

@ -135,19 +135,19 @@ if ($permission) {
<input type="hidden" name="id" value="<?php echo $object->id; ?>" /> <input type="hidden" name="id" value="<?php echo $object->id; ?>" />
<input type="hidden" name="action" value="addcontact" /> <input type="hidden" name="action" value="addcontact" />
<input type="hidden" name="source" value="external" /> <input type="hidden" name="source" value="external" />
<input type="hidden" name="page_y" value="" />
<?php if (!empty($withproject)) { <?php if (!empty($withproject)) {
print '<input type="hidden" name="withproject" value="'.$withproject.'">'; print '<input type="hidden" name="withproject" value="'.$withproject.'">';
} ?> } ?>
<div class="tagtd nowrap maxwidthonsmartphone noborderbottom"> <div class="tagtd nowrap noborderbottom">
<?php <?php
$selectedCompany = GETPOSTISSET("newcompany") ? GETPOST("newcompany", 'int') : (empty($object->socid) ? 0 : $object->socid); $selectedCompany = GETPOSTISSET("newcompany") ? GETPOST("newcompany", 'int') : (empty($object->socid) ? 0 : $object->socid);
$selectedCompany = $formcompany->selectCompaniesForNewContact($object, 'id', $selectedCompany, 'newcompany', '', 0, '', 'minwidth300imp'); ?> $selectedCompany = $formcompany->selectCompaniesForNewContact($object, 'id', $selectedCompany, 'newcompany', '', 0, '', 'minwidth300imp'); ?>
</div> </div>
<!-- <div class="tagtd nowrap noborderbottom"><?php echo img_object('', 'contact').' '.$langs->trans("ThirdPartyContacts"); ?></div>--> <div class="tagtd noborderbottom minwidth500imp">
<div class="tagtd maxwidthonsmartphone noborderbottom">
<?php <?php
print img_object('', 'contact', 'class="pictofixedwidth"').$form->selectcontacts(($selectedCompany > 0 ? $selectedCompany : -1), '', 'contactid', 3, '', '', 1, 'minwidth100imp'); print img_object('', 'contact', 'class="pictofixedwidth"').$form->selectcontacts(($selectedCompany > 0 ? $selectedCompany : -1), '', 'contactid', 3, '', '', 1, 'minwidth100imp widthcentpercentminusxx maxwidth400');
$nbofcontacts = $form->num; $nbofcontacts = $form->num;
$newcardbutton = ''; $newcardbutton = '';
@ -157,7 +157,7 @@ if ($permission) {
print $newcardbutton; print $newcardbutton;
?> ?>
</div> </div>
<div class="tagtd maxwidthonsmartphone noborderbottom"> <div class="tagtd noborderbottom">
<?php <?php
$tmpobject = $object; $tmpobject = $object;
if (($object->element == 'shipping' || $object->element == 'reception') && is_object($objectsrc)) { if (($object->element == 'shipping' || $object->element == 'reception') && is_object($objectsrc)) {

View File

@ -643,6 +643,7 @@ print '<input type="hidden" name="action" value="list">';
print '<input type="hidden" name="sortfield" value="'.$sortfield.'">'; print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
print '<input type="hidden" name="sortorder" value="'.$sortorder.'">'; print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
print '<input type="hidden" name="contextpage" value="'.$contextpage.'">'; print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
print '<input type="hidden" name="page_y" value="">';
$title = $langs->trans("ListOfConferencesOrBooths"); $title = $langs->trans("ListOfConferencesOrBooths");

View File

@ -697,6 +697,7 @@ print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
print '<input type="hidden" name="contextpage" value="'.$contextpage.'">'; print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
print '<input type="hidden" name="withproject" value="'.$withproject.'">'; print '<input type="hidden" name="withproject" value="'.$withproject.'">';
print '<input type="hidden" name="fk_project" value="'.$fk_project.'">'; print '<input type="hidden" name="fk_project" value="'.$fk_project.'">';
print '<input type="hidden" name="page_y" value="">';
$newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/eventorganization/conferenceorboothattendee_card.php?action=create'.(!empty($confOrBooth->id)?'&conforboothid='.$confOrBooth->id:'').(!empty($projectstatic->id)?'&fk_project='.$projectstatic->id:'').$withProjectUrl.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?projectid='.$projectstatic->id.(empty($confOrBooth->id) ? '' : '&conforboothid='.$confOrBooth->id).$withProjectUrl), '', $permissiontoadd); $newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/eventorganization/conferenceorboothattendee_card.php?action=create'.(!empty($confOrBooth->id)?'&conforboothid='.$confOrBooth->id:'').(!empty($projectstatic->id)?'&fk_project='.$projectstatic->id:'').$withProjectUrl.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?projectid='.$projectstatic->id.(empty($confOrBooth->id) ? '' : '&conforboothid='.$confOrBooth->id).$withProjectUrl), '', $permissiontoadd);

View File

@ -846,7 +846,7 @@ class ProductFournisseur extends Product
$this->fourn_qty = $record["quantity"]; $this->fourn_qty = $record["quantity"];
$this->fourn_remise_percent = $record["remise_percent"]; $this->fourn_remise_percent = $record["remise_percent"];
$this->fourn_remise = $record["remise"]; $this->fourn_remise = $record["remise"];
$this->fourn_unitprice = $record["unitprice"]; $this->fourn_unitprice = $fourn_unitprice;
$this->fourn_charges = $record["charges"]; // deprecated $this->fourn_charges = $record["charges"]; // deprecated
$this->fourn_tva_tx = $record["tva_tx"]; $this->fourn_tva_tx = $record["tva_tx"];
$this->fourn_id = $record["fourn_id"]; $this->fourn_id = $record["fourn_id"];

View File

@ -133,7 +133,6 @@ IdModule=Module ID
IdPermissions=Permissions ID IdPermissions=Permissions ID
LanguageBrowserParameter=Parameter %s LanguageBrowserParameter=Parameter %s
LocalisationDolibarrParameters=Localization parameters LocalisationDolibarrParameters=Localization parameters
ClientTZ=Client Time Zone (user)
ClientHour=Client time (user) ClientHour=Client time (user)
OSTZ=Server OS Time Zone OSTZ=Server OS Time Zone
PHPTZ=PHP server Time Zone PHPTZ=PHP server Time Zone

View File

@ -1156,3 +1156,4 @@ RecordAproved=Record approved
RecordsApproved=%s Record(s) approved RecordsApproved=%s Record(s) approved
Properties=Properties Properties=Properties
hasBeenValidated=%s has been validated hasBeenValidated=%s has been validated
ClientTZ=Client Time Zone (user)

View File

@ -1089,6 +1089,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0) {
print '<input type="hidden" name="projectid" value="'.$projectidforalltimes.'">'; print '<input type="hidden" name="projectid" value="'.$projectidforalltimes.'">';
print '<input type="hidden" name="withproject" value="'.$withproject.'">'; print '<input type="hidden" name="withproject" value="'.$withproject.'">';
print '<input type="hidden" name="tab" value="'.$tab.'">'; print '<input type="hidden" name="tab" value="'.$tab.'">';
print '<input type="hidden" name="page_y" value="">';
// Form to convert time spent into invoice // Form to convert time spent into invoice
if ($massaction == 'generateinvoice') { if ($massaction == 'generateinvoice') {

View File

@ -1738,6 +1738,20 @@ td.showDragHandle {
display: inline-block; display: inline-block;
} }
/*
.classforhorizontalscrolloftabs .fiche .div-table-responsive
{
transform:rotateX(180deg);
-ms-transform:rotateX(180deg);
-webkit-transform:rotateX(180deg);
}
.classforhorizontalscrolloftabs .fiche .div-table-responsive-inside
{
transform:rotateX(180deg);
-ms-transform:rotateX(180deg);
-webkit-transform:rotateX(180deg);
}
*/
<?php if (empty($conf->global->THEME_DISABLE_STICKY_TOPMENU)) { ?> <?php if (empty($conf->global->THEME_DISABLE_STICKY_TOPMENU)) { ?>
@ -1848,10 +1862,11 @@ div.vmenu, td.vmenu {
display: none; display: none;
} }
/* if no side-nav, we don't need to have width forced */ /* if no side-nav, we don't need to have width forced to calc(100% - 210px); */
.classforhorizontalscrolloftabs #id-right { .classforhorizontalscrolloftabs #id-right {
width: unset; width: 100%;
display: unset; /* width: unset; */
/* display: unset; */
} }
body.sidebar-collapse .login_block { body.sidebar-collapse .login_block {

View File

@ -45,7 +45,7 @@ $show_files = GETPOST('show_files', 'int'); // Show files area generated by bulk
$confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation $confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation
$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button $cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button
$toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list $toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list
$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'tickep#selectedfieldstlist'; // To manage different context of search $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'ticketlist'; // To manage different context of search
$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page $backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page
$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
@ -698,6 +698,7 @@ print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
print '<input type="hidden" name="sortorder" value="'.$sortorder.'">'; print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
print '<input type="hidden" name="contextpage" value="'.$contextpage.'">'; print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
print '<input type="hidden" name="mode" value="'.$mode.'" >'; print '<input type="hidden" name="mode" value="'.$mode.'" >';
if ($socid) { if ($socid) {
print '<input type="hidden" name="socid" value="'.$socid.'" >'; print '<input type="hidden" name="socid" value="'.$socid.'" >';
} }
@ -759,6 +760,7 @@ $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfi
$selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : ''); $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table
print '<div class="div-table-responsive-inside">';
print '<table class="tagtable liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n"; print '<table class="tagtable liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
@ -1088,6 +1090,7 @@ print $hookmanager->resPrint;
print '</table>'."\n"; print '</table>'."\n";
print '</div>'."\n"; print '</div>'."\n";
print '</div>'."\n";
print '</form>'."\n"; print '</form>'."\n";