dolibarr 25.0.0-alpha
card.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2013-2017 Olivier Geffroy <jeff@jeffinfo.com>
3 * Copyright (C) 2013-2017 Florian Henry <florian.henry@open-concept.pro>
4 * Copyright (C) 2013-2026 Alexandre Spangaro <alexandre@inovea-conseil.com>
5 * Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
6 * Copyright (C) 2018-2026 Frédéric France <frederic.france@free.fr>
7 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
8 * Copyright (C) 2025 Nicolas Barrouillet <nicolas@pragma-tech.fr>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
30// Load Dolibarr environment
31require '../../main.inc.php';
32require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
33require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php';
34require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php';
35require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
36require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
37require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
38require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
39require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
40require_once DOL_DOCUMENT_ROOT.'/accountancy/class/lettering.class.php';
41require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeepingtemplate.class.php';
42require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeepingtemplateline.class.php';
43
52// Load translation files required by the page
53$langs->loadLangs(array("accountancy", "bills", "compta", "errors"));
54
55$action = GETPOST('action', 'aZ09');
56$cancel = GETPOST('cancel', 'alpha');
57$confirm = GETPOST('confirm', 'alpha');
58
59$type = GETPOST('type', 'alpha');
60$backtopage = GETPOST('backtopage', 'alpha');
61if (empty($backtopage)) {
62 $backtopage = DOL_URL_ROOT . '/accountancy/bookkeeping/list.php';
63}
64
65$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
66
67$id = GETPOSTINT('id'); // id of record
68$mode = GETPOST('mode', 'aZ09'); // '' or '_tmp'
69$piece_num = GETPOSTINT("piece_num") ? GETPOSTINT("piece_num") : GETPOST('ref'); // id of transaction (several lines share the same transaction id)
70$clonedate = (int) GETPOSTINT('clonedate');
71
72$accountingaccount = new AccountingAccount($db);
73$accountingjournal = new AccountingJournal($db);
74
75$accountingaccount_number = GETPOST('accountingaccount_number', 'alphanohtml');
76$accountingaccount->fetch(0, $accountingaccount_number, true);
77$accountingaccount_label = $accountingaccount->label;
78
79$journal_code = GETPOST('code_journal', 'alpha');
80$accountingjournal->fetch(0, $journal_code);
81$journal_label = $accountingjournal->label;
82
83$subledger_account = GETPOST('subledger_account', 'alphanohtml');
84if ($subledger_account == -1) {
85 $subledger_account = null;
86}
87$subledger_label = GETPOST('subledger_label', 'alphanohtml');
88
89$label_operation = GETPOST('label_operation', 'alphanohtml');
90$debit = (float) price2num(GETPOST('debit', 'alpha'));
91$credit = (float) price2num(GETPOST('credit', 'alpha'));
92
93$save = GETPOST('save', 'alpha');
94if (!empty($save)) {
95 $action = 'add';
96}
97$update = GETPOST('update', 'alpha');
98if (!empty($update)) {
99 $action = 'confirm_update';
100}
101
102// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
103$hookmanager->initHooks(array('bookkeepingcard', 'globalcard'));
104
105$object = new BookKeeping($db);
106
107// Security check
108if (!isModEnabled('accounting')) {
110}
111if ($user->socid > 0) {
113}
114if (!$user->hasRight('accounting', 'mouvements', 'lire')) {
116}
117
118$permissiontoadd = $user->hasRight('accounting', 'mouvements', 'creer');
119$permissiontodelete = $user->hasRight('accounting', 'mouvements', 'supprimer');
120$numRefModel = getDolGlobalString('BOOKKEEPING_ADDON', 'mod_bookkeeping_neon');
121
122/*
123 * Actions
124 */
125
126$parameters = array();
127$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action);
128if ($reshook < 0) {
129 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
130}
131if (empty($reshook)) {
132 $error = 0;
133
134 if ($cancel) {
135 header("Location: ". $backtopage . (!empty($type) ? '?type=sub' : ''));
136 exit;
137 }
138
139 if ($action == "confirm_update" && $permissiontoadd) {
140 if (((float) $debit != 0.0) && ((float) $credit != 0.0)) {
141 $error++;
142 setEventMessages($langs->trans('ErrorDebitCredit'), null, 'errors');
143 $action = 'update';
144 }
145 if (empty($accountingaccount_number) || $accountingaccount_number == '-1') {
146 $error++;
147 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("AccountAccountingShort")), null, 'errors');
148 $action = 'update';
149 }
150
151 if (!$error) {
152 $object = new BookKeeping($db);
153
154 $result = $object->fetch($id, null, $mode);
155 if ($result < 0) {
156 $error++;
157 setEventMessages($object->error, $object->errors, 'errors');
158 } else {
159 $object->numero_compte = $accountingaccount_number;
160 $object->subledger_account = $subledger_account;
161 $object->subledger_label = $subledger_label;
162 $object->label_compte = $accountingaccount_label;
163 $object->label_operation = $label_operation;
164 $object->debit = $debit;
165 $object->credit = $credit;
166
167 if ((float) $debit != 0.0) {
168 $object->montant = $debit; // deprecated
169 $object->amount = $debit;
170 $object->sens = 'D';
171 }
172 if ((float) $credit != 0.0) {
173 $object->montant = $credit; // deprecated
174 $object->amount = $credit;
175 $object->sens = 'C';
176 }
177
178 $result = $object->update($user, 0, $mode);
179 if ($result < 0) {
180 setEventMessages($object->error, $object->errors, 'errors');
181 } else {
182 if ($mode != '_tmp') {
183 setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
184 }
185
186 $debit = 0;
187 $credit = 0;
188
189 $action = '';
190 }
191 }
192 }
193 } elseif ($action == "add" && $permissiontoadd) {
194 if (((float) $debit != 0.0) && ((float) $credit != 0.0)) {
195 $error++;
196 setEventMessages($langs->trans('ErrorDebitCredit'), null, 'errors');
197 $action = '';
198 }
199 if (empty($accountingaccount_number) || $accountingaccount_number == '-1') {
200 $error++;
201 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("AccountAccountingShort")), null, 'errors');
202 $action = '';
203 }
204 $subledger_account_str = is_array($subledger_account) ? reset($subledger_account) : (string) $subledger_account;
205 if (!checkGeneralAccountAllowsAuxiliary($db, $accountingaccount_number, $subledger_account_str)) {
206 $error++;
207 setEventMessages($langs->trans("ErrorAccountNotCentralized"). ". " . $langs->trans("RemoveSubsidiaryAccountOrAdjustTheGeneralAccount"), null, 'errors');
208 }
209
210 if (!$error) {
211 if (GETPOSTINT('doc_datemonth') && GETPOSTINT('doc_dateday') && GETPOSTINT('doc_dateyear')) {
212 $datedoc = dol_mktime(0, 0, 0, GETPOSTINT('doc_datemonth'), GETPOSTINT('doc_dateday'), GETPOSTINT('doc_dateyear'));
213 } else {
214 $datedoc = (int) GETPOSTINT('doc_date'); // TODO Use instead the mode day-month-year
215 }
216
217 $object = new BookKeeping($db);
218
219 $object->numero_compte = $accountingaccount_number;
220 $object->subledger_account = $subledger_account;
221 $object->subledger_label = $subledger_label;
222 $object->label_compte = $accountingaccount_label;
223 $object->label_operation = $label_operation;
224 $object->debit = $debit;
225 $object->credit = $credit;
226 $object->doc_date = $datedoc;
227 $object->doc_type = (string) GETPOST('doc_type', 'alpha');
228 $object->piece_num = $piece_num;
229 $object->doc_ref = (string) GETPOST('doc_ref', 'alpha');
230 $object->ref = (string) GETPOST('ref', 'alpha');
231 $object->code_journal = $journal_code;
232 $object->journal_label = $journal_label;
233 $object->fk_doc = GETPOSTINT('fk_doc');
234 $object->fk_docdet = GETPOSTINT('fk_docdet');
235
236 if ((float) $debit != 0.0) {
237 $object->montant = $debit; // deprecated
238 $object->amount = $debit;
239 $object->sens = 'D';
240 }
241
242 if ((float) $credit != 0.0) {
243 $object->montant = $credit; // deprecated
244 $object->amount = $credit;
245 $object->sens = 'C';
246 }
247
248 $result = $object->createStd($user, 0, $mode);
249
250 if ($result < 0) {
251 setEventMessages($object->error, $object->errors, 'errors');
252 } else {
253 if ($mode != '_tmp') {
254 setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
255 }
256
257 $debit = 0;
258 $credit = 0;
259
260 $action = '';
261 }
262 }
263 } elseif ($action == "confirm_delete" && $permissiontoadd) { // Delete line
264 $object = new BookKeeping($db);
265
266 $result = $object->fetch($id, null, $mode);
267 $piece_num = (int) $object->piece_num;
268 if ($result < 0) {
269 setEventMessages($object->error, $object->errors, 'errors');
270
271 $action = 'create';
272 } elseif ($result > 0) {
273 $object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
274 $result = $object->delete($user, 0, $mode);
275 if ($result < 0) {
276 setEventMessages($object->error, $object->errors, 'errors');
277 }
278 }
279 $action = '';
280 } elseif ($action == "confirm_create" && $permissiontoadd) {
281 $object = new BookKeeping($db);
282
283 if (!$journal_code || $journal_code == '-1') {
284 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Journal")), null, 'errors');
285 $action = 'create';
286 $error++;
287 }
288 if (!GETPOST('doc_ref', 'alpha')) {
289 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Piece")), null, 'errors');
290 $action = 'create';
291 $error++;
292 }
293 if (dol_strlen(GETPOST('ref', 'alpha')) > 30) { // Size of field ref in database
294 setEventMessages($langs->trans("ErrorFieldTooLong", $langs->transnoentitiesnoconv("Ref")), null, 'errors');
295 $action = 'create';
296 $error++;
297 }
298
299 if (!$error) {
300 $date_start = dol_mktime(0, 0, 0, GETPOSTINT('doc_datemonth'), GETPOSTINT('doc_dateday'), GETPOSTINT('doc_dateyear'));
301
302 $object->label_compte = '';
303 $object->debit = 0;
304 $object->credit = 0;
305 $object->doc_date = $date_start;
306 $object->doc_type = GETPOST('doc_type', 'alpha');
307 $object->piece_num = GETPOSTINT('next_num_mvt');
308 $object->doc_ref = GETPOST('doc_ref', 'alpha');
309 $object->code_journal = $journal_code;
310 $object->journal_label = $journal_label;
311 $object->fk_doc = 0;
312 $object->fk_docdet = 0;
313 $object->ref = (GETPOST('ref', 'alpha') ? GETPOST('ref', 'alpha') : $object->getNextNumRef());
314 $object->montant = 0; // deprecated
315 $object->amount = 0;
316
317 $result = $object->createStd($user, 0, $mode);
318
319 if ($result < 0) {
320 setEventMessages($object->error, $object->errors, 'errors');
321
322 $action = 'create';
323 } else {
324 // Transaction created successfully
325 $piece_num = $object->piece_num;
326
327 // Check if a template was selected
328 $template_id = GETPOSTINT('template_id');
329
330 if ($template_id > 0) {
331 require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeepingtemplate.class.php';
332 require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeepingtemplateline.class.php';
333
334 $template = new BookkeepingTemplate($db);
335 $result_template = $template->fetch($template_id);
336
337 if ($result_template > 0 && !empty($template->lines)) {
338 $db->begin();
339 $error_template = 0;
340
341 foreach ($template->lines as $templateline) {
342 $bookkeeping = new BookKeeping($db);
343
344 // Set common fields from the form
345 $bookkeeping->doc_date = $date_start;
346 $bookkeeping->doc_type = GETPOST('doctype', 'alpha');
347 $bookkeeping->piece_num = $piece_num;
348 $bookkeeping->doc_ref = GETPOST('docref', 'alpha');
349 $bookkeeping->code_journal = $journal_code;
350 $bookkeeping->journal_label = $journal_label;
351 $bookkeeping->fk_doc = 0;
352 $bookkeeping->fk_docdet = 0;
353 $bookkeeping->ref = GETPOST('ref', 'alpha') ? GETPOST('ref', 'alpha') : $object->ref;
354
355 // Set fields from template line
356 $bookkeeping->numero_compte = $templateline->general_account;
357 $bookkeeping->label_compte = $templateline->general_label;
358 $bookkeeping->subledger_account = $templateline->subledger_account;
359 $bookkeeping->subledger_label = $templateline->subledger_label;
360 $bookkeeping->label_operation = $templateline->operation_label;
361 $bookkeeping->debit = (float) $templateline->debit;
362 $bookkeeping->credit = (float) $templateline->credit;
363
364 // Backward compatibility
365 if ((float) $bookkeeping->debit != 0.0) {
366 $bookkeeping->montant = $bookkeeping->debit;
367 $bookkeeping->amount = $bookkeeping->debit;
368 $bookkeeping->sens = 'D';
369 }
370 if ((float) $bookkeeping->credit != 0.0) {
371 $bookkeeping->montant = $bookkeeping->credit;
372 $bookkeeping->amount = $bookkeeping->credit;
373 $bookkeeping->sens = 'C';
374 }
375
376 $result_line = $bookkeeping->createStd($user, 0, '_tmp');
377
378 if ($result_line < 0) {
379 $error_template++;
380 setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
381 break;
382 }
383 }
384
385 if (!$error_template) {
386 $db->commit();
387 setEventMessages($langs->trans('TemplateLinesLoaded', count($template->lines)), null, 'mesgs');
388 } else {
389 $db->rollback();
390 }
391 }
392 }
393
394 // Redirect to the transaction
395 header("Location: ".$_SERVER["PHP_SELF"]."?piece_num=".$piece_num."&mode=_tmp");
396 exit;
397 }
398 }
399 }
400
401 if ($action == 'setdate' && $permissiontoadd) {
402 $datedoc = dol_mktime(0, 0, 0, GETPOSTINT('doc_datemonth'), GETPOSTINT('doc_dateday'), GETPOSTINT('doc_dateyear'));
403 $result = $object->updateByMvt($piece_num, 'doc_date', $db->idate($datedoc), $mode);
404 if ($result < 0) {
405 setEventMessages($object->error, $object->errors, 'errors');
406 } else {
407 if ($mode != '_tmp') {
408 setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
409 }
410 $action = '';
411 }
412 }
413
414 if ($action == 'setjournal' && $permissiontoadd) {
415 $result = $object->updateByMvt($piece_num, 'code_journal', $journal_code, $mode);
416 $result = $object->updateByMvt($piece_num, 'journal_label', $journal_label, $mode);
417 if ($result < 0) {
418 setEventMessages($object->error, $object->errors, 'errors');
419 } else {
420 if ($mode != '_tmp') {
421 setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
422 }
423 $action = '';
424 }
425 }
426
427 if ($action == 'setdocref' && $permissiontoadd) {
428 $refdoc = GETPOST('doc_ref', 'alpha');
429 $result = $object->updateByMvt($piece_num, 'doc_ref', $refdoc, $mode);
430 if ($result < 0) {
431 setEventMessages($object->error, $object->errors, 'errors');
432 } else {
433 if ($mode != '_tmp') {
434 setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
435 }
436 $action = '';
437 }
438 }
439
440 if ($action == 'setref' && $permissiontoadd && $numRefModel === 'mod_bookkeeping_neon') {
441 $newref = GETPOST('ref', 'alpha');
442 if (dol_strlen($newref) > 30) { // Size of field ref in database
443 $result = -1;
444 $object->error = $langs->trans("ErrorFieldTooLong", $langs->transnoentitiesnoconv("Ref"));
445 $object->errors = array();
446 } else {
447 $result = $object->updateByMvt($piece_num, 'ref', $newref, $mode);
448 }
449 if ($result < 0) {
450 setEventMessages($object->error, $object->errors, 'errors');
451 } else {
452 if ($mode != '_tmp') {
453 setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
454 }
455 $action = '';
456 }
457 }
458
459 // Validate transaction
460 if ($action == 'valid' && $permissiontoadd) {
461 $result = $object->transformTransaction(0, $piece_num);
462 if ($result < 0) {
463 setEventMessages($object->error, $object->errors, 'errors');
464 } else {
465 // Retrieve the actual final part number (not the temporary number)
466 $piece_num = $object->piece_num;
467
468 $linkEntry = '<a href="'.$_SERVER["PHP_SELF"].'?piece_num='.(int) $piece_num.'">'.$langs->trans('NumMvts').': '.(int) $piece_num.'</a>';
469 setEventMessages($langs->trans('RecordSaved').' - '.$linkEntry, null, 'mesgs', '', 1);
470
471 if (getDolGlobalInt('ACCOUNTANCY_VALID_REDIRECT_TO_CARD')) {
472 // Redirection to the validated entry record
473 header("Location: ".$_SERVER["PHP_SELF"]."?piece_num=".(int) $piece_num);
474 } else {
475 // Default behavior: return on journal view
476 header("Location: ".$backtopage."?sortfield=t.piece_num&sortorder=asc".($type ? '&type='.$type : ''));
477 }
478 exit;
479 }
480 }
481
482 // Delete all lines into the transaction
483 $toselect_str = explode(',', GETPOST('toselect', 'alphanohtml'));
484 $toselect = array();
485 foreach ($toselect_str as $i) {
486 $toselect[] = (int) $i;
487 }
488
489 if ($action == 'deletebookkeepingwriting' && $confirm == "yes" && $permissiontodelete) {
490 $db->begin();
491
492 if (getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING')) {
493 $lettering = new Lettering($db);
494 $nb_lettering = $lettering->bookkeepingLetteringAll($toselect, true);
495 if ($nb_lettering < 0) {
496 setEventMessages('', $lettering->errors, 'errors');
497 $error++;
498 }
499 }
500
501 $nbok = 0;
502 $result = 0;
503 if (!$error) {
504 foreach ($toselect as $toselectid) {
505 $result = $object->fetch($toselectid);
506 if ($result >= 0 && (!isset($object->date_validation) || $object->date_validation === '')) {
507 $result = $object->deleteMvtNum($object->piece_num);
508 if ($result >= 0) {
509 $nbok += $result;
510 } else {
511 setEventMessages($object->error, $object->errors, 'errors');
512 $error++;
513 break;
514 }
515 } elseif ($result < 0) {
516 setEventMessages($object->error, $object->errors, 'errors');
517 $error++;
518 break;
519 } elseif (isset($object->date_validation) && $object->date_validation != '') {
520 setEventMessages($langs->trans("ValidatedRecordWhereFound"), null, 'errors');
521 $error++;
522 break;
523 }
524 }
525 }
526
527 if (!$error) {
528 $db->commit();
529
530 // Message for elements well deleted
531 if ($nbok > 1) {
532 setEventMessages($langs->trans("RecordsDeleted", $nbok), null, 'mesgs');
533 } elseif ($nbok > 0) {
534 setEventMessages($langs->trans("RecordDeleted", $nbok), null, 'mesgs');
535 } else {
536 setEventMessages($langs->trans("NoRecordDeleted"), null, 'mesgs');
537 }
538
539 header("Location: ".DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?noreset=1');
540 exit;
541 } else {
542 $db->rollback();
543 }
544 }
545
546 if ($action == 'clonebookkeepingwriting' && $confirm == "yes" && $permissiontoadd) {
547 // Reread the values sent by the validated form
548 $piece_num = GETPOST('piece_num', 'alpha');
549 $journal_code = GETPOST('code_journal', 'alpha');
550
551 // Reconstruct the selected date
552 $clonedate = dol_mktime(0, 0, 0, GETPOSTINT('clonedatemonth'), GETPOSTINT('clonedateday'), GETPOSTINT('clonedateyear'));
553
554 $result = $object->newClone($piece_num, $journal_code, $clonedate);
555
556 if ($result == -1) {
557 $error++;
558 setEventMessages($object->error, $object->errors, 'errors');
559 }
560
561 if (!$error) {
562 $db->commit();
563 header("Location: " . $_SERVER['PHP_SELF'] . "?piece_num=" . ($object->getNextNumMvt() - 1));
564 exit();
565 } else {
566 $db->rollback();
567 }
568 }
569}
570
571
572
573/*
574 * View
575 */
576
577$form = new Form($db);
578$formaccounting = new FormAccounting($db);
579
580$title = $langs->trans("CreateMvts");
581$help_url = 'EN:Module_Double_Entry_Accounting|FR:Module_Comptabilit&eacute;_en_Partie_Double';
582
583llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-accountancy accountancy-consultation page-card');
584
585// Confirmation to delete the command
586if ($action == 'delete') {
587 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$id.'&mode='.$mode, $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvt', $langs->transnoentitiesnoconv("RegistrationInAccounting")), 'confirm_delete', '', 0, 1);
588 print $formconfirm;
589}
590
591// Update fields properties in realtime
592if (!empty($conf->use_javascript_ajax)) {
593 print "\n" . '<script type="text/javascript">';
594 print '$(document).ready(function () {
595 function toggleSubledger() {
596 var isCentral = $("#accountingaccount_number option:selected").data("centralized");
597 console.log("the selected general ledger account is centralised?", isCentral);
598
599 var isAjaxMode = $("#search_subledger_account").length > 0;
600 var $visibleSubledger = isAjaxMode
601 ? $("#search_subledger_account")
602 : $("#subledger_account");
603
604 if (isCentral) {
605 $visibleSubledger.prop("disabled", false);
606 if (!isAjaxMode) {
607 $("#subledger_account").prop("disabled", false).trigger("change");
608 }
609 $("#subledger_label").prop("disabled", false);
610 } else {
611 $visibleSubledger.prop("disabled", true).val("");
612 if (!isAjaxMode) {
613 $("#subledger_account").val("").prop("disabled", true).trigger("change");
614 } else {
615 $("#subledger_account").val("");
616 }
617 $("#subledger_label").val("").prop("disabled", true);
618 }
619 }
620
621 toggleSubledger();
622
623 $("#accountingaccount_number").on("change", toggleSubledger);
624 $("#accountingaccount_number").on("select2:select", toggleSubledger);
625 ';
626 print ' });' . "\n";
627 print ' </script>' . "\n";
628}
629
630if ($action == 'create') {
631 print load_fiche_titre($title);
632
633 $object = new BookKeeping($db);
634 $next_num_mvt = $object->getNextNumMvt('_tmp');
635
636 if (empty($next_num_mvt)) {
637 dol_print_error(null, 'Failed to get next piece number');
638 }
639
640 print '<form action="'.$_SERVER["PHP_SELF"].'" name="create_mvt" method="POST">';
641 if ($optioncss != '') {
642 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
643 }
644 print '<input type="hidden" name="token" value="'.newToken().'">';
645 print '<input type="hidden" name="action" value="confirm_create">'."\n";
646 print '<input type="hidden" name="next_num_mvt" value="'.$next_num_mvt.'">'."\n";
647 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
648 print '<input type="hidden" name="type" value="'.$type.'">';
649 print '<input type="hidden" name="mode" value="_tmp">'."\n";
650
651 print dol_get_fiche_head();
652
653 print '<table class="border centpercent">';
654
655 print '<tr>';
656 print '<td class="fieldrequired">'.$langs->trans("Docdate").'</td>';
657 print '<td>';
658 print $form->selectDate('', 'doc_date', 0, 0, 0, "create_mvt", 1, 1);
659 print '</td>';
660 print '</tr>';
661
662 print '<tr>';
663 print '<td class="fieldrequired">'.$langs->trans("Codejournal").'</td>';
664 print '<td>'.$formaccounting->select_journal($journal_code, 'code_journal', 0, 0, 1, 1).'</td>';
665 print '</tr>';
666
667 print '<tr>';
668 print '<td class="fieldrequired">'.$form->textwithpicto($langs->trans("Piece"), $langs->trans("PieceDesc")).'</td>';
669 print '<td><input type="text" class="minwidth200" name="doc_ref" value="'.GETPOST('doc_ref', 'alpha').'"></td>';
670 print '</tr>';
671
672 // Piece number
673 print '<tr>';
674 print '<td>'.$form->textwithpicto($langs->trans("Ref"), $langs->trans("BankTransactionRef")).'</td>';
675 print '<td>';
676 if ($numRefModel === 'mod_bookkeeping_neon') {
677 print '<input type="text" class="minwidth200" name="ref" maxlength="30" value="">';
678 } else {
679 print '<span class="opacitymedium">'.$langs->trans("Automatic").'</span>';
680 }
681 print '</td>';
682
683 // Template
684 print '<tr>';
685 print '<td>'.$langs->trans("BookkeepingTemplate").'</td>';
686 print '<td>';
687 require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeepingtemplate.class.php';
688
689 $sql = "SELECT rowid, code, label";
690 $sql .= " FROM ".MAIN_DB_PREFIX."accounting_transaction_template";
691 $sql .= " WHERE entity IN (".getEntity('accounting').")";
692 $sql .= " ORDER BY code ASC";
693
694 $resql = $db->query($sql);
695 $templates = array();
696
697 if ($resql) {
698 $num = $db->num_rows($resql);
699 $i = 0;
700 while ($i < $num) {
701 $obj = $db->fetch_object($resql);
702 $templates[$obj->rowid] = $obj->code.' - '.$obj->label;
703 $i++;
704 }
705 $db->free($resql);
706 }
707
708 if (count($templates) > 0) {
709 print '<select class="flat minwidth300" name="template_id" id="template_id">';
710 print '<option value=""></option>';
711 foreach ($templates as $key => $label) {
712 print '<option value="'.$key.'">'.dol_escape_htmltag($label).'</option>';
713 }
714 print '</select>';
715 } else {
716 print '<span class="opacitymedium">'.$langs->trans("NoTemplateAvailable").'</span>';
717 }
718
719 print '</td>';
720 print '</tr>';
721
722 $reshookAddLine = $hookmanager->executeHooks('bookkeepingAddLine', $parameters, $object, $action);
723
724 print '</table>';
725
726 print dol_get_fiche_end();
727
728 print $form->buttonsSaveCancel("Create");
729
730 print '</form>';
731} else {
732 $object = new BookKeeping($db);
733
734 $result = $object->fetchPerMvt($piece_num, $mode);
735 if ($result < 0) {
736 setEventMessages($object->error, $object->errors, 'errors');
737 }
738
739 if (!empty($object->piece_num)) {
740 $backlink = '<a href="'.DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?restore_lastsearch_values=1">'.$langs->trans('BackToList').'</a>';
741
742 /*if ($mode == '_tmp') {
743 print load_fiche_titre($langs->trans("CreateMvts"), $backlink);
744 } else {
745 print load_fiche_titre($langs->trans("UpdateMvts"), $backlink);
746 }*/
747
748 $head = accounting_transaction_prepare_head($object, $mode, $type, $backtopage);
749
750 print dol_get_fiche_head($head, 'transaction', '', -1);
751
752 //$object->label = $object->doc_ref;
753 if ($mode == '_tmp') {
754 $object->context['mode'] = $mode;
755 $object->next_prev_filter = '1=0'; // Add a test always false to disable navigation into the dol_banner_tab. In tmp mode, we just want to create/edit lines of bank transaction.
756 }
757 $object->label = $object->ref;
758
759 $morehtmlref = '<div style="clear: both;"></div>';
760 $morehtmlref .= '<div class="refidno opacitymedium">';
761 $morehtmlref .= $object->label;
762 $morehtmlref .= '</div>';
763
764 dol_banner_tab($object, 'ref', $backlink, 1, 'piece_num', 'piece_num', $morehtmlref);
765
766
767 if ($action == 'clonebookkeepingwriting' && $confirm != 'yes' && $permissiontoadd) {
768 $piece_num = GETPOST('piece_num', 'alpha');
769 $formaccounting = new FormAccounting($db);
770
771 $form = new Form($db);
772 $input1 = $form->selectDate('', 'clonedate', 0, 0, 0, "", 1, 1);
773 $input2 = $formaccounting->select_journal($journal_code, 'code_journal', 0, 0, 1, 1);
774
775 $formquestion = array(
776 array(
777 'type' => 'other',
778 'name' => 'clonedate',
779 'label' => '<span class="fieldrequired">' . $langs->trans("Docdate") . '</span>',
780 'value' => $input1
781 )
782 );
783
784 $formquestion[] = array('type' => 'hidden', 'name' => 'piece_num', 'value' => $piece_num);
785
786 if (getDolGlobalString('ACCOUNTING_CLONING_ENABLE_INPUT_JOURNAL')) {
787 $formquestion[] = array(
788 'type' => 'text',
789 'name' => 'code_journal',
790 'label' => '<span class="fieldrequired">' . $langs->trans("Codejournal") . '</span>',
791 'value' => $input2
792 );
793 }
794
795 print $form->formconfirm(
796 $_SERVER["PHP_SELF"],
797 $langs->trans("ConfirmMassCloneBookkeepingWriting"),
798 $langs->trans("ConfirmMassCloneBookkeepingWritingQuestion", 1),
799 "clonebookkeepingwriting",
800 $formquestion,
801 '', 0, 300, 1000, 0
802 );
803 }
804
805
806 print '<div class="fichecenter">';
807
808 print '<div class="fichehalfleft">';
809
810 print '<div class="underbanner clearboth"></div>';
811 print '<table class="border tableforfield centpercent">';
812
813 // Account movement
814 /*
815 print '<tr>';
816 print '<td class="titlefieldmiddle">'.$langs->trans("NumMvts").'</td>';
817 print '<td>'.($mode == '_tmp' ? '<span class="opacitymedium" title="Id tmp '.$object->piece_num.'">'.$langs->trans("Draft").'</span>' : $object->piece_num).'</td>';
818 print '</tr>';
819 */
820
821 // Account movement ref. Edit allowed only for free ref num model.
822 print '<tr><td class="titlefieldmiddle">';
823 print '<table class="nobordernopadding centpercent"><tr><td>';
824 print $langs->trans('Ref');
825 print '</td>';
826 if ($action != 'editref' && empty($object->date_validation)) {
827 print '<td class="right">';
828 if ($permissiontoadd && $numRefModel === 'mod_bookkeeping_neon') {
829 print '<a class="editfielda reposition" href="'.$_SERVER["PHP_SELF"].'?action=editref&token='.newToken().'&piece_num='.((int) $object->piece_num).'&mode='.urlencode((string) $mode).'">'.img_edit($langs->transnoentitiesnoconv('Edit'), 1).'</a>';
830 }
831 print '</td>';
832 }
833 print '</tr></table>';
834 print '</td><td>';
835 if ($action == 'editref' && empty($object->date_validation)) {
836 print '<form name="setref" action="'.$_SERVER["PHP_SELF"].'?piece_num='.((int) $object->piece_num).'" method="POST">';
837 if ($optioncss != '') {
838 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
839 }
840 print '<input type="hidden" name="token" value="'.newToken().'">';
841 print '<input type="hidden" name="action" value="setref">';
842 print '<input type="hidden" name="mode" value="'.$mode.'">';
843 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
844 print '<input type="hidden" name="type" value="'.$type.'">';
845 print '<input type="text" size="20" name="ref" maxlength="30" value="'.dol_escape_htmltag($object->ref).'">';
846 print '<input type="submit" class="button button-edit smallpaddingimp" value="'.$langs->trans('Modify').'">';
847 print '</form>';
848 } else {
849 print $object->ref;
850 }
851 print '</td>';
852 print '</tr>';
853
854 // Ref document
855 print '<tr><td>';
856 print '<table class="nobordernopadding centpercent"><tr><td>';
857 print $form->textwithpicto($langs->trans('Piece'), $langs->trans('PieceDesc'));
858 print '</td>';
859 if ($action != 'editdocref') {
860 print '<td class="right">';
861 if ($permissiontoadd && empty($object->date_validation)) {
862 print '<a class="editfielda reposition" href="'.$_SERVER["PHP_SELF"].'?action=editdocref&token='.newToken().'&piece_num='.((int) $object->piece_num).'&mode='.urlencode((string) $mode).'">'.img_edit($langs->transnoentitiesnoconv('Edit'), 1).'</a>';
863 }
864 print '</td>';
865 }
866 print '</tr></table>';
867 print '</td><td>';
868 if ($action == 'editdocref' && empty($object->date_validation)) {
869 print '<form name="setdocref" action="'.$_SERVER["PHP_SELF"].'?piece_num='.((int) $object->piece_num).'" method="POST">';
870 if ($optioncss != '') {
871 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
872 }
873 print '<input type="hidden" name="token" value="'.newToken().'">';
874 print '<input type="hidden" name="action" value="setdocref">';
875 print '<input type="hidden" name="mode" value="'.$mode.'">';
876 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
877 print '<input type="hidden" name="type" value="'.$type.'">';
878 print '<input type="text" size="20" name="doc_ref" value="'.dol_escape_htmltag($object->doc_ref).'">';
879 print '<input type="submit" class="button button-edit smallpaddingimp" value="'.$langs->trans('Modify').'">';
880 print '</form>';
881 } else {
882 // Get information of an element
883 if ($object->doc_type === 'customer_invoice' && !empty($object->fk_doc)) {
884 $invoicestatic = new Facture($db);
885 $result = $invoicestatic->fetch($object->fk_doc);
886
887 if ($result > 0) {
888 $label_element = $invoicestatic->getNomUrl(1);
889 } else {
890 $label_element = $object->doc_ref;
891 }
892 } elseif ($object->doc_type === 'supplier_invoice' && !empty($object->fk_doc)) {
893 $supplierinvoicestatic = new FactureFournisseur($db);
894 $result = $supplierinvoicestatic->fetch($object->fk_doc);
895
896 if ($result > 0) {
897 $label_element = $supplierinvoicestatic->getNomUrl(1);
898 } else {
899 $label_element = $object->doc_ref;
900 }
901 } elseif ($object->doc_type === 'expense_report' && !empty($object->fk_doc)) {
902 $expensereportstatic = new ExpenseReport($db);
903 $result = $expensereportstatic->fetch($object->fk_doc);
904
905 if ($result > 0) {
906 $label_element = $expensereportstatic->getNomUrl(1);
907 } else {
908 $label_element = $object->doc_ref;
909 }
910 } else {
911 $label_element = $object->doc_ref;
912 }
913 print $label_element;
914 }
915 print '</td>';
916 print '</tr>';
917
918 // Date
919 print '<tr><td>';
920 print '<table class="nobordernopadding centpercent"><tr><td>';
921 print $langs->trans('Docdate');
922 print '</td>';
923 if ($action != 'editdate') {
924 print '<td class="right">';
925 if ($permissiontoadd && empty($object->date_validation)) {
926 print '<a class="editfielda reposition" href="'.$_SERVER["PHP_SELF"].'?action=editdate&token='.newToken().'&piece_num='.((int) $object->piece_num).'&mode='.urlencode((string) $mode).'">'.img_edit($langs->transnoentitiesnoconv('SetDate'), 1).'</a>';
927 }
928 print '</td>';
929 }
930 print '</tr></table>';
931 print '</td><td colspan="3">';
932 if ($action == 'editdate' && empty($object->date_validation)) {
933 print '<form name="setdate" action="'.$_SERVER["PHP_SELF"].'?piece_num='.((int) $object->piece_num).'" method="POST">';
934 if ($optioncss != '') {
935 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
936 }
937 print '<input type="hidden" name="token" value="'.newToken().'">';
938 print '<input type="hidden" name="action" value="setdate">';
939 print '<input type="hidden" name="mode" value="'.$mode.'">';
940 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
941 print '<input type="hidden" name="type" value="'.$type.'">';
942 print $form->selectDate($object->doc_date ? $object->doc_date : -1, 'doc_date', 0, 0, 0, "setdate");
943 print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
944 print '</form>';
945 } else {
946 print $object->doc_date ? dol_print_date($object->doc_date, 'day') : '&nbsp;';
947 }
948 print '</td>';
949 print '</tr>';
950
951 // Journal
952 print '<tr><td>';
953 print '<table class="nobordernopadding centpercent"><tr><td>';
954 print $langs->trans('Codejournal');
955 print '</td>';
956 if ($action != 'editjournal') {
957 print '<td class="right">';
958 if ($permissiontoadd && empty($object->date_validation)) {
959 print '<a class="editfielda reposition" href="'.$_SERVER["PHP_SELF"].'?action=editjournal&token='.newToken().'&piece_num='.((int) $object->piece_num).'&mode='.urlencode((string) $mode).'">'.img_edit($langs->transnoentitiesnoconv('Edit'), 1).'</a>';
960 }
961 print '</td>';
962 }
963 print '</tr></table>';
964 print '</td><td>';
965 if ($action == 'editjournal' && empty($object->date_validation)) {
966 print '<form name="setjournal" action="'.$_SERVER["PHP_SELF"].'?piece_num='.((int) $object->piece_num).'" method="POST">';
967 if ($optioncss != '') {
968 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
969 }
970 print '<input type="hidden" name="token" value="'.newToken().'">';
971 print '<input type="hidden" name="action" value="setjournal">';
972 print '<input type="hidden" name="mode" value="'.$mode.'">';
973 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
974 print '<input type="hidden" name="type" value="'.$type.'">';
975 print $formaccounting->select_journal($object->code_journal, 'code_journal', 0, 0, 0, 1, '');
976 print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
977 print '</form>';
978 } else {
979 // Get information of a journal
980 $accountingjournalstatic = new AccountingJournal($db);
981 $accountingjournalstatic->fetch(0, $object->code_journal);
982 $journal = $accountingjournalstatic->code;
983 $journal_label = $accountingjournalstatic->label;
984
985 print $accountingjournalstatic->getNomUrl(1, 1, 1);
986 }
987 print '</td>';
988 print '</tr>';
989
990 print '</table>';
991
992 print '</div>';
993
994
995 print '<div class="fichehalfright">';
996
997 print '<div class="underbanner clearboth"></div>';
998 print '<table class="border tableforfield centpercent">';
999
1000 // Doc type
1001 if (!empty($object->doc_type)) {
1002 print '<tr>';
1003 print '<td class="titlefield">'.$langs->trans("Doctype").'</td>';
1004 print '<td>'.$object->doc_type.'</td>';
1005 print '</tr>';
1006 }
1007
1008 // Date document creation
1009 print '<tr>';
1010 print '<td class="titlefield">'.$langs->trans("DateCreation").'</td>';
1011 print '<td>';
1012 print $object->date_creation ? dol_print_date($object->date_creation, 'day') : '&nbsp;';
1013 print '</td>';
1014 print '</tr>';
1015
1016 // Due date (if invoice)
1017 //if (in_array($object->doc_type, array('customer_invoice', 'supplier_invoice'))) {
1018 print '<tr>';
1019 print '<td class="titlefield">' . $form->textwithpicto($langs->trans('DateDue'), $langs->trans("IfTransactionHasDueDate")) . '</td>';
1020 print '<td>';
1021 print $object->date_lim_reglement ? dol_print_date($object->date_lim_reglement, 'day') : '&nbsp;';
1022 print '</td>';
1023 print '</tr>';
1024 //}
1025
1026 // Don't show in tmp mode, inevitably empty
1027 if ($mode != "_tmp") {
1028 // Date document export
1029 print '<tr>';
1030 print '<td class="titlefield">' . $langs->trans("DateExport") . '</td>';
1031 print '<td>';
1032 print $object->date_export ? img_picto($langs->trans("TransactionExportDesc"), 'fa-file-export', 'class="pictofixedwidth opacitymedium"').dol_print_date($object->date_export, 'dayhour') : '&nbsp;';
1033 print '</td>';
1034 print '</tr>';
1035
1036 // Date document validation
1037 print '<tr>';
1038 print '<td class="titlefield">' . $langs->trans("DateValidation") . '</td>';
1039 print '<td>';
1040 print $object->date_validation ? img_picto($langs->trans("TransactionBlockedLockedDesc"), 'fa-lock', 'class="pictofixedwidth opacitymedium"').dol_print_date($object->date_validation, 'dayhour') : '&nbsp;';
1041 print '</td>';
1042 print '</tr>';
1043
1044 // Id_import
1045 if (!empty($object->import_key)) {
1046 print '<tr>';
1047 print '<td class="titlefield">' . $langs->trans("ImportId") . '</td>';
1048 print '<td>';
1049 print $object->import_key;
1050 print '</td>';
1051 print '</tr>';
1052 }
1053 }
1054
1055 // Validate
1056 /*
1057 print '<tr>';
1058 print '<td class="titlefield">' . $langs->trans("Status") . '</td>';
1059 print '<td>';
1060 if (empty($object->validated)) {
1061 print '<a class="reposition" href="' . $_SERVER["PHP_SELF"] . '?piece_num=' . $line->id . '&action=enable&token='.newToken().'">';
1062 print img_picto($langs->trans("Disabled"), 'switch_off');
1063 print '</a>';
1064 } else {
1065 print '<a class="reposition" href="' . $_SERVER["PHP_SELF"] . '?piece_num=' . $line->id . '&action=disable&token='.newToken().'">';
1066 print img_picto($langs->trans("Activated"), 'switch_on');
1067 print '</a>';
1068 }
1069 print '</td>';
1070 print '</tr>';
1071 */
1072
1073 // check data
1074 /*
1075 print '<tr>';
1076 print '<td class="titlefield">' . $langs->trans("Control") . '</td>';
1077 if ($object->doc_type == 'customer_invoice')
1078 {
1079 $sqlmid = 'SELECT rowid as ref';
1080 $sqlmid .= " FROM ".MAIN_DB_PREFIX."facture as fac";
1081 $sqlmid .= " WHERE fac.rowid=" . ((int) $object->fk_doc);
1082 dol_syslog("accountancy/bookkeeping/card.php::sqlmid=" . $sqlmid, LOG_DEBUG);
1083 $resultmid = $db->query($sqlmid);
1084 if ($resultmid) {
1085 $objmid = $db->fetch_object($resultmid);
1086 $invoicestatic = new Facture($db);
1087 $invoicestatic->fetch($objmid->ref);
1088 $ref=$langs->trans("Invoice").' '.$invoicestatic->getNomUrl(1);
1089 }
1090 else dol_print_error($db);
1091 }
1092 print '<td>' . $ref .'</td>';
1093 print '</tr>';
1094 */
1095 print "</table>\n";
1096
1097 print '</div>';
1098
1099 print '</div>';
1100 print '<div class="clearboth"></div>';
1101
1102
1103 print dol_get_fiche_end();
1104
1105
1106 $result = $object->fetchAllPerMvt($piece_num, $mode); // This load $object->linesmvt
1107
1108 if ($result < 0) {
1109 setEventMessages($object->error, $object->errors, 'errors');
1110 } else {
1111 // Variable that contains all transaction lines
1112 $tmptoselect = array();
1113 $atleastonevalidated = 0;
1114 $atleastoneexported = 0;
1115 foreach ($object->linesmvt as $line) {
1116 $tmptoselect[] = $line->id;
1117 if (!empty($line->date_validation)) {
1118 $atleastonevalidated = 1;
1119 }
1120 if (!empty($line->date_export) || !empty($line->date_validation)) {
1121 $atleastoneexported = 1;
1122 }
1123 }
1124
1125 if ($mode != '_tmp' && !$atleastonevalidated) {
1126 print "\n".'<div class="tabsAction">'."\n";
1127
1128 $parameters = array();
1129 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1130 if (empty($reshook)) {
1131 if ($permissiontodelete) {
1132 if (!isset($hookmanager->resArray['no_button_edit']) || $hookmanager->resArray['no_button_edit'] != 1) {
1133 print dolGetButtonAction($langs->trans('Delete'), $langs->trans('Delete'), 'delete', DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?action=deletebookkeepingwriting&confirm=yes&token='.newToken().'&piece_num='.((int) $object->piece_num).'&toselect='.implode(',', $tmptoselect), '', $permissiontodelete, array('attr' => array('class' => 'reposition')))."\n";
1134 }
1135 }
1136 if ($permissiontoadd) {
1137 print dolGetButtonAction($langs->trans('ToClone'), $langs->trans('ToClone'), 'clone', DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?action=clonebookkeepingwriting&token=' . newToken() . '&piece_num=' . ((int) $object->piece_num) . '&toselect=' . implode(',', $tmptoselect), 'action-clone', $permissiontoadd, array('attr' => array('class' => 'reposition')));
1138 }
1139 }
1140
1141 print '</div>';
1142 }
1143
1144 // List of movements
1145 print load_fiche_titre($langs->trans("ListeMvts"), '', '');
1146
1147 if (empty($object->date_validation)) {
1148 print '<form action="' . $_SERVER["PHP_SELF"] . '?piece_num=' . ((int) $object->piece_num) . '" method="POST">';
1149 if ($optioncss != '') {
1150 print '<input type="hidden" name="optioncss" value="' . $optioncss . '">';
1151 }
1152 print '<input type="hidden" name="token" value="' . newToken() . '">';
1153 print '<input type="hidden" name="doc_date" value="' . $object->doc_date . '">' . "\n";
1154 print '<input type="hidden" name="doc_type" value="' . $object->doc_type . '">' . "\n";
1155 print '<input type="hidden" name="doc_ref" value="' . $object->doc_ref . '">' . "\n";
1156 print '<input type="hidden" name="ref" value="' . $object->ref . '">' . "\n";
1157 print '<input type="hidden" name="code_journal" value="' . $object->code_journal . '">' . "\n";
1158 print '<input type="hidden" name="fk_doc" value="' . $object->fk_doc . '">' . "\n";
1159 print '<input type="hidden" name="fk_docdet" value="' . $object->fk_docdet . '">' . "\n";
1160 print '<input type="hidden" name="mode" value="' . $mode . '">' . "\n";
1161 print '<input type="hidden" name="backtopage" value="' . $backtopage . '">';
1162 print '<input type="hidden" name="type" value="' . $type . '">';
1163 }
1164
1165 if (count($object->linesmvt) > 0) {
1166 print '<div class="div-table-responsive-no-min">';
1167 print '<table class="noborder centpercent">';
1168
1169 $total_debit = 0;
1170 $total_credit = 0;
1171
1172 print '<tr class="liste_titre">';
1173
1174 print_liste_field_titre("AccountAccountingShort");
1175 print_liste_field_titre("SubledgerAccount");
1176 print_liste_field_titre("LabelOperation");
1177 print_liste_field_titre("AccountingDebit", "", "", "", "", 'class="right"');
1178 print_liste_field_titre("AccountingCredit", "", "", "", "", 'class="right"');
1179 if (empty($object->date_validation)) {
1180 print_liste_field_titre("Action", "", "", "", "", 'width="60"', "", "", 'center ');
1181 } else {
1183 }
1184
1185 print "</tr>\n";
1186
1187 // Add an empty line if there is not yet
1188 if (!empty($object->linesmvt[0]) && empty($object->date_validation)) {
1189 $tmpline = $object->linesmvt[0];
1190 if (!empty($tmpline->numero_compte)) {
1191 $line = new BookKeepingLine($db);
1192 $object->linesmvt[] = $line;
1193 }
1194 }
1195
1196 foreach ($object->linesmvt as $line) {
1197 $total_debit += $line->debit;
1198 $total_credit += $line->credit;
1199
1200 if ($action == 'update' && $line->id == $id && empty($object->date_validation)) {
1201 print '<tr class="oddeven" data-lineid="'.((int) $line->id).'">';
1202 print '<!-- td columns in edit mode -->';
1203 print '<td>';
1204 print $formaccounting->select_account((GETPOSTISSET("accountingaccount_number") ? GETPOST("accountingaccount_number", "alpha") : $line->numero_compte), 'accountingaccount_number', 1, array(), 1, 1, 'minwidth200 maxwidth500');
1205 print '</td>';
1206 print '<td>';
1207 print $formaccounting->select_auxaccount((GETPOSTISSET("subledger_account") ? GETPOST("subledger_account", "alpha") : $line->subledger_account), 'subledger_account', 1, 'maxwidth250', '', 'subledger_label');
1208 // Add also input for subledger label
1209 print '<br><input type="text" class="maxwidth150" name="subledger_label" id="subledger_label" value="'.(GETPOSTISSET("subledger_label") ? GETPOST("subledger_label", "alpha") : $line->subledger_label).'" placeholder="'.dol_escape_htmltag($langs->trans("SubledgerAccountLabel")).'">';
1210 print '</td>';
1211 print '<td><input type="text" class="minwidth200" name="label_operation" value="'.(GETPOSTISSET("label_operation") ? GETPOST("label_operation", "alpha") : $line->label_operation).'"></td>';
1212 print '<td class="right"><input type="text" class="right width50" name="debit" value="'.(GETPOSTISSET("debit") ? GETPOST("debit", "alpha") : price($line->debit)).'"></td>';
1213 print '<td class="right"><input type="text" class="right width50" name="credit" value="'.(GETPOSTISSET("credit") ? GETPOST("credit", "alpha") : price($line->credit)).'"></td>';
1214 print '<td>';
1215 print '<input type="hidden" name="id" value="'.$line->id.'">'."\n";
1216 print '<input type="submit" class="button" name="update" value="'.$langs->trans("Update").'">';
1217 print '</td>';
1218 print "</tr>\n";
1219 } elseif ((empty($line->numero_compte) || (empty($line->debit) && empty($line->credit))) && empty($object->date_validation)) {
1220 if (($action == "" || $action == 'add') && $permissiontoadd) {
1221 print '<tr class="oddeven" data-lineid="'.((int) $line->id).'">';
1222 print '<!-- td columns in add mode -->';
1223 print '<td>';
1224 print $formaccounting->select_account($action == 'add' ? GETPOST('accountingaccount_number') : '', 'accountingaccount_number', 1, array(), 1, 1, 'minwidth200 maxwidth500');
1225 print '</td>';
1226 print '<td>';
1227 print $formaccounting->select_auxaccount('', 'subledger_account', 1, 'maxwidth250', '', 'subledger_label');
1228 print '<br><input type="text" class="maxwidth150" name="subledger_label" id="subledger_label" value="" placeholder="' . dol_escape_htmltag($langs->trans("SubledgerAccountLabel")) . '">';
1229 print '</td>';
1230 print '<td><input type="text" class="minwidth200" name="label_operation" value="' . dol_escape_htmltag($label_operation) . '"/></td>';
1231 print '<td class="right"><input type="text" class="right width50" name="debit" value=""/></td>';
1232 print '<td class="right"><input type="text" class="right width50" name="credit" value=""/></td>';
1233 print '<td class="center"><input type="submit" class="button small" name="save" value="' . $langs->trans("Add") . '"></td>';
1234 print "</tr>\n";
1235 }
1236 } else {
1237 print '<tr class="oddeven" data-lineid="'.((int) $line->id).'">';
1238 print '<!-- td columns in display mode -->';
1239 $resultfetch = $accountingaccount->fetch(0, $line->numero_compte, true);
1240 print '<td>';
1241 if ($resultfetch > 0) {
1242 print $accountingaccount->getNomUrl(0, 1, 1, '', 0);
1243 } else {
1244 print dol_escape_htmltag($line->numero_compte).' <span class="warning">('.$langs->trans("AccountRemovedFromCurrentChartOfAccount").')</span>';
1245 }
1246 print '</td>';
1247 print '<td>'.length_accounta($line->subledger_account);
1248 if ($line->subledger_label) {
1249 print ' - <span class="opacitymedium">'.dol_escape_htmltag($line->subledger_label).'</span>';
1250 }
1251 print '</td>';
1252 print '<td>'.$line->label_operation.'</td>';
1253 print '<td class="right nowraponall amount">'.($line->debit != 0 ? price($line->debit) : '').'</td>';
1254 print '<td class="right nowraponall amount">'.($line->credit != 0 ? price($line->credit) : '').'</td>';
1255
1256 print '<td class="center nowraponall">';
1257 if ($permissiontoadd) {
1258 if (empty($line->date_export) && empty($line->date_validation)) {
1259 print '<a class="editfielda reposition" href="' . $_SERVER["PHP_SELF"] . '?action=update&id=' . $line->id . '&piece_num=' . ((int) $line->piece_num) . '&mode=' . urlencode((string) $mode) . '&token=' . urlencode(newToken()) . '">';
1260 print img_edit('', 0, 'class="marginrightonly"');
1261 print '</a> &nbsp;';
1262 } else {
1263 print '<a class="editfielda nohover cursornotallowed reposition disabled" href="#" title="'.dol_escape_htmltag($langs->trans("ForbiddenTransactionAlreadyExported")).'">';
1264 print img_edit($langs->trans("ForbiddenTransactionAlreadyExported"), 0, 'class="marginrightonly"');
1265 print '</a> &nbsp;';
1266 }
1267
1268 if (empty($line->date_validation)) {
1269 $actiontodelete = 'delete';
1270 if ($mode == '_tmp' || $action != 'delmouv') {
1271 $actiontodelete = 'confirm_delete';
1272 }
1273
1274 print '<a href="' . $_SERVER["PHP_SELF"] . '?action=' . $actiontodelete . '&id=' . $line->id . '&piece_num=' . ((int) $line->piece_num) . '&mode=' . urlencode((string) $mode) . '&token=' . urlencode(newToken()) . '">';
1275 print img_delete();
1276 print '</a>';
1277 } else {
1278 print '<a class="editfielda nohover cursornotallowed disabled" href="#" title="'.dol_escape_htmltag($langs->trans("ForbiddenTransactionAlreadyExported")).'">';
1279 print img_delete($langs->trans("ForbiddenTransactionAlreadyValidated"));
1280 print '</a>';
1281 }
1282 }
1283 print '</td>';
1284 print "</tr>\n";
1285 }
1286 }
1287
1288 $total_debit = price2num($total_debit, 'MT');
1289 $total_credit = price2num($total_credit, 'MT');
1290
1291 if ($total_debit != $total_credit) {
1292 setEventMessages(null, array($langs->trans('MvtNotCorrectlyBalanced', $total_debit, $total_credit)), 'warnings');
1293 }
1294
1295 print '</table>';
1296 print '</div>';
1297
1298 if ($mode == '_tmp' && $action == '' && $permissiontoadd) {
1299 print '<br>';
1300 print '<div class="center">';
1301 if (empty($total_debit) && empty($total_credit)) {
1302 print '<a class="button disabled cursornotallowed" disabled="disabled" href="#" title="'.dol_escape_htmltag($langs->trans("EnterNonEmptyLinesFirst")).'">'.dol_escape_htmltag($langs->trans("ValidTransaction")).'</a>';
1303 } elseif ($total_debit == $total_credit) {
1304 print '<a class="button" href="'.$_SERVER["PHP_SELF"].'?piece_num='.((int) $object->piece_num).(!empty($type) ? '&type=sub' : '').'&backtopage='.urlencode($backtopage).'&action=valid&token='.newToken().'">'.$langs->trans("ValidTransaction").'</a>';
1305 } else {
1306 print '<a class="button disabled cursornotallowed" disabled="disabled" href="#" title="'.dol_escape_htmltag($langs->trans("MvtNotCorrectlyBalanced", $total_debit, $total_credit)).'">'.dol_escape_htmltag($langs->trans("ValidTransaction")).'</a>';
1307 }
1308
1309 print ' &nbsp; ';
1310 print '<a class="button button-cancel" href="'.$backtopage.(!empty($type) ? '?type=sub' : '').'">'.$langs->trans("Cancel").'</a>';
1311
1312 print "</div>";
1313 }
1314 }
1315
1316 print '</form>';
1317 }
1318 } else {
1319 print $langs->trans("NoRecordFound");
1320 }
1321}
1322
1323print dol_get_fiche_end();
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
accounting_transaction_prepare_head(BookKeeping $object, $mode='', $type='', $backtopage='/accountancy/bookkeeping/listbyaccount.php')
Prepare array with list of tabs for accounting transaction.
checkGeneralAccountAllowsAuxiliary($db, $general_account, $auxiliary_account, $general_account_id=0)
Check if a general accounting account allows the use of an auxiliary account.
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
$object ref
Definition info.php:90
Class to manage accounting accounts.
Class to manage accounting journals.
Class to manage Ledger (General Ledger and Subledger)
Class BookKeepingLine.
Class for BookkeepingTemplate.
Class to manage Trips and Expenses.
Class to manage suppliers invoices.
Class to manage invoices.
Class to manage generation of HTML components for accounting management.
Class to manage generation of HTML components Only common components must be here.
Class Lettering.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
$date_start
Variables from include:
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...
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
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.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
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).
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
print_liste_field_titre($name, $file="", $field="", $begin="", $param="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
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.
Definition html.lib.php:540
dol_get_fiche_end($notab=0)
Return tab footer of a card.
Definition html.lib.php:738
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Definition html.lib.php:181
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.