| '.$form->editfieldkey("Date",'datep',$object->date,$object,$user->rights->facture->paiement).' | ';
diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php
index 7e92a608c52..45c9d0b526b 100644
--- a/htdocs/compta/paiement/class/paiement.class.php
+++ b/htdocs/compta/paiement/class/paiement.class.php
@@ -4,7 +4,8 @@
* Copyright (C) 2005 Marc Barilley / Ocebo
* Copyright (C) 2012 Cédric Salvador
* Copyright (C) 2014 Raphaël Doursenaud
- * Copyright (C) 2014 Marcos García
+ * Copyright (C) 2014 Marcos García
+ * Copyright (C) 2015 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
@@ -81,7 +82,7 @@ class Paiement extends CommonObject
*/
function fetch($id, $ref='', $fk_bank='')
{
- $sql = 'SELECT p.rowid, p.datep as dp, p.amount, p.statut, p.fk_bank,';
+ $sql = 'SELECT p.rowid, p.ref, p.datep as dp, p.amount, p.statut, p.fk_bank,';
$sql.= ' c.code as type_code, c.libelle as type_libelle,';
$sql.= ' p.num_paiement, p.note,';
$sql.= ' b.fk_account';
@@ -104,7 +105,7 @@ class Paiement extends CommonObject
{
$obj = $this->db->fetch_object($result);
$this->id = $obj->rowid;
- $this->ref = $obj->rowid;
+ $this->ref = $obj->ref;
$this->date = $this->db->jdate($obj->dp);
$this->datepaye = $this->db->jdate($obj->dp);
$this->numero = $obj->num_paiement;
@@ -173,8 +174,10 @@ class Paiement extends CommonObject
$this->db->begin();
- $sql = "INSERT INTO ".MAIN_DB_PREFIX."paiement (entity, datec, datep, amount, fk_paiement, num_paiement, note, fk_user_creat)";
- $sql.= " VALUES (".$conf->entity.", '".$this->db->idate($now)."', '".$this->db->idate($this->datepaye)."', '".$totalamount."', ".$this->paiementid.", '".$this->num_paiement."', '".$this->db->escape($this->note)."', ".$user->id.")";
+ $ref = $this->getNextNumRef('');
+
+ $sql = "INSERT INTO ".MAIN_DB_PREFIX."paiement (entity, ref, datec, datep, amount, fk_paiement, num_paiement, note, fk_user_creat)";
+ $sql.= " VALUES (".$conf->entity.", '".$ref."', '". $this->db->idate($now)."', '".$this->db->idate($this->datepaye)."', '".$totalamount."', ".$this->paiementid.", '".$this->num_paiement."', '".$this->db->escape($this->note)."', ".$user->id.")";
dol_syslog(get_class($this)."::Create insert paiement", LOG_DEBUG);
$resql = $this->db->query($sql);
@@ -773,6 +776,116 @@ class Paiement extends CommonObject
}
}
+ /**
+ * Return next reference of customer invoice not already used (or last reference)
+ * according to numbering module defined into constant FACTURE_ADDON
+ *
+ * @param Societe $soc object company
+ * @param string $mode 'next' for next value or 'last' for last value
+ * @return string free ref or last ref
+ */
+ function getNextNumRef($soc,$mode='next')
+ {
+ global $conf, $db, $langs;
+ $langs->load("bills");
+
+ // Clean parameters (if not defined or using deprecated value)
+ if (empty($conf->global->PAYMENT_ADDON)) $conf->global->PAYMENT_ADDON='mod_payment_cicada';
+ else if ($conf->global->PAYMENT_ADDON=='ant') $conf->global->PAYMENT_ADDON='mod_payment_ant';
+ else if ($conf->global->PAYMENT_ADDON=='cicada') $conf->global->PAYMENT_ADDON='mod_payment_cicada';
+
+ if (! empty($conf->global->PAYMENT_ADDON))
+ {
+ $mybool=false;
+
+ $file = $conf->global->PAYMENT_ADDON.".php";
+ $classname = $conf->global->PAYMENT_ADDON;
+
+ // Include file with class
+ $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
+
+ foreach ($dirmodels as $reldir) {
+
+ $dir = dol_buildpath($reldir."core/modules/payment/");
+
+ // Load file with numbering class (if found)
+ if (is_file($dir.$file) && is_readable($dir.$file))
+ {
+ $mybool |= include_once $dir . $file;
+ }
+ }
+
+ // For compatibility
+ if (! $mybool)
+ {
+ $file = $conf->global->PAYMENT_ADDON.".php";
+ $classname = "mod_payment_".$conf->global->PAYMENT_ADDON;
+ $classname = preg_replace('/\-.*$/','',$classname);
+ // Include file with class
+ foreach ($conf->file->dol_document_root as $dirroot)
+ {
+ $dir = $dirroot."/core/modules/payment/";
+
+ // Load file with numbering class (if found)
+ if (is_file($dir.$file) && is_readable($dir.$file)) {
+ $mybool |= include_once $dir . $file;
+ }
+ }
+ }
+
+ if (! $mybool)
+ {
+ dol_print_error('',"Failed to include file ".$file);
+ return '';
+ }
+
+ $obj = new $classname();
+ $numref = "";
+ $numref = $obj->getNextValue($soc,$this);
+
+ /**
+ * $numref can be empty in case we ask for the last value because if there is no invoice created with the
+ * set up mask.
+ */
+ if ($mode != 'last' && !$numref) {
+ dol_print_error($db,"Payment::getNextNumRef ".$obj->error);
+ return "";
+ }
+
+ return $numref;
+ }
+ else
+ {
+ $langs->load("errors");
+ print $langs->trans("Error")." ".$langs->trans("ErrorModuleSetupNotComplete");
+ return "";
+ }
+ }
+
+ /**
+ * Initialise an instance with random values.
+ * Used to build previews or test instances.
+ * id must be 0 if object instance is a specimen.
+ *
+ * @param string $option ''=Create a specimen invoice with lines, 'nolines'=No lines
+ * @return void
+ */
+ function initAsSpecimen($option='')
+ {
+ global $user,$langs,$conf;
+
+ $now=dol_now();
+ $arraynow=dol_getdate($now);
+ $nownotime=dol_mktime(0, 0, 0, $arraynow['mon'], $arraynow['mday'], $arraynow['year']);
+
+ // Initialize parameters
+ $this->id=0;
+ $this->ref = 'SPECIMEN';
+ $this->specimen=1;
+ $this->facid = 1;
+ $this->datepaye = $nownotime;
+ }
+
/**
* Return clicable name (with picto eventually)
diff --git a/htdocs/compta/paiement/list.php b/htdocs/compta/paiement/list.php
index c688ca780d4..8231f607ef7 100644
--- a/htdocs/compta/paiement/list.php
+++ b/htdocs/compta/paiement/list.php
@@ -4,6 +4,7 @@
* Copyright (C) 2005-2009 Regis Houssin
* Copyright (C) 2013 Cédric Salvador
* Copyright (C) 2015 Jean-François Ferry
+ * Copyright (C) 2015 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
@@ -95,7 +96,7 @@ $formother=new FormOther($db);
if (GETPOST("orphelins"))
{
// Paiements lies a aucune facture (pour aide au diagnostic)
- $sql = "SELECT p.rowid, p.datep as dp, p.amount,";
+ $sql = "SELECT p.rowid, p.ref, p.datep as dp, p.amount,";
$sql.= " p.statut, p.num_paiement,";
$sql.= " c.code as paiement_code";
// Add fields for extrafields
@@ -117,7 +118,7 @@ if (GETPOST("orphelins"))
}
else
{
- $sql = "SELECT DISTINCT p.rowid, p.datep as dp, p.amount,"; // DISTINCT is to avoid duplicate when there is a link to sales representatives
+ $sql = "SELECT DISTINCT p.rowid, p.ref, p.datep as dp, p.amount,"; // DISTINCT is to avoid duplicate when there is a link to sales representatives
$sql.= " p.statut, p.num_paiement,";
$sql.= " c.code as paiement_code,";
$sql.= " ba.rowid as bid, ba.label,";
@@ -164,7 +165,7 @@ else
{
$sql.= " AND p.datep BETWEEN '".$db->idate(dol_get_first_day($year,1,false))."' AND '".$db->idate(dol_get_last_day($year,12,false))."'";
}
- if ($search_ref > 0) $sql .=" AND p.rowid=".$search_ref;
+ if ($search_ref) $sql .=natural_search('p.ref', $search_ref);
if ($search_account > 0) $sql .=" AND b.fk_account=".$search_account;
if ($search_paymenttype != "") $sql .=" AND c.code='".$db->escape($search_paymenttype)."'";
if ($search_amount) $sql .=" AND p.amount='".$db->escape(price2num($search_amount))."'";
@@ -253,7 +254,7 @@ if ($resql)
print '| ';
$paymentstatic->id=$objp->rowid;
- $paymentstatic->ref=$objp->rowid;
+ $paymentstatic->ref=$objp->ref;
print $paymentstatic->getNomUrl(1);
print ' | ';
diff --git a/htdocs/core/lib/invoice.lib.php b/htdocs/core/lib/invoice.lib.php
index ac9da88bdc2..be73dd12b37 100644
--- a/htdocs/core/lib/invoice.lib.php
+++ b/htdocs/core/lib/invoice.lib.php
@@ -2,6 +2,7 @@
/* Copyright (C) 2005-2012 Laurent Destailleur
* Copyright (C) 2005-2012 Regis Houssin
* Copyright (C) 2013 Florian Henry
+ * Copyright (C) 2015 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
@@ -120,6 +121,11 @@ function invoice_admin_prepare_head()
$head[$h][2] = 'general';
$h++;
+ $head[$h][0] = DOL_URL_ROOT.'/admin/payment.php';
+ $head[$h][1] = $langs->trans("Payments");
+ $head[$h][2] = 'payment';
+ $h++;
+
// Show more tabs from modules
// Entries must be declared in modules descriptor with line
// $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
diff --git a/htdocs/core/modules/payment/mod_payment_ant.php b/htdocs/core/modules/payment/mod_payment_ant.php
new file mode 100644
index 00000000000..a09ad2355e4
--- /dev/null
+++ b/htdocs/core/modules/payment/mod_payment_ant.php
@@ -0,0 +1,140 @@
+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ * or see http://www.gnu.org/
+ */
+
+/**
+ * \file htdocs/core/modules/payment/mod_payment_ant.php
+ * \ingroup payment
+ * \brief File containing class for numbering module Ant
+ */
+
+require_once DOL_DOCUMENT_ROOT .'/core/modules/payment/modules_payment.php';
+
+
+/**
+ * Class to manage customer payment numbering rules Ant
+ */
+class mod_payment_ant extends ModeleNumRefPayments
+{
+ var $version='dolibarr'; // 'development', 'experimental', 'dolibarr'
+ var $error = '';
+ var $nom = 'Ant';
+
+
+ /**
+ * Renvoi la description du modele de numerotation
+ *
+ * @return string Texte descripif
+ */
+ function info()
+ {
+ global $conf,$langs;
+
+ $langs->load("bills");
+
+ $form = new Form($this->db);
+
+ $texte = $langs->trans('GenericNumRefModelDesc')." \n";
+ $texte.= '';
+
+ return $texte;
+ }
+
+ /**
+ * Renvoi un exemple de numerotation
+ *
+ * @return string Example
+ */
+ function getExample()
+ {
+ global $conf,$langs,$mysoc;
+
+ $old_code_client=$mysoc->code_client;
+ $mysoc->code_client='CCCCCCCCCC';
+ $numExample = $this->getNextValue($mysoc,'');
+ $mysoc->code_client=$old_code_client;
+
+ if (! $numExample)
+ {
+ $numExample = $langs->trans('NotConfigured');
+ }
+ return $numExample;
+ }
+
+ /**
+ * Return next free value
+ *
+ * @param Societe $objsoc Object thirdparty
+ * @param Object $object Object we need next value for
+ * @return string Value if KO, <0 if KO
+ */
+ function getNextValue($objsoc,$object)
+ {
+ global $db,$conf;
+
+ require_once DOL_DOCUMENT_ROOT .'/core/lib/functions2.lib.php';
+
+ // We get cursor rule
+ $mask=$conf->global->PAYMENT_ANT_MASK;
+
+ if (! $mask)
+ {
+ $this->error='NotConfigured';
+ return 0;
+ }
+
+ $numFinal=get_next_value($db,$mask,'paiement','ref','',$objsoc,$object->datepaye);
+
+ return $numFinal;
+ }
+
+
+ /**
+ * Return next free value
+ *
+ * @param Societe $objsoc Object third party
+ * @param string $objforref Object for number to search
+ * @return string Next free value
+ */
+ function commande_get_num($objsoc,$objforref)
+ {
+ return $this->getNextValue($objsoc,$objforref);
+ }
+
+}
+
diff --git a/htdocs/core/modules/payment/mod_payment_cicada.php b/htdocs/core/modules/payment/mod_payment_cicada.php
new file mode 100644
index 00000000000..482261e9fe1
--- /dev/null
+++ b/htdocs/core/modules/payment/mod_payment_cicada.php
@@ -0,0 +1,150 @@
+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ * or see http://www.gnu.org/
+ */
+
+/**
+ * \file htdocs/core/modules/payment/mod_payment_cicada.php
+ * \ingroup payment
+ * \brief File containing class for numbering module Cicada
+ */
+
+require_once DOL_DOCUMENT_ROOT .'/core/modules/payment/modules_payment.php';
+
+/**
+ * Class to manage customer payment numbering rules Cicada
+ */
+class mod_payment_cicada extends ModeleNumRefPayments
+{
+ var $version='dolibarr'; // 'development', 'experimental', 'dolibarr'
+ var $prefix='PAY';
+ var $error='';
+ var $nom='Cicada';
+
+
+ /**
+ * Return description of numbering module
+ *
+ * @return string Text with description
+ */
+ function info()
+ {
+ global $langs;
+ return $langs->trans("SimpleNumRefModelDesc",$this->prefix);
+ }
+
+
+ /**
+ * Renvoi un exemple de numerotation
+ *
+ * @return string Example
+ */
+ function getExample()
+ {
+ return $this->prefix."0501-0001";
+ }
+
+
+ /**
+ * Test si les numeros deje en vigueur dans la base ne provoquent pas de
+ * de conflits qui empechera cette numerotation de fonctionner.
+ *
+ * @return boolean false si conflit, true si ok
+ */
+ function canBeActivated()
+ {
+ global $conf,$langs,$db;
+
+ $payyymm=''; $max='';
+
+ $posindice=9;
+ $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max";
+ $sql.= " FROM ".MAIN_DB_PREFIX."paiement";
+ $sql.= " WHERE ref LIKE '".$this->prefix."____-%'";
+ $sql.= " AND entity = ".$conf->entity;
+
+ $resql=$db->query($sql);
+ if ($resql)
+ {
+ $row = $db->fetch_row($resql);
+ if ($row) { $payyymm = substr($row[0],0,6); $max=$row[0]; }
+ }
+ if ($payyymm && ! preg_match('/'.$this->prefix.'[0-9][0-9][0-9][0-9]/i',$payyymm))
+ {
+ $langs->load("errors");
+ $this->error=$langs->trans('ErrorNumRefModel', $max);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Return next free value
+ *
+ * @param Societe $objsoc Object thirdparty
+ * @param Object $object Object we need next value for
+ * @return string Value if KO, <0 if KO
+ */
+ function getNextValue($objsoc,$object)
+ {
+ global $db,$conf;
+
+ // D'abord on recupere la valeur max
+ $posindice=9;
+ $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max";
+ $sql.= " FROM ".MAIN_DB_PREFIX."paiement";
+ $sql.= " WHERE ref like '".$this->prefix."____-%'";
+ $sql.= " AND entity = ".$conf->entity;
+
+ $resql=$db->query($sql);
+ if ($resql)
+ {
+ $obj = $db->fetch_object($resql);
+ if ($obj) $max = intval($obj->max);
+ else $max=0;
+ }
+ else
+ {
+ dol_syslog(__METHOD__, LOG_DEBUG);
+ return -1;
+ }
+
+ //$date=time();
+ $date=$object->datepaye;
+ $yymm = strftime("%y%m",$date);
+
+ if ($max >= (pow(10, 4) - 1)) $num=$max+1; // If counter > 9999, we do not format on 4 chars, we take number as it is
+ else $num = sprintf("%04s",$max+1);
+
+ dol_syslog(__METHOD__." return ".$this->prefix.$yymm."-".$num);
+ return $this->prefix.$yymm."-".$num;
+ }
+
+
+ /**
+ * Return next free value
+ *
+ * @param Societe $objsoc Object third party
+ * @param string $objforref Object for number to search
+ * @return string Next free value
+ */
+ function payment_get_num($objsoc,$objforref)
+ {
+ return $this->getNextValue($objsoc,$objforref);
+ }
+
+}
diff --git a/htdocs/core/modules/payment/modules_payment.php b/htdocs/core/modules/payment/modules_payment.php
new file mode 100644
index 00000000000..c9023a9fc65
--- /dev/null
+++ b/htdocs/core/modules/payment/modules_payment.php
@@ -0,0 +1,101 @@
+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ * or see http://www.gnu.org/
+ */
+
+/**
+ * \class ModeleNumRefPayments
+ * \brief Payment numbering references mother class
+ */
+
+abstract class ModeleNumRefPayments
+{
+ var $error='';
+
+ /**
+ * Return if a module can be used or not
+ *
+ * @return boolean true if module can be used
+ */
+ function isEnabled()
+ {
+ return true;
+ }
+
+ /**
+ * Return the default description of numbering module
+ *
+ * @return string Texte descripif
+ */
+ function info()
+ {
+ global $langs;
+ $langs->load("bills");
+ return $langs->trans("NoDescription");
+ }
+
+ /**
+ * Return numbering example
+ *
+ * @return string Example
+ */
+ function getExample()
+ {
+ global $langs;
+ $langs->load("bills");
+ return $langs->trans("NoExample");
+ }
+
+ /**
+ * Test if the existing numbers in the database do not cause conflicts that would prevent this numbering run.
+ *
+ * @return boolean false si conflit, true si ok
+ */
+ function canBeActivated()
+ {
+ return true;
+ }
+
+ /**
+ * Returns the next value
+ *
+ * @param Societe $objsoc Object thirdparty
+ * @param Object $object Object we need next value for
+ * @return string Valeur
+ */
+ function getNextValue($objsoc,$object)
+ {
+ global $langs;
+ return $langs->trans("NotAvailable");
+ }
+
+ /**
+ * Returns the module numbering version
+ *
+ * @return string Value
+ */
+ function getVersion()
+ {
+ global $langs;
+ $langs->load("admin");
+
+ if ($this->version == 'development') return $langs->trans("VersionDevelopment");
+ if ($this->version == 'experimental') return $langs->trans("VersionExperimental");
+ if ($this->version == 'dolibarr') return DOL_VERSION;
+ if ($this->version) return $this->version;
+ return $langs->trans("NotAvailable");
+ }
+}
diff --git a/htdocs/install/mysql/migration/3.8.0-3.9.0.sql b/htdocs/install/mysql/migration/3.8.0-3.9.0.sql
index 2b761758974..8bda380c0dd 100755
--- a/htdocs/install/mysql/migration/3.8.0-3.9.0.sql
+++ b/htdocs/install/mysql/migration/3.8.0-3.9.0.sql
@@ -53,3 +53,4 @@ ALTER TABLE llx_payment_salary CHANGE COLUMN fk_user_creat fk_user_author intege
ALTER TABLE llx_adherent ADD COLUMN pass_crypted varchar(128) after pass;
+ALTER TABLE llx_paiement ADD COLUMN ref varchar(30) NOT NULL AFTER rowid;
\ No newline at end of file
diff --git a/htdocs/install/mysql/tables/llx_paiement.sql b/htdocs/install/mysql/tables/llx_paiement.sql
index 00680f29d69..a82d5eb40e8 100644
--- a/htdocs/install/mysql/tables/llx_paiement.sql
+++ b/htdocs/install/mysql/tables/llx_paiement.sql
@@ -21,6 +21,7 @@
create table llx_paiement
(
rowid integer AUTO_INCREMENT PRIMARY KEY,
+ ref varchar(30) NOT NULL, -- payment reference number
entity integer DEFAULT 1 NOT NULL, -- Multi company id
datec datetime, -- date de creation
tms timestamp,
diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
index 71575782508..e06553afd89 100755
--- a/htdocs/langs/en_US/admin.lang
+++ b/htdocs/langs/en_US/admin.lang
@@ -1178,6 +1178,7 @@ SuggestPaymentByRIBOnAccount=Suggest payment by withdraw on account
SuggestPaymentByChequeToAddress=Suggest payment by cheque to
FreeLegalTextOnInvoices=Free text on invoices
WatermarkOnDraftInvoices=Watermark on draft invoices (none if empty)
+PaymentsNumberingModule=Payments numbering model
##### Proposals #####
PropalSetup=Commercial proposals module setup
CreateForm=Create forms
|