Merge branch '16.0' into 16.0-issue-23799

This commit is contained in:
Laurent Destailleur 2023-03-12 17:47:02 +01:00 committed by GitHub
commit f6b8cd0208
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
63 changed files with 325 additions and 171 deletions

View File

@ -41,7 +41,7 @@ $ref = GETPOST('ref', 'alpha');
$rowid = GETPOST('rowid', 'int');
$cancel = GETPOST('cancel', 'alpha');
$account_number = GETPOST('account_number', 'string');
$account_number = GETPOST('account_number', 'alphanohtml');
$label = GETPOST('label', 'alpha');
// Security check

View File

@ -743,7 +743,7 @@ class AccountancyCategory // extends CommonObject
}
$listofaccount .= "'".$cptcursor."'";
}
$sql .= " AND t.numero_compte IN (".$this->db->sanitize($listofaccount).")";
$sql .= " AND t.numero_compte IN (".$this->db->sanitize($listofaccount, 1).")";
} else {
$sql .= " AND t.numero_compte = '".$this->db->escape($cpt)."'";
}
@ -861,20 +861,29 @@ class AccountancyCategory // extends CommonObject
exit();
}
$pcgverid = $conf->global->CHARTOFACCOUNTS;
$pcgvercode = dol_getIdFromCode($this->db, $pcgverid, 'accounting_system', 'rowid', 'pcg_version');
if (empty($pcgvercode)) {
$pcgvercode = $pcgverid;
}
if (!empty($cat_id)) {
$sql = "SELECT t.rowid, t.account_number, t.label as account_label";
$sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as t";
$sql .= " WHERE t.fk_accounting_category = ".((int) $cat_id);
$sql .= " AND t.entity = ".$conf->entity;
$sql .= " AND t.active = 1";
$sql .= " AND t.fk_pcg_version = '".$this->db->escape($pcgvercode)."'";
$sql .= " ORDER BY t.account_number";
} else {
$sql = "SELECT t.rowid, t.account_number, t.label as account_label";
$sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as t";
$sql .= " WHERE ".$predefinedgroupwhere;
$sql .= " AND t.entity = ".$conf->entity;
$sql .= ' AND t.active = 1';
$sql .= " AND t.fk_pcg_version = '".$this->db->escape($pcgvercode)."'";
$sql .= " ORDER BY t.account_number";
}
//echo $sql;
$resql = $this->db->query($sql);
if ($resql) {

View File

@ -297,6 +297,7 @@ class Lettering extends BookKeeping
// Update request
$now = dol_now();
$affected_rows = 0;
if (!$error) {
$sql = "UPDATE ".MAIN_DB_PREFIX."accounting_bookkeeping SET";
@ -309,6 +310,8 @@ class Lettering extends BookKeeping
if (!$resql) {
$error++;
$this->errors[] = "Error ".$this->db->lasterror();
} else {
$affected_rows = $this->db->affected_rows($resql);
}
}
@ -320,7 +323,7 @@ class Lettering extends BookKeeping
}
return -1 * $error;
} else {
return 1;
return $affected_rows;
}
}
@ -355,7 +358,7 @@ class Lettering extends BookKeeping
}
return -1 * $error;
} else {
return 1;
return $this->db->affected_rows($resql);
}
}
@ -457,7 +460,7 @@ class Lettering extends BookKeeping
else $result = $this->updateLettering($bookkeeping_lines);
if ($result < 0) {
$group_error++;
} else {
} elseif ($result > 0) {
$nb_lettering++;
}
}
@ -655,7 +658,7 @@ class Lettering extends BookKeeping
// Get payment lines
$sql = "SELECT DISTINCT pe2.$fk_payment_element, pe2.$fk_element";
$sql .= " FROM " . MAIN_DB_PREFIX . "$payment_element AS pe";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "$payment_element AS pe2 ON pe2.$fk_element = pe.$fk_element";
$sql .= " INNER JOIN " . MAIN_DB_PREFIX . "$payment_element AS pe2 ON pe2.$fk_element = pe.$fk_element";
$sql .= " WHERE pe.$fk_payment_element IN (" . $this->db->sanitize(implode(',', $payment_ids)) . ")";
dol_syslog(__METHOD__ . " - Get payment lines", LOG_DEBUG);

View File

@ -797,6 +797,12 @@ if (!$error && $action == 'writebookkeeping') {
require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php';
$lettering_static = new Lettering($db);
$nb_lettering = $lettering_static->bookkeepingLetteringAll(array($bookkeeping->id));
if ($nb_lettering < 0) {
$error++;
$errorforline++;
setEventMessages($lettering_static->error, $lettering_static->errors, 'errors');
}
}
}
}

View File

@ -380,6 +380,12 @@ if ($action == 'writebookkeeping') {
require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php';
$lettering_static = new Lettering($db);
$nb_lettering = $lettering_static->bookkeepingLettering(array($bookkeeping->id), 'supplier_invoice');
if ($nb_lettering < 0) {
$error++;
$errorforline++;
setEventMessages($lettering_static->error, $lettering_static->errors, 'errors');
}
}
}
}

View File

@ -393,6 +393,13 @@ if ($action == 'writebookkeeping') {
require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php';
$lettering_static = new Lettering($db);
$nb_lettering = $lettering_static->bookkeepingLettering(array($bookkeeping->id), 'customer_invoice');
if ($nb_lettering < 0) {
$error++;
$errorforline++;
$errorforinvoice[$key] = 'other';
setEventMessages($lettering_static->error, $lettering_static->errors, 'errors');
}
}
}
}

View File

@ -512,7 +512,7 @@ $tabcond[25] = !empty($conf->website->enabled);
$tabcond[27] = !empty($conf->societe->enabled);
$tabcond[28] = !empty($conf->holiday->enabled);
$tabcond[29] = !empty($conf->project->enabled);
$tabcond[30] = !empty($conf->label->enabled);
$tabcond[30] = (isModEnabled('label') || isModEnabled('barcode') || isModEnabled('adherent')); // stickers format dictionary
//$tabcond[31]= !empty($conf->accounting->enabled);
$tabcond[32] = (!empty($conf->holiday->enabled) || !empty($conf->hrm->enabled));
$tabcond[33] = !empty($conf->hrm->enabled);

View File

@ -4,7 +4,7 @@ LOG INALTERABLE
## Fonctionnalité
Ce module trace, en temps réel, certains évènements métiers dans une log inaltérable (que vous ne pouvez pas modifier une fois enregistrés) de type blockchain.
Ce module est requis pour la compatibilité avec les exigences légales de certains pays (comme la France avec la loi Fincance 2016 - Norme NF535).
Ce module est requis pour la compatibilité avec les exigences légales de certains pays (comme la France avec la loi Finance 2016 - Norme NF525).
**Les évènements tracés de manière inaltérables sont:**

View File

@ -4,7 +4,7 @@ BLOCKED LOG
## Feature
This module tracks, in real time, some events into a non reversible log (that you can't modify once recorded) into a block chain.
This module provides compatibility with requirements of laws of some countries (like France with the law Fincance 2016 - Norme NF535).
This module provides compatibility with requirements of laws of some countries (like France with the law Finance 2016 - Norme NF525).
**The tracked events are:**

View File

@ -1,5 +1,6 @@
<?php
/* Copyright (C) 2019 Laurent Destailleur <eldy@users.sourceforge.net>
/* Copyright (C) 2019 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2023 Benjamin Falière <benjamin.faliere@altairis.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -1058,8 +1059,10 @@ class BOM extends CommonObject
return -1;
}
$line->unit_cost = price2num((!empty($tmpproduct->cost_price)) ? $tmpproduct->cost_price : $tmpproduct->pmp);
if (empty($line->unit_cost)) {
if ($productFournisseur->find_min_price_product_fournisseur($line->fk_product) > 0) {
if ((empty($line->unit_cost)) && ($productFournisseur->find_min_price_product_fournisseur($line->fk_product) > 0)) {
if ($productFournisseur->fourn_remise_percent != "0") {
$line->unit_cost = $productFournisseur->fourn_unitprice_with_discount;
} else {
$line->unit_cost = $productFournisseur->fourn_unitprice;
}
}

View File

@ -11,6 +11,7 @@
* Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
* Copyright (C) 2016 Charlie Benke <charlie@patas-monkey.com>
* Copyright (C) 2018-2022 Frédéric France <frederic.france@netlogic.fr>
* Copyright (C) 2023 Benjamin Falière <benjamin.faliere@altairis.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -1463,7 +1464,7 @@ class Categorie extends CommonObject
$ways = array();
$parents = $this->get_meres();
if (!empty($parents)) {
if (is_array($parents)) {
foreach ($parents as $parent) {
$allways = $parent->get_all_ways();
foreach ($allways as $way) {

View File

@ -1261,7 +1261,7 @@ if ($action == 'create') {
print "\n".'<script type="text/javascript">';
print '$(document).ready(function () {
$("#projectid").change(function () {
var url = "'.DOL_URL_ROOT.'/projet/ajax/projects.php?mode=gettasks&socid="+$("#projectid").val()+"&projectid="+$("#projectid").val();
var url = "'.DOL_URL_ROOT.'/projet/ajax/projects.php?mode=gettasks&socid="+$("#search_socid").val()+"&projectid="+$("#projectid").val();
console.log("Call url to get new list of tasks: "+url);
$.get(url, function(data) {
console.log(data);

View File

@ -412,7 +412,7 @@ if ($usergroup > 0) {
}
$sql .= " s.nom as societe, s.rowid as socid, s.client, s.email as socemail,";
$sql .= " a.id, a.code, a.label, a.note, a.datep as dp, a.datep2 as dp2, a.fulldayevent, a.location,";
$sql .= ' a.fk_user_author,a.fk_user_action,';
$sql .= " a.fk_user_author, a.fk_user_action,";
$sql .= " a.fk_contact, a.note, a.percent as percent,";
$sql .= " a.fk_element, a.elementtype, a.datec, a.tms as datem,";
$sql .= " c.code as type_code, c.libelle as type_label, c.color as type_color, c.type as type_type, c.picto as type_picto,";
@ -916,6 +916,7 @@ while ($i < $imaxinloop) {
$actionstatic->note_private = dol_htmlentitiesbr($obj->note);
$actionstatic->datep = $db->jdate($obj->dp);
$actionstatic->percentage = $obj->percent;
$actionstatic->authorid = $obj->fk_user_author;
// Initialize $this->userassigned && this->socpeopleassigned array && this->userownerid
// but only if we need it

View File

@ -915,6 +915,10 @@ while ($currentdaytoshow < $lastdaytoshow) {
if ($usergroup > 0) {
$sql .= " AND ug.fk_usergroup = ".((int) $usergroup);
}
if ($user->socid > 0) {
// External users should see only contacts of their company
$sql .= " AND u.fk_soc = ".((int) $user->socid);
}
//print $sql;
$resql = $db->query($sql);

View File

@ -5,7 +5,7 @@
* Copyright (C) 2005 Marc Barilley / Ocebo <marc@ocebo.com>
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr>
* Copyright (C) 2010-2016 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2010-2023 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2010-2021 Philippe Grand <philippe.grand@atoo-net.com>
* Copyright (C) 2012-2013 Christophe Battarel <christophe.battarel@altairis.fr>
* Copyright (C) 2012 Cedric Salvador <csalvador@gpcsolutions.fr>
@ -132,7 +132,6 @@ $permissiontoedit = $usercancreate; // Used by the include of actions_lineupdown
// Security check
if (!empty($user->socid)) {
$socid = $user->socid;
$object->id = $user->socid;
}
restrictedArea($user, 'propal', $object->id);

View File

@ -248,13 +248,14 @@ class PropaleStats extends Stats
global $user;
$sql = "SELECT product.ref, COUNT(product.ref) as nb, SUM(tl.".$this->field_line.") as total, AVG(tl.".$this->field_line.") as avg";
$sql .= " FROM ".$this->from.", ".$this->from_line.", ".MAIN_DB_PREFIX."product as product";
$sql .= " FROM ".$this->from;
$sql .= " INNER JOIN ".$this->from_line." ON p.rowid = tl.fk_propal";
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."product as product ON tl.fk_product = product.rowid";
if (empty($user->rights->societe->client->voir) && !$user->socid) {
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
}
$sql .= $this->join;
$sql .= " WHERE ".$this->where;
$sql .= " AND p.rowid = tl.fk_propal AND tl.fk_product = product.rowid";
$sql .= " AND ".$this->field_date." BETWEEN '".$this->db->idate(dol_get_first_day($year, 1, false))."' AND '".$this->db->idate(dol_get_last_day($year, 12, false))."'";
$sql .= " GROUP BY product.ref";
$sql .= $this->db->order('nb', 'DESC');

View File

@ -187,7 +187,7 @@ $search_array_options = $extrafields->getOptionalsFromPost($object->table_elemen
// List of fields to search into when doing a "search in all"
$fieldstosearchall = array(
'p.ref'=>'Ref',
'p.ref_client'=>'CustomerRef',
'p.ref_client'=>'RefCustomer',
'pd.description'=>'Description',
's.nom'=>"ThirdParty",
's.name_alias'=>"AliasNameShort",

View File

@ -3038,7 +3038,11 @@ if ($action == 'create') {
}
// when bank account is empty (means not override by payment mode form a other object, like third-party), try to use default value
$fk_account = GETPOSTISSET("fk_account") ? GETPOST("fk_account", 'int') : $fk_account;
if ($socid > 0 && $fk_account) { // A company has already been set and it has a default fk_account
$fk_account = GETPOSTISSET('fk_account') ? GETPOST("fk_account", 'int') : $fk_account; // The GETPOST is used only if form was posted to avoid to take default value, because in such case, the default must be the one of the company
} else { // No company forced
$fk_account = GETPOST("fk_account", 'int');
}
if (!empty($soc->id)) {
$absolute_discount = $soc->getAvailableDiscounts();

View File

@ -1703,11 +1703,11 @@ if ($resql) {
$with_margin_info = false;
if (isModEnabled('margin') && (
!empty($arrayfields['total_pa']['checked'])
|| !empty($arrayfields['total_margin']['checked'])
|| !empty($arrayfields['total_margin_rate']['checked'])
|| !empty($arrayfields['total_mark_rate']['checked'])
)
!empty($arrayfields['total_pa']['checked'])
|| !empty($arrayfields['total_margin']['checked'])
|| !empty($arrayfields['total_margin_rate']['checked'])
|| !empty($arrayfields['total_mark_rate']['checked'])
)
) {
$with_margin_info = true;
}

View File

@ -311,7 +311,11 @@ if ($id) {
print img_object($langs->trans("ShowBill"), "bill");
print '</a>&nbsp;';
print '<a href="'.DOL_URL_ROOT.'/compta/facture/card.php?facid='.$obj->facid.'">'.$obj->ref."</a></td>\n";
if ($type == 'bank-transfer') {
print '<a href="'.DOL_URL_ROOT.'/fourn/facture/card.php?facid='.$obj->facid.'">'.$obj->ref."</a></td>\n";
} else {
print '<a href="'.DOL_URL_ROOT.'/compta/facture/card.php?facid='.$obj->facid.'">'.$obj->ref."</a></td>\n";
}
print '<td><a href="'.DOL_URL_ROOT.'/comm/card.php?socid='.$obj->socid.'">';
print img_object($langs->trans("ShowCompany"), "company").' '.$obj->name."</a></td>\n";

View File

@ -334,6 +334,9 @@ if ($modecompta == 'CREANCES-DETTES') {
// Previous Fiscal year (N-1)
foreach ($sommes as $code => $det) {
if (is_null($det['NP'])) {
$det['NP'] = 0;
}
$vars[$code] = $det['NP'];
}
@ -341,8 +344,11 @@ if ($modecompta == 'CREANCES-DETTES') {
//var_dump($result);
//$r = $AccCat->calculate($result);
$r = dol_eval($result, 1, 1, '1');
//var_dump($r);
if (is_nan($r)) {
$r = 0;
}
print '<td class="liste_total right"><span class="amount">'.price($r).'</span></td>';
@ -361,6 +367,9 @@ if ($modecompta == 'CREANCES-DETTES') {
//$r = $AccCat->calculate($result);
$r = dol_eval($result, 1, 1, 1);
if (is_nan($r)) {
$r = 0;
}
print '<td class="liste_total right"><span class="amount">'.price($r).'</span></td>';
$sommes[$code]['N'] += $r;
@ -375,6 +384,9 @@ if ($modecompta == 'CREANCES-DETTES') {
//$r = $AccCat->calculate($result);
$r = dol_eval($result, 1, 1, 1);
if (is_nan($r)) {
$r = 0;
}
print '<td class="liste_total right"><span class="amount">'.price($r).'</span></td>';
$sommes[$code]['M'][$k] += $r;
@ -389,6 +401,9 @@ if ($modecompta == 'CREANCES-DETTES') {
//$r = $AccCat->calculate($result);
$r = dol_eval($result, 1, 1, 1);
if (is_nan($r)) {
$r = 0;
}
print '<td class="liste_total right"><span class="amount">'.price($r).'</span></td>';
$sommes[$code]['M'][$k] += $r;
@ -417,8 +432,10 @@ if ($modecompta == 'CREANCES-DETTES') {
$arrayofaccountforfilter = array();
foreach ($cpts as $i => $cpt) { // Loop on each account.
$arrayofaccountforfilter[] = $cpt['account_number'];
foreach ($cpts as $i => $cpt) {// Loop on each account.
if (!empty($cpt['account_number'])) {
$arrayofaccountforfilter[] = $cpt['account_number'];
}
}
// N-1

View File

@ -239,9 +239,9 @@ if ($modecompta == 'CREANCES-DETTES') {
$sql .= " sum(f.total_ht) as amount, sum(f.total_ttc) as amount_ttc";
$sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f, ".MAIN_DB_PREFIX."societe as s";
if ($selected_cat === -2) { // Without any category
$sql .= " LEFT OUTER JOIN ".MAIN_DB_PREFIX."categorie_societe as cs ON s.rowid = cs.fk_soc";
$sql .= " LEFT OUTER JOIN ".MAIN_DB_PREFIX."categorie_fournisseur as cs ON s.rowid = cs.fk_soc";
} elseif ($selected_cat) { // Into a specific category
$sql .= ", ".MAIN_DB_PREFIX."categorie as c, ".MAIN_DB_PREFIX."categorie_societe as cs";
$sql .= ", ".MAIN_DB_PREFIX."categorie as c, ".MAIN_DB_PREFIX."categorie_fournisseur as cs";
}
$sql .= " WHERE f.fk_statut in (1,2)";
$sql .= " AND f.type IN (0,2)";
@ -266,9 +266,9 @@ if ($modecompta == 'CREANCES-DETTES') {
$sql .= ", ".MAIN_DB_PREFIX."paiementfourn as p";
$sql .= ", ".MAIN_DB_PREFIX."societe as s";
if ($selected_cat === -2) { // Without any category
$sql .= " LEFT OUTER JOIN ".MAIN_DB_PREFIX."categorie_societe as cs ON s.rowid = cs.fk_soc";
$sql .= " LEFT OUTER JOIN ".MAIN_DB_PREFIX."categorie_fournisseur as cs ON s.rowid = cs.fk_soc";
} elseif ($selected_cat) { // Into a specific category
$sql .= ", ".MAIN_DB_PREFIX."categorie as c, ".MAIN_DB_PREFIX."categorie_societe as cs";
$sql .= ", ".MAIN_DB_PREFIX."categorie as c, ".MAIN_DB_PREFIX."categorie_fournisseur as cs";
}
$sql .= " WHERE p.rowid = pf.fk_paiementfourn";
$sql .= " AND pf.fk_facturefourn = f.rowid";

View File

@ -63,6 +63,7 @@ class CMailFile
public $atleastonefile;
public $msg;
public $eol;
public $eol2;
@ -142,6 +143,9 @@ 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: subject=".$subject.", deliveryreceipt=".$deliveryreceipt.", msgishtml=".$msgishtml, LOG_DEBUG);
// Clean values of $mimefilename_list
if (is_array($mimefilename_list)) {
foreach ($mimefilename_list as $key => $val) {
@ -184,9 +188,6 @@ class CMailFile
// On defini alternative_boundary
$this->alternative_boundary = 'mul_'.dol_hash(uniqid("dolibarr3"), 3); // Force md5 hash (does not contains special chars)
dol_syslog("CMailFile::CMailfile: sendmode=".$this->sendmode." 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: subject=".$subject.", deliveryreceipt=".$deliveryreceipt.", msgishtml=".$msgishtml, LOG_DEBUG);
if (empty($subject)) {
dol_syslog("CMailFile::CMailfile: Try to send an email with empty subject");
$this->error = 'ErrorSubjectIsRequired';
@ -314,6 +315,8 @@ class CMailFile
}
}
dol_syslog("CMailFile::CMailfile: sendmode=".$this->sendmode." addr_bcc=$addr_bcc, replyto=$replyto", LOG_DEBUG);
// We set all data according to choosed sending method.
// We also set a value for ->msgid
if ($this->sendmode == 'mail') {

View File

@ -6066,6 +6066,8 @@ abstract class CommonObject
if (!empty($extrafields->attributes[$this->table_element]) && !empty($extrafields->attributes[$this->table_element]['computed'][$key])) {
//var_dump($conf->disable_compute);
if (empty($conf->disable_compute)) {
global $objectoffield; // We set a global variable to $objectoffield so
$objectoffield = $this; // we can use it inside computed formula
$this->array_options["options_".$key] = dol_eval($extrafields->attributes[$this->table_element]['computed'][$key], 1, 0, '');
}
}
@ -6296,7 +6298,6 @@ abstract class CommonObject
$new_array_options[$key] = $object->id;
} else {
$this->error = "Id/Ref '".$value."' for object '".$object->element."' not found";
$this->db->rollback();
return -1;
}
}

View File

@ -4054,7 +4054,7 @@ class Form
public function select_conditions_paiements($selected = 0, $htmlname = 'condid', $filtertype = -1, $addempty = 0, $noinfoadmin = 0, $morecss = '', $deposit_percent = -1)
{
// phpcs:enable
print $this->getSelectConditionsPaiements($selected, $htmlname, $filtertype, $addempty, $noinfoadmin, $morecss, $deposit_percent = -1);
print $this->getSelectConditionsPaiements($selected, $htmlname, $filtertype, $addempty, $noinfoadmin, $morecss, $deposit_percent);
}

View File

@ -175,6 +175,7 @@ class FormTicket
print '<form method="POST" '.($withdolfichehead ? '' : 'style="margin-bottom: 30px;" ').'name="ticket" id="form_create_ticket" enctype="multipart/form-data" action="'.(!empty($this->param["returnurl"]) ? $this->param["returnurl"] : "").'">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="'.$this->action.'">';
print '<input type="hidden" name="trackid" value="'.$this->trackid.'">';
foreach ($this->param as $key => $value) {
print '<input type="hidden" name="'.$key.'" value="'.$value.'">';
}
@ -1251,7 +1252,7 @@ class FormTicket
$langs->loadLangs(array('other', 'mails'));
// Clear temp files. Must be done at beginning, before call of triggers
if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) {
if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelselected') && GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) {
$this->clear_attached_files();
}
@ -1284,8 +1285,8 @@ class FormTicket
$listofmimes = array();
$keytoavoidconflict = empty($this->track_id) ? '' : '-'.$this->track_id; // track_id instead of trackid
if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) {
if (!empty($arraydefaultmessage->joinfiles) && is_array($this->param['fileinit'])) {
if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelselected') && GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) {
if (!empty($arraydefaultmessage->joinfiles) && !empty($this->param['fileinit']) && is_array($this->param['fileinit'])) {
foreach ($this->param['fileinit'] as $file) {
$formmail->add_attached_files($file, basename($file), dol_mimetype($file));
}

View File

@ -1058,7 +1058,7 @@ class Ldap
if (is_array($attributeArray)) {
// Return list with required fields
$attributeArray = array_values($attributeArray); // This is to force to have index reordered from 0 (not make ldap_search fails)
dol_syslog(get_class($this)."::getRecords connection=".$this->connection." userDn=".$userDn." filter=".$filter." attributeArray=(".join(',', $attributeArray).")");
dol_syslog(get_class($this)."::getRecords connection=".get_resource_type($this->connection)." userDn=".$userDn." filter=".$filter." attributeArray=(".join(',', $attributeArray).")");
//var_dump($attributeArray);
$this->result = @ldap_search($this->connection, $userDn, $filter, $attributeArray);
} else {

View File

@ -3410,7 +3410,7 @@ function dol_print_phone($phone, $countrycode = '', $cid = 0, $socid = 0, $addli
$type = 'AC_FAX';
}
if (!empty($conf->global->AGENDA_ADDACTIONFORPHONE)) {
$link = '<a href="'.DOL_URL_ROOT.'/comm/action/card.php?action=create&amp;backtopage=1&amp;actioncode='.$type.($cid ? '&amp;contactid='.$cid : '').($socid ? '&amp;socid='.$socid : '').'">'.img_object($langs->trans("AddAction"), "calendar").'</a>';
$link = '<a href="'.DOL_URL_ROOT.'/comm/action/card.php?action=create&amp;backtopage='. urlencode($_SERVER['REQUEST_URI']) .'&amp;actioncode='.$type.($cid ? '&amp;contactid='.$cid : '').($socid ? '&amp;socid='.$socid : '').'">'.img_object($langs->trans("AddAction"), "calendar").'</a>';
}
if ($link) {
$newphone = '<div>'.$newphone.' '.$link.'</div>';
@ -8599,10 +8599,12 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1'
// Only global variables can be changed by eval function and returned to caller
global $db, $langs, $user, $conf, $website, $websitepage;
global $action, $mainmenu, $leftmenu;
global $mysoc;
global $objectoffield;
// Old variables used
global $rights;
global $object;
global $mysoc;
global $obj; // To get $obj used into list when dol_eval is used for computed fields and $obj is not yet $object
global $soc; // For backward compatibility

View File

@ -281,13 +281,16 @@ function getNumberInvoicesPieChart($mode)
$sql .= ", sum(".$db->ifsql("f.date_lim_reglement > '".date_format($datenowadd15, 'Y-m-d')."'", 1, 0).") as nbnotlate15";
$sql .= ", sum(".$db->ifsql("f.date_lim_reglement > '".date_format($datenowadd30, 'Y-m-d')."'", 1, 0).") as nbnotlate30";
if ($mode == 'customers') {
$element = 'invoice';
$sql .= " FROM ".MAIN_DB_PREFIX."facture as f";
} elseif ($mode == 'fourn' || $mode == 'suppliers') {
$element = 'supplier_invoice';
$sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f";
} else {
return '';
}
$sql .= " WHERE f.type <> 2";
$sql .= " WHERE f.entity IN (".getEntity($element).")";
$sql .= " AND f.type <> 2";
$sql .= " AND f.fk_statut = 1";
if (isset($user->socid) && $user->socid > 0) {
$sql .= " AND f.fk_soc = ".((int) $user->socid);

View File

@ -2436,10 +2436,12 @@ function pdf_getLinkedObjects(&$object, $outputlangs)
$linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefSending");
if (! empty($linkedobjects[$objecttype]['ref_value'])) $linkedobjects[$objecttype]['ref_value'] .= ' / ';
$linkedobjects[$objecttype]['ref_value'] .= $outputlangs->transnoentities($elementobject->ref);
$linkedobjects[$objecttype]['date_value'] = dol_print_date(empty($elementobject->date_shipping) ? $elementobject->date_delivery : $elementobject->date_shipping, 'day', '', $outputlangs);
} else {
$linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefOrder").' / '.$outputlangs->transnoentities("RefSending");
if (empty($linkedobjects[$objecttype]['ref_value'])) $linkedobjects[$objecttype]['ref_value'] = $outputlangs->convToOutputCharset($order->ref).($order->ref_client ? ' ('.$order->ref_client.')' : '');
$linkedobjects[$objecttype]['ref_value'] .= ' / '.$outputlangs->transnoentities($elementobject->ref);
$linkedobjects[$objecttype]['date_value'] = dol_print_date(empty($elementobject->date_shipping) ? $elementobject->date_delivery : $elementobject->date_shipping, 'day', '', $outputlangs);
}
}
}

View File

@ -682,7 +682,7 @@ function checkUserAccessToObject($user, array $featuresarray, $object = 0, $tabl
// Array to define rules of checks to do
$check = array('adherent', 'banque', 'bom', 'don', 'mrp', 'user', 'usergroup', 'payment', 'payment_supplier', 'product', 'produit', 'service', 'produit|service', 'categorie', 'resource', 'expensereport', 'holiday', 'salaries', 'website', 'recruitment'); // Test on entity only (Objects with no link to company)
$checksoc = array('societe'); // Test for societe object
$checkother = array('contact', 'agenda', 'contrat'); // Test on entity + link to third party on field $dbt_keyfield. Allowed if link is empty (Ex: contacts...).
$checkother = array('contact', 'agenda', 'contrat'); // Test on entity + link to third party on field $dbt_keyfield. Allowed if link is empty (Ex: contacts...).
$checkproject = array('projet', 'project'); // Test for project object
$checktask = array('projet_task'); // Test for task object
$checkhierarchy = array('expensereport', 'holiday');

View File

@ -120,7 +120,7 @@ function getOnlineSignatureUrl($mode, $type, $ref = '', $localorexternal = 1)
// For multicompany
if (!empty($out) && !empty($conf->multicompany->enabled)) {
$out .= "&entity=".$conf->entity; // Check the entity because we may have the same reference in several entities
$out .= "&entity=".$object->entity; // Check the entity because we may have the same reference in several entities
}
return $out;

View File

@ -230,7 +230,7 @@ class pdf_strato extends ModelePDFContract
$default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
$heightforinfotot = 50; // Height reserved to output the info and total part
$heightforfreetext = (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT) ? $conf->global->MAIN_PDF_FREETEXT_HEIGHT : 5); // Height reserved to output the free text on last page
$heightforfooter = $this->marge_basse + 8; // Height reserved to output the footer (value include bottom margin)
$heightforfooter = $this->marge_basse + 9; // Height reserved to output the footer (value include bottom margin)
if (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS)) {
$heightforfooter += 6;
}
@ -383,7 +383,6 @@ class pdf_strato extends ModelePDFContract
$pdf->writeHTMLCell(0, 0, $curX, $curY, dol_concatdesc($txtpredefinedservice, dol_concatdesc($txt, $desc)), 0, 1, 0);
$pageposafter = $pdf->getPage();
$posyafter = $pdf->GetY();
if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text
if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page
$pdf->AddPage('', '', true);
@ -437,6 +436,9 @@ class pdf_strato extends ModelePDFContract
$pagenb++;
$pdf->setPage($pagenb);
$pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) {
$this->_pagehead($pdf, $object, 0, $outputlangs);
}
if (!empty($tplidx)) {
$pdf->useTemplate($tplidx);
}
@ -459,6 +461,7 @@ class pdf_strato extends ModelePDFContract
}
}
// Show square
if ($pagenb == 1) {
$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0);

View File

@ -240,7 +240,7 @@ class modFacture extends DolibarrModules
'f.ref' => 'InvoiceRef*',
'f.ref_ext' => 'ExternalRef',
'f.ref_int' => 'ExternalRef',
'f.ref_client' => 'CustomerRef',
'f.ref_client' => 'RefCustomer',
'f.type' => 'Type*',
'f.fk_soc' => 'Customer*',
'f.datec' => 'InvoiceDateCreation',

View File

@ -393,6 +393,13 @@ class pdf_aurore extends ModelePDFSupplierProposal
}
}
}
// Extrafields in note
$extranote = $this->getExtrafieldsInHtml($object, $outputlangs);
if (!empty($extranote)) {
$notetoshow = dol_concatdesc($notetoshow, $extranote);
}
if ($notetoshow) {
$tab_top -= 2;

View File

@ -19,7 +19,7 @@
*/
/**
* \file htdocs/multicompany_page.php
* \file htdocs/core/multicompany_page.php
* \brief File to return a page with the list of all entities user can switch to
*/
@ -41,7 +41,7 @@ if (!defined('NOREQUIREMENU')) {
require_once '../main.inc.php';
$action = GETPOST('action', 'aZ09');
$action = GETPOST('action', 'aZ');
$entityid = GETPOST('entity', 'int');
$backtourl = GETPOST('backtourl');
if (empty($backtourl)) {
@ -63,7 +63,7 @@ $left = ($langs->trans("DIRECTION") == 'rtl' ? 'right' : 'left');
* Actions
*/
if (GETPOST('acction', 'aZ') == 'switchentity') {
if ($action == 'switchentity') {
if (is_object($mc)) {
$mc->switchEntity($entityid);
}

View File

@ -187,10 +187,11 @@ if (($line->info_bits & 2) == 2) {
if ($line->date_start || $line->date_end) {
print '<div class="clearboth nowraponall opacitymedium daterangeofline">'.get_date_range($line->date_start, $line->date_end, $format).'</div>';
}
if (!$line->date_start || !$line->date_end) {
// show warning under line
// we need to fetch product associated to line for some test
if ($object->element == 'propal' || $object->element == 'order' || $object->element == 'propal_supplier' || $object->element == 'supplier_proposal' || $object->element == 'commande') {
if ($object->element == 'propal' || $object->element == 'order' || $object->element == 'facture' || $object->element == 'propal_supplier' || $object->element == 'supplier_proposal' || $object->element == 'commande') {
$res = $line->fetch_product();
if ($res > 0 ) {
if ($line->product->isService() && $line->product->isMandatoryPeriod()) {

View File

@ -1980,7 +1980,7 @@ class EmailCollector extends CommonObject
'ticket' => array('table' => 'ticket',
'fields' => array('ref'),
'class' => 'ticket/class/ticket.class.php',
'object' => ' Ticket'),
'object' => 'Ticket'),
'knowledgemanagement' => array('table' => 'knowledgemanagement_knowledgerecord',
'fields' => array('ref'),
'class' => 'knowledgemanagement/class/knowledgemanagement.class.php',
@ -1998,7 +1998,7 @@ class EmailCollector extends CommonObject
'class' => 'compta/facture/class/facture.class.php',
'object' => 'Facture'),
'fournisseur/facture' => array('table' => 'facture_fourn',
'fields' => array('ref', ref_client),
'fields' => array('ref', 'ref_client'),
'class' => 'fourn/class/fournisseur.facture.class.php',
'object' => 'FactureFournisseur'),
'produit' => array('table' => 'product',

View File

@ -5,6 +5,7 @@
* Copyright (C) 2016-2021 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2019 Nicolas ZABOURI <info@inovea-conseil.com>
* Copyright (C) 2020 Thibault FOUCART <support@ptibogxiv.net>
* Copyright (C) 2023 Christophe Battarel <christophe@altairis.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -71,7 +72,6 @@ $search_datedelivery_end = dol_mktime(23, 59, 59, GETPOST('search_datedelivery_e
$search_datereceipt_start = dol_mktime(0, 0, 0, GETPOST('search_datereceipt_startmonth', 'int'), GETPOST('search_datereceipt_startday', 'int'), GETPOST('search_datereceipt_startyear', 'int'));
$search_datereceipt_end = dol_mktime(23, 59, 59, GETPOST('search_datereceipt_endmonth', 'int'), GETPOST('search_datereceipt_endday', 'int'), GETPOST('search_datereceipt_endyear', 'int'));
$sall = trim((GETPOST('search_all', 'alphanohtml') != '') ?GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml'));
$socid = GETPOST('socid', 'int');
$search_user = GETPOST('search_user', 'int');
$search_sale = GETPOST('search_sale', 'int');
$search_categ_cus = GETPOST("search_categ_cus", 'int');

View File

@ -2594,8 +2594,8 @@ if ($action == 'create') {
print '</table>';
print '</div>';
//var_dump($object);
print '<script javascript>
print '<script>
/* JQuery for product free or predefined select */
jQuery(document).ready(function() {
@ -2611,6 +2611,10 @@ if ($action == 'create') {
jQuery("#value_unit_ht").val("");
}
});
';
if (! empty($conf->global->MAIN_USE_EXPENSE_IK)) {
print '
/* unit price coéf calculation */
jQuery(".input_qty, #fk_c_type_fees, #select_fk_c_exp_tax_cat, #vatrate ").change(function(event) {
@ -2656,6 +2660,10 @@ if ($action == 'create') {
jQuery("#value_unit_ht").val("");
}*/
});
';
}
print '
});

View File

@ -2681,6 +2681,11 @@ class ExpenseReportLine extends CommonObjectLine
*/
public $db;
/**
* @var string Name of table without prefix where object is stored
*/
public $table_element = 'expensereport_det';
/**
* @var string Error code (or message)
*/

View File

@ -198,9 +198,9 @@ class ExpenseReportIk extends CommonObject
$default_range = (int) $userauthor->default_range; // if not defined, then 0
$ranges = $this->getRangesByCategory($fk_c_exp_tax_cat);
// prevent out of range -1 indice
$indice = $default_range > 0 ? $default_range - 1 : 0;
$indice = $default_range - 1;
// substract 1 because array start from 0
if (empty($ranges) || !isset($ranges[$indice])) {
if (empty($ranges) || $indice < 0 || !isset($ranges[$indice])) {
return false;
} else {
return $ranges[$indice];

View File

@ -884,8 +884,12 @@ if (empty($reshook)) {
$totalcreditnotes = $facture_source->getSumCreditNotesUsed();
$totaldeposits = $facture_source->getSumDepositsUsed();
$remain_to_pay = abs($facture_source->total_ttc - $totalpaid - $totalcreditnotes - $totaldeposits);
$desc = $langs->trans('invoiceAvoirLineWithPaymentRestAmount');
$retAddLine = $object->addline($desc, $remain_to_pay, 0, 0, 0, 1, 0, 0, '', '', 0, '', 'TTC');
$object->addline($langs->trans('invoiceAvoirLineWithPaymentRestAmount'), $remain_to_pay, 0, 0, 0, 1, 0, 0, '', '', 'TTC');
if ($retAddLine < 0) {
$error++;
}
}
}
}

View File

@ -557,3 +557,6 @@ ALTER TABLE llx_element_tag ADD CONSTRAINT fk_element_tag_categorie_rowid FOREIG
-- Idea is to update this column manually in v15 with value in currency of company for bank that are not into the main currency and the transfer
-- into accounting will use it in priority if value is not null. The script repair.sql contains the sequence to fix datas in llx_bank.
ALTER TABLE llx_bank ADD COLUMN amount_main_currency double(24,8) NULL;
ALTER TABLE llx_commande_fournisseurdet MODIFY COLUMN ref varchar(128);
ALTER TABLE llx_facture_fourn_det MODIFY COLUMN ref varchar(128);

View File

@ -688,7 +688,7 @@ ALTER TABLE llx_actioncomm MODIFY COLUMN note mediumtext;
DELETE FROM llx_boxes WHERE box_id IN (select rowid FROM llx_boxes_def WHERE file IN ('box_bom.php@bom', 'box_bom.php', 'box_members.php', 'box_last_modified_ticket', 'box_members_last_subscriptions', 'box_members_last_modified', 'box_members_subscriptions_by_year'));
DELETE FROM llx_boxes_def WHERE file IN ('box_bom.php@bom', 'box_bom.php', 'box_members.php', 'box_last_modified_ticket', 'box_members_last_subscriptions', 'box_members_last_modified', 'box_members_subscriptions_by_year');
ALTER TABLE llx_takepos_floor_tables ADD UNIQUE(entity,label);
ALTER TABLE llx_takepos_floor_tables ADD UNIQUE INDEX uk_takepos_floor_tables (entity,label);
ALTER TABLE llx_partnership ADD COLUMN url_to_check varchar(255);
ALTER TABLE llx_c_partnership_type ADD COLUMN keyword varchar(128);

View File

@ -25,7 +25,7 @@ create table llx_commande_fournisseurdet
fk_commande integer NOT NULL,
fk_parent_line integer NULL,
fk_product integer,
ref varchar(50), -- supplier product ref
ref varchar(128), -- supplier product ref
label varchar(255), -- product label
description text,
vat_src_code varchar(10) DEFAULT '', -- Vat code used as source of vat fields. Not strict foreign key here.

View File

@ -24,7 +24,7 @@ create table llx_facture_fourn_det
fk_facture_fourn integer NOT NULL,
fk_parent_line integer NULL,
fk_product integer NULL,
ref varchar(50), -- supplier product ref
ref varchar(128), -- supplier product ref
label varchar(255), -- product label
description text,
pu_ht double(24,8), -- unit price excluding tax

View File

@ -903,9 +903,8 @@ if ($ok && GETPOST('clean_product_stock_batch', 'alpha')) {
$sql = "SELECT p.rowid, p.ref, p.tobatch, ps.rowid as psrowid, ps.fk_entrepot, ps.reel, SUM(pb.qty) as reelbatch";
$sql .= " FROM ".MAIN_DB_PREFIX."product as p, ".MAIN_DB_PREFIX."product_stock as ps LEFT JOIN ".MAIN_DB_PREFIX."product_batch as pb ON ps.rowid = pb.fk_product_stock";
$sql .= " WHERE p.rowid = ps.fk_product";
$sql .= " AND p.tobatch > 0";
$sql .= " GROUP BY p.rowid, p.ref, p.tobatch, ps.rowid, ps.fk_entrepot, ps.reel";
$sql .= " HAVING reel != SUM(pb.qty) or SUM(pb.qty) IS NULL";
$sql .= " HAVING (SUM(pb.qty) IS NOT NULL AND reel != SUM(pb.qty)) OR (SUM(pb.qty) IS NULL AND p.tobatch > 0)";
print $sql;
$resql = $db->query($sql);
if ($resql) {
@ -915,53 +914,73 @@ if ($ok && GETPOST('clean_product_stock_batch', 'alpha')) {
$i = 0;
while ($i < $num) {
$obj = $db->fetch_object($resql);
print '<tr><td>Product '.$obj->rowid.'-'.$obj->ref.' in warehose '.$obj->fk_entrepot.' -> '.$obj->psrowid.': '.$obj->reel.' (product_stock.reel) != '.($obj->reelbatch ? $obj->reelbatch : '0').' (sum product_batch)';
print '<tr><td>Product '.$obj->rowid.'-'.$obj->ref.' in warehouse id='.$obj->fk_entrepot.' -> product_stock.id='.$obj->psrowid.': '.$obj->reel.' (product_stock.reel) != '.($obj->reelbatch ? $obj->reelbatch : '0').' (sum product_batch)';
// Fix
// Fix is required
if ($obj->reel != $obj->reelbatch) {
if ($methodtofix == 'updatebatch') {
// Method 1
print ' -> Insert qty '.($obj->reel - $obj->reelbatch).' with lot 000000 linked to fk_product_stock='.$obj->psrowid;
if (empty($obj->tobatch)) {
// If product is not a product that support batches, we can clean stock by deleting the product batch lines
print ' -> Delete qty '.$obj->reelbatch.' for any lot linked to fk_product_stock='.$obj->psrowid;
$sql2 = "DELETE FROM ".MAIN_DB_PREFIX."product_batch";
$sql2 .= " WHERE fk_product_stock = ".((int) $obj->psrowid);
print '<br>'.$sql2;
if (GETPOST('clean_product_stock_batch') == 'confirmed') {
$sql2 = "INSERT INTO ".MAIN_DB_PREFIX."product_batch(fk_product_stock, batch, qty)";
$sql2 .= "VALUES(".$obj->psrowid.", '000000', ".($obj->reel - $obj->reelbatch).")";
$resql2 = $db->query($sql2);
if (!$resql2) {
// TODO If it fails, we must make update
//$sql2 ="UPDATE ".MAIN_DB_PREFIX."product_batch";
//$sql2.=" SET ".$obj->psrowid.", '000000', ".($obj->reel - $obj->reelbatch).")";
//$sql2.=" WHERE fk_product_stock = ".((int) $obj->psrowid)
}
}
}
if ($methodtofix == 'updatestock') {
// Method 2
print ' -> Update qty of product_stock with qty = '.($obj->reelbatch ? ((float) $obj->reelbatch) : '0').' for ps.rowid = '.((int) $obj->psrowid);
if (GETPOST('clean_product_stock_batch') == 'confirmed') {
$error = 0;
$db->begin();
$sql2 = "UPDATE ".MAIN_DB_PREFIX."product_stock";
$sql2 .= " SET reel = ".($obj->reelbatch ? ((float) $obj->reelbatch) : '0')." WHERE rowid = ".((int) $obj->psrowid);
$resql2 = $db->query($sql2);
if ($resql2) {
// We update product_stock, so we must fill p.stock into product too.
$sql3 = 'UPDATE '.MAIN_DB_PREFIX.'product p SET p.stock= (SELECT SUM(ps.reel) FROM '.MAIN_DB_PREFIX.'product_stock ps WHERE ps.fk_product = p.rowid)';
$resql3 = $db->query($sql3);
if (!$resql3) {
$error++;
dol_print_error($db);
}
} else {
$error++;
dol_print_error($db);
}
}
} else {
if ($methodtofix == 'updatebatch') {
// Method 1
print ' -> Insert qty '.($obj->reel - $obj->reelbatch).' with lot 000000 linked to fk_product_stock='.$obj->psrowid;
$sql2 = "INSERT INTO ".MAIN_DB_PREFIX."product_batch(fk_product_stock, batch, qty)";
$sql2 .= "VALUES(".((int) $obj->psrowid).", '000000', ".((float) ($obj->reel - $obj->reelbatch)).")";
print '<br>'.$sql2;
if (!$error) {
$db->commit();
} else {
$db->rollback();
if (GETPOST('clean_product_stock_batch') == 'confirmed') {
$resql2 = $db->query($sql2);
if (!$resql2) {
// TODO If it fails, we must make update
//$sql2 ="UPDATE ".MAIN_DB_PREFIX."product_batch";
//$sql2.=" SET ".$obj->psrowid.", '000000', ".($obj->reel - $obj->reelbatch).")";
//$sql2.=" WHERE fk_product_stock = ".((int) $obj->psrowid)
}
}
}
if ($methodtofix == 'updatestock') {
// Method 2
print ' -> Update qty of product_stock with qty = '.($obj->reelbatch ? ((float) $obj->reelbatch) : '0').' for ps.rowid = '.((int) $obj->psrowid);
$sql2 = "UPDATE ".MAIN_DB_PREFIX."product_stock";
$sql2 .= " SET reel = ".($obj->reelbatch ? ((float) $obj->reelbatch) : '0')." WHERE rowid = ".((int) $obj->psrowid);
print '<br>'.$sql2;
if (GETPOST('clean_product_stock_batch') == 'confirmed') {
$error = 0;
$db->begin();
$resql2 = $db->query($sql2);
if ($resql2) {
// We update product_stock, so we must fill p.stock into product too.
$sql3 = 'UPDATE '.MAIN_DB_PREFIX.'product p SET p.stock= (SELECT SUM(ps.reel) FROM '.MAIN_DB_PREFIX.'product_stock ps WHERE ps.fk_product = p.rowid)';
$resql3 = $db->query($sql3);
if (!$resql3) {
$error++;
dol_print_error($db);
}
} else {
$error++;
dol_print_error($db);
}
if (!$error) {
$db->commit();
} else {
$db->rollback();
}
}
}
}

View File

@ -50,7 +50,7 @@ UseDateWithoutHourOnFichinter=Hides hours and minutes off the date field for int
InterventionStatistics=Statistics of interventions
NbOfinterventions=No. of intervention cards
NumberOfInterventionsByMonth=No. of intervention cards by month (date of validation)
AmountOfInteventionNotIncludedByDefault=Amount of intervention is not included by default into profit (in most cases, timesheets are used to count time spent). Add option PROJECT_INCLUDE_INTERVENTION_AMOUNT_IN_PROFIT to 1 into home-setup-other to include them.
AmountOfInteventionNotIncludedByDefault=Amount of intervention is not included by default into profit (in most cases, timesheets are used to count time spent). You can use PROJECT_ELEMENTS_FOR_ADD_MARGIN and PROJECT_ELEMENTS_FOR_MINUS_MARGIN option into home-setup-other to complete list of element included into profit.
InterId=Intervention id
InterRef=Intervention ref.
InterDateCreation=Date creation intervention

View File

@ -49,7 +49,7 @@ BoxTitleLastActionsToDo=Les %s derniers événements à réaliser
BoxTitleLastContracts=Les %s derniers contrats modifiés
BoxTitleLastModifiedDonations=Les %s derniers dons modifiés
BoxTitleLastModifiedExpenses=Les %s dernières notes de frais modifiées
BoxTitleLatestModifiedBoms=Les %s derières BOMS modifiées
BoxTitleLatestModifiedBoms=Les %s dernières BOMS modifiées
BoxTitleLatestModifiedMos=Les %s derniers ordres de fabrication modifiés
BoxTitleLastOutstandingBillReached=Clients dont l'en-cours autorisé est dépassé
BoxGlobalActivity=Activité globale (factures, propositions, commandes)

View File

@ -167,16 +167,20 @@ function testSqlAndScriptInject($val, $type)
$inj += preg_match('/on(lostpointercapture|offline|online|pagehide|pageshow)\s*=/i', $val);
$inj += preg_match('/on(paste|pause|play|playing|progress|ratechange|reset|resize|scroll|search|seeked|seeking|show|stalled|start|submit|suspend)\s*=/i', $val);
$inj += preg_match('/on(timeupdate|toggle|unload|volumechange|waiting|wheel)\s*=/i', $val);
// More not into the previous list
$inj += preg_match('/on(repeat|begin|finish|beforeinput)\s*=/i', $val);
// We refuse html into html because some hacks try to obfuscate evil strings by inserting HTML into HTML. Example: <img on<a>error=alert(1) to bypass test on onerror
$tmpval = preg_replace('/<[^<]+>/', '', $val);
// List of dom events is on https://www.w3schools.com/jsref/dom_obj_event.asp and https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers
$inj += preg_match('/on(mouse|drag|key|load|touch|pointer|select|transition)([a-z]*)\s*=/i', $val); // onmousexxx can be set on img or any html tag like <img title='...' onmouseover=alert(1)>
$inj += preg_match('/on(mouse|drag|key|load|touch|pointer|select|transition)([a-z]*)\s*=/i', $tmpval); // onmousexxx can be set on img or any html tag like <img title='...' onmouseover=alert(1)>
$inj += preg_match('/on(abort|afterprint|animation|auxclick|beforecopy|beforecut|beforeprint|beforeunload|blur|cancel|canplay|canplaythrough|change|click|close|contextmenu|cuechange|copy|cut)\s*=/i', $tmpval);
$inj += preg_match('/on(dblclick|drop|durationchange|emptied|end|ended|error|focus|focusin|focusout|formdata|gotpointercapture|hashchange|input|invalid)\s*=/i', $tmpval);
$inj += preg_match('/on(lostpointercapture|offline|online|pagehide|pageshow)\s*=/i', $tmpval);
$inj += preg_match('/on(paste|pause|play|playing|progress|ratechange|reset|resize|scroll|search|seeked|seeking|show|stalled|start|submit|suspend)\s*=/i', $tmpval);
$inj += preg_match('/on(timeupdate|toggle|unload|volumechange|waiting|wheel)\s*=/i', $tmpval);
// More not into the previous list
$inj += preg_match('/on(repeat|begin|finish|beforeinput)\s*=/i', $tmpval);
//$inj += preg_match('/on[A-Z][a-z]+\*=/', $val); // To lock event handlers onAbort(), ...
$inj += preg_match('/&#58;|&#0000058|&#x3A/i', $val); // refused string ':' encoded (no reason to have it encoded) to lock 'javascript:...'

View File

@ -49,7 +49,7 @@ if ($id > 0 || !empty($ref)) {
$object->fetch($id, $ref);
}
$permissionnote = $user->rights->produit->creer; // Used by the include of actions_setnotes.inc.php
$permissionnote = ($user->rights->produit->creer || $user->rights->service->creer); // Used by the include of actions_setnotes.inc.php
if ($object->id > 0) {
if ($object->type == $object::TYPE_PRODUCT) {

View File

@ -214,7 +214,7 @@ $morecss = array();
$sql = 'SELECT p.rowid, p.ref, p.label, p.barcode, p.price, p.price_ttc, p.price_base_type, p.entity,';
$sql .= ' p.fk_product_type, p.tms as datem,';
$sql .= ' p.duration, p.tosell as statut, p.tobuy, p.seuil_stock_alerte, p.desiredstock, p.stock, p.tosell, p.tobuy, p.tobatch,';
$sql .= ' ps.fk_entrepot,';
$sql .= ' ps.fk_entrepot, ps.reel,';
$sql .= ' e.ref as warehouse_ref, e.lieu as warehouse_lieu, e.fk_parent as warehouse_parent,';
$sql .= ' pb.batch, pb.eatby as oldeatby, pb.sellby as oldsellby,';
$sql .= ' pl.rowid as lotid, pl.eatby, pl.sellby,';
@ -313,7 +313,7 @@ foreach ($search as $key => $val) {
$sql .= " GROUP BY p.rowid, p.ref, p.label, p.barcode, p.price, p.price_ttc, p.price_base_type, p.entity,";
$sql .= " p.fk_product_type, p.tms,";
$sql .= " p.duration, p.tosell, p.tobuy, p.seuil_stock_alerte, p.desiredstock, p.stock, p.tosell, p.tobuy, p.tobatch,";
$sql .= " ps.fk_entrepot,";
$sql .= " ps.fk_entrepot, ps.reel,";
$sql .= " e.ref, e.lieu, e.fk_parent,";
$sql .= " pb.batch, pb.eatby, pb.sellby,";
$sql .= " pl.rowid, pl.eatby, pl.sellby";
@ -322,7 +322,7 @@ if ($toolowstock) {
$sql_having .= " HAVING SUM(".$db->ifsql('ps.reel IS NULL', '0', 'ps.reel').") < p.seuil_stock_alerte"; // Not used yet
}
if ($search_stock_physique != '') {
$natural_search_physique = natural_search('SUM(' . $db->ifsql('pb.qty IS NULL', '0', 'pb.qty') . ')', $search_stock_physique, 1, 1);
$natural_search_physique = natural_search('SUM(' . $db->ifsql('pb.qty IS NULL', $db->ifsql('ps.reel IS NULL', '0', 'ps.reel'), 'pb.qty') . ')', $search_stock_physique, 1, 1);
$natural_search_physique = " " . substr($natural_search_physique, 1, -1); // remove first "(" and last ")" characters
if (!empty($sql_having)) {
$sql_having .= " AND";
@ -689,7 +689,15 @@ while ($i < $imaxinloop) {
print '<td class="right">';
//if ($objp->seuil_stock_alerte && ($objp->stock_physique < $objp->seuil_stock_alerte)) print img_warning($langs->trans("StockTooLow")).' ';
print $objp->stock_physique;
if (is_null($objp->stock_physique)) {
if (!empty($objp->reel)) {
print price2num($objp->reel, 'MS');
}
} else {
if (!empty($objp->stock_physique)) {
print price2num($objp->stock_physique, 'MS');
}
}
print '</td>';
print '<td class="right">';

View File

@ -811,9 +811,11 @@ class Task extends CommonObjectLine
* @param array $search_array_options Array of search
* @param int $loadextras Fetch all Extrafields on each task
* @param int $loadRoleMode 1= will test Roles on task; 0 used in delete project action
* @param string $sortfield Sort field
* @param string $sortorder Sort order
* @return array Array of tasks
*/
public function getTasksArray($usert = null, $userp = null, $projectid = 0, $socid = 0, $mode = 0, $filteronproj = '', $filteronprojstatus = '-1', $morewherefilter = '', $filteronprojuser = 0, $filterontaskuser = 0, $extrafields = array(), $includebilltime = 0, $search_array_options = array(), $loadextras = 0, $loadRoleMode = 1)
public function getTasksArray($usert = null, $userp = null, $projectid = 0, $socid = 0, $mode = 0, $filteronproj = '', $filteronprojstatus = '-1', $morewherefilter = '', $filteronprojuser = 0, $filterontaskuser = 0, $extrafields = array(), $includebilltime = 0, $search_array_options = array(), $loadextras = 0, $loadRoleMode = 1, $sortfield = '', $sortorder = '')
{
global $conf, $hookmanager;
@ -953,8 +955,11 @@ class Task extends CommonObjectLine
}
}
$sql .= " ORDER BY p.ref, t.rang, t.dateo";
if ($sortfield && $sortorder) {
$sql .= $this->db->order($sortfield, $sortorder);
} else {
$sql .= " ORDER BY p.ref, t.rang, t.dateo";
}
//print $sql;exit;
dol_syslog(get_class($this)."::getTasksArray", LOG_DEBUG);

View File

@ -474,7 +474,7 @@ $listofreferent = array(
'table'=>'fichinter',
'datefieldname'=>'date_valid',
'disableamount'=>0,
'margin'=>'minus',
'margin'=>'',
'urlnew'=>DOL_URL_ROOT.'/fichinter/card.php?action=create&origin=project&originid='.$id.'&socid='.$socid.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id),
'lang'=>'interventions',
'buttonnew'=>'AddIntervention',
@ -584,9 +584,9 @@ $listofreferent = array(
'name'=>"MouvementStockAssociated",
'title'=>"ListMouvementStockProject",
'class'=>'MouvementStock',
'margin'=>'minus',
'table'=>'stock_mouvement',
'datefieldname'=>'datem',
'margin'=>'minus',
'disableamount'=>0,
'test'=>($conf->stock->enabled && $user->rights->stock->mouvement->lire && !empty($conf->global->STOCK_MOVEMENT_INTO_PROJECT_OVERVIEW))),
'salaries'=>array(
@ -752,6 +752,7 @@ $total_revenue_ht = 0;
$balance_ht = 0;
$balance_ttc = 0;
// Loop on each element type (proposal, sale order, invoices, ...)
foreach ($listofreferent as $key => $value) {
$parameters = array(
'total_revenue_ht' =>& $total_revenue_ht,
@ -787,6 +788,7 @@ foreach ($listofreferent as $key => $value) {
$total_ht = 0;
$total_ttc = 0;
// Loop on each object for the current element type
$num = count($elementarray);
for ($i = 0; $i < $num; $i++) {
$tmp = explode('_', $elementarray[$i]);
@ -871,7 +873,7 @@ foreach ($listofreferent as $key => $value) {
$defaultvat = get_default_tva($mysoc, $mysoc);
$total_ttc_by_line = price2num($total_ht_by_line * (1 + ($defaultvat / 100)), 'MT');
} elseif ($key == 'loan') {
$total_ttc_by_line = $total_ht_by_line; // For loan there is actually no taxe managed in Dolibarr
$total_ttc_by_line = $total_ht_by_line; // For loan there is actually no taxe managed in Dolibarr
} else {
$total_ttc_by_line = $element->total_ttc;
}
@ -892,19 +894,14 @@ foreach ($listofreferent as $key => $value) {
}
// Each element with at least one line is output
$qualifiedforfinalprofit = true;
if ($key == 'intervention' && empty($conf->global->PROJECT_INCLUDE_INTERVENTION_AMOUNT_IN_PROFIT)) {
$qualifiedforfinalprofit = false;
}
//var_dump($key.' '.$qualifiedforfinalprofit);
// Calculate margin
if ($qualifiedforfinalprofit) {
if ($margin == 'add') {
if ($margin) {
if ($margin === 'add') {
$total_revenue_ht += $total_ht;
}
if ($margin != "add") { // Revert sign
if ($margin === "minus") { // Revert sign
$total_ht = -$total_ht;
$total_ttc = -$total_ttc;
}
@ -920,24 +917,24 @@ foreach ($listofreferent as $key => $value) {
print '<td class="right">'.$i.'</td>';
// Amount HT
print '<td class="right">';
if ($key == 'intervention' && !$qualifiedforfinalprofit) {
if ($key == 'intervention' && !$margin) {
print '<span class="opacitymedium">'.$form->textwithpicto($langs->trans("NA"), $langs->trans("AmountOfInteventionNotIncludedByDefault")).'</span>';
} else {
print price($total_ht);
if ($key == 'propal') {
print '<span class="opacitymedium">'.$form->textwithpicto('', $langs->trans("SignedOnly")).'</span>';
}
print price($total_ht);
}
print '</td>';
// Amount TTC
print '<td class="right">';
if ($key == 'intervention' && !$qualifiedforfinalprofit) {
if ($key == 'intervention' && !$margin) {
print '<span class="opacitymedium">'.$form->textwithpicto($langs->trans("NA"), $langs->trans("AmountOfInteventionNotIncludedByDefault")).'</span>';
} else {
print price($total_ttc);
if ($key == 'propal') {
print '<span class="opacitymedium">'.$form->textwithpicto('', $langs->trans("SignedOnly")).'</span>';
}
print price($total_ttc);
}
print '</td>';
print '</tr>';

View File

@ -124,12 +124,12 @@ $search_array_options = $extrafields->getOptionalsFromPost($taskstatic->table_el
// Default sort order (if not yet defined by previous GETPOST)
if (!$sortfield) {
/* if (!$sortfield) {
reset($object->fields); $sortfield="t.".key($object->fields);
} // Set here default search field. By default 1st field in definition. Reset is required to avoid key() to return null.
if (!$sortorder) {
$sortorder = "ASC";
}
} */
// Security check
@ -848,7 +848,7 @@ if ($action == 'create' && $user->rights->projet->creer && (empty($object->third
// Get list of tasks in tasksarray and taskarrayfiltered
// We need all tasks (even not limited to a user because a task to user can have a parent that is not affected to him).
$filteronthirdpartyid = $socid;
$tasksarray = $taskstatic->getTasksArray(0, 0, $object->id, $filteronthirdpartyid, 0, '', -1, $morewherefilter, 0, 0, $extrafields, 1, $search_array_options);
$tasksarray = $taskstatic->getTasksArray(0, 0, $object->id, $filteronthirdpartyid, 0, '', -1, $morewherefilter, 0, 0, $extrafields, 1, $search_array_options, 0, 1, $sortfield, $sortorder);
// We load also tasks limited to a particular user
$tmpuser = new User($db);
@ -998,41 +998,41 @@ if ($action == 'create' && $user->rights->projet->creer && (empty($object->third
print '<tr class="liste_titre nodrag nodrop">';
// print '<td>'.$langs->trans("Project").'</td>';
if (!empty($arrayfields['t.ref']['checked'])) {
print_liste_field_titre($arrayfields['t.ref']['label'], $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, '');
print_liste_field_titre($arrayfields['t.ref']['label'], $_SERVER["PHP_SELF"], 't.ref', '', $param, '', $sortfield, $sortorder, '');
}
if (!empty($arrayfields['t.label']['checked'])) {
print_liste_field_titre($arrayfields['t.label']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, '');
print_liste_field_titre($arrayfields['t.label']['label'], $_SERVER["PHP_SELF"], "t.label", '', $param, '', $sortfield, $sortorder, '');
}
if (!empty($arrayfields['t.description']['checked'])) {
print_liste_field_titre($arrayfields['t.description']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, '');
}
if (!empty($arrayfields['t.dateo']['checked'])) {
print_liste_field_titre($arrayfields['t.dateo']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'center ');
print_liste_field_titre($arrayfields['t.dateo']['label'], $_SERVER["PHP_SELF"], "t.dateo", '', $param, '', $sortfield, $sortorder, 'center ');
}
if (!empty($arrayfields['t.datee']['checked'])) {
print_liste_field_titre($arrayfields['t.datee']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'center ');
print_liste_field_titre($arrayfields['t.datee']['label'], $_SERVER["PHP_SELF"], "t.datee", '', $param, '', $sortfield, $sortorder, 'center ');
}
if (!empty($arrayfields['t.planned_workload']['checked'])) {
print_liste_field_titre($arrayfields['t.planned_workload']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'right ', '', 1);
print_liste_field_titre($arrayfields['t.planned_workload']['label'], $_SERVER["PHP_SELF"], "t.planned_workload", '', $param, '', $sortfield, $sortorder, 'right ', '', 1);
}
if (!empty($arrayfields['t.duration_effective']['checked'])) {
print_liste_field_titre($arrayfields['t.duration_effective']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'right ', '', 1);
print_liste_field_titre($arrayfields['t.duration_effective']['label'], $_SERVER["PHP_SELF"], "t.duration_effective", '', $param, '', $sortfield, $sortorder, 'right ', '', 1);
}
if (!empty($arrayfields['t.progress_calculated']['checked'])) {
print_liste_field_titre($arrayfields['t.progress_calculated']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'right ', '', 1);
}
if (!empty($arrayfields['t.progress']['checked'])) {
print_liste_field_titre($arrayfields['t.progress']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'right ', '', 1);
print_liste_field_titre($arrayfields['t.progress']['label'], $_SERVER["PHP_SELF"], "t.progress", '', $param, '', $sortfield, $sortorder, 'right ', '', 1);
}
if (!empty($arrayfields['t.progress_summary']['checked'])) {
print_liste_field_titre($arrayfields['t.progress_summary']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'center ', '', 1);
}
if ($object->usage_bill_time) {
if (!empty($arrayfields['t.tobill']['checked'])) {
print_liste_field_titre($arrayfields['t.tobill']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'right ');
print_liste_field_titre($arrayfields['t.tobill']['label'], $_SERVER["PHP_SELF"], "t.tobill", '', $param, '', $sortfield, $sortorder, 'right ');
}
if (!empty($arrayfields['t.billed']['checked'])) {
print_liste_field_titre($arrayfields['t.billed']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'right ');
print_liste_field_titre($arrayfields['t.billed']['label'], $_SERVER["PHP_SELF"], "t.billed", '', $param, '', $sortfield, $sortorder, 'right ');
}
}
// Contacts of task, disabled because available by default jsut after
@ -1043,7 +1043,7 @@ if ($action == 'create' && $user->rights->projet->creer && (empty($object->third
*/
if (!empty($arrayfields['t.budget_amount']['checked'])) {
print_liste_field_titre($arrayfields['t.budget_amount']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'center ');
print_liste_field_titre($arrayfields['t.budget_amount']['label'], $_SERVER["PHP_SELF"], "t.budget_amount", "", $param, '', $sortfield, $sortorder, 'center ');
}
if (!empty($arrayfields['c.assigned']['checked'])) {

View File

@ -544,7 +544,6 @@ if (empty($conf->global->MEMBER_NEWFORM_FORCEMORPHY)) {
print $form->selectarray("morphy", $morphys, GETPOST('morphy'), 1);
print '</td></tr>'."\n";
} else {
print $morphys[$conf->global->MEMBER_NEWFORM_FORCEMORPHY];
print '<input type="hidden" id="morphy" name="morphy" value="'.$conf->global->MEMBER_NEWFORM_FORCEMORPHY.'">';
}

View File

@ -58,6 +58,15 @@ $id = GETPOST('id', 'int');
$email = GETPOST('email', 'alphanohtml');
if (!isModEnabled('ticket')) {
accessforbidden('', 0, 0, 1);
}
if (empty($conf->global->TICKET_CREATE_THIRD_PARTY_WITH_CONTACT_IF_NOT_EXIST)) {
accessforbidden('', 0, 0, 1);
}
/*
* View
*/

View File

@ -367,7 +367,7 @@ if ($search_login) {
$sql .= natural_search(array('u.lastname', 'u.firstname', 'u.login'), $search_login);
}
if ($search_montant_ht) {
$sql .= natural_search('sp.total_ht=', $search_montant_ht, 1);
$sql .= natural_search('sp.total_ht', $search_montant_ht, 1);
}
if ($search_montant_vat != '') {
$sql .= natural_search("sp.total_tva", $search_montant_vat, 1);

View File

@ -260,7 +260,7 @@ if (empty($reshook)) {
if (!$error) {
// File transfer
$object->copyFilesForTicket();
$object->copyFilesForTicket(''); // trackid is forced to '' because files were uploaded when no id for ticket exists yet and trackid was ''
}
if (!$error) {
@ -713,6 +713,7 @@ if ($action == 'create' || $action == 'presend') {
print load_fiche_titre($langs->trans('NewTicket'), '', 'ticket');
$formticket->trackid = ''; // TODO Use a unique key to avoid conflict in upload file feature
$formticket->withfromsocid = $socid ? $socid : $user->socid;
$formticket->withfromcontactid = $contactid ? $contactid : '';
$formticket->withtitletopic = 1;

View File

@ -2349,9 +2349,10 @@ class Ticket extends CommonObject
* Used for files linked into messages.
* Files may be renamed during copy to avoid overwriting existing files.
*
* @return array Array with final path/name/mime of files.
* @param string $forcetrackid Force trackid
* @return array Array with final path/name/mime of files.
*/
public function copyFilesForTicket()
public function copyFilesForTicket($forcetrackid = null)
{
global $conf;
@ -2366,7 +2367,7 @@ class Ticket extends CommonObject
$maxheightmini = 72;
$formmail = new FormMail($this->db);
$formmail->trackid = (is_null($forcetrackid) ? 'tic'.$this->id : '');
$attachedfiles = $formmail->get_attached_files();
$filepath = $attachedfiles['paths'];
@ -2534,24 +2535,24 @@ class Ticket extends CommonObject
$assigned_user = new User($this->db);
$assigned_user->fetch($this->fk_user_assign);
if (!empty($assigned_user->email)) {
$sendto[] = $assigned_user->getFullName($langs)." <".$assigned_user->email.">";
$sendto[$assigned_user->email] = $assigned_user->getFullName($langs)." <".$assigned_user->email.">";
} else {
$assigned_user_dont_have_email = $assigned_user->getFullName($langs);
}
}
if (empty($sendto)) {
if (!empty($conf->global->TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_DEFAULT_EMAIL)) {
$sendto[] = $conf->global->TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_DEFAULT_EMAIL;
$sendto[$conf->global->TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_DEFAULT_EMAIL] = $conf->global->TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_DEFAULT_EMAIL;
} elseif (!empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO)) {
$sendto[] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO;
$sendto[$conf->global->TICKET_NOTIFICATION_EMAIL_TO] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO;
}
}
// Add global email address recipient
if (!empty($conf->global->TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS) &&
!empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO) && !in_array($conf->global->TICKET_NOTIFICATION_EMAIL_TO, $sendto)
!empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO) && !array_key_exists($conf->global->TICKET_NOTIFICATION_EMAIL_TO, $sendto)
) {
$sendto[] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO;
$sendto[$conf->global->TICKET_NOTIFICATION_EMAIL_TO] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO;
}
if (!empty($sendto)) {
@ -2635,7 +2636,7 @@ class Ticket extends CommonObject
if ($info_sendto['email'] != '') {
if (!empty($info_sendto['email'])) {
$sendto[] = trim($info_sendto['firstname']." ".$info_sendto['lastname'])." <".$info_sendto['email'].">";
$sendto[$info_sendto['email']] = trim($info_sendto['firstname']." ".$info_sendto['lastname'])." <".$info_sendto['email'].">";
}
//Contact type
@ -2651,9 +2652,9 @@ class Ticket extends CommonObject
$message .= '<br>'.$langs->trans('TicketNotificationEmailBodyInfosTrackUrlinternal').' : <a href="'.$url_internal_ticket.'">'.$object->track_id.'</a><br>';
// Add global email address recipient
if ($conf->global->TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS && !in_array($conf->global->TICKET_NOTIFICATION_EMAIL_TO, $sendto)) {
if ($conf->global->TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS && !array_key_exists($conf->global->TICKET_NOTIFICATION_EMAIL_TO, $sendto)) {
if (!empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO)) {
$sendto[] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO;
$sendto[$conf->global->TICKET_NOTIFICATION_EMAIL_TO] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO;
}
}
@ -2713,7 +2714,7 @@ class Ticket extends CommonObject
if ($info_sendto['email'] != '' && $info_sendto['email'] != $object->origin_email) {
if (!empty($info_sendto['email'])) {
$sendto[] = trim($info_sendto['firstname']." ".$info_sendto['lastname'])." <".$info_sendto['email'].">";
$sendto[$info_sendto['email']] = trim($info_sendto['firstname']." ".$info_sendto['lastname'])." <".$info_sendto['email'].">";
}
$recipient = dolGetFirstLastname($info_sendto['firstname'], $info_sendto['lastname'], '-1').' ('.strtolower($info_sendto['libelle']).')';
@ -2733,21 +2734,21 @@ class Ticket extends CommonObject
$message .= '<br>'.$message_signature;
if (!empty($object->origin_email)) {
$sendto[] = $object->origin_email;
$sendto[$object->origin_email] = $object->origin_email;
}
if ($object->fk_soc > 0 && !in_array($object->origin_email, $sendto)) {
if ($object->fk_soc > 0 && !array_key_exists($object->origin_email, $sendto)) {
$object->socid = $object->fk_soc;
$object->fetch_thirdparty();
if (!empty($object->thirdparty->email)) {
$sendto[] = $object->thirdparty->email;
$sendto[$object->thirdparty->email] = $object->thirdparty->email;
}
}
// altairis: Add global email address reciepient
if ($conf->global->TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS && !in_array($conf->global->TICKET_NOTIFICATION_EMAIL_TO, $sendto)) {
if ($conf->global->TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS && !array_key_exists($conf->global->TICKET_NOTIFICATION_EMAIL_TO, $sendto)) {
if (!empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO)) {
$sendto[] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO;
$sendto[$conf->global->TICKET_NOTIFICATION_EMAIL_TO] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO;
}
}

View File

@ -2359,7 +2359,7 @@ class User extends CommonObject
/**
* Send new password by email
*
* @param User $user Object user that send the email (not the user we send too)
* @param User $user Object user that send the email (not the user we send to) @todo object $user is not used !
* @param string $password New password
* @param int $changelater 0=Send clear passwod into email, 1=Change password only after clicking on confirm email. @todo Add method 2 = Send link to reset password
* @return int < 0 si erreur, > 0 si ok
@ -2425,6 +2425,9 @@ class User extends CommonObject
//print $password.'-'.$this->id.'-'.$dolibarr_main_instance_unique_id;
$url = $urlwithroot.'/user/passwordforgotten.php?action=validatenewpassword';
$url .= '&username='.urlencode($this->login)."&passworduidhash=".urlencode(dol_hash($password.'-'.$this->id.'-'.$dolibarr_main_instance_unique_id));
if (!empty($conf->multicompany->enabled)) {
$url .= '&entity='.(!empty($this->entity) ? $this->entity : 1);
}
$msgishtml = 1;

View File

@ -87,7 +87,7 @@ if (empty($reshook)) {
// Validate new password
if ($action == 'validatenewpassword' && $username && $passworduidhash) {
$edituser = new User($db);
$result = $edituser->fetch('', $username);
$result = $edituser->fetch('', $username, '', 0, $conf->entity);
if ($result < 0) {
$message = '<div class="error">'.dol_escape_htmltag($langs->trans("ErrorLoginDoesNotExists", $username)).'</div>';
} else {
@ -122,9 +122,9 @@ if (empty($reshook)) {
$isanemail = preg_match('/@/', $username);
$edituser = new User($db);
$result = $edituser->fetch('', $username, '', 1);
$result = $edituser->fetch('', $username, '', 1, $conf->entity);
if ($result == 0 && $isanemail) {
$result = $edituser->fetch('', '', '', 1, -1, $username);
$result = $edituser->fetch('', '', '', 1, $conf->entity, $username);
}
if ($result <= 0 && $edituser->error == 'USERNOTFOUND') {