From f32673cb495b4903e29ed0b6ca9d53b5a890cd57 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 20 Jan 2007 12:15:34 +0000 Subject: [PATCH] =?UTF-8?q?Fix:=20Une=20facture=20class=E9e=20pay=E9e=20pa?= =?UTF-8?q?rtiellement=20ne=20doit=20pas=20aparraitre=20dans=20la=20liste?= =?UTF-8?q?=20des=20factures=20sur=20lesquelles=20un=20avoir=20est=20possi?= =?UTF-8?q?ble.=20En=20effet=20si=20elles=20ont=20=E9t=E9=20class=E9e=20"p?= =?UTF-8?q?ay=E9e=20partiellement"=20alors=20un=20motif=20a=20=E9t=E9=20do?= =?UTF-8?q?nn=E9=20et=20le=20manque=20a=20gagn=E9=20peut=20etre=20imput=E9?= =?UTF-8?q?=20en=20compta.=20Il=20n'y=20a=20pas=20de=20trous=20dans=20la?= =?UTF-8?q?=20compta.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- htdocs/compta/facture.php | 2844 ++++++++++++++++----------------- htdocs/facture.class.php | 8 +- htdocs/langs/en_US/bills.lang | 3 + htdocs/langs/fr_BE/bills.lang | 2 + htdocs/langs/fr_FR/bills.lang | 3 + htdocs/main.inc.php | 6 +- 6 files changed, 1392 insertions(+), 1474 deletions(-) diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index 88a75024348..e437692ab83 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -1597,1503 +1597,1407 @@ if ($_GET['action'] == 'create') } else { - /* *************************************************************************** */ - /* */ - /* Fiche en mode visu */ - /* */ - /* *************************************************************************** */ - $id = $_GET['facid']; - if ($id > 0) - { - if ($mesg) print $mesg.'
'; - - $fac = New Facture($db); - if ( $fac->fetch($_GET['facid'], $user->societe_id) > 0) + /* *************************************************************************** */ + /* */ + /* Fiche en mode visu */ + /* */ + /* *************************************************************************** */ + $id = $_GET['facid']; + if ($id > 0) { - $soc = new Societe($db, $fac->socid); - $soc->fetch($fac->socid); - $absolute_discount=$soc->getCurrentDiscount(); - - $totalpaye = $fac->getSommePaiement(); - $resteapayer = $fac->total_ttc - $totalpaye; - if ($fac->paye) $resteapayer=0; - - $author = new User($db); - if ($fac->user_author) - { - $author->id = $fac->user_author; - $author->fetch(); - } - - $facidnext=$fac->getIdReplacingInvoice(); - - - $head = facture_prepare_head($fac); - - dolibarr_fiche_head($head, 'compta', $langs->trans('InvoiceCustomer')); - - /* - * Confirmation de la suppression de la facture - */ - if ($_GET['action'] == 'delete') - { - $text=$langs->trans('ConfirmDeleteBill'); - $html->form_confirm($_SERVER['PHP_SELF'].'?facid='.$fac->id,$langs->trans('DeleteBill'),$text,'confirm_delete'); - print '
'; - } - - /* - * Confirmation de la validation - */ - if ($_GET['action'] == 'valid') - { - // on vérifie si la facture est en numérotation provisoire - $facref = substr($fac->ref, 1, 4); - if ($facref == 'PROV') + if ($mesg) print $mesg.'
'; + + $fac = New Facture($db); + if ( $fac->fetch($_GET['facid'], $user->societe_id) > 0) { - $numfa = $fac->getNextNumRef($soc); - } - else - { - $numfa = $fac->ref; - } - - $text=$langs->trans('ConfirmValidateBill',$numfa); - if ($conf->notification->enabled) - { - require_once(DOL_DOCUMENT_ROOT ."/notify.class.php"); - $notify=new Notify($db); - $text.='
'; - $text.=$notify->confirmMessage(2,$fac->socid); - } - - $html->form_confirm($_SERVER["PHP_SELF"].'?facid='.$fac->id,$langs->trans('ValidateBill'),$text,'confirm_valid'); - print '
'; - } - - /* - * Confirmation du classement payé - */ - if ($_GET['action'] == 'payed' && $resteapayer <= 0) - { - $html->form_confirm($_SERVER["PHP_SELF"].'?facid='.$fac->id,$langs->trans('ClassifyPayed'),$langs->trans('ConfirmClassifyPayedBill',$fac->ref),'confirm_payed'); - print '
'; - } - if ($_GET['action'] == 'payed' && $resteapayer > 0) - { - // Code - $close[0]['code']='discount_vat'; - $close[1]['code']='badcustomer'; - $close[2]['code']='abandon'; - // Help - $close[0]['label']=$langs->trans("HelpEscompte").'

'.$langs->trans("ConfirmClassifyPayedPartiallyVat"); - $close[1]['label']=$langs->trans("ConfirmClassifyPayedPartiallyBadCustomer"); - $close[2]['label']=$langs->trans("ConfirmClassifyPayedPartiallyOther"); - // Texte - $close[0]['reason']=$html->textwithhelp($langs->transnoentities("ConfirmClassifyPayedPartiallyReasonDiscountVat",$resteapayer,$langs->trans("Currency".$conf->monnaie)),$close[0]['label'],1); - $close[1]['reason']=$html->textwithhelp($langs->transnoentities("ConfirmClassifyPayedPartiallyReasonBadCustomer",$resteapayer,$langs->trans("Currency".$conf->monnaie)),$close[1]['label'],1); - $close[2]['reason']=$html->textwithhelp($langs->transnoentities("ConfirmClassifyPayedPartiallyReasonOther",$resteapayer,$langs->trans("Currency".$conf->monnaie)),$close[2]['label'],1); - // arrayreasons - $arrayreasons[$close[0]['code']]=$close[0]['reason']; - $arrayreasons[$close[1]['code']]=$close[1]['reason']; - $arrayreasons[$close[2]['code']]=$close[2]['reason']; - - // Crée un tableau formulaire - $formquestion=array( - 'text' => $langs->trans("ConfirmClassifyPayedPartiallyQuestion"), - array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons), - array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100') - ); - // Paiement incomplet. On demande si motif = escompte ou autre - $html->form_confirm($_SERVER["PHP_SELF"].'?facid='.$fac->id,$langs->trans('ClassifyPayed'),$langs->trans('ConfirmClassifyPayedPartially',$fac->ref),'confirm_payed_partially',$formquestion); - print '
'; - } - - /* - * Confirmation du classement abandonne - */ - if ($_GET['action'] == 'canceled') - { - // S'il y a une facture de remplacement pas encore validée (etat brouillon), - // on ne permet pas de classer abandonner la facture. - if ($facidnext) - { - $facturereplacement=new Facture($db); - $facturereplacement->fetch($facidnext); - $statusreplacement=$facturereplacement->statut; - } - if ($facidnext && $statusreplacement == 0) - { - print '
'.$langs->trans("ErrorCantCancelIfReplacementInvoiceNotValidated").'
'; - } - else - { - $html->form_confirm($_SERVER['PHP_SELF'].'?facid='.$fac->id,$langs->trans('CancelBill'),$langs->trans('ConfirmCancelBill',$fac->ref),'confirm_canceled'); - print '
'; - } - } - - /* - * Confirmation de la suppression d'une ligne produit - */ - if ($_GET['action'] == 'delete_product_line' && $conf->global->PRODUIT_CONFIRM_DELETE_LINE) - { - $html->form_confirm($_SERVER["PHP_SELF"].'?facid='.$fac->id.'&rowid='.$_GET["rowid"], $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteproductline'); - print '
'; - } - - /* - * Facture - */ - print ''; - - // Reference - print ''; - - // Ref client - /* - \todo - L'info "Reference commande client" est une carac de la commande et non de la facture. - Elle devrait donc etre stockée sur l'objet commande lié à la facture et non sur la facture. - Pour ceux qui utilisent ainsi, positionner la constante FAC_USE_CUSTOMER_ORDER_REF à 1. - */ - if ($conf->global->FAC_USE_CUSTOMER_ORDER_REF) - { - print ''; - print ''; - } - - // Tiers Société - print ''; - print ''; - print ''; - - // Type - print ''; - - // Ligne info remises tiers - print ''; - - // Dates - print ''; - print ''; - - $nbrows=8; - if ($conf->global->FAC_USE_CUSTOMER_ORDER_REF) $nbrows++; - if ($conf->projet->enabled) $nbrows++; - - print ''; - - // Date limite reglement - print ''; - print ''; - print ''; - - // Conditions de réglement - print ''; - - // Mode de reglement - print ''; - - // Lit lignes de facture pour déterminer montant - // On s'en sert pas mais ca sert pour debuggage - $sql = 'SELECT l.price as price, l.qty, l.rowid, l.tva_taux,'; - $sql .= ' l.remise_percent, l.subprice'; - $sql .= ' FROM '.MAIN_DB_PREFIX.'facturedet as l '; - $sql .= ' WHERE l.fk_facture = '.$fac->id; - $resql = $db->query($sql); - if ($resql) - { - $num_lignes = $db->num_rows($resql); - $i=0; - $total_lignes_ht=0; - $total_lignes_vat=0; - $total_lignes_ttc=0; - while ($i < $num_lignes) - { - $obj=$db->fetch_object($resql); - $ligne_ht=($obj->price*$obj->qty); - $ligne_vat=($ligne_ht*$obj->tva_taux/100); - $ligne_ttc=($ligne_ht+$ligne_vat); - $total_lignes_ht+=$ligne_ht; - $total_lignes_vat+=$ligne_vat; - $total_lignes_ttc+=$ligne_ttc; - $i++; - } - } - - // Montants - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - - // Statut - print ''; - print ''; - - // Projet - if ($conf->projet->enabled) - { - $langs->load('projects'); - print ''; - print ''; - print ''; - } - - print '
'.$langs->trans('Ref').''.$fac->ref.'
'; - print ''; - if ($_GET['action'] != 'RefCustomerOrder' && $fac->brouillon) print ''; - print '
'; - print $langs->trans('RefCustomerOrder').''; - print ''.img_edit($langs->trans('Edit')).'
'; - print '
'; - if ($user->rights->facture->creer && $_GET['action'] == 'RefCustomerOrder') - { - print '
'; - print ''; - print ''; - print ' '; - print '
'; - } - else - { - print $fac->ref_client; - } - print '
'.$langs->trans('Company').''.$soc->getNomUrl(1,'compta').'
'.$langs->trans('Type').''; - print $fac->getLibType(); - if ($fac->type == 1) - { - $facreplaced=new Facture($db); - $facreplaced->fetch($fac->fk_facture_source); - print ' ('.$langs->transnoentities("ReplaceInvoice",$facreplaced->getNomUrl(1)).')'; - } - if ($fac->type == 2) - { - $facreplaced=new Facture($db); - $facreplaced->fetch($fac->fk_facture_source); - print ' ('.$langs->transnoentities("CorrectInvoice",$facreplaced->getNomUrl(1)).')'; - } - $facidavoir=$fac->getIdAvoirInvoice(); - if (sizeof($facidavoir) > 0) - { - print ' ('.$langs->transnoentities("InvoiceHasAvoir"); - $i=0; - foreach($facidavoir as $id) - { - if ($i==0) print ' '; - else print ','; - $facavoir=new Facture($db); - $facavoir->fetch($id); - print $facavoir->getNomUrl(1); - } - print ')'; - } - if ($facidnext > 0) - { - $facthatreplace=new Facture($db); - $facthatreplace->fetch($facidnext); - print ' ('.$langs->transnoentities("ReplacedByInvoice",$facthatreplace->getNomUrl(1)).')'; - } - print '
'.$langs->trans('Discounts').''; - if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",$soc->remise_client); - else print $langs->trans("CompanyHasNoRelativeDiscount"); - print '. '; - if ($absolute_discount) - { - if ($fac->statut > 0 || $fac->type == 2) - { - print $langs->trans("CompanyHasAbsoluteDiscount",$absolute_discount,$langs->trans("Currency".$conf->monnaie)); - } - else - { - print '
'; - print $html->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$fac->id,0,'remise_id',$soc->id,$absolute_discount); - } - } - else print $langs->trans("CompanyHasNoAbsoluteDiscount").'.'; - print '
'.$langs->trans('Date').''.dolibarr_print_date($fac->date,'%A %d %B %Y').''; - - /* - * Liste des paiements - */ - $sql = 'SELECT '.$db->pdate('datep').' as dp, pf.amount,'; - $sql.= ' c.libelle as paiement_type, p.num_paiement, p.rowid'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'paiement as p, '.MAIN_DB_PREFIX.'c_paiement as c, '.MAIN_DB_PREFIX.'paiement_facture as pf'; - $sql.= ' WHERE pf.fk_facture = '.$fac->id.' AND p.fk_paiement = c.id AND pf.fk_paiement = p.rowid'; - $sql.= ' ORDER BY dp DESC'; - - $result = $db->query($sql); - if ($result) - { - $num = $db->num_rows($result); - $i = 0; - print ''; - - if ($fac->type != 2) - { - // Liste des paiements - print ''; - print ''; - - $var=True; - while ($i < $num) - { - $objp = $db->fetch_object($result); - $var=!$var; - print ''; - print ''; - print ''; - print ''; - $i++; - } - - // Solde facture - print ''; - print ''; - if ($fac->close_code == 'escompte') - { - print ''; - } - print ''; - print ''; - } - else - { - // Solde avoir - print ''; - print ''; - } - print '
'.$langs->trans('Payments').''.$langs->trans('Type').''.$langs->trans('Amount').' 
'; - print ''.img_object($langs->trans('ShowPayment'),'payment').' '; - print dolibarr_print_date($objp->dp).''.$objp->paiement_type.' '.$objp->num_paiement.''.price($objp->amount).''.$langs->trans('Currency'.$conf->monnaie).'
'.$langs->trans('AlreadyPayed').' :'.price($totalpaye).''.$langs->trans('Currency'.$conf->monnaie).'
'.$langs->trans("Billed").' :'.price($fac->total_ttc).''.$langs->trans('Currency'.$conf->monnaie).'
'; - print $html->textwithhelp($langs->trans("Escompte").':',$langs->trans("HelpEscompte"),-1); - print ''.price($fac->total_ttc - $totalpaye).''.$langs->trans('Currency'.$conf->monnaie).'
'.$langs->trans('RemainderToPay').' :'.price($resteapayer).''.$langs->trans('Currency'.$conf->monnaie).'
'.$langs->trans('TotalTTCToYourCredit').' :'.price(abs($fac->total_ttc)).''.$langs->trans('Currency'.$conf->monnaie).'
'; - $db->free($result); - } - else - { - dolibarr_print_error($db); - } - - print '
'.$langs->trans('DateMaxPayment').''; - if ($fac->type != 2) - { - print dolibarr_print_date($fac->date_lim_reglement,'%A %d %B %Y'); - if ($fac->date_lim_reglement < (time() - $conf->facture->client->warning_delay) && ! $fac->paye && $fac->statut == 1 && ! $fac->am) print img_warning($langs->trans('Late')); - } - else - { - print ' '; - } - print '
'; - print ''; - if ($fac->type != 2 && $_GET['action'] != 'editconditions' && $fac->brouillon && $user->rights->facture->creer) print ''; - print '
'; - print $langs->trans('PaymentConditionsShort'); - print 'id.'">'.img_edit($langs->trans('SetConditions'),1).'
'; - print '
'; - if ($fac->type != 2) - { - if ($_GET['action'] == 'editconditions') - { - $html->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$fac->id,$fac->cond_reglement_id,'cond_reglement_id'); - } - else - { - $html->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$fac->id,$fac->cond_reglement_id,'none'); - } - } - else - { - print ' '; - } - print '
'; - print ''; - if ($_GET['action'] != 'editmode' && $fac->brouillon && $user->rights->facture->creer) print ''; - print '
'; - print $langs->trans('PaymentMode'); - print 'id.'">'.img_edit($langs->trans('SetMode'),1).'
'; - print '
'; - if ($_GET['action'] == 'editmode') - { - $html->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$fac->id,$fac->mode_reglement_id,'mode_reglement_id'); - } - else - { - $html->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$fac->id,$fac->mode_reglement_id,'none'); - } - print '
'.$langs->trans('AmountHT').''.price($fac->total_ht).''.$langs->trans('Currency'.$conf->monnaie).'
'.$langs->trans('AmountVAT').''.price($fac->total_tva).''.$langs->trans('Currency'.$conf->monnaie).'
'.$langs->trans('AmountTTC').''.price($fac->total_ttc).''.$langs->trans('Currency'.$conf->monnaie).'
'.$langs->trans('Status').''.($fac->getLibStatut(4,$totalpaye)).'
'; - - print ''; - if ($_GET['action'] != 'classer') - { - print ''; - } - print '
'; - print $langs->trans('Project'); - print 'id.'">'; - print img_edit($langs->trans('SetProject'),1); - print '
'; - - print '
'; - if ($_GET['action'] == 'classer') - { - $html->form_project($_SERVER['PHP_SELF'].'?facid='.$fac->id,$fac->socid,$fac->projetid,'projetid'); - } - else - { - $html->form_project($_SERVER['PHP_SELF'].'?facid='.$fac->id,$fac->socid,$fac->projetid,'none'); - } - print '

'; - - - /* - * Lignes de factures - */ - $sql = 'SELECT l.fk_product, l.description, l.price, l.qty, l.rowid, l.tva_taux,'; - $sql.= ' l.remise_percent, l.subprice, l.info_bits,'; - $sql.= ' '.$db->pdate('l.date_start').' as date_start,'; - $sql.= ' '.$db->pdate('l.date_end').' as date_end,'; - $sql.= ' p.ref, p.fk_product_type, p.label as product,'; - $sql.= ' p.description as product_desc'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet as l'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product p ON l.fk_product=p.rowid'; - $sql.= ' WHERE l.fk_facture = '.$fac->id; - $sql.= ' ORDER BY l.rang ASC, l.rowid'; - - $resql = $db->query($sql); - if ($resql) - { - $num_lignes = $db->num_rows($resql); - $i = 0; $total = 0; - - print ''; - - if ($num_lignes) - { - - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print "\n"; - - } - $var=true; - while ($i < $num_lignes) - { - $objp = $db->fetch_object($resql); - $var=!$var; - - // Ligne en mode visu - if ($_GET['action'] != 'editline' || $_GET['rowid'] != $objp->rowid) - { - print ''; - if ($objp->fk_product > 0) - { - print ''; - } - else - { - print '\n"; - } - print ''; - print '\n"; - print ''; - if ($objp->remise_percent > 0) - { - print '\n"; - } - else - { - print ''; - } - print '\n"; - - // Icone d'edition et suppression - if ($fac->statut == 0 && $user->rights->facture->creer) - { - print ''; - if ($conf->global->PRODUIT_CONFIRM_DELETE_LINE) - { - print ''; - print ''; - } - else - { - print ''; - } - print ''; - } - - // Ligne en mode update - if ($_GET['action'] == 'editline' && $user->rights->facture->creer && $_GET['rowid'] == $objp->rowid) - { - print 'rowid.'" method="post">'; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print '' . "\n"; - if ($conf->service->enabled) - { - print ''; - print ''; - print ''; - } - print "\n"; - } - - $total = $total + ($objp->qty * $objp->price); - $i++; - } - - $db->free($resql); - } - else - { - dolibarr_print_error($db); - } - - /* - * Lignes de remise - */ - - // Réductions relatives (Remises-Ristournes-Rabbais) - /* Une réduction doit s'appliquer obligatoirement sur des lignes de factures - $var=!$var; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - if ($_GET['action'] != 'editrelativediscount') - { - if ($fac->brouillon && $user->rights->facture->creer) - { - print ''; - } - else - { - print ''; - } - if ($fac->brouillon && $user->rights->facture->creer && $fac->remise_percent) - { - print ''; - } - else - { - print ''; - } - print ''; - } - else - { - print ''; - } - print ''; - print ''; - */ - - // Réductions absolues (Remises-Ristournes-Rabbais) - /* Les remises absolues doivent s'appliquer par ajout de lignes spécialisées - $var=!$var; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - if ($_GET['action'] != 'editabsolutediscount') - { - if ($fac->brouillon && $user->rights->facture->creer) - { - print ''; - } - else - { - print ''; - } - if ($fac->brouillon && $user->rights->facture->creer && $fac->remise_absolue) - { - print ''; - } - else - { - print ''; - } - print ''; - } - else - { - print ''; - } - print ''; - print ''; - */ - - /* - * Ajouter une ligne - */ - if ($fac->statut == 0 && $user->rights->facture->creer && $_GET['action'] <> 'valid') - { - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print "\n"; - - // Ajout produit produits/services personalisés - print ''; - print ''; - print ''; - - $var=true; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - if ($conf->service->enabled) - { - print ''; - print ''; - print ''; - } - print ''; - - // Ajout de produits/services prédéfinis - if ($conf->produit->enabled) - { - print ''; - print ''; - print ''; - - $var=! $var; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - if ($conf->service->enabled) - { - print ''; - print ''; - print ''; - } - print ''; - } - - } - print "
'.$langs->trans('Description').''.$langs->trans('VAT').''.$langs->trans('PriceUHT').''.$langs->trans('Qty').''.$langs->trans('ReductionShort').''.$langs->trans('AmountHT').'   
'; - print ''; // ancre pour retourner sur la ligne - print ''; - if ($objp->fk_product_type) print img_object($langs->trans('ShowService'),'service'); - else print img_object($langs->trans('ShowProduct'),'product'); - print ' '.$objp->ref.''; - print ' - '.nl2br(stripslashes($objp->product)); - print_date_range($objp->date_start,$objp->date_end); - print ($objp->description && $objp->description!=$objp->product)?'
'.stripslashes(nl2br($objp->description)):''; - - // \todo Ne faut-il pas rendre $conf->global->PRODUIT_CHANGE_PROD_DESC toujours a on - if ($conf->global->PRODUIT_DESC_IN_FORM && !$conf->global->PRODUIT_CHANGE_PROD_DESC) - { - print '
'.nl2br($objp->product_desc); - } - - print '
'; - print ''; // ancre pour retourner sur la ligne - if (($objp->info_bits & 2) == 2) - { - print ''; - print img_object($langs->trans("ShowReduc"),'reduc').' '.$langs->trans("Discount"); - print ''; - if ($objp->description) print ' - '.nl2br($objp->description); - } - else - { - print nl2br($objp->description); - print_date_range($objp->date_start,$objp->date_end); - } - print "'.$objp->tva_taux.'%'.price($objp->subprice)."'; - if (($objp->info_bits & 2) != 2) - { - print $objp->qty; - } - else print ' '; - print ''.$objp->remise_percent."% '.price($objp->subprice*$objp->qty*(100-$objp->remise_percent)/100)."rowid.'#'.$objp->rowid.'">'; - print img_edit(); - print 'rowid.'">'; - } - else - { - print 'rowid.'">'; - } - print img_delete(); - print ''; - if ($i > 0) - { - print 'rowid.'">'; - print img_up(); - print ''; - } - if ($i < $num_lignes-1) - { - print 'rowid.'">'; - print img_down(); - print ''; - } - print ' 
'; - print ''; // ancre pour retourner sur la ligne - if ($objp->fk_product > 0) - { - print ''; - if ($objp->fk_product_type) print img_object($langs->trans('ShowService'),'service'); - else print img_object($langs->trans('ShowProduct'),'product'); - print ' '.$objp->ref.''; - print ' - '.nl2br($objp->product); - print '
'; - } - // éditeur wysiwyg - if ($conf->fckeditor->enabled && $conf->global->FCKEDITOR_ENABLE_DETAILS) - { - require_once(DOL_DOCUMENT_ROOT."/lib/doleditor.class.php"); - $doleditor=new DolEditor('desc',$objp->description,164,'dolibarr_details'); - $doleditor->Create(); - } - else - { - print ''; - } - print '
'; - if(! $soc->tva_assuj) - print '0'; - else - print $html->select_tva('tva_tx',$objp->tva_taux,$mysoc,$soc); - print ''; - if (($objp->info_bits & 2) != 2) - { - print ''; - } - else print ' '; - print ''; - if (($objp->info_bits & 2) != 2) - { - print '%'; - } - else print ' '; - print ''; - print '
'.$langs->trans('ServiceLimitedDuration').' '.$langs->trans('From').' '; - print $html->select_date($objp->date_start,'date_start',0,0,$objp->date_start?0:1,"updateligne"); - print ' '.$langs->trans('to').' '; - print $html->select_date($objp->date_end,'date_end',0,0,$objp->date_end?0:1,"updateligne"); - print '
'; - print $langs->trans('CustomerRelativeDiscount'); - if ($fac->brouillon) print ' ('.($soc->remise_client?$langs->trans("CompanyHasRelativeDiscount",$soc->remise_client):$langs->trans("CompanyHasNoRelativeDiscount")).')'; - print '   '; - if ($_GET['action'] == 'editrelativediscount') - { - print '%'; - } - else - { - print $fac->remise_percent?$fac->remise_percent.'%':' '; - } - print ''; - if ($_GET['action'] != 'editrelativediscount') print $fac->remise_percent?'-'.price($fac->remise_percent*$total/100):$langs->trans("DiscountNone"); - else print ' '; - print 'id.'">'.img_edit($langs->trans('SetRelativeDiscount'),1).' rowid.'">'; - print img_delete(); - print '  
'; - print $langs->trans('CustomerAbsoluteDiscount'); - if ($fac->brouillon) print ' ('.($absolute_discount?$langs->trans("CompanyHasAbsoluteDiscount",$absolute_discount,$langs->trans("Currency".$conf->monnaie)):$langs->trans("CompanyHasNoAbsoluteDiscount")).')'; - print '    '; - if ($_GET['action'] == 'editabsolutediscount') - { - print '-'; - } - else - { - print $fac->remise_absolue?'-'.price($fac->remise_absolue):$langs->trans("DiscountNone"); - } - print 'id.'">'.img_edit($langs->trans('SetAbsoluteDiscount'),1).' rowid.'">'; - print img_delete(); - print '  
'; - print ''; // ancre - print $langs->trans('Description').''.$langs->trans('VAT').''.$langs->trans('PriceUHT').''.$langs->trans('Qty').''.$langs->trans('ReductionShort').'    
'; - print ''; - if($soc->tva_assuj == "0") - print '0'; - else - $html->select_tva('tva_tx',$conf->defaulttx,$mysoc,$soc); - print '%
'.$langs->trans('ServiceLimitedDuration').' '.$langs->trans('From').' '; - print $html->select_date('','date_start',0,0,1,"addligne"); - print ' '.$langs->trans('to').' '; - print $html->select_date('','date_end',0,0,1,"addligne"); - print '
'; - // multiprix - if($conf->global->PRODUIT_MULTIPRICES == 1) - $html->select_produits('','idprod','',$conf->produit->limit_size,$soc->price_level); - else - $html->select_produits('','idprod','',$conf->produit->limit_size); - if (! $conf->use_ajax) print '
'; - print '
 %
'.$langs->trans('ServiceLimitedDuration').' '.$langs->trans('From').' '; - print $html->select_date('','date_start_predef',0,0,1,"addligne_predef"); - print ' '.$langs->trans('to').' '; - print $html->select_date('','date_end_predef',0,0,1,"addligne_predef"); - print '
\n"; - - print "\n"; - - - /* - * Boutons actions - */ - - if ($user->societe_id == 0 && $_GET['action'] <> 'valid' && $_GET['action'] <> 'editline') - { - print '
'; - - // Editer une facture déjà validée, sans paiement effectué et pas exporté en compta - if ($fac->statut == 1) - { - // On vérifie si les lignes de factures ont été exportées en compta et/ou ventilées - $ventilExportCompta = $fac->getVentilExportCompta(); - - if ($conf->global->FACTURE_ENABLE_EDITDELETE && $user->rights->facture->modifier - && ($resteapayer == $fac->total_ttc && $fac->paye == 0 && $ventilExportCompta == 0)) - { - print ''.$langs->trans('Edit').''; - } - } - - // Récurrente - if (! $conf->global->FACTURE_DISABLE_RECUR) - { - print ''.$langs->trans("ChangeIntoRepeatableInvoice").''; - } - - // Valider - if ($fac->statut == 0 && $num_lignes > 0) - { - if ($user->rights->facture->valider) - { - print ''.$langs->trans('Validate').''; - } - } - else - { - // Générer - if ($fac->statut >= 1 && $user->rights->facture->creer) - { - if ($fac->paye == 0) - { - print ''.$langs->trans('BuildPDF').''; - } - else - { - print ''.$langs->trans('RebuildPDF').''; - } - } - } + $soc = new Societe($db, $fac->socid); + $soc->fetch($fac->socid); + $absolute_discount=$soc->getCurrentDiscount(); - // Envoyer - if ($fac->statut == 1 && $user->rights->facture->envoyer) - { - if ($facidnext) - { - print ''.$langs->trans('SendByMail').''; - } - else - { - print ''.$langs->trans('SendByMail').''; - } - } - - // Envoyer une relance - if ($fac->statut == 1 && $resteapayer > 0 && $user->rights->facture->envoyer) - { - if ($facidnext) - { - print ''.$langs->trans('SendRemindByMail').''; - } - else - { - print ''.$langs->trans('SendRemindByMail').''; - } - } - - // Emettre paiement - if ($fac->statut == 1 && $fac->paye == 0 && $user->rights->facture->paiement) - { - if ($facidnext) - { - print ''.$langs->trans('DoPaiement').''; - } - else - { - print ''.$langs->trans('DoPaiement').''; - } - } - - // Classer 'payé' - if ($fac->statut == 1 && $fac->paye == 0 && $user->rights->facture->paiement - && $resteapayer <= 0) - { - print ''.$langs->trans('ClassifyPayed').''; - } - - // Classer 'fermée' (possible si validée et pas encore classée payée) - if ($fac->statut == 1 && $fac->paye == 0 && $resteapayer > 0 - && $user->rights->facture->paiement) - { - if ($totalpaye > 0) - { - print ''.$langs->trans('ClassifyPayedPartially').''; - } - else - { - print ''.$langs->trans('ClassifyCanceled').''; - - // \todo - // Ajouter bouton "Annuler et Créer facture remplacement" - } - } - - // Supprimer - if ($fac->is_erasable() && $user->rights->facture->supprimer && $_GET['action'] != 'delete') - { - print ''.$langs->trans('Delete').''; - } - - print '
'; - } - - print ''; - print ''; - print ''; - print ''; - print ''; - print '
'; - print ''; // ancre - - /* - * Documents générés - */ - $filename=sanitize_string($fac->ref); - $filedir=$conf->facture->dir_output . '/' . sanitize_string($fac->ref); - $urlsource=$_SERVER['PHP_SELF'].'?facid='.$fac->id; - $genallowed=($fac->statut >= 1 && $user->rights->facture->creer); - $delallowed=$user->rights->facture->supprimer; - - $var=true; - - print '
'; - $somethingshown=$html->show_documents('facture',$filename,$filedir,$urlsource,$genallowed,$delallowed,$fac->modelpdf); - - /* - * Propales rattachées - */ - $sql = 'SELECT '.$db->pdate('p.datep').' as dp, p.price, p.ref, p.rowid as propalid'; - $sql .= ' FROM '.MAIN_DB_PREFIX.'propal as p'; - if (!$conf->commande->enabled) - { - $sql .= ", ".MAIN_DB_PREFIX."fa_pr as fp"; - $sql .= " WHERE fp.fk_propal = p.rowid AND fp.fk_facture = ".$fac->id; - } - else - { - $sql .= ", ".MAIN_DB_PREFIX."co_pr as cp, ".MAIN_DB_PREFIX."co_fa as cf"; - $sql .= " WHERE cf.fk_facture = ".$fac->id." AND cf.fk_commande = cp.fk_commande AND cp.fk_propale = p.rowid"; - } - - $resql = $db->query($sql); - if ($resql) - { - $num = $db->num_rows($resql); - if ($num) - { - $i = 0; $total = 0; - if ($somethingshown) print '
'; - $somethingshown=1; - print_titre($langs->trans('RelatedCommercialProposals')); - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - - $var=True; - while ($i < $num) - { - $objp = $db->fetch_object($resql); - $var=!$var; - print ''; - print ''; - print ''; - print ''; - print ''; - $total = $total + $objp->price; - $i++; - } - print ''; - print '
'.$langs->trans('Ref').''.$langs->trans('Date').''.$langs->trans('Price').'
'.img_object($langs->trans('ShowPropal'),'propal').' '.$objp->ref.''.dolibarr_print_date($objp->dp).''.price($objp->price).'
 '.$langs->trans('TotalHT').''.price($total).'
'; - } - } - else - { - dolibarr_print_error($db); - } - - /* - * Commandes rattachées - */ - if($conf->commande->enabled) - { - $sql = 'SELECT '.$db->pdate('c.date_commande').' as date_commande, c.total_ht, c.ref, c.ref_client, c.rowid as id'; - $sql .= ' FROM '.MAIN_DB_PREFIX.'commande as c, '.MAIN_DB_PREFIX.'co_fa as co_fa WHERE co_fa.fk_commande = c.rowid AND co_fa.fk_facture = '.$fac->id; - $resql = $db->query($sql); - if ($resql) - { - $num = $db->num_rows($resql); - if ($num) - { - $i = 0; $total = 0; - if ($somethingshown) print '
'; - $somethingshown=1; - print_titre($langs->trans('RelatedOrders')); - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - $var=true; - while ($i < $num) + $totalpaye = $fac->getSommePaiement(); + $resteapayer = $fac->total_ttc - $totalpaye; + if ($fac->paye) $resteapayer=0; + + $author = new User($db); + if ($fac->user_author) { - $objp = $db->fetch_object($resql); - $var=!$var; - print '\n"; - print ''; - print ''; - print ''; - print "\n"; - $total = $total + $objp->total_ht; - $i++; + $author->id = $fac->user_author; + $author->fetch(); + } + + $facidnext=$fac->getIdReplacingInvoice(); + + + $head = facture_prepare_head($fac); + + dolibarr_fiche_head($head, 'compta', $langs->trans('InvoiceCustomer')); + + /* + * Confirmation de la suppression de la facture + */ + if ($_GET['action'] == 'delete') + { + $text=$langs->trans('ConfirmDeleteBill'); + $html->form_confirm($_SERVER['PHP_SELF'].'?facid='.$fac->id,$langs->trans('DeleteBill'),$text,'confirm_delete'); + print '
'; + } + + /* + * Confirmation de la validation + */ + if ($_GET['action'] == 'valid') + { + // on vérifie si la facture est en numérotation provisoire + $facref = substr($fac->ref, 1, 4); + if ($facref == 'PROV') + { + $numfa = $fac->getNextNumRef($soc); + } + else + { + $numfa = $fac->ref; + } + + $text=$langs->trans('ConfirmValidateBill',$numfa); + if ($conf->notification->enabled) + { + require_once(DOL_DOCUMENT_ROOT ."/notify.class.php"); + $notify=new Notify($db); + $text.='
'; + $text.=$notify->confirmMessage(2,$fac->socid); + } + + $html->form_confirm($_SERVER["PHP_SELF"].'?facid='.$fac->id,$langs->trans('ValidateBill'),$text,'confirm_valid'); + print '
'; + } + + /* + * Confirmation du classement payé + */ + if ($_GET['action'] == 'payed' && $resteapayer <= 0) + { + $html->form_confirm($_SERVER["PHP_SELF"].'?facid='.$fac->id,$langs->trans('ClassifyPayed'),$langs->trans('ConfirmClassifyPayedBill',$fac->ref),'confirm_payed'); + print '
'; + } + if ($_GET['action'] == 'payed' && $resteapayer > 0) + { + // Code + $close[0]['code']='discount_vat'; + $close[1]['code']='badcustomer'; + $close[2]['code']='abandon'; + // Help + $close[0]['label']=$langs->trans("HelpEscompte").'

'.$langs->trans("ConfirmClassifyPayedPartiallyVat"); + $close[1]['label']=$langs->trans("ConfirmClassifyPayedPartiallyBadCustomer"); + $close[2]['label']=$langs->trans("ConfirmClassifyPayedPartiallyOther"); + // Texte + $close[0]['reason']=$html->textwithhelp($langs->transnoentities("ConfirmClassifyPayedPartiallyReasonDiscountVat",$resteapayer,$langs->trans("Currency".$conf->monnaie)),$close[0]['label'],1); + $close[1]['reason']=$html->textwithhelp($langs->transnoentities("ConfirmClassifyPayedPartiallyReasonBadCustomer",$resteapayer,$langs->trans("Currency".$conf->monnaie)),$close[1]['label'],1); + $close[2]['reason']=$html->textwithhelp($langs->transnoentities("ConfirmClassifyPayedPartiallyReasonOther",$resteapayer,$langs->trans("Currency".$conf->monnaie)),$close[2]['label'],1); + // arrayreasons + $arrayreasons[$close[0]['code']]=$close[0]['reason']; + $arrayreasons[$close[1]['code']]=$close[1]['reason']; + $arrayreasons[$close[2]['code']]=$close[2]['reason']; + + // Crée un tableau formulaire + $formquestion=array( + 'text' => $langs->trans("ConfirmClassifyPayedPartiallyQuestion"), + array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons), + array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100') + ); + // Paiement incomplet. On demande si motif = escompte ou autre + $html->form_confirm($_SERVER["PHP_SELF"].'?facid='.$fac->id,$langs->trans('ClassifyPayed'),$langs->trans('ConfirmClassifyPayedPartially',$fac->ref),'confirm_payed_partially',$formquestion); + print '
'; + } + + /* + * Confirmation du classement abandonne + */ + if ($_GET['action'] == 'canceled') + { + // S'il y a une facture de remplacement pas encore validée (etat brouillon), + // on ne permet pas de classer abandonner la facture. + if ($facidnext) + { + $facturereplacement=new Facture($db); + $facturereplacement->fetch($facidnext); + $statusreplacement=$facturereplacement->statut; + } + if ($facidnext && $statusreplacement == 0) + { + print '
'.$langs->trans("ErrorCantCancelIfReplacementInvoiceNotValidated").'
'; + } + else + { + $html->form_confirm($_SERVER['PHP_SELF'].'?facid='.$fac->id,$langs->trans('CancelBill'),$langs->trans('ConfirmCancelBill',$fac->ref),'confirm_canceled'); + print '
'; + } + } + + /* + * Confirmation de la suppression d'une ligne produit + */ + if ($_GET['action'] == 'delete_product_line' && $conf->global->PRODUIT_CONFIRM_DELETE_LINE) + { + $html->form_confirm($_SERVER["PHP_SELF"].'?facid='.$fac->id.'&rowid='.$_GET["rowid"], $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteproductline'); + print '
'; + } + + /* + * Facture + */ + print '
'.$langs->trans('Ref').''.$langs->trans('RefCustomerOrderShort').''.$langs->trans('Date').''.$langs->trans('AmountHT').'
'; - print ''.img_object($langs->trans('ShowOrder'), 'order').' '.$objp->ref."'.$objp->ref_client.''.dolibarr_print_date($objp->date_commande).''.price($objp->total_ht).'
'; + + // Reference + print ''; + + // Ref client + /* + \todo + L'info "Reference commande client" est une carac de la commande et non de la facture. + Elle devrait donc etre stockée sur l'objet commande lié à la facture et non sur la facture. + Pour ceux qui utilisent ainsi, positionner la constante FAC_USE_CUSTOMER_ORDER_REF à 1. + */ + if ($conf->global->FAC_USE_CUSTOMER_ORDER_REF) + { + print ''; + print ''; + } + + // Tiers Société + print ''; + print ''; + print ''; + + // Type + print ''; + + // Ligne info remises tiers + print ''; + + // Dates + print ''; + print ''; + + $nbrows=8; + if ($conf->global->FAC_USE_CUSTOMER_ORDER_REF) $nbrows++; + if ($conf->projet->enabled) $nbrows++; + + print ''; + + // Date limite reglement + print ''; + print ''; + print ''; + + // Conditions de réglement + print ''; + + // Mode de reglement + print ''; + + // Lit lignes de facture pour déterminer montant + // On s'en sert pas mais ca sert pour debuggage + $sql = 'SELECT l.price as price, l.qty, l.rowid, l.tva_taux,'; + $sql .= ' l.remise_percent, l.subprice'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'facturedet as l '; + $sql .= ' WHERE l.fk_facture = '.$fac->id; + $resql = $db->query($sql); + if ($resql) + { + $num_lignes = $db->num_rows($resql); + $i=0; + $total_lignes_ht=0; + $total_lignes_vat=0; + $total_lignes_ttc=0; + while ($i < $num_lignes) + { + $obj=$db->fetch_object($resql); + $ligne_ht=($obj->price*$obj->qty); + $ligne_vat=($ligne_ht*$obj->tva_taux/100); + $ligne_ttc=($ligne_ht+$ligne_vat); + $total_lignes_ht+=$ligne_ht; + $total_lignes_vat+=$ligne_vat; + $total_lignes_ttc+=$ligne_ttc; + $i++; + } + } + + // Montants + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + // Statut + print ''; + print ''; + + // Projet + if ($conf->projet->enabled) + { + $langs->load('projects'); + print ''; + print ''; + print ''; + } + + print '
'.$langs->trans('Ref').''.$fac->ref.'
'; + print ''; + if ($_GET['action'] != 'RefCustomerOrder' && $fac->brouillon) print ''; + print '
'; + print $langs->trans('RefCustomerOrder').''; + print ''.img_edit($langs->trans('Edit')).'
'; + print '
'; + if ($user->rights->facture->creer && $_GET['action'] == 'RefCustomerOrder') + { + print '
'; + print ''; + print ''; + print ' '; + print '
'; + } + else + { + print $fac->ref_client; + } + print '
'.$langs->trans('Company').''.$soc->getNomUrl(1,'compta').'
'.$langs->trans('Type').''; + print $fac->getLibType(); + if ($fac->type == 1) + { + $facreplaced=new Facture($db); + $facreplaced->fetch($fac->fk_facture_source); + print ' ('.$langs->transnoentities("ReplaceInvoice",$facreplaced->getNomUrl(1)).')'; + } + if ($fac->type == 2) + { + $facreplaced=new Facture($db); + $facreplaced->fetch($fac->fk_facture_source); + print ' ('.$langs->transnoentities("CorrectInvoice",$facreplaced->getNomUrl(1)).')'; + } + $facidavoir=$fac->getIdAvoirInvoice(); + if (sizeof($facidavoir) > 0) + { + print ' ('.$langs->transnoentities("InvoiceHasAvoir"); + $i=0; + foreach($facidavoir as $id) + { + if ($i==0) print ' '; + else print ','; + $facavoir=new Facture($db); + $facavoir->fetch($id); + print $facavoir->getNomUrl(1); + } + print ')'; + } + if ($facidnext > 0) + { + $facthatreplace=new Facture($db); + $facthatreplace->fetch($facidnext); + print ' ('.$langs->transnoentities("ReplacedByInvoice",$facthatreplace->getNomUrl(1)).')'; + } + print '
'.$langs->trans('Discounts').''; + if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",$soc->remise_client); + else print $langs->trans("CompanyHasNoRelativeDiscount"); + print '. '; + if ($absolute_discount) + { + if ($fac->statut > 0 || $fac->type == 2) + { + print $langs->trans("CompanyHasAbsoluteDiscount",$absolute_discount,$langs->trans("Currency".$conf->monnaie)); + } + else + { + print '
'; + print $html->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$fac->id,0,'remise_id',$soc->id,$absolute_discount); + } + } + else print $langs->trans("CompanyHasNoAbsoluteDiscount").'.'; + print '
'.$langs->trans('Date').''.dolibarr_print_date($fac->date,'%A %d %B %Y').''; + + /* + * Liste des paiements + */ + $sql = 'SELECT '.$db->pdate('datep').' as dp, pf.amount,'; + $sql.= ' c.libelle as paiement_type, p.num_paiement, p.rowid'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'paiement as p, '.MAIN_DB_PREFIX.'c_paiement as c, '.MAIN_DB_PREFIX.'paiement_facture as pf'; + $sql.= ' WHERE pf.fk_facture = '.$fac->id.' AND p.fk_paiement = c.id AND pf.fk_paiement = p.rowid'; + $sql.= ' ORDER BY dp DESC'; + + $result = $db->query($sql); + if ($result) + { + $num = $db->num_rows($result); + $i = 0; + print ''; + + if ($fac->type != 2) + { + // Liste des paiements + print ''; + print ''; + + $var=True; + while ($i < $num) + { + $objp = $db->fetch_object($result); + $var=!$var; + print ''; + print ''; + print ''; + print ''; + $i++; + } + + // Already payed + print ''; + // Facturé + print ''; + $resteapayeraffiche=$resteapayer; + // Escompte + if ($fac->close_code == 'escompte') + { + print ''; + $resteapayeraffiche=0; + } + // Abandon bad customer + if ($fac->close_code == 'badcustomer') + { + print ''; + $resteapayeraffiche=0; + } + // Abandon other + if ($fac->close_code == 'abandon') + { + print ''; + $resteapayeraffiche=0; + } + print ''; + print ''; + } + else + { + // Solde avoir + print ''; + print ''; + } + print '
'.$langs->trans('Payments').''.$langs->trans('Type').''.$langs->trans('Amount').' 
'; + print ''.img_object($langs->trans('ShowPayment'),'payment').' '; + print dolibarr_print_date($objp->dp).''.$objp->paiement_type.' '.$objp->num_paiement.''.price($objp->amount).''.$langs->trans('Currency'.$conf->monnaie).'
'.$langs->trans('AlreadyPayed').' :'.price($totalpaye).''.$langs->trans('Currency'.$conf->monnaie).'
'.$langs->trans("Billed").' :'.price($fac->total_ttc).''.$langs->trans('Currency'.$conf->monnaie).'
'; + print $html->textwithhelp($langs->trans("Escompte").':',$langs->trans("HelpEscompte"),-1); + print ''.price($fac->total_ttc - $totalpaye).''.$langs->trans('Currency'.$conf->monnaie).'
'; + print $html->textwithhelp($langs->trans("Abandoned").':',$langs->trans("HelpAbandonBadCustomer"),-1); + print ''.price($fac->total_ttc - $totalpaye).''.$langs->trans('Currency'.$conf->monnaie).'
'; + print $html->textwithhelp($langs->trans("Abandoned").':',$langs->trans("HelpAbandonOther"),-1); + print ''.price($fac->total_ttc - $totalpaye).''.$langs->trans('Currency'.$conf->monnaie).'
'.$langs->trans('RemainderToPay').' :'.price($resteapayeraffiche).''.$langs->trans('Currency'.$conf->monnaie).'
'.$langs->trans('TotalTTCToYourCredit').' :'.price(abs($fac->total_ttc)).''.$langs->trans('Currency'.$conf->monnaie).'
'; + $db->free($result); + } + else + { + dolibarr_print_error($db); + } + + print '
'.$langs->trans('DateMaxPayment').''; + if ($fac->type != 2) + { + print dolibarr_print_date($fac->date_lim_reglement,'%A %d %B %Y'); + if ($fac->date_lim_reglement < (time() - $conf->facture->client->warning_delay) && ! $fac->paye && $fac->statut == 1 && ! $fac->am) print img_warning($langs->trans('Late')); + } + else + { + print ' '; + } + print '
'; + print ''; + if ($fac->type != 2 && $_GET['action'] != 'editconditions' && $fac->brouillon && $user->rights->facture->creer) print ''; + print '
'; + print $langs->trans('PaymentConditionsShort'); + print 'id.'">'.img_edit($langs->trans('SetConditions'),1).'
'; + print '
'; + if ($fac->type != 2) + { + if ($_GET['action'] == 'editconditions') + { + $html->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$fac->id,$fac->cond_reglement_id,'cond_reglement_id'); + } + else + { + $html->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$fac->id,$fac->cond_reglement_id,'none'); + } + } + else + { + print ' '; + } + print '
'; + print ''; + if ($_GET['action'] != 'editmode' && $fac->brouillon && $user->rights->facture->creer) print ''; + print '
'; + print $langs->trans('PaymentMode'); + print 'id.'">'.img_edit($langs->trans('SetMode'),1).'
'; + print '
'; + if ($_GET['action'] == 'editmode') + { + $html->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$fac->id,$fac->mode_reglement_id,'mode_reglement_id'); + } + else + { + $html->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$fac->id,$fac->mode_reglement_id,'none'); + } + print '
'.$langs->trans('AmountHT').''.price($fac->total_ht).''.$langs->trans('Currency'.$conf->monnaie).'
'.$langs->trans('AmountVAT').''.price($fac->total_tva).''.$langs->trans('Currency'.$conf->monnaie).'
'.$langs->trans('AmountTTC').''.price($fac->total_ttc).''.$langs->trans('Currency'.$conf->monnaie).'
'.$langs->trans('Status').''.($fac->getLibStatut(4,$totalpaye)).'
'; + + print ''; + if ($_GET['action'] != 'classer') + { + print ''; + } + print '
'; + print $langs->trans('Project'); + print 'id.'">'; + print img_edit($langs->trans('SetProject'),1); + print '
'; + + print '
'; + if ($_GET['action'] == 'classer') + { + $html->form_project($_SERVER['PHP_SELF'].'?facid='.$fac->id,$fac->socid,$fac->projetid,'projetid'); + } + else + { + $html->form_project($_SERVER['PHP_SELF'].'?facid='.$fac->id,$fac->socid,$fac->projetid,'none'); + } + print '

'; + + + /* + * Lignes de factures + */ + $sql = 'SELECT l.fk_product, l.description, l.price, l.qty, l.rowid, l.tva_taux,'; + $sql.= ' l.remise_percent, l.subprice, l.info_bits,'; + $sql.= ' '.$db->pdate('l.date_start').' as date_start,'; + $sql.= ' '.$db->pdate('l.date_end').' as date_end,'; + $sql.= ' p.ref, p.fk_product_type, p.label as product,'; + $sql.= ' p.description as product_desc'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet as l'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product p ON l.fk_product=p.rowid'; + $sql.= ' WHERE l.fk_facture = '.$fac->id; + $sql.= ' ORDER BY l.rang ASC, l.rowid'; + + $resql = $db->query($sql); + if ($resql) + { + $num_lignes = $db->num_rows($resql); + $i = 0; $total = 0; + + print ''; + + if ($num_lignes) + { + + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print "\n"; + + } + $var=true; + while ($i < $num_lignes) + { + $objp = $db->fetch_object($resql); + $var=!$var; + + // Ligne en mode visu + if ($_GET['action'] != 'editline' || $_GET['rowid'] != $objp->rowid) + { + print ''; + if ($objp->fk_product > 0) + { + print ''; + } + else + { + print '\n"; + } + print ''; + print '\n"; + print ''; + if ($objp->remise_percent > 0) + { + print '\n"; + } + else + { + print ''; + } + print '\n"; + + // Icone d'edition et suppression + if ($fac->statut == 0 && $user->rights->facture->creer) + { + print ''; + if ($conf->global->PRODUIT_CONFIRM_DELETE_LINE) + { + print ''; + print ''; + } + else + { + print ''; + } + print ''; + } + + // Ligne en mode update + if ($_GET['action'] == 'editline' && $user->rights->facture->creer && $_GET['rowid'] == $objp->rowid) + { + print 'rowid.'" method="post">'; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print '' . "\n"; + if ($conf->service->enabled) + { + print ''; + print ''; + print ''; + } + print "\n"; + } + + $total = $total + ($objp->qty * $objp->price); + $i++; + } + + $db->free($resql); + } + else + { + dolibarr_print_error($db); + } + + /* + * Ajouter une ligne + */ + if ($fac->statut == 0 && $user->rights->facture->creer && $_GET['action'] <> 'valid') + { + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print "\n"; + + // Ajout produit produits/services personalisés + print ''; + print ''; + print ''; + + $var=true; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + if ($conf->service->enabled) + { + print ''; + print ''; + print ''; + } + print ''; + + // Ajout de produits/services prédéfinis + if ($conf->produit->enabled) + { + print ''; + print ''; + print ''; + + $var=! $var; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + if ($conf->service->enabled) + { + print ''; + print ''; + print ''; + } + print ''; + } + + } + print "
'.$langs->trans('Description').''.$langs->trans('VAT').''.$langs->trans('PriceUHT').''.$langs->trans('Qty').''.$langs->trans('ReductionShort').''.$langs->trans('AmountHT').'   
'; + print ''; // ancre pour retourner sur la ligne + print ''; + if ($objp->fk_product_type) print img_object($langs->trans('ShowService'),'service'); + else print img_object($langs->trans('ShowProduct'),'product'); + print ' '.$objp->ref.''; + print ' - '.nl2br(stripslashes($objp->product)); + print_date_range($objp->date_start,$objp->date_end); + print ($objp->description && $objp->description!=$objp->product)?'
'.stripslashes(nl2br($objp->description)):''; + + // \todo Ne faut-il pas rendre $conf->global->PRODUIT_CHANGE_PROD_DESC toujours a on + if ($conf->global->PRODUIT_DESC_IN_FORM && !$conf->global->PRODUIT_CHANGE_PROD_DESC) + { + print '
'.nl2br($objp->product_desc); + } + + print '
'; + print ''; // ancre pour retourner sur la ligne + if (($objp->info_bits & 2) == 2) + { + print ''; + print img_object($langs->trans("ShowReduc"),'reduc').' '.$langs->trans("Discount"); + print ''; + if ($objp->description) print ' - '.nl2br($objp->description); + } + else + { + print nl2br($objp->description); + print_date_range($objp->date_start,$objp->date_end); + } + print "'.$objp->tva_taux.'%'.price($objp->subprice)."'; + if (($objp->info_bits & 2) != 2) + { + print $objp->qty; + } + else print ' '; + print ''.$objp->remise_percent."% '.price($objp->subprice*$objp->qty*(100-$objp->remise_percent)/100)."rowid.'#'.$objp->rowid.'">'; + print img_edit(); + print 'rowid.'">'; + } + else + { + print 'rowid.'">'; + } + print img_delete(); + print ''; + if ($i > 0) + { + print 'rowid.'">'; + print img_up(); + print ''; + } + if ($i < $num_lignes-1) + { + print 'rowid.'">'; + print img_down(); + print ''; + } + print ' 
'; + print ''; // ancre pour retourner sur la ligne + if ($objp->fk_product > 0) + { + print ''; + if ($objp->fk_product_type) print img_object($langs->trans('ShowService'),'service'); + else print img_object($langs->trans('ShowProduct'),'product'); + print ' '.$objp->ref.''; + print ' - '.nl2br($objp->product); + print '
'; + } + // éditeur wysiwyg + if ($conf->fckeditor->enabled && $conf->global->FCKEDITOR_ENABLE_DETAILS) + { + require_once(DOL_DOCUMENT_ROOT."/lib/doleditor.class.php"); + $doleditor=new DolEditor('desc',$objp->description,164,'dolibarr_details'); + $doleditor->Create(); + } + else + { + print ''; + } + print '
'; + if(! $soc->tva_assuj) + print '0'; + else + print $html->select_tva('tva_tx',$objp->tva_taux,$mysoc,$soc); + print ''; + if (($objp->info_bits & 2) != 2) + { + print ''; + } + else print ' '; + print ''; + if (($objp->info_bits & 2) != 2) + { + print '%'; + } + else print ' '; + print ''; + print '
'.$langs->trans('ServiceLimitedDuration').' '.$langs->trans('From').' '; + print $html->select_date($objp->date_start,'date_start',0,0,$objp->date_start?0:1,"updateligne"); + print ' '.$langs->trans('to').' '; + print $html->select_date($objp->date_end,'date_end',0,0,$objp->date_end?0:1,"updateligne"); + print '
'; + print ''; // ancre + print $langs->trans('Description').''.$langs->trans('VAT').''.$langs->trans('PriceUHT').''.$langs->trans('Qty').''.$langs->trans('ReductionShort').'    
'; + print ''; + if($soc->tva_assuj == "0") + print '0'; + else + $html->select_tva('tva_tx',$conf->defaulttx,$mysoc,$soc); + print '%
'.$langs->trans('ServiceLimitedDuration').' '.$langs->trans('From').' '; + print $html->select_date('','date_start',0,0,1,"addligne"); + print ' '.$langs->trans('to').' '; + print $html->select_date('','date_end',0,0,1,"addligne"); + print '
'; + // multiprix + if($conf->global->PRODUIT_MULTIPRICES == 1) + $html->select_produits('','idprod','',$conf->produit->limit_size,$soc->price_level); + else + $html->select_produits('','idprod','',$conf->produit->limit_size); + if (! $conf->use_ajax) print '
'; + print '
 %
'.$langs->trans('ServiceLimitedDuration').' '.$langs->trans('From').' '; + print $html->select_date('','date_start_predef',0,0,1,"addligne_predef"); + print ' '.$langs->trans('to').' '; + print $html->select_date('','date_end_predef',0,0,1,"addligne_predef"); + print '
\n"; + + print "\n"; + + + /* + * Boutons actions + */ + if ($user->societe_id == 0 && $_GET['action'] <> 'valid' && $_GET['action'] <> 'editline') + { + print '
'; + + // Editer une facture déjà validée, sans paiement effectué et pas exporté en compta + if ($fac->statut == 1) + { + // On vérifie si les lignes de factures ont été exportées en compta et/ou ventilées + $ventilExportCompta = $fac->getVentilExportCompta(); + + if ($conf->global->FACTURE_ENABLE_EDITDELETE && $user->rights->facture->modifier + && ($resteapayer == $fac->total_ttc && $fac->paye == 0 && $ventilExportCompta == 0)) + { + print ''.$langs->trans('Edit').''; + } + } + + // Récurrente + if (! $conf->global->FACTURE_DISABLE_RECUR) + { + print ''.$langs->trans("ChangeIntoRepeatableInvoice").''; + } + + // Valider + if ($fac->statut == 0 && $num_lignes > 0) + { + if ($user->rights->facture->valider) + { + print ''.$langs->trans('Validate').''; + } + } + else + { + // Générer + if ($fac->statut >= 1 && $user->rights->facture->creer) + { + if ($fac->paye == 0) + { + print ''.$langs->trans('BuildPDF').''; + } + else + { + print ''.$langs->trans('RebuildPDF').''; + } + } + } + + // Envoyer + if ($fac->statut == 1 && $user->rights->facture->envoyer) + { + if ($facidnext) + { + print ''.$langs->trans('SendByMail').''; + } + else + { + print ''.$langs->trans('SendByMail').''; + } + } + + // Envoyer une relance + if ($fac->statut == 1 && $resteapayer > 0 && $user->rights->facture->envoyer) + { + if ($facidnext) + { + print ''.$langs->trans('SendRemindByMail').''; + } + else + { + print ''.$langs->trans('SendRemindByMail').''; + } + } + + // Emettre paiement + if ($fac->statut == 1 && $fac->paye == 0 && $user->rights->facture->paiement) + { + if ($facidnext) + { + print ''.$langs->trans('DoPaiement').''; + } + else + { + print ''.$langs->trans('DoPaiement').''; + } + } + + // Classer 'payé' + if ($fac->statut == 1 && $fac->paye == 0 && $user->rights->facture->paiement + && $resteapayer <= 0) + { + print ''.$langs->trans('ClassifyPayed').''; + } + + // Classer 'fermée' (possible si validée et pas encore classée payée) + if ($fac->statut == 1 && $fac->paye == 0 && $resteapayer > 0 + && $user->rights->facture->paiement) + { + if ($totalpaye > 0) + { + print ''.$langs->trans('ClassifyPayedPartially').''; + } + else + { + print ''.$langs->trans('ClassifyCanceled').''; + + // \todo + // Ajouter bouton "Annuler et Créer facture remplacement" + } + } + + // Supprimer + if ($fac->is_erasable() && $user->rights->facture->supprimer && $_GET['action'] != 'delete') + { + print ''.$langs->trans('Delete').''; + } + + print '
'; + } + + print '
'; + print ''; // ancre + + /* + * Documents générés + */ + $filename=sanitize_string($fac->ref); + $filedir=$conf->facture->dir_output . '/' . sanitize_string($fac->ref); + $urlsource=$_SERVER['PHP_SELF'].'?facid='.$fac->id; + $genallowed=($fac->statut >= 1 && $user->rights->facture->creer); + $delallowed=$user->rights->facture->supprimer; + + $var=true; + + print '
'; + $somethingshown=$html->show_documents('facture',$filename,$filedir,$urlsource,$genallowed,$delallowed,$fac->modelpdf); + + /* + * Propales rattachées + */ + $sql = 'SELECT '.$db->pdate('p.datep').' as dp, p.price, p.ref, p.rowid as propalid'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'propal as p'; + if (!$conf->commande->enabled) + { + $sql .= ", ".MAIN_DB_PREFIX."fa_pr as fp"; + $sql .= " WHERE fp.fk_propal = p.rowid AND fp.fk_facture = ".$fac->id; + } + else + { + $sql .= ", ".MAIN_DB_PREFIX."co_pr as cp, ".MAIN_DB_PREFIX."co_fa as cf"; + $sql .= " WHERE cf.fk_facture = ".$fac->id." AND cf.fk_commande = cp.fk_commande AND cp.fk_propale = p.rowid"; + } + + $resql = $db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + if ($num) + { + $i = 0; $total = 0; + if ($somethingshown) print '
'; + $somethingshown=1; + print_titre($langs->trans('RelatedCommercialProposals')); + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + $var=True; + while ($i < $num) + { + $objp = $db->fetch_object($resql); + $var=!$var; + print ''; + print ''; + print ''; + print ''; + print ''; + $total = $total + $objp->price; + $i++; + } + print ''; + print '
'.$langs->trans('Ref').''.$langs->trans('Date').''.$langs->trans('Price').'
'.img_object($langs->trans('ShowPropal'),'propal').' '.$objp->ref.''.dolibarr_print_date($objp->dp).''.price($objp->price).'
 '.$langs->trans('TotalHT').''.price($total).'
'; + } + } + else + { + dolibarr_print_error($db); + } + + /* + * Commandes rattachées + */ + if($conf->commande->enabled) + { + $sql = 'SELECT '.$db->pdate('c.date_commande').' as date_commande, c.total_ht, c.ref, c.ref_client, c.rowid as id'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'commande as c, '.MAIN_DB_PREFIX.'co_fa as co_fa WHERE co_fa.fk_commande = c.rowid AND co_fa.fk_facture = '.$fac->id; + $resql = $db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + if ($num) + { + $i = 0; $total = 0; + if ($somethingshown) print '
'; + $somethingshown=1; + print_titre($langs->trans('RelatedOrders')); + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + $var=true; + while ($i < $num) + { + $objp = $db->fetch_object($resql); + $var=!$var; + print '\n"; + print ''; + print ''; + print ''; + print "\n"; + $total = $total + $objp->total_ht; + $i++; + } + print ''; + print ''; + print ''; + print ''; + print ''; + print '
'.$langs->trans('Ref').''.$langs->trans('RefCustomerOrderShort').''.$langs->trans('Date').''.$langs->trans('AmountHT').'
'; + print ''.img_object($langs->trans('ShowOrder'), 'order').' '.$objp->ref."'.$objp->ref_client.''.dolibarr_print_date($objp->date_commande).''.price($objp->total_ht).'
'.$langs->trans('TotalHT').'  '.price($total).'
'; + } + } + else + { + dolibarr_print_error($db); + } + } + + print '
'; + + /* + * Liste des actions propres à la facture + */ + $sql = 'SELECT id, '.$db->pdate('a.datea').' as da, a.label, a.note, code'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'actioncomm as a, '.MAIN_DB_PREFIX.'user as u '; + $sql .= ' WHERE a.fk_user_author = u.rowid '; + $sql .= ' AND a.fk_action in (9,10) '; + $sql .= ' AND a.fk_soc = '.$fac->socid ; + $sql .= ' AND a.fk_facture = '.$fac->id; + + $resql = $db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + if ($num) + { + print '
'; + print_titre($langs->trans('ActionsOnBill')); + + $i = 0; $total = 0; + print ''; + print ''; + print "\n"; + + $var=True; + while ($i < $num) + { + $objp = $db->fetch_object($resql); + $var=!$var; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + $i++; + } + print '
'.$langs->trans('Ref').''.$langs->trans('Date').''.$langs->trans('Action').''.$langs->trans('By').'
'.img_object($langs->trans('ShowTask'),'task').' '.$objp->id.''.dolibarr_print_date($objp->da).''.stripslashes($objp->label).''.$objp->code.'
'; + } + } + else + { + dolibarr_print_error($db); + } + + print '
'; + + + /* + * Affiche formulaire mail + */ + if ($_GET['action'] == 'presend') + { + $facref = sanitize_string($fac->ref); + $file = $conf->facture->dir_output . '/' . $facref . '/' . $facref . '.pdf'; + + // Construit PDF si non existant + if (! is_readable($file)) + { + if ($_REQUEST['lang_id']) + { + $outputlangs = new Translate(DOL_DOCUMENT_ROOT ."/langs"); + $outputlangs->setDefaultLang($_REQUEST['lang_id']); + } + $result=facture_pdf_create($db, $fac->id, '', $_REQUEST['model'], $outputlangs); + if ($result <= 0) + { + dolibarr_print_error($db,$result); + exit; + } + } + + print '
'; + print_titre($langs->trans('SendBillByMail')); + + $liste[0]=' '; + foreach ($soc->thirdparty_and_contact_email_array() as $key=>$value) + { + $liste[$key]=$value; + } + + // Créé l'objet formulaire mail + include_once(DOL_DOCUMENT_ROOT.'/html.formmail.class.php'); + $formmail = new FormMail($db); + $formmail->fromname = $user->fullname; + $formmail->frommail = $user->email; + $formmail->withfrom=1; + $formmail->withto=$liste; + $formmail->withcc=1; + $formmail->withtopic=$langs->trans('SendBillRef','__FACREF__'); + $formmail->withfile=1; + $formmail->withbody=1; + $formmail->withdeliveryreceipt=1; + $formmail->withcancel=1; + // Tableau des substitutions + $formmail->substit['__FACREF__']=$fac->ref; + // Tableau des paramètres complémentaires du post + $formmail->param['action']='send'; + $formmail->param['models']='facture_send'; + $formmail->param['facid']=$fac->id; + $formmail->param['returnurl']=DOL_URL_ROOT.'/compta/facture.php?facid='.$fac->id; + + $formmail->show_form(); + + print '
'; + } + + if ($_GET['action'] == 'prerelance') + { + $facref = sanitize_string($fac->ref); + $file = $conf->facture->dir_output . '/' . $facref . '/' . $facref . '.pdf'; + + // Construit PDF si non existant + if (! is_readable($file)) + { + if ($_REQUEST['lang_id']) + { + $outputlangs = new Translate(DOL_DOCUMENT_ROOT ."/langs"); + $outputlangs->setDefaultLang($_REQUEST['lang_id']); + } + $result=facture_pdf_create($db, $fac->id, '', $_REQUEST['model'], $outputlangs); + if ($result <= 0) + { + dolibarr_print_error($db,$result); + exit; + } + } + + print '
'; + print_titre($langs->trans('SendReminderBillByMail')); + + $liste[0]=' '; + foreach ($soc->thirdparty_and_contact_email_array() as $key=>$value) + { + $liste[$key]=$value; + } + + // Créé l'objet formulaire mail + include_once(DOL_DOCUMENT_ROOT.'/html.formmail.class.php'); + $formmail = new FormMail($db); + $formmail->fromname = $user->fullname; + $formmail->frommail = $user->email; + $formmail->withfrom=1; + $formmail->withto=$liste; + $formmail->withcc=1; + $formmail->withtopic=$langs->trans('SendReminderBillRef','__FACREF__'); + $formmail->withfile=1; + $formmail->withbody=1; + $formmail->withdeliveryreceipt=1; + // Tableau des substitutions + $formmail->substit['__FACREF__']=$fac->ref; + // Tableau des paramètres complémentaires + $formmail->param['action']='relance'; + $formmail->param['models']='facture_relance'; + $formmail->param['facid']=$fac->id; + $formmail->param['returnurl']=DOL_URL_ROOT.'/compta/facture.php?facid='.$fac->id; + + $formmail->show_form(); + + print '
'; } - print '
'.$langs->trans('TotalHT').'  '.price($total).'
'; - } } - else + else { - dolibarr_print_error($db); + dolibarr_print_error($db,$fac->error); } - } + } + else + { + /*************************************************************************** + * * + * Mode Liste * + * * + ***************************************************************************/ + $page =$_GET['page']; + $sortorder=$_GET['sortorder']; + $sortfield=$_GET['sortfield']; + $month =$_GET['month']; + $year =$_GET['year']; + $limit = $conf->liste_limit; + $offset = $limit * $page ; - print ''; + if (! $sortorder) $sortorder='DESC'; + if (! $sortfield) $sortfield='f.datef'; - /* - * Liste des actions propres à la facture - */ - $sql = 'SELECT id, '.$db->pdate('a.datea').' as da, a.label, a.note, code'; - $sql .= ' FROM '.MAIN_DB_PREFIX.'actioncomm as a, '.MAIN_DB_PREFIX.'user as u '; - $sql .= ' WHERE a.fk_user_author = u.rowid '; - $sql .= ' AND a.fk_action in (9,10) '; - $sql .= ' AND a.fk_soc = '.$fac->socid ; - $sql .= ' AND a.fk_facture = '.$fac->id; + $facturestatic=new Facture($db); - $resql = $db->query($sql); - if ($resql) - { - $num = $db->num_rows($resql); - if ($num) + if ($page == -1) $page = 0 ; + + $sql = 'SELECT '; + $sql.= ' f.rowid as facid, f.facnumber, f.type, f.increment, f.total, f.total_ttc,'; + $sql.= ' '.$db->pdate('f.datef').' as df, '.$db->pdate('f.date_lim_reglement').' as datelimite,'; + $sql.= ' f.paye as paye, f.fk_statut,'; + $sql.= ' s.nom, s.idp'; + if (! $sall) $sql.= ' ,sum(pf.amount) as am'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'societe as s'; + $sql.= ','.MAIN_DB_PREFIX.'facture as f'; + if (! $sall) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'paiement_facture as pf ON f.rowid=pf.fk_facture '; + if ($sall) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'facturedet as fd ON f.rowid=fd.fk_facture '; + $sql.= ' WHERE f.fk_soc = s.idp'; + if ($socid) $sql .= ' AND s.idp = '.$socid; + if ($month > 0) $sql .= ' AND date_format(f.datef, \'%m\') = '.$month; + if ($_GET['filtre']) { - print '
'; - print_titre($langs->trans('ActionsOnBill')); - - $i = 0; $total = 0; - print ''; - print ''; - print "\n"; - - $var=True; - while ($i < $num) - { - $objp = $db->fetch_object($resql); - $var=!$var; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - $i++; - } - print '
'.$langs->trans('Ref').''.$langs->trans('Date').''.$langs->trans('Action').''.$langs->trans('By').'
'.img_object($langs->trans('ShowTask'),'task').' '.$objp->id.''.dolibarr_print_date($objp->da).''.stripslashes($objp->label).''.$objp->code.'
'; + $filtrearr = split(',', $_GET['filtre']); + foreach ($filtrearr as $fil) + { + $filt = split(':', $fil); + $sql .= ' AND ' . trim($filt[0]) . ' = ' . trim($filt[1]); + } } - } - else - { - dolibarr_print_error($db); - } - - print ''; - - - /* - * Affiche formulaire mail - */ - if ($_GET['action'] == 'presend') - { - $facref = sanitize_string($fac->ref); - $file = $conf->facture->dir_output . '/' . $facref . '/' . $facref . '.pdf'; - - // Construit PDF si non existant - if (! is_readable($file)) + if ($_GET['search_ref']) { - if ($_REQUEST['lang_id']) - { - $outputlangs = new Translate(DOL_DOCUMENT_ROOT ."/langs"); - $outputlangs->setDefaultLang($_REQUEST['lang_id']); - } - $result=facture_pdf_create($db, $fac->id, '', $_REQUEST['model'], $outputlangs); - if ($result <= 0) - { - dolibarr_print_error($db,$result); - exit; - } + $sql .= ' AND f.facnumber like \'%'.addslashes(trim($_GET['search_ref'])).'%\''; } - - print '
'; - print_titre($langs->trans('SendBillByMail')); - - $liste[0]=' '; - foreach ($soc->thirdparty_and_contact_email_array() as $key=>$value) + if ($_GET['search_societe']) { - $liste[$key]=$value; + $sql .= ' AND s.nom like \'%'.addslashes(trim($_GET['search_societe'])).'%\''; } - - // Créé l'objet formulaire mail - include_once(DOL_DOCUMENT_ROOT.'/html.formmail.class.php'); - $formmail = new FormMail($db); - $formmail->fromname = $user->fullname; - $formmail->frommail = $user->email; - $formmail->withfrom=1; - $formmail->withto=$liste; - $formmail->withcc=1; - $formmail->withtopic=$langs->trans('SendBillRef','__FACREF__'); - $formmail->withfile=1; - $formmail->withbody=1; - $formmail->withdeliveryreceipt=1; - $formmail->withcancel=1; - // Tableau des substitutions - $formmail->substit['__FACREF__']=$fac->ref; - // Tableau des paramètres complémentaires du post - $formmail->param['action']='send'; - $formmail->param['models']='facture_send'; - $formmail->param['facid']=$fac->id; - $formmail->param['returnurl']=DOL_URL_ROOT.'/compta/facture.php?facid='.$fac->id; - - $formmail->show_form(); - - print '
'; - } - - if ($_GET['action'] == 'prerelance') - { - $facref = sanitize_string($fac->ref); - $file = $conf->facture->dir_output . '/' . $facref . '/' . $facref . '.pdf'; - - // Construit PDF si non existant - if (! is_readable($file)) + if ($_GET['search_montant_ht']) { - if ($_REQUEST['lang_id']) - { - $outputlangs = new Translate(DOL_DOCUMENT_ROOT ."/langs"); - $outputlangs->setDefaultLang($_REQUEST['lang_id']); - } - $result=facture_pdf_create($db, $fac->id, '', $_REQUEST['model'], $outputlangs); - if ($result <= 0) - { - dolibarr_print_error($db,$result); - exit; - } + $sql .= ' AND f.total = \''.addslashes(trim($_GET['search_montant_ht'])).'\''; } - - print '
'; - print_titre($langs->trans('SendReminderBillByMail')); - - $liste[0]=' '; - foreach ($soc->thirdparty_and_contact_email_array() as $key=>$value) + if ($_GET['search_montant_ttc']) { - $liste[$key]=$value; + $sql .= ' AND f.total_ttc = \''.addslashes(trim($_GET['search_montant_ttc'])).'\''; } - - // Créé l'objet formulaire mail - include_once(DOL_DOCUMENT_ROOT.'/html.formmail.class.php'); - $formmail = new FormMail($db); - $formmail->fromname = $user->fullname; - $formmail->frommail = $user->email; - $formmail->withfrom=1; - $formmail->withto=$liste; - $formmail->withcc=1; - $formmail->withtopic=$langs->trans('SendReminderBillRef','__FACREF__'); - $formmail->withfile=1; - $formmail->withbody=1; - $formmail->withdeliveryreceipt=1; - // Tableau des substitutions - $formmail->substit['__FACREF__']=$fac->ref; - // Tableau des paramètres complémentaires - $formmail->param['action']='relance'; - $formmail->param['models']='facture_relance'; - $formmail->param['facid']=$fac->id; - $formmail->param['returnurl']=DOL_URL_ROOT.'/compta/facture.php?facid='.$fac->id; - - $formmail->show_form(); - - print '
'; - } - } - else - { - dolibarr_print_error($db,$fac->error); - } - } - else - { - /*************************************************************************** - * * - * Mode Liste * - * * - ***************************************************************************/ - $page =$_GET['page']; - $sortorder=$_GET['sortorder']; - $sortfield=$_GET['sortfield']; - $month =$_GET['month']; - $year =$_GET['year']; - $limit = $conf->liste_limit; - $offset = $limit * $page ; - - if (! $sortorder) $sortorder='DESC'; - if (! $sortfield) $sortfield='f.datef'; - - $facturestatic=new Facture($db); - - if ($page == -1) $page = 0 ; - - $sql = 'SELECT '; - $sql.= ' f.rowid as facid, f.facnumber, f.type, f.increment, f.total, f.total_ttc,'; - $sql.= ' '.$db->pdate('f.datef').' as df, '.$db->pdate('f.date_lim_reglement').' as datelimite,'; - $sql.= ' f.paye as paye, f.fk_statut,'; - $sql.= ' s.nom, s.idp'; - if (! $sall) $sql.= ' ,sum(pf.amount) as am'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'societe as s'; - $sql.= ','.MAIN_DB_PREFIX.'facture as f'; - if (! $sall) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'paiement_facture as pf ON f.rowid=pf.fk_facture '; - if ($sall) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'facturedet as fd ON f.rowid=fd.fk_facture '; - $sql.= ' WHERE f.fk_soc = s.idp'; - if ($socid) $sql .= ' AND s.idp = '.$socid; - if ($month > 0) $sql .= ' AND date_format(f.datef, \'%m\') = '.$month; - if ($_GET['filtre']) - { - $filtrearr = split(',', $_GET['filtre']); - foreach ($filtrearr as $fil) - { - $filt = split(':', $fil); - $sql .= ' AND ' . trim($filt[0]) . ' = ' . trim($filt[1]); - } - } - if ($_GET['search_ref']) - { - $sql .= ' AND f.facnumber like \'%'.addslashes(trim($_GET['search_ref'])).'%\''; - } - if ($_GET['search_societe']) - { - $sql .= ' AND s.nom like \'%'.addslashes(trim($_GET['search_societe'])).'%\''; - } - if ($_GET['search_montant_ht']) - { - $sql .= ' AND f.total = \''.addslashes(trim($_GET['search_montant_ht'])).'\''; - } - if ($_GET['search_montant_ttc']) - { - $sql .= ' AND f.total_ttc = \''.addslashes(trim($_GET['search_montant_ttc'])).'\''; - } - if ($year > 0) - { - $sql .= ' AND date_format(f.datef, \'%Y\') = '.$year; - } - if ($_POST['sf_ref']) - { - $sql .= ' AND f.facnumber like \'%'.addslashes(trim($_POST['sf_ref'])) . '%\''; - } - if ($sall) - { - $sql .= ' AND (s.nom like \'%'.addslashes($sall).'%\' OR f.facnumber like \'%'.addslashes($sall).'%\' OR f.note like \'%'.addslashes($sall).'%\' OR fd.description like \'%'.addslashes($sall).'%\')'; - } - - $sql .= ' GROUP BY f.rowid'; - - $sql .= ' ORDER BY '; - $listfield=split(',',$sortfield); - foreach ($listfield as $key => $value) - $sql.= $listfield[$key].' '.$sortorder.','; - $sql .= ' f.rowid DESC '; - - $sql .= $db->plimit($limit+1,$offset); - - $resql = $db->query($sql); - if ($resql) - { - $num = $db->num_rows($resql); - - if ($socid) - { - $soc = new Societe($db); - $soc->fetch($socid); - } - - print_barre_liste($langs->trans('BillsCustomers').' '.($socid?' '.$soc->nom:''),$page,'facture.php','&socid='.$socid,$sortfield,$sortorder,'',$num); - - $i = 0; - print '
'."\n"; - print ''; - print ''; - print_liste_field_titre($langs->trans('Ref'),$_SERVER['PHP_SELF'],'f.facnumber','','&socid='.$socid,'',$sortfield); - print_liste_field_titre($langs->trans('Date'),$_SERVER['PHP_SELF'],'f.datef','','&socid='.$socid,'align="center"',$sortfield); - print_liste_field_titre($langs->trans('Company'),$_SERVER['PHP_SELF'],'s.nom','','&socid='.$socid,'',$sortfield); - print_liste_field_titre($langs->trans('AmountHT'),$_SERVER['PHP_SELF'],'f.total','','&socid='.$socid,'align="right"',$sortfield); - print_liste_field_titre($langs->trans('AmountTTC'),$_SERVER['PHP_SELF'],'f.total_ttc','','&socid='.$socid,'align="right"',$sortfield); - print_liste_field_titre($langs->trans('Received'),$_SERVER['PHP_SELF'],'am','','&socid='.$socid,'align="right"',$sortfield); - print_liste_field_titre($langs->trans('Status'),$_SERVER['PHP_SELF'],'fk_statut,paye,am','','&socid='.$socid,'align="right"',$sortfield); - print ''; - - // Lignes des champs de filtre - - print ''; - print ''; - print '\n"; - - if ($num > 0) - { - $var=True; - $total=0; - $totalrecu=0; - - while ($i < min($num,$limit)) + if ($year > 0) { - $objp = $db->fetch_object($resql); - $var=!$var; - - print ''; - print '\n"; - - if ($objp->df > 0 ) - { - print ''; - } - else - { - print ''; - } - print ''; - print ''; - print ''; - print ''; - - // Affiche statut de la facture - print '\n"; - $total+=$objp->total; - $total_ttc+=$objp->total_ttc; - $totalrecu+=$objp->am; - $i++; + $sql .= ' AND date_format(f.datef, \'%Y\') = '.$year; } - - if (($offset + $num) <= $limit) + if ($_POST['sf_ref']) { - // Print total - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; + $sql .= ' AND f.facnumber like \'%'.addslashes(trim($_POST['sf_ref'])) . '%\''; + } + if ($sall) + { + $sql .= ' AND (s.nom like \'%'.addslashes($sall).'%\' OR f.facnumber like \'%'.addslashes($sall).'%\' OR f.note like \'%'.addslashes($sall).'%\' OR fd.description like \'%'.addslashes($sall).'%\')'; } - } - print "
'; - print ''; - print ' '; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print "
'; - $facturestatic->id=$objp->facid; - $facturestatic->ref=$objp->facnumber; - $facturestatic->type=$objp->type; - print $facturestatic->getNomUrl(1); - print $objp->increment; - if ($objp->datelimite < (time() - $conf->facture->client->warning_delay) && ! $objp->paye && $objp->fk_statut == 1 && ! $objp->am) print img_warning($langs->trans('Late')); - print "'; - $y = strftime('%Y',$objp->df); - $m = strftime('%m',$objp->df); - print strftime('%d',$objp->df); - print ' '; - print substr(strftime('%B',$objp->df),0,3).''; - print ' '; - print strftime('%Y',$objp->df).'!!!'.img_object($langs->trans('ShowCompany'),'company').' '.dolibarr_trunc($objp->nom,48).''.price($objp->total).''.price($objp->total_ttc).''.price($objp->am).''; - print $facturestatic->LibStatut($objp->paye,$objp->fk_statut,5,$objp->am); - print "
'.$langs->trans('Total').''.price($total).''.price($total_ttc).''.price($totalrecu).' 
\n"; - print "
\n"; - $db->free($resql); + $sql .= ' GROUP BY f.rowid'; + + $sql .= ' ORDER BY '; + $listfield=split(',',$sortfield); + foreach ($listfield as $key => $value) + $sql.= $listfield[$key].' '.$sortorder.','; + $sql .= ' f.rowid DESC '; + + $sql .= $db->plimit($limit+1,$offset); + + $resql = $db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + + if ($socid) + { + $soc = new Societe($db); + $soc->fetch($socid); + } + + print_barre_liste($langs->trans('BillsCustomers').' '.($socid?' '.$soc->nom:''),$page,'facture.php','&socid='.$socid,$sortfield,$sortorder,'',$num); + + $i = 0; + print '
'."\n"; + print ''; + print ''; + print_liste_field_titre($langs->trans('Ref'),$_SERVER['PHP_SELF'],'f.facnumber','','&socid='.$socid,'',$sortfield); + print_liste_field_titre($langs->trans('Date'),$_SERVER['PHP_SELF'],'f.datef','','&socid='.$socid,'align="center"',$sortfield); + print_liste_field_titre($langs->trans('Company'),$_SERVER['PHP_SELF'],'s.nom','','&socid='.$socid,'',$sortfield); + print_liste_field_titre($langs->trans('AmountHT'),$_SERVER['PHP_SELF'],'f.total','','&socid='.$socid,'align="right"',$sortfield); + print_liste_field_titre($langs->trans('AmountTTC'),$_SERVER['PHP_SELF'],'f.total_ttc','','&socid='.$socid,'align="right"',$sortfield); + print_liste_field_titre($langs->trans('Received'),$_SERVER['PHP_SELF'],'am','','&socid='.$socid,'align="right"',$sortfield); + print_liste_field_titre($langs->trans('Status'),$_SERVER['PHP_SELF'],'fk_statut,paye,am','','&socid='.$socid,'align="right"',$sortfield); + print ''; + + // Lignes des champs de filtre + + print ''; + print ''; + print '\n"; + + if ($num > 0) + { + $var=True; + $total=0; + $totalrecu=0; + + while ($i < min($num,$limit)) + { + $objp = $db->fetch_object($resql); + $var=!$var; + + print ''; + print '\n"; + + if ($objp->df > 0 ) + { + print ''; + } + else + { + print ''; + } + print ''; + print ''; + print ''; + print ''; + + // Affiche statut de la facture + print '\n"; + $total+=$objp->total; + $total_ttc+=$objp->total_ttc; + $totalrecu+=$objp->am; + $i++; + } + + if (($offset + $num) <= $limit) + { + // Print total + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + } + } + + print "
'; + print ''; + print ' '; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print "
'; + $facturestatic->id=$objp->facid; + $facturestatic->ref=$objp->facnumber; + $facturestatic->type=$objp->type; + print $facturestatic->getNomUrl(1); + print $objp->increment; + if ($objp->datelimite < (time() - $conf->facture->client->warning_delay) && ! $objp->paye && $objp->fk_statut == 1 && ! $objp->am) print img_warning($langs->trans('Late')); + print "'; + $y = strftime('%Y',$objp->df); + $m = strftime('%m',$objp->df); + print strftime('%d',$objp->df); + print ' '; + print substr(strftime('%B',$objp->df),0,3).''; + print ' '; + print strftime('%Y',$objp->df).'!!!'.img_object($langs->trans('ShowCompany'),'company').' '.dolibarr_trunc($objp->nom,48).''.price($objp->total).''.price($objp->total_ttc).''.price($objp->am).''; + print $facturestatic->LibStatut($objp->paye,$objp->fk_statut,5,$objp->am); + print "
'.$langs->trans('Total').''.price($total).''.price($total_ttc).''.price($totalrecu).' 
\n"; + print "
\n"; + $db->free($resql); + } + else + { + dolibarr_print_error($db); + } } - else - { - dolibarr_print_error($db); - } - } } $db->close(); diff --git a/htdocs/facture.class.php b/htdocs/facture.class.php index 9af906b5050..96cf2a4bcfa 100644 --- a/htdocs/facture.class.php +++ b/htdocs/facture.class.php @@ -2304,8 +2304,8 @@ class Facture extends CommonObject /** * \brief Renvoi liste des factures qualifiables pour avoir - * Statut validee + pas deja remplacées - * \param socid Id societe + * Statut >= validee + pas classé payée completement + pas classé payée partiellement + pas deja remplacée + * \param socid Id societe * \return array Tableau des factures ($id => $ref) */ function list_qualified_avoir_invoices($socid=0) @@ -2318,7 +2318,9 @@ class Facture extends CommonObject $sql.= " FROM ".MAIN_DB_PREFIX."facture as f"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON f.rowid = pf.fk_facture"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as ff ON (f.rowid = ff.fk_facture_source AND ff.type=1)"; - $sql.= " WHERE f.fk_statut >= 1 AND f.paye = 0"; + $sql.= " WHERE f.fk_statut >= 1"; + $sql.= " AND f.paye = 0"; // Pas classé payé complètement + $sql.= " AND f.close_code IS NULL"; // Pas classé payé partiellement $sql.= " AND ff.type IS NULL"; // Renvoi vrai si pas facture de remplacement if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid; $sql.= " ORDER BY f.facnumber"; diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang index aa7514b078d..6573d70fd47 100644 --- a/htdocs/langs/en_US/bills.lang +++ b/htdocs/langs/en_US/bills.lang @@ -135,6 +135,7 @@ ShowInvoiceAvoir=Show credit note ShowPayment=Show payment File=File AlreadyPayed=Already payed +Abandoned=Abandoned RemainderToPay=Remainder to pay RemainderToTake=Remainder to take EscompteOffered=Discount offered (payment before term) @@ -192,6 +193,8 @@ DiscountStillRemaining=Discount still remaining DiscountAlreadyCounted=Discount already counted BillAddress=Bill address HelpEscompte=This discount is a discount granted to customer because its paiement was made before term. +HelpAbandonBadCustomer=This amount has been abandoned (customer said to be a bad customer) and is considered as an exceptionnal loose. +HelpAbandonOther=This amount has been abandoned and is considered as an exceptionnal loose. # PaymentConditions PaymentConditionShortRECEP=Immediate PaymentConditionRECEP=Immediate diff --git a/htdocs/langs/fr_BE/bills.lang b/htdocs/langs/fr_BE/bills.lang index b7adf51abbb..8b5c84a62c4 100644 --- a/htdocs/langs/fr_BE/bills.lang +++ b/htdocs/langs/fr_BE/bills.lang @@ -186,6 +186,8 @@ DiscountStillRemaining=Remises fixes restant en cours DiscountAlreadyCounted=Remises fixes déjà appliquées BillAddress=Adresse de facturation HelpEscompte=Cette réduction est allouée au client car son paiement a été fait avant échéance. +HelpAbandonBadCustomer=Ce montant a été abandonné (client jugé mauvais payeur) et est considéré comme un perte exceptionnelle. +HelpAbandonOther=Ce montant a été abandonné et est considéré comme un perte exceptionnelle. # PaymentConditions=undefined PaymentConditionShortRECEP=À réception PaymentConditionRECEP=À réception de facture diff --git a/htdocs/langs/fr_FR/bills.lang b/htdocs/langs/fr_FR/bills.lang index 40e6707288f..8cf154c6b48 100644 --- a/htdocs/langs/fr_FR/bills.lang +++ b/htdocs/langs/fr_FR/bills.lang @@ -136,6 +136,7 @@ ShowInvoiceAvoir=Afficher facture avoir ShowPayment=Afficher réglement File=Fichier AlreadyPayed=Déjà réglé +Abandoned=Abandonné RemainderToPay=Reste à payer RemainderToTake=Reste à encaisser EscompteOffered=Escompte (réglement avant échéance) @@ -193,6 +194,8 @@ DiscountStillRemaining=Remises fixes restant en cours DiscountAlreadyCounted=Remises fixes déjà appliquées BillAddress=Adresse de facturation HelpEscompte=Un escompte est une remise accordée, sur une facture donnée, à un client car ce dernier a réalisé son réglement bien avant l'échéance. +HelpAbandonBadCustomer=Ce montant a été abandonné (client jugé mauvais payeur) et est considéré comme un perte exceptionnelle. +HelpAbandonOther=Ce montant a été abandonné et est considéré comme un perte exceptionnelle. # PaymentConditions PaymentConditionShortRECEP=A réception PaymentConditionRECEP=A réception de facture diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 44f9adf4766..0eec61d3a1e 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -515,7 +515,11 @@ function top_htmlhead($head, $title="", $target="") if ($conf->use_javascript || $conf->use_ajax) { print ''."\n"; - } + if (file_exists(DOL_DOCUMENT_ROOT.'/lib/lib_head_perso.js')) + { + print ''; + } + } if ($conf->use_ajax) { print ''."\n";