diff --git a/htdocs/accountancy/admin/defaultaccounts.php b/htdocs/accountancy/admin/defaultaccounts.php index 9a3b63adcc3..2bd1037db39 100644 --- a/htdocs/accountancy/admin/defaultaccounts.php +++ b/htdocs/accountancy/admin/defaultaccounts.php @@ -84,6 +84,9 @@ $list_account[] = 'ACCOUNTING_VAT_PAY_ACCOUNT'; if (isModEnabled('banque')) { $list_account[] = 'ACCOUNTING_ACCOUNT_TRANSFER_CASH'; } +if (!empty($conf->global->INVOICE_USE_RETAINED_WARRANTY)) { + $list_account[] = 'ACCOUNTING_ACCOUNT_CUSTOMER_RETAINED_WARRANTY'; +} if (isModEnabled('don')) { $list_account[] = 'DONATION_ACCOUNTINGACCOUNT'; } diff --git a/htdocs/accountancy/journal/sellsjournal.php b/htdocs/accountancy/journal/sellsjournal.php index f67fd76b3f1..666024833d0 100644 --- a/htdocs/accountancy/journal/sellsjournal.php +++ b/htdocs/accountancy/journal/sellsjournal.php @@ -4,7 +4,7 @@ * Copyright (C) 2011 Juanjo Menent * Copyright (C) 2012 Regis Houssin * Copyright (C) 2013 Christophe Battarel - * Copyright (C) 2013-2021 Alexandre Spangaro + * Copyright (C) 2013-2022 Alexandre Spangaro * Copyright (C) 2013-2016 Florian Henry * Copyright (C) 2013-2016 Olivier Geffroy * Copyright (C) 2014 Raphaƫl Doursenaud @@ -106,7 +106,7 @@ if (!GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end)) $date_end = dol_get_last_day($pastmonthyear, $pastmonth, false); } -$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 = "SELECT f.rowid, f.ref, f.type, f.datef as df, f.ref_client, f.date_lim_reglement as dlr, f.close_code, f.retained_warranty,"; $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,"; if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) { @@ -168,6 +168,7 @@ if ($result) { $tabht = array(); $tabtva = array(); $def_tva = array(); + $tabwarranty = array(); $tabttc = array(); $tablocaltax1 = array(); $tablocaltax2 = array(); @@ -248,7 +249,13 @@ if ($result) { $tablocaltax2[$obj->rowid][$compta_localtax2] = 0; } - $tabttc[$obj->rowid][$compta_soc] += $obj->total_ttc * $situation_ratio; + $total_ttc = $obj->total_ttc * $situation_ratio; + if (!empty($conf->global->INVOICE_USE_RETAINED_WARRANTY) && $obj->retained_warranty > 0) { + $retained_warranty = (double) price2num($total_ttc * $obj->retained_warranty / 100, 'MT'); + $tabwarranty[$obj->rowid][$compta_soc] += $retained_warranty; + $total_ttc -= $retained_warranty; + } + $tabttc[$obj->rowid][$compta_soc] += $total_ttc; $tabht[$obj->rowid][$compta_prod] += $obj->total_ht * $situation_ratio; if (empty($line->tva_npr)) { $tabtva[$obj->rowid][$compta_tva] += $obj->total_tva * $situation_ratio; // We ignore line if VAT is a NPR @@ -300,6 +307,10 @@ if ($action == 'writebookkeeping') { $accountingaccountcustomer->fetch(null, $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER, true); + $accountingaccountcustomerwarranty = new AccountingAccount($db); + + $accountingaccountcustomerwarranty->fetch(null, $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_RETAINED_WARRANTY, true); + foreach ($tabfac as $key => $val) { // Loop on each invoice $errorforline = 0; @@ -344,6 +355,55 @@ if ($action == 'writebookkeeping') { setEventMessages($langs->trans('ErrorInvoiceContainsLinesNotYetBounded', $val['ref']), null, 'errors'); } + // Warranty + if (!$errorforline) { + foreach ($tabwarranty[$key] as $k => $mt) { + $bookkeeping = new BookKeeping($db); + $bookkeeping->doc_date = $val["date"]; + $bookkeeping->date_lim_reglement = $val["datereg"]; + $bookkeeping->doc_ref = $val["ref"]; + $bookkeeping->date_creation = $now; + $bookkeeping->doc_type = 'customer_invoice'; + $bookkeeping->fk_doc = $key; + $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add + $bookkeeping->thirdparty_code = $companystatic->code_client; + + $bookkeeping->subledger_account = $tabcompany[$key]['code_compta']; + $bookkeeping->subledger_label = $tabcompany[$key]['name']; + + $bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_RETAINED_WARRANTY; + $bookkeeping->label_compte = $accountingaccountcustomerwarranty->label; + + $bookkeeping->label_operation = dol_trunc($companystatic->name, 16).' - '.$invoicestatic->ref.' - '.$langs->trans("Retainedwarranty"); + $bookkeeping->montant = $mt; + $bookkeeping->sens = ($mt >= 0) ? 'D' : 'C'; + $bookkeeping->debit = ($mt >= 0) ? $mt : 0; + $bookkeeping->credit = ($mt < 0) ? -$mt : 0; + $bookkeeping->code_journal = $journal; + $bookkeeping->journal_label = $langs->transnoentities($journal_label); + $bookkeeping->fk_user_author = $user->id; + $bookkeeping->entity = $conf->entity; + + $totaldebit += $bookkeeping->debit; + $totalcredit += $bookkeeping->credit; + + $result = $bookkeeping->create($user); + if ($result < 0) { + if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists + $error++; + $errorforline++; + $errorforinvoice[$key] = 'alreadyjournalized'; + //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings'); + } else { + $error++; + $errorforline++; + $errorforinvoice[$key] = 'other'; + setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors'); + } + } + } + } + // Thirdparty if (!$errorforline) { foreach ($tabttc[$key] as $k => $mt) { @@ -624,6 +684,25 @@ if ($action == 'exportcsv') { // ISO and not UTF8 ! continue; } + // Warranty + foreach ($tabwarranty[$key] as $k => $mt) { + //if ($mt) { + print '"'.$key.'"'.$sep; + print '"'.$date.'"'.$sep; + print '"'.$val["ref"].'"'.$sep; + print '"'.utf8_decode(dol_trunc($companystatic->name, 32)).'"'.$sep; + print '"'.length_accounta(html_entity_decode($k)).'"'.$sep; + print '"'.length_accountg($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_RETAINED_WARRANTY).'"'.$sep; + print '"'.length_accounta(html_entity_decode($k)).'"'.$sep; + print '"'.$langs->trans("Thirdparty").'"'.$sep; + print '"'.utf8_decode(dol_trunc($companystatic->name, 16)).' - '.$invoicestatic->ref.' - '.$langs->trans("Retainedwarranty").'"'.$sep; + print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep; + print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep; + print '"'.$journal.'"'; + print "\n"; + //} + } + // Third party foreach ($tabttc[$key] as $k => $mt) { //if ($mt) { @@ -849,6 +928,36 @@ if (empty($action) || $action == 'view') { print ""; } + // Warranty + foreach ($tabwarranty[$key] as $k => $mt) { + print ''; + print ""; + print "".$date.""; + print "".$invoicestatic->getNomUrl(1).""; + // Account + print ""; + $accountoshow = length_accountg($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_RETAINED_WARRANTY); + if (($accountoshow == "") || $accountoshow == 'NotDefined') { + print ''.$langs->trans("MainAccountForCustomersNotDefined").''; + } else { + print $accountoshow; + } + print ''; + // Subledger account + print ""; + $accountoshow = length_accounta($k); + if (($accountoshow == "") || $accountoshow == 'NotDefined') { + print ''.$langs->trans("ThirdpartyAccountNotDefined").''; + } else { + print $accountoshow; + } + print ''; + print "".$companystatic->getNomUrl(0, 'customer', 16).' - '.$invoicestatic->ref.' - '.$langs->trans("Retainedwarranty").""; + print ''.($mt >= 0 ? price($mt) : '').""; + print ''.($mt < 0 ? price(-$mt) : '').""; + print ""; + } + // Third party foreach ($tabttc[$key] as $k => $mt) { print ''; diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index c32ff7c5c65..419b69a3f90 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -189,6 +189,7 @@ ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT=Account (from the Chart Of Account) to be us UseAuxiliaryAccountOnCustomerDeposit=Store customer account as individual account in subsidiary ledger for lines of down payments (if disabled, individual account for down payment lines will remain empty) ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT=Account (from the Chart Of Account) to be used as the default UseAuxiliaryAccountOnSupplierDeposit=Store supplier account as individual account in subsidiary ledger for lines of down payments (if disabled, individual account for down payment lines will remain empty) +ACCOUNTING_ACCOUNT_CUSTOMER_RETAINED_WARRANTY=Accounting account by default to register customer retained warranty ACCOUNTING_PRODUCT_BUY_ACCOUNT=Account (from the Chart Of Account) to be used as the default account for the products purchased within same country (used if not defined in the product sheet) ACCOUNTING_PRODUCT_BUY_INTRA_ACCOUNT=Account (from the Chart Of Account) to be used as the default account for the products purchased from EEC to another EEC country (used if not defined in the product sheet)