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&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&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 ' ';
}
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 ' ';
}
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.