27 require
'../../main.inc.php';
29 require_once DOL_DOCUMENT_ROOT .
'/core/lib/accounting.lib.php';
30 require_once DOL_DOCUMENT_ROOT .
'/core/lib/report.lib.php';
31 require_once DOL_DOCUMENT_ROOT .
'/core/lib/admin.lib.php';
32 require_once DOL_DOCUMENT_ROOT .
'/core/lib/date.lib.php';
33 require_once DOL_DOCUMENT_ROOT .
'/core/class/html.formaccounting.class.php';
34 require_once DOL_DOCUMENT_ROOT .
'/accountancy/class/accountingaccount.class.php';
35 require_once DOL_DOCUMENT_ROOT .
'/product/class/product.class.php';
38 $langs->loadLangs(array(
"companies",
"compta",
"accountancy",
"products"));
41 if (empty($conf->accounting->enabled)) {
44 if (! $user->rights->accounting->bind->write)
48 $action =
GETPOST(
'action',
'aZ09');
49 $codeventil_buy =
GETPOST(
'codeventil_buy',
'array');
50 $codeventil_sell =
GETPOST(
'codeventil_sell',
'array');
51 $chk_prod =
GETPOST(
'chk_prod',
'array');
52 $account_number_buy =
GETPOST(
'account_number_buy');
53 $account_number_sell =
GETPOST(
'account_number_sell');
54 $changeaccount =
GETPOST(
'changeaccount',
'array');
55 $changeaccount_buy =
GETPOST(
'changeaccount_buy',
'array');
56 $changeaccount_sell =
GETPOST(
'changeaccount_sell',
'array');
57 $search_ref =
GETPOST(
'search_ref',
'alpha');
58 $search_label =
GETPOST(
'search_label',
'alpha');
59 $search_desc =
GETPOST(
'search_desc',
'alpha');
60 $search_current_account =
GETPOST(
'search_current_account',
'alpha');
61 $search_current_account_valid =
GETPOST(
'search_current_account_valid',
'alpha');
62 if ($search_current_account_valid ==
'') $search_current_account_valid=
'withoutvalidaccount';
64 $accounting_product_mode =
GETPOST(
'accounting_product_mode',
'alpha');
65 $btn_changeaccount =
GETPOST(
'changeaccount',
'alpha');
66 $btn_changetype =
GETPOST(
'changetype',
'alpha');
68 $limit =
GETPOST(
'limit',
'int')?
GETPOST(
'limit',
'int'):(empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION)?$conf->liste_limit:$conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION);
69 $sortfield =
GETPOST(
"sortfield",
'alpha');
70 $sortorder =
GETPOST(
"sortorder",
'alpha');
72 if (empty($page) || $page == -1) { $page = 0; }
73 $offset = $limit * $page;
74 $pageprev = $page - 1;
75 $pagenext = $page + 1;
76 if (! $sortfield) $sortfield=
"p.ref";
77 if (! $sortorder) $sortorder=
"ASC";
79 if (empty($action)) $action=
'list';
88 if (
GETPOST(
'cancel',
'alpha')) { $action=
'list'; $massaction=
''; }
89 if (!
GETPOST(
'confirmmassaction',
'alpha') && $massaction !=
'presend' && $massaction !=
'confirm_presend') { $massaction=
''; }
92 $reshook=$hookmanager->executeHooks(
'doActions',$parameters,$object,$action);
93 if ($reshook < 0)
setEventMessages($hookmanager->error, $hookmanager->errors,
'errors');
96 if (
GETPOST(
'button_removefilter_x',
'alpha') ||
GETPOST(
'button_removefilter.x',
'alpha') ||
GETPOST(
'button_removefilter',
'alpha'))
101 $search_current_account =
'';
102 $search_current_account_valid =
'-1';
106 if ($action ==
'update') {
107 if (! empty($btn_changetype)) {
110 $accounting_product_modes = array (
115 $accounting_product_mode =
GETPOST(
'accounting_product_mode',
'alpha');
117 if (in_array($accounting_product_mode, $accounting_product_modes)) {
119 if (!
dolibarr_set_const($db,
'ACCOUNTING_PRODUCT_MODE', $accounting_product_mode,
'chaine', 0,
'', $conf->entity)) {
127 if (! empty($btn_changeaccount)) {
129 if (! empty($chk_prod)) {
134 $arrayofdifferentselectedvalues = array();
136 $cpt = 0; $ok = 0; $ko = 0;
137 foreach ( $chk_prod as $productid )
139 $accounting_account_id =
GETPOST(
'codeventil_' . $productid);
142 if ($accounting_account_id > 0)
144 $arrayofdifferentselectedvalues[$accounting_account_id]=$accounting_account_id;
145 $result = $accounting->fetch($accounting_account_id, null, 1);
149 $msg .=
'<div><font color="red">' . $langs->trans(
"ErrorDB") .
' : ' . $langs->trans(
"Product") .
' ' . $productid .
' ' . $langs->trans(
"NotVentilatedinAccount") .
' : id=' . $accounting_account_id .
'<br/> <pre>' . $sql .
'</pre></font></div>';
154 $sql =
" UPDATE " . MAIN_DB_PREFIX .
"product";
155 if ($accounting_product_mode ==
'ACCOUNTANCY_BUY') {
156 $sql .=
" SET accountancy_code_buy = " . $accounting->account_number;
158 if ($accounting_product_mode ==
'ACCOUNTANCY_SELL') {
159 $sql .=
" SET accountancy_code_sell = " . $accounting->account_number;
161 $sql .=
" WHERE rowid = " . $productid;
163 dol_syslog(
"/accountancy/admin/productaccount.php sql=" . $sql, LOG_DEBUG);
164 if ($db->query($sql))
178 if ($ko)
setEventMessages($langs->trans(
"XLineFailedToBeBinded", $ko), null,
'errors');
179 if ($ok)
setEventMessages($langs->trans(
"XLineSuccessfullyBinded", $ok), null,
'mesgs');
196 $aarowid_servbuy = $accounting->fetch(
'', $conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT, 1);
197 $aarowid_prodbuy = $accounting->fetch(
'', $conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT, 1);
198 $aarowid_servsell = $accounting->fetch(
'', $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT, 1);
199 $aarowid_prodsell = $accounting->fetch(
'', $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT, 1);
201 $aacompta_servbuy = (! empty($conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT : $langs->trans(
"CodeNotDef"));
202 $aacompta_prodbuy = (! empty($conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT : $langs->trans(
"CodeNotDef"));
203 $aacompta_servsell = (! empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : $langs->trans(
"CodeNotDef"));
204 $aacompta_prodsell = (! empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : $langs->trans(
"CodeNotDef"));
206 llxHeader(
'', $langs->trans(
"ProductsBinding"));
208 $pcgverid = $conf->global->CHARTOFACCOUNTS;
209 $pcgvercode =
dol_getIdFromCode($db, $pcgverid,
'accounting_system',
'rowid',
'pcg_version');
210 if (empty($pcgvercode)) $pcgvercode=$pcgverid;
212 $sql =
"SELECT p.rowid, p.ref, p.label, p.description, p.tosell, p.tobuy, p.accountancy_code_sell, p.accountancy_code_buy, p.tms, p.fk_product_type as product_type,";
213 $sql.=
" aa.rowid as aaid";
214 $sql.=
" FROM " . MAIN_DB_PREFIX .
"product as p";
215 $sql.=
" LEFT JOIN ".MAIN_DB_PREFIX.
"accounting_account as aa ON";
216 if ($accounting_product_mode ==
'ACCOUNTANCY_BUY') {
217 $sql.=
" p.accountancy_code_buy = aa.account_number AND aa.fk_pcg_version = '" . $pcgvercode .
"'";
221 $sql.=
" p.accountancy_code_sell = aa.account_number AND aa.fk_pcg_version = '" . $pcgvercode .
"'";
223 $sql.=
' WHERE p.entity IN ('.getEntity(
'product').
')';
224 if ($accounting_product_mode ==
'ACCOUNTANCY_BUY') {
225 if (strlen(trim($search_current_account))) {
226 $sql .=
natural_search(
"p.accountancy_code_buy",$search_current_account);
229 if (strlen(trim($search_current_account))) {
230 $sql .=
natural_search(
"p.accountancy_code_sell",$search_current_account);
233 if ($search_current_account_valid ==
'withoutvalidaccount')
235 $sql .=
" AND aa.account_number IS NULL";
237 if ($search_current_account_valid ==
'withvalidaccount')
239 $sql .=
" AND aa.account_number IS NOT NULL";
242 if (strlen(trim($search_ref))) {
245 if (strlen(trim($search_label))) {
248 if (strlen(trim($search_desc))) {
251 $sql .= $db->order($sortfield, $sortorder);
253 $nbtotalofrecords =
'';
254 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
256 $result = $db->query($sql);
257 $nbtotalofrecords = $db->num_rows($result);
258 if (($page * $limit) > $nbtotalofrecords)
265 $sql .= $db->plimit($limit + 1, $offset);
267 dol_syslog(
"/accountancy/admin/productaccount.php:: sql=" . $sql, LOG_DEBUG);
268 $result = $db->query($sql);
271 $num = $db->num_rows($result);
275 if (! empty($contextpage) && $contextpage != $_SERVER[
"PHP_SELF"]) $param.=
'&contextpage='.urlencode($contextpage);
276 if ($limit > 0 && $limit != $conf->liste_limit) $param.=
'&limit='.urlencode($limit);
277 if ($search_ref > 0) $param.=
"&search_desc=".urlencode($search_ref);
278 if ($search_label > 0) $param.=
"&search_desc=".urlencode($search_label);
279 if ($search_desc > 0) $param.=
"&search_desc=".urlencode($search_desc);
280 if ($search_current_account > 0) $param.=
"&search_current_account=".urlencode($search_current_account);
281 if ($search_current_account_valid && $search_current_account_valid !=
'-1') $param.=
"&search_current_account_valid=".urlencode($search_current_account_valid);
283 print '<form action="' . $_SERVER[
"PHP_SELF"] .
'" method="post">';
284 if ($optioncss !=
'')
print '<input type="hidden" name="optioncss" value="'.$optioncss.
'">';
285 print '<input type="hidden" name="token" value="'.$_SESSION[
'newtoken'].
'">';
286 print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
287 print '<input type="hidden" name="action" value="update">';
288 print '<input type="hidden" name="sortfield" value="'.$sortfield.
'">';
289 print '<input type="hidden" name="sortorder" value="'.$sortorder.
'">';
290 print '<input type="hidden" name="page" value="'.$page.
'">';
295 print $langs->trans(
"InitAccountancyDesc") .
'<br>';
299 print
'<table class="noborder" width="100%">';
300 print
'<tr class="liste_titre">';
301 print
'<td>' . $langs->trans(
'Options') .
'</td><td>' . $langs->trans(
'Description') .
'</td>';
303 print
'<tr class="oddeven"><td class="titlefield"><input type="radio" name="accounting_product_mode" value="ACCOUNTANCY_SELL"' . ($accounting_product_mode !=
'ACCOUNTANCY_BUY' ?
' checked' :
'') .
'> ' . $langs->trans(
'OptionModeProductSell') .
'</td>';
304 print
'<td>'.$langs->trans(
'OptionModeProductSellDesc');
305 print
"</td></tr>\n";
306 print
'<tr class="oddeven"><td class="titlefield"><input type="radio" name="accounting_product_mode" value="ACCOUNTANCY_BUY"' . ($accounting_product_mode ==
'ACCOUNTANCY_BUY' ?
' checked' :
'') .
'> ' . $langs->trans(
'OptionModeProductBuy') .
'</td>';
307 print
'<td>'.$langs->trans(
'OptionModeProductBuyDesc').
"</td></tr>\n";
310 print
'<div align="center"><input type="submit" class="button" value="' . $langs->trans(
'Refresh') .
'" name="changetype"></div>';
317 $varpage=empty($contextpage)?$_SERVER[
"PHP_SELF"]:$contextpage;
318 $selectedfields=$form->multiSelectArrayWithCheckbox(
'selectedfields', $arrayfields, $varpage);
320 $texte=$langs->trans(
"ListOfProductsServices");
321 print_barre_liste($texte, $page, $_SERVER[
"PHP_SELF"], $param, $sortfield, $sortorder,
'', $num, $nbtotalofrecords,
'', 0,
'',
'', $limit);
323 print
'<div class="div-table-responsive">';
324 print
'<table class="liste '.($moreforfilter?
"listwithfilterbefore":
"").
'">';
326 print
'<tr class="liste_titre_filter">';
327 print
'<td class="liste_titre"><input type="text" class="flat" size="8" name="search_ref" value="' .
dol_escape_htmltag($search_ref) .
'"></td>';
328 print
'<td class="liste_titre"><input type="text" class="flat" size="10" name="search_label" value="' .
dol_escape_htmltag($search_label) .
'"></td>';
329 if (! empty($conf->global->ACCOUNTANCY_SHOW_PROD_DESC)) print
'<td class="liste_titre"><input type="text" class="flat" size="20" name="search_desc" value="' .
dol_escape_htmltag($search_desc) .
'"></td>';
331 if ($accounting_product_mode ==
'ACCOUNTANCY_SELL') print
'<td class="liste_titre"></td>';
333 if ($accounting_product_mode ==
'ACCOUNTANCY_BUY') print
'<td class="liste_titre"></td>';
335 print
'<td class="liste_titre">';
336 print
'<input type="text" class="flat" size="6" name="search_current_account" value="' .
dol_escape_htmltag($search_current_account) .
'">';
337 $listofvals=array(
'withoutvalidaccount'=>$langs->trans(
"WithoutValidAccount"),
'withvalidaccount'=>$langs->trans(
"WithValidAccount"));
338 print
' '.$langs->trans(
"or").
' '.$form->selectarray(
'search_current_account_valid', $listofvals, $search_current_account_valid, 1);
340 print
'<td class="liste_titre"> </td>';
341 print
'<td align="center" class="liste_titre">';
342 $searchpicto=$form->showFilterButtons();
347 print
'<tr class="liste_titre">';
350 if (! empty($conf->global->ACCOUNTANCY_SHOW_PROD_DESC))
print_liste_field_titre(
"Description", $_SERVER[
"PHP_SELF"],
"p.description",
"", $param,
'', $sortfield, $sortorder);
351 if ($accounting_product_mode ==
'ACCOUNTANCY_SELL')
print_liste_field_titre(
"OnSell", $_SERVER[
"PHP_SELF"],
"p.tosell",
"", $param,
'align="center"', $sortfield, $sortorder);
352 if ($accounting_product_mode ==
'ACCOUNTANCY_BUY')
print_liste_field_titre(
"OnBuy", $_SERVER[
"PHP_SELF"],
"p.tobuy",
"", $param,
'align="center"', $sortfield, $sortorder);
353 if ($accounting_product_mode ==
'ACCOUNTANCY_BUY') $fieldtosortaccount=
"p.accountancy_code_buy";
354 else $fieldtosortaccount=
"p.accountancy_code_sell";
355 print_liste_field_titre(
"CurrentDedicatedAccountingAccount", $_SERVER[
"PHP_SELF"], $fieldtosortaccount,
"", $param,
'', $sortfield, $sortorder);
357 $clickpitco=$form->showCheckAddButtons(
'checkforselect', 1);
361 $product_static =
new Product($db);
364 while ($i < min($num,$limit))
366 $obj = $db->fetch_object($result);
369 $product_static->ref = $obj->ref;
370 $product_static->id = $obj->rowid;
371 $product_static->type = $obj->product_type;
372 $product_static->label = $obj->label;
373 $product_static->description = $obj->description;
374 $product_static->status = $obj->tosell;
375 $product_static->status_buy = $obj->tobuy;
377 if ($obj->product_type == 0) {
378 $compta_prodsell = (! empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : $langs->trans(
"CodeNotDef"));
379 $compta_prodsell_id = $aarowid_prodsell;
381 $compta_prodsell = (! empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : $langs->trans(
"CodeNotDef"));
382 $compta_prodsell_id = $aarowid_servsell;
385 if ($obj->product_type == 0) {
386 $compta_prodbuy = (! empty($conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT : $langs->trans(
"CodeNotDef"));
387 $compta_prodbuy_id = $aarowid_prodbuy;
389 $compta_prodbuy = (! empty($conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT : $langs->trans(
"CodeNotDef"));
390 $compta_prodbuy_id = $aarowid_servbuy;
393 print
'<tr class="oddeven">';
396 print $product_static->getNomUrl(1);
399 print
'<td align="left">'.$obj->label.
'</td>';
401 if (! empty($conf->global->ACCOUNTANCY_SHOW_PROD_DESC))
406 $trunclengh = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION;
407 print
'<td style="' . $code_sell_p_l_differ .
'">' . nl2br(
dol_trunc($obj->description, $trunclengh)) .
'</td>';
410 if ($accounting_product_mode ==
'ACCOUNTANCY_SELL')
411 print
'<td align="center">'.$product_static->getLibStatut(3, 0).
'</td>';
413 if ($accounting_product_mode ==
'ACCOUNTANCY_BUY')
414 print
'<td align="center">'.$product_static->getLibStatut(3, 1).
'</td>';
417 print
'<td align="left">';
418 if ($accounting_product_mode ==
'ACCOUNTANCY_BUY') {
420 if ($obj->accountancy_code_buy && empty($obj->aaid)) print
' '.img_warning($langs->trans(
"ValueNotIntoChartOfAccount"));
425 if ($obj->accountancy_code_sell && empty($obj->aaid)) print
' '.img_warning($langs->trans(
"ValueNotIntoChartOfAccount"));
431 if ($accounting_product_mode ==
'ACCOUNTANCY_BUY') {
433 print
'<td align="left">';
435 if (empty($defaultvalue)) $defaultvalue=$compta_prodbuy;
437 if (! empty($obj->aaid)) $defaultvalue =
'';
438 print $form->select_account($defaultvalue,
'codeventil_' . $product_static->id, 1, array(), 1);
442 print
'<td align="left">';
444 if (empty($defaultvalue)) $defaultvalue=$compta_prodsell;
447 if (! empty($obj->aaid)) $defaultvalue =
'';
448 print $form->select_account($defaultvalue,
'codeventil_' . $product_static->id, 1, array(), 1);
453 print
'<td align="center">';
454 print
'<input type="checkbox" class="checkforselect" name="chk_prod[]" value="' . $obj->rowid .
'"/></td>';
462 print
'<script type="text/javascript" language="javascript"> 463 jQuery(document).ready(function() { 464 function init_savebutton() 466 console.log("We check if at least one line is checked") 468 atleastoneselected=0; 469 jQuery(".checkforselect").each(function( index ) { 470 /* console.log( index + ": " + $( this ).text() ); */ 471 if ($(this).is(\':checked\')) atleastoneselected++; 474 if (atleastoneselected) jQuery("#changeaccount").removeAttr(\'disabled\'); 475 else jQuery("#changeaccount").attr(\'disabled\',\'disabled\'); 476 if (atleastoneselected) jQuery("#changeaccount").attr(\'class\',\'butAction\'); 477 else jQuery("#changeaccount").attr(\'class\',\'butActionRefused\'); 479 jQuery(".checkforselect, #checkallactions").click(function() { 488 print
'<br><div align="center"><input type="submit" class="butAction" id="changeaccount" name="changeaccount" value="' . $langs->trans(
"Save") .
'"></div>';
load_fiche_titre($titre, $morehtmlright='', $picto='title_generic.png', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
GETPOST($paramname, $check='none', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
print
Draft customers invoices.
setEventMessages($mesg, $mesgs, $style='mesgs')
Set event messages in dol_events session object.
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.
Class to manage products or services.
dol_getIdFromCode($db, $key, $tablename, $fieldkey='code', $fieldid='id', $entityfilter=0)
Return an id or code from a code or id.
dolibarr_set_const($db, $name, $value, $type='chaine', $visible=0, $note='', $entity=1)
Insert a parameter (key,value) into database (delete old key then insert it again).
dol_print_error($db='', $error='', $errors=null)
Affiche message erreur system avec toutes les informations pour faciliter le diagnostic et la remonte...
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields...
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0)
Show a message to say access is forbidden and stop program Calling this function terminate execution ...
print_barre_liste($titre, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='title_generic.png', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $hideselectlimit=0, $hidenavigation=0)
Print a title with navigation controls for pagination.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='')
Write log message into outputs.
natural_search($fields, $value, $mode=0, $nofirstand=0)
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="")
Show title line of an array.
Class to manage accounting accounts.
length_accountg($account)
Return General accounting account with defined length (used for product and miscellaneous) ...