Total Complexity | 156 |
Total Lines | 928 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like AccountingJournal often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use AccountingJournal, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
37 | class AccountingJournal extends CommonObject |
||
38 | { |
||
39 | /** |
||
40 | * @var string ID to identify managed object |
||
41 | */ |
||
42 | public $element = 'accounting_journal'; |
||
43 | |||
44 | /** |
||
45 | * @var string Name of table without prefix where object is stored |
||
46 | */ |
||
47 | public $table_element = 'accounting_journal'; |
||
48 | |||
49 | /** |
||
50 | * @var string Fieldname with ID of parent key if this field has a parent |
||
51 | */ |
||
52 | public $fk_element = ''; |
||
53 | |||
54 | /** |
||
55 | * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png |
||
56 | */ |
||
57 | public $picto = 'generic'; |
||
58 | |||
59 | /** |
||
60 | * @var int ID |
||
61 | */ |
||
62 | public $rowid; |
||
63 | |||
64 | /** |
||
65 | * @var string Accounting journal code |
||
66 | */ |
||
67 | public $code; |
||
68 | |||
69 | /** |
||
70 | * @var string Accounting Journal label |
||
71 | */ |
||
72 | public $label; |
||
73 | |||
74 | /** |
||
75 | * @var int 1:various operations, 2:sale, 3:purchase, 4:bank, 5:expense-report, 8:inventory, 9: has-new |
||
76 | */ |
||
77 | public $nature; |
||
78 | |||
79 | /** |
||
80 | * @var int is active or not |
||
81 | */ |
||
82 | public $active; |
||
83 | |||
84 | /** |
||
85 | * @var array Accounting account cached |
||
86 | */ |
||
87 | public static $accounting_account_cached = array(); |
||
88 | |||
89 | /** |
||
90 | * @var array Nature mapping |
||
91 | */ |
||
92 | public static $nature_maps = array( |
||
93 | 1 => 'variousoperations', |
||
94 | 2 => 'sells', |
||
95 | 3 => 'purchases', |
||
96 | 4 => 'bank', |
||
97 | 5 => 'expensereports', |
||
98 | 8 => 'inventories', |
||
99 | 9 => 'hasnew', |
||
100 | ); |
||
101 | |||
102 | /** |
||
103 | * Constructor |
||
104 | * |
||
105 | * @param DoliDB $db Database handle |
||
|
|||
106 | */ |
||
107 | public function __construct($db) |
||
108 | { |
||
109 | $this->db = $db; |
||
110 | |||
111 | $this->ismultientitymanaged = 0; |
||
112 | } |
||
113 | |||
114 | /** |
||
115 | * Load an object from database |
||
116 | * |
||
117 | * @param int $rowid Id of record to load |
||
118 | * @param string|null $journal_code Journal code |
||
119 | * @return int Return integer <0 if KO, Id of record if OK and found |
||
120 | */ |
||
121 | public function fetch($rowid = 0, $journal_code = null) |
||
122 | { |
||
123 | global $conf; |
||
124 | |||
125 | if ($rowid || $journal_code) { |
||
126 | $sql = "SELECT rowid, code, label, nature, active"; |
||
127 | $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_journal"; |
||
128 | $sql .= " WHERE"; |
||
129 | if ($rowid) { |
||
130 | $sql .= " rowid = " . ((int) $rowid); |
||
131 | } elseif ($journal_code) { |
||
132 | $sql .= " code = '" . $this->db->escape($journal_code) . "'"; |
||
133 | $sql .= " AND entity = " . $conf->entity; |
||
134 | } |
||
135 | |||
136 | dol_syslog(get_class($this) . "::fetch", LOG_DEBUG); |
||
137 | $result = $this->db->query($sql); |
||
138 | if ($result) { |
||
139 | $obj = $this->db->fetch_object($result); |
||
140 | |||
141 | if ($obj) { |
||
142 | $this->id = $obj->rowid; |
||
143 | $this->rowid = $obj->rowid; |
||
144 | |||
145 | $this->code = $obj->code; |
||
146 | $this->ref = $obj->code; |
||
147 | $this->label = $obj->label; |
||
148 | $this->nature = $obj->nature; |
||
149 | $this->active = $obj->active; |
||
150 | |||
151 | return $this->id; |
||
152 | } else { |
||
153 | return 0; |
||
154 | } |
||
155 | } else { |
||
156 | $this->error = "Error " . $this->db->lasterror(); |
||
157 | $this->errors[] = "Error " . $this->db->lasterror(); |
||
158 | } |
||
159 | } |
||
160 | return -1; |
||
161 | } |
||
162 | |||
163 | /** |
||
164 | * Return clickable name (with picto eventually) |
||
165 | * |
||
166 | * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto |
||
167 | * @param int $withlabel 0=No label, 1=Include label of journal, 2=Include nature of journal |
||
168 | * @param int $nourl 1=Disable url |
||
169 | * @param string $moretitle Add more text to title tooltip |
||
170 | * @param int $notooltip 1=Disable tooltip |
||
171 | * @return string String with URL |
||
172 | */ |
||
173 | public function getNomUrl($withpicto = 0, $withlabel = 0, $nourl = 0, $moretitle = '', $notooltip = 0) |
||
174 | { |
||
175 | global $langs, $conf, $hookmanager; |
||
176 | |||
177 | if (!empty($conf->dol_no_mouse_hover)) { |
||
178 | $notooltip = 1; // Force disable tooltips |
||
179 | } |
||
180 | |||
181 | $result = ''; |
||
182 | |||
183 | $url = constant('BASE_URL') . '/accountancy/admin/journals_list.php?id=35'; |
||
184 | |||
185 | $label = '<u>' . $langs->trans("ShowAccountingJournal") . '</u>'; |
||
186 | if (!empty($this->code)) { |
||
187 | $label .= '<br><b>' . $langs->trans('Code') . ':</b> ' . $this->code; |
||
188 | } |
||
189 | if (!empty($this->label)) { |
||
190 | $label .= '<br><b>' . $langs->trans('Label') . ':</b> ' . $langs->transnoentities($this->label); |
||
191 | } |
||
192 | if ($moretitle) { |
||
193 | $label .= ' - ' . $moretitle; |
||
194 | } |
||
195 | |||
196 | $linkclose = ''; |
||
197 | if (empty($notooltip)) { |
||
198 | if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) { |
||
199 | $label = $langs->trans("ShowAccountingJournal"); |
||
200 | $linkclose .= ' alt="' . dol_escape_htmltag($label, 1) . '"'; |
||
201 | } |
||
202 | $linkclose .= ' title="' . dol_escape_htmltag($label, 1) . '"'; |
||
203 | $linkclose .= ' class="classfortooltip"'; |
||
204 | } |
||
205 | |||
206 | $linkstart = '<a href="' . $url . '"'; |
||
207 | $linkstart .= $linkclose . '>'; |
||
208 | $linkend = '</a>'; |
||
209 | |||
210 | if ($nourl) { |
||
211 | $linkstart = ''; |
||
212 | $linkclose = ''; |
||
213 | $linkend = ''; |
||
214 | } |
||
215 | |||
216 | $label_link = $this->code; |
||
217 | if ($withlabel == 1 && !empty($this->label)) { |
||
218 | $label_link .= ' - ' . ($nourl ? '<span class="opacitymedium">' : '') . $langs->transnoentities($this->label) . ($nourl ? '</span>' : ''); |
||
219 | } |
||
220 | if ($withlabel == 2 && !empty($this->nature)) { |
||
221 | $key = $langs->trans("AccountingJournalType" . $this->nature); |
||
222 | $transferlabel = ($this->nature && $key != "AccountingJournalType" . strtoupper($langs->trans($this->nature)) ? $key : $this->label); |
||
223 | $label_link .= ' - ' . ($nourl ? '<span class="opacitymedium">' : '') . $transferlabel . ($nourl ? '</span>' : ''); |
||
224 | } |
||
225 | |||
226 | $result .= $linkstart; |
||
227 | if ($withpicto) { |
||
228 | $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="' . (($withpicto != 2) ? 'paddingright ' : '') . 'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); |
||
229 | } |
||
230 | if ($withpicto != 2) { |
||
231 | $result .= $label_link; |
||
232 | } |
||
233 | $result .= $linkend; |
||
234 | |||
235 | global $action; |
||
236 | $hookmanager->initHooks(array('accountingjournaldao')); |
||
237 | $parameters = array('id' => $this->id, 'getnomurl' => &$result); |
||
238 | $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks |
||
239 | if ($reshook > 0) { |
||
240 | $result = $hookmanager->resPrint; |
||
241 | } else { |
||
242 | $result .= $hookmanager->resPrint; |
||
243 | } |
||
244 | return $result; |
||
245 | } |
||
246 | |||
247 | /** |
||
248 | * Return the label of the status |
||
249 | * |
||
250 | * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto |
||
251 | * @return string Label of status |
||
252 | */ |
||
253 | public function getLibType($mode = 0) |
||
256 | } |
||
257 | |||
258 | // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
||
259 | /** |
||
260 | * Return type of an accounting journal |
||
261 | * |
||
262 | * @param int $nature Id type |
||
263 | * @param int $mode 0=label long, 1=label short |
||
264 | * @return string Label of type |
||
265 | */ |
||
266 | public function LibType($nature, $mode = 0) |
||
267 | { |
||
268 | // phpcs:enable |
||
269 | global $langs; |
||
270 | |||
271 | $langs->loadLangs(array("accountancy")); |
||
272 | |||
273 | if ($mode == 0) { |
||
274 | $prefix = ''; |
||
275 | if ($nature == 9) { |
||
276 | return $langs->trans('AccountingJournalType9'); |
||
277 | } elseif ($nature == 5) { |
||
278 | return $langs->trans('AccountingJournalType5'); |
||
279 | } elseif ($nature == 4) { |
||
280 | return $langs->trans('AccountingJournalType4'); |
||
281 | } elseif ($nature == 3) { |
||
282 | return $langs->trans('AccountingJournalType3'); |
||
283 | } elseif ($nature == 2) { |
||
284 | return $langs->trans('AccountingJournalType2'); |
||
285 | } elseif ($nature == 1) { |
||
286 | return $langs->trans('AccountingJournalType1'); |
||
287 | } |
||
288 | } elseif ($mode == 1) { |
||
289 | if ($nature == 9) { |
||
290 | return $langs->trans('AccountingJournalType9'); |
||
291 | } elseif ($nature == 5) { |
||
292 | return $langs->trans('AccountingJournalType5'); |
||
293 | } elseif ($nature == 4) { |
||
294 | return $langs->trans('AccountingJournalType4'); |
||
295 | } elseif ($nature == 3) { |
||
296 | return $langs->trans('AccountingJournalType3'); |
||
297 | } elseif ($nature == 2) { |
||
298 | return $langs->trans('AccountingJournalType2'); |
||
299 | } elseif ($nature == 1) { |
||
300 | return $langs->trans('AccountingJournalType1'); |
||
301 | } |
||
302 | } |
||
303 | return ""; |
||
304 | } |
||
305 | |||
306 | |||
307 | /** |
||
308 | * Get journal data |
||
309 | * |
||
310 | * @param User $user User who get infos |
||
311 | * @param string $type Type data returned ('view', 'bookkeeping', 'csv') |
||
312 | * @param int $date_start Filter 'start date' |
||
313 | * @param int $date_end Filter 'end date' |
||
314 | * @param string $in_bookkeeping Filter 'in bookkeeping' ('already', 'notyet') |
||
315 | * @return array|int Return integer <0 if KO, >0 if OK |
||
316 | */ |
||
317 | public function getData(User $user, $type = 'view', $date_start = null, $date_end = null, $in_bookkeeping = 'notyet') |
||
318 | { |
||
319 | global $hookmanager; |
||
320 | |||
321 | // Clean parameters |
||
322 | if (empty($type)) { |
||
323 | $type = 'view'; |
||
324 | } |
||
325 | if (empty($in_bookkeeping)) { |
||
326 | $in_bookkeeping = 'notyet'; |
||
327 | } |
||
328 | |||
329 | $data = array(); |
||
330 | |||
331 | $hookmanager->initHooks(array('accountingjournaldao')); |
||
332 | $parameters = array('data' => &$data, 'user' => $user, 'type' => $type, 'date_start' => $date_start, 'date_end' => $date_end, 'in_bookkeeping' => $in_bookkeeping); |
||
333 | $reshook = $hookmanager->executeHooks('getData', $parameters, $this); // Note that $action and $object may have been |
||
334 | if ($reshook < 0) { |
||
335 | $this->error = $hookmanager->error; |
||
336 | $this->errors = $hookmanager->errors; |
||
337 | return -1; |
||
338 | } elseif (empty($reshook)) { |
||
339 | switch ($this->nature) { |
||
340 | case 1: // Various Journal |
||
341 | $data = $this->getAssetData($user, $type, $date_start, $date_end, $in_bookkeeping); |
||
342 | break; |
||
343 | // case 2: // Sells Journal |
||
344 | // case 3: // Purchases Journal |
||
345 | // case 4: // Bank Journal |
||
346 | // case 5: // Expense reports Journal |
||
347 | // case 8: // Inventory Journal |
||
348 | // case 9: // hasnew Journal |
||
349 | } |
||
350 | } |
||
351 | |||
352 | return $data; |
||
353 | } |
||
354 | |||
355 | /** |
||
356 | * Get asset data for various journal |
||
357 | * |
||
358 | * @param User $user User who get infos |
||
359 | * @param string $type Type data returned ('view', 'bookkeeping', 'csv') |
||
360 | * @param int $date_start Filter 'start date' |
||
361 | * @param int $date_end Filter 'end date' |
||
362 | * @param string $in_bookkeeping Filter 'in bookkeeping' ('already', 'notyet') |
||
363 | * @return array|int Return integer <0 if KO, >0 if OK |
||
364 | */ |
||
365 | public function getAssetData(User $user, $type = 'view', $date_start = null, $date_end = null, $in_bookkeeping = 'notyet') |
||
676 | } |
||
677 | |||
678 | /** |
||
679 | * Write bookkeeping |
||
680 | * |
||
681 | * @param User $user User who write in the bookkeeping |
||
682 | * @param array $journal_data Journal data to write in the bookkeeping |
||
683 | * $journal_data = array( |
||
684 | * id_element => array( |
||
685 | * 'ref' => 'ref', |
||
686 | * 'error' => '', |
||
687 | * 'blocks' => array( |
||
688 | * pos_block => array( |
||
689 | * num_line => array( |
||
690 | * 'doc_date' => '', |
||
691 | * 'date_lim_reglement' => '', |
||
692 | * 'doc_ref' => '', |
||
693 | * 'date_creation' => '', |
||
694 | * 'doc_type' => '', |
||
695 | * 'fk_doc' => '', |
||
696 | * 'fk_docdet' => '', |
||
697 | * 'thirdparty_code' => '', |
||
698 | * 'subledger_account' => '', |
||
699 | * 'subledger_label' => '', |
||
700 | * 'numero_compte' => '', |
||
701 | * 'label_compte' => '', |
||
702 | * 'label_operation' => '', |
||
703 | * 'montant' => '', |
||
704 | * 'sens' => '', |
||
705 | * 'debit' => '', |
||
706 | * 'credit' => '', |
||
707 | * 'code_journal' => '', |
||
708 | * 'journal_label' => '', |
||
709 | * 'piece_num' => '', |
||
710 | * 'import_key' => '', |
||
711 | * 'fk_user_author' => '', |
||
712 | * 'entity' => '', |
||
713 | * ), |
||
714 | * ), |
||
715 | * ), |
||
716 | * ), |
||
717 | * ); |
||
718 | * @param int $max_nb_errors Nb error authorized before stop the process |
||
719 | * @return int Return integer <0 if KO, >0 if OK |
||
720 | */ |
||
721 | public function writeIntoBookkeeping(User $user, &$journal_data = array(), $max_nb_errors = 10) |
||
722 | { |
||
723 | global $conf, $langs, $hookmanager; |
||
724 | |||
725 | $error = 0; |
||
726 | |||
727 | $hookmanager->initHooks(array('accountingjournaldao')); |
||
728 | $parameters = array('journal_data' => &$journal_data); |
||
729 | $reshook = $hookmanager->executeHooks('writeBookkeeping', $parameters, $this); // Note that $action and $object may have been |
||
730 | if ($reshook < 0) { |
||
731 | $this->error = $hookmanager->error; |
||
732 | $this->errors = $hookmanager->errors; |
||
733 | return -1; |
||
734 | } elseif (empty($reshook)) { |
||
735 | // Clean parameters |
||
736 | $journal_data = is_array($journal_data) ? $journal_data : array(); |
||
737 | |||
738 | foreach ($journal_data as $element_id => $element) { |
||
739 | $error_for_line = 0; |
||
740 | $total_credit = 0; |
||
741 | $total_debit = 0; |
||
742 | |||
743 | $this->db->begin(); |
||
744 | |||
745 | if ($element['error'] == 'somelinesarenotbound') { |
||
746 | $error++; |
||
747 | $error_for_line++; |
||
748 | $this->errors[] = $langs->trans('ErrorInvoiceContainsLinesNotYetBounded', $element['ref']); |
||
749 | } |
||
750 | |||
751 | if (!$error_for_line) { |
||
752 | foreach ($element['blocks'] as $lines) { |
||
753 | foreach ($lines as $line) { |
||
754 | $bookkeeping = new BookKeeping($this->db); |
||
755 | $bookkeeping->doc_date = $line['doc_date']; |
||
756 | $bookkeeping->date_lim_reglement = $line['date_lim_reglement']; |
||
757 | $bookkeeping->doc_ref = $line['doc_ref']; |
||
758 | $bookkeeping->date_creation = $line['date_creation']; // not used |
||
759 | $bookkeeping->doc_type = $line['doc_type']; |
||
760 | $bookkeeping->fk_doc = $line['fk_doc']; |
||
761 | $bookkeeping->fk_docdet = $line['fk_docdet']; |
||
762 | $bookkeeping->thirdparty_code = $line['thirdparty_code']; |
||
763 | $bookkeeping->subledger_account = $line['subledger_account']; |
||
764 | $bookkeeping->subledger_label = $line['subledger_label']; |
||
765 | $bookkeeping->numero_compte = $line['numero_compte']; |
||
766 | $bookkeeping->label_compte = $line['label_compte']; |
||
767 | $bookkeeping->label_operation = $line['label_operation']; |
||
768 | $bookkeeping->montant = $line['montant']; |
||
769 | $bookkeeping->sens = $line['sens']; |
||
770 | $bookkeeping->debit = $line['debit']; |
||
771 | $bookkeeping->credit = $line['credit']; |
||
772 | $bookkeeping->code_journal = $line['code_journal']; |
||
773 | $bookkeeping->journal_label = $line['journal_label']; |
||
774 | $bookkeeping->piece_num = $line['piece_num']; |
||
775 | $bookkeeping->import_key = $line['import_key']; |
||
776 | $bookkeeping->fk_user_author = $user->id; |
||
777 | $bookkeeping->entity = $conf->entity; |
||
778 | |||
779 | $total_debit += $bookkeeping->debit; |
||
780 | $total_credit += $bookkeeping->credit; |
||
781 | |||
782 | $result = $bookkeeping->create($user); |
||
783 | if ($result < 0) { |
||
784 | if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists |
||
785 | $error++; |
||
786 | $error_for_line++; |
||
787 | $journal_data[$element_id]['error'] = 'alreadyjournalized'; |
||
788 | } else { |
||
789 | $error++; |
||
790 | $error_for_line++; |
||
791 | $journal_data[$element_id]['error'] = 'other'; |
||
792 | $this->errors[] = $bookkeeping->errorsToString(); |
||
793 | } |
||
794 | } |
||
795 | // |
||
796 | // if (!$error_for_line && isModEnabled('asset') && $this->nature == 1 && $bookkeeping->fk_doc > 0) { |
||
797 | // // Set last cumulative depreciation |
||
798 | // require_once constant('DOL_DOCUMENT_ROOT') . '/asset/class/asset.class.php'; |
||
799 | // $asset = new Asset($this->db); |
||
800 | // $result = $asset->setLastCumulativeDepreciation($bookkeeping->fk_doc); |
||
801 | // if ($result < 0) { |
||
802 | // $error++; |
||
803 | // $error_for_line++; |
||
804 | // $journal_data[$element_id]['error'] = 'other'; |
||
805 | // $this->errors[] = $asset->errorsToString(); |
||
806 | // } |
||
807 | // } |
||
808 | } |
||
809 | |||
810 | if ($error_for_line) { |
||
811 | break; |
||
812 | } |
||
813 | } |
||
814 | } |
||
815 | |||
816 | // Protection against a bug on lines before |
||
817 | if (!$error_for_line && (price2num($total_debit, 'MT') != price2num($total_credit, 'MT'))) { |
||
818 | $error++; |
||
819 | $error_for_line++; |
||
820 | $journal_data[$element_id]['error'] = 'amountsnotbalanced'; |
||
821 | $this->errors[] = 'Try to insert a non balanced transaction in book for ' . $element['blocks'] . '. Canceled. Surely a bug.'; |
||
822 | } |
||
823 | |||
824 | if (!$error_for_line) { |
||
825 | $this->db->commit(); |
||
826 | } else { |
||
827 | $this->db->rollback(); |
||
828 | |||
829 | if ($error >= $max_nb_errors) { |
||
830 | $this->errors[] = $langs->trans("ErrorTooManyErrorsProcessStopped"); |
||
831 | break; // Break in the foreach |
||
832 | } |
||
833 | } |
||
834 | } |
||
835 | } |
||
836 | |||
837 | return $error ? -$error : 1; |
||
838 | } |
||
839 | |||
840 | /** |
||
841 | * Export journal CSV |
||
842 | * ISO and not UTF8 ! |
||
843 | * |
||
844 | * @param array $journal_data Journal data to write in the bookkeeping |
||
845 | * $journal_data = array( |
||
846 | * id_element => array( |
||
847 | * 'continue' => false, |
||
848 | * 'blocks' => array( |
||
849 | * pos_block => array( |
||
850 | * num_line => array( |
||
851 | * data to write in the CSV line |
||
852 | * ), |
||
853 | * ), |
||
854 | * ), |
||
855 | * ), |
||
856 | * ); |
||
857 | * @param int $search_date_end Search date end |
||
858 | * @param string $sep CSV separator |
||
859 | * @return int|string Return integer <0 if KO, >0 if OK |
||
860 | */ |
||
861 | public function exportCsv(&$journal_data = array(), $search_date_end = 0, $sep = '') |
||
931 | } |
||
932 | |||
933 | /** |
||
934 | * Get accounting account infos |
||
935 | * |
||
936 | * @param string $account Accounting account number |
||
937 | * @return array Accounting account infos |
||
938 | */ |
||
939 | public function getAccountingAccountInfos($account) |
||
967 |