From abccfdd168dc27bd1bae8900a83167309e6d88c2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 9 Jan 2013 19:56:43 +0100 Subject: [PATCH 01/36] Fix: Option SERVICE_ARE_ECOMMERCE_200238EC --- htdocs/core/lib/functions.lib.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 988493874e2..f216bfb359b 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2920,6 +2920,18 @@ function get_default_tva($thirdparty_seller, $thirdparty_buyer, $idprod=0, $idpr dol_syslog("get_default_tva: seller use vat=".$thirdparty_seller->tva_assuj.", seller country=".$thirdparty_seller->country_code.", seller in cee=".$thirdparty_seller->isInEEC().", buyer country=".$thirdparty_buyer->country_code.", buyer in cee=".$thirdparty_buyer->isInEEC().", idprod=".$idprod.", idprodfournprice=".$idprodfournprice.", SERVICE_ARE_ECOMMERCE_200238EC=".(! empty($conf->global->SERVICES_ARE_ECOMMERCE_200238EC)?$conf->global->SERVICES_ARE_ECOMMERCE_200238EC:'')); + // If services are eServices according to EU Council Directive 2002/38/EC (http://ec.europa.eu/taxation_customs/taxation/vat/traders/e-commerce/article_1610_en.htm) + // we use the buyer VAT. + if (! empty($conf->global->SERVICE_ARE_ECOMMERCE_200238EC)) + { + //print "eee".$thirdparty_buyer->isACompany();exit; + if (! $thirdparty_seller->isInEEC() && $thirdparty_buyer->isInEEC() && ! $thirdparty_buyer->isACompany()) + { + //print 'VATRULE 6'; + return get_product_vat_for_country($idprod,$thirdparty_buyer,$idprodfournprice); + } + } + // Si vendeur non assujeti a TVA (tva_assuj vaut 0/1 ou franchise/reel) if (is_numeric($thirdparty_seller->tva_assuj) && ! $thirdparty_seller->tva_assuj) { @@ -2963,18 +2975,6 @@ function get_default_tva($thirdparty_seller, $thirdparty_buyer, $idprod=0, $idpr } } - // If services are eServices according to EU Council Directive 2002/38/EC (ec.europa.eu/taxation_customs/taxation/v.../article_1610_en.htm) - // we use the buyer VAT. - if (! empty($conf->global->SERVICE_ARE_ECOMMERCE_200238EC)) - { - //print "eee".$thirdparty_buyer->isACompany();exit; - if (! $thirdparty_seller->isInEEC() && $thirdparty_buyer->isInEEC() && ! $thirdparty_buyer->isACompany()) - { - //print 'VATRULE 6'; - return get_product_vat_for_country($idprod,$thirdparty_buyer,$idprodfournprice); - } - } - // Sinon la TVA proposee par defaut=0. Fin de regle. // Rem: Cela signifie qu'au moins un des 2 est hors Communaute europeenne et que le pays differe //print 'VATRULE 7'; From e369d5dfd8efbf723036f4ca39f1146612f44669 Mon Sep 17 00:00:00 2001 From: fhenry Date: Wed, 9 Jan 2013 20:34:36 +0100 Subject: [PATCH 02/36] Fix [ bug #668 ] Event created with a profile is not visible by the same profile --- htdocs/comm/action/fiche.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/htdocs/comm/action/fiche.php b/htdocs/comm/action/fiche.php index b0c01cdd9f4..bb2eb7dce35 100644 --- a/htdocs/comm/action/fiche.php +++ b/htdocs/comm/action/fiche.php @@ -555,7 +555,13 @@ if ($action == 'create') } else { - print $form->select_company('','socid','',1,1); + //For external user force the company to user company + if (!empty($user->societe_id)) { + print $form->select_company($user->societe_id,'socid','',1,1); + } else { + print $form->select_company('','socid','',1,1); + } + } print ''; From 3f42c198db2dc01f8e69f1ae211beaa175e4211e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Wed, 9 Jan 2013 20:53:28 +0100 Subject: [PATCH 03/36] Little typo in es_ES translation --- htdocs/langs/es_ES/suppliers.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/es_ES/suppliers.lang b/htdocs/langs/es_ES/suppliers.lang index e500aea17bb..69846ff3daa 100644 --- a/htdocs/langs/es_ES/suppliers.lang +++ b/htdocs/langs/es_ES/suppliers.lang @@ -12,7 +12,7 @@ ShowSupplier=Mostrar proveedor OrderDate=Fecha de pedido BuyingPrice=Precio de compra BuyingPriceMin=Precio mínimo de compra -BuyingPriceMinShort=Precio mín compra +BuyingPriceMinShort=Precio mín. compra AddSupplierPrice=Añadir precio de proveedor ChangeSupplierPrice=Modificar precio de proveedor ErrorSupplierCountryIsNotDefined=El país de este proveedor no está definido, corrígalo en su ficha From 7b1aed65cfbb521f2e31cc0f332dd57d1588fe52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Wed, 9 Jan 2013 21:23:50 +0100 Subject: [PATCH 04/36] Little es_ES typo --- htdocs/langs/es_ES/withdrawals.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/es_ES/withdrawals.lang b/htdocs/langs/es_ES/withdrawals.lang index bbbee4a6198..95bf99b2258 100644 --- a/htdocs/langs/es_ES/withdrawals.lang +++ b/htdocs/langs/es_ES/withdrawals.lang @@ -77,7 +77,7 @@ WithBankUsingRIB=Para las cuentas bancarias que utilizan CCC WithBankUsingBANBIC=Para las cuentas bancarias que utilizan el código BAN/BIC/SWIFT BankToReceiveWithdraw=Cuenta bancaria receptora de las domiciliaciones CreditDate=Abonada el -WithdrawalFileNotCapable=No es posible generar fichero bancario de domiciliacion para su pais +WithdrawalFileNotCapable=No es posible generar el fichero bancario de domiciliacion para su país. ShowWithdraw=Ver domiciliación IfInvoiceNeedOnWithdrawPaymentWontBeClosed=Sin embargo, si la factura tiene pendiente algún pago por domiciliación, no será cerrada para permitir la gestión de la domiciliación. DoStandingOrdersBeforePayments=Esta pestaña le permite realizar una petición de domiciliación. Una vez terminada, puede ingresar el pago en la factura para proceder a su cierre. From a1e17978d1cb60e686dd7f9d4b93b989d368adb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Wed, 9 Jan 2013 21:24:40 +0100 Subject: [PATCH 05/36] Little es_ES typo (again) --- htdocs/langs/es_ES/withdrawals.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/es_ES/withdrawals.lang b/htdocs/langs/es_ES/withdrawals.lang index 95bf99b2258..75156b22660 100644 --- a/htdocs/langs/es_ES/withdrawals.lang +++ b/htdocs/langs/es_ES/withdrawals.lang @@ -77,7 +77,7 @@ WithBankUsingRIB=Para las cuentas bancarias que utilizan CCC WithBankUsingBANBIC=Para las cuentas bancarias que utilizan el código BAN/BIC/SWIFT BankToReceiveWithdraw=Cuenta bancaria receptora de las domiciliaciones CreditDate=Abonada el -WithdrawalFileNotCapable=No es posible generar el fichero bancario de domiciliacion para su país. +WithdrawalFileNotCapable=No es posible generar el fichero bancario de domiciliación para su país. ShowWithdraw=Ver domiciliación IfInvoiceNeedOnWithdrawPaymentWontBeClosed=Sin embargo, si la factura tiene pendiente algún pago por domiciliación, no será cerrada para permitir la gestión de la domiciliación. DoStandingOrdersBeforePayments=Esta pestaña le permite realizar una petición de domiciliación. Una vez terminada, puede ingresar el pago en la factura para proceder a su cierre. From be401145411ccf4de4e218680512ce1ea1eb98f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Wed, 9 Jan 2013 21:33:55 +0100 Subject: [PATCH 06/36] Fixed translation problems with Prelevement module --- htdocs/compta/prelevement/factures.php | 1 + htdocs/compta/prelevement/fiche-rejet.php | 1 + htdocs/compta/prelevement/fiche.php | 4 ++-- htdocs/compta/prelevement/lignes.php | 1 + 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/prelevement/factures.php b/htdocs/compta/prelevement/factures.php index 9778bf999c0..7ec5356c97b 100644 --- a/htdocs/compta/prelevement/factures.php +++ b/htdocs/compta/prelevement/factures.php @@ -32,6 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php'; $langs->load("companies"); $langs->load("categories"); +$langs->load('withdrawals'); // Securite acces client if ($user->societe_id > 0) accessforbidden(); diff --git a/htdocs/compta/prelevement/fiche-rejet.php b/htdocs/compta/prelevement/fiche-rejet.php index b5678b26923..988f1db2bc6 100644 --- a/htdocs/compta/prelevement/fiche-rejet.php +++ b/htdocs/compta/prelevement/fiche-rejet.php @@ -31,6 +31,7 @@ require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/rejetprelevement.class require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php'; $langs->load("categories"); +$langs->load('withdrawals'); // Securite acces client if ($user->societe_id > 0) accessforbidden(); diff --git a/htdocs/compta/prelevement/fiche.php b/htdocs/compta/prelevement/fiche.php index 9bfe97a4737..73450228480 100644 --- a/htdocs/compta/prelevement/fiche.php +++ b/htdocs/compta/prelevement/fiche.php @@ -130,7 +130,7 @@ if ($action == 'infocredit' && $user->rights->prelevement->bons->credit) $bon = new BonPrelevement($db,""); $form = new Form($db); -llxHeader('',$langs->trans("WithdrawalReceipts")); +llxHeader('',$langs->trans("WithdrawalReceipt")); if ($id > 0) @@ -138,7 +138,7 @@ if ($id > 0) $bon->fetch($id); $head = prelevement_prepare_head($bon); - dol_fiche_head($head, 'prelevement', $langs->trans("WithdrawalReceipts"), '', 'payment'); + dol_fiche_head($head, 'prelevement', $langs->trans("WithdrawalReceipt"), '', 'payment'); if (GETPOST('error','alpha')!='') { diff --git a/htdocs/compta/prelevement/lignes.php b/htdocs/compta/prelevement/lignes.php index 16da5e8c9e9..2e8978778ef 100644 --- a/htdocs/compta/prelevement/lignes.php +++ b/htdocs/compta/prelevement/lignes.php @@ -35,6 +35,7 @@ require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php'; if ($user->societe_id > 0) accessforbidden(); $langs->load("categories"); +$langs->load('withdrawals'); // Get supervariables $prev_id = GETPOST('id','int'); From e6e183aad4422ecd3ea8cb3815e0787bba5bcd2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Thu, 10 Jan 2013 12:03:08 +0100 Subject: [PATCH 07/36] Fix bug in Adherent class not saving civilite=0 --- htdocs/adherents/class/adherent.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 065a39db3f3..8e219b47286 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -423,7 +423,7 @@ class Adherent extends CommonObject $this->db->begin(); $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET"; - $sql.= " civilite = ".($this->civilite_id?"'".$this->civilite_id."'":"null"); + $sql.= " civilite = ".(!is_null($this->civilite_id)?"'".$this->civilite_id."'":"null"); $sql.= ", prenom = ".($this->firstname?"'".$this->db->escape($this->firstname)."'":"null"); $sql.= ", nom=" .($this->lastname?"'".$this->db->escape($this->lastname)."'":"null"); $sql.= ", login=" .($this->login?"'".$this->db->escape($this->login)."'":"null"); From 8ac33e98e7da9be90f08719e404c78b1dd16d50a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 10 Jan 2013 12:58:46 +0100 Subject: [PATCH 08/36] Fix: property object_total_discount was not working when quantity was not 1. --- htdocs/core/class/commonobject.class.php | 37 +++++++++++++----- .../doc/doc_generic_order_odt.modules.php | 2 +- .../doc/doc_generic_invoice_odt.modules.php | 2 +- .../doc/doc_generic_proposal_odt.modules.php | 2 +- .../invoices/template_invoice.odt | Bin 25649 -> 18694 bytes 5 files changed, 31 insertions(+), 12 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 02691a2b2de..e0646e4f2c8 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -2253,24 +2253,43 @@ abstract class CommonObject } /** - * Function that returns the total amount of discounts applied. + * Function that returns the total amount HT of discounts applied for all lines. * - * @return false|float False is returned if the discount couldn't be retrieved + * @return in 0 if no discount */ function getTotalDiscount() { - $sql = 'SELECT (SUM(`subprice`) - SUM(`total_ht`)) as `discount` FROM '.MAIN_DB_PREFIX.$this->table_element.'det WHERE `'.$this->fk_element.'` = '.$this->id; + $total_discount=0; - $query = $this->db->query($sql); + $sql = "SELECT subprice as pu_ht, qty, remise_percent, total_ht"; + $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element."det"; + $sql.= " WHERE ".$this->fk_element." = ".$this->id; - if ($query) + dol_syslog(get_class($this).'::getTotalDiscount sql='.$sql); + $resql = $this->db->query($sql); + if ($resql) { - $result = $this->db->fetch_object($query); + $num=$this->db->num_rows($resql); + $i=0; + while ($i < $num) + { + $obj = $this->db->fetch_object($query); - return price2num($result->discount); + $pu_ht = $obj->pu_ht; + $qty= $obj->qty; + $discount_percent_line = $obj->remise_percent; + $total_ht = $obj->total_ht; + + $total_discount_line = price2num(($pu_ht * $qty) - $total_ht, 'MT'); + $total_discount += $total_discount_line; + + $i++; + } } - - return false; + else dol_syslog(get_class($this).'::getTotalDiscount '.$this->db->lasterror(), LOG_ERR); + + //print $total_discount; exit; + return price2num($total_discount); } /** diff --git a/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php index ad1a2eaa4d4..de7fde68667 100644 --- a/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php +++ b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php @@ -115,7 +115,7 @@ class doc_generic_order_odt extends ModelePDFCommandes 'object_total_ht'=>price($object->total_ht,0,$outputlangs), 'object_total_vat'=>price($object->total_tva,0,$outputlangs), 'object_total_ttc'=>price($object->total_ttc,0,$outputlangs), - 'object_total_discount' => price($object->getTotalDiscount(), 0, $outputlangs), + 'object_total_discount_ht' => price($object->getTotalDiscount(), 0, $outputlangs), 'object_vatrate'=>vatrate($object->tva), 'object_note_private'=>$object->note, 'object_note'=>$object->note_public, diff --git a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php index c85f5cd950a..81b2477f819 100644 --- a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php +++ b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php @@ -124,7 +124,7 @@ class doc_generic_invoice_odt extends ModelePDFFactures 'object_total_ht'=>price($object->total_ht,0,$outputlangs), 'object_total_vat'=>price($object->total_tva,0,$outputlangs), 'object_total_ttc'=>price($object->total_ttc,0,$outputlangs), - 'object_total_discount' => price($object->getTotalDiscount(), 0, $outputlangs), + 'object_total_discount_ht' => price($object->getTotalDiscount(), 0, $outputlangs), 'object_vatrate'=>(isset($object->tva)?vatrate($object->tva):''), 'object_note_private'=>$object->note, 'object_note'=>$object->note_public, diff --git a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php index b9732b103db..2dc391dc08d 100644 --- a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php +++ b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php @@ -114,7 +114,7 @@ class doc_generic_proposal_odt extends ModelePDFPropales 'object_total_ht'=>price($object->total_ht,0,$outputlangs), 'object_total_vat'=>price($object->total_tva,0,$outputlangs), 'object_total_ttc'=>price($object->total_ttc,0,$outputlangs), - 'object_total_discount' => price($object->getTotalDiscount(), 0, $outputlangs), + 'object_total_discount_ht' => price($object->getTotalDiscount(), 0, $outputlangs), 'object_vatrate'=>vatrate($object->tva), 'object_note_private'=>$object->note, 'object_note'=>$object->note_public, diff --git a/htdocs/install/doctemplates/invoices/template_invoice.odt b/htdocs/install/doctemplates/invoices/template_invoice.odt index 2d50e4352216833aa560c62fb962def5bb62cdc1..2c43d353bbb9d8fd01bfed0fc3802a5a17049898 100644 GIT binary patch literal 18694 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 H-fI63&?Q1Z delta 24026 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%0D(kD^=>z#Q~q=!7VK7O5P;8(Ya({VBdz(j5YU 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 QC@d&rI4Gz_gTMCv4~2i5hyVZp From acd4e8f747ab854b3d2e3b4e4bdc836d29d7067b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Thu, 10 Jan 2013 13:51:52 +0100 Subject: [PATCH 09/36] Updated changelog with renamed ODT tag --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index b3ef7d205e2..a2d95573257 100644 --- a/ChangeLog +++ b/ChangeLog @@ -60,7 +60,7 @@ For users: - New: [ task #210 ] Can choose cash account during POS login. - New: [ task #104 ] Can create an invoice from several orders. - New: Update libs/tools/logo for DoliWamp (now use PHP 5.3). -- New: Added ODT Template tag {object_total_discount} +- New: Added ODT Template tag {object_total_discount_ht} - New: Add new import options: Third parties bank details, warehouses and stocks, categories and suppliers prices - New: English bank account need a bank code (called sort code) to identify an account. - New: Can choose menu entry to show with external site module. From 593db37423fbbb9dd1af1df4bd37e5868e826aa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Thu, 10 Jan 2013 13:53:46 +0100 Subject: [PATCH 10/36] Function getTotalDiscount of commonobject.class.php should always return a float for precission --- htdocs/core/class/commonobject.class.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index e0646e4f2c8..95ff4b66c12 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -1525,20 +1525,20 @@ abstract class CommonObject if ($this->total_localtax1 == 0) { // Search to know if there is a localtax of type 7 - // TODO : store local taxes types into object lines and remove this. We should use here $obj->localtax1_type but it is not yet filled into database, so we search into table of vat rate + // TODO : store local taxes types into object lines and remove this. We should use here $obj->localtax1_type but it is not yet filled into database, so we search into table of vat rate global $mysoc; - $localtax1_array=getLocalTaxesFromRate($vatrate,1,$mysoc); + $localtax1_array=getLocalTaxesFromRate($vatrate,1,$mysoc); if (empty($obj->localtax1_type)) { $obj->localtax1_type = $localtax1_array[0]; $obj->localtax1_tx = $localtax1_array[1]; - } + } //end TODO if ($obj->localtax1_type == '7') { - $this->total_localtax1 += $obj->localtax1_tx; - $this->total_ttc += $obj->localtax1_tx; + $this->total_localtax1 += $obj->localtax1_tx; + $this->total_ttc += $obj->localtax1_tx; } } if ($this->total_localtax2 == 0) @@ -2255,11 +2255,11 @@ abstract class CommonObject /** * Function that returns the total amount HT of discounts applied for all lines. * - * @return in 0 if no discount + * @return float */ function getTotalDiscount() { - $total_discount=0; + $total_discount=0.00; $sql = "SELECT subprice as pu_ht, qty, remise_percent, total_ht"; $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element."det"; @@ -2289,7 +2289,7 @@ abstract class CommonObject else dol_syslog(get_class($this).'::getTotalDiscount '.$this->db->lasterror(), LOG_ERR); //print $total_discount; exit; - return price2num($total_discount); + return price2num($total_discount); } /** From 809367d23b4a4cb24fe7066f81a02ced65de73de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Thu, 10 Jan 2013 14:17:43 +0100 Subject: [PATCH 11/36] Updated EU VAT area links and added Isle of Man Isle of Man is in included in UK state as shown in http://ec.europa.eu/taxation_customs/common/faq/faq_1179_en.htm#9 --- htdocs/core/class/commonobject.class.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index e0646e4f2c8..eb27a7f91d9 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -2332,7 +2332,7 @@ abstract class CommonObject function isInEEC() { // List of all country codes that are in europe for european vat rules - // List found on http://ec.europa.eu/taxation_customs/vies/lang.do?fromWhichPage=vieshome + // List found on http://ec.europa.eu/taxation_customs/common/faq/faq_1179_en.htm#9 $country_code_in_EEC=array( 'AT', // Austria 'BE', // Belgium @@ -2345,16 +2345,17 @@ abstract class CommonObject 'ES', // Spain 'FI', // Finland 'FR', // France - 'GB', // Royaume-uni + 'GB', // United Kingdom 'GR', // Greece 'NL', // Holland 'HU', // Hungary 'IE', // Ireland + 'IM', // Isle of Man - Included in UK 'IT', // Italy 'LT', // Lithuania 'LU', // Luxembourg 'LV', // Latvia - 'MC', // Monaco Seems to use same IntraVAT than France (http://www.gouv.mc/devwww/wwwnew.nsf/c3241c4782f528bdc1256d52004f970b/9e370807042516a5c1256f81003f5bb3!OpenDocument) + 'MC', // Monaco - Included in France 'MT', // Malta //'NO', // Norway 'PL', // Poland From 8e7a66a5445a42b985af481868b72b6b67e050a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Thu, 10 Jan 2013 14:20:03 +0100 Subject: [PATCH 12/36] Fixed indentation problem --- htdocs/core/class/commonobject.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index eb27a7f91d9..9aebd007750 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -2350,7 +2350,7 @@ abstract class CommonObject 'NL', // Holland 'HU', // Hungary 'IE', // Ireland - 'IM', // Isle of Man - Included in UK + 'IM', // Isle of Man - Included in UK 'IT', // Italy 'LT', // Lithuania 'LU', // Luxembourg From a1282f52362d33375de4e353e96a0c1d7944c5fc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 10 Jan 2013 16:04:23 +0100 Subject: [PATCH 13/36] Fix: Navigation into projects --- htdocs/projet/ganttview.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/htdocs/projet/ganttview.php b/htdocs/projet/ganttview.php index 164a9ef6ce2..fcd413bd80b 100644 --- a/htdocs/projet/ganttview.php +++ b/htdocs/projet/ganttview.php @@ -32,7 +32,9 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; $id=GETPOST('id','int'); $ref=GETPOST('ref','alpha'); -$mine = $_REQUEST['mode']=='mine' ? 1 : 0; + +$mode = GETPOST('mode', 'alpha'); +$mine = ($mode == 'mine' ? 1 : 0); //if (! $user->rights->projet->all->lire) $mine=1; // Special for projects $object = new Project($db); @@ -99,7 +101,7 @@ if ($id > 0 || ! empty($ref)) $head=project_prepare_head($object); dol_fiche_head($head, $tab, $langs->trans("Project"),0,($object->public?'projectpub':'project')); - $param=($_REQUEST["mode"]=='mine'?'&mode=mine':''); + $param=($mode=='mine'?'&mode=mine':''); print ''; @@ -110,8 +112,11 @@ if ($id > 0 || ! empty($ref)) print $langs->trans("Ref"); print ''; From eb078e6c8ae3fee56ab7559a594a85ea1bf4a425 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 10 Jan 2013 16:06:13 +0100 Subject: [PATCH 14/36] Fix: Missing css entries. Solve look of ecm module. --- htdocs/theme/amarok/style.css.php | 368 ++++++++++++++++++++++++++++-- 1 file changed, 349 insertions(+), 19 deletions(-) diff --git a/htdocs/theme/amarok/style.css.php b/htdocs/theme/amarok/style.css.php index a3e85c0ce82..dc2aa4479b5 100755 --- a/htdocs/theme/amarok/style.css.php +++ b/htdocs/theme/amarok/style.css.php @@ -77,9 +77,15 @@ $img_button=dol_buildpath($path.'/theme/amarok/img/button_bg.png',1); *, html { margin:0; padding:0; - font-size:100%; +font-size:100%; } +/*.fiche ul { + margin:0.5em; + padding:0.5em; + padding-left: 2em; +}*/ + body { background-color:#f5f5f5; @@ -517,38 +523,195 @@ div.vmenu { /* Panes for ECM or Filemanager */ /* ============================================================================== */ + #containerlayout .layout-with-no-border { - border:0 !important; - border-width:0 !important; + border: 0 !important; + border-width: 0 !important; } #containerlayout .layout-padding { - padding:2px !important; + padding: 2px !important; } -#containerlayout .ui-layout-pane {/* all 'panes' */ - background:#ffffff; - border:1px solid #bbbbbb; - padding:0px; - overflow:auto; +/* + * PANES and CONTENT-DIVs + */ +#containerlayout .ui-layout-pane { /* all 'panes' */ + background: #FFF; + border: 1px solid #BBB; + /* DO NOT add scrolling (or padding) to 'panes' that have a content-div, + otherwise you may get double-scrollbars - on the pane AND on the content-div + */ + padding: 0px; + overflow: auto; } - +/* (scrolling) content-div inside pane allows for fixed header(s) and/or footer(s) */ #containerlayout .ui-layout-content { - padding:10px; - position:relative; /* contain floated or positioned elements */ - overflow:auto; /* add scrolling to content-div */ + padding: 10px; + position: relative; /* contain floated or positioned elements */ + overflow: auto; /* add scrolling to content-div */ } -#containerlayout .pane-in.ecm-in-layout-center.ui-layout-pane.ui-layout-pane-center { - border:0px solid #bbbbbb; - border-bottom:1px solid #bbbbbb; +/* + * RESIZER-BARS + */ +.ui-layout-resizer { /* all 'resizer-bars' */ + width: browser->phone)?'8':'24'); ?>px !important; +} +.ui-layout-resizer-hover { /* affects both open and closed states */ +} +/* NOTE: It looks best when 'hover' and 'dragging' are set to the same color, + otherwise color shifts while dragging when bar can't keep up with mouse */ +/*.ui-layout-resizer-open-hover ,*/ /* hover-color to 'resize' */ +.ui-layout-resizer-dragging { /* resizer beging 'dragging' */ + background: #DDD; + width: browser->phone)?'8':'24'); ?>px; +} +.ui-layout-resizer-dragging { /* CLONED resizer being dragged */ + border-left: 1px solid #BBB; + border-right: 1px solid #BBB; +} +/* NOTE: Add a 'dragging-limit' color to provide visual feedback when resizer hits min/max size limits */ +.ui-layout-resizer-dragging-limit { /* CLONED resizer at min or max size-limit */ + background: #E1A4A4; /* red */ +} +.ui-layout-resizer-closed { + background-color: #DDDDDD; +} +.ui-layout-resizer-closed:hover { + background-color: #EEDDDD; +} +.ui-layout-resizer-sliding { /* resizer when pane is 'slid open' */ + opacity: .10; /* show only a slight shadow */ + filter: alpha(opacity=10); +} +.ui-layout-resizer-sliding-hover { /* sliding resizer - hover */ + opacity: 1.00; /* on-hover, show the resizer-bar normally */ + filter: alpha(opacity=100); +} +/* sliding resizer - add 'outside-border' to resizer on-hover */ +/* this sample illustrates how to target specific panes and states */ +/*.ui-layout-resizer-north-sliding-hover { border-bottom-width: 1px; } +.ui-layout-resizer-south-sliding-hover { border-top-width: 1px; } +.ui-layout-resizer-west-sliding-hover { border-right-width: 1px; } +.ui-layout-resizer-east-sliding-hover { border-left-width: 1px; } +*/ + +/* + * TOGGLER-BUTTONS + */ +.ui-layout-toggler { + browser->phone)) { ?> + border-top: 1px solid #AAA; /* match pane-border */ + border-right: 1px solid #AAA; /* match pane-border */ + border-bottom: 1px solid #AAA; /* match pane-border */ + background-color: #DDD; + top: 5px !important; + + diplay: none; + +} +.ui-layout-toggler-open { + height: 54px !important; + width: browser->phone)?'7':'22'); ?>px !important; + -moz-border-radius:0px 10px 10px 0px; + -webkit-border-radius:0px 10px 10px 0px; + border-radius:0px 10px 10px 0px; +} +.ui-layout-toggler-closed { + height: browser->phone)?'54':'2'); ?>px !important; + width: browser->phone)?'7':'22'); ?>px !important; + -moz-border-radius:0px 10px 10px 0px; + -webkit-border-radius:0px 10px 10px 0px; + border-radius:0px 10px 10px 0px; +} +.ui-layout-toggler .content { /* style the text we put INSIDE the togglers */ + color: #666; + font-size: 12px; + font-weight: bold; + width: 100%; + padding-bottom: 0.35ex; /* to 'vertically center' text inside text-span */ } -#containerlayout .pane-in.ecm-in-layout-south.layout-padding.ui-layout-pane.ui-layout-pane-south { - border:0px solid #bbbbbb; - border-top:1px solid #bbbbbb; +/* hide the toggler-button when the pane is 'slid open' */ +.ui-layout-resizer-sliding ui-layout-toggler { + display: none; } +.ui-layout-north { + height: browser->phone)?'54':'21'); ?>px !important; +} + + +/* ECM */ + +#containerlayout .ecm-layout-pane { /* all 'panes' */ + background: #FFF; + border: 1px solid #BBB; + /* DO NOT add scrolling (or padding) to 'panes' that have a content-div, + otherwise you may get double-scrollbars - on the pane AND on the content-div + */ + padding: 0px; + overflow: auto; +} +/* (scrolling) content-div inside pane allows for fixed header(s) and/or footer(s) */ +#containerlayout .ecm-layout-content { + padding: 10px; + position: relative; /* contain floated or positioned elements */ + overflow: auto; /* add scrolling to content-div */ +} + +.ecm-layout-toggler { + border-top: 1px solid #AAA; /* match pane-border */ + border-right: 1px solid #AAA; /* match pane-border */ + border-bottom: 1px solid #AAA; /* match pane-border */ + background-color: #CCC; + } +.ecm-layout-toggler-open { + height: 48px !important; + width: 6px !important; + -moz-border-radius:0px 10px 10px 0px; + -webkit-border-radius:0px 10px 10px 0px; + border-radius:0px 10px 10px 0px; +} +.ecm-layout-toggler-closed { + height: 48px !important; + width: 6px !important; +} + +.ecm-layout-toggler .content { /* style the text we put INSIDE the togglers */ + color: #666; + font-size: 12px; + font-weight: bold; + width: 100%; + padding-bottom: 0.35ex; /* to 'vertically center' text inside text-span */ +} +#ecm-layout-west-resizer { + width: 6px !important; +} + +.ecm-layout-resizer { /* all 'resizer-bars' */ + border: 1px solid #BBB; + border-width: 0; + } +.ecm-layout-resizer-closed { +} + +.ecm-in-layout-center { + border-left: 1px !important; + border-right: 0px !important; + border-top: 0px !important; +} + +.ecm-in-layout-south { + border-left: 0px !important; + border-right: 0px !important; + border-bottom: 0px !important; + padding: 4px 0 4px 4px !important; +} + + + /* ============================================================================== */ /* Onglets */ /* ============================================================================== */ @@ -1003,6 +1166,9 @@ div.error { * Other */ +.product_line_stock_ok { color: #002200; } +.product_line_stock_too_low { color: #664400; } + .fieldrequired { font-weight:bold; color:#333333; @@ -1024,6 +1190,40 @@ div.titre { padding-bottom:2px; } +#dolpaymenttable { width: 600px; font-size: 13px; } +#tablepublicpayment { border: 1px solid #CCCCCC !important; width: 100%; } +#tablepublicpayment .CTableRow1 { background-color: #F0F0F0 !important; } +#tablepublicpayment tr.liste_total { border-bottom: 1px solid #CCCCCC !important; } +#tablepublicpayment tr.liste_total td { border-top: none; } + +#divsubscribe { width: 700px; } +#tablesubscribe { width: 100%; } + +div.table-border { + display:table; + width: 100%; + border-collapse: collapse; + border: 1px solid #DDD; +} +div.table-border-row { + display:table-row; +} +div.table-key-border-col { + display:table-cell; + width: 25%; + vertical-align:top; + padding: 1px 2px 1px 1px; + border: 1px solid #DDD; + border-collapse: collapse; +} +div.table-val-border-col { + display:table-cell; + width:auto; + padding: 1px 2px 1px 1px; + border: 1px solid #DDD; + border-collapse: collapse; +} + /* ============================================================================== */ /* Formulaire confirmation (When Ajax JQuery is used) */ @@ -1636,3 +1836,133 @@ span.cke_skin_kama {padding:0px !important;} /* ============================================================================== */ .template-upload {height:72px !important;} + + +/* ============================================================================== */ +/* JSGantt */ +/* ============================================================================== */ + +div.scroll2 { + width: px !important; +} + + +/* ============================================================================== */ +/* jFileTree */ +/* ============================================================================== */ + +.ecmfiletree { + width: 99%; + height: 99%; + background: #FFF; + padding-left: 2px; + font-weight: normal; +} + +.fileview { + width: 99%; + height: 99%; + background: #FFF; + padding-left: 2px; + padding-top: 4px; + font-weight: normal; +} + +div.filedirelem { + position: relative; + display: block; + text-decoration: none; +} + +ul.filedirelem { + padding: 2px; + margin: 0 5px 5px 5px; +} +ul.filedirelem li { + list-style: none; + padding: 2px; + margin: 0 10px 20px 10px; + width: 160px; + height: 120px; + text-align: center; + display: block; + float: ; + border: solid 1px #DDDDDD; +} + +ui-layout-north { + +} + +ul.ecmjqft { + font-size: 11px; + line-height: 16px; + padding: 0px; + margin: 0px; + font-weight: normal; +} + +ul.ecmjqft li { + list-style: none; + padding: 0px; + padding-left: 20px; + margin: 0px; + white-space: nowrap; + display: block; +} + +ul.ecmjqft a { + line-height: 16px; + vertical-align: middle; + color: #333; + padding: 0px 0px; + font-weight:normal; + display: inline-block !important; +/* float: left;*/ +} +ul.ecmjqft a:active { + font-weight: bold !important; +} +ul.ecmjqft a:hover { + text-decoration: underline; +} +div.ecmjqft { + vertical-align: middle; + display: inline-block !important; + text-align: right; + position:absolute; + right:4px; +} + +/* Core Styles */ +.ecmjqft LI.directory { font-weight:normal; background: url() left top no-repeat; } +.ecmjqft LI.expanded { font-weight:normal; background: url() left top no-repeat; } +.ecmjqft LI.wait { font-weight:normal; background: url() left top no-repeat; } + + + +/* ============================================================================== */ +/* jNotify */ +/* ============================================================================== */ + +.jnotify-container { + position: fixed !important; +global->MAIN_JQUERY_JNOTIFY_BOTTOM)) { ?> + top: auto !important; + bottom: 4px !important; + + text-align: center; + min-width: 500px; + width: auto; + padding-left: 10px !important; + padding-right: 10px !important; +} + +/* use or not ? */ +div.jnotify-background { + opacity : 0.95 !important; + -moz-box-shadow: 4px 4px 4px #AAA !important; + -webkit-box-shadow: 4px 4px 4px #AAA !important; + box-shadow: 4px 4px 4px #AAA !important; +} + From 9d57ea7cd0fc56b27d47b33e6f82524c73ac3e31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Thu, 10 Jan 2013 16:24:07 +0100 Subject: [PATCH 15/36] Fixed typo in console message --- dev/skeletons/build_webservice_from_class.php | 2 +- scripts/company/export-contacts-xls-example.php | 2 +- scripts/company/sync_contacts_dolibarr2ldap.php | 2 +- scripts/invoices/rebuild_merge_pdf.php | 2 +- scripts/members/sync_members_dolibarr2ldap.php | 2 +- scripts/members/sync_members_ldap2dolibarr.php | 2 +- scripts/user/sync_groups_dolibarr2ldap.php | 2 +- scripts/user/sync_users_dolibarr2ldap.php | 2 +- scripts/user/sync_users_ldap2dolibarr.php | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dev/skeletons/build_webservice_from_class.php b/dev/skeletons/build_webservice_from_class.php index f489f32201b..e21b4cf89f7 100644 --- a/dev/skeletons/build_webservice_from_class.php +++ b/dev/skeletons/build_webservice_from_class.php @@ -28,7 +28,7 @@ $path=dirname(__FILE__).'/'; // Test if batch mode if (substr($sapi_type, 0, 3) == 'cgi') { - echo "Error: You ar usingr PH for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; exit; } diff --git a/scripts/company/export-contacts-xls-example.php b/scripts/company/export-contacts-xls-example.php index bdef2e43d40..83e7c9e165c 100644 --- a/scripts/company/export-contacts-xls-example.php +++ b/scripts/company/export-contacts-xls-example.php @@ -30,7 +30,7 @@ $path=dirname(__FILE__).'/'; // Test if batch mode if (substr($sapi_type, 0, 3) == 'cgi') { - echo "Error: You ar usingr PH for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; exit; } diff --git a/scripts/company/sync_contacts_dolibarr2ldap.php b/scripts/company/sync_contacts_dolibarr2ldap.php index e80443430b1..f0adfe682ef 100644 --- a/scripts/company/sync_contacts_dolibarr2ldap.php +++ b/scripts/company/sync_contacts_dolibarr2ldap.php @@ -30,7 +30,7 @@ $path=dirname(__FILE__).'/'; // Test if batch mode if (substr($sapi_type, 0, 3) == 'cgi') { - echo "Error: You ar usingr PH for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; exit; } diff --git a/scripts/invoices/rebuild_merge_pdf.php b/scripts/invoices/rebuild_merge_pdf.php index c44ed149c03..5b2b4aedb2f 100644 --- a/scripts/invoices/rebuild_merge_pdf.php +++ b/scripts/invoices/rebuild_merge_pdf.php @@ -29,7 +29,7 @@ $path=dirname(__FILE__).'/'; // Test if batch mode if (substr($sapi_type, 0, 3) == 'cgi') { - echo "Error: You ar usingr PH for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; exit; } diff --git a/scripts/members/sync_members_dolibarr2ldap.php b/scripts/members/sync_members_dolibarr2ldap.php index af564b6f67b..43d5964707c 100755 --- a/scripts/members/sync_members_dolibarr2ldap.php +++ b/scripts/members/sync_members_dolibarr2ldap.php @@ -30,7 +30,7 @@ $path=dirname(__FILE__).'/'; // Test if batch mode if (substr($sapi_type, 0, 3) == 'cgi') { - echo "Error: You ar usingr PH for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; exit; } diff --git a/scripts/members/sync_members_ldap2dolibarr.php b/scripts/members/sync_members_ldap2dolibarr.php index 7e7d55fbf90..618a090b4c1 100755 --- a/scripts/members/sync_members_ldap2dolibarr.php +++ b/scripts/members/sync_members_ldap2dolibarr.php @@ -30,7 +30,7 @@ $path=dirname(__FILE__).'/'; // Test if batch mode if (substr($sapi_type, 0, 3) == 'cgi') { - echo "Error: You ar usingr PH for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; exit; } diff --git a/scripts/user/sync_groups_dolibarr2ldap.php b/scripts/user/sync_groups_dolibarr2ldap.php index 32086f51752..71af532b098 100755 --- a/scripts/user/sync_groups_dolibarr2ldap.php +++ b/scripts/user/sync_groups_dolibarr2ldap.php @@ -30,7 +30,7 @@ $path=dirname(__FILE__).'/'; // Test if batch mode if (substr($sapi_type, 0, 3) == 'cgi') { - echo "Error: You ar usingr PH for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; exit; } diff --git a/scripts/user/sync_users_dolibarr2ldap.php b/scripts/user/sync_users_dolibarr2ldap.php index a4931d91d32..3d36549f494 100755 --- a/scripts/user/sync_users_dolibarr2ldap.php +++ b/scripts/user/sync_users_dolibarr2ldap.php @@ -30,7 +30,7 @@ $path=dirname(__FILE__).'/'; // Test if batch mode if (substr($sapi_type, 0, 3) == 'cgi') { - echo "Error: You ar usingr PH for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; exit; } diff --git a/scripts/user/sync_users_ldap2dolibarr.php b/scripts/user/sync_users_ldap2dolibarr.php index e94c2cd618a..f4c908fb150 100755 --- a/scripts/user/sync_users_ldap2dolibarr.php +++ b/scripts/user/sync_users_ldap2dolibarr.php @@ -30,7 +30,7 @@ $path=dirname(__FILE__).'/'; // Test if batch mode if (substr($sapi_type, 0, 3) == 'cgi') { - echo "Error: You ar usingr PH for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; exit; } From de03f57620479954cc082b0cb90785c930a4ba85 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 10 Jan 2013 18:02:06 +0100 Subject: [PATCH 16/36] Fix: Translation --- htdocs/langs/en_US/install.lang | 2 +- htdocs/langs/fr_FR/install.lang | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/langs/en_US/install.lang b/htdocs/langs/en_US/install.lang index f111bfad1d6..a5d3d5e7ce8 100644 --- a/htdocs/langs/en_US/install.lang +++ b/htdocs/langs/en_US/install.lang @@ -65,7 +65,7 @@ DatabaseSuperUserAccess=Database server - Superuser access CheckToCreateDatabase=Check box if database does not exist and must be created.
In this case, you must fill the login/password for superuser account at the bottom of this page. CheckToCreateUser=Check box if database owner does not exist and must be created.
In this case, you must choose its login and password and also fill the login/password for the superuser account at the bottom of this page. If this box is unchecked, owner database and its passwords must exists. Experimental=(experimental) -DatabaseRootLoginDescription=Login of the user allowed to create new databases or new users, useless if your database and your database login already exists (like when you're hosted by a web hosting provider). +DatabaseRootLoginDescription=Login of the user allowed to create new databases or new users, mandatory if your database or its owner does not already exists. KeepEmptyIfNoPassword=Leave empty if user has no password (avoid this) SaveConfigurationFile=Save values ConfigurationSaving=Saving configuration file diff --git a/htdocs/langs/fr_FR/install.lang b/htdocs/langs/fr_FR/install.lang index da7fbe1b610..5a34feaf94e 100644 --- a/htdocs/langs/fr_FR/install.lang +++ b/htdocs/langs/fr_FR/install.lang @@ -65,7 +65,7 @@ DatabaseSuperUserAccess=Serveur de base de données - Accès super utilisateur CheckToCreateDatabase=Cochez cette option si la base de données n'existe pas et doit être créée.
Dans ce cas, il faut renseigner le login/mot de passe du super-utilisateur au bas de cette page. CheckToCreateUser=Cochez cette option si l'utilisateur propriétaire n'existe pas et doit être créé.
Dans ce cas, il faut renseigner le nom et mot de passe du propriétaire à créer ainsi que le login/mot de passe du superutilisateur au bas de cette page. Si la case n'est pas cochée, le nom et mot de passe du propriétaire doivent exister. Experimental=(expérimental) -DatabaseRootLoginDescription=Login de l'utilisateur de la base ayant les droits de création de bases de données ou de comptes pour la base, inutile si la base et son compte d'accès existent déjà (comme lorsque vous êtes chez un hébergeur). +DatabaseRootLoginDescription=Login de l'utilisateur de la base ayant les droits de création de bases de données ou de comptes pour la base, requis si la base ou son propriétaire n'existe pas déjà et doivent être créés. KeepEmptyIfNoPassword=Laissez vide si l'administrateur n'a pas de mot de passe SaveConfigurationFile=Enregistrement du fichier de configuration ConfigurationSaving=Enregistrement du fichier de configuration From 0c7b469192bbab3966d8078729fb4f964fcb1aa6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 10 Jan 2013 20:07:44 +0100 Subject: [PATCH 17/36] Fix: Session was lost when user change its own login. --- htdocs/user/fiche.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/htdocs/user/fiche.php b/htdocs/user/fiche.php index fd314fef0a8..125b79c5559 100644 --- a/htdocs/user/fiche.php +++ b/htdocs/user/fiche.php @@ -454,6 +454,12 @@ if ($action == 'update' && ! $_POST["cancel"]) { $message.='
'.$langs->trans("UserModified").'
'; $db->commit(); + + $login=$_SESSION["dol_login"]; + if ($login && $login == $object->oldcopy->login && $object->oldcopy->login != $object->login) // Current user has changed its login + { + $_SESSION["dol_login"]=$object->login; // Set new login to avoid disconnect at next page + } } else { From 941afd75452dc52bc08d3e43ef28bd00ed0762b2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 10 Jan 2013 20:12:14 +0100 Subject: [PATCH 18/36] Fix: Because of autocomplete, password was changed when we changed login. --- htdocs/user/fiche.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/user/fiche.php b/htdocs/user/fiche.php index 125b79c5559..e3d6236ff4a 100644 --- a/htdocs/user/fiche.php +++ b/htdocs/user/fiche.php @@ -775,7 +775,7 @@ if (($action == 'create') || ($action == 'adduserldap')) else { // We do not use a field password but a field text to show new password to use. - print ''; + print ''; } } print ''; @@ -1654,7 +1654,7 @@ else } else if ($caneditpassword) { - $text=''; + $text=''; if ($dolibarr_main_authentication && $dolibarr_main_authentication == 'http') { $text=$form->textwithpicto($text,$langs->trans("DolibarrInHttpAuthenticationSoPasswordUseless",$dolibarr_main_authentication),1,'warning'); From 14dede1a74de8912048c9f63a11a17ed88b86e06 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 10 Jan 2013 21:32:10 +0100 Subject: [PATCH 19/36] Fix: Protection to avoid renaming a user with a login that already exists. --- htdocs/user/fiche.php | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/htdocs/user/fiche.php b/htdocs/user/fiche.php index e3d6236ff4a..607ed452657 100644 --- a/htdocs/user/fiche.php +++ b/htdocs/user/fiche.php @@ -307,9 +307,27 @@ if ($action == 'update' && ! $_POST["cancel"]) if (! $error) { - $db->begin(); $object->fetch($id); + // Test if new login + if (GETPOST("login") && GETPOST("login") != $object->login) + { + dol_syslog("New login ".$object->login." is requested. We test it does not exists."); + $tmpuser=new User($db); + $result=$tmpuser->fetch(0, GETPOST("login")); + if ($result > 0) + { + $message='
'.$langs->trans("ErrorLoginAlreadyExists").'
'; + $action="edit"; // Go back to create page + $error++; + } + } + } + + if (! $error) + { + $db->begin(); + $object->oldcopy=dol_clone($object); $object->lastname = GETPOST("nom"); From 37b6bab893e989dbba24d0add8e767183873c7b7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 10 Jan 2013 22:45:55 +0100 Subject: [PATCH 20/36] Fix: Missing lang loading --- htdocs/core/class/html.formfile.class.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 15ea8b2cc2c..5afcd27ac67 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -120,6 +120,7 @@ class FormFile { if ($perm) { + $langs->load('other'); print ' ('.$langs->trans("MaxSize").': '.$max.' '.$langs->trans("Kb"); print ' '.info_admin($langs->trans("ThisLimitIsDefinedInSetup",$max,$maxphp),1); print ')'; From 38e9290729c426ba7f4a532af963df10431ffd98 Mon Sep 17 00:00:00 2001 From: Christophe Battarel Date: Fri, 11 Jan 2013 15:33:34 +0100 Subject: [PATCH 21/36] show costprice instead of buyingprice if setup of margin module is costprice --- htdocs/core/class/commonobject.class.php | 7 +- .../core/tpl/freeproductline_create.tpl.php | 297 ++++++------- .../tpl/predefinedproductline_create.tpl.php | 393 +++++++++--------- htdocs/fourn/ajax/getSupplierPrices.php | 7 +- 4 files changed, 359 insertions(+), 345 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 1c2a62c8b62..0a5ae5df34c 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -2649,7 +2649,7 @@ abstract class CommonObject if ($conf->global->MARGIN_TYPE == "1") print '
'; else - print ''; + print ''; if (! empty($conf->global->DISPLAY_MARGIN_RATES)) print ''; if (! empty($conf->global->DISPLAY_MARK_RATES)) @@ -3049,7 +3049,10 @@ abstract class CommonObject print ''; print ''; print ''; - print ''; + if ($conf->global->MARGIN_TYPE == "1") + print ''; + else + print ''; print ''; if (! empty($conf->global->DISPLAY_MARGIN_RATES)) print ''; diff --git a/htdocs/core/tpl/freeproductline_create.tpl.php b/htdocs/core/tpl/freeproductline_create.tpl.php index 763e8d414c9..679e89429fc 100644 --- a/htdocs/core/tpl/freeproductline_create.tpl.php +++ b/htdocs/core/tpl/freeproductline_create.tpl.php @@ -1,148 +1,155 @@ - - * Copyright (C) 2010-2011 Laurent Destailleur - * Copyright (C) 2012 Christophe Battarel - * - * 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 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * Need to have following variables defined: - * $conf - * $langs - * $dateSelector - * $this (invoice, order, ...) - * $line defined - */ - -$usemargins=0; -if (! empty($conf->margin->enabled) && ! empty($object->element) && in_array($object->element,array('facture','propal','commande'))) $usemargins=1; - -?> - - - - - - - - - - - global->DISPLAY_MARGIN_RATES)) $colspan++; - if (! empty($conf->global->DISPLAY_MARK_RATES)) $colspan++; - } - ?> - - - -"> - - - - - > - global->MAIN_VIEW_LINE_NUMBER) ? ' colspan="2"' : ''); ?>> - '; - echo $form->select_type_of_lines(isset($_POST["type"])?$_POST["type"]:-1,'type',1); - echo ''; - - if (is_object($hookmanager)) - { - $parameters=array(); - $reshook=$hookmanager->executeHooks('formCreateProductOptions',$parameters,$object,$action); - } - - if ((! empty($conf->product->enabled) && ! empty($conf->service->enabled)) || (empty($conf->product->enabled) && empty($conf->service->enabled))) echo '
'; - - // Editor wysiwyg - require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $nbrows=ROWS_2; - $enabled=(! empty($conf->global->FCKEDITOR_ENABLE_DETAILS)?$conf->global->FCKEDITOR_ENABLE_DETAILS:0); - if (! empty($conf->global->MAIN_INPUT_DESC_HEIGHT)) $nbrows=$conf->global->MAIN_INPUT_DESC_HEIGHT; - $doleditor=new DolEditor('dp_desc',GETPOST('dp_desc'),'',100,'dolibarr_details','',false,true,$enabled,$nbrows,70); - $doleditor->Create(); - ?> - - -
- - - - - - global->DISPLAY_MARGIN_RATES)) $colspan++; - if (! empty($conf->global->DISPLAY_MARK_RATES)) $colspan++; - } - ?> - - - - service->enabled) && $dateSelector) - { - if(! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) $colspan = 10; - else $colspan = 9; - - if (! empty($usemargins)) - { - $colspan++; // For the buying price - if($conf->global->DISPLAY_MARGIN_RATES) $colspan++; - if($conf->global->DISPLAY_MARK_RATES) $colspan++; - } - ?> - > - + + + + + + + + global->DISPLAY_MARGIN_RATES)) $colspan++; + if (! empty($conf->global->DISPLAY_MARK_RATES)) $colspan++; + } + ?> + + + +"> + + + + + > + global->MAIN_VIEW_LINE_NUMBER) ? ' colspan="2"' : ''); ?>> + '; + echo $form->select_type_of_lines(isset($_POST["type"])?$_POST["type"]:-1,'type',1); + echo ''; + + if (is_object($hookmanager)) + { + $parameters=array(); + $reshook=$hookmanager->executeHooks('formCreateProductOptions',$parameters,$object,$action); + } + + if ((! empty($conf->product->enabled) && ! empty($conf->service->enabled)) || (empty($conf->product->enabled) && empty($conf->service->enabled))) echo '
'; + + // Editor wysiwyg + require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; + $nbrows=ROWS_2; + $enabled=(! empty($conf->global->FCKEDITOR_ENABLE_DETAILS)?$conf->global->FCKEDITOR_ENABLE_DETAILS:0); + if (! empty($conf->global->MAIN_INPUT_DESC_HEIGHT)) $nbrows=$conf->global->MAIN_INPUT_DESC_HEIGHT; + $doleditor=new DolEditor('dp_desc',GETPOST('dp_desc'),'',100,'dolibarr_details','',false,true,$enabled,$nbrows,70); + $doleditor->Create(); + ?> + + +
+ + + + + + global->DISPLAY_MARGIN_RATES)) $colspan++; + if (! empty($conf->global->DISPLAY_MARK_RATES)) $colspan++; + } + ?> + + + + service->enabled) && $dateSelector) + { + if(! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) $colspan = 10; + else $colspan = 9; + + if (! empty($usemargins)) + { + $colspan++; // For the buying price + if($conf->global->DISPLAY_MARGIN_RATES) $colspan++; + if($conf->global->DISPLAY_MARK_RATES) $colspan++; + } + ?> + > + - - - - - + $form->select_date('',"date_end_sl",$usehm,$usehm,1,"addline_sl"); + } + else + { + echo $langs->trans('ServiceLimitedDuration').' '.$langs->trans('From').' '; + echo $form->select_date('','date_start',$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE,$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE,1,"addproduct"); + echo ' '.$langs->trans('to').' '; + echo $form->select_date('','date_end',$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE,$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE,1,"addproduct"); + } + ?> + + + + + + diff --git a/htdocs/core/tpl/predefinedproductline_create.tpl.php b/htdocs/core/tpl/predefinedproductline_create.tpl.php index 07178b42bb2..7ccf1f63407 100644 --- a/htdocs/core/tpl/predefinedproductline_create.tpl.php +++ b/htdocs/core/tpl/predefinedproductline_create.tpl.php @@ -1,200 +1,207 @@ - - * Copyright (C) 2010-2012 Laurent Destailleur - * Copyright (C) 2012 Christophe Battarel - * - * 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 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * - * Need to have following variables defined: - * $conf - * $langs - * $dateSelector - * $this (invoice, order, ...) - * $line defined - */ - + + * Copyright (C) 2010-2012 Laurent Destailleur + * Copyright (C) 2012 Christophe Battarel + * + * 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 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * + * Need to have following variables defined: + * $conf + * $langs + * $dateSelector + * $this (invoice, order, ...) + * $line defined + */ + $usemargins=0; if (! empty($conf->margin->enabled) && ! empty($object->element) && in_array($object->element,array('facture','propal','commande'))) $usemargins=1; - -?> - - - - - global->MAIN_VIEW_LINE_NUMBER) ? ' colspan="4"' : ' colspan="3"'); ?>> - trans("AddNewLine").' - '; - if (! empty($conf->product->enabled) && empty($conf->service->enabled)) echo $langs->trans('RecordedProducts'); - else if (empty($conf->product->enabled) && ! empty($conf->service->enabled)) echo $langs->trans('RecordedServices'); - else echo $langs->trans('RecordedProductsAndServices'); - ?> - - - -global->DISPLAY_MARGIN_RATES)) $colspan++; - if (! empty($conf->global->DISPLAY_MARK_RATES)) $colspan++; - ?> - - - - - -"> - - - - - - -> - global->MAIN_VIEW_LINE_NUMBER) ? ' colspan="4"' : ' colspan="3"'); ?>> - '; - $filtertype=''; - if (! empty($object->element) && $object->element == 'contrat') $filtertype='1'; - $form->select_produits('','idprod',$filtertype,$conf->product->limit_size,$buyer->price_level); - echo ''; - - if (is_object($hookmanager)) - { - $parameters=array('fk_parent_line'=>GETPOST('fk_parent_line','int')); - $reshook=$hookmanager->executeHooks('formCreateProductOptions',$parameters,$object,$action); - } - - echo '
'; - - // Editor wysiwyg - require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $nbrows=ROWS_2; - $enabled=(! empty($conf->global->FCKEDITOR_ENABLE_DETAILS)?$conf->global->FCKEDITOR_ENABLE_DETAILS:0); - if (! empty($conf->global->MAIN_INPUT_DESC_HEIGHT)) $nbrows=$conf->global->MAIN_INPUT_DESC_HEIGHT; - $doleditor=new DolEditor('np_desc',GETPOST('np_desc"'),'',100,'dolibarr_details','',false,true,$enabled,$nbrows,70); - $doleditor->Create(); - ?> - -
- - global->DISPLAY_MARGIN_RATES)) $colspan++; - if (! empty($conf->global->DISPLAY_MARK_RATES)) $colspan++; - ?> - - - - - -service->enabled) && $dateSelector) -{ - if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) $colspan = 10; - else $colspan = 9; - if (! empty($usemargins)) - { - $colspan++; // For the buying price - if (! empty($conf->global->DISPLAY_MARGIN_RATES)) $colspan++; - if (! empty($conf->global->DISPLAY_MARK_RATES)) $colspan++; - } -?> -> - + global->MAIN_VIEW_LINE_NUMBER) ? ' colspan="4"' : ' colspan="3"'); ?>> + trans("AddNewLine").' - '; + if (! empty($conf->product->enabled) && empty($conf->service->enabled)) echo $langs->trans('RecordedProducts'); + else if (empty($conf->product->enabled) && ! empty($conf->service->enabled)) echo $langs->trans('RecordedServices'); + else echo $langs->trans('RecordedProductsAndServices'); + ?> + + + +global->DISPLAY_MARGIN_RATES)) $colspan++; + if (! empty($conf->global->DISPLAY_MARK_RATES)) $colspan++; + ?> + + + + + +"> + + + + + + +> + global->MAIN_VIEW_LINE_NUMBER) ? ' colspan="4"' : ' colspan="3"'); ?>> + '; + $filtertype=''; + if (! empty($object->element) && $object->element == 'contrat') $filtertype='1'; + $form->select_produits('','idprod',$filtertype,$conf->product->limit_size,$buyer->price_level); + echo ''; + + if (is_object($hookmanager)) + { + $parameters=array('fk_parent_line'=>GETPOST('fk_parent_line','int')); + $reshook=$hookmanager->executeHooks('formCreateProductOptions',$parameters,$object,$action); + } + + echo '
'; + + // Editor wysiwyg + require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; + $nbrows=ROWS_2; + $enabled=(! empty($conf->global->FCKEDITOR_ENABLE_DETAILS)?$conf->global->FCKEDITOR_ENABLE_DETAILS:0); + if (! empty($conf->global->MAIN_INPUT_DESC_HEIGHT)) $nbrows=$conf->global->MAIN_INPUT_DESC_HEIGHT; + $doleditor=new DolEditor('np_desc',GETPOST('np_desc"'),'',100,'dolibarr_details','',false,true,$enabled,$nbrows,70); + $doleditor->Create(); + ?> + +
+ + global->DISPLAY_MARGIN_RATES)) $colspan++; + if (! empty($conf->global->DISPLAY_MARK_RATES)) $colspan++; + ?> + + + + + +service->enabled) && $dateSelector) +{ + if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) $colspan = 10; + else $colspan = 9; + if (! empty($usemargins)) + { + $colspan++; // For the buying price + if (! empty($conf->global->DISPLAY_MARGIN_RATES)) $colspan++; + if (! empty($conf->global->DISPLAY_MARK_RATES)) $colspan++; + } +?> +> + - - - - - - - - - + echo $langs->trans('ServiceLimitedDuration').' '.$langs->trans('From').' '; + echo $form->select_date('','date_start_predef',$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE,$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE,1,"addpredefinedproduct"); + echo ' '.$langs->trans('to').' '; + echo $form->select_date('','date_end_predef',$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE,$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE,1,"addpredefinedproduct"); + } + ?> + + + + + + + + + + diff --git a/htdocs/fourn/ajax/getSupplierPrices.php b/htdocs/fourn/ajax/getSupplierPrices.php index 3dfe6de2d64..67ffbad93ce 100644 --- a/htdocs/fourn/ajax/getSupplierPrices.php +++ b/htdocs/fourn/ajax/getSupplierPrices.php @@ -73,12 +73,9 @@ if (! empty($idprod)) $objp = $db->fetch_object($result); $title = $objp->nom.' - '.$objp->ref_fourn.' - '; - $label = ''; if ($objp->quantity == 1) { - $label.= price($objp->fprice).getCurrencySymbol($conf->currency)."/".strtolower($langs->trans("Unit")); - $title.= price($objp->fprice); $title.= getCurrencySymbol($conf->currency)."/"; @@ -100,8 +97,6 @@ if (! empty($idprod)) $title.=" - "; $title.= price($objp->unitprice).getCurrencySymbol($conf->currency)."/".strtolower($langs->trans("Unit")); - $label.= price($objp->unitprice).getCurrencySymbol($conf->currency)."/".strtolower($langs->trans("Unit")); - $price = $objp->unitprice; } if ($objp->unitcharges > 0 && ($conf->global->MARGIN_TYPE == "2")) { @@ -111,6 +106,8 @@ if (! empty($idprod)) } if ($objp->duration) $label .= " - ".$objp->duration; + $label = price($price).getCurrencySymbol($conf->currency)."/".strtolower($langs->trans("Unit")); + $prices[] = array("id" => $objp->idprodfournprice, "price" => price($price,0,'',0), "label" => $label, "title" => $title); $i++; } From 729a8017c32419ddb177216f8999c7160123af37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Fri, 11 Jan 2013 17:13:37 +0100 Subject: [PATCH 22/36] Added test for Adherent class functions setUserId and setThirdPartyId --- test/phpunit/AdherentTest.php | 103 ++++++++++++++++++++++++++++++++-- 1 file changed, 98 insertions(+), 5 deletions(-) diff --git a/test/phpunit/AdherentTest.php b/test/phpunit/AdherentTest.php index e6ed5ebdddb..1a613fe4845 100644 --- a/test/phpunit/AdherentTest.php +++ b/test/phpunit/AdherentTest.php @@ -139,7 +139,7 @@ class AdherentTest extends PHPUnit_Framework_TestCase /** * testAdherentFetch * - * @param int $id Id of object to fecth + * @param int $id Id of object to fetch * @return object Fetched object * * @depends testAdherentCreate @@ -225,6 +225,7 @@ class AdherentTest extends PHPUnit_Framework_TestCase $this->assertEquals($localobject->town, $newobject->town); $this->assertEquals($localobject->country_id, $newobject->country_id); $this->assertEquals('BE', $newobject->country_code); + $this->assertEquals('Belgium', $newobject->country); $this->assertEquals($localobject->statut, $newobject->statut); $this->assertEquals($localobject->phone, $newobject->phone); $this->assertEquals($localobject->phone_perso, $newobject->phone_perso); @@ -233,7 +234,8 @@ class AdherentTest extends PHPUnit_Framework_TestCase $this->assertEquals($localobject->naiss, $timestamp); $this->assertEquals($localobject->morphy, $newobject->morphy); - return $localobject; + //We return newobject because of new values + return $newobject; } /** @@ -258,8 +260,8 @@ class AdherentTest extends PHPUnit_Framework_TestCase '%NOM%,%SOCIETE%,%ADRESSE%,%CP%,%VILLE%,%PAYS%'; $expected = DOL_MAIN_URL_ROOT.','.$localobject->id.',0,New firstname,New name,New firstname New name,'. - 'New company,New address,New zip,New town,,newemail@newemail.com,'.dol_print_date($localobject->naiss,'day').',,'. - 'newlogin,dolibspec,New firstname,New name,New company,New address,New zip,New town,'; + 'New company,New address,New zip,New town,Belgium,newemail@newemail.com,'.dol_print_date($localobject->naiss,'day').',,'. + 'newlogin,dolibspec,New firstname,New name,New company,New address,New zip,New town,Belgium'; $result = $localobject->makeSubstitution($template); print __METHOD__." result=".$result."\n"; @@ -268,13 +270,104 @@ class AdherentTest extends PHPUnit_Framework_TestCase return $localobject; } + /** + * testAdherentSetUserId + * + * @param Adherent $localobject Member instance + * @return Adherent + * + * @depends testAdherentMakeSubstitution + * The depends says test is run only if previous is ok + */ + public function testAdherentSetUserId(Adherent $localobject) + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + //We associate member with user + $result = $localobject->setUserId($user->id); + print __METHOD__." id=".$localobject->id." result=".$result."\n"; + $this->assertEquals($result, 1); + + //We update user object + $user->fetch($user->id); + print __METHOD__." user id=".$user->id." fk_member=".$user->fk_member."\n"; + + $this->assertEquals($user->fk_member, $localobject->id); + + //We remove association with user + $result = $localobject->setUserId(0); + print __METHOD__." id=".$localobject->id." result=".$result."\n"; + $this->assertEquals($result, 1); + + //We update user object + $user->fetch($user->id); + print __METHOD__." user id=".$user->id." fk_member=".$user->fk_member."\n"; + + $this->assertNull($user->fk_member); + + return $localobject; + } + + /** + * testAdherentSetThirdPartyId + * + * @param Adherent $localobject Member instance + * @return Adherent + * + * @depends testAdherentSetUserId + * The depends says test is run only if previous is ok + */ + public function testAdherentSetThirdPartyId(Adherent $localobject) + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + //Create a Third Party + $thirdparty = new Societe($db); + $thirdparty->initAsSpecimen(); + $result = $thirdparty->create($user); + print __METHOD__." id=".$localobject->id." third party id=".$thirdparty->id." result=".$result."\n"; + $this->assertTrue($result > 0); + + //Set Third Party ID + $result = $localobject->setThirdPartyId($thirdparty->id); + $this->assertEquals($result, 1); + print __METHOD__." id=".$localobject->id." result=".$result."\n"; + + //Adherent is updated with new data + $localobject->fetch($localobject->id); + $this->assertEquals($localobject->fk_soc, $thirdparty->id); + print __METHOD__." id=".$localobject->id." result=".$result."\n"; + + //We remove the third party association + $result = $localobject->setThirdPartyId(0); + $this->assertEquals($result, 1); + + //And check if it has been updated + $localobject->fetch($localobject->id); + $this->assertNull($localobject->fk_soc); + + //Now we remove the third party + $result = $thirdparty->delete($thirdparty->id); + $this->assertEquals($result, 1); + + return $localobject; + } + /** * testAdherentValid * * @param Adherent $localobject Member instance * @return Adherent * - * @depends testAdherentMakeSubstitution + * @depends testAdherentSetThirdPartyId * The depends says test is run only if previous is ok */ public function testAdherentValid(Adherent $localobject) From 96c5eacf4aa669786b90b4ce6c6930a5dda8fd1b Mon Sep 17 00:00:00 2001 From: simnandez Date: Sat, 12 Jan 2013 09:58:21 +0100 Subject: [PATCH 23/36] [ task #652 ] Reduce clicks into creaton of orders, invoices, etc. --- htdocs/compta/facture.php | 164 +++++++++++++----------- htdocs/core/menus/standard/eldy.lib.php | 4 +- 2 files changed, 92 insertions(+), 76 deletions(-) diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index 75a67be6bff..adecacd40ef 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -5,7 +5,7 @@ * Copyright (C) 2005 Marc Barilley / Ocebo * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2006 Andre Cianfarani - * Copyright (C) 2010-2012 Juanjo Menent + * Copyright (C) 2010-2013 Juanjo Menent * Copyright (C) 2012 Christophe Battarel * * This program is free software; you can redistribute it and/or modify @@ -1804,7 +1804,7 @@ if ($action == 'create') print ''; // Factures predefinies - if (empty($origin) && empty($originid)) + if (empty($origin) && empty($originid) && $socid) { $sql = 'SELECT r.rowid, r.titre, r.total_ttc'; $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_rec as r'; @@ -1834,16 +1834,27 @@ if ($action == 'create') $db->free($resql); } else - { + { dol_print_error($db); } } // Tiers - print ''; + print ''; + print ''; + if($socid) + { + print ''; + } + else + { + print ''; + } print ''."\n"; // Type de facture @@ -1916,72 +1927,77 @@ if ($action == 'create') print $desc; print ''."\n"; } - - // Replacement - print ''."\n"; - - // Credit note - print ''."\n"; - - print '
'; // Define a complementary filter for search of next/prev ref. - $objectsListId = $object->getProjectsAuthorizedForUser($user,$mine,1); - $object->next_prev_filter=" rowid in (".$objectsListId.")"; + if (! $user->rights->projet->all->lire) + { + $projectsListId = $object->getProjectsAuthorizedForUser($user,$mine,0); + $object->next_prev_filter=" rowid in (".(count($projectsListId)?join(',',array_keys($projectsListId)):'0').")"; + } print $form->showrefnav($object, 'ref', $linkback, 1, 'ref', 'ref', '', $param); print '
'.$langs->trans('BuyingPrice').''.$langs->trans('BuyingCost').''.$langs->trans('CostPrice').''.$langs->trans('MarginRate').'
'.$langs->trans('Margins').''.$langs->trans('SellingPrice').''.$langs->trans('BuyingPrice').''.$langs->trans('BuyingPrice').''.$langs->trans('CostPrice').''.$langs->trans('Margin').''.$langs->trans('MarginRate').'
global->MAIN_VIEW_LINE_NUMBER) ? ' colspan="2"' : ''); ?>>
trans('AddNewLine').' - '.$langs->trans("FreeZone"); ?> -
trans('VAT'); ?>trans('PriceUHT'); ?>trans('Qty'); ?>trans('ReductionShort'); ?>trans('BuyingPrice'); ?> 
tva_assuj == "0") echo '0'; - else echo $form->load_tva('tva_tx', (isset($_POST["tva_tx"])?$_POST["tva_tx"]:-1), $seller, $buyer); - ?> - "> - ">%"> -
element) && $object->element == 'contrat') - { + + * Copyright (C) 2010-2011 Laurent Destailleur + * Copyright (C) 2012 Christophe Battarel + * + * 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 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Need to have following variables defined: + * $conf + * $langs + * $dateSelector + * $this (invoice, order, ...) + * $line defined + */ + +$usemargins=0; +if (! empty($conf->margin->enabled) && ! empty($object->element) && in_array($object->element,array('facture','propal','commande'))) $usemargins=1; + +?> + + +
global->MAIN_VIEW_LINE_NUMBER) ? ' colspan="2"' : ''); ?>>
trans('AddNewLine').' - '.$langs->trans("FreeZone"); ?> +
trans('VAT'); ?>trans('PriceUHT'); ?>trans('Qty'); ?>trans('ReductionShort'); ?> + global->MARGIN_TYPE == "1") + echo $langs->trans('BuyingPrice'); + else + echo $langs->trans('CostPrice'); + ?> +  
tva_assuj == "0") echo '0'; + else echo $form->load_tva('tva_tx', (isset($_POST["tva_tx"])?$_POST["tva_tx"]:-1), $seller, $buyer); + ?> + "> + ">%"> +
element) && $object->element == 'contrat') + { print $langs->trans("DateStartPlanned").' '; $form->select_date('',"date_start_sl",$usehm,$usehm,1,"addline_sl"); print '   '.$langs->trans("DateEndPlanned").' '; - $form->select_date('',"date_end_sl",$usehm,$usehm,1,"addline_sl"); - } - else - { - echo $langs->trans('ServiceLimitedDuration').' '.$langs->trans('From').' '; - echo $form->select_date('','date_start',$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE,$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE,1,"addproduct"); - echo ' '.$langs->trans('to').' '; - echo $form->select_date('','date_end',$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE,$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE,1,"addproduct"); - } - ?> -
trans('Qty'); ?>trans('ReductionShort'); ?>trans('BuyingPrice'); ?> 
% - - "> - - " name="addline"> -
- + + + +
trans('Qty'); ?>trans('ReductionShort'); ?> + global->MARGIN_TYPE == "1") + echo $langs->trans('BuyingPrice'); + else + echo $langs->trans('CostPrice'); + ?> +  
% + + "> + + " name="addline"> +
+ element) && $object->element == 'contrat') - { + { print $langs->trans("DateStartPlanned").' '; $form->select_date('',"date_start",$usehm,$usehm,1,"addline"); print '   '.$langs->trans("DateEndPlanned").' '; - $form->select_date('',"date_end",$usehm,$usehm,1,"addline"); - } - else + $form->select_date('',"date_end",$usehm,$usehm,1,"addline"); + } + else { - echo $langs->trans('ServiceLimitedDuration').' '.$langs->trans('From').' '; - echo $form->select_date('','date_start_predef',$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE,$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE,1,"addpredefinedproduct"); - echo ' '.$langs->trans('to').' '; - echo $form->select_date('','date_end_predef',$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE,$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE,1,"addpredefinedproduct"); - } - ?> -
'.$langs->trans('Ref').''.$langs->trans('Draft').'
'.$langs->trans('Customer').''; - print $soc->getNomUrl(1); - print ''; - print '
'.$langs->trans('Customer').''; + print $soc->getNomUrl(1); + print ''; + print ''; + print $form->select_company('','socid','s.client = 1',1); + print '
'; - print ''; - print ''; - $text=$langs->trans("InvoiceReplacementAsk").' '; - $text.=''; - $desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceReplacementDesc"),1); - print $desc; - print '
'; - print ''; - print ''; - $text=$langs->transnoentities("InvoiceAvoirAsk").' '; - // $text.=''; - $text.=''; - $desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceAvoirDesc"),1); - print $desc; - print '
'; - print ''; - - // Discounts for third party - print ''.$langs->trans('Discounts').''; - if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",''.$soc->remise_client.''); - else print $langs->trans("CompanyHasNoRelativeDiscount"); - print ' ('.$langs->trans("EditRelativeDiscount").')'; - print '. '; - print '
'; - if ($absolute_discount) print $langs->trans("CompanyHasAbsoluteDiscount",''.price($absolute_discount).'',$langs->trans("Currency".$conf->currency)); - else print $langs->trans("CompanyHasNoAbsoluteDiscount"); - print ' ('.$langs->trans("EditGlobalDiscounts").')'; - print '.'; - print ''; - + + if ($socid) + { + // Replacement + print ''; + print ''; + print ''; + $text=$langs->trans("InvoiceReplacementAsk").' '; + $text.=''; + $desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceReplacementDesc"),1); + print $desc; + print ''."\n"; + + // Credit note + print ''; + print ''; + print ''; + $text=$langs->transnoentities("InvoiceAvoirAsk").' '; + // $text.=''; + $text.=''; + $desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceAvoirDesc"),1); + print $desc; + print ''."\n"; + } + print ''; + print ''; + + if($socid) + { + // Discounts for third party + print ''.$langs->trans('Discounts').''; + if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",''.$soc->remise_client.''); + else print $langs->trans("CompanyHasNoRelativeDiscount"); + print ' ('.$langs->trans("EditRelativeDiscount").')'; + print '. '; + print '
'; + if ($absolute_discount) print $langs->trans("CompanyHasAbsoluteDiscount",''.price($absolute_discount).'',$langs->trans("Currency".$conf->currency)); + else print $langs->trans("CompanyHasNoAbsoluteDiscount"); + print ' ('.$langs->trans("EditGlobalDiscounts").')'; + print '.'; + print ''; + } + // Date invoice print ''.$langs->trans('Date').''; $form->select_date($dateinvoice,'','','','',"add",1,1); @@ -1998,7 +2014,7 @@ if ($action == 'create') print ''; // Project - if (! empty($conf->projet->enabled)) + if (! empty($conf->projet->enabled) && $socid) { $langs->load('projects'); print ''.$langs->trans('Project').''; diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 7fdff999410..51e61dfb6c9 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -1,7 +1,7 @@ * Copyright (C) 2010 Regis Houssin - * Copyright (C) 2012 Juanjo Menent + * Copyright (C) 2012-2013 Juanjo Menent * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -913,7 +913,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after) $newmenu->add("/compta/facture/list.php?leftmenu=customers_bills",$langs->trans("BillsCustomers"),0,$user->rights->facture->lire, '', $mainmenu, 'customers_bills'); if (empty($user->societe_id)) { - $newmenu->add("/compta/clients.php?action=facturer&leftmenu=customers_bills",$langs->trans("NewBill"),1,$user->rights->facture->creer); + $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); From d39368fd369bd23ea5ffad6703ebbcd85ac5c1b6 Mon Sep 17 00:00:00 2001 From: fhenry Date: Sat, 12 Jan 2013 14:02:39 +0100 Subject: [PATCH 24/36] Add boolean (checkbox) standard extrafield feature --- htdocs/core/class/extrafields.class.php | 42 +++++++++++++++++-- htdocs/core/tpl/admin_extrafields.tpl.php | 1 + htdocs/core/tpl/admin_extrafields_add.tpl.php | 1 + .../core/tpl/admin_extrafields_edit.tpl.php | 1 + htdocs/langs/en_US/admin.lang | 1 + htdocs/langs/fr_FR/admin.lang | 1 + 6 files changed, 43 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 87e3eb5dce7..b387537165b 100755 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -52,7 +52,8 @@ class ExtraFields 'int'=>'Int', 'double'=>'Float', 'date'=>'Date', - 'datetime'=>'DateAndTime' + 'datetime'=>'DateAndTime', + 'boolean'=>'Boolean' ); /** @@ -135,7 +136,14 @@ class ExtraFields if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname)) { - $field_desc = array('type'=>$type, 'value'=>$length, 'null'=>($required?'NOT NULL':'NULL')); + if ($type=='boolean') { + $typedb='int'; + $lengthdb='1'; + } else { + $typedb=$type; + $lengthdb=$length; + } + $field_desc = array('type'=>$typedb, 'value'=>$lengthdb, 'null'=>($required?'NOT NULL':'NULL')); $result=$this->db->DDLAddField(MAIN_DB_PREFIX.$table, $attrname, $field_desc); if ($result > 0) { @@ -304,7 +312,14 @@ class ExtraFields if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname)) { - $field_desc = array('type'=>$type, 'value'=>$length, 'null'=>($required?'NOT NULL':'NULL')); + if ($type=='boolean') { + $typedb='int'; + $lengthdb='1'; + } else { + $typedb=$type; + $lengthdb=$length; + } + $field_desc = array('type'=>$typedb, 'value'=>$lengthdb, 'null'=>($required?'NOT NULL':'NULL')); $result=$this->db->DDLUpdateField(MAIN_DB_PREFIX.$table, $attrname, $field_desc); if ($result > 0) { @@ -487,7 +502,7 @@ class ExtraFields function showInputField($key,$value,$moreparam='') { global $conf; - + $label=$this->attribute_label[$key]; $type =$this->attribute_type[$key]; $size =$this->attribute_size[$key]; @@ -534,6 +549,16 @@ class ExtraFields $doleditor=new DolEditor('options_'.$key,$value,'',200,'dolibarr_notes','In',false,false,! empty($conf->fckeditor->enabled) && $conf->global->FCKEDITOR_ENABLE_SOCIETE,5,100); $out=$doleditor->Create(1); } + else if ($type == 'boolean') + { + $checked=''; + if (!empty($value)) { + $checked=' checked="checked" value="1" '; + } else { + $checked=' value="1" '; + } + $out=''; + } // Add comments if ($type == 'date') $out.=' (YYYY-MM-DD)'; elseif ($type == 'datetime') $out.=' (YYYY-MM-DD HH:MM:SS)'; @@ -550,6 +575,7 @@ class ExtraFields */ function showOutputField($key,$value,$moreparam='') { + $label=$this->attribute_label[$key]; $type=$this->attribute_type[$key]; $size=$this->attribute_size[$key]; @@ -568,6 +594,14 @@ class ExtraFields { $showsize=10; } + elseif ($type == 'boolean') + { + $checked=''; + if (!empty($value)) { + $checked=' checked="checked" '; + } + $value=''; + } else { $showsize=round($size); diff --git a/htdocs/core/tpl/admin_extrafields.tpl.php b/htdocs/core/tpl/admin_extrafields.tpl.php index d8f23a4c183..f2ce0efa59b 100644 --- a/htdocs/core/tpl/admin_extrafields.tpl.php +++ b/htdocs/core/tpl/admin_extrafields.tpl.php @@ -29,6 +29,7 @@ else if (type == 'int') { size.val('10').removeAttr('disabled'); } else if (type == 'text') { size.val('2000').removeAttr('disabled'); } else if (type == 'varchar') { size.val('255').removeAttr('disabled'); } + else if (type == 'boolean') { size.val('').attr('disabled','disabled'); unique.attr('disabled','disabled');} else size.val('').attr('disabled','disabled'); } init_typeoffields(); diff --git a/htdocs/core/tpl/admin_extrafields_add.tpl.php b/htdocs/core/tpl/admin_extrafields_add.tpl.php index d28fe1c33b2..3215c235281 100644 --- a/htdocs/core/tpl/admin_extrafields_add.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_add.tpl.php @@ -31,6 +31,7 @@ else if (type == 'int') { size.val('10').removeAttr('disabled'); unique.removeAttr('disabled','disabled'); } else if (type == 'text') { size.val('2000').removeAttr('disabled'); unique.attr('disabled','disabled').removeAttr('checked'); } else if (type == 'varchar') { size.val('255').removeAttr('disabled'); unique.removeAttr('disabled','disabled'); } + else if (type == 'boolean') { size.val('').attr('disabled','disabled'); unique.attr('disabled','disabled');} else size.val('').attr('disabled','disabled'); } init_typeoffields(''); diff --git a/htdocs/core/tpl/admin_extrafields_edit.tpl.php b/htdocs/core/tpl/admin_extrafields_edit.tpl.php index d681d7cf82c..4df48df6702 100644 --- a/htdocs/core/tpl/admin_extrafields_edit.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_edit.tpl.php @@ -31,6 +31,7 @@ else if (type == 'int') { size.removeAttr('disabled'); } else if (type == 'text') { size.removeAttr('disabled'); unique.attr('disabled','disabled').removeAttr('checked'); } else if (type == 'varchar') { size.removeAttr('disabled'); } + else if (type == 'boolean') { size.val('').attr('disabled','disabled'); unique.attr('disabled','disabled');} else size.val('').attr('disabled','disabled'); } init_typeoffields(jQuery("#type").val()); diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 6007be581fc..9ecda1dbcef 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -351,6 +351,7 @@ Int=Integer Float=Float DateAndTime=Date and hour Unique=Unique +Boolean=Boolean (Checkbox) LibraryToBuildPDF=Library used to build PDF WarningUsingFPDF=Warning: Your conf.php contains directive dolibarr_pdf_force_fpdf=1. This means you use the FPDF library to generate PDF files. This library is old and does not support a lot of features (Unicode, image transparency, cyrillic, arab and asiatic languages, ...), so you may experience errors during PDF generation.
To solve this and have a full support of PDF generation, please download TCPDF library, then comment or remove the line $dolibarr_pdf_force_fpdf=1, and add instead $dolibarr_lib_TCPDF_PATH='path_to_TCPDF_dir' LocalTaxDesc=Some countries apply 2 or 3 taxes on each invoice line. If this is the case, choose type for second and third tax and its rate. Possible type are:
1 : local tax apply on products and services without vat (vat is not applied on local tax)
2 : local tax apply on products and services before vat (vat is calculated on amount + localtax)
3 : local tax apply on products without vat (vat is not applied on local tax)
4 : local tax apply on products before vat (vat is calculated on amount + localtax)
5 : local tax apply on services without vat (vat is not applied on local tax)
6 : local tax apply on services before vat (vat is calculated on amount + localtax) diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index d077ffedb4e..0effda388ec 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -346,6 +346,7 @@ TextLong=Texte long Int=Numérique entier Float=Décimal DateAndTime=Date et heure +Boolean=Booleen (Checkbox) LibraryToBuildPDF=Bibliothèque utilisée pour la génération des PDF WarningUsingFPDF=Attention: Votre fichier conf.php contient la directive dolibarr_pdf_force_fpdf=1. Cela signifie que vous utilisez la librairie FPDF pour générer vos fichiers PDF. Cette librairie est ancienne et ne couvre pas de nombreuses fonctionnalitée (Unicode, transparence des images, langues cyrillic, arabes ou asiatiques...), aussi vous pouvez rencontrez des problèmes durant la génération des PDF.
Pour résoudre cela et avoir un support complet de PDF, vous pouvez télécharger la librairie TCPDF puis commenter ou supprimer la ligne $dolibarr_pdf_force_fpdf=1, et ajouter à la place $dolibarr_lib_TCPDF_PATH='chemin_vers_TCPDF' LocalTaxDesc=Certains pays appliquent 2 voir 3 taux sur chaque ligne de facture. Si c'est le cas, choisissez le type du deuxième et troisième taux et sa valeur. Les types possibles sont:
1 : taxe locale sur les produits et services hors tva (la tva n'est pas appliquée sur la taxe locale)
2 : taxe locale sur les produits et services avant tva (la tva est appliquée sur le montant + la taxe locale)
3 : taxe locale uniquement sur les produits hors tva (la tva n'est pas appliquée sur la taxe locale)
4 : taxe locale uniquement sur les produits avant tva (la tva est appliquée sur le montant + la taxe locale)
5 : taxe locale uniquement sur les services hors tva (la tva n'est pas appliquée sur la taxe locale)
6 : taxe locale uniquement sur les service avant tva (la tva est appliquée sur le montant + la taxe locale) From aff96e50503a00f081f72a670333f8313d042629 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a?= Date: Sat, 12 Jan 2013 14:14:36 +0100 Subject: [PATCH 25/36] Added test for functions fetch_login and resiliate --- test/phpunit/AdherentTest.php | 84 ++++++++++++++++++++++++++++++----- 1 file changed, 72 insertions(+), 12 deletions(-) diff --git a/test/phpunit/AdherentTest.php b/test/phpunit/AdherentTest.php index 1a613fe4845..493783ae2eb 100644 --- a/test/phpunit/AdherentTest.php +++ b/test/phpunit/AdherentTest.php @@ -161,13 +161,38 @@ class AdherentTest extends PHPUnit_Framework_TestCase return $localobject; } + /** + * testAdherentFetchLogin + * + * @param Adherent $localobject Member instance + * @return Adherent + * + * @depends testAdherentFetch + * The depends says test is run only if previous is ok + */ + public function testAdherentFetchLogin(Adherent $localobject) + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + $newobject = new Adherent($this->savdb); + $result = $newobject->fetch_login($localobject->login); + + $this->assertEquals($newobject, $localobject); + + return $localobject; + } + /** * testAdherentUpdate * * @param Adherent $localobject Member instance * @return Adherent * - * @depends testAdherentFetch + * @depends testAdherentFetchLogin * The depends says test is run only if previous is ok */ public function testAdherentUpdate(Adherent $localobject) @@ -259,7 +284,7 @@ class AdherentTest extends PHPUnit_Framework_TestCase '%ADDRESS%,%ZIP%,%TOWN%,%COUNTRY%,%EMAIL%,%NAISS%,%PHOTO%,%LOGIN%,%PASSWORD%,%PRENOM%,'. '%NOM%,%SOCIETE%,%ADRESSE%,%CP%,%VILLE%,%PAYS%'; - $expected = DOL_MAIN_URL_ROOT.','.$localobject->id.',0,New firstname,New name,New firstname New name,'. + $expected = DOL_MAIN_URL_ROOT.','.$localobject->id.',,New firstname,New name,New firstname New name,'. 'New company,New address,New zip,New town,Belgium,newemail@newemail.com,'.dol_print_date($localobject->naiss,'day').',,'. 'newlogin,dolibspec,New firstname,New name,New company,New address,New zip,New town,Belgium'; @@ -370,7 +395,7 @@ class AdherentTest extends PHPUnit_Framework_TestCase * @depends testAdherentSetThirdPartyId * The depends says test is run only if previous is ok */ - public function testAdherentValid(Adherent $localobject) + public function testAdherentValidate(Adherent $localobject) { global $conf,$user,$langs,$db; $conf=$this->savconf; @@ -391,7 +416,7 @@ class AdherentTest extends PHPUnit_Framework_TestCase * @param Adherent $localobject Member instance * @return int Id of object * - * @depends testAdherentValid + * @depends testAdherentValidate * The depends says test is run only if previous is ok */ public function testAdherentOther(Adherent $localobject) @@ -411,19 +436,56 @@ class AdherentTest extends PHPUnit_Framework_TestCase print __METHOD__." localobject->date_creation=".$localobject->date_creation."\n"; $this->assertNotEquals($localobject->date_creation, ''); - return $localobject->id; + return $localobject; + } + + /** + * testAdherentResiliate + * + * @param Adherent $localobject Member instance + * @return Adherent + * + * @depends testAdherentOther + * The depends says test is run only if previous is ok + */ + public function testAdherentResiliate(Adherent $localobject) + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + //Let's resilie un adherent + $result = $localobject->resiliate($user); + print __METHOD__." id=".$localobject->id." result=".$result."\n"; + $this->assertEquals($result, 1); + + //Is statut updated? + $this->assertEquals($localobject->statut, 0); + + //We update the object and let's check if it was updated on DB + $localobject->fetch($localobject->id); + $this->assertEquals($localobject->statut, 0); + + //Now that status=0, resiliate should return 0 + $result = $localobject->resiliate($user); + print __METHOD__." id=".$localobject->id." result=".$result."\n"; + $this->assertEquals($result, 0); + + return $localobject; } /** * testAdherentDelete * - * @param int $id Id of object to delete + * @param Adherent $localobject Member instance * @return void * - * @depends testAdherentOther + * @depends testAdherentResiliate * The depends says test is run only if previous is ok */ - public function testAdherentDelete($id) + public function testAdherentDelete($localobject) { global $conf,$user,$langs,$db; $conf=$this->savconf; @@ -431,10 +493,8 @@ class AdherentTest extends PHPUnit_Framework_TestCase $langs=$this->savlangs; $db=$this->savdb; - $localobject=new Adherent($this->savdb); - $result=$localobject->fetch($id); - $result=$localobject->delete($id); - print __METHOD__." id=".$id." result=".$result."\n"; + $result=$localobject->delete($localobject->id); + print __METHOD__." id=".$localobject->id." result=".$result."\n"; $this->assertLessThan($result, 0); return $result; From ec8b260bf6ce7bb41a5622f2aac325390f0a3c71 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 12 Jan 2013 14:34:16 +0100 Subject: [PATCH 26/36] New: Prepare 3.4 branch New: Add hook for agenda, info and category tabs --- dev/initdata/savedemo.sh | 1 + htdocs/categories/categorie.php | 146 ++++++++++-------- htdocs/core/class/hookmanager.class.php | 6 +- htdocs/filefunc.inc.php | 2 +- htdocs/install/check.php | 5 +- .../install/mysql/migration/3.3.0-3.4.0.sql | 17 ++ htdocs/societe/agenda.php | 8 + htdocs/societe/info.php | 23 ++- 8 files changed, 133 insertions(+), 75 deletions(-) create mode 100755 htdocs/install/mysql/migration/3.3.0-3.4.0.sql diff --git a/dev/initdata/savedemo.sh b/dev/initdata/savedemo.sh index 2dd19e55fd4..dc1141f504b 100755 --- a/dev/initdata/savedemo.sh +++ b/dev/initdata/savedemo.sh @@ -188,6 +188,7 @@ export list=" --ignore-table=$base.llx_cabinetmed_examenprescrit --ignore-table=$base.llx_cabinetmed_motifcons --ignore-table=$base.llx_cabinetmed_patient + --ignore-table=$base.llx_cabinetmed_societe --ignore-table=$base.llx_publi_c_contact_list --ignore-table=$base.llx_publi_c_dnd_list --ignore-table=$base.llx_publi_c_method_list diff --git a/htdocs/categories/categorie.php b/htdocs/categories/categorie.php index 011e500eed4..61351343556 100644 --- a/htdocs/categories/categorie.php +++ b/htdocs/categories/categorie.php @@ -85,84 +85,96 @@ if ($id || $ref) if ($user->societe_id) $socid=$user->societe_id; $result = restrictedArea($user,$objecttype,$objectid,$dbtablename,'','',$fieldid); +// Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array +include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; +$hookmanager=new HookManager($db); +$hookmanager->initHooks(array('categorycard')); + /* * Actions */ -//Suppression d'un objet d'une categorie -if ($removecat > 0) +$parameters=array('id'=>$socid); +$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks +$error=$hookmanager->error; $errors=array_merge($errors, (array) $hookmanager->errors); + +if (empty($reshook)) { - if ($type==0 && ($user->rights->produit->creer || $user->rights->service->creer)) + //Suppression d'un objet d'une categorie + if ($removecat > 0) { - require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; - $object = new Product($db); - $result = $object->fetch($id, $ref); - $elementtype = 'product'; - } - if ($type==1 && $user->rights->societe->creer) - { - $object = new Societe($db); - $result = $object->fetch($objectid); - } - if ($type==2 && $user->rights->societe->creer) - { - $object = new Societe($db); - $result = $object->fetch($objectid); - } - if ($type == 3 && $user->rights->adherent->creer) - { - require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; - $object = new Adherent($db); - $result = $object->fetch($objectid); - } - $cat = new Categorie($db); - $result=$cat->fetch($removecat); + if ($type==0 && ($user->rights->produit->creer || $user->rights->service->creer)) + { + require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; + $object = new Product($db); + $result = $object->fetch($id, $ref); + $elementtype = 'product'; + } + if ($type==1 && $user->rights->societe->creer) + { + $object = new Societe($db); + $result = $object->fetch($objectid); + } + if ($type==2 && $user->rights->societe->creer) + { + $object = new Societe($db); + $result = $object->fetch($objectid); + } + if ($type == 3 && $user->rights->adherent->creer) + { + require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; + $object = new Adherent($db); + $result = $object->fetch($objectid); + } + $cat = new Categorie($db); + $result=$cat->fetch($removecat); - $result=$cat->del_type($object,$elementtype); -} + $result=$cat->del_type($object,$elementtype); + } -// Add object into a category -if ($parent > 0) -{ - if ($type==0 && ($user->rights->produit->creer || $user->rights->service->creer)) + // Add object into a category + if ($parent > 0) { - require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; - $object = new Product($db); - $result = $object->fetch($id, $ref); - $elementtype = 'product'; - } - if ($type==1 && $user->rights->societe->creer) - { - $object = new Societe($db); - $result = $object->fetch($objectid); - $elementtype = 'fournisseur'; - } - if ($type==2 && $user->rights->societe->creer) - { - $object = new Societe($db); - $result = $object->fetch($objectid); - $elementtype = 'societe'; - } - if ($type==3 && $user->rights->adherent->creer) - { - require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; - $object = new Adherent($db); - $result = $object->fetch($objectid); - $elementtype = 'member'; - } - $cat = new Categorie($db); - $result=$cat->fetch($parent); + if ($type==0 && ($user->rights->produit->creer || $user->rights->service->creer)) + { + require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; + $object = new Product($db); + $result = $object->fetch($id, $ref); + $elementtype = 'product'; + } + if ($type==1 && $user->rights->societe->creer) + { + $object = new Societe($db); + $result = $object->fetch($objectid); + $elementtype = 'fournisseur'; + } + if ($type==2 && $user->rights->societe->creer) + { + $object = new Societe($db); + $result = $object->fetch($objectid); + $elementtype = 'societe'; + } + if ($type==3 && $user->rights->adherent->creer) + { + require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; + $object = new Adherent($db); + $result = $object->fetch($objectid); + $elementtype = 'member'; + } + $cat = new Categorie($db); + $result=$cat->fetch($parent); - $result=$cat->add_type($object,$elementtype); - if ($result >= 0) - { - $mesg='
'.$langs->trans("WasAddedSuccessfully",$cat->label).'
'; - } - else - { - if ($cat->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') $mesg='
'.$langs->trans("ObjectAlreadyLinkedToCategory").'
'; - else $mesg=$langs->trans("Error").' '.$cat->error; + $result=$cat->add_type($object,$elementtype); + if ($result >= 0) + { + $mesg='
'.$langs->trans("WasAddedSuccessfully",$cat->label).'
'; + } + else + { + if ($cat->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') $mesg='
'.$langs->trans("ObjectAlreadyLinkedToCategory").'
'; + else $mesg=$langs->trans("Error").' '.$cat->error; + } } } diff --git a/htdocs/core/class/hookmanager.class.php b/htdocs/core/class/hookmanager.class.php index 91db5b31419..d18f1fafa0b 100755 --- a/htdocs/core/class/hookmanager.class.php +++ b/htdocs/core/class/hookmanager.class.php @@ -115,7 +115,7 @@ class HookManager * @param Object &$object Object to use hooks on * @param string &$action Action code on calling page ('create', 'edit', 'view', 'add', 'update', 'delete'...) * @return mixed For doActions,formObjectOptions: Return 0 if we want to keep standard actions, >0 if if want to stop standard actions, <0 means KO. - * For printSearchForm,printLeftBlock,printTopRightMenu,formAddObjectLine,...: Return HTML string. TODO Must always return an int and things to print into ->resprints. + * For printSearchForm,printLeftBlock,printTopRightMenu,formAddObjectLine,...: Return HTML string. TODO Must always return an int and things to print into ->resprints. * Can also return some values into an array ->results. * $this->error or this->errors are also defined by class called by this function if error. */ @@ -136,6 +136,8 @@ class HookManager { foreach($modules as $module => $actionclassinstance) { + //print 'class='.get_class($actionclassinstance).' method='.$method.' action='.$action; + // jump to next class if method does not exists if (! method_exists($actionclassinstance,$method)) continue; // test to avoid to run twice a hook, when a module implements several active contexts @@ -178,7 +180,7 @@ class HookManager } } - if ($method != 'doActions' && $method != 'formObjectOptions') return $this->resPrint; // TODO remove this. When there is something to print, ->resPrint is filled. + if ($method != 'doActions' && $method != 'formObjectOptions') return $this->resPrint; // TODO remove this. When there is something to print, ->resPrint is filled. return ($error?-1:$resaction); } diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index 35404140050..739a2372430 100755 --- a/htdocs/filefunc.inc.php +++ b/htdocs/filefunc.inc.php @@ -29,7 +29,7 @@ * \brief File that include conf.php file and commons lib like functions.lib.php */ -if (! defined('DOL_VERSION')) define('DOL_VERSION','3.3.0-beta'); +if (! defined('DOL_VERSION')) define('DOL_VERSION','3.4.0-alpha'); if (! defined('EURO')) define('EURO',chr(128)); // Define syslog constants diff --git a/htdocs/install/check.php b/htdocs/install/check.php index afd2ae450b3..250bbd2b049 100644 --- a/htdocs/install/check.php +++ b/htdocs/install/check.php @@ -394,8 +394,9 @@ else array('from'=>'2.9.0', 'to'=>'3.0.0'), array('from'=>'3.0.0', 'to'=>'3.1.0'), array('from'=>'3.1.0', 'to'=>'3.2.0'), - array('from'=>'3.2.0', 'to'=>'3.3.0') - ); + array('from'=>'3.2.0', 'to'=>'3.3.0'), + array('from'=>'3.3.0', 'to'=>'3.4.0') + ); $count=0; foreach ($migrationscript as $migarray) diff --git a/htdocs/install/mysql/migration/3.3.0-3.4.0.sql b/htdocs/install/mysql/migration/3.3.0-3.4.0.sql new file mode 100755 index 00000000000..0943c5aca11 --- /dev/null +++ b/htdocs/install/mysql/migration/3.3.0-3.4.0.sql @@ -0,0 +1,17 @@ +-- +-- Be carefull to requests order. +-- This file must be loaded by calling /install/index.php page +-- when current version is 3.4.0 or higher. +-- +-- To rename a table: ALTER TABLE llx_table RENAME TO llx_table_new; +-- To add a column: ALTER TABLE llx_table ADD COLUMN newcol varchar(60) NOT NULL DEFAULT '0' AFTER existingcol; +-- To rename a column: ALTER TABLE llx_table CHANGE COLUMN oldname newname varchar(60); +-- To drop a column: ALTER TABLE llx_table DROP COLUMN oldname; +-- To change type of field: ALTER TABLE llx_table MODIFY COLUMN name varchar(60); +-- To restrict request to Mysql version x.y use -- VMYSQLx.y +-- To restrict request to Pgsql version x.y use -- VPGSQLx.y + + +-- -- 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); + diff --git a/htdocs/societe/agenda.php b/htdocs/societe/agenda.php index b922db4c50d..a377f5c6e4c 100644 --- a/htdocs/societe/agenda.php +++ b/htdocs/societe/agenda.php @@ -37,11 +37,19 @@ $socid = GETPOST('socid','int'); if ($user->societe_id) $socid=$user->societe_id; $result = restrictedArea($user, 'societe', $socid, '&societe'); +// Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array +include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; +$hookmanager=new HookManager($db); +$hookmanager->initHooks(array('agendathirdparty')); + /* * Actions */ +$parameters=array('id'=>$socid); +$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks +$error=$hookmanager->error; $errors=array_merge($errors, (array) $hookmanager->errors); diff --git a/htdocs/societe/info.php b/htdocs/societe/info.php index 21d3549ed86..240fdaaf66d 100644 --- a/htdocs/societe/info.php +++ b/htdocs/societe/info.php @@ -37,12 +37,29 @@ $socid = GETPOST('socid','int'); if ($user->societe_id) $socid=$user->societe_id; $result = restrictedArea($user, 'societe', $socid, '&societe'); +// Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array +include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; +$hookmanager=new HookManager($db); +$hookmanager->initHooks(array('infothirdparty')); + + + +/* + * Actions + */ + +$parameters=array('id'=>$socid); +$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks +$error=$hookmanager->error; $errors=array_merge($errors, (array) $hookmanager->errors); + + /* -* View -*/ + * View + */ -llxHeader(); +$help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas'; +llxHeader('',$langs->trans("ThirdParty"),$help_url); $soc = new Societe($db); $soc->fetch($socid); From 2cdeb95b675c75f79417e9825f0fe637fd0515ba Mon Sep 17 00:00:00 2001 From: fhenry Date: Sat, 12 Jan 2013 15:16:38 +0100 Subject: [PATCH 27/36] Set member id on create not by sql request after. Mandatory for trigger USER_CREATE to do action if user is member --- htdocs/user/class/user.class.php | 42 +++++++++++++++++--------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 441186179b3..ef1bba983a0 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -980,6 +980,8 @@ class User extends CommonObject $this->lastname = $member->lastname; $this->firstname = $member->firstname; $this->email = $member->email; + $this->fk_member = $member->id; + if ($member->fk_soc) $sql.= ", fk_societe=".$member->fk_soc; $this->pass = $member->pass; if (empty($login)) $login=strtolower(substr($member->firstname, 0, 4)) . strtolower(substr($member->lastname, 0, 4)); @@ -992,26 +994,26 @@ class User extends CommonObject if ($result > 0) { $result=$this->setPassword($user,$this->pass); - - $sql = "UPDATE ".MAIN_DB_PREFIX."user"; - $sql.= " SET fk_member=".$member->id; - if ($member->fk_soc) $sql.= ", fk_societe=".$member->fk_soc; - $sql.= " WHERE rowid=".$this->id; - - dol_syslog(get_class($this)."::create_from_member sql=".$sql, LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - $this->db->commit(); - return $this->id; - } - else - { - $this->error=$this->db->error(); - dol_syslog(get_class($this)."::create_from_member - 1 - ".$this->error, LOG_ERR); - - $this->db->rollback(); - return -1; + if ($member->fk_soc) { + $sql = "UPDATE ".MAIN_DB_PREFIX."user"; + $sql.= " SET fk_societe=".$member->fk_soc; + $sql.= " WHERE rowid=".$this->id; + + dol_syslog(get_class($this)."::create_from_member sql=".$sql, LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $this->db->commit(); + return $this->id; + } + else + { + $this->error=$this->db->error(); + dol_syslog(get_class($this)."::create_from_member - 1 - ".$this->error, LOG_ERR); + + $this->db->rollback(); + return -1; + } } } else From 979ea42d3f3d8fe42bf8734391580d4e0ffdaeda Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 12 Jan 2013 15:40:38 +0100 Subject: [PATCH 28/36] Comments --- htdocs/adherents/class/adherent.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 065a39db3f3..e2e20f41fba 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -950,7 +950,7 @@ class Adherent extends CommonObject $this->db->begin(); - // Update link to third party + // Remove link to third party onto any other members if ($thirdpartyid > 0) { $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = null"; @@ -960,7 +960,7 @@ class Adherent extends CommonObject $resql = $this->db->query($sql); } - // Update link to third party + // Add link to third party for current member $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = ".($thirdpartyid>0 ? $thirdpartyid : 'null'); $sql.= " WHERE rowid = ".$this->id; From c9a6da610d78a5fa499b7e22e8475509c4ae8d90 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 12 Jan 2013 16:00:38 +0100 Subject: [PATCH 29/36] To allow module to use ckeditor/config.js --- htdocs/main.inc.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 28e990aa298..97d5d78f467 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -912,13 +912,15 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs print ''."\n"; // Output style sheets (optioncss='print' or ''). Note: $conf->css looks like '/theme/eldy/style.css.php' $themepath=dol_buildpath((empty($conf->global->MAIN_FORCETHEMEDIR)?'':$conf->global->MAIN_FORCETHEMEDIR).$conf->css,1); + $themesubdir=''; if (! empty($conf->modules_parts['theme'])) // This slow down { foreach($conf->modules_parts['theme'] as $reldir) { - if (file_exists(dol_buildpath($reldir.$conf->css, 0))) + if (file_exists(dol_buildpath($reldir.$conf->css, 0))) { $themepath=dol_buildpath($reldir.$conf->css, 1); + $themesubdir=$reldir; break; } } @@ -1063,7 +1065,7 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs if (constant('JS_CKEDITOR')) $pathckeditor=JS_CKEDITOR; // To use external ckeditor js lib print ''."\n"; From b1369a2f01369887e372ec6390ad7cb2f373cb55 Mon Sep 17 00:00:00 2001 From: simnandez Date: Sat, 12 Jan 2013 22:08:52 +0100 Subject: [PATCH 30/36] [ task #652 ] Reduce clicks into creaton of orders, invoices, etc. --- htdocs/compta/facture.php | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index adecacd40ef..56a8ed25c44 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -593,7 +593,8 @@ else if ($action == 'confirm_converttoreduc' && $confirm == 'yes' && $user->righ */ else if ($action == 'add' && $user->rights->facture->creer) { - $object->socid=GETPOST('socid','int'); + if ($socid>0) + $object->socid=GETPOST('socid','int'); $db->begin(); @@ -732,6 +733,12 @@ else if ($action == 'add' && $user->rights->facture->creer) // Standard or deposit or proforma invoice if (($_POST['type'] == 0 || $_POST['type'] == 3 || $_POST['type'] == 4) && $_POST['fac_rec'] <= 0) { + if (GETPOST('socid','int')<1) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Customer")),'errors'); + } + $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); if (empty($datefacture)) { @@ -1727,7 +1734,7 @@ if ($action == 'create') print_fiche_titre($langs->trans('NewBill')); $soc = new Societe($db); - if ($socid) $res=$soc->fetch($socid); + if ($socid>1) $res=$soc->fetch($socid); if (! empty($origin) && ! empty($originid)) { @@ -1804,7 +1811,7 @@ if ($action == 'create') print ''.$langs->trans('Ref').''.$langs->trans('Draft').''; // Factures predefinies - if (empty($origin) && empty($originid) && $socid) + if (empty($origin) && empty($originid) && $socid>1) { $sql = 'SELECT r.rowid, r.titre, r.total_ttc'; $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_rec as r'; @@ -1842,7 +1849,7 @@ if ($action == 'create') // Tiers print ''; print ''.$langs->trans('Customer').''; - if($socid) + if($socid>1) { print ''; print $soc->getNomUrl(1); @@ -1928,7 +1935,7 @@ if ($action == 'create') print ''."\n"; } - if ($socid) + if ($socid>1) { // Replacement print ''; @@ -1982,7 +1989,7 @@ if ($action == 'create') print ''; print ''; - if($socid) + if($socid>1) { // Discounts for third party print ''.$langs->trans('Discounts').''; @@ -2014,7 +2021,7 @@ if ($action == 'create') print ''; // Project - if (! empty($conf->projet->enabled) && $socid) + if (! empty($conf->projet->enabled) && $socid>1) { $langs->load('projects'); print ''.$langs->trans('Project').''; From ffbb611eb4cb2035b262a935c9dd80f77d0f8946 Mon Sep 17 00:00:00 2001 From: simnandez Date: Sun, 13 Jan 2013 10:57:39 +0100 Subject: [PATCH 31/36] [ task #652 ] Reduce clicks into creaton of orders, invoices, etc. --- htdocs/compta/facture.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index 56a8ed25c44..2c4bbf372a0 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -1734,7 +1734,7 @@ if ($action == 'create') print_fiche_titre($langs->trans('NewBill')); $soc = new Societe($db); - if ($socid>1) $res=$soc->fetch($socid); + if ($socid>0) $res=$soc->fetch($socid); if (! empty($origin) && ! empty($originid)) { @@ -1811,7 +1811,7 @@ if ($action == 'create') print ''.$langs->trans('Ref').''.$langs->trans('Draft').''; // Factures predefinies - if (empty($origin) && empty($originid) && $socid>1) + if (empty($origin) && empty($originid) && $socid>0) { $sql = 'SELECT r.rowid, r.titre, r.total_ttc'; $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_rec as r'; @@ -1849,7 +1849,7 @@ if ($action == 'create') // Tiers print ''; print ''.$langs->trans('Customer').''; - if($socid>1) + if($socid>0) { print ''; print $soc->getNomUrl(1); @@ -1935,7 +1935,7 @@ if ($action == 'create') print ''."\n"; } - if ($socid>1) + if ($socid>0) { // Replacement print ''; @@ -1989,7 +1989,7 @@ if ($action == 'create') print ''; print ''; - if($socid>1) + if($socid>0) { // Discounts for third party print ''.$langs->trans('Discounts').''; @@ -2021,7 +2021,7 @@ if ($action == 'create') print ''; // Project - if (! empty($conf->projet->enabled) && $socid>1) + if (! empty($conf->projet->enabled) && $socid>0) { $langs->load('projects'); print ''.$langs->trans('Project').''; From 1d95c68a74a495a0e399f6229ba79f265484b454 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 13 Jan 2013 14:38:05 +0100 Subject: [PATCH 32/36] Update 2013 --- build/exe/doliwamp/doliwamp.iss | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/build/exe/doliwamp/doliwamp.iss b/build/exe/doliwamp/doliwamp.iss index 1dd37f24700..4aebbdb0814 100644 --- a/build/exe/doliwamp/doliwamp.iss +++ b/build/exe/doliwamp/doliwamp.iss @@ -22,8 +22,7 @@ AppVerName=DoliWamp-3.3.0-beta OutputBaseFilename=DoliWamp-3.3.0-beta ; Define full path from wich all relative path are defined ; You must modify this to put here your dolibarr root directory -;SourceDir=C:\Documents and Settings\ldestailleur\git\dolibarr_old -;SourceDir=Z:\home\ldestailleur\git\dolibarr_veryold +;SourceDir=Z:\home\ldestailleur\git\dolibarrxxx SourceDir=..\..\.. ; ----- End of change ;OutputManifestFile=build\doliwampbuild.log @@ -33,7 +32,7 @@ AppPublisherURL=http://www.nltechno.com AppSupportURL=http://www.dolibarr.org AppUpdatesURL=http://www.dolibarr.org AppComments=DoliWamp includes Dolibarr, Apache, PHP and Mysql softwares. -AppCopyright=Copyright (C) 2008-2012 Laurent Destailleur, NLTechno +AppCopyright=Copyright (C) 2008-2013 Laurent Destailleur, NLTechno DefaultDirName=c:\dolibarr DefaultGroupName=Dolibarr ;LicenseFile=COPYING @@ -88,12 +87,12 @@ Name: "{app}\bin\apache\apache2.2.11\logs" ; Stop/start Source: "build\exe\doliwamp\stopdoliwamp.bat"; DestDir: "{app}\"; Flags: ignoreversion; AfterInstall: close() Source: "build\exe\doliwamp\startdoliwamp.bat"; DestDir: "{app}\"; Flags: ignoreversion; +Source: "build\exe\doliwamp\install_services.bat.install"; DestDir: "{app}\"; Flags: ignoreversion; +Source: "build\exe\doliwamp\uninstall_services.bat.install"; DestDir: "{app}\"; Flags: ignoreversion; Source: "build\exe\doliwamp\removefiles.bat"; DestDir: "{app}\"; Flags: ignoreversion; Source: "build\exe\doliwamp\rundoliwamp.bat.install"; DestDir: "{app}\"; Flags: ignoreversion; Source: "build\exe\doliwamp\rundolihelp.bat.install"; DestDir: "{app}\"; Flags: ignoreversion; Source: "build\exe\doliwamp\rundoliadmin.bat.install"; DestDir: "{app}\"; Flags: ignoreversion; -Source: "build\exe\doliwamp\install_services.bat.install"; DestDir: "{app}\"; Flags: ignoreversion; -Source: "build\exe\doliwamp\uninstall_services.bat.install"; DestDir: "{app}\"; Flags: ignoreversion; Source: "build\exe\doliwamp\mysqlinitpassword.bat.install"; DestDir: "{app}\"; Flags: ignoreversion; Source: "build\exe\doliwamp\mysqltestinstall.bat.install"; DestDir: "{app}\"; Flags: ignoreversion; Source: "build\exe\doliwamp\startdoliwamp_manual_donotuse.bat.install"; DestDir: "{app}\"; Flags: ignoreversion; From 0f6506d4574e08b82327c88f707749fbfafd07e0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 13 Jan 2013 18:53:52 +0100 Subject: [PATCH 33/36] Fix: not object error with option SERVICE_ARE_ECOMMERCE_200238EC --- htdocs/core/class/html.form.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 6cf1f3aff41..8ff1f5706bf 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -3181,19 +3181,19 @@ class Form //print "name=$name, selectedrate=$selectedrate, seller=".$societe_vendeuse->country_code." buyer=".$societe_acheteuse->country_code." buyer is company=".$societe_acheteuse->isACompany()." idprod=$idprod, info_bits=$info_bits type=$type"; //exit; - // Get list of all VAT rates to show + // Define list of countries to use to search VAT rates to show // First we defined code_pays to use to find list if (is_object($societe_vendeuse)) { $code_pays="'".$societe_vendeuse->country_code."'"; } else - { + { $code_pays="'".$mysoc->country_code."'"; // Pour compatibilite ascendente } if (! empty($conf->global->SERVICE_ARE_ECOMMERCE_200238EC)) // If option to have vat for end customer for services is on { - if (! $societe_vendeuse->isInEEC() && $societe_acheteuse->isInEEC() && ! $societe_acheteuse->isACompany()) + if (! $societe_vendeuse->isInEEC() && (! is_object($societe_acheteuse) || ($societe_acheteuse->isInEEC() && ! $societe_acheteuse->isACompany()))) { // We also add the buyer if (is_numeric($type)) From ff24a7df6706036933e3901a870bdc891a83a909 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 13 Jan 2013 19:34:43 +0100 Subject: [PATCH 34/36] New: Add script to detect DOS (non Linux) files. --- dev/finddosfiles.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100755 dev/finddosfiles.sh diff --git a/dev/finddosfiles.sh b/dev/finddosfiles.sh new file mode 100755 index 00000000000..f77859ba1ea --- /dev/null +++ b/dev/finddosfiles.sh @@ -0,0 +1,15 @@ +#!/bin/sh +#------------------------------------------------------ +# Script to find files that are not Unix encoded +# +# Laurent Destailleur - eldy@users.sourceforge.net +#------------------------------------------------------ +# Usage: finddosfiles.sh +#------------------------------------------------------ + +# To detec +find . -type f -iname "*.php" -exec file "{}" + | grep CRLF + +# To convert +#find . -type f -iname "*.php" -exec dos2unix "{}" +; + From b9c53fd796a790a3dc7df88864d8e8796d4ed2a8 Mon Sep 17 00:00:00 2001 From: fhenry Date: Sun, 13 Jan 2013 20:50:54 +0100 Subject: [PATCH 35/36] remove dummy line --- htdocs/user/class/user.class.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index ef1bba983a0..6ae0315c143 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -981,7 +981,6 @@ class User extends CommonObject $this->firstname = $member->firstname; $this->email = $member->email; $this->fk_member = $member->id; - if ($member->fk_soc) $sql.= ", fk_societe=".$member->fk_soc; $this->pass = $member->pass; if (empty($login)) $login=strtolower(substr($member->firstname, 0, 4)) . strtolower(substr($member->lastname, 0, 4)); From cf12815ca9afcba7bb8690ac80ea8ebb57a4402a Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Mon, 14 Jan 2013 09:39:35 +0100 Subject: [PATCH 36/36] Fix: phpunit error --- test/phpunit/AdherentTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/phpunit/AdherentTest.php b/test/phpunit/AdherentTest.php index 493783ae2eb..03be97ecec2 100644 --- a/test/phpunit/AdherentTest.php +++ b/test/phpunit/AdherentTest.php @@ -284,7 +284,7 @@ class AdherentTest extends PHPUnit_Framework_TestCase '%ADDRESS%,%ZIP%,%TOWN%,%COUNTRY%,%EMAIL%,%NAISS%,%PHOTO%,%LOGIN%,%PASSWORD%,%PRENOM%,'. '%NOM%,%SOCIETE%,%ADRESSE%,%CP%,%VILLE%,%PAYS%'; - $expected = DOL_MAIN_URL_ROOT.','.$localobject->id.',,New firstname,New name,New firstname New name,'. + $expected = DOL_MAIN_URL_ROOT.','.$localobject->id.',0,New firstname,New name,New firstname New name,'. 'New company,New address,New zip,New town,Belgium,newemail@newemail.com,'.dol_print_date($localobject->naiss,'day').',,'. 'newlogin,dolibspec,New firstname,New name,New company,New address,New zip,New town,Belgium'; @@ -320,7 +320,7 @@ class AdherentTest extends PHPUnit_Framework_TestCase //We update user object $user->fetch($user->id); print __METHOD__." user id=".$user->id." fk_member=".$user->fk_member."\n"; - + $this->assertEquals($user->fk_member, $localobject->id); //We remove association with user