Echéancier sur facture

Bonjour
Je pense que ceci est dangereux et c’ets pourquoi le module ne le propose pas. En effet, imaginez que votre client disparaissent sans laisser de trace et sans avoir terminé de payer… dans votre gestion, la somme totale est enregistrée comme recu alors que ce n’est pas le cas…

Bonsoir,
Effectivement, après vérification sur le site de démo l’échéancier apparait bien sur la facture provisoire mais pas sur la facture finale.
J’aimerai avoir une facture avec l’échéancier (mois par mois) + le total HT, la tva et le TTC.
Est ce que vous pensez que cela est possible ?
En effet, du point de vu comptable, la ventilation des charges est divisée entre les années. Ainsi, si j’ai 4 mois en 2013 et 9 mois en 2014 je dois pouvoir les saisir différemment en HT.
Est ce que vous comprenez ma problématique ?
Merci d’avance.
Philippe Faure

Bonjour,
Une MàJ vers la 3.6 est-elle prévue ?

https://www.dolistore.com/fr/modules/378-echeancier.html
Dolibarr 3.7 n’est pas noté comme compatible… est il suivi?

Bonjour oui il est compatible

Je viens d’acheter ce module et j’ai une erreur de type:

« Fatal error: Access level to echeancier::$db must be public (as in class CommonObject) in /home/sebastie/public_html/dolibarr/htdocs/echeancier/class/echeancier.class.php on line 31 »

Quand je clic sur schedule depuis une facture.

bonjour

je vous envoi de suite la mise a jour par mail

Super merci
Bien recu

Bonjour, votre module est compatible avec Dolibarr 4.0.4 ? Si non vous avez prévue une mise à jour ?
Merci, cordialement, François.

Bonjour,

oui il est compatible

Cordialement

Bonjour,

J’ai acheté votre module pour un client qui utilise Dolibarr, mais il n’arrive pas à l’utiliser : vous auriez une documentation en ligne quelque part ?

Merci, Cordialement, François.

Avez-vous pu avoir la documentation ? Je serais preneur d’un petit coup demain pour utiliser ce module

Merci par avance

Bonjour, votre module est compatible avec Dolibarr 5 ? Si non vous avez prévue une mise à jour ?
Merci

Bonjour,

La loi concernant la durée de vie des chèques à changé en 2014 passant de 1 an à 6 mois, nous avons donc du changer nos échéanciers pour des paiements bimestriels.

Je me suis donc permis de modifier un fichier de l’échéancier qui se trouve dans le répertoire htdocs/echeancier/echeancier_facture.php, voici une copie pour ceux qui souhaiteraient ajouter le paiement bimestriel.

<?php
/* <one line to give the program's name and a brief idea of what it does.>
 * Copyright (C) 2012-2013 jacquel jerome <[email protected]>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


/**
 * 	\file		mypage.php
 * 	\ingroup	mymodule
 * 	\brief		This file is an example php page
 * 				Put some comments here
 */
//if (! defined('NOREQUIREUSER'))	define('NOREQUIREUSER','1');
//if (! defined('NOREQUIREDB'))		define('NOREQUIREDB','1');
//if (! defined('NOREQUIRESOC'))	define('NOREQUIRESOC','1');
//if (! defined('NOREQUIRETRAN'))	define('NOREQUIRETRAN','1');
//if (! defined('NOCSRFCHECK'))		define('NOCSRFCHECK','1');
//if (! defined('NOTOKENRENEWAL'))	define('NOTOKENRENEWAL','1');
// If there is no menu to show
//if (! defined('NOREQUIREMENU'))	define('NOREQUIREMENU','1');
// If we don't need to load the html.form.class.php
//if (! defined('NOREQUIREHTML'))	define('NOREQUIREHTML','1');
//if (! defined('NOREQUIREAJAX'))	define('NOREQUIREAJAX','1');
// If this page is public (can be called outside logged session)
//if (! defined("NOLOGIN"))			define("NOLOGIN",'1');
// Choose the following lines to use the correct relative path
// (../, ../../, etc)
$res = 0;
if (!$res && file_exists("../main.inc.php")) {
    $res = @include("../main.inc.php");
}
if (!$res && file_exists("../../main.inc.php")) {
    $res = @include("../../main.inc.php");
}
if (!$res && file_exists("../../../main.inc.php")) {
    $res = @include("../../../main.inc.php");
}
// The following should only be used in development environments
if (!$res && file_exists("../../../dolibarr/htdocs/main.inc.php")) {
    $res = @include("../../../dolibarr/htdocs/main.inc.php");
}
if (!$res && file_exists("../../../../dolibarr/htdocs/main.inc.php")) {
    $res = @include("../../../../dolibarr/htdocs/main.inc.php");
}
if (!$res && file_exists("../../../../../dolibarr/htdocs/main.inc.php")) {
    $res = @include("../../../../../dolibarr/htdocs/main.inc.php");
}
if (!$res) {
    die("Main include failed");
}
// Change this following line to use the correct relative path from htdocs
// (do not remove DOL_DOCUMENT_ROOT)
//require_once DOL_DOCUMENT_ROOT . "custom/mymodule/class/myclass.class.php";
// Load translation files required by the page
$langs->load("echeancier@echeancier");

// Get parameters
$id = GETPOST('id', 'int');
$action = GETPOST('action', 'alpha');
$total = GETPOST('montant', 'alpha');

// Access control
if ($user->societe_id > 0) {
    // External user
    accessforbidden();
}

require_once(DOL_DOCUMENT_ROOT . '/core/lib/invoice.lib.php');
require_once(DOL_DOCUMENT_ROOT . "/compta/facture/class/facture.class.php");
$res = 0;
if (!$res && file_exists(DOL_DOCUMENT_ROOT . "/compta/prelevement/class/bonprelevement.class.php"))
    $res = @require_once(DOL_DOCUMENT_ROOT . "/compta/prelevement/class/bonprelevement.class.php");
if (!$res && file_exists(DOL_DOCUMENT_ROOT . "/compta/prelevement/class/bon-prelevement.class.php"))
    $res = @require_once(DOL_DOCUMENT_ROOT . "/compta/prelevement/class/bon-prelevement.class.php");
if (!$res)
    die("Include of bon prelevement class fails");

require_once(DOL_DOCUMENT_ROOT . '/core/class/discount.class.php');

if (!$user->rights->facture->lire || !$user->rights->echeancier->facture)
    accessforbidden();

$langs->load("bills");
$langs->load("banks");
$langs->load("withdrawals");

// Security check
if ($user->societe_id > 0) {
    $action = '';
    $socid = $user->societe_id;
}




/*
 * ACTIONS
 *
 * Put here all code to do according to value of "action" parameter
 */
if (GETPOST('action')) {

    if (GETPOST('action') == 'add') {


        $sql = "insert into " . MAIN_DB_PREFIX . "echeancier (type,montant,nombre,id_element,id_client,date_debut) values (2,'" . GETPOST('montant') . "'," . GETPOST('mois') . ",'" . GETPOST('id') . "','" . GETPOST('id_client') . "','" . GETPOST('datedyear') . '-' . GETPOST('datedmonth') . '-' . GETPOST('datedday') . "')";
        $result = $db->query($sql);


        $lastid = $db->last_insert_id(MAIN_DB_PREFIX . "echeancier", "id");

        for ($i = 1; $i < GETPOST('mois') + 1; $i++) {
            if (GETPOST(creation_facture)) {
                $acompte = "FALSE";
            } else {
                $acompte = 'TRUE';
            }
            $sql = "insert into " . MAIN_DB_PREFIX . "echeance (fk_echeancier,fk_facture,date_reglement,montant,acompte,paye) value (" . $lastid . ",'" . GETPOST('id') . "','" . date('Y-m-d', strtotime(GETPOST('date' . $i))) . "','" . GETPOST('textbox' . $i) . "'," . $acompte . ",FALSE)";
            $result = $db->query($sql);
            dol_syslog("add echeance :: sql:".$sql);
            
            
            
        }
        $j = $i - 1;
        $sql = "update " . MAIN_DB_PREFIX . "facture set date_lim_reglement= '" . date('Y-m-d', strtotime(GETPOST('date' . $j))) . "' where rowid=" . GETPOST('id');
        $result = $db->query($sql);



        header('location:' . dol_buildpath('/echeancier/fiche_facture.php?id='.$id,2));
    }

    $now = dol_now();
    $js = array('echeancier/js/date.format.js');
    $css = array('/echeancier/css/styles.css');
    llxHeader('', 'Echeancier', '', '', '', '', $js, $css);
    print_fiche_titre($langs->trans('echeancier_on') . ' ' . GETPOST('facture'));


    $html = new Form($db);


    if (GETPOST('action') == 'create') {




        if ($_REQUEST["id"] > 0 || $_REQUEST["ref"]) {
            $fac = new Facture($db);
            if ($fac->fetch($_REQUEST["id"], $_REQUEST["ref"])) {
                if ($mesg)
                    print $mesg . '<br>';

                $soc = new Societe($db, $fac->socid);
                $soc->fetch($fac->socid);

                $totalpaye = $fac->getSommePaiement();
                $totalcreditnotes = $fac->getSumCreditNotesUsed();
                $totaldeposits = $fac->getSumDepositsUsed();

                $resteapayer = price2num($fac->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT');

                if ($fac->paye)
                    $resteapayer = 0;
                $resteapayeraffiche = $resteapayer;

                $absolute_discount = $soc->getAvailableDiscounts('', 'fk_facture_source IS NULL');
                $absolute_creditnote = $soc->getAvailableDiscounts('', 'fk_facture_source IS NOT NULL');
                $absolute_discount = price2num($absolute_discount, 'MT');
                $absolute_creditnote = price2num($absolute_creditnote, 'MT');

                $author = new User($db);
                if ($fac->user_author) {
                    $author->fetch($fac->user_author);
                }

                $head = facture_prepare_head($fac);

                //dol_fiche_head($head, 'tabTicket', $langs->trans('InvoiceCustomer'),0,'bill');

                /*
                 *   Facture
                 */
                print '<table class="border" width="100%">';

                // Ref
                print '<tr><td width="20%">' . $langs->trans("Ref") . '</td><td colspan="5">';
                $morehtmlref = '';
                $discount = new DiscountAbsolute($db);
                $result = $discount->fetch(0, $fac->id);
                if ($result > 0) {
                    $morehtmlref = ' (' . $langs->trans("CreditNoteConvertedIntoDiscount", $discount->getNomUrl(1, 'discount')) . ')';
                }
                if ($result < 0) {
                    dol_print_error('', $discount->error);
                }
                print $html->showrefnav($fac, 'ref', '', 1, 'facnumber', 'ref', $morehtmlref);
                print "</td></tr>";

                // Third party
                print '<tr><td>' . $langs->trans('Company') . '</td>';
                print '<td colspan="5">' . $soc->getNomUrl(1, 'compta');
                print '</tr>';

                // Type
                print '<tr><td>' . $langs->trans('Type') . '</td><td colspan="5">';
                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) {
                    $facusing = new Facture($db);
                    $facusing->fetch($fac->fk_facture_source);
                    print ' (' . $langs->transnoentities("CorrectInvoice", $facusing->getNomUrl(1)) . ')';
                }

                $facidavoir = $fac->getListIdAvoirFromInvoice();
                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 '</td></tr>';



                // Date invoice
                print '<tr><td>';
                print '<table class="nobordernopadding" width="100%"><tr><td>';
                print $langs->trans('Date');
                print '</td>';
                if ($fac->type != 2 && $_GET['action'] != 'editinvoicedate' && $fac->brouillon && $user->rights->facture->creer)
                    print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editinvoicedate&amp;facid=' . $fac->id . '">' . img_edit($langs->trans('SetDate'), 1) . '</a></td>';
                print '</tr></table>';
                print '</td><td colspan="3">';

                if ($fac->type != 2) {
                    if ($_GET['action'] == 'editinvoicedate') {
                        $html->form_date($_SERVER['PHP_SELF'] . '?facid=' . $fac->id, $fac->date, 'invoicedate');
                    } else {
                        print dol_print_date($fac->date, 'daytext');
                    }
                } else {
                    print dol_print_date($fac->date, 'daytext');
                }
                print '</td>';
                print '</tr>';

                // Date payment term
                print '<tr><td>';
                print '<table class="nobordernopadding" width="100%"><tr><td>';
                print $langs->trans('DateMaxPayment');
                print '</td>';
                if ($fac->type != 2 && $_GET['action'] != 'editpaymentterm' && $fac->brouillon && $user->rights->facture->creer)
                    print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editpaymentterm&amp;facid=' . $fac->id . '">' . img_edit($langs->trans('SetDate'), 1) . '</a></td>';
                print '</tr></table>';
                print '</td><td colspan="3">';
                if ($fac->type != 2) {
                    if ($_GET['action'] == 'editpaymentterm') {
                        $html->form_date($_SERVER['PHP_SELF'] . '?facid=' . $fac->id, $fac->date_lim_reglement, 'paymentterm');
                    } else {
                        print dol_print_date($fac->date_lim_reglement, 'daytext');
                        if ($fac->date_lim_reglement < ($now - $conf->facture->client->warning_delay) && !$fac->paye && $fac->statut == 1 && !$fac->am)
                            print img_warning($langs->trans('Late'));
                    }
                }
                else {
                    print '&nbsp;';
                }
                print '</td></tr>';

                // Conditions de reglement
                print '<tr><td>';
                print '<table class="nobordernopadding" width="100%"><tr><td>';
                print $langs->trans('PaymentConditionsShort');
                print '</td>';
                print '</tr></table>';
                print '</td><td colspan="3">';
                if ($fac->type != 2) {

                    $html->form_conditions_reglement($_SERVER['PHP_SELF'] . '?facid=' . $fac->id, $fac->cond_reglement_id, 'none');
                } else {
                    print '&nbsp;';
                }
                print '</td></tr>';

                // Mode de reglement
                print '<tr><td>';
                print '<table class="nobordernopadding" width="100%"><tr><td>';
                print $langs->trans('PaymentMode');
                print '</td>';
                print '</tr></table>';
                print '</td><td colspan="3">';
                $html->form_modes_reglement($_SERVER['PHP_SELF'] . '?facid=' . $fac->id, $fac->mode_reglement_id, 'none');

                print '</td></tr>';

                // Montants
                print '<tr><td>' . $langs->trans('AmountHT') . '</td>';
                print '<td align="right" colspan="2" nowrap>' . price($fac->total_ht) . '</td>';
                print '<td>' . $langs->trans('Currency' . $conf->monnaie) . '</td></tr>';
                print '<tr><td>' . $langs->trans('AmountVAT') . '</td><td align="right" colspan="2" nowrap>' . price($fac->total_tva) . '</td>';
                print '<td>' . $langs->trans('Currency' . $conf->monnaie) . '</td></tr>';

                // Amount Local Taxes
                if ($mysoc->pays_code == 'ES') {
                    if ($mysoc->localtax1_assuj == "1") { //Localtax1 RE
                        print '<tr><td>' . $langs->transcountry("AmountLT1", $mysoc->pays_code) . '</td>';
                        print '<td align="right" colspan="2" nowrap>' . price($fac->total_localtax1) . '</td>';
                        print '<td>' . $langs->trans("Currency" . $conf->monnaie) . '</td></tr>';
                    }
                    if ($mysoc->localtax2_assuj == "1") { //Localtax2 IRPF
                        print '<tr><td>' . $langs->transcountry("AmountLT2", $mysoc->pays_code) . '</td>';
                        print '<td align="right" colspan="2" nowrap>' . price($fac->total_localtax2) . '</td>';
                        print '<td>' . $langs->trans("Currency" . $conf->monnaie) . '</td></tr>';
                    }
                }

                print '<tr><td>' . $langs->trans('AmountTTC') . '</td><td align="right" colspan="2" nowrap>' . price($fac->total_ttc) . '</td>';
                print '<td>' . $langs->trans('Currency' . $conf->monnaie) . '</td></tr>';

                // Statut
                print '<tr><td>' . $langs->trans('Status') . '</td>';
                print '<td align="left" colspan="3">' . ($fac->getLibStatut(4, $totalpaye)) . '</td></tr>';



                print '</table>';
            } else {
                /* Invoice not found */
                print $langs->trans("ErrorBillNotFound", $_GET["facid"]);
            }
        }
        $facture = GETPOST('id');
        $montant = GETPOST('montant');
        print '<form action="echeancier_facture.php" method="post">';
        print '<input type="hidden" name="action" value="add">';
        print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
        print '<input type="hidden" name="id" value="' . $facture . '">';
        print '<input type="hidden" name="montant" value="' . $montant . '">';
        print '<input type="hidden" name="id_client" value="' . GETPOST('id_client') . '">';
        print '<div id="select"><p><label>' . $langs->trans('start_date') . ' : </label>';
        $html->select_date($object->date, 'dated', '', '', '', "setdate");
        print '</p><p><label>' . $langs->trans('echeance number') . ' : </label><input name="mois" type="textbox" id="mois" >';
        print'<select id="periodicite" onchange="calc()"><option value="1">' . $langs->trans('mensuel') . '</option><option value="2">' . $langs->trans('bimestriel') . '</option><option value="3">' . $langs->trans('trimestriel') . '</option><option value="6">' . $langs->trans('semestriel') . '</option><option value="12">' . $langs->trans('Annuel') . '</option></select></p></div>';
        print '<!--input type="checkbox" name="creation_facture" value="true">' . $langs->trans('reglement_facture') . '<br-->';
        print ' <div id="TextBoxesGroup"><div id="TextBoxDiv1"></div></div>';
        print '<input type="submit" disabled id="addelementbuton" class="butAction" value="' . $langs->trans("Create") . '">';
        $fac->fetchObjectLinked('','propale',$fac->id,$fac->element);
        if (count($fac->linkedObjects) > 0 ) {
            $propale = $fac->linkedObjects['propale'][0];
        print '<button class="butAction" data-id="'.$propale->id.'" >'.$langs->trans('FromPropale').'</button>';    
        }
        
        print '</form>';
    }
}




/*
 * VIEW
 *
 * Put here all code to build page
 */
?>
<script type="text/javascript">var tot =  '<?php print $montant; ?>
	';
	var MAX_DECIMALS_TOT = 
 <?php echo $conf -> global -> MAIN_MAX_DECIMALS_TOT; ?>;
jQuery(document).ready(function() {
var nonmanuel = 0;
var date;
var $idset;
var counter = 1;

// jQuery('#select :input').live('change',function(event) {
jQuery('#select :input').on('input', function() {
calc();
});
jQuery('#dated').on('change', function() {
calc();
});



});

//

 function change (event) {
    console.log('change');
nonmanuel = 0;
var totalmanuel = 0;
var reste = 0;
//clearInterval($idset)
jQuery(event.target).attr('manuel', true);
jQuery('#TextBoxDiv1 :input:text').each(function(index, domEle) {

if ($(domEle).attr('manuel')) {

totalmanuel = totalmanuel + parseFloat($(domEle).val());
} else {

nonmanuel++;

}

});

var val = ((tot - totalmanuel) / nonmanuel).toFixed(<?php echo $conf -> global -> MAIN_MAX_DECIMALS_TOT; ?>)
;
jQuery('#TextBoxDiv1 :input:text').each(function(index, domEle) {
if (!($(domEle).attr('manuel'))) {
jQuery($(domEle)).val(val);

}

});

calclast();

}

function totalttc() {

var totalttc = 0;
jQuery('#TextBoxDiv1 :input:text').each(function(index, domEle) {

totalttc = totalttc + parseFloat($(domEle).val());

});

return totalttc

}

function calclast() {
var diff = tot - totalttc();
var last = "#textbox" + $loopcount.toString();
var lastele = $('#TextBoxDiv1').find(last);
var lasttextbox = parseFloat(jQuery(lastele).val());
var lastval = (lasttextbox + diff).toFixed(<?php echo $conf->global->MAIN_MAX_DECIMALS_TOT ?>
	)
	;
	jQuery(last).val(lastval);
	//setTimeout(function(){clearInterval($idset)},100);

	}

	function calc() {
		date = new Date(jQuery('#datedyear').val(), jQuery('#datedmonth').val() - 1, jQuery('#datedday').val());
		$idset = setInterval(function() {
			date = new Date(jQuery('#datedyear').val(), jQuery('#datedmonth').val() - 1, jQuery('#datedday').val());

		}, 1000);
		var $periodicite = jQuery('#periodicite').val();

		jQuery('#TextBoxDiv1').html('')
		$loopcount = $('#mois').val();
		// get the selected value
		if ($loopcount >= 1) {
			jQuery('#addelementbuton').removeAttr('disabled');
		}
		else {
			jQuery('#addelementbuton').attr("disabled", "disabled");
		}

		var totalfix = (tot / $loopcount).toFixed(MAX_DECIMALS_TOT);
		for (var i = 1; i <= $loopcount; i++) {
			// formate la date en Y-m-d pour la value
			dateText = date.getFullYear() + '-' + ('0' + (date.getMonth() + 1)).substr(-2) + '-' + ('0' + date.getDate()).substr(-2);

			jQuery('#TextBoxDiv1').append('<div class="label_echeance"><input type="hidden" name="date' + i + '" value="' + dateText + '"><label>' + date.toLocaleDateString() + '</label><input type="text" id="textbox' + i + '" name="textbox' + i + '" class="textbox2" value="' + totalfix + '" /></div>');
            
			date.setMonth(parseInt(date.getMonth()) + parseFloat($periodicite));

		}
jQuery('.textbox2').on('change',change);
		calclast();

	}
</script>

<?php
// End of page
llxFooter();
$db -> close();

Bonjour,

Cela m’intéresserait aussi de savoir si ce module est compatible avec Dolibarr 5 ???

Salut

la personne que j’avais contacté il y a 15 jours m’avait qu’il était compatible. Mais comme je n’ai aucune notice d’utilisation et que je rencontre quelques difficulités, je ne pourrais pas te confirmer s’il l’est réellement ou non.

Pour l’instant, j’ai un soucis de numéro de chèques grisé !!! et aucune réponse du dév.

Bonjour,

J’ai acheté le module échéancier mais je n’arrive pas à le faire fonctionner.
J’ai un onglet schedule en plus mais je ne peux rien faire dedans.

Que faire ?

Merci d’avance
aleblos

bonjour je vous contact par mail

Cordialement

Bonjour,

Pouvez-vous me confirmer la version de Dolibarr compatible avec votre module ?

Bonjour,

le développement est suivi, il est compatible avec la dernière version stable de dolibarr.