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

This commit is contained in:
Laurent Destailleur
2024-09-23 22:09:24 +02:00
17 changed files with 102 additions and 49 deletions

View File

@@ -81,7 +81,7 @@ if (!empty($update)) {
}
// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
$hookmanager->initHooks(array('bookkeepingccard', 'globalcard'));
$hookmanager->initHooks(array('bookkeepingcard', 'globalcard'));
$object = new BookKeeping($db);
@@ -376,10 +376,10 @@ if (empty($reshook)) {
if (!$error) {
foreach ($toselect as $toselectid) {
$result = $object->fetch($toselectid);
if ($result > 0 && (!isset($object->date_validation) || $object->date_validation === '')) {
if ($result >= 0 && (!isset($object->date_validation) || $object->date_validation === '')) {
$result = $object->deleteMvtNum($object->piece_num);
if ($result > 0) {
$nbok++;
if ($result >= 0) {
$nbok += $result;
} else {
setEventMessages($object->error, $object->errors, 'errors');
$error++;
@@ -767,12 +767,12 @@ if ($action == 'create') {
if (!empty($line->date_validation)) {
$atleastonevalidated = 1;
}
if (empty($line->date_export) && empty($line->date_validation)) {
if (!empty($line->date_export) || !empty($line->date_validation)) {
$atleastoneexported = 1;
}
}
if ($mode != '_tmp' && !$atleastonevalidated && !$atleastoneexported) {
if ($mode != '_tmp' && !$atleastonevalidated) {
print "\n".'<div class="tabsAction">'."\n";
$parameters = array();
@@ -780,7 +780,7 @@ if ($action == 'create') {
if (empty($reshook)) {
if ($permissiontodelete) {
if (!isset($hookmanager->resArray['no_button_edit']) || $hookmanager->resArray['no_button_edit'] != 1) {
print dolGetButtonAction('', $langs->trans('Delete'), 'delete', DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?action=deletebookkeepingwriting&confirm=yes&token='.newToken().'&toselect='.implode(',', $tmptoselect), '', $permissiontodelete);
print dolGetButtonAction('', $langs->trans('Delete'), 'delete', DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?action=deletebookkeepingwriting&confirm=yes&token='.newToken().'&piece_num='.((int) $object->piece_num).'&toselect='.implode(',', $tmptoselect), '', $permissiontodelete);
}
}
}

View File

@@ -1706,7 +1706,7 @@ class BookKeeping extends CommonObject
*
* @param int $piecenum Piecenum to delete
* @param string $mode Mode ('' or '_tmp')
* @return int Result
* @return int Nb of record deleted
*/
public function deleteMvtNum($piecenum, $mode = '')
{
@@ -1717,6 +1717,8 @@ class BookKeeping extends CommonObject
return -1;
}
$nbprocessed = 0;
$this->db->begin();
// first check if line not yet in bookkeeping
@@ -1737,10 +1739,13 @@ class BookKeeping extends CommonObject
}
$this->db->rollback();
return -1;
} else {
$nbprocessed = $this->db->affected_rows($resql);
}
$this->db->commit();
return 1;
return $nbprocessed;
}
/**

View File

@@ -229,7 +229,7 @@ class CMailFile
{
global $conf, $dolibarr_main_data_root, $user;
dol_syslog("CMailFile::CMailfile: charset=".$conf->file->character_set_client." from=$from, to=$to, addr_cc=$addr_cc, addr_bcc=$addr_bcc, errors_to=$errors_to, replyto=$replyto trackid=$trackid sendcontext=$sendcontext", LOG_DEBUG);
dol_syslog("CMailFile::CMailfile: charset=".$conf->file->character_set_client." from=$from, to=$to, addr_cc=$addr_cc, addr_bcc=$addr_bcc, errors_to=$errors_to, replyto=$replyto trackid=$trackid sendcontext=$sendcontext");
dol_syslog("CMailFile::CMailfile: subject=".$subject.", deliveryreceipt=".$deliveryreceipt.", msgishtml=".$msgishtml, LOG_DEBUG);
@@ -318,7 +318,7 @@ class CMailFile
if (getDolGlobalString('MAIN_MAIL_FORCE_CONTENT_TYPE_TO_HTML')) {
$this->msgishtml = 1; // To force to send everything with content type html.
}
dol_syslog("CMailFile::CMailfile: msgishtml=".$this->msgishtml);
dol_syslog("CMailFile::CMailfile: msgishtml=".$this->msgishtml, LOG_DEBUG);
// Detect images
if ($this->msgishtml) {
@@ -943,7 +943,7 @@ class CMailFile
if ($this->sendmode == 'mail') {
// Use mail php function (default PHP method)
// ------------------------------------------
dol_syslog("CMailFile::sendfile addr_to=".$this->addr_to.", subject=".$this->subject, LOG_DEBUG);
dol_syslog("CMailFile::sendfile addr_to=".$this->addr_to.", subject=".$this->subject, LOG_NOTICE);
//dol_syslog("CMailFile::sendfile header=\n".$this->headers, LOG_DEBUG);
//dol_syslog("CMailFile::sendfile message=\n".$message);
@@ -1181,7 +1181,7 @@ class CMailFile
}
if ($res) {
dol_syslog("CMailFile::sendfile: sendMsg, HOST=".$server.", PORT=" . getDolGlobalString($keyforsmtpport), LOG_DEBUG);
dol_syslog("CMailFile::sendfile: sendMsg, HOST=".$server.", PORT=" . getDolGlobalString($keyforsmtpport), LOG_NOTICE);
if (getDolGlobalString('MAIN_MAIL_DEBUG')) {
$this->smtps->setDebug(true);
@@ -1358,7 +1358,7 @@ class CMailFile
$this->mailer->registerPlugin(new Swift_Plugins_LoggerPlugin($this->logger));
}
dol_syslog("CMailFile::sendfile: mailer->send, HOST=".$server.", PORT=" . getDolGlobalString($keyforsmtpport), LOG_DEBUG);
dol_syslog("CMailFile::sendfile: mailer->send, HOST=".$server.", PORT=" . getDolGlobalString($keyforsmtpport), LOG_NOTICE);
// send mail
$failedRecipients = array();
@@ -1374,9 +1374,10 @@ class CMailFile
$res = true;
if (!empty($this->error) || !empty($this->errors) || !$result) {
if (!empty($failedRecipients)) {
$this->errors[] = 'Transport failed for the following addresses: "' . implode('", "', $failedRecipients) . '".';
$this->error = 'Transport failed for the following addresses: "' . implode('", "', $failedRecipients) . '".';
$this->errors[] = $this->error;
}
dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR);
dol_syslog("CMailFile::sendfile: mail end error=". join(' ', $this->errors), LOG_ERR);
$res = false;
if (getDolGlobalString('MAIN_MAIL_DEBUG')) {
@@ -1666,7 +1667,7 @@ class CMailFile
$out .= "Content-Type: multipart/mixed;".$this->eol2." boundary=\"".$this->mixed_boundary."\"".$this->eol2;
$out .= "Content-Transfer-Encoding: 8bit".$this->eol2; // TODO Seems to be ignored. Header is 7bit once received.
dol_syslog("CMailFile::write_smtpheaders smtp_header=\n".$out);
dol_syslog("CMailFile::write_smtpheaders smtp_header=\n".$out, LOG_DEBUG);
return $out;
}

View File

@@ -9144,7 +9144,7 @@ abstract class CommonObject
if (getDolGlobalString('MAIN_VIEW_LINE_NUMBER') && ($action == 'view' || $action == 'valid' || $action == 'editline' || $action == 'confirm_valid' || $action == 'confirm_cancel')) {
$out .= '<td></td>';
}
$out .= '<td class="'.(empty($params['tdclass']) ? 'titlefieldcreate' : $params['tdclass']).' wordbreak';
$out .= '<td class="'.(empty($params['tdclass']) ? 'titlefieldmax45' : $params['tdclass']).' wordbreak';
if ($extrafields->attributes[$this->table_element]['type'][$key] == 'text') {
$out .= ' tdtop';
}

View File

@@ -448,7 +448,7 @@ function getEntity($element, $shared = 1, $currentobject = null)
$out = $mc->getEntity($element, $shared, $currentobject);
} else {
$out = '';
$addzero = array('user', 'usergroup', 'cronjob', 'c_email_templates', 'email_template', 'default_values', 'overwrite_trans');
$addzero = array('user', 'usergroup', 'cronjob', 'c_email_templates', 'c_holiday_types', 'email_template', 'default_values', 'overwrite_trans');
if (in_array($element, $addzero)) {
$out .= '0,';
}

View File

@@ -400,8 +400,8 @@ class modStock extends DolibarrModules
$this->export_sql_end[$r] .= ' WHERE p.rowid = sm.fk_product AND sm.fk_entrepot = e.rowid';
$this->export_sql_end[$r] .= ' AND e.entity IN ('.getEntity('stock').')';
// Export inventory
// Export inventories
$r++;
$this->export_code[$r] = $this->rights_class.'_inventory';
$this->export_label[$r] = "Inventories"; // Translation key (used only if key ExportDataset_xxx_z not found)
@@ -409,7 +409,7 @@ class modStock extends DolibarrModules
$this->export_permission[$r] = array(array("stock", "lire"));
$this->export_fields_array[$r] = array(
'i.rowid' => 'InventoryId', 'i.ref' => 'InventoryRef', 'i.date_inventory' => 'DateInventory', 'i.status' => 'InventoryStatus', 'i.title' => 'InventoryTitle',
'id.rowid' => 'InventoryLineId', 'id.qty_view' => 'QtyViewed', 'id.qty_stock' => 'QtyStock', 'id.qty_regulated' => 'QtyRegulated', 'id.fk_warehouse' => 'InventoryEntrepot',
'id.rowid' => 'InventoryLineId', 'id.qty_view' => 'QtyViewed', 'id.qty_stock' => 'QtyStock', 'id.qty_regulated' => 'QtyRegulated',
'id.batch' => 'Lotserial',
'e.rowid' => 'IdWarehouse', 'e.ref' => 'LocationSummary', 'e.description' => 'DescWareHouse', 'e.lieu' => 'LieuWareHouse', 'e.address' => 'Address', 'e.zip' => 'Zip', 'e.town' => 'Town',
'p.rowid' => "ProductId", 'p.ref' => "Ref", 'p.fk_product_type' => "Type", 'p.label' => "Label", 'p.description' => "Description", 'p.note' => "Note",
@@ -438,7 +438,7 @@ class modStock extends DolibarrModules
if (isModEnabled('productbatch')) {
$this->export_fields_array[$r]['id.batch'] = 'Batch';
$this->export_TypeFields_array[$r]['id.batch'] = 'Text';
$this->export_entities_array[$r]['id.batch'] = 'movement';
$this->export_entities_array[$r]['id.batch'] = 'inventory_line';
}
if (isModEnabled('barcode')) {
$this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('p.barcode' => 'product'));

View File

@@ -586,14 +586,17 @@ class InterfaceWorkflowManager extends DolibarrTriggers
}
}
// Automatically create intervention
if (isModEnabled('intervention') && isModEnabled('ticket') && !empty($conf->workflow->enabled) && getDolGlobalString('WORKFLOW_TICKET_CREATE_INTERVENTION')) {
if (isModEnabled('intervention') && isModEnabled('ticket') && isModEnabled('workflow') && getDolGlobalString('WORKFLOW_TICKET_CREATE_INTERVENTION')) {
$fichinter = new Fichinter($this->db);
$fichinter->socid = (int) $object->fk_soc;
$fichinter->fk_project = (int) $object->fk_project;
$fichinter->fk_contrat = (int) $object->fk_contract;
$fichinter->user_author_id = $user->id;
$fichinter->model_pdf = (getDolGlobalString('FICHEINTER_ADDON_PDF')) ? $conf->global->FICHEINTER_ADDON_PDF : 'soleil';
$fichinter->model_pdf = getDolGlobalString('FICHEINTER_ADDON_PDF', 'soleil');
$fichinter->origin = $object->element;
$fichinter->origin_type = $object->element;
$fichinter->origin_id = $object->id;
// Extrafields

View File

@@ -41,8 +41,8 @@ TitreRequestCP=Leave request
TypeOfLeaveId=Type of leave ID
TypeOfLeaveCode=Type of leave code
TypeOfLeaveLabel=Type of leave label
NbUseDaysCP=Number of days of leave used
NbUseDaysCPHelp=The calculation takes into account the non-working days and the holidays defined in the dictionary.
NbUseDaysCP=Number of days
NbUseDaysCPHelp=The calculation of the number of days o fleave used takes into account the non-working days and the holidays defined in the dictionary.
NbUseDaysCPShort=Days of leave
NbUseDaysCPShortInMonth=Days of leave in month
DayIsANonWorkingDay=%s is a non-working day

View File

@@ -41,9 +41,9 @@ TitreRequestCP=Demande de congés
TypeOfLeaveId=Type de la demande de congès
TypeOfLeaveCode=Code du type de congès
TypeOfLeaveLabel=Libellé du type de congès
NbUseDaysCP=Nombre de jours de congés consommés
NbUseDaysCPHelp=Le calcul prend en compte les jours non ouvrés et les jours fériés définis dans le dictionnaire.
NbUseDaysCPShort=Jours consommés
NbUseDaysCP=Nombre de jours de congés
NbUseDaysCPHelp=Le calcul du nombre de jours de congés pris prend en compte les jours non ouvrés et les jours fériés définis dans le dictionnaire.
NbUseDaysCPShort=Jours
NbUseDaysCPShortInMonth=Jours consommés pour le mois
DayIsANonWorkingDay=%s est un jour non ouvré
DateStartInMonth=Date de début pour le mois

View File

@@ -341,7 +341,7 @@ InventoryId=ID d'inventaire
DateInventory=Date d'inventaire
InventoryStatus=Statut inventaire
InventoryTitle=Nom de l'inventaire
InventoryLineId=Ligne d'inventaire
InventoryLineId=ID Ligne d'inventaire
InventoryRef=Réf d'inventaire
QtyViewed=Quantité vue
QtyStock=Quantité en stock

View File

@@ -356,12 +356,14 @@ if ($result || !($id > 0)) {
}
if (isModEnabled('order')) {
$langs->load("orders");
$graphfiles['orders'] = array('modulepart' => 'productstats_orders',
'file' => $object->id.'/orders12m'.((string) $type != '' ? '_type'.$type : '').'_'.$mode.($search_year > 0 ? '_year'.$search_year : '').'.png',
'label' => $langs->transnoentitiesnoconv($arrayforlabel[$mode], $langs->transnoentitiesnoconv("Orders")));
}
if (isModEnabled('supplier_order')) {
$langs->load("orders");
$graphfiles['orderssuppliers'] = array('modulepart' => 'productstats_orderssuppliers',
'file' => $object->id.'/orderssuppliers12m'.((string) $type != '' ? '_type'.$type : '').'_'.$mode.($search_year > 0 ? '_year'.$search_year : '').'.png',
'label' => $langs->transnoentitiesnoconv($arrayforlabel[$mode], $langs->transnoentitiesnoconv("SuppliersOrders")));

View File

@@ -33,7 +33,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formorder.class.php';
// Load translation files required by the page
$langs->loadLangs(array('orders', 'products', 'companies'));
$langs->loadLangs(array('orders', 'products', 'companies', 'sendings'));
$id = GETPOSTINT('id');
$ref = GETPOST('ref', 'alpha');

View File

@@ -198,6 +198,13 @@ if ($action == 'order' && GETPOST('valid') && $user->hasRight('fournisseur', 'co
// TODO Get desc in language of thirdparty
}
// If we use multicurrency
if (isModEnabled('multicurrency') && !empty($productsupplier->fourn_multicurrency_code) && $productsupplier->fourn_multicurrency_code != $conf->currency) {
$line->multicurrency_code = $productsupplier->fourn_multicurrency_code;
$line->fk_multicurrency = $productsupplier->fourn_multicurrency_id;
$line->multicurrency_subprice = $productsupplier->fourn_multicurrency_unitprice;
}
$line->tva_tx = $productsupplier->vatrate_supplier;
$line->subprice = $productsupplier->fourn_pu;
$line->total_ht = $productsupplier->fourn_pu * $qty;
@@ -267,7 +274,8 @@ if ($action == 'order' && GETPOST('valid') && $user->hasRight('fournisseur', 'co
null,
null,
0,
$line->fk_unit
$line->fk_unit,
$line->multicurrency_subprice ?? 0
);
}
if ($result < 0) {
@@ -282,6 +290,7 @@ if ($action == 'order' && GETPOST('valid') && $user->hasRight('fournisseur', 'co
} else {
$order->socid = $suppliersid[$i];
$order->fetch_thirdparty();
$order->multicurrency_code = $order->thirdparty->multicurrency_code;
// Trick to know which orders have been generated using the replenishment feature
$order->source = $order::SOURCE_ID_REPLENISHMENT;

View File

@@ -93,10 +93,11 @@ $hookmanager->initHooks(array('publicnewmembercard', 'globalcard'));
$extrafields = new ExtraFields($db);
$objectsoc = new Societe($db);
$user->loadDefaultValues();
$extrafields->fetch_name_optionals_label($objectsoc->table_element); // fetch optionals attributes and labels
/**
* Show header for new prospect
@@ -217,26 +218,26 @@ if (empty($reshook) && $action == 'add') { // Test on permission not required he
$societe = new Societe($db);
$societe->name = GETPOST('name', 'alphanohtml');
$societe->client = GETPOSTINT('client') ? GETPOSTINT('client') : $societe->client;
$societe->address = GETPOST('address', 'alphanohtml');
$societe->country_id = GETPOSTINT('country_id');
$societe->phone = GETPOST('phone', 'alpha');
$societe->fax = GETPOST('fax', 'alpha');
$societe->email = trim(GETPOST('email', 'custom', 0, FILTER_SANITIZE_EMAIL));
$societe->client = 2 ; // our client is a prospect
$societe->code_client = '-1';
$societe->name_alias = GETPOST('name_alias', 'alphanohtml');
$societe->note_private = GETPOST('note_private', 'alphanohtml');
$societe->note_private = GETPOST('note_private');
// Fill array 'array_options' with data from add form
/*
$extrafields->fetch_name_optionals_label($societe->table_element);
$ret = $extrafields->setOptionalsFromPost(null, $societe);
if ($ret < 0) {
$error++;
$errmsg .= $societe->error;
}
*/
$nb_post_max = getDolGlobalInt("MAIN_SECURITY_MAX_POST_ON_PUBLIC_PAGES_BY_IP_ADDRESS", 200);
@@ -304,7 +305,6 @@ $form = new Form($db);
$formcompany = new FormCompany($db);
$adht = new AdherentType($db);
$formadmin = new FormAdmin($db);
$extrafields->fetch_name_optionals_label($objectsoc->table_element); // fetch optionals attributes and labels
llxHeaderVierge($langs->trans("ContactUs"));
@@ -442,10 +442,15 @@ print '<tr>';
print '<td class="tdtop">' . $langs->trans("Comments") . '</td>';
print '<td class="tdtop"><textarea name="note_private" id="note_private" wrap="soft" class="quatrevingtpercent" rows="' . ROWS_3 . '">' . dol_escape_htmltag(GETPOST('note_private', 'restricthtml'), 0, 1) . '</textarea></td>';
print '</tr>' . "\n";
// Other attributes
$parameters['tpl_context'] = 'public'; // define template context to public
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php';
// TODO Move this into generic feature.
// Display Captcha code if is enabled
if (getDolGlobalString('MAIN_SECURITY_ENABLECAPTCHA')) {
require_once DOL_DOCUMENT_ROOT . '/core/lib/security2.lib.php';

View File

@@ -87,7 +87,9 @@ if ($type == 'conf') {
}
$conference = new ConferenceOrBooth($db);
$confattendee = new ConferenceOrBoothAttendee($db);
$project = new Project($db);
$object = $confattendee;
if ($type == 'conf') {
$resultconf = $conference->fetch($id);
@@ -152,6 +154,8 @@ if (empty($conf->eventorganization->enabled)) {
httponly_accessforbidden('Module Event organization not enabled');
}
$extrafields->fetch_name_optionals_label($object->table_element); // fetch optionals attributes and labels
/**
* Show header for new member
@@ -265,8 +269,6 @@ if (empty($reshook) && $action == 'add' && (!empty($conference->id) && $conferen
if (!$error) {
// Check if attendee already exists (by email and for this event)
$confattendee = new ConferenceOrBoothAttendee($db);
$filter = array();
if ($type == 'global') {
@@ -293,6 +295,15 @@ if (empty($reshook) && $action == 'add' && (!empty($conference->id) && $conferen
$confattendee->firstname = $firstname;
$confattendee->lastname = $lastname;
// Fill array 'array_options' with data from add form
$extrafields->fetch_name_optionals_label($confattendee->table_element);
$ret = $extrafields->setOptionalsFromPost(null, $confattendee);
if ($ret < 0) {
$error++;
$errmsg .= $confattendee->error;
}
// Count recent already posted event
$confattendee->ip = getUserRemoteIP();
$nb_post_max = getDolGlobalInt("MAIN_SECURITY_MAX_POST_ON_PUBLIC_PAGES_BY_IP_ADDRESS", 200);
$now = dol_now();
@@ -489,6 +500,7 @@ if (empty($reshook) && $action == 'add' && (!empty($conference->id) && $conferen
$tmpcode = $modCodeClient->getNextValue($thirdparty, 0);
}
$thirdparty->code_client = $tmpcode;
$readythirdparty = $thirdparty->create($user);
if ($readythirdparty < 0) {
$error++;
@@ -892,14 +904,20 @@ if ((!empty($conference->id) && $conference->status == ConferenceOrBooth::STATUS
print '</td></tr>';
}
// Other attributes
$parameters['tpl_context'] = 'public'; // define template context to public
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php';
$notetoshow = $note_public;
print '<tr><td>' . $langs->trans('Note') . '</td><td>';
if (getDolGlobalString('EVENTORGANIZATION_DEFAULT_NOTE_ON_REGISTRATION')) {
$notetoshow = str_replace('\n', "\n", $conf->global->EVENTORGANIZATION_DEFAULT_NOTE_ON_REGISTRATION);
$notetoshow = str_replace('\n', "\n", getDolGlobalString('EVENTORGANIZATION_DEFAULT_NOTE_ON_REGISTRATION'));
}
print '<textarea name="note_public" class="centpercent" rows="'.ROWS_9.'">'.dol_escape_htmltag($notetoshow, 0, 1).'</textarea>';
print '</td></tr>';
print "</table>\n";
print dol_get_fiche_end();

View File

@@ -1708,6 +1708,11 @@ table.paymenttable td.amountpaymentcomplete, table.paymenttable td.amountremaint
.fa-15 {
font-size: 1.5em;
}
.fa-map-marked-alt:before {
font-size: 0.85em;
}
.text-security {
-webkit-text-security: disc;
}

View File

@@ -1897,6 +1897,11 @@ select.flat.selectlimit {
.fa-15 {
font-size: 1.5em;
}
.fa-map-marked-alt:before {
font-size: 0.85em;
}
.text-security {
-webkit-text-security: disc;
}