Merge remote-tracking branch 'upstream/develop' into 13a8

This commit is contained in:
Alexandre SPANGARO 2020-09-04 20:26:05 +02:00
commit 247cc71ef4
68 changed files with 1777 additions and 562 deletions

View File

@ -62,12 +62,12 @@ No vulnerability disclosure, including partial is allowed for the moment.
## Scope for qualified vulnerabilities
ONLY vulnerabilities discovered when the following setup is used are accepted:
ONLY vulnerabilities discovered, when the following setup on tested platform is used, are accepted:
* $dolibarr_main_prod must be 1 into conf.php
* $dolibarr_nocsrfcheck must not be set to 0 (should be 1 by default) into conf.php
* The constant MAIN_SECURITY_CSRF_WITH_TOKEN must be set to 1 into backoffice menu Home - Setup - Other (this value should be switched soon to 1 by default)
* ONLY security reports on "stable" modules are allowed (troubles into experimental and developement modules are not accepted).
* The constant MAIN_SECURITY_CSRF_WITH_TOKEN must be set to 1 into backoffice menu Home - Setup - Other (this value should be hard switched soon to 1 by default)
* ONLY security reports on "stable" modules are allowed (troubles into "experimental" and "developement" modules are not accepted).
Scope is the web application (back office) and the APIs.
@ -84,6 +84,8 @@ Scope is the web application (back office) and the APIs.
* CORS with real security impact
* Horizontal and vertical privilege escalation
* "HTTP Host Header" XSS
* Software version disclosure (for non admin users only)
* Stack traces or path disclosure (for non admin users only)
## Non-qualifying vulnerabilities for Bug bounty programs, but qualified for reporting
@ -93,8 +95,6 @@ Scope is the web application (back office) and the APIs.
* Mixed content warnings
* Denial of Service attacks
* Clickjacking/UI redressing
* Software version disclosure
* Stack traces or path disclosure
* Physical or social engineering attempts
* Recently disclosed 0-day vulnerabilities
* Presence of autocomplete attribute on web forms
@ -104,5 +104,7 @@ Scope is the web application (back office) and the APIs.
* Missing security-related HTTP headers which do not lead directly to a vulnerability
* Reports from automated web vulnerability scanners (Acunetix, Vega, etc.) that have not been validated
* Invalid or missing SPF (Sender Policy Framework) records (Incomplete or missing SPF/DKIM/DMARC)
* Reports on features flagged as experimental
* Reports on features flagged as "experimental" or "development"
* Software version disclosure when logged user is admin
* Stack traces or path disclosure when logged user is admin

View File

@ -1,7 +1,7 @@
<?php
/* Copyright (C) 2016 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2016 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2016-2019 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2016-2020 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
*
* This program is free software; you can redistribute it and/or modify
@ -31,6 +31,7 @@ require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountancyexport.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
@ -244,7 +245,7 @@ if ($action != 'export_csv')
print '<table class="liste '.($moreforfilter ? "listwithfilterbefore" : "").'">';
print '<tr class="liste_titre_filter">';
print '<td class="liste_titre" colspan="6">';
print '<td class="liste_titre" colspan="5">';
print $langs->trans('From');
print $formaccounting->select_account($search_accountancy_code_start, 'search_accountancy_code_start', 1, array(), 1, 1, '');
print ' ';
@ -260,7 +261,6 @@ if ($action != 'export_csv')
print '<tr class="liste_titre">';
print_liste_field_titre("AccountAccounting", $_SERVER['PHP_SELF'], "t.numero_compte", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("Label", $_SERVER['PHP_SELF'], "t.label_operation", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("OpeningBalance", $_SERVER['PHP_SELF'], "", $param, "", 'class="right"', $sortfield, $sortorder);
print_liste_field_titre("Debit", $_SERVER['PHP_SELF'], "t.debit", "", $param, 'class="right"', $sortfield, $sortorder);
print_liste_field_titre("Credit", $_SERVER['PHP_SELF'], "t.credit", "", $param, 'class="right"', $sortfield, $sortorder);
@ -274,6 +274,8 @@ if ($action != 'export_csv')
$sous_total_credit = 0;
$displayed_account = "";
$accountingaccountstatic = new AccountingAccount($db);
$sql = "select t.numero_compte, (SUM(t.debit) - SUM(t.credit)) as opening_balance from ".MAIN_DB_PREFIX."accounting_bookkeeping as t where entity in ".$conf->entity;
$sql .= " AND t.doc_date < '".$db->idate($search_date_start)."' GROUP BY t.numero_compte";
$resql = $db->query($sql);
@ -286,12 +288,18 @@ if ($action != 'export_csv')
foreach ($object->lines as $line)
{
$accountingaccountstatic->fetch(null, $line->numero_compte, true);
if (!empty($accountingaccountstatic->account_number)) {
$accounting_account = $accountingaccountstatic->getNomUrl(0, 1, 1, '', 1);
} else {
$accounting_account = length_accountg($line->numero_compte);
}
$link = '';
$total_debit += $line->debit;
$total_credit += $line->credit;
$description = $object->get_compte_desc($line->numero_compte); // Search description of the account
$root_account_description = $object->get_compte_racine($line->numero_compte);
if (empty($description)) {
if (empty($accountingaccountstatic->account_number)) {
$link = '<a href="'.DOL_URL_ROOT.'/accountancy/admin/card.php?action=create&accountingaccount='.length_accountg($line->numero_compte).'">'.img_edit_add().'</a>';
}
print '<tr class="oddeven">';
@ -303,7 +311,7 @@ if ($action != 'export_csv')
// Show subtotal per accounting account
if ($displayed_account != "") {
print '<tr class="liste_total">';
print '<td class="right" colspan="3">'.$langs->trans("SubTotal").':</td>';
print '<td class="right" colspan="2">'.$langs->trans("SubTotal").':</td>';
print '<td class="nowrap right">'.price($sous_total_debit).'</td>';
print '<td class="nowrap right">'.price($sous_total_credit).'</td>';
print '<td class="nowrap right">'.price(price2num($sous_total_credit - $sous_total_debit)).'</td>';
@ -313,7 +321,7 @@ if ($action != 'export_csv')
// Show first line of a break
print '<tr class="trforbreak">';
print '<td colspan="7" style="font-weight:bold; border-bottom: 1pt solid black;">'.$line->numero_compte.($root_account_description ? ' - '.$root_account_description : '').'</td>';
print '<td colspan="6" style="font-weight:bold; border-bottom: 1pt solid black;">'.$line->numero_compte.($root_account_description ? ' - '.$root_account_description : '').'</td>';
print '</tr>';
$displayed_account = $root_account_description;
@ -321,10 +329,9 @@ if ($action != 'export_csv')
$sous_total_credit = 0;
}
}
// $object->get_compte_racine($line->numero_compte);
print '<td>'.length_accountg($line->numero_compte).'</td>';
print '<td>'.$description.'</td>';
// $object->get_compte_racine($line->numero_compte);
print '<td>'.$accounting_account.'</td>';
print '<td class="nowraponall right">'.price($opening_balances["'".$line->numero_compte."'"]).'</td>';
print '<td class="nowraponall right">'.price($line->debit).'</td>';
print '<td class="nowraponall right">'.price($line->credit).'</td>';
@ -340,12 +347,12 @@ if ($action != 'export_csv')
if (!empty($show_subgroup))
{
print '<tr class="liste_total"><td class="right" colspan="3">'.$langs->trans("SubTotal").':</td><td class="nowrap right">'.price($sous_total_debit).'</td><td class="nowrap right">'.price($sous_total_credit).'</td><td class="nowrap right">'.price(price2num($sous_total_debit - $sous_total_credit)).'</td>';
print '<tr class="liste_total"><td class="right" colspan="2">'.$langs->trans("SubTotal").':</td><td class="nowrap right">'.price($sous_total_debit).'</td><td class="nowrap right">'.price($sous_total_credit).'</td><td class="nowrap right">'.price(price2num($sous_total_debit - $sous_total_credit)).'</td>';
print "<td></td>\n";
print '</tr>';
}
print '<tr class="liste_total"><td class="right" colspan="3">'.$langs->trans("AccountBalance").':</td><td class="nowrap right">'.price($total_debit).'</td><td class="nowrap right">'.price($total_credit).'</td><td class="nowrap right">'.price(price2num($total_debit - $total_credit)).'</td>';
print '<tr class="liste_total"><td class="right" colspan="2">'.$langs->trans("AccountBalance").':</td><td class="nowrap right">'.price($total_debit).'</td><td class="nowrap right">'.price($total_credit).'</td><td class="nowrap right">'.price(price2num($total_debit - $total_credit)).'</td>';
print "<td></td>\n";
print '</tr>';

View File

@ -448,9 +448,10 @@ class AccountingAccount extends CommonObject
* @param int $notooltip 1=Disable tooltip
* @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
* @param int $withcompletelabel 0=Short label (field short label), 1=Complete label (field label)
* @param int $option 'bookkeeping', 'bookkeepinglistbyaccount', 'accountcard'
* @return string String with URL
*/
public function getNomUrl($withpicto = 0, $withlabel = 0, $nourl = 0, $moretitle = '', $notooltip = 0, $save_lastsearch_value = -1, $withcompletelabel = 0)
public function getNomUrl($withpicto = 0, $withlabel = 0, $nourl = 0, $moretitle = '', $notooltip = 0, $save_lastsearch_value = -1, $withcompletelabel = 0, $option = '')
{
global $langs, $conf, $user;
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
@ -459,7 +460,13 @@ class AccountingAccount extends CommonObject
$result = '';
$url = DOL_URL_ROOT.'/accountancy/admin/card.php?id='.$this->id;
if (empty($option)) {
$url = DOL_URL_ROOT . '/accountancy/bookkeeping/list.php?search_accountancy_code_start=' . $this->account_number . '&search_accountancy_code_end=' . $this->account_number;
} elseif ($option == 'bookkeepinglistbyaccount') {
$url = DOL_URL_ROOT . '/accountancy/bookkeeping/listbyaccount.php?search_accountancy_code_start=' . $this->account_number . '&search_accountancy_code_end=' . $this->account_number;
} elseif ($option == 'accountcard') {
$url = DOL_URL_ROOT . '/accountancy/admin/card.php?id=' . $this->id;
}
// Add param to save lastsearch_values or not
$add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);

View File

@ -854,7 +854,7 @@ if ($rowid > 0) {
print '"></td></tr>';
// Complementary action
if (!empty($conf->banque->enabled) || !empty($conf->facture->enabled)) {
if ((!empty($conf->banque->enabled) || !empty($conf->facture->enabled)) && empty($conf->global->ADHERENT_SUBSCRIPTION_HIDECOMPLEMENTARYACTIONS)) {
$company = new Societe($db);
if ($object->fk_soc) {
$result = $company->fetch($object->fk_soc);

View File

@ -0,0 +1,574 @@
<?php
/* Copyright (C) 2007-2017 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2009-2012 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2013 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2016 Jonathan TISSEAU <jonathan.tisseau@86dev.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
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/admin/mails_ticket.php
* \brief Page to setup mails for ticket
*/
require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
// Load translation files required by the page
$langs->loadLangs(array('companies', 'products', 'admin', 'mails', 'other', 'errors'));
$action = GETPOST('action', 'alpha');
if (!$user->admin) accessforbidden();
$usersignature = $user->signature;
// For action = test or send, we ensure that content is not html, even for signature, because this we want a test with NO html.
if ($action == 'test' || $action == 'send')
{
$usersignature = dol_string_nohtmltag($usersignature);
}
$substitutionarrayfortest = array(
'__LOGIN__' => $user->login,
'__ID__' => 'TESTIdRecord',
'__EMAIL__' => 'TESTEMail',
'__LASTNAME__' => 'TESTLastname',
'__FIRSTNAME__' => 'TESTFirstname',
'__USER_SIGNATURE__' => (($user->signature && empty($conf->global->MAIN_MAIL_DO_NOT_USE_SIGN)) ? $usersignature : ''),
//'__PERSONALIZED__' => 'TESTPersonalized' // Hiden because not used yet
);
complete_substitutions_array($substitutionarrayfortest, $langs);
/*
* Actions
*/
if ($action == 'update' && empty($_POST["cancel"]))
{
// Send mode parameters
dolibarr_set_const($db, "MAIN_MAIL_SENDMODE_TICKET", GETPOST("MAIN_MAIL_SENDMODE_TICKET"), 'chaine', 0, '', $conf->entity);
dolibarr_set_const($db, "MAIN_MAIL_SMTP_PORT_TICKET", GETPOST("MAIN_MAIL_SMTP_PORT_TICKET"), 'chaine', 0, '', $conf->entity);
dolibarr_set_const($db, "MAIN_MAIL_SMTP_SERVER_TICKET", GETPOST("MAIN_MAIL_SMTP_SERVER_TICKET"), 'chaine', 0, '', $conf->entity);
dolibarr_set_const($db, "MAIN_MAIL_SMTPS_ID_TICKET", GETPOST("MAIN_MAIL_SMTPS_ID_TICKET"), 'chaine', 0, '', $conf->entity);
dolibarr_set_const($db, "MAIN_MAIL_SMTPS_PW_TICKET", GETPOST("MAIN_MAIL_SMTPS_PW_TICKET"), 'chaine', 0, '', $conf->entity);
dolibarr_set_const($db, "MAIN_MAIL_EMAIL_TLS_TICKET", GETPOST("MAIN_MAIL_EMAIL_TLS_TICKET"), 'chaine', 0, '', $conf->entity);
dolibarr_set_const($db, "MAIN_MAIL_EMAIL_STARTTLS_TICKET", GETPOST("MAIN_MAIL_EMAIL_STARTTLS_TICKET"), 'chaine', 0, '', $conf->entity);
header("Location: ".$_SERVER["PHP_SELF"]."?mainmenu=home&leftmenu=setup");
exit;
}
// Actions to send emails
$id = 0;
$actiontypecode = ''; // Not an event for agenda
$triggersendname = ''; // Disable triggers
$paramname = 'id';
$mode = 'emailfortest';
$trackid = (($action == 'testhtml') ? "testhtml" : "test");
$sendcontext = 'ticket'; // Force to use dedicated context of setup for ticket
include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
if ($action == 'presend' && GETPOST('trackid') == 'test') $action = 'test';
if ($action == 'presend' && GETPOST('trackid') == 'testhtml') $action = 'testhtml';
/*
* View
*/
$form = new Form($db);
$linuxlike = 1;
if (preg_match('/^win/i', PHP_OS)) $linuxlike = 0;
if (preg_match('/^mac/i', PHP_OS)) $linuxlike = 0;
if (empty($conf->global->MAIN_MAIL_SENDMODE_TICKET)) $conf->global->MAIN_MAIL_SENDMODE_TICKET = 'default';
$port = !empty($conf->global->MAIN_MAIL_SMTP_PORT_TICKET) ? $conf->global->MAIN_MAIL_SMTP_PORT_TICKET : ini_get('smtp_port');
if (!$port) $port = 25;
$server = !empty($conf->global->MAIN_MAIL_SMTP_SERVER_TICKET) ? $conf->global->MAIN_MAIL_SMTP_SERVER_TICKET : ini_get('SMTP');
if (!$server) $server = '127.0.0.1';
$wikihelp = 'EN:Setup_EMails|FR:Paramétrage_EMails|ES:Configuración_EMails';
llxHeader('', $langs->trans("Setup"), $wikihelp);
print load_fiche_titre($langs->trans("EMailsSetup"), '', 'title_setup');
$head = email_admin_prepare_head();
// List of sending methods
$listofmethods = array();
$listofmethods['default'] = $langs->trans('DefaultOutgoingEmailSetup');
$listofmethods['mail'] = 'PHP mail function';
//$listofmethods['simplemail']='Simplemail class';
$listofmethods['smtps'] = 'SMTP/SMTPS socket library';
$listofmethods['swiftmailer'] = 'Swift Mailer socket library';
if ($action == 'edit')
{
if ($conf->use_javascript_ajax)
{
print "\n".'<script type="text/javascript" language="javascript">';
print 'jQuery(document).ready(function () {
function initfields()
{
if (jQuery("#MAIN_MAIL_SENDMODE_TICKET").val()==\'default\')
{
jQuery(".hideifdefault").hide();
}
else
{
jQuery(".hideifdefault").show();
}
if (jQuery("#MAIN_MAIL_SENDMODE_TICKET").val()==\'mail\')
{
jQuery(".drag").hide();
jQuery("#MAIN_MAIL_EMAIL_TLS_TICKET").val(0);
jQuery("#MAIN_MAIL_EMAIL_TLS_TICKET").prop("disabled", true);
jQuery("#MAIN_MAIL_EMAIL_STARTTLS_TICKET").val(0);
jQuery("#MAIN_MAIL_EMAIL_STARTTLS_TICKET").prop("disabled", true);
';
if ($linuxlike)
{
print '
jQuery("#MAIN_MAIL_SMTP_SERVER_TICKET").hide();
jQuery("#MAIN_MAIL_SMTP_PORT_TICKET").hide();
jQuery("#smtp_server_mess").show();
jQuery("#smtp_port_mess").show();
';
} else {
print '
jQuery("#MAIN_MAIL_SMTP_SERVER_TICKET").prop("disabled", true);
jQuery("#MAIN_MAIL_SMTP_PORT_TICKET").prop("disabled", true);
jQuery("#smtp_server_mess").hide();
jQuery("#smtp_port_mess").hide();
';
}
print '
}
if (jQuery("#MAIN_MAIL_SENDMODE_TICKET").val()==\'smtps\')
{
jQuery(".drag").show();
jQuery("#MAIN_MAIL_EMAIL_TLS_TICKET").val('.$conf->global->MAIN_MAIL_EMAIL_TLS_TICKET.');
jQuery("#MAIN_MAIL_EMAIL_TLS_TICKET").removeAttr("disabled");
jQuery("#MAIN_MAIL_EMAIL_STARTTLS_TICKET").val('.$conf->global->MAIN_MAIL_EMAIL_STARTTLS_TICKET.');
jQuery("#MAIN_MAIL_EMAIL_STARTTLS_TICKET").removeAttr("disabled");
jQuery("#MAIN_MAIL_SMTP_SERVER_TICKET").removeAttr("disabled");
jQuery("#MAIN_MAIL_SMTP_PORT_TICKET").removeAttr("disabled");
jQuery("#MAIN_MAIL_SMTP_SERVER_TICKET").show();
jQuery("#MAIN_MAIL_SMTP_PORT_TICKET").show();
jQuery("#smtp_server_mess").hide();
jQuery("#smtp_port_mess").hide();
}
if (jQuery("#MAIN_MAIL_SENDMODE_TICKET").val()==\'swiftmailer\')
{
jQuery(".drag").show();
jQuery("#MAIN_MAIL_EMAIL_TLS_TICKET").val('.$conf->global->MAIN_MAIL_EMAIL_TLS_TICKET.');
jQuery("#MAIN_MAIL_EMAIL_TLS_TICKET").removeAttr("disabled");
jQuery("#MAIN_MAIL_EMAIL_STARTTLS_TICKET").val('.$conf->global->MAIN_MAIL_EMAIL_STARTTLS_TICKET.');
jQuery("#MAIN_MAIL_EMAIL_STARTTLS_TICKET").removeAttr("disabled");
jQuery("#MAIN_MAIL_SMTP_SERVER_TICKET").removeAttr("disabled");
jQuery("#MAIN_MAIL_SMTP_PORT_TICKET").removeAttr("disabled");
jQuery("#MAIN_MAIL_SMTP_SERVER_TICKET").show();
jQuery("#MAIN_MAIL_SMTP_PORT_TICKET").show();
jQuery("#smtp_server_mess").hide();
jQuery("#smtp_port_mess").hide();
}
}
initfields();
jQuery("#MAIN_MAIL_SENDMODE_TICKET").change(function() {
initfields();
});
jQuery("#MAIN_MAIL_EMAIL_TLS").change(function() {
if (jQuery("#MAIN_MAIL_EMAIL_STARTTLS_TICKET").val() == 1)
jQuery("#MAIN_MAIL_EMAIL_STARTTLS_TICKET").val(0);
});
jQuery("#MAIN_MAIL_EMAIL_STARTTLS_TICKET").change(function() {
if (jQuery("#MAIN_MAIL_EMAIL_TLS_TICKET").val() == 1)
jQuery("#MAIN_MAIL_EMAIL_TLS_TICKET").val(0);
});
})';
print '</script>'."\n";
}
print '<form method="post" action="'.$_SERVER["PHP_SELF"].'">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="update">';
dol_fiche_head($head, 'common_ticket', '', -1);
print '<span class="opacitymedium">'.$langs->trans("EMailsDesc")."</span><br>\n";
print "<br>\n";
clearstatcache();
print '<table class="noborder centpercent">';
print '<tr class="liste_titre"><td class="titlefieldmiddle">'.$langs->trans("Parameter").'</td><td>'.$langs->trans("Value").'</td></tr>';
// Method
print '<tr class="oddeven"><td>'.$langs->trans("MAIN_MAIL_SENDMODE").'</td><td>';
// SuperAdministrator access only
if ((empty($conf->global->MAIN_MODULE_MULTICOMPANY)) || ($user->admin && !$user->entity))
{
print $form->selectarray('MAIN_MAIL_SENDMODE_TICKET', $listofmethods, $conf->global->MAIN_MAIL_SENDMODE_TICKET);
} else {
$text = $listofmethods[$conf->global->MAIN_MAIL_SENDMODE_TICKET];
if (empty($text)) $text = $langs->trans("Undefined");
$htmltext = $langs->trans("ContactSuperAdminForChange");
print $form->textwithpicto($text, $htmltext, 1, 'superadmin');
print '<input type="hidden" name="MAIN_MAIL_SENDMODE_TICKET" value="'.$conf->global->MAIN_MAIL_SENDMODE_TICKET.'">';
}
print '</td></tr>';
// Host server
print '<tr class="oddeven hideifdefault"><td>';
if (!$conf->use_javascript_ajax && $linuxlike && $conf->global->MAIN_MAIL_SENDMODE_TICKET == 'mail')
{
print $langs->trans("MAIN_MAIL_SMTP_SERVER_NotAvailableOnLinuxLike");
print '</td><td>';
print $langs->trans("SeeLocalSendMailSetup");
} else {
$mainserver = (!empty($conf->global->MAIN_MAIL_SMTP_SERVER_TICKET) ? $conf->global->MAIN_MAIL_SMTP_SERVER_TICKET : '');
$smtpserver = ini_get('SMTP') ?ini_get('SMTP') : $langs->transnoentities("Undefined");
if ($linuxlike) print $langs->trans("MAIN_MAIL_SMTP_SERVER_NotAvailableOnLinuxLike");
else print $langs->trans("MAIN_MAIL_SMTP_SERVER", $smtpserver);
print '</td><td>';
// SuperAdministrator access only
if (empty($conf->multicompany->enabled) || ($user->admin && !$user->entity))
{
print '<input class="flat" id="MAIN_MAIL_SMTP_SERVER_TICKET" name="MAIN_MAIL_SMTP_SERVER_TICKET" size="18" value="'.$mainserver.'">';
print '<input type="hidden" id="MAIN_MAIL_SMTP_SERVER_TICKET_sav" name="MAIN_MAIL_SMTP_SERVER_TICKET_sav" value="'.$mainserver.'">';
print '<span id="smtp_server_mess">'.$langs->trans("SeeLocalSendMailSetup").'</span>';
} else {
$text = !empty($mainserver) ? $mainserver : $smtpserver;
$htmltext = $langs->trans("ContactSuperAdminForChange");
print $form->textwithpicto($text, $htmltext, 1, 'superadmin');
print '<input type="hidden" id="MAIN_MAIL_SMTP_SERVER_TICKET" name="MAIN_MAIL_SMTP_SERVER_TICKET" value="'.$mainserver.'">';
}
}
print '</td></tr>';
// Port
print '<tr class="oddeven hideifdefault"><td>';
if (!$conf->use_javascript_ajax && $linuxlike && $conf->global->MAIN_MAIL_SENDMODE_TICKET == 'mail')
{
print $langs->trans("MAIN_MAIL_SMTP_PORT_NotAvailableOnLinuxLike");
print '</td><td>';
print $langs->trans("SeeLocalSendMailSetup");
} else {
$mainport = (!empty($conf->global->MAIN_MAIL_SMTP_PORT_TICKET) ? $conf->global->MAIN_MAIL_SMTP_PORT_TICKET : '');
$smtpport = ini_get('smtp_port') ?ini_get('smtp_port') : $langs->transnoentities("Undefined");
if ($linuxlike) print $langs->trans("MAIN_MAIL_SMTP_PORT_NotAvailableOnLinuxLike");
else print $langs->trans("MAIN_MAIL_SMTP_PORT", $smtpport);
print '</td><td>';
// SuperAdministrator access only
if (empty($conf->multicompany->enabled) || ($user->admin && !$user->entity))
{
print '<input class="flat" id="MAIN_MAIL_SMTP_PORT_TICKET" name="MAIN_MAIL_SMTP_PORT_TICKET" size="3" value="'.$mainport.'">';
print '<input type="hidden" id="MAIN_MAIL_SMTP_PORT_TICKET_sav" name="MAIN_MAIL_SMTP_PORT_TICKET_sav" value="'.$mainport.'">';
print '<span id="smtp_port_mess">'.$langs->trans("SeeLocalSendMailSetup").'</span>';
} else {
$text = (!empty($mainport) ? $mainport : $smtpport);
$htmltext = $langs->trans("ContactSuperAdminForChange");
print $form->textwithpicto($text, $htmltext, 1, 'superadmin');
print '<input type="hidden" id="MAIN_MAIL_SMTP_PORT_TICKET" name="MAIN_MAIL_SMTP_PORT_TICKET" value="'.$mainport.'">';
}
}
print '</td></tr>';
// ID
if (!empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE_TICKET) && in_array($conf->global->MAIN_MAIL_SENDMODE_TICKET, array('smtps', 'swiftmailer'))))
{
$mainstmpid = (!empty($conf->global->MAIN_MAIL_SMTPS_ID_TICKET) ? $conf->global->MAIN_MAIL_SMTPS_ID_TICKET : '');
print '<tr class="drag drop oddeven hideifdefault"><td>'.$langs->trans("MAIN_MAIL_SMTPS_ID").'</td><td>';
// SuperAdministrator access only
if (empty($conf->multicompany->enabled) || ($user->admin && !$user->entity))
{
print '<input class="flat" name="MAIN_MAIL_SMTPS_ID_TICKET" size="32" value="'.$mainstmpid.'">';
} else {
$htmltext = $langs->trans("ContactSuperAdminForChange");
print $form->textwithpicto($conf->global->MAIN_MAIL_SMTPS_ID_TICKET, $htmltext, 1, 'superadmin');
print '<input type="hidden" name="MAIN_MAIL_SMTPS_ID_TICKET" value="'.$mainstmpid.'">';
}
print '</td></tr>';
}
// PW
if (!empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE_TICKET) && in_array($conf->global->MAIN_MAIL_SENDMODE_TICKET, array('smtps', 'swiftmailer'))))
{
$mainsmtppw = (!empty($conf->global->MAIN_MAIL_SMTPS_PW_TICKET) ? $conf->global->MAIN_MAIL_SMTPS_PW_TICKET : '');
print '<tr class="drag drop oddeven hideifdefault"><td>'.$langs->trans("MAIN_MAIL_SMTPS_PW").'</td><td>';
// SuperAdministrator access only
if (empty($conf->multicompany->enabled) || ($user->admin && !$user->entity))
{
print '<input class="flat" type="password" name="MAIN_MAIL_SMTPS_PW_TICKET" size="32" value="'.$mainsmtppw.'">';
} else {
$htmltext = $langs->trans("ContactSuperAdminForChange");
print $form->textwithpicto($conf->global->MAIN_MAIL_SMTPS_PW_TICKET, $htmltext, 1, 'superadmin');
print '<input type="hidden" name="MAIN_MAIL_SMTPS_PW_TICKET" value="'.$mainsmtppw.'">';
}
print '</td></tr>';
}
// TLS
print '<tr class="oddeven hideifdefault"><td>'.$langs->trans("MAIN_MAIL_EMAIL_TLS").'</td><td>';
if (!empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE_TICKET) && in_array($conf->global->MAIN_MAIL_SENDMODE_TICKET, array('smtps', 'swiftmailer'))))
{
if (function_exists('openssl_open'))
{
print $form->selectyesno('MAIN_MAIL_EMAIL_TLS_TICKET', (!empty($conf->global->MAIN_MAIL_EMAIL_TLS_TICKET) ? $conf->global->MAIN_MAIL_EMAIL_TLS_TICKET : 0), 1);
} else print yn(0).' ('.$langs->trans("YourPHPDoesNotHaveSSLSupport").')';
} else print yn(0).' ('.$langs->trans("NotSupported").')';
print '</td></tr>';
// STARTTLS
print '<tr class="oddeven hideifdefault"><td>'.$langs->trans("MAIN_MAIL_EMAIL_STARTTLS").'</td><td>';
if (!empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE_TICKET) && in_array($conf->global->MAIN_MAIL_SENDMODE_TICKET, array('smtps', 'swiftmailer'))))
{
if (function_exists('openssl_open'))
{
print $form->selectyesno('MAIN_MAIL_EMAIL_STARTTLS_TICKET', (!empty($conf->global->MAIN_MAIL_EMAIL_STARTTLS_TICKET) ? $conf->global->MAIN_MAIL_EMAIL_STARTTLS_TICKET : 0), 1);
} else print yn(0).' ('.$langs->trans("YourPHPDoesNotHaveSSLSupport").')';
} else print yn(0).' ('.$langs->trans("NotSupported").')';
print '</td></tr>';
print '</table>';
dol_fiche_end();
print '<br><div class="center">';
print '<input class="button" type="submit" name="save" value="'.$langs->trans("Save").'">';
print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
print '<input class="button" type="submit" name="cancel" value="'.$langs->trans("Cancel").'">';
print '</div>';
print '</form>';
} else {
dol_fiche_head($head, 'common_ticket', '', -1);
print '<span class="opacitymedium">'.$langs->trans("EMailsDesc")."</span><br>\n";
print "<br>\n";
print '<table class="noborder centpercent">';
print '<tr class="liste_titre"><td class="titlefieldmiddle">'.$langs->trans("Parameter").'</td><td>'.$langs->trans("Value").'</td></tr>';
// Method
print '<tr class="oddeven"><td>'.$langs->trans("MAIN_MAIL_SENDMODE").'</td><td>';
$text = $listofmethods[$conf->global->MAIN_MAIL_SENDMODE_TICKET];
if (empty($text)) $text = $langs->trans("Undefined").img_warning();
print $text;
print '</td></tr>';
if (!empty($conf->global->MAIN_MAIL_SENDMODE_TICKET) && $conf->global->MAIN_MAIL_SENDMODE_TICKET != 'default')
{
// Host server
if ($linuxlike && (isset($conf->global->MAIN_MAIL_SENDMODE_TICKET) && $conf->global->MAIN_MAIL_SENDMODE_TICKET == 'mail'))
{
print '<tr class="oddeven hideifdefault"><td>'.$langs->trans("MAIN_MAIL_SMTP_SERVER_NotAvailableOnLinuxLike").'</td><td>'.$langs->trans("SeeLocalSendMailSetup").'</td></tr>';
} else {
print '<tr class="oddeven hideifdefault"><td>'.$langs->trans("MAIN_MAIL_SMTP_SERVER", ini_get('SMTP') ?ini_get('SMTP') : $langs->transnoentities("Undefined")).'</td><td>'.(!empty($conf->global->MAIN_MAIL_SMTP_SERVER_TICKET) ? $conf->global->MAIN_MAIL_SMTP_SERVER_TICKET : '').'</td></tr>';
}
// Port
if ($linuxlike && (isset($conf->global->MAIN_MAIL_SENDMODE_TICKET) && $conf->global->MAIN_MAIL_SENDMODE_TICKET == 'mail'))
{
print '<tr class="oddeven hideifdefault"><td>'.$langs->trans("MAIN_MAIL_SMTP_PORT_NotAvailableOnLinuxLike").'</td><td>'.$langs->trans("SeeLocalSendMailSetup").'</td></tr>';
} else {
print '<tr class="oddeven hideifdefault"><td>'.$langs->trans("MAIN_MAIL_SMTP_PORT", ini_get('smtp_port') ?ini_get('smtp_port') : $langs->transnoentities("Undefined")).'</td><td>'.(!empty($conf->global->MAIN_MAIL_SMTP_PORT_TICKET) ? $conf->global->MAIN_MAIL_SMTP_PORT_TICKET : '').'</td></tr>';
}
// SMTPS ID
if (isset($conf->global->MAIN_MAIL_SENDMODE_TICKET) && in_array($conf->global->MAIN_MAIL_SENDMODE_TICKET, array('smtps', 'swiftmailer')))
{
print '<tr class="oddeven hideifdefault"><td>'.$langs->trans("MAIN_MAIL_SMTPS_ID").'</td><td>'.$conf->global->MAIN_MAIL_SMTPS_ID_TICKET.'</td></tr>';
}
// SMTPS PW
if (isset($conf->global->MAIN_MAIL_SENDMODE_TICKET) && in_array($conf->global->MAIN_MAIL_SENDMODE_TICKET, array('smtps', 'swiftmailer')))
{
print '<tr class="oddeven hideifdefault"><td>'.$langs->trans("MAIN_MAIL_SMTPS_PW").'</td><td>'.preg_replace('/./', '*', $conf->global->MAIN_MAIL_SMTPS_PW_TICKET).'</td></tr>';
}
// TLS
print '<tr class="oddeven hideifdefault"><td>'.$langs->trans("MAIN_MAIL_EMAIL_TLS").'</td><td>';
if (isset($conf->global->MAIN_MAIL_SENDMODE_TICKET) && in_array($conf->global->MAIN_MAIL_SENDMODE_TICKET, array('smtps', 'swiftmailer')))
{
if (function_exists('openssl_open'))
{
print yn($conf->global->MAIN_MAIL_EMAIL_TLS_TICKET);
} else print yn(0).' ('.$langs->trans("YourPHPDoesNotHaveSSLSupport").')';
} else print yn(0).' ('.$langs->trans("NotSupported").')';
print '</td></tr>';
// STARTTLS
print '<tr class="oddeven hideifdefault"><td>'.$langs->trans("MAIN_MAIL_EMAIL_STARTTLS").'</td><td>';
if (isset($conf->global->MAIN_MAIL_SENDMODE_TICKET) && in_array($conf->global->MAIN_MAIL_SENDMODE_TICKET, array('smtps', 'swiftmailer')))
{
if (function_exists('openssl_open'))
{
print yn($conf->global->MAIN_MAIL_EMAIL_STARTTLS_TICKET);
} else print yn(0).' ('.$langs->trans("YourPHPDoesNotHaveSSLSupport").')';
} else print yn(0).' ('.$langs->trans("NotSupported").')';
print '</td></tr>';
}
print '</table>';
dol_fiche_end();
if ($conf->global->MAIN_MAIL_SENDMODE_TICKET == 'mail' && empty($conf->global->MAIN_FIX_FOR_BUGGED_MTA))
{
print '<br>';
/*
// Warning 1
if ($linuxlike)
{
$sendmailoption=ini_get('mail.force_extra_parameters');
if (empty($sendmailoption) || ! preg_match('/ba/',$sendmailoption))
{
print info_admin($langs->trans("SendmailOptionNotComplete"));
}
}*/
// Warning 2
print info_admin($langs->trans("SendmailOptionMayHurtBuggedMTA"));
}
// Buttons for actions
print '<div class="tabsAction">';
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=edit">'.$langs->trans("Modify").'</a>';
if (!empty($conf->global->MAIN_MAIL_SENDMODE_TICKET) && $conf->global->MAIN_MAIL_SENDMODE_TICKET != 'default')
{
if ($conf->global->MAIN_MAIL_SENDMODE_TICKET != 'mail' || !$linuxlike)
{
if (function_exists('fsockopen') && $port && $server)
{
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=testconnect">'.$langs->trans("DoTestServerAvailability").'</a>';
}
} else {
print '<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("FeatureNotAvailableOnLinux").'">'.$langs->trans("DoTestServerAvailability").'</a>';
}
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=test&amp;mode=init">'.$langs->trans("DoTestSend").'</a>';
if (!empty($conf->fckeditor->enabled))
{
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=testhtml&amp;mode=init">'.$langs->trans("DoTestSendHTML").'</a>';
}
}
print '</div>';
if ($conf->global->MAIN_MAIL_SENDMODE_TICKET == 'mail' && !in_array($action, array('testconnect', 'test', 'testhtml')))
{
$text = $langs->trans("WarningPHPMail");
print info_admin($text);
}
// Run the test to connect
if ($action == 'testconnect')
{
print load_fiche_titre($langs->trans("DoTestServerAvailability"));
include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
$mail = new CMailFile('', '', '', '', array(), array(), array(), '', '', 0, '', '', '', '', $trackid, $sendcontext);
$result = $mail->check_server_port($server, $port);
if ($result) print '<div class="ok">'.$langs->trans("ServerAvailableOnIPOrPort", $server, $port).'</div>';
else {
$errormsg = $langs->trans("ServerNotAvailableOnIPOrPort", $server, $port);
if ($mail->error) {
$errormsg .= ' - '.$mail->error;
}
setEventMessages($errormsg, null, 'errors');
}
print '<br>';
}
// Show email send test form
if ($action == 'test' || $action == 'testhtml')
{
print '<div id="formmailbeforetitle" name="formmailbeforetitle"></div>';
print load_fiche_titre($action == 'testhtml' ? $langs->trans("DoTestSendHTML") : $langs->trans("DoTestSend"));
dol_fiche_head('');
// Cree l'objet formulaire mail
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
$formmail = new FormMail($db);
$formmail->fromname = (isset($_POST['fromname']) ? $_POST['fromname'] : $conf->global->MAIN_MAIL_EMAIL_FROM);
$formmail->frommail = (isset($_POST['frommail']) ? $_POST['frommail'] : $conf->global->MAIN_MAIL_EMAIL_FROM);
$formmail->trackid = (($action == 'testhtml') ? "testhtml" : "test");
$formmail->withfromreadonly = 0;
$formmail->withsubstit = 0;
$formmail->withfrom = 1;
$formmail->witherrorsto = 1;
$formmail->withto = (!empty($_POST['sendto']) ? $_POST['sendto'] : ($user->email ? $user->email : 1));
$formmail->withtocc = (!empty($_POST['sendtocc']) ? $_POST['sendtocc'] : 1); // ! empty to keep field if empty
$formmail->withtoccc = (!empty($_POST['sendtoccc']) ? $_POST['sendtoccc'] : 1); // ! empty to keep field if empty
$formmail->withtopic = (isset($_POST['subject']) ? $_POST['subject'] : $langs->trans("Test"));
$formmail->withtopicreadonly = 0;
$formmail->withfile = 2;
$formmail->withbody = (isset($_POST['message']) ? $_POST['message'] : ($action == 'testhtml' ? $langs->transnoentities("PredefinedMailTestHtml") : $langs->transnoentities("PredefinedMailTest")));
$formmail->withbodyreadonly = 0;
$formmail->withcancel = 1;
$formmail->withdeliveryreceipt = 1;
$formmail->withfckeditor = ($action == 'testhtml' ? 1 : 0);
$formmail->ckeditortoolbar = 'dolibarr_mailings';
// Tableau des substitutions
$formmail->substit = $substitutionarrayfortest;
// Tableau des parametres complementaires du post
$formmail->param["action"] = "send";
$formmail->param["models"] = "body";
$formmail->param["mailid"] = 0;
$formmail->param["returnurl"] = $_SERVER["PHP_SELF"];
// Init list of files
if (GETPOST("mode") == 'init')
{
$formmail->clear_attached_files();
}
print $formmail->get_form('addfile', 'removefile');
dol_fiche_end();
}
}
// End of page
llxFooter();
$db->close();

View File

@ -58,23 +58,23 @@ $origin = GETPOST('origin', 'alpha');
$originid = GETPOST('originid', 'int');
$confirm = GETPOST('confirm', 'alpha');
$fulldayevent = GETPOST('fullday');
$fulldayevent = GETPOST('fullday', 'alpha');
$aphour = GETPOST('aphour');
$apmin = GETPOST('apmin');
$p2hour = GETPOST('p2hour');
$p2min = GETPOST('p2min');
$aphour = GETPOST('aphour', 'int');
$apmin = GETPOST('apmin', 'int');
$p2hour = GETPOST('p2hour', 'int');
$p2min = GETPOST('p2min', 'int');
$addreminder = GETPOST('addreminder');
$offsetvalue = GETPOST('offsetvalue');
$offsetunit = GETPOST('offsetunittype_duration');
$remindertype = GETPOST('selectremindertype');
$modelmail = GETPOST('actioncommsendmodel_mail');
$addreminder = GETPOST('addreminder', 'alpha');
$offsetvalue = GETPOST('offsetvalue', 'int');
$offsetunit = GETPOST('offsetunittype_duration', 'aZ09');
$remindertype = GETPOST('selectremindertype', 'aZ09');
$modelmail = GETPOST('actioncommsendmodel_mail', 'int');
//var_dump($_POST); exit;
$datep = dol_mktime($fulldayevent ? '00' : $aphour, $fulldayevent ? '00' : $apmin, 0, GETPOST("apmonth"), GETPOST("apday"), GETPOST("apyear"));
$datef = dol_mktime($fulldayevent ? '23' : $p2hour, $fulldayevent ? '59' : $p2min, $fulldayevent ? '59' : '0', GETPOST("p2month"), GETPOST("p2day"), GETPOST("p2year"));
$datep = dol_mktime($fulldayevent ? '00' : $aphour, $fulldayevent ? '00' : $apmin, 0, GETPOST("apmonth", 'int'), GETPOST("apday", 'int'), GETPOST("apyear", 'int'));
$datef = dol_mktime($fulldayevent ? '23' : $p2hour, $fulldayevent ? '59' : $p2min, $fulldayevent ? '59' : '0', GETPOST("p2month", 'int'), GETPOST("p2day", 'int'), GETPOST("p2year", 'int'));
// Security check
$socid = GETPOST('socid', 'int');
@ -391,21 +391,9 @@ if (empty($reshook) && $action == 'add')
if ($addreminder == 'on'){
$actionCommReminder = new ActionCommReminder($db);
if ($offsetunit == 'minute'){
$dateremind = dol_time_plus_duree($datep, -$offsetvalue, 'i');
} elseif ($offsetunit == 'hour'){
$dateremind = dol_time_plus_duree($datep, -$offsetvalue, 'h');
} elseif ($offsetunit == 'day') {
$dateremind = dol_time_plus_duree($datep, -$offsetvalue, 'd');
} elseif ($offsetunit == 'week') {
$dateremind = dol_time_plus_duree($datep, -$offsetvalue, 'w');
} elseif ($offsetunit == 'month') {
$dateremind = dol_time_plus_duree($datep, -$offsetvalue, 'm');
} elseif ($offsetunit == 'year') {
$dateremind = dol_time_plus_duree($datep, -$offsetvalue, 'y');
}
$dateremind = dol_time_plus_duree($datep, -$offsetvalue, 'i');
$actionCommReminder->dateremind = $db->idate($dateremind);
$actionCommReminder->dateremind = $dateremind;
$actionCommReminder->typeremind = $remindertype;
$actionCommReminder->fk_user = $user;
$actionCommReminder->offsetunit = $offsetunit;
@ -418,15 +406,20 @@ if (empty($reshook) && $action == 'add')
if ($res <= 0){
// If error
$db->rollback();
$error++;
$langs->load("errors");
$error = $langs->trans('ErrorReminderActionCommCreation');
setEventMessages($error, null, 'errors');
$error = $langs->trans('ErrorReminderActionCommCreation').' '.$actionCommReminder->error;
setEventMessages($error, $actionCommReminder->errors, 'errors');
$action = 'create'; $donotclearsession = 1;
}
}
$db->commit();
if ($error) {
$db->rollback();
} else {
$db->commit();
}
if (!empty($backtopage))
{
dol_syslog("Back to ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : ''));
@ -904,31 +897,48 @@ if ($action == 'create')
// Full day
print '<tr><td>'.$langs->trans("EventOnFullDay").'</td><td><input type="checkbox" id="fullday" name="fullday" '.(GETPOST('fullday') ? ' checked' : '').'></td></tr>';
// Date start
$datep = ($datep ? $datep : $object->datep);
if (GETPOST('datep', 'int', 1)) $datep = dol_stringtotime(GETPOST('datep', 'int', 1), 0);
print '<tr><td class="nowrap"><span class="fieldrequired">'.$langs->trans("DateActionStart").'</span></td><td>';
$datep = ($datep ? $datep : $object->datep);
if (GETPOST('datep', 'int', 1)) $datep = dol_stringtotime(GETPOST('datep', 'int', 1), 0);
$datef = ($datef ? $datef : $object->datef);
if (GETPOST('datef', 'int', 1)) $datef = dol_stringtotime(GETPOST('datef', 'int', 1), 0);
if (empty($datef) && !empty($datep))
{
if (GETPOST("actioncode", 'aZ09') == 'AC_RDV' || empty($conf->global->AGENDA_USE_EVENT_TYPE_DEFAULT)) {
$datef = dol_time_plus_duree($datep, (empty($conf->global->AGENDA_AUTOSET_END_DATE_WITH_DELTA_HOURS) ? 1 : $conf->global->AGENDA_AUTOSET_END_DATE_WITH_DELTA_HOURS), 'h');
}
}
// Date start
print '<tr><td class="nowrap">';
print '<span class="fieldrequired">'.$langs->trans("DateActionStart").'</span>';
print ' - ';
print '<span id="dateend"'.(GETPOST("actioncode", 'aZ09') == 'AC_RDV' ? ' class="fieldrequired"' : '').'>'.$langs->trans("DateActionEnd").'</span>';
print '</td><td>';
if (GETPOST("afaire") == 1) {
print $form->selectDate($datep, 'ap', 1, 1, 0, "action", 1, 2, 0, 'fulldaystart'); // Empty value not allowed for start date and hours if "todo"
} else {
print $form->selectDate($datep, 'ap', 1, 1, 1, "action", 1, 2, 0, 'fulldaystart');
}
print '</td></tr>';
print ' <span class="hideonsmartphone">&nbsp; &nbsp; - &nbsp; &nbsp;</span> ';
//print ' - ';
if (GETPOST("afaire") == 1) {
print $form->selectDate($datef, 'p2', 1, 1, 1, "action", 1, 0, 0, 'fulldayend');
} else {
print $form->selectDate($datef, 'p2', 1, 1, 1, "action", 1, 0, 0, 'fulldayend');
}
print '</td></tr>';
// Date end
$datef = ($datef ? $datef : $object->datef);
if (GETPOST('datef', 'int', 1)) $datef = dol_stringtotime(GETPOST('datef', 'int', 1), 0);
if (empty($datef) && !empty($datep) && !empty($conf->global->AGENDA_AUTOSET_END_DATE_WITH_DELTA_HOURS))
{
$datef = dol_time_plus_duree($datep, $conf->global->AGENDA_AUTOSET_END_DATE_WITH_DELTA_HOURS, 'h');
}
print '<tr><td><span id="dateend"'.(GETPOST("actioncode", 'aZ09') == 'AC_RDV' ? ' class="fieldrequired"' : '').'>'.$langs->trans("DateActionEnd").'</span></td><td>';
/*print '<tr><td>';
print '<span id="dateend"'.(GETPOST("actioncode", 'aZ09') == 'AC_RDV' ? ' class="fieldrequired"' : '').'>'.$langs->trans("DateActionEnd").'</span>';
print '</td>';
print '<td>';
if (GETPOST("afaire") == 1) {
print $form->selectDate($datef, 'p2', 1, 1, 1, "action", 1, 2, 0, 'fulldayend');
} else {
print $form->selectDate($datef, 'p2', 1, 1, 1, "action", 1, 2, 0, 'fulldayend');
}
print '</td></tr>';
print '</td></tr>';*/
// Dev in progress
$userepeatevent = ($conf->global->MAIN_FEATURES_LEVEL == 2 ? 1 : 0);
@ -1173,13 +1183,14 @@ if ($action == 'create')
if ($conf->global->AGENDA_REMINDER_EMAIL || $conf->global->AGENDA_REMINDER_BROWSER)
{
//checkbox create reminder
print '<br>';
print '<tr><td>'.$langs->trans("AddReminder").'</td><td colspan="3"><input type="checkbox" id="addreminder" name="addreminder"></td></tr>';
print '<hr>';
print '<br>';
print '<label for="addreminder">'.$langs->trans("AddReminder").'</label> <input type="checkbox" id="addreminder" name="addreminder"><br><br>';
print '<div class="reminderparameters" style="display: none;">';
print '<hr>';
print load_fiche_titre($langs->trans("AddReminder"), '', '');
//print '<hr>';
//print load_fiche_titre($langs->trans("AddReminder"), '', '');
print '<table class="border centpercent">';
@ -1190,7 +1201,7 @@ if ($action == 'create')
//Time Type
print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("TimeType").'</td><td colspan="3">';
print $form->selectTypeDuration('offsetunit');
print $form->selectTypeDuration('offsetunit', 'i');
print '</td></tr>';
//Reminder Type
@ -1203,7 +1214,7 @@ if ($action == 'create')
//Mail Model
print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("EMailTemplates").'</td><td colspan="3">';
print $form->selectModelMail('actioncommsend', 'actioncomm_send');
print $form->selectModelMail('actioncommsend', 'actioncomm_send', 1);
print '</td></tr>';
@ -1235,9 +1246,13 @@ if ($action == 'create')
dol_fiche_end();
print '<div class="center">';
print '<input type="submit" class="button" value="'.$langs->trans("Add").'">';
print '<input type="submit" class="button" name="save" value="'.$langs->trans("Add").'">';
print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
print '<input type="button" class="button" name="cancel" value="'.$langs->trans("Cancel").'" onClick="javascript:history.go(-1)">';
if (empty($backtopage)) {
print '<input type="button" class="button" name="cancel" value="'.$langs->trans("Cancel").'" onClick="javascript:history.go(-1)">';
} else {
print '<input type="submit" class="button" name="cancel" value="'.$langs->trans("Cancel").'">';
}
print '</div>';
print "</form>";
@ -1579,9 +1594,11 @@ if ($id > 0)
}
// Priority
print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("Priority").'</td><td>';
print '<input type="text" name="priority" value="'.($object->priority ? $object->priority : '').'" size="5">';
print '</td></tr>';
if (! empty($conf->global->AGENDA_SUPPORT_PRIORITY_IN_EVENTS)) {
print '<tr><td class="titlefieldcreate nowrap">'.$langs->trans("Priority").'</td><td>';
print '<input type="text" name="priority" value="'.($object->priority ? $object->priority : '').'" size="5">';
print '</td></tr>';
}
// Object linked
if (!empty($object->fk_element) && !empty($object->elementtype))

View File

@ -28,6 +28,12 @@
*/
require_once DOL_DOCUMENT_ROOT.'/comm/action/class/cactioncomm.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncommreminder.class.php';
/**
@ -1954,11 +1960,13 @@ class ActionComm extends CommonObject
*/
public function sendEmailsReminder()
{
global $conf, $langs;
global $conf, $langs, $user;
$error = 0;
$this->output = '';
$this->error = '';
$nbMailSend = 0;
$errorsMsg = array();
if (empty($conf->agenda->enabled)) // Should not happen. If module disabled, cron job should not be visible.
{
@ -1977,17 +1985,119 @@ class ActionComm extends CommonObject
dol_syslog(__METHOD__, LOG_DEBUG);
$this->db->begin();
$this->db->begin();
// TODO Scan events of type 'email' into table llx_actioncomm_reminder with status todo, send email, then set status to done
//Select all action comm reminder
$sql = "SELECT rowid as id FROM ".MAIN_DB_PREFIX."actioncomm_reminder";
$sql .= " WHERE typeremind = 'email' AND status = 0";
$sql .= " AND dateremind <= '".$this->db->idate(dol_now())."'";
$sql .= $this->db->order("dateremind", "ASC");
$resql = $this->db->query($sql);
// Delete also very old past events (we do not keep more than 1 month record in past)
$sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_reminder WHERE dateremind < '".$this->db->jdate($now - (3600 * 24 * 32))."'";
$this->db->query($sql);
if ($resql) {
$formmail = new FormMail($this->db);
$actionCommReminder = new ActionCommReminder($this->db);
$this->db->commit();
while ($obj = $this->db->fetch_object($resql)){
$res = $actionCommReminder->fetch($obj->id);
if ($res < 0) {
$error++;
$errorsMsg[] = "Failed to load invoice ActionComm Reminder";
}
return $error;
if (!$error)
{
//Select email template
$arraymessage = $formmail->getEMailTemplate($this->db, 'actioncomm_send', $user, $langs, (!empty($actionCommReminder->fk_email_template)) ? $actionCommReminder->fk_email_template : -1, 1);
// Load event
$res = $this->fetch($actionCommReminder->fk_actioncomm);
if ($res > 0)
{
// PREPARE EMAIL
// Make substitution in email content
$substitutionarray = getCommonSubstitutionArray($langs, 0, '', $this);
complete_substitutions_array($substitutionarray, $langs, $this);
// Content
$sendContent = make_substitutions($langs->trans($arraymessage->content), $substitutionarray);
//Topic
$sendTopic = (!empty($arraymessage->topic)) ? $arraymessage->topic : html_entity_decode($langs->trans('EventReminder'));
// Recipient
$recipient = new User($this->db);
$res = $recipient->fetch($actionCommReminder->fk_user);
if ($res > 0 && !empty($recipient->email)) $to = $recipient->email;
else {
$errorsMsg[] = "Failed to load recipient";
$error++;
}
// Sender
$from = $conf->global->MAIN_MAIL_EMAIL_FROM;
if (empty($from)) {
$errorsMsg[] = "Failed to load recipient";
$error++;
}
// Errors Recipient
$errors_to = $conf->global->MAIN_MAIL_ERRORS_TO;
// Mail Creation
$cMailFile = new CMailFile($sendTopic, $to, $from, $sendContent, array(), array(), array(), '', "", 0, 1, $errors_to, '', '', '', '', '');
// Sending Mail
if ($cMailFile->sendfile())
{
$actionCommReminder->status = $actionCommReminder::STATUS_DONE;
$res = $actionCommReminder->update($user);
if ($res < 0)
{
$errorsMsg[] = "Failed to update status of ActionComm Reminder";
$error++;
break; // This is to avoid to have this error on all the selected email. If we fails here for one record, it may fails for others. We must solve first.
} else {
$nbMailSend++;
}
} else {
$errorsMsg[] = $cMailFile->error.' : '.$to;
$error++;
}
} else {
$error++;
}
}
}
} else {
$error++;
}
if (!$error)
{
// Delete also very old past events (we do not keep more than 1 month record in past)
$sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_reminder";
$sql .= " WHERE dateremind < '".$this->db->idate($now - (3600 * 24 * 32))."'";
$resql = $this->db->query($sql);
if (!$resql) {
$errorsMsg[] = 'Failed to delete old reminders';
//$error++; // If this fails, we must not rollback other SQL requests already done. Never mind.
}
}
if (!$error) {
$this->output = 'Nb of emails sent : '.$nbMailSend;
$this->db->commit();
return 0;
}
else {
$this->db->rollback();
$this->error = 'Nb of emails sent : '.$nbMailSend.', '.(!empty($errorsMsg)) ? join(', ', $errorsMsg) : $error;
return $error;
}
}
/**

View File

@ -50,6 +50,9 @@ class ActionCommReminder extends CommonObject
*/
public $picto = 'generic';
const STATUS_TODO = 0;
const STATUS_DONE = 1;
/**
* 'type' if the field format.
@ -79,7 +82,7 @@ class ActionCommReminder extends CommonObject
'typeremind' => array('type'=>'varchar(32)', 'label'=>'TypeRemind', 'visible'=>-1, 'enabled'=>1, 'position'=>55, 'notnull'=>1, 'comment'=>"email, browser, sms",),
'fk_user' => array('type'=>'integer', 'label'=>'User', 'visible'=>-1, 'enabled'=>1, 'position'=>65, 'notnull'=>1, 'index'=>1,),
'offsetvalue' => array('type'=>'integer', 'label'=>'OffsetValue', 'visible'=>1, 'enabled'=>1, 'position'=>56, 'notnull'=>1,),
'offsetunit' => array('type'=>'varchar(1)', 'label'=>'OffsetUnit', 'visible'=>1, 'enabled'=>1, 'position'=>57, 'notnull'=>1, 'comment'=>"m, h, d, w",),
'offsetunit' => array('type'=>'varchar(1)', 'label'=>'OffsetUnit', 'visible'=>1, 'enabled'=>1, 'position'=>57, 'notnull'=>1, 'comment'=>"y, m, d, w, h, i",),
'status' => array('type'=>'integer', 'label'=>'Status', 'visible'=>1, 'enabled'=>1, 'position'=>58, 'notnull'=>1, 'default'=>0, 'index'=>0, 'arrayofkeyval'=>array('0'=>'ToDo', '1'=>'Done')),
'fk_actioncomm' => array('type'=>'integer', 'label'=>'Project', 'visible'=>1, 'enabled'=>1, 'position'=>59, 'notnull'=>1, 'index'=>1,),
'fk_email_template' => array('type'=>'integer', 'label'=>'EmailTemplate', 'visible'=>1, 'enabled'=>1, 'position'=>60, 'notnull'=>0),
@ -121,9 +124,6 @@ class ActionCommReminder extends CommonObject
*/
public $fk_email_template;
const STATUS_TODO = 0;
const STATUS_DONE = 1;
// END MODULEBUILDER PROPERTIES

View File

@ -467,7 +467,7 @@ if (!empty($conf->use_javascript_ajax)) // If javascript on
$s .= "\n".'<!-- Div to calendars selectors -->'."\n";
$s .= '<script type="text/javascript">'."\n";
$s .= 'jQuery(document).ready(function () {'."\n";
$s .= 'jQuery("#check_birthday").click(function() { console.log("Toggle birthday"); jQuery(".family_birthday").toggle(); });'."\n";
$s .= 'jQuery(".check_birthday").click(function() { console.log("Toggle birthday"); jQuery(".family_birthday").toggle(); });'."\n";
$s .= 'jQuery(".family_birthday").toggle();'."\n";
if ($action == "show_week" || $action == "show_month" || empty($action))
{
@ -510,7 +510,7 @@ if (!empty($conf->use_javascript_ajax)) // If javascript on
}
// Birthdays
$s .= '<div class="nowrap inline-block"><input type="checkbox" id="check_birthday" name="check_birthday"> '.$langs->trans("AgendaShowBirthdayEvents").' &nbsp; </div>';
$s .= '<div class="nowrap inline-block"><input type="checkbox" id="check_birthday" name="check_birthday" class="check_birthday"> <span class="check_birthday_text">'.$langs->trans("AgendaShowBirthdayEvents").'</span> &nbsp; </div>';
// Calendars from hooks
$parameters = array(); $object = null;
@ -1207,13 +1207,15 @@ if (empty($action) || $action == 'show_month') // View by month
print_actions_filter($form, $canedit, $status, $year, $month, $day, $showbirthday, 0, $filtert, 0, $pid, $socid, $action, -1, $actioncode, $usergroup, '', $resourceid);
print '</div>';
print '<div class="div-table-responsive-no-min">';
print '<div class="div-table-responsive-no-min sectioncalendarbymonth maxscreenheightless300">';
print '<table width="100%" class="noborder nocellnopadd cal_pannel cal_month">';
print ' <tr class="liste_titre">';
// Column title of weeks numbers
echo ' <td align="center">#</td>';
$i = 0;
while ($i < 7)
{
print ' <td class="center bold uppercase">';
print ' <td class="center bold uppercase tdfordaytitle">';
$numdayinweek = (($i + (isset($conf->global->MAIN_START_WEEK) ? $conf->global->MAIN_START_WEEK : 1)) % 7);
if (!empty($conf->dol_optimize_smallscreen))
{
@ -1232,6 +1234,24 @@ if (empty($action) || $action == 'show_month') // View by month
//var_dump($eventarray);
for ($iter_week = 0; $iter_week < 6; $iter_week++) {
echo " <tr>\n";
// Get date of the current day, format 'yyyy-mm-dd'
if ($tmpday <= 0) // If number of the current day is in previous month
{
$currdate0 = sprintf("%04d", $prev_year).sprintf("%02d", $prev_month).sprintf("%02d", $max_day_in_prev_month + $tmpday);
}
elseif ($tmpday <= $max_day_in_month) // If number of the current day is in current month
{
$currdate0 = sprintf("%04d", $year).sprintf("%02d", $month).sprintf("%02d", $tmpday);
}
else // If number of the current day is in next month
{
$currdate0 = sprintf("%04d", $next_year).sprintf("%02d", $next_month).sprintf("%02d", $tmpday - $max_day_in_month);
}
// Get week number for the targeted date '$currdate0'
$numweek0 = date("W", strtotime(date($currdate0)));
// Show the week number, and define column width
echo ' <td class="center weeknumber opacitymedium" width="2%">'.$numweek0.'</td>';
for ($iter_day = 0; $iter_day < 7; $iter_day++) {
if ($tmpday <= 0) {
/* Show days before the beginning of the current month (previous month) */
@ -1288,12 +1308,12 @@ if (empty($action) || $action == 'show_month') // View by month
print_actions_filter($form, $canedit, $status, $year, $month, $day, $showbirthday, 0, $filtert, 0, $pid, $socid, $action, -1, $actioncode, $usergroup, '', $resourceid);
print '</div></div>';
print '<div class="div-table-responsive-no-min">';
print '<div class="div-table-responsive-no-min sectioncalendarbyweek maxscreenheightless300">';
print '<table width="100%" class="noborder nocellnopadd cal_pannel cal_month">';
print ' <tr class="liste_titre">';
$i = 0;
while ($i < 7) {
echo ' <td class="center bold uppercase">'.$langs->trans("Day".(($i + (isset($conf->global->MAIN_START_WEEK) ? $conf->global->MAIN_START_WEEK : 1)) % 7))."</td>\n";
echo ' <td class="center bold uppercase tdfordaytitle">'.$langs->trans("Day".(($i + (isset($conf->global->MAIN_START_WEEK) ? $conf->global->MAIN_START_WEEK : 1)) % 7))."</td>\n";
$i++;
}
echo " </tr>\n";
@ -1348,11 +1368,10 @@ if (empty($action) || $action == 'show_month') // View by month
print_actions_filter($form, $canedit, $status, $year, $month, $day, $showbirthday, 0, $filtert, 0, $pid, $socid, $action, -1, $actioncode, $usergroup, '', $resourceid);
print '</div></div>';
print '<div class="div-table-responsive-no-min">';
print '<div class="div-table-responsive-no-min sectioncalendarbyday maxscreenheightless300">';
echo '<table class="tagtable centpercent noborder nocellnopadd cal_pannel cal_month noborderbottom" style="margin-bottom: 5px !important;">';
echo ' <tr class="tagtr liste_titre">';
echo ' <td class="tagtd width100"></td>';
echo ' <td class="tagtd center bold uppercase">'.$langs->trans("Day".$arraytimestamp['wday'])."</td>\n";
echo " </td>\n";

View File

@ -716,7 +716,7 @@ if ($resql)
// Label
if (!empty($arrayfields['a.label']['checked'])) {
print '<td class="tdoverflowmax200">';
print '<td class="tdoverflowmax200" title="'.dol_escape_htmltag($actionstatic->label).'">';
print $actionstatic->label;
print '</td>';
}

View File

@ -142,7 +142,7 @@ if (!empty($conf->global->MAIN_SEARCH_FORM_ON_HOME_AREAS)) // This is useles
/*
* Draft proposals
* Draft customer proposals
*/
if (!empty($conf->propal->enabled) && $user->rights->propal->lire)
{
@ -256,7 +256,7 @@ if (!empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposa
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th colspan="3">'.$langs->trans("SupplierProposalsDraft").($num ? '<span class="badge marginleftonlyshort">'.$num.'</span>' : '').'</th></tr>';
print '<th colspan="3">'.$langs->trans("SupplierProposalsDraft").' <a href="'.DOL_URL_ROOT.'/supplier_proposal/list.php?search_status=0"><span class="badge">'.$num.'</span></a></th></tr>';
if ($num > 0)
{
@ -309,7 +309,7 @@ if (!empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposa
/*
* Draft orders
* Draft customer orders
*/
if (!empty($conf->commande->enabled) && $user->rights->commande->lire)
{
@ -338,7 +338,7 @@ if (!empty($conf->commande->enabled) && $user->rights->commande->lire)
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th colspan="3">'.$langs->trans("DraftOrders").($num ? '<span class="badge marginleftonlyshort">'.$num.'</span>' : '').'</th></tr>';
print '<th colspan="3">'.$langs->trans("DraftOrders").' <a href="'.DOL_URL_ROOT.'/commande/list.php?search_status=0"><span class="badge">'.$num.'</span></a></th></tr>';
if ($num > 0)
{
@ -425,7 +425,7 @@ if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SU
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th colspan="3">'.$langs->trans("DraftSuppliersOrders").($num ? '<span class="badge marginleftonlyshort">'.$num.'</span>' : '').'</th></tr>';
print '<th colspan="3">'.$langs->trans("DraftSuppliersOrders").' <a href="'.DOL_URL_ROOT.'/fourn/commande/list.php?search_status=0"><span class="badge">'.$num.'</span></a></th></tr>';
if ($num > 0)
{

View File

@ -603,7 +603,7 @@ if (empty($reshook))
{
$db->begin();
$result = $object->cloture($user, Propal::STATUS_BILLED, '');
$result = $object->cloture($user, $object::STATUS_BILLED, '');
if ($result < 0)
{
setEventMessages($object->error, $object->errors, 'errors');
@ -617,13 +617,13 @@ if (empty($reshook))
$db->rollback();
}
} // Close proposal
elseif ($action == 'setstatut' && $usercanclose && !GETPOST('cancel', 'alpha')) {
elseif ($action == 'confirm_closeas' && $usercanclose && !GETPOST('cancel', 'alpha')) {
if (!(GETPOST('statut', 'int') > 0)) {
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CloseAs")), null, 'errors');
$action = 'statut';
$action = 'closeas';
} else {
// prevent browser refresh from closing proposal several times
if ($object->statut == Propal::STATUS_VALIDATED)
if ($object->statut == $object::STATUS_VALIDATED)
{
$db->begin();
@ -1824,11 +1824,11 @@ if ($action == 'create')
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmClonePropal', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
}
if ($action == 'statut')
if ($action == 'closeas')
{
//Form to close proposal (signed or not)
$formquestion = array(
array('type' => 'select', 'name' => 'statut', 'label' => '<span class="fieldrequired">'.$langs->trans("CloseAs").'</span>', 'values' => array(2=>$object->LibStatut(Propal::STATUS_SIGNED), 3=>$object->LibStatut(Propal::STATUS_NOTSIGNED))),
array('type' => 'select', 'name' => 'statut', 'label' => '<span class="fieldrequired">'.$langs->trans("CloseAs").'</span>', 'values' => array(2=>$object->LibStatut($object::STATUS_SIGNED), 3=>$object->LibStatut($object::STATUS_NOTSIGNED))),
array('type' => 'text', 'name' => 'note_private', 'label' => $langs->trans("Note"), 'value' => '') // Field to complete private note (not replace)
);
@ -1841,7 +1841,7 @@ if ($action == 'create')
));
}
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('SetAcceptedRefused'), $text, 'setstatut', $formquestion, '', 1, 250);
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('SetAcceptedRefused'), $text, 'confirm_closeas', $formquestion, '', 1, 250);
} // Confirm delete
elseif ($action == 'delete') {
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteProp'), $langs->trans('ConfirmDeleteProp', $object->ref), 'confirm_delete', '', 0, 1);
@ -2483,9 +2483,9 @@ if ($action == 'create')
}
}
// Set accepted/refused
// Close as accepted/refused
if ($object->statut == Propal::STATUS_VALIDATED && $usercanclose) {
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=statut'.(empty($conf->global->MAIN_JUMP_TAG) ? '' : '#close').'"';
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=closeas'.(empty($conf->global->MAIN_JUMP_TAG) ? '' : '#close').'"';
print '>'.$langs->trans('SetAcceptedRefused').'</a>';
}

View File

@ -2504,12 +2504,12 @@ class Propal extends CommonObject
* Close the commercial proposal
*
* @param User $user Object user that close
* @param int $statut Statut
* @param int $status Status
* @param string $note Complete private note with this note
* @param int $notrigger 1=Does not execute triggers, 0=Execute triggers
* @return int <0 if KO, >0 if OK
*/
public function cloture($user, $statut, $note = "", $notrigger = 0)
public function cloture($user, $status, $note = "", $notrigger = 0)
{
global $langs, $conf;
@ -2521,7 +2521,7 @@ class Propal extends CommonObject
$newprivatenote = dol_concatdesc($this->note_private, $note);
$sql = "UPDATE ".MAIN_DB_PREFIX."propal";
$sql .= " SET fk_statut = ".$statut.", note_private = '".$this->db->escape($newprivatenote)."', date_cloture='".$this->db->idate($now)."', fk_user_cloture=".$user->id;
$sql .= " SET fk_statut = ".$status.", note_private = '".$this->db->escape($newprivatenote)."', date_cloture='".$this->db->idate($now)."', fk_user_cloture=".$user->id;
$sql .= " WHERE rowid = ".$this->id;
$resql = $this->db->query($sql);
@ -2530,7 +2530,7 @@ class Propal extends CommonObject
$modelpdf = $conf->global->PROPALE_ADDON_PDF_ODT_CLOSED ? $conf->global->PROPALE_ADDON_PDF_ODT_CLOSED : $this->modelpdf;
$triggerName = 'PROPAL_CLOSE_REFUSED';
if ($statut == self::STATUS_SIGNED)
if ($status == self::STATUS_SIGNED)
{
$triggerName = 'PROPAL_CLOSE_SIGNED';
$modelpdf = $conf->global->PROPALE_ADDON_PDF_ODT_TOBILL ? $conf->global->PROPALE_ADDON_PDF_ODT_TOBILL : $this->modelpdf;
@ -2547,7 +2547,7 @@ class Propal extends CommonObject
return -2;
}
}
if ($statut == self::STATUS_BILLED) // Why this ?
if ($status == self::STATUS_BILLED) // ->cloture() can also be called when we set it to billed, after setting it to signed
{
$triggerName = 'PROPAL_CLASSIFY_BILLED';
}
@ -2569,7 +2569,7 @@ class Propal extends CommonObject
if (!$error)
{
$this->oldcopy = clone $this;
$this->statut = $statut;
$this->statut = $status;
$this->date_cloture = $now;
$this->note_private = $newprivatenote;
}

View File

@ -456,6 +456,40 @@ class Orders extends DolibarrApi
}
}
/**
* Get contacts of given order
*
* Return an array with contact informations
*
* @param int $id ID of order
* @param string $type Type of the contact (BILLING, SHIPPING, CUSTOMER)
*
* @url GET {id}/contacts
*
* @return array data without useless information
*
* @throws RestException
*/
public function getContacts($id, $type = '')
{
if (! DolibarrApiAccess::$user->rights->commande->lire) {
throw new RestException(401);
}
$result = $this->commande->fetch($id);
if ( ! $result ) {
throw new RestException(404, 'Order not found');
}
if ( ! DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
$contacts = $this->commande->liste_contact(-1, 'external', 0, $type);
return $this->_cleanObjectDatas($contacts);
}
/**
* Add a contact type of given order
*
@ -487,15 +521,24 @@ class Orders extends DolibarrApi
$result = $this->commande->add_contact($contactid, $type, 'external');
if (!$result) {
if ($result < 0) {
throw new RestException(500, 'Error when added the contact');
}
return $this->commande;
if ($result == 0) {
throw new RestException(304, 'contact already added');
}
return array(
'success' => array(
'code' => 200,
'message' => 'Contact linked to the order'
)
);
}
/**
* Delete a contact type of given order
* Unlink a contact type of given order
*
* @param int $id Id of order to update
* @param int $rowid Row key of the contact in the array contact_ids.
@ -510,26 +553,31 @@ class Orders extends DolibarrApi
*/
public function deleteContact($id, $rowid)
{
if (!DolibarrApiAccess::$user->rights->commande->creer) {
if (! DolibarrApiAccess::$user->rights->commande->creer) {
throw new RestException(401);
}
$result = $this->commande->fetch($id);
if (!$result) {
if (! $result) {
throw new RestException(404, 'Order not found');
}
if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) {
if (! DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
$result = $this->commande->delete_contact($rowid);
$result = $this->commande->delete_linked_contact($rowid);
if (!$result) {
throw new RestException(500, 'Error when deleted the contact');
}
return $this->commande;
return array(
'success' => array(
'code' => 200,
'message' => 'Contact unlinked from order'
)
);
}
/**

View File

@ -3397,13 +3397,16 @@ if ($action == 'create')
print '</td></tr>';
// Bank Account
if (GETPOSTISSET('fk_account')) {
$fk_account = GETPOST('fk_account');
}
if (!empty($conf->banque->enabled))
{
if (GETPOSTISSET('fk_account')) {
$fk_account = GETPOST('fk_account');
}
print '<tr><td>'.$langs->trans('BankAccount').'</td><td colspan="2">';
$form->select_comptes($fk_account, 'fk_account', 0, '', 1);
print '</td></tr>';
print '<tr><td>'.$langs->trans('BankAccount').'</td><td colspan="2">';
$form->select_comptes($fk_account, 'fk_account', 0, '', 1);
print '</td></tr>';
}
// Project
if (!empty($conf->projet->enabled))
@ -4264,22 +4267,25 @@ if ($action == 'create')
}
// Bank Account
print '<tr><td class="nowrap">';
print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
print $langs->trans('BankAccount');
print '<td>';
if (($action != 'editbankaccount') && $usercancreate)
print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editbankaccount&amp;id='.$object->id.'">'.img_edit($langs->trans('SetBankAccount'), 1).'</a></td>';
print '</tr></table>';
print '</td><td>';
if ($action == 'editbankaccount')
if (!empty($conf->banque->enabled))
{
$form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'fk_account', 1);
} else {
$form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'none');
print '<tr><td class="nowrap">';
print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
print $langs->trans('BankAccount');
print '<td>';
if (($action != 'editbankaccount') && $usercancreate)
print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editbankaccount&amp;id='.$object->id.'">'.img_edit($langs->trans('SetBankAccount'), 1).'</a></td>';
print '</tr></table>';
print '</td><td>';
if ($action == 'editbankaccount')
{
$form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'fk_account', 1);
} else {
$form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'none');
}
print "</td>";
print '</tr>';
}
print "</td>";
print '</tr>';
// Incoterms
if (!empty($conf->incoterm->enabled))

View File

@ -3157,7 +3157,7 @@ class Facture extends CommonInvoice
return -2;
}
} else {
dol_syslog(get_class($this)."::addline status of order must be Draft to allow use of ->addline()", LOG_ERR);
dol_syslog(get_class($this)."::addline status of invoice must be Draft to allow use of ->addline()", LOG_ERR);
return -3;
}
}

View File

@ -7,6 +7,7 @@
* Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
* Copyright (C) 2016 Marcos García <marcosgdf@gmail.com>
* Copyright (C) 2019 Nicolas ZABOURI <info@inovea-conseil.com>
* Copyright (C) 2020 Tobias Sekan <tobias.sekan@startmail.com>
*
* 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
@ -32,12 +33,9 @@ require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
if (!empty($conf->commande->enabled))
require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
if (!empty($conf->commande->enabled))
require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
if (!empty($conf->tax->enabled))
require_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php';
require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
require_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php';
// L'espace compta/treso doit toujours etre actif car c'est un espace partage
// par de nombreux modules (banque, facture, commande a facturer, etc...) independamment
@ -148,7 +146,7 @@ if (!empty($conf->facture->enabled) && $user->rights->facture->lire)
if (!$user->rights->societe->client->voir && !$socid) $sql .= ", sc.fk_soc, sc.fk_user ";
$sql .= " FROM ".MAIN_DB_PREFIX."facture as f, ".MAIN_DB_PREFIX."societe as s";
if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
$sql .= " WHERE s.rowid = f.fk_soc AND f.fk_statut = 0";
$sql .= " WHERE s.rowid = f.fk_soc AND f.fk_statut = ".Facture::STATUS_DRAFT;
$sql .= " AND f.entity IN (".getEntity('invoice').")";
if (!$user->rights->societe->client->voir && !$socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id;
@ -175,10 +173,18 @@ if (!empty($conf->facture->enabled) && $user->rights->facture->lire)
{
$num = $db->num_rows($resql);
print '<div class="div-table-responsive-no-min">';
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th colspan="3">'.$langs->trans("CustomersDraftInvoices").($num ? '<span class="badge marginleftonlyshort">'.$num.'</span>' : '').'</th></tr>';
print '<th colspan="3">';
print $langs->trans("CustomersDraftInvoices").' ';
print '<a href="'.DOL_URL_ROOT.'/compta/facture/list.php?search_status='.Facture::STATUS_DRAFT.'">';
print '<span class="badge marginleftonlyshort">'.$num.'</span>';
print '</a>';
print '</th>';
print '</tr>';
if ($num)
{
$companystatic = new Societe($db);
@ -244,7 +250,7 @@ if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SU
$sql .= ", cc.rowid as country_id, cc.code as country_code";
$sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f, ".MAIN_DB_PREFIX."societe as s LEFT JOIN ".MAIN_DB_PREFIX."c_country as cc ON cc.rowid = s.fk_pays";
if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
$sql .= " WHERE s.rowid = f.fk_soc AND f.fk_statut = 0";
$sql .= " WHERE s.rowid = f.fk_soc AND f.fk_statut = ".FactureFournisseur::STATUS_DRAFT;
$sql .= " AND f.entity IN (".getEntity('invoice').')';
if (!$user->rights->societe->client->voir && !$socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id;
if ($socid) $sql .= " AND f.fk_soc = ".$socid;
@ -258,10 +264,18 @@ if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SU
{
$num = $db->num_rows($resql);
print '<div class="div-table-responsive-no-min">';
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th colspan="3">'.$langs->trans("SuppliersDraftInvoices").($num ? '<span class="badge marginleftonlyshort">'.$num.'</span>' : '').'</th></tr>';
print '<th colspan="3">';
print $langs->trans("SuppliersDraftInvoices").' ';
print '<a href="'.DOL_URL_ROOT.'/fourn/facture/list.php?search_status='.FactureFournisseur::STATUS_DRAFT.'">';
print '<span class="badge marginleftonlyshort">'.$num.'</span>';
print '</a>';
print '</th>';
print '</tr>';
if ($num)
{
$companystatic = new Societe($db);
@ -709,7 +723,7 @@ if (!empty($conf->facture->enabled) && !empty($conf->commande->enabled) && $user
$sql .= " AND c.entity = ".$conf->entity;
if (!$user->rights->societe->client->voir && !$socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id;
if ($socid) $sql .= " AND c.fk_soc = ".$socid;
$sql .= " AND c.fk_statut = 3";
$sql .= " AND c.fk_statut = ".Commande::STATUS_CLOSED;
$sql .= " AND c.facture = 0";
// Add where from hooks
$parameters = array();
@ -729,8 +743,15 @@ if (!empty($conf->facture->enabled) && !empty($conf->commande->enabled) && $user
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print "<tr class=\"liste_titre\">";
print '<th colspan="2">'.$langs->trans("OrdersDeliveredToBill").' <a href="'.DOL_URL_ROOT.'/commande/list.php?search_status=3&amp;billed=0"><span class="badge">'.$num.'</span></a></th>';
print '<th colspan="2">';
print $langs->trans("OrdersDeliveredToBill").' ';
print '<a href="'.DOL_URL_ROOT.'/commande/list.php?search_status='.Commande::STATUS_CLOSED.'&amp;billed=0">';
print '<span class="badge">'.$num.'</span>';
print '</a>';
print '</th>';
if (!empty($conf->global->MAIN_SHOW_HT_ON_SUMMARY)) print '<th class="right">'.$langs->trans("AmountHT").'</th>';
print '<th class="right">'.$langs->trans("AmountTTC").'</th>';
print '<th class="right">'.$langs->trans("ToBill").'</th>';
@ -822,7 +843,7 @@ if (!empty($conf->facture->enabled) && $user->rights->facture->lire)
$sql .= " FROM ".MAIN_DB_PREFIX."societe as s LEFT JOIN ".MAIN_DB_PREFIX."c_country as cc ON cc.rowid = s.fk_pays,".MAIN_DB_PREFIX."facture as f";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf on f.rowid=pf.fk_facture";
if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
$sql .= " WHERE s.rowid = f.fk_soc AND f.paye = 0 AND f.fk_statut = 1";
$sql .= " WHERE s.rowid = f.fk_soc AND f.paye = 0 AND f.fk_statut = ".Facture::STATUS_VALIDATED;
$sql .= " AND f.entity IN (".getEntity('invoice').')';
if (!$user->rights->societe->client->voir && !$socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id;
if ($socid) $sql .= " AND f.fk_soc = ".$socid;
@ -843,7 +864,15 @@ if (!empty($conf->facture->enabled) && $user->rights->facture->lire)
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre"><th colspan="2">'.$langs->trans("BillsCustomersUnpaid", $num).' <a href="'.DOL_URL_ROOT.'/compta/facture/list.php?search_status=1"><span class="badge">'.$num.'</span></a></th>';
print '<tr class="liste_titre">';
print '<th colspan="2">';
print $langs->trans("BillsCustomersUnpaid", $num).' ';
print '<a href="'.DOL_URL_ROOT.'/compta/facture/list.php?search_status='.Facture::STATUS_VALIDATED.'">';
print '<span class="badge">'.$num.'</span>';
print '</a>';
print '</th>';
print '<th class="right">'.$langs->trans("DateDue").'</th>';
if (!empty($conf->global->MAIN_SHOW_HT_ON_SUMMARY)) print '<th class="right">'.$langs->trans("AmountHT").'</th>';
print '<th class="right">'.$langs->trans("AmountTTC").'</th>';
@ -954,7 +983,7 @@ if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SU
$sql .= " WHERE s.rowid = ff.fk_soc";
$sql .= " AND ff.entity = ".$conf->entity;
$sql .= " AND ff.paye = 0";
$sql .= " AND ff.fk_statut = 1";
$sql .= " AND ff.fk_statut = ".FactureFournisseur::STATUS_VALIDATED;
if (!$user->rights->societe->client->voir && !$socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id;
if ($socid) $sql .= " AND ff.fk_soc = ".$socid;
// Add where from hooks
@ -973,7 +1002,17 @@ if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SU
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre"><th colspan="2">'.$langs->trans("BillsSuppliersUnpaid", $num).' <a href="'.DOL_URL_ROOT.'/fourn/facture/impayees.php"><span class="badge">'.$num.'</span></a></th>';
print '<tr class="liste_titre">';
print '<th colspan="2">';
print $langs->trans("BillsSuppliersUnpaid", $num).' ';
print '<a href="'.DOL_URL_ROOT.'/fourn/facture/list.php?search_status='.FactureFournisseur::STATUS_VALIDATED.'">';
// TODO: "impayees.php" looks very outdatetd and should be set to deprecated or directly remove in the next version
// <a href="'.DOL_URL_ROOT.'/fourn/facture/impayees.php">
print '<span class="badge">'.$num.'</span>';
print '</a>';
print '</th>';
print '<th class="right">'.$langs->trans("DateDue").'</th>';
if (!empty($conf->global->MAIN_SHOW_HT_ON_SUMMARY)) print '<th class="right">'.$langs->trans("AmountHT").'</th>';
print '<th class="right">'.$langs->trans("AmountTTC").'</th>';

View File

@ -168,9 +168,13 @@ class CMailFile
// Define this->sendmode
$this->sendmode = '';
if ($this->sendcontext == 'emailing' && !empty($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && $conf->global->MAIN_MAIL_SENDMODE_EMAILING != 'default')
{
$this->sendmode = $conf->global->MAIN_MAIL_SENDMODE_EMAILING;
if (!empty($this->sendcontext)) {
$smtpContextKey = strtoupper($this->sendcontext);
$keyForSMTPSendMode = 'MAIN_MAIL_SENDMODE_' . $smtpContextKey;
$smtpContextSendMode = $conf->global->{$keyForSMTPSendMode};
if (!empty($smtpContextSendMode) && $smtpContextSendMode != 'default') {
$this->sendmode = $smtpContextSendMode;
}
}
if (empty($this->sendmode)) $this->sendmode = $conf->global->MAIN_MAIL_SENDMODE;
if (empty($this->sendmode)) $this->sendmode = 'mail';
@ -635,14 +639,18 @@ class CMailFile
$keyforsmtppw = 'MAIN_MAIL_SMTPS_PW';
$keyfortls = 'MAIN_MAIL_EMAIL_TLS';
$keyforstarttls = 'MAIN_MAIL_EMAIL_STARTTLS';
if ($this->sendcontext == 'emailing' && !empty($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && $conf->global->MAIN_MAIL_SENDMODE_EMAILING != 'default')
{
$keyforsmtpserver = 'MAIN_MAIL_SMTP_SERVER_EMAILING';
$keyforsmtpport = 'MAIN_MAIL_SMTP_PORT_EMAILING';
$keyforsmtpid = 'MAIN_MAIL_SMTPS_ID_EMAILING';
$keyforsmtppw = 'MAIN_MAIL_SMTPS_PW_EMAILING';
$keyfortls = 'MAIN_MAIL_EMAIL_TLS_EMAILING';
$keyforstarttls = 'MAIN_MAIL_EMAIL_STARTTLS_EMAILING';
if (!empty($this->sendcontext)) {
$smtpContextKey = strtoupper($this->sendcontext);
$keyForSMTPSendMode = 'MAIN_MAIL_SENDMODE_' . $smtpContextKey;
$smtpContextSendMode = $conf->global->{$keyForSMTPSendMode};
if (!empty($smtpContextSendMode) && $smtpContextSendMode != 'default') {
$keyforsmtpserver = 'MAIN_MAIL_SMTP_SERVER_' . $smtpContextKey;
$keyforsmtpport = 'MAIN_MAIL_SMTP_PORT_' . $smtpContextKey;
$keyforsmtpid = 'MAIN_MAIL_SMTPS_ID_' . $smtpContextKey;
$keyforsmtppw = 'MAIN_MAIL_SMTPS_PW_' . $smtpContextKey;
$keyfortls = 'MAIN_MAIL_EMAIL_TLS_' . $smtpContextKey;
$keyforstarttls = 'MAIN_MAIL_EMAIL_STARTTLS_' . $smtpContextKey;
}
}
// Action according to choosed sending method

View File

@ -1303,6 +1303,8 @@ abstract class CommonObject
// phpcs:enable
global $langs, $conf;
$langs->loadLangs(array('bills', 'contracts', 'interventions', 'orders', 'projects', 'propal', 'ticket', 'agenda'));
$tab = array();
$sql = "SELECT DISTINCT tc.rowid, tc.code, tc.libelle, tc.position, tc.element";
@ -7645,6 +7647,12 @@ abstract class CommonObject
$this->errors[] = $langs->trans("ErrorFieldRequired", $this->fields[$key]['label']);
}
// If value is null and there is a default value for field
if (isset($this->fields[$key]['notnull']) && $this->fields[$key]['notnull'] == 1 && (!isset($values[$key]) || $values[$key] === 'NULL') && !is_null($this->fields[$key]['default']))
{
$values[$key] = $this->fields[$key]['default'];
}
// If field is an implicit foreign key field
if (preg_match('/^integer:/i', $this->fields[$key]['type']) && empty($values[$key])) {
if (isset($this->fields[$key]['default'])) $values[$key] = $this->fields[$key]['default'];

View File

@ -5680,11 +5680,11 @@ class Form
* @param string $selected Selected type
* @return string HTML select string
*/
public function selectTypeDuration($prefix, $selected = 'minute')
public function selectTypeDuration($prefix, $selected = 'i')
{
global $langs;
$TDurationTypes = array('year'=>$langs->trans('Years'), 'month'=>$langs->trans('Month'), 'week'=>$langs->trans('Weeks'), 'day'=>$langs->trans('Days'), 'hour'=>$langs->trans('Hours'), 'minute'=>$langs->trans('Minutes'));
$TDurationTypes = array('y'=>$langs->trans('Years'), 'm'=>$langs->trans('Month'), 'w'=>$langs->trans('Weeks'), 'd'=>$langs->trans('Days'), 'h'=>$langs->trans('Hours'), 'i'=>$langs->trans('Minutes'));
$retstring = '<select class="flat" id="select_'.$prefix.'type_duration" name="'.$prefix.'type_duration">';
foreach ($TDurationTypes as $key=>$typeduration) {
@ -7977,9 +7977,10 @@ class Form
*
* @param string $prefix Prefix
* @param string $modelType Model type
* @param int $default 1=Show also Default mail template
* @return string HTML select string
*/
public function selectModelMail($prefix, $modelType = '')
public function selectModelMail($prefix, $modelType = '', $default = 0)
{
global $langs, $db, $user;
@ -7991,6 +7992,7 @@ class Form
$formmail = new FormMail($db);
$result = $formmail->fetchAllEMailTemplate($modelType, $user, $langs);
if ($default) $TModels[0] = $langs->trans('DefaultMailModel');
if ($result > 0) {
foreach ($formmail->lines_model as $model){
$TModels[$model->id] = $model->label;

View File

@ -122,7 +122,7 @@ class FormFile
$out .= '<input type="hidden" name="sortorder" value="'.GETPOST('sortorder', 'aZ09').'">';
}
$out .= '<table class="nobordernopadding cenpercent">';
$out .= '<table class="nobordernopadding centpercent">';
$out .= '<tr>';
if (!empty($options)) $out .= '<td>'.$options.'</td>';

View File

@ -1253,6 +1253,8 @@ class FormMail extends Form
$defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendShipping");
} elseif ($type_template == 'fichinter_send') {
$defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendFichInter");
} elseif ($type_template == 'actioncomm_send') {
$defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendActionComm");
} elseif (!empty($type_template)) {
$defaultmessage = $outputlangs->transnoentities("PredefinedMailContentGeneric");
}

View File

@ -1769,6 +1769,14 @@ function email_admin_prepare_head()
$head[$h][2] = 'common_emailing';
$h++;
}
if ($conf->ticket->enabled)
{
$head[$h][0] = DOL_URL_ROOT."/admin/mails_ticket.php";
$head[$h][1] = $langs->trans("OutGoingEmailSetupForEmailing", $langs->transnoentitiesnoconv("Ticket"));
$head[$h][2] = 'common_ticket';
$h++;
}
}
$head[$h][0] = DOL_URL_ROOT."/admin/mails_templates.php";

View File

@ -6244,6 +6244,13 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null,
if (is_object($object) && $object->element == 'commande') $substitutionarray['__URL_ORDER__'] = DOL_MAIN_URL_ROOT."/commande/card.php?id=".$object->id;
if (is_object($object) && $object->element == 'facture') $substitutionarray['__URL_INVOICE__'] = DOL_MAIN_URL_ROOT."/compta/facture/card.php?id=".$object->id;
}
if (is_object($object) && $object->element == 'action')
{
$substitutionarray['__EVENT_LABEL__'] = $object->label;
$substitutionarray['__EVENT_DATE__'] = dol_print_date($object->datep, '%A %d %b %Y');
$substitutionarray['__EVENT_TIME__'] = dol_print_date($object->datep, '%H:%M:%S');
}
}
}
if (empty($exclude) || !in_array('objectamount', $exclude))

View File

@ -1339,7 +1339,7 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM
}
// Reports
$newmenu->add("/compta/resultat/index.php?mainmenu=accountancy&amp;leftmenu=accountancy_report", $langs->trans("Reportings"), 1, $user->rights->accounting->comptarapport->lire, '', $mainmenu, 'ca');
$newmenu->add("/accountancy/index.php?leftmenu=accountancy_report", $langs->trans("Reportings"), 1, $user->rights->accounting->comptarapport->lire, '', $mainmenu, 'ca');
if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_report/', $leftmenu)) {
$newmenu->add("/compta/resultat/index.php?leftmenu=accountancy_report", $langs->trans("MenuReportInOut"), 2, $user->rights->accounting->comptarapport->lire);

View File

@ -796,7 +796,7 @@ class pdf_standard extends ModeleExpenseReport
$pdf->MultiCell(80, 5, $outputlangs->transnoentities("TripNDF")." :", 0, 'L');
$pdf->rect($posx, $posy, $this->page_largeur - $this->marge_gauche - $posx, $hautcadre);
// Informations for trip (dates and users workflow)
// Informations for expense report (dates and users workflow)
if ($object->fk_user_author > 0) {
$userfee = new User($this->db);
$userfee->fetch($object->fk_user_author);
@ -804,7 +804,7 @@ class pdf_standard extends ModeleExpenseReport
$pdf->SetXY($posx + 2, $posy);
$pdf->SetFont('', '', 10);
$pdf->MultiCell(96, 4, $outputlangs->transnoentities("AUTHOR")." : ".dolGetFirstLastname($userfee->firstname, $userfee->lastname), 0, 'L');
$posy += 5;
$posy = $pdf->GetY() + 1;
$pdf->SetXY($posx + 2, $posy);
$pdf->MultiCell(96, 4, $outputlangs->transnoentities("DateCreation")." : ".dol_print_date($object->date_create, "day", false, $outputlangs), 0, 'L');
}
@ -822,8 +822,7 @@ class pdf_standard extends ModeleExpenseReport
$pdf->SetXY($posx + 2, $posy);
$pdf->MultiCell(96, 4, $outputlangs->transnoentities("DATE_REFUS")." : ".dol_print_date($object->date_refuse, "day", false, $outputlangs), 0, 'L');
}
} elseif ($object->fk_statut == 4)
{
} elseif ($object->fk_statut == 4) {
if ($object->fk_user_cancel > 0) {
$userfee = new User($this->db);
$userfee->fetch($object->fk_user_cancel); $posy += 6;

View File

@ -198,16 +198,19 @@ class InterfaceTicketEmail extends DolibarrTriggers
/* Send email to admin */
$subject = '['.$conf->global->MAIN_INFO_SOCIETE_NOM.'] '.$langs->transnoentities('TicketNewEmailSubjectAdmin');
$message_admin = $langs->transnoentities('TicketNewEmailBodyAdmin', $object->track_id)."\n\n";
$message_admin = $langs->transnoentities('TicketNewEmailBodyAdmin', $object->track_id).'<br><br>';
$message_admin .= '<ul><li>'.$langs->trans('Title').' : '.$object->subject.'</li>';
$message_admin .= '<li>'.$langs->trans('Type').' : '.$object->type_label.'</li>';
$message_admin .= '<li>'.$langs->trans('Category').' : '.$object->category_label.'</li>';
$message_admin .= '<li>'.$langs->trans('Severity').' : '.$object->severity_label.'</li>';
$message_admin .= '<li>'.$langs->trans('From').' : '.($object->email_from ? $object->email_from : ($object->fk_user_create > 0 ? $langs->trans('Internal') : '')).'</li>';
// Extrafields
$extraFields = new ExtraFields($this->db);
$extraFields->fetch_name_optionals_label($object->table_element);
if (is_array($object->array_options) && count($object->array_options) > 0) {
foreach ($object->array_options as $key => $value) {
$message_admin .= '<li>'.$langs->trans($key).' : '.$value.'</li>';
$key = substr($key, 8); // remove "options_"
$message_admin .= '<li>' . $langs->trans($extraFields->attributes[$object->element]['label'][$key]) . ' : ' . $extraFields->showOutputField($key, $value) . '</li>';
}
}
$message_admin .= '</ul>';
@ -217,14 +220,16 @@ class InterfaceTicketEmail extends DolibarrTriggers
$message_admin .= '<p>'.$langs->trans('Company').' : '.$object->thirdparty->name.'</p>';
}
$message_admin .= '<p>'.$langs->trans('Message').' : <br>'.$object->message.'</p>';
$message = $object->message;
if (!dol_textishtml($message)) {
$message = dol_nl2br($message);
}
$message_admin .= '<p>'.$langs->trans('Message').' : <br>'.$message.'</p>';
$message_admin .= '<p><a href="'.dol_buildpath('/ticket/card.php', 2).'?track_id='.$object->track_id.'">'.$langs->trans('SeeThisTicketIntomanagementInterface').'</a></p>';
$from = $conf->global->MAIN_INFO_SOCIETE_NOM.'<'.$conf->global->TICKET_NOTIFICATION_EMAIL_FROM.'>';
$replyto = $from;
$message_admin = dol_nl2br($message_admin);
$trackid = 'tic'.$object->id;
if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) {
@ -232,7 +237,7 @@ class InterfaceTicketEmail extends DolibarrTriggers
$conf->global->MAIN_MAIL_AUTOCOPY_TO = '';
}
include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
$mailfile = new CMailFile($subject, $sendto, $from, $message_admin, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, -1);
$mailfile = new CMailFile($subject, $sendto, $from, $message_admin, $filepath, $mimetype, $filename, '', '', 0, -1, '', '', $trackid, '', 'ticket');
if ($mailfile->error) {
dol_syslog($mailfile->error, LOG_DEBUG);
} else {
@ -263,7 +268,7 @@ class InterfaceTicketEmail extends DolibarrTriggers
$mimetype = array();
$subject = '['.$conf->global->MAIN_INFO_SOCIETE_NOM.'] '.$langs->transnoentities('TicketNewEmailSubjectCustomer');
$message_customer = $langs->transnoentities('TicketNewEmailBodyCustomer', $object->track_id)."\n\n";
$message_customer = $langs->transnoentities('TicketNewEmailBodyCustomer', $object->track_id).'<br><br>';
$message_customer .= '<ul><li>'.$langs->trans('Title').' : '.$object->subject.'</li>';
$message_customer .= '<li>'.$langs->trans('Type').' : '.$object->type_label.'</li>';
$message_customer .= '<li>'.$langs->trans('Category').' : '.$object->category_label.'</li>';
@ -291,7 +296,12 @@ class InterfaceTicketEmail extends DolibarrTriggers
}
$message_customer .= '</ul>';
$message_customer .= '<p>'.$langs->trans('Message').' : <br>'.$object->message.'</p>';
$message = $object->message;
if (!dol_textishtml($message)) {
$message = dol_nl2br($message);
}
$message_customer .= '<p>'.$langs->trans('Message').' : <br>'.$message.'</p>';
$url_public_ticket = ($conf->global->TICKET_URL_PUBLIC_INTERFACE ? $conf->global->TICKET_URL_PUBLIC_INTERFACE.'/' : dol_buildpath('/public/ticket/view.php', 2)).'?track_id='.$object->track_id;
$message_customer .= '<p>'.$langs->trans('TicketNewEmailBodyInfosTrackUrlCustomer').' : <a href="'.$url_public_ticket.'">'.$url_public_ticket.'</a></p>';
$message_customer .= '<p>'.$langs->trans('TicketEmailPleaseDoNotReplyToThisEmail').'</p>';
@ -299,8 +309,6 @@ class InterfaceTicketEmail extends DolibarrTriggers
$from = $conf->global->MAIN_INFO_SOCIETE_NOM.'<'.$conf->global->TICKET_NOTIFICATION_EMAIL_FROM.'>';
$replyto = $from;
$message_customer = dol_nl2br($message_customer);
$trackid = 'tic'.$object->id;
if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) {
@ -308,7 +316,7 @@ class InterfaceTicketEmail extends DolibarrTriggers
$conf->global->MAIN_MAIL_AUTOCOPY_TO = '';
}
include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
$mailfile = new CMailFile($subject, $sendto, $from, $message_customer, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, -1, '', '', $trackid);
$mailfile = new CMailFile($subject, $sendto, $from, $message_customer, $filepath, $mimetype, $filename, '', '', 0, -1, '', '', $trackid, '', 'ticket');
if ($mailfile->error) {
dol_syslog($mailfile->error, LOG_DEBUG);
} else {

View File

@ -1305,8 +1305,12 @@ if ($action == 'create')
$detail = '';
$detail .= $langs->trans("Batch").': '.$dbatch->batch;
$detail .= ' - '.$langs->trans("SellByDate").': '.dol_print_date($dbatch->sellby, "day");
$detail .= ' - '.$langs->trans("EatByDate").': '.dol_print_date($dbatch->eatby, "day");
if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
$detail .= ' - '.$langs->trans("SellByDate").': '.dol_print_date($dbatch->sellby, "day");
}
if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
$detail .= ' - '.$langs->trans("EatByDate").': '.dol_print_date($dbatch->eatby, "day");
}
$detail .= ' - '.$langs->trans("Qty").': '.$dbatch->qty;
$detail .= '<br>';
print $detail;
@ -2308,8 +2312,12 @@ if ($action == 'create')
foreach ($lines[$i]->detail_batch as $dbatch) // $dbatch is instance of ExpeditionLineBatch
{
$detail .= $langs->trans("Batch").': '.$dbatch->batch;
$detail .= ' - '.$langs->trans("SellByDate").': '.dol_print_date($dbatch->sellby, "day");
$detail .= ' - '.$langs->trans("EatByDate").': '.dol_print_date($dbatch->eatby, "day");
if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
$detail .= ' - '.$langs->trans("SellByDate").': '.dol_print_date($dbatch->sellby, "day");
}
if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
$detail .= ' - '.$langs->trans("EatByDate").': '.dol_print_date($dbatch->eatby, "day");
}
$detail .= ' - '.$langs->trans("Qty").': '.$dbatch->qty;
$detail .= '<br>';
}

View File

@ -2195,10 +2195,10 @@ if ($action == 'create')
{
print '<td class="nowrap right">';
print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=editline&amp;rowid='.$line->rowid.'">';
print '<a class="editfielda reposition paddingrightonly" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=editline&amp;rowid='.$line->rowid.'">';
print img_edit();
print '</a> &nbsp; ';
print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=delete_line&amp;rowid='.$line->rowid.'">';
print '<a class="paddingrightonly" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=delete_line&amp;rowid='.$line->rowid.'">';
print img_delete();
print '</a>';

View File

@ -384,12 +384,12 @@ class SupplierInvoices extends DolibarrApi
*
* @param int $id Id of invoice
* @param string $datepaye {@from body} Payment date {@type timestamp}
* @param int $paiementid {@from body} Payment mode Id {@min 1}
* @param int $payment_mode_id {@from body} Payment mode ID (look it up via REST GET to /setup/dictionary/payment_types) {@min 1}
* @param string $closepaidinvoices {@from body} Close paid invoices {@choice yes,no}
* @param int $accountid {@from body} Account Id {@min 1}
* @param string $num_payment {@from body} Payment number (optional)
* @param int $accountid {@from body} Bank account ID (look it up via REST GET to /bankaccounts) {@min 1}
* @param string $num_payment {@from body} Payment number (optional)
* @param string $comment {@from body} Note (optional)
* @param string $chqemetteur {@from body} Payment issuer (mandatory if paiementcode = 'CHQ')
* @param string $chqemetteur {@from body} Payment issuer (mandatory if payment_mode_id corresponds to 'CHQ'-payment type)
* @param string $chqbank {@from body} Issuer bank name (optional)
*
* @url POST {id}/payments
@ -399,7 +399,7 @@ class SupplierInvoices extends DolibarrApi
* @throws RestException 401
* @throws RestException 404
*/
public function addPayment($id, $datepaye, $paiementid, $closepaidinvoices, $accountid, $num_payment = '', $comment = '', $chqemetteur = '', $chqbank = '')
public function addPayment($id, $datepaye, $payment_mode_id, $closepaidinvoices, $accountid, $num_payment = '', $comment = '', $chqemetteur = '', $chqbank = '')
{
global $conf;
@ -416,12 +416,12 @@ class SupplierInvoices extends DolibarrApi
if (!empty($conf->banque->enabled)) {
if (empty($accountid)) {
throw new RestException(400, 'Account ID is mandatory');
throw new RestException(400, 'Bank account ID is mandatory');
}
}
if (empty($paiementid)) {
throw new RestException(400, 'Paiement ID or Paiement Code is mandatory');
if (empty($payment_mode_id)) {
throw new RestException(400, 'Payment mode ID is mandatory');
}
@ -452,8 +452,8 @@ class SupplierInvoices extends DolibarrApi
$paiement->datepaye = $datepaye;
$paiement->amounts = $amounts; // Array with all payments dispatching with invoice id
$paiement->multicurrency_amounts = $multicurrency_amounts; // Array with all payments dispatching
$paiement->paiementid = $paiementid;
$paiement->paiementcode = dol_getIdFromCode($this->db, $paiementid, 'c_paiement', 'id', 'code', 1);
$paiement->paiementid = $payment_mode_id;
$paiement->paiementcode = dol_getIdFromCode($this->db, $payment_mode_id, 'c_paiement', 'id', 'code', 1);
$paiement->oper = $paiement->paiementcode; // For backward compatibility
$paiement->num_payment = $num_payment;
$paiement->note_public = $comment;

View File

@ -177,7 +177,7 @@ class PaiementFourn extends Paiement
foreach ($amounts as $key => $value)
{
$value_converted = Multicurrency::getAmountConversionFromInvoiceRate($key, $value, $way, 'facture_fourn');
$value_converted = Multicurrency::getAmountConversionFromInvoiceRate($key, $value? $value : 0, $way, 'facture_fourn');
$totalamount_converted += $value_converted;
$amounts_to_update[$key] = price2num($value_converted, 'MT');

View File

@ -733,8 +733,12 @@ if ($id > 0 || !empty($ref)) {
print '<td>'.$langs->trans("Description").'</td>';
if (!empty($conf->productbatch->enabled)) {
print '<td class="dispatch_batch_number_title">'.$langs->trans("batch_number").'</td>';
print '<td class="dispatch_dluo_title">'.$langs->trans("EatByDate").'</td>';
print '<td class="dispatch_dlc_title">'.$langs->trans("SellByDate").'</td>';
if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
print '<td class="dispatch_dluo_title">'.$langs->trans("EatByDate").'</td>';
}
if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
print '<td class="dispatch_dlc_title">'.$langs->trans("SellByDate").'</td>';
}
} else {
print '<td></td>';
print '<td></td>';
@ -819,8 +823,12 @@ if ($id > 0 || !empty($ref)) {
print $linktoprod;
print "</td>";
print '<td class="dispatch_batch_number"></td>';
print '<td class="dispatch_dluo"></td>';
print '<td class="dispatch_dlc"></td>';
if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
print '<td class="dispatch_dluo"></td>';
}
if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
print '<td class="dispatch_dlc"></td>';
}
} else {
print '<td>';
print $linktoprod;
@ -828,8 +836,12 @@ if ($id > 0 || !empty($ref)) {
print '<td class="dispatch_batch_number">';
print $langs->trans("ProductDoesNotUseBatchSerial");
print '</td>';
print '<td class="dispatch_dluo"></td>';
print '<td class="dispatch_dlc"></td>';
if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
print '<td class="dispatch_dluo"></td>';
}
if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
print '<td class="dispatch_dlc"></td>';
}
}
} else {
print '<td colspan="4">';
@ -896,14 +908,18 @@ if ($id > 0 || !empty($ref)) {
print '<td>';
print '<input type="text" class="inputlotnumber quatrevingtquinzepercent" id="lot_number'.$suffix.'" name="lot_number'.$suffix.'" value="'.GETPOST('lot_number'.$suffix).'">';
print '</td>';
print '<td class="nowraponall">';
$dlcdatesuffix = dol_mktime(0, 0, 0, GETPOST('dlc'.$suffix.'month'), GETPOST('dlc'.$suffix.'day'), GETPOST('dlc'.$suffix.'year'));
print $form->selectDate($dlcdatesuffix, 'dlc'.$suffix, '', '', 1, '');
print '</td>';
print '<td class="nowraponall">';
$dluodatesuffix = dol_mktime(0, 0, 0, GETPOST('dluo'.$suffix.'month'), GETPOST('dluo'.$suffix.'day'), GETPOST('dluo'.$suffix.'year'));
print $form->selectDate($dluodatesuffix, 'dluo'.$suffix, '', '', 1, '');
print '</td>';
if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
print '<td class="nowraponall">';
$dlcdatesuffix = dol_mktime(0, 0, 0, GETPOST('dlc' . $suffix . 'month'), GETPOST('dlc' . $suffix . 'day'), GETPOST('dlc' . $suffix . 'year'));
print $form->selectDate($dlcdatesuffix, 'dlc' . $suffix, '', '', 1, '');
print '</td>';
}
if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
print '<td class="nowraponall">';
$dluodatesuffix = dol_mktime(0, 0, 0, GETPOST('dluo'.$suffix.'month'), GETPOST('dluo'.$suffix.'day'), GETPOST('dluo'.$suffix.'year'));
print $form->selectDate($dluodatesuffix, 'dluo'.$suffix, '', '', 1, '');
print '</td>';
}
print '<td colspan="3">&nbsp</td>'; // Supplier ref + Qty ordered + qty already dispatched
} else {
$type = 'dispatch';
@ -1118,8 +1134,12 @@ if ($id > 0 || !empty($ref)) {
print '<td>'.$langs->trans("DateDeliveryPlanned").'</td>';
if (!empty($conf->productbatch->enabled)) {
print '<td class="dispatch_batch_number_title">'.$langs->trans("batch_number").'</td>';
print '<td class="dispatch_dluo_title">'.$langs->trans("EatByDate").'</td>';
print '<td class="dispatch_dlc_title">'.$langs->trans("SellByDate").'</td>';
if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
print '<td class="dispatch_dluo_title">' . $langs->trans("EatByDate") . '</td>';
}
if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
print '<td class="dispatch_dlc_title">' . $langs->trans("SellByDate") . '</td>';
}
}
print '<td class="right">'.$langs->trans("QtyDispatched").'</td>';
print '<td>'.$langs->trans("Warehouse").'</td>';
@ -1174,8 +1194,12 @@ if ($id > 0 || !empty($ref)) {
$lot=new Productlot($db);
$lot->fetch(0, $objp->pid, $objp->batch);
print '<td class="dispatch_batch_number">'.$lot->getNomUrl(1).'</td>';
print '<td class="dispatch_dluo">'.dol_print_date($lot->eatby, 'day').'</td>';
print '<td class="dispatch_dlc">'.dol_print_date($lot->sellby, 'day').'</td>';
if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
print '<td class="dispatch_dluo">' . dol_print_date($lot->eatby, 'day') . '</td>';
}
if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
print '<td class="dispatch_dlc">' . dol_print_date($lot->sellby, 'day') . '</td>';
}
} else {
print '<td class="dispatch_batch_number"></td>';
print '<td class="dispatch_dluo"></td>';

View File

@ -2015,9 +2015,12 @@ if ($action == 'create')
print '</td></tr>';
// Bank Account
print '<tr><td>'.$langs->trans('BankAccount').'</td><td>';
$form->select_comptes((GETPOSTISSET('fk_account') ?GETPOST('fk_account', 'alpha') : $fk_account), 'fk_account', 0, '', 1);
print '</td></tr>';
if (!empty($conf->banque->enabled))
{
print '<tr><td>'.$langs->trans('BankAccount').'</td><td>';
$form->select_comptes((GETPOSTISSET('fk_account') ?GETPOST('fk_account', 'alpha') : $fk_account), 'fk_account', 0, '', 1);
print '</td></tr>';
}
// Multicurrency
if (!empty($conf->multicurrency->enabled))
@ -2589,21 +2592,24 @@ if ($action == 'create')
}
// Bank Account
print '<tr><td class="nowrap">';
print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
print $langs->trans('BankAccount');
print '<td>';
if ($action != 'editbankaccount' && $usercancreate)
print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editbankaccount&amp;id='.$object->id.'">'.img_edit($langs->trans('SetBankAccount'), 1).'</a></td>';
print '</tr></table>';
print '</td><td colspan="3">';
if ($action == 'editbankaccount') {
$form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'fk_account', 1);
} else {
$form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'none');
if (!empty($conf->banque->enabled))
{
print '<tr><td class="nowrap">';
print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
print $langs->trans('BankAccount');
print '<td>';
if ($action != 'editbankaccount' && $usercancreate)
print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editbankaccount&amp;id='.$object->id.'">'.img_edit($langs->trans('SetBankAccount'), 1).'</a></td>';
print '</tr></table>';
print '</td><td colspan="3">';
if ($action == 'editbankaccount') {
$form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'fk_account', 1);
} else {
$form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'none');
}
print "</td>";
print '</tr>';
}
print "</td>";
print '</tr>';
// Incoterms
if (!empty($conf->incoterm->enabled))

View File

@ -205,6 +205,8 @@ ALTER TABLE llx_recruitment_recruitmentcandidature_extrafields ADD INDEX idx_rec
ALTER TABLE llx_recruitment_recruitmentcandidature ADD UNIQUE INDEX uk_recruitmentcandidature_email_msgid(email_msgid);
ALTER TABLE llx_product_attribute ADD COLUMN ref_ext VARCHAR(255) after ref;
ALTER TABLE llx_product_attribute_combination ADD COLUMN variation_ref_ext varchar(255) AFTER variation_weight;
CREATE TABLE llx_product_attribute_combination_price_level
@ -301,7 +303,12 @@ insert into llx_c_action_trigger (code,label,description,elementtype,rang) value
ALTER TABLE llx_actioncomm_reminder ADD COLUMN entity integer NOT NULL DEFAULT 1;
ALTER TABLE llx_actioncomm_reminder ADD COLUMN fk_actioncomm integer NOT NULL;
ALTER TABLE llx_actioncomm_reminder ADD COLUMN fk_email_template integer;
ALTER TABLE llx_actioncomm_reminder DROP INDEX uk_actioncomm_reminder_unique, ADD UNIQUE uk_actioncomm_reminder_unique (fk_user, typeremind, offsetvalue, offsetunit, fk_actioncomm);
ALTER TABLE llx_actioncomm_reminder DROP INDEX uk_actioncomm_reminder_unique;
ALTER TABLE llx_actioncomm_reminder ADD UNIQUE uk_actioncomm_reminder_unique (fk_user, typeremind, offsetvalue, offsetunit, fk_actioncomm);
ALTER TABLE llx_actioncomm_reminder ADD INDEX idx_actioncomm_reminder_status (status);
ALTER TABLE llx_inventorydet ADD UNIQUE uk_inventorydet(fk_inventory, fk_warehouse, fk_product, batch);

View File

@ -15,9 +15,9 @@
-- BEGIN MODULEBUILDER INDEXES
ALTER TABLE llx_actioncomm_reminder ADD INDEX idx_actioncomm_reminder_rowid (rowid);
ALTER TABLE llx_actioncomm_reminder ADD INDEX idx_actioncomm_reminder_dateremind (dateremind);
ALTER TABLE llx_actioncomm_reminder ADD INDEX idx_actioncomm_reminder_fk_user (fk_user);
ALTER TABLE llx_actioncomm_reminder ADD INDEX idx_actioncomm_reminder_status (status);
-- END MODULEBUILDER INDEXES
ALTER TABLE llx_actioncomm_reminder ADD UNIQUE INDEX uk_actioncomm_reminder_unique(fk_actioncomm, fk_user, typeremind, offsetvalue, offsetunit);

View File

@ -1,5 +1,6 @@
-- ============================================================================
-- Copyright (C) 2016 Marcos García <marcosgdf@gmail.com>
-- Copyright (C) 2020 Laurent Destailleur <eldy@users.sourceforge.net>
--
-- 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
@ -14,12 +15,15 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <https://www.gnu.org/licenses/>.
--
-- llx_product_attribute is table for labels of product variants attributes. For exemple: COLOR, SIZE, ...
-- The different possible values (for example BLUE, GREEN, ... for COLOR) are defined into llx_product_attribute_value.
-- ============================================================================
CREATE TABLE llx_product_attribute
(
rowid INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
ref VARCHAR(255) NOT NULL,
ref_ext VARCHAR(255) NOT NULL,
label VARCHAR(255) NOT NULL,
rang INT DEFAULT 0 NOT NULL,
entity INT DEFAULT 1 NOT NULL

View File

@ -1,5 +1,6 @@
-- ============================================================================
-- Copyright (C) 2016 Marcos García <marcosgdf@gmail.com>
-- Copyright (C) 2020 Laurent Destailleur <eldy@users.sourceforge.net>
--
-- 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
@ -14,7 +15,7 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <https://www.gnu.org/licenses/>.
--
-- Table to store all product variants of a parent product
-- Table to store links between a parent product and its variant products.
-- ============================================================================
CREATE TABLE llx_product_attribute_combination
@ -25,5 +26,6 @@ CREATE TABLE llx_product_attribute_combination
variation_price DOUBLE(24,8) NOT NULL,
variation_price_percentage INTEGER NULL,
variation_weight REAL NOT NULL,
variation_ref_ext VARCHAR(255) NULL,
entity INTEGER DEFAULT 1 NOT NULL
)ENGINE=innodb;

View File

@ -15,6 +15,8 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <https://www.gnu.org/licenses/>.
--
-- llx_product_attribute_value is table for different available values of a product variants attributes.
-- For example BLUE, GREEN, ... for the product attribute COLOR.
-- ============================================================================
CREATE TABLE llx_product_attribute_value

View File

@ -165,4 +165,5 @@ TimeType=Duration type
ReminderType=Callback type
AddReminder=Create an automatic reminder notification for this event
ErrorReminderActionCommCreation=Error creating the reminder notification for this event
BrowserPush=Browser Notification
BrowserPush=Browser Notification
EventReminder=Event Reminder

View File

@ -456,3 +456,6 @@ PaymentTermsSupplier=Payment Term - Vendor
PaymentTypeBoth=Payment Type - Customer and Vendor
MulticurrencyUsed=Use Multicurrency
MulticurrencyCurrency=Currency
InEEC=Europe (EEC)
RestOfEurope=Rest of Europe (EEC)
OutOfEurope=Out of Europe (EEC)

View File

@ -155,6 +155,7 @@ RemoveLink=Remove link
AddToDraft=Add to draft
Update=Update
Close=Close
CloseAs=Set status to
CloseBox=Remove widget from your dashboard
Confirm=Confirm
ConfirmSendCardByMail=Do you really want to send the content of this card by mail to <b>%s</b>?
@ -1083,4 +1084,5 @@ CREATEInDolibarr=Record %s created
MODIFYInDolibarr=Record %s modified
DELETEInDolibarr=Record %s deleted
VALIDATEInDolibarr=Record %s validated
APPROVEDInDolibarr=Record %s approved
APPROVEDInDolibarr=Record %s approved
DefaultMailModel=Default Mail Model

View File

@ -117,6 +117,7 @@ SendingEmailOnMemberValidation=Sending email on new member validation
SendingEmailOnNewSubscription=Sending email on new subscription
SendingReminderForExpiredSubscription=Sending reminder for expired subscriptions
SendingEmailOnCancelation=Sending email on cancelation
SendingReminderActionComm=Sending reminder for agenda event
# Topic of email templates
YourMembershipRequestWasReceived=Your membership was received.
YourMembershipWasValidated=Your membership was validated

View File

@ -101,6 +101,7 @@ PredefinedMailContentSendShipping=__(Hello)__\n\nPlease find shipping __REF__ at
PredefinedMailContentSendFichInter=__(Hello)__\n\nPlease find intervention __REF__ attached\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
PredefinedMailContentLink=You can click on the link below to make your payment if it is not already done.\n\n%s\n\n
PredefinedMailContentGeneric=__(Hello)__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
PredefinedMailContentSendActionComm=Event reminder "__EVENT_LABEL__" on __EVENT_DATE__ at __EVENT_TIME__<br><br>This is an automatic message, please do not reply.
DemoDesc=Dolibarr is a compact ERP/CRM supporting several business modules. A demo showcasing all modules makes no sense as this scenario never occurs (several hundred available). So, several demo profiles are available.
ChooseYourDemoProfil=Choose the demo profile that best suits your needs...
ChooseYourDemoProfilMore=...or build your own profile<br>(manual module selection)

View File

@ -47,7 +47,6 @@ SendPropalByMail=Send commercial proposal by mail
DatePropal=Date of proposal
DateEndPropal=Validity ending date
ValidityDuration=Validity duration
CloseAs=Set status to
SetAcceptedRefused=Set accepted/refused
ErrorPropalNotFound=Propal %s not found
AddToDraftProposals=Add to draft proposal

View File

@ -160,9 +160,10 @@ DateStartPlusOne=Date de début + 1 heure
SetAllEventsToTodo=Réglez tous les événements à "A faire"
SetAllEventsToInProgress=Définir tous les événements à "En cours"
SetAllEventsToFinished=Définir tous les événements sur "Terminés"
ReminderTime=Reminder period before the event
TimeType=Duration type
ReminderType=Callback type
AddReminder=Create an automatic reminder notification for this event
ErrorReminderActionCommCreation=Error creating the reminder notification for this event
BrowserPush=Browser Notification
ReminderTime=Délai de rappel avant l'événement
TimeType=Type de durée
ReminderType=Type de rappel
AddReminder=Créer une notification de rappel automatique pour cet évènement
ErrorReminderActionCommCreation=Erreur lors de la création de la notification de rappel de cet événement
BrowserPush=Notification navigateur
EventReminder=Rappel événement

View File

@ -97,8 +97,12 @@ PredefinedMailContentSendSupplierOrder=__(Hello)__\n\nVeuillez trouver, ci-joint
PredefinedMailContentSendSupplierInvoice=__(Hello)__\n\nVeuillez trouver, ci-joint, la facture __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
PredefinedMailContentSendShipping=__(Hello)__\n\nVeuillez trouver, ci-joint, le bon d'expédition __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
PredefinedMailContentSendFichInter=__(Hello)__\n\nVeuillez trouver, ci-joint, la fiche intervention __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
PredefinedMailContentThirdparty=__(Hello)__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
PredefinedMailContentContact=__(Hello)__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
PredefinedMailContentUser=__(Hello)__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
PredefinedMailContentLink=Vous pouvez cliquer sur le lien ci-dessous pour effectuer votre paiement si ce n'est déjà fait.\n\n%s\n\n
PredefinedMailContentGeneric=__(Hello)__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
PredefinedMailContentSendActionComm=Rappel événement "__EVENT_LABEL__" le __EVENT_DATE__ à __EVENT_TIME__<br><br>Ceci est un message automatique, merci de ne pas répondre.
DemoDesc=Dolibarr est un logiciel de gestion proposant plusieurs modules métiers. Une démonstration qui inclut tous ces modules n'a pas de sens car ce cas n'existe jamais (plusieurs centaines de modules disponibles). Aussi, quelques profils type de démo sont disponibles.
ChooseYourDemoProfil=Veuillez choisir le profil de démonstration qui correspond le mieux à votre activité…
ChooseYourDemoProfilMore=...ou construisez votre propre profil<br>(sélection manuelle des modules)

View File

@ -143,6 +143,12 @@ $arrayfields = array(
//'m.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500),
//'m.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500)
);
if (!empty($conf->global->PRODUCT_DISABLE_EATBY)) {
unset($arrayfields['pl.eatby']);
}
if (!empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
unset($arrayfields['pl.sellby']);
}
$objectlist->fields = dol_sort_array($objectlist->fields, 'position');
$arrayfields = dol_sort_array($arrayfields, 'position');

View File

@ -455,7 +455,7 @@ class Products extends DolibarrApi
* @throws RestException 401
* @throws RestException 404
*
* @url DELETE {id}/subproducts/remove
* @url DELETE {id}/subproducts/remove/{subproduct_id}
*/
public function delSubproducts($id, $subproduct_id)
{

View File

@ -284,8 +284,12 @@ if ($resql)
print '<td class="liste_titre center"><input class="flat" type="text" name="search_batch" size="6" value="'.$search_batch.'"></td>';
print '<td class="liste_titre right">&nbsp;</td>';
print '<td class="liste_titre">&nbsp;</td>';
print '<td class="liste_titre">&nbsp;</td>';
print '<td class="liste_titre">&nbsp;</td>';
if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
print '<td class="liste_titre">&nbsp;</td>';
}
if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
print '<td class="liste_titre">&nbsp;</td>';
}
print '<td class="liste_titre">&nbsp;</td>';
print '<td class="liste_titre">&nbsp;</td>';
print '<td class="liste_titre maxwidthsearch">';
@ -302,8 +306,12 @@ if ($resql)
print_liste_field_titre("Warehouse", $_SERVER["PHP_SELF"], "e.ref", $param, "", '', $sortfield, $sortorder);
//print_liste_field_titre("DesiredStock", $_SERVER["PHP_SELF"], "p.desiredstock",$param,"",'',$sortfield,$sortorder, 'right );
print_liste_field_titre("Batch", $_SERVER["PHP_SELF"], "pb.batch", $param, "", '', $sortfield, $sortorder, 'center ');
print_liste_field_titre("EatByDate", $_SERVER["PHP_SELF"], "pb.eatby", $param, "", '', $sortfield, $sortorder, 'center ');
print_liste_field_titre("SellByDate", $_SERVER["PHP_SELF"], "pb.sellby", $param, "", '', $sortfield, $sortorder, 'center ');
if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
print_liste_field_titre("EatByDate", $_SERVER["PHP_SELF"], "pb.eatby", $param, "", '', $sortfield, $sortorder, 'center ');
}
if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
print_liste_field_titre("SellByDate", $_SERVER["PHP_SELF"], "pb.sellby", $param, "", '', $sortfield, $sortorder, 'center ');
}
print_liste_field_titre("PhysicalStock", $_SERVER["PHP_SELF"], "stock_physique", $param, "", '', $sortfield, $sortorder, 'right ');
// TODO Add info of running suppliers/customers orders
//print_liste_field_titre("TheoreticalStock",$_SERVER["PHP_SELF"], "stock_theorique",$param,"",'',$sortfield,$sortorder, 'right ');
@ -400,8 +408,12 @@ if ($resql)
}
print '</td>';
print '<td class="center">'.dol_print_date($db->jdate($objp->eatby), 'day').'</td>';
print '<td class="center">'.dol_print_date($db->jdate($objp->sellby), 'day').'</td>';
if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
print '<td class="center">'.dol_print_date($db->jdate($objp->eatby), 'day').'</td>';
}
if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
print '<td class="center">'.dol_print_date($db->jdate($objp->sellby), 'day').'</td>';
}
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;

View File

@ -1,8 +1,9 @@
<?php
/* Copyright (C) 2003-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2004-2016 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2009 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2019 Nicolas ZABOURI <info@inovea-conseil.com>
/* Copyright (C) 2003-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2004-2016 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2009 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2019 Nicolas ZABOURI <info@inovea-conseil.com>
* Copyright (C) 2020 Tobias Sekan <tobias.sekan@startmail.com>
*
* 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
@ -19,9 +20,9 @@
*/
/**
* \file htdocs/product/stock/index.php
* \ingroup stock
* \brief Home page of stock area
* \file htdocs/product/stock/index.php
* \ingroup stock
* \brief Home page of stock area
*/
require '../../main.inc.php';
@ -60,22 +61,22 @@ print '<div class="fichecenter"><div class="fichethirdleft">';
if (!empty($conf->global->MAIN_SEARCH_FORM_ON_HOME_AREAS)) // This is useless due to the global search combo
{
print '<form method="post" action="'.DOL_URL_ROOT.'/product/stock/list.php">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder nohover centpercent">';
print "<tr class=\"liste_titre\">";
print '<td colspan="3">'.$langs->trans("Search").'</td></tr>';
print '<tr class="oddevene"><td>';
print $langs->trans("Warehouse").':</td><td><input class="flat" type="text" size="18" name="sall"></td><td rowspan="2"><input type="submit" value="'.$langs->trans("Search").'" class="button"></td></tr>';
print "</table></div></form><br>";
print '<form method="post" action="'.DOL_URL_ROOT.'/product/stock/list.php">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder nohover centpercent">';
print "<tr class=\"liste_titre\">";
print '<td colspan="3">'.$langs->trans("Search").'</td></tr>';
print '<tr class="oddevene"><td>';
print $langs->trans("Warehouse").':</td><td><input class="flat" type="text" size="18" name="sall"></td><td rowspan="2"><input type="submit" value="'.$langs->trans("Search").'" class="button"></td></tr>';
print "</table></div></form><br>";
}
$max = 15;
$sql = "SELECT e.rowid, e.ref as label, e.lieu, e.statut as status";
$sql .= " FROM ".MAIN_DB_PREFIX."entrepot as e";
$sql .= " WHERE e.statut in (0,1)";
$sql .= " WHERE e.statut in (".Entrepot::STATUS_CLOSED.",".Entrepot::STATUS_OPEN_ALL.")";
$sql .= " AND e.entity IN (".getEntity('stock').")";
$sql .= $db->order('e.statut', 'DESC');
$sql .= $db->plimit($max + 1, 0);
@ -84,45 +85,55 @@ $result = $db->query($sql);
if ($result)
{
$num = $db->num_rows($result);
$num = $db->num_rows($result);
$i = 0;
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th colspan="2">';
print $langs->trans("Warehouses").' ';
print '<a href="'.DOL_URL_ROOT.'/product/stock/list.php">';
// TODO: "search_status" on "/product/stock/list.php" currently only accept a single integer value
//print '<a href="'.DOL_URL_ROOT.'/product/stock/list.php?search_status='.Entrepot::STATUS_CLOSED.','.Entrepot::STATUS_OPEN_ALL.'">';
print '<span class="badge">'.$num.'</span>';
print '</a>';
print '</th>';
print '</tr>';
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre"><th colspan="2">'.$langs->trans("Warehouses").'</th></tr>';
$i = 0;
if ($num)
{
while ($i < min($max, $num))
{
$objp = $db->fetch_object($result);
if ($num)
{
while ($i < min($max, $num))
{
$objp = $db->fetch_object($result);
$warehouse->id = $objp->rowid;
$warehouse->statut = $objp->status;
$warehouse->label = $objp->label;
$warehouse->lieu = $objp->lieu;
$warehouse->id = $objp->rowid;
$warehouse->statut = $objp->status;
$warehouse->label = $objp->label;
$warehouse->lieu = $objp->lieu;
print '<tr class="oddeven">';
print '<td>';
print $warehouse->getNomUrl(1);
print '</td>'."\n";
print '<td class="right">';
print $warehouse->getLibStatut(5);
print '</td>';
print "</tr>\n";
$i++;
}
$db->free($result);
} else {
print '<tr><td>'.$langs->trans("None").'</td><td></td></tr>';
}
if ($num > $max) {
print '<tr><td><span class="opacitymedium">'.$langs->trans("More").'...</span></td><td></td></tr>';
}
print '<tr class="oddeven">';
print '<td>';
print $warehouse->getNomUrl(1);
print '</td>'."\n";
print '<td class="right">';
print $warehouse->getLibStatut(5);
print '</td>';
print "</tr>\n";
$i++;
}
$db->free($result);
}
if ($num > $max) {
print '<tr><td><span class="opacitymedium">'.$langs->trans("More").'...</span></td><td></td></tr>';
}
print "</table>";
print '</div>';
print "</table>";
print '</div>';
} else {
dol_print_error($db);
dol_print_error($db);
}
@ -141,7 +152,7 @@ $sql .= ", ".MAIN_DB_PREFIX."product as p";
$sql .= " WHERE m.fk_product = p.rowid";
$sql .= " AND m.fk_entrepot = e.rowid";
$sql .= " AND e.entity IN (".getEntity('stock').")";
if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) $sql .= " AND p.fk_product_type = 0";
if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) $sql .= " AND p.fk_product_type = ".Product::TYPE_PRODUCT;
$sql .= $db->order("datem", "DESC");
$sql .= $db->plimit($max, 0);
@ -151,7 +162,7 @@ if ($resql)
{
$num = $db->num_rows($resql);
print '<div class="div-table-responsive-no-min">';
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print "<tr class=\"liste_titre\">";
print '<th>'.$langs->trans("LastMovements", min($num, $max)).'</th>';
@ -159,8 +170,12 @@ if ($resql)
if (!empty($conf->productbatch->enabled))
{
print '<th>'.$langs->trans("Batch").'</th>';
print '<th>'.$langs->trans("SellByDate").'</th>';
print '<th>'.$langs->trans("EatByDate").'</th>';
if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
print '<th>'.$langs->trans("SellByDate").'</th>';
}
if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
print '<th>'.$langs->trans("EatByDate").'</th>';
}
}
print '<th>'.$langs->trans("Warehouse").'</th>';
print '<th class="right"><a class="notasortlink" href="'.DOL_URL_ROOT.'/product/stock/movement_list.php">'.$langs->trans("FullList").'</a></th>';
@ -191,8 +206,12 @@ if ($resql)
if (!empty($conf->productbatch->enabled))
{
print '<td>'.$objp->batch.'</td>';
print '<td>'.dol_print_date($db->jdate($objp->sellby), 'day').'</td>';
print '<td>'.dol_print_date($db->jdate($objp->eatby), 'day').'</td>';
if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
print '<td>'.dol_print_date($db->jdate($objp->sellby), 'day').'</td>';
}
if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
print '<td>'.dol_print_date($db->jdate($objp->eatby), 'day').'</td>';
}
}
print '<td class="tdoverflowmax200">';
print $warehouse->getNomUrl(1);
@ -206,7 +225,7 @@ if ($resql)
$db->free($resql);
print "</table>";
print '</div>';
print '</div>';
} else {
dol_print_error($db);
}

View File

@ -121,6 +121,12 @@ $arrayfields = array(
//'m.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500),
//'m.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500)
);
if (!empty($conf->global->PRODUCT_DISABLE_EATBY)) {
unset($arrayfields['pl.eatby']);
}
if (!empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
unset($arrayfields['pl.sellby']);
}
// Security check
if (!$user->rights->stock->mouvement->lire) {

View File

@ -1,14 +1,14 @@
<?php
/* Copyright (C) 2001-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2004-2015 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
* Copyright (C) 2005 Simon TOSSER <simon@kornog-computing.com>
* Copyright (C) 2005-2009 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2013 Cédric Salvador <csalvador.gpcsolutions.fr>
* Copyright (C) 2013-2018 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2014-2015 Cédric Gross <c.gross@kreiz-it.fr>
* Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
* Copyright (C) 2018-2019 Frédéric France <frederic.france@netlogic.fr>
/* Copyright (C) 2001-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2004-2020 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
* Copyright (C) 2005 Simon TOSSER <simon@kornog-computing.com>
* Copyright (C) 2005-2009 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2013 Cédric Salvador <csalvador.gpcsolutions.fr>
* Copyright (C) 2013-2018 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2014-2015 Cédric Gross <c.gross@kreiz-it.fr>
* Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
* Copyright (C) 2018-2019 Frédéric France <frederic.france@netlogic.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
@ -67,8 +67,8 @@ $stocklimit = GETPOST('seuil_stock_alerte');
$desiredstock = GETPOST('desiredstock');
$cancel = GETPOST('cancel', 'alpha');
$fieldid = isset($_GET["ref"]) ? 'ref' : 'rowid';
$d_eatby = dol_mktime(0, 0, 0, $_POST['eatbymonth'], $_POST['eatbyday'], $_POST['eatbyyear']);
$d_sellby = dol_mktime(0, 0, 0, $_POST['sellbymonth'], $_POST['sellbyday'], $_POST['sellbyyear']);
$d_eatby = dol_mktime(0, 0, 0, GETPOST('eatbymonth', 'int'), GETPOST('eatbyday', 'int'), GETPOST('eatbyyear', 'int'));
$d_sellby = dol_mktime(0, 0, 0, GETPOST('sellbymonth', 'int'), GETPOST('sellbyday', 'int'), GETPOST('sellbyyear', 'int'));
$pdluoid = GETPOST('pdluoid', 'int');
$batchnumber = GETPOST('batch_number', 'san_alpha');
if (!empty($batchnumber)) {
@ -224,7 +224,8 @@ if ($action == "correct_stock" && !$cancel)
if (!$error)
{
$priceunit = price2num(GETPOST("unitprice"));
if (is_numeric(GETPOST("nbpiece")) && $id)
$nbpiece = price2num(GETPOST("nbpiece", 'alphanohtml'));
if (is_numeric($nbpiece) && $nbpiece != 0 && $id)
{
$origin_element = '';
$origin_id = null;
@ -244,14 +245,14 @@ if ($action == "correct_stock" && !$cancel)
$result = $object->correct_stock_batch(
$user,
GETPOST("id_entrepot", 'int'),
GETPOST("nbpiece"),
GETPOST("mouvement"),
$nbpiece,
GETPOST("mouvement", 'int'),
GETPOST("label", 'alphanohtml'), // label movement
$priceunit,
$d_eatby,
$d_sellby,
$batchnumber,
GETPOST('inventorycode'),
GETPOST('inventorycode', 'alphanohtml'),
$origin_element,
$origin_id
); // We do not change value of stock for a correction
@ -259,11 +260,11 @@ if ($action == "correct_stock" && !$cancel)
$result = $object->correct_stock(
$user,
GETPOST("id_entrepot", 'int'),
GETPOST("nbpiece"),
GETPOST("mouvement"),
$nbpiece,
GETPOST("mouvement", 'int'),
GETPOST("label", 'alphanohtml'),
$priceunit,
GETPOST('inventorycode'),
GETPOST('inventorycode', 'alphanohtml'),
$origin_element,
$origin_id
); // We do not change value of stock for a correction
@ -337,6 +338,8 @@ if ($action == "transfert_stock" && !$cancel)
if (isset($object->pmp)) $pricesrc = $object->pmp;
$pricedest = $pricesrc;
$nbpiece = price2num(GETPOST("nbpiece", 'alphanohtml'));
if ($object->hasbatch())
{
$pdluo = new Productbatch($db);
@ -361,18 +364,20 @@ if ($action == "transfert_stock" && !$cancel)
$sellby = $d_sellby;
}
$nbpiece = price2num(GETPOST("nbpiece", 'alphanohtml'));
if (!$error)
{
// Remove stock
$result1 = $object->correct_stock_batch(
$user,
$srcwarehouseid,
GETPOST("nbpiece", 'int'),
$nbpiece,
1,
GETPOST("label", 'san_alpha'),
GETPOST("label", 'alphanohtml'),
$pricesrc,
$eatby, $sellby, $batch,
GETPOST('inventorycode')
GETPOST('inventorycode', 'alphanohtml')
);
if ($result1 < 0) $error++;
}
@ -382,12 +387,12 @@ if ($action == "transfert_stock" && !$cancel)
$result2 = $object->correct_stock_batch(
$user,
GETPOST("id_entrepot_destination", 'int'),
GETPOST("nbpiece", 'int'),
$nbpiece,
0,
GETPOST("label", 'san_alpha'),
GETPOST("label", 'alphanohtml'),
$pricedest,
$eatby, $sellby, $batch,
GETPOST('inventorycode')
GETPOST('inventorycode', 'alphanohtml')
);
if ($result2 < 0) $error++;
}
@ -398,11 +403,11 @@ if ($action == "transfert_stock" && !$cancel)
$result1 = $object->correct_stock(
$user,
GETPOST("id_entrepot", 'int'),
GETPOST("nbpiece"),
$nbpiece,
1,
GETPOST("label"),
GETPOST("label", 'alphanohtml'),
$pricesrc,
GETPOST('inventorycode')
GETPOST('inventorycode', 'alphanohtml')
);
if ($result1 < 0) $error++;
}
@ -412,11 +417,11 @@ if ($action == "transfert_stock" && !$cancel)
$result2 = $object->correct_stock(
$user,
GETPOST("id_entrepot_destination", 'int'),
GETPOST("nbpiece"),
$nbpiece,
0,
GETPOST("label"),
GETPOST("label", 'alphanohtml'),
$pricedest,
GETPOST('inventorycode')
GETPOST('inventorycode', 'alphanohtml')
);
if ($result2 < 0) $error++;
}
@ -805,11 +810,18 @@ if (!$variants) {
print '<td class="right">'.$langs->trans("EstimatedStockValueSellShort").'</td>';
print '</tr>';
if ((!empty($conf->productbatch->enabled)) && $object->hasbatch()) {
$colspan = 3;
print '<tr class="liste_titre"><td width="10%"></td>';
print '<td class="right" width="10%">'.$langs->trans("batch_number").'</td>';
print '<td class="center" width="10%">'.$langs->trans("EatByDate").'</td>';
print '<td class="center" width="10%">'.$langs->trans("SellByDate").'</td>';
print '<td></td>';
if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
$colspan--;
print '<td class="center" width="10%">'.$langs->trans("EatByDate").'</td>';
}
if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
$colspan--;
print '<td class="center" width="10%">'.$langs->trans("SellByDate").'</td>';
}
print '<td colspan="'.$colspan.'"></td>';
print '<td></td>';
print '<td></td>';
print '<td></td>';
@ -888,13 +900,17 @@ if (!$variants) {
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="pdluoid" value="'.$pdluo->id.'"><input type="hidden" name="action" value="updateline"><input type="hidden" name="id" value="'.$id.'"><table class="noborder centpercent"><tr><td width="10%"></td>';
print '<td class="right" width="10%"><input type="text" name="batch_number" value="'.$pdluo->batch.'"></td>';
print '<td class="center" width="10%">';
print $form->selectDate($pdluo->eatby, 'eatby', '', '', 1, '', 1, 0);
print '</td>';
print '<td class="center" width="10%">';
print $form->selectDate($pdluo->sellby, 'sellby', '', '', 1, '', 1, 0);
print '</td>';
print '<td class="right" width="10%">'.$pdluo->qty.($pdluo->qty < 0 ? ' '.img_warning() : '').'</td>';
if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
print '<td class="center" width="10%">';
print $form->selectDate($pdluo->eatby, 'eatby', '', '', 1, '', 1, 0);
print '</td>';
}
if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
print '<td class="center" width="10%">';
print $form->selectDate($pdluo->sellby, 'sellby', '', '', 1, '', 1, 0);
print '</td>';
}
print '<td class="right" colspan="3">'.$pdluo->qty.($pdluo->qty < 0 ? ' '.img_warning() : '').'</td>';
print '<td colspan="4"><input type="submit" class="button" id="savelinebutton marginbottomonly" name="save" value="'.$langs->trans("Save").'">';
print '<input type="submit" class="button" id="cancellinebutton" name="Cancel" value="'.$langs->trans("Cancel").'"></td></tr>';
print '</table>';
@ -911,9 +927,16 @@ if (!$variants) {
print '<td class="right">';
print $product_lot_static->getNomUrl(1);
print '</td>';
print '<td class="center">'.dol_print_date($pdluo->eatby, 'day').'</td>';
print '<td class="center">'.dol_print_date($pdluo->sellby, 'day').'</td>';
print '<td class="right">'.$pdluo->qty.($pdluo->qty < 0 ? ' '.img_warning() : '').'</td>';
$colspan = 3;
if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
$colspan--;
print '<td class="center">'.dol_print_date($pdluo->eatby, 'day').'</td>';
}
if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
$colspan--;
print '<td class="center">'.dol_print_date($pdluo->sellby, 'day').'</td>';
}
print '<td class="right" colspan="'.$colspan.'">'.$pdluo->qty.($pdluo->qty < 0 ? ' '.img_warning() : '').'</td>';
print '<td colspan="4"></td>';
print '</tr>';
}

View File

@ -327,21 +327,24 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
print '</td></tr>';
// Eat by
print '<tr><td>';
print $form->editfieldkey($langs->trans('EatByDate'), 'eatby', $object->eatby, $object, $user->rights->stock->creer, 'datepicker');
print '</td><td>';
print $form->editfieldval($langs->trans('EatByDate'), 'eatby', $object->eatby, $object, $user->rights->stock->creer, 'datepicker');
print '</td>';
print '</tr>';
if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
print '<tr><td>';
print $form->editfieldkey($langs->trans('EatByDate'), 'eatby', $object->eatby, $object, $user->rights->stock->creer, 'datepicker');
print '</td><td>';
print $form->editfieldval($langs->trans('EatByDate'), 'eatby', $object->eatby, $object, $user->rights->stock->creer, 'datepicker');
print '</td>';
print '</tr>';
}
// Sell by
print '<tr><td>';
print $form->editfieldkey($langs->trans('SellByDate'), 'sellby', $object->sellby, $object, $user->rights->stock->creer, 'datepicker');
print '</td><td>';
print $form->editfieldval($langs->trans('SellByDate'), 'sellby', $object->sellby, $object, $user->rights->stock->creer, 'datepicker');
print '</td>';
print '</tr>';
if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
print '<tr><td>';
print $form->editfieldkey($langs->trans('SellByDate'), 'sellby', $object->sellby, $object, $user->rights->stock->creer, 'datepicker');
print '</td><td>';
print $form->editfieldval($langs->trans('SellByDate'), 'sellby', $object->sellby, $object, $user->rights->stock->creer, 'datepicker');
print '</td>';
print '</tr>';
}
// Other attributes
$cols = 2;
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';

View File

@ -99,6 +99,12 @@ $arrayfields = array(
't.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500),
//'t.statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000),
);
if (!empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
unset($arrayfields['t.sellby']);
}
if (!empty($conf->global->PRODUCT_DISABLE_EATBY)) {
unset($arrayfields['t.eatby']);
}
// Extra fields
if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label']) > 0)
{

View File

@ -103,14 +103,18 @@ if (!empty($conf->productbatch->enabled) &&
print '</td>';
print '</tr>';
print '<tr>';
print '<td>'.$langs->trans("EatByDate").'</td><td>';
$eatbyselected = dol_mktime(0, 0, 0, GETPOST('eatbymonth'), GETPOST('eatbyday'), GETPOST('eatbyyear'));
print $form->selectDate($eatbyselected, 'eatby', '', '', 1, "");
print '</td>';
print '<td>'.$langs->trans("SellByDate").'</td><td>';
$sellbyselected = dol_mktime(0, 0, 0, GETPOST('sellbymonth'), GETPOST('sellbyday'), GETPOST('sellbyyear'));
print $form->selectDate($sellbyselected, 'sellby', '', '', 1, "");
print '</td>';
if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
print '<td>'.$langs->trans("EatByDate").'</td><td>';
$eatbyselected = dol_mktime(0, 0, 0, GETPOST('eatbymonth'), GETPOST('eatbyday'), GETPOST('eatbyyear'));
print $form->selectDate($eatbyselected, 'eatby', '', '', 1, "");
print '</td>';
}
if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
print '<td>'.$langs->trans("SellByDate").'</td><td>';
$sellbyselected = dol_mktime(0, 0, 0, GETPOST('sellbymonth'), GETPOST('sellbyday'), GETPOST('sellbyyear'));
print $form->selectDate($sellbyselected, 'sellby', '', '', 1, "");
print '</td>';
}
print '</tr>';
}

View File

@ -107,12 +107,16 @@ if (!empty($conf->productbatch->enabled) &&
print '</tr>';
print '<tr>';
print '<td>'.$langs->trans("EatByDate").'</td><td>';
print $form->selectDate(($d_eatby ? $d_eatby : $pdluo->eatby), 'eatby', '', '', 1, "", 1, 0, ($pdluoid > 0 ? 1 : 0)); // If form was opened for a specific pdluoid, field is disabled
print '</td>';
print '<td>'.$langs->trans("SellByDate").'</td><td>';
print $form->selectDate(($d_sellby ? $d_sellby : $pdluo->sellby), 'sellby', '', '', 1, "", 1, 0, ($pdluoid > 0 ? 1 : 0)); // If form was opened for a specific pdluoid, field is disabled
print '</td>';
if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
print '<td>'.$langs->trans("EatByDate").'</td><td>';
print $form->selectDate(($d_eatby ? $d_eatby : $pdluo->eatby), 'eatby', '', '', 1, "", 1, 0, ($pdluoid > 0 ? 1 : 0)); // If form was opened for a specific pdluoid, field is disabled
print '</td>';
}
if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
print '<td>'.$langs->trans("SellByDate").'</td><td>';
print $form->selectDate(($d_sellby ? $d_sellby : $pdluo->sellby), 'sellby', '', '', 1, "", 1, 0, ($pdluoid > 0 ? 1 : 0)); // If form was opened for a specific pdluoid, field is disabled
print '</td>';
}
print '</tr>';
}

View File

@ -966,8 +966,12 @@ if ($action == 'create')
if (!empty($conf->productbatch->enabled))
{
print '<td class="left">'.$langs->trans("batch_number").'</td>';
print '<td class="left">'.$langs->trans("EatByDate").'</td>';
print '<td class="left">'.$langs->trans("SellByDate").'</td>';
if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
print '<td class="left">'.$langs->trans("EatByDate").'</td>';
}
if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
print '<td class="left">'.$langs->trans("SellByDate").'</td>';
}
}
print "</tr>\n";
}
@ -1114,12 +1118,16 @@ if ($action == 'create')
if (!empty($product->status_batch))
{
print '<td><input name="batch'.$indiceAsked.'" value="'.$dispatchLines[$indiceAsked]['lot'].'"></td>';
print '<td>';
print $form->selectDate($dispatchLines[$indiceAsked]['DLC'], 'dlc'.$indiceAsked, '', '', 1, "");
print '</td>';
print '<td>';
print $form->selectDate($dispatchLines[$indiceAsked]['DLUO'], 'dluo'.$indiceAsked, '', '', 1, "");
print '</td>';
if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
print '<td>';
print $form->selectDate($dispatchLines[$indiceAsked]['DLC'], 'dlc'.$indiceAsked, '', '', 1, "");
print '</td>';
}
if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
print '<td>';
print $form->selectDate($dispatchLines[$indiceAsked]['DLUO'], 'dluo'.$indiceAsked, '', '', 1, "");
print '</td>';
}
} else {
print '<td colspan="3"></td>';
}
@ -1807,10 +1815,14 @@ if ($action == 'create')
if ($conf->productbatch->enabled && !empty($lines[$i]->product->status_batch))
{
print '<td> <input name="batch'.$line_id.'" id="batch'.$line_id.'" type="text" value="'.$lines[$i]->batch.'"> </br>';
print $langs->trans('EatByDate').' : ';
print $form->selectDate($lines[$i]->eatby, 'dlc'.$line_id, '', '', 1, "").'</br>';
print $langs->trans('SellByDate').' : ';
print $form->selectDate($lines[$i]->sellby, 'dluo'.$line_id, '', '', 1, "");
if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
print $langs->trans('EatByDate').' : ';
print $form->selectDate($lines[$i]->eatby, 'dlc'.$line_id, '', '', 1, "").'</br>';
}
if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
print $langs->trans('SellByDate').' : ';
print $form->selectDate($lines[$i]->sellby, 'dluo'.$line_id, '', '', 1, "");
}
print '</td>';
}
print '</tr>';
@ -1856,11 +1868,14 @@ if ($action == 'create')
$detail = '';
if ($lines[$i]->product->status_batch)
{
$detail .= $langs->trans("Batch").': '.$lines[$i]->batch;
$detail .= $langs->trans("Batch").': '.$lines[$i]->batch;
if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
$detail .= ' - '.$langs->trans("SellByDate").': '.dol_print_date($lines[$i]->sellby, "day");
}
if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
$detail .= ' - '.$langs->trans("EatByDate").': '.dol_print_date($lines[$i]->eatby, "day");
$detail .= '<br>';
}
$detail .= '<br>';
print $form->textwithtooltip(img_picto('', 'object_barcode').' '.$langs->trans("DetailBatchNumber"), $detail);
} else {

View File

@ -712,7 +712,7 @@ class RecruitmentCandidature extends CommonObject
$label .= '<br>';
$label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
$label .= '<br><b>'.$langs->trans('Email').':</b> '.$this->email;
$label .= '<br><b>'.$langs->trans('Fullname').':</b> '.$this->getFullName($langs);
$label .= '<br><b>'.$langs->trans('Name').':</b> '.$this->getFullName($langs);
if (isset($this->status)) {
$label .= '<br><b>'.$langs->trans("Status").":</b> ".$this->getLibStatut(5);
}

View File

@ -122,7 +122,7 @@ class RecruitmentJobPosition extends CommonObject
'last_main_doc' => array('type'=>'varchar(255)', 'label'=>'LastMainDoc', 'enabled'=>'1', 'position'=>900, 'notnull'=>0, 'visible'=>0,),
'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>'1', 'position'=>1000, 'notnull'=>-1, 'visible'=>-2,),
'model_pdf' => array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>'1', 'position'=>1010, 'notnull'=>-1, 'visible'=>0,),
'status' => array('type'=>'smallint', 'label'=>'Status', 'enabled'=>'1', 'position'=>1000, 'notnull'=>1, 'visible'=>1, 'default'=>'0', 'index'=>1, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Validated', '3'=>'Recruited', '9'=>'Canceled'),),
'status' => array('type'=>'smallint', 'label'=>'Status', 'enabled'=>'1', 'position'=>1000, 'notnull'=>1, 'visible'=>5, 'default'=>'0', 'index'=>1, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Validated', '3'=>'Recruited', '9'=>'Canceled'),),
);
public $rowid;
public $ref;
@ -660,6 +660,99 @@ class RecruitmentJobPosition extends CommonObject
return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'RECRUITMENTJOBPOSITION_CLOSE');
}
/**
* Close the commercial proposal
*
* @param User $user Object user that close
* @param int $status Statut
* @param string $note Complete private note with this note
* @param int $notrigger 1=Does not execute triggers, 0=Execute triggers
* @return int <0 if KO, >0 if OK
*/
public function cloture($user, $status, $note = "", $notrigger = 0)
{
global $langs, $conf;
$error = 0;
$now = dol_now();
$this->db->begin();
$newprivatenote = dol_concatdesc($this->note_private, $note);
$sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
$sql .= " SET status = ".$status.", note_private = '".$this->db->escape($newprivatenote)."'";
//$sql .= ", date_cloture='".$this->db->idate($now)."', fk_user_cloture=".$user->id;
$sql .= " WHERE rowid = ".$this->id;
$resql = $this->db->query($sql);
if ($resql)
{
$modelpdf = $this->modelpdf;
$triggerName = 'PROPAL_CLOSE_REFUSED';
if ($status == self::STATUS_RECRUITED)
{
$triggerName = 'RECRUITMENTJOB_CLOSE_RECRUITED';
$modelpdf = $this->modelpdf;
if ($result < 0)
{
$this->error = $this->db->lasterror();
$this->db->rollback();
return -2;
}
}
if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
{
// Define output language
$outputlangs = $langs;
if (!empty($conf->global->MAIN_MULTILANGS))
{
$outputlangs = new Translate("", $conf);
$newlang = (GETPOST('lang_id', 'aZ09') ? GETPOST('lang_id', 'aZ09') : $this->thirdparty->default_lang);
$outputlangs->setDefaultLang($newlang);
}
//$ret=$object->fetch($id); // Reload to get new records
$this->generateDocument($modelpdf, $outputlangs);
}
if (!$error)
{
$this->oldcopy = clone $this;
$this->status = $status;
$this->date_cloture = $now;
$this->note_private = $newprivatenote;
}
if (!$notrigger && empty($error))
{
// Call trigger
$result = $this->call_trigger($triggerName, $user);
if ($result < 0) { $error++; }
// End call triggers
}
if (!$error)
{
$this->db->commit();
return 1;
} else {
$this->status = $this->oldcopy->status;
$this->date_cloture = $this->oldcopy->date_cloture;
$this->note_private = $this->oldcopy->note_private;
$this->db->rollback();
return -1;
}
} else {
$this->error = $this->db->lasterror();
$this->db->rollback();
return -1;
}
}
/**
* Set back to validated status
*
@ -818,7 +911,9 @@ class RecruitmentJobPosition extends CommonObject
}
$statusType = 'status'.$status;
if ($status == self::STATUS_CANCELED) $statusType = 'status6';
if ($status == self::STATUS_VALIDATED) $statusType = 'status4';
if ($status == self::STATUS_RECRUITED) $statusType = 'status6';
if ($status == self::STATUS_CANCELED) $statusType = 'status9';
return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
}

View File

@ -116,8 +116,8 @@ if ($conf->use_javascript_ajax)
{
$dataseries[] = array(dol_html_entity_decode($staticrecruitmentjobposition->LibStatut($status, 1), ENT_QUOTES), (isset($vals[$status]) ? (int) $vals[$status] : 0));
if ($status == RecruitmentJobPosition::STATUS_DRAFT) $colorseries[$status] = '-'.$badgeStatus0;
if ($status == RecruitmentJobPosition::STATUS_VALIDATED) $colorseries[$status] = $badgeStatus1;
if ($status == RecruitmentJobPosition::STATUS_RECRUITED) $colorseries[$status] = $badgeStatus4;
if ($status == RecruitmentJobPosition::STATUS_VALIDATED) $colorseries[$status] = $badgeStatus4;
if ($status == RecruitmentJobPosition::STATUS_RECRUITED) $colorseries[$status] = $badgeStatus6;
if ($status == RecruitmentJobPosition::STATUS_CANCELED) $colorseries[$status] = $badgeStatus9;
if (empty($conf->use_javascript_ajax))
@ -195,7 +195,7 @@ if ($conf->use_javascript_ajax)
if ($status == RecruitmentCandidature::STATUS_VALIDATED) $colorseries[$status] = $badgeStatus1;
if ($status == RecruitmentCandidature::STATUS_CONTRACT_PROPOSED) $colorseries[$status] = $badgeStatus4;
if ($status == RecruitmentCandidature::STATUS_CONTRACT_SIGNED) $colorseries[$status] = $badgeStatus5;
if ($status == RecruitmentCandidature::STATUS_REFUSED) $colorseries[$status] = $badgeStatus8;
if ($status == RecruitmentCandidature::STATUS_REFUSED) $colorseries[$status] = $badgeStatus9;
if ($status == RecruitmentCandidature::STATUS_CANCELED) $colorseries[$status] = $badgeStatus9;
if (empty($conf->use_javascript_ajax))
@ -323,7 +323,7 @@ $max = 3;
// Last modified job position
if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->recruitmentjobposition->read)
{
$sql = "SELECT s.rowid, s.ref, s.label, s.date_creation, s.tms";
$sql = "SELECT s.rowid, s.ref, s.label, s.date_creation, s.tms, s.status";
$sql.= " FROM ".MAIN_DB_PREFIX."recruitment_recruitmentjobposition as s";
if (! $user->rights->societe->client->voir && ! $socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
$sql.= " WHERE s.entity IN (".getEntity($staticrecruitmentjobposition->element).")";
@ -343,7 +343,7 @@ if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->recruitm
print '<th colspan="2">';
print $langs->trans("BoxTitleLatestModifiedJobPositions", $max);
print '</th>';
print '<th class="right"><a href="'.DOL_URL_ROOT.'/recruitment/recruitmentjobposition_list.php?sortfield=t.tms&sortorder=DESC">'.$langs->trans("FullList").'</th>';
print '<th class="right" colspan="2"><a href="'.DOL_URL_ROOT.'/recruitment/recruitmentjobposition_list.php?sortfield=t.tms&sortorder=DESC">'.$langs->trans("FullList").'</th>';
print '</tr>';
if ($num)
{
@ -361,13 +361,16 @@ if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->recruitm
print '<td class="right nowrap">';
print "</td>";
print '<td class="right nowrap">'.dol_print_date($db->jdate($objp->tms), 'day')."</td>";
print '<td class="right nowrap">';
print $staticrecruitmentjobposition->getLibStatut(3);
print "</td>";
print '</tr>';
$i++;
}
$db->free($resql);
} else {
print '<tr class="oddeven"><td colspan="3" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
print '<tr class="oddeven"><td colspan="4" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
}
print "</table><br>";
} else {
@ -378,7 +381,7 @@ if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->recruitm
// Last modified job position
if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->recruitmentjobposition->read)
{
$sql = "SELECT rc.rowid, rc.ref, rc.date_creation, rc.tms";
$sql = "SELECT rc.rowid, rc.ref, rc.email, rc.lastname, rc.firstname, rc.date_creation, rc.tms, rc.status";
$sql.= " FROM ".MAIN_DB_PREFIX."recruitment_recruitmentcandidature as rc";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."recruitment_recruitmentjobposition as s ON rc.fk_recruitmentjobposition = s.rowid";
if (! $user->rights->societe->client->voir && ! $socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
@ -399,7 +402,7 @@ if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->recruitm
print '<th colspan="2">';
print $langs->trans("BoxTitleLatestModifiedCandidatures", $max);
print '</th>';
print '<th class="right"><a href="'.DOL_URL_ROOT.'/recruitment/recruitmentcandidature_list.php?sortfield=t.tms&sortorder=DESC">'.$langs->trans("FullList").'</th>';
print '<th class="right" colspan="2"><a href="'.DOL_URL_ROOT.'/recruitment/recruitmentcandidature_list.php?sortfield=t.tms&sortorder=DESC">'.$langs->trans("FullList").'</th>';
print '</tr>';
if ($num)
{
@ -408,21 +411,27 @@ if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->recruitm
$objp = $db->fetch_object($resql);
$staticrecruitmentcandidature->id=$objp->rowid;
$staticrecruitmentcandidature->ref=$objp->ref;
$staticrecruitmentcandidature->email=$objp->email;
$staticrecruitmentcandidature->status = $objp->status;
$staticrecruitmentcandidature->date_creation = $objp->date_creation;
$staticrecruitmentcandidature->firstname = $objp->firstname;
$staticrecruitmentcandidature->lastname = $objp->lastname;
print '<tr class="oddeven">';
print '<td class="nowrap">'.$staticrecruitmentcandidature->getNomUrl(1, '').'</td>';
print '<td class="right nowrap">';
print "</td>";
print '<td class="right nowrap">'.dol_print_date($db->jdate($objp->tms), 'day')."</td>";
print '<td class="right nowrap">';
print $staticrecruitmentcandidature->getLibStatut(3);
print "</td>";
print '</tr>';
$i++;
}
$db->free($resql);
} else {
print '<tr class="oddeven"><td colspan="3" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
print '<tr class="oddeven"><td colspan="4" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
}
print "</table><br>";
} else {

View File

@ -109,6 +109,8 @@ $permissionnote = $user->rights->recruitment->recruitmentjobposition->write; //
$permissiondellink = $user->rights->recruitment->recruitmentjobposition->write; // Used by the include of actions_dellink.inc.php
$upload_dir = $conf->recruitment->multidir_output[isset($object->entity) ? $object->entity : 1];
$usercanclose = $permissiontoadd;
// Security check - Protection if external user
//if ($user->socid > 0) accessforbidden();
//if ($user->socid > 0) $socid = $user->socid;
@ -163,6 +165,32 @@ if (empty($reshook))
{
$object->setProject(GETPOST('projectid', 'int'));
}
if ($action == 'confirm_closeas' && $usercanclose && !GETPOST('cancel', 'alpha')) {
if (!(GETPOST('status', 'int') > 0)) {
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CloseAs")), null, 'errors');
$action = 'closeas';
} else {
// prevent browser refresh from closing proposal several times
if ($object->status == $object::STATUS_VALIDATED)
{
$db->begin();
$result = $object->cloture($user, GETPOST('status', 'int'), GETPOST('note_private', 'none'));
if ($result < 0)
{
setEventMessages($object->error, $object->errors, 'errors');
$error++;
}
if (!$error)
{
$db->commit();
} else {
$db->rollback();
}
}
}
}
// Actions to send emails
$triggersendname = 'RECRUITMENTJOBPOSITION_SENTBYMAIL';
@ -286,22 +314,24 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
$formquestion = array();
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneAsk', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
}
// Confirmation of action xxxx
if ($action == 'xxx')
if ($action == 'closeas')
{
$formquestion = array();
/*
$forcecombo=0;
if ($conf->browser->name == 'ie') $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy
//Form to close proposal (signed or not)
$formquestion = array(
// 'text' => $langs->trans("ConfirmClone"),
// array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
// array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
// array('type' => 'other', 'name' => 'idwarehouse', 'label' => $langs->trans("SelectWarehouseForStockDecrease"), 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse')?GETPOST('idwarehouse'):'ifone', 'idwarehouse', '', 1, 0, 0, '', 0, $forcecombo))
array('type' => 'select', 'name' => 'status', 'label' => '<span class="fieldrequired">'.$langs->trans("CloseAs").'</span>', 'values' => array(3=>$object->LibStatut($object::STATUS_RECRUITED), 9=>$object->LibStatut($object::STATUS_CANCELED))),
array('type' => 'text', 'name' => 'note_private', 'label' => $langs->trans("Note"), 'value' => '') // Field to complete private note (not replace)
);
*/
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('XXX'), $text, 'confirm_xxx', $formquestion, 0, 1, 220);
/*if (!empty($conf->notification->enabled))
{
require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
$notify = new Notify($db);
$formquestion = array_merge($formquestion, array(
array('type' => 'onecolumn', 'value' => $notify->confirmMessage('PROPAL_CLOSE_SIGNED', $object->socid, $object)),
));
}*/
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Close'), $text, 'confirm_closeas', $formquestion, '', 1, 250);
}
// Call Hook formConfirm
@ -482,6 +512,16 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
}
}
// Close as recruited/canceled
if ($object->status == $object::STATUS_VALIDATED) {
if ($usercanclose) {
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=closeas'.(empty($conf->global->MAIN_JUMP_TAG) ? '' : '#close').'"';
print '>'.$langs->trans('Close').'</a>';
} else {
print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotEnoughPermissions")).'">'.$langs->trans('Close').'</a>';
}
}
// Clone
if ($permissiontoadd) {
print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&socid='.$object->socid.'&action=clone&object=recruitmentjobposition">'.$langs->trans("ToClone").'</a>'."\n";
@ -497,9 +537,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
}*/
if ($permissiontoadd)
{
if ($object->status == $object::STATUS_VALIDATED) {
print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=confirm_close&confirm=yes">'.$langs->trans("Cancel").'</a>'."\n";
} else {
if ($object->status == $object::STATUS_CANCELED) {
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=confirm_reopen&confirm=yes">'.$langs->trans("Re-Open").'</a>'."\n";
}
}

View File

@ -85,7 +85,7 @@ class Thirdparties extends DolibarrApi
* @param string $email Email of third party to load
* @return array|mixed data without useless information
*
* @url GET byEmail/{email}
* @url GET email/{email}
*
* @throws RestException
*/

View File

@ -1077,6 +1077,15 @@ table[summary="list_of_modules"] .fa-cog {
height: 100px;
}
.maxscreenheightless200 {
max-height: <?php echo isset($_SESSION['dol_screenheight']) ? max(500, $_SESSION['dol_screenheight'] - 200) : 700; ?>px; /* we guarantee height of 500 */
}
.maxscreenheightless300 {
max-height: <?php echo isset($_SESSION['dol_screenheight']) ? max(400, $_SESSION['dol_screenheight'] - 300) : 700; ?>px; /* we guarantee height of 500 */
}
/* ============================================================================== */
/* Styles to hide objects */
@ -2074,90 +2083,7 @@ a.tmenuimage:hover{
/* Do not load menu img for other if hidden to save bandwidth */
<?php if (empty($dol_hide_topmenu)) { ?>
<?php if (!defined('DISABLE_FONT_AWSOME')) { ?>
<?php include dol_buildpath($path.'/theme/'.$theme.'/main_menu_fa_icons.inc.php', 0); ?>
<?php } else { ?>
div.mainmenu.home{
background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/home_over.png', 1) ?>);
background-position-x: center;
}
div.mainmenu.billing {
background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/money_over.png', 1) ?>);
}
div.mainmenu.accountancy {
background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/money_over.png', 1) ?>);
}
div.mainmenu.agenda {
background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/agenda_over.png', 1) ?>);
}
div.mainmenu.bank {
background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/bank_over.png', 1) ?>);
}
div.mainmenu.cashdesk {
background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/pointofsale_over.png', 1) ?>);
}
div.mainmenu.takepos {
background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/pointofsale_over.png', 1) ?>);
}
div.mainmenu.companies {
background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/company_over.png', 1) ?>);
}
div.mainmenu.commercial {
background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/commercial_over.png', 1) ?>);
}
div.mainmenu.ecm {
background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/ecm_over.png', 1) ?>);
}
div.mainmenu.externalsite {
background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/externalsite_over.png', 1) ?>);
}
div.mainmenu.ftp {
background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/tools_over.png', 1) ?>);
}
div.mainmenu.hrm {
background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/holiday_over.png', 1) ?>);
}
div.mainmenu.members {
background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/members_over.png', 1) ?>);
}
div.mainmenu.products {
background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/products_over.png', 1) ?>);
}
div.mainmenu.mrp {
background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/products_over.png', 1) ?>);
}
div.mainmenu.project {
background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/project_over.png', 1) ?>);
}
div.mainmenu.ticket {
background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/ticket_over.png', 1) ?>);
}
div.mainmenu.tools {
background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/tools_over.png', 1) ?>);
}
div.mainmenu.website {
background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/externalsite_over.png', 1) ?>);
}
<?php } ?>
<?php include dol_buildpath($path.'/theme/'.$theme.'/main_menu_fa_icons.inc.php', 0); ?>
<?php
// Add here more div for other menu entries. moduletomainmenu=array('module name'=>'name of class for div')
@ -4485,7 +4411,7 @@ table.cal_month td { padding-left: 1px !important; padding-right: 1px !important
.cal_other_month_right { border-right: solid 1px #C0C0C0; }
.cal_other_month { /* opacity: 0.6; */ background: #EAEAEA; padding-<?php print $left; ?>: 2px; padding-<?php print $right; ?>: 1px; padding-top: 0px; padding-bottom: 0px; }
.cal_past_month { /* opacity: 0.6; */ background: #EEEEEE; padding-<?php print $left; ?>: 2px; padding-<?php print $right; ?>: 1px; padding-top: 0px; padding-bottom: 0px; }
.cal_current_month { background: #FFFFFF; border-left: solid 1px #E0E0E0; padding-<?php print $left; ?>: 2px; padding-<?php print $right; ?>: 1px; padding-top: 0px; padding-bottom: 0px; }
.cal_current_month { background: #FFFFFF; border-left: solid 1px #E0E0E0; padding-<?php print $left; ?>: 2px; padding-<?php print $right; ?>: 1px; padding-top: 0px; padding-bottom: 0px !important; }
.cal_current_month_peruserleft { background: #FFFFFF; border-left: solid 2px #6C7C7B; padding-<?php print $left; ?>: 2px; padding-<?php print $right; ?>: 1px; padding-top: 0px; padding-bottom: 0px; }
.cal_today { background: #FDFDF0; border-left: solid 1px #E0E0E0; border-bottom: solid 1px #E0E0E0; padding-<?php print $left; ?>: 2px; padding-<?php print $right; ?>: 1px; padding-top: 0px; padding-bottom: 0px; }
.cal_today_peruser { background: #FDFDF0; border-right: solid 1px #E0E0E0; border-bottom: solid 1px #E0E0E0; padding-<?php print $left; ?>: 2px; padding-<?php print $right; ?>: 1px; padding-top: 0px; padding-bottom: 0px; }
@ -4502,7 +4428,7 @@ table.cal_month td { padding-left: 1px !important; padding-right: 1px !important
.cal_today_peruser_impair { background: #F8F8F0; }
.peruser_busy { }
.peruser_notbusy { opacity: 0.5; }
div.event { margin: 8px; border-radius: 4px; box-shadow: 2px 2px 5px rgba(100, 100, 100, 0.2); }
div.event { margin-left: 8px; margin-right: 8px; margin-bottom: 8px; margin-top: 4px; border-radius: 4px; box-shadow: 2px 2px 5px rgba(100, 100, 100, 0.2); }
table.cal_event { border: none; border-collapse: collapse; margin-bottom: 1px; min-height: 20px; filter: saturate(0.8); border-radius: 3px; }
table.cal_event td { border: none; padding-<?php print $left; ?>: 2px; padding-<?php print $right; ?>: 2px; padding-top: 0px; padding-bottom: 0px; }
table.cal_event td.cal_event { padding: 4px 4px !important; }
@ -4514,7 +4440,9 @@ table.cal_event td.cal_event_right { padding: 4px 4px !important; }
.cal_event_notbusy a.cal_event_title:hover { color: #111111; font-weight: normal !important; color:rgba(255,255,255,.75); }
.cal_event_busy { }
.cal_peruserviewname { max-width: 140px; height: 22px; }
.cal_event span.badge.badge-status { border: 1px solid #aaa; }
table.cal_month tr td table.nobordernopadding tr td { padding: 0 2px 0 2px; }
table.cal_month tr.liste_titre td.tdfordaytitle { min-width: 120px; }
a.dayevent-aday {
padding-left: 8px;
}

View File

@ -215,7 +215,7 @@ function _createStatusBadgeCss($statusName, $statusVarNamePrefix = '', $commentL
if (!empty(${$statusVarNamePrefix.'badgeStatus'.$statusName})) {
print "\n/* ".strtoupper($commentLabel)." */\n";
$thisBadgeBackgroundColor = $thisBadgeBorderColor = ${$statusVarNamePrefix.'badgeStatus'.$statusName};
@ -233,7 +233,7 @@ function _createStatusBadgeCss($statusName, $statusVarNamePrefix = '', $commentL
if (in_array((string) $statusName, array('0', '5', '9'))) $thisBadgeTextColor = '#999999';
if (in_array((string) $statusName, array('6'))) $thisBadgeTextColor = '#777777';
print $cssPrefix.".badge-status".$statusName." {\n";
print " color: ".$thisBadgeTextColor." !important;\n";
if (in_array((string) $statusName, $TBadgeBorderOnly)) {

View File

@ -127,6 +127,7 @@ $parameters = array();
$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
$error = 0;
if (empty($reshook)) {
// Purge search criteria
if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) // All test are required to be compatible with all browsers{
@ -157,6 +158,8 @@ if (empty($reshook)) {
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Message")), null, 'errors');
$action = 'create';
}
$ret = $extrafields->setOptionalsFromPost(null, $object);
if ($ret < 0) $error++;
if (!$error) {
$db->begin();
@ -174,12 +177,10 @@ if (empty($reshook)) {
$object->fk_project = GETPOST('projectid', 'int');
$ret = $extrafields->setOptionalsFromPost(null, $object);
$id = $object->create($user);
if ($id <= 0) {
$error++;
setEventMessage($object->error, $object->errors, 'errors');
setEventMessages($object->error, $object->errors, 'errors');
$action = 'create';
}
@ -305,7 +306,7 @@ if (empty($reshook)) {
$ret = $object->update($user);
if ($ret <= 0) {
$error++;
setEventMessage($object->error, $object->errors, 'errors');
setEventMessages($object->error, $object->errors, 'errors');
$action = 'edit';
}
@ -560,18 +561,22 @@ if (empty($reshook)) {
// Action to update one extrafield
if ($action == "update_extras" && !empty($permissiontoadd)) {
$object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha'));
$attributekey = GETPOST('attribute', 'alpha');
$attributekeylong = 'options_' . $attributekey;
$object->array_options['options_' . $attributekey] = GETPOST($attributekeylong, ' alpha');
$result = $object->insertExtraFields(empty($triggermodname) ? '' : $triggermodname, $user);
if ($result > 0) {
setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
$action = 'view';
} else {
setEventMessages($object->error, $object->errors, 'errors');
$action = 'edit_extras';
$ret = $extrafields->setOptionalsFromPost(null, $object, GETPOST('attribute', 'none'));
if ($ret < 0) $error++;
if (!$error) {
$result = $object->insertExtraFields(empty($triggermodname) ? '' : $triggermodname, $user);
if ($result > 0) {
setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
$action = 'view';
} else {
$error++;
setEventMessages($object->error, $object->errors, 'errors');
}
}
if ($error) $action = 'edit_extras';
}
if ($action == "change_property" && GETPOST('btn_update_ticket_prop', 'alpha') && $user->rights->ticket->write) {

View File

@ -2539,7 +2539,11 @@ class Ticket extends CommonObject
// Message send
$message = $langs->trans('TicketMessageMailIntroText');
$message .= '<br><br>';
$message .= GETPOST('message', 'none');
$messagePost = GETPOST('message', 'restricthtml');
if (!dol_textishtml($messagePost)) {
$messagePost = dol_nl2br($messagePost);
}
$message .= $messagePost;
// Customer company infos
$message .= '<br><br>';
@ -2588,7 +2592,11 @@ class Ticket extends CommonObject
$message = $langs->trans('TicketMessageMailIntroText');
$message .= '<br><br>';
$message .= GETPOST('message', 'restricthtml');
$messagePost = GETPOST('message', 'restricthtml');
if (!dol_textishtml($messagePost)) {
$messagePost = dol_nl2br($messagePost);
}
$message .= $messagePost;
// Coordonnées client
$message .= '<br><br>';
@ -2657,9 +2665,19 @@ class Ticket extends CommonObject
$message_intro = GETPOST('mail_intro') ? GETPOST('mail_intro', 'restricthtml') : $conf->global->TICKET_MESSAGE_MAIL_INTRO;
$message_signature = GETPOST('mail_signature') ? GETPOST('mail_signature', 'restricthtml') : $conf->global->TICKET_MESSAGE_MAIL_SIGNATURE;
if (!dol_textishtml($message_intro)) {
$message_intro = dol_nl2br($message_intro);
}
if (!dol_textishtml($message_signature)) {
$message_signature = dol_nl2br($message_signature);
}
// We put intro after
$message = GETPOST('message', 'restricthtml');
$messagePost = GETPOST('message', 'restricthtml');
if (!dol_textishtml($messagePost)) {
$messagePost = dol_nl2br($messagePost);
}
$message = $messagePost;
$message .= '<br><br>';
foreach ($external_contacts as $key => $info_sendto) {
@ -2781,7 +2799,7 @@ class Ticket extends CommonObject
}
include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
$trackid = "tic".$this->id;
$mailfile = new CMailFile($subject, $receiver, $from, $message, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, -1, '', '', $trackid);
$mailfile = new CMailFile($subject, $receiver, $from, $message, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, -1, '', '', $trackid, '', 'ticket');
if ($mailfile->error) {
setEventMessages($mailfile->error, null, 'errors');
} else {

View File

@ -1,6 +1,6 @@
<?php
/* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
/* Copyright (C) 2030 Thibault FOUCART <support@ptibogxiv.net>
/* Copyright (C) 2020 Thibault FOUCART <support@ptibogxiv.net>
*
* 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
@ -143,13 +143,13 @@ class Users extends DolibarrApi
/**
* Get properties of an user object
* Return an array with user informations
*
* @param int $id ID of user
* @param int $includepermissions Set this to 1 to have the array of permissions loaded (not done by default for performance purpose)
* @return array|mixed data without useless information
*
* @throws RestException
* @throws RestException 401 Insufficient rights
* @throws RestException 404 User or group not found
*/
public function get($id, $includepermissions = 0)
{
@ -175,6 +175,78 @@ class Users extends DolibarrApi
return $this->_cleanObjectDatas($this->useraccount);
}
/**
* Get properties of an user object by login
*
* @param string $login Login of user
* @param int $includepermissions Set this to 1 to have the array of permissions loaded (not done by default for performance purpose)
* @return array|mixed data without useless information
*
* @url GET login/{login}
*
* @throws RestException 401 Insufficient rights
* @throws RestException 404 User or group not found
*/
public function getByLogin($login, $includepermissions = 0)
{
//if (!DolibarrApiAccess::$user->rights->user->user->lire) {
//throw new RestException(401);
//}
$result = $this->useraccount->fetch('', $login);
if (!$result)
{
throw new RestException(404, 'User not found');
}
if (!DolibarrApi::_checkAccessToResource('user', $this->useraccount->id, 'user'))
{
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
if ($includepermissions) {
$this->useraccount->getRights();
}
return $this->_cleanObjectDatas($this->useraccount);
}
/**
* Get properties of an user object by Email
*
* @param string $email Email of user
* @param int $includepermissions Set this to 1 to have the array of permissions loaded (not done by default for performance purpose)
* @return array|mixed data without useless information
*
* @url GET email/{email}
*
* @throws RestException 401 Insufficient rights
* @throws RestException 404 User or group not found
*/
public function getByEmail($email, $includepermissions = 0)
{
//if (!DolibarrApiAccess::$user->rights->user->user->lire) {
//throw new RestException(401);
//}
$result = $this->useraccount->fetch('', '', '', 0, -1, $email);
if (!$result)
{
throw new RestException(404, 'User not found');
}
if (!DolibarrApi::_checkAccessToResource('user', $this->useraccount->id, 'user'))
{
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
if ($includepermissions) {
$this->useraccount->getRights();
}
return $this->_cleanObjectDatas($this->useraccount);
}
/**
* Get properties of user connected
*

View File

@ -165,18 +165,12 @@ class ProductCombination
/**
* for auto retrocompatibility with last behavior
*/
$productCombinationLevel = new ProductCombinationLevel($this->db);
$productCombinationLevel->fk_price_level = intval($fk_price_level);
$productCombinationLevel->fk_product_attribute_combination = $this->id;
$productCombinationLevel->variation_price = $this->variation_price;
$productCombinationLevel->variation_price_percentage = $this->variation_price_percentage;
if ($fk_price_level>0){
$combination_price_levels[$fk_price_level] = $productCombinationLevel;
$combination_price_levels[$fk_price_level] = ProductCombinationLevel::createFromParent($this->db, $this, $fk_price_level);
}
else {
for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++){
$combination_price_levels[$i] = $productCombinationLevel;
$combination_price_levels[$i] = ProductCombinationLevel::createFromParent($this->db, $this, $i);
}
}
}
@ -234,16 +228,18 @@ class ProductCombination
/**
* Retrieves a product combination by a child product row id
* Retrieves information of a variant product and ID of its parent product.
*
* @param int $fk_child Product row id
* @return int <0 KO, >0 OK
* @param int $productid Product ID of variant
* @param int $donotloadpricelevel Avoid loading price impact for each level. If PRODUIT_MULTIPRICES is not set, this has no effect.
* @return int <0 if KO, 0 if product ID is not ID of a variant product (so parent not found), >0 if OK (ID of parent)
*/
public function fetchByFkProductChild($fk_child)
public function fetchByFkProductChild($productid, $donotloadpricelevel = 0)
{
global $conf;
$sql = "SELECT rowid, fk_product_parent, fk_product_child, variation_price, variation_price_percentage, variation_weight FROM ".MAIN_DB_PREFIX."product_attribute_combination WHERE fk_product_child = ".(int) $fk_child." AND entity IN (".getEntity('product').")";
$sql = "SELECT rowid, fk_product_parent, fk_product_child, variation_price, variation_price_percentage, variation_weight";
$sql .= " FROM ".MAIN_DB_PREFIX."product_attribute_combination WHERE fk_product_child = ".((int) $productid)." AND entity IN (".getEntity('product').")";
$query = $this->db->query($sql);
@ -252,7 +248,7 @@ class ProductCombination
}
if (!$this->db->num_rows($query)) {
return -1;
return 0;
}
$result = $this->db->fetch_object($query);
@ -264,11 +260,11 @@ class ProductCombination
$this->variation_price_percentage = $result->variation_price_percentage;
$this->variation_weight = $result->variation_weight;
if (!empty($conf->global->PRODUIT_MULTIPRICES)) {
if (empty($donotloadpricelevel) && !empty($conf->global->PRODUIT_MULTIPRICES)) {
$this->fetchCombinationPriceLevels();
}
return 1;
return $this->fk_product_parent;
}
/**
@ -1211,4 +1207,24 @@ class ProductCombinationLevel
return $res ? 1 : -1;
}
/**
* Create new Product Combination Price level from Parent
*
* @param DoliDB $db Database handler
* @param ProductCombination $productCombination Product combination
* @param int $fkPriceLevel Price level
* @return ProductCombinationLevel
*/
public static function createFromParent(DoliDB $db, ProductCombination $productCombination, $fkPriceLevel)
{
$productCombinationLevel = new self($db);
$productCombinationLevel->fk_price_level = $fkPriceLevel;
$productCombinationLevel->fk_product_attribute_combination = $productCombination->id;
$productCombinationLevel->variation_price = $productCombination->variation_price;
$productCombinationLevel->variation_price_percentage = $productCombination->variation_price_percentage;
return $productCombinationLevel;
}
}