dolibarr 19.0.3
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$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 = '';
45if (!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$extrafields = new ExtraFields($db);
52
53// Fetch optionals attributes and labels
54$extrafields->fetch_name_optionals_label('facture');
55
56$search_array_options = $extrafields->getOptionalsFromPost('facture', '', 'search_');
57
58$showmessage = GETPOST('showmessage');
59
60// Load variable for pagination
61$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
62$sortfield = GETPOST('sortfield', 'aZ09comma');
63$sortorder = GETPOST('sortorder', 'aZ09comma');
64$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
65if (empty($page) || $page == -1) {
66 $page = 0;
67} // If $page is not defined, or '' or -1
68$offset = $limit * $page;
69$pageprev = $page - 1;
70$pagenext = $page + 1;
71if (!$sortorder) {
72 $sortorder = "DESC";
73}
74if (!$sortfield) {
75 $sortfield = "f.datef";
76}
77
78$search_date_startday = GETPOSTINT('search_date_startday');
79if (!empty($search_date_startday)) {
80 $option .= '&search_date_startday='.$search_date_startday;
81}
82$search_date_startmonth = GETPOSTINT('search_date_startmonth');
83if (!empty($search_date_startmonth)) {
84 $option .= '&search_date_startmonth='.$search_date_startmonth;
85}
86$search_date_startyear = GETPOSTINT('search_date_startyear');
87if (!empty($search_date_startyear)) {
88 $option .= '&search_date_startyear='.$search_date_startyear;
89}
90$search_date_endday = GETPOSTINT('search_date_endday');
91if (!empty($search_date_endday)) {
92 $option .= '&search_date_endday='.$search_date_endday;
93}
94$search_date_endmonth = GETPOSTINT('search_date_endmonth');
95if (!empty($search_date_endmonth)) {
96 $option .= '&search_date_endmonth='.$search_date_endmonth;
97}
98$search_date_endyear = GETPOSTINT('search_date_endyear');
99if (!empty($search_date_endyear)) {
100 $option .= '&search_date_endyear='.$search_date_endyear;
101}
102$search_date_start = dol_mktime(0, 0, 0, $search_date_startmonth, $search_date_startday, $search_date_startyear); // Use tzserver
103$search_date_end = dol_mktime(23, 59, 59, $search_date_endmonth, $search_date_endday, $search_date_endyear);
104
105if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
106 $search_date_startday = '';
107 $search_date_startmonth = '';
108 $search_date_startyear = '';
109 $search_date_endday = '';
110 $search_date_endmonth = '';
111 $search_date_endyear = '';
112 $search_date_start = '';
113 $search_date_end = '';
114}
115
116$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype);
117
118
119/*
120 * View
121 */
122
123$invoicestatic = new Facture($db);
124$societestatic = new Societe($db);
125
126$form = new Form($db);
127$formother = new FormOther($db);
128
129if ($id > 0 || !empty($ref)) {
130 $product = new Product($db);
131 $result = $product->fetch($id, $ref);
132
133 $object = $product;
134
135 $parameters = array('id'=>$id);
136 $reshook = $hookmanager->executeHooks('doActions', $parameters, $product, $action); // Note that $action and $object may have been modified by some hooks
137 if ($reshook < 0) {
138 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
139 }
140
141 $title = $langs->trans('ProductServiceCard');
142 $helpurl = '';
143 $shortlabel = dol_trunc($object->label, 16);
144 if (GETPOST("type") == '0' || ($object->type == Product::TYPE_PRODUCT)) {
145 $title = $langs->trans('Product')." ".$shortlabel." - ".$langs->trans('Referers');
146 $helpurl = 'EN:Module_Products|FR:Module_Produits|ES:M&oacute;dulo_Productos';
147 }
148 if (GETPOST("type") == '1' || ($object->type == Product::TYPE_SERVICE)) {
149 $title = $langs->trans('Service')." ".$shortlabel." - ".$langs->trans('Referers');
150 $helpurl = 'EN:Module_Services_En|FR:Module_Services|ES:M&oacute;dulo_Servicios';
151 }
152
153 llxHeader('', $title, $helpurl);
154
155 if ($result > 0) {
156 $head = product_prepare_head($product);
157 $titre = $langs->trans("CardProduct".$product->type);
158 $picto = ($product->type == Product::TYPE_SERVICE ? 'service' : 'product');
159 print dol_get_fiche_head($head, 'referers', $titre, -1, $picto);
160
161 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $product, $action); // Note that $action and $object may have been modified by hook
162 print $hookmanager->resPrint;
163 if ($reshook < 0) {
164 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
165 }
166
167 $linkback = '<a href="'.DOL_URL_ROOT.'/product/list.php?restore_lastsearch_values=1&type='.$object->type.'">'.$langs->trans("BackToList").'</a>';
168
169 $shownav = 1;
170 if ($user->socid && !in_array('product', explode(',', getDolGlobalString('MAIN_MODULES_FOR_EXTERNAL')))) {
171 $shownav = 0;
172 }
173
174 dol_banner_tab($object, 'ref', $linkback, $shownav, 'ref');
175
176 print '<div class="fichecenter">';
177
178 print '<div class="underbanner clearboth"></div>';
179 print '<table class="border tableforfield" width="100%">';
180
181 $nboflines = show_stats_for_company($product, $socid);
182
183 print "</table>";
184
185 print '</div>';
186 print '<div class="clearboth"></div>';
187
188 print dol_get_fiche_end();
189
190 if ($showmessage && $nboflines > 1) {
191 print '<span class="opacitymedium">'.$langs->trans("ClinkOnALinkOfColumn", $langs->transnoentitiesnoconv("Referers")).'</span>';
192 } elseif ($user->hasRight('facture', 'lire')) {
193 $sql = "SELECT DISTINCT s.nom as name, s.rowid as socid, s.code_client,";
194 $sql .= " f.ref, f.datef, f.paye, f.type, f.fk_statut as statut, f.rowid as facid,";
195 $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
196 if (!$user->hasRight('societe', 'client', 'voir') && !$socid) {
197 $sql .= ", sc.fk_soc, sc.fk_user ";
198 }
199 // Add fields from extrafields
200 if (!empty($extrafields->attributes['facture']['label'])) {
201 foreach ($extrafields->attributes['facture']['label'] as $key => $val) {
202 $sql .= ($extrafields->attributes['facture']['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : '');
203 }
204 }
205 // Add fields from hooks
206 $parameters = array();
207 $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
208 $sql .= $hookmanager->resPrint;
209 $sql = preg_replace('/,\s*$/', '', $sql);
210
211 $sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
212 $sql .= ", ".MAIN_DB_PREFIX."facture as f";
213 if (isset($extrafields->attributes['facture']['label']) && is_array($extrafields->attributes['facture']['label']) && count($extrafields->attributes['facture']['label'])) {
214 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.'facture'."_extrafields as ef on (f.rowid = ef.fk_object)";
215 }
216 $sql .= ", ".MAIN_DB_PREFIX."facturedet as d";
217 if (!$user->hasRight('societe', 'client', 'voir') && !$socid) {
218 $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
219 }
220 // Add table from hooks
221 $parameters = array();
222 $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook
223 $sql .= $hookmanager->resPrint;
224
225 $sql .= " WHERE f.fk_soc = s.rowid";
226 $sql .= " AND f.entity IN (".getEntity('invoice').")";
227 $sql .= " AND d.fk_facture = f.rowid";
228 $sql .= " AND d.fk_product = ".((int) $product->id);
229 if ($search_date_start) {
230 $sql .= " AND f.datef >= '".$db->idate($search_date_start)."'";
231 }
232 if ($search_date_end) {
233 $sql .= " AND f.datef <= '".$db->idate($search_date_end)."'";
234 }
235 if (!$user->hasRight('societe', 'client', 'voir') && !$socid) {
236 $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
237 }
238 if ($socid) {
239 $sql .= " AND f.fk_soc = ".((int) $socid);
240 }
241 // Add where from extra fields
242 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
243 // Add where from hooks
244 $parameters = array();
245 $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
246 $sql .= $hookmanager->resPrint;
247
248 // Add HAVING from hooks
249 $parameters = array();
250 $reshook = $hookmanager->executeHooks('printFieldListHaving', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
251 $sql .= empty($hookmanager->resPrint) ? "" : " HAVING 1=1 ".$hookmanager->resPrint;
252
253 $sql .= $db->order($sortfield, $sortorder);
254
255 // Calcul total qty and amount for global if full scan list
256 $total_ht = 0;
257 $total_qty = 0;
258
259 // Count total nb of records
260 $totalofrecords = '';
261 if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
262 $result = $db->query($sql);
263 $totalofrecords = $db->num_rows($result);
264 }
265
266 $sql .= $db->plimit($limit + 1, $offset);
267
268 $result = $db->query($sql);
269 if ($result) {
270 $num = $db->num_rows($result);
271
272 $option .= '&id='.$product->id;
273
274 if ($limit > 0 && $limit != $conf->liste_limit) {
275 $option .= '&limit='.((int) $limit);
276 }
277 if (!empty($search_month)) {
278 $option .= '&search_month='.urlencode($search_month);
279 }
280 if (!empty($search_year)) {
281 $option .= '&search_year='.urlencode($search_year);
282 }
283
284 // Add $param from extra fields
285 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
286 // Add $param from hooks
287 $parameters = array('param' => &$param);
288 $reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
289 $option .= $hookmanager->resPrint;
290
291 print '<form method="post" action="'.$_SERVER ['PHP_SELF'].'?id='.$product->id.'" name="search_form">'."\n";
292 print '<input type="hidden" name="token" value="'.newToken().'">';
293 if (!empty($sortfield)) {
294 print '<input type="hidden" name="sortfield" value="'.$sortfield.'"/>';
295 }
296 if (!empty($sortorder)) {
297 print '<input type="hidden" name="sortorder" value="'.$sortorder.'"/>';
298 }
299
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($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 align="right">'.price($objp->total_ht)."</td>\n";
365 print '<td align="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) {
376 print '<td class="left">'.$langs->trans("Total").'</td>';
377 } else {
378 print '<td class="left">'.$langs->trans("Totalforthispage").'</td>';
379 }
380 print '<td colspan="3"></td>';
381 print '<td class="center">'.$total_qty.'</td>';
382 print '<td align="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(!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.
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...)
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_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...
GETPOSTINT($paramname, $method=0)
Return value of a param into GET or POST supervariable.
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_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.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
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.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
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.
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 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.