Issues (2811)

public/htdocs/salaries/card.php (5 issues)

1
<?php
2
3
/* Copyright (C) 2011-2023  Alexandre Spangaro          <[email protected]>
4
 * Copyright (C) 2014-2020  Laurent Destailleur         <[email protected]>
5
 * Copyright (C) 2015       Jean-François Ferry         <[email protected]>
6
 * Copyright (C) 2015       Charlie BENKE               <[email protected]>
7
 * Copyright (C) 2018-2024  Frédéric France             <[email protected]>
8
 * Copyright (C) 2021       Gauthier VERDOL             <[email protected]>
9
 * Copyright (C) 2023       Maxime Nicolas              <[email protected]>
10
 * Copyright (C) 2023       Benjamin GREMBI             <[email protected]>
11
 * Copyright (C) 2024		MDW							<[email protected]>
12
 * Copyright (C) 2024       Rafael San José             <[email protected]>
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 3 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
26
 */
27
28
use Dolibarr\Code\Accountancy\Classes\AccountingJournal;
29
use Dolibarr\Code\Compta\Classes\Account;
30
use Dolibarr\Code\Core\Classes\ExtraFields;
31
use Dolibarr\Code\Core\Classes\Form;
32
use Dolibarr\Code\Core\Classes\FormActions;
33
use Dolibarr\Code\Core\Classes\FormFile;
34
use Dolibarr\Code\Core\Classes\FormProjets;
35
use Dolibarr\Code\Projet\Classes\Project;
36
use Dolibarr\Code\Salaries\Classes\PaymentSalary;
37
use Dolibarr\Code\Salaries\Classes\Salary;
38
use Dolibarr\Code\User\Classes\User;
39
use Dolibarr\Lib\ViewMain;
40
41
/**
42
 *  \file       htdocs/salaries/card.php
43
 *  \ingroup    salaries
44
 *  \brief      Page of salaries payments
45
 */
46
47
// Load Dolibarr environment
48
require constant('DOL_DOCUMENT_ROOT') . '/main.inc.php';
49
require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/date.lib.php';
50
require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/files.lib.php';
51
require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/salaries.lib.php';
52
53
// Load translation files required by the page
54
$langs->loadLangs(array("compta", "banks", "bills", "users", "salaries", "hrm", "trips"));
55
if (isModEnabled('project')) {
56
    $langs->load("projects");
57
}
58
59
$id = GETPOSTINT('id');
60
$ref = GETPOST('ref', 'alpha');
61
$action = GETPOST('action', 'aZ09');
62
$cancel = GETPOST('cancel', 'alpha');
63
$backtopage = GETPOST('backtopage', 'alpha');
64
$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha');
65
$confirm = GETPOST('confirm');
66
67
$label = GETPOST('label', 'alphanohtml');
68
$projectid = GETPOSTINT('projectid') ? GETPOSTINT('projectid') : GETPOSTINT('fk_project');
69
$accountid = GETPOSTINT('accountid') > 0 ? GETPOSTINT('accountid') : 0;
70
if (GETPOSTISSET('auto_create_paiement') || $action === 'add') {
71
    $auto_create_paiement = GETPOSTINT("auto_create_paiement");
72
} else {
73
    $auto_create_paiement = !getDolGlobalString('CREATE_NEW_SALARY_WITHOUT_AUTO_PAYMENT');
74
}
75
76
$datep = dol_mktime(12, 0, 0, GETPOSTINT("datepmonth"), GETPOSTINT("datepday"), GETPOSTINT("datepyear"));
77
$datev = dol_mktime(12, 0, 0, GETPOSTINT("datevmonth"), GETPOSTINT("datevday"), GETPOSTINT("datevyear"));
78
$datesp = dol_mktime(12, 0, 0, GETPOSTINT("datespmonth"), GETPOSTINT("datespday"), GETPOSTINT("datespyear"));
79
$dateep = dol_mktime(12, 0, 0, GETPOSTINT("dateepmonth"), GETPOSTINT("dateepday"), GETPOSTINT("dateepyear"));
80
$fk_user = GETPOSTINT('userid');
81
82
$object = new Salary($db);
83
$extrafields = new ExtraFields($db);
84
85
$childids = $user->getAllChildIds(1);
86
87
// fetch optionals attributes and labels
88
$extrafields->fetch_name_optionals_label($object->table_element);
89
90
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
91
$hookmanager->initHooks(array('salarycard', 'globalcard'));
92
93
if ($id > 0 || !empty($ref)) {
94
    $object->fetch($id, $ref);
95
96
    // Check current user can read this salary
97
    $canread = 0;
98
    if ($user->hasRight('salaries', 'readall')) {
99
        $canread = 1;
100
    }
101
    if ($user->hasRight('salaries', 'read') && $object->fk_user > 0 && in_array($object->fk_user, $childids)) {
102
        $canread = 1;
103
    }
104
    if (!$canread) {
105
        accessforbidden();
106
    }
107
}
108
109
// Security check
110
$socid = GETPOSTINT('socid');
111
if ($user->socid) {
112
    $socid = $user->socid;
113
}
114
115
restrictedArea($user, 'salaries', $object->id, 'salary', '');
116
117
$permissiontoread = $user->hasRight('salaries', 'read');
118
$permissiontoadd = $user->hasRight('salaries', 'write'); // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
119
$permissiontodelete = $user->hasRight('salaries', 'delete') || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_UNPAID);
120
121
$upload_dir = $conf->salaries->multidir_output[$conf->entity];
122
123
124
/*
125
 * Actions
126
 */
127
128
$parameters = array();
129
// Note that $action and $object may be modified by some hooks
130
$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action);
131
if ($reshook < 0) {
132
    setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
133
}
134
135
if (empty($reshook)) {
136
    $error = 0;
137
138
    $backurlforlist = constant('BASE_URL') . '/salaries/list.php';
139
140
    if (empty($backtopage) || ($cancel && empty($id))) {
141
        if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
142
            if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
143
                $backtopage = $backurlforlist;
144
            } else {
145
                $backtopage = '/salaries/card.php?id=' . ($id > 0 ? $id : '__ID__');
146
            }
147
        }
148
    }
149
150
    if ($cancel) {
151
        //var_dump($cancel);
152
        //var_dump($backtopage);exit;
153
        if (!empty($backtopageforcancel)) {
154
            header("Location: " . $backtopageforcancel);
155
            exit;
156
        } elseif (!empty($backtopage)) {
157
            header("Location: " . $backtopage);
158
            exit;
159
        }
160
        $action = '';
161
    }
162
163
    // Actions to send emails
164
    $triggersendname = 'COMPANY_SENTBYMAIL';
165
    $paramname = 'id';
166
    $mode = 'emailfromthirdparty';
167
    $trackid = 'sal' . $object->id;
168
    include DOL_DOCUMENT_ROOT . '/core/actions_sendmails.inc.php';
169
170
    //var_dump($upload_dir);var_dump($permissiontoadd);var_dump($action);exit;
171
    // Actions to build doc
172
    include DOL_DOCUMENT_ROOT . '/core/actions_builddoc.inc.php';
173
}
174
175
// Link to a project
176
if ($action == 'classin' && $permissiontoadd) {
177
    $object->fetch($id);
178
    $object->setProject($projectid);
179
}
180
181
// set label
182
if ($action == 'setlabel' && $permissiontoadd) {
183
    $object->fetch($id);
184
    $object->label = $label;
0 ignored issues
show
Documentation Bug introduced by
It seems like $label can also be of type array or array or array. However, the property $label is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
185
    $object->update($user);
186
}
187
188
// Classify paid
189
if ($action == 'confirm_paid' && $permissiontoadd && $confirm == 'yes') {
190
    $object->fetch($id);
191
    $result = $object->setPaid($user);
192
}
193
194
if ($action == 'setfk_user' && $permissiontoadd) {
195
    $result = $object->fetch($id);
196
    if ($result > 0) {
197
        $object->fk_user = $fk_user;
198
        $object->update($user);
199
    } else {
200
        dol_print_error($db);
201
        exit;
202
    }
203
}
204
205
if ($action == 'reopen' && $permissiontoadd) {
206
    $result = $object->fetch($id);
207
    if ($object->paye) {
208
        $result = $object->set_unpaid($user);
209
        if ($result > 0) {
210
            header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id);
211
            exit();
212
        } else {
213
            setEventMessages($object->error, $object->errors, 'errors');
214
        }
215
    }
216
}
217
218
// payment mode
219
if ($action == 'setmode' && $permissiontoadd) {
220
    $object->fetch($id);
221
    $result = $object->setPaymentMethods(GETPOSTINT('mode_reglement_id'));
222
    if ($result < 0) {
223
        setEventMessages($object->error, $object->errors, 'errors');
224
    }
225
}
226
227
// bank account
228
if ($action == 'setbankaccount' && $permissiontoadd) {
229
    $object->fetch($id);
230
    $result = $object->setBankAccount(GETPOSTINT('fk_account'));
231
    if ($result < 0) {
232
        setEventMessages($object->error, $object->errors, 'errors');
233
    }
234
}
235
236
if ($action == 'add' && empty($cancel)) {
237
    $error = 0;
238
239
    if (empty($datev)) {
240
        $datev = $datep;
241
    }
242
243
    $type_payment = GETPOSTINT("paymenttype");
244
    $amount = price2num(GETPOST("amount", 'alpha'), 'MT', 2);
245
246
    $object->accountid = GETPOSTINT("accountid") > 0 ? GETPOSTINT("accountid") : 0;
247
    $object->fk_user = GETPOSTINT("fk_user") > 0 ? GETPOSTINT("fk_user") : 0;
248
    $object->datev = $datev;
249
    $object->datep = $datep;
250
    $object->amount = $amount;
251
    $object->label = GETPOST("label", 'alphanohtml');
252
    $object->datesp = $datesp;
253
    $object->dateep = $dateep;
254
    $object->note = GETPOST("note", 'restricthtml');
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$note has been deprecated: Use $note_private instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

254
    /** @scrutinizer ignore-deprecated */ $object->note = GETPOST("note", 'restricthtml');

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
Documentation Bug introduced by
It seems like GETPOST('note', 'restricthtml') can also be of type array or array or array. However, the property $note is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
255
    $object->type_payment = ($type_payment > 0 ? $type_payment : 0);
256
    $object->fk_user_author = $user->id;
257
    $object->fk_project = $projectid;
258
259
    // Set user current salary as ref salary for the payment
260
    $fuser = new User($db);
261
    $fuser->fetch(GETPOSTINT("fk_user"));
262
    $object->salary = $fuser->salary;
263
264
    // Fill array 'array_options' with data from add form
265
    $ret = $extrafields->setOptionalsFromPost(null, $object);
266
    if ($ret < 0) {
267
        $error++;
268
    }
269
270
    if (!empty($auto_create_paiement) && empty($datep)) {
271
        setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("DATE_PAIEMENT")), null, 'errors');
272
        $error++;
273
    }
274
    if (empty($datesp) || empty($dateep)) {
275
        setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
276
        $error++;
277
    }
278
    if (empty($object->fk_user) || $object->fk_user < 0) {
279
        setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Employee")), null, 'errors');
280
        $error++;
281
    }
282
    if (!empty($auto_create_paiement) && (empty($type_payment) || $type_payment < 0)) {
283
        setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("PaymentMode")), null, 'errors');
284
        $error++;
285
    }
286
    if (empty($object->amount)) {
287
        setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Amount")), null, 'errors');
288
        $error++;
289
    }
290
    if (isModEnabled("bank") && !empty($auto_create_paiement) && !$object->accountid > 0) {
291
        setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("BankAccount")), null, 'errors');
292
        $error++;
293
    }
294
295
    if (!$error) {
296
        $db->begin();
297
298
        $ret = $object->create($user);
299
        if ($ret < 0) {
300
            setEventMessages($object->error, $object->errors, 'errors');
301
            $error++;
302
        }
303
        if (!empty($auto_create_paiement) && !$error) {
304
            // Create a line of payments
305
            $paiement = new PaymentSalary($db);
306
            $paiement->fk_salary    = $object->id;
307
            $paiement->chid         = $object->id;  // deprecated
308
            $paiement->datep        = $datep;
309
            $paiement->datev        = $datev;
310
            $paiement->amounts      = array($object->id => $amount); // Tableau de montant
311
            $paiement->fk_typepayment = $type_payment;
312
            $paiement->num_payment  = GETPOST("num_payment", 'alphanohtml');
0 ignored issues
show
Documentation Bug introduced by
It seems like GETPOST('num_payment', 'alphanohtml') can also be of type array or array or array. However, the property $num_payment is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
313
            $paiement->note_private = GETPOST("note", 'restricthtml');
0 ignored issues
show
Documentation Bug introduced by
It seems like GETPOST('note', 'restricthtml') can also be of type array or array or array. However, the property $note_private is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
314
315
            if (!$error) {
316
                $paymentid = $paiement->create($user, (int) GETPOST('closepaidsalary'));
317
                if ($paymentid < 0) {
318
                    $error++;
319
                    setEventMessages($paiement->error, null, 'errors');
320
                    $action = 'create';
321
                }
322
            }
323
324
            if (!$error) {
325
                $result = $paiement->addPaymentToBank($user, 'payment_salary', '(SalaryPayment)', GETPOSTINT('accountid'), '', '');
326
                if (!($result > 0)) {
327
                    $error++;
328
                    setEventMessages($paiement->error, null, 'errors');
329
                }
330
            }
331
        }
332
333
        if (empty($error)) {
334
            $db->commit();
335
336
            if (GETPOST('saveandnew', 'alpha')) {
337
                setEventMessages($langs->trans("RecordSaved"), null, 'mesgs');
338
                header("Location: card.php?action=create&fk_project=" . urlencode((string) ($projectid)) . "&accountid=" . urlencode((string) ($accountid)) . '&paymenttype=' . urlencode((string) (GETPOSTINT('paymenttype'))) . '&datepday=' . GETPOSTINT("datepday") . '&datepmonth=' . GETPOSTINT("datepmonth") . '&datepyear=' . GETPOSTINT("datepyear"));
339
                exit;
340
            } else {
341
                header("Location: " . $_SERVER['PHP_SELF'] . '?id=' . $object->id);
342
                exit;
343
            }
344
        } else {
345
            $db->rollback();
346
        }
347
    }
348
349
    $action = 'create';
350
}
351
352
if ($action == 'confirm_delete') {
353
    $result = $object->fetch($id);
354
    $totalpaid = $object->getSommePaiement();
355
356
    if (empty($totalpaid)) {
357
        $db->begin();
358
359
        $ret = $object->delete($user);
360
        if ($ret > 0) {
361
            $db->commit();
362
            header("Location: " . constant('BASE_URL') . '/salaries/list.php');
363
            exit;
364
        } else {
365
            $db->rollback();
366
            setEventMessages($object->error, $object->errors, 'errors');
367
        }
368
    } else {
369
        setEventMessages($langs->trans('DisabledBecausePayments'), null, 'errors');
370
    }
371
}
372
373
374
if ($action == 'update' && !GETPOST("cancel") && $permissiontoadd) {
375
    $amount = price2num(GETPOST('amount'), 'MT', 2);
376
377
    if (empty($amount)) {
378
        setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Amount")), null, 'errors');
379
        $action = 'edit';
380
    } elseif (!is_numeric($amount)) {
381
        setEventMessages($langs->trans("ErrorFieldMustBeANumeric", $langs->transnoentities("Amount")), null, 'errors');
382
        $action = 'create';
383
    } else {
384
        $result = $object->fetch($id);
385
386
        $object->amount = price2num($amount);
387
        $object->datesp = price2num($datesp);
388
        $object->dateep = price2num($dateep);
389
390
        $result = $object->update($user);
391
        if ($result <= 0) {
392
            setEventMessages($object->error, $object->errors, 'errors');
393
        }
394
    }
395
}
396
397
if ($action == 'confirm_clone' && $confirm != 'yes') {
398
    $action = '';
399
}
400
401
if ($action == 'confirm_clone' && $confirm == 'yes' && $permissiontoadd) {
402
    $db->begin();
403
404
    $originalId = $id;
405
406
    $object->fetch($id);
407
408
    if ($object->id > 0) {
409
        $object->paye = 0;
410
        $object->id = 0;
411
        $object->ref = '';
412
413
        if (GETPOST('amount', 'alphanohtml')) {
414
            $object->amount = price2num(GETPOST('amount', 'alphanohtml'), 'MT', 2);
415
        }
416
417
        if (GETPOST('clone_label', 'alphanohtml')) {
418
            $object->label = GETPOST('clone_label', 'alphanohtml');
419
        } else {
420
            $object->label = $langs->trans("CopyOf") . ' ' . $object->label;
421
        }
422
423
        $newdatestart = dol_mktime(0, 0, 0, GETPOSTINT('clone_date_startmonth'), GETPOSTINT('clone_date_startday'), GETPOSTINT('clone_date_startyear'));
424
        $newdateend = dol_mktime(0, 0, 0, GETPOSTINT('clone_date_endmonth'), GETPOSTINT('clone_date_endday'), GETPOSTINT('clone_date_endyear'));
425
426
        if ($newdatestart) {
427
            $object->datesp = $newdatestart;
428
        }
429
        if ($newdateend) {
430
            $object->dateep = $newdateend;
431
        }
432
433
        $id = $object->create($user);
434
        if ($id > 0) {
435
            $db->commit();
436
            $db->close();
437
438
            header("Location: " . $_SERVER["PHP_SELF"] . "?id=" . $id);
439
            exit;
440
        } else {
441
            $id = $originalId;
442
            $db->rollback();
443
444
            setEventMessages($object->error, $object->errors, 'errors');
445
        }
446
    } else {
447
        $db->rollback();
448
        dol_print_error($db, $object->error);
449
    }
450
}
451
452
// Action to update one extrafield
453
if ($action == "update_extras" && $permissiontoadd) {
454
    $object->fetch(GETPOSTINT('id'));
455
456
    $attributekey = GETPOST('attribute', 'alpha');
457
    $attributekeylong = 'options_' . $attributekey;
458
459
    if (GETPOSTISSET($attributekeylong . 'day') && GETPOSTISSET($attributekeylong . 'month') && GETPOSTISSET($attributekeylong . 'year')) {
460
        // This is properties of a date
461
        $object->array_options['options_' . $attributekey] = dol_mktime(GETPOSTINT($attributekeylong . 'hour'), GETPOSTINT($attributekeylong . 'min'), GETPOSTINT($attributekeylong . 'sec'), GETPOSTINT($attributekeylong . 'month'), GETPOSTINT($attributekeylong . 'day'), GETPOSTINT($attributekeylong . 'year'));
462
        //var_dump(dol_print_date($object->array_options['options_'.$attributekey]));exit;
463
    } else {
464
        $object->array_options['options_' . $attributekey] = GETPOST($attributekeylong, 'alpha');
465
    }
466
467
    $result = $object->insertExtraFields(empty($triggermodname) ? '' : $triggermodname, $user);
468
    if ($result > 0) {
469
        setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
470
        $action = 'view';
471
    } else {
472
        setEventMessages($object->error, $object->errors, 'errors');
473
        $action = 'edit_extras';
474
    }
475
}
476
477
/*
478
 *	View
479
 */
480
481
$form = new Form($db);
482
$formfile = new FormFile($db);
483
if (isModEnabled('project')) {
484
    $formproject = new FormProjets($db);
485
}
486
487
$title = $langs->trans('Salary') . " - " . $object->ref;
488
if ($action == 'create') {
489
    $title = $langs->trans("NewSalary");
490
}
491
$help_url = "";
492
ViewMain::llxHeader('', $title, $help_url);
493
494
495
if ($id > 0) {
496
    $result = $object->fetch($id);
497
    if ($result <= 0) {
498
        dol_print_error($db);
499
        exit;
500
    }
501
}
502
503
// Create
504
if ($action == 'create' && $permissiontoadd) {
505
    $year_current = dol_print_date(dol_now('gmt'), "%Y", 'gmt');
506
    $pastmonth = 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="' . $_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 /** @lang JavaScript */'
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
        print '</script>' . "\n";
567
    }
568
569
    print dol_get_fiche_head();
570
571
    print '<table class="border centpercent">';
572
573
    // Employee
574
    print '<tr><td class="titlefieldcreate">';
575
    print $form->editfieldkey('Employee', 'fk_user', '', $object, 0, 'string', '', 1) . '</td><td>';
576
    $noactive = 0; // We keep active and unactive users
577
    print img_picto('', 'user', 'class="pictofixedwidth"') . $form->select_dolusers(GETPOSTINT('fk_user'), 'fk_user', 1, '', 0, '', '', 0, 0, 0, 'AND employee=1', 0, '', 'maxwidth300', $noactive);
578
    print '</td></tr>';
579
580
    // Label
581
    print '<tr><td>';
582
    print $form->editfieldkey('Label', 'label', '', $object, 0, 'string', '', 1) . '</td><td>';
583
    print '<input name="label" id="label" class="minwidth300" value="' . (GETPOST("label") ? GETPOST("label") : $langs->trans("Salary")) . '">';
584
    print '</td></tr>';
585
586
    // Date start period
587
    print '<tr><td>';
588
    print $form->editfieldkey('DateStartPeriod', 'datesp', '', $object, 0, 'string', '', 1) . '</td><td>';
589
    print $form->selectDate($datesp, "datesp", 0, 0, 0, 'add');
590
    print '</td></tr>';
591
592
    // Date end period
593
    print '<tr><td>';
594
    print $form->editfieldkey('DateEndPeriod', 'dateep', '', $object, 0, 'string', '', 1) . '</td><td>';
595
    print $form->selectDate($dateep, "dateep", 0, 0, 0, 'add');
596
    print '</td></tr>';
597
598
    // Amount
599
    print '<tr><td>';
600
    print $form->editfieldkey('Amount', 'amount', '', $object, 0, 'string', '', 1) . '</td><td>';
601
    print '<input name="amount" id="amount" class="minwidth75 maxwidth100" value="' . GETPOST("amount") . '"> &nbsp;';
602
    print ' <button class="dpInvisibleButtons datenowlink" id="updateAmountWithLastSalary" name="_useless" type="button">' . $langs->trans('UpdateAmountWithLastSalary') . '</a>';
603
    print '</td>';
604
    print '</tr>';
605
606
    // Project
607
    if (isModEnabled('project')) {
608
        $formproject = new FormProjets($db);
609
610
        print '<tr><td>' . $langs->trans("Project") . '</td><td>';
611
        print img_picto('', 'project', 'class="pictofixedwidth"');
612
        print $formproject->select_projects(-1, $projectid, 'fk_project', 0, 0, 1, 1, 0, 0, 0, '', 1);
613
        print '</td></tr>';
614
    }
615
616
    // Comments
617
    print '<tr>';
618
    print '<td class="tdtop">' . $langs->trans("Comments") . '</td>';
619
    print '<td class="tdtop"><textarea name="note" wrap="soft" cols="60" rows="' . ROWS_3 . '">' . GETPOST('note', 'restricthtml') . '</textarea></td>';
620
    print '</tr>';
621
622
623
    print '<tr><td colspan="2"><hr></td></tr>';
624
625
626
    // Auto create payment
627
    print '<tr><td><label for="auto_create_paiement">' . $langs->trans('AutomaticCreationPayment') . '</label></td>';
628
    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
629
630
    // Bank
631
    if (isModEnabled("bank")) {
632
        print '<tr><td id="label_fk_account">';
633
        print $form->editfieldkey('BankAccount', 'selectaccountid', '', $object, 0, 'string', '', 1) . '</td><td>';
634
        print img_picto('', 'bank_account', 'class="pictofixedwidth"');
635
        $form->select_comptes($accountid, "accountid", 0, '', 1); // Affiche liste des comptes courant
636
        print '</td></tr>';
637
    }
638
639
    // Type payment
640
    print '<tr><td id="label_type_payment">';
641
    print $form->editfieldkey('PaymentMode', 'selectpaymenttype', '', $object, 0, 'string', '', 1) . '</td><td>';
642
    print img_picto('', 'bank', 'class="pictofixedwidth"');
643
    print $form->select_types_paiements(GETPOST("paymenttype", 'aZ09'), "paymenttype", '');
644
    print '</td></tr>';
645
646
    // Date payment
647
    print '<tr class="hide_if_no_auto_create_payment"><td>';
648
    print $form->editfieldkey('DatePayment', 'datep', '', $object, 0, 'string', '', 1) . '</td><td>';
649
    print $form->selectDate((empty($datep) ? '' : $datep), "datep", 0, 0, 0, 'add', 1, 1);
650
    print '</td></tr>';
651
652
    // Date value for bank
653
    print '<tr class="hide_if_no_auto_create_payment"><td>';
654
    print $form->editfieldkey('DateValue', 'datev', '', $object, 0) . '</td><td>';
655
    print $form->selectDate((empty($datev) ? -1 : $datev), "datev", 0, 0, 0, 'add', 1, 1);
656
    print '</td></tr>';
657
658
    // Number
659
    if (isModEnabled("bank")) {
660
        // Number
661
        print '<tr class="hide_if_no_auto_create_payment"><td><label for="num_payment">' . $langs->trans('Numero');
662
        print ' <em>(' . $langs->trans("ChequeOrTransferNumber") . ')</em>';
663
        print '</label></td>';
664
        print '<td><input name="num_payment" id="num_payment" type="text" value="' . GETPOST("num_payment") . '"></td></tr>' . "\n";
665
    }
666
667
    // Bouton Save payment
668
    /*
669
    print '<tr class="hide_if_no_auto_create_payment"><td>';
670
    print $langs->trans("ClosePaidSalaryAutomatically");
671
    print '</td><td><input type="checkbox" checked value="1" name="closepaidsalary"></td></tr>';
672
    */
673
674
    // Other attributes
675
    $parameters = array();
676
    $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
677
    print $hookmanager->resPrint;
678
    if (empty($reshook)) {
679
        print $object->showOptionals($extrafields, 'create');
680
    }
681
682
    print '</table>';
683
684
    print dol_get_fiche_end();
685
686
    print '<div class="center">';
687
688
    print '<div class="hide_if_no_auto_create_payment paddingbottom">';
689
    print '<input type="checkbox" checked value="1" name="closepaidsalary">' . $langs->trans("ClosePaidSalaryAutomatically");
690
    print '</div>';
691
692
    print '</div>';
693
694
    $addition_button = array(
695
        'name' => 'saveandnew',
696
        'label_key' => 'SaveAndNew',
697
    );
698
    print $form->buttonsSaveCancel("Save", "Cancel", $addition_button);
699
700
    print '</form>';
701
    print '<script>';
702
    print '$( document ).ready(function() {';
703
    print '$("#updateAmountWithLastSalary").on("click", function updateAmountWithLastSalary() {
704
					var fk_user = $("#fk_user").val()
705
					var url = "' . constant('BASE_URL') . '/salaries/ajax/ajaxsalaries.php?fk_user="+fk_user;
706
					console.log("We click on link to autofill salary amount url="+url);
707
708
					if (fk_user != -1) {
709
						$.get(
710
							url,
711
							function( data ) {
712
								console.log("Data returned: "+data);
713
								if (data != null) {
714
									if (typeof data == "object") {
715
										console.log("data is already type object, no need to parse it");
716
										item = data;
717
									} else {
718
										console.log("data is type "+(typeof data));
719
										item = JSON.parse(data);
720
									}
721
									if (item[0].key == "Amount") {
722
										value = item[0].value;
723
										console.log("amount returned = "+value);
724
										if (value != null) {
725
											$("#amount").val(item[0].value);
726
										} else {
727
											console.error("Error: Ajax url "+url+" has returned a null value.");
728
										}
729
									} else {
730
										console.error("Error: Ajax url "+url+" has returned the wrong key.");
731
									}
732
								} else {
733
									console.error("Error: Ajax url "+url+" has returned an empty page.");
734
								}
735
							}
736
						);
737
738
					} else {
739
						alert("' . dol_escape_js($langs->transnoentitiesnoconv("FillFieldFirst")) . '");
740
					}
741
		});
742
743
	})';
744
    print '</script>';
745
}
746
747
// View mode
748
if ($id > 0) {
749
    $head = salaries_prepare_head($object);
750
    $formconfirm = '';
751
752
    if ($action === 'clone') {
753
        $formquestion = array(
754
            array('type' => 'text', 'name' => 'clone_label', 'label' => $langs->trans("Label"), 'value' => $langs->trans("CopyOf") . ' ' . $object->label),
755
        );
756
757
        //$formquestion[] = array('type' => 'date', 'name' => 'clone_date_ech', 'label' => $langs->trans("Date"), 'value' => -1);
758
        $formquestion[] = array('type' => 'date', 'name' => 'clone_date_start', 'label' => $langs->trans("DateStart"), 'value' => -1);
759
        $formquestion[] = array('type' => 'date', 'name' => 'clone_date_end', 'label' => $langs->trans("DateEnd"), 'value' => -1);
760
        $formquestion[] = array('type' => 'text', 'name' => 'amount', 'label' => $langs->trans("Amount"), 'value' => price($object->amount), 'morecss' => 'width100 right');
761
762
        $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneSalary', $object->ref), 'confirm_clone', $formquestion, 'yes', 1, 280);
763
764
        //Add fill with end of month button
765
        $formconfirm .= "<script>
766
			$('#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>'));
767
			$('#fill_end_of_month').click(function(){
768
				var clone_date_startmonth = +$('#clone_date_startmonth').val();
769
				var clone_date_startyear = +$('#clone_date_startyear').val();
770
				var end_date = new Date(clone_date_startyear, clone_date_startmonth, 0);
771
				end_date.setMonth(clone_date_startmonth - 1);
772
				$('#clone_date_end').val(formatDate(end_date,'" . $langs->trans("FormatDateShortJavaInput") . "'));
773
				$('#clone_date_endday').val(end_date.getDate());
774
				$('#clone_date_endmonth').val(end_date.getMonth() + 1);
775
				$('#clone_date_endyear').val(end_date.getFullYear());
776
			});
777
		</script>";
778
    }
779
780
    if ($action == 'paid') {
781
        $text = $langs->trans('ConfirmPaySalary');
782
        $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . "?id=" . $object->id, $langs->trans('PaySalary'), $text, "confirm_paid", '', '', 2);
783
    }
784
785
    if ($action == 'delete') {
786
        $text = $langs->trans('ConfirmDeleteSalary');
787
        $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'] . '?id=' . $object->id, $langs->trans('DeleteSalary'), $text, 'confirm_delete', '', '', 2);
788
    }
789
790
    if ($action == 'edit') {
791
        print "<form name=\"charge\" action=\"" . $_SERVER["PHP_SELF"] . "?id=$object->id&amp;action=update\" method=\"post\">";
792
        print '<input type="hidden" name="token" value="' . newToken() . '">';
793
    }
794
795
    // Call Hook formConfirm
796
    $parameters = array('formConfirm' => $formconfirm);
797
    $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
798
    if (empty($reshook)) {
799
        $formconfirm .= $hookmanager->resPrint;
800
    } elseif ($reshook > 0) {
801
        $formconfirm = $hookmanager->resPrint;
802
    }
803
804
    // Print form confirm
805
    print $formconfirm;
806
807
808
    print dol_get_fiche_head($head, 'card', $langs->trans("SalaryPayment"), -1, 'salary', 0, '', '', 0, '', 1);
809
810
    $linkback = '<a href="' . constant('BASE_URL') . '/salaries/list.php?restore_lastsearch_values=1' . (!empty($socid) ? '&socid=' . $socid : '') . '">' . $langs->trans("BackToList") . '</a>';
811
812
    $morehtmlref = '<div class="refidno">';
813
814
    // Label
815
    if ($action != 'editlabel') {
816
        $morehtmlref .= $form->editfieldkey("Label", 'label', $object->label, $object, $permissiontoadd, 'string', '', 0, 1);
817
        $morehtmlref .= $object->label;
818
    } else {
819
        $morehtmlref .= $langs->trans('Label') . ' :&nbsp;';
820
        $morehtmlref .= '<form method="post" action="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '">';
821
        $morehtmlref .= '<input type="hidden" name="action" value="setlabel">';
822
        $morehtmlref .= '<input type="hidden" name="token" value="' . newToken() . '">';
823
        $morehtmlref .= '<input type="text" name="label" value="' . $object->label . '"/>';
824
        $morehtmlref .= '<input type="submit" class="button valignmiddle" value="' . $langs->trans("Modify") . '">';
825
        $morehtmlref .= '</form>';
826
    }
827
828
    // Employee
829
    if ($action != 'editfk_user') {
830
        if ($object->getSommePaiement() > 0 && !empty($object->fk_user)) {
831
            $userstatic = new User($db);
832
            $result = $userstatic->fetch($object->fk_user);
833
            if ($result > 0) {
834
                $morehtmlref .= '<br>' . $langs->trans('Employee') . ' : ' . $userstatic->getNomUrl(-1);
835
            }
836
        } else {
837
            $morehtmlref .= '<br>' . $form->editfieldkey("Employee", 'fk_user', $object->label, $object, $permissiontoadd, 'string', '', 0, 1);
838
839
            if (!empty($object->fk_user)) {
840
                $userstatic = new User($db);
841
                $result = $userstatic->fetch($object->fk_user);
842
                if ($result > 0) {
843
                    $morehtmlref .= $userstatic->getNomUrl(-1);
844
                } else {
845
                    dol_print_error($db);
846
                    exit();
847
                }
848
            }
849
        }
850
    } else {
851
        $morehtmlref .= '<br>' . $langs->trans('Employee') . ' :&nbsp;';
852
        $morehtmlref .= '<form method="post" action="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '">';
853
        $morehtmlref .= '<input type="hidden" name="action" value="setfk_user">';
854
        $morehtmlref .= '<input type="hidden" name="token" value="' . newToken() . '">';
855
        $morehtmlref .= $form->select_dolusers($object->fk_user, 'userid', 1);
856
        $morehtmlref .= '<input type="submit" class="button valignmiddle" value="' . $langs->trans("Modify") . '">';
857
        $morehtmlref .= '</form>';
858
    }
859
860
    $usercancreate = $permissiontoadd;
861
862
    // Project
863
    if (isModEnabled('project')) {
864
        $langs->load("projects");
865
        $morehtmlref .= '<br>';
866
        if ($usercancreate) {
867
            $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
868
            if ($action != 'classify') {
869
                $morehtmlref .= '<a class="editfielda" href="' . $_SERVER['PHP_SELF'] . '?action=classify&token=' . newToken() . '&id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> ';
870
            }
871
            $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, -1, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
872
        } else {
873
            if (!empty($object->fk_project)) {
874
                $proj = new Project($db);
875
                $proj->fetch($object->fk_project);
876
                $morehtmlref .= $proj->getNomUrl(1);
877
                if ($proj->title) {
878
                    $morehtmlref .= '<span class="opacitymedium"> - ' . dol_escape_htmltag($proj->title) . '</span>';
879
                }
880
            }
881
        }
882
    }
883
884
    $morehtmlref .= '</div>';
885
886
    $totalpaid = $object->getSommePaiement();
887
    $object->alreadypaid = $totalpaid;
888
    $object->totalpaid = $totalpaid;
889
890
    dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', '');
891
892
    print '<div class="fichecenter">';
893
    print '<div class="fichehalfleft">';
894
    print '<div class="underbanner clearboth"></div>';
895
896
    print '<table class="border centpercent tableforfield">';
897
898
    if ($action == 'edit') {
899
        print '<tr><td class="titlefield">' . $langs->trans("DateStartPeriod") . "</td><td>";
900
        print $form->selectDate($object->datesp, 'datesp', 0, 0, 0, 'datesp', 1);
901
        print "</td></tr>";
902
    } else {
903
        print "<tr>";
904
        print '<td class="titlefield">' . $langs->trans("DateStartPeriod") . '</td><td>';
905
        print dol_print_date($object->datesp, 'day');
906
        print '</td></tr>';
907
    }
908
909
    if ($action == 'edit') {
910
        print '<tr><td>' . $langs->trans("DateEndPeriod") . "</td><td>";
911
        print $form->selectDate($object->dateep, 'dateep', 0, 0, 0, 'dateep', 1);
912
        print "</td></tr>";
913
    } else {
914
        print "<tr>";
915
        print '<td>' . $langs->trans("DateEndPeriod") . '</td><td>';
916
        print dol_print_date($object->dateep, 'day');
917
        print '</td></tr>';
918
    }
919
920
    /*print "<tr>";
921
    print '<td>'.$langs->trans("DatePayment").'</td><td>';
922
    print dol_print_date($object->datep, 'day');
923
    print '</td></tr>';
924
925
    print '<tr><td>'.$langs->trans("DateValue").'</td><td>';
926
    print dol_print_date($object->datev, 'day');
927
    print '</td></tr>';*/
928
929
    if ($action == 'edit') {
930
        print '<tr><td class="fieldrequired">' . $langs->trans("Amount") . '</td><td><input name="amount" size="10" value="' . price($object->amount) . '"></td></tr>';
931
    } else {
932
        print '<tr><td>' . $langs->trans("Amount") . '</td><td><span class="amount">' . price($object->amount, 0, $langs, 1, -1, -1, $conf->currency) . '</span></td></tr>';
933
    }
934
935
    // Default mode of payment
936
    print '<tr><td>';
937
    print '<table class="nobordernopadding" width="100%"><tr><td>';
938
    print $langs->trans('DefaultPaymentMode');
939
    print '</td>';
940
    if ($action != 'editmode') {
941
        print '<td class="right"><a class="editfielda" href="' . $_SERVER["PHP_SELF"] . '?action=editmode&token=' . newToken() . '&id=' . $object->id . '">' . img_edit($langs->trans('SetMode'), 1) . '</a></td>';
942
    }
943
    print '</tr></table>';
944
    print '</td><td>';
945
946
    if ($action == 'editmode') {
947
        $form->form_modes_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->type_payment, 'mode_reglement_id');
948
    } else {
949
        $form->form_modes_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->type_payment, 'none');
950
    }
951
    print '</td></tr>';
952
953
    // Default Bank Account
954
    if (isModEnabled("bank")) {
955
        print '<tr><td class="nowrap">';
956
        print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
957
        print $langs->trans('DefaultBankAccount');
958
        print '<td>';
959
        if ($action != 'editbankaccount' && $permissiontoadd) {
960
            print '<td class="right"><a class="editfielda" href="' . $_SERVER["PHP_SELF"] . '?action=editbankaccount&token=' . newToken() . '&id=' . $object->id . '">' . img_edit($langs->trans('SetBankAccount'), 1) . '</a></td>';
961
        }
962
        print '</tr></table>';
963
        print '</td><td>';
964
        if ($action == 'editbankaccount') {
965
            $form->formSelectAccount($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->fk_account, 'fk_account', 1);
966
        } else {
967
            $form->formSelectAccount($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->fk_account, 'none');
968
        }
969
        print '</td>';
970
        print '</tr>';
971
    }
972
973
    // Other attributes
974
    include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php';
975
976
    print '</table>';
977
978
    print '</div>';
979
980
    print '<div class="fichehalfright">';
981
982
    $nbcols = 3;
983
    if (isModEnabled("bank")) {
984
        $nbcols++;
985
    }
986
987
    /*
988
     * Payments
989
     */
990
    $sql = "SELECT p.rowid, p.num_payment as num_payment, p.datep as dp, p.amount,";
991
    $sql .= " c.code as type_code,c.libelle as paiement_type,";
992
    $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';
993
    $sql .= " FROM " . MAIN_DB_PREFIX . "payment_salary as p";
994
    $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'bank as b ON p.fk_bank = b.rowid';
995
    $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'bank_account as ba ON b.fk_account = ba.rowid';
996
    $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_paiement as c ON p.fk_typepayment = c.id";
997
    $sql .= ", " . MAIN_DB_PREFIX . "salary as salaire";
998
    $sql .= " WHERE p.fk_salary = " . ((int) $id);
999
    $sql .= " AND p.fk_salary = salaire.rowid";
1000
    $sql .= " AND salaire.entity IN (" . getEntity('tax') . ")";
1001
    $sql .= " ORDER BY dp DESC";
1002
    //print $sql;
1003
    $resql = $db->query($sql);
1004
    if ($resql) {
1005
        $totalpaid = 0;
1006
1007
        $num = $db->num_rows($resql);
1008
        $i = 0;
1009
        $total = 0;
1010
1011
        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
1012
        print '<table class="noborder paymenttable">';
1013
        print '<tr class="liste_titre">';
1014
        print '<td>' . $langs->trans("RefPayment") . '</td>';
1015
        print '<td>' . $langs->trans("Date") . '</td>';
1016
        print '<td>' . $langs->trans("Type") . '</td>';
1017
        if (isModEnabled("bank")) {
1018
            print '<td class="liste_titre right">' . $langs->trans('BankAccount') . '</td>';
1019
        }
1020
        print '<td class="right">' . $langs->trans("Amount") . '</td>';
1021
        print '</tr>';
1022
1023
        $paymentsalarytemp = new PaymentSalary($db);
1024
1025
        if ($num > 0) {
1026
            $bankaccountstatic = new Account($db);
1027
            while ($i < $num) {
1028
                $objp = $db->fetch_object($resql);
1029
1030
                $paymentsalarytemp->id = $objp->rowid;
1031
                $paymentsalarytemp->ref = $objp->rowid;
1032
                $paymentsalarytemp->num_payment = $objp->num_payment;
1033
                $paymentsalarytemp->datep = $objp->dp;
1034
1035
                print '<tr class="oddeven"><td>';
1036
                print $paymentsalarytemp->getNomUrl(1);
1037
                print '</td>';
1038
                print '<td>' . dol_print_date($db->jdate($objp->dp), 'dayhour', 'tzuserrel') . "</td>\n";
1039
                $labeltype = $langs->trans("PaymentType" . $objp->type_code) != "PaymentType" . $objp->type_code ? $langs->trans("PaymentType" . $objp->type_code) : $objp->paiement_type;
1040
                print "<td>" . $labeltype . ' ' . $objp->num_payment . "</td>\n";
1041
                if (isModEnabled("bank")) {
1042
                    $bankaccountstatic->id = $objp->baid;
1043
                    $bankaccountstatic->ref = $objp->baref;
1044
                    $bankaccountstatic->label = $objp->baref;
1045
                    $bankaccountstatic->number = $objp->banumber;
1046
                    $bankaccountstatic->currency_code = $objp->bacurrency_code;
1047
1048
                    if (isModEnabled('accounting')) {
1049
                        $bankaccountstatic->account_number = $objp->account_number;
1050
1051
                        $accountingjournal = new AccountingJournal($db);
1052
                        $accountingjournal->fetch($objp->fk_accountancy_journal);
1053
                        $bankaccountstatic->accountancy_journal = $accountingjournal->getNomUrl(0, 1, 1, '', 1);
1054
                    }
1055
1056
                    print '<td class="right">';
1057
                    if ($bankaccountstatic->id) {
1058
                        print $bankaccountstatic->getNomUrl(1, 'transactions');
1059
                    }
1060
                    print '</td>';
1061
                }
1062
                print '<td class="right nowrap amountcard">' . price($objp->amount) . "</td>\n";
1063
                print "</tr>";
1064
                $totalpaid += $objp->amount;
1065
                $i++;
1066
            }
1067
        } else {
1068
            print '<tr class="oddeven"><td><span class="opacitymedium">' . $langs->trans("None") . '</span></td>';
1069
            print '<td></td><td></td><td></td><td></td>';
1070
            print '</tr>';
1071
        }
1072
1073
        print '<tr><td colspan="' . $nbcols . '" class="right">' . $langs->trans("AlreadyPaid") . ' :</td><td class="right nowrap amountcard">' . price($totalpaid) . "</td></tr>\n";
1074
        print '<tr><td colspan="' . $nbcols . '" class="right">' . $langs->trans("AmountExpected") . ' :</td><td class="right nowrap amountcard">' . price($object->amount) . "</td></tr>\n";
1075
1076
        $resteapayer = $object->amount - $totalpaid;
1077
        $cssforamountpaymentcomplete = 'amountpaymentcomplete';
1078
1079
        print '<tr><td colspan="' . $nbcols . '" class="right">' . $langs->trans("RemainderToPay") . " :</td>";
1080
        print '<td class="right nowrap' . ($resteapayer ? ' amountremaintopay' : (' ' . $cssforamountpaymentcomplete)) . '">' . price($resteapayer) . "</td></tr>\n";
1081
1082
        print "</table>";
1083
        print '</div>';
1084
1085
        $db->free($resql);
1086
    } else {
1087
        dol_print_error($db);
1088
    }
1089
1090
    print '</div>';
1091
    print '</div>';
1092
1093
    print '<div class="clearboth"></div>';
1094
1095
    print dol_get_fiche_end();
1096
1097
    if ($action == 'edit') {
1098
        print $form->buttonsSaveCancel();
1099
        print "</form>";
1100
    }
1101
1102
    $resteapayer = price2num($resteapayer, 'MT');
1103
1104
1105
    /*
1106
     * Action bar
1107
     */
1108
1109
    print '<div class="tabsAction">' . "\n";
1110
    if ($action != 'edit') {
1111
        // Dynamic send mail button
1112
        $parameters = array();
1113
        $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1114
        if (empty($reshook)) {
1115
            if (empty($user->socid)) {
1116
                $canSendMail = true;
1117
1118
                print dolGetButtonAction($langs->trans('SendMail'), '', 'default', $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&action=presend&token=' . newToken() . '&mode=init#formmailbeforetitle', '', $canSendMail);
1119
            }
1120
        }
1121
1122
        // Reopen
1123
        if ($object->paye && $permissiontoadd) {
1124
            print dolGetButtonAction('', $langs->trans('ReOpen'), 'default', $_SERVER["PHP_SELF"] . '?action=reopen&token=' . newToken() . '&id=' . $object->id, '');
1125
        }
1126
1127
        // Edit
1128
        if ($object->paye == 0 && $permissiontoadd) {
1129
            print dolGetButtonAction('', $langs->trans('Modify'), 'default', $_SERVER["PHP_SELF"] . '?action=edit&token=' . newToken() . '&id=' . $object->id, '');
1130
        }
1131
1132
        // Emit payment
1133
        if ($object->paye == 0 && ((price2num($object->amount) < 0 && $resteapayer < 0) || (price2num($object->amount) > 0 && $resteapayer > 0)) && $permissiontoadd) {
1134
            print dolGetButtonAction('', $langs->trans('DoPayment'), 'default', constant('BASE_URL') . '/salaries/paiement_salary.php?action=create&token=' . newToken() . '&id=' . $object->id, '');
1135
        }
1136
1137
        // Classify 'paid'
1138
        // If payment complete $resteapayer <= 0 on a positive salary, or if amount is negative, we allow to classify as paid.
1139
        if ($object->paye == 0 && (($resteapayer <= 0 && $object->amount > 0) || ($object->amount <= 0)) && $permissiontoadd) {
1140
            print dolGetButtonAction('', $langs->trans('ClassifyPaid'), 'default', $_SERVER["PHP_SELF"] . '?action=paid&token=' . newToken() . '&id=' . $object->id, '');
1141
        }
1142
1143
        // Transfer request
1144
        print dolGetButtonAction('', $langs->trans('MakeTransferRequest'), 'default', constant('BASE_URL') . '/salaries/virement_request.php?id=' . $object->id, '');
1145
1146
        // Clone
1147
        if ($permissiontoadd) {
1148
            print dolGetButtonAction('', $langs->trans('ToClone'), 'default', $_SERVER["PHP_SELF"] . '?action=clone&token=' . newToken() . '&id=' . $object->id, '');
1149
        }
1150
1151
        if ($permissiontodelete && empty($totalpaid)) {
1152
            print dolGetButtonAction('', $langs->trans('Delete'), 'delete', $_SERVER["PHP_SELF"] . '?action=delete&token=' . newToken() . '&id=' . $object->id, '');
1153
        } else {
1154
            print dolGetButtonAction($langs->trans('DisabledBecausePayments'), $langs->trans('Delete'), 'default', $_SERVER['PHP_SELF'] . '#', '', false);
1155
        }
1156
    }
1157
    print "</div>";
1158
1159
1160
1161
    // Select mail models is same action as presend
1162
    if (GETPOST('modelselected')) {
1163
        $action = 'presend';
1164
    }
1165
1166
    if ($action != 'presend') {
1167
        print '<div class="fichecenter"><div class="fichehalfleft">';
1168
        print '<a name="builddoc"></a>'; // ancre
1169
1170
        $includedocgeneration = 1;
1171
1172
        // Documents
1173
        if ($includedocgeneration) {
1174
            $objref = dol_sanitizeFileName($object->ref);
1175
            $relativepath = $objref . '/' . $objref . '.pdf';
1176
            $filedir = $conf->salaries->dir_output . '/' . $objref;
1177
            $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id;
1178
            //$genallowed = $permissiontoread; // If you can read, you can build the PDF to read content
1179
            $genallowed = 0; // If you can read, you can build the PDF to read content
1180
            $delallowed = $permissiontoadd; // If you can create/edit, you can remove a file on card
1181
            print $formfile->showdocuments('salaries', $objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang);
1182
        }
1183
1184
        // Show links to link elements
1185
        /*
1186
        $linktoelem = $form->showLinkToObjectBlock($object, null, array('salaries'));
1187
        $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
1188
        */
1189
1190
        print '</div><div class="fichehalfright">';
1191
1192
        $MAXEVENT = 10;
1193
1194
        $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', dol_buildpath('/mymodule/myobject_agenda.php', 1) . '?id=' . $object->id);
1195
1196
        // List of actions on element
1197
                $formactions = new FormActions($db);
1198
        //$somethingshown = $formactions->showactions($object, $object->element.'@'.$object->module, (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlcenter);
1199
1200
        print '</div></div>';
1201
    }
1202
1203
    //Select mail models is same action as presend
1204
    if (GETPOST('modelselected')) {
1205
        $action = 'presend';
1206
    }
1207
1208
    // Presend form
1209
    $modelmail = 'salary';
1210
    $defaulttopic = 'InformationMessage';
1211
    $diroutput = $conf->salaries->dir_output;
1212
    $trackid = 'salary' . $object->id;
1213
1214
    include DOL_DOCUMENT_ROOT . '/core/tpl/card_presend.tpl.php';
1215
1216
    // Hook to add more things on page
1217
    $parameters = array();
1218
    $reshook = $hookmanager->executeHooks('salaryCardTabAddMore', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1219
}
1220
1221
// End of page
1222
ViewMain::llxFooter();
1223
$db->close();
1224