dolibarr 21.0.0-alpha
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 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
27// Load Dolibarr environment
28require '../main.inc.php';
29require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php';
30require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php';
31require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
32require_once DOL_DOCUMENT_ROOT.'/loan/class/loanschedule.class.php';
33require_once DOL_DOCUMENT_ROOT.'/loan/class/paymentloan.class.php';
34require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
35if (isModEnabled('project')) {
36 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
37}
38
39$loanid = GETPOSTINT('loanid');
40$action = GETPOST('action', 'aZ09');
41
42// Security check
43$socid = 0;
44if (GETPOSTISSET('socid')) {
45 $socid = GETPOSTINT('socid');
46}
47if ($user->socid) {
48 $socid = $user->socid;
49}
50if (!$user->hasRight('loan', 'calc')) {
52}
53
54// Load translation files required by the page
55$langs->loadLangs(array("compta", "bills", "loan"));
56
57$object = new Loan($db);
58$object->fetch($loanid);
59
60$echeances = new LoanSchedule($db);
61$echeances->fetchAll($object->id);
62
63if ($object->paid > 0 && count($echeances->lines) == 0) {
64 $pay_without_schedule = 1;
65} else {
66 $pay_without_schedule = 0;
67}
68
69$permissiontoadd = $user->hasRight('loan', 'write');
70
71
72/*
73 * Actions
74 */
75
76if ($action == 'createecheancier' && empty($pay_without_schedule) && $permissiontoadd) {
77 $db->begin();
78 $i = 1;
79 while ($i < $object->nbterm + 1) {
80 $date = GETPOSTINT('hi_date'.$i);
81 $mens = price2num(GETPOST('mens'.$i));
82 $int = price2num(GETPOST('hi_interets'.$i));
83 $insurance = price2num(GETPOST('hi_insurance'.$i));
84
85 $new_echeance = new LoanSchedule($db);
86
87 $new_echeance->fk_loan = $object->id;
88 $new_echeance->datec = dol_now();
89 $new_echeance->tms = dol_now();
90 $new_echeance->datep = $date;
91 $new_echeance->amount_capital = (float) $mens - (float) $int;
92 $new_echeance->amount_insurance = $insurance;
93 $new_echeance->amount_interest = $int;
94 $new_echeance->fk_typepayment = 3;
95 $new_echeance->fk_bank = 0;
96 $new_echeance->fk_user_creat = $user->id;
97 $new_echeance->fk_user_modif = $user->id;
98 $result = $new_echeance->create($user);
99 if ($result < 0) {
100 setEventMessages($new_echeance->error, $new_echeance->errors, 'errors');
101 $db->rollback();
102 $echeances->lines = [];
103 break;
104 }
105 $echeances->lines[] = $new_echeance;
106 $i++;
107 }
108 if ($result > 0) {
109 $db->commit();
110 }
111}
112
113if ($action == 'updateecheancier' && empty($pay_without_schedule) && $permissiontoadd) {
114 $db->begin();
115 $i = 1;
116 while ($i < $object->nbterm + 1) {
117 $mens = price2num(GETPOST('mens'.$i));
118 $int = price2num(GETPOST('hi_interets'.$i));
119 $id = GETPOST('hi_rowid'.$i);
120 $insurance = price2num(GETPOST('hi_insurance'.$i));
121
122 $new_echeance = new LoanSchedule($db);
123 $new_echeance->fetch($id);
124 $new_echeance->tms = dol_now();
125 $new_echeance->amount_capital = (float) $mens - (float) $int;
126 $new_echeance->amount_insurance = $insurance;
127 $new_echeance->amount_interest = $int;
128 $new_echeance->fk_user_modif = $user->id;
129 $result = $new_echeance->update($user, 0);
130 if ($result < 0) {
131 setEventMessages(null, $new_echeance->errors, 'errors');
132 $db->rollback();
133 $echeances->fetchAll($object->id);
134 break;
135 }
136
137 $echeances->lines[$i - 1] = $new_echeance;
138 $i++;
139 }
140 if ($result > 0) {
141 $db->commit();
142 }
143}
144
145
146/*
147 * View
148 */
149
150$form = new Form($db);
151$formproject = new FormProjets($db);
152
153$title = $langs->trans("Loan").' - '.$langs->trans("Card");
154$help_url = 'EN:Module_Loan|FR:Module_Emprunt';
155
156llxHeader("", $title, $help_url, '', 0, 0, '', '', '', 'mod-loan page-card_schedule');
157
158$head = loan_prepare_head($object);
159print dol_get_fiche_head($head, 'FinancialCommitment', $langs->trans("Loan"), -1, 'money-bill-alt');
160
161$linkback = '<a href="'.DOL_URL_ROOT.'/loan/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
162
163$morehtmlref = '<div class="refidno">';
164// Ref loan
165$morehtmlref .= $form->editfieldkey("Label", 'label', $object->label, $object, 0, 'string', '', 0, 1);
166$morehtmlref .= $form->editfieldval("Label", 'label', $object->label, $object, 0, 'string', '', null, null, '', 1);
167// Project
168if (isModEnabled('project')) {
169 $langs->loadLangs(array("projects"));
170 $morehtmlref .= '<br>'.$langs->trans('Project').' : ';
171 if ($user->hasRight('loan', 'write')) {
172 if ($action != 'classify') {
173 //$morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> : ';
174 if ($action == 'classify') {
175 //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
176 $morehtmlref .= '<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
177 $morehtmlref .= '<input type="hidden" name="action" value="classin">';
178 $morehtmlref .= '<input type="hidden" name="token" value="'.newToken().'">';
179 $morehtmlref .= $formproject->select_projects(-1, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1);
180 $morehtmlref .= '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
181 $morehtmlref .= '</form>';
182 } else {
183 $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, -1, $object->fk_project, 'none', 0, 0, 0, 1, '', 'maxwidth300');
184 }
185 }
186 } else {
187 if (!empty($object->fk_project)) {
188 $proj = new Project($db);
189 $proj->fetch($object->fk_project);
190 $morehtmlref .= ' : '.$proj->getNomUrl(1);
191 if ($proj->title) {
192 $morehtmlref .= ' - '.$proj->title;
193 }
194 } else {
195 $morehtmlref .= '';
196 }
197 }
198}
199$morehtmlref .= '</div>';
200
201$morehtmlstatus = '';
202
203dol_banner_tab($object, 'loanid', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', $morehtmlstatus);
204
205?>
206<script type="text/javascript">
207$(document).ready(function() {
208 $('[name^="mens"]').focusout(function() {
209 var echeance=$(this).attr('ech');
210 var mens=price2numjs($(this).val());
211 var idcap=echeance-1;
212 idcap = '#hi_capital'+idcap;
213 var capital=price2numjs($(idcap).val());
214 console.log("Change monthly amount echeance="+echeance+" idcap="+idcap+" capital="+capital);
215 $.ajax({
216 method: "GET",
217 dataType: 'json',
218 url: 'calcmens.php',
219 data: { echeance: echeance, mens: mens, capital:capital, rate:<?php echo $object->rate / 100; ?>, nbterm: <?php echo $object->nbterm; ?>, token: '<?php echo currentToken(); ?>' },
220 success: function(data) {
221 $.each(data, function(index, element) {
222 var idcap_res='#hi_capital'+index;
223 var idcap_res_srt='#capital'+index;
224 var interet_res='#hi_interets'+index;
225 var interet_res_str='#interets'+index;
226 var men_res='#mens'+index;
227 $(idcap_res).val(element.cap_rest);
228 $(idcap_res_srt).text(element.cap_rest_str);
229 $(interet_res).val(element.interet);
230 $(interet_res_str).text(element.interet_str);
231 $(men_res).val(element.mens);
232 });
233 }
234 });
235 });
236});
237</script>
238<?php
239
240if ($pay_without_schedule == 1) {
241 print '<div class="warning">'.$langs->trans('CantUseScheduleWithLoanStartedToPaid').'</div>'."\n";
242}
243
244print '<form name="createecheancier" action="'.$_SERVER["PHP_SELF"].'" method="POST">';
245print '<input type="hidden" name="token" value="'.newToken().'">';
246print '<input type="hidden" name="loanid" value="'.$loanid.'">';
247if (count($echeances->lines) > 0) {
248 print '<input type="hidden" name="action" value="updateecheancier">';
249} else {
250 print '<input type="hidden" name="action" value="createecheancier">';
251}
252
253//print_fiche_titre($langs->trans("FinancialCommitment"));
254print '<br>';
255
256print '<div class="div-table-responsive-no-min">';
257print '<table class="border centpercent">';
258
259$colspan = 6;
260if (count($echeances->lines) > 0) {
261 $colspan++;
262}
263
264print '<tr class="liste_titre">';
265print '<th class="center">'.$langs->trans("Term").'</th>';
266print '<th class="center">'.$langs->trans("Date").'</th>';
267print '<th class="center">'.$langs->trans("Insurance");
268print '<th class="center">'.$langs->trans("InterestAmount").'</th>';
269print '<th class="center">'.$langs->trans("Amount").'</th>';
270print '<th class="center">'.$langs->trans("CapitalRemain");
271print '<br>('.price($object->capital, 0, '', 1, -1, -1, $conf->currency).')';
272print '<input type="hidden" name="hi_capital0" id ="hi_capital0" value="'.$object->capital.'">';
273print '</th>';
274if (count($echeances->lines) > 0) {
275 print '<th class="center">'.$langs->trans('DoPayment').'</th>';
276}
277print '</tr>'."\n";
278
279if ($object->nbterm > 0 && count($echeances->lines) == 0) {
280 $i = 1;
281 $capital = $object->capital;
282 $insurance = (float) $object->insurance_amount / $object->nbterm;
283 $insurance = price2num($insurance, 'MT');
284 $regulInsurance = price2num((float) $object->insurance_amount - ((float) $insurance * $object->nbterm));
285 while ($i < $object->nbterm + 1) {
286 $mens = price2num($echeances->calcMonthlyPayments($capital, $object->rate / 100, $object->nbterm - $i + 1), 'MT');
287 $int = ($capital * ($object->rate / 12)) / 100;
288 $int = price2num($int, 'MT');
289 $insu = ((float) $insurance + (($i == 1) ? (float) $regulInsurance : 0));
290 $cap_rest = price2num((float) $capital - ((float) $mens - (float) $int), 'MT');
291 print '<tr>';
292 print '<td class="center" id="n'.$i.'">'.$i.'</td>';
293 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>';
294 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.'">';
295 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.'">';
296 print '<td class="center"><input class="width75 right" name="mens'.$i.'" id="mens'.$i.'" value="'.$mens.'" ech="'.$i.'"></td>';
297 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.'">';
298 print '</tr>'."\n";
299 $i++;
300 $capital = $cap_rest;
301 }
302} elseif (count($echeances->lines) > 0) {
303 $i = 1;
304 $capital = $object->capital;
305 $insurance = (float) $object->insurance_amount / $object->nbterm;
306 $insurance = price2num($insurance, 'MT');
307 $regulInsurance = price2num((float) $object->insurance_amount - ((float) $insurance * $object->nbterm));
308 $printed = false;
309 foreach ($echeances->lines as $line) {
310 $mens = $line->amount_capital + $line->amount_interest;
311 $int = $line->amount_interest;
312 $insu = ((float) $insurance + (($i == 1) ? (float) $regulInsurance : 0));
313 $cap_rest = price2num($capital - ($mens - $int), 'MT');
314
315 print '<tr>';
316 print '<td class="center" id="n'.$i.'"><input type="hidden" name="hi_rowid'.$i.'" id ="hi_rowid'.$i.'" value="'.$line->id.'">'.$i.'</td>';
317 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>';
318 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.'">';
319 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.'">';
320 if (empty($line->fk_bank)) {
321 print '<td class="center"><input class="right width75" name="mens'.$i.'" id="mens'.$i.'" value="'.$mens.'" ech="'.$i.'"></td>';
322 } else {
323 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.'">';
324 }
325
326 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.'">';
327 print '<td class="center">';
328 if (!empty($line->fk_bank)) {
329 print $langs->trans('Paid');
330 if (!empty($line->fk_payment_loan)) {
331 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>';
332 }
333 } elseif (!$printed) {
334 print '<a class="butAction smallpaddingimp" href="'.DOL_URL_ROOT.'/loan/payment/payment.php?id='.$object->id.'&action=create">'.$langs->trans('DoPayment').'</a>';
335 $printed = true;
336 }
337 print '</td>';
338 print '</tr>'."\n";
339 $i++;
340 $capital = $cap_rest;
341 }
342}
343
344print '</table>';
345print '</div>';
346
347print '</br>';
348
349if (count($echeances->lines) == 0) {
350 $label = $langs->trans("Create");
351} else {
352 $label = $langs->trans("Save");
353}
354print '<div class="center"><input type="submit" class="button button-add" value="'.$label.'" '.(($pay_without_schedule == 1) ? 'disabled title="'.$langs->trans('CantUseScheduleWithLoanStartedToPaid').'"' : '').'title=""></div>';
355print '</form>';
356
357// End of page
358llxFooter();
359$db->close();
$id
Definition account.php:39
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
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:70
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
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:137
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.