diff --git a/ChangeLog b/ChangeLog index 239686a449a..fe7db57ccf4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,7 @@ For users: - New: task #10113 : Show list of emailing on clicking on "number of mass emailing received" - New: Add default language for third parties and use it when multilang is enabled to define default language for document generation. +- New: Can reopen a closed supplier invoice. - Fix: Formant number as wrong for ar_AR language. For developers: diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php index d603367ef37..6705587a024 100644 --- a/htdocs/comm/propal.php +++ b/htdocs/comm/propal.php @@ -1,6 +1,6 @@ - * Copyright (C) 2004-2009 Laurent Destailleur + * Copyright (C) 2004-2010 Laurent Destailleur * Copyright (C) 2004 Eric Seigne * Copyright (C) 2005 Marc Barilley / Ocebo * Copyright (C) 2005-2009 Regis Houssin @@ -24,7 +24,7 @@ /** * \file htdocs/comm/propal.php * \ingroup propale - * \brief Page liste des propales (vision commercial) + * \brief Page of commercial proposals card and list * \version $Id$ */ @@ -162,10 +162,13 @@ if ($_REQUEST['action'] == 'confirm_validate' && $_REQUEST['confirm'] == 'yes' & if ($result >= 0) { $outputlangs = $langs; - if (! empty($_REQUEST['lang_id'])) + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$propal->client->default_lang; + if (! empty($newlang)) { $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($_REQUEST['lang_id']); + $outputlangs->setDefaultLang($newlang); } propale_pdf_create($db, $propal->id, $propal->modelpdf, $outputlangs); } diff --git a/htdocs/facture.class.php b/htdocs/facture.class.php index 2fe47ed0935..542515235b7 100644 --- a/htdocs/facture.class.php +++ b/htdocs/facture.class.php @@ -1113,16 +1113,19 @@ class Facture extends CommonObject /** * \brief Tag la facture comme paye completement (close_code non renseigne) ou partiellement (close_code renseigne) + appel trigger BILL_PAYED * \param user Objet utilisateur qui modifie - * \param close_code Code renseigne si on classe a payee completement alors que paiement incomplet (cas ecompte par exemple) - * \param close_note Commentaire renseigne si on classe a payee alors que paiement incomplet (cas ecompte par exemple) - * \return int <0 si ok, >0 si ok + * \param close_code Code renseigne si on classe a payee completement alors que paiement incomplet (cas ecompte par exemple) + * \param close_note Commentaire renseigne si on classe a payee alors que paiement incomplet (cas ecompte par exemple) + * \return int <0 si ok, >0 si ok */ function set_paid($user,$close_code='',$close_note='') { global $conf,$langs; + $error=0; if ($this->paye != 1) { + $this->db->begin(); + dol_syslog("Facture::set_paid rowid=".$this->id, LOG_DEBUG); $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture SET'; $sql.= ' fk_statut=2'; @@ -1143,8 +1146,23 @@ class Facture extends CommonObject if ($result < 0) { $error++; $this->errors=$interface->errors; } // Fin appel triggers } + else + { + $error++; + $this->error=$this->db->error(); + dol_print_error($this->db); + } - return 1; + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } } else { @@ -1163,8 +1181,10 @@ class Facture extends CommonObject function set_unpaid($user) { global $conf,$langs; + $error=0; + + $this->db->begin(); - dol_syslog("Facture::set_unpaid rowid=".$this->id, LOG_DEBUG); $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture'; $sql.= ' SET paye=0, fk_statut=1, close_code=null, close_note=null'; $sql.= ' WHERE rowid = '.$this->id; @@ -1182,18 +1202,33 @@ class Facture extends CommonObject if ($result < 0) { $error++; $this->errors=$interface->errors; } // Fin appel triggers } + else + { + $error++; + $this->error=$this->db->error(); + dol_print_error($this->db); + } - return 1; + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } } /** - \brief Tag la facture comme abandonnee, sans paiement dessus (exemple car facture de remplacement) + appel trigger BILL_CANCEL - \param user Objet utilisateur qui modifie - \param close_code Code de fermeture - \param close_note Commentaire de fermeture - \return int <0 si ok, >0 si ok - */ + * \brief Tag la facture comme abandonnee, sans paiement dessus (exemple car facture de remplacement) + appel trigger BILL_CANCEL + * \param user Objet utilisateur qui modifie + * \param close_code Code de fermeture + * \param close_note Commentaire de fermeture + * \return int <0 si ok, >0 si ok + */ function set_canceled($user,$close_code='',$close_note='') { global $conf,$langs; diff --git a/htdocs/fourn/facture/fiche.php b/htdocs/fourn/facture/fiche.php index 4400530015a..40819b26494 100644 --- a/htdocs/fourn/facture/fiche.php +++ b/htdocs/fourn/facture/fiche.php @@ -445,6 +445,27 @@ if ($_GET['action'] == 'edit' && $user->rights->fournisseur->facture->creer) } } +if ($_GET['action'] == 'reopen' && $user->rights->fournisseur->facture->creer) +{ + $fac = new FactureFournisseur($db); + $result = $fac->fetch($_GET['facid']); + if ($fac->statut == 2 + || ($fac->statut == 3 && $fac->close_code != 'replaced')) + { + $result = $fac->set_unpaid($user); + if ($result > 0) + { + Header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$_GET['facid']); + exit; + } + else + { + $mesg='
'.$fac->error.'
'; + } + } +} + + /* @@ -1165,6 +1186,20 @@ else print '
'; + // Reopen a standard paid invoice + if ($fac->type == 1 && $fac->statut == 2) // A paid invoice (partially or completely) + { + print ''.$langs->trans('ReOpen').''; + } + + // Reopen a classified invoice + if (($fac->statut == 2 || $fac->statut == 3) && // Closed invoice + $fac->getIdReplacingInvoice() == 0 && // Not replaced by another invoice + $fac->close_code != 'replaced') // Not replaced by another invoice + { + print ''.$langs->trans('ReOpen').''; + } + if ($_GET['action'] != 'edit' && $fac->statut <= 1 && $fac->getSommePaiement() <= 0 && $user->rights->fournisseur->facture->creer) { print ''.$langs->trans('Modify').''; diff --git a/htdocs/fourn/fournisseur.facture.class.php b/htdocs/fourn/fournisseur.facture.class.php index 55862271bb5..b05f95cfd0d 100644 --- a/htdocs/fourn/fournisseur.facture.class.php +++ b/htdocs/fourn/fournisseur.facture.class.php @@ -52,9 +52,9 @@ class FactureFournisseur extends Facture //! 0=Standard invoice, 1=Replacement invoice, 2=Credit note invoice, 3=Deposit invoice, 4=Proformat invoice var $type; //! 0=draft, - //! 1=validated, - //! TODO Ce statut doit etre 2 et non 1 classee payee partiellement (close_code='discount_vat','badcustomer') ou completement (close_code=null), - //! TODO Ce statut doit etre 2 et non 1 classee abandonnee et aucun paiement n'a eu lieu (close_code='badcustomer','abandon' ou 'replaced') + //! 1=validated + //! 2=classified paid partially (close_code='discount_vat','badcustomer') or completely (close_code=null), + //! Also 2, should be 3=classified abandoned and no payment done (close_code='badcustomer','abandon' ou 'replaced') var $statut; //! 1 si facture payee COMPLETEMENT, 0 sinon (ce champ ne devrait plus servir car insuffisant) var $paye; @@ -419,10 +419,10 @@ class FactureFournisseur extends Facture { if ($user->rights->fournisseur->facture->creer) { - dol_syslog('FactureFournisseur::set_ref_supplier this->id='.$this->id.', ref_supplier='.$ref_supplier); - $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture_fourn SET facnumber = '.(empty($ref_supplier) ? 'NULL' : '\''.addslashes($ref_supplier).'\''); $sql.= ' WHERE rowid = '.$this->id; + + dol_syslog("FactureFournisseur::set_ref_supplier sql=".$sql); if ($this->db->query($sql)) { $this->ref_supplier = $ref_supplier; @@ -448,21 +448,99 @@ class FactureFournisseur extends Facture */ function set_paid($user) { + global $conf,$langs; + $error=0; + + $this->db->begin(); + $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture_fourn'; - $sql.= ' SET paye = 1'; + $sql.= ' SET paye = 1, fk_statut=2'; $sql.= ' WHERE rowid = '.$this->id; + dol_syslog("FactureFournisseur::set_paid sql=".$sql); $resql = $this->db->query($sql); - if (! $resql) + if ($resql) { + $this->use_webcal=($conf->global->PHPWEBCALENDAR_BILLSTATUS=='always'?1:0); + + // Appel des triggers + include_once(DOL_DOCUMENT_ROOT . "/interfaces.class.php"); + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('BILL_SUPPLIER_PAYED',$this,$user,$langs,$conf); + if ($result < 0) { $error++; $this->errors=$interface->errors; } + // Fin appel triggers + } + else + { + $error++; $this->error=$this->db->error(); dol_print_error($this->db); + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); return -1; } - return 1; } + /** + * \brief Tag la facture comme non payee completement + appel trigger BILL_UNPAYED + * Fonction utilisee quand un paiement prelevement est refuse, + * ou quand une facture annulee et reouverte. + * \param user Object user that change status + * \return int <0 si ok, >0 si ok + */ + function set_unpaid($user) + { + global $conf,$langs; + $error=0; + + $this->db->begin(); + + dol_syslog("FactureFournisseur::set_unpaid rowid=".$this->id, LOG_DEBUG); + $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture_fourn'; + $sql.= ' SET paye=0, fk_statut=1, close_code=null, close_note=null'; + $sql.= ' WHERE rowid = '.$this->id; + + dol_syslog("FactureFournisseur::set_unpaid sql=".$sql); + $resql = $this->db->query($sql); + if ($resql) + { + $this->use_webcal=($conf->global->PHPWEBCALENDAR_BILLSTATUS=='always'?1:0); + + // Appel des triggers + include_once(DOL_DOCUMENT_ROOT . "/interfaces.class.php"); + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('BILL_SUPPLIER_UNPAYED',$this,$user,$langs,$conf); + if ($result < 0) { $error++; $this->errors=$interface->errors; } + // Fin appel triggers + } + else + { + $error++; + $this->error=$this->db->error(); + dol_print_error($this->db); + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + /** * \brief Set invoice status as validated * \param user Object user @@ -487,7 +565,7 @@ class FactureFournisseur extends Facture $sql.= " SET fk_statut = 1, fk_user_valid = ".$user->id; $sql.= " WHERE rowid = ".$this->id; - dol_syslog("FactureFournisseur::set_valid sql=".$sql, LOG_DEBUG); + dol_syslog("FactureFournisseur::set_valid sql=".$sql); $resql = $this->db->query($sql); if ($resql) { diff --git a/htdocs/install/mysql/migration/2.8.0-2.9.0.sql b/htdocs/install/mysql/migration/2.8.0-2.9.0.sql index 0fdab5ea9ac..a4962cd1631 100755 --- a/htdocs/install/mysql/migration/2.8.0-2.9.0.sql +++ b/htdocs/install/mysql/migration/2.8.0-2.9.0.sql @@ -22,3 +22,8 @@ alter table llx_mailing add column joined_file1 varchar(255); alter table llx_mailing add column joined_file2 varchar(255); alter table llx_mailing add column joined_file3 varchar(255); alter table llx_mailing add column joined_file4 varchar(255); + +update llx_facture_fourn set fk_statut=2 where fk_statut=1 AND paye=1; + +alter table llx_facture_fourn add column close_code varchar(16) after remise; +alter table llx_facture_fourn add column close_note varchar(128) after close_code; diff --git a/htdocs/install/mysql/tables/llx_facture_fourn.sql b/htdocs/install/mysql/tables/llx_facture_fourn.sql index c7ddcd98a7e..1a9e6abe853 100644 --- a/htdocs/install/mysql/tables/llx_facture_fourn.sql +++ b/htdocs/install/mysql/tables/llx_facture_fourn.sql @@ -35,6 +35,10 @@ create table llx_facture_fourn paye smallint DEFAULT 0 NOT NULL, amount double(24,8) DEFAULT 0 NOT NULL, remise double(24,8) DEFAULT 0, + + close_code varchar(16), -- Code motif cloture sans paiement complet + close_note varchar(128), -- Commentaire cloture sans paiement complet + tva double(24,8) DEFAULT 0, total double(24,8) DEFAULT 0, total_ht double(24,8) DEFAULT 0,