diff --git a/.tx/config b/.tx/config index 0e71a09468e..efa9dc872a2 100644 --- a/.tx/config +++ b/.tx/config @@ -182,6 +182,12 @@ source_file = htdocs/langs/en_US/link.lang source_lang = en_US type = MOZILLAPROPERTIES +[dolibarr.loan] +file_filter = htdocs/langs//loan.lang +source_file = htdocs/langs/en_US/loan.lang +source_lang = en_US +type = MOZILLAPROPERTIES + [dolibarr.mailmanspip] file_filter = htdocs/langs//mailmanspip.lang source_file = htdocs/langs/en_US/mailmanspip.lang diff --git a/ChangeLog b/ChangeLog index b641ebf3ddb..6ed93c77235 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,13 @@ English Dolibarr ChangeLog -------------------------------------------------------------- +WARNING: Do not try to make any Dolibarr upgrade if you are running Mysql version 5.5.40. +Mysql version 5.5.40 has a very critical bug making your data beeing definitely lost. +You may also experience troubles with Mysql 5.5.41 with error "Lost connection" during migration. +Upgrading to any other version or database system is abolutely required BEFORE trying to +make a migration. + + ***** ChangeLog for 3.8 compared to 3.7.* ***** For users: - New: Add Option to not change date on cloning project diff --git a/build/rpm/dolibarr_fedora.spec b/build/rpm/dolibarr_fedora.spec index 0682f400b98..1a6371b1bf8 100755 --- a/build/rpm/dolibarr_fedora.spec +++ b/build/rpm/dolibarr_fedora.spec @@ -186,6 +186,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/install %_datadir/dolibarr/htdocs/langs/HOWTO-Translation.txt %_datadir/dolibarr/htdocs/livraison +%_datadir/dolibarr/htdocs/loan %_datadir/dolibarr/htdocs/mailmanspip %_datadir/dolibarr/htdocs/margin %_datadir/dolibarr/htdocs/opensurvey diff --git a/build/rpm/dolibarr_generic.spec b/build/rpm/dolibarr_generic.spec index 884e883d86c..59569c2c9fd 100755 --- a/build/rpm/dolibarr_generic.spec +++ b/build/rpm/dolibarr_generic.spec @@ -266,6 +266,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/install %_datadir/dolibarr/htdocs/langs/HOWTO-Translation.txt %_datadir/dolibarr/htdocs/livraison +%_datadir/dolibarr/htdocs/loan %_datadir/dolibarr/htdocs/mailmanspip %_datadir/dolibarr/htdocs/margin %_datadir/dolibarr/htdocs/opensurvey diff --git a/build/rpm/dolibarr_mandriva.spec b/build/rpm/dolibarr_mandriva.spec index e2b5309b572..0c7050ef049 100755 --- a/build/rpm/dolibarr_mandriva.spec +++ b/build/rpm/dolibarr_mandriva.spec @@ -183,6 +183,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/install %_datadir/dolibarr/htdocs/langs/HOWTO-Translation.txt %_datadir/dolibarr/htdocs/livraison +%_datadir/dolibarr/htdocs/loan %_datadir/dolibarr/htdocs/mailmanspip %_datadir/dolibarr/htdocs/margin %_datadir/dolibarr/htdocs/opensurvey diff --git a/build/rpm/dolibarr_opensuse.spec b/build/rpm/dolibarr_opensuse.spec index 3cf98a83375..34833025e81 100755 --- a/build/rpm/dolibarr_opensuse.spec +++ b/build/rpm/dolibarr_opensuse.spec @@ -194,6 +194,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/install %_datadir/dolibarr/htdocs/langs/HOWTO-Translation.txt %_datadir/dolibarr/htdocs/livraison +%_datadir/dolibarr/htdocs/loan %_datadir/dolibarr/htdocs/mailmanspip %_datadir/dolibarr/htdocs/margin %_datadir/dolibarr/htdocs/opensurvey diff --git a/dev/skeletons/skeleton_class.class.php b/dev/skeletons/skeleton_class.class.php index c59b3986a08..ff0c2f61200 100644 --- a/dev/skeletons/skeleton_class.class.php +++ b/dev/skeletons/skeleton_class.class.php @@ -221,7 +221,7 @@ class Skeleton_Class extends CommonObject $line->prop1 = $obj->field1; $line->prop2 = $obj->field2; - $this->line[]=$line; + $this->lines[]=$line; //... } $this->db->free($resql); diff --git a/htdocs/admin/loan.php b/htdocs/admin/loan.php new file mode 100644 index 00000000000..4cd22ef2c8c --- /dev/null +++ b/htdocs/admin/loan.php @@ -0,0 +1,119 @@ + + * + * 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/admin/loan.php + * \ingroup loan + * \brief Setup page to configure loan module + */ + +require '../main.inc.php'; + +// Class +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; + +$langs->load("admin"); +$langs->load("loan"); + +// Security check +if (!$user->admin) + accessforbidden(); + +$action = GETPOST('action', 'alpha'); + +// Other parameters LOAN_* +$list = array ( + 'LOAN_ACCOUNTING_ACCOUNT_CAPITAL', + 'LOAN_ACCOUNTING_ACCOUNT_INTEREST', + 'LOAN_ACCOUNTING_ACCOUNT_INSURANCE' +); + +/* + * Actions + */ + +if ($action == 'update') +{ + $error = 0; + + foreach ($list as $constname) { + $constvalue = GETPOST($constname, 'alpha'); + + if (!dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) { + $error++; + } + } + + if (! $error) + { + setEventMessage($langs->trans("SetupSaved")); + } + else + { + setEventMessage($langs->trans("Error"),'errors'); + } +} + +/* + * View + */ + +llxHeader(); + +$form = new Form($db); + +$linkback=''.$langs->trans("BackToModuleList").''; +print_fiche_titre($langs->trans('ConfigLoan'),$linkback,'setup'); + +print '
'; +print ''; +print ''; + +/* + * Params + */ +print ''; +print ''; +print ''; +print "\n"; + +foreach ($list as $key) +{ + $var=!$var; + + print ''; + + // Param + $label = $langs->trans($key); + print ''; + + // Value + print ''; +} + +print ''; + +print ''; +print "
' . $langs->trans('Options') . '
'; + print ''; + print '
\n"; + +print '
'; + +llxFooter(); +$db->close(); \ No newline at end of file diff --git a/htdocs/admin/notification.php b/htdocs/admin/notification.php index 6de3cc09665..b9c163972ce 100644 --- a/htdocs/admin/notification.php +++ b/htdocs/admin/notification.php @@ -240,7 +240,7 @@ foreach($listofnotifiedevents as $notifiedevent) } // New entry input fields $s=''; // Do not use type="email" here, we must be able to enter a list of email with , separator. - print $form->textwithpicto($s,$langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"),1,'help','',0,2); + print $form->textwithpicto($s,$langs->trans("YouCanUseCommaSeparatorForSeveralRecipients").'
'.$langs->trans("YouCanAlsoUseSupervisorKeyword"),1,'help','',0,2); print ''; print ''; diff --git a/htdocs/compta/bank/account.php b/htdocs/compta/bank/account.php index 024e21510e1..80fd211634e 100644 --- a/htdocs/compta/bank/account.php +++ b/htdocs/compta/bank/account.php @@ -37,6 +37,7 @@ require_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php' require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/tva/class/tva.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/salaries/class/paymentsalary.class.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/loan/class/loan.class.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; @@ -44,6 +45,7 @@ $langs->load("banks"); $langs->load("categories"); $langs->load("bills"); $langs->load("companies"); +$langs->load("loan"); $id = (GETPOST('id','int') ? GETPOST('id','int') : GETPOST('account','int')); $ref = GETPOST('ref','alpha'); @@ -148,6 +150,7 @@ llxHeader(); $societestatic=new Societe($db); $userstatic=new User($db); $chargestatic=new ChargeSociales($db); +$loanstatic=new Loan($db); $memberstatic=new Adherent($db); $paymentstatic=new Paiement($db); $paymentsupplierstatic=new PaiementFourn($db); @@ -606,6 +609,12 @@ if ($id > 0 || ! empty($ref)) $paymentsalstatic->ref=$links[$key]['url_id']; print ' '.$paymentsalstatic->getNomUrl(2); } + elseif ($links[$key]['type']=='payment_loan') + { + print ''; + print ' '.img_object($langs->trans('ShowPayment'),'payment').' '; + print ''; + } elseif ($links[$key]['type']=='banktransfert') { // Do not show link to transfer since there is no transfer card (avoid confusion). Can already be accessed from transaction detail. @@ -705,6 +714,21 @@ if ($id > 0 || ! empty($ref)) $chargestatic->ref=$chargestatic->lib; print $chargestatic->getNomUrl(1,16); } + else if ($links[$key]['type']=='loan') + { + $loanstatic->id=$links[$key]['url_id']; + if (preg_match('/^\((.*)\)$/i',$links[$key]['label'],$reg)) + { + if ($reg[1]=='loan') $reg[1]='Loan'; + $loanstatic->label=$langs->trans($reg[1]); + } + else + { + $loanstatic->label=$links[$key]['label']; + } + $loanstatic->ref=$loanstatic->label; + print $loanstatic->getLinkUrl(1,16); + } else if ($links[$key]['type']=='member') { $memberstatic->id=$links[$key]['url_id']; diff --git a/htdocs/compta/prelevement/list.php b/htdocs/compta/prelevement/list.php index 921736faedf..5c5a6c8ffce 100644 --- a/htdocs/compta/prelevement/list.php +++ b/htdocs/compta/prelevement/list.php @@ -127,7 +127,7 @@ if ($result) print ' '; print ''; - print '
'; + print ''; print ''; print ''; print ''; diff --git a/htdocs/compta/salaries/card.php b/htdocs/compta/salaries/card.php index 43e53140d35..e4376af61de 100644 --- a/htdocs/compta/salaries/card.php +++ b/htdocs/compta/salaries/card.php @@ -211,7 +211,7 @@ if ($action == 'create') $datesp=dol_get_first_day($pastmonthyear,$pastmonth,false); $dateep=dol_get_last_day($pastmonthyear,$pastmonth,false); } - print "\n"; + print ''; print ''; print ''; diff --git a/htdocs/conf/conf.php.example b/htdocs/conf/conf.php.example index b94893a741a..414b5c84ab7 100644 --- a/htdocs/conf/conf.php.example +++ b/htdocs/conf/conf.php.example @@ -315,12 +315,10 @@ $dolibarr_main_db_prefix=''; // multicompany_transverse_mode // Prerequisite: Need external module "multicompany" -// Pyramidal (0): The rights and groups are managed in each entity, -// users belong to the entity for their rights. -// Transversal (1): The groups can belong only to the master entity -// and that the user belongs to a particular entity +// Pyramidal (0): The rights and groups are managed in each entity. Each user belongs to the entity he was created into. +// Transversal (1): The user is created and managed only into master entity but can login to all entities. // Default value: 0 (pyramidal) // Examples: // $multicompany_transverse_mode='1'; -?> \ No newline at end of file +?> diff --git a/htdocs/core/boxes/box_activity.php b/htdocs/core/boxes/box_activity.php index 515cf26241e..7fdb3510afe 100644 --- a/htdocs/core/boxes/box_activity.php +++ b/htdocs/core/boxes/box_activity.php @@ -89,8 +89,11 @@ class box_activity extends ModeleBoxes // compute the year limit to show $tmpdate= dol_time_plus_duree(dol_now(), -1*$nbofyears, "y"); + $cumuldata = array(); + // list the summary of the bills - if (! empty($conf->facture->enabled) && $user->rights->facture->lire) { + if (! empty($conf->facture->enabled) && $user->rights->facture->lire) + { include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; $facturestatic=new Facture($db); @@ -130,9 +133,11 @@ class box_activity extends ModeleBoxes } else { $data = dol_readcachefile($cachedir, $filename); } + + $cumuldata=array_merge($cumuldata, $data); if (! empty($data)) { $j=0; - while ($line < count($data)) { + while ($line < count($cumuldata)) { $billurl="viewstatut=2&paye=1&year=".$data[$j]->annee; $this->info_box_contents[$line][0] = array( 'td' => 'align="left" width="16"', @@ -193,7 +198,7 @@ class box_activity extends ModeleBoxes $result = $db->query($sql); if ($result) { - $num = $db->num_rows($result) + $line; + $num = $db->num_rows($result); $j=0; while ($j < $num) { $data[$j]=$db->fetch_object($result); @@ -209,10 +214,12 @@ class box_activity extends ModeleBoxes } else { $data = dol_readcachefile($cachedir, $filename); } + + $cumuldata=array_merge($cumuldata, $data); if (! empty($data)) { $j=0; - while ($line < count($data)) { + while ($line < count($cumuldata)) { $billurl="viewstatut=".$data[$j]->fk_statut."&paye=0"; $this->info_box_contents[$line][0] = array( 'td' => 'align="left" width="16"', @@ -286,7 +293,7 @@ class box_activity extends ModeleBoxes $result = $db->query($sql); if ($result) { - $num = $db->num_rows($result) + $line; + $num = $db->num_rows($result); $j=0; while ($j < $num) { $data[$j]=$db->fetch_object($result); @@ -302,9 +309,11 @@ class box_activity extends ModeleBoxes } else { $data = dol_readcachefile($cachedir, $filename); } + + $cumuldata=array_merge($cumuldata, $data); if (! empty($data)) { $j=0; - while ($line < count($data)) { + while ($line < count($cumuldata)) { $this->info_box_contents[$line][0] = array( 'td' => 'align="left" width="16"', 'url' => DOL_URL_ROOT."/commande/list.php?mainmenu=commercial&leftmenu=orders&viewstatut=".$data[$j]->fk_statut, @@ -369,7 +378,8 @@ class box_activity extends ModeleBoxes $result = $db->query($sql); if ($result) { - $num = $db->num_rows($result) + $line; + $num = $db->num_rows($result); + $j=0; while ($j < $num) { $data[$j]=$db->fetch_object($result); @@ -388,24 +398,25 @@ class box_activity extends ModeleBoxes $data = dol_readcachefile($cachedir, $filename); } + $cumuldata=array_merge($cumuldata, $data); if (! empty($data)) { $j=0; - while ($line < count($data)) + while ($line < count($cumuldata)) { - $this->info_box_contents[$line][] = array( + $this->info_box_contents[$line][0] = array( 'td' => 'align="left" width="16"', 'url' => DOL_URL_ROOT."/comm/propal/list.php?mainmenu=commercial&leftmenu=propals&viewstatut=".$data[$j]->fk_statut, 'tooltip' => $langs->trans("Proposals")." ".$propalstatic->LibStatut($data[$j]->fk_statut,0), 'logo' => 'object_propal' ); - $this->info_box_contents[$line][] = array( + $this->info_box_contents[$line][1] = array( 'td' => 'align="left"', 'text' => $langs->trans("Proposals")." ".$propalstatic->LibStatut($data[$j]->fk_statut,0), ); - $this->info_box_contents[$line][] = array( + $this->info_box_contents[$line][2] = array( 'td' => 'align="right"', 'text' => $data[$j]->nb, 'tooltip' => $langs->trans("Proposals")." ".$propalstatic->LibStatut($data[$j]->fk_statut,0), @@ -413,12 +424,12 @@ class box_activity extends ModeleBoxes ); $totalnb += $data[$j]->nb; - $this->info_box_contents[$line][] = array( + $this->info_box_contents[$line][3] = array( 'td' => 'align="right"', 'text' => price($data[$j]->Mnttot,1,$langs,0,0,-1,$conf->currency), ); $totalMnt += $data[$j]->Mnttot; - $this->info_box_contents[$line][] = array( + $this->info_box_contents[$line][4] = array( 'td' => 'align="right" width="18"', 'text' => $propalstatic->LibStatut($data[$j]->fk_statut,3), ); @@ -429,38 +440,24 @@ class box_activity extends ModeleBoxes } } - // Add the sum in the bottom of the boxes - $this->info_box_contents[$line][1] = array( - 'td' => 'align="left" ', - 'text' => $langs->trans("Total")." ".$textHead, - ); - $this->info_box_contents[$line][2] = array( - 'td' => 'align="right" ', - 'text' => $totalnb, - ); - $this->info_box_contents[$line][3] = array( - 'td' => 'align="right" ', - 'text' => price($totalMnt,1,$langs,0,0,-1,$conf->currency) - ); - $this->info_box_contents[$line][4] = array( - 'td' => 'align="right" ', - 'text' => "", - ); - $this->info_box_contents[$line][5] = array( - 'td' => 'align="right"', - 'text' => "", - ); + // Add the sum in the bottom of the boxes + $this->info_box_contents[$line][0] = array('tr' => 'class="liste_total"'); + $this->info_box_contents[$line][1] = array('td' => 'align="left" class="liste_total" ', 'text' => $langs->trans("Total")." ".$textHead); + $this->info_box_contents[$line][2] = array('td' => 'align="right" class="liste_total" ', 'text' => $totalnb); + $this->info_box_contents[$line][3] = array('td' => 'align="right" class="liste_total" ', 'text' => ''); + $this->info_box_contents[$line][4] = array('td' => 'align="right" class="liste_total" ', 'text' => ""); } - /** - * Method to show box - * - * @param array $head Array with properties of box title - * @param array $contents Array with properties of box lines - * @return void - */ - function showBox($head = null, $contents = null) - { - parent::showBox($this->info_box_head, $this->info_box_contents); - } + + /** + * Method to show box + * + * @param array $head Array with properties of box title + * @param array $contents Array with properties of box lines + * @return void + */ + function showBox($head = null, $contents = null) + { + parent::showBox($this->info_box_head, $this->info_box_contents); + } } diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index b6cc390ca33..6370062a6a9 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -379,16 +379,6 @@ class Conf $this->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER=1; } - if (! empty($conf->productbatch->enabled)) - { - $this->global->STOCK_CALCULATE_ON_BILL=0; - $this->global->STOCK_CALCULATE_ON_VALIDATE_ORDER=0; - $this->global->STOCK_CALCULATE_ON_SHIPMENT=1; - $this->global->STOCK_CALCULATE_ON_SUPPLIER_BILL=0; - $this->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER=0; - $this->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER=1; - } - // conf->currency if (empty($this->global->MAIN_MONNAIE)) $this->global->MAIN_MONNAIE='EUR'; $this->currency=$this->global->MAIN_MONNAIE; @@ -448,6 +438,9 @@ class Conf // Default pdf use dash between lines if (! isset($this->global->MAIN_PDF_DASH_BETWEEN_LINES)) $this->global->MAIN_PDF_DASH_BETWEEN_LINES=1; + // Set default value to MAIN_SHOW_LOGO + if (! isset($this->global->MAIN_SHOW_LOGO)) $this->global->MAIN_SHOW_LOGO=1; + // Default max file size for upload $this->maxfilesize = (empty($this->global->MAIN_UPLOAD_DOC) ? 0 : $this->global->MAIN_UPLOAD_DOC * 1024); @@ -455,8 +448,8 @@ class Conf if (! isset($this->global->MAIN_MODULES_FOR_EXTERNAL)) $this->global->MAIN_MODULES_FOR_EXTERNAL='user,askpricesupplier,facture,categorie,commande,fournisseur,contact,propal,projet,contrat,societe,ficheinter,expedition,agenda,adherent'; // '' means 'all'. Note that contact is added here as it should be a module later. // Enable select2 - if (empty($conf->global->MAIN_USE_JQUERY_MULTISELECT)) $conf->global->MAIN_USE_JQUERY_MULTISELECT='select2'; - + if (empty($this->global->MAIN_USE_JQUERY_MULTISELECT)) $this->global->MAIN_USE_JQUERY_MULTISELECT='select2'; + // Timeouts if (empty($this->global->MAIN_USE_CONNECT_TIMEOUT)) $this->global->MAIN_USE_CONNECT_TIMEOUT=10; if (empty($this->global->MAIN_USE_RESPONSE_TIMEOUT)) $this->global->MAIN_USE_RESPONSE_TIMEOUT=30; diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php index aa92e6ee50f..8d54d05a810 100644 --- a/htdocs/core/class/notify.class.php +++ b/htdocs/core/class/notify.class.php @@ -91,7 +91,8 @@ class Notify $error=0; $num=0; - $valueforthreshold = $object->total_ht; + $valueforthreshold = 0; + if (is_object($object)) $valueforthreshold = $object->total_ht; if (! $error) { @@ -103,8 +104,11 @@ class Notify $sql.= " WHERE n.fk_contact = c.rowid"; $sql.= " AND a.rowid = n.fk_action"; $sql.= " AND n.fk_soc = s.rowid"; - if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode; // Old usage - else $sql.= " AND a.code = '".$notifcode."'"; // New usage + if ($notifcode) + { + if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode; // Old usage + else $sql.= " AND a.code = '".$notifcode."'"; // New usage + } $sql.= " AND s.entity IN (".getEntity('societe', 1).")"; if ($socid > 0) $sql.= " AND s.rowid = ".$socid; @@ -125,16 +129,21 @@ class Notify if (! $error) { + // List of notifications enabled for fixed email foreach($conf->global as $key => $val) { - if ($val == '' || ! preg_match('/^NOTIFICATION_FIXEDEMAIL_'.$notifcode.'_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) continue; + if ($notifcode) + { + if ($val == '' || ! preg_match('/^NOTIFICATION_FIXEDEMAIL_'.$notifcode.'_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) continue; + } + else + { + if ($val == '' || ! preg_match('/^NOTIFICATION_FIXEDEMAIL_.*_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) continue; + } $threshold = (float) $reg[1]; - if ($valueforthreshold <= $threshold) - { - continue; - } + if ($valueforthreshold < $threshold) continue; $tmpemail=explode(',',$val); $num+=count($tmpemail); diff --git a/htdocs/core/get_menudiv.php b/htdocs/core/get_menudiv.php index b52c1f73c98..b8eae83d4eb 100644 --- a/htdocs/core/get_menudiv.php +++ b/htdocs/core/get_menudiv.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2005-2015 Laurent Destailleur * * This file is a modified version of datepicker.php from phpBSM to fix some * bugs, to add new features and to dramatically increase speed. diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index cfa5a945841..8abdf32c635 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -471,7 +471,7 @@ function show_projects($conf,$langs,$db,$object,$backtopage='') print_fiche_titre($langs->trans("ProjectsDedicatedToThisThirdParty"),$buttoncreate,''); print "\n".''; - $sql = "SELECT p.rowid,p.title,p.ref,p.public, p.dateo as do, p.datee as de"; + $sql = "SELECT p.rowid as id, p.title, p.ref, p.public, p.dateo as do, p.datee as de, p.fk_statut as status"; $sql .= " FROM ".MAIN_DB_PREFIX."projet as p"; $sql .= " WHERE p.fk_soc = ".$object->id; $sql .= " ORDER BY p.dateo DESC"; @@ -483,23 +483,24 @@ function show_projects($conf,$langs,$db,$object,$backtopage='') print ''; print ''; + print ''; print ''; if ($num > 0) { require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; - $projectstatic = new Project($db); + $projecttmp = new Project($db); $i=0; $var=false; while ($i < $num) { $obj = $db->fetch_object($result); - $projectstatic->fetch($obj->rowid); + $projecttmp->fetch($obj->id); // To verify role of users - $userAccess = $projectstatic->restrictedProjectArea($user); + $userAccess = $projecttmp->restrictedProjectArea($user); if ($user->rights->projet->lire && $userAccess > 0) { @@ -507,13 +508,15 @@ function show_projects($conf,$langs,$db,$object,$backtopage='') print ""; // Ref - print ''; + print ''; // Label print ''; // Date start print ''; // Date end print ''; + // Status + print ''; print ''; } diff --git a/htdocs/core/lib/loan.lib.php b/htdocs/core/lib/loan.lib.php new file mode 100644 index 00000000000..323516bbbd6 --- /dev/null +++ b/htdocs/core/lib/loan.lib.php @@ -0,0 +1,66 @@ + + * + * 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/core/lib/loan.lib.php + * \ingroup loan + * \brief Library for loan module + */ + + +/** + * Prepare array with list of tabs + * + * @param Object $object Object related to tabs + * @return array Array of tabs to show + */ +function loan_prepare_head($object) +{ + global $langs, $conf; + + $h = 0; + $head = array(); + + $head[$h][0] = DOL_URL_ROOT.'/loan/card.php?id='.$object->id; + $head[$h][1] = $langs->trans('Card'); + $head[$h][2] = 'card'; + $h++; + + // Show more tabs from modules + // Entries must be declared in modules descriptor with line + // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab + // $this->tabs = array('entity:-tabname); to remove a tab + complete_head_from_modules($conf,$langs,$object,$head,$h,'loan'); + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + $upload_dir = $conf->loan->dir_output . "/" . dol_sanitizeFileName($object->ref); + $nbFiles = count(dol_dir_list($upload_dir,'files',0,'','(\.meta|_preview\.png)$')); + $head[$h][0] = DOL_URL_ROOT.'/loan/document.php?id='.$object->id; + $head[$h][1] = $langs->trans("Documents"); + if($nbFiles > 0) $head[$h][1].= ' ('.$nbFiles.')'; + $head[$h][2] = 'documents'; + $h++; + + $head[$h][0] = DOL_URL_ROOT.'/loan/info.php?id='.$object->id; + $head[$h][1] = $langs->trans("Info"); + $head[$h][2] = 'info'; + $h++; + + complete_head_from_modules($conf,$langs,$object,$head,$h,'loan','remove'); + + return $head; +} \ No newline at end of file diff --git a/htdocs/core/login/functions_dolibarr.php b/htdocs/core/login/functions_dolibarr.php index 8e5a8b13ea9..69aec814413 100644 --- a/htdocs/core/login/functions_dolibarr.php +++ b/htdocs/core/login/functions_dolibarr.php @@ -36,9 +36,6 @@ function check_user_password_dolibarr($usertotest,$passwordtotest,$entitytotest=1) { global $db,$conf,$langs; - global $mc; - - dol_syslog("functions_dolibarr::check_user_password_dolibarr usertotest=".$usertotest); // Force master entity in transversal mode $entity=$entitytotest; @@ -48,6 +45,8 @@ function check_user_password_dolibarr($usertotest,$passwordtotest,$entitytotest= if (! empty($usertotest)) { + dol_syslog("functions_dolibarr::check_user_password_dolibarr usertotest=".$usertotest." passwordtotest=".preg_replace('/./','*',$passwordtotest)." entitytotest=".$entitytotest); + // If test username/password asked, we define $test=false and $login var if ok, set $_SESSION["dol_loginmesg"] if ko $table = MAIN_DB_PREFIX."user"; $usernamecol1 = 'login'; @@ -60,7 +59,6 @@ function check_user_password_dolibarr($usertotest,$passwordtotest,$entitytotest= if (preg_match('/@/',$usertotest)) $sql.=' OR '.$usernamecol2." = '".$db->escape($usertotest)."'"; $sql.=') AND '.$entitycol." IN (0," . ($entity ? $entity : 1) . ")"; - dol_syslog("functions_dolibarr::check_user_password_dolibarr", LOG_DEBUG); $resql=$db->query($sql); if ($resql) { @@ -99,12 +97,6 @@ function check_user_password_dolibarr($usertotest,$passwordtotest,$entitytotest= } } - if ($passok && ! empty($obj->entity) && (! empty($conf->multicompany->enabled) && ! empty($conf->multicompany->transverse_mode))) - { - $ret=$mc->checkRight($obj->rowid, $entitytotest); - if ($ret < 0) $passok=false; - } - // Password ok ? if ($passok) { @@ -112,12 +104,24 @@ function check_user_password_dolibarr($usertotest,$passwordtotest,$entitytotest= } else { - dol_syslog("functions_dolibarr::check_user_password_dolibarr Authentification ko bad password pour '".$usertotest."'"); + dol_syslog("functions_dolibarr::check_user_password_dolibarr Authentification ko bad password for '".$usertotest."'"); sleep(1); $langs->load('main'); $langs->load('errors'); $_SESSION["dol_loginmesg"]=$langs->trans("ErrorBadLoginPassword"); } + + if ($passok && ! empty($conf->multicompany->enabled)) // We must check entity + { + global $mc; + + $ret=$mc->checkRight($obj->rowid, $entitytotest); + if ($ret < 0) + { + dol_syslog("functions_dolibarr::check_user_password_dolibarr Authentification ko entity '".$entitytotest."' not allowed for user '".$obj->rowid."'"); + $login=''; // force authentication failure + } + } } else { diff --git a/htdocs/core/login/functions_ldap.php b/htdocs/core/login/functions_ldap.php index 88a5f55de19..208ccd0c37c 100644 --- a/htdocs/core/login/functions_ldap.php +++ b/htdocs/core/login/functions_ldap.php @@ -34,7 +34,8 @@ */ function check_user_password_ldap($usertotest,$passwordtotest,$entitytotest) { - global $_POST,$db,$conf,$langs; + global $db,$conf,$langs; + global $_POST; global $dolibarr_main_auth_ldap_host,$dolibarr_main_auth_ldap_port; global $dolibarr_main_auth_ldap_version,$dolibarr_main_auth_ldap_servertype; global $dolibarr_main_auth_ldap_login_attribute,$dolibarr_main_auth_ldap_dn; @@ -42,6 +43,13 @@ function check_user_password_ldap($usertotest,$passwordtotest,$entitytotest) global $dolibarr_main_auth_ldap_filter; global $dolibarr_main_auth_ldap_debug; + // Force master entity in transversal mode + $entity=$entitytotest; + if (! empty($conf->multicompany->enabled) && ! empty($conf->multicompany->transverse_mode)) $entity=1; + + $login=''; + $resultFetchUser=''; + if (! function_exists("ldap_connect")) { dol_syslog("functions_ldap::check_user_password_ldap Authentification ko failed to connect to LDAP. LDAP functions are disabled on this PHP"); @@ -52,11 +60,10 @@ function check_user_password_ldap($usertotest,$passwordtotest,$entitytotest) return; } - $login=''; - $resultFetchUser=''; - - if (!empty($_POST["username"]) || $usertotest) + if ($usertotest) { + dol_syslog("functions_ldap::check_user_password_ldap usertotest=".$usertotest." passwordtotest=".preg_replace('/./','*',$passwordtotest)." entitytotest=".$entitytotest); + // If test username/password asked, we define $test=false and $login var if ok, set $_SESSION["dol_loginmesg"] if ko $ldaphost=$dolibarr_main_auth_ldap_host; $ldapport=$dolibarr_main_auth_ldap_port; @@ -80,7 +87,6 @@ function check_user_password_ldap($usertotest,$passwordtotest,$entitytotest) $ldap->searchUser=$ldapadminlogin; $ldap->searchPassword=$ldapadminpass; - dol_syslog("functions_ldap::check_user_password_ldap usertotest=".$usertotest); if ($ldapdebug) { dol_syslog("functions_ldap::check_user_password_ldap Server:".join(',',$ldap->server).", Port:".$ldap->serverPort.", Protocol:".$ldap->ldapProtocolVersion.", Type:".$ldap->serverType); @@ -146,47 +152,56 @@ function check_user_password_ldap($usertotest,$passwordtotest,$entitytotest) $login=$usertotest; // ldap2dolibarr synchronisation - if ($login && ! empty($conf->ldap->enabled) && $conf->global->LDAP_SYNCHRO_ACTIVE == 'ldap2dolibarr') + if ($login && ! empty($conf->ldap->enabled) && $conf->global->LDAP_SYNCHRO_ACTIVE == 'ldap2dolibarr') // ldap2dolibarr synchronisation { - dol_syslog("functions_ldap::check_user_password_ldap Sync ldap2dolibarr"); + dol_syslog("functions_ldap::check_user_password_ldap Sync ldap2dolibarr"); - // On charge les attributs du user ldap - if ($ldapdebug) print "DEBUG: login ldap = ".$login."
\n"; - $resultFetchLdapUser = $ldap->fetch($login,$userSearchFilter); + // On charge les attributs du user ldap + if ($ldapdebug) print "DEBUG: login ldap = ".$login."
\n"; + $resultFetchLdapUser = $ldap->fetch($login,$userSearchFilter); - if ($ldapdebug) print "DEBUG: UACF = ".join(',',$ldap->uacf)."
\n"; - if ($ldapdebug) print "DEBUG: pwdLastSet = ".dol_print_date($ldap->pwdlastset,'day')."
\n"; - if ($ldapdebug) print "DEBUG: badPasswordTime = ".dol_print_date($ldap->badpwdtime,'day')."
\n"; + if ($ldapdebug) print "DEBUG: UACF = ".join(',',$ldap->uacf)."
\n"; + if ($ldapdebug) print "DEBUG: pwdLastSet = ".dol_print_date($ldap->pwdlastset,'day')."
\n"; + if ($ldapdebug) print "DEBUG: badPasswordTime = ".dol_print_date($ldap->badpwdtime,'day')."
\n"; - // On recherche le user dolibarr en fonction de son SID ldap - $sid = $ldap->getObjectSid($login); - if ($ldapdebug) print "DEBUG: sid = ".$sid."
\n"; + // On recherche le user dolibarr en fonction de son SID ldap + $sid = $ldap->getObjectSid($login); + if ($ldapdebug) print "DEBUG: sid = ".$sid."
\n"; - $user=new User($db); - $resultFetchUser=$user->fetch('',$login,$sid); - if ($resultFetchUser > 0) - { - dol_syslog("functions_ldap::check_user_password_ldap Sync user found id=".$user->id); - // On verifie si le login a change et on met a jour les attributs dolibarr - - if ($conf->multicompany->enabled) { - global $mc; - - $ret=$mc->checkRight($user->id, $entitytotest); - if ($ret < 0) $login=false; // provoque l'echec de l'identification - } - - - if ($user->login != $ldap->login && $ldap->login) + $usertmp=new User($db); + $resultFetchUser=$usertmp->fetch('',$login,$sid); + if ($resultFetchUser > 0) { - $user->login = $ldap->login; - $user->update($user); - // TODO Que faire si update echoue car on update avec un login deja existant. - } + dol_syslog("functions_ldap::check_user_password_ldap Sync user found user id=".$usertmp->id); + // On verifie si le login a change et on met a jour les attributs dolibarr - //$resultUpdate = $user->update_ldap2dolibarr($ldap); - } + if ($usertmp->login != $ldap->login && $ldap->login) + { + $usertmp->login = $ldap->login; + $usertmp->update($usertmp); + // TODO Que faire si update echoue car on update avec un login deja existant. + } + + //$resultUpdate = $usertmp->update_ldap2dolibarr($ldap); + } + unset($usertmp); } + + if (! empty($conf->multicompany->enabled)) // We must check entity (even if sync is not active) + { + global $mc; + + $usertmp=new User($db); + $usertmp->fetch('',$login); + $ret=$mc->checkRight($usertmp->id, $entitytotest); + if ($ret < 0) + { + dol_syslog("functions_ldap::check_user_password_ldap Authentification ko entity '".$entitytotest."' not allowed for user '".$usertmp->id."'"); + $login=''; // force authentication failure + } + unset($usertmp); + } + } if ($result == 1) { diff --git a/htdocs/core/menus/init_menu_auguria.sql b/htdocs/core/menus/init_menu_auguria.sql index ec265cd4d3f..c385eaab4bf 100644 --- a/htdocs/core/menus/init_menu_auguria.sql +++ b/htdocs/core/menus/init_menu_auguria.sql @@ -12,7 +12,7 @@ insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, left insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('societe|fournisseur', '( ! empty($conf->societe->enabled) && (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) || empty($conf->global->SOCIETE_DISABLE_CUSTOMERS))) || ! empty($conf->fournisseur->enabled)', 2__+MAX_llx_menu__, __HANDLER__, 'top', 'companies', '', 0, '/societe/index.php?mainmenu=companies&leftmenu=', 'ThirdParties', -1, 'companies', '$user->rights->societe->lire || $user->rights->societe->contact->lire', '', 2, 20, __ENTITY__); insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('product|service', '$conf->product->enabled || $conf->service->enabled', 3__+MAX_llx_menu__, __HANDLER__, 'top', 'products', '', 0, '/product/index.php?mainmenu=products&leftmenu=', 'Products/Services', -1, 'products', '$user->rights->produit->lire||$user->rights->service->lire', '', 0, 30, __ENTITY__); insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('propal|commande|fournisseur|contrat|ficheinter', '$conf->propal->enabled || $conf->commande->enabled || $conf->fournisseur->enabled || $conf->contrat->enabled || $conf->ficheinter->enabled', 5__+MAX_llx_menu__, __HANDLER__, 'top', 'commercial', '', 0, '/comm/index.php?mainmenu=commercial&leftmenu=', 'Commercial', -1, 'commercial', '$user->rights->societe->lire || $user->rights->societe->contact->lire', '', 2, 40, __ENTITY__); -insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('comptabilite|accounting|facture|deplacement|don|tax|salaries', '$conf->comptabilite->enabled || $conf->accounting->enabled || $conf->facture->enabled || $conf->deplacement->enabled || $conf->don->enabled || $conf->tax->enabled || $conf->salaries->enabled', 6__+MAX_llx_menu__, __HANDLER__, 'top', 'accountancy', '', 0, '/compta/index.php?mainmenu=accountancy&leftmenu=', 'MenuFinancial', -1, 'compta', '$user->rights->compta->resultat->lire || $user->rights->accounting->plancompte->lire || $user->rights->facture->lire|| $user->rights->deplacement->lire || $user->rights->don->lire || $user->rights->tax->charges->lire || $user->rights->salaries->read', '', 2, 50, __ENTITY__); +insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('comptabilite|accounting|facture|deplacement|don|tax|salaries|loan', '$conf->comptabilite->enabled || $conf->accounting->enabled || $conf->facture->enabled || $conf->deplacement->enabled || $conf->don->enabled || $conf->tax->enabled || $conf->salaries->enabled || $conf->loan->enabled', 6__+MAX_llx_menu__, __HANDLER__, 'top', 'accountancy', '', 0, '/compta/index.php?mainmenu=accountancy&leftmenu=', 'MenuFinancial', -1, 'compta', '$user->rights->compta->resultat->lire || $user->rights->accounting->plancompte->lire || $user->rights->facture->lire|| $user->rights->deplacement->lire || $user->rights->don->lire || $user->rights->tax->charges->lire || $user->rights->salaries->read || $user->rights->loan->read', '', 2, 50, __ENTITY__); insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('banque|prelevement', '$conf->banque->enabled || $conf->prelevement->enabled', 14__+MAX_llx_menu__, __HANDLER__, 'top', 'bank', '', 0, '/compta/bank/index.php?mainmenu=bank&leftmenu=bank', 'MenuBankCash', -1, 'banks', '$user->rights->banque->lire || $user->rights->prelevement->bons->lire', '', 0, 60, __ENTITY__); insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('projet', '$conf->projet->enabled', 7__+MAX_llx_menu__, __HANDLER__, 'top', 'project', '', 0, '/projet/index.php?mainmenu=project&leftmenu=', 'Projects', -1, 'projects', '$user->rights->projet->lire', '', 2, 70, __ENTITY__); insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('mailing|export|import|opensurvey', '$conf->mailing->enabled || $conf->export->enabled || $conf->import->enabled || $conf->opensurvey->enabled', 8__+MAX_llx_menu__, __HANDLER__, 'top', 'tools', '', 0, '/core/tools.php?mainmenu=tools&leftmenu=', 'Tools', -1, 'other', '$user->rights->mailing->lire || $user->rights->export->lire || $user->rights->import->run || $user->rights->opensurvey->read', '', 2, 90, __ENTITY__); @@ -181,6 +181,10 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->salaries->enabled', __HANDLER__, 'left', 2210__+MAX_llx_menu__, 'accountancy', 'tax_sal', 2200__+MAX_llx_menu__, '/compta/salaries/index.php?leftmenu=tax_salary&mainmenu=accountancy', 'Salaries', 1, 'salaries', '$user->rights->salaries->read', '', 0, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->salaries->enabled && $leftmenu=="tax_salary"', __HANDLER__, 'left', 2211__+MAX_llx_menu__, 'accountancy', '', 2210__+MAX_llx_menu__, '/compta/salaries/card.php?leftmenu=tax_salary&action=create', 'NewPayment', 2, 'companies', '$user->rights->salaries->write', '', 0, 2, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->salaries->enabled && $leftmenu=="tax_salary"', __HANDLER__, 'left', 2212__+MAX_llx_menu__, 'accountancy', '', 2210__+MAX_llx_menu__, '/compta/salaries/index.php?leftmenu=tax_salary', 'Payments', 2, 'companies', '$user->rights->salaries->read', '', 0, 3, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->loan->enabled', __HANDLER__, 'left', 2220__+MAX_llx_menu__, 'accountancy', 'tax_loan', 2200__+MAX_llx_menu__, '/loan/index.php?leftmenu=tax_loan&mainmenu=accountancy', 'Loans', 1, 'loan', '$user->rights->loan->read', '', 0, 1, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->loan->enabled && $leftmenu=="tax_loan"', __HANDLER__, 'left', 2221__+MAX_llx_menu__, 'accountancy', '', 2220__+MAX_llx_menu__, '/loan/card.php?leftmenu=tax_loan&action=create', 'NewLoan', 2, 'loan', '$user->rights->loan->write', '', 0, 2, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->loan->enabled && $leftmenu=="tax_loan"', __HANDLER__, 'left', 2222__+MAX_llx_menu__, 'accountancy', '', 2220__+MAX_llx_menu__, '/loan/index.php?leftmenu=tax_loan', 'Payments', 2, 'companies', '$user->rights->loan->read', '', 0, 3, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->loan->enabled && $leftmenu=="tax_loan"', __HANDLER__, 'left', 2223__+MAX_llx_menu__, 'accountancy', '', 2220__+MAX_llx_menu__, '/loan/calc.php?leftmenu=tax_loan', 'Calculator', 2, 'companies', '$user->rights->loan->calc', '', 0, 4, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->tax->enabled', __HANDLER__, 'left', 2250__+MAX_llx_menu__, 'accountancy', 'tax_social', 2200__+MAX_llx_menu__, '/compta/sociales/index.php?leftmenu=tax_social', 'SocialContributions', 1, '', '$user->rights->tax->charges->lire', '', 0, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->tax->enabled && $leftmenu=="tax_social"', __HANDLER__, 'left', 2251__+MAX_llx_menu__, 'accountancy', '', 2250__+MAX_llx_menu__, '/compta/sociales/charges.php?leftmenu=tax_social&action=create', 'MenuNewSocialContribution', 2, '', '$user->rights->tax->charges->creer', '', 0, 2, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->tax->enabled && $leftmenu=="tax_social"', __HANDLER__, 'left', 2252__+MAX_llx_menu__, 'accountancy', '', 2250__+MAX_llx_menu__, '/compta/charges/index.php?leftmenu=tax_social&mainmenu=accountancy&mode=sconly', 'Payments', 2, '', '$user->rights->tax->charges->lire', '', 0, 3, __ENTITY__); diff --git a/htdocs/core/menus/standard/auguria.lib.php b/htdocs/core/menus/standard/auguria.lib.php index cbc73b2767d..59c0329b172 100644 --- a/htdocs/core/menus/standard/auguria.lib.php +++ b/htdocs/core/menus/standard/auguria.lib.php @@ -220,22 +220,27 @@ function print_left_auguria_menu($db,$menu_array_before,$menu_array_after,&$tabM $leftmenu=($forceleftmenu?'':(empty($_SESSION["leftmenu"])?'none':$_SESSION["leftmenu"])); // Show logo company - if (empty($noout) && ! empty($conf->global->MAIN_SHOW_LOGO)) + if (empty($noout) && ! empty($conf->global->MAIN_SHOW_LOGO) && empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $mysoc->logo_mini=$conf->global->MAIN_INFO_SOCIETE_LOGO_MINI; if (! empty($mysoc->logo_mini) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_mini)) { $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=companylogo&file='.urlencode('thumbs/'.$mysoc->logo_mini); - print "\n".''."\n"; - print '
'."\n"; - print ''; - print ''; - print ''; - print ''; - print '
'."\n"; } + else + { + $urllogo=DOL_URL_ROOT.'/theme/dolibarr_logo.png'; + } + $title=$langs->trans("GoIntoSetupToChangeLogo"); + print "\n".''."\n"; + print '
'."\n"; + print ''; + print ''; + print ''; + print ''; + print '
'."\n"; } // We update newmenu with entries found into database diff --git a/htdocs/core/menus/standard/auguria_menu.php b/htdocs/core/menus/standard/auguria_menu.php index 36ecfd7effa..b54c746388e 100644 --- a/htdocs/core/menus/standard/auguria_menu.php +++ b/htdocs/core/menus/standard/auguria_menu.php @@ -218,18 +218,42 @@ class MenuManager } foreach($submenu->liste as $key2 => $val2) // $val['url','titre','level','enabled'=0|1|2,'target','mainmenu','leftmenu' { - $relurl2=dol_buildpath($val2['url'],1); - $relurl2=preg_replace('/__LOGIN__/',$user->login,$relurl2); - $relurl2=preg_replace('/__USERID__/',$user->id,$relurl2); - $canonurl2=preg_replace('/\?.*$/','',$val2['url']); - //var_dump($val2['url'].' - '.$canonurl2.' - '.$val2['level']); - if (in_array($canonurl2,array('/admin/index.php','/admin/tools/index.php','/core/tools.php'))) $relurl2=''; - if ($val2['level']==0) print str_pad('',$val2['level']+1).''; // ui-btn to highlight on clic - else print str_pad('',$val2['level']+1).'
  • '; // ui-btn to highlight on clic - if ($relurl2) print ''; - print $val2['titre']; - if ($relurl2) print ''; - print '
  • '."\n"; + $showmenu=true; + if (! empty($conf->global->MAIN_MENU_HIDE_UNAUTHORIZED) && empty($val2['enabled'])) $showmenu=false; + + if ($showmenu) // Visible (option to hide when not allowed is off or allowed) + { + $relurl2=dol_buildpath($val2['url'],1); + $relurl2=preg_replace('/__LOGIN__/',$user->login,$relurl2); + $relurl2=preg_replace('/__USERID__/',$user->id,$relurl2); + $canonurl2=preg_replace('/\?.*$/','',$val2['url']); + //var_dump($val2['url'].' - '.$canonurl2.' - '.$val2['level']); + if (in_array($canonurl2,array('/admin/index.php','/admin/tools/index.php','/core/tools.php'))) $relurl2=''; + if ($val2['level']==0) print str_pad('',$val2['level']+1).''; // ui-btn to highlight on clic + else print str_pad('',$val2['level']+1).'
  • '; // ui-btn to highlight on clic + if ($relurl2) + { + if ($val2['enabled']) // Allowed + { + print ''; + } + else // Not allowed but visible (greyed) + { + print ''; + } + } + print $val2['titre']; + if ($relurl2) + { + if ($val2['enabled']) // Allowed + print ''; + else + print ''; + } + print '
  • '."\n"; + } } //var_dump($submenu); print ''; diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 7c6ef944f7c..32fc9a07aed 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -3,6 +3,7 @@ * Copyright (C) 2010 Regis Houssin * Copyright (C) 2012-2014 Juanjo Menent * Copyright (C) 2013 Cédric Salvador + * Copyright (C) 2015 Marcos García * * 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 @@ -134,9 +135,9 @@ function print_eldy_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0) } // Financial - $tmpentry=array('enabled'=>(! empty($conf->comptabilite->enabled) || ! empty($conf->accounting->enabled) || ! empty($conf->facture->enabled) || ! empty($conf->don->enabled) || ! empty($conf->tax->enabled) || ! empty($conf->salaries->enabled)), - 'perms'=>(! empty($user->rights->compta->resultat->lire) || ! empty($user->rights->accounting->plancompte->lire) || ! empty($user->rights->facture->lire) || ! empty($user->rights->don->lire) || ! empty($user->rights->tax->charges->lire) || ! empty($user->rights->salaries->read)), - 'module'=>'comptabilite|accounting|facture|don|tax|salaries'); + $tmpentry=array('enabled'=>(! empty($conf->comptabilite->enabled) || ! empty($conf->accounting->enabled) || ! empty($conf->facture->enabled) || ! empty($conf->don->enabled) || ! empty($conf->tax->enabled) || ! empty($conf->salaries->enabled) || ! empty($conf->loan->enabled)), + 'perms'=>(! empty($user->rights->compta->resultat->lire) || ! empty($user->rights->accounting->plancompte->lire) || ! empty($user->rights->facture->lire) || ! empty($user->rights->don->lire) || ! empty($user->rights->tax->charges->lire) || ! empty($user->rights->salaries->read) || ! empty($user->rights->loan->read)), + 'module'=>'comptabilite|accounting|facture|don|tax|salaries|loan'); $showmode=dol_eldy_showmenu($type_user, $tmpentry, $listofmodulesforexternal); if ($showmode) { @@ -425,22 +426,27 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $leftmenu=($forceleftmenu?'':(empty($_SESSION["leftmenu"])?'none':$_SESSION["leftmenu"])); // Show logo company - if (empty($conf->global->MAIN_MENU_INVERT) && empty($noout) && ! empty($conf->global->MAIN_SHOW_LOGO)) + if (empty($conf->global->MAIN_MENU_INVERT) && empty($noout) && ! empty($conf->global->MAIN_SHOW_LOGO) && empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $mysoc->logo_mini=$conf->global->MAIN_INFO_SOCIETE_LOGO_MINI; if (! empty($mysoc->logo_mini) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_mini)) { $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=companylogo&file='.urlencode('thumbs/'.$mysoc->logo_mini); - print "\n".''."\n"; - print '
    '."\n"; - print ''; - print ''; - print ''; - print ''; - print '
    '."\n"; } + else + { + $urllogo=DOL_URL_ROOT.'/theme/dolibarr_logo.png'; + } + $title=$langs->trans("GoIntoSetupToChangeLogo"); + print "\n".''."\n"; + print '
    '."\n"; + print ''; + print ''; + print ''; + print ''; + print '
    '."\n"; } /** @@ -738,8 +744,14 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $newmenu->add("/compta/facture/list.php?leftmenu=customers_bills",$langs->trans("BillsCustomers"),0,$user->rights->facture->lire, '', $mainmenu, 'customers_bills'); $newmenu->add("/compta/facture.php?action=create&leftmenu=customers_bills",$langs->trans("NewBill"),1,$user->rights->facture->creer); $newmenu->add("/compta/facture/fiche-rec.php?leftmenu=customers_bills",$langs->trans("Repeatables"),1,$user->rights->facture->lire); + $newmenu->add("/compta/facture/list.php?leftmenu=customers_bills",$langs->trans("List"),1,$user->rights->facture->lire); - $newmenu->add("/compta/facture/impayees.php?leftmenu=customers_bills",$langs->trans("Unpaid"),1,$user->rights->facture->lire); + if (empty($leftmenu) || ($leftmenu == 'customers_bills')) { + $newmenu->add("/compta/facture/list.php?leftmenu=customers_bills&search_status=0",$langs->trans("BillShortStatusDraft"),2,$user->rights->facture->lire); + $newmenu->add("/compta/facture/impayees.php?leftmenu=customers_bills",$langs->trans("BillShortStatusNotPaid"),2,$user->rights->facture->lire); + $newmenu->add("/compta/facture/list.php?leftmenu=customers_bills&search_status=2",$langs->trans("BillShortStatusPaid"),2,$user->rights->facture->lire); + $newmenu->add("/compta/facture/list.php?leftmenu=customers_bills&search_status=3",$langs->trans("BillShortStatusCanceled"),2,$user->rights->facture->lire); + } $newmenu->add("/compta/paiement/list.php?leftmenu=customers_bills_payments",$langs->trans("Payments"),1,$user->rights->facture->lire); @@ -758,7 +770,14 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $langs->load("bills"); $newmenu->add("/fourn/facture/list.php?leftmenu=suppliers_bills", $langs->trans("BillsSuppliers"),0,$user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills'); $newmenu->add("/fourn/facture/card.php?action=create",$langs->trans("NewBill"),1,$user->rights->fournisseur->facture->creer); - $newmenu->add("/fourn/facture/impayees.php", $langs->trans("Unpaid"),1,$user->rights->fournisseur->facture->lire); + $newmenu->add("/fourn/facture/list.php?leftmenu=suppliers_bills", $langs->trans("List"),1,$user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills'); + + if (empty($leftmenu) || ($leftmenu == 'suppliers_bills')) { + $newmenu->add("/fourn/facture/list.php?leftmenu=suppliers_bills&search_status=0", $langs->trans("BillShortStatusDraft"),2,$user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills'); + $newmenu->add("/fourn/facture/impayees.php", $langs->trans("BillShortStatusNotPaid"),2,$user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills'); + $newmenu->add("/fourn/facture/list.php?leftmenu=suppliers_bills&search_status=2", $langs->trans("BillShortStatusPaid"),2,$user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills'); + } + $newmenu->add("/fourn/facture/paiement.php", $langs->trans("Payments"),1,$user->rights->fournisseur->facture->lire); $newmenu->add("/compta/facture/stats/index.php?leftmenu=suppliers_bills&mode=supplier", $langs->trans("Statistics"),1,$user->rights->fournisseur->facture->lire); @@ -795,11 +814,11 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu } // Taxes and social contributions - if (! empty($conf->tax->enabled) || ! empty($conf->salaries->enabled)) + if (! empty($conf->tax->enabled) || ! empty($conf->salaries->enabled) || ! empty($conf->loan->enabled)) { global $mysoc; - $permtoshowmenu=((! empty($conf->tax->enabled) && $user->rights->tax->charges->lire) || (! empty($conf->salaries->enabled) && $user->rights->salaries->read)); + $permtoshowmenu=((! empty($conf->tax->enabled) && $user->rights->tax->charges->lire) || (! empty($conf->salaries->enabled) && $user->rights->salaries->read) || (! empty($conf->loan->enabled) && $user->rights->loan->read)); $newmenu->add("/compta/charges/index.php?leftmenu=tax&mainmenu=accountancy",$langs->trans("MenuSpecialExpenses"), 0, $permtoshowmenu, '', $mainmenu, 'tax'); // Salaries @@ -811,6 +830,16 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu if (empty($leftmenu) || preg_match('/^tax_salary/i',$leftmenu)) $newmenu->add("/compta/salaries/index.php?leftmenu=tax_salary",$langs->trans("Payments"),2,$user->rights->salaries->read); } + // Loan + if (! empty($conf->loan->enabled)) + { + $langs->load("loan"); + $newmenu->add("/loan/index.php?leftmenu=tax_loan&mainmenu=accountancy",$langs->trans("Loans"),1,$user->rights->loan->read, '', $mainmenu, 'tax_loan'); + if (empty($leftmenu) || preg_match('/^tax_loan/i',$leftmenu)) $newmenu->add("/loan/card.php?leftmenu=tax_loan&action=create",$langs->trans("NewLoan"),2,$user->rights->loan->write); + if (empty($leftmenu) || preg_match('/^tax_loan/i',$leftmenu)) $newmenu->add("/loan/index.php?leftmenu=tax_loan",$langs->trans("Payments"),2,$user->rights->loan->read); + if (empty($leftmenu) || preg_match('/^tax_loan/i',$leftmenu)) $newmenu->add("/loan/calc.php?leftmenu=tax_loan",$langs->trans("Calculator"),2,$user->rights->loan->calc); + } + // Social contributions if (! empty($conf->tax->enabled)) { diff --git a/htdocs/core/menus/standard/eldy_menu.php b/htdocs/core/menus/standard/eldy_menu.php index 40d1d562552..fc66eef7fd6 100644 --- a/htdocs/core/menus/standard/eldy_menu.php +++ b/htdocs/core/menus/standard/eldy_menu.php @@ -150,6 +150,7 @@ class MenuManager { print '
      '; print '
    • '; + if ($val['enabled'] == 1) { $relurl=dol_buildpath($val['url'],1); @@ -184,23 +185,42 @@ class MenuManager } foreach($submenu->liste as $key2 => $val2) // $val['url','titre','level','enabled'=0|1|2,'target','mainmenu','leftmenu'] { - $relurl2=dol_buildpath($val2['url'],1); - $relurl2=preg_replace('/__LOGIN__/',$user->login,$relurl2); - $relurl2=preg_replace('/__USERID__/',$user->id,$relurl2); - $canonurl2=preg_replace('/\?.*$/','',$val2['url']); - //var_dump($val2['url'].' - '.$canonurl2.' - '.$val2['level']); - if (in_array($canonurl2,array('/admin/index.php','/admin/tools/index.php','/core/tools.php'))) $relurl2=''; - if ($val2['level']==0) print str_pad('',$val2['level']+1).''; // ui-btn to highlight on clic - else print str_pad('',$val2['level']+1).'
    • '; // ui-btn to highlight on clic - if ($relurl2) - { - print ''; - } - print $val2['titre']; - if ($relurl2) print ''; - print '
    • '."\n"; + $showmenu=true; + if (! empty($conf->global->MAIN_MENU_HIDE_UNAUTHORIZED) && empty($val2['enabled'])) $showmenu=false; + + if ($showmenu) // Visible (option to hide when not allowed is off or allowed) + { + $relurl2=dol_buildpath($val2['url'],1); + $relurl2=preg_replace('/__LOGIN__/',$user->login,$relurl2); + $relurl2=preg_replace('/__USERID__/',$user->id,$relurl2); + $canonurl2=preg_replace('/\?.*$/','',$val2['url']); + //var_dump($val2['url'].' - '.$canonurl2.' - '.$val2['level']); + if (in_array($canonurl2,array('/admin/index.php','/admin/tools/index.php','/core/tools.php'))) $relurl2=''; + if ($val2['level']==0) print str_pad('',$val2['level']+1).''; // ui-btn to highlight on clic + else print str_pad('',$val2['level']+1).'
    • '; // ui-btn to highlight on clic + if ($relurl2) + { + if ($val2['enabled']) // Allowed + { + print ''; + } + else // Not allowed but visible (greyed) + { + print ''; + } + } + print $val2['titre']; + if ($relurl2) + { + if ($val2['enabled']) // Allowed + print ''; + else + print ''; + } + print '
    • '."\n"; + } } //var_dump($submenu); print '
    '; diff --git a/htdocs/core/modules/modLoan.class.php b/htdocs/core/modules/modLoan.class.php new file mode 100644 index 00000000000..21ae96eba26 --- /dev/null +++ b/htdocs/core/modules/modLoan.class.php @@ -0,0 +1,181 @@ + + * + * 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 . + * or see http://www.gnu.org/ + */ + +/** + * \defgroup tax Module Loans + * \brief Module to include loans management + * \file htdocs/core/modules/modLoan.class.php + * \ingroup loan + * \brief File to activate module loan + */ +include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; + + +/** + * Class to manage loan module + */ +class modLoan extends DolibarrModules +{ + + /** + * Constructor. Define names, constants, directories, boxes, permissions + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $conf; + + $this->db = $db; + $this->numero = 520; + + $this->family = "financial"; + // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) + $this->name = preg_replace('/^mod/i','',get_class($this)); + // Module description used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module) + $this->description = "Loans management"; + + // Possible values for version are: 'development', 'experimental', 'dolibarr' or version + $this->version = 'development'; + + $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); + $this->special = 0; + $this->picto='bill'; + + // Data directories to create when module is enabled + $this->dirs = array("/loan/temp"); + + // Config pages + $this->config_page_url = array('loan.php'); + + // Dependances + $this->depends = array(); + $this->requiredby = array(); + $this->conflictwith = array(); + $this->langfiles = array("loan"); + + // Constants + $this->const = array(); + $this->const[0] = array( + "LOAN_ACCOUNTING_ACCOUNT_CAPITAL", + "chaine", + "164" + ); + $this->const[1] = array( + "LOAN_ACCOUNTING_ACCOUNT_INTEREST", + "chaine", + "6611" + ); + $this->const[1] = array( + "LOAN_ACCOUNTING_ACCOUNT_INSURANCE", + "chaine", + "6162" + ); + + // Boxes + $this->boxes = array(); + + // Permissions + $this->rights = array(); + $this->rights_class = 'loan'; + $r=0; + + $r++; + $this->rights[$r][0] = 520; + $this->rights[$r][1] = 'Read loans'; + $this->rights[$r][2] = 'r'; + $this->rights[$r][3] = 1; + $this->rights[$r][4] = 'read'; + $this->rights[$r][5] = ''; + + $r++; + $this->rights[$r][0] = 522; + $this->rights[$r][1] = 'Create/modify loans'; + $this->rights[$r][2] = 'w'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'write'; + $this->rights[$r][5] = ''; + + $r++; + $this->rights[$r][0] = 524; + $this->rights[$r][1] = 'Delete loans'; + $this->rights[$r][2] = 'd'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'delete'; + $this->rights[$r][5] = ''; + + $r++; + $this->rights[$r][0] = 525; + $this->rights[$r][1] = 'Access loan calculator'; + $this->rights[$r][2] = 'r'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'calc'; + $this->rights[$r][5] = ''; + + $r++; + $this->rights[$r][0] = 527; + $this->rights[$r][1] = 'Export loans'; + $this->rights[$r][2] = 'r'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'export'; + $this->rights[$r][5] = ''; + + + // Exports + //-------- + $r=0; + + } + + + /** + * Function called when module is enabled. + * The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database. + * It also creates data directories + * + * @param string $options Options when enabling module ('', 'noboxes') + * @return int 1 if OK, 0 if KO + */ + function init($options='') + { + global $conf; + + // Clean before activation + $this->remove($options); + + $sql = array(); + + return $this->_init($sql,$options); + } + + /** + * Function called when module is disabled. + * Remove from database constants, boxes and permissions from Dolibarr database. + * Data directories are not deleted + * + * @param string $options Options when enabling module ('', 'noboxes') + * @return int 1 if OK, 0 if KO + */ + function remove($options='') + { + $sql = array(); + + return $this->_remove($sql,$options); + } + +} diff --git a/htdocs/core/modules/modResource.class.php b/htdocs/core/modules/modResource.class.php index 9acebd5d90d..e63f44c3945 100644 --- a/htdocs/core/modules/modResource.class.php +++ b/htdocs/core/modules/modResource.class.php @@ -59,7 +59,7 @@ class modResource extends DolibarrModules // Module description // used if translation string 'ModuleXXXDesc' not found // (where XXX is value of numeric property 'numero' of module) - $this->description = "Description of module Resource"; + $this->description = "Manage resources (printers, cars, room, ...) you can then share into events"; // Possible values for version are: 'development', 'experimental' or version $this->version = 'development'; // Key used in llx_const table to save module status enabled/disabled diff --git a/htdocs/cron/list.php b/htdocs/cron/list.php index 3c2844f3fe4..e543c269fb4 100644 --- a/htdocs/cron/list.php +++ b/htdocs/cron/list.php @@ -100,7 +100,7 @@ if ($action == 'confirm_execute' && $confirm == "yes" && $user->rights->cron->ex if ($result < 0) { setEventMessage($object->error,'errors'); } - else + else { $res = $object->reprogram_jobs($user->login); if ($res > 0) @@ -314,11 +314,11 @@ print "\n
    \n"; if (! $user->rights->cron->create) { - print ''.$langs->trans("New").''; + print ''.$langs->trans("CronCreateJob").''; } else { - print ''.$langs->trans("New").''; + print ''.$langs->trans("CronCreateJob").''; } print '
    '; diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 26a0b5a5438..ff3d4b5d955 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -448,14 +448,12 @@ if (empty($reshook)) { $price_base_type = 'HT'; $ht = price2num(GETPOST('price_ht')); - $result=$object->addline($desc, $ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, 0, 0, '', $remise_percent, $price_base_type, 0, $type,'','', $date_start, $date_end); } else { $ttc = price2num(GETPOST('price_ttc')); $ht = $ttc / (1 + ($tva_tx / 100)); $price_base_type = 'HT'; - $result=$object->addline($desc, $ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, 0, 0, '', $remise_percent, $price_base_type, $ttc, $type,'','', $date_start, $date_end); } if ($lineid) @@ -1657,7 +1655,7 @@ elseif (! empty($object->id)) require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; $notify=new Notify($db); $text.='
    '; - $text.=$notify->confirmMessage('ORDER_SUPPLIER_APPROVE', $object->socid, $object); + $text.=$notify->confirmMessage('ORDER_SUPPLIER_VALIDATE', $object->socid, $object); } $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateOrder'), $text, 'confirm_valid', '', 0, 1); @@ -1692,9 +1690,16 @@ elseif (! empty($object->id)) array('type' => 'other', 'name' => 'idwarehouse', 'label' => $langs->trans("SelectWarehouseForStockIncrease"), 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1)) ); } + $text=$langs->trans("ConfirmApproveThisOrder",$object->ref); + if (! empty($conf->notification->enabled)) + { + require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; + $notify=new Notify($db); + $text.='
    '; + $text.=$notify->confirmMessage('ORDER_SUPPLIER_APPROVE', $object->socid, $object); + } - $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id,$langs->trans("ApproveThisOrder"),$langs->trans("ConfirmApproveThisOrder",$object->ref),"confirm_approve", $formquestion, 1, 1, 240); - + $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id, $langs->trans("ApproveThisOrder"), $text, "confirm_approve", $formquestion, 1, 1, 240); } /* @@ -1731,7 +1736,8 @@ elseif (! empty($object->id)) $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 0, 1); } - if (!$formconfirm) { + if (!$formconfirm) + { $parameters=array('lineid'=>$lineid); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) $formconfirm.=$hookmanager->resPrint; @@ -2561,7 +2567,7 @@ elseif (! empty($object->id)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->fournisseur->supplier_order_advance->validate))) { $tmpbuttonlabel=$langs->trans('Validate'); - if ($user->rights->fournisseur->commande->approuver) $tmpbuttonlabel = $langs->trans("ValidateAndApprove"); + if ($user->rights->fournisseur->commande->approuver && empty($conf->global->SUPPLIER_ORDER_NO_DIRECT_APPROVE)) $tmpbuttonlabel = $langs->trans("ValidateAndApprove"); print ''; print $tmpbuttonlabel; diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index 66ad20e4c05..3c1b0f06cb6 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -5,6 +5,7 @@ * Copyright (C) 2013 Philippe Grand * Copyright (C) 2013 Florian Henry * Copyright (C) 2013 Cédric Salvador + * Copyright (C) 2015 Marcos García * * 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 @@ -70,6 +71,7 @@ $search_label = GETPOST("search_label","alpha"); $search_company = GETPOST("search_company","alpha"); $search_amount_no_tax = GETPOST("search_amount_no_tax","alpha"); $search_amount_all_tax = GETPOST("search_amount_all_tax","alpha"); +$search_status=GETPOST('search_status','alpha'); $month = GETPOST("month","int"); $year = GETPOST("year","int"); $filter = GETPOST("filtre"); @@ -188,6 +190,11 @@ if ($search_amount_all_tax != '') $sql .= natural_search('fac.total_ttc', $search_amount_all_tax, 1); } +if ($search_status != '') +{ + $sql.= " AND fac.fk_statut = '".$db->escape($search_status)."'"; +} + $nbtotalofrecords = 0; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { diff --git a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql old mode 100755 new mode 100644 index 5b589a70a0b..34974d3ebd4 --- a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql +++ b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql @@ -18,6 +18,49 @@ -- -- VPGSQL8.2 DELETE FROM llx_usergroup_user WHERE fk_user NOT IN (SELECT rowid from llx_user); -- -- VMYSQL4.1 DELETE FROM llx_usergroup_user WHERE fk_usergroup NOT IN (SELECT rowid from llx_usergroup); +-- Loan +create table llx_loan +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + entity integer DEFAULT 1 NOT NULL, + datec datetime, + tms timestamp, + label varchar(80) NOT NULL, + fk_bank integer, + capital real default 0 NOT NULL, + datestart date, + dateend date, + nbterm real, + rate double NOT NULL, + note text, + capital_position real default 0, + date_position date, + paid smallint default 0 NOT NULL, + accountancy_account_capital varchar(32), + accountancy_account_insurance varchar(32), + accountancy_account_interest varchar(32), + fk_user_author integer DEFAULT NULL, + fk_user_modif integer DEFAULT NULL, + active tinyint DEFAULT 1 NOT NULL +)ENGINE=innodb; + +create table llx_payment_loan +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + fk_loan integer, + datec datetime, + tms timestamp, + datep datetime, + amount_capital real DEFAULT 0, + amount_insurance real DEFAULT 0, + amount_interest real DEFAULT 0, + fk_typepayment integer NOT NULL, + num_payment varchar(50), + note text, + fk_bank integer NOT NULL, + fk_user_creat integer, + fk_user_modif integer +)ENGINE=innodb; ALTER TABLE llx_extrafields ADD COLUMN perms varchar(255) after fieldrequired; ALTER TABLE llx_extrafields ADD COLUMN list integer DEFAULT 0 after perms; diff --git a/htdocs/install/mysql/tables/llx_loan.sql b/htdocs/install/mysql/tables/llx_loan.sql new file mode 100644 index 00000000000..bc152099a04 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_loan.sql @@ -0,0 +1,49 @@ +-- ======================================================================== +-- Copyright (C) 2014 Alexandre Spangaro +-- +-- 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 . +-- +-- ======================================================================== + +create table llx_loan +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + entity integer DEFAULT 1 NOT NULL, + datec datetime, + tms timestamp, + + label varchar(80) NOT NULL, + fk_bank integer, + + capital real default 0 NOT NULL, + datestart date, + dateend date, + nbterm real, + rate double NOT NULL, + + note text, + + capital_position real default 0, -- If not a new loan, just have the position of capital + date_position date, + + paid smallint default 0 NOT NULL, + + accountancy_account_capital varchar(32), + accountancy_account_insurance varchar(32), + accountancy_account_interest varchar(32), + + fk_user_author integer DEFAULT NULL, + fk_user_modif integer DEFAULT NULL, + active tinyint DEFAULT 1 NOT NULL +)ENGINE=innodb; \ No newline at end of file diff --git a/htdocs/install/mysql/tables/llx_payment_loan.sql b/htdocs/install/mysql/tables/llx_payment_loan.sql new file mode 100644 index 00000000000..0fb6b566ca5 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_payment_loan.sql @@ -0,0 +1,35 @@ +-- =================================================================== +-- Copyright (C) 2014 Alexandre Spangaro +-- +-- 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 . +-- +-- =================================================================== + +create table llx_payment_loan +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + fk_loan integer, + datec datetime, -- creation date + tms timestamp, + datep datetime, -- payment date + amount_capital real DEFAULT 0, + amount_insurance real DEFAULT 0, + amount_interest real DEFAULT 0, + fk_typepayment integer NOT NULL, + num_payment varchar(50), + note text, + fk_bank integer NOT NULL, + fk_user_creat integer, -- creation user + fk_user_modif integer -- last modification user +)ENGINE=innodb; diff --git a/htdocs/install/upgrade.php b/htdocs/install/upgrade.php index 359980763b0..c001a771f06 100644 --- a/htdocs/install/upgrade.php +++ b/htdocs/install/upgrade.php @@ -198,9 +198,9 @@ if (! GETPOST("action") || preg_match('/upgrade/i',GETPOST('action'))) { $dbversion_disallowed=array( array('type'=>'mysql','version'=>array(5,5,40)), - array('type'=>'mysqli','version'=>array(5,5,40)), - array('type'=>'mysql','version'=>array(5,5,41)), - array('type'=>'mysqli','version'=>array(5,5,41)) + array('type'=>'mysqli','version'=>array(5,5,40)) //, + //array('type'=>'mysql','version'=>array(5,5,41)), + //array('type'=>'mysqli','version'=>array(5,5,41)) ); $listofforbiddenversion=''; foreach ($dbversion_disallowed as $dbversion_totest) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 2439066ad9c..21b008b1d0e 100755 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -494,6 +494,8 @@ Module500Name=Special expenses (tax, social contributions, dividends) Module500Desc=Management of special expenses like taxes, social contribution, dividends and salaries Module510Name=Salaries Module510Desc=Management of employees salaries and payments +Module520Name=Loan +Module520Desc=Management of loans Module600Name=Notifications Module600Desc=Send EMail notifications on some Dolibarr business events to third-party contacts (setup defined on each thirdparty) Module700Name=Donations @@ -515,7 +517,7 @@ Module2000Desc=Allow to edit some text area using an advanced editor Module2200Name=Dynamic Prices Module2200Desc=Enable the usage of math expressions for prices Module2300Name=Cron -Module2300Desc=Scheduled task management +Module2300Desc=Scheduled job management Module2400Name=Agenda Module2400Desc=Events/tasks and agenda management Module2500Name=Electronic Content Management @@ -714,6 +716,11 @@ Permission510=Read Salaries Permission512=Create/modify salaries Permission514=Delete salaries Permission517=Export salaries +Permission520=Read Loans +Permission522=Create/modify loans +Permission524=Delete loans +Permission525=Access loan calculator +Permission527=Export loans Permission531=Read services Permission532=Create/modify services Permission534=Delete services @@ -758,10 +765,10 @@ Permission1237=Export supplier orders and their details Permission1251=Run mass imports of external data into database (data load) Permission1321=Export customer invoices, attributes and payments Permission1421=Export customer orders and attributes -Permission23001 = Read Scheduled task -Permission23002 = Create/update Scheduled task -Permission23003 = Delete Scheduled task -Permission23004 = Execute Scheduled task +Permission23001=Read Scheduled job +Permission23002=Create/update Scheduled job +Permission23003=Delete Scheduled job +Permission23004=Execute Scheduled job Permission2401=Read actions (events or tasks) linked to his account Permission2402=Create/modify actions (events or tasks) linked to his account Permission2403=Delete actions (events or tasks) linked to his account diff --git a/htdocs/langs/en_US/cron.lang b/htdocs/langs/en_US/cron.lang index 9ca1a6df430..cf5e1a6198c 100644 --- a/htdocs/langs/en_US/cron.lang +++ b/htdocs/langs/en_US/cron.lang @@ -26,15 +26,15 @@ CronLastOutput=Last run output CronLastResult=Last result code CronListOfCronJobs=List of scheduled jobs CronCommand=Command -CronList=Jobs list -CronDelete= Delete cron jobs -CronConfirmDelete= Are you sure you want to delete this cron job ? -CronExecute=Launch job -CronConfirmExecute= Are you sure to execute this job now -CronInfo= Jobs allow to execute task that have been planned -CronWaitingJobs=Wainting jobs +CronList=Scheduled job +CronDelete=Delete scheduled jobs +CronConfirmDelete=Are you sure you want to delete this scheduled jobs ? +CronExecute=Launch scheduled jobs +CronConfirmExecute=Are you sure to execute this scheduled jobs now ? +CronInfo=Scheduled job module allow to execute job that have been planned +CronWaitingJobs=Waiting jobs CronTask=Job -CronNone= None +CronNone=None CronDtStart=Start date CronDtEnd=End date CronDtNextLaunch=Next execution @@ -75,6 +75,7 @@ CronObjectHelp=The object name to load.
    For exemple to fetch method of Doli CronMethodHelp=The object method to launch.
    For exemple to fetch method of Dolibarr Product object /htdocs/product/class/product.class.php, the value of method is is fecth CronArgsHelp=The method arguments.
    For exemple to fetch method of Dolibarr Product object /htdocs/product/class/product.class.php, the value of paramters can be 0, ProductRef CronCommandHelp=The system command line to execute. +CronCreateJob=Create new Scheduled Job # Info CronInfoPage=Information # Common diff --git a/htdocs/langs/en_US/loan.lang b/htdocs/langs/en_US/loan.lang new file mode 100644 index 00000000000..4922c0fc0a1 --- /dev/null +++ b/htdocs/langs/en_US/loan.lang @@ -0,0 +1,28 @@ +# Dolibarr language file - Source file is en_US - loan +Loan=Loan +Loans=Loans +NewLoan=New Loan +ShowLoan=Show Loan +PaymentLoan=Loan payment +Capital=Capital +Insurance=Insurance +Interest=Interest +Nbterms=Number of terms +LoanAccountancyCapitalCode=Accountancy code capital +LoanAccountancyInsuranceCode=Accountancy code insurance +LoanAccountancyInterestCode=Accountancy code interest +LoanPayment=Loan payment +ConfirmDeleteLoan=Confirm deleting this loan +ConfirmPayLoan=Confirm classify paid this loan +ErrorLoanCapital=Loan amount has to be numeric and greater than zero. +ErrorLoanLength=Loan length has to be numeric and greater than zero. +ErrorLoanInterest=Annual interest has to be numeric and greater than zero. +# Calc +Totalsforyear=Totals for year +MonthlyPayment=Monthly Payment +LoanCalcDesc=This mortgage calculator can be used to figure out monthly payments of a home mortgage loan, based on the home's sale price, the term of the loan desired, buyer's down payment percentage, and the loan's interest rate.
    This calculator factors in PMI (Private Mortgage Insurance) for loans where less than 20% is put as a down payment. Also taken into consideration are the town property taxes, and their effect on the total monthly mortgage payment.
    +# Admin +ConfigLoan=Configuration of the module loan +LOAN_ACCOUNTING_ACCOUNT_CAPITAL=Accountancy code capital by default +LOAN_ACCOUNTING_ACCOUNT_INTEREST=Accountancy code interest by default +LOAN_ACCOUNTING_ACCOUNT_INSURANCE=Accountancy code insurance by default \ No newline at end of file diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 551807aad59..b160c4303a0 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -694,6 +694,7 @@ AddBox=Add box SelectElementAndClickRefresh=Select an element and click Refresh PrintFile=Print File %s ShowTransaction=Show transaction +GoIntoSetupToChangeLogo=Go into Home - Setup - Company to change logo or go into Home - Setup - Display to hide. # Week day Monday=Monday Tuesday=Tuesday diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index 4bab1133041..fb2b1687199 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -495,6 +495,8 @@ Module500Name=Dépenses spéciales (taxes, charges, dividendes) Module500Desc=Gestion des dépenses spéciales comme les taxes, charges sociales et dividendes Module510Name=Salaires Module510Desc=Gestion des paiements des salaires des employés +Module520Name=Emprunts +Module520Desc=Suivi des emprunts Module600Name=Notifications Module600Desc=Envoi de notifications Email sur certains événements métiers Dolibarr, aux contacts de tiers (configuration réalisé sur chaque tiers) Module700Name=Dons @@ -715,6 +717,10 @@ Permission510=Consulter les salaires Permission512=Créer/modifier les salaires Permission514=Supprimer les salaires Permission517=Exporter les salaires +Permission520=Consulter les emprunts +Permission522=Créer/modifier les emprunts +Permission524=Supprimer les emprunts +Permission527=Exporter les emprunts Permission531=Consulter les services Permission532=Créer/modifier les services Permission534=Supprimer les services diff --git a/htdocs/langs/fr_FR/loan.lang b/htdocs/langs/fr_FR/loan.lang new file mode 100644 index 00000000000..0a5c6320d5b --- /dev/null +++ b/htdocs/langs/fr_FR/loan.lang @@ -0,0 +1,24 @@ +# Dolibarr language file - Source file is en_US - loan +Loan=Emprunt +Loans=Emprunts +NewLoan=Nouvel emprunt +ShowLoan=Voir emprunt +PaymentLoan=Règlement d'emprunt +Capital=Capital +Insurance=Assurance +Interest=Intérêt +Nbterms=Nombre d'échéances +LoanAccountancyCapitalCode=Compte comptable capital +LoanAccountancyInsuranceCode=Compte comptable assurance +LoanAccountancyInterestCode=Compte comptable intérêts +LoanPayment=Règlement emprunt +ConfirmDeleteLoan=Confirmation de supression de cet emprunt +ConfirmPayLoan=Confirmation que cet emprunt est classé comme payé +ErrorLoanCapital=Le capital de l'emprunt doit être au format numérique et supérieur à zéro. +ErrorLoanLength=La durée de l'emprunt doit être au format numérique et supérieur à zéro. +ErrorLoanInterest=Les intérêts d'emprunt doivent être au format numérique et supérieur à zéro. +# Admin +ConfigLoan=Configuration du module emprunt +LOAN_ACCOUNTING_ACCOUNT_CAPITAL=Compte comptable capital par défaut +LOAN_ACCOUNTING_ACCOUNT_INTEREST=Compte comptable intérêts par défaut +LOAN_ACCOUNTING_ACCOUNT_INSURANCE=Compte comptable assurance par défaut \ No newline at end of file diff --git a/htdocs/langs/tr_TR/main.lang b/htdocs/langs/tr_TR/main.lang index 36d6a87625e..cd5b2b24f7e 100644 --- a/htdocs/langs/tr_TR/main.lang +++ b/htdocs/langs/tr_TR/main.lang @@ -66,7 +66,7 @@ SeeHere=Buraya bak BackgroundColorByDefault=Varsayılan arkaplan rengi FileNotUploaded=Dosya yüklenmemiş FileUploaded=Dosya yüklemesi başarılı -FileWasNotUploaded=Bu ekleme için bir dosya seçildi ama henüz gönderilmedi. Bunun için “Dosya ekle” ye tıklayın. +FileWasNotUploaded=Bu ekleme için bir dosya seçildi ama henüz gönderilmedi. Bunun için “Dosya ekle? ye tıklayın. NbOfEntries=Kayıt sayısı GoToWikiHelpPage=Çevrimiçi yardım oku (Internet erişimi gerekir) GoToHelpPage=Yardım oku @@ -632,7 +632,7 @@ CoreErrorTitle=Sistem hatası CoreErrorMessage=Üzgünüz, bir hata oluştu. Günlükleri kontrol edin veya sistem yöneticinize başvurun. CreditCard=Kredi kartı FieldsWithAreMandatory=%s olan alanları zorunludur -FieldsWithIsForPublic=Üyelerin genel listelerinde %s olan alanlar gösterilir. Bunu istemiyorsanız, “genel” kutusundan işareti kaldırın. +FieldsWithIsForPublic=Üyelerin genel listelerinde %s olan alanlar gösterilir. Bunu istemiyorsanız, “genel? kutusundan işareti kaldırın. AccordingToGeoIPDatabase=(GeoIP dönüşümüne göre) Line=Satır NotSupported=Desteklenmez diff --git a/htdocs/loan/calc.php b/htdocs/loan/calc.php new file mode 100644 index 00000000000..0a5ee21923a --- /dev/null +++ b/htdocs/loan/calc.php @@ -0,0 +1,387 @@ + + * Copyright (C) 2014 Alexandre Spangaro + * Copyright (C) 2015 Frederic France + * + * 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 . + */ + +require '../main.inc.php'; + +$langs->load("loan"); + +/* --------------------------------------------------- * + * Set Form DEFAULT values + * --------------------------------------------------- */ +$default_sale_price = "150000"; +$default_annual_interest_percent = 7.0; +$default_year_term = 30; +$default_down_percent = 10; +$default_show_progress = TRUE; + +/* --------------------------------------------------- * + * Initialize Variables + * --------------------------------------------------- */ +$sale_price = 0; +$annual_interest_percent = 0; +$year_term = 0; +$down_percent = 0; +$this_year_interest_paid = 0; +$this_year_principal_paid = 0; +$form_complete = false; +$show_progress = false; +$monthly_payment = false; +$show_progress = false; +$error = false; + +/* --------------------------------------------------- * + * Set the USER INPUT values + * --------------------------------------------------- */ +if (isset($_REQUEST['form_complete'])) { + $sale_price = $_REQUEST['sale_price']; + $annual_interest_percent = $_REQUEST['annual_interest_percent']; + $year_term = $_REQUEST['year_term']; + $down_percent = $_REQUEST['down_percent']; + $show_progress = (isset($_REQUEST['show_progress'])) ? $_REQUEST['show_progress'] : false; + $form_complete = $_REQUEST['form_complete']; +} + +// This function does the actual mortgage calculations +// by plotting a PVIFA (Present Value Interest Factor of Annuity) +// table... +function get_interest_factor($year_term, $monthly_interest_rate) { + global $base_rate; + + $factor = 0; + $base_rate = 1 + $monthly_interest_rate; + $denominator = $base_rate; + for ($i=0; $i < ($year_term * 12); $i++) { + $factor += (1 / $denominator); + $denominator *= $base_rate; + } + return $factor; +} + +// If the form is complete, we'll start the math +if ($form_complete) { + // We'll set all the numeric values to JUST + // numbers - this will delete any dollars signs, + // commas, spaces, and letters, without invalidating + // the value of the number + $sale_price = preg_replace( "[^0-9.]", "", $sale_price); + $annual_interest_percent = preg_replace( "[^0-9.]", "", $annual_interest_percent); + $year_term = preg_replace( "[^0-9.]", "", $year_term); + $down_percent = preg_replace( "[^0-9.]", "", $down_percent); + + if ((float) $year_term <= 0) { + $errors[] = "You must enter a Sale Price of Home"; + } + if ((float) $sale_price <= 0) { + $errors[] = "You must enter a Length of Mortgage"; + } + if ((float) $annual_interest_percent <= 0) { + $errors[] = "You must enter an Annual Interest Rate"; + } + if (!$errors) { + $month_term = $year_term * 12; + $down_payment = $sale_price * ($down_percent / 100); + $annual_interest_rate = $annual_interest_percent / 100; + $monthly_interest_rate = $annual_interest_rate / 12; + $financing_price = $sale_price - $down_payment; + $monthly_factor = get_interest_factor($year_term, $monthly_interest_rate); + $monthly_payment = $financing_price / $monthly_factor; + } +} else { + if (!$sale_price) { $sale_price = $default_sale_price; } + if (!$annual_interest_percent) { $annual_interest_percent = $default_annual_interest_percent; } + if (!$year_term) { $year_term = $default_year_term; } + if (!$down_percent) { $down_percent = $default_down_percent; } + if (!$show_progress) { $show_progress = $default_show_progress; } +} + +if (! empty($errors)) { + setEventMessages('', $errors, 'errors'); + $form_complete = false; +} + +/* + * View + */ + +llxHeader(); + +print $langs->trans('LoanCalcDesc'); + +print ''; +print ''; +print '
    '.$langs->trans("Ref").''.$langs->trans("Name").''.$langs->trans("DateStart").''.$langs->trans("DateEnd").''.$langs->trans("Status").'
    '.img_object($langs->trans("ShowProject"),($obj->public?'projectpub':'project'))." ".$obj->ref.''.img_object($langs->trans("ShowProject"),($obj->public?'projectpub':'project'))." ".$obj->ref.''.$obj->title.''.dol_print_date($db->jdate($obj->do),"day").''.dol_print_date($db->jdate($obj->de),"day").''.$projecttmp->getLibStatut(5).'
    '; +//print ''; +//print ''; +//print ''; +//print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print '';print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; + +if (! empty($show_progress)) +{ + print ''; +} +else +{ + print ''; +} + +print ''; +print '
    Purchase & Financing Information
    Sale Price of Home: '.$langs->trans("Currency".$conf->currency).'
    Percentage Down:%
    Length of Mortgage:years
    Annual Interest Rate:%
    Explain Calculations:Show me the calculations and amortizationShow me the calculations and amortization
    '; + +print '
        '; +print '
    '; + +// If the form has already been calculated, the $down_payment +// and $monthly_payment variables will be figured out, so we can show them in this table +if ($form_complete && $monthly_payment) +{ + print '
    '; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + if ($down_percent < 20) + { + $pmi_per_month = 55 * ($financing_price / 100000); + + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + } + + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; +} + +print '
    Mortgage Payment Information
    Down Payment:' . number_format($down_payment, "2", ".", ",") . ' ' . $langs->trans("Currency".$conf->currency) . '
    Amount Financed:' . number_format($financing_price, "2", ".", ",") . ' ' . $langs->trans("Currency".$conf->currency) . '
    Monthly Payment:' . number_format($monthly_payment, "2", ".", ",") . ' ' . $langs->trans("Currency".$conf->currency) . '
    (Principal & Interest ONLY)
     '; + print '
    '; + echo 'Since you are putting LESS than 20% down, you will need to pay PMI + (Private Mortgage Insurance), which tends + to be about $55 per month for every $100,000 financed (until you have paid off 20% of your loan). This could add + '."\$" . number_format($pmi_per_month, "2", ".", ",").' to your monthly payment.'; + print '
    Monthly Payment:' . number_format(($monthly_payment + $pmi_per_month), "2", ".", ",") . $langs->trans("Currency".$conf->currency) . '
    '; + print '(Principal & Interest, and PMI)
     '; + print '
    '; + + $assessed_price = ($sale_price * .85); + $residential_yearly_tax = ($assessed_price / 1000) * 14; + $residential_monthly_tax = $residential_yearly_tax / 12; + + if ($pmi_per_month) + { + $pmi_text = "PMI and "; + } + + echo "Residential (or Property) Taxes are a little harder to figure out... In Massachusetts, the average resedential tax rate seems + to be around $14 per year for every $1,000 of your property's assessed value."; + + print '

    '; + print "Let's say that your property's assessed value is 85% of what you actually paid for it - "; + print number_format($assessed_price, "2", ".", ",") . ' ' . $langs->trans("Currency".$conf->currency) . 'This would mean that your yearly residential taxes will be around'; + print number_format($residential_yearly_tax, "2", ".", ",") . ' ' . $langs->trans("Currency".$conf->currency); + print 'This could add ' . number_format($residential_monthly_tax, "2", ".", ",") . ' ' . $langs->trans("Currency".$conf->currency) . 'to your monthly payment'; + print '
    TOTAL Monthly Payment:' . number_format(($monthly_payment + $pmi_per_month + $residential_monthly_tax), "2", ".", ",") . ' ' . $langs->trans("Currency".$conf->currency) . '
    '; + print '(including '.$pmi_text.' residential tax)
    '; +print ''; + +// This prints the calculation progress and +// the instructions of HOW everything is figured +// out +if ($form_complete && $show_progress) { + $step = 1; + + print '

    '; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print '
    '. $step++ .''; + echo 'The down payment + = The price of the home multiplied by the percentage down divided by 100 (for 5% down becomes 5/100 or 0.05)

    + ' . number_format($down_payment,"2",".",",") . ' ' . $langs->trans("Currency".$conf->currency) . ' = '.number_format($sale_price,"2",".",",") . ' ' . $langs->trans("Currency".$conf->currency) . ' X + ('.$down_percent.' / 100)'; + print '
    ' . $step++ . ''; + print 'The interest rate = The annual interest percentage divided by 100

    '; + print $annual_interest_rate . ' = ' . $annual_interest_percent . '% / 100'; + print '
    '; + print 'The monthly factor = The result of the following formula:'; + print '
    ' . $step++ . ''; + print 'The monthly interest rate = The annual interest rate divided by 12 (for the 12 months in a year)

    '; + print $monthly_interest_rate . ' = ' . $annual_interest_rate . ' / 12'; + print '
    ' . $step++ . ''; + print 'The month term of the loan in months = The number of years you\'ve taken the loan out for times 12

    '; + print $month_term . ' Months = ' . $year_term . ' Years X 12'; + print '
    ' . $step++ . ''; + print 'The montly payment is figured out using the following formula:
    '; + print 'Monthly Payment = ' . number_format($financing_price, "2", "", "") . ' * '; + print $langs->trans('MonthlyPayment').' = ' . number_format($financing_price, "2", "", "") . ' * '; + print '(1 - ((1 + ' . number_format($monthly_interest_rate, "4", "", "") . ')'; + print '-(' . $month_term . '))))'; + print '

    '; + print 'The amortization breaks down how much of your monthly payment goes towards the bank\'s interest,'; + print 'and how much goes into paying off the principal of your loan.'; + print '
    '; + print '
    '; + + + // Set some base variables + $principal = $financing_price; + $current_month = 1; + $current_year = 1; + + // This basically, re-figures out the monthly payment, again. + $power = -($month_term); + $denom = pow((1 + $monthly_interest_rate), $power); + $monthly_payment = $principal * ($monthly_interest_rate / (1 - $denom)); + + print "

    Amortization For Monthly Payment: " . number_format($monthly_payment, "2", ".", ",") . " over " . $year_term . " years
    \n"; + + print ''; + + // This LEGEND will get reprinted every 12 months + $legend = ''; + $legend.= ''; + $legend.= ''; + $legend.= ''; + $legend.= ''; + $legend.= ''; + + print $legend; + + // Loop through and get the current month's payments for + // the length of the loan + while ($current_month <= $month_term) + { + $interest_paid = $principal * $monthly_interest_rate; + $principal_paid = $monthly_payment - $interest_paid; + $remaining_balance = $principal - $principal_paid; + + $this_year_interest_paid = $this_year_interest_paid + $interest_paid; + $this_year_principal_paid = $this_year_principal_paid + $principal_paid; + + $var = !$var; + print ""; + print ''; + print ''; + print ''; + print ''; + print ''; + + ($current_month % 12) ? $show_legend = FALSE : $show_legend = TRUE; + + if ($show_legend) { + print ''; + print ''; + print ''; + + $total_spent_this_year = $this_year_interest_paid + $this_year_principal_paid; + print ''; + print ''; + print ''; + print ''; + + print ''; + print ''; + print ''; + + $current_year++; + $this_year_interest_paid = 0; + $this_year_principal_paid = 0; + + if (($current_month + 6) < $month_term) + { + echo $legend; + } + } + $principal = $remaining_balance; + $current_month++; + } + print "
    ' . $langs->trans("Month") . '' . $langs->trans("Interest") . '' . $langs->trans("Capital") . '' . $langs->trans("Position") . '
    ' . $current_month . '' . number_format($interest_paid, "2", ".", ",") . ' ' . $langs->trans("Currency".$conf->currency) . '' . number_format($principal_paid, "2", ".", ",") . ' ' . $langs->trans("Currency".$conf->currency) . '' . number_format($remaining_balance, "2", ".", ",") . ' ' . $langs->trans("Currency".$conf->currency) . '
    ' . $langs->trans("Totalsforyear") . ' ' . $current_year . '
     '; + print 'You will spend ' . number_format($total_spent_this_year, "2", ".", ",") . ' ' . $langs->trans("Currency".$conf->currency) . ' on your house in year ' . $current_year . '
    '; + print number_format($this_year_interest_paid, "2", ".", ",") . ' ' . $langs->trans("Currency".$conf->currency) . ' will go towards INTEREST
    '; + print number_format($this_year_principal_paid, "2", ".", ",") . ' ' . $langs->trans("Currency".$conf->currency) . ' will go towards PRINCIPAL
    '; + print '
     
    \n"; +} + +llxFooter(); + +$db->close(); diff --git a/htdocs/loan/card.php b/htdocs/loan/card.php new file mode 100644 index 00000000000..6a62ffe09ea --- /dev/null +++ b/htdocs/loan/card.php @@ -0,0 +1,493 @@ + + * + * 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/loan/card.php + * \ingroup loan + * \brief Loan card + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; + +$langs->load("compta"); +$langs->load("bills"); +$langs->load("loan"); + +$id=GETPOST('id','int'); +$action=GETPOST('action'); +$confirm=GETPOST('confirm'); +$cancel=GETPOST('cancel','alpha'); + +// Security check +$socid = GETPOST('socid','int'); +if ($user->societe_id) $socid=$user->societe_id; +$result = restrictedArea($user, 'loan', $id, '',''); + +$object = new Loan($db); + +/* + * Actions + */ + +// Classify paid +if ($action == 'confirm_paid' && $confirm == 'yes') +{ + $object->fetch($id); + $result = $object->set_paid($user); +} + +// Delete loan +if ($action == 'confirm_delete' && $confirm == 'yes') +{ + $object->fetch($id); + $result=$object->delete($user); + if ($result > 0) + { + header("Location: index.php"); + exit; + } + else + { + setEventMessage($loan->error, 'errors'); + } +} + +// Add loan +if ($action == 'add' && $user->rights->loan->write) +{ + if (! $cancel) + { + $datestart=@dol_mktime(12,0,0, $_POST["startmonth"], $_POST["startday"], $_POST["startyear"]); + $dateend=@dol_mktime(12,0,0, $_POST["endmonth"], $_POST["endday"], $_POST["endyear"]); + + if (! $datestart) + { + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("DateStart")), 'errors'); + $action = 'create'; + } + elseif (! $dateend) + { + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("DateEnd")), 'errors'); + $action = 'create'; + } + elseif (! $_POST["capital"]) + { + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("Capital")), 'errors'); + $action = 'create'; + } + else + { + $object->label = $_POST["label"]; + $object->fk_bank = $_POST["accountid"]; + $object->capital = $_POST["capital"]; + $object->datestart = $datestart; + $object->dateend = $dateend; + $object->nbterm = $_POST["nbterm"]; + $object->rate = $_POST["rate"]; + + $object->account_capital = $_POST["accountancy_account_capital"]; + $object->account_insurance = $_POST["accountancy_account_insurance"]; + $object->account_interest = $_POST["accountancy_account_interest"]; + + $id=$object->create($user); + if ($id <= 0) + { + setEventMessage($object->error, 'errors'); + } + } + } + else + { + header("Location: index.php"); + exit(); + } +} + +// Update record +else if ($action == 'update' && $user->rights->loan->write) +{ + if (! $cancel) + { + $result = $object->fetch($id); + + if ($object->fetch($id)) + { + $object->label = GETPOST("label"); + $object->datestart = dol_mktime(12, 0, 0, GETPOST('startmonth','int'), GETPOST('startday','int'), GETPOST('startyear','int')); + $object->dateend = dol_mktime(12, 0, 0, GETPOST('endmonth','int'), GETPOST('endday','int'), GETPOST('endyear','int')); + $object->nbterm = GETPOST("nbterm"); + $object->rate = GETPOST("rate"); + } + + $result = $object->update($user); + + if ($result > 0) + { + header("Location: " . $_SERVER["PHP_SELF"] . "?id=" . $id); + exit; + } + else + { + setEventMessage($object->error, 'errors'); + } + } + else + { + header("Location: " . $_SERVER["PHP_SELF"] . "?id=" . $id); + exit; + } +} + +/* + * View + */ + +$form = new Form($db); + +$help_url='EN:Module_Loan|FR:Module_Emprunt'; +llxHeader("",$langs->trans("Loan"),$help_url); + + +// Create mode +if ($action == 'create') +{ + //WYSIWYG Editor + require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; + + print_fiche_titre($langs->trans("NewLoan")); + + $datec = dol_mktime(12, 0, 0, GETPOST('remonth','int'), GETPOST('reday','int'), GETPOST('reyear','int')); + + print '
    ' . "\n"; + print ''; + print ''; + + print ''; + + // Label + print ''; + + // Bank account + if (! empty($conf->banque->enabled)) + { + print ''; + } + else + { + print ''; + } + + // Capital + print ''; + + // Date Start + print ""; + print ''; + + // Date End + print ""; + print ''; + + // Number of terms + print ''; + + // Rate + print ''; + + // Note + print ''; + print ''; + print ''; + print '
    '.$langs->trans("Label").'
    '.$langs->trans("Account").''; + $form->select_comptes($GETPOST["accountid"],"accountid",0,"courant=1",1); // Show list of bank account with courant + print '
    '.$langs->trans("Account").''; + print $langs->trans("NoBankAccountDefined"); + print '
    '.$langs->trans("Capital").'
    '.$langs->trans("DateStart").''; + print $form->select_date($datestart?$datestart:-1,'start','','','','add',1,1); + print '
    '.$langs->trans("DateEnd").''; + print $form->select_date($dateend?$dateend:-1,'end','','','','add',1,1); + print '
    '.$langs->trans("Nbterms").'
    '.$langs->trans("Rate").' %
    '.$langs->trans('Note').''; + + $doleditor = new DolEditor('note', GETPOST('note', 'alpha'), '', 200, 'dolibarr_notes', 'In', false, true, true, ROWS_8, 100); + print $doleditor->Create(1); + + print '
    '; + + print '
    '; + + // Accountancy + print ''; + + if ($conf->accounting->enabled) + { + print ''; + print ''; + + print ''; + print ''; + + print ''; + print ''; + } + else + { + print ''; + print ''; + + print ''; + print ''; + + print ''; + print ''; + } + + print '
    '.$langs->trans("LoanAccountancyCapitalCode").''; + print '
    '.$langs->trans("LoanAccountancyInsuranceCode").''; + print '
    '.$langs->trans("LoanAccountancyInterestCode").''; + print '
    '.$langs->trans("LoanAccountancyCapitalCode").''; + print '
    '.$langs->trans("LoanAccountancyInsuranceCode").''; + print '
    '.$langs->trans("LoanAccountancyInterestCode").''; + print '
    '; + + print '
        '; + print '
    '; + + print '
    '; +} + +// View +if ($id > 0) +{ + $result = $object->fetch($id); + + if ($result > 0) + { + $head=loan_prepare_head($object); + + dol_fiche_head($head, 'card', $langs->trans("Loan"),0,'bill'); + + // Confirm for loan + if ($action == 'paid') + { + $text=$langs->trans('ConfirmPayLoan'); + print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id,$langs->trans('PayLoan'),$text,"confirm_paid",'','',2); + } + + if ($action == 'delete') + { + $text=$langs->trans('ConfirmDeleteLoan'); + print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id,$langs->trans('DeleteLoan'),$text,'confirm_delete','','',2); + } + + if ($action == 'edit') + { + print '
    ' . "\n"; + print ''; + print ''; + print ''; + } + + print ''; + + // Ref + print '"; + + // Label + if ($action == 'edit') + { + print ''; + } + else + { + print ''; + } + + // Capital + print ''; + + // Date start + print ""; + print ""; + + // Date end + print ""; + print ""; + + // Nbterms + print ''; + + // Rate + print ''; + + // Status + print ''; + + print '
    '.$langs->trans("Ref").''; + print $form->showrefnav($object,'id'); + print "
    '.$langs->trans("Label").''; + print ''; + print '
    '.$langs->trans("Label").''.$object->label.'
    '.$langs->trans("Capital").''.price($object->capital,0,$outputlangs,1,-1,-1,$conf->currency).'
    ".$langs->trans("DateStart").""; + if ($action == 'edit') + { + print $form->select_date($object->datestart, 'start', 0, 0, 0, 'update', 1); + } + else + { + print dol_print_date($object->datestart,"day"); + } + print "
    ".$langs->trans("DateEnd").""; + if ($action == 'edit') + { + print $form->select_date($object->dateend, 'end', 0, 0, 0, 'update', 1); + } + else + { + print dol_print_date($object->dateend,"day"); + } + print "
    '.$langs->trans("Nbterms").''.$object->nbterm.'
    '.$langs->trans("Rate").''.$object->rate.' %
    '.$langs->trans("Status").''.$object->getLibStatut(4, $totalpaye).'
    '; + + if ($action == 'edit') + { + print '
    '; + print ''; + print '   '; + print ''; + print '
    '; + print '
    '; + } + + dol_fiche_end(); + + print ''; + print '"; + print "
    '; + + /* + * Payments + */ + $sql = "SELECT p.rowid, p.num_payment, datep as dp,"; + $sql.= " p.amount_capital, p.amount_insurance, p.amount_interest,"; + $sql.= " c.libelle as paiement_type"; + $sql.= " FROM ".MAIN_DB_PREFIX."payment_loan as p"; + $sql.= ", ".MAIN_DB_PREFIX."c_paiement as c "; + $sql.= ", ".MAIN_DB_PREFIX."loan as l"; + $sql.= " WHERE p.fk_loan = ".$id; + $sql.= " AND p.fk_loan = l.rowid"; + $sql.= " AND l.entity = ".$conf->entity; + $sql.= " AND p.fk_typepayment = c.id"; + $sql.= " ORDER BY dp DESC"; + + //print $sql; + $resql = $db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + $i = 0; $total = 0; + echo ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + $var=True; + while ($i < $num) + { + $objp = $db->fetch_object($resql); + $var=!$var; + print "'; + print '\n"; + print "\n"; + print '\n"; + print '\n"; + print '\n"; + print ""; + $totalpaid += $objp->amount_capital; + $i++; + } + + if ($object->paid == 0) + { + print ''; + print ''; + + $staytopay = $object->capital - $totalpaid; + + print ''; + print ''; + } + print "
    '.$langs->trans("RefPayment").''.$langs->trans("Date").''.$langs->trans("Type").''.$langs->trans("Insurance").''.$langs->trans("Interest").''.$langs->trans("Capital").' 
    "; + print ''.img_object($langs->trans("Payment"),"payment").' '.$objp->rowid.''.dol_print_date($db->jdate($objp->dp),'day')."".$objp->paiement_type.' '.$objp->num_payment."'.price($objp->amount_insurance)." ".$langs->trans("Currency".$conf->currency)."'.price($objp->amount_interest)." ".$langs->trans("Currency".$conf->currency)."'.price($objp->amount_capital)." ".$langs->trans("Currency".$conf->currency)."
    '.$langs->trans("AlreadyPaid").' :'.price($totalpaid).' '.$langs->trans("Currency".$conf->currency).'
    '.$langs->trans("AmountExpected").' :'.price($object->capital).' '.$langs->trans("Currency".$conf->currency).'
    '.$langs->trans("RemainderToPay").' :'.price($staytopay).' '.$langs->trans("Currency".$conf->currency).'
    "; + $db->free($resql); + } + else + { + dol_print_error($db); + } + print "
    "; + + /* + * Buttons actions + */ + if ($action != 'edit') + { + print '
    '; + + // Edit + if ($user->rights->loan->write) + { + print "id&action=edit\">".$langs->trans("Modify").""; + } + + // Emit payment + if ($object->paid == 0 && ((price2num($object->capital) > 0 && round($staytopay) < 0) || (price2num($object->capital) > 0 && round($staytopay) > 0)) && $user->rights->loan->write) + { + print "id&action=create\">".$langs->trans("DoPayment").""; + } + + // Classify 'paid' + if ($object->paid == 0 && round($staytopay) <=0 && $user->rights->loan->write) + { + print "id&action=paid\">".$langs->trans("ClassifyPaid").""; + } + + // Delete + if ($user->rights->loan->delete) + { + print "id&action=delete\">".$langs->trans("Delete").""; + } + + print "
    "; + } + } + else + { + // Loan not find + dol_print_error('',$object->error); + } +} + +llxFooter(); + +$db->close(); \ No newline at end of file diff --git a/htdocs/loan/class/index.html b/htdocs/loan/class/index.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/htdocs/loan/class/loan.class.php b/htdocs/loan/class/loan.class.php new file mode 100644 index 00000000000..9ab8a690494 --- /dev/null +++ b/htdocs/loan/class/loan.class.php @@ -0,0 +1,487 @@ + + * + * 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/loan/class/loan.class.php + * \ingroup loan + * \brief Class for loan module + */ +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; + + +/** \class Loan + * \brief Class to manage loan + */ +class Loan extends CommonObject +{ + public $element='loan'; + public $table='loan'; + public $table_element='loan'; + + var $id; + var $rowid; + var $ref; + var $datestart; + var $dateend; + var $label; + var $capital; + var $nbterm; + var $rate; + var $note; + var $paid; + var $account_capital; + var $account_insurance; + var $account_interest; + var $date_creation; + var $date_modification; + var $date_validation; + var $fk_bank; + var $fk_user_creat; + var $fk_user_modif; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + $this->db = $db; + return 1; + } + + /** + * Load object in memory from database + * + * @param int $id id object + * @return int <0 error , >=0 no error + */ + function fetch($id) + { + $sql = "SELECT l.rowid, l.label, l.capital, l.datestart, l.dateend, l.nbterm, l.rate, l.note,"; + $sql.= " l.paid"; + $sql.= " FROM ".MAIN_DB_PREFIX."loan as l"; + $sql.= " WHERE l.rowid = ".$id; + + dol_syslog(get_class($this)."::fetch", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + if ($this->db->num_rows($resql)) + { + $obj = $this->db->fetch_object($resql); + + $this->id = $obj->rowid; + $this->ref = $obj->rowid; + $this->datestart = $this->db->jdate($obj->datestart); + $this->dateend = $this->db->jdate($obj->dateend); + $this->label = $obj->label; + $this->capital = $obj->capital; + $this->nbterm = $obj->nbterm; + $this->rate = $obj->rate; + $this->note = $obj->note; + $this->paid = $obj->paid; + + return 1; + } + else + { + return 0; + } + $this->db->free($resql); + } + else + { + $this->error=$this->db->lasterror(); + return -1; + } + } + + + /** + * Create a loan into database + * + * @param User $user User making creation + * @return int <0 if KO, id if OK + */ + function create($user) + { + global $conf; + + $error=0; + + $now=dol_now(); + + // clean parameters + $newcapital=price2num($this->capital,'MT'); + if (isset($this->note)) $this->note = trim($this->note); + if (isset($this->account_capital)) $this->account_capital = trim($this->account_capital); + if (isset($this->account_insurance)) $this->account_insurance = trim($this->account_insurance); + if (isset($this->account_interest)) $this->account_interest = trim($this->account_interest); + if (isset($this->fk_bank)) $this->fk_bank=trim($this->fk_bank); + if (isset($this->fk_user_creat)) $this->fk_user_creat=trim($this->fk_user_creat); + if (isset($this->fk_user_modif)) $this->fk_user_modif=trim($this->fk_user_modif); + + // Check parameters + if (! $newcapital > 0 || empty($this->datestart) || empty($this->dateend)) + { + $this->error="ErrorBadParameter"; + return -2; + } + if (($conf->accounting->enabled) && empty($this->account_capital) && empty($this->account_insurance) && empty($this->account_interest)) + { + $this->error="ErrorAccountingParameter"; + return -2; + } + + $this->db->begin(); + + $sql = "INSERT INTO ".MAIN_DB_PREFIX."loan (label, fk_bank, capital, datestart, dateend, nbterm, rate, note"; + $sql.= " ,accountancy_account_capital, accountancy_account_insurance, accountancy_account_interest, entity"; + $sql.= " ,datec, fk_user_author)"; + $sql.= " VALUES ('".$this->db->escape($this->label)."',"; + $sql.= " '".$this->db->escape($this->fk_bank)."',"; + $sql.= " '".price2num($newcapital)."',"; + $sql.= " '".$this->db->idate($this->datestart)."',"; + $sql.= " '".$this->db->idate($this->dateend)."',"; + $sql.= " '".$this->db->escape($this->nbterm)."',"; + $sql.= " '".$this->db->escape($this->rate)."',"; + $sql.= " '".$this->db->escape($this->note)."',"; + $sql.= " '".$this->db->escape($this->account_capital)."',"; + $sql.= " '".$this->db->escape($this->account_insurance)."',"; + $sql.= " '".$this->db->escape($this->account_interest)."',"; + $sql.= " ".$conf->entity.","; + $sql.= " '".$this->db->idate($now)."',"; + $sql.= " ".$user->id; + $sql.= ")"; + + dol_syslog(get_class($this)."::create", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $this->id=$this->db->last_insert_id(MAIN_DB_PREFIX."loan"); + + //dol_syslog("Loans::create this->id=".$this->id); + $this->db->commit(); + return $this->id; + } + else + { + $this->error=$this->db->error(); + $this->db->rollback(); + return -1; + } + } + + + /** + * Delete a loan + * + * @param User $user Object user making delete + * @return int <0 if KO, >0 if OK + */ + function delete($user) + { + $error=0; + + $this->db->begin(); + + // Get bank transaction lines for this loan + include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; + $account=new Account($this->db); + $lines_url=$account->get_url('',$this->id,'loan'); + + // Delete bank urls + foreach ($lines_url as $line_url) + { + if (! $error) + { + $accountline=new AccountLine($this->db); + $accountline->fetch($line_url['fk_bank']); + $result=$accountline->delete_urls($user); + if ($result < 0) + { + $error++; + } + } + } + + // Delete payments + if (! $error) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."payment_loan where fk_loan='".$this->id."'"; + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + $error++; + $this->error=$this->db->lasterror(); + } + } + + if (! $error) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."loan where rowid='".$this->id."'"; + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + $error++; + $this->error=$this->db->lasterror(); + } + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + + } + + + /** + * Update loan + * + * @param User $user User who modified + * @return int <0 if error, >0 if ok + */ + function update($user) + { + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."loan"; + $sql.= " SET label='".$this->db->escape($this->label)."',"; + $sql.= " datestart='".$this->db->idate($this->datestart)."',"; + $sql.= " dateend='".$this->db->idate($this->dateend)."',"; + $sql.= " fk_user_modif = ".$user->id; + $sql.= " WHERE rowid=".$this->id; + + dol_syslog(get_class($this)."::update", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->error(); + $this->db->rollback(); + return -1; + } + } + + /** + * Tag loan as payed completely + * + * @param User $user Object user making change + * @return int <0 if KO, >0 if OK + */ + function set_paid($user) + { + $sql = "UPDATE ".MAIN_DB_PREFIX."loan SET"; + $sql.= " paid = 1"; + $sql.= " WHERE rowid = ".$this->id; + $return = $this->db->query($sql); + if ($return) { + return 1; + } else { + $this->error=$this->db->lasterror(); + return -1; + } + } + + /** + * Return label of loan status (unpaid, paid) + * + * @param int $mode 0=label, 1=short label, 2=Picto + Short label, 3=Picto, 4=Picto + Label + * @param double $alreadypaid 0=No payment already done, >0=Some payments were already done (we recommand to put here amount payed if you have it, 1 otherwise) + * @return string Label + */ + function getLibStatut($mode=0,$alreadypaid=-1) + { + return $this->LibStatut($this->paid,$mode,$alreadypaid); + } + + /** + * Return label for given status + * + * @param int $statut Id statut + * @param int $mode 0=Label, 1=Short label, 2=Picto + Short label, 3=Picto, 4=Picto + Label, 5=Short label + Picto + * @param double $alreadypaid 0=No payment already done, >0=Some payments were already done (we recommand to put here amount payed if you have it, 1 otherwise) + * @return string Label + */ + function LibStatut($statut,$mode=0,$alreadypaid=-1) + { + global $langs; + $langs->load('customers'); + $langs->load('bills'); + + if ($mode == 0) + { + if ($statut == 0) return $langs->trans("Unpaid"); + if ($statut == 1) return $langs->trans("Paid"); + } + if ($mode == 1) + { + if ($statut == 0) return $langs->trans("Unpaid"); + if ($statut == 1) return $langs->trans("Paid"); + } + if ($mode == 2) + { + if ($statut == 0 && $alreadypaid <= 0) return img_picto($langs->trans("Unpaid"), 'statut1').' '.$langs->trans("Unpaid"); + if ($statut == 0 && $alreadypaid > 0) return img_picto($langs->trans("BillStatusStarted"), 'statut3').' '.$langs->trans("BillStatusStarted"); + if ($statut == 1) return img_picto($langs->trans("Paid"), 'statut6').' '.$langs->trans("Paid"); + } + if ($mode == 3) + { + if ($statut == 0 && $alreadypaid <= 0) return img_picto($langs->trans("Unpaid"), 'statut1'); + if ($statut == 0 && $alreadypaid > 0) return img_picto($langs->trans("BillStatusStarted"), 'statut3'); + if ($statut == 1) return img_picto($langs->trans("Paid"), 'statut6'); + } + if ($mode == 4) + { + if ($statut == 0 && $alreadypaid <= 0) return img_picto($langs->trans("Unpaid"), 'statut1').' '.$langs->trans("Unpaid"); + if ($statut == 0 && $alreadypaid > 0) return img_picto($langs->trans("BillStatusStarted"), 'statut3').' '.$langs->trans("BillStatusStarted"); + if ($statut == 1) return img_picto($langs->trans("Paid"), 'statut6').' '.$langs->trans("Paid"); + } + if ($mode == 5) + { + if ($statut == 0 && $alreadypaid <= 0) return $langs->trans("Unpaid").' '.img_picto($langs->trans("Unpaid"), 'statut1'); + if ($statut == 0 && $alreadypaid > 0) return $langs->trans("BillStatusStarted").' '.img_picto($langs->trans("BillStatusStarted"), 'statut3'); + if ($statut == 1) return $langs->trans("Paid").' '.img_picto($langs->trans("Paid"), 'statut6'); + } + + return "Error, mode/status not found"; + } + + + /** + * Return clicable name (with eventually the picto) + * + * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto + * @param int $maxlen Label max length + * @return string Chaine with URL + */ + function getLinkUrl($withpicto=0,$maxlen=0) + { + global $langs; + + $result=''; + + $link = ''; + $linkend=''; + + if ($withpicto) $result.=($link.img_object($langs->trans("ShowLoan").': '.$this->label,'bill').$linkend.' '); + if ($withpicto && $withpicto != 2) $result.=' '; + if ($withpicto != 2) $result.=$link.($maxlen?dol_trunc($this->label,$maxlen):$this->label).$linkend; + return $result; + } + + /** + * Return amount of payments already done + * + * @return int Amount of payment already done, <0 if KO + */ + function getSumPayment() + { + $table='payment_loan'; + $field='fk_loan'; + + $sql = 'SELECT sum(amount) as amount'; + $sql.= ' FROM '.MAIN_DB_PREFIX.$table; + $sql.= ' WHERE '.$field.' = '.$this->id; + + dol_syslog(get_class($this)."::getSumPayment", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $amount=0; + + $obj = $this->db->fetch_object($resql); + if ($obj) $amount=$obj->amount?$obj->amount:0; + + $this->db->free($resql); + return $amount; + } + else + { + $this->error=$this->db->lasterror(); + return -1; + } + } + + /** + * Information on record + * + * @param int $id Id of record + * @return void + */ + function info($id) + { + $sql = 'SELECT l.rowid, l.datec, l.fk_user_author, l.fk_user_modif,'; + $sql.= ' l.tms'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'loan as l'; + $sql.= ' WHERE l.rowid = '.$id; + + dol_syslog(get_class($this).'::info', LOG_DEBUG); + $result = $this->db->query($sql); + + if ($result) + { + if ($this->db->num_rows($result)) + { + $obj = $this->db->fetch_object($result); + $this->id = $obj->rowid; + if ($obj->fk_user_author) + { + $cuser = new User($this->db); + $cuser->fetch($obj->fk_user_author); + $this->user_creation = $cuser; + } + if ($obj->fk_user_modif) + { + $muser = new User($this->db); + $muser->fetch($obj->fk_user_modif); + $this->user_modification = $muser; + } + $this->date_creation = $this->db->jdate($obj->datec); + if (empty($obj->fk_user_modif)) $obj->tms = ""; + $this->date_modification = $this->db->jdate($obj->tms); + + return 1; + } + else + { + return 0; + } + $this->db->free($result); + } + else + { + $this->error=$this->db->lasterror(); + return -1; + } + } +} \ No newline at end of file diff --git a/htdocs/loan/class/paymentloan.class.php b/htdocs/loan/class/paymentloan.class.php new file mode 100644 index 00000000000..bb94a86d945 --- /dev/null +++ b/htdocs/loan/class/paymentloan.class.php @@ -0,0 +1,526 @@ + + * + * 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/loan/class/paymentloan.class.php + * \ingroup facture + * \brief File of class to manage payment of loans + */ + +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; + + +/** \class PaymentLoan + * \brief Class to manage payments of loans + */ +class PaymentLoan extends CommonObject +{ + public $element='payment_loan'; //!< Id that identify managed objects + public $table_element='payment_loan'; //!< Name of table without prefix where object is stored + + var $id; + var $ref; + + var $fk_loan; + var $datec=''; + var $tms=''; + var $datep=''; + var $amounts=array(); // Array of amounts + var $amount_capital; // Total amount of payment + var $amount_insurance; + var $amount_interest; + var $fk_typepayment; + var $num_payment; + var $note; + var $fk_bank; + var $fk_user_creat; + var $fk_user_modif; + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + $this->db = $db; + } + + /** + * Create payment of loan into database. + * Use this->amounts to have list of lines for the payment + * + * @param User $user User making payment + * @return int <0 if KO, id of payment if OK + */ + function create($user) + { + global $conf, $langs; + + $error=0; + + $now=dol_now(); + + // Validate parameters + if (! $this->datepaid) + { + $this->error='ErrorBadValueForParameter'; + return -1; + } + + // Clean parameters + if (isset($this->fk_loan)) $this->fk_loan = trim($this->fk_loan); + if (isset($this->amount_capital)) $this->amount_capital = trim($this->amount_capital); + if (isset($this->amount_insurance)) $this->amount_insurance = trim($this->amount_insurance); + if (isset($this->amount_interest)) $this->amount_interest = trim($this->amount_interest); + if (isset($this->fk_typepayment)) $this->fk_typepayment = trim($this->fk_typepayment); + if (isset($this->num_payment)) $this->num_payment = trim($this->num_payment); + if (isset($this->note)) $this->note = trim($this->note); + if (isset($this->fk_bank)) $this->fk_bank = trim($this->fk_bank); + if (isset($this->fk_user_creat)) $this->fk_user_creat = trim($this->fk_user_creat); + if (isset($this->fk_user_modif)) $this->fk_user_modif = trim($this->fk_user_modif); + + $totalamount = 0; + foreach ($this->amounts as $key => $value) // How payment is dispatch + { + $newvalue = price2num($value,'MT'); + $this->amounts[$key] = $newvalue; + $totalamount += $newvalue; + } + $totalamount = price2num($totalamount); + + // Check parameters + if ($totalamount == 0) return -1; // Negative amounts are accepted for reject prelevement but not null + + + $this->db->begin(); + + if ($totalamount != 0) + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."payment_loan (fk_loan, datec, datep, amount_capital, amount_insurance, amount_interest,"; + $sql.= " fk_typepayment, num_payment, note, fk_user_creat, fk_bank)"; + $sql.= " VALUES ($this->chid, '".$this->db->idate($now)."',"; + $sql.= " '".$this->db->idate($this->datepaid)."',"; + $sql.= " ".$totalamount.","; + $sql.= " ".$this->paymenttype.", '".$this->db->escape($this->num_payment)."', '".$this->db->escape($this->note)."', ".$user->id.","; + $sql.= " 0)"; + + dol_syslog(get_class($this)."::create", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."payment_loan"); + } + else + { + $error++; + } + + } + + if ($totalamount != 0 && ! $error) + { + $this->amount_capital=$totalamount; + $this->total=$totalamount; // deprecated + $this->db->commit(); + return $this->id; + } + else + { + $this->error=$this->db->error(); + $this->db->rollback(); + return -1; + } + } + + /** + * Load object in memory from database + * + * @param int $id Id object + * @return int <0 if KO, >0 if OK + */ + function fetch($id) + { + global $langs; + $sql = "SELECT"; + $sql.= " t.rowid,"; + $sql.= " t.fk_loan,"; + $sql.= " t.datec,"; + $sql.= " t.tms,"; + $sql.= " t.datep,"; + $sql.= " t.amount_capital,"; + $sql.= " t.amount_insurance,"; + $sql.= " t.amount_interest,"; + $sql.= " t.fk_typepayment,"; + $sql.= " t.num_payment,"; + $sql.= " t.note,"; + $sql.= " t.fk_bank,"; + $sql.= " t.fk_user_creat,"; + $sql.= " t.fk_user_modif,"; + $sql.= " pt.code as type_code, pt.libelle as type_libelle,"; + $sql.= ' b.fk_account'; + $sql.= " FROM (".MAIN_DB_PREFIX."c_paiement as pt, ".MAIN_DB_PREFIX."payment_loan as t)"; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON t.fk_bank = b.rowid'; + $sql.= " WHERE t.rowid = ".$id." AND t.fk_typepayment = pt.id"; + + dol_syslog(get_class($this)."::fetch", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + if ($this->db->num_rows($resql)) + { + $obj = $this->db->fetch_object($resql); + + $this->id = $obj->rowid; + $this->ref = $obj->rowid; + + $this->fk_loan = $obj->fk_loan; + $this->datec = $this->db->jdate($obj->datec); + $this->tms = $this->db->jdate($obj->tms); + $this->datep = $this->db->jdate($obj->datep); + $this->amount_capital = $obj->amount_capital; + $this->amount_insurance = $obj->amount_insurance; + $this->amount_interest = $obj->amount_interest; + $this->fk_typepayment = $obj->fk_typepayment; + $this->num_payment = $obj->num_payment; + $this->note = $obj->note; + $this->fk_bank = $obj->fk_bank; + $this->fk_user_creat = $obj->fk_user_creat; + $this->fk_user_modif = $obj->fk_user_modif; + + $this->type_code = $obj->type_code; + $this->type_libelle = $obj->type_libelle; + + $this->bank_account = $obj->fk_account; + $this->bank_line = $obj->fk_bank; + } + $this->db->free($resql); + + return 1; + } + else + { + $this->error="Error ".$this->db->lasterror(); + return -1; + } + } + + + /** + * Update database + * + * @param User $user User that modify + * @param int $notrigger 0=launch triggers after, 1=disable triggers + * @return int <0 if KO, >0 if OK + */ + function update($user=0, $notrigger=0) + { + global $conf, $langs; + $error=0; + + // Clean parameters + if (isset($this->fk_loan)) $this->fk_loan=trim($this->fk_loan); + if (isset($this->amount_capital)) $this->amount_capital=trim($this->amount_capital); + if (isset($this->amount_insurance)) $this->amount_insurance=trim($this->amount_insurance); + if (isset($this->amount_interest)) $this->amount_interest=trim($this->amount_interest); + if (isset($this->fk_typepayment)) $this->fk_typepayment=trim($this->fk_typepayment); + if (isset($this->num_payment)) $this->num_payment=trim($this->num_payment); + if (isset($this->note)) $this->note=trim($this->note); + if (isset($this->fk_bank)) $this->fk_bank=trim($this->fk_bank); + if (isset($this->fk_user_creat)) $this->fk_user_creat=trim($this->fk_user_creat); + if (isset($this->fk_user_modif)) $this->fk_user_modif=trim($this->fk_user_modif); + + // Check parameters + // Put here code to add control on parameters values + + // Update request + $sql = "UPDATE ".MAIN_DB_PREFIX."payment_loan SET"; + + $sql.= " fk_loan=".(isset($this->fk_loan)?$this->fk_loan:"null").","; + $sql.= " datec=".(dol_strlen($this->datec)!=0 ? "'".$this->db->idate($this->datec)."'" : 'null').","; + $sql.= " tms=".(dol_strlen($this->tms)!=0 ? "'".$this->db->idate($this->tms)."'" : 'null').","; + $sql.= " datep=".(dol_strlen($this->datep)!=0 ? "'".$this->db->idate($this->datep)."'" : 'null').","; + $sql.= " amount_capital=".(isset($this->amount_capital)?$this->amount_capital:"null").","; + $sql.= " amount_insurance=".(isset($this->amount_insurance)?$this->amount_insurance:"null").","; + $sql.= " amount_interest=".(isset($this->amount_interest)?$this->amount_interest:"null").","; + $sql.= " fk_typepayment=".(isset($this->fk_typepayment)?$this->fk_typepayment:"null").","; + $sql.= " num_payment=".(isset($this->num_payment)?"'".$this->db->escape($this->num_payment)."'":"null").","; + $sql.= " note=".(isset($this->note)?"'".$this->db->escape($this->note)."'":"null").","; + $sql.= " fk_bank=".(isset($this->fk_bank)?$this->fk_bank:"null").","; + $sql.= " fk_user_creat=".(isset($this->fk_user_creat)?$this->fk_user_creat:"null").","; + $sql.= " fk_user_modif=".(isset($this->fk_user_modif)?$this->fk_user_modif:"null").""; + + $sql.= " WHERE rowid=".$this->id; + + $this->db->begin(); + + dol_syslog(get_class($this)."::update", LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } + + if (! $error) + { + if (! $notrigger) + { + // Uncomment this and change MYOBJECT to your own tag if you + // want this action call a trigger. + + //// Call triggers + //include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + //$interface=new Interfaces($this->db); + //$result=$interface->run_triggers('MYOBJECT_MODIFY',$this,$user,$langs,$conf); + //if ($result < 0) { $error++; $this->errors=$interface->errors; } + //// End call triggers + } + } + + // Commit or rollback + if ($error) + { + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + else + { + $this->db->commit(); + return 1; + } + } + + + /** + * Delete object in database + * + * @param User $user User that delete + * @param int $notrigger 0=launch triggers after, 1=disable triggers + * @return int <0 if KO, >0 if OK + */ + function delete($user, $notrigger=0) + { + global $conf, $langs; + $error=0; + + $this->db->begin(); + + if (! $error) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_url"; + $sql.= " WHERE type='payment_loan' AND url_id=".$this->id; + + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } + } + + if (! $error) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."payment_loan"; + $sql.= " WHERE rowid=".$this->id; + + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } + } + + if (! $error) + { + if (! $notrigger) + { + // Uncomment this and change MYOBJECT to your own tag if you + // want this action call a trigger. + + //// Call triggers + //include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + //$interface=new Interfaces($this->db); + //$result=$interface->run_triggers('MYOBJECT_DELETE',$this,$user,$langs,$conf); + //if ($result < 0) { $error++; $this->errors=$interface->errors; } + //// End call triggers + } + } + + // Commit or rollback + if ($error) + { + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + else + { + $this->db->commit(); + return 1; + } + } + + /** + * Add record into bank for payment with links between this bank record and invoices of payment. + * All payment properties must have been set first like after a call to create(). + * + * @param User $user Object of user making payment + * @param string $mode 'payment_loan' + * @param string $label Label to use in bank record + * @param int $accountid Id of bank account to do link with + * @param string $emetteur_nom Name of transmitter + * @param string $emetteur_banque Name of bank + * @return int <0 if KO, >0 if OK + */ + function addPaymentToBank($user,$mode,$label,$accountid,$emetteur_nom,$emetteur_banque) + { + global $conf; + + $error=0; + + if (! empty($conf->banque->enabled)) + { + require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; + + $acc = new Account($this->db); + $acc->fetch($accountid); + + $total=$this->total; + if ($mode == 'payment_loan') $total=-$total; + + // Insert payment into llx_bank + $bank_line_id = $acc->addline( + $this->datepaid, + $this->paymenttype, // Payment mode id or code ("CHQ or VIR for example") + $label, + $total, + $this->num_payment, + '', + $user, + $emetteur_nom, + $emetteur_banque + ); + + // Update fk_bank into llx_paiement. + // We know the payment who generated the account write + if ($bank_line_id > 0) + { + $result=$this->update_fk_bank($bank_line_id); + if ($result <= 0) + { + $error++; + dol_print_error($this->db); + } + + // Add link 'payment_loan' in bank_url between payment and bank transaction + $url=''; + if ($mode == 'payment_loan') $url=DOL_URL_ROOT.'/loan/payment/card.php?id='; + if ($url) + { + $result=$acc->add_url_line($bank_line_id, $this->id, $url, '(payment)', $mode); + if ($result <= 0) + { + $error++; + dol_print_error($this->db); + } + } + + // Add link 'company' in bank_url between invoice and bank transaction (for each invoice concerned by payment) + $linkaddedforthirdparty=array(); + foreach ($this->amounts as $key => $value) + { + if ($mode == 'payment_loan') + { + $loan = new Loan($this->db); + $loan->fetch($key); + $result=$acc->add_url_line($bank_line_id, $loan->id, DOL_URL_ROOT.'/loan/card.php?id=', $loan->type_libelle.(($loan->lib && $loan->lib!=$loan->type_libelle)?' ('.$loan->lib.')':''),'loan'); + if ($result <= 0) dol_print_error($this->db); + } + } + } + else + { + $this->error=$acc->error; + $error++; + } + } + + if (! $error) + { + return 1; + } + else + { + return -1; + } + } + + + /** + * Update link between loan's payment and the line generate in llx_bank + * + * @param int $id_bank Id if bank + * @return int >0 if OK, <=0 if KO + */ + function update_fk_bank($id_bank) + { + $sql = "UPDATE ".MAIN_DB_PREFIX."payment_loan SET fk_bank = ".$id_bank." WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::update_fk_bank", LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) + { + return 1; + } + else + { + $this->error=$this->db->error(); + return 0; + } + } + + /** + * Return clicable name (with eventually a picto) + * + * @param int $withpicto 0=No picto, 1=Include picto into link, 2=No picto + * @param int $maxlen Max length label + * @return string Chaine with URL + */ + function getNameUrl($withpicto=0,$maxlen=0) + { + global $langs; + + $result=''; + + if (empty($this->ref)) $this->ref=$this->lib; + + if (!empty($this->id)) + { + $link = ''; + $linkend=''; + + if ($withpicto) $result.=($link.img_object($langs->trans("ShowPayment").': '.$this->ref,'payment').$linkend.' '); + if ($withpicto && $withpicto != 2) $result.=' '; + if ($withpicto != 2) $result.=$link.($maxlen?dol_trunc($this->ref,$maxlen):$this->ref).$linkend; + } + + return $result; + } +} + + diff --git a/htdocs/loan/document.php b/htdocs/loan/document.php new file mode 100644 index 00000000000..788048a215b --- /dev/null +++ b/htdocs/loan/document.php @@ -0,0 +1,171 @@ + + * + * 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/loan/document.php + * \ingroup loan + * \brief Page with attached files on loan + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; + +$langs->load("other"); +$langs->load("companies"); +$langs->load("compta"); +$langs->load("bills"); +$langs->load("loan"); + +$id = GETPOST('id','int'); +$action = GETPOST("action"); +$confirm = GETPOST('confirm', 'alpha'); + +// Security check +if ($user->societe_id) $socid=$user->societe_id; +$result = restrictedArea($user, 'loan', $id, '',''); + +// Get parameters +$sortfield = GETPOST("sortfield",'alpha'); +$sortorder = GETPOST("sortorder",'alpha'); +$page = GETPOST("page",'int'); +if ($page == -1) { + $page = 0; +} +$offset = $conf->liste_limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (! $sortorder) $sortorder="ASC"; +if (! $sortfield) $sortfield="name"; + +$object = new Loan($db); +if ($id > 0) $object->fetch($id); + +$upload_dir = $conf->loan->dir_output.'/'.dol_sanitizeFileName($object->ref); +$modulepart='loan'; + + +/* + * Actions + */ + +include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_pre_headers.tpl.php'; + + +/* + * View + */ + +$form = new Form($db); + +$help_url='EN:Module_Loan|FR:Module_Emprunt'; +llxHeader("",$langs->trans("Loan"),$help_url); + +if ($object->id) +{ + $alreadypayed=$object->getSumPayment(); + + $head = loan_prepare_head($object, $user); + + dol_fiche_head($head, 'documents', $langs->trans("Loan"), 0, 'bill'); + + + // Construit liste des fichiers + $filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); + $totalsize=0; + foreach($filearray as $key => $file) + { + $totalsize+=$file['size']; + } + + + print ''; + + // Ref + print '"; + + // Label + if ($action == 'edit') + { + print ''; + } + else + { + print ''; + } + + // Amount + print ''; + + // Date start + print ""; + print ""; + print ""; + + // Date end + print ""; + print ""; + print ""; + + // Status + print ''; + + print ''; + print ''; + print '
    '.$langs->trans("Ref").''; + print $form->showrefnav($object,'id'); + print "
    '.$langs->trans("Label").''; + print ''; + print '
    '.$langs->trans("Label").''.$object->label.'
    '.$langs->trans("Capital").''.price($object->capital,0,$outputlangs,1,-1,-1,$conf->currency).'
    ".$langs->trans("DateStart").""; + if ($action == 'edit') + { + print $form->select_date($object->datestart, 'start', 0, 0, 0, 'loan', 1); + } + else + { + print dol_print_date($object->datestart,"day"); + } + print "
    ".$langs->trans("DateEnd").""; + if ($action == 'edit') + { + print $form->select_date($object->dateend, 'end', 0, 0, 0, 'loan', 1); + } + else + { + print dol_print_date($object->dateend,"day"); + } + print "
    '.$langs->trans("Status").''.$object->getLibStatut(4,$alreadypayed).'
    '.$langs->trans("NbOfAttachedFiles").''.count($filearray).'
    '.$langs->trans("TotalSizeOfAttachedFiles").''.$totalsize.' '.$langs->trans("bytes").'
    '; + + print ''; + + $modulepart = 'loan'; + $permission = $user->rights->loan->write; + $param = '&id=' . $object->id; + include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_post_headers.tpl.php'; +} +else +{ + print $langs->trans("ErrorUnknown"); +} + + +llxFooter(); + +$db->close(); diff --git a/htdocs/loan/index.html b/htdocs/loan/index.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/htdocs/loan/index.php b/htdocs/loan/index.php new file mode 100644 index 00000000000..082e5d0d0c2 --- /dev/null +++ b/htdocs/loan/index.php @@ -0,0 +1,153 @@ + + * + * 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/loan/index.php + * \ingroup loan + * \brief Page to list all loans + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; + +$langs->load("loan"); +$langs->load("compta"); +$langs->load("banks"); +$langs->load("bills"); + +// Security check +$socid = isset($_GET["socid"])?$_GET["socid"]:''; +if ($user->societe_id) $socid=$user->societe_id; +$result = restrictedArea($user, 'loan', '', '', ''); + +$sortfield = GETPOST("sortfield",'alpha'); +$sortorder = GETPOST("sortorder",'alpha'); +$page = GETPOST("page",'int'); +if ($page == -1) { $page = 0; } +$offset = $conf->liste_limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (! $sortfield) $sortfield="l.rowid"; +if (! $sortorder) $sortorder="DESC"; +$limit = $conf->liste_limit; + +$search_ref=GETPOST('search_ref','int'); +$search_label=GETPOST('search_label','alpha'); +$search_amount=GETPOST('search_amount','alpha'); +$filtre=GETPOST("filtre"); + +// Purge search criteria +if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter")) // Both test are required to be compatible with all browsers +{ + $search_ref=""; + $search_label=""; + $search_amount=""; +} + +/* + * View + */ + +$loan_static = new Loan($db); + +llxHeader(); + +$sql = "SELECT l.rowid, l.label, l.capital, l.datestart, l.dateend,"; +$sql.= " SUM(pl.amount_capital) as alreadypayed"; +$sql.= " FROM ".MAIN_DB_PREFIX."loan as l LEFT JOIN ".MAIN_DB_PREFIX."payment_loan AS pl"; +$sql.= " ON l.rowid = pl.fk_loan"; +$sql.= " WHERE l.entity = ".$conf->entity; +if ($search_amount) $sql.=" AND l.capital='".$db->escape(price2num(trim($search_amount)))."'"; +if ($search_ref) $sql.=" AND l.rowid = ".$db->escape($search_ref); +if ($search_label) $sql.=" AND l.label LIKE '%".$db->escape($search_label)."%'"; +if ($filtre) { + $filtre=str_replace(":","=",$filtre); + $sql .= " AND ".$filtre; +} +$sql.= " GROUP BY l.rowid, l.label, l.capital, l.datestart, l.dateend"; +$sql.= $db->order($sortfield,$sortorder); +$sql.= $db->plimit($limit+1, $offset); + +//print $sql; +$resql=$db->query($sql); +if ($resql) +{ + $num = $db->num_rows($resql); + $i = 0; + $var=true; + + print_fiche_titre($langs->trans("Loans")); + + print '
    '."\n"; + print ''; + print ''; + print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"l.rowid","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Label"),$_SERVER["PHP_SELF"],"l.label","",$param,'align="left"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Capital"),$_SERVER["PHP_SELF"],"l.capital","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DateStart"),$_SERVER["PHP_SELF"],"l.datestart","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"l.paid","",$param,'align="right"',$sortfield,$sortorder); + print "\n"; + + // Filters lines + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + while ($i < min($num,$limit)) + { + $obj = $db->fetch_object($resql); + + $var = !$var; + print ""; + + // Ref + print ''; + + // Label + print ''; + + // Capital + print ''; + + // Date start + print ''; + + print ''; + + print "\n"; + + $i++; + } + + print "
     '; + print ''; + print ''; + print '
    '.img_object($langs->trans("ShowLoan"),"label").' '.$obj->rowid.''.dol_trunc($obj->label,42).''.price($obj->capital).''.dol_print_date($db->jdate($obj->datestart), 'day').''.$loan_static->LibStatut($obj->paid,5,$obj->alreadypayed).'
    "; + print "
    \n"; + $db->free($resql); +} +else +{ + dol_print_error($db); +} +llxFooter(); + +$db->close(); \ No newline at end of file diff --git a/htdocs/loan/info.php b/htdocs/loan/info.php new file mode 100644 index 00000000000..16c349b92e9 --- /dev/null +++ b/htdocs/loan/info.php @@ -0,0 +1,71 @@ + + * + * 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/loan/info.php + * \ingroup loan + * \brief Page with info about loan + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + +$langs->load("compta"); +$langs->load("bills"); +$langs->load("loan"); + +$id=GETPOST('id','int'); +$action=GETPOST("action"); + +// Security check +$socid = GETPOST('socid','int'); +if ($user->societe_id) $socid=$user->societe_id; +$result = restrictedArea($user, 'loan', $id, '',''); + + +/* + * View + */ + +$help_url='EN:Module_Loan|FR:Module_Emprunt'; +llxHeader("",$langs->trans("Loan"),$help_url); + +if ($id > 0) { + $loan = new Loan($db); + $loan->fetch($id); + $loan->info($id); + + $head = loan_prepare_head($loan); + + dol_fiche_head($head, 'info', $langs->trans("Loan"), 0, 'bill'); + + print '
    '; + dol_print_object_info($loan); + print '
    '; + + print ''; +} +else +{ + // $id ? +} + +llxFooter(); + +$db->close(); diff --git a/htdocs/loan/payment/card.php b/htdocs/loan/payment/card.php new file mode 100644 index 00000000000..f75a2244154 --- /dev/null +++ b/htdocs/loan/payment/card.php @@ -0,0 +1,302 @@ + + * + * 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/loan/payment/card.php + * \ingroup loan + * \brief Payment's card of loan + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; +require_once DOL_DOCUMENT_ROOT.'/loan/class/paymentloan.class.php'; +if (! empty($conf->banque->enabled)) require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; + +$langs->load('bills'); +$langs->load('banks'); +$langs->load('companies'); +$langs->load('loan'); + +// Security check +$id=GETPOST("id"); +$action=GETPOST("action"); +$confirm=GETPOST('confirm'); +if ($user->societe_id) $socid=$user->societe_id; +// TODO ajouter regle pour restreindre acces paiement +//$result = restrictedArea($user, 'facture', $id,''); + +$payment = new PaymentLoan($db); +if ($id > 0) +{ + $result=$payment->fetch($id); + if (! $result) dol_print_error($db,'Failed to get payment id '.$id); +} + + +/* + * Actions + */ + +// Delete payment +if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->loan->delete) +{ + $db->begin(); + + $result = $payment->delete($user); + if ($result > 0) + { + $db->commit(); + header("Location: ".DOL_URL_ROOT."/loan/index.php"); + exit; + } + else + { + setEventMessage($payment->error, 'errors'); + $db->rollback(); + } +} + +// Create payment +if ($action == 'confirm_valide' && $confirm == 'yes' && $user->rights->loan->write) +{ + $db->begin(); + + $result=$payment->valide(); + + if ($result > 0) + { + $db->commit(); + + $factures=array(); // TODO Get all id of invoices linked to this payment + foreach($factures as $id) + { + $fac = new Facture($db); + $fac->fetch($id); + + $outputlangs = $langs; + if (! empty($_REQUEST['lang_id'])) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($_REQUEST['lang_id']); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + $fac->generateDocument($fac->modelpdf, $outputlangs); + } + } + + header('Location: card.php?id='.$payment->id); + exit; + } + else + { + setEventMessage($payment->error); + $db->rollback(); + } +} + + +/* + * View + */ + +llxHeader(); + +$loan = new Loan($db); +$form = new Form($db); + +$h=0; + +$head[$h][0] = DOL_URL_ROOT.'/loan/payment/card.php?id='.$_GET["id"]; +$head[$h][1] = $langs->trans("Card"); +$hselected = $h; +$h++; + +dol_fiche_head($head, $hselected, $langs->trans("PaymentLoan"), 0, 'payment'); + +/* + * Confirm deletion of the payment + */ +if ($action == 'delete') +{ + print $form->formconfirm('card.php?id='.$payment->id, $langs->trans("DeletePayment"), $langs->trans("ConfirmDeletePayment"), 'confirm_delete','',0,2); +} + +/* + * Confirm validation of the payment + */ +if ($action == 'valide') +{ + $facid = $_GET['facid']; + print $form->formconfirm('card.php?id='.$payment->id.'&facid='.$facid, $langs->trans("ValidatePayment"), $langs->trans("ConfirmValidatePayment"), 'confirm_valide','',0,2); +} + + +print ''; + +// Ref +print ''; +print ''; + +// Date +print ''; + +// Mode +print ''; + +// Number +print ''; + +// Amount +print ''; +print ''; +print ''; + +// Note +print ''; + +// Bank account +if (! empty($conf->banque->enabled)) +{ + if ($payment->bank_account) + { + $bankline=new AccountLine($db); + $bankline->fetch($payment->bank_line); + + print ''; + print ''; + print ''; + print ''; + } +} + +print '
    '.$langs->trans('Ref').''; +print $form->showrefnav($payment,'id','',1,'rowid','id'); +print '
    '.$langs->trans('Date').''.dol_print_date($payment->datep,'day').'
    '.$langs->trans('Mode').''.$langs->trans("PaymentType".$payment->type_code).'
    '.$langs->trans('Number').''.$payment->num_payment.'
    '.$langs->trans('Capital').''.price($payment->amount_capital, 0, $outputlangs, 1, -1, -1, $conf->currency).'
    '.$langs->trans('Insurance').''.price($payment->amount_insurance, 0, $outputlangs, 1, -1, -1, $conf->currency).'
    '.$langs->trans('Interest').''.price($payment->amount_interest, 0, $outputlangs, 1, -1, -1, $conf->currency).'
    '.$langs->trans('Note').''.nl2br($payment->note).'
    '.$langs->trans('BankTransactionLine').''; + print $bankline->getNomUrl(1,0,'showall'); + print '
    '; + + +/* + * List of loans payed + */ + +$disable_delete = 0; +$sql = 'SELECT l.rowid as id, l.label, l.paid, l.capital as capital, pl.amount_capital, pl.amount_insurance, pl.amount_interest'; +$sql.= ' FROM '.MAIN_DB_PREFIX.'payment_loan as pl,'.MAIN_DB_PREFIX.'loan as l'; +$sql.= ' WHERE pl.fk_loan = l.rowid'; +$sql.= ' AND l.entity = '.$conf->entity; +$sql.= ' AND pl.rowid = '.$payment->id; + +dol_syslog("loan/payment/card.php", LOG_DEBUG); +$resql=$db->query($sql); +if ($resql) +{ + $num = $db->num_rows($resql); + + $i = 0; + $total = 0; + print '
    '; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print "\n"; + + if ($num > 0) + { + $var=True; + + while ($i < $num) + { + $objp = $db->fetch_object($resql); + + $var=!$var; + print ''; + // Ref + print '\n"; + // Label + print ''; + // Expected to pay + print ''; + // Status + print ''; + // Amount payed + print ''; + print "\n"; + if ($objp->paid == 1) // If at least one invoice is paid, disable delete + { + $disable_delete = 1; + } + $total = $total + $objp->amount_capital; + $i++; + } + } + $var=!$var; + + print "
    '.$langs->trans('Loan').''.$langs->trans('Label').''.$langs->trans('ExpectedToPay').''.$langs->trans('Status').''.$langs->trans('PayedByThisPayment').'
    '; + $loan->fetch($objp->id); + print $loan->getLinkUrl(1); + print "'.$objp->label.''.price($objp->capital).''.$loan->getLibStatut(4,$objp->amount_capital).''.price($objp->amount_capital).'
    \n"; + $db->free($resql); +} +else +{ + dol_print_error($db); +} + +print ''; + + +/* + * Actions buttons + */ +print '
    '; + +/* +if (! empty($conf->global->BILL_ADD_PAYMENT_VALIDATION)) +{ + if ($user->societe_id == 0 && $payment->statut == 0 && $_GET['action'] == '') + { + if ($user->rights->facture->paiement) + { + print ''.$langs->trans('Valid').''; + } + } +} +*/ + +if (empty($action) && ! empty($user->rights->loan->delete)) +{ + if (! $disable_delete) + { + print ''.$langs->trans('Delete').''; + } + else + { + print ''.$langs->trans('Delete').''; + } +} + +print '
    '; + + + +llxFooter(); + +$db->close(); diff --git a/htdocs/loan/payment/index.html b/htdocs/loan/payment/index.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/htdocs/loan/payment/payment.php b/htdocs/loan/payment/payment.php new file mode 100644 index 00000000000..9a087d60633 --- /dev/null +++ b/htdocs/loan/payment/payment.php @@ -0,0 +1,355 @@ + + * + * 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/loan/payment/payment.php + * \ingroup Loan + * \brief Page to add payment of a loan + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; +require_once DOL_DOCUMENT_ROOT.'/loan/class/paymentloan.class.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; + +$langs->load("bills"); +$langs->load("loan"); + +$chid=GETPOST('id','int'); +$action=GETPOST('action'); +$amounts = array(); +$cancel=GETPOST('cancel','alpha'); + +// Security check +$socid=0; +if ($user->societe_id > 0) +{ + $socid = $user->societe_id; +} + +/* + * Actions + */ +if ($action == 'add_payment') +{ + $error=0; + + if ($cancel) + { + $loc = DOL_URL_ROOT.'/loan/card.php?id='.$chid; + header("Location: ".$loc); + exit; + } + + $datepaid = dol_mktime(12, 0, 0, $_POST["remonth"], $_POST["reday"], $_POST["reyear"]); + + if (! $_POST["paymenttype"] > 0) + { + $mesg = $langs->trans("ErrorFieldRequired",$langs->transnoentities("PaymentMode")); + $error++; + } + if ($datepaid == '') + { + $mesg = $langs->trans("ErrorFieldRequired",$langs->transnoentities("Date")); + $error++; + } + if (! empty($conf->banque->enabled) && ! $_POST["accountid"] > 0) + { + $mesg = $langs->trans("ErrorFieldRequired",$langs->transnoentities("AccountToCredit")); + $error++; + } + + if (! $error) + { + $paymentid = 0; + + // Read possible payments + foreach ($_POST as $key => $value) + { + if (substr($key,0,7) == 'amount_') + { + $other_chid = substr($key,7); + $amounts[$other_chid] = price2num($_POST[$key]); + } + } + + if (count($amounts) <= 0) + { + $error++; + $errmsg='ErrorNoPaymentDefined'; + } + + if (! $error) + { + $db->begin(); + + // Create a line of payments + $payment = new PaymentLoan($db); + $payment->chid = $chid; + $payment->datepaid = $datepaid; + $payment->amounts = $amounts; // Tableau de montant + $payment->amount_capital = $_POST["amount_capital"]; + $payment->amount_insurance = $_POST["amount_insurance"]; + $payment->amount_interest = $_POST["amount_interest"]; + $payment->paymenttype = $_POST["paymenttype"]; + $payment->num_payment = $_POST["num_payment"]; + $payment->note = $_POST["note"]; + + if (! $error) + { + $paymentid = $payment->create($user); + if ($paymentid < 0) + { + $errmsg=$payment->error; + $error++; + } + } + + if (! $error) + { + $result=$payment->addPaymentToBank($user,'payment_loan','(LoanPayment)',$_POST['accountid'],'',''); + if (! $result > 0) + { + $errmsg=$payment->error; + $error++; + } + } + + if (! $error) + { + $db->commit(); + $loc = DOL_URL_ROOT.'/loan/card.php?id='.$chid; + header('Location: '.$loc); + exit; + } + else + { + $db->rollback(); + } + } + } + + $_GET["action"]='create'; +} + + +/* + * View + */ + +llxHeader(); + +$form=new Form($db); + + +// Form to create loan's payment +if ($_GET["action"] == 'create') +{ + + $loan = new Loan($db); + $loan->fetch($chid); + + $total = $loan->capital; + + print_fiche_titre($langs->trans("DoPayment")); + print "
    \n"; + + if ($mesg) + { + print "
    $mesg
    "; + } + + print '
    '; + print ''; + print ''; + print ''; + print ''; + + print ''; + + print ''; + + print ''; + print '\n"; + print '\n"; + print ''; + + $sql = "SELECT sum(p.amount) as total"; + $sql.= " FROM ".MAIN_DB_PREFIX."payment_loan as p"; + $sql.= " WHERE p.fk_loan = ".$chid; + $resql = $db->query($sql); + if ($resql) + { + $obj=$db->fetch_object($resql); + $sumpaid = $obj->total; + $db->free(); + } + print ''; + print ''; + print ''; + + print '
    '.$langs->trans("Loan").'
    '.$langs->trans("Ref").''.$chid.'
    '.$langs->trans("DateStart").''.dol_print_date($loan->datestart,'day')."
    '.$langs->trans("Label").''.$loan->label."
    '.$langs->trans("Amount").''.price($loan->capital,0,$outputlangs,1,-1,-1,$conf->currency).'
    '.$langs->trans("AlreadyPaid").''.price($sumpaid,0,$outputlangs,1,-1,-1,$conf->currency).'
    '.$langs->trans("RemainderToPay").''.price($total-$sumpaid,0,$outputlangs,1,-1,-1,$conf->currency).'
    '; + + print '
    '; + + print ''; + print ''; + print ''; + print ''; + + print '"; + print ''; + + print '\n"; + print ''; + + print ''; + print ''; + print ''; + + // Number + print ''; + print ''."\n"; + + print ''; + print ''; + print ''; + print ''; + + print '
    '.$langs->trans("Payment").'
    '.$langs->trans("Date").''; + $datepaid = dol_mktime(12, 0, 0, $_POST["remonth"], $_POST["reday"], $_POST["reyear"]); + $datepayment = empty($conf->global->MAIN_AUTOFILL_DATE)?(empty($_POST["remonth"])?-1:$datepaye):0; + $form->select_date($datepayment,'','','','',"add_payment",1,1); + print "
    '.$langs->trans("PaymentMode").''; + $form->select_types_paiements(isset($_POST["paymenttype"])?$_POST["paymenttype"]:$loan->paymenttype, "paymenttype"); + print "
    '.$langs->trans('AccountToDebit').''; + $form->select_comptes(isset($_POST["accountid"])?$_POST["accountid"]:$loan->accountid, "accountid", 0, '',1); // Show opend bank account list + print '
    '.$langs->trans('Number'); + print ' ('.$langs->trans("ChequeOrTransferNumber").')'; + print '
    '.$langs->trans("Comments").'
    '; + + print '
    '; + + /* + * Other loan unpaid + */ + $num = 1; + $i = 0; + + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print "\n"; + + $var=True; + $total=0; + $totalrecu=0; + + while ($i < $num) + { + $objp = $loan; + + $var=!$var; + + print ""; + + if ($objp->datestart > 0) + { + print ''; + } + else + { + print ''; + } + + print '"; + + print '"; + + print '"; + + print '"; + + print "\n"; + $total+=$objp->total; + $total_ttc+=$objp->total_ttc; + $totalrecu+=$objp->am; + $i++; + } + if ($i > 1) + { + // Print total + print ""; + print ''; + print ''; + print ''; + print ''; + print ''; + print "\n"; + } + + print "
    '.$langs->trans("DateDue").''.$langs->trans("Capital").''.$langs->trans("AlreadyPaid").''.$langs->trans("RemainderToPay").''.$langs->trans("Amount").'
    '.dol_print_date($objp->datestart,'day').'!!!'.price($objp->capital)."'.price($sumpaid)."'.price($objp->capital - $sumpaid)."'; + if ($sumpaid < $objp->capital) + { + $namec = "amount_capital_".$objp->id; + print $langs->trans("Capital") .': '; + } + else + { + print '-'; + } + print '
    '; + if ($sumpaid < $objp->capital) + { + $namea = "amount_insurance_".$objp->id; + print $langs->trans("Insurance") .': '; + } + else + { + print '-'; + } + print '
    '; + if ($sumpaid < $objp->capital) + { + $namei = "amount_interest_".$objp->id; + print $langs->trans("Interest") .': '; + } + else + { + print '-'; + } + print "
    '.$langs->trans("Total").':"'.price($total_ttc).'""'.price($totalrecu).'""'.price($total_ttc - $totalrecu).'" 
    "; + + print '
    '; + + print ''; + print '   '; + print ''; + + print '
    '; + + print "
    \n"; +} + + +$db->close(); + +llxFooter(); diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index cf5df4eb21c..da0296e4b00 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1391,6 +1391,8 @@ function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $a if (empty($conf->dol_hide_topmenu)) { + print '
    '; + // Show menu entries print '
    '."\n"; $menumanager->atarget=$target; @@ -1431,8 +1433,8 @@ function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $a print '
    '; unset($form); } diff --git a/htdocs/product/popuprop.php b/htdocs/product/popuprop.php index 92ad4cfbe1f..376647834b5 100644 --- a/htdocs/product/popuprop.php +++ b/htdocs/product/popuprop.php @@ -44,6 +44,8 @@ if ($page < 0) $page = 0; if (! $sortfield) $sortfield="c"; if (! $sortorder) $sortorder="DESC"; +$conf->liste_limit = 3; + if ($page == -1) $page = 0; $limit = $conf->liste_limit; $offset = $limit * $page ; @@ -57,36 +59,28 @@ $staticproduct=new Product($db); */ $helpurl=''; -if ($type == 0) +if ($type == '0') { $helpurl='EN:Module_Products|FR:Module_Produits|ES:Módulo_Productos'; + //$title=$langs->trans("StatisticsOfProducts"); + $title=$langs->trans("Statistics"); } -else if ($type == 1) +else if ($type == '1') { $helpurl='EN:Module_Services_En|FR:Module_Services|ES:Módulo_Servicios'; + $title=$langs->trans("StatisticsOfServices"); + $title=$langs->trans("Statistics"); } llxHeader('','',$helpurl); -//On n'affiche le lien page suivante que s'il y a une page suivante ... -$sql = "SELECT count(*) as c"; -$sql.= " FROM ".MAIN_DB_PREFIX."product"; -$sql.= ' WHERE entity IN ('.getEntity('product', 1).')'; -if ($type !== '') { - $sql.= " AND fk_product_type = ".$type; -} +print_fiche_titre($title, $mesg); -$result=$db->query($sql); -if ($result) -{ - $obj = $db->fetch_object($result); - $num = $obj->c; -} $param = ''; $title = $langs->trans("ListProductServiceByPopularity"); -if ($type !== '') { - $param = '&type='.$type; +if ($type != '') { + $param = '&type='.$type; if ($type == 1) { $title = $langs->trans("ListServiceByPopularity"); @@ -95,17 +89,17 @@ if ($type !== '') { } } -print_barre_liste($title, $page, $_SERVER["PHP_SELF"],$param,"","","",$num); +$h=0; +$head = array(); +$head[$h][0] = $_SERVER['PHP_SELF']; +$head[$h][1] = $title; +$head[$h][2] = 'product'; +$h++; + +dol_fiche_head($head,'product',$langs->trans("Statistics")); -print ''; -print ""; -print_liste_field_titre($langs->trans('Ref'), $_SERVER["PHP_SELF"], 'p.ref', '', '', '', $sortfield, $sortorder); -print_liste_field_titre($langs->trans('Type'), $_SERVER["PHP_SELF"], 'p.type', '', '', '', $sortfield, $sortorder); -print_liste_field_titre($langs->trans('Label'), $_SERVER["PHP_SELF"], 'p.label', '', '', '', $sortfield, $sortorder); -print_liste_field_titre($langs->trans('NbOfProposals'), $_SERVER["PHP_SELF"], 'c', '', '', 'align="right"', $sortfield, $sortorder); -print "\n"; $sql = "SELECT p.rowid, p.label, p.ref, p.fk_product_type as type, count(*) as c"; $sql.= " FROM ".MAIN_DB_PREFIX."propaldet as pd"; @@ -116,8 +110,15 @@ if ($type !== '') { $sql.= " AND fk_product_type = ".$type; } $sql.= " GROUP BY (p.rowid)"; + +$result=$db->query($sql); +if ($result) +{ + $totalnboflines = $db->num_rows($result); +} + $sql.= $db->order($sortfield,$sortorder); -$sql.= $db->plimit($limit, $offset); +$sql.= $db->plimit($limit+1, $offset); $result=$db->query($sql); if ($result) @@ -125,6 +126,18 @@ if ($result) $num = $db->num_rows($result); $i = 0; + print_barre_liste($title, $page, $_SERVER["PHP_SELF"],$param,$sortfield,$sortorder,"",$num, $totalnboflines, ''); + + print '
    '; + + print ""; + print_liste_field_titre($langs->trans('Ref'), $_SERVER["PHP_SELF"], 'p.ref', '', '', '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans('Type'), $_SERVER["PHP_SELF"], 'p.type', '', '', '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans('Label'), $_SERVER["PHP_SELF"], 'p.label', '', '', '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans('NbOfProposals'), $_SERVER["PHP_SELF"], 'c', '', '', 'align="right"', $sortfield, $sortorder); + print "\n"; + + $var=True; while ($i < $num) { @@ -155,8 +168,8 @@ if ($result) print " "; print $objp->ref.''; print ''; print ''; print ''; @@ -165,9 +178,12 @@ if ($result) } $db->free(); + + print "
    '; - if ($objp->type==1) print $langs->trans("ShowService"); - else print $langs->trans("ShowProduct"); + if ($objp->type==1) print $langs->trans("Service"); + else print $langs->trans("Product"); print ''.$objp->label.''.$objp->c.'
    "; } -print ""; + +dol_fiche_end(); llxFooter(); diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 40ca7d92699..74d94d5b98c 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -319,6 +319,7 @@ fieldset { border: 1px solid #AAAAAA !important; box-shadow: 2px 2px 3px #DDD; } display: inline-block; padding: 4px 14px; margin-bottom: 0; + margin-top: 0; text-align: center; cursor: pointer; color: #333333; @@ -1005,6 +1006,7 @@ div.vmenu, td.vmenu { } .menu_contenu { padding-top: 1px; } +#menu_contenu_logo { padding-right: 4px; } a.vmenu:link, a.vmenu:visited, a.vmenu:hover, a.vmenu:active { font-size:px; font-family: ; text-align: ; font-weight: bold; } font.vmenudisabled { font-size:px; font-family: ; text-align: ; font-weight: bold; color: #93a5aa; } @@ -1392,10 +1394,10 @@ div.tabsElem { margin-top: 8px; } /* To avoid overlap of tabs when not browser div.tabBar { color: #; - padding-top: 9px; + padding-top: px; padding-left: px; padding-right: px; - padding-bottom: 12px; + padding-bottom: px; margin: 0px 0px 14px 0px; -moz-border-radius:6px; -webkit-border-radius: 6px; @@ -1741,24 +1743,25 @@ table.noborder, table.formdoc, div.noborder { border-collapse: separate !important; border-spacing: 0px; -/* + border-right-width: 1px; - border-right-color: #BBBBBB; + border-right-color: #CCC; border-right-style: solid; +/* border-bottom-width: 1px; border-bottom-color: #BBBBBB; border-bottom-style: solid; */ border-left-width: 1px; - border-left-color: #DDDDDD; + border-left-color: #CCC; border-left-style: solid; margin: 0px 0px 2px 0px; - -moz-box-shadow: 3px 3px 4px #ddd; - -webkit-box-shadow: 3px 3px 4px #ddd; - box-shadow: 3px 3px 4px #ddd; + -moz-box-shadow: 2px 2px 4px #CCC; + -webkit-box-shadow: 2px 2px 4px #CCC; + box-shadow: 2px 2px 4px #CCC; -moz-border-radius: 0.2em; -webkit-border-radius: 0.2em; @@ -1802,25 +1805,26 @@ table.liste { border-collapse: collapse; border-top-color: #FEFEFE; -/* + border-right-width: 1px; - border-right-color: #BBBBBB; + border-right-color: #CCC; border-right-style: solid; - border-left-width: 1px; - border-left-color: #CCCCCC; - border-left-style: solid; -*/ +/* border-bottom-width: 1px; border-bottom-color: #BBBBBB; border-bottom-style: solid; +*/ + border-left-width: 1px; + border-left-color: #CCC; + border-left-style: solid; margin-bottom: 2px; margin-top: 0px; - -moz-box-shadow: 0px 3px 4px #DDD; - -webkit-box-shadow: 0px 3px 4px #DDD; - box-shadow: 0px 3px 4px #DDD; + -moz-box-shadow: 0px 3px 4px #CCC; + -webkit-box-shadow: 0px 3px 4px #CC; + box-shadow: 0px 3px 4px #CCC; } table.liste td { padding-right: 2px; @@ -1982,6 +1986,7 @@ input.liste_titre { color: #332266; font-weight: normal; white-space: nowrap; + padding: 4px; } @@ -2039,7 +2044,7 @@ div.tabBar .noborder { } tr.box_titre { - height: 20px; + height: 26px; background: rgb(); background-repeat: repeat-x; @@ -2198,6 +2203,13 @@ div.dolgraph div.legend table tbody tr { height: auto; } margin-bottom: 2px; margin-top: 2px; } +.photointooltip { + -webkit-box-shadow: -1px -1px 5px #777; + -moz-box-shadow: -1px -1px 5px #777; + box-shadow: -1px -1px 5px #777; + margin-top: 6px; + float: left; +} .logo_setup { @@ -2318,6 +2330,7 @@ border-radius: 6px; #tiptip_content { background-color: rgb(252,248,246); background-color: rgba(252,248,246,0.95); + line-height: 1.4em; } /* ============================================================================== */ diff --git a/htdocs/theme/md_exp/style.css.php b/htdocs/theme/md_exp/style.css.php index 927a0c35266..4b8ebe8d178 100644 --- a/htdocs/theme/md_exp/style.css.php +++ b/htdocs/theme/md_exp/style.css.php @@ -114,14 +114,15 @@ $fontsizesmaller='11'; // Eldy colors if (empty($conf->global->THEME_ELDY_ENABLE_PERSONALIZED)) { + // 90A4AE, 607D8B, 455A64, 37474F //$conf->global->THEME_ELDY_TOPMENU_BACK1=join(',',colorStringToArray('#37474f')); // topmenu #607D8B - $conf->global->THEME_ELDY_TOPMENU_BACK1=join(',',colorStringToArray('#607D8B')); // topmenu #607D8B + $conf->global->THEME_ELDY_TOPMENU_BACK1=join(',',colorStringToArray('#37474F')); // topmenu #607D8B //$conf->global->THEME_ELDY_TOPMENU_BACK1=join(',',colorStringToArray('000')); // topmenu #607D8B $conf->global->THEME_ELDY_TOPMENU_BACK2='236,236,236'; $conf->global->THEME_ELDY_VERMENU_BACK1='255,255,255'; // vmenu $conf->global->THEME_ELDY_VERMENU_BACK1b='230,232,232'; // vmenu (not menu) $conf->global->THEME_ELDY_VERMENU_BACK2='240,240,240'; - $conf->global->THEME_ELDY_BACKTITLE1=join(',',colorStringToArray('607D8B')); // title of arrays + $conf->global->THEME_ELDY_BACKTITLE1=join(',',colorStringToArray('#607D8B')); // title of arrays $conf->global->THEME_ELDY_BACKTITLE2='230,230,230'; $conf->global->THEME_ELDY_BACKTABCARD2='255,255,255'; // card $conf->global->THEME_ELDY_BACKTABCARD1='234,234,234'; @@ -512,19 +513,25 @@ td.showDragHandle { table-layout: fixed; } #id-right, #id-left { - padding-top: 8px; display: table-cell; float: none; vertical-align: top; } +#id-top { +/* min-width: 100%; + position: relative; + heigth: 52px; + background: #f00;*/ +} #id-left { min-height: 100%; position: relative; - width: 184px; + width: 183px; } -#id-right { /* This must stay id-right ant not be replaced with echo $right */ +#id-right { /* This must stay id-right and not be replaced with echo $right */ width: 100%; padding-left: 184px; + padding-top: 12px; } .side-nav { @@ -537,7 +544,6 @@ td.showDragHandle { left: 0; position: fixed; top: 50px; - width: 192px; z-index: 4; -webkit-transform: translateZ(0); -moz-transform: translateZ(0); @@ -565,10 +571,13 @@ td.showDragHandle { overflow-x: hidden; overflow-y: auto; } +.side-nav-vert { + margin-left: 184px; +} div.fiche { - margin-: global->MAIN_MENU_USE_JQUERY_LAYOUT))?($dol_hide_leftmenu?'4':'20'):'24')); ?>px; + margin-: global->MAIN_MENU_USE_JQUERY_LAYOUT))?($dol_hide_leftmenu?'4':'12'):'24')); ?>px; margin-: dol_optimize_smallscreen)?'12':'4')); ?>px; dol_hide_leftmenu) && ! empty($conf->dol_hide_topmenu)) print 'margin-top: 4px;'; ?> } @@ -619,7 +628,7 @@ div#tmenu_tooltip { display:none; - padding-: 100px; + /* padding-: 100px; */ background: ; /*box-shadow: 0 0 6px rgba(0, 0, 0, .4) !important;*/ @@ -978,11 +987,19 @@ table.login_table_securitycode tr td { } div.login_block { + padding-top: 8px; position: absolute; - : 5px; - top: 3px; + : 5px; + left: 0; + top: 0px; + position: fixed; font-weight: bold; - max-width: 110px; + z-index: 10; + text-align: center; + vertical-align: middle; + background: #FFF; + width: 183px; + height: 42px; display: none; @@ -1049,7 +1066,7 @@ div.vmenu, td.vmenu { float: left; padding: 0px; padding-bottom: 0px; - padding-top: 1px; + padding-top: 0px; width: 174px; } @@ -1516,14 +1533,7 @@ a.tab:link, a.tab:visited, a.tab:hover, a.tab#active { text-decoration: none; white-space: nowrap; - /*border-bottom: none; - border-right: 1px solid #CCCCCC; - border-left: 1px solid #D0D0D0; - border-top: 1px solid #D8D8D8; - */ - - /* - -moz-border-radius:6px 6px 0px 0px; + /*-moz-border-radius:6px 6px 0px 0px; -webkit-border-radius:6px 6px 0px 0px; border-radius:6px 6px 0px 0px; @@ -1531,6 +1541,13 @@ a.tab:link, a.tab:visited, a.tab:hover, a.tab#active { -webkit-box-shadow: 0 -1px 4px rgba(0,0,0,.1); box-shadow: 0 -1px 4px rgba(0,0,0,.1); + border-bottom: none; + border-right: 1px solid #CCCCCC; + border-left: 1px solid #D0D0D0; + border-top: 1px solid #D8D8D8; + */ + + /* background: rgb(); /*background-image: -o-linear-gradient(bottom, rgb() 35%, rgb() 100%); @@ -1570,7 +1587,8 @@ a.tab:hover { /* background: rgba(, 0.5) url() 50% 0 repeat-x; - color: #;*/ + color: #; + */ text-decoration: underline; } a.tab:link, a.tab:visited @@ -1828,22 +1846,23 @@ table.noborder, table.formdoc, div.noborder { border-spacing: 0px; border-right-width: 1px; - border-right-color: #BBBBBB; + border-right-color: #CCC; border-right-style: solid; - border-left-width: 1px; - border-left-color: #B0B0B0; - border-left-style: solid; - +/* border-bottom-width: 1px; border-bottom-color: #BBBBBB; border-bottom-style: solid; +*/ + border-left-width: 1px; + border-left-color: #CCC; + border-left-style: solid; margin: 0px 0px 2px 0px; - -moz-box-shadow: 2px 2px 4px #DDD; - -webkit-box-shadow: 2px 2px 4px #DDD; - box-shadow: 2px 2px 4px #DDD; + -moz-box-shadow: 2px 2px 4px #CCC; + -webkit-box-shadow: 2px 2px 4px #CCC; + box-shadow: 2px 2px 4px #CCC; -moz-border-radius: 0.2em; -webkit-border-radius: 0.2em; @@ -1860,7 +1879,7 @@ table.noborder tr, div.noborder form { border-left-width: 1px; border-left-color: #BBBBBB; border-left-style: solid; - height: 20px; + height: 26px; } table.noborder th, table.noborder td, div.noborder form, div.noborder form div { @@ -1888,23 +1907,24 @@ table.liste { border-top-color: #FEFEFE; border-right-width: 1px; - border-right-color: #BBBBBB; + border-right-color: #CCC; border-right-style: solid; - border-left-width: 1px; - border-left-color: #CCCCCC; - border-left-style: solid; - +/* border-bottom-width: 1px; border-bottom-color: #BBBBBB; border-bottom-style: solid; +*/ + border-left-width: 1px; + border-left-color: #CCC; + border-left-style: solid; margin-bottom: 2px; margin-top: 0px; - -moz-box-shadow: 3px 3px 4px #DDD; - -webkit-box-shadow: 3px 3px 4px #DDD; - box-shadow: 3px 3px 4px #DDD; + -moz-box-shadow: 0px 3px 4px #CCC; + -webkit-box-shadow: 0px 3px 4px #CC; + box-shadow: 0px 3px 4px #CCC; } table.liste td { padding-right: 2px; @@ -1978,6 +1998,7 @@ table.liste td { } .pair, .nohover .pair:hover, tr.pair td.nohover { +/* background: linear-gradient(bottom, rgb() 85%, rgb() 100%) !important; background: -o-linear-gradient(bottom, rgb() 85%, rgb() 100%) !important; @@ -1987,13 +2008,17 @@ table.liste td { background: #ffffff; +*/ font-family: ; border: 0px; margin-bottom: 1px; color: #202020; + background-color: #f9f9f9; +} +tr.pair td, tr.impair td { + padding: 4px; + border-bottom: 1px solid #ddd; } - - div.liste_titre .tagtd { vertical-align: middle; } @@ -2062,6 +2087,7 @@ input.liste_titre { color: #332266; font-weight: normal; white-space: nowrap; + padding: 4px; } @@ -2180,6 +2206,13 @@ tr.box_pair { background: #ffffff; font-family: ; + + background-color: #f9f9f9; +} + +tr.box_pair td, tr.box_impair td { + padding: 4px; + border-bottom: 1px solid #ddd; } .formboxfilter { @@ -2283,6 +2316,13 @@ div.dolgraph div.legend table tbody tr { height: auto; } margin-bottom: 2px; margin-top: 2px; } +.photointooltip { + -webkit-box-shadow: 0px 0px 5px #777; + -moz-box-shadow: 0px 0px 5px #777; + box-shadow: 0px 0px 6px #777; + margin-top: 8px; + float: left; +} .logo_setup { @@ -2403,6 +2443,7 @@ border-radius: 6px; #tiptip_content { background-color: rgb(252,248,246); background-color: rgba(252,248,246,0.95); + line-height: 1.4em; } /* ============================================================================== */ diff --git a/htdocs/user/card.php b/htdocs/user/card.php index cc880878671..8a6b08401df 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -213,7 +213,7 @@ if ($action == 'add' && $canadduser) $ret = $extrafields->setOptionalsFromPost($extralabels,$object); if ($ret < 0) $error++; - // Set entity of new user + // Set entity property $entity=GETPOST('entity','int'); if (! empty($conf->multicompany->enabled)) { @@ -987,7 +987,7 @@ if (($action == 'create') || ($action == 'adduserldap')) print ''; print ''; print "\n"; - + // Accountancy code if ($conf->salaries->enabled) { @@ -1340,7 +1340,7 @@ else print ''.$langs->trans("AccountancyCode").''; print ''.$object->accountancy_code.''; } - + // Color user if (! empty($conf->agenda->enabled)) { @@ -1428,7 +1428,7 @@ else if (! empty($conf->multicompany->enabled) && empty($conf->multicompany->transverse_mode) && $conf->entity == 1 && $user->admin && ! $user->entity) { print ''.$langs->trans("Entity").''; - if ($object->admin && ! $object->entity) + if (empty($object->entity)) { print $langs->trans("AllEntities"); } @@ -2052,7 +2052,7 @@ else } print ''; print ""; - } + } // User color if (! empty($conf->agenda->enabled)) @@ -2122,7 +2122,7 @@ else if (empty($conf->multicompany->transverse_mode) && $conf->entity == 1 && $user->admin && ! $user->entity) { print "".''.$langs->trans("Entity").''; - print "".$mc->select_entities($object->entity); + print "".$mc->select_entities($object->entity, 'entity', '', 0, 1); // last parameter 1 means, show also a choice 0=>'all entities' print "\n"; } else diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 9ffa762afd1..d8d8a1f071c 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -1808,12 +1808,13 @@ class User extends CommonObject } $type=($this->societe_id?$langs->trans("External").$company:$langs->trans("Internal")); $label.= '
    ' . $langs->trans("Type") . ': ' . $type; + $label.='
    '; if (! empty($this->photo)) { - $label.= '
    '; + $label.= '
    '; $label.= Form::showphoto('userphoto', $this, 80); + $label.= '
    '; } - $label.= '
    '; // Info Login if ($infologin) diff --git a/htdocs/user/home.php b/htdocs/user/home.php index 72e9b124ae0..61d09e0e4c2 100644 --- a/htdocs/user/home.php +++ b/htdocs/user/home.php @@ -181,7 +181,7 @@ if ($resql) { if (! empty($conf->multicompany->enabled)) { - if ($obj->admin && ! $obj->entity) + if (empty($obj->entity)) { print ' ('.$langs->trans("AllEntities").')'; } diff --git a/htdocs/user/index.php b/htdocs/user/index.php index 5d0b0ac77e4..9e3e40b2e59 100644 --- a/htdocs/user/index.php +++ b/htdocs/user/index.php @@ -125,9 +125,11 @@ if ($result) print ' '; print "\n"; - //SearchBar + // SearchBar + $colspan=7; + if (! empty($conf->multicompany->enabled) && empty($conf->multicompany->transverse_mode)) $colspan++; print ''; - print ' '; + print ' '; // Status print ''; diff --git a/htdocs/webservices/server_productorservice.php b/htdocs/webservices/server_productorservice.php index 08eb76b834b..474988fa6e8 100644 --- a/htdocs/webservices/server_productorservice.php +++ b/htdocs/webservices/server_productorservice.php @@ -379,43 +379,43 @@ function getProductOrService($authentication,$id='',$ref='',$ref_ext='',$lang='' if (! empty($product->multilangs[$langs->defaultlang]["description"])) $product->description = $product->multilangs[$langs->defaultlang]["description"]; if (! empty($product->multilangs[$langs->defaultlang]["note"])) $product->note = $product->multilangs[$langs->defaultlang]["note"]; - $productorservice_result_fields = array( - 'id' => $product->id, - 'ref' => $product->ref, - 'ref_ext' => $product->ref_ext, - 'label' => $product->label, - 'description' => $product->description, - 'date_creation' => dol_print_date($product->date_creation,'dayhourrfc'), - 'date_modification' => dol_print_date($product->date_modification,'dayhourrfc'), - 'note' => $product->note, - 'status_tosell' => $product->status, - 'status_tobuy' => $product->status_buy, - 'type' => $product->type, - 'barcode' => $product->barcode, - 'barcode_type' => $product->barcode_type, - 'country_id' => $product->country_id>0?$product->country_id:'', - 'country_code' => $product->country_code, - 'custom_code' => $product->customcode, + $productorservice_result_fields = array( + 'id' => $product->id, + 'ref' => $product->ref, + 'ref_ext' => $product->ref_ext, + 'label' => $product->label, + 'description' => $product->description, + 'date_creation' => dol_print_date($product->date_creation,'dayhourrfc'), + 'date_modification' => dol_print_date($product->date_modification,'dayhourrfc'), + 'note' => $product->note, + 'status_tosell' => $product->status, + 'status_tobuy' => $product->status_buy, + 'type' => $product->type, + 'barcode' => $product->barcode, + 'barcode_type' => $product->barcode_type, + 'country_id' => $product->country_id>0?$product->country_id:'', + 'country_code' => $product->country_code, + 'custom_code' => $product->customcode, - 'price_net' => $product->price, - 'price' => $product->price_ttc, - 'price_min_net' => $product->price_min, - 'price_min' => $product->price_min_ttc, - 'price_base_type' => $product->price_base_type, - 'vat_rate' => $product->tva_tx, - //! French VAT NPR - 'vat_npr' => $product->tva_npr, - //! Spanish local taxes - 'localtax1_tx' => $product->localtax1_tx, - 'localtax2_tx' => $product->localtax2_tx, + 'price_net' => $product->price, + 'price' => $product->price_ttc, + 'price_min_net' => $product->price_min, + 'price_min' => $product->price_min_ttc, + 'price_base_type' => $product->price_base_type, + 'vat_rate' => $product->tva_tx, + //! French VAT NPR + 'vat_npr' => $product->tva_npr, + //! Spanish local taxes + 'localtax1_tx' => $product->localtax1_tx, + 'localtax2_tx' => $product->localtax2_tx, - 'stock_real' => $product->stock_reel, - 'stock_alert' => $product->seuil_stock_alerte, - 'pmp' => $product->pmp, - 'import_key' => $product->import_key, - 'dir' => $pdir, - 'images' => $product->liste_photos($dir,$nbmax=10) - ); + 'stock_real' => $product->stock_reel, + 'stock_alert' => $product->seuil_stock_alerte, + 'pmp' => $product->pmp, + 'import_key' => $product->import_key, + 'dir' => $pdir, + 'images' => $product->liste_photos($dir,$nbmax=10) + ); //Retreive all extrafield for thirdsparty // fetch optionals attributes and labels @@ -515,11 +515,11 @@ function createProductOrService($authentication,$product) $newobject->price_base_type=$product['price_base_type']; $newobject->date_creation=$now; - if ($product['barcode']) - { - $newobject->barcode = $product['barcode']; - $newobject->barcode_type = $product['barcode_type']; - } + if ($product['barcode']) + { + $newobject->barcode = $product['barcode']; + $newobject->barcode_type = $product['barcode_type']; + } $newobject->stock_reel=$product['stock_real']; $newobject->pmp=$product['pmp']; @@ -547,12 +547,12 @@ function createProductOrService($authentication,$product) //var_dump($product['lines'][0]['type']); $extrafields=new ExtraFields($db); - $extralabels=$extrafields->fetch_name_optionals_label('product',true); - foreach($extrafields->attribute_label as $key=>$label) - { - $key='options_'.$key; - $newobject->array_options[$key]=$product[$key]; - } + $extralabels=$extrafields->fetch_name_optionals_label('product',true); + foreach($extrafields->attribute_label as $key=>$label) + { + $key='options_'.$key; + $newobject->array_options[$key]=$product[$key]; + } $db->begin(); @@ -622,7 +622,7 @@ function updateProductOrService($authentication,$product) { $errror++; $errorcode='KO' ; $errorlabel="You must set a barcode type when setting a barcode."; } - + if (! $error) { include_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; @@ -645,7 +645,7 @@ function updateProductOrService($authentication,$product) $newobject->price_base_type=$product['price_base_type']; $newobject->date_creation=$now; - if ($product['barcode']) + if ($product['barcode']) { $newobject->barcode = $product['barcode']; $newobject->barcode_type = $product['barcode_type']; @@ -676,13 +676,13 @@ function updateProductOrService($authentication,$product) //var_dump($product['ref_ext']); //var_dump($product['lines'][0]['type']); - $extrafields=new ExtraFields($db); - $extralabels=$extrafields->fetch_name_optionals_label('product',true); - foreach($extrafields->attribute_label as $key=>$label) - { - $key='options_'.$key; - $newobject->array_options[$key]=$product[$key]; - } + $extrafields=new ExtraFields($db); + $extralabels=$extrafields->fetch_name_optionals_label('product',true); + foreach($extrafields->attribute_label as $key=>$label) + { + $key='options_'.$key; + $newobject->array_options[$key]=$product[$key]; + } $db->begin();