dolibarr 20.0.2
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
29require '../../main.inc.php';
30require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
31require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
32require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
33require_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$action = GETPOST('action', 'aZ');
39
40$id = GETPOSTINT('id');
41$ref = GETPOST('ref', 'alpha');
42
43// Security check
44$fieldvalue = (!empty($id) ? $id : (!empty($ref) ? $ref : ''));
45$fieldtype = (!empty($ref) ? 'ref' : 'rowid');
46$socid = '';
47if (!empty($user->socid)) {
48 $socid = $user->socid;
49}
50
51// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
52$hookmanager->initHooks(array('productstatsinvoice'));
53$extrafields = new ExtraFields($db);
54
55// Fetch optionals attributes and labels
56$extrafields->fetch_name_optionals_label('facture');
57
58$search_array_options = $extrafields->getOptionalsFromPost('facture', '', 'search_');
59
60$showmessage = GETPOST('showmessage');
61
62// Load variable for pagination
63$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
64$sortfield = GETPOST('sortfield', 'aZ09comma');
65$sortorder = GETPOST('sortorder', 'aZ09comma');
66$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
67if (empty($page) || $page == -1) {
68 $page = 0;
69} // If $page is not defined, or '' or -1
70$offset = $limit * $page;
71$pageprev = $page - 1;
72$pagenext = $page + 1;
73if (!$sortorder) {
74 $sortorder = "DESC";
75}
76if (!$sortfield) {
77 $sortfield = "f.datef";
78}
79
80$option = '';
81
82$search_date_startday = GETPOSTINT('search_date_startday');
83if (!empty($search_date_startday)) {
84 $option .= '&search_date_startday='.$search_date_startday;
85}
86$search_date_startmonth = GETPOSTINT('search_date_startmonth');
87if (!empty($search_date_startmonth)) {
88 $option .= '&search_date_startmonth='.$search_date_startmonth;
89}
90$search_date_startyear = GETPOSTINT('search_date_startyear');
91if (!empty($search_date_startyear)) {
92 $option .= '&search_date_startyear='.$search_date_startyear;
93}
94$search_date_endday = GETPOSTINT('search_date_endday');
95if (!empty($search_date_endday)) {
96 $option .= '&search_date_endday='.$search_date_endday;
97}
98$search_date_endmonth = GETPOSTINT('search_date_endmonth');
99if (!empty($search_date_endmonth)) {
100 $option .= '&search_date_endmonth='.$search_date_endmonth;
101}
102$search_date_endyear = GETPOSTINT('search_date_endyear');
103if (!empty($search_date_endyear)) {
104 $option .= '&search_date_endyear='.$search_date_endyear;
105}
106$search_date_start = dol_mktime(0, 0, 0, $search_date_startmonth, $search_date_startday, $search_date_startyear); // Use tzserver
107$search_date_end = dol_mktime(23, 59, 59, $search_date_endmonth, $search_date_endday, $search_date_endyear);
108
109if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
110 $search_date_startday = '';
111 $search_date_startmonth = '';
112 $search_date_startyear = '';
113 $search_date_endday = '';
114 $search_date_endmonth = '';
115 $search_date_endyear = '';
116 $search_date_start = '';
117 $search_date_end = '';
118}
119
120$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype);
121
122
123/*
124 * View
125 */
126
127$invoicestatic = new Facture($db);
128$societestatic = new Societe($db);
129
130$form = new Form($db);
131$formother = new FormOther($db);
132
133if ($id > 0 || !empty($ref)) {
134 $product = new Product($db);
135 $result = $product->fetch($id, $ref);
136
137 $object = $product;
138
139 $parameters = array('id' => $id);
140 $reshook = $hookmanager->executeHooks('doActions', $parameters, $product, $action); // Note that $action and $object may have been modified by some hooks
141 if ($reshook < 0) {
142 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
143 }
144
145 $title = $langs->trans('ProductServiceCard');
146 $helpurl = '';
147 $shortlabel = dol_trunc($object->label, 16);
148 if (GETPOST("type") == '0' || ($object->type == Product::TYPE_PRODUCT)) {
149 $title = $langs->trans('Product')." ".$shortlabel." - ".$langs->trans('Referers');
150 $helpurl = 'EN:Module_Products|FR:Module_Produits|ES:M&oacute;dulo_Productos';
151 }
152 if (GETPOST("type") == '1' || ($object->type == Product::TYPE_SERVICE)) {
153 $title = $langs->trans('Service')." ".$shortlabel." - ".$langs->trans('Referers');
154 $helpurl = 'EN:Module_Services_En|FR:Module_Services|ES:M&oacute;dulo_Servicios';
155 }
156
157 llxHeader('', $title, $helpurl, '', 0, 0, '', '', '', 'mod-product page-stats_facture');
158
159 if ($result > 0) {
160 $head = product_prepare_head($product);
161 $titre = $langs->trans("CardProduct".$product->type);
162 $picto = ($product->type == Product::TYPE_SERVICE ? 'service' : 'product');
163 print dol_get_fiche_head($head, 'referers', $titre, -1, $picto);
164
165 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $product, $action); // Note that $action and $object may have been modified by hook
166 print $hookmanager->resPrint;
167 if ($reshook < 0) {
168 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
169 }
170
171 $linkback = '<a href="'.DOL_URL_ROOT.'/product/list.php?restore_lastsearch_values=1&type='.$object->type.'">'.$langs->trans("BackToList").'</a>';
172
173 $shownav = 1;
174 if ($user->socid && !in_array('product', explode(',', getDolGlobalString('MAIN_MODULES_FOR_EXTERNAL')))) {
175 $shownav = 0;
176 }
177
178 dol_banner_tab($object, 'ref', $linkback, $shownav, 'ref');
179
180 print '<div class="fichecenter">';
181
182 print '<div class="underbanner clearboth"></div>';
183 print '<table class="border tableforfield centpercent">';
184
185 $nboflines = show_stats_for_company($product, $socid);
186
187 print "</table>";
188
189 print '</div>';
190 print '<div class="clearboth"></div>';
191
192 print dol_get_fiche_end();
193
194 if ($showmessage && $nboflines > 1) {
195 print '<span class="opacitymedium">'.$langs->trans("ClinkOnALinkOfColumn", $langs->transnoentitiesnoconv("Referers")).'</span>';
196 } elseif ($user->hasRight('facture', 'lire')) {
197 $sql = "SELECT DISTINCT s.nom as name, s.rowid as socid, s.code_client,";
198 $sql .= " f.ref, f.datef, f.paye, f.type, f.fk_statut as statut, f.rowid as facid,";
199 $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
200 if (!$user->hasRight('societe', 'client', 'voir')) {
201 $sql .= ", sc.fk_soc, sc.fk_user ";
202 }
203 // Add fields from extrafields
204 if (!empty($extrafields->attributes['facture']['label'])) {
205 foreach ($extrafields->attributes['facture']['label'] as $key => $val) {
206 $sql .= ($extrafields->attributes['facture']['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : '');
207 }
208 }
209 // Add fields from hooks
210 $parameters = array();
211 $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
212 $sql .= $hookmanager->resPrint;
213 $sql = preg_replace('/,\s*$/', '', $sql);
214
215 $sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
216 $sql .= ", ".MAIN_DB_PREFIX."facture as f";
217 if (isset($extrafields->attributes['facture']['label']) && is_array($extrafields->attributes['facture']['label']) && count($extrafields->attributes['facture']['label'])) {
218 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.'facture'."_extrafields as ef on (f.rowid = ef.fk_object)";
219 }
220 $sql .= ", ".MAIN_DB_PREFIX."facturedet as d";
221 if (!$user->hasRight('societe', 'client', 'voir')) {
222 $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
223 }
224 // Add table from hooks
225 $parameters = array();
226 $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook
227 $sql .= $hookmanager->resPrint;
228
229 $sql .= " WHERE f.fk_soc = s.rowid";
230 $sql .= " AND f.entity IN (".getEntity('invoice').")";
231 $sql .= " AND d.fk_facture = f.rowid";
232 $sql .= " AND d.fk_product = ".((int) $product->id);
233 if ($search_date_start) {
234 $sql .= " AND f.datef >= '".$db->idate($search_date_start)."'";
235 }
236 if ($search_date_end) {
237 $sql .= " AND f.datef <= '".$db->idate($search_date_end)."'";
238 }
239 if (!$user->hasRight('societe', 'client', 'voir')) {
240 $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
241 }
242 if ($socid) {
243 $sql .= " AND f.fk_soc = ".((int) $socid);
244 }
245 // Add where from extra fields
246 $extrafieldsobjectkey = 'facture';
247 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
248 // Add where from hooks
249 $parameters = array();
250 $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
251 $sql .= $hookmanager->resPrint;
252
253 // Add HAVING from hooks
254 $parameters = array();
255 $reshook = $hookmanager->executeHooks('printFieldListHaving', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
256 $sql .= empty($hookmanager->resPrint) ? "" : " HAVING 1=1 ".$hookmanager->resPrint;
257
258 $sql .= $db->order($sortfield, $sortorder);
259
260 // Calcul total qty and amount for global if full scan list
261 $total_ht = 0;
262 $total_qty = 0;
263
264 // Count total nb of records
265 $totalofrecords = '';
266 if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
267 $result = $db->query($sql);
268 $totalofrecords = $db->num_rows($result);
269 }
270
271 $sql .= $db->plimit($limit + 1, $offset);
272
273 $result = $db->query($sql);
274 if ($result) {
275 $num = $db->num_rows($result);
276
277 $option .= '&id='.$product->id;
278
279 if ($limit > 0 && $limit != $conf->liste_limit) {
280 $option .= '&limit='.((int) $limit);
281 }
282
283 // Add $param from extra fields
284 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
285 // Add $param from hooks
286 $parameters = array('param' => &$param);
287 $reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
288 $option .= $hookmanager->resPrint;
289
290 print '<form method="post" action="'.$_SERVER ['PHP_SELF'].'?id='.$product->id.'" name="search_form">'."\n";
291 print '<input type="hidden" name="token" value="'.newToken().'">';
292 if (!empty($sortfield)) {
293 print '<input type="hidden" name="sortfield" value="'.$sortfield.'"/>';
294 }
295 if (!empty($sortorder)) {
296 print '<input type="hidden" name="sortorder" value="'.$sortorder.'"/>';
297 }
298
299 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
300 print_barre_liste($langs->trans("CustomersInvoices"), $page, $_SERVER["PHP_SELF"], $option, $sortfield, $sortorder, '', $num, $totalofrecords, '', 0, '', '', $limit, 0, 0, 1);
301
302 if (!empty($page)) {
303 $option .= '&page='.urlencode((string) ($page));
304 }
305
306 print '<div class="liste_titre liste_titre_bydiv centpercent">';
307 print '<div class="divsearchfield">';
308 print $langs->trans('Period').' ('.$langs->trans("DateInvoice").') - ';
309 print $form->selectDate($search_date_start ? $search_date_start : -1, 'search_date_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
310 print $form->selectDate($search_date_end ? $search_date_end : -1, 'search_date_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
311 $parameters = array();
312 $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
313 print $hookmanager->resPrint;
314
315 print '<div style="vertical-align: middle; display: inline-block">';
316 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")).'">';
317 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")).'">';
318 print '</div>';
319 print '</div>';
320 print '</div>';
321
322 $i = 0;
323 print '<div class="div-table-responsive">';
324 print '<table class="tagtable liste listwithfilterbefore" width="100%">';
325 print '<tr class="liste_titre">';
326 print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "s.rowid", "", $option, '', $sortfield, $sortorder);
327 print_liste_field_titre("Company", $_SERVER["PHP_SELF"], "s.nom", "", $option, '', $sortfield, $sortorder);
328 print_liste_field_titre("CustomerCode", $_SERVER["PHP_SELF"], "s.code_client", "", $option, '', $sortfield, $sortorder);
329 print_liste_field_titre("DateInvoice", $_SERVER["PHP_SELF"], "f.datef", "", $option, 'align="center"', $sortfield, $sortorder);
330 print_liste_field_titre("Qty", $_SERVER["PHP_SELF"], "d.qty", "", $option, 'align="center"', $sortfield, $sortorder);
331 print_liste_field_titre("AmountHT", $_SERVER["PHP_SELF"], "d.total_ht", "", $option, 'align="right"', $sortfield, $sortorder);
332 print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "f.paye,f.fk_statut", "", $option, 'align="right"', $sortfield, $sortorder);
333 // Hook fields
334 $parameters = array('param' => $option, 'sortfield' => $sortfield, 'sortorder' => $sortorder);
335 $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
336 print $hookmanager->resPrint;
337 print "</tr>\n";
338
339 if ($num > 0) {
340 while ($i < min($num, $limit)) {
341 $objp = $db->fetch_object($result);
342
343 if ($objp->type == Facture::TYPE_CREDIT_NOTE) {
344 $objp->qty = -($objp->qty);
345 }
346
347 $total_ht += $objp->total_ht;
348 $total_qty += $objp->qty;
349
350 $invoicestatic->id = $objp->facid;
351 $invoicestatic->ref = $objp->ref;
352 $societestatic->fetch($objp->socid);
353 $paiement = $invoicestatic->getSommePaiement();
354
355 print '<tr class="oddeven">';
356 print '<td>';
357 print $invoicestatic->getNomUrl(1);
358 print "</td>\n";
359 print '<td>'.$societestatic->getNomUrl(1).'</td>';
360 print "<td>".$objp->code_client."</td>\n";
361 print '<td class="center">';
362 print dol_print_date($db->jdate($objp->datef), 'dayhour')."</td>";
363 print '<td class="center">'.$objp->qty."</td>\n";
364 print '<td class="right">'.price($objp->total_ht)."</td>\n";
365 print '<td class="right">'.$invoicestatic->LibStatut($objp->paye, $objp->statut, 5, $paiement, $objp->type).'</td>';
366 // Fields from hook
367 $parameters = array();
368 $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
369 print $hookmanager->resPrint;
370 print "</tr>\n";
371 $i++;
372 }
373 }
374 print '<tr class="liste_total">';
375 if ($num < $limit && empty($offset)) {
376 print '<td>'.$langs->trans("Total").'</td>';
377 } else {
378 print '<td>'.$form->textwithpicto($langs->trans("Total"), $langs->trans("Totalforthispage")).'</td>';
379 }
380 print '<td colspan="3"></td>';
381 print '<td class="center">'.$total_qty.'</td>';
382 print '<td class="right">'.price($total_ht).'</td>';
383 print '<td></td>';
384 print "</table>";
385 print '</div>';
386 print '</form>';
387 } else {
388 dol_print_error($db);
389 }
390 $db->free($result);
391 }
392 }
393} else {
395}
396
397// End of page
398llxFooter();
399$db->close();
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader()
Empty header.
Definition wrapper.php:55
llxFooter()
Empty footer.
Definition wrapper.php:69
Class to manage standard extra fields.
Class to manage invoices.
const TYPE_CREDIT_NOTE
Credit note invoice.
Class to manage generation of HTML components Only common components must be here.
Class 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...)
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $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.
print_barre_liste($title, $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.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
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.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
product_prepare_head($object)
Prepare array with list of tabs.
show_stats_for_company($product, $socid)
Show stats for a product.
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.