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