dolibarr  17.0.4
facture.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2003-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2004-2016 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
5  * Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es>
6  * Copyright (C) 2014 Florian Henry <florian.henry@open-concept.pro>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <https://www.gnu.org/licenses/>.
20  */
21 
28 // Load Dolibarr environment
29 require '../../main.inc.php';
30 require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
31 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
32 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
33 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
34 
35 // Load translation files required by the page
36 $langs->loadLangs(array('companies', 'bills', 'products', 'supplier_proposal'));
37 
38 $id = GETPOST('id', 'int');
39 $ref = GETPOST('ref', 'alpha');
40 
41 // Security check
42 $fieldvalue = (!empty($id) ? $id : (!empty($ref) ? $ref : ''));
43 $fieldtype = (!empty($ref) ? 'ref' : 'rowid');
44 $socid = '';
45 if (!empty($user->socid)) {
46  $socid = $user->socid;
47 }
48 
49 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
50 $hookmanager->initHooks(array('productstatsinvoice'));
51 
52 $showmessage = GETPOST('showmessage');
53 
54 // Load variable for pagination
55 $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
56 $sortfield = GETPOST('sortfield', 'aZ09comma');
57 $sortorder = GETPOST('sortorder', 'aZ09comma');
58 $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
59 if (empty($page) || $page == -1) {
60  $page = 0;
61 } // If $page is not defined, or '' or -1
62 $offset = $limit * $page;
63 $pageprev = $page - 1;
64 $pagenext = $page + 1;
65 if (!$sortorder) {
66  $sortorder = "DESC";
67 }
68 if (!$sortfield) {
69  $sortfield = "f.datef";
70 }
71 
72 $search_month = GETPOST('search_month', 'int');
73 $search_year = GETPOST('search_year', 'int');
74 
75 if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
76  $search_month = '';
77  $search_year = '';
78 }
79 
80 $result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype);
81 
82 
83 /*
84  * View
85  */
86 
87 $invoicestatic = new Facture($db);
88 $societestatic = new Societe($db);
89 
90 $form = new Form($db);
91 $formother = new FormOther($db);
92 
93 if ($id > 0 || !empty($ref)) {
94  $product = new Product($db);
95  $result = $product->fetch($id, $ref);
96 
97  $object = $product;
98 
99  $parameters = array('id'=>$id);
100  $reshook = $hookmanager->executeHooks('doActions', $parameters, $product, $action); // Note that $action and $object may have been modified by some hooks
101  if ($reshook < 0) {
102  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
103  }
104 
105  $title = $langs->trans('ProductServiceCard');
106  $helpurl = '';
107  $shortlabel = dol_trunc($object->label, 16);
108  if (GETPOST("type") == '0' || ($object->type == Product::TYPE_PRODUCT)) {
109  $title = $langs->trans('Product')." ".$shortlabel." - ".$langs->trans('Referers');
110  $helpurl = 'EN:Module_Products|FR:Module_Produits|ES:M&oacute;dulo_Productos';
111  }
112  if (GETPOST("type") == '1' || ($object->type == Product::TYPE_SERVICE)) {
113  $title = $langs->trans('Service')." ".$shortlabel." - ".$langs->trans('Referers');
114  $helpurl = 'EN:Module_Services_En|FR:Module_Services|ES:M&oacute;dulo_Servicios';
115  }
116 
117  llxHeader('', $title, $helpurl);
118 
119  if ($result > 0) {
120  $head = product_prepare_head($product);
121  $titre = $langs->trans("CardProduct".$product->type);
122  $picto = ($product->type == Product::TYPE_SERVICE ? 'service' : 'product');
123  print dol_get_fiche_head($head, 'referers', $titre, -1, $picto);
124 
125  $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $product, $action); // Note that $action and $object may have been modified by hook
126  print $hookmanager->resPrint;
127  if ($reshook < 0) {
128  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
129  }
130 
131  $linkback = '<a href="'.DOL_URL_ROOT.'/product/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
132 
133  $shownav = 1;
134  if ($user->socid && !in_array('product', explode(',', $conf->global->MAIN_MODULES_FOR_EXTERNAL))) {
135  $shownav = 0;
136  }
137 
138  dol_banner_tab($object, 'ref', $linkback, $shownav, 'ref');
139 
140  print '<div class="fichecenter">';
141 
142  print '<div class="underbanner clearboth"></div>';
143  print '<table class="border tableforfield" width="100%">';
144 
145  $nboflines = show_stats_for_company($product, $socid);
146 
147  print "</table>";
148 
149  print '</div>';
150  print '<div style="clear:both"></div>';
151 
152  print dol_get_fiche_end();
153 
154  if ($showmessage && $nboflines > 1) {
155  print '<span class="opacitymedium">'.$langs->trans("ClinkOnALinkOfColumn", $langs->transnoentitiesnoconv("Referers")).'</span>';
156  } elseif ($user->rights->facture->lire) {
157  $sql = "SELECT DISTINCT s.nom as name, s.rowid as socid, s.code_client,";
158  $sql .= " f.ref, f.datef, f.paye, f.type, f.fk_statut as statut, f.rowid as facid,";
159  $sql .= " d.rowid, d.total_ht as total_ht, d.qty"; // We must keep the d.rowid here to not loose record because of the distinct used to ignore duplicate line when link on societe_commerciaux is used
160  if (empty($user->rights->societe->client->voir) && !$socid) {
161  $sql .= ", sc.fk_soc, sc.fk_user ";
162  }
163  $sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
164  $sql .= ", ".MAIN_DB_PREFIX."facture as f";
165  $sql .= ", ".MAIN_DB_PREFIX."facturedet as d";
166  if (empty($user->rights->societe->client->voir) && !$socid) {
167  $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
168  }
169  $sql .= " WHERE f.fk_soc = s.rowid";
170  $sql .= " AND f.entity IN (".getEntity('invoice').")";
171  $sql .= " AND d.fk_facture = f.rowid";
172  $sql .= " AND d.fk_product = ".((int) $product->id);
173  if (!empty($search_month)) {
174  $sql .= ' AND MONTH(f.datef) IN ('.$db->sanitize($search_month).')';
175  }
176  if (!empty($search_year)) {
177  $sql .= ' AND YEAR(f.datef) IN ('.$db->sanitize($search_year).')';
178  }
179  if (empty($user->rights->societe->client->voir) && !$socid) {
180  $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
181  }
182  if ($socid) {
183  $sql .= " AND f.fk_soc = ".((int) $socid);
184  }
185  $sql .= $db->order($sortfield, $sortorder);
186 
187  // Calcul total qty and amount for global if full scan list
188  $total_ht = 0;
189  $total_qty = 0;
190 
191  // Count total nb of records
192  $totalofrecords = '';
193  if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
194  $result = $db->query($sql);
195  $totalofrecords = $db->num_rows($result);
196  }
197 
198  $sql .= $db->plimit($limit + 1, $offset);
199 
200  $result = $db->query($sql);
201  if ($result) {
202  $num = $db->num_rows($result);
203 
204  $option .= '&id='.$product->id;
205 
206  if ($limit > 0 && $limit != $conf->liste_limit) {
207  $option .= '&limit='.urlencode($limit);
208  }
209  if (!empty($search_month)) {
210  $option .= '&search_month='.urlencode($search_month);
211  }
212  if (!empty($search_year)) {
213  $option .= '&search_year='.urlencode($search_year);
214  }
215 
216  print '<form method="post" action="'.$_SERVER ['PHP_SELF'].'?id='.$product->id.'" name="search_form">'."\n";
217  print '<input type="hidden" name="token" value="'.newToken().'">';
218  if (!empty($sortfield)) {
219  print '<input type="hidden" name="sortfield" value="'.$sortfield.'"/>';
220  }
221  if (!empty($sortorder)) {
222  print '<input type="hidden" name="sortorder" value="'.$sortorder.'"/>';
223  }
224 
225  print_barre_liste($langs->trans("CustomersInvoices"), $page, $_SERVER["PHP_SELF"], $option, $sortfield, $sortorder, '', $num, $totalofrecords, '', 0, '', '', $limit, 0, 0, 1);
226 
227  if (!empty($page)) {
228  $option .= '&page='.urlencode($page);
229  }
230 
231  print '<div class="liste_titre liste_titre_bydiv centpercent">';
232  print '<div class="divsearchfield">';
233  print $langs->trans('Period').' ('.$langs->trans("DateInvoice").') - ';
234  print $langs->trans('Month').':<input class="flat" type="text" size="4" name="search_month" value="'.$search_month.'"> ';
235  print $langs->trans('Year').':'.$formother->selectyear($search_year ? $search_year : - 1, 'search_year', 1, 20, 5);
236  print '<div style="vertical-align: middle; display: inline-block">';
237  print '<input type="image" class="liste_titre" name="button_search" src="'.img_picto($langs->trans("Search"), 'search.png', '', '', 1).'" value="'.dol_escape_htmltag($langs->trans("Search")).'" title="'.dol_escape_htmltag($langs->trans("Search")).'">';
238  print '<input type="image" class="liste_titre" name="button_removefilter" src="'.img_picto($langs->trans("Search"), 'searchclear.png', '', '', 1).'" value="'.dol_escape_htmltag($langs->trans("RemoveFilter")).'" title="'.dol_escape_htmltag($langs->trans("RemoveFilter")).'">';
239  print '</div>';
240  print '</div>';
241  print '</div>';
242 
243  $i = 0;
244  print '<div class="div-table-responsive">';
245  print '<table class="tagtable liste listwithfilterbefore" width="100%">';
246  print '<tr class="liste_titre">';
247  print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "s.rowid", "", $option, '', $sortfield, $sortorder);
248  print_liste_field_titre("Company", $_SERVER["PHP_SELF"], "s.nom", "", $option, '', $sortfield, $sortorder);
249  print_liste_field_titre("CustomerCode", $_SERVER["PHP_SELF"], "s.code_client", "", $option, '', $sortfield, $sortorder);
250  print_liste_field_titre("DateInvoice", $_SERVER["PHP_SELF"], "f.datef", "", $option, 'align="center"', $sortfield, $sortorder);
251  print_liste_field_titre("Qty", $_SERVER["PHP_SELF"], "d.qty", "", $option, 'align="center"', $sortfield, $sortorder);
252  print_liste_field_titre("AmountHT", $_SERVER["PHP_SELF"], "d.total_ht", "", $option, 'align="right"', $sortfield, $sortorder);
253  print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "f.paye,f.fk_statut", "", $option, 'align="right"', $sortfield, $sortorder);
254  print "</tr>\n";
255 
256  if ($num > 0) {
257  while ($i < min($num, $limit)) {
258  $objp = $db->fetch_object($result);
259 
260  if ($objp->type == Facture::TYPE_CREDIT_NOTE) {
261  $objp->qty = -($objp->qty);
262  }
263 
264  $total_ht += $objp->total_ht;
265  $total_qty += $objp->qty;
266 
267  $invoicestatic->id = $objp->facid;
268  $invoicestatic->ref = $objp->ref;
269  $societestatic->fetch($objp->socid);
270  $paiement = $invoicestatic->getSommePaiement();
271 
272  print '<tr class="oddeven">';
273  print '<td>';
274  print $invoicestatic->getNomUrl(1);
275  print "</td>\n";
276  print '<td>'.$societestatic->getNomUrl(1).'</td>';
277  print "<td>".$objp->code_client."</td>\n";
278  print '<td class="center">';
279  print dol_print_date($db->jdate($objp->datef), 'dayhour')."</td>";
280  print '<td class="center">'.$objp->qty."</td>\n";
281  print '<td align="right">'.price($objp->total_ht)."</td>\n";
282  print '<td align="right">'.$invoicestatic->LibStatut($objp->paye, $objp->statut, 5, $paiement, $objp->type).'</td>';
283  print "</tr>\n";
284  $i++;
285  }
286  }
287  print '<tr class="liste_total">';
288  if ($num < $limit) {
289  print '<td class="left">'.$langs->trans("Total").'</td>';
290  } else {
291  print '<td class="left">'.$langs->trans("Totalforthispage").'</td>';
292  }
293  print '<td colspan="3"></td>';
294  print '<td class="center">'.$total_qty.'</td>';
295  print '<td align="right">'.price($total_ht).'</td>';
296  print '<td></td>';
297  print "</table>";
298  print '</div>';
299  print '</form>';
300  } else {
301  dol_print_error($db);
302  }
303  $db->free($result);
304  }
305  }
306 } else {
307  dol_print_error();
308 }
309 
310 // End of page
311 llxFooter();
312 $db->close();
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:56
llxFooter()
Empty footer.
Definition: wrapper.php:70
Class to manage invoices.
const TYPE_CREDIT_NOTE
Credit note invoice.
Class to manage generation of HTML components Only common components must be here.
Classe permettant la generation de composants html autre Only common components are here.
Class to manage products or services.
const TYPE_PRODUCT
Regular product.
const TYPE_SERVICE
Service.
Class to manage third parties objects (customers, suppliers, prospects...)
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='rowid', $fieldref='ref', $morehtmlref='', $moreparam='', $nodbprefix=0, $morehtmlleft='', $morehtmlstatus='', $onlybanner=0, $morehtmlright='')
Show tab footer of a card.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='')
Show tabs of a record.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_get_fiche_end($notab=0)
Return tab footer of a card.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='')
Set event messages in dol_events session object.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
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.
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
product_prepare_head($object)
Prepare array with list of tabs.
Definition: product.lib.php:35
show_stats_for_company($product, $socid)
Show stats for company.
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.