From 0e7ba927849d51e787dd9ae3b9c3c3598a512b52 Mon Sep 17 00:00:00 2001 From: patrick Delcroix Date: Thu, 5 Jul 2018 21:34:36 +0200 Subject: [PATCH 001/328] New: Accounting dossier file checks page Page to check to attachement of those operation invoice, invoicesupplier, salary, donation, Expense, tax --- htdocs/compta/compta-files.php | 341 +++++++++++++++++++++++ htdocs/core/tpl/extrafields_view.tpl.php | 182 ------------ 2 files changed, 341 insertions(+), 182 deletions(-) create mode 100644 htdocs/compta/compta-files.php delete mode 100644 htdocs/core/tpl/extrafields_view.tpl.php diff --git a/htdocs/compta/compta-files.php b/htdocs/compta/compta-files.php new file mode 100644 index 00000000000..d48679c5291 --- /dev/null +++ b/htdocs/compta/compta-files.php @@ -0,0 +1,341 @@ + + * Copyright (C) 2004-2017 Laurent Destailleur + * Copyright (C) 2017 Pierre-Henry Favre + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/compta/recap-compta.php + * \ingroup compta + * \brief Page de fiche recap customer + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; +require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php'; +restrictedArea($user,'banque'); + +$langs->load("companies"); +if (! empty($conf->facture->enabled)) $langs->load("bills"); + +$date_start =GETPOST('date_start','alpha'); +$date_startDay= GETPOST('date_startday','int'); +$date_startMonth= GETPOST('date_startmonth','int'); +$date_startYear= GETPOST('date_startyear','int'); +$date_start=($date_startDay)?dol_mktime(0,0,0,$date_startMonth,$date_startDay,$date_startYear):strtotime($date_start); + +$date_stop =GETPOST('date_stop','alpha'); +$date_stopDay= GETPOST('date_stopday','int'); +$date_stopMonth= GETPOST('date_stopmonth','int'); +$date_stopYear= GETPOST('date_stopyear','int'); +//FIXME doldate +$date_stop=($date_stopDay)?dol_mktime(0,0,0,$date_stopMonth,$date_stopDay,$date_stopYear):strtotime($date_stop); + +$action =GETPOST('action','alpha'); +// Security check +//if ($user->societe_id) $id=$user->societe_id; +//$result = restrictedArea($user, 'societe', $id, '&societe'); + +//$object = new Societe($db); +//if ($id > 0) $object->fetch($id); + + +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('comptafilescard','globalcard')); + +// Load variable for pagination +$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; +$sortfield = GETPOST('sortfield','alpha'); +$sortorder = GETPOST('sortorder','alpha'); +$page = GETPOST('page','int'); +if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (! $sortfield) $sortfield="f.datef,f.rowid"; // Set here default search field +if (! $sortorder) $sortorder="DESC"; + + +$arrayfields=array( + 'date'=>array('label'=>"Date", 'checked'=>1), + //... +); + +/* + * Actions + */ +//$parameters = array('socid' => $id); +//$reshook = $hookmanager->executeHooks('doActions', $parameters, $object); // Note that $object may have been modified by some hooks +//if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + +/* + * Fetch the lines/files from db / + */ +$filesarray=array(); +$result=false; +if(($action=="searchfiles"||$action=="dl" ) && $date_start && $date_stop){ + $wheretail=" '".$db->idate($date_start)."' AND '".$db->idate($date_stop)."'"; + $sql="SELECT rowid, facnumber as ref,paye as paid,total_ttc,fk_soc,datef as date, 'Invoice' as item FROM ".MAIN_DB_PREFIX."facture"; + $sql.=" WHERE datef between ".$wheretail; + $sql.=" UNION ALL"; + $sql.=" SELECT rowid,ref, paye as paid, total_ttc, fk_soc,datef as date, 'InvoiceSupplier' as item FROM ".MAIN_DB_PREFIX."facture_fourn"; + $sql.=" WHERE datef between ".$wheretail; + $sql.=" UNION ALL"; + $sql.=" SELECT rowid,ref,paid,total_ttc,fk_user_author as fk_soc,date_fin as date,'Expense' as item FROM ".MAIN_DB_PREFIX."expensereport"; + $sql.=" WHERE date_fin between ".$wheretail; + $sql.=" UNION ALL"; + $sql.=" SELECT rowid,ref,paid,amount as total_ttc,CONCAT(firstname,' ',lastname) as fk_soc,datedon as date,'Donation' as item FROM ".MAIN_DB_PREFIX."don"; + $sql.=" WHERE datedon between ".$wheretail; + $sql.=" UNION ALL"; + $sql.=" SELECT rowid,label as ref,1 as paid,amount as total_ttc,fk_user as fk_soc,datep as date,'Salary' as item FROM ".MAIN_DB_PREFIX."payment_salary"; + $sql.=" WHERE datep between ".$wheretail; + $sql.=" UNION ALL"; + $sql.=" SELECT rowid,num_paiement as ref,1 as paid,amount as total_ttc,fk_charge as fk_soc,datep as date,'Charge' as item FROM ".MAIN_DB_PREFIX."paiementcharge"; + $sql.=" WHERE datep between ".$wheretail; + $resd = $db->query($sql); + $files=array(); + $link=''; + + if ($resd) + { + $numd = $db->num_rows($resd); + + $upload_dir =''; + $i=0; + while($i<$numd) + { + + + $objd = $db->fetch_object($resd); + + switch($objd->item){ + case "Invoice": + $subdir=dol_sanitizeFileName($objd->ref); + $upload_dir = $conf->facture->dir_output.'/'.$subdir; + $link="../../document.php?modulepart=facture&file=".str_replace('/','%2F',$subdir).'%2F'; + break; + case "InvoiceSupplier": + $subdir=get_exdir($objd->id,2,0,0,$objd,'invoice_supplier').$objd->ref; + $upload_dir = $conf->fournisseur->facture->dir_output.'/'.$subdir; + $link="../../document.php?modulepart=facture_fournisseur&file=".str_replace('/','%2F',$subdir).'%2F'; + break; + case "Expense": + $subdir=dol_sanitizeFileName($objd->ref); + $upload_dir = $conf->expensereport->dir_output.'/'.$subdir; + $link="../../document.php?modulepart=expensereport&file=".str_replace('/','%2F',$subdir).'%2F'; + break; + case "Salary": + $subdir=dol_sanitizeFileName($objd->rowid); + $upload_dir = $conf->salaries->dir_output.'/'.$subdir; + $link="../../document.php?modulepart=salaries&file=".str_replace('/','%2F',$subdir).'%2F'; + break; + case "Donation": + $subdir=get_exdir(null,2,0,1,$objd,'donation'). '/'. dol_sanitizeFileName($objd->idd); + $upload_dir = $conf->don->dir_output . '/' . $subdir; + $link="../../document.php?modulepart=don&file=".str_replace('/','%2F',$subdir).'%2F'; + break; + case "Charge": + $subdir=dol_sanitizeFileName($objd->rowid); + $upload_dir = $conf->tax->dir_output . '/' . $subdir; + $link="../../document.php?modulepart=tax&file=".str_replace('/','%2F',$subdir).'%2F'; + break; + default: + break; + } + + if(!empty($upload_dir)){ + $result=true; + $files=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview\.png)$','',SORT_ASC,1); + foreach ($files as $key => $file){ + $file['date']=$db->idate($objd->date); + $file['paid']=$objd->paid; + $file['amount']=$objd->total_ttc; + $file['ref']=$objd->ref; + $file['fk']=$objd->fk_soc; + $file['item']=$objd->item; + $file['link']=$link.$file['name']; + $out.= '
'.$file['name'].''; + $filesarray[]=$file; + } + if(count($files)<1){ + $nofile['date']=$db->idate($objd->date); + $nofile['paid']=$objd->paid; + $nofile['amount']=$objd->total_ttc; + $nofile['ref']=$objd->ref; + $nofile['fk']=$objd->fk_soc; + $nofile['item']=$objd->item; + + $filesarray[]=$nofile; + } + } + $i++; + } + } + $db->free($resd); + +} +/* + * cleanup of old ZIP + */ +//FIXME + + +/* +*ZIP creation +*/ +if($result & $action=="dl"){ + unset($zip); + $log='date,type,ref,total,paid,filename,item_id'."\n"; + $zipname = 'export.zip'; + $zip = new ZipArchive; + $res = $zip->open($zipname, ZipArchive::OVERWRITE|ZipArchive::CREATE); + if ($res){ + foreach ($filesarray as $key=> $file) { + + if(file_exists($file["fullname"])) $zip->addFile($file["fullname"],$file["name"]);// + $log.=$file['date'].','.$file['item'].','.$file['ref'].','.$file['amount'].','.$file['paid'].','.$file["name"].','.$file['fk']."\n"; + } + + + $zip->addFromString('log.csv', $log); + $zip->close(); + ///Then download the zipped file. + header('Content-Type: application/zip'); + header('Content-disposition: attachment; filename='.$zipname); + header('Content-Length: ' . filesize($zipname)); + readfile($zipname); + exit(); + } +} + + +// None + + +/* + * View + */ + +$form = new Form($db); +$userstatic=new User($db); + +$title=$langs->trans("ComptaFiles").' - '.$langs->trans("List"); +//if (! empty($conf->global->MAIN_HTML_TITLE) && preg_match('/thirdpartynameonly/',$conf->global->MAIN_HTML_TITLE) && $object->name) $title=$object->name.' - '.$langs->trans("Symmary"); +$help_url='EN:Module_Accounting|FR:Module_Compatibilite'; //FIXME + +llxHeader('',$title,$help_url); + +print '
'."\n\t\t\t"; +print ''.$langs->trans("dateStart").': '.$form->select_date($date_start,'date_start',0,0,0,"",1,1,1)."\n"; +print ''.$langs->trans("dateStop").': '.$form->select_date($date_stop,'date_stop',0,0,0,"",1,1,1)."\n"; + +print '
'."\n\t\t"; + +if (!empty($date_start) && !empty($date_stop))echo dol_print_date($date_start)." - ".dol_print_date($date_stop); +print ''; +print ''; +//if (! empty($arrayfields['f.datef']['checked'])) +print_liste_field_titre($arrayfields['date']['label'],$_SERVER["PHP_SELF"],"date","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; + +print ''; + +if ($result) +{ + $TData = dol_sort_array($filesarray, 'date', 'ASC'); + if(empty($TData)) { + print ''; + } else { + + // Sort array by date ASC to calucalte balance + + $totalDebit = 0; + $totalCredit = 0; + // Balance calculation + $balance = 0; + foreach($TData as &$data1) { + if($data1['item']=='Invoice'||$data1['item']=='Donation' ){ + $balance += $data1['amount']; + $totalCredit+=$data1['amount']; + }else{ + $balance -= $data1['amount']; + $totalDebit+=$data1['amount']; + } + $data1['balance'] = $balance; + } + + + + // Display array + foreach($TData as $data) { + + $html_class = ''; + //if (!empty($data['fk_facture'])) $html_class = 'facid-'.$data['fk_facture']; + //elseif (!empty($data['fk_paiement'])) $html_class = 'payid-'.$data['fk_paiement']; + + print ''; + + print "\n"; + print ''; + print ''; + print '\n"; + + print ''; + print '\n"; + $totalDebit += ($data['amount'] > 0) ? abs($data['amount']) : 0; + print '\n"; + $totalCredit += ($data['amount'] > 0) ? 0 : abs($data['amount']); + // Balance + print '\n"; + + + + print "\n"; + } + + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print "\n"; + } + + + } +print "
'.$langs->trans("Type").''.$langs->trans("Ref").''.$langs->trans("File").''.$langs->trans("Paid").''.$langs->trans("Debit").''.$langs->trans("Credit").''.$langs->trans("Balance").'
'.$langs->trans("NoItem").'
"; + print dol_print_date($data['date'],'day'); + print "'.$data['item'].''.$data['ref'].' ".$data['name']."'.$data['paid'].''.(($data['amount'] > 0) ? price(abs($data['amount'])) : '')."'.(($data['amount'] > 0) ? '' : price(abs($data['amount'])))."'.price($data['balance'])."
 '.price($totalDebit).''.price($totalCredit).''.price(price2num($totalDebit - $totalCredit, 'MT')).'
"; +print '
'."\n\t\t\t"; +print ''; +print ''; +print '
'."\n\t\t\n\t\t\n\t\t\t"; + +llxFooter(); + +$db->close(); diff --git a/htdocs/core/tpl/extrafields_view.tpl.php b/htdocs/core/tpl/extrafields_view.tpl.php deleted file mode 100644 index 3559df44c9c..00000000000 --- a/htdocs/core/tpl/extrafields_view.tpl.php +++ /dev/null @@ -1,182 +0,0 @@ - - * Copyright (C) 2014 Juanjo Menent - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * Need to have following variables defined: - * $object (invoice, order, ...) - * $action - * $conf - * $langs - * - * $parameters - * $cols - */ - -// Protection to avoid direct call of template -if (empty($object) || ! is_object($object)) -{ - print "Error, template page can't be called as URL"; - exit; -} - -?> - -fk_soc)) $parameters['socid'] = $object->fk_soc; - -$reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); -print $hookmanager->resPrint; -if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); - -//var_dump($extrafields->attributes); -if (empty($reshook) && ! empty($extrafields->attributes[$object->table_element]['label'])) -{ - foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) - { - // Discard if extrafield is a hidden field on form - if (empty($extrafields->attributes[$object->table_element]['list'][$key])) continue; // 0 = Never visible field - if (abs($extrafields->attributes[$object->table_element]['list'][$key]) != 1 && abs($extrafields->attributes[$object->table_element]['list'][$key]) != 3) continue; // <> -1 and <> 1 and <> 3 = not visible on forms, only on list - - // Load language if required - if (! empty($extrafields->attributes[$object->table_element]['langfile'][$key])) $langs->load($extrafields->attributes[$object->table_element]['langfile'][$key]); - - if ($action == 'edit_extras') - { - $value = (isset($_POST["options_" . $key]) ? $_POST["options_" . $key] : $object->array_options["options_" . $key]); - } - else - { - $value = $object->array_options["options_" . $key]; - } - if ($extrafields->attributes[$object->table_element]['type'][$key] == 'separate') - { - print $extrafields->showSeparator($key); - } - else - { - print ''; - print ''; - print ''; - print 'attributes[$object->table_element]['required'][$key])) print ' class="fieldrequired"'; - print '>' . $langs->trans($label) . ''; - - //TODO Improve element and rights detection - //var_dump($user->rights); - $permok=false; - - $keyforperm=$object->element; - if ($object->element == 'fichinter') $keyforperm='ficheinter'; - if (isset($user->rights->$keyforperm)) $permok=$user->rights->$keyforperm->creer||$user->rights->$keyforperm->create||$user->rights->$keyforperm->write; - - if ($object->element=='order_supplier') $permok=$user->rights->fournisseur->commande->creer; - if ($object->element=='invoice_supplier') $permok=$user->rights->fournisseur->facture->creer; - if ($object->element=='shipping') $permok=$user->rights->expedition->creer; - if ($object->element=='delivery') $permok=$user->rights->expedition->livraison->creer; - if ($object->element=='productlot') $permok=$user->rights->stock->creer; - if ($object->element=='facturerec') $permok=$user->rights->facture->creer; - - if (($object->statut == 0 || ! empty($extrafields->attributes[$object->table_element]['alwayseditable'][$key])) - && $permok && ($action != 'edit_extras' || GETPOST('attribute') != $key) - && empty($extrafields->attributes[$object->table_element]['computed'][$key])) - { - $fieldid='id'; - if ($object->table_element == 'societe') $fieldid='socid'; - print ''; - } - print '
' . img_edit().'
'; - $html_id = !empty($object->id) ? $object->element.'_extras_'.$key.'_'.$object->id : ''; - print ''; - - // Convert date into timestamp format - if (in_array($extrafields->attributes[$object->table_element]['type'][$key], array('date','datetime'))) - { - $datenotinstring = $object->array_options['options_' . $key]; - // print 'X'.$object->array_options['options_' . $key].'-'.$datenotinstring.'x'; - if (! is_numeric($object->array_options['options_' . $key])) // For backward compatibility - { - $datenotinstring = $db->jdate($datenotinstring); - } - //print 'x'.$object->array_options['options_' . $key].'-'.$datenotinstring.' - '.dol_print_date($datenotinstring, 'dayhour'); - $value = isset($_POST["options_" . $key]) ? dol_mktime($_POST["options_" . $key . "hour"], $_POST["options_" . $key . "min"], 0, $_POST["options_" . $key . "month"], $_POST["options_" . $key . "day"], $_POST["options_" . $key . "year"]) : $datenotinstring; - } - - //TODO Improve element and rights detection - if ($action == 'edit_extras' && $permok && GETPOST('attribute') == $key) - { - $fieldid='id'; - if ($object->table_element == 'societe') $fieldid='socid'; - - print '
'; - print ''; - print ''; - print ''; - print ''; - - print $extrafields->showInputField($key, $value, '', '', '', 0, $object->id); - - print ''; - - print '
'; - } - else - { - print $extrafields->showOutputField($key, $value, '', (empty($extrafieldsobjectkey)?'':$extrafieldsobjectkey)); - } - print '' . "\n"; - - print "\n"; - // Add code to manage list depending on others - if (! empty($conf->use_javascript_ajax)) - print ' - '."\n"; - } - } -} -?> - \ No newline at end of file From e88dd77ea557afd6c507cd6cc52a93bec59a7e1e Mon Sep 17 00:00:00 2001 From: delcroix Patrick Date: Thu, 5 Jul 2018 21:42:34 +0200 Subject: [PATCH 002/328] no change --- htdocs/core/tpl/extrafields_view.tpl.php | 163 +++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 htdocs/core/tpl/extrafields_view.tpl.php diff --git a/htdocs/core/tpl/extrafields_view.tpl.php b/htdocs/core/tpl/extrafields_view.tpl.php new file mode 100644 index 00000000000..f88a9d1bdf7 --- /dev/null +++ b/htdocs/core/tpl/extrafields_view.tpl.php @@ -0,0 +1,163 @@ + + * Copyright (C) 2014 Juanjo Menent + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Need to have following variables defined: + * $object (invoice, order, ...) + * $action + * $conf + * $langs + * + * $parameters + * $cols + */ +// Protection to avoid direct call of template +if (empty($object) || ! is_object($object)) +{ + print "Error, template page can't be called as URL"; + exit; +} +?> + +fk_soc)) $parameters['socid'] = $object->fk_soc; +$reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); +print $hookmanager->resPrint; +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +//var_dump($extrafields->attributes); +if (empty($reshook) && ! empty($extrafields->attributes[$object->table_element]['label'])) +{ + foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) + { + // Discard if extrafield is a hidden field on form + if (empty($extrafields->attributes[$object->table_element]['list'][$key])) continue; // 0 = Never visible field + if (abs($extrafields->attributes[$object->table_element]['list'][$key]) != 1 && abs($extrafields->attributes[$object->table_element]['list'][$key]) != 3) continue; // <> -1 and <> 1 and <> 3 = not visible on forms, only on list + // Load language if required + if (! empty($extrafields->attributes[$object->table_element]['langfile'][$key])) $langs->load($extrafields->attributes[$object->table_element]['langfile'][$key]); + if ($action == 'edit_extras') + { + $value = (isset($_POST["options_" . $key]) ? $_POST["options_" . $key] : $object->array_options["options_" . $key]); + } + else + { + $value = $object->array_options["options_" . $key]; + } + if ($extrafields->attributes[$object->table_element]['type'][$key] == 'separate') + { + print $extrafields->showSeparator($key); + } + else + { + print ''; + print ''; + print ''; + print 'attributes[$object->table_element]['required'][$key])) print ' class="fieldrequired"'; + print '>' . $langs->trans($label) . ''; + //TODO Improve element and rights detection + //var_dump($user->rights); + $permok=false; + $keyforperm=$object->element; + if ($object->element == 'fichinter') $keyforperm='ficheinter'; + if (isset($user->rights->$keyforperm)) $permok=$user->rights->$keyforperm->creer||$user->rights->$keyforperm->create||$user->rights->$keyforperm->write; + if ($object->element=='order_supplier') $permok=$user->rights->fournisseur->commande->creer; + if ($object->element=='invoice_supplier') $permok=$user->rights->fournisseur->facture->creer; + if ($object->element=='shipping') $permok=$user->rights->expedition->creer; + if ($object->element=='delivery') $permok=$user->rights->expedition->livraison->creer; + if ($object->element=='productlot') $permok=$user->rights->stock->creer; + if ($object->element=='facturerec') $permok=$user->rights->facture->creer; + if (($object->statut == 0 || ! empty($extrafields->attributes[$object->table_element]['alwayseditable'][$key])) + && $permok && ($action != 'edit_extras' || GETPOST('attribute') != $key) + && empty($extrafields->attributes[$object->table_element]['computed'][$key])) + { + $fieldid='id'; + if ($object->table_element == 'societe') $fieldid='socid'; + print ''; + } + print '
' . img_edit().'
'; + $html_id = !empty($object->id) ? $object->element.'_extras_'.$key.'_'.$object->id : ''; + print ''; + // Convert date into timestamp format + if (in_array($extrafields->attributes[$object->table_element]['type'][$key], array('date','datetime'))) + { + $datenotinstring = $object->array_options['options_' . $key]; + // print 'X'.$object->array_options['options_' . $key].'-'.$datenotinstring.'x'; + if (! is_numeric($object->array_options['options_' . $key])) // For backward compatibility + { + $datenotinstring = $db->jdate($datenotinstring); + } + //print 'x'.$object->array_options['options_' . $key].'-'.$datenotinstring.' - '.dol_print_date($datenotinstring, 'dayhour'); + $value = isset($_POST["options_" . $key]) ? dol_mktime($_POST["options_" . $key . "hour"], $_POST["options_" . $key . "min"], 0, $_POST["options_" . $key . "month"], $_POST["options_" . $key . "day"], $_POST["options_" . $key . "year"]) : $datenotinstring; + } + //TODO Improve element and rights detection + if ($action == 'edit_extras' && $permok && GETPOST('attribute') == $key) + { + $fieldid='id'; + if ($object->table_element == 'societe') $fieldid='socid'; + print '
'; + print ''; + print ''; + print ''; + print ''; + print $extrafields->showInputField($key, $value, '', '', '', 0, $object->id); + print ''; + print '
'; + } + else + { + print $extrafields->showOutputField($key, $value, '', (empty($extrafieldsobjectkey)?'':$extrafieldsobjectkey)); + } + print '' . "\n"; + print "\n"; + // Add code to manage list depending on others + if (! empty($conf->use_javascript_ajax)) + print ' + '."\n"; + } + } +} +?> + From a90974378e1c540643515a8e478bd9a115abc168 Mon Sep 17 00:00:00 2001 From: patrick Delcroix Date: Thu, 5 Jul 2018 22:31:29 +0200 Subject: [PATCH 003/328] FIX: credit / debit --- htdocs/compta/compta-files.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/htdocs/compta/compta-files.php b/htdocs/compta/compta-files.php index d48679c5291..a04cd2a7c66 100644 --- a/htdocs/compta/compta-files.php +++ b/htdocs/compta/compta-files.php @@ -278,13 +278,15 @@ if ($result) // Balance calculation $balance = 0; foreach($TData as &$data1) { - if($data1['item']=='Invoice'||$data1['item']=='Donation' ){ - $balance += $data1['amount']; - $totalCredit+=$data1['amount']; + if($data1['item']!='Invoice'&& $data1['item']!='Donation' ){ + $data1['amount']=-$data1['amount']; + } + if ($data1['amount']>0){ + }else{ - $balance -= $data1['amount']; - $totalDebit+=$data1['amount']; + } + $balance += $data1['amount']; $data1['balance'] = $balance; } @@ -320,7 +322,7 @@ if ($result) } print ''; - print ' '; + print ' '; print ''.price($totalDebit).''; print ''.price($totalCredit).''; print ''.price(price2num($totalDebit - $totalCredit, 'MT')).''; From 294f14ab63010b840ba3d5a219a9dcefdba45073 Mon Sep 17 00:00:00 2001 From: "STAGIAIRE-PC\\Pierre" Date: Thu, 19 Jul 2018 15:09:32 +0200 Subject: [PATCH 004/328] Generation of the mandate file from the api --- .../societe/class/api_thirdparties.class.php | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php index 3faf2f14994..1510c9c2b03 100644 --- a/htdocs/societe/class/api_thirdparties.class.php +++ b/htdocs/societe/class/api_thirdparties.class.php @@ -1170,6 +1170,127 @@ class Thirdparties extends DolibarrApi return $account->delete(DolibarrApiAccess::$user); } + /** + * Generate a sepamandate Document + * + * @param int $socid thirdparty id + * + * @return array Check success + * + * @url GET /generateMandat/{socid} + */ + public function generateMandat($socid){ + + $this->langs->load("database"); + $this->langs->load("main"); + $this->langs->load("dict"); + $this->langs->load("agenda"); + $this->langs->load("margins"); + $this->langs->load("resource"); + $this->langs->load("commercial"); + $this->langs->load("ecm"); + $this->langs->load("products"); + $this->langs->load("companies"); + $this->langs->load("banks"); + $this->langs->load("bills"); + $this->langs->load("withdrawals"); + + + $model = "sepamandate"; + + $this->company->fetch($socid); + + $action = 'builddoc'; + if(! DolibarrApiAccess::$user->rights->societe->creer) + throw new RestException(401); + + + // Reload to get all modified line records and be ready for hooks + + + $this->company->setDocModel($user, $model); + + $this->company->fk_bank = $this->company->fk_account; + + $outputlangs = $this->langs; + $newlang=''; + + + + if ($this->conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang=GETPOST('lang_id','aZ09'); + if ($this->conf->global->MAIN_MULTILANGS && empty($newlang) && isset($this->company->thirdparty->default_lang)) $newlang=$this->company->thirdparty->default_lang; // for proposal, order, invoice, ... + if ($this->conf->global->MAIN_MULTILANGS && empty($newlang) && isset($this->company->default_lang)) $newlang=$this->company->default_lang; // for thirdparty + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + + // To be sure vars is defined + if (empty($hidedetails)) $hidedetails=0; + if (empty($hidedesc)) $hidedesc=0; + if (empty($hideref)) $hideref=0; + if (empty($moreparams)) $moreparams=null; + + + $sql = "SELECT rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."societe_rib"; + if ($socid) $sql.= " WHERE fk_soc = ".$socid." "; + + + $result = $this->db->query($sql); + + if($result->num_rows == 0 ){ + throw new RestException(404, 'Account not found'); + } + + $i=0; + + $accounts =[]; + + if ($result) + { + $num = $this->db->num_rows($result); + while ($i < $num) + { + $obj = $this->db->fetch_object($result); + $account = new CompanyBankAccount($this->db); + if($account->fetchFromApi($obj->rowid)) { + $accounts[] = $account; + } + $i++; + } + } + else{ + throw new RestException(404, 'Account not found'); + } + + + $moreparams = array( + 'use_companybankid'=>$accounts[0]->id, + 'force_dir_output'=>$this->conf->societe->multidir_output[$this->company->entity].'/'.dol_sanitizeFileName($this->company->id) + ); + + + + + $result = 0; + + + + + $result = $this->company->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams); + + if ($result > 0) + { + return array("success" => $result); + } + else + { + throw new RestException(500); + } + } + /** * Clean sensible object datas From d8b212897b5583d57ee9c268a57e15b1e7b24dbe Mon Sep 17 00:00:00 2001 From: "STAGIAIRE-PC\\Pierre" Date: Thu, 19 Jul 2018 15:13:55 +0200 Subject: [PATCH 005/328] ajout de credits --- htdocs/societe/class/api_thirdparties.class.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php index 1510c9c2b03..e2e6a497a41 100644 --- a/htdocs/societe/class/api_thirdparties.class.php +++ b/htdocs/societe/class/api_thirdparties.class.php @@ -1,5 +1,6 @@ + * Copyright (C) 2015 Pierre Chéné * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by From df6ad4426181a819d7c44dcfcf8b181eb6c70232 Mon Sep 17 00:00:00 2001 From: "STAGIAIRE-PC\\Pierre" Date: Thu, 19 Jul 2018 15:15:54 +0200 Subject: [PATCH 006/328] =?UTF-8?q?correction=20de=20l'ann=C3=A9e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- htdocs/societe/class/api_thirdparties.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php index e2e6a497a41..bacdd330041 100644 --- a/htdocs/societe/class/api_thirdparties.class.php +++ b/htdocs/societe/class/api_thirdparties.class.php @@ -1,6 +1,6 @@ - * Copyright (C) 2015 Pierre Chéné + * Copyright (C) 2018 Pierre Chéné * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by From ff8d31925b191e20d509e0eb07d2e227bba5bf67 Mon Sep 17 00:00:00 2001 From: "STAGIAIRE-PC\\Pierre" Date: Mon, 30 Jul 2018 09:37:41 +0200 Subject: [PATCH 007/328] ajout du parametre companyBankid --- htdocs/societe/class/api_thirdparties.class.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php index bacdd330041..6c5533a9ebf 100644 --- a/htdocs/societe/class/api_thirdparties.class.php +++ b/htdocs/societe/class/api_thirdparties.class.php @@ -1175,12 +1175,13 @@ class Thirdparties extends DolibarrApi * Generate a sepamandate Document * * @param int $socid thirdparty id + * @param int $id companybankid * * @return array Check success * * @url GET /generateMandat/{socid} */ - public function generateMandat($socid){ + public function generateMandat($socid, $id = null){ $this->langs->load("database"); $this->langs->load("main"); @@ -1237,6 +1238,7 @@ class Thirdparties extends DolibarrApi $sql = "SELECT rowid"; $sql.= " FROM ".MAIN_DB_PREFIX."societe_rib"; if ($socid) $sql.= " WHERE fk_soc = ".$socid." "; + if ($id) $sql.= " AND id = ".$id.""; $result = $this->db->query($sql); From 61995a3e02ce7da129d914c53ac0de03bb3c7718 Mon Sep 17 00:00:00 2001 From: "STAGIAIRE-PC\\Pierre" Date: Mon, 30 Jul 2018 17:34:43 +0200 Subject: [PATCH 008/328] Ajout d'une colonne indispensable dans la requete json --- htdocs/societe/class/api_thirdparties.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php index 6c5533a9ebf..125d1faff18 100644 --- a/htdocs/societe/class/api_thirdparties.class.php +++ b/htdocs/societe/class/api_thirdparties.class.php @@ -1057,7 +1057,7 @@ class Thirdparties extends DolibarrApi } - $fields = ['socid', 'default_rib', 'frstrecur', '1000110000001', 'datec', 'datem', 'label', 'bank', 'bic', 'iban', 'id']; + $fields = ['socid', 'default_rib', 'frstrecur', '1000110000001', 'datec', 'datem', 'label', 'bank', 'bic', 'iban', 'id', 'rum']; $returnAccounts = []; From 09dfcc601638c06a47a9d0f4c50af20705642105 Mon Sep 17 00:00:00 2001 From: atm-quentin Date: Fri, 3 Aug 2018 14:54:21 +0200 Subject: [PATCH 009/328] FIX exclude element of the select --- htdocs/projet/element.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index dd19ceeb263..5952be3264d 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -697,7 +697,9 @@ foreach ($listofreferent as $key => $value) $urlnew=$value['urlnew']; $buttonnew=$value['buttonnew']; $testnew=$value['testnew']; + $exclude_select_element=array('payment_various',$value['exclude_select_element']); + if ($qualified) { // If we want the project task array to have details of users @@ -717,7 +719,7 @@ foreach ($listofreferent as $key => $value) if (! empty($conf->global->PROJECT_OTHER_THIRDPARTY_ID_TO_ADD_ELEMENTS)) $idtofilterthirdparty.=','.$conf->global->PROJECT_OTHER_THIRDPARTY_ID_TO_ADD_ELEMENTS; } - if (empty($conf->global->PROJECT_LINK_ON_OVERWIEW_DISABLED) && $idtofilterthirdparty && !in_array($tablename, array('payment_various'))) + if (empty($conf->global->PROJECT_LINK_ON_OVERWIEW_DISABLED) && $idtofilterthirdparty && !in_array($tablename,$exclude_select_element)) { $selectList=$formproject->select_element($tablename, $idtofilterthirdparty, 'minwidth300'); if (! $selectList || ($selectList<0)) From ec9eeb5201c9c7bc3dfbb85e82a57c2f85f15920 Mon Sep 17 00:00:00 2001 From: atm-quentin Date: Mon, 27 Aug 2018 10:17:18 +0200 Subject: [PATCH 010/328] FIX check !empty exclude select element --- htdocs/projet/element.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 5952be3264d..03a5bfc0880 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -697,9 +697,10 @@ foreach ($listofreferent as $key => $value) $urlnew=$value['urlnew']; $buttonnew=$value['buttonnew']; $testnew=$value['testnew']; - $exclude_select_element=array('payment_various',$value['exclude_select_element']); + $exclude_select_element = array('payment_various'); + if (!empty($value['exclude_select_element'])) $exclude_select_element[] = $value['exclude_select_element']; + - if ($qualified) { // If we want the project task array to have details of users From ab9bf78ecfdcc21464d3b38b642a6430e4d5a390 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sat, 1 Sep 2018 17:42:16 +0200 Subject: [PATCH 011/328] replace test_sql_and_script_inject --- htdocs/core/class/html.form.class.php | 8 +-- htdocs/main.inc.php | 4 +- test/phpunit/CoreTest.php | 79 +++++++++++++-------------- 3 files changed, 45 insertions(+), 46 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 0419e2cfc68..38bf8289ed5 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -51,12 +51,12 @@ class Form * @var DoliDB Database handler. */ public $db; - + /** * @var string Error code (or message) */ public $error=''; - + var $num; // Cache arrays @@ -1099,8 +1099,8 @@ class Form else if (!is_array($selected)) $selected = array($selected); // Clean $filter that may contains sql conditions so sql code - if (function_exists('test_sql_and_script_inject')) { - if (test_sql_and_script_inject($filter, 3)>0) { + if (function_exists('testSqlAndScriptInject')) { + if (testSqlAndScriptInject($filter, 3)>0) { $filter =''; } } diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 26dcb94a0ba..8af8147d552 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -75,7 +75,7 @@ if (function_exists('get_magic_quotes_gpc')) // magic_quotes_* deprecated in PHP * @param string $type 1=GET, 0=POST, 2=PHP_SELF, 3=GET without sql reserved keywords (the less tolerant test) * @return int >0 if there is an injection, 0 if none */ -function test_sql_and_script_inject($val, $type) +function testSqlAndScriptInject($val, $type) { $inj = 0; // For SQL Injection (only GET are used to be included into bad escaped SQL requests) @@ -158,7 +158,7 @@ function analyseVarsForSqlAndScriptsInjection(&$var, $type) } else { - return (test_sql_and_script_inject($var, $type) <= 0); + return (testSqlAndScriptInject($var, $type) <= 0); } } diff --git a/test/phpunit/CoreTest.php b/test/phpunit/CoreTest.php index c29adf0861f..14493d3dbae 100644 --- a/test/phpunit/CoreTest.php +++ b/test/phpunit/CoreTest.php @@ -257,8 +257,7 @@ class CoreTest extends PHPUnit_Framework_TestCase * @param string $type 1=GET, 0=POST, 2=PHP_SELF * @return int >0 if there is an injection */ - // phpcs:ignore PEAR.NamingConventions.ValidFunctionName.NotCamelCaps - function test_sql_and_script_inject($val, $type) + function testSqlAndScriptInject($val, $type) { $inj = 0; // For SQL Injection (only GET and POST are used to be included into bad escaped SQL requests) @@ -307,55 +306,55 @@ class CoreTest extends PHPUnit_Framework_TestCase $expectedresult=0; $_SERVER["PHP_SELF"]='/DIR WITH SPACE/htdocs/admin/index.php?mainmenu=home&leftmenu=setup&username=weservices'; - $result=test_sql_and_script_inject($_SERVER["PHP_SELF"], 2); - $this->assertEquals($expectedresult, $result, 'Error on test_sql_and_script_inject 1a'); + $result=testSqlAndScriptInject($_SERVER["PHP_SELF"], 2); + $this->assertEquals($expectedresult, $result, 'Error on testSqlAndScriptInject 1a'); // Should detect XSS $expectedresult=1; $_SERVER["PHP_SELF"]='/DIR WITH SPACE/htdocs/admin/index.php?mainmenu=home&leftmenu=setup&username=weservices;badaction'; - $result=test_sql_and_script_inject($_SERVER["PHP_SELF"], 2); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject 1b'); + $result=testSqlAndScriptInject($_SERVER["PHP_SELF"], 2); + $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject 1b'); $test=""; - $result=test_sql_and_script_inject($test, 0); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject aaa'); + $result=testSqlAndScriptInject($test, 0); + $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject aaa'); $test=""; - $result=test_sql_and_script_inject($test, 2); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject aaa2'); + $result=testSqlAndScriptInject($test, 2); + $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject aaa2'); $test=''; - $result=test_sql_and_script_inject($test, 0); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject aaa3'); + $result=testSqlAndScriptInject($test, 0); + $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject aaa3'); $test=''; - $result=test_sql_and_script_inject($test, 0); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject aaa4'); + $result=testSqlAndScriptInject($test, 0); + $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject aaa4'); $test=''; - $result=test_sql_and_script_inject($test, 0); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject aaa5'); + $result=testSqlAndScriptInject($test, 0); + $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject aaa5'); $test=''; - $result=test_sql_and_script_inject($test, 0); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject aaa6'); + $result=testSqlAndScriptInject($test, 0); + $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject aaa6'); $test=''; - $result=test_sql_and_script_inject($test, 0); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject aaa7'); + $result=testSqlAndScriptInject($test, 0); + $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject aaa7'); $test=''; - $result=test_sql_and_script_inject($test, 0); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject bbb'); + $result=testSqlAndScriptInject($test, 0); + $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject bbb'); $test=''; - $result=test_sql_and_script_inject($test, 0); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject ccc'); + $result=testSqlAndScriptInject($test, 0); + $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject ccc'); $test=''; - $result=test_sql_and_script_inject($test, 1); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject ddd'); + $result=testSqlAndScriptInject($test, 1); + $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject ddd'); $test='">'; - $result=test_sql_and_script_inject($test, 0); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject eee'); + $result=testSqlAndScriptInject($test, 0); + $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject eee'); $test=' '; - $result=test_sql_and_script_inject($test, 0); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject eee'); + $result=testSqlAndScriptInject($test, 0); + $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject eee'); $test=""; // Is locked by some brwoser like chrome because the default directive no-referrer-when-downgrade is sent when requesting the SRC and then refused because of browser protection on img src load without referrer. $test=""; // Same $test=''; - $result=test_sql_and_script_inject($test, 0); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject fff1'); + $result=testSqlAndScriptInject($test, 0); + $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject fff1'); $test=''; - $result=test_sql_and_script_inject($test, 0); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject fff2'); + $result=testSqlAndScriptInject($test, 0); + $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject fff2'); // This case seems to be filtered by browsers now. $test=''; - //$result=test_sql_and_script_inject($test, 0); - //$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject ggg'); + //$result=testSqlAndScriptInject($test, 0); + //$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject ggg'); $test='