dolibarr  13.0.2
agentMargins.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2012-2013 Christophe Battarel <christophe.battarel@altairis.fr>
3  * Copyright (C) 2014 Ferran Marcet <fmarcet@2byte.es>
4  * Copyright (C) 2015 Marcos GarcĂ­a <marcosgdf@gmail.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <https://www.gnu.org/licenses/>.
18  */
19 
26 require '../main.inc.php';
27 require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
28 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
29 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
30 require_once DOL_DOCUMENT_ROOT.'/margin/lib/margins.lib.php';
31 
32 // Load translation files required by the page
33 $langs->loadLangs(array('companies', 'bills', 'products', 'margins'));
34 
35 $mesg = '';
36 
37 // Load variable for pagination
38 $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
39 $sortfield = GETPOST('sortfield', 'aZ09comma');
40 $sortorder = GETPOST('sortorder', 'aZ09comma');
41 $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
42 if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
43 $offset = $limit * $page;
44 $pageprev = $page - 1;
45 $pagenext = $page + 1;
46 if (!$sortorder) $sortorder = "ASC";
47 if (!$sortfield)
48 {
49  if ($agentid > 0)
50  $sortfield = "s.nom";
51  else $sortfield = "u.lastname";
52 }
53 
54 $startdate = $enddate = '';
55 
56 $startdateday = GETPOST('startdateday', 'int');
57 $startdatemonth = GETPOST('startdatemonth', 'int');
58 $startdateyear = GETPOST('startdateyear', 'int');
59 $enddateday = GETPOST('enddateday', 'int');
60 $enddatemonth = GETPOST('enddatemonth', 'int');
61 $enddateyear = GETPOST('enddateyear', 'int');
62 
63 if (!empty($startdatemonth))
64  $startdate = dol_mktime(0, 0, 0, $startdatemonth, $startdateday, $startdateyear);
65 if (!empty($enddatemonth))
66  $enddate = dol_mktime(23, 59, 59, $enddatemonth, $enddateday, $enddateyear);
67 
68 // Security check
69 if ($user->rights->margins->read->all) {
70  $agentid = GETPOST('agentid', 'int');
71 } else {
72  $agentid = $user->id;
73 }
74 $result = restrictedArea($user, 'margins');
75 
76 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
77 $object = new User($db);
78 $hookmanager->initHooks(array('marginagentlist'));
79 
80 /*
81  * Actions
82  */
83 
84 // None
85 
86 
87 
88 /*
89  * View
90  */
91 
92 $userstatic = new User($db);
93 $companystatic = new Societe($db);
94 $invoicestatic = new Facture($db);
95 
96 $form = new Form($db);
97 
98 llxHeader('', $langs->trans("Margins").' - '.$langs->trans("Agents"));
99 
100 $text = $langs->trans("Margins");
101 //print load_fiche_titre($text);
102 
103 // Show tabs
104 $head = marges_prepare_head($user);
105 $titre = $langs->trans("Margins");
106 $picto = 'margin';
107 
108 print '<form method="post" name="sel" action="'.$_SERVER['PHP_SELF'].'">';
109 print '<input type="hidden" name="token" value="'.newToken().'">';
110 
111 print dol_get_fiche_head($head, 'agentMargins', $titre, 0, $picto);
112 
113 print '<table class="border centpercent">';
114 
115 print '<tr><td class="titlefield">'.$langs->trans('ContactOfInvoice').'</td>';
116 print '<td class="maxwidthonsmartphone" colspan="4">';
117 print img_picto('', 'user').$form->select_dolusers($agentid, 'agentid', 1, '', $user->rights->margins->read->all ? 0 : 1, '', '', 0, 0, 0, '', 0, '', 'maxwidth300');
118 print '</td></tr>';
119 
120 // Start date
121 print '<td>'.$langs->trans('DateStart').' ('.$langs->trans("DateValidation").')</td>';
122 print '<td>';
123 print $form->selectDate($startdate, 'startdate', '', '', 1, "sel", 1, 1);
124 print '</td>';
125 print '<td>'.$langs->trans('DateEnd').' ('.$langs->trans("DateValidation").')</td>';
126 print '<td>';
127 print $form->selectDate($enddate, 'enddate', '', '', 1, "sel", 1, 1);
128 print '</td>';
129 print '<td style="text-align: center;">';
130 print '<input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans('Refresh')).'" />';
131 print '</td></tr>';
132 print "</table>";
133 
135 
136 print '</form>';
137 
138 $invoice_status_except_list = array(Facture::STATUS_DRAFT, Facture::STATUS_ABANDONED);
139 
140 $sql = "SELECT";
141 $sql .= " s.rowid as socid, s.nom as name, s.code_client, s.client,";
142 $sql .= " u.rowid as agent, u.login, u.lastname, u.firstname,";
143 $sql .= " sum(d.total_ht) as selling_price,";
144 // Note: qty and buy_price_ht is always positive (if not your database may be corrupted, you can update this)
145 $sql .= " sum(".$db->ifsql('d.total_ht < 0', 'd.qty * d.buy_price_ht * -1 * (d.situation_percent / 100)', 'd.qty * d.buy_price_ht * (d.situation_percent / 100)').") as buying_price,";
146 $sql .= " sum(".$db->ifsql('d.total_ht < 0', '-1 * (abs(d.total_ht) - (d.buy_price_ht * d.qty * (d.situation_percent / 100)))', 'd.total_ht - (d.buy_price_ht * d.qty * (d.situation_percent / 100))').") as marge";
147 $sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
148 $sql .= ", ".MAIN_DB_PREFIX."facture as f";
149 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."element_contact e ON e.element_id = f.rowid and e.statut = 4 and e.fk_c_type_contact = ".(empty($conf->global->AGENT_CONTACT_TYPE) ?-1 : $conf->global->AGENT_CONTACT_TYPE);
150 $sql .= ", ".MAIN_DB_PREFIX."facturedet as d";
151 $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
152 $sql .= ", ".MAIN_DB_PREFIX."user as u";
153 $sql .= " WHERE f.fk_soc = s.rowid";
154 $sql .= ' AND f.entity IN ('.getEntity('invoice').')';
155 $sql .= " AND sc.fk_soc = f.fk_soc";
156 $sql .= " AND (d.product_type = 0 OR d.product_type = 1)";
157 if (!empty($conf->global->AGENT_CONTACT_TYPE))
158  $sql .= " AND ((e.fk_socpeople IS NULL AND sc.fk_user = u.rowid) OR (e.fk_socpeople IS NOT NULL AND e.fk_socpeople = u.rowid))";
159 else $sql .= " AND sc.fk_user = u.rowid";
160 $sql .= " AND f.fk_statut NOT IN (".implode(', ', $invoice_status_except_list).")";
161 $sql .= ' AND s.entity IN ('.getEntity('societe').')';
162 $sql .= " AND d.fk_facture = f.rowid";
163 if ($agentid > 0) {
164  if (!empty($conf->global->AGENT_CONTACT_TYPE))
165  $sql .= " AND ((e.fk_socpeople IS NULL AND sc.fk_user = ".$agentid.") OR (e.fk_socpeople IS NOT NULL AND e.fk_socpeople = ".$agentid."))";
166  else $sql .= " AND sc.fk_user = ".$agentid;
167 }
168 if (!empty($startdate))
169  $sql .= " AND f.datef >= '".$db->idate($startdate)."'";
170 if (!empty($enddate))
171  $sql .= " AND f.datef <= '".$db->idate($enddate)."'";
172 $sql .= " AND d.buy_price_ht IS NOT NULL";
173 if (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1) $sql .= " AND d.buy_price_ht <> 0";
174 //if ($agentid > 0) $sql.= " GROUP BY s.rowid, s.nom, s.code_client, s.client, u.rowid, u.login, u.lastname, u.firstname";
175 //else $sql.= " GROUP BY u.rowid, u.login, u.lastname, u.firstname";
176 $sql .= " GROUP BY s.rowid, s.nom, s.code_client, s.client, u.rowid, u.login, u.lastname, u.firstname";
177 $sql .= $db->order($sortfield, $sortorder);
178 // TODO: calculate total to display then restore pagination
179 //$sql.= $db->plimit($conf->liste_limit +1, $offset);
180 
181 
182 print '<br>';
183 print img_info('').' '.$langs->trans("MarginPerSaleRepresentativeWarning").'<br>';
184 
185 $param = '';
186 if (!empty($agentid)) $param .= "&amp;agentid=".urlencode($agentid);
187 if (!empty($startdateday)) $param .= "&amp;startdateday=".urlencode($startdateday);
188 if (!empty($startdatemonth)) $param .= "&amp;startdatemonth=".urlencode($startdatemonth);
189 if (!empty($startdateyear)) $param .= "&amp;startdateyear=".urlencode($startdateyear);
190 if (!empty($enddateday)) $param .= "&amp;enddateday=".urlencode($enddateday);
191 if (!empty($enddatemonth)) $param .= "&amp;enddatemonth=".urlencode($enddatemonth);
192 if (!empty($enddateyear)) $param .= "&amp;enddateyear=".urlencode($enddateyear);
193 
194 
195 dol_syslog('margin::agentMargins.php', LOG_DEBUG);
196 $result = $db->query($sql);
197 if ($result)
198 {
199  $num = $db->num_rows($result);
200 
201  print '<br>';
202  print_barre_liste($langs->trans("MarginDetails"), $page, $_SERVER["PHP_SELF"], "", $sortfield, $sortorder, '', $num, $num, '', 0, '', '', 0, 1);
203 
204  if ($conf->global->MARGIN_TYPE == "1")
205  $labelcostprice = 'BuyingPrice';
206  else // value is 'costprice' or 'pmp'
207  $labelcostprice = 'CostPrice';
208 
209  $moreforfilter = '';
210 
211  $i = 0;
212  print '<div class="div-table-responsive">';
213  print '<table class="tagtable liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
214 
215  print '<tr class="liste_titre">';
216  if ($agentid > 0)
217  print_liste_field_titre("Customer", $_SERVER["PHP_SELF"], "s.nom", "", $param, '', $sortfield, $sortorder);
218  else print_liste_field_titre("SalesRepresentative", $_SERVER["PHP_SELF"], "u.lastname", "", $param, '', $sortfield, $sortorder);
219 
220  print_liste_field_titre("SellingPrice", $_SERVER["PHP_SELF"], "selling_price", "", $param, '', $sortfield, $sortorder, 'right ');
221  print_liste_field_titre($labelcostprice, $_SERVER["PHP_SELF"], "buying_price", "", $param, '', $sortfield, $sortorder, 'right ');
222  print_liste_field_titre("Margin", $_SERVER["PHP_SELF"], "marge", "", $param, '', $sortfield, $sortorder, 'right ');
223  if (!empty($conf->global->DISPLAY_MARGIN_RATES))
224  print_liste_field_titre("MarginRate", $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'right ');
225  if (!empty($conf->global->DISPLAY_MARK_RATES))
226  print_liste_field_titre("MarkRate", $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'right ');
227  print "</tr>\n";
228 
229  if ($num > 0)
230  {
231  $group_list = array();
232  while ($objp = $db->fetch_object($result)) {
233  if ($agentid > 0) {
234  $group_id = $objp->socid;
235  } else {
236  $group_id = $objp->agent;
237  }
238 
239  if (!isset($group_list[$group_id])) {
240  if ($agentid > 0) {
241  $group_name = $objp->name;
242  $companystatic->id = $objp->socid;
243  $companystatic->name = $objp->name;
244  $companystatic->client = $objp->client;
245  $group_htmlname = $companystatic->getNomUrl(1, 'customer');
246  } else {
247  $group_name = $objp->lastname;
248  $userstatic->fetch($objp->agent);
249  $group_htmlname = $userstatic->getFullName($langs, 0, 0, 0);
250  }
251  $group_list[$group_id] = array('name' => $group_name, 'htmlname' => $group_htmlname, 'selling_price' => 0, 'buying_price' => 0, 'marge' => 0);
252  }
253 
254  $seller_nb = 1;
255  if ($objp->socid > 0) {
256  // sql nb sellers
257  $sql_seller = "SELECT COUNT(sc.rowid) as nb";
258  $sql_seller .= " FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc";
259  $sql_seller .= " WHERE sc.fk_soc = ".$objp->socid;
260  $sql_seller .= " LIMIT 1";
261 
262  $resql_seller = $db->query($sql_seller);
263  if (!$resql_seller) {
264  dol_print_error($db);
265  } else {
266  if ($obj_seller = $db->fetch_object($resql_seller)) {
267  if ($obj_seller->nb > 0) {
268  $seller_nb = $obj_seller->nb;
269  }
270  }
271  }
272  }
273 
274  $group_list[$group_id]['selling_price'] += $objp->selling_price / $seller_nb;
275  $group_list[$group_id]['buying_price'] += $objp->buying_price / $seller_nb;
276  $group_list[$group_id]['marge'] += $objp->marge / $seller_nb;
277  }
278 
279  // sort group array by sortfield
280  if ($sortfield == 'u.lastname' || $sortfield == 's.nom') {
281  $sortfield = 'name';
282  }
283  $group_list = dol_sort_array($group_list, $sortfield, $sortorder);
284 
285  foreach ($group_list as $group_id => $group_array) {
286  $pa = $group_array['buying_price'];
287  $pv = $group_array['selling_price'];
288  $marge = $group_array['marge'];
289 
290  $marginRate = ($pa != 0) ? (100 * $marge / $pa) : '';
291  $markRate = ($pv != 0) ? (100 * $marge / $pv) : '';
292 
293  print '<tr class="oddeven">';
294  print "<td>".$group_array['htmlname']."</td>\n";
295  print "<td class=\"right\">".price(price2num($pv, 'MT'))."</td>\n";
296  print "<td class=\"right\">".price(price2num($pa, 'MT'))."</td>\n";
297  print "<td class=\"right\">".price(price2num($marge, 'MT'))."</td>\n";
298  if (!empty($conf->global->DISPLAY_MARGIN_RATES))
299  print "<td class=\"right\">".(($marginRate === '') ? 'n/a' : price(price2num($marginRate, 'MT'))."%")."</td>\n";
300  if (!empty($conf->global->DISPLAY_MARK_RATES))
301  print "<td class=\"right\">".(($markRate === '') ? 'n/a' : price(price2num($markRate, 'MT'))."%")."</td>\n";
302  print "</tr>\n";
303  }
304  }
305  print "</table>";
306  print '</div>';
307 } else {
308  dol_print_error($db);
309 }
310 $db->free($result);
311 
312 // End of page
313 llxFooter();
314 $db->close();
GETPOST($paramname, $check= 'alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm= 'auto', $check=1)
Return a timestamp date built from detailed informations (by default a local PHP server timestamp) Re...
Class to manage Dolibarr users.
Definition: user.class.php:44
price($amount, $form=0, $outlangs= '', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code= '')
Function to format a value into an amount for visual output Function used into PDF and HTML pages...
llxHeader()
Empty header.
Definition: wrapper.php:45
print_barre_liste($titre, $page, $file, $options= '', $sortfield= '', $sortorder= '', $morehtmlcenter= '', $num=-1, $totalnboflines= '', $picto= 'generic', $pictoisfullpath=0, $morehtmlright= '', $morecss= '', $limit=-1, $hideselectlimit=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow= '')
Print a title with navigation controls for pagination.
Class to manage generation of HTML components Only common components must be here.
marges_prepare_head()
Return array of tabs to used on pages for third parties cards.
Definition: margins.lib.php:59
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname.
Class to manage third parties objects (customers, suppliers, prospects...)
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
price2num($amount, $rounding= '', $option=0)
Function that return a number with universal decimal format (decimal separator is &#39;...
img_picto($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt= '', $morecss= '', $marginleftonlyshort=2)
Show picto whatever it&#39;s its name (generic function)
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename= '', $restricttologhandler= '', $logcontext=null)
Write log message into outputs.
const STATUS_DRAFT
Draft status.
restrictedArea($user, $features, $objectid=0, $tableandshare= '', $feature2= '', $dbt_keyfield= 'fk_soc', $dbt_select= 'rowid', $isdraft=0)
Check permissions of a user to show a page and an object.
const STATUS_ABANDONED
Classified abandoned and no payment done.
print $_SERVER["PHP_SELF"]
Edit parameters.
dol_sort_array(&$array, $index, $order= 'asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by second index function, which produces ascending (default) or descending output...
dol_get_fiche_head($links=array(), $active= '', $title= '', $notab=0, $picto= '', $pictoisfullpath=0, $morehtmlright= '', $morecss= '', $limittoshow=0, $moretabssuffix= '')
Show tabs of a record.
print
Draft customers invoices.
Definition: index.php:89
dol_print_error($db= '', $error= '', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_info($titlealt= 'default')
Show info logo.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
Class to manage invoices.
llxFooter()
Empty footer.
Definition: wrapper.php:59