dolibarr 21.0.0-beta
schedule.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2017 Franck Moreau <franck.moreau@theobald.com>
3 * Copyright (C) 2018-2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
4 * Copyright (C) 2020 Maxime DEMAREST <maxime@indelog.fr>
5 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
6 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
28// Load Dolibarr environment
29require '../main.inc.php';
30require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php';
31require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php';
32require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
33require_once DOL_DOCUMENT_ROOT.'/loan/class/loanschedule.class.php';
34require_once DOL_DOCUMENT_ROOT.'/loan/class/paymentloan.class.php';
35require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
36if (isModEnabled('project')) {
37 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
38}
39
48$loanid = GETPOSTINT('loanid');
49$action = GETPOST('action', 'aZ09');
50
51// Security check
52$socid = 0;
53if (GETPOSTISSET('socid')) {
54 $socid = GETPOSTINT('socid');
55}
56if ($user->socid) {
57 $socid = $user->socid;
58}
59if (!$user->hasRight('loan', 'calc')) {
61}
62
63// Load translation files required by the page
64$langs->loadLangs(array("compta", "bills", "loan"));
65
66$object = new Loan($db);
67$object->fetch($loanid);
68
69$echeances = new LoanSchedule($db);
70$echeances->fetchAll($object->id);
71
72if ($object->paid > 0 && count($echeances->lines) == 0) {
73 $pay_without_schedule = 1;
74} else {
75 $pay_without_schedule = 0;
76}
77
78$permissiontoadd = $user->hasRight('loan', 'write');
79
80
81/*
82 * Actions
83 */
84
85if ($action == 'createecheancier' && empty($pay_without_schedule) && $permissiontoadd) {
86 $db->begin();
87 $i = 1;
88 while ($i < $object->nbterm + 1) {
89 $date = GETPOSTINT('hi_date'.$i);
90 $mens = price2num(GETPOST('mens'.$i));
91 $int = price2num(GETPOST('hi_interets'.$i));
92 $insurance = price2num(GETPOST('hi_insurance'.$i));
93
94 $new_echeance = new LoanSchedule($db);
95
96 $new_echeance->fk_loan = $object->id;
97 $new_echeance->datec = dol_now();
98 $new_echeance->tms = dol_now();
99 $new_echeance->datep = $date;
100 $new_echeance->amount_capital = (float) $mens - (float) $int;
101 $new_echeance->amount_insurance = $insurance;
102 $new_echeance->amount_interest = $int;
103 $new_echeance->fk_typepayment = 3;
104 $new_echeance->fk_bank = 0;
105 $new_echeance->fk_user_creat = $user->id;
106 $new_echeance->fk_user_modif = $user->id;
107 $result = $new_echeance->create($user);
108 if ($result < 0) {
109 setEventMessages($new_echeance->error, $new_echeance->errors, 'errors');
110 $db->rollback();
111 $echeances->lines = [];
112 break;
113 }
114 $echeances->lines[] = $new_echeance;
115 $i++;
116 }
117 if ($result > 0) {
118 $db->commit();
119 }
120}
121
122if ($action == 'updateecheancier' && empty($pay_without_schedule) && $permissiontoadd) {
123 $db->begin();
124 $i = 1;
125 while ($i < $object->nbterm + 1) {
126 $mens = price2num(GETPOST('mens'.$i));
127 $int = price2num(GETPOST('hi_interets'.$i));
128 $id = GETPOST('hi_rowid'.$i);
129 $insurance = price2num(GETPOST('hi_insurance'.$i));
130
131 $new_echeance = new LoanSchedule($db);
132 $new_echeance->fetch($id);
133 $new_echeance->tms = dol_now();
134 $new_echeance->amount_capital = (float) $mens - (float) $int;
135 $new_echeance->amount_insurance = $insurance;
136 $new_echeance->amount_interest = $int;
137 $new_echeance->fk_user_modif = $user->id;
138 $result = $new_echeance->update($user, 0);
139 if ($result < 0) {
140 setEventMessages(null, $new_echeance->errors, 'errors');
141 $db->rollback();
142 $echeances->fetchAll($object->id);
143 break;
144 }
145
146 $echeances->lines[$i - 1] = $new_echeance;
147 $i++;
148 }
149 if ($result > 0) {
150 $db->commit();
151 }
152}
153
154
155/*
156 * View
157 */
158
159$form = new Form($db);
160$formproject = new FormProjets($db);
161
162$title = $langs->trans("Loan").' - '.$langs->trans("FinancialCommitment");
163$help_url = 'EN:Module_Loan|FR:Module_Emprunt';
164
165llxHeader("", $title, $help_url, '', 0, 0, '', '', '', 'mod-loan page-card_schedule');
166
167$head = loan_prepare_head($object);
168print dol_get_fiche_head($head, 'FinancialCommitment', $langs->trans("Loan"), -1, 'money-bill-alt');
169
170$linkback = '<a href="'.DOL_URL_ROOT.'/loan/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
171
172$morehtmlref = '<div class="refidno">';
173// Ref loan
174$morehtmlref .= $form->editfieldkey("Label", 'label', $object->label, $object, 0, 'string', '', 0, 1);
175$morehtmlref .= $form->editfieldval("Label", 'label', $object->label, $object, 0, 'string', '', null, null, '', 1);
176// Project
177if (isModEnabled('project')) {
178 $langs->loadLangs(array("projects"));
179 $morehtmlref .= '<br>'.$langs->trans('Project').' : ';
180 if ($user->hasRight('loan', 'write')) {
181 if ($action != 'classify') {
182 //$morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> : ';
183 if ($action == 'classify') {
184 //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
185 $morehtmlref .= '<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
186 $morehtmlref .= '<input type="hidden" name="action" value="classin">';
187 $morehtmlref .= '<input type="hidden" name="token" value="'.newToken().'">';
188 $morehtmlref .= $formproject->select_projects(-1, $object->fk_project, 'projectid', 16, 0, 1, 0, 1, 0, 0, '', 1);
189 $morehtmlref .= '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
190 $morehtmlref .= '</form>';
191 } else {
192 $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, -1, $object->fk_project, 'none', 0, 0, 0, 1, '', 'maxwidth300');
193 }
194 }
195 } else {
196 if (!empty($object->fk_project)) {
197 $proj = new Project($db);
198 $proj->fetch($object->fk_project);
199 $morehtmlref .= ' : '.$proj->getNomUrl(1);
200 if ($proj->title) {
201 $morehtmlref .= ' - '.$proj->title;
202 }
203 } else {
204 $morehtmlref .= '';
205 }
206 }
207}
208$morehtmlref .= '</div>';
209
210$morehtmlstatus = '';
211
212dol_banner_tab($object, 'loanid', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', $morehtmlstatus);
213
214?>
215<script type="text/javascript">
216$(document).ready(function() {
217 $('[name^="mens"]').focusout(function() {
218 var echeance=$(this).attr('ech');
219 var mens=price2numjs($(this).val());
220 var idcap=echeance-1;
221 idcap = '#hi_capital'+idcap;
222 var capital=price2numjs($(idcap).val());
223 console.log("Change monthly amount echeance="+echeance+" idcap="+idcap+" capital="+capital);
224 $.ajax({
225 method: "GET",
226 dataType: 'json',
227 url: 'calcmens.php',
228 data: { echeance: echeance, mens: mens, capital:capital, rate:<?php echo $object->rate / 100; ?>, nbterm: <?php echo $object->nbterm; ?>, token: '<?php echo currentToken(); ?>' },
229 success: function(data) {
230 $.each(data, function(index, element) {
231 var idcap_res='#hi_capital'+index;
232 var idcap_res_srt='#capital'+index;
233 var interet_res='#hi_interets'+index;
234 var interet_res_str='#interets'+index;
235 var men_res='#mens'+index;
236 $(idcap_res).val(element.cap_rest);
237 $(idcap_res_srt).text(element.cap_rest_str);
238 $(interet_res).val(element.interet);
239 $(interet_res_str).text(element.interet_str);
240 $(men_res).val(element.mens);
241 });
242 }
243 });
244 });
245});
246</script>
247<?php
248
249if ($pay_without_schedule == 1) {
250 print '<div class="warning">'.$langs->trans('CantUseScheduleWithLoanStartedToPaid').'</div>'."\n";
251}
252
253print '<form name="createecheancier" action="'.$_SERVER["PHP_SELF"].'" method="POST">';
254print '<input type="hidden" name="token" value="'.newToken().'">';
255print '<input type="hidden" name="loanid" value="'.$loanid.'">';
256if (count($echeances->lines) > 0) {
257 print '<input type="hidden" name="action" value="updateecheancier">';
258} else {
259 print '<input type="hidden" name="action" value="createecheancier">';
260}
261
262//print_fiche_titre($langs->trans("FinancialCommitment"));
263print '<br>';
264
265print '<div class="div-table-responsive-no-min">';
266print '<table class="border centpercent">';
267
268$colspan = 6;
269if (count($echeances->lines) > 0) {
270 $colspan++;
271}
272
273print '<tr class="liste_titre">';
274print '<th class="center">'.$langs->trans("Term").'</th>';
275print '<th class="center">'.$langs->trans("Date").'</th>';
276print '<th class="center">'.$langs->trans("Insurance");
277print '<th class="center">'.$langs->trans("InterestAmount").'</th>';
278print '<th class="center">'.$langs->trans("Amount").'</th>';
279print '<th class="center">'.$langs->trans("CapitalRemain");
280print '<br>('.price($object->capital, 0, '', 1, -1, -1, $conf->currency).')';
281print '<input type="hidden" name="hi_capital0" id ="hi_capital0" value="'.$object->capital.'">';
282print '</th>';
283if (count($echeances->lines) > 0) {
284 print '<th class="center">'.$langs->trans('DoPayment').'</th>';
285}
286print '</tr>'."\n";
287
288if ($object->nbterm > 0 && count($echeances->lines) == 0) {
289 $i = 1;
290 $capital = $object->capital;
291 $insurance = (float) $object->insurance_amount / $object->nbterm;
292 $insurance = price2num($insurance, 'MT');
293 $regulInsurance = price2num((float) $object->insurance_amount - ((float) $insurance * $object->nbterm));
294 while ($i < $object->nbterm + 1) {
295 $mens = price2num($echeances->calcMonthlyPayments($capital, $object->rate / 100, $object->nbterm - $i + 1), 'MT');
296 $int = ($capital * ($object->rate / 12)) / 100;
297 $int = price2num($int, 'MT');
298 $insu = ((float) $insurance + (($i == 1) ? (float) $regulInsurance : 0));
299 $cap_rest = price2num((float) $capital - ((float) $mens - (float) $int), 'MT');
300 print '<tr>';
301 print '<td class="center" id="n'.$i.'">'.$i.'</td>';
302 print '<td class="center" id ="date'.$i.'"><input type="hidden" name="hi_date'.$i.'" id ="hi_date'.$i.'" value="'.dol_time_plus_duree($object->datestart, $i - 1, 'm').'">'.dol_print_date(dol_time_plus_duree($object->datestart, $i - 1, 'm'), 'day').'</td>';
303 print '<td class="center amount" id="insurance'.$i.'">'.price($insu, 0, '', 1, -1, -1, $conf->currency).'</td><input type="hidden" name="hi_insurance'.$i.'" id ="hi_insurance'.$i.'" value="'.$insu.'">';
304 print '<td class="center amount" id="interets'.$i.'">'.price($int, 0, '', 1, -1, -1, $conf->currency).'</td><input type="hidden" name="hi_interets'.$i.'" id ="hi_interets'.$i.'" value="'.$int.'">';
305 print '<td class="center"><input class="width75 right" name="mens'.$i.'" id="mens'.$i.'" value="'.$mens.'" ech="'.$i.'"></td>';
306 print '<td class="center amount" id="capital'.$i.'">'.price($cap_rest).'</td><input type="hidden" name="hi_capital'.$i.'" id ="hi_capital'.$i.'" value="'.$cap_rest.'">';
307 print '</tr>'."\n";
308 $i++;
309 $capital = $cap_rest;
310 }
311} elseif (count($echeances->lines) > 0) {
312 $i = 1;
313 $capital = $object->capital;
314 $insurance = (float) $object->insurance_amount / $object->nbterm;
315 $insurance = price2num($insurance, 'MT');
316 $regulInsurance = price2num((float) $object->insurance_amount - ((float) $insurance * $object->nbterm));
317 $printed = false;
318 foreach ($echeances->lines as $line) {
319 $mens = $line->amount_capital + $line->amount_interest;
320 $int = $line->amount_interest;
321 $insu = ((float) $insurance + (($i == 1) ? (float) $regulInsurance : 0));
322 $cap_rest = price2num($capital - ($mens - $int), 'MT');
323
324 print '<tr>';
325 print '<td class="center" id="n'.$i.'"><input type="hidden" name="hi_rowid'.$i.'" id ="hi_rowid'.$i.'" value="'.$line->id.'">'.$i.'</td>';
326 print '<td class="center" id ="date'.$i.'"><input type="hidden" name="hi_date'.$i.'" id ="hi_date'.$i.'" value="'.$line->datep.'">'.dol_print_date($line->datep, 'day').'</td>';
327 print '<td class="center amount" id="insurance'.$i.'">'.price($insu, 0, '', 1, -1, -1, $conf->currency).'</td><input type="hidden" name="hi_insurance'.$i.'" id ="hi_insurance'.$i.'" value="'.$insu.'">';
328 print '<td class="center amount" id="interets'.$i.'">'.price($int, 0, '', 1, -1, -1, $conf->currency).'</td><input type="hidden" name="hi_interets'.$i.'" id ="hi_interets'.$i.'" value="'.$int.'">';
329 if (empty($line->fk_bank)) {
330 print '<td class="center"><input class="right width75" name="mens'.$i.'" id="mens'.$i.'" value="'.$mens.'" ech="'.$i.'"></td>';
331 } else {
332 print '<td class="center amount">'.price($mens, 0, '', 1, -1, -1, $conf->currency).'</td><input type="hidden" name="mens'.$i.'" id ="mens'.$i.'" value="'.$mens.'">';
333 }
334
335 print '<td class="center amount" id="capital'.$i.'">'.price($cap_rest, 0, '', 1, -1, -1, $conf->currency).'</td><input type="hidden" name="hi_capital'.$i.'" id ="hi_capital'.$i.'" value="'.$cap_rest.'">';
336 print '<td class="center">';
337 if (!empty($line->fk_bank)) {
338 print $langs->trans('Paid');
339 if (!empty($line->fk_payment_loan)) {
340 print '&nbsp;<a href="'.DOL_URL_ROOT.'/loan/payment/card.php?id='.$line->fk_payment_loan.'">('.img_object($langs->trans("Payment"), "payment").' '.$line->fk_payment_loan.')</a>';
341 }
342 } elseif (!$printed) {
343 print '<a class="butAction smallpaddingimp" href="'.DOL_URL_ROOT.'/loan/payment/payment.php?id='.$object->id.'&action=create">'.$langs->trans('DoPayment').'</a>';
344 $printed = true;
345 }
346 print '</td>';
347 print '</tr>'."\n";
348 $i++;
349 $capital = $cap_rest;
350 }
351}
352
353print '</table>';
354print '</div>';
355
356print '</br>';
357
358if (count($echeances->lines) == 0) {
359 $label = $langs->trans("Create");
360} else {
361 $label = $langs->trans("Save");
362}
363print '<div class="center"><input type="submit" class="button button-add" value="'.$label.'" '.(($pay_without_schedule == 1) ? 'disabled title="'.$langs->trans('CantUseScheduleWithLoanStartedToPaid').'"' : '').'title=""></div>';
364print '</form>';
365
366// End of page
367llxFooter();
368$db->close();
$id
Definition account.php:48
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:71
Class to manage generation of HTML components Only common components must be here.
Class to manage building of HTML components.
Loan.
Class to manage Schedule of loans.
Class to manage projects.
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition date.lib.php:125
llxFooter()
Footer empty.
Definition document.php:107
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dol_now($mode='auto')
Return date for now.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
price2numjs(amount)
Function similar to PHP price2num()
loan_prepare_head($object)
Prepare array with list of tabs.
Definition loan.lib.php:34
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:149
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.