dolibarr 24.0.0-beta
card.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2011-2026 Alexandre Spangaro <alexandre@inovea-conseil.com>
3 * Copyright (C) 2014-2020 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
5 * Copyright (C) 2015 Charlie BENKE <charlie@patas-monkey.com>
6 * Copyright (C) 2018-2025 Frédéric France <frederic.france@free.fr>
7 * Copyright (C) 2021 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
8 * Copyright (C) 2023 Maxime Nicolas <maxime@oarces.com>
9 * Copyright (C) 2023 Benjamin GREMBI <benjamin@oarces.com>
10 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
11 * Copyright (C) 2024-2025 Nick Fragoulis
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <https://www.gnu.org/licenses/>.
25 */
26
33// Load Dolibarr environment
34require '../main.inc.php';
42require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
43require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
44require_once DOL_DOCUMENT_ROOT.'/salaries/class/salary.class.php';
45require_once DOL_DOCUMENT_ROOT.'/salaries/class/paymentsalary.class.php';
46require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
47require_once DOL_DOCUMENT_ROOT.'/core/lib/salaries.lib.php';
48require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
49require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
50require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
51if (isModEnabled('project')) {
52 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
53 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
54}
55
56// Load translation files required by the page
57$langs->loadLangs(array("compta", "banks", "bills", "users", "salaries", "hrm", "trips"));
58if (isModEnabled('project')) {
59 $langs->load("projects");
60}
61
62$id = GETPOSTINT('id');
63$ref = GETPOST('ref', 'alpha');
64$action = GETPOST('action', 'aZ09');
65$cancel = GETPOST('cancel', 'alpha');
66$backtopage = GETPOST('backtopage', 'alpha');
67$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha');
68$confirm = GETPOST('confirm');
69$backurlforlist = GETPOST('backtopage', 'alpha');
70
71$label = GETPOST('label', 'alphanohtml');
72$projectid = GETPOSTINT('projectid') ? GETPOSTINT('projectid') : GETPOSTINT('fk_project');
73$accountid = GETPOSTINT('accountid') > 0 ? GETPOSTINT('accountid') : 0;
74if (GETPOSTISSET('auto_create_paiement') || $action === 'add') {
75 $auto_create_paiement = GETPOSTINT("auto_create_paiement");
76} else {
77 $auto_create_paiement = !getDolGlobalString('CREATE_NEW_SALARY_WITHOUT_AUTO_PAYMENT');
78}
79
80$datep = dol_mktime(12, 0, 0, GETPOSTINT("datepmonth"), GETPOSTINT("datepday"), GETPOSTINT("datepyear"));
81$datev = dol_mktime(12, 0, 0, GETPOSTINT("datevmonth"), GETPOSTINT("datevday"), GETPOSTINT("datevyear"));
82$datesp = dol_mktime(12, 0, 0, GETPOSTINT("datespmonth"), GETPOSTINT("datespday"), GETPOSTINT("datespyear"));
83$dateep = dol_mktime(12, 0, 0, GETPOSTINT("dateepmonth"), GETPOSTINT("dateepday"), GETPOSTINT("dateepyear"));
84$fk_user = GETPOSTINT('userid');
85
86$object = new Salary($db);
87$extrafields = new ExtraFields($db);
88
89$childids = $user->getAllChildIds(1);
90
91// fetch optionals attributes and labels
92$extrafields->fetch_name_optionals_label($object->table_element);
93
94// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
95$hookmanager->initHooks(array('salarycard', 'globalcard'));
96
97if ($id > 0) {
98 $object->fetch($id);
99
100 // Check current user can read this salary
101 $canread = 0;
102 if ($user->hasRight('salaries', 'readall')) {
103 $canread = 1;
104 }
105 if ($user->hasRight('salaries', 'read') && $object->fk_user > 0 && in_array($object->fk_user, $childids)) {
106 $canread = 1;
107 }
108 if (!$canread) {
110 }
111}
112
113// Security check
114$socid = GETPOSTINT('socid');
115if ($user->socid) {
116 $socid = $user->socid;
117}
118
119restrictedArea($user, 'salaries', $id, 'salary', '');
120
121$permissiontoread = $user->hasRight('salaries', 'read');
122$permissiontoadd = $user->hasRight('salaries', 'write'); // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
123$permissiontodelete = $user->hasRight('salaries', 'delete') || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_UNPAID);
124$permissiontoeditextra = $permissiontoadd;
125if (GETPOST('attribute', 'aZ09') && isset($extrafields->attributes[$object->table_element]['perms'][GETPOST('attribute', 'aZ09')])) {
126 // For action 'update_extras', is there a specific permission set for the attribute to update
127 $permissiontoeditextra = dol_eval((string) $extrafields->attributes[$object->table_element]['perms'][GETPOST('attribute', 'aZ09')]);
128}
129
130$upload_dir = $conf->salaries->multidir_output[$conf->entity];
131
132$error = 0;
133$resteapayer = 0;
134
135/*
136 * Actions
137 */
138
139$parameters = array();
140$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action);
141if ($reshook < 0) {
142 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
143}
144
145if (empty($reshook)) {
146 $error = 0;
147
148 // Actions to build the document
149 $upload_dir = $conf->salaries->dir_output;
150 $permissiontoadd = $user->hasRight('salaries', 'write');
151
152 // $object->element = 'salary';
153 if (empty($object->ref) && !empty($object->id)) {
154 $object->ref = (string) $object->id;
155 }
156
157 include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
158
159 // Actions to send emails
160 $trackid = 'sal'.$object->id;
161 include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
162}
163
164// Link to a project
165if ($action == 'classin' && $permissiontoadd) {
166 $object->fetch($id);
167 $object->setProject($projectid);
168}
169
170// set label
171if ($action == 'setlabel' && $permissiontoadd) {
172 $object->fetch($id);
173 $object->label = $label;
174 $object->update($user);
175}
176
177// Classify paid
178if ($action == 'confirm_paid' && $permissiontoadd && $confirm == 'yes') {
179 $object->fetch($id);
180 $result = $object->setPaid($user);
181}
182
183if ($action == 'setfk_user' && $permissiontoadd) {
184 $result = $object->fetch($id);
185 if ($result > 0) {
186 $object->fk_user = $fk_user;
187 $object->update($user);
188 } else {
190 exit;
191 }
192}
193
194if ($action == 'reopen' && $permissiontoadd) {
195 $result = $object->fetch($id);
196 if ($object->paye) {
197 $result = $object->set_unpaid($user);
198 if ($result > 0) {
199 header('Location: '.dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $id]));
200 exit();
201 } else {
202 setEventMessages($object->error, $object->errors, 'errors');
203 }
204 }
205}
206
207// payment mode
208if ($action == 'setmode' && $permissiontoadd) {
209 $object->fetch($id);
210 $result = $object->setPaymentMethods(GETPOSTINT('mode_reglement_id'));
211 if ($result < 0) {
212 setEventMessages($object->error, $object->errors, 'errors');
213 }
214}
215
216// bank account
217if ($action == 'setbankaccount' && $permissiontoadd) {
218 $object->fetch($id);
219 $result = $object->setBankAccount(GETPOSTINT('fk_account'));
220 if ($result < 0) {
221 setEventMessages($object->error, $object->errors, 'errors');
222 }
223}
224
225if ($action == 'add' && empty($cancel) && $permissiontoadd) {
226 $error = 0;
227
228 if (empty($datev)) {
229 $datev = $datep;
230 }
231
232 $type_payment = GETPOSTINT("paymenttype");
233 $amount = price2num(GETPOST("amount", 'alpha'), 'MT', 2);
234
235 $object->accountid = GETPOSTINT("accountid") > 0 ? GETPOSTINT("accountid") : 0;
236 $object->fk_user = GETPOSTINT("fk_user") > 0 ? GETPOSTINT("fk_user") : 0;
237 $object->datev = $datev;
238 $object->datep = $datep;
239 $object->amount = $amount;
240 $object->label = GETPOST("label", 'alphanohtml');
241 $object->datesp = $datesp;
242 $object->dateep = $dateep;
243 $object->note = GETPOST("note", 'restricthtml');
244 $object->type_payment = ($type_payment > 0 ? $type_payment : 0);
245 $object->fk_user_author = $user->id;
246 $object->fk_project = $projectid;
247
248 // Set user current salary as ref salary for the payment
249 $fuser = new User($db);
250 $fuser->fetch(GETPOSTINT("fk_user"));
251 $object->salary = $fuser->salary;
252
253 // Fill array 'array_options' with data from add form
254 $ret = $extrafields->setOptionalsFromPost(null, $object);
255 if ($ret < 0) {
256 $error++;
257 }
258
259 if (!empty($auto_create_paiement) && empty($datep)) {
260 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("DATE_PAIEMENT")), null, 'errors');
261 $error++;
262 }
263 if (empty($datesp) || empty($dateep)) {
264 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
265 $error++;
266 }
267 if (empty($object->fk_user) || $object->fk_user < 0) {
268 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Employee")), null, 'errors');
269 $error++;
270 }
271 if (!empty($auto_create_paiement) && (empty($type_payment) || $type_payment < 0)) {
272 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("PaymentMode")), null, 'errors');
273 $error++;
274 }
275 if (empty($object->amount)) {
276 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Amount")), null, 'errors');
277 $error++;
278 }
279 if (isModEnabled("bank") && !empty($auto_create_paiement) && !$object->accountid > 0) {
280 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("BankAccount")), null, 'errors');
281 $error++;
282 }
283
284 if (!$error) {
285 $db->begin();
286
287 $ret = $object->create($user);
288 if ($ret < 0) {
289 setEventMessages($object->error, $object->errors, 'errors');
290 $error++;
291 }
292 if (!empty($auto_create_paiement) && !$error) {
293 // Create a line of payments
294 $paiement = new PaymentSalary($db);
295 $paiement->fk_salary = $object->id;
296 $paiement->chid = $object->id; // deprecated
297 $paiement->datep = $datep;
298 $paiement->datev = $datev;
299 $paiement->amounts = array($object->id => $amount); // Tableau de montant
300 $paiement->fk_typepayment = $type_payment;
301 $paiement->num_payment = GETPOST("num_payment", 'alphanohtml');
302 $paiement->note_private = GETPOST("note", 'restricthtml');
303
304 if (!$error) {
305 $paymentid = $paiement->create($user, (int) GETPOST('closepaidsalary'));
306 if ($paymentid < 0) {
307 $error++;
308 setEventMessages($paiement->error, null, 'errors');
309 $action = 'create';
310 }
311 }
312
313 if (!$error) {
314 $result = $paiement->addPaymentToBank($user, 'payment_salary', '(SalaryPayment)', GETPOSTINT('accountid'), '', '');
315 if (!($result > 0)) {
316 $error++;
317 setEventMessages($paiement->error, null, 'errors');
318 }
319 }
320 }
321
322 if (empty($error)) {
323 $db->commit();
324
325 if (GETPOST('saveandnew', 'alpha')) {
326 setEventMessages($langs->trans("RecordSaved"), null);
327 $query = [
328 'action' => 'create',
329 'fk_project' => $projectid,
330 'accountid' => $accountid,
331 'paymenttype' => GETPOSTINT('paymenttype'),
332 'datepday' => GETPOSTINT("datepday"),
333 'datepmonth' => GETPOSTINT("datepmonth"),
334 'datepyear' => GETPOSTINT("datepyear"),
335 ];
336 header("Location: ". dolBuildUrl($_SERVER['PHP_SELF'], $query));
337 exit;
338 } else {
339 header("Location: " . dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id]));
340 exit;
341 }
342 } else {
343 $db->rollback();
344 }
345 }
346
347 $action = 'create';
348}
349
350if ($action == 'confirm_delete' && $permissiontodelete) {
351 $result = $object->fetch($id);
352 $totalpaid = $object->getSommePaiement();
353
354 if (empty($totalpaid)) {
355 $db->begin();
356
357 $ret = $object->delete($user);
358 if ($ret > 0) {
359 $db->commit();
360 header("Location: ".dolBuildUrl(DOL_URL_ROOT.'/salaries/list.php'));
361 exit;
362 } else {
363 $db->rollback();
364 setEventMessages($object->error, $object->errors, 'errors');
365 }
366 } else {
367 setEventMessages($langs->trans('DisabledBecausePayments'), null, 'errors');
368 }
369}
370
371
372if ($action == 'update' && !GETPOST("cancel") && $permissiontoadd) {
373 $amount = price2num(GETPOST('amount'), 'MT', 2);
374
375 if (empty($amount)) {
376 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Amount")), null, 'errors');
377 $action = 'edit';
378 } elseif (!is_numeric($amount)) {
379 setEventMessages($langs->trans("ErrorFieldMustBeANumeric", $langs->transnoentities("Amount")), null, 'errors');
380 $action = 'create';
381 } else {
382 $result = $object->fetch($id);
383
384 $object->amount = price2num($amount);
385 $object->datesp = price2num($datesp);
386 $object->dateep = price2num($dateep);
387
388 $result = $object->update($user);
389 if ($result <= 0) {
390 setEventMessages($object->error, $object->errors, 'errors');
391 }
392 }
393}
394
395if ($action == 'confirm_clone' && $confirm != 'yes') { // Test on permission not required here
396 $action = '';
397}
398
399if ($action == 'confirm_clone' && $confirm == 'yes' && $permissiontoadd) {
400 $db->begin();
401
402 $originalId = $id;
403
404 $object->fetch($id);
405
406 if ($object->id > 0) {
407 $object->paye = 0;
408 $object->id = 0;
409 $object->ref = '';
410
411 if (GETPOST('amount', 'alphanohtml')) {
412 $object->amount = price2num(GETPOST('amount', 'alphanohtml'), 'MT', 2);
413 }
414
415 if (GETPOST('clone_label', 'alphanohtml')) {
416 $object->label = GETPOST('clone_label', 'alphanohtml');
417 } else {
418 $object->label = $langs->trans("CopyOf").' '.$object->label;
419 }
420
421 $newdatestart = dol_mktime(0, 0, 0, GETPOSTINT('clone_date_startmonth'), GETPOSTINT('clone_date_startday'), GETPOSTINT('clone_date_startyear'));
422 $newdateend = dol_mktime(0, 0, 0, GETPOSTINT('clone_date_endmonth'), GETPOSTINT('clone_date_endday'), GETPOSTINT('clone_date_endyear'));
423
424 if ($newdatestart) {
425 $object->datesp = $newdatestart;
426 }
427 if ($newdateend) {
428 $object->dateep = $newdateend;
429 }
430
431 $id = $object->create($user);
432 if ($id > 0) {
433 $db->commit();
434 $db->close();
435
436 header("Location: ".dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $id]));
437 exit;
438 } else {
439 $id = $originalId;
440 $db->rollback();
441
442 setEventMessages($object->error, $object->errors, 'errors');
443 }
444 } else {
445 $db->rollback();
446 dol_print_error($db, $object->error);
447 }
448}
449
450
451// Action to update one extrafield
452if ($action == 'update_extras' && $permissiontoeditextra) {
453 $object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
454
455 $attribute = GETPOST('attribute', 'aZ09');
456
457 // Fill array 'array_options' with data from update form
458 $ret = $extrafields->setOptionalsFromPost(null, $object, $attribute);
459 if ($ret < 0) {
460 setEventMessages($extrafields->error, $object->errors, 'errors');
461 $error++;
462 }
463
464 if (!$error) {
465 $result = $object->updateExtraField($attribute, 'SALARY_MODIFY');
466 if ($result < 0) {
467 setEventMessages($object->error, $object->errors, 'errors');
468 $error++;
469 }
470 }
471
472 if ($error) {
473 $action = 'edit_extras';
474 }
475}
476
477/*
478 * View
479 */
480
481$form = new Form($db);
482$formfile = new FormFile($db);
483if (isModEnabled('project')) {
484 $formproject = new FormProjets($db);
485}
486
487$title = $langs->trans('Salary')." - ".$object->ref;
488if ($action == 'create') {
489 $title = $langs->trans("NewSalary");
490}
491$help_url = "";
492llxHeader('', $title, $help_url);
493
494
495if ($id > 0) {
496 $result = $object->fetch($id);
497 if ($result <= 0) {
499 exit;
500 }
501}
502
503// Create
504if ($action == 'create' && $permissiontoadd) {
505 $year_current = (int) dol_print_date(dol_now('gmt'), "%Y", 'gmt');
506 $pastmonth = (int) dol_print_date(dol_now(), "%m") - 1;
507 $pastmonthyear = $year_current;
508 if ($pastmonth == 0) {
509 $pastmonth = 12;
510 $pastmonthyear--;
511 }
512
513 $datespmonth = GETPOSTINT('datespmonth');
514 $datespday = GETPOSTINT('datespday');
515 $datespyear = GETPOSTINT('datespyear');
516 $dateepmonth = GETPOSTINT('dateepmonth');
517 $dateepday = GETPOSTINT('dateepday');
518 $dateepyear = GETPOSTINT('dateepyear');
519 $datesp = dol_mktime(0, 0, 0, $datespmonth, $datespday, $datespyear);
520 $dateep = dol_mktime(23, 59, 59, $dateepmonth, $dateepday, $dateepyear);
521
522 if (empty($datesp) || empty($dateep)) { // We define date_start and date_end
523 $datesp = dol_get_first_day($pastmonthyear, $pastmonth, false);
524 $dateep = dol_get_last_day($pastmonthyear, $pastmonth, false);
525 }
526
527 print '<form name="salary" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'" method="POST">';
528 print '<input type="hidden" name="token" value="'.newToken().'">';
529 print '<input type="hidden" name="action" value="add">';
530 if ($backtopage) {
531 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
532 }
533 if ($backtopageforcancel) {
534 print '<input type="hidden" name="backtopageforcancel" value="'.$backtopageforcancel.'">';
535 }
536
537 print load_fiche_titre($langs->trans("NewSalary"), '', 'salary');
538
539 if (!empty($conf->use_javascript_ajax)) {
540 print "\n".'<script type="text/javascript">';
541 print '
542 $(document).ready(function () {
543 let onAutoCreatePaiementChange = function () {
544 if($("#auto_create_paiement").is(":checked")) {
545 $("#label_fk_account").find("span").addClass("fieldrequired");
546 $("#label_type_payment").find("span").addClass("fieldrequired");
547 $(".hide_if_no_auto_create_payment").show();
548 } else {
549 $("#label_fk_account").find("span").removeClass("fieldrequired");
550 $("#label_type_payment").find("span").removeClass("fieldrequired");
551 $(".hide_if_no_auto_create_payment").hide();
552 }
553 };
554 $("#radiopayment").click(function() {
555 $("#label").val($(this).data("label"));
556 });
557 $("#radiorefund").click(function() {
558 $("#label").val($(this).data("label"));
559 });
560 $("#auto_create_paiement").click(function () {
561 onAutoCreatePaiementChange();
562 });
563 onAutoCreatePaiementChange();
564 });
565
566 // Month shortcut keys for datesp / dateep
567 window.setSalaryDatePeriod = function(offset) {
568 var now = new Date();
569 var year = now.getFullYear();
570 var month = now.getMonth() + 1 + parseInt(offset);
571
572 if (month < 1) { month = 12; year--; }
573 if (month > 12) { month = 1; year++; }
574
575 var lastDay = new Date(year, month, 0).getDate();
576
577 var mm = String(month).padStart(2, "0");
578 var ld = String(lastDay).padStart(2, "0");
579 var yy = String(year);
580
581 // Start date
582 $("#datespday").val("01");
583 $("#datespmonth").val(mm);
584 $("#datespyear").val(yy);
585 $("#datesp").val("01/" + mm + "/" + yy);
586
587 // End date
588 $("#dateepday").val(ld);
589 $("#dateepmonth").val(mm);
590 $("#dateepyear").val(yy);
591 $("#dateep").val(ld + "/" + mm + "/" + yy);
592 };
593 ';
594 print '</script>'."\n";
595 }
596
597 print dol_get_fiche_head();
598
599 print '<table class="border centpercent">';
600
601 // Employee
602 print '<tr><td class="titlefieldcreate">';
603 print $form->editfieldkey('Employee', 'fk_user', '', $object, 0, 'string', '', 1).'</td><td>';
604 $noactive = 0; // We keep active and unactive users
605 print img_picto('', 'user', 'class="pictofixedwidth"').$form->select_dolusers(GETPOSTINT('fk_user'), 'fk_user', 1, null, 0, '', '', '0', 0, 0, 'employee:=:1', 0, '', 'maxwidth300', $noactive);
606 print '</td></tr>';
607
608 // Label
609 print '<tr><td>';
610 print $form->editfieldkey('Label', 'label', '', $object, 0, 'string', '', 1).'</td><td>';
611 print '<input name="label" id="label" class="minwidth300" value="'.(GETPOST("label") ? GETPOST("label") : $langs->trans("Salary")).'">';
612 print '</td></tr>';
613
614 // Date start period
615 print '<tr><td>';
616 print $form->editfieldkey('DateStartPeriod', 'datesp', '', $object, 0, 'string', '', 1).'</td><td>';
617 print $form->selectDate($datesp, "datesp", 0, 0, 0, 'add');
618
619 // Shortcut buttons: previous month / current month / next month
620 if (!empty($conf->use_javascript_ajax)) {
621 print '<button type="button" class="dpInvisibleButtons" style="color: var(--colortextlink);font-size: 0.8em;opacity: 0.7;margin-left:4px;" onclick="setSalaryDatePeriod(-1)">'.$langs->trans('PreviousMonthShort').'</button> ';
622 print '<button type="button" class="dpInvisibleButtons" style="color: var(--colortextlink);font-size: 0.8em;opacity: 0.7;margin-left:4px;" onclick="setSalaryDatePeriod(0)">'.$langs->trans('CurrentMonthShort').'</button> ';
623 print '<button type="button" class="dpInvisibleButtons" style="color: var(--colortextlink);font-size: 0.8em;opacity: 0.7;margin-left:4px;" onclick="setSalaryDatePeriod(1)">'.$langs->trans('NextMonthShort').'</button>';
624 }
625 print '</td></tr>';
626
627 // Date end period
628 print '<tr><td>';
629 print $form->editfieldkey('DateEndPeriod', 'dateep', '', $object, 0, 'string', '', 1).'</td><td>';
630 print $form->selectDate($dateep, "dateep", 0, 0, 0, 'add');
631 print '</td></tr>';
632
633 // Amount
634 print '<tr><td>';
635 print $form->editfieldkey('Amount', 'amount', '', $object, 0, 'string', '', 1).'</td><td>';
636 print '<input name="amount" id="amount" class="minwidth75 maxwidth100" value="'.GETPOST("amount").'"> &nbsp;';
637 print ' <button class="dpInvisibleButtons datenowlink" id="updateAmountWithLastSalary" name="_useless" type="button">'.$langs->trans('UpdateAmountWithLastSalary').'</a>';
638 print '</td>';
639 print '</tr>';
640
641 // Project
642 if (isModEnabled('project')) {
643 $formproject = new FormProjets($db);
644
645 print '<tr><td>'.$langs->trans("Project").'</td><td>';
646 print img_picto('', 'project', 'class="pictofixedwidth"');
647 print $formproject->select_projects(-1, (string) $projectid, 'fk_project', 0, 0, 1, 1, 0, 0, 0, '', 1);
648 print '</td></tr>';
649 }
650
651 // Comments
652 print '<tr>';
653 print '<td class="tdtop">'.$langs->trans("Comments").'</td>';
654 print '<td class="tdtop"><textarea name="note" wrap="soft" cols="60" rows="'.ROWS_3.'">'.GETPOST('note', 'restricthtml').'</textarea></td>';
655 print '</tr>';
656
657
658 print '<tr><td colspan="2"><hr></td></tr>';
659
660
661 // Auto create payment
662 print '<tr><td><label for="auto_create_paiement">'.$langs->trans('AutomaticCreationPayment').'</label></td>';
663 print '<td><input id="auto_create_paiement" name="auto_create_paiement" type="checkbox" ' . (empty($auto_create_paiement) ? '' : 'checked="checked"') . ' value="1"></td></tr>'."\n"; // Date payment
664
665 // Bank
666 if (isModEnabled("bank")) {
667 print '<tr><td id="label_fk_account">';
668 print $form->editfieldkey('BankAccount', 'selectaccountid', '', $object, 0, 'string', '', 1).'</td><td>';
669 print img_picto('', 'bank_account', 'class="pictofixedwidth"');
670 $form->select_comptes($accountid, "accountid", 0, '', 1); // Affiche liste des comptes courant
671 print '</td></tr>';
672 }
673
674 // Type payment
675 print '<tr><td id="label_type_payment">';
676 print $form->editfieldkey('PaymentMode', 'selectpaymenttype', '', $object, 0, 'string', '', 1).'</td><td>';
677 print img_picto('', 'bank', 'class="pictofixedwidth"');
678 print $form->select_types_paiements(GETPOST("paymenttype", 'aZ09'), "paymenttype", '');
679 print '</td></tr>';
680
681 // Date payment
682 print '<tr class="hide_if_no_auto_create_payment"><td>';
683 print $form->editfieldkey('DatePayment', 'datep', '', $object, 0, 'string', '', 1).'</td><td>';
684 print $form->selectDate((empty($datep) ? '' : $datep), "datep", 0, 0, 0, 'add', 1, 1);
685 print '</td></tr>';
686
687 // Date value for bank
688 print '<tr class="hide_if_no_auto_create_payment"><td>';
689 print $form->editfieldkey('DateValue', 'datev', '', $object, 0).'</td><td>';
690 print $form->selectDate((empty($datev) ? -1 : $datev), "datev", 0, 0, 0, 'add', 1, 1);
691 print '</td></tr>';
692
693 // Number
694 if (isModEnabled("bank")) {
695 // Number
696 print '<tr class="hide_if_no_auto_create_payment"><td><label for="num_payment">'.$langs->trans('Numero');
697 print ' <em>('.$langs->trans("ChequeOrTransferNumber").')</em>';
698 print '</label></td>';
699 print '<td><input name="num_payment" id="num_payment" type="text" value="'.GETPOST("num_payment").'"></td></tr>'."\n";
700 }
701
702 // Other attributes
703 $parameters = array();
704 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
705 print $hookmanager->resPrint;
706 if (empty($reshook)) {
707 print $object->showOptionals($extrafields, 'create');
708 }
709
710 print '</table>';
711
712 print dol_get_fiche_end();
713
714 print '<div class="center">';
715
716 print '<div class="hide_if_no_auto_create_payment paddingbottom">';
717 print '<input type="checkbox" checked value="1" name="closepaidsalary" id="closepaidsalary" class="marginrightonly"><label for="closepaidsalary" class="opacitymedium">'.$langs->trans("ClosePaidSalaryAutomatically").'</label>';
718 print '</div>';
719
720 print '</div>';
721
722 $addition_button = array(
723 'name' => 'saveandnew',
724 'label_key' => 'SaveAndNew',
725 );
726 print $form->buttonsSaveCancel("Save", "Cancel", $addition_button);
727
728 print '</form>';
729 print '<script>';
730 print '$( document ).ready(function() {';
731 print '$("#updateAmountWithLastSalary").on("click", function updateAmountWithLastSalary() {
732 var fk_user = $("#fk_user").val()
733 var url = "'.DOL_URL_ROOT.'/salaries/ajax/ajaxsalaries.php?fk_user="+fk_user;
734 console.log("We click on link to autofill salary amount url="+url);
735
736 if (fk_user != -1) {
737 $.get(
738 url,
739 function( data ) {
740 console.log("Data returned: "+data);
741 if (data != null) {
742 if (typeof data == "object") {
743 console.log("data is already type object, no need to parse it");
744 item = data;
745 } else {
746 console.log("data is type "+(typeof data));
747 item = JSON.parse(data);
748 }
749 if (item[0].key == "Amount") {
750 value = item[0].value;
751 console.log("amount returned = "+value);
752 if (value != null) {
753 $("#amount").val(item[0].value);
754 } else {
755 console.error("Error: Ajax url "+url+" has returned a null value.");
756 }
757 } else {
758 console.error("Error: Ajax url "+url+" has returned the wrong key.");
759 }
760 } else {
761 console.error("Error: Ajax url "+url+" has returned an empty page.");
762 }
763 }
764 );
765
766 } else {
767 alert("'.dol_escape_js($langs->transnoentitiesnoconv("FillFieldFirst")).'");
768 }
769 });
770
771 })';
772 print '</script>';
773}
774
775// View mode
776if ($id > 0) {
777 $head = salaries_prepare_head($object);
778 $formconfirm = '';
779 $pageurl = dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id]);
780
781 if ($action === 'clone') {
782 $formquestion = array(
783 array('type' => 'text', 'name' => 'clone_label', 'label' => $langs->trans("Label"), 'value' => $langs->trans("CopyOf").' '.$object->label),
784 );
785
786 //$formquestion[] = array('type' => 'date', 'name' => 'clone_date_ech', 'label' => $langs->trans("Date"), 'value' => -1);
787 if (!empty($object->dateep)) {
788 $formquestion[] = array('type' => 'date', 'name' => 'clone_date_start', 'label' => $langs->trans("DateStart"), 'value' => ($object->dateep) + 86400);
789 } else {
790 $formquestion[] = array('type' => 'date', 'name' => 'clone_date_start', 'label' => $langs->trans("DateStart"), 'value' => -1);
791 }
792 $formquestion[] = array('type' => 'date', 'name' => 'clone_date_end', 'label' => $langs->trans("DateEnd"), 'value' => -1);
793 $formquestion[] = array('type' => 'text', 'name' => 'amount', 'label' => $langs->trans("Amount"), 'value' => price($object->amount), 'morecss' => 'width100 right');
794
795 $formconfirm = $form->formconfirm(dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id]), $langs->trans('ToClone'), $langs->trans('ConfirmCloneSalary', $object->ref), 'confirm_clone', $formquestion, 'yes', 1, 300);
796
797 // Add buttons to fill start and end dates
798 $formconfirm .= "<script>
799 // Buttons for start date: previous month, current month, previous week, current week
800 $('#clone_date_start').after(
801 $('<button id=\"start_prev_month\" class=\"dpInvisibleButtons\" style=\"color: var(--colortextlink);font-size: 0.8em;opacity: 0.7;margin-left:4px;\" type=\"button\">".$langs->trans('PreviousMonthShort')."</button>')
802 .add('<button id=\"start_curr_month\" class=\"dpInvisibleButtons\" style=\"color: var(--colortextlink);font-size: 0.8em;opacity: 0.7;margin-left:4px;\" type=\"button\">".$langs->trans('CurrentMonthShort')."</button>')
803 ";
804 if (getDolGlobalString('SALARY_MANAGEMENT_PER_WEEK')) {
805 $formconfirm .= "
806 .add('<button id=\"start_prev_week\" class=\"dpInvisibleButtons\" style=\"color: var(--colortextlink);font-size: 0.8em;opacity: 0.7;margin-left:4px;\" type=\"button\">".$langs->trans('PreviousWeekShort')."</button>')
807 .add('<button id=\"start_curr_week\" class=\"dpInvisibleButtons\" style=\"color: var(--colortextlink);font-size: 0.8em;opacity: 0.7;margin-left:4px;\" type=\"button\">".$langs->trans('CurrentWeekShort')."</button>')";
808 }
809 $formconfirm .= "
810 );
811
812 $('#start_prev_month').click(function(){
813 var now = new Date();
814 var startPrevMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1);
815 setStartDate(startPrevMonth);
816 });
817
818 $('#start_curr_month').click(function(){
819 var now = new Date();
820 var startCurrMonth = new Date(now.getFullYear(), now.getMonth(), 1);
821 setStartDate(startCurrMonth);
822 });
823
824 $('#start_prev_week').click(function(){
825 var now = new Date();
826 var startPrevWeek = new Date(now.setDate(now.getDate() - now.getDay() - 7));
827 startPrevWeek.setDate(startPrevWeek.getDate() + 1);
828 setStartDate(startPrevWeek);
829 });
830
831 $('#start_curr_week').click(function(){
832 var now = new Date();
833 var startCurrWeek = new Date(now.setDate(now.getDate() - now.getDay() + 1));
834 setStartDate(startCurrWeek);
835 });
836
837 function setStartDate(date) {
838 $('#clone_date_start').val(formatDate(date, '".$langs->trans("FormatDateShortJavaInput")."'));
839 $('#clone_date_startday').val(date.getDate());
840 $('#clone_date_startmonth').val(date.getMonth() + 1);
841 $('#clone_date_startyear').val(date.getFullYear());
842 }
843
844 // Button for end date
845 $('#clone_date_end').after($('<button id=\"fill_end_of_month\" class=\"dpInvisibleButtons\" style=\"color: var(--colortextlink);font-size: 0.8em;opacity: 0.7;margin-left:4px;\" type=\"button\">".$langs->trans('FillEndOfMonth')."</button>'));
846 $('#fill_end_of_month').click(function(){
847 var clone_date_startmonth = +$('#clone_date_startmonth').val();
848 var clone_date_startyear = +$('#clone_date_startyear').val();
849 var end_date;
850
851 if (clone_date_startmonth && clone_date_startyear) {
852 end_date = new Date(clone_date_startyear, clone_date_startmonth, 0);
853 } else {
854 var currentDate = new Date();
855 var currentDay = currentDate.getDate();
856 if (currentDay <= 15) {
857 end_date = new Date(currentDate.getFullYear(), currentDate.getMonth(), 0);
858 } else {
859 end_date = new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 0);
860 }
861 }
862
863 $('#clone_date_end').val(formatDate(end_date,'".$langs->trans("FormatDateShortJavaInput")."'));
864 $('#clone_date_endday').val(end_date.getDate());
865 $('#clone_date_endmonth').val(end_date.getMonth() + 1);
866 $('#clone_date_endyear').val(end_date.getFullYear());
867 });
868 </script>";
869 }
870
871 if ($action == 'paid') {
872 $text = $langs->trans('ConfirmPaySalary');
873 $formconfirm = $form->formconfirm(dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id]), $langs->trans('PaySalary'), $text, "confirm_paid", '', '', 2);
874 }
875
876 if ($action == 'delete') {
877 $text = $langs->trans('ConfirmDeleteSalary');
878 $formconfirm = $form->formconfirm(dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id]), $langs->trans('DeleteSalary'), $text, 'confirm_delete', '', '', 2);
879 }
880
881 if ($action == 'edit') {
882 print '<form name="charge" action="'.dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'action' => 'update']).'" method="post">';
883 print '<input type="hidden" name="token" value="'.newToken().'">';
884 }
885
886 // Call Hook formConfirm
887 $parameters = array('formConfirm' => $formconfirm);
888 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
889 if (empty($reshook)) {
890 $formconfirm .= $hookmanager->resPrint;
891 } elseif ($reshook > 0) {
892 $formconfirm = $hookmanager->resPrint;
893 }
894
895 // Print form confirm
896 print $formconfirm;
897
898
899 print dol_get_fiche_head($head, 'card', $langs->trans("SalaryPayment"), -1, 'salary', 0, '', '', 0, '', 1);
900
901 $linkback = '<a href="'.dolBuildUrl(DOL_URL_ROOT.'/salaries/list.php', ['restore_lastsearch_values' => 1]).(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
902
903 $morehtmlref = '<div class="refidno">';
904
905 // Label
906 if ($action != 'editlabel') {
907 $morehtmlref .= $form->editfieldkey("Label", 'label', $object->label, $object, $permissiontoadd, 'string', '', 0, 1);
908 $morehtmlref .= $object->label;
909 } else {
910 $morehtmlref .= $langs->trans('Label').' :&nbsp;';
911 $morehtmlref .= '<form method="post" action="'.$pageurl.'">';
912 $morehtmlref .= '<input type="hidden" name="action" value="setlabel">';
913 $morehtmlref .= '<input type="hidden" name="token" value="'.newToken().'">';
914 $morehtmlref .= '<input type="text" name="label" value="'.$object->label.'"/>';
915 $morehtmlref .= '<input type="submit" class="button valignmiddle smallpaddingimp" value="'.$langs->trans("Modify").'">';
916 $morehtmlref .= '</form>';
917 }
918
919 // Employee
920 if ($action != 'editfk_user') {
921 if ($object->getSommePaiement() > 0 && !empty($object->fk_user)) {
922 $userstatic = new User($db);
923 $result = $userstatic->fetch($object->fk_user);
924 if ($result > 0) {
925 $morehtmlref .= '<br>'.$userstatic->getNomUrl(-1);
926 }
927 } else {
928 $morehtmlref .= '<br>' . $form->editfieldkey("", 'fk_user', $object->label, $object, $permissiontoadd, 'string', '', 0, 1);
929
930 if (!empty($object->fk_user)) {
931 $userstatic = new User($db);
932 $result = $userstatic->fetch($object->fk_user);
933 if ($result > 0) {
934 $morehtmlref .= $userstatic->getNomUrl(-1);
935 } else {
937 exit();
938 }
939 }
940 }
941 } else {
942 $morehtmlref .= '<br>';
943 $morehtmlref .= '<form method="post" action="'.$pageurl.'">';
944 $morehtmlref .= '<input type="hidden" name="action" value="setfk_user">';
945 $morehtmlref .= '<input type="hidden" name="token" value="'.newToken().'">';
946 $morehtmlref .= $form->select_dolusers($object->fk_user, 'userid', 1);
947 $morehtmlref .= '<input type="submit" class="button valignmiddle smallpaddingimp" value="'.$langs->trans("Modify").'">';
948 $morehtmlref .= '</form>';
949 }
950
951 $usercancreate = $permissiontoadd;
952
953 // Project
954 if (isModEnabled('project')) {
955 $langs->load("projects");
956 $morehtmlref .= '<br>';
957 if ($usercancreate) {
958 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
959 if ($action != 'classify') {
960 $morehtmlref .= '<a class="editfielda" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['action' => 'classify', 'id' => $object->id], true).'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
961 }
962 $morehtmlref .= $form->form_project($pageurl, -1, (string) $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
963 } else {
964 if (!empty($object->fk_project)) {
965 $proj = new Project($db);
966 $proj->fetch($object->fk_project);
967 $morehtmlref .= $proj->getNomUrl(1);
968 if ($proj->title) {
969 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
970 }
971 }
972 }
973 }
974
975 $morehtmlref .= '</div>';
976
977 $totalpaid = $object->getSommePaiement();
978
979 $object->totalpaid = $totalpaid;
980 $object->alreadypaid = $totalpaid; // Same then $totalpaid because there is no amount of credit note or deposits for salary payments.
981
982 dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', '');
983
984 print '<div class="fichecenter">';
985 print '<div class="fichehalfleft">';
986 print '<div class="underbanner clearboth"></div>';
987
988 print '<table class="border centpercent tableforfield">';
989
990 if ($action == 'edit') {
991 print '<tr><td class="titlefieldmiddle">'.$langs->trans("DateStartPeriod")."</td><td>";
992 print $form->selectDate($object->datesp, 'datesp', 0, 0, 0, 'datesp', 1);
993 print "</td></tr>";
994 } else {
995 print "<tr>";
996 print '<td class="titlefieldmiddle">' . $langs->trans("DateStartPeriod") . '</td><td>';
997 print dol_print_date($object->datesp, 'day');
998 print '</td></tr>';
999 }
1000
1001 if ($action == 'edit') {
1002 print '<tr><td>'.$langs->trans("DateEndPeriod")."</td><td>";
1003 print $form->selectDate($object->dateep, 'dateep', 0, 0, 0, 'dateep', 1);
1004 print "</td></tr>";
1005 } else {
1006 print "<tr>";
1007 print '<td>' . $langs->trans("DateEndPeriod") . '</td><td>';
1008 print dol_print_date($object->dateep, 'day');
1009 print '</td></tr>';
1010 }
1011
1012 if ($action == 'edit') {
1013 print '<tr><td class="fieldrequired">' . $langs->trans("Amount") . '</td><td><input name="amount" size="10" value="' . price($object->amount) . '"></td></tr>';
1014 } else {
1015 print '<tr><td>' . $langs->trans("Amount") . '</td><td><span class="amount">' . price($object->amount, 0, $langs, 1, -1, -1, $conf->currency) . '</span></td></tr>';
1016 }
1017
1018 // Default mode of payment
1019 print '<tr><td>';
1020 print '<table class="nobordernopadding" width="100%"><tr><td>';
1021 print $langs->trans('DefaultPaymentMode');
1022 print '</td>';
1023 if ($action != 'editmode') {
1024 print '<td class="right"><a class="editfielda" href="'.dolBuildUrl($_SERVER["PHP_SELF"], ['action' => 'editmode', 'id' => $object->id], true).'">'.img_edit($langs->trans('SetMode'), 1).'</a></td>';
1025 }
1026 print '</tr></table>';
1027 print '</td><td>';
1028
1029 if ($action == 'editmode') {
1030 $form->form_modes_reglement($pageurl, (string) $object->type_payment, 'mode_reglement_id');
1031 } else {
1032 $form->form_modes_reglement($pageurl, (string) $object->type_payment, 'none');
1033 }
1034 print '</td></tr>';
1035
1036 // Default Bank Account
1037 if (isModEnabled("bank")) {
1038 print '<tr><td class="nowrap">';
1039 print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
1040 print $langs->trans('DefaultBankAccount');
1041 print '<td>';
1042 if ($action != 'editbankaccount' && $permissiontoadd) {
1043 print '<td class="right"><a class="editfielda" href="'.dolBuildUrl($_SERVER["PHP_SELF"], ['action' => 'editbankaccount', 'id' => $object->id], true).'">'.img_edit($langs->trans('SetBankAccount'), 1).'</a></td>';
1044 }
1045 print '</tr></table>';
1046 print '</td><td>';
1047 if ($action == 'editbankaccount') {
1048 $form->formSelectAccount($pageurl, (string) $object->fk_account, 'fk_account', 1);
1049 } else {
1050 $form->formSelectAccount($pageurl, (string) $object->fk_account, 'none');
1051 }
1052 print '</td>';
1053 print '</tr>';
1054 }
1055
1056 // Other attributes
1057 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
1058
1059 print '</table>';
1060
1061 print '</div>';
1062
1063 print '<div class="fichehalfright">';
1064
1065 $nbcols = 3;
1066 if (isModEnabled("bank")) {
1067 $nbcols++;
1068 }
1069
1070 /*
1071 * Payments
1072 */
1073 $sql = "SELECT p.rowid, p.num_payment as num_payment, p.datep as dp, p.amount,";
1074 $sql .= " c.code as type_code,c.libelle as paiement_type,";
1075 $sql .= ' ba.rowid as baid, ba.ref as baref, ba.label, ba.number as banumber, ba.account_number, ba.currency_code as bacurrency_code, ba.fk_accountancy_journal';
1076 $sql .= " FROM ".MAIN_DB_PREFIX."payment_salary as p";
1077 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid';
1078 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid';
1079 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as c ON p.fk_typepayment = c.id";
1080 $sql .= ", ".MAIN_DB_PREFIX."salary as salaire";
1081 $sql .= " WHERE p.fk_salary = ".((int) $id);
1082 $sql .= " AND p.fk_salary = salaire.rowid";
1083 $sql .= " AND salaire.entity IN (".getEntity('tax').")";
1084 $sql .= " ORDER BY dp DESC";
1085 //print $sql;
1086 $resql = $db->query($sql);
1087 if ($resql) {
1088 $totalpaid = 0;
1089
1090 $num = $db->num_rows($resql);
1091 $i = 0;
1092
1093 print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
1094 print '<table class="noborder paymenttable">';
1095 print '<tr class="liste_titre">';
1096 print '<td>'.$langs->trans("RefPayment").'</td>';
1097 print '<td>'.$langs->trans("Date").'</td>';
1098 print '<td>'.$langs->trans("Type").'</td>';
1099 if (isModEnabled("bank")) {
1100 print '<td class="liste_titre right">'.$langs->trans('BankAccount').'</td>';
1101 }
1102 print '<td class="right">'.$langs->trans("Amount").'</td>';
1103 print '</tr>';
1104
1105 $paymentsalarytemp = new PaymentSalary($db);
1106
1107 if ($num > 0) {
1108 $bankaccountstatic = new Account($db);
1109 $objp = $objp ?? null;
1110 while ($i < $num) {
1111 $objp = $db->fetch_object($resql);
1112
1113 $paymentsalarytemp->id = $objp->rowid;
1114 $paymentsalarytemp->ref = $objp->rowid;
1115 $paymentsalarytemp->num_payment = $objp->num_payment;
1116 $paymentsalarytemp->datep = $objp->dp;
1117
1118 print '<tr class="oddeven"><td>';
1119 print $paymentsalarytemp->getNomUrl(1);
1120 print '</td>';
1121 print '<td>'.dol_print_date($db->jdate($objp->dp), 'dayhour', 'tzuserrel')."</td>\n";
1122 $labeltype = $langs->trans("PaymentType".$objp->type_code) != "PaymentType".$objp->type_code ? $langs->trans("PaymentType".$objp->type_code) : $objp->paiement_type;
1123 print "<td>".$labeltype.' '.$objp->num_payment."</td>\n";
1124 if (isModEnabled("bank")) {
1125 $bankaccountstatic->id = $objp->baid;
1126 $bankaccountstatic->ref = $objp->baref;
1127 $bankaccountstatic->label = $objp->baref;
1128 $bankaccountstatic->number = $objp->banumber;
1129 $bankaccountstatic->currency_code = $objp->bacurrency_code;
1130
1131 if (isModEnabled('accounting')) {
1132 $bankaccountstatic->account_number = $objp->account_number;
1133
1134 $accountingjournal = new AccountingJournal($db);
1135 $accountingjournal->fetch($objp->fk_accountancy_journal);
1136 $bankaccountstatic->accountancy_journal = $accountingjournal->getNomUrl(0, 1, 1, '', 1);
1137 }
1138
1139 print '<td class="right">';
1140 if ($bankaccountstatic->id) {
1141 print $bankaccountstatic->getNomUrl(1, 'transactions');
1142 }
1143 print '</td>';
1144 }
1145 print '<td class="right nowrap amountcard">'.price($objp->amount)."</td>\n";
1146 print "</tr>";
1147 $totalpaid += $objp->amount;
1148 $i++;
1149 }
1150 } else {
1151 print '<tr class="oddeven"><td><span class="opacitymedium">'.$langs->trans("None").'</span></td>';
1152 print '<td></td><td></td><td></td><td></td>';
1153 print '</tr>';
1154 }
1155
1156 print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans("AlreadyPaid").' :</td><td class="right nowrap amountcard">'.price($totalpaid)."</td></tr>\n";
1157 print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans("AmountExpected").' :</td><td class="right nowrap amountcard">'.price($object->amount)."</td></tr>\n";
1158
1159 $resteapayer = (float) $object->amount - $totalpaid;
1160 $cssforamountpaymentcomplete = 'amountpaymentcomplete';
1161
1162 print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans("RemainderToPay")." :</td>";
1163 print '<td class="right nowrap'.($resteapayer ? ' amountremaintopay' : (' '.$cssforamountpaymentcomplete)).'">'.price($resteapayer)."</td></tr>\n";
1164
1165 print "</table>";
1166 print '</div>';
1167
1168 $db->free($resql);
1169 } else {
1171 }
1172
1173 print '</div>';
1174 print '</div>';
1175
1176 print '<div class="clearboth"></div>';
1177
1178 print dol_get_fiche_end();
1179
1180 if ($action == 'edit') {
1181 print $form->buttonsSaveCancel();
1182 print "</form>";
1183 }
1184
1185 $resteapayer = price2num($resteapayer, 'MT');
1186
1187
1188 /*
1189 * Action bar
1190 */
1191
1192 print '<div class="tabsAction">'."\n";
1193 if ($action != 'edit') {
1194 // Dynamic send mail button
1195 $parameters = array();
1196 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1197 if (empty($reshook)) {
1198 if (empty($user->socid)) {
1199 $canSendMail = true;
1200
1201 print dolGetButtonAction($langs->trans('SendMail'), '', 'default', dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'action' => 'presend', 'mode' => 'init'], true).'#formmailbeforetitle', '', $canSendMail);
1202 }
1203 }
1204
1205 // Reopen
1206 if ($object->status == $object::STATUS_PAID && $permissiontoadd) {
1207 print dolGetButtonAction('', $langs->trans('ReOpen'), 'default', dolBuildUrl($_SERVER["PHP_SELF"], ['action' => 'reopen', 'id' => $object->id], true), '');
1208 }
1209
1210 // Edit
1211 if ($object->status == $object::STATUS_UNPAID && $permissiontoadd) {
1212 print dolGetButtonAction('', $langs->trans('Modify'), 'default', dolBuildUrl($_SERVER["PHP_SELF"], ['action' => 'edit', 'id' => $object->id]), '');
1213 }
1214
1215 // Transfer request
1216 if ($object->status == $object::STATUS_UNPAID && ((price2num($object->amount) < 0 && $resteapayer < 0) || (price2num($object->amount) > 0 && $resteapayer > 0)) && $permissiontoadd) {
1217 print dolGetButtonAction('', $langs->trans('MakeTransferRequest'), 'default', dolBuildUrl(DOL_URL_ROOT . '/salaries/virement_request.php', ['id' => $object->id]), '');
1218 }
1219
1220 // Emit payment
1221 if ($object->status == $object::STATUS_UNPAID && ((price2num($object->amount) < 0 && $resteapayer < 0) || (price2num($object->amount) > 0 && $resteapayer > 0)) && $permissiontoadd) {
1222 print dolGetButtonAction('', $langs->trans('DoPayment'), 'default', dolBuildUrl(DOL_URL_ROOT.'/salaries/payment_salary.php', ['action' => 'create', 'id' => $object->id], false), '');
1223 }
1224
1225 // Classify 'paid'
1226 // If payment complete $resteapayer <= 0 on a positive salary, or if amount is negative, we allow to classify as paid.
1227 if ($object->status == $object::STATUS_UNPAID && (($resteapayer <= 0 && $object->amount > 0) || ($object->amount <= 0)) && $permissiontoadd) {
1228 print dolGetButtonAction('', $langs->trans('ClassifyPaid'), 'default', dolBuildUrl($_SERVER["PHP_SELF"], ['action' => 'paid', 'id' => $object->id], true), '');
1229 }
1230
1231 // Clone
1232 if ($permissiontoadd) {
1233 print dolGetButtonAction('', $langs->trans('ToClone'), 'default', dolBuildUrl($_SERVER["PHP_SELF"], ['action' => 'clone', 'id' => $object->id], true), '');
1234 }
1235
1236 if ($permissiontodelete && empty($totalpaid)) {
1237 print dolGetButtonAction('', $langs->trans('Delete'), 'delete', dolBuildUrl($_SERVER["PHP_SELF"], ['action' => 'delete', 'id' => $object->id], true), '');
1238 } else {
1239 print dolGetButtonAction($langs->trans('DisabledBecausePayments'), $langs->trans('Delete'), 'default', dolBuildUrl($_SERVER['PHP_SELF']).'#', '', false);
1240 }
1241 }
1242 print "</div>";
1243
1244
1245
1246 // Select mail models is same action as presend
1247 if (GETPOST('modelselected')) {
1248 $action = 'presend';
1249 }
1250
1251 if ($action != 'presend') {
1252 print '<div class="fichecenter"><div class="fichehalfleft">';
1253 print '<a name="builddoc"></a>'; // ancre
1254
1255 $includedocgeneration = 1;
1256
1257 // Documents
1258 if ($includedocgeneration) {
1259 // Force values if object properties are missing
1260 $object->element = 'salary';
1261 if (empty($object->ref)) $object->ref = (string) $object->id;
1262
1263 $objref = dol_sanitizeFileName($object->ref);
1264 $filedir = $conf->salaries->dir_output.'/'.$object->element.'/'.$objref;
1265 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
1266
1267 $genallowed = 1;
1268 $genallowed = ($user->hasRight('salaries', 'read') || $user->hasRight('salaries', 'readall'));
1269 $delallowed = $user->hasRight('salaries', 'write');
1270
1271 print $formfile->showdocuments(
1272 'salaries:Salary',
1273 $object->element.'/'.$objref,
1274 $filedir,
1275 $urlsource,
1276 (int) $genallowed,
1277 $delallowed,
1278 $object->model_pdf,
1279 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang
1280 );
1281 }
1282
1283 // Show links to link elements
1284 /*
1285 $tmparray = $form->showLinkToObjectBlock($object, array(), array('salaries'), 1);
1286 $linktoelem = $tmparray['linktoelem'];
1287 $htmltoenteralink = $tmparray['htmltoenteralink'];
1288 print $htmltoenteralink;
1289
1290 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
1291 */
1292
1293 print '</div><div class="fichehalfright">';
1294
1295 $MAXEVENT = 10;
1296
1297 $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', dol_buildpath('/mymodule/myobject_agenda.php', 1).'?id='.$object->id);
1298
1299 // List of actions on element
1300 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
1301 $formactions = new FormActions($db);
1302 //$somethingshown = $formactions->showactions($object, $object->element.'@'.$object->module, (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlcenter);
1303
1304 print '</div></div>';
1305 }
1306
1307 // Select mail models is same action as presend
1308 if (GETPOST('modelselected')) {
1309 $action = 'presend';
1310 }
1311
1312 // Presend form
1313 $modelmail = 'salary';
1314 $defaulttopic = 'InformationMessage';
1315 $diroutput = $conf->salaries->dir_output;
1316 $trackid = 'salary'.$object->id;
1317
1318 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
1319
1320 // Hook to add more things on page
1321 $parameters = array();
1322 $reshook = $hookmanager->executeHooks('salaryCardTabAddMore', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1323}
1324
1325// End of page
1326llxFooter();
1327$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
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:73
Class to manage bank accounts.
Class to manage accounting journals.
Class to manage standard extra fields.
Class to manage building of HTML components.
Class to offer components to list and upload files.
Class to manage generation of HTML components Only common components must be here.
Class to manage building of HTML components.
Class to manage payments of salaries.
Class to manage projects.
Class to manage salary payments.
Class to manage Dolibarr users.
dol_get_first_day($year, $month=1, $gm=false)
Return GMT time for first day of a month or year.
Definition date.lib.php:604
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition date.lib.php:623
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
dol_now($mode='gmt')
Return date for now.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
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, $morecssdiv='')
Show tabs of a record.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dolBuildUrl($url, $params=[], $addtoken=false, $anchor='')
Return path of url.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
dol_eval($s, $returnvalue=1, $hideerrors=1, $onlysimplestring='1')
Replace eval function to add more security.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
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_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into JavaScript code.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_clone($srcobject, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
img_edit($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php
print $langs trans('Date')." left Ref Label right Qty right Price right TotalHT right TotalTTC right right right right right right right right right centpercent right TotalHT right n right VAT right n right TotalVAT right n No sujeto a RE IRPF right TotalLT1 right n right TotalLT2 right n right TotalTTC right n takeposcustomercurrency takeposcustomercurrency takeposcustomercurrency takeposcustomercurrency right TotalTTC takeposcustomercurrency right takeposcustomercurrency n right Paid right PaymentTypeShortLIQ right SELECT p pos_change as p datep as p p num_paiement as f pf amount as amount
Definition receipt.php:489
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.