';
if (! $i) $totalarray['nbfield']++;
diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php
index 73f3f9bbfc5..cfe49764c74 100644
--- a/htdocs/accountancy/journal/bankjournal.php
+++ b/htdocs/accountancy/journal/bankjournal.php
@@ -107,8 +107,6 @@ if (! GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end)
$date_end = dol_get_last_day($pastmonthyear, $pastmonth, false);
}
-$idpays = $mysoc->country_id;
-
$sql = "SELECT b.rowid, b.dateo as do, b.datev as dv, b.amount, b.label, b.rappro, b.num_releve, b.num_chq, b.fk_type, b.fk_account,";
$sql .= " ba.courant, ba.ref as baref, ba.account_number, ba.fk_accountancy_journal,";
$sql .= " soc.code_compta, soc.code_compta_fournisseur, soc.rowid as socid, soc.nom as name, soc.email as email, bu1.type as typeop_company,";
@@ -154,6 +152,9 @@ $paymentloanstatic = new PaymentLoan($db);
$accountLinestatic=new AccountLine($db);
$paymentsubscriptionstatic = new Subscription($db);
+$tmppayment = new Paiement($db);
+$tmpinvoice = new Facture($db);
+
$accountingaccount = new AccountingAccount($db);
// Get code of finance journal
@@ -185,13 +186,14 @@ if ($result) {
$tabbq = array ();
$tabtp = array ();
$tabtype = array ();
+ $tabmoreinfo = array();
// Loop on each line into llx_bank table. For each line, we should get:
// one line tabpay = line into bank
// one line for bank record = tabbq
// one line for thirdparty record = tabtp
$i = 0;
- while ( $i < $num )
+ while ($i < $num)
{
$obj = $db->fetch_object($result);
@@ -215,7 +217,7 @@ if ($result) {
// Set accountancy code for bank
$compta_bank = $obj->account_number;
- // Set accountancy code for thirdparty
+ // Set accountancy code for thirdparty (example: '411CU...' or '411' if no subledger account defined on customer)
$compta_soc = 'NotDefined';
if ($lineisapurchase > 0)
$compta_soc = (($obj->code_compta_fournisseur != "") ? $obj->code_compta_fournisseur : $account_supplier);
@@ -257,10 +259,12 @@ if ($result) {
//var_dump($i);
//var_dump($tabpay);
+ //var_dump($tabcompany);
// By default
$tabpay[$obj->rowid]['type'] = 'unknown'; // Can be SOLD, miscellaneous entry, payment of patient, or any old record with no links in bank_url.
$tabtype[$obj->rowid] = 'unknown';
+ $tabmoreinfo[$obj->rowid] = array();
// get_url may return -1 which is not traversable
if (is_array($links) && count($links) > 0) {
@@ -285,6 +289,10 @@ if ($result) {
}
}
+ if ($links[$key]['type'] == 'withdraw') {
+ $tabmoreinfo[$obj->rowid]['withdraw']=1;
+ }
+
if ($links[$key]['type'] == 'payment') {
$paymentstatic->id = $links[$key]['url_id'];
$paymentstatic->ref = $links[$key]['url_id'];
@@ -411,8 +419,30 @@ if ($result) {
$tabbq[$obj->rowid][$compta_bank] += $obj->amount;
- // If not links were found to know amount on thirdparty, we init it.
- if (empty($tabtp[$obj->rowid])) $tabtp[$obj->rowid]['NotDefined']= $tabbq[$obj->rowid][$compta_bank];
+ // If no links were found to know the amount on thirdparty, we try to guess it.
+ // This may happens on bank entries without the links lines to 'company'.
+ if (empty($tabtp[$obj->rowid]) && ! empty($tabmoreinfo[$obj->rowid]['withdraw'])) // If we dont find 'company' link because it is an old 'withdraw' record
+ {
+ foreach ($links as $key => $val) {
+ if ($links[$key]['type'] == 'payment') {
+ // Get thirdparty
+ $tmppayment->fetch($links[$key]['url_id']);
+ $arrayofamounts = $tmppayment->getAmountsArray();
+ foreach($arrayofamounts as $invoiceid => $amount)
+ {
+ $tmpinvoice->fetch($invoiceid);
+ $tmpinvoice->fetch_thirdparty();
+ if ($tmpinvoice->thirdparty->code_compta)
+ {
+ $tabtp[$obj->rowid][$tmpinvoice->thirdparty->code_compta] += $amount;
+ }
+ }
+ }
+ }
+ }
+
+ // If no links were found to know the amount on thirdparty, we init it to account 'NotDefined'.
+ if (empty($tabtp[$obj->rowid])) $tabtp[$obj->rowid]['NotDefined'] = $tabbq[$obj->rowid][$compta_bank];
// Check account number is ok
/*if ($action == 'writebookkeeping') // Make test now in such a case
@@ -441,11 +471,12 @@ if ($result) {
dol_print_error($db);
}
-/*
-var_dump($tabpay);
+
+/*var_dump($tabpay);
+var_dump($tabcompany);
var_dump($tabbq);
var_dump($tabtp);
-*/
+var_dump($tabtype);*/
// Write bookkeeping
if (! $error && $action == 'writebookkeeping') {
@@ -561,15 +592,15 @@ if (! $error && $action == 'writebookkeeping') {
$bookkeeping->date_create = $now;
if ($tabtype[$key] == 'payment') { // If payment is payment of customer invoice, we get ref of invoice
- $bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
- $bookkeeping->subledger_label = $tabcompany[$key]['name'];
+ $bookkeeping->subledger_account = $k; // For payment, the subledger account is stored as $key of $tabtp
+ $bookkeeping->subledger_label = $tabcompany[$key]['name']; // $tabcompany is defined only if we are sure there is 1 thirdparty for the bank transaction
$bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER;
$accountingaccount->fetch(null, $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER, true);
$bookkeeping->label_compte = $accountingaccount->label;
- } elseif ($tabtype[$key] == 'payment_supplier') { // If payment is payment of supplier invoice, we get ref of invoice
- $bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
- $bookkeeping->subledger_label = $tabcompany[$key]['name'];
+ } elseif ($tabtype[$key] == 'payment_supplier') { // If payment is payment of supplier invoice, we get ref of invoice
+ $bookkeeping->subledger_account = $k; // For payment, the subledger account is stored as $key of $tabtp
+ $bookkeeping->subledger_label = $tabcompany[$key]['name']; // $tabcompany is defined only if we are sure there is 1 thirdparty for the bank transaction
$bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER;
$accountingaccount->fetch(null, $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER, true);
@@ -701,6 +732,7 @@ if (! $error && $action == 'writebookkeeping') {
$totalcredit += $bookkeeping->credit;
$result = $bookkeeping->create($user);
+
if ($result < 0) {
if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') // Already exists
{
@@ -1071,7 +1103,6 @@ if (empty($action) || $action == 'view') {
if ($tabtype[$key] == 'payment_salary') $account_ledger = $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT;
if ($tabtype[$key] == 'payment_vat') $account_ledger = $conf->global->ACCOUNTING_VAT_PAY_ACCOUNT;
if ($tabtype[$key] == 'member') $account_ledger = $conf->global->ADHERENT_SUBSCRIPTION_ACCOUNTINGACCOUNT;
-
$accounttoshow = length_accounta($account_ledger);
if (empty($accounttoshow) || $accounttoshow == 'NotDefined')
{
@@ -1104,6 +1135,7 @@ if (empty($action) || $action == 'view') {
print "";
// Subledger account
print "
";
+
if (in_array($tabtype[$key], array('payment', 'payment_supplier', 'payment_expensereport', 'payment_salary'))) // Type of payment with subledger
{
$accounttoshowsubledger = length_accounta($k);
@@ -1115,7 +1147,14 @@ if (empty($action) || $action == 'view') {
var_dump($tabtype[$key]);
var_dump($tabbq[$key]);*/
//print ''.$langs->trans("ThirdpartyAccountNotDefined").'';
- print ''.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknown").'';
+ if (! empty($tabcompany[$key]['code_compta']))
+ {
+ print ''.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknown", $tabcompany[$key]['code_compta']).'';
+ }
+ else
+ {
+ print ''.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknownBlocking").'';
+ }
}
else print $accounttoshowsubledger;
}
diff --git a/htdocs/accountancy/journal/expensereportsjournal.php b/htdocs/accountancy/journal/expensereportsjournal.php
index 3f4632a0103..c06506c0895 100644
--- a/htdocs/accountancy/journal/expensereportsjournal.php
+++ b/htdocs/accountancy/journal/expensereportsjournal.php
@@ -87,15 +87,11 @@ if (! GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end)
$date_end = dol_get_last_day($pastmonthyear, $pastmonth, false);
}
-$idpays = $mysoc->country_id;
-
$sql = "SELECT er.rowid, er.ref, er.date_debut as de,";
$sql .= " erd.rowid as erdid, erd.comments, erd.total_ht, erd.total_tva, erd.total_localtax1, erd.total_localtax2, erd.tva_tx, erd.total_ttc, erd.fk_code_ventilation, erd.vat_src_code, ";
$sql .= " u.rowid as uid, u.firstname, u.lastname, u.accountancy_code as user_accountancy_account,";
$sql .= " f.accountancy_code, aa.rowid as fk_compte, aa.account_number as compte, aa.label as label_compte";
-//$sql .= " ct.accountancy_code_buy as account_tva";
$sql .= " FROM " . MAIN_DB_PREFIX . "expensereport_det as erd";
-//$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_tva as ct ON erd.tva_tx = ct.taux AND ct.fk_pays = '" . $idpays . "'";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_type_fees as f ON f.id = erd.fk_c_type_fees";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON aa.rowid = erd.fk_code_ventilation";
$sql .= " JOIN " . MAIN_DB_PREFIX . "expensereport as er ON er.rowid = erd.fk_expensereport";
diff --git a/htdocs/accountancy/journal/purchasesjournal.php b/htdocs/accountancy/journal/purchasesjournal.php
index 66a54934e1c..8ff70219c68 100644
--- a/htdocs/accountancy/journal/purchasesjournal.php
+++ b/htdocs/accountancy/journal/purchasesjournal.php
@@ -92,8 +92,6 @@ if (! GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end)
$date_end = dol_get_last_day($pastmonthyear, $pastmonth, false);
}
-$idpays = $mysoc->country_id;
-
$sql = "SELECT f.rowid, f.ref as ref, f.type, f.datef as df, f.libelle,f.ref_supplier, f.date_lim_reglement as dlf, f.close_code,";
$sql .= " fd.rowid as fdid, fd.description, fd.product_type, fd.total_ht, fd.tva as total_tva, fd.total_localtax1, fd.total_localtax2, fd.tva_tx, fd.total_ttc, fd.vat_src_code,";
$sql .= " s.rowid as socid, s.nom as name, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,";
diff --git a/htdocs/accountancy/journal/sellsjournal.php b/htdocs/accountancy/journal/sellsjournal.php
index 57a2ff1586b..b69f485a558 100644
--- a/htdocs/accountancy/journal/sellsjournal.php
+++ b/htdocs/accountancy/journal/sellsjournal.php
@@ -95,8 +95,6 @@ if (! GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end)
$date_end = dol_get_last_day($pastmonthyear, $pastmonth, false);
}
-$idpays = $mysoc->country_id;
-
$sql = "SELECT f.rowid, f.ref, f.type, f.datef as df, f.ref_client, f.date_lim_reglement as dlr, f.close_code,";
$sql .= " fd.rowid as fdid, fd.description, fd.product_type, fd.total_ht, fd.total_tva, fd.total_localtax1, fd.total_localtax2, fd.tva_tx, fd.total_ttc, fd.situation_percent, fd.vat_src_code,";
$sql .= " s.rowid as socid, s.nom as name, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,";
diff --git a/htdocs/compta/bank/various_payment/card.php b/htdocs/compta/bank/various_payment/card.php
index 2d911b5c6bb..67f1e2909fc 100644
--- a/htdocs/compta/bank/various_payment/card.php
+++ b/htdocs/compta/bank/various_payment/card.php
@@ -382,7 +382,7 @@ if ($action == 'create')
}
else
{
- print '';
+ print '';
}
print '
';
}
diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php
index 28417a6d4f1..a3c79d23602 100644
--- a/htdocs/compta/paiement/class/paiement.class.php
+++ b/htdocs/compta/paiement/class/paiement.class.php
@@ -991,16 +991,16 @@ class Paiement extends CommonObject
}
/**
- * Retourne la liste des factures sur lesquels porte le paiement
+ * Return list of invoices the payment is related to.
*
- * @param string $filter Critere de filtre
- * @return array Tableau des id de factures
+ * @param string $filter Filter
+ * @return int|array <0 if KO or array of invoice id
*/
public function getBillsArray($filter = '')
{
- $sql = 'SELECT fk_facture';
- $sql.= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf, '.MAIN_DB_PREFIX.'facture as f';
- $sql.= ' WHERE pf.fk_facture = f.rowid AND fk_paiement = '.$this->id;
+ $sql = 'SELECT pf.fk_facture';
+ $sql.= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf, '.MAIN_DB_PREFIX.'facture as f'; // We keep link on invoice to allow use of some filters on invoice
+ $sql.= ' WHERE pf.fk_facture = f.rowid AND pf.fk_paiement = '.$this->id;
if ($filter) $sql.= ' AND '.$filter;
$resql = $this->db->query($sql);
if ($resql)
@@ -1026,6 +1026,40 @@ class Paiement extends CommonObject
}
}
+ /**
+ * Return list of amounts of payments.
+ *
+ * @return int|array Array of amount of payments
+ */
+ public function getAmountsArray()
+ {
+ $sql = 'SELECT pf.fk_facture, pf.amount';
+ $sql.= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf';
+ $sql.= ' WHERE pf.fk_paiement = '.$this->id;
+ $resql = $this->db->query($sql);
+ if ($resql)
+ {
+ $i=0;
+ $num=$this->db->num_rows($resql);
+ $amounts = array();
+
+ while ($i < $num)
+ {
+ $obj = $this->db->fetch_object($resql);
+ $amounts[$obj->fk_facture]=$obj->amount;
+ $i++;
+ }
+
+ return $amounts;
+ }
+ else
+ {
+ $this->error=$this->db->error();
+ dol_syslog(get_class($this).'::getAmountsArray Error '.$this->error.' -', LOG_DEBUG);
+ return -1;
+ }
+ }
+
/**
* Return next reference of customer invoice not already used (or last reference)
* according to numbering module defined into constant FACTURE_ADDON
diff --git a/htdocs/core/lib/accounting.lib.php b/htdocs/core/lib/accounting.lib.php
index 9619bee580f..f7e1b28876f 100644
--- a/htdocs/core/lib/accounting.lib.php
+++ b/htdocs/core/lib/accounting.lib.php
@@ -25,15 +25,15 @@
*/
- /**
- * Check if a value is empty with some options
- *
- * @author Michael - https://www.php.net/manual/fr/function.empty.php#90767
- * @param mixed $var Value to test
- * @param int|null $allow_false Setting this to true will make the function consider a boolean value of false as NOT empty. This parameter is false by default.
- * @param int|null $allow_ws Setting this to true will make the function consider a string with nothing but white space as NOT empty. This parameter is false by default.
- * @return boolean True of False
- */
+/**
+ * Check if a value is empty with some options
+ *
+ * @author Michael - https://www.php.net/manual/fr/function.empty.php#90767
+ * @param mixed $var Value to test
+ * @param int|null $allow_false Setting this to true will make the function consider a boolean value of false as NOT empty. This parameter is false by default.
+ * @param int|null $allow_ws Setting this to true will make the function consider a string with nothing but white space as NOT empty. This parameter is false by default.
+ * @return boolean True of False
+ */
function is_empty($var, $allow_false = false, $allow_ws = false)
{
if (!isset($var) || is_null($var) || ($allow_ws == false && trim($var) == "" && !is_bool($var)) || ($allow_false === false && is_bool($var) && $var === false) || (is_array($var) && empty($var))) {
diff --git a/htdocs/install/mysql/tables/llx_paiement.sql b/htdocs/install/mysql/tables/llx_paiement.sql
index 9f40cb2cfc9..a57c345c968 100644
--- a/htdocs/install/mysql/tables/llx_paiement.sql
+++ b/htdocs/install/mysql/tables/llx_paiement.sql
@@ -28,7 +28,7 @@ create table llx_paiement
datep datetime, -- payment date
amount double(24,8) DEFAULT 0, -- amount paid in Dolibarr currency
multicurrency_amount double(24,8) DEFAULT 0, -- amount paid in invoice currency
- fk_paiement integer NOT NULL,
+ fk_paiement integer NOT NULL, -- type of payment in llx_c_paiement
num_paiement varchar(50),
note text,
ext_payment_id varchar(128), -- external id of payment (for example Stripe charge id)
diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang
index 3a08e422600..3bb0df59812 100644
--- a/htdocs/langs/en_US/accountancy.lang
+++ b/htdocs/langs/en_US/accountancy.lang
@@ -216,7 +216,8 @@ DescThirdPartyReport=Consult here the list of third-party customers and vendors
ListAccounts=List of the accounting accounts
UnknownAccountForThirdparty=Unknown third-party account. We will use %s
UnknownAccountForThirdpartyBlocking=Unknown third-party account. Blocking error
-ThirdpartyAccountNotDefinedOrThirdPartyUnknown=Third-party account not defined or third party unknown. Blocking error.
+ThirdpartyAccountNotDefinedOrThirdPartyUnknown=Third-party account not defined or third party unknown. We will use %s
+ThirdpartyAccountNotDefinedOrThirdPartyUnknownBlocking=Third-party account not defined or third party unknown. Blocking error.
UnknownAccountForThirdpartyAndWaitingAccountNotDefinedBlocking=Unknown third-party account and waiting account not defined. Blocking error
PaymentsNotLinkedToProduct=Payment not linked to any product / service
diff --git a/htdocs/product/stock/class/entrepot.class.php b/htdocs/product/stock/class/entrepot.class.php
index 4593037da10..593b5f1bcea 100644
--- a/htdocs/product/stock/class/entrepot.class.php
+++ b/htdocs/product/stock/class/entrepot.class.php
@@ -292,7 +292,9 @@ class Entrepot extends CommonObject
{
global $conf;
- $error = 0;
+ $error = 0;
+
+ dol_syslog(get_class($this)."::delete id=".$this->id, LOG_DEBUG);
$this->db->begin();
@@ -311,7 +313,7 @@ class Entrepot extends CommonObject
{
$sql = "DELETE FROM ".MAIN_DB_PREFIX.$table;
$sql.= " WHERE fk_entrepot = " . $this->id;
- dol_syslog(get_class($this)."::delete", LOG_DEBUG);
+
$result=$this->db->query($sql);
if (! $result)
{
@@ -321,49 +323,52 @@ class Entrepot extends CommonObject
}
}
+ // Removed extrafields
+ if (! $error)
+ {
+ if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
+ {
+ $result=$this->deleteExtraFields();
+ if ($result < 0)
+ {
+ $error++;
+ dol_syslog(get_class($this)."::delete Error ".$this->error, LOG_ERR);
+ }
+ }
+ }
+
if (! $error)
{
$sql = "DELETE FROM ".MAIN_DB_PREFIX."entrepot";
$sql.= " WHERE rowid = " . $this->id;
- dol_syslog(get_class($this)."::delete", LOG_DEBUG);
$resql1=$this->db->query($sql);
- if (!$resql1) $error++;
+ if (! $resql1)
+ {
+ $error++;
+ $this->errors[] = $this->db->lasterror();
+ }
+ }
+ if (! $error)
+ {
// Update denormalized fields because we change content of produt_stock. Warning: Do not use "SET p.stock", does not works with pgsql
$sql = "UPDATE ".MAIN_DB_PREFIX."product as p SET stock = (SELECT SUM(ps.reel) FROM ".MAIN_DB_PREFIX."product_stock as ps WHERE ps.fk_product = p.rowid)";
- dol_syslog(get_class($this)."::delete", LOG_DEBUG);
$resql2=$this->db->query($sql);
- if (!$resql2) $error++;
-
- // Removed extrafields
- if (! $error) {
- if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
- {
- $result=$this->deleteExtraFields();
- if ($result < 0) {
- $error++;
- $errorflag=-4;
- dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR);
- }
- }
- }
-
- if (!$error)
+ if (! $resql2)
{
- $this->db->commit();
- return 1;
- }
- else
- {
- $this->db->rollback();
- $this->error=$this->db->lasterror();
- return -2;
+ $error++;
+ $this->errors[] = $this->db->lasterror();
}
}
+
+ if (! $error)
+ {
+ $this->db->commit();
+ return 1;
+ }
else
{
$this->db->rollback();
- $this->error=$this->db->lasterror();
return -1;
}
}
diff --git a/test/phpunit/EntrepotTest.php b/test/phpunit/EntrepotTest.php
index 9672123f103..16555d88e39 100644
--- a/test/phpunit/EntrepotTest.php
+++ b/test/phpunit/EntrepotTest.php
@@ -211,6 +211,7 @@ class EntrepotTest extends PHPUnit_Framework_TestCase
$langs=$this->savlangs;
$db=$this->savdb;
+ //$this->assertLessThan(1, 0);
return $localobject->id;
}
@@ -257,6 +258,8 @@ class EntrepotTest extends PHPUnit_Framework_TestCase
$localobject=new Entrepot($db);
+ //$this->assertLessThan(1, 0);
+
return;
}
}