Merge branch 'develop' of github.com:Dolibarr/dolibarr into NEW/add_real_payments_on_vat_objects

This commit is contained in:
Gauthier PC portable 024 2021-02-01 12:00:04 +01:00
commit 1eb4968a29
71 changed files with 547 additions and 321 deletions

View File

@ -265,9 +265,9 @@ Following changes may create regressions for some external modules, but were nec
* Function showStripePaymentUrl, getStripePaymentUrl, showPaypalPaymentUrl and getPaypalPaymentUrl has been removed. The generic one showOnlinePaymentUrl and getOnlinePaymentUrl are always used.
* Context for hook showSocinfoOnPrint has been moved from "showsocinfoonprint" to "main"
* Library htdocs/includes/phpoffice/phpexcel as been removed (replaced with htdocs/includes/phpoffice/PhpSpreadsheet)
* Databse transaction in your triggers must be correctly balanced (one close for one open). If not, an error will be returned by the trigger, even if trigger did return error code.
* Database transaction in your triggers must be correctly balanced (one close for one open). If not, an error will be returned by the trigger, even if trigger did return error code.
* Dolibarr v13 is still compatible with any PHP version between 5.6.0 and 7.4.*; Unit tests are OK with PHP 8.0 but some warnings or troubles may appears with PHP 8.0.
* All your Ajax services must contains such a line at begin of file: if (!defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); // Disables token renewal
***** ChangeLog for 12.0.4 compared to 12.0.3 *****
FIX: make formConfirm an addreplace-type hook

View File

@ -4,7 +4,7 @@ Priority: optional
Maintainer: Laurent Destailleur (eldy) <eldy@users.sourceforge.net>
# Uploaders: Laurent Destailleur (eldy) <eldy@users.sourceforge.net> # Only if differs from Maintainer
Standards-Version: 3.9.6
Homepage: http://www.dolibarr.org
Homepage: https://www.dolibarr.org
Build-Depends: debhelper (>= 9), po-debconf
# This package need at least debian 7 or ubuntu 13.04 or any distribution based on this version

View File

@ -370,7 +370,7 @@ class BookKeeping extends CommonObject
$sql .= ", ".(!empty($this->subledger_account) ? ("'".$this->db->escape($this->subledger_account)."'") : "NULL");
$sql .= ", ".(!empty($this->subledger_label) ? ("'".$this->db->escape($this->subledger_label)."'") : "NULL");
$sql .= ", '".$this->db->escape($this->numero_compte)."'";
$sql .= ", ".(!empty($this->label_operation) ? ("'".$this->db->escape($this->label_operation)."'") : "NULL");
$sql .= ", ".(!empty($this->label_compte) ? ("'".$this->db->escape($this->label_compte)."'") : "NULL");
$sql .= ", '".$this->db->escape($this->label_operation)."'";
$sql .= ", ".$this->debit;
$sql .= ", ".$this->credit;

View File

@ -768,7 +768,7 @@ if ($action == 'edit')
{
if (function_exists('fsockopen') && $port && $server)
{
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=testconnect#formmailbeforetitle">'.$langs->trans("DoTestServerAvailability").'</a>';
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=testconnect&date='.dol_now().'#formmailaftertstconnect">'.$langs->trans("DoTestServerAvailability").'</a>';
}
} else {
print '<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("FeatureNotAvailableOnLinux").'">'.$langs->trans("DoTestServerAvailability").'</a>';
@ -844,6 +844,7 @@ if ($action == 'edit')
// Run the test to connect
if ($action == 'testconnect')
{
print '<div id="formmailaftertstconnect" name="formmailaftertstconnect"></div>';
print load_fiche_titre($langs->trans("DoTestServerAvailability"));
include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
@ -858,6 +859,7 @@ if ($action == 'edit')
}
setEventMessages($errormsg, null, 'errors');
print $errormsg;
}
print '<br>';
}

View File

@ -523,10 +523,10 @@ if ($mode == 'common' || $mode == 'commonkanban') {
$moreforfilter .= '<div class="colorbacktimesheet float valignmiddle">';
$moreforfilter .= '<div class="divsearchfield paddingtop">';
$moreforfilter .= $langs->trans('Keyword').': <input type="text" id="search_keyword" name="search_keyword" class="maxwidth100" value="'.dol_escape_htmltag($search_keyword).'">';
$moreforfilter .= img_picto($langs->trans("Filter"), 'filter', 'class="paddingright opacitymedium"').'<input type="text" id="search_keyword" name="search_keyword" class="maxwidth100" value="'.dol_escape_htmltag($search_keyword).'" placeholder="'.dol_escape_htmltag($langs->trans('Keyword')).'">';
$moreforfilter .= '</div>';
$moreforfilter .= '<div class="divsearchfield paddingtop">';
$moreforfilter .= $langs->trans('Origin').': '.$form->selectarray('search_nature', $arrayofnatures, dol_escape_htmltag($search_nature), 1, 0, 0, '', 0, 0, 0, '', 'maxwidth200', 1);
$moreforfilter .= $form->selectarray('search_nature', $arrayofnatures, dol_escape_htmltag($search_nature), $langs->trans('Origin'), 0, 0, '', 0, 0, 0, '', 'maxwidth200', 1);
$moreforfilter .= '</div>';
if (!empty($conf->global->MAIN_FEATURES_LEVEL)) {
$array_version = array('stable'=>$langs->transnoentitiesnoconv("Stable"));
@ -540,11 +540,11 @@ if ($mode == 'common' || $mode == 'commonkanban') {
$array_version['development'] = $langs->trans("Development");
}
$moreforfilter .= '<div class="divsearchfield paddingtop">';
$moreforfilter .= $langs->trans('Version').': '.$form->selectarray('search_version', $array_version, $search_version, 1, 0, 0, '', 0, 0, 0, '', 'maxwidth150', 1);
$moreforfilter .= $form->selectarray('search_version', $array_version, $search_version, $langs->trans('Version'), 0, 0, '', 0, 0, 0, '', 'maxwidth150', 1);
$moreforfilter .= '</div>';
}
$moreforfilter .= '<div class="divsearchfield paddingtop">';
$moreforfilter .= $langs->trans('Status').': '.$form->selectarray('search_status', array('active'=>$langs->transnoentitiesnoconv("Enabled"), 'disabled'=>$langs->transnoentitiesnoconv("Disabled")), $search_status, 1, 0, 0, '', 0, 0, 0, '', 'maxwidth150', 1);
$moreforfilter .= $form->selectarray('search_status', array('active'=>$langs->transnoentitiesnoconv("Enabled"), 'disabled'=>$langs->transnoentitiesnoconv("Disabled")), $search_status, $langs->trans('Status'), 0, 0, '', 0, 0, 0, '', 'maxwidth150', 1);
$moreforfilter .= '</div>';
$moreforfilter .= ' ';
$moreforfilter .= '<div class="divsearchfield">';
@ -937,6 +937,8 @@ if ($mode == 'common' || $mode == 'commonkanban') {
if ($mode == 'marketplace') {
print dol_get_fiche_head($head, $mode, '', -1);
print '<br>';
// Marketplace
print '<div class="div-table-responsive-no-min">';
print '<table summary="list_of_modules" class="noborder centpercent">'."\n";
@ -977,8 +979,8 @@ if ($mode == 'marketplace') {
?>
<input type="hidden" name="token" value="<?php echo newToken(); ?>">
<input type="hidden" name="mode" value="marketplace">
<div class="divsearchfield"><?php echo $langs->trans('Keyword') ?>:
<input name="search_keyword" placeholder="<?php echo $langs->trans('Chercher un module') ?>" id="search_keyword" type="text" size="50" value="<?php echo $options['search'] ?>"><br>
<div class="divsearchfield">
<input name="search_keyword" placeholder="<?php echo $langs->trans('Keyword') ?>" id="search_keyword" type="text" size="50" value="<?php echo $options['search'] ?>"><br>
</div>
<div class="divsearchfield">
<input class="button buttongen" value="<?php echo $langs->trans('Rechercher') ?>" type="submit">
@ -1190,6 +1192,8 @@ if ($mode == 'deploy') {
if ($mode == 'develop') {
print dol_get_fiche_head($head, $mode, '', -1);
print '<br>';
// Marketplace
print "<table summary=\"list_of_modules\" class=\"noborder\" width=\"100%\">\n";
print "<tr class=\"liste_titre\">\n";

View File

@ -443,7 +443,6 @@ if ($mode == 'template' && $user->admin) {
print '<td><input size="50" type="text" name="templatename" value="'.$printer->listprinterstemplates[$line]['name'].'"></td>';
print '<td>';
print '<textarea name="template" wrap="soft" cols="120" rows="12">';
print GETPOSTISSET('template') ? GETPOST('template', 'alpha') : $printer->listprinterstemplates[$line]['template'];
print '</textarea>';
print '</td>';
print '<td></td>';

View File

@ -80,7 +80,7 @@ $_SESSION["commandbackuptorun"] = '';
$_SESSION["commandbackupresult"] = '';
// Increase limit of time. Works only if we are not in safe mode
$ExecTimeLimit = 600;
$ExecTimeLimit = 600; // Set it to 0 to not use a forced time limit
if (!empty($ExecTimeLimit))
{
$err = error_reporting();
@ -95,8 +95,6 @@ if (!empty($MemoryLimit))
@ini_set('memory_limit', $MemoryLimit);
}
$form = new Form($db);
$formfile = new FormFile($db);
//$help_url='EN:Backups|FR:Sauvegardes|ES:Copias_de_seguridad';
//llxHeader('','',$help_url);
@ -222,16 +220,7 @@ if ($errormsg)
}
/*
$filearray=dol_dir_list($conf->admin->dir_output.'/backup','files',0,'','',$sortfield,(strtolower($sortorder)=='asc'?SORT_ASC:SORT_DESC),1);
$result=$formfile->list_of_documents($filearray,null,'systemtools','',1,'backup/',1,0,($langs->trans("NoBackupFileAvailable").'<br>'.$langs->trans("ToBuildBackupFileClickHere",DOL_URL_ROOT.'/admin/tools/dolibarr_export.php')),0,$langs->trans("PreviousDumpFiles"));
print '<br>';
*/
// Redirect to backup page
header("Location: dolibarr_export.php".(GETPOST('page_y', 'int') ? '?page_y='.GETPOST('page_y', 'int') : ''));
$time_end = time();
$db->close();

View File

@ -425,7 +425,7 @@ class Documents extends DolibarrApi
throw new RestException(500, 'Error while fetching object: '.$object->error);
}
$upload_dir = $conf->product->multidir_output[$object->entity].'/'.get_exdir(0, 0, 0, 0, $object, 'product').dol_sanitizeFileName($object->ref);
$upload_dir = $conf->product->multidir_output[$object->entity].'/'.get_exdir(0, 0, 0, 1, $object, 'product');
}
elseif ($modulepart == 'agenda' || $modulepart == 'action' || $modulepart == 'event')
{

View File

@ -1222,13 +1222,20 @@ class ActionComm extends CommonObject
}
$sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as a";
if (!$user->rights->societe->client->voir && !$user->socid) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON a.fk_soc = sc.fk_soc";
if (!$user->rights->agenda->allactions->read) {
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."actioncomm_resources AS ar ON a.id = ar.fk_actioncomm AND ar.element_type ='user' AND ar.fk_element = ".$user->id;
}
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON a.fk_soc = s.rowid";
$sql .= " WHERE 1 = 1";
if (empty($load_state_board)) $sql .= " AND a.percent >= 0 AND a.percent < 100";
$sql .= " AND a.entity IN (".getEntity('agenda').")";
if (!$user->rights->societe->client->voir && !$user->socid) $sql .= " AND (a.fk_soc IS NULL OR sc.fk_user = ".$user->id.")";
if ($user->socid) $sql .= " AND a.fk_soc = ".$user->socid;
if (!$user->rights->agenda->allactions->read) $sql .= " AND (a.fk_user_author = ".$user->id." OR a.fk_user_action = ".$user->id." OR a.fk_user_done = ".$user->id.")";
if (!$user->rights->agenda->allactions->read) {
$sql .= " AND (a.fk_user_author = ".$user->id." OR a.fk_user_action = ".$user->id." OR a.fk_user_done = ".$user->id;
$sql .= " OR ar.fk_element = ".$user->id; // Added by PV
$sql .= ")";
}
$resql = $this->db->query($sql);
if ($resql)

View File

@ -366,7 +366,7 @@ if ($socid > 0) $sql .= " AND s.rowid = ".$socid;
if ($filtert > 0 || $usergroup > 0) $sql .= " AND ar.fk_actioncomm = a.id AND ar.element_type='user'";
if ($type) $sql .= " AND c.id = ".(int) $type;
if ($search_status == '0') { $sql .= " AND a.percent = 0"; }
if ($search_status == '-1') { $sql .= " AND a.percent = -1"; } // Not applicable
if ($search_status == 'na') { $sql .= " AND a.percent = -1"; } // Not applicable
if ($search_status == '50') { $sql .= " AND (a.percent > 0 AND a.percent < 100)"; } // Running already started
if ($search_status == '100') { $sql .= " AND a.percent = 100"; }
if ($search_status == 'done') { $sql .= " AND (a.percent = 100)"; }

View File

@ -119,9 +119,8 @@ llxHeader('', $langs->trans("Mailing"), 'EN:Module_EMailing|FR:Module_Mailing|ES
$form = new Form($db);
if ($filteremail)
{
$sql = "SELECT m.rowid, m.titre, m.nbemail, m.statut, m.date_creat as datec, m.date_envoi as date_envoi,";
if ($filteremail) {
$sql = "SELECT m.rowid, m.titre as title, m.nbemail, m.statut, m.date_creat as datec, m.date_envoi as date_envoi,";
$sql .= " mc.statut as sendstatut";
$sql .= " FROM ".MAIN_DB_PREFIX."mailing as m, ".MAIN_DB_PREFIX."mailing_cibles as mc";
$sql .= " WHERE m.rowid = mc.fk_mailing AND m.entity = ".$conf->entity;
@ -131,7 +130,7 @@ if ($filteremail)
if (!$sortorder) $sortorder = "ASC";
if (!$sortfield) $sortfield = "m.rowid";
} else {
$sql = "SELECT m.rowid, m.titre, m.nbemail, m.statut, m.date_creat as datec, m.date_envoi as date_envoi";
$sql = "SELECT m.rowid, m.titre as title, m.nbemail, m.statut, m.date_creat as datec, m.date_envoi as date_envoi";
$sql .= " FROM ".MAIN_DB_PREFIX."mailing as m";
$sql .= " WHERE m.entity = ".$conf->entity;
if ($search_ref) $sql .= " AND m.rowid = '".$db->escape($search_ref)."'";
@ -238,9 +237,10 @@ if ($resql)
print $email->getNomUrl(1);
print '</td>';
// Title
print '<td>'.$obj->title.'</td>';
// Date creation
// Date creation
print '<td class="center">';
print dol_print_date($db->jdate($obj->datec), 'day');
print '</td>';

View File

@ -354,8 +354,8 @@ if (empty($reshook))
$object->cond_reglement_id = GETPOST('cond_reglement_id');
$object->mode_reglement_id = GETPOST('mode_reglement_id');
$object->fk_account = GETPOST('fk_account', 'int');
$object->remise_percent = GETPOST('remise_percent');
$object->remise_absolue = GETPOST('remise_absolue');
$object->remise_percent = price2num(GETPOST('remise_percent'), 2);
$object->remise_absolue = price2num(GETPOST('remise_absolue'), 'MU');
$object->socid = GETPOST('socid', 'int');
$object->contact_id = GETPOST('contactid', 'int');
$object->fk_project = GETPOST('projectid', 'int');
@ -812,7 +812,7 @@ if (empty($reshook))
}
$qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS');
$remise_percent = GETPOST('remise_percent'.$predef);
$remise_percent = price2num(GETPOST('remise_percent'.$predef), 2);
if (empty($remise_percent)) $remise_percent = 0;
// Extrafields
@ -1210,7 +1210,7 @@ if (empty($reshook))
$price_min = $product->multiprices_min [$object->thirdparty->price_level];
$label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : '');
if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS)) && ($price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min)))) {
if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS)) && ($price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent'), 2) / 100) < price2num($price_min)))) {
setEventMessages($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), null, 'errors');
$error++;
}
@ -1243,7 +1243,7 @@ if (empty($reshook))
$qty = price2num(GETPOST('qty', 'alpha'), 'MS');
$result = $object->updateline(GETPOST('lineid', 'int'), $pu_ht, $qty, GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, $description, 'HT', $info_bits, $special_code, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $type, $date_start, $date_end, $array_options, $_POST["units"], $pu_ht_devise);
$result = $object->updateline(GETPOST('lineid', 'int'), $pu_ht, $qty, price2num(GETPOST('remise_percent'), 2), $vat_rate, $localtax1_rate, $localtax2_rate, $description, 'HT', $info_bits, $special_code, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $type, $date_start, $date_end, $array_options, GETPOST("units"), $pu_ht_devise);
if ($result >= 0) {
$db->commit();

View File

@ -291,7 +291,7 @@ $help_url = 'EN:Commercial_Proposals|FR:Proposition_commerciale|ES:Presupuestos'
//llxHeader('',$langs->trans('Proposal'),$help_url);
$sql = 'SELECT';
if ($sall || $search_product_category > 0) $sql = 'SELECT DISTINCT';
if ($sall || $search_product_category > 0 || $search_user > 0) $sql = 'SELECT DISTINCT';
$sql .= ' s.rowid as socid, s.nom as name, s.name_alias as alias, s.email, s.town, s.zip, s.fk_pays, s.client, s.code_client, ';
$sql .= " typent.code as typent_code,";
$sql .= " ava.rowid as availability,";

View File

@ -607,9 +607,9 @@ if (empty($reshook))
setEventMessages($object->error, $object->errors, 'errors');
}
} elseif ($action == 'setremisepercent' && $usercancreate) {
$result = $object->set_remise($user, GETPOST('remise_percent'));
$result = $object->set_remise($user, price2num(GETPOST('remise_percent'), 2));
} elseif ($action == 'setremiseabsolue' && $usercancreate) {
$result = $object->set_remise_absolue($user, GETPOST('remise_absolue'));
$result = $object->set_remise_absolue($user, price2num(GETPOST('remise_absolue'), 'MU'));
} elseif ($action == 'addline' && GETPOST('submitforalllines', 'aZ09') && GETPOST('vatforalllines', 'alpha')) {
// Define vat_rate
$vat_rate = (GETPOST('vatforalllines') ? GETPOST('vatforalllines') : 0);
@ -640,7 +640,7 @@ if (empty($reshook))
}
$qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS');
$remise_percent = (GETPOSTISSET('remise_percent'.$predef) ? price2num(GETPOST('remise_percent'.$predef, 'alpha')) : 0);
$remise_percent = (GETPOSTISSET('remise_percent'.$predef) ? price2num(GETPOST('remise_percent'.$predef), 2) : 0);
// Extrafields
$extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
@ -1032,7 +1032,7 @@ if (empty($reshook))
$label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : '');
if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS)) && ($price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min)))) {
if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS)) && ($price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent'), 2) / 100) < price2num($price_min)))) {
setEventMessages($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), null, 'errors');
$error++;
}
@ -1060,7 +1060,7 @@ if (empty($reshook))
}
}
}
$result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $date_start, $date_end, $type, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $special_code, $array_options, GETPOST('units'), $pu_ht_devise);
$result = $object->updateline(GETPOST('lineid', 'int'), $description, $pu_ht, price2num(GETPOST('qty'), 'MS'), price2num(GETPOST('remise_percent'), 2), $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $date_start, $date_end, $type, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $special_code, $array_options, GETPOST('units'), $pu_ht_devise);
if ($result >= 0) {
if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {

View File

@ -282,7 +282,7 @@ $help_url = "EN:Module_Customers_Orders|FR:Module_Commandes_Clients|ES:Módulo_P
// llxHeader('',$title,$help_url);
$sql = 'SELECT';
if ($sall || $search_product_category > 0) $sql = 'SELECT DISTINCT';
if ($sall || $search_product_category > 0 || $search_user > 0) $sql = 'SELECT DISTINCT';
$sql .= ' s.rowid as socid, s.nom as name, s.name_alias as name_alias, s.email, s.town, s.zip, s.fk_pays, s.client, s.code_client,';
$sql .= " typent.code as typent_code,";
$sql .= " state.code_departement as state_code, state.nom as state_name,";

View File

@ -451,7 +451,7 @@ if (empty($reshook))
}
$qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS');
$remise_percent = GETPOST('remise_percent'.$predef);
$remise_percent = price2num(GETPOST('remise_percent'.$predef), 2);
// Extrafields
$extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
@ -801,7 +801,7 @@ if (empty($reshook))
$label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : '');
// Check price is not lower than minimum (check is done only for standard or replacement invoices)
if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS)) && (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT) && $price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))))
if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS)) && (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT) && $price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent', 2)) / 100) < price2num($price_min))))
{
setEventMessages($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), null, 'errors');
$error++;
@ -837,7 +837,7 @@ if (empty($reshook))
$localtax1_rate,
$localtax1_rate,
GETPOST('productid'),
GETPOST('remise_percent'),
price2num(GETPOST('remise_percent'), 2),
'HT',
$info_bits,
0,

View File

@ -476,19 +476,15 @@ if (empty($reshook))
}
}
} // Set incoterm
elseif ($action == 'set_incoterms' && !empty($conf->incoterm->enabled))
{
elseif ($action == 'set_incoterms' && !empty($conf->incoterm->enabled)) {
$result = $object->setIncoterms(GETPOST('incoterm_id', 'int'), GETPOST('location_incoterms', 'alpha'));
} // bank account
elseif ($action == 'setbankaccount' && $usercancreate)
{
elseif ($action == 'setbankaccount' && $usercancreate) {
$result = $object->setBankAccount(GETPOST('fk_account', 'int'));
} elseif ($action == 'setremisepercent' && $usercancreate)
{
} elseif ($action == 'setremisepercent' && $usercancreate) {
$object->fetch($id);
$result = $object->set_remise($user, $_POST['remise_percent']);
} elseif ($action == "setabsolutediscount" && $usercancreate)
{
$result = $object->set_remise($user, price2num(GETPOST('remise_percent'), 2));
} elseif ($action == "setabsolutediscount" && $usercancreate) {
// POST[remise_id] or POST[remise_id_for_payment]
// We use the credit to reduce amount of invoice
@ -981,7 +977,7 @@ if (empty($reshook))
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
$action = 'create';
} elseif ($dateinvoice > (dol_now() + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
} elseif ($dateinvoice > (dol_get_last_hour(dol_now()) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
$error++;
setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors');
$action = 'create';
@ -993,26 +989,25 @@ if (empty($reshook))
$action = 'create';
}
$date_pointoftax = dol_mktime(12, 0, 0, $_POST['date_pointoftaxmonth'], $_POST['date_pointoftaxday'], $_POST['date_pointoftaxyear']);
$date_pointoftax = dol_mktime(12, 0, 0, GETPOST('date_pointoftaxmonth', 'int'), GETPOST('date_pointoftaxday', 'int'), GETPOST('date_pointoftaxyear', 'int'));
if (!$error) {
// This is a replacement invoice
$result = $object->fetch($_POST['fac_replacement']);
$result = $object->fetch(GETPOST('fac_replacement', 'int'));
$object->fetch_thirdparty();
$object->date = $dateinvoice;
$object->date_pointoftax = $date_pointoftax;
$object->note_public = trim(GETPOST('note_public', 'restricthtml'));
// We do not copy the private note
$object->ref_client = $_POST['ref_client'];
$object->ref_int = $_POST['ref_int'];
$object->model_pdf = $_POST['model'];
$object->fk_project = $_POST['projectid'];
$object->cond_reglement_id = $_POST['cond_reglement_id'];
$object->mode_reglement_id = $_POST['mode_reglement_id'];
$object->ref_client = GETPOST('ref_client', 'alphanohtml');
$object->model_pdf = GETPOST('model', 'alphanohtml');
$object->fk_project = GETPOST('projectid', 'int');
$object->cond_reglement_id = GETPOST('cond_reglement_id', 'int');
$object->mode_reglement_id = GETPOST('mode_reglement_id', 'int');
$object->fk_account = GETPOST('fk_account', 'int');
$object->remise_absolue = $_POST['remise_absolue'];
$object->remise_percent = $_POST['remise_percent'];
$object->remise_absolue = price2num(GETPOST('remise_absolue'), 'MU');
$object->remise_percent = price2num(GETPOST('remise_percent'), 2);
$object->fk_incoterms = GETPOST('incoterm_id', 'int');
$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
$object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
@ -1045,7 +1040,7 @@ if (empty($reshook))
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
$action = 'create';
} elseif ($dateinvoice > (dol_now() + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
} elseif ($dateinvoice > (dol_get_last_hour(dol_now()) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
$error++;
setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors');
$action = 'create';
@ -1067,11 +1062,11 @@ if (empty($reshook))
$object->ref_client = GETPOST('ref_client');
$object->model_pdf = GETPOST('model');
$object->fk_project = GETPOST('projectid', 'int');
$object->cond_reglement_id = 0;
$object->mode_reglement_id = GETPOST('mode_reglement_id');
$object->cond_reglement_id = 0; // No payment term for a credit note
$object->mode_reglement_id = GETPOST('mode_reglement_id', 'int');
$object->fk_account = GETPOST('fk_account', 'int');
$object->remise_absolue = GETPOST('remise_absolue');
$object->remise_percent = GETPOST('remise_percent');
$object->remise_absolue = price2num(GETPOST('remise_absolue'), 'MU');
$object->remise_percent = price2num(GETPOST('remise_percent'), 2);
$object->fk_incoterms = GETPOST('incoterm_id', 'int');
$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
$object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
@ -1265,7 +1260,7 @@ if (empty($reshook))
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
$action = 'create';
} elseif ($dateinvoice > (dol_now() + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
} elseif ($dateinvoice > (dol_get_last_hour(dol_now()) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
$error++;
setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors');
$action = 'create';
@ -1289,8 +1284,8 @@ if (empty($reshook))
$object->mode_reglement_id = GETPOST('mode_reglement_id', 'int');
$object->fk_account = GETPOST('fk_account', 'int');
$object->amount = price2num(GETPOST('amount'));
$object->remise_absolue = GETPOST('remise_absolue');
$object->remise_percent = GETPOST('remise_percent');
$object->remise_absolue = price2num(GETPOST('remise_absolue'), 'MU');
$object->remise_percent = price2num(GETPOST('remise_percent'), 2);
$object->fk_incoterms = GETPOST('incoterm_id', 'int');
$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
$object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
@ -1318,7 +1313,7 @@ if (empty($reshook))
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
$action = 'create';
} elseif ($dateinvoice > (dol_now() + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
} elseif ($dateinvoice > (dol_get_last_hour(dol_now()) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
$error++;
setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors');
$action = 'create';
@ -1343,8 +1338,8 @@ if (empty($reshook))
$object->mode_reglement_id = GETPOST('mode_reglement_id');
$object->fk_account = GETPOST('fk_account', 'int');
$object->amount = price2num(GETPOST('amount'));
$object->remise_absolue = GETPOST('remise_absolue');
$object->remise_percent = GETPOST('remise_percent');
$object->remise_absolue = price2num(GETPOST('remise_absolue'), 'MU');
$object->remise_percent = price2num(GETPOST('remise_percent'), 2);
$object->fk_incoterms = GETPOST('incoterm_id', 'int');
$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
$object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
@ -1742,7 +1737,7 @@ if (empty($reshook))
$error++;
$mesg = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date"));
setEventMessages($mesg, null, 'errors');
} elseif ($dateinvoice > (dol_now() + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
} elseif ($dateinvoice > (dol_get_last_hour(dol_now()) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
$error++;
setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors');
$action = 'create';
@ -1837,8 +1832,8 @@ if (empty($reshook))
$object->fk_project = GETPOST('projectid', 'int');
$object->cond_reglement_id = GETPOST('cond_reglement_id', 'int');
$object->mode_reglement_id = GETPOST('mode_reglement_id', 'int');
$object->remise_absolue = GETPOST('remise_absolue', 'int');
$object->remise_percent = GETPOST('remise_percent', 'int');
$object->remise_absolue =price2num(GETPOST('remise_absolue'), 'MU');
$object->remise_percent = price2num(GETPOST('remise_percent'), 2);
// Proprietes particulieres a facture de remplacement
@ -1923,8 +1918,8 @@ if (empty($reshook))
$tva_tx = '';
}
$qty = GETPOST('qty'.$predef);
$remise_percent = GETPOST('remise_percent'.$predef);
$qty = price2num(GETPOST('qty'.$predef), 'MS');
$remise_percent = price2num(GETPOST('remise_percent'.$predef), 2);
// Extrafields
$extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
@ -2314,7 +2309,7 @@ if (empty($reshook))
$label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : '');
// Check price is not lower than minimum (check is done only for standard or replacement invoices)
if ($usercanproductignorepricemin && (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT) && $price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min)))) {
if ($usercanproductignorepricemin && (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT) && $price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent'), 2) / 100) < price2num($price_min)))) {
setEventMessages($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), null, 'errors');
$error++;
}
@ -2367,7 +2362,7 @@ if (empty($reshook))
}
}
$result = $object->updateline(GETPOST('lineid', 'int'), $description, $pu_ht, $qty, price2num(GETPOST('remise_percent', 'alpha')),
$result = $object->updateline(GETPOST('lineid', 'int'), $description, $pu_ht, $qty, price2num(GETPOST('remise_percent'), 2),
$date_start, $date_end, $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $type,
GETPOST('fk_parent_line', 'int'), 0, $fournprice, $buyingprice, $label, $special_code, $array_options, price2num(GETPOST('progress', 'alpha')),
GETPOST('units', 'alpha'), $pu_ht_devise);

View File

@ -1191,23 +1191,23 @@ class Facture extends CommonInvoice
{
unset($object->lines[$i]);
}
// Bloc to update dates of service (month by month only if previously filled at 1d near start or end of month)
// Bloc to update dates of service (month by month only if previously filled and similare to start and end of month)
// If it's a service with start and end dates
if (!empty($line->date_start) && !empty($line->date_end)) {
if (!empty($conf->global->INVOICE_AUTO_NEXT_MONTH_ON_LINES) && !empty($line->date_start) && !empty($line->date_end)) {
// Get the dates
$start = dol_getdate($line->date_start);
$end = dol_getdate($line->date_end);
// Get the first and last day of the month
$first = dol_get_first_day($start['year'], $start['mon']);
$last = dol_get_first_day($end['year'], $end['mon']);
$last = dol_get_last_day($end['year'], $end['mon']);
// Get diff betweend start/end of month and previously filled
$diffFirst = num_between_day($first, dol_mktime($start['hours'], $start['minutes'], $start['seconds'], $start['mon'], $start['mday'], $start['year'], 'user'));
$diffLast = num_between_day(dol_mktime($end['hours'], $end['minutes'], $end['seconds'], $end['mon'], $end['mday'], $end['year'], 'user'), $last);
// If there is <= 1d (or 2?) of start/or/end of month
if ($diffFirst <= 2 && $diffLast <= 2) {
//print dol_print_date(dol_mktime(0, 0, 0, $start['mon'], $start['mday'], $start['year'], 'gmt'), 'dayhour').' '.dol_print_date($first, 'dayhour').'<br>';
//print dol_mktime(23, 59, 59, $end['mon'], $end['mday'], $end['year'], 'gmt').' '.$last.'<br>';exit;
// If start date is first date of month and end date is last date of month
if (dol_mktime(0, 0, 0, $start['mon'], $start['mday'], $start['year'], 'gmt') == $first
&& dol_mktime(23, 59, 59, $end['mon'], $end['mday'], $end['year'], 'gmt') == $last) {
$nextMonth = dol_get_next_month($end['mon'], $end['year']);
$newFirst = dol_get_first_day($nextMonth['year'], $nextMonth['month']);
$newLast = dol_get_last_day($nextMonth['year'], $nextMonth['month']);

View File

@ -416,7 +416,7 @@ $formcompany = new FormCompany($db);
$thirdpartystatic = new Societe($db);
$sql = 'SELECT';
if ($sall || $search_product_category > 0) $sql = 'SELECT DISTINCT';
if ($sall || $search_product_category > 0 || $search_user > 0) $sql = 'SELECT DISTINCT';
$sql .= ' f.rowid as id, f.ref, f.ref_client, f.type, f.note_private, f.note_public, f.increment, f.fk_mode_reglement, f.fk_cond_reglement, f.total as total_ht, f.tva as total_vat, f.total_ttc,';
$sql .= ' f.localtax1 as total_localtax1, f.localtax2 as total_localtax2,';
$sql .= ' f.fk_user_author,';

View File

@ -161,8 +161,9 @@ if (!empty($conf->facture->enabled) && $user->rights->facture->lire)
$sql .= $hookmanager->resPrint;
$sql .= " GROUP BY f.rowid, f.ref, f.datef, f.total, f.tva, f.total_ttc, f.ref_client, f.type, f.fk_statut, f.paye,";
$sql .= " s.email, s.nom, s.rowid, s.code_client, s.code_compta, s.code_fournisseur, s.code_compta_fournisseur,";
$sql .= " s.nom, s.rowid, s.email, s.code_client, s.code_compta, s.code_fournisseur, s.code_compta_fournisseur,";
$sql .= " cc.rowid, cc.code";
if (!$user->rights->societe->client->voir && !$socid) $sql.= ", sc.fk_soc, sc.fk_user";
// Add Group from hooks
$parameters = array();

View File

@ -3,6 +3,7 @@
* Copyright (C) 2005-2013 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2016-2018 Frédéric France <frederic.france@netlogic.fr>
* Copyright (C) 2017 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2021 Gauthier VERDOL <gauthier.verdol@atm-consulting.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
@ -28,10 +29,13 @@ require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
require_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php';
require_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/paymentsocialcontribution.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formsocialcontrib.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/tax.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
if (!empty($conf->projet->enabled)) {
require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
if (!empty($conf->projet->enabled))
{
include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
}
@ -40,7 +44,7 @@ if (!empty($conf->accounting->enabled)) {
}
// Load translation files required by the page
$langs->loadLangs(array('compta', 'bills', 'banks'));
$langs->loadLangs(array('compta', 'bills', 'banks', 'hrm'));
$id = GETPOST('id', 'int');
$action = GETPOST('action', 'aZ09');
@ -51,6 +55,7 @@ $dateech = dol_mktime(GETPOST('echhour'), GETPOST('echmin'), GETPOST('echsec'),
$dateperiod = dol_mktime(GETPOST('periodhour'), GETPOST('periodmin'), GETPOST('periodsec'), GETPOST('periodmonth'), GETPOST('periodday'), GETPOST('periodyear'));
$label = GETPOST('label', 'alpha');
$actioncode = GETPOST('actioncode');
$fk_user = GETPOST('userid', 'int');
// Security check
$socid = GETPOST('socid', 'int');
@ -94,6 +99,12 @@ if ($action == 'classin' && $user->rights->tax->charges->creer)
$object->setProject(GETPOST('projectid'));
}
if ($action == 'setfk_user' && $user->rights->tax->charges->creer) {
$object->fetch($id);
$object->fk_user = $fk_user;
$object->update($user);
}
if ($action == 'setlib' && $user->rights->tax->charges->creer)
{
$object->fetch($id);
@ -163,6 +174,7 @@ if ($action == 'add' && $user->rights->tax->charges->creer)
$object->date_ech = $dateech;
$object->periode = $dateperiod;
$object->amount = $amount;
$object->fk_user = $fk_user;
$object->mode_reglement_id = (int) GETPOST('mode_reglement_id', 'int');
$object->fk_account = (int) GETPOST('fk_account', 'int');
$object->fk_project = (int) GETPOST('fk_project', 'int');
@ -202,6 +214,7 @@ if ($action == 'update' && !$_POST["cancel"] && $user->rights->tax->charges->cre
$object->date_ech = $dateech;
$object->periode = $dateperiod;
$object->amount = $amount;
$object->fk_user = $fk_user;
$result = $object->update($user);
if ($result <= 0) {
@ -342,6 +355,12 @@ if ($action == 'create')
print '<td><input type="text" size="6" name="amount" class="flat" value="'.dol_escape_htmltag(GETPOST('amount', 'alpha')).'"></td>';
print '</tr>';
// Employee
print '<tr><td>';
print $langs->trans('Employee');
print '</td>';
print '<td>'.$form->select_dolusers($fk_user, 'userid', 1).'</td></tr>';
// Project
if (!empty($conf->projet->enabled))
{
@ -442,6 +461,26 @@ if ($id > 0)
// Ref customer
$morehtmlref .= $form->editfieldkey("Label", 'lib', $object->label, $object, $user->rights->tax->charges->creer, 'string', '', 0, 1);
$morehtmlref .= $form->editfieldval("Label", 'lib', $object->label, $object, $user->rights->tax->charges->creer, 'string', '', null, null, '', 1);
// Employee
if ($action != 'editfk_user') {
$morehtmlref .= '<br>' . $form->editfieldkey("Employee", 'fk_user', $object->label, $object, $user->rights->tax->charges->creer, 'string', '', 0, 1);
if (!empty($object->fk_user)) {
$userstatic = new User($db);
$userstatic->fetch($object->fk_user);
$morehtmlref .= $userstatic->getNomUrl(1);
}
} else {
$morehtmlref .= '<br>'.$langs->trans('Employee').' :&nbsp;';
$morehtmlref .= '<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
$morehtmlref .= '<input type="hidden" name="action" value="setfk_user">';
$morehtmlref .= '<input type="hidden" name="token" value="'.newToken().'">';
$morehtmlref .= $form->select_dolusers($object->fk_user, 'userid', 1);
$morehtmlref .= '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
$morehtmlref .= '</form>';
}
// Project
if (!empty($conf->projet->enabled))
{

View File

@ -46,9 +46,15 @@ class Cchargesociales
/**
* @var string Label
* @deprecated
*/
public $libelle;
/**
* @var string Label
*/
public $label;
public $deductible;
public $active;
public $code;
@ -107,7 +113,6 @@ class Cchargesociales
// Insert request
$sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element.'(';
$sql .= 'libelle,';
$sql .= 'deductible,';
$sql .= 'active,';
@ -115,10 +120,7 @@ class Cchargesociales
$sql .= 'fk_pays,';
$sql .= 'module';
$sql .= 'accountancy_code';
$sql .= ') VALUES (';
$sql .= ' '.(!isset($this->libelle) ? 'NULL' : "'".$this->db->escape($this->libelle)."'").',';
$sql .= ' '.(!isset($this->deductible) ? 'NULL' : $this->deductible).',';
$sql .= ' '.(!isset($this->active) ? 'NULL' : $this->active).',';
@ -126,8 +128,6 @@ class Cchargesociales
$sql .= ' '.(!isset($this->fk_pays) ? 'NULL' : $this->fk_pays).',';
$sql .= ' '.(!isset($this->module) ? 'NULL' : "'".$this->db->escape($this->module)."'").',';
$sql .= ' '.(!isset($this->accountancy_code) ? 'NULL' : "'".$this->db->escape($this->accountancy_code)."'");
$sql .= ')';
$this->db->begin();
@ -179,7 +179,7 @@ class Cchargesociales
$sql = 'SELECT';
$sql .= " t.id,";
$sql .= " t.libelle,";
$sql .= " t.libelle as label,";
$sql .= " t.deductible,";
$sql .= " t.active,";
$sql .= " t.code,";
@ -201,7 +201,8 @@ class Cchargesociales
$this->id = $obj->id;
$this->libelle = $obj->libelle;
$this->libelle = $obj->label;
$this->label = $obj->label;
$this->deductible = $obj->deductible;
$this->active = $obj->active;
$this->code = $obj->code;
@ -501,6 +502,7 @@ class Cchargesociales
$this->id = 0;
$this->libelle = '';
$this->label = '';
$this->deductible = '';
$this->active = '';
$this->code = '';

View File

@ -3,6 +3,7 @@
* Copyright (C) 2004-2007 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2016-2020 Frédéric France <frederic.france@netlogic.fr>
* Copyright (C) 2017 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2021 Gauthier VERDOL <gauthier.verdol@atm-consulting.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
@ -107,6 +108,11 @@ class ChargeSociales extends CommonObject
*/
public $fk_project;
/**
* @var int ID
*/
public $fk_user;
const STATUS_UNPAID = 0;
const STATUS_PAID = 1;
@ -133,8 +139,8 @@ class ChargeSociales extends CommonObject
{
$sql = "SELECT cs.rowid, cs.date_ech";
$sql .= ", cs.libelle as label, cs.fk_type, cs.amount, cs.fk_projet as fk_project, cs.paye, cs.periode, cs.import_key";
$sql .= ", cs.fk_account, cs.fk_mode_reglement";
$sql .= ", c.libelle";
$sql .= ", cs.fk_account, cs.fk_mode_reglement, cs.fk_user";
$sql .= ", c.libelle as type_label";
$sql .= ', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle';
$sql .= " FROM ".MAIN_DB_PREFIX."chargesociales as cs";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_chargesociales as c ON cs.fk_type = c.id";
@ -157,13 +163,14 @@ class ChargeSociales extends CommonObject
$this->lib = $obj->label;
$this->label = $obj->label;
$this->type = $obj->fk_type;
$this->type_label = $obj->libelle;
$this->type_label = $obj->type_label;
$this->fk_account = $obj->fk_account;
$this->mode_reglement_id = $obj->fk_mode_reglement;
$this->mode_reglement_code = $obj->mode_reglement_code;
$this->mode_reglement = $obj->mode_reglement_libelle;
$this->amount = $obj->amount;
$this->fk_project = $obj->fk_project;
$this->fk_user = $obj->fk_user;
$this->paye = $obj->paye;
$this->periode = $this->db->jdate($obj->periode);
$this->import_key = $this->import_key;
@ -222,7 +229,7 @@ class ChargeSociales extends CommonObject
$this->db->begin();
$sql = "INSERT INTO ".MAIN_DB_PREFIX."chargesociales (fk_type, fk_account, fk_mode_reglement, libelle, date_ech, periode, amount, fk_projet, entity, fk_user_author, date_creation)";
$sql = "INSERT INTO ".MAIN_DB_PREFIX."chargesociales (fk_type, fk_account, fk_mode_reglement, libelle, date_ech, periode, amount, fk_projet, entity, fk_user_author, fk_user, date_creation)";
$sql .= " VALUES (".$this->type;
$sql .= ", ".($this->fk_account > 0 ? $this->fk_account : 'NULL');
$sql .= ", ".($this->mode_reglement_id > 0 ? $this->mode_reglement_id : "NULL");
@ -233,6 +240,7 @@ class ChargeSociales extends CommonObject
$sql .= ", ".($this->fk_project > 0 ? $this->fk_project : 'NULL');
$sql .= ", ".$conf->entity;
$sql .= ", ".$user->id;
$sql .= ", ".($this->fk_user > 0 ? $this->db->escape($this->fk_user) : 'NULL');
$sql .= ", '".$this->db->idate($now)."'";
$sql .= ")";
@ -346,6 +354,7 @@ class ChargeSociales extends CommonObject
$sql .= ", periode='".$this->db->idate($this->periode)."'";
$sql .= ", amount='".price2num($this->amount, 'MT')."'";
$sql .= ", fk_projet=".($this->fk_project > 0 ? $this->db->escape($this->fk_project) : "NULL");
$sql .= ", fk_user=".($this->fk_user > 0 ? $this->db->escape($this->fk_user) : "NULL");
$sql .= ", fk_user_modif=".$user->id;
$sql .= " WHERE rowid=".$this->id;

View File

@ -46,6 +46,11 @@ class PaymentSocialContribution extends CommonObject
*/
public $picto = 'payment';
/**
* @var string Label
*/
public $label;
/**
* @var int ID
*/
@ -679,7 +684,7 @@ class PaymentSocialContribution extends CommonObject
$result = '';
if (empty($this->ref)) $this->ref = $this->lib;
if (empty($this->ref)) $this->ref = $this->label;
$label = img_picto('', $this->picto).' <u>'.$langs->trans("SocialContributionPayment").'</u>';
$label .= '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;

View File

@ -5,7 +5,8 @@
* Copyright (C) 2016 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2020 Pierre Ardoin <mapiolca@me.com>
* Copyright (C) 2020 Tobias Sekan <tobias.sekan@startmail.com>
* Copyright (C) 2021 Gauthier VERDOL <gauthier.verdol@atm-consulting.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
@ -40,7 +41,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
if (!empty($conf->projet->enabled)) require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
// Load translation files required by the page
$langs->loadLangs(array('compta', 'banks', 'bills'));
$langs->loadLangs(array('compta', 'banks', 'bills', 'hrm'));
$action = GETPOST('action', 'aZ09');
$massaction = GETPOST('massaction', 'alpha');
@ -56,7 +57,8 @@ $search_day_lim = GETPOST('search_day_lim', 'int');
$search_month_lim = GETPOST('search_month_lim', 'int');
$search_year_lim = GETPOST('search_year_lim', 'int');
$search_project_ref = GETPOST('search_project_ref', 'alpha');
$search_project = GETPOST('search_project', 'alpha');
$search_project = GETPOST('search_project', 'alpha');
$search_users = GETPOST('search_users');
$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
@ -91,6 +93,7 @@ $arrayfields = array(
'cs.rowid' =>array('label'=>"Ref", 'checked'=>1, 'position'=>10),
'cs.libelle' =>array('label'=>"Label", 'checked'=>1, 'position'=>20),
'cs.fk_type' =>array('label'=>"Type", 'checked'=>1, 'position'=>30),
'cs.fk_user' =>array('label'=>"Employee", 'checked'=>1, 'position'=>30),
'p.ref' =>array('label'=>"ProjectRef", 'checked'=>1, 'position'=>40, 'enable'=>(!empty($conf->projet->enabled))),
'cs.date_ech' =>array('label'=>"Date", 'checked'=>1, 'position'=>50),
'cs.periode' =>array('label'=>"PeriodEndDate", 'checked'=>1, 'position'=>60),
@ -128,6 +131,7 @@ if (empty($reshook)) {
$search_month_lim = '';
$search_project_ref = '';
$search_project = '';
$search_users = '';
$search_array_options = array();
}
}
@ -144,8 +148,8 @@ if (!empty($conf->projet->enabled)) $projectstatic = new Project($db);
llxHeader('', $langs->trans("SocialContributions"));
$sql = "SELECT cs.rowid, cs.fk_type as type, ";
$sql .= " cs.amount, cs.date_ech, cs.libelle, cs.paye, cs.periode,";
$sql = "SELECT cs.rowid, cs.fk_type as type, cs.fk_user, ";
$sql .= " cs.amount, cs.date_ech, cs.libelle as label, cs.paye, cs.periode,";
if (!empty($conf->projet->enabled)) $sql .= " p.rowid as project_id, p.ref as project_ref, p.title as project_label,";
$sql .= " c.libelle as type_label,";
$sql .= " SUM(pc.amount) as alreadypayed";
@ -153,12 +157,14 @@ $sql .= " FROM ".MAIN_DB_PREFIX."c_chargesociales as c,";
$sql .= " ".MAIN_DB_PREFIX."chargesociales as cs";
if (!empty($conf->projet->enabled)) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet as p ON p.rowid = cs.fk_projet";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."paiementcharge as pc ON pc.fk_charge = cs.rowid";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u ON (cs.fk_user = u.rowid)";
$sql .= " WHERE cs.fk_type = c.id";
$sql .= " AND cs.entity = ".$conf->entity;
// Search criteria
if ($search_ref) $sql .= " AND cs.rowid=".$db->escape($search_ref);
if ($search_label) $sql .= natural_search("cs.libelle", $search_label);
if (!empty($conf->projet->enabled)) if ($search_project_ref != '') $sql .= natural_search("p.ref", $search_project_ref);
if (!empty($search_users)) $sql .= ' AND cs.fk_user IN('.implode(', ', $search_users).')';
if ($search_amount) $sql .= natural_search("cs.amount", $search_amount, 1);
if ($search_status != '' && $search_status >= 0) $sql .= " AND cs.paye = ".$db->escape($search_status);
$sql .= dolSqlDateFilter("cs.periode", $search_day_lim, $search_month_lim, $search_year_lim);
@ -211,6 +217,9 @@ if ($search_label) $param .= '&search_label='.urlencode($search_label);
if ($search_project_ref >= 0) $param .= "&search_project_ref=".urlencode($search_project_ref);
if ($search_amount) $param .= '&search_amount='.urlencode($search_amount);
if ($search_typeid) $param .= '&search_typeid='.urlencode($search_typeid);
if ($search_users) {
foreach ($search_users as $id_user) $param .= '&search_users[]='.urlencode($id_user);
}
if ($search_status != '' && $search_status != '-1') $param .= '&search_status='.urlencode($search_status);
if ($year) $param .= '&year='.urlencode($year);
@ -289,6 +298,12 @@ if (!empty($arrayfields['cs.fk_type']['checked'])) {
print '</td>';
}
if (!empty($arrayfields['cs.fk_user']['checked'])) {
// Employee
print '<td class="liste_titre" align="left">';
print $form->select_dolusers($search_users, 'search_users', 1, null, 0, '', '', '0', '0', 0, '', 0, '', '', 0, 0, true);
}
// Filter: Project ref
if (!empty($arrayfields['p.ref']['checked'])) {
print '<td class="liste_titre">';
@ -343,6 +358,7 @@ if (!empty($conf->global->MAIN_VIEW_LINE_NUMBER_IN_LIST)) print_liste_field_titr
if (!empty($arrayfields['cs.rowid']['checked'])) print_liste_field_titre($arrayfields['cs.rowid']['label'], $_SERVER["PHP_SELF"], "cs.rowid", '', $param, '', $sortfield, $sortorder);
if (!empty($arrayfields['cs.libelle']['checked'])) print_liste_field_titre($arrayfields['cs.libelle']['label'], $_SERVER["PHP_SELF"], "cs.libelle", '', $param, 'class="left"', $sortfield, $sortorder);
if (!empty($arrayfields['cs.fk_type']['checked'])) print_liste_field_titre($arrayfields['cs.fk_type']['label'], $_SERVER["PHP_SELF"], "cs.fk_type", '', $param, 'class="left"', $sortfield, $sortorder);
if (!empty($arrayfields['cs.fk_user']['checked'])) print_liste_field_titre("Employee", $_SERVER["PHP_SELF"], "u.lastname", "", $param, 'class="left"', $sortfield, $sortorder);
if (!empty($arrayfields['p.ref']['checked'])) print_liste_field_titre($arrayfields['p.ref']['label'], $_SERVER["PHP_SELF"], "p.ref", '', $param, '', $sortfield, $sortorder);
if (!empty($arrayfields['cs.date_ech']['checked'])) print_liste_field_titre($arrayfields['cs.date_ech']['label'], $_SERVER["PHP_SELF"], "cs.date_ech", '', $param, 'align="center"', $sortfield, $sortorder);
if (!empty($arrayfields['cs.periode']['checked'])) print_liste_field_titre($arrayfields['cs.periode']['label'], $_SERVER["PHP_SELF"], "cs.periode", '', $param, 'align="center"', $sortfield, $sortorder);
@ -358,14 +374,14 @@ print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], '', '', '', '', $
print '</tr>';
$i = 0;
$totalarray = array();
$totalarray = $TLoadedUsers = array();
while ($i < min($num, $limit))
{
$obj = $db->fetch_object($resql);
$chargesociale_static->id = $obj->rowid;
$chargesociale_static->ref = $obj->rowid;
$chargesociale_static->label = $obj->libelle;
$chargesociale_static->label = $obj->label;
$chargesociale_static->type_label = $obj->type_label;
if (!empty($conf->projet->enabled)) {
$projectstatic->id = $obj->project_id;
@ -389,7 +405,7 @@ while ($i < min($num, $limit))
// Label
if (!empty($arrayfields['cs.libelle']['checked'])) {
print '<td>'.dol_trunc($obj->libelle, 42).'</td>';
print '<td>'.dol_trunc($obj->label, 42).'</td>';
if (!$i) $totalarray['nbfield']++;
}
@ -399,6 +415,22 @@ while ($i < min($num, $limit))
if (!$i) $totalarray['nbfield']++;
}
if (!empty($arrayfields['cs.fk_user']['checked'])) {
// Employee
print "<td>";
if (!empty($obj->fk_user)) {
if (!empty($TLoadedUsers[$obj->fk_user])) $ustatic = $TLoadedUsers[$obj->fk_user];
else {
$ustatic = new User($db);
$ustatic->fetch($obj->fk_user);
$TLoadedUsers[$obj->fk_user] = $ustatic;
}
print $ustatic->getNomUrl(-1);
}
print "</td>\n";
if (!$i) $totalarray['nbfield']++;
}
// Project ref
if (!empty($arrayfields['p.ref']['checked'])) {
print '<td class="nowrap">';

View File

@ -44,12 +44,12 @@ $nbofyear = 4;
$year = GETPOST('year', 'int');
if (empty($year))
{
$year_current = strftime("%Y", dol_now());
$month_current = strftime("%m", dol_now());
$year_current = dol_print_date(dol_now(), "%Y");
$month_current = dol_print_date(dol_now(), "%m");
$year_start = $year_current - ($nbofyear - 1);
} else {
$year_current = $year;
$month_current = strftime("%m", dol_now());
$month_current = dol_print_date(dol_now(), "%m");
$year_start = $year - ($nbofyear - 1);
}
$date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear);
@ -58,12 +58,12 @@ $date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear);
// We define date_start and date_end
if (empty($date_start) || empty($date_end)) // We define date_start and date_end
{
$q = GETPOST("q") ?GETPOST("q") : 0;
$q = GETPOST("q") ? GETPOST("q") : 0;
if ($q == 0)
{
// We define date_start and date_end
$year_end = $year_start + ($nbofyear - 1);
$month_start = GETPOST("month") ?GETPOST("month") : ($conf->global->SOCIETE_FISCAL_MONTH_START ? ($conf->global->SOCIETE_FISCAL_MONTH_START) : 1);
$month_start = GETPOSTISSET("month") ? GETPOST("month", 'int') : ($conf->global->SOCIETE_FISCAL_MONTH_START ? $conf->global->SOCIETE_FISCAL_MONTH_START : 1);
if (!GETPOST('month'))
{
if (!GETPOST("year") && $month_start > $month_current)
@ -86,8 +86,10 @@ $userid = GETPOST('userid', 'int');
$socid = GETPOST('socid', 'int');
$tmps = dol_getdate($date_start);
$mothn_start = $tmps['mon'];
$year_start = $tmps['year'];
$tmpe = dol_getdate($date_end);
$month_end = $tmpe['mon'];
$year_end = $tmpe['year'];
$nbofyear = ($year_end - $year_start) + 1;
@ -306,7 +308,7 @@ $now = dol_now();
$casenow = dol_print_date($now, "%Y-%m");
// Loop on each month
$nb_mois_decalage = $conf->global->SOCIETE_FISCAL_MONTH_START ? ($conf->global->SOCIETE_FISCAL_MONTH_START - 1) : 0;
$nb_mois_decalage = GETPOSTISSET('date_startmonth') ? (GETPOST('date_startmonth', 'int') - 1) : (empty($conf->global->SOCIETE_FISCAL_MONTH_START) ? 0 : ($conf->global->SOCIETE_FISCAL_MONTH_START - 1));
for ($mois = 1 + $nb_mois_decalage; $mois <= 12 + $nb_mois_decalage; $mois++)
{
$mois_modulo = $mois; // ajout
@ -338,68 +340,75 @@ for ($mois = 1 + $nb_mois_decalage; $mois <= 12 + $nb_mois_decalage; $mois++)
if ($annee >= $year_start) // We ignore $annee < $year_start, we loop on it to be able to make delta, nothing is output.
{
if ($modecompta == 'CREANCES-DETTES') {
// Valeur CA du mois w/o VAT
// Value turnover of month w/o VAT
print '<td class="right">';
if ($cum_ht[$case])
{
$now_show_delta = 1; // On a trouve le premier mois de la premiere annee generant du chiffre.
print '<a href="casoc.php?year='.$annee_decalage.'&month='.$mois_modulo.($modecompta ? '&modecompta='.$modecompta : '').'">'.price($cum_ht[$case], 1).'</a>';
} else {
if ($minyearmonth < $case && $case <= max($maxyearmonth, $nowyearmonth)) { print '0'; } else { print '&nbsp;'; }
if ($annee < $year_end || ($annee == $year_end && $mois <= $month_end)) {
if ($cum_ht[$case]) {
$now_show_delta = 1; // On a trouve le premier mois de la premiere annee generant du chiffre.
print '<a href="casoc.php?year='.$annee_decalage.'&month='.$mois_modulo.($modecompta ? '&modecompta='.$modecompta : '').'">'.price($cum_ht[$case], 1).'</a>';
} else {
if ($minyearmonth < $case && $case <= max($maxyearmonth, $nowyearmonth)) { print '0'; } else { print '&nbsp;'; }
}
}
print "</td>";
}
// Valeur CA du mois
// Value turnover of month
print '<td class="right">';
if ($cum[$case])
{
$now_show_delta = 1; // On a trouve le premier mois de la premiere annee generant du chiffre.
if ($modecompta != 'BOOKKEEPING') print '<a href="casoc.php?year='.$annee_decalage.'&month='.$mois_modulo.($modecompta ? '&modecompta='.$modecompta : '').'">';
print price($cum[$case], 1);
if ($modecompta != 'BOOKKEEPING') print '</a>';
} else {
if ($minyearmonth < $case && $case <= max($maxyearmonth, $nowyearmonth)) { print '0'; } else { print '&nbsp;'; }
if ($annee < $year_end || ($annee == $year_end && $mois <= $month_end)) {
if ($cum[$case]) {
$now_show_delta = 1; // On a trouve le premier mois de la premiere annee generant du chiffre.
if ($modecompta != 'BOOKKEEPING') print '<a href="casoc.php?year='.$annee_decalage.'&month='.$mois_modulo.($modecompta ? '&modecompta='.$modecompta : '').'">';
print price($cum[$case], 1);
if ($modecompta != 'BOOKKEEPING') print '</a>';
} else {
if ($minyearmonth < $case && $case <= max($maxyearmonth, $nowyearmonth)) { print '0'; } else { print '&nbsp;'; }
}
}
print "</td>";
// Pourcentage du mois
if ($annee_decalage > $minyear && $case <= $casenow)
{
if ($cum[$caseprev] && $cum[$case])
// Percentage of month
print '<td class="borderrightlight right">';
//var_dump($annee.' '.$year_end.' '.$mois.' '.$month_end);
if ($annee < $year_end || ($annee == $year_end && $mois <= $month_end)) {
if ($annee_decalage > $minyear && $case <= $casenow)
{
$percent = (round(($cum[$case] - $cum[$caseprev]) / $cum[$caseprev], 4) * 100);
//print "X $cum[$case] - $cum[$caseprev] - $cum[$caseprev] - $percent X";
print '<td class="borderrightlight right">'.($percent >= 0 ? "+$percent" : "$percent").'%</td>';
if ($cum[$caseprev] && $cum[$case])
{
$percent = (round(($cum[$case] - $cum[$caseprev]) / $cum[$caseprev], 4) * 100);
//print "X $cum[$case] - $cum[$caseprev] - $cum[$caseprev] - $percent X";
print ($percent >= 0 ? "+$percent" : "$percent").'%';
}
if ($cum[$caseprev] && !$cum[$case])
{
print '-100%';
}
if (!$cum[$caseprev] && $cum[$case])
{
//print '<td class="right">+Inf%</td>';
print '-';
}
if (isset($cum[$caseprev]) && !$cum[$caseprev] && !$cum[$case])
{
print '+0%';
}
if (!isset($cum[$caseprev]) && !$cum[$case])
{
print '-';
}
} else {
if ($minyearmonth <= $case && $case <= $maxyearmonth) { print '-'; } else { print '&nbsp;'; }
}
if ($cum[$caseprev] && !$cum[$case])
{
print '<td class="borderrightlight right">-100%</td>';
}
if (!$cum[$caseprev] && $cum[$case])
{
//print '<td class="right">+Inf%</td>';
print '<td class="borderrightlight right">-</td>';
}
if (isset($cum[$caseprev]) && !$cum[$caseprev] && !$cum[$case])
{
print '<td class="borderrightlight right">+0%</td>';
}
if (!isset($cum[$caseprev]) && !$cum[$case])
{
print '<td class="borderrightlight right">-</td>';
}
} else {
print '<td class="borderrightlight right">';
if ($minyearmonth <= $case && $case <= $maxyearmonth) { print '-'; } else { print '&nbsp;'; }
print '</td>';
}
print '</td>';
if ($annee_decalage < $year_end || ($annee_decalage == $year_end && $mois > 12 && $annee < $year_end)) print '<td width="15">&nbsp;</td>';
}
$total_ht[$annee] += ((!empty($cum_ht[$case])) ? $cum_ht[$case] : 0);
$total[$annee] += $cum[$case];
if ($annee < $year_end || ($annee == $year_end && $mois <= $month_end)) {
$total_ht[$annee] += ((!empty($cum_ht[$case])) ? $cum_ht[$case] : 0);
$total[$annee] += $cum[$case];
}
}
print '</tr>';
@ -470,34 +479,37 @@ for ($mois = 1 + $nb_mois_decalage; $mois <= 12 + $nb_mois_decalage; $mois++)
}
*/
// Affiche total
// Show total
print '<tr class="liste_total"><td>'.$langs->trans("Total").'</td>';
for ($annee = $year_start; $annee <= $year_end; $annee++)
{
if ($modecompta == 'CREANCES-DETTES') {
// Montant total HT
if ($total_ht[$annee] || ($annee >= $minyear && $annee <= max($nowyear, $maxyear)))
{
print '<td class="nowrap right">'.($total_ht[$annee] ?price($total_ht[$annee]) : "0")."</td>";
if ($total_ht[$annee] || ($annee >= $minyear && $annee <= max($nowyear, $maxyear))) {
print '<td class="nowrap right">';
print ($total_ht[$annee] ?price($total_ht[$annee]) : "0");
print "</td>";
} else {
print '<td>&nbsp;</td>';
}
}
// Montant total
if ($total[$annee] || ($annee >= $minyear && $annee <= max($nowyear, $maxyear)))
{
print '<td class="nowrap right">'.($total[$annee] ?price($total[$annee]) : "0")."</td>";
// Total amount
if ($total[$annee] || ($annee >= $minyear && $annee <= max($nowyear, $maxyear))) {
print '<td class="nowrap right">';
print ($total[$annee] ?price($total[$annee]) : "0");
print "</td>";
} else {
print '<td>&nbsp;</td>';
}
// Pourcentage total
if ($annee > $minyear && $annee <= max($nowyear, $maxyear))
{
if ($annee > $minyear && $annee <= max($nowyear, $maxyear)) {
if ($total[$annee - 1] && $total[$annee]) {
$percent = (round(($total[$annee] - $total[$annee - 1]) / $total[$annee - 1], 4) * 100);
print '<td class="nowrap borderrightlight right">'.($percent >= 0 ? "+$percent" : "$percent").'%</td>';
print '<td class="nowrap borderrightlight right">';
print ($percent >= 0 ? "+$percent" : "$percent").'%';
print '</td>';
}
if ($total[$annee - 1] && !$total[$annee])
{

View File

@ -213,7 +213,7 @@ if (empty($reshook))
$object->note_private = GETPOST('note_private', 'alpha');
$object->note_public = GETPOST('note_public', 'alpha');
$object->fk_project = GETPOST('projectid', 'int');
$object->remise_percent = GETPOST('remise_percent', 'alpha');
$object->remise_percent = price2num(GETPOST('remise_percent'), 2);
$object->ref = GETPOST('ref', 'alpha');
$object->ref_customer = GETPOST('ref_customer', 'alpha');
$object->ref_supplier = GETPOST('ref_supplier', 'alpha');
@ -396,7 +396,7 @@ if (empty($reshook))
}
$qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS');
$remise_percent = ((GETPOST('remise_percent'.$predef) != '') ? GETPOST('remise_percent'.$predef) : 0);
$remise_percent = (GETPOSTISSET('remise_percent'.$predef) ? price2num(GETPOST('remise_percent'.$predef), 2) : 0);
if ($qty == '')
{
@ -673,10 +673,10 @@ if (empty($reshook))
$objectline->fk_product = GETPOST('idprod', 'int');
$objectline->description = GETPOST('product_desc', 'restricthtml');
$objectline->price_ht = GETPOST('elprice');
$objectline->subprice = GETPOST('elprice');
$objectline->qty = GETPOST('elqty');
$objectline->remise_percent = GETPOST('elremise_percent');
$objectline->price_ht = price2num(GETPOST('elprice'), 'MU');
$objectline->subprice = price2num(GETPOST('elprice'), 'MU');
$objectline->qty = price2num(GETPOST('elqty'), 'MS');
$objectline->remise_percent = price2num(GETPOST('elremise_percent'), 2);
$objectline->tva_tx = ($txtva ? $txtva : 0); // Field may be disabled, so we use vat rate 0
$objectline->vat_src_code = $vat_src_code;
$objectline->localtax1_tx = is_numeric($localtax1_tx) ? $localtax1_tx : 0;

View File

@ -5429,6 +5429,7 @@ abstract class CommonObject
$mandatorypb = false;
if ($attributeType == 'link' && $this->array_options[$key] == '-1') $mandatorypb = true;
if ($this->array_options[$key] === '') $mandatorypb = true;
if ($attributeType == 'sellist' && $this->array_options[$key] == '0') $mandatorypb = true;
if ($mandatorypb)
{
dol_syslog("Mandatory extra field ".$key." is empty");

View File

@ -2030,9 +2030,12 @@ class ExtraFields
if ($this->attributes[$object->table_element]['required'][$key]) // Value is required
{
// Check if empty without using GETPOST, value can be alpha, int, array, etc...
if ((!is_array($_POST["options_".$key]) && empty($_POST["options_".$key]) && $this->attributes[$object->table_element]['type'][$key] != 'select' && $_POST["options_".$key] != '0')
|| (!is_array($_POST["options_".$key]) && empty($_POST["options_".$key]) && $this->attributes[$object->table_element]['type'][$key] == 'select')
// Check if functionally empty without using GETPOST (depending on the type of extrafield, a
// technically non-empty value may be treated as empty functionally).
// value can be alpha, int, array, etc...
if ((!is_array($_POST["options_".$key]) && empty($_POST["options_".$key]) && $this->attributes[$object->table_element]['type'][$key] != 'select' && $_POST["options_".$key] != '0')
|| (!is_array($_POST["options_".$key]) && empty($_POST["options_".$key]) && $this->attributes[$object->table_element]['type'][$key] == 'select')
|| (!is_array($_POST["options_".$key]) && isset($_POST["options_".$key]) && $this->attributes[$object->table_element]['type'][$key] == 'sellist' && $_POST['options_'.$key] == '0')
|| (is_array($_POST["options_".$key]) && empty($_POST["options_".$key])))
{
//print 'ccc'.$value.'-'.$this->attributes[$object->table_element]['required'][$key];

View File

@ -1448,7 +1448,7 @@ class Form
* @param string $htmlid Html id to use instead of htmlname
* @param bool $multiple add [] in the name of element and add 'multiple' attribut
* @param integer $disableifempty Set tag 'disabled' on select if there is no choice
* @return int <0 if KO, Nb of contact in list if OK
* @return int|string <0 if KO, HTML with select string if OK.
*/
public function selectcontacts($socid, $selected = '', $htmlname = 'contactid', $showempty = 0, $exclude = '', $limitto = '', $showfunction = 0, $moreclass = '', $options_only = false, $showsoc = 0, $forcecombo = 0, $events = array(), $moreparam = '', $htmlid = '', $multiple = false, $disableifempty = 0)
{
@ -6427,7 +6427,7 @@ class Form
* @param string $htmlname Name of html select area. Must start with "multi" if this is a multiselect
* @param array $array Array like array(key => value) or array(key=>array('label'=>..., 'data-...'=>..., 'disabled'=>..., 'css'=>...))
* @param string|string[] $id Preselected key or preselected keys for multiselect
* @param int|string $show_empty 0 no empty value allowed, 1 or string to add an empty value into list (key is -1 and value is '' or '&nbsp;' if 1, key is -1 and value is text if string), <0 to add an empty value with key that is this value.
* @param int|string $show_empty 0 no empty value allowed, 1 or string to add an empty value into list (key is -1 and value is '' or '&nbsp;' if 1, key is -1 and value is the text if it is a placeholder string), <0 to add an empty value with key that is this value.
* @param int $key_in_label 1 to show key into label with format "[key] value"
* @param int $value_as_key 1 to use value as key
* @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container

View File

@ -70,7 +70,7 @@ class FormActions
global $langs, $conf;
$listofstatus = array(
'-1' => $langs->trans("ActionNotApplicable"),
'na' => $langs->trans("ActionNotApplicable"),
'0' => $langs->trans("ActionsToDoShort"),
'50' => $langs->trans("ActionRunningShort"),
'100' => $langs->trans("ActionDoneShort")

View File

@ -210,3 +210,36 @@ print '
}
});
});'."\n";
print "\n/* JS CODE TO ENABLE ClipBoard copy paste*/\n";
print 'jQuery(\'.clipboardCPShowOnHover\').hover(
function() {
console.log("We hover a value with a copy paste feature");
$(this).children(".clipboardCPButton, .clipboardCPText").show();
},
function() {
console.log("We hover out the value with a copy paste feature");
$(this).children(".clipboardCPButton, .clipboardCPText").hide();
}
);';
print 'jQuery(\'.clipboardCPButton\').click(function() {
/* console.log(this.parentNode); */
console.log("We click on a clipboardCPButton tag");
if (window.getSelection) {
selection = window.getSelection();
range = document.createRange();
range.selectNodeContents(this.parentNode.firstChild);
selection.removeAllRanges();
selection.addRange( range );
}
document.execCommand( \'copy\' );
window.getSelection().removeAllRanges();
/* Show message */
var lastchild = this.parentNode.lastChild;
var tmp = lastchild.innerHTML
lastchild.innerHTML = \''.dol_escape_js($langs->trans('CopiedToClipboard')).'\';
setTimeout(() => { lastchild.innerHTML = tmp; }, 1000);
})'."\n";

View File

@ -434,14 +434,17 @@ function ajax_combobox($htmlname, $events = array(), $minLengthToAutocomplete =
minimumInputLength: '.$minLengthToAutocomplete.',
language: select2arrayoflanguage,
containerCssClass: \':all:\', /* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag */
selectionCssClass: \':all:\', /* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag */
templateResult: function (data, container) { /* Format visible output into combo list */
/* Code to add class of origin OPTION propagated to the new select2 <li> tag */
if (data.element) { $(container).addClass($(data.element).attr("class")); }
//console.log(data.html);
if (data.id == -1) return \'&nbsp;\';
if ($(data.element).attr("data-html") != undefined) return htmlEntityDecodeJs($(data.element).attr("data-html")); // If property html set, we decode html entities and use this
return data.text;
return data.text;
},
templateSelection: function (selection) { /* Format visible output of selected value */
if (selection.id == -1) return \'<span class="placeholder">\'+selection.text+\'</span>\';
return selection.text;
},
escapeMarkup: function(markup) {

View File

@ -356,7 +356,8 @@ function dol_stringtotime($string, $gm = 1)
}
/** Return previous day
/**
* Return previous day
*
* @param int $day Day
* @param int $month Month
@ -371,7 +372,8 @@ function dol_get_prev_day($day, $month, $year)
return array('year' => $tmparray['year'], 'month' => $tmparray['mon'], 'day' => $tmparray['mday']);
}
/** Return next day
/**
* Return next day
*
* @param int $day Day
* @param int $month Month
@ -386,7 +388,8 @@ function dol_get_next_day($day, $month, $year)
return array('year' => $tmparray['year'], 'month' => $tmparray['mon'], 'day' => $tmparray['mday']);
}
/** Return previous month
/**
* Return previous month
*
* @param int $month Month
* @param int $year Year
@ -405,7 +408,8 @@ function dol_get_prev_month($month, $year)
return array('year' => $prev_year, 'month' => $prev_month);
}
/** Return next month
/**
* Return next month
*
* @param int $month Month
* @param int $year Year
@ -424,7 +428,8 @@ function dol_get_next_month($month, $year)
return array('year' => $next_year, 'month' => $next_month);
}
/** Return previous week
/**
* Return previous week
*
* @param int $day Day
* @param int $week Week
@ -442,7 +447,8 @@ function dol_get_prev_week($day, $week, $month, $year)
return array('year' => $tmparray['year'], 'month' => $tmparray['mon'], 'day' => $tmparray['mday']);
}
/** Return next week
/**
* Return next week
*
* @param int $day Day
* @param int $week Week
@ -461,7 +467,8 @@ function dol_get_next_week($day, $week, $month, $year)
return array('year' => $tmparray['year'], 'month' => $tmparray['mon'], 'day' => $tmparray['mday']);
}
/** Return GMT time for first day of a month or year
/**
* Return GMT time for first day of a month or year
*
* @param int $year Year
* @param int $month Month
@ -478,7 +485,9 @@ function dol_get_first_day($year, $month = 1, $gm = false)
}
/** Return GMT time for last day of a month or year
/**
* Return GMT time for last day of a month or year.
* Note: The timestamp contains last day and last hours (23:59:59)
*
* @param int $year Year
* @param int $month Month
@ -504,9 +513,10 @@ function dol_get_last_day($year, $month = 12, $gm = false)
return $datelim;
}
/** Return GMT time for last hour of a given GMT date (it removes hours, min and second part)
/**
* Return GMT time for last hour of a given GMT date (it replaces hours, min and second part to 23:59:59)
*
* @param int $date Date
* @param int $date Date GMT
* @return int Date for last hour of a given date
*/
function dol_get_last_hour($date)
@ -515,7 +525,8 @@ function dol_get_last_hour($date)
return dol_mktime(23, 59, 59, $tmparray['mon'], $tmparray['mday'], $tmparray['year'], false);
}
/** Return GMT time for first hour of a given GMT date (it removes hours, min and second part)
/**
* Return GMT time for first hour of a given GMT date (it removes hours, min and second part)
*
* @param int $date Date
* @return int Date for last hour of a given date

View File

@ -1985,8 +1985,8 @@ function dol_print_date($time, $format = '', $tzoutput = 'auto', $outputlangs =
{
global $conf, $langs;
if ($tzoutput == 'auto' && property_exists($conf, 'tzuserinputkey')) {
$tzoutput = $conf->tzuserinputkey;
if ($tzoutput === 'auto') {
$tzoutput = (empty($conf) ? 'tzserver' : $conf->tzuserinputkey);
}
// Clean parameters
@ -4831,13 +4831,13 @@ function price($amount, $form = 0, $outlangs = '', $trunc = 1, $rounding = -1, $
* should be roundtext2num().
*
* @param string|float $amount Amount to convert/clean or round
* @param string $rounding ''=No rounding
* @param string|int $rounding ''=No rounding
* 'MU'=Round to Max unit price (MAIN_MAX_DECIMALS_UNIT)
* 'MT'=Round to Max for totals with Tax (MAIN_MAX_DECIMALS_TOT)
* 'MS'=Round to Max for stock quantity (MAIN_MAX_DECIMALS_STOCK)
* 'CU'=Round to Max unit price of foreign currency accuracy
* 'CT'=Round to Max for totals with Tax of foreign currency accuracy
* Numeric = Nb of digits for rounding
* Numeric = Nb of digits for rounding (For example 2 for a percentage)
* @param int $option Put 1 if you know that content is already universal format number (so no correction on decimal will be done)
* Put 2 if you know that number is a user input (so we know we don't have to fix decimal separator).
* @return string Amount with universal numeric format (Example: '99.99999').
@ -4912,7 +4912,7 @@ function price2num($amount, $rounding = '', $option = 0)
elseif ($rounding == 'CT') {
$nbofdectoround = max($conf->global->MAIN_MAX_DECIMALS_TOT, 8); // TODO Use param of currency
}
elseif (is_numeric($rounding)) $nbofdectoround = $rounding;
elseif (is_numeric($rounding)) $nbofdectoround = (int) $rounding;
//print "RR".$amount.' - '.$nbofdectoround.'<br>';
if (dol_strlen($nbofdectoround)) $amount = round(is_string($amount) ? (float) $amount : $amount, $nbofdectoround); // $nbofdectoround can be 0.
else return 'ErrorBadParameterProvidedToFunction';
@ -5653,7 +5653,7 @@ function get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart = '
$arrayforoldpath = array('cheque', 'category', 'holiday', 'supplier_invoice', 'invoice_supplier', 'mailing', 'supplier_payment');
if (!empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) $arrayforoldpath[] = 'product';
if (!empty($level) && in_array($modulepart, $arrayforoldpath)) {
// This part should be removed once all code is using "get_exdir" to forge path, with all parameters provided.
// This part should be removed once all code is using "get_exdir" to forge path, with parameter $object and $modulepart provided.
if (empty($alpha)) $num = preg_replace('/([^0-9])/i', '', $num);
else $num = preg_replace('/^.*\-/i', '', $num);
$num = substr("000".$num, -$level);
@ -7400,6 +7400,7 @@ function picto_from_langcode($codelang, $moreatt = '')
'da_DA' => 'dk',
'fr_CA' => 'mq',
'sv_SV' => 'se',
'sw_SW' => 'unknown',
'AQ' => 'unknown',
'CW' => 'unknown',
'IM' => 'unknown',
@ -9240,3 +9241,16 @@ function readfileLowMemory($fullpath_original_file_osencoded, $method = -1)
fclose($handle2);
}
}
/**
* Create a button to copy $valuetoprint in the clipboard
*
* @param string $valuetoprint The value to print
* @param int $showonlyonhover Show the copypaste button only on hover
* @return string The string to print for the button
*/
function showValueWithClipboardCPButton($valuetoprint, $showonlyonhover = 1)
{
$result = '<span class="clipboardCP'.($showonlyonhover ? ' clipboardCPShowOnHover' : '').'"><span class="clipboardCPValue">'.$valuetoprint.'</span><span class="clipboardCPButton far fa-clipboard opacitymedium paddingleft paddingright"></span><span class="clipboardCPText opacitymedium"></span></span>';
return $result;
}

View File

@ -2185,7 +2185,8 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks
$sql2 .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = p.fk_soc";
$sql2 .= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task as t ON p.rowid = t.fk_projet";
$sql2 .= " WHERE p.rowid IN (".join(',', $arrayidofprojects).")";
$sql2 .= " GROUP BY p.rowid, p.ref, p.title, p.fk_soc, s.nom, p.fk_user_creat, p.public, p.fk_statut, p.fk_opp_status, p.opp_percent, p.opp_amount, p.dateo, p.datee";
$sql2 .= " GROUP BY p.rowid, p.ref, p.title, p.fk_soc, s.rowid, s.nom, s.name_alias, s.code_client, s.code_compta, s.client, s.code_fournisseur, s.code_compta_fournisseur, s.fournisseur,";
$sql2 .= " s.logo, s.email, s.entity, p.fk_user_creat, p.public, p.fk_statut, p.fk_opp_status, p.opp_percent, p.opp_amount, p.dateo, p.datee";
$sql2 .= " ORDER BY p.title, p.ref";
$resql = $db->query($sql2);

View File

@ -47,6 +47,11 @@ class pdf_einstein extends ModelePDFCommandes
*/
public $db;
/**
* @var int The environment ID when using a multicompany module
*/
public $entity;
/**
* @var string model name
*/

View File

@ -47,6 +47,11 @@ class pdf_eratosthene extends ModelePDFCommandes
*/
public $db;
/**
* @var int The environment ID when using a multicompany module
*/
public $entity;
/**
* @var string model name
*/

View File

@ -243,7 +243,7 @@ class pdf_azur extends ModelePDFPropales
$pdir[0] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/";
$pdir[1] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/';
} else {
$pdir[0] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/'; // default
$pdir[0] = get_exdir(0, 0, 0, 0, $objphoto, 'product'); // default
$pdir[1] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/"; // alternative
}
@ -257,7 +257,6 @@ class pdf_azur extends ModelePDFPropales
} else {
$dir = $conf->product->dir_output.'/'.$midir; //Check repertory of the current product
}
foreach ($objphoto->liste_photos($dir, 1) as $key => $obj)
{
if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES)) // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo

View File

@ -242,7 +242,7 @@ class pdf_cyan extends ModelePDFPropales
$pdir[0] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/";
$pdir[1] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/';
} else {
$pdir[0] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/'; // default
$pdir[0] = get_exdir(0, 0, 0, 0, $objphoto, 'product'); // default
$pdir[1] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/"; // alternative
}

View File

@ -271,9 +271,10 @@ class InterfaceWorkflowManager extends DolibarrTriggers
}
}
//Build array of quantity ordered by product
//Build array of quantity ordered to be shipped
if (is_array($order->lines) && count($order->lines) > 0) {
foreach ($order->lines as $orderline) {
// Exclude lines not qualified for shipment, similar code is found into calcAndSetStatusDispatch() for vendors
if (empty($conf->global->STOCK_SUPPORTS_SERVICES) && $orderline->product_type > 0) continue;
$qtyordred[$orderline->fk_product] += $orderline->qty;
}

View File

@ -211,8 +211,9 @@ $helpurl = 'EN:Module_Shipments|FR:Module_Exp&eacute;ditions|ES:M&oacute;dulo_Ex
llxHeader('', $langs->trans('ListOfSendings'), $helpurl);
$sql = 'SELECT';
if ($sall || $search_product_category > 0) $sql = 'SELECT DISTINCT';
$sql .= " e.rowid, e.ref, e.ref_customer, e.date_expedition as date_expedition, e.weight, e.weight_units, e.date_delivery as delivery_date, l.date_delivery as date_reception, e.fk_statut, e.billed, e.tracking_number,";
if ($sall || $search_product_category > 0 || $search_user > 0) $sql = 'SELECT DISTINCT';
$sql .= " e.rowid, e.ref, e.ref_customer, e.date_expedition as date_expedition, e.weight, e.weight_units, e.date_delivery as delivery_date, e.fk_statut, e.billed, e.tracking_number,";
$sql .= " l.date_delivery as date_reception,";
$sql .= " s.rowid as socid, s.nom as name, s.town, s.zip, s.fk_pays, s.client, s.code_client, ";
$sql .= " typent.code as typent_code,";
$sql .= " state.code_departement as state_code, state.nom as state_name,";
@ -242,11 +243,12 @@ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as state on (state.rowid =
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."element_element as ee ON e.rowid = ee.fk_source AND ee.sourcetype = 'shipping' AND ee.targettype = 'delivery'";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."delivery as l ON l.rowid = ee.fk_target";
$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'user as u ON e.fk_user_author = u.rowid';
if ($search_user > 0) { // Get link to order to get the order id in eesource.fk_source
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."element_element as eesource ON eesource.fk_target = e.rowid AND eesource.targettype = 'shipping' AND eesource.sourcetype = 'commande'";
}
// We'll need this table joined to the select in order to filter by sale
if ($search_sale > 0 || (!$user->rights->societe->client->voir && !$socid)) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
if ($search_user > 0)
{
if ($search_user > 0) {
$sql .= ", ".MAIN_DB_PREFIX."element_contact as ec";
$sql .= ", ".MAIN_DB_PREFIX."c_type_contact as tc";
}
@ -274,6 +276,11 @@ if ($search_country) $sql .= " AND s.fk_pays IN (".$search_country.')';
if ($search_tracking) $sql .= natural_search("e.tracking_number", $search_tracking);
if ($search_type_thirdparty) $sql .= " AND s.fk_typent IN (".$search_type_thirdparty.')';
if ($search_sale > 0) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$search_sale;
if ($search_user > 0)
{
// The contact on a shipment is also the contact of the order.
$sql .= " AND ec.fk_c_type_contact = tc.rowid AND tc.element='commande' AND tc.source='internal' AND ec.element_id = eesource.fk_source AND ec.fk_socpeople = ".$db->escape($search_user);
}
if ($search_ref_exp) $sql .= natural_search('e.ref', $search_ref_exp);
if ($search_ref_liv) $sql .= natural_search('l.ref', $search_ref_liv);
if ($search_company) $sql .= natural_search('s.nom', $search_company);

View File

@ -217,8 +217,9 @@ if (empty($reshook))
if (!empty($origin) && !empty($originid))
{
// Parse element/subelement (ex: project_task)
$element = $subelement = $_POST['origin'];
if (preg_match('/^([^_]+)_([^_]+)/i', $_POST['origin'], $regs))
$regs = array();
$element = $subelement = GETPOST('origin', 'alphanohtml');
if (preg_match('/^([^_]+)_([^_]+)/i', GETPOST('origin', 'alphanohtml'), $regs))
{
$element = $regs[1];
$subelement = $regs[2];
@ -478,8 +479,7 @@ if (empty($reshook))
$desc = GETPOST('np_desc', 'restricthtml');
$date_intervention = dol_mktime(GETPOST('dihour', 'int'), GETPOST('dimin', 'int'), 0, GETPOST('dimonth', 'int'), GETPOST('diday', 'int'), GETPOST('diyear', 'int'));
$duration = empty($conf->global->FICHINTER_WITHOUT_DURATION) ?convertTime2Seconds(GETPOST('durationhour', 'int'), GETPOST('durationmin', 'int')) : 0;
$duration = empty($conf->global->FICHINTER_WITHOUT_DURATION) ? convertTime2Seconds(GETPOST('durationhour', 'int'), GETPOST('durationmin', 'int')) : 0;
// Extrafields
$extrafields->fetch_name_optionals_label($object->table_element_line);
@ -1335,8 +1335,7 @@ if ($action == 'create')
print '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" name="addinter" method="post">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="id" value="'.$object->id.'">';
if ($action == 'editline')
{
if ($action == 'editline') {
print '<input type="hidden" name="action" value="updateline">';
print '<input type="hidden" name="line_id" value="'.GETPOST('line_id', 'int').'">';
} else {
@ -1348,8 +1347,9 @@ if ($action == 'create')
$sql .= ' ft.date as date_intervention';
$sql .= ' FROM '.MAIN_DB_PREFIX.'fichinterdet as ft';
$sql .= ' WHERE ft.fk_fichinter = '.$object->id;
if (!empty($conf->global->FICHINTER_HIDE_EMPTY_DURATION))
if (!empty($conf->global->FICHINTER_HIDE_EMPTY_DURATION)) {
$sql .= ' AND ft.duree <> 0';
}
$sql .= ' ORDER BY ft.rang ASC, ft.date ASC, ft.rowid';
$resql = $db->query($sql);
@ -1376,13 +1376,11 @@ if ($action == 'create')
print '<td class="liste_titre">&nbsp;</td>';
print "</tr>\n";
}
while ($i < $num)
{
while ($i < $num) {
$objp = $db->fetch_object($resql);
// Ligne en mode visu
if ($action != 'editline' || GETPOST('line_id', 'int') != $objp->rowid)
{
if ($action != 'editline' || GETPOST('line_id', 'int') != $objp->rowid) {
print '<tr class="oddeven">';
// No.
@ -1402,8 +1400,7 @@ if ($action == 'create')
print "</td>\n";
// Econ to edit and delete
// Icon to edit and delete
if ($object->statut == 0 && $user->rights->ficheinter->creer)
{
print '<td class="center">';

View File

@ -3132,13 +3132,12 @@ class CommandeFournisseur extends CommonOrder
}
$ret = $supplierorderdispatch->fetchAll('', '', 0, 0, $filter);
if ($ret < 0)
{
if ($ret < 0) {
$this->error = $supplierorderdispatch->error; $this->errors = $supplierorderdispatch->errors;
return $ret;
} else {
if (is_array($supplierorderdispatch->lines) && count($supplierorderdispatch->lines) > 0)
{
if (is_array($supplierorderdispatch->lines) && count($supplierorderdispatch->lines) > 0) {
require_once DOL_DOCUMENT_ROOT.'/htdocs/product/class/product.class.php';
$date_liv = dol_now();
// Build array with quantity deliverd by product
@ -3146,13 +3145,17 @@ class CommandeFournisseur extends CommonOrder
$qtydelivered[$line->fk_product] += $line->qty;
}
foreach ($this->lines as $line) {
// Exclude lines not qualified for shipment, similar code is found into interface_20_modWrokflow for customers
if (empty($conf->global->STOCK_SUPPORTS_SERVICES) && $line->product_type > 0) continue;
$qtywished[$line->fk_product] += $line->qty;
}
//Compare array
$diff_array = array_diff_assoc($qtydelivered, $qtywished); // Warning: $diff_array is done only on common keys.
$keysinwishednotindelivered = array_diff(array_keys($qtywished), array_keys($qtydelivered)); // To check we also have same number of keys
$keysindeliverednotinwished = array_diff(array_keys($qtydelivered), array_keys($qtywished)); // To check we also have same number of keys
/*var_dump(array_keys($qtydelivered));
var_dump(array_keys($qtywished));
var_dump($diff_array);
var_dump($keysinwishednotindelivered);

View File

@ -372,7 +372,7 @@ if (empty($reshook))
}
$qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS');
$remise_percent = GETPOST('remise_percent'.$predef);
$remise_percent = price2num(GETPOST('remise_percent'.$predef), 2);
$price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU');
// Extrafields
@ -721,21 +721,21 @@ if (empty($reshook))
$result = $object->updateline(
$lineid,
$_POST['product_desc'],
GETPOST('product_desc', 'restricthtml'),
$ht,
GETPOST('qty', 'int'),
$_POST['remise_percent'],
price2num(GETPOST('qty'), 'MS'),
price2num(GETPOST('remise_percent'), 2),
$vat_rate,
$localtax1_rate,
$localtax2_rate,
$price_base_type,
0,
isset($_POST["type"]) ? $_POST["type"] : $line->product_type,
GETPOSTISSET("type") ? GETPOST("type") : $line->product_type,
false,
$date_start,
$date_end,
$array_options,
$_POST['units'],
GETPOST('units'),
$pu_ht_devise,
GETPOST('fourn_ref', 'alpha')
);

View File

@ -3,7 +3,7 @@
* Copyright (C) 2004-2016 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005 Eric Seigne <eric.seigne@ryxeo.com>
* Copyright (C) 2005-2009 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2010-2019 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2010-2021 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2014 Cedric Gross <c.gross@kreiz-it.fr>
* Copyright (C) 2016 Florian Henry <florian.henry@atm-consulting.fr>
* Copyright (C) 2017-2020 Ferran Marcet <fmarcet@2byte.es>
@ -228,6 +228,7 @@ if ($action == 'dispatch' && $user->rights->fournisseur->commande->receptionner)
foreach ($_POST as $key => $value)
{
// without batch module enabled
$reg = array();
if (preg_match('/^product_([0-9]+)_([0-9]+)$/i', $key, $reg))
{
$pos++;
@ -269,16 +270,20 @@ if ($action == 'dispatch' && $user->rights->fournisseur->commande->receptionner)
if (!$error && !empty($conf->global->SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT)) {
if (empty($conf->multicurrency->enabled) && empty($conf->dynamicprices->enabled)) {
$dto = GETPOST("dto_".$reg[1].'_'.$reg[2], 'int');
$dto = price2num(GETPOST("dto_".$reg[1].'_'.$reg[2], 'int'), '');
if (empty($dto)) {
$dto = 0;
}
//update supplier price
if (GETPOSTISSET($saveprice)) {
// TODO Use class
$sql = "UPDATE ".MAIN_DB_PREFIX."product_fournisseur_price";
$sql .= " SET unitprice='".GETPOST($pu)."'";
$sql .= ", price=".GETPOST($pu)."*quantity";
$sql .= ", remise_percent='".(!empty($dto) ? $dto : 0)."'";
$sql .= " WHERE fk_soc=".$object->socid;
$sql .= " AND fk_product=".GETPOST($prod, 'int');
$sql .= " SET unitprice='".price2num(GETPOST($pu), 'MU')."'";
$sql .= ", price=".price2num(GETPOST($pu), 'MU')."*quantity";
$sql .= ", remise_percent = ".((float) $dto);
$sql .= " WHERE fk_soc=".((int) $object->socid);
$sql .= " AND fk_product=".((int) GETPOST($prod, 'int'));
$resql = $db->query($sql);
}

View File

@ -535,7 +535,7 @@ $help_url = '';
// llxHeader('',$title,$help_url);
$sql = 'SELECT';
if ($sall || $search_product_category > 0) $sql = 'SELECT DISTINCT';
if ($sall || $search_product_category > 0 || $search_user > 0) $sql = 'SELECT DISTINCT';
$sql .= ' s.rowid as socid, s.nom as name, s.town, s.zip, s.fk_pays, s.client, s.code_client, s.email,';
$sql .= " typent.code as typent_code,";
$sql .= " state.code_departement as state_code, state.nom as state_name,";

View File

@ -666,7 +666,7 @@ if (empty($reshook))
$action = 'create';
$_GET['socid'] = $_POST['socid'];
$error++;
} elseif ($dateinvoice > (dol_now() + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
} elseif ($dateinvoice > (dol_get_last_hour(dol_now()) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
$error++;
setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors');
$action = 'create';
@ -733,7 +733,7 @@ if (empty($reshook))
$action = 'create';
$_GET['socid'] = $_POST['socid'];
$error++;
} elseif ($dateinvoice > (dol_now() + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
} elseif ($dateinvoice > (dol_get_last_hour(dol_now()) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
$error++;
setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors');
$action = 'create';
@ -851,7 +851,7 @@ if (empty($reshook))
$action = 'create';
$_GET['socid'] = $_POST['socid'];
$error++;
} elseif ($dateinvoice > (dol_now() + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
} elseif ($dateinvoice > (dol_get_last_hour(dol_now()) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
$error++;
setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors');
$action = 'create';
@ -1137,8 +1137,8 @@ if (empty($reshook))
$localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty);
$localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty);
$remise_percent = GETPOST('remise_percent');
$pu_ht_devise = GETPOST('multicurrency_subprice');
$remise_percent = price2num(GETPOST('remise_percent'), 2);
$pu_ht_devise = price2num(GETPOST('multicurrency_subprice'), 'CU');
// Extrafields Lines
$extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
@ -1150,7 +1150,7 @@ if (empty($reshook))
}
}
$result = $object->updateline(GETPOST('lineid'), $label, $up, $tva_tx, $localtax1_tx, $localtax2_tx, GETPOST('qty'), GETPOST('productid'), $price_base_type, $info_bits, $type, $remise_percent, 0, $date_start, $date_end, $array_options, $_POST['units'], $pu_ht_devise, GETPOST('fourn_ref', 'alpha'));
$result = $object->updateline(GETPOST('lineid', 'int'), $label, $up, $tva_tx, $localtax1_tx, $localtax2_tx, price2num(GETPOST('qty'), 'MS'), GETPOST('productid', 'int'), $price_base_type, $info_bits, $type, $remise_percent, 0, $date_start, $date_end, $array_options, GETPOST('units'), $pu_ht_devise, GETPOST('fourn_ref', 'alpha'));
if ($result >= 0)
{
unset($_POST['label']);
@ -1206,7 +1206,7 @@ if (empty($reshook))
}
$qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS');
$remise_percent = GETPOST('remise_percent'.$predef);
$remise_percent = price2num(GETPOST('remise_percent'.$predef), 2);
$price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU');
// Extrafields

View File

@ -583,7 +583,9 @@ if (!$search_all)
$sql .= " GROUP BY f.rowid, f.ref, f.ref_supplier, f.type, f.datef, f.date_lim_reglement, f.fk_mode_reglement, f.fk_cond_reglement,";
$sql .= " f.total_ht, f.total_ttc, f.total_tva, f.paye, f.fk_statut, f.libelle, f.datec, f.tms,";
$sql .= " f.localtax1, f.localtax2,";
$sql .= ' f.fk_multicurrency, f.multicurrency_code, f.multicurrency_tx, f.multicurrency_total_ht, f.multicurrency_total_tva, f.multicurrency_total_ttc,';
$sql .= " f.note_public, f.note_private,";
$sql .= " f.fk_user_author,";
$sql .= ' s.rowid, s.nom, s.email, s.town, s.zip, s.fk_pays, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,';
$sql .= " typent.code,";
$sql .= " state.code_departement, state.nom,";

View File

@ -558,4 +558,3 @@ INSERT INTO llx_c_socialnetworks (entity, code, label, url, icon, active) VALUES
ALTER TABLE llx_product_fournisseur_price ADD COLUMN packaging varchar(64);
ALTER TABLE llx_projet ADD COLUMN fk_opp_status_end integer DEFAULT NULL;

View File

@ -121,6 +121,7 @@ ALTER TABLE llx_societe ADD INDEX idx_societe_warehouse(fk_warehouse);
ALTER TABLE llx_socpeople MODIFY poste varchar(255);
ALTER TABLE llx_chargesociales ADD COLUMN fk_user integer DEFAULT NULL;
create table llx_payment_vat
(

View File

@ -2,6 +2,7 @@
-- Copyright (C) 2001-2002 Rodolphe Quiedeville <rodolphe@quiedeville.org>
-- Copyright (C) 2005-2009 Regis Houssin <regis.houssin@inodbox.com>
-- Copyright (C) 2017 Alexandre Spangaro <aspangaro@open-dsi.fr>
-- Copyright (C) 2021 Gauthier VERDOL <gauthier.verdol@atm-consulting.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
@ -28,6 +29,7 @@ create table llx_chargesociales
tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
date_creation datetime, -- date de creation
date_valid datetime, -- date de validation
fk_user integer DEFAULT NULL, -- utilisateur concerné
fk_user_author integer, -- user making creation
fk_user_modif integer, -- user making last change
fk_user_valid integer, -- user validating

View File

@ -16,7 +16,7 @@
CREATE TABLE llx_mrp_production(
rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL,
fk_mo integer NOT NULL,
fk_mo integer NOT NULL,
position integer NOT NULL DEFAULT 0,
fk_product integer NOT NULL,
fk_warehouse integer,

View File

@ -59,6 +59,7 @@ ErrorDirNotFound=Directory <b>%s</b> not found (Bad path, wrong permissions or a
ErrorFunctionNotAvailableInPHP=Function <b>%s</b> is required for this feature but is not available in this version/setup of PHP.
ErrorDirAlreadyExists=A directory with this name already exists.
ErrorFileAlreadyExists=A file with this name already exists.
ErrorDestinationAlreadyExists=Another file with the name <b>%s</b> already exists.
ErrorPartialFile=File not received completely by server.
ErrorNoTmpDir=Temporary directy %s does not exists.
ErrorUploadBlockedByAddon=Upload blocked by a PHP/Apache plugin.
@ -255,6 +256,7 @@ ErrorPublicInterfaceNotEnabled=Public interface was not enabled
ErrorLanguageRequiredIfPageIsTranslationOfAnother=The language of new page must be defined if it is set as a translation of another page
ErrorLanguageMustNotBeSourceLanguageIfPageIsTranslationOfAnother=The language of new page must not be the source language if it is set as a translation of another page
ErrorAParameterIsRequiredForThisOperation=A parameter is mandatory for this operation
ErrorDateIsInFuture=Error, the date can't be in the future
# Warnings
WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Your PHP parameter upload_max_filesize (%s) is higher than PHP parameter post_max_size (%s). This is not a consistent setup.

View File

@ -1119,4 +1119,5 @@ Civility=Civility
AffectTag=Affect Tag
ConfirmAffectTag=Bulk Tag Affect
ConfirmAffectTagQuestion=Are you sure you want to affect tags to the %s selected record(s)?
CategTypeNotFound=No tag type found for type of records
CategTypeNotFound=No tag type found for type of records
CopiedToClipboard=Copied to clipboard

View File

@ -386,7 +386,7 @@ if (!defined('NOLOGIN') && !defined('NOIPCHECK') && !empty($dolibarr_main_restri
// Loading of additional presentation includes
if (!defined('NOREQUIREHTML')) require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; // Need 660ko memory (800ko in 2.2)
require_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php'; // Need 22ko memory
if (!defined('NOREQUIREAJAX')) require_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php'; // Need 22ko memory
// If install or upgrade process not done or not completely finished, we call the install page.
if (!empty($conf->global->MAIN_NOT_INSTALLED) || !empty($conf->global->MAIN_NOT_UPGRADED))

View File

@ -106,7 +106,7 @@ class Mo extends CommonObject
'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>61, 'notnull'=>-1,),
'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>62, 'notnull'=>-1,),
'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'position'=>500, 'notnull'=>1,),
'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'position'=>501, 'notnull'=>-1,),
'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'position'=>501, 'notnull'=>1,),
'date_valid' => array('type'=>'datetime', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-2, 'position'=>502,),
'fk_user_creat' => array('type'=>'integer', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-2, 'position'=>510, 'notnull'=>1, 'foreignkey'=>'user.rowid',),
'fk_user_modif' => array('type'=>'integer', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'position'=>511, 'notnull'=>-1,),
@ -1352,7 +1352,7 @@ class Mo extends CommonObject
*/
public static function replaceThirdparty($db, $origin_id, $dest_id)
{
$tables = array('mrp_production');
$tables = array('mrp_mo');
return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
}

View File

@ -743,7 +743,7 @@ if (empty($reshook))
if (GETPOST('propalid') > 0) {
// Define cost price for margin calculation
$buyprice = 0;
if (($result = $propal->defineBuyPrice($pu_ht, GETPOST('remise_percent'), $object->id)) < 0)
if (($result = $propal->defineBuyPrice($pu_ht, price2num(GETPOST('remise_percent'), 2), $object->id)) < 0)
{
dol_syslog($langs->trans('FailedToGetCostPrice'));
setEventMessages($langs->trans('FailedToGetCostPrice'), null, 'errors');
@ -754,12 +754,12 @@ if (empty($reshook))
$result = $propal->addline(
$desc,
$pu_ht,
GETPOST('qty'),
price2num(GETPOST('qty'), 'MS'),
$tva_tx,
$localtax1_tx, // localtax1
$localtax2_tx, // localtax2
$object->id,
GETPOST('remise_percent'),
price2num(GETPOST('remise_percent'), 2),
$price_base_type,
$pu_ttc,
0,
@ -784,7 +784,7 @@ if (empty($reshook))
} elseif (GETPOST('commandeid') > 0) {
// Define cost price for margin calculation
$buyprice = 0;
if (($result = $commande->defineBuyPrice($pu_ht, GETPOST('remise_percent'), $object->id)) < 0)
if (($result = $commande->defineBuyPrice($pu_ht, GETPOST('remise_percent', 2), $object->id)) < 0)
{
dol_syslog($langs->trans('FailedToGetCostPrice'));
setEventMessages($langs->trans('FailedToGetCostPrice'), null, 'errors');
@ -795,12 +795,12 @@ if (empty($reshook))
$result = $commande->addline(
$desc,
$pu_ht,
GETPOST('qty'),
price2num(GETPOST('qty'), 'MS'),
$tva_tx,
$localtax1_tx, // localtax1
$localtax2_tx, // localtax2
$object->id,
GETPOST('remise_percent'),
price2num(GETPOST('remise_percent'), 2),
'',
'',
$price_base_type,
@ -825,7 +825,7 @@ if (empty($reshook))
} elseif (GETPOST('factureid') > 0) {
// Define cost price for margin calculation
$buyprice = 0;
if (($result = $facture->defineBuyPrice($pu_ht, GETPOST('remise_percent'), $object->id)) < 0)
if (($result = $facture->defineBuyPrice($pu_ht, GETPOST('remise_percent', 2), $object->id)) < 0)
{
dol_syslog($langs->trans('FailedToGetCostPrice'));
setEventMessages($langs->trans('FailedToGetCostPrice'), null, 'errors');
@ -836,12 +836,12 @@ if (empty($reshook))
$result = $facture->addline(
$desc,
$pu_ht,
GETPOST('qty'),
price2nm(GETPOST('qty'), 'MS'),
$tva_tx,
$localtax1_tx,
$localtax2_tx,
$object->id,
GETPOST('remise_percent'),
price2num(GETPOST('remise_percent'), 2),
'',
'',
'',

View File

@ -160,7 +160,7 @@ if (empty($reshook))
if (empty($ref_fourn_old)) $ref_fourn_old = $ref_fourn;
$quantity = price2num(GETPOST("qty", 'nohtml'), 'MS');
$remise_percent = price2num(GETPOST('remise_percent', 'alpha'));
$npr = preg_match('/\*/', $_POST['tva_tx']) ? 1 : 0;
$npr = preg_match('/\*/', GETPOST('tva_tx', 'alpha')) ? 1 : 0;
$tva_tx = str_replace('*', '', GETPOST('tva_tx', 'alpha'));
$tva_tx = price2num($tva_tx);
$price_expression = GETPOST('eid', 'int') ? GETPOST('eid', 'int') : ''; // Discard expression if not in expression mode
@ -697,14 +697,14 @@ END;
print '<tr><td class="fieldrequired">'.$langs->trans("PriceQtyMin").'</td>';
print '<td><input class="flat" name="price" size="8" value="'.(GETPOST('price') ? price(GETPOST('price')) : (isset($object->fourn_price) ? price($object->fourn_price) : '')).'">';
print '&nbsp;';
print $form->selectPriceBaseType((GETPOST('price_base_type') ? GETPOST('price_base_type') : 'HT'), "price_base_type"); // We keep 'HT' here, price_base_type is not yet supported for supplier prices
print $form->selectPriceBaseType((GETPOSTISSET('price_base_type') ? GETPOST('price_base_type') : 'HT'), "price_base_type"); // We keep 'HT' here, price_base_type is not yet supported for supplier prices
print '</td></tr>';
}
// Discount qty min
print '<tr><td>'.$langs->trans("DiscountQtyMin").'</td>';
print '<td><input class="flat" name="remise_percent" size="4" value="'.(GETPOST('remise_percent') ?vatrate(GETPOST('remise_percent')) : (isset($object->fourn_remise_percent) ?vatrate($object->fourn_remise_percent) : '')).'"> %';
print '<td><input class="flat" name="remise_percent" size="4" value="'.(GETPOSTISSET('remise_percent') ? vatrate(price2num(GETPOST('remise_percent'), 2)) : (isset($object->fourn_remise_percent) ?vatrate($object->fourn_remise_percent) : '')).'"> %';
print '</td>';
print '</tr>';

View File

@ -419,10 +419,10 @@ if (empty($reshook))
// Récupération des variables
$rowid = GETPOST('rowid', 'int');
$priceid = GETPOST('priceid', 'int');
$newprice = price2num(GETPOST("price", 'alpha'), 'MU');
$newprice = price2num(GETPOST("price"), 'MU');
// $newminprice=price2num(GETPOST("price_min"),'MU'); // TODO : Add min price management
$quantity = GETPOST('quantity', 'int');
$remise_percent = price2num(GETPOST('remise_percent', 'alpha'));
$quantity = price2num(GETPOST('quantity'), 'MS');
$remise_percent = price2num(GETPOST('remise_percent'), 2);
$remise = 0; // TODO : allow discount by amount when available on documents
if (empty($quantity)) {

View File

@ -1361,7 +1361,6 @@ if ($conf->use_javascript_ajax)
{
include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php';
$comboenhancement = ajax_combobox('.elementselect');
$out .= $comboenhancement;
print $comboenhancement;
}

View File

@ -322,7 +322,7 @@ $sql .= " WHERE p.entity IN (".getEntity('project').")";
$sql .= " AND p.fk_statut = 1";
if ($mine || empty($user->rights->projet->all->lire)) $sql .= " AND p.rowid IN (".$projectsListId.")"; // If we have this test true, it also means projectset is not 2
if ($socid) $sql .= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")";
$sql .= " GROUP BY s.rowid, s.nom, s.email, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.canvas, s.status";
$sql .= " GROUP BY s.rowid, s.nom, s.name_alias, s.code_client, s.code_compta, s.client, s.code_fournisseur, s.code_compta_fournisseur, s.fournisseur, s.logo, s.email, s.entity, s.canvas, s.status";
$sql .= $db->order($sortfield, $sortorder);
//$sql .= $db->plimit($max + 1, 0);

View File

@ -1235,9 +1235,8 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action))
print '<table class="border centpercent">';
// Name, firstname
print '<tr class="tr-field-thirdparty-name"><td class="titlefieldcreate tdtop">';
if ($object->particulier || $private)
{
print '<tr class="tr-field-thirdparty-name"><td class="titlefieldcreate">';
if ($object->particulier || $private) {
print '<span id="TypeName" class="fieldrequired">'.$langs->trans('ThirdPartyName').' / '.$langs->trans('LastName', 'name').'</span>';
} else {
print '<span id="TypeName" class="fieldrequired">'.$form->editfieldkey('ThirdPartyName', 'name', '', $object, 0).'</span>';
@ -2415,7 +2414,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action))
// Prefix
if (!empty($conf->global->SOCIETE_USEPREFIX)) // Old not used prefix field
{
print '<tr><td>'.$langs->trans('Prefix').'</td><td>'.$object->prefix_comm.'</td>';
print '<tr><td>'.$langs->trans('Prefix').'</td><td>'.dol_escape_htmltag($object->prefix_comm).'</td>';
print '</tr>';
}
@ -2423,8 +2422,11 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action))
if ($object->client)
{
print '<tr><td>';
print $langs->trans('CustomerCode').'</td><td>';
print $object->code_client;
print $langs->trans('CustomerCode');
print '</td>';
print '<td>';
print showValueWithClipboardCPButton(dol_escape_htmltag($object->code_client));
print '</td>';
$tmpcheck = $object->check_codeclient();
if ($tmpcheck != 0 && $tmpcheck != -5) {
print ' <font class="error">('.$langs->trans("WrongCustomerCode").')</font>';
@ -2438,7 +2440,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action))
{
print '<tr><td>';
print $langs->trans('SupplierCode').'</td><td>';
print $object->code_fournisseur;
print showValueWithClipboardCPButton(dol_escape_htmltag($object->code_fournisseur));
$tmpcheck = $object->check_codefournisseur();
if ($tmpcheck != 0 && $tmpcheck != -5) {
print ' <font class="error">('.$langs->trans("WrongSupplierCode").')</font>';
@ -2451,7 +2453,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action))
if (!empty($conf->barcode->enabled))
{
print '<tr><td>';
print $langs->trans('Gencod').'</td><td>'.dol_escape_htmltag($object->barcode);
print $langs->trans('Gencod').'</td><td>'.showValueWithClipboardCPButton(dol_escape_htmltag($object->barcode));
print '</td>';
print '</tr>';
}
@ -2467,7 +2469,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action))
print '<tr>';
print '<td>'.$idprof.'</td><td>';
$key = 'idprof'.$i;
print $object->$key;
print showValueWithClipboardCPButton(dol_escape_htmltag($object->$key));
if ($object->$key)
{
if ($object->id_prof_check($i, $object) > 0) print ' &nbsp; '.$object->id_prof_url($i, $object);
@ -2935,7 +2937,6 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action))
include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
}
}
// End of page
llxFooter();
$db->close();

View File

@ -1311,7 +1311,7 @@ while ($i < min($num, $limit))
// Parent company
if (!empty($arrayfields['s2.nom']['checked']))
{
print '<td class="center">';
print '<td class="center tdoverflowmax100">';
if ($companystatic->fk_parent > 0)
{
$companyparent->fetch($companystatic->fk_parent);

View File

@ -538,7 +538,7 @@ $token = '';
include DOL_DOCUMENT_ROOT.'/core/tpl/onlinepaymentlinks.tpl.php';
print info_admin($langs->trans("ExampleOfTestCreditCard", '4242424242424242 (no 3DSecure) or 4000000000003063 (3DSecure required) or 4000002760003184 (3DSecure2 required on all transaction) or 4000003800000446 (3DSecure2 required the off-seesion allowed)', '4000000000000101', '4000000000000069', '4000000000000341'));
print info_admin($langs->trans("ExampleOfTestCreditCard", '4242424242424242 (no 3DSecure) or 4000000000003063 (3DSecure required) or 4000002760003184 (3DSecure2 required on all transaction) or 4000003800000446 (3DSecure2 required, the off-session allowed)', '4000000000000101', '4000000000000069', '4000000000000341'));
if (!empty($conf->use_javascript_ajax))
{

View File

@ -321,7 +321,7 @@ class Stripe extends CommonObject
* @param string $noidempotency_key Do not use the idempotency_key when creating the PaymentIntent
* @return \Stripe\PaymentIntent|null Stripe PaymentIntent or null if not found and failed to create
*/
public function getPaymentIntent($amount, $currency_code, $tag, $description = '', $object = null, $customer = null, $key = null, $status = 0, $usethirdpartyemailforreceiptemail = 0, $mode = 'automatic', $confirmnow = false, $payment_method = null, $off_session = 0, $noidempotency_key = 0)
public function getPaymentIntent($amount, $currency_code, $tag, $description = '', $object = null, $customer = null, $key = null, $status = 0, $usethirdpartyemailforreceiptemail = 0, $mode = 'automatic', $confirmnow = false, $payment_method = null, $off_session = 0, $noidempotency_key = 1)
{
global $conf, $user;
@ -397,6 +397,7 @@ class Stripe extends CommonObject
if (empty($paymentintent))
{
// Try to create intent. See https://stripe.com/docs/api/payment_intents/create
$ipaddress = getUserRemoteIP();
$metadata = array('dol_version'=>DOL_VERSION, 'dol_entity'=>$conf->entity, 'ipaddress'=>$ipaddress);
if (is_object($object))
@ -433,9 +434,13 @@ class Stripe extends CommonObject
if ($off_session)
{
unset($dataforintent['setup_future_usage']);
$dataforintent["setup_future_usage"] = "off_session";
// We can't use both "setup_future_usage" = "off_session" and "off_session" = true.
// Because $off_session parameter is dedicated to create paymentintent off_line (and not future payment), we need to use "off_session" = true.
//$dataforintent["setup_future_usage"] = "off_session";
$dataforintent["off_session"] = true;
}
if (!empty($conf->global->STRIPE_GIROPAY)) unset($dataforintent['setup_future_usage']);
if (!is_null($payment_method))
{
$dataforintent["payment_method"] = $payment_method;
@ -464,6 +469,9 @@ class Stripe extends CommonObject
if (!empty($key)) { // If the Stripe connect account not set, we use common API usage
$arrayofoptions["stripe_account"] = $key;
}
dol_syslog("dataforintent to create paymentintent = ".var_export($dataforintent, true));
$paymentintent = \Stripe\PaymentIntent::create($dataforintent, $arrayofoptions);
// Store the payment intent

View File

@ -263,8 +263,8 @@ if (empty($reshook))
$object->cond_reglement_id = GETPOST('cond_reglement_id');
$object->mode_reglement_id = GETPOST('mode_reglement_id');
$object->fk_account = GETPOST('fk_account', 'int');
$object->remise_percent = GETPOST('remise_percent');
$object->remise_absolue = GETPOST('remise_absolue');
$object->remise_percent = price2num(GETPOST('remise_percent'), 2);
$object->remise_absolue = price2num(GETPOST('remise_absolue'), 'MU');
$object->socid = GETPOST('socid');
$object->fk_project = GETPOST('projectid', 'int');
$object->model_pdf = GETPOST('model');
@ -556,7 +556,7 @@ if (empty($reshook))
}
$qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS');
$remise_percent = GETPOST('remise_percent'.$predef);
$remise_percent = price2num(GETPOST('remise_percent'.$predef), 2);
$price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU');
// Extrafields
@ -929,10 +929,10 @@ if (empty($reshook))
$fk_unit = GETPOST('units');
$result = $object->updateline(
GETPOST('lineid'),
GETPOST('lineid', 'int'),
$ht,
GETPOST('qty'),
GETPOST('remise_percent'),
price2num(GETPOST('qty'), 'MS'),
price2num(GETPOST('remise_percent'), 2),
$vat_rate,
$localtax1_rate,
$localtax2_rate,
@ -940,7 +940,7 @@ if (empty($reshook))
$price_base_type,
$info_bits,
$special_code,
GETPOST('fk_parent_line'),
GETPOST('fk_parent_line', 'int'),
0,
$fournprice,
$buyingprice,
@ -1018,9 +1018,9 @@ if (empty($reshook))
elseif ($action == 'setconditions' && $usercancreate) {
$result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'));
} elseif ($action == 'setremisepercent' && $usercancreate) {
$result = $object->set_remise_percent($user, GETPOST('remise_percent', 'alpha'));
$result = $object->set_remise_percent($user, price2num(GETPOST('remise_percent'), 2));
} elseif ($action == 'setremiseabsolue' && $usercancreate) {
$result = $object->set_remise_absolue($user, GETPOST('remise_absolue', 'alpha'));
$result = $object->set_remise_absolue($user, price2num(GETPOST('remise_absolue'), 'MU'));
}
// Payment mode

View File

@ -2183,16 +2183,16 @@ class SupplierProposal extends CommonObject
{
global $langs;
$langs->load("supplier_proposal");
$this->labelStatus[self::STATUS_DRAFT] = $langs->trans("SupplierProposalStatusDraft");
$this->labelStatus[self::STATUS_VALIDATED] = $langs->trans("SupplierProposalStatusValidated");
$this->labelStatus[self::STATUS_SIGNED] = $langs->trans("SupplierProposalStatusSigned");
$this->labelStatus[self::STATUS_NOTSIGNED] = $langs->trans("SupplierProposalStatusNotSigned");
$this->labelStatus[self::STATUS_CLOSE] = $langs->trans("SupplierProposalStatusClosed");
$this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans("SupplierProposalStatusDraftShort");
$this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans("Opened");
$this->labelStatusShort[self::STATUS_SIGNED] = $langs->trans("SupplierProposalStatusSignedShort");
$this->labelStatusShort[self::STATUS_NOTSIGNED] = $langs->trans("SupplierProposalStatusNotSignedShort");
$this->labelStatusShort[self::STATUS_CLOSE] = $langs->trans("SupplierProposalStatusClosedShort");
$this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv("SupplierProposalStatusDraft");
$this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv("SupplierProposalStatusValidated");
$this->labelStatus[self::STATUS_SIGNED] = $langs->transnoentitiesnoconv("SupplierProposalStatusSigned");
$this->labelStatus[self::STATUS_NOTSIGNED] = $langs->transnoentitiesnoconv("SupplierProposalStatusNotSigned");
$this->labelStatus[self::STATUS_CLOSE] = $langs->transnoentitiesnoconv("SupplierProposalStatusClosed");
$this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv("SupplierProposalStatusDraftShort");
$this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv("Opened");
$this->labelStatusShort[self::STATUS_SIGNED] = $langs->transnoentitiesnoconv("SupplierProposalStatusSignedShort");
$this->labelStatusShort[self::STATUS_NOTSIGNED] = $langs->transnoentitiesnoconv("SupplierProposalStatusNotSignedShort");
$this->labelStatusShort[self::STATUS_CLOSE] = $langs->transnoentitiesnoconv("SupplierProposalStatusClosedShort");
}
$statusnew = '';

View File

@ -249,7 +249,7 @@ $help_url = 'EN:Ask_Price_Supplier|FR:Demande_de_prix_fournisseur';
//llxHeader('',$langs->trans('CommRequest'),$help_url);
$sql = 'SELECT';
if ($sall || $search_product_category > 0) $sql = 'SELECT DISTINCT';
if ($sall || $search_product_category > 0 || $search_user > 0) $sql = 'SELECT DISTINCT';
$sql .= ' s.rowid as socid, s.nom as name, s.town, s.zip, s.fk_pays, s.client, s.code_client,';
$sql .= " typent.code as typent_code,";
$sql .= " state.code_departement as state_code, state.nom as state_name,";

View File

@ -125,6 +125,10 @@ th.liste_titre a div div:hover, th.liste_titre_sel a div div:hover { text-decora
tr.liste_titre th.liste_titre_sel:not(.maxwidthsearch), tr.liste_titre td.liste_titre_sel:not(.maxwidthsearch),
tr.liste_titre th.liste_titre:not(.maxwidthsearch), tr.liste_titre td.liste_titre:not(.maxwidthsearch) { opacity: 0.8; }
/* th.liste_titre_sel a, th.liste_titre a, td.liste_titre_sel a, td.liste_titre a { color: #766; } */
input {
font-size: unset;
}
input, input.flat, textarea, textarea.flat, form.flat select, select, select.flat, .dataTables_length label select {
background-color: var(--inputbackgroundcolor);
color: var(--colortext);
@ -174,9 +178,12 @@ input, input.flat, textarea, textarea.flat, form.flat select, select, select.fla
input {
line-height: 1.3em;
padding: 5px;
padding: 4px;
padding-left: 5px;
}
.liste_titre input {
padding: 5px;
}
select {
padding-top: 5px;
padding-right: 4px;
@ -440,8 +447,12 @@ input:-webkit-autofill {
background-image:none !important;
-webkit-box-shadow: 0 0 0 50px #FDFFF0 inset;
}
::-webkit-input-placeholder { color:#ccc; }
input:-moz-placeholder { color:#ccc; }
/* CSS for placeholder */
.placeholder { color: #ccc; }
::-webkit-input-placeholder { color: #ccc; }
input:-moz-placeholder { color: #ccc; }
input[name=price], input[name=weight], input[name=volume], input[name=surface], input[name=sizeheight], input[name=net_measure], select[name=incoterm_id] { margin-right: 6px; }
fieldset { border: 1px solid #AAAAAA !important; }
.legendforfieldsetstep { padding-bottom: 10px; }
@ -4139,7 +4150,7 @@ div.boximport {
.fieldrequired { font-weight: bold; color: var(--fieldrequiredcolor) !important; }
td.widthpictotitle { width: 26px; text-align: <?php echo $left; ?>; }
td.widthpictotitle { width: 38px; text-align: <?php echo $left; ?>; }
span.widthpictotitle { font-size: 1.7em; }
table.titlemodulehelp tr td img.widthpictotitle { width: 80px; }
@ -6562,6 +6573,15 @@ div.phpdebugbar-widgets-templates a.phpdebugbar-widgets-editor-link:before
}
/* ============================================================================== */
/* For copypaste feature */
/* ============================================================================== */
.clipboardCPShowOnHover .clipboardCPButton {
display: none;
}
/* ============================================================================== */
/* CSS style used for small screen */
/* ============================================================================== */

View File

@ -297,6 +297,9 @@ a:link, a:visited, a:hover, a:active { font-family: <?php print $fontlist ?>; fo
a:hover { text-decoration: underline; color: rgb(<?php print $colortextlink; ?>); }
a.commonlink { color: rgb(<?php print $colortextlink; ?>) !important; text-decoration: none; }
input {
font-size: unset;
}
input, input.flat, textarea, textarea.flat, form.flat select, select, select.flat, .dataTables_length label select {
background-color: #FDFDFD;
}
@ -568,11 +571,15 @@ input:-webkit-autofill {
background-image:none !important;
-webkit-box-shadow: 0 0 0 50px #FBFFEA inset;
}
/* CSS for placeholder */
.placeholder { color: #ccc; }
::-webkit-input-placeholder { color:#ccc; }
:-moz-placeholder { color:#bbb; } /* firefox 18- */
::-moz-placeholder { color:#bbb; } /* firefox 19+ */
:-ms-input-placeholder { color:#ccc; } /* ie */
input:-moz-placeholder { color:#ccc; }
input[name=price], input[name=weight], input[name=volume], input[name=surface], input[name=sizeheight], input[name=net_measure], select[name=incoterm_id] { margin-right: 6px; }
fieldset { border: 1px solid #AAAAAA !important; }
.legendforfieldsetstep { padding-bottom: 10px; }