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

This commit is contained in:
florian HENRY
2019-09-10 08:36:54 +02:00
29 changed files with 405 additions and 92 deletions

View File

@@ -10,7 +10,6 @@ File added into doxygen generated documentation
<br>
</div>
<!-- Global site tag (gtag.js) - Google Analytics -->
@@ -24,13 +23,30 @@ File added into doxygen generated documentation
</script>
<!-- Facebook Pixel Code -->
<script>
!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
document,'script','//connect.facebook.net/en_US/fbevents.js');
fbq('init', '1998533953704960');
fbq('track', "PageView");</script>
<noscript><img height="1" width="1" style="display:none"
src="https://www.facebook.com/tr?id=1998533953704960&ev=PageView&noscript=1"
/></noscript>
<!-- End Facebook Pixel Code -->
<!-- Twitter ad collector -->
<script src="//platform.twitter.com/oct.js" type="text/javascript"></script>
<script src="//static.ads-twitter.com/oct.js" type="text/javascript"></script>
<script type="text/javascript">twttr.conversion.trackPid('ntm4n', { tw_sale_amount: 0, tw_order_quantity: 0 });</script>
<noscript>
<img height="1" width="1" style="display:none;" alt="" src="https://analytics.twitter.com/i/adsct?txn_id=ntm4n&p_id=Twitter&tw_sale_amount=0&tw_order_quantity=0" />
<img height="1" width="1" style="display:none;" alt="" src="//t.co/i/adsct?txn_id=ntm4n&p_id=Twitter&tw_sale_amount=0&tw_order_quantity=0" />
</noscript>
</body>
</html>

View File

@@ -30,7 +30,6 @@ src="https://www.facebook.com/tr?id=1998533953704960&ev=PageView&noscript=1"
</head>
<body>
<div id="top">
<div class="topmaincol">
<div class="divpath">

View File

@@ -1,7 +1,7 @@
<?php
/* Copyright (C) 2016 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2016 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2016-2018 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2016-2019 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
*
* This program is free software; you can redistribute it and/or modify
@@ -164,7 +164,7 @@ if ($action == 'export_csv')
print $object->get_compte_desc($line->numero_compte) . $sep;
print price($line->debit) . $sep;
print price($line->credit) . $sep;
print price($line->credit - $line->debit) . $sep;
print price($line->debit - $line->credit) . $sep;
print "\n";
}
@@ -293,9 +293,9 @@ if ($action != 'export_csv')
print '<td>' . length_accountg($line->numero_compte) . '</td>';
print '<td>' . $description . '</td>';
print '<td class="right">' . price($line->debit) . '</td>';
print '<td class="right">' . price($line->credit) . '</td>';
print '<td class="right">' . price($line->credit - $line->debit) . '</td>';
print '<td class="nowraponall right">' . price($line->debit) . '</td>';
print '<td class="nowraponall right">' . price($line->credit) . '</td>';
print '<td class="nowraponall right">' . price($line->debit - $line->credit) . '</td>';
print '<td class="center">' . $link;
print '</td>';
print "</tr>\n";
@@ -305,11 +305,11 @@ if ($action != 'export_csv')
$sous_total_credit += $line->credit;
}
print '<tr class="liste_total"><td class="right" colspan="2">' . $langs->trans("SubTotal") . ':</td><td class="nowrap right">' . price($sous_total_debit) . '</td><td class="nowrap right">' . price($sous_total_credit) . '</td><td class="nowrap right">' . price(price2num($sous_total_credit - $sous_total_debit)) . '</td>';
print '<tr class="liste_total"><td class="right" colspan="2">' . $langs->trans("SubTotal") . ':</td><td class="nowrap right">' . price($sous_total_debit) . '</td><td class="nowrap right">' . price($sous_total_credit) . '</td><td class="nowrap right">' . price(price2num($sous_total_debit - $sous_total_credit)) . '</td>';
print "<td>&nbsp;</td>\n";
print '</tr>';
print '<tr class="liste_total"><td class="right" colspan="2">' . $langs->trans("AccountBalance") . ':</td><td class="nowrap right">' . price($total_debit) . '</td><td class="nowrap right">' . price($total_credit) . '</td><td class="nowrap right">' . price(price2num($total_credit - $total_debit)) . '</td>';
print '<tr class="liste_total"><td class="right" colspan="2">' . $langs->trans("AccountBalance") . ':</td><td class="nowrap right">' . price($total_debit) . '</td><td class="nowrap right">' . price($total_credit) . '</td><td class="nowrap right">' . price(price2num($total_debit - $total_credit)) . '</td>';
print "<td>&nbsp;</td>\n";
print '</tr>';

View File

@@ -424,7 +424,7 @@ class AdherentType extends CommonObject
global $langs;
if ($morphy == 'phy') { return $langs->trans("Physical"); }
elseif ($morphy == 'mor') { return $langs->trans("Moral"); }
else return $langs->trans("Physical & Morale");
else return $langs->trans("MorPhy");
//return $morphy;
}

View File

@@ -283,7 +283,7 @@ if (! $rowid && $action != 'create' && $action != 'edit')
print '<td class="center">';
if ($objp->morphy == 'phy') { print $langs->trans("Physical"); }
elseif ($objp->morphy == 'mor') { print $langs->trans("Moral"); }
else print $langs->trans("Physical & Morale");
else print $langs->trans("MorPhy");
print '</td>';
print '<td class="center">'.yn($objp->subscription).'</td>';
print '<td class="center">'.yn($objp->vote).'</td>';

View File

@@ -746,13 +746,19 @@ class Categorie extends CommonObject
/**
* Return list of fetched instance of elements having this category
*
* @param string $type Type of category ('customer', 'supplier', 'contact', 'product', 'member')
* @param int $onlyids Return only ids of objects (consume less memory)
* @return array|int -1 if KO, array of instance of object if OK
* @param string $type Type of category ('customer', 'supplier', 'contact', 'product', 'member')
* @param int $onlyids Return only ids of objects (consume less memory)
* @param int $limit Limit
* @param int $offset Offset
* @param string $sortfield Sort fields
* @param string $sortorder Sort order ('ASC' or 'DESC');
* @return array|int -1 if KO, array of instance of object if OK
* @see containsObject()
*/
public function getObjectsInCateg($type, $onlyids = 0)
public function getObjectsInCateg($type, $onlyids = 0, $limit = 0, $offset = 0, $sortfield = '', $sortorder = 'ASC')
{
global $user;
$objs = array();
$obj = new $this->MAP_OBJ_CLASS[$type]( $this->db );
@@ -761,8 +767,15 @@ class Categorie extends CommonObject
$sql .= " FROM " . MAIN_DB_PREFIX . "categorie_" . $this->MAP_CAT_TABLE[$type] . " as c";
$sql .= ", " . MAIN_DB_PREFIX . $this->MAP_OBJ_TABLE[$type] . " as o";
$sql .= " WHERE o.entity IN (" . getEntity($obj->element).")";
$sql.= " AND c.fk_categorie = ".$this->id;
$sql .= " AND c.fk_categorie = ".$this->id;
$sql .= " AND c.fk_" . $this->MAP_CAT_FK[$type] . " = o.rowid";
// Protection for external users
if (($type == 'customer' || $type == 'supplier') && $user->societe_id > 0)
{
$sql.= " AND o.rowid = ".$user->societe_id;
}
if ($limit > 0 || $offset > 0) $sql .= $this->db->plimit($limit + 1, $offset);
$sql .= $this->db->order($sortfield, $sortorder);
dol_syslog(get_class($this)."::getObjectsInCateg", LOG_DEBUG);
$resql = $this->db->query($sql);

View File

@@ -34,13 +34,32 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
// Load translation files required by the page
$langs->load("categories");
$id = GETPOST('id', 'int');
$label= GETPOST('label', 'alpha');
$type = GETPOST('type', 'az09');
$action=GETPOST('action', 'aZ09');
$confirm = GETPOST('confirm', 'alpha');
$id = GETPOST('id', 'int');
$label = GETPOST('label', 'alpha');
$type = GETPOST('type', 'az09');
$removeelem = GETPOST('removeelem', 'int');
$elemid = GETPOST('elemid', 'alpha');
$elemid = GETPOST('elemid', 'int');
$action = GETPOST('action', 'aZ09')?GETPOST('action', 'aZ09'):'view'; // The action 'add', 'create', 'edit', 'update', 'view', ...
$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists)
$show_files = GETPOST('show_files', 'int'); // Show files area generated by bulk actions ?
$confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation
$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button
$toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list
$contextpage= GETPOST('contextpage', 'aZ')?GETPOST('contextpage', 'aZ'):'myobjectlist'; // To manage different context of search
$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page
$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
// Load variable for pagination
$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit;
$sortfield = GETPOST('sortfield', 'alpha');
$sortorder = GETPOST('sortorder', 'alpha');
$page = GETPOST('page', 'int');
if (empty($page) || $page == -1 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) { $page = 0; } // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action
$offset = $limit * $page;
$pageprev = $page - 1;
$pagenext = $page + 1;
if ($id == "" && $label == "")
{
@@ -319,10 +338,20 @@ else
}
// List of mass actions available
$arrayofmassactions = array(
//'validate'=>$langs->trans("Validate"),
//'generate_doc'=>$langs->trans("ReGeneratePDF"),
//'builddoc'=>$langs->trans("PDFMerge"),
//'presend'=>$langs->trans("SendByMail"),
);
$massactionbutton=$form->selectMassAction('', $arrayofmassactions);
// List of products or services (type is type of category)
if ($type == Categorie::TYPE_PRODUCT)
{
$prods = $object->getObjectsInCateg("product");
$prods = $object->getObjectsInCateg("product", 0, $limit, $offset);
if ($prods < 0)
{
dol_print_error($db, $prods->error, $prods->errors);
@@ -351,14 +380,28 @@ if ($type == Categorie::TYPE_PRODUCT)
print '</form>';
}
print "<br>";
print '<form method="post" action="'.$_SERVER["PHP_SELF"].'">';
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<input type="hidden" name="typeid" value="'.$typeid.'">';
print '<input type="hidden" name="type" value="'.$typeid.'">';
print '<input type="hidden" name="id" value="'.$object->id.'">';
print '<input type="hidden" name="action" value="list">';
print '<br>';
$param = '&limit='.$limit.'&id='.$id.'&type='.$type; $num = count($prods); $nbtotalofrecords = ''; $newcardbutton = '';
print_barre_liste($langs->trans("ProductsAndServices"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, '', 0, $newcardbutton, '', $limit);
print "<table class='noborder' width='100%'>\n";
print '<tr class="liste_titre"><td colspan="3">'.$langs->trans("ProductsAndServices").' <span class="badge">'.count($prods).'</span></td></tr>'."\n";
print '<tr class="liste_titre"><td colspan="3">'.$langs->trans("Ref").'</td></tr>'."\n";
if (count($prods) > 0)
{
$i = 0;
foreach ($prods as $prod)
{
$i++;
if ($i > $limit) break;
print "\t".'<tr class="oddeven">'."\n";
print '<td class="nowrap" valign="top">';
print $prod->getNomUrl(1);
@@ -388,26 +431,42 @@ if ($type == Categorie::TYPE_PRODUCT)
print '<tr class="oddeven"><td colspan="2" class="opacitymedium">'.$langs->trans("ThisCategoryHasNoProduct").'</td></tr>';
}
print "</table>\n";
print '</form>'."\n";
}
}
if ($type == Categorie::TYPE_SUPPLIER)
{
$socs = $object->getObjectsInCateg("supplier");
$socs = $object->getObjectsInCateg("supplier", 0, $limit, $offset);
if ($socs < 0)
{
dol_print_error($db, $socs->error, $socs->errors);
}
else
{
print "<br>";
print '<form method="post" action="'.$_SERVER["PHP_SELF"].'">';
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<input type="hidden" name="typeid" value="'.$typeid.'">';
print '<input type="hidden" name="type" value="'.$typeid.'">';
print '<input type="hidden" name="id" value="'.$object->id.'">';
print '<input type="hidden" name="action" value="list">';
print '<br>';
$param = '&limit='.$limit.'&id='.$id.'&type='.$type; $num = count($socs); $nbtotalofrecords = ''; $newcardbutton = '';
print_barre_liste($langs->trans("Suppliers"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, '', 0, $newcardbutton, '', $limit);
print '<table class="noborder" width="100%">'."\n";
print '<tr class="liste_titre"><td colspan="2">'.$langs->trans("Suppliers").' <span class="badge">'.count($socs)."</span></td></tr>\n";
print '<tr class="liste_titre"><td colspan="2">'.$langs->trans("Name")."</td></tr>\n";
if (count($socs) > 0)
{
$i = 0;
foreach ($socs as $soc)
{
$i++;
if ($i > $limit) break;
print "\t".'<tr class="oddeven">'."\n";
print '<td class="nowrap" valign="top">';
print $soc->getNomUrl(1);
@@ -437,30 +496,41 @@ if ($type == Categorie::TYPE_SUPPLIER)
print '<tr class="oddeven"><td class="opacitymedium">'.$langs->trans("ThisCategoryHasNoSupplier").'</td></tr>';
}
print "</table>\n";
print '</form>'."\n";
}
}
if($type == Categorie::TYPE_CUSTOMER)
{
$socs = $object->getObjectsInCateg("customer");
$socs = $object->getObjectsInCateg("customer", 0, $limit, $offset);
if ($socs < 0)
{
dol_print_error($db, $socs->error, $socs->errors);
}
else
{
print "<br>";
print '<form method="post" action="'.$_SERVER["PHP_SELF"].'">';
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<input type="hidden" name="typeid" value="'.$typeid.'">';
print '<input type="hidden" name="type" value="'.$typeid.'">';
print '<input type="hidden" name="id" value="'.$object->id.'">';
print '<input type="hidden" name="action" value="list">';
print '<br>';
$param = '&limit='.$limit.'&id='.$id.'&type='.$type; $num = count($socs); $nbtotalofrecords = ''; $newcardbutton = '';
print_barre_liste($langs->trans("Customers"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, '', 0, $newcardbutton, '', $limit);
print '<table class="noborder" width="100%">'."\n";
print '<tr class="liste_titre"><td colspan="2">'.$langs->trans("Customers").' <span class="badge">'.count($socs).'</span></td></tr>'."\n";
print '<tr class="liste_titre"><td colspan="2">'.$langs->trans("Name").'</td></tr>'."\n";
if (count($socs) > 0)
{
$i = 0;
foreach ($socs as $key => $soc)
{
if ($user->societe_id > 0 && $soc->id != $user->societe_id) continue; // External user always see only themself
$i++;
if ($i > $limit) break;
print "\t".'<tr class="oddeven">'."\n";
print '<td class="nowrap" valign="top">';
@@ -490,6 +560,8 @@ if($type == Categorie::TYPE_CUSTOMER)
print '<tr class="oddeven"><td class="opacitymedium">'.$langs->trans("ThisCategoryHasNoCustomer").'</td></tr>';
}
print "</table>\n";
print '</form>'."\n";
}
}
@@ -498,21 +570,35 @@ if ($type == Categorie::TYPE_MEMBER)
{
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
$prods = $object->getObjectsInCateg("member");
$prods = $object->getObjectsInCateg("member", 0, $limit, $offset);
if ($prods < 0)
{
dol_print_error($db, $prods->error, $prods->errors);
}
else
{
print "<br>";
print '<form method="post" action="'.$_SERVER["PHP_SELF"].'">';
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<input type="hidden" name="typeid" value="'.$typeid.'">';
print '<input type="hidden" name="type" value="'.$typeid.'">';
print '<input type="hidden" name="id" value="'.$object->id.'">';
print '<input type="hidden" name="action" value="list">';
print '<br>';
$param = '&limit='.$limit.'&id='.$id.'&type='.$type; $num = count($prods); $nbtotalofrecords = ''; $newcardbutton = '';
print_barre_liste($langs->trans("Member"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, '', 0, $newcardbutton, '', $limit);
print "<table class='noborder' width='100%'>\n";
print '<tr class="liste_titre"><td colspan="4">'.$langs->trans("Member").' <span class="badge">'.count($prods).'</span></td></tr>'."\n";
print '<tr class="liste_titre"><td colspan="4">'.$langs->trans("Name").'</td></tr>'."\n";
if (count($prods) > 0)
{
$i = 0;
foreach ($prods as $key => $member)
{
$i++;
if ($i > $limit) break;
print "\t".'<tr class="oddeven">'."\n";
print '<td class="nowrap" valign="top">';
$member->ref=$member->login;
@@ -543,22 +629,35 @@ if ($type == Categorie::TYPE_MEMBER)
print '<tr class="oddeven"><td colspan="3" class="opacitymedium">'.$langs->trans("ThisCategoryHasNoMember").'</td></tr>';
}
print "</table>\n";
print '</form>'."\n";
}
}
// Categorie contact
if ($type == Categorie::TYPE_CONTACT)
{
$contacts = $object->getObjectsInCateg("contact");
$contacts = $object->getObjectsInCateg("contact", 0, $limit, $offset);
if ($contacts < 0)
{
dol_print_error($db, $contacts->error, $contacts->errors);
}
else
{
print "<br>";
print '<form method="post" action="'.$_SERVER["PHP_SELF"].'">';
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<input type="hidden" name="typeid" value="'.$typeid.'">';
print '<input type="hidden" name="type" value="'.$typeid.'">';
print '<input type="hidden" name="id" value="'.$object->id.'">';
print '<input type="hidden" name="action" value="list">';
print '<br>';
$param = '&limit='.$limit.'&id='.$id.'&type='.$type; $num = count($contacts); $nbtotalofrecords = ''; $newcardbutton = '';
print_barre_liste($langs->trans("Contact"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, '', 0, $newcardbutton, '', $limit);
print '<table class="noborder" width="100%">'."\n";
print '<tr class="liste_titre"><td colspan="2">'.$langs->trans("Contact").' <span class="badge">'.count($contacts).'</span></td></tr>'."\n";
print '<tr class="liste_titre"><td colspan="2">'.$langs->trans("Ref").'</td></tr>'."\n";
if (count($contacts) > 0)
{
@@ -566,6 +665,7 @@ if ($type == Categorie::TYPE_CONTACT)
foreach ($contacts as $key => $contact)
{
$i++;
if ($i > $limit) break;
print "\t".'<tr class="oddeven">'."\n";
print '<td class="nowrap" valign="top">';
@@ -595,6 +695,8 @@ if ($type == Categorie::TYPE_CONTACT)
print '<tr class="oddeven"><td class="opacitymedium">'.$langs->trans("ThisCategoryHasNoContact").'</td></tr>';
}
print "</table>\n";
print '</form>'."\n";
}
}
@@ -603,21 +705,35 @@ if ($type == Categorie::TYPE_ACCOUNT)
{
require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
$accounts = $object->getObjectsInCateg("account");
$accounts = $object->getObjectsInCateg("account", 0, $limit, $offset);
if ($accounts < 0)
{
dol_print_error($db, $accounts->error, $accounts->errors);
}
else
{
print "<br>";
print "<table class='noborder' width='100%'>\n";
print '<tr class="liste_titre"><td colspan="4">'.$langs->trans("Account").' <span class="badge">'.count($accounts).'</span></td></tr>'."\n";
print '<form method="post" action="'.$_SERVER["PHP_SELF"].'">';
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<input type="hidden" name="typeid" value="'.$typeid.'">';
print '<input type="hidden" name="type" value="'.$typeid.'">';
print '<input type="hidden" name="id" value="'.$object->id.'">';
print '<input type="hidden" name="action" value="list">';
print '<br>';
$param = '&limit='.$limit.'&id='.$id.'&type='.$type; $num = count($accounts); $nbtotalofrecords = ''; $newcardbutton = '';
print_barre_liste($langs->trans("Account"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, '', 0, $newcardbutton, '', $limit);
print "<table class='noborder' width='100%'>\n";
print '<tr class="liste_titre"><td colspan="4">'.$langs->trans("Ref").'</td></tr>'."\n";
if (count($accounts) > 0)
{
$i = 0;
foreach ($accounts as $key => $account)
{
$i++;
if ($i > $limit) break;
print "\t".'<tr class="oddeven">'."\n";
print '<td class="nowrap" valign="top">';
print $account->getNomUrl(1, 0);
@@ -647,6 +763,8 @@ if ($type == Categorie::TYPE_ACCOUNT)
print '<tr class="oddeven"><td colspan="3" class="opacitymedium">'.$langs->trans("ThisCategoryHasNoAccount").'</td></tr>';
}
print "</table>\n";
print '</form>'."\n";
}
}
@@ -655,21 +773,35 @@ if ($type == Categorie::TYPE_PROJECT)
{
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
$projects = $object->getObjectsInCateg("project");
$projects = $object->getObjectsInCateg("project", 0, $limit, $offset);
if ($projects < 0)
{
dol_print_error($db, $object->error, $object->errors);
}
else
{
print "<br>";
print '<form method="post" action="'.$_SERVER["PHP_SELF"].'">';
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<input type="hidden" name="typeid" value="'.$typeid.'">';
print '<input type="hidden" name="type" value="'.$typeid.'">';
print '<input type="hidden" name="id" value="'.$object->id.'">';
print '<input type="hidden" name="action" value="list">';
print '<br>';
$param = '&limit='.$limit.'&id='.$id.'&type='.$type; $num = count($projects); $nbtotalofrecords = ''; $newcardbutton = '';
print_barre_liste($langs->trans("Project"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, '', 0, $newcardbutton, '', $limit);
print "<table class='noborder' width='100%'>\n";
print '<tr class="liste_titre"><td colspan="4">'.$langs->trans("Project").' <span class="badge">'.count($projects).'</span></td></tr>'."\n";
print '<tr class="liste_titre"><td colspan="4">'.$langs->trans("Ref").'</td></tr>'."\n";
if (count($projects) > 0)
{
$i = 0;
foreach ($projects as $key => $project)
{
$i++;
if ($i > $limit) break;
print "\t".'<tr class="oddeven">'."\n";
print '<td class="nowrap" valign="top">';
print $project->getNomUrl(1);
@@ -699,6 +831,8 @@ if ($type == Categorie::TYPE_PROJECT)
print '<tr class="oddeven"><td colspan="3" class="opacitymedium">'.$langs->trans("ThisCategoryHasNoProject").'</td></tr>';
}
print "</table>\n";
print '</form>'."\n";
}
}

View File

@@ -835,7 +835,7 @@ else
{
// EMailing feature may be a spam problem, so when you host several users/instance, having this option may force each user to use their own SMTP agent.
// You ensure that every user is using its own SMTP server when using the mass emailing module.
$linktoadminemailbefore='<a href="'.DOL_URL_ROOT.'/admin/mails.php">';
$linktoadminemailbefore='<a href="'.DOL_URL_ROOT.'/admin/mails_emailing.php">';
$linktoadminemailend='</a>';
setEventMessages($langs->trans("MailSendSetupIs", $listofmethods[$sendingmode]), null, 'warnings');
setEventMessages($langs->trans("MailSendSetupIs2", $linktoadminemailbefore, $linktoadminemailend, $langs->transnoentitiesnoconv("MAIN_MAIL_SENDMODE"), $listofmethods['smtps']), null, 'warnings');

View File

@@ -335,15 +335,15 @@ class Mailing extends CommonObject
$target_array=array();
$sql = "SELECT fk_contact, ";
$sql.=" lastname, ";
$sql.=" firstname,";
$sql.=" email,";
$sql.=" other,";
$sql.=" source_url,";
$sql.=" source_id ,";
$sql.=" source_type ";
$sql.= " FROM ".MAIN_DB_PREFIX."mailing_cibles ";
$sql = "SELECT fk_contact,";
$sql.= " lastname,";
$sql.= " firstname,";
$sql.= " email,";
$sql.= " other,";
$sql.= " source_url,";
$sql.= " source_id ,";
$sql.= " source_type";
$sql.= " FROM ".MAIN_DB_PREFIX."mailing_cibles";
$sql.= " WHERE fk_mailing = ".$fromid;
$result=$this->db->query($sql);
@@ -353,14 +353,16 @@ class Mailing extends CommonObject
{
while ($obj = $this->db->fetch_object($result)) {
$target_array[]=array('fk_contact'=>$obj->fk_contact,
'lastname'=>$obj->lastname,
'firstname'=>$obj->firstname,
'email'=>$obj->email,
'other'=>$obj->other,
'source_url'=>$obj->source_url,
'source_id'=>$obj->source_id,
'source_type'=>$obj->source_type);
$target_array[]=array(
'fk_contact'=>$obj->fk_contact,
'lastname'=>$obj->lastname,
'firstname'=>$obj->firstname,
'email'=>$obj->email,
'other'=>$obj->other,
'source_url'=>$obj->source_url,
'source_id'=>$obj->source_id,
'source_type'=>$obj->source_type
);
}
}
}

View File

@@ -739,8 +739,11 @@ class BonPrelevement extends CommonObject
$sql = "SELECT count(f.rowid) as nb";
$sql.= " FROM ".MAIN_DB_PREFIX."facture as f";
$sql.= ", ".MAIN_DB_PREFIX."prelevement_facture_demande as pfd";
$sql.= " WHERE f.fk_statut = ".Facture::STATUS_VALIDATED;
$sql.= " AND f.entity IN (".getEntity('invoice').")";
$sql.= " WHERE f.entity IN (".getEntity('invoice').")";
if (empty($conf->global->WITHDRAWAL_ALLOW_ANY_INVOICE_STATUS))
{
$sql.= " AND f.fk_statut = ".Facture::STATUS_VALIDATED;
}
$sql.= " AND f.rowid = pfd.fk_facture";
$sql.= " AND pfd.traite = 0";
$sql.= " AND f.total_ttc > 0";

View File

@@ -208,7 +208,10 @@ $sql.= " ".MAIN_DB_PREFIX."societe as s,";
$sql.= " ".MAIN_DB_PREFIX."prelevement_facture_demande as pfd";
$sql.= " WHERE s.rowid = f.fk_soc";
$sql.= " AND f.entity IN (".getEntity('invoice').")";
$sql.= " AND f.fk_statut = ".Facture::STATUS_VALIDATED;
if (empty($conf->global->WITHDRAWAL_ALLOW_ANY_INVOICE_STATUS))
{
$sql.= " AND f.fk_statut = ".Facture::STATUS_VALIDATED;
}
$sql.= " AND f.total_ttc > 0";
$sql.= " AND pfd.traite = 0";
$sql.= " AND pfd.fk_facture = f.rowid";

View File

@@ -93,7 +93,10 @@ if ($socid) $sql.= " AND f.fk_soc = ".$socid;
if (!$status) $sql.= " AND pfd.traite = 0";
if ($status) $sql.= " AND pfd.traite = ".$status;
$sql.= " AND f.total_ttc > 0";
$sql.= " AND f.fk_statut = ".Facture::STATUS_VALIDATED;
if (empty($conf->global->WITHDRAWAL_ALLOW_ANY_INVOICE_STATUS))
{
$sql.= " AND f.fk_statut = ".Facture::STATUS_VALIDATED;
}
$sql.= " AND pfd.fk_facture = f.rowid";
if (dol_strlen(trim(GETPOST('search_societe', 'alpha'))))
{

View File

@@ -102,7 +102,10 @@ $sql.= " , ".MAIN_DB_PREFIX."prelevement_facture_demande as pfd";
$sql.= " WHERE s.rowid = f.fk_soc";
$sql.= " AND f.entity IN (".getEntity('invoice').")";
$sql.= " AND f.total_ttc > 0";
$sql.= " AND f.fk_statut = ".Facture::STATUS_VALIDATED;
if (empty($conf->global->WITHDRAWAL_ALLOW_ANY_INVOICE_STATUS))
{
$sql.= " AND f.fk_statut = ".Facture::STATUS_VALIDATED;
}
$sql.= " AND pfd.traite = 0 AND pfd.fk_facture = f.rowid";
if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id;
if ($socid) $sql.= " AND f.fk_soc = ".$socid;

View File

@@ -433,7 +433,7 @@ if (empty($reshook))
}
$qty = GETPOST('qty'.$predef);
$remise_percent = GETPOST('remise_percent'.$predef);
$remise_percent = ((GETPOST('remise_percent'.$predef) != '') ? GETPOST('remise_percent'.$predef) : 0);
if ($qty == '')
{
@@ -566,7 +566,8 @@ if (empty($reshook))
$info_bits=0;
if ($tva_npr) $info_bits |= 0x01;
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($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($remise_percent)/100) < price2num($price_min))))
{
$object->error = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, -1, $conf->currency));
$result = -1 ;

View File

@@ -173,7 +173,7 @@ class box_activity extends ModeleBoxes
$totalnb += $data[$j]->nb;
$this->info_box_contents[$line][3] = array(
'td' => 'class="right"',
'td' => 'class="nowrap right"',
'text' => price($data[$j]->Mnttot, 1, $langs, 0, 0, -1, $conf->currency),
);
$this->info_box_contents[$line][4] = array(
@@ -256,7 +256,7 @@ class box_activity extends ModeleBoxes
$totalnb += $data[$j]->nb;
$this->info_box_contents[$line][3] = array(
'td' => 'class="right"',
'td' => 'class="nowrap right"',
'text' => price($data[$j]->Mnttot, 1, $langs, 0, 0, -1, $conf->currency),
);
$this->info_box_contents[$line][4] = array(
@@ -340,7 +340,7 @@ class box_activity extends ModeleBoxes
);
$this->info_box_contents[$line][3] = array(
'td' => 'class="right"',
'td' => 'class="nowrap right"',
'text' => price($data[$j]->Mnttot, 1, $langs, 0, 0, -1, $conf->currency)
);

View File

@@ -134,7 +134,7 @@ class box_comptes extends ModeleBoxes
);
$this->info_box_contents[$line][] = array(
'td' => 'class="right"',
'td' => 'class="right nowraponall"',
'text' => price($solde, 0, $langs, 0, -1, -1, $objp->currency_code)
);

View File

@@ -179,12 +179,12 @@ class box_produits_alerte_stock extends ModeleBoxes
}
$this->info_box_contents[$line][] = array(
'td' => 'class="right"',
'td' => 'class="right nowraponall"',
'text' => $price,
);
$this->info_box_contents[$line][] = array(
'td' => 'class="nowrap"',
'td' => 'class="right"',
'text' => $price_base_type,
);

View File

@@ -135,7 +135,7 @@ class box_supplier_orders extends ModeleBoxes
);
$this->info_box_contents[$line][] = array(
'td' => 'class="right"',
'td' => 'class="right nowrap"',
'text' => price($objp->total_ht, 0, $langs, 0, -1, -1, $conf->currency),
);

View File

@@ -4237,7 +4237,7 @@ class Form
$formconfirm.= '<td class="valid">';
$formconfirm.= $this->selectyesno("confirm", $newselectedchoice);
$formconfirm.= '</td>';
$formconfirm.= '<td class="valid center"><input class="button valignmiddle" type="submit" onclick="this.disabled=\'disabled\' value="'.$langs->trans("Validate").'"></td>';
$formconfirm.= '<td class="valid center"><input class="button valignmiddle" type="submit" value="'.$langs->trans("Validate").'"></td>';
$formconfirm.= '</tr>'."\n";
$formconfirm.= '</table>'."\n";

View File

@@ -88,7 +88,6 @@ class mailing_advthirdparties extends MailingTargets
dol_syslog(get_class($this)."::add_to_target_spec mailing ".$num." targets found", LOG_DEBUG);
$old = '';
while ($i < $num)
{
$obj = $this->db->fetch_object($result);
@@ -144,7 +143,6 @@ class mailing_advthirdparties extends MailingTargets
dol_syslog(get_class($this)."::add_to_target_spec mailing ".$num." targets found");
$old = '';
while ($i < $num)
{
$obj = $this->db->fetch_object($result);

View File

@@ -78,6 +78,7 @@ print 'Option rebuild_product_thumbs (\'test\' or \'confirmed\') is '.(GETPOST('
print 'Option force_disable_of_modules_not_found (\'test\' or \'confirmed\') is '.(GETPOST('force_disable_of_modules_not_found', 'alpha')?GETPOST('force_disable_of_modules_not_found', 'alpha'):'undefined').'<br>'."\n";
print 'Option clean_perm_table (\'test\' or \'confirmed\') is '.(GETPOST('clean_perm_table', 'alpha')?GETPOST('clean_perm_table', 'alpha'):'undefined').'<br>'."\n";
print 'Option force_utf8_on_tables, for mysql/mariadb only (\'test\' or \'confirmed\') is '.(GETPOST('force_utf8_on_tables', 'alpha')?GETPOST('force_utf8_on_tables', 'alpha'):'undefined').'<br>'."\n";
print 'Option repair_link_dispatch_lines_supplier_order_lines, (\'test\' or \'confirmed\') is '.(GETPOST('repair_link_dispatch_lines_supplier_order_lines', 'alpha')?GETPOST('repair_link_dispatch_lines_supplier_order_lines', 'alpha'):'undefined').'<br>'."\n";
print '<br>';
print '<table cellspacing="0" cellpadding="1" border="0" width="100%">';
@@ -1275,6 +1276,144 @@ if ($ok && GETPOST('force_utf8_on_tables', 'alpha'))
}
}
//
if ($ok && GETPOST('repair_link_dispatch_lines_supplier_order_lines')) {
/*
* This script is meant to be run when upgrading from a dolibarr version < 3.8
* to a newer version.
*
* Version 3.8 introduces a new column in llx_commande_fournisseur_dispatch, which
* matches the dispatch to a specific supplier order line (so that if there are
* several with the same product, the user can specifically tell which products of
* which line were dispatched where).
*
* However when migrating, the new column has a default value of 0, which means that
* old supplier orders whose lines were dispatched using the old dolibarr version
* have unspecific dispatch lines, which are not taken into account by the new version,
* thus making the order look like it was never dispatched at all.
*
* This scripts sets this foreign key to the first matching supplier order line whose
* product (and supplier order of course) are the same as the dispatchs.
*
* If the dispatched quantity is more than indicated on the order line (this happens if
* there are several order lines for the same product), it creates new dispatch lines
* pointing to the other order lines accordingly, until all the dispatched quantity is
* accounted for.
*/
$repair_link_dispatch_lines_supplier_order_lines = GETPOST('repair_link_dispatch_lines_supplier_order_lines', 'alpha');
echo '<tr><th>Repair llx_commande_fournisseur_dispatch.fk_commandefourndet</th></tr>';
echo '<tr><td>Repair in progress. This may take a while.</td></tr>';
$sql_dispatch = 'SELECT * FROM ' . MAIN_DB_PREFIX . 'commande_fournisseur_dispatch WHERE COALESCE(fk_commandefourndet, 0) = 0';
$db->begin();
$resql_dispatch = $db->query($sql_dispatch);
$n_processed_rows = 0;
$errors = array();
if ($resql_dispatch) {
if ($db->num_rows($resql_dispatch) == 0) {
echo '<tr><td>Nothing to do.</td></tr>';
exit;
}
while ($obj_dispatch = $db->fetch_object($resql_dispatch)) {
$sql_line = 'SELECT line.rowid, line.qty FROM ' . MAIN_DB_PREFIX . 'commande_fournisseurdet AS line'
. ' WHERE line.fk_commande = ' . $obj_dispatch->fk_commande
. ' AND line.fk_product = ' . $obj_dispatch->fk_product;
$resql_line = $db->query($sql_line);
// sil y a plusieurs lignes avec le même produit sur cette commande fournisseur,
// on divise la ligne de dispatch en autant de lignes quon en a sur la commande pour le produit
// et on met la quantité de la ligne dans la limite du "budget" indiqué par dispatch.qty
$remaining_qty = $obj_dispatch->qty;
$first_iteration = true;
if (!$resql_line) {
echo '<tr><td>Unable to find a matching supplier order line for dispatch #' . $obj_dispatch->rowid . '</td></tr>';
$errors[] = $sql_line;
$n_processed_rows++;
continue;
}
if ($db->num_rows($resql_line) == 0) continue;
while ($obj_line = $db->fetch_object($resql_line)) {
if (!$remaining_qty) break;
if (!$obj_line->rowid) {
continue;
}
$qty_for_line = min($remaining_qty, $obj_line->qty);
if ($first_iteration) {
$sql_attach = 'UPDATE ' . MAIN_DB_PREFIX . 'commande_fournisseur_dispatch'
. ' SET fk_commandefourndet = ' . $obj_line->rowid . ', qty = ' . $qty_for_line
. ' WHERE rowid = ' . $obj_dispatch->rowid;
$first_iteration = false;
} else {
$sql_attach_values = array(
$obj_dispatch->fk_commande,
$obj_dispatch->fk_product,
$obj_line->rowid,
$qty_for_line,
$obj_dispatch->fk_entrepot,
$obj_dispatch->fk_user,
$obj_dispatch->datec ? '"' . $db->escape($obj_dispatch->datec) . '"' : 'NULL',
$obj_dispatch->comment ? '"' . $db->escape($obj_dispatch->comment) . '"' : 'NULL',
$obj_dispatch->status ?: 'NULL',
$obj_dispatch->tms ? '"' . $db->escape($obj_dispatch->tms) . '"': 'NULL',
$obj_dispatch->batch ?: 'NULL',
$obj_dispatch->eatby ? '"' . $db->escape($obj_dispatch->eatby) . '"': 'NULL',
$obj_dispatch->sellby ? '"' . $db->escape($obj_dispatch->sellby) . '"': 'NULL'
);
$sql_attach_values = join(', ', $sql_attach_values);
$sql_attach = 'INSERT INTO ' . MAIN_DB_PREFIX . 'commande_fournisseur_dispatch'
. ' (fk_commande, fk_product, fk_commandefourndet, qty, fk_entrepot, fk_user, datec, comment, status, tms, batch, eatby, sellby)'
. ' VALUES (' . $sql_attach_values . ')';
}
if ($repair_link_dispatch_lines_supplier_order_lines == 'confirmed')
{
$resql_attach = $db->query($sql_attach);
}
else
{
$resql_attach = true; // Force success in test mode
}
if ($resql_attach) {
$remaining_qty -= $qty_for_line;
} else {
$errors[] = $sql_attach;
}
$first_iteration = false;
}
$n_processed_rows++;
// report progress every 256th row
if (!($n_processed_rows & 0xff)) {
echo '<tr><td>Processed ' . $n_processed_rows . ' rows with ' . count($errors) . ' errors…' . "</td></tr>\n";
flush();
ob_flush();
}
}
} else {
echo '<tr><td>Unable to find any dispatch without an fk_commandefourndet.' . "</td></tr>\n";
echo $sql_dispatch . "\n";
}
echo '<tr><td>Fixed ' . $n_processed_rows . ' rows with ' . count($errors) . ' errors…' . "</td></tr>\n";
echo '<tr><td>DONE.' . "</td></tr>\n";
if (count($errors)) {
$db->rollback();
echo '<tr><td>The transaction was rolled back due to errors: nothing was changed by the script.</td></tr>';
} else {
$db->commit();
}
$db->close();
echo '<tr><td><h3>SQL queries with errors:</h3></tr></td>';
echo '<tr><td>' . join('</td></tr><tr><td>', $errors) . '</td></tr>';
}
print '</table>';

View File

@@ -97,16 +97,14 @@ class mailing_mailinglist_mymodule_myobject extends MailingTargets
* This is the main function that returns the array of emails
*
* @param int $mailing_id Id of emailing
* @param array $cibles Array with targets
* @return int <0 if error, number of emails added if ok
*/
public function add_to_target($mailing_id, $cibles)
public function add_to_target($mailing_id)
{
// phpcs:enable
$target = array();
$j = 0;
$sql = " select rowid as id, email, firstname, lastname, plan, partner";
$sql.= " from ".MAIN_DB_PREFIX."myobject";
$sql.= " where email IS NOT NULL AND email != ''";

View File

@@ -284,14 +284,14 @@ class Product extends CommonObject
* @var int
*/
public $barcode_type;
/**
* Main Barcode type code
*
* @var string
*/
public $barcode_type_code;
/**
* Additional barcodes (Some products have different barcodes according to the country of origin of manufacture)
*
@@ -447,7 +447,7 @@ class Product extends CommonObject
$error=0;
// Clean parameters
$this->ref = dol_string_nospecial(trim($this->ref));
$this->ref = dol_sanitizeFileName(dol_string_nospecial(trim($this->ref)));
$this->label = trim($this->label);
$this->price_ttc=price2num($this->price_ttc);
$this->price=price2num($this->price);
@@ -2052,7 +2052,7 @@ class Product extends CommonObject
$sql.= " fk_price_expression, price_autogen";
$sql.= " FROM ".MAIN_DB_PREFIX."product";
if ($id) {
$sql.= " WHERE rowid = ".$this->db->escape($id);
$sql.= " WHERE rowid = ".(int) $id;
} else {
$sql.= " WHERE entity IN (".getEntity($this->element).")";
if ($ref) {

View File

@@ -515,7 +515,7 @@ $moreforfilter='';
// If the user can view user other than himself
$moreforfilter.='<div class="divsearchfield">';
$moreforfilter.='<div class="inline-block hideonsmartphone">'.$langs->trans('User'). ' </div>';
$includeonly='hierachyme';
$includeonly='hierarchyme';
if (empty($user->rights->user->user->lire)) $includeonly=array($user->id);
$moreforfilter.=$form->select_dolusers($search_usertoprocessid?$search_usertoprocessid:$usertoprocess->id, 'search_usertoprocessid', $user->rights->user->user->lire?0:0, null, 0, $includeonly, null, 0, 0, 0, '', 0, '', 'maxwidth200 marginleftonly');
$moreforfilter.='</div>';

View File

@@ -564,7 +564,7 @@ if (! empty($conf->categorie->enabled))
// If the user can view user other than himself
$moreforfilter.='<div class="divsearchfield">';
$moreforfilter.='<div class="inline-block hideonsmartphone">'.$langs->trans('User'). ' </div>';
$includeonly='hierachyme';
$includeonly='hierarchyme';
if (empty($user->rights->user->user->lire)) $includeonly=array($user->id);
$moreforfilter.=$form->select_dolusers($search_usertoprocessid?$search_usertoprocessid:$usertoprocess->id, 'search_usertoprocessid', $user->rights->user->user->lire?0:0, null, 0, $includeonly, null, 0, 0, 0, '', 0, '', 'maxwidth200');
$moreforfilter.='</div>';

View File

@@ -515,7 +515,7 @@ if (! empty($conf->categorie->enabled))
// If the user can view user other than himself
$moreforfilter.='<div class="divsearchfield">';
$moreforfilter.=$langs->trans('ProjectsWithThisUserAsContact'). ': ';
$includeonly='hierachyme';
$includeonly='hierarchyme';
if (empty($user->rights->user->user->lire)) $includeonly=array($user->id);
$moreforfilter.=$form->select_dolusers($search_project_user?$search_project_user:'', 'search_project_user', 1, '', 0, $includeonly, '', 0, 0, 0, '', 0, '', 'maxwidth200');
$moreforfilter.='</div>';

View File

@@ -393,6 +393,7 @@ class Stripe extends CommonObject
{
$metadata['dol_type'] = $object->element;
$metadata['dol_id'] = $object->id;
if (is_object($object->thirdparty) && $object->thirdparty->id > 0) $metadata['dol_thirdparty_id'] = $object->thirdparty->id;
}
$dataforintent = array(

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB