| Total Complexity | 90 |
| Total Lines | 465 |
| Duplicated Lines | 0 % |
| Changes | 1 | ||
| Bugs | 0 | Features | 0 |
Complex classes like PlantillaDOM 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 PlantillaDOM, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 31 | class PlantillaDOM extends BaseTemplate |
||
| 32 | { |
||
| 33 | |||
| 34 | public function addInvoiceFooter($model) |
||
| 35 | { |
||
| 36 | $i18n = Tools::lang(); |
||
| 37 | |||
| 38 | } |
||
| 39 | |||
| 40 | public function addInvoiceHeader($model) |
||
| 41 | { |
||
| 42 | // TODO: Implement addInvoiceHeader() method. |
||
| 43 | $html = $this->getInvoiceHeaderBilling($model) |
||
| 44 | . $this->getInvoiceHeaderShipping($model); |
||
| 45 | $this->writeHTML('<table class="table-big table-border"><tr>' . $html . '</tr></table><br/>'); |
||
| 46 | } |
||
| 47 | |||
| 48 | public function addInvoiceLines($model) |
||
| 49 | { |
||
| 50 | $lines = $model->getLines(); |
||
| 51 | $this->autoHideLineColumns($lines); |
||
| 52 | |||
| 53 | $tHead = '<thead><tr>'; |
||
| 54 | foreach ($this->getInvoiceLineFields() as $field) { |
||
| 55 | $tHead .= '<th class="' . $field['css'] . '" align="' . $field['align'] . '">' . $field['title'] . '</th>'; |
||
| 56 | } |
||
| 57 | $tHead .= '</tr></thead>'; |
||
| 58 | |||
| 59 | $tBody = ''; |
||
| 60 | $numLinea = 1; |
||
| 61 | $tLines = []; |
||
| 62 | foreach ($lines as $line) { |
||
| 63 | $tLines[] = $line; |
||
| 64 | $line->numlinea = $numLinea; |
||
| 65 | $tBody .= '<tr>'; |
||
| 66 | foreach ($this->getInvoiceLineFields() as $field) { |
||
| 67 | $tBody .= '<td class="' . $field['css'] . '" align="' . $field['align'] . '" valign="top">' . $this->getInvoiceLineValue($model, $line, $field) . '</td>'; |
||
| 68 | } |
||
| 69 | $tBody .= '</tr>'; |
||
| 70 | $numLinea++; |
||
| 71 | |||
| 72 | if (property_exists($line, 'salto_pagina') && $line->salto_pagina) { |
||
| 73 | $this->writeHTML('<div class="table-lines"><table class="table-big table-list">' . $tHead . $tBody . '</table></div>'); |
||
| 74 | $this->writeHTML($this->getInvoiceTotalsPartial($model, $tLines, 'mt-20')); |
||
| 75 | $this->mpdf->AddPage(); |
||
| 76 | $tBody = ''; |
||
| 77 | } |
||
| 78 | } |
||
| 79 | |||
| 80 | $this->writeHTML('<div class="table-lines"><table class="table-big table-list">' . $tHead . $tBody . '</table></div>'); |
||
| 81 | |||
| 82 | // clonamos el documento y añadimos los totales para ver si salta de página |
||
| 83 | $copier = new DeepCopy(); |
||
| 84 | $clonedPdf = $copier->copy($this->mpdf); |
||
| 85 | $clonedPdf->writeHTML($this->getInvoiceTotalsFinal($model, 'mt-20')); |
||
| 86 | |||
| 87 | // comprobamos si clonedPdf tiene más páginas que el original |
||
| 88 | if (count($clonedPdf->pages) > count($this->mpdf->pages)) { |
||
| 89 | $this->mpdf->AddPage(); |
||
| 90 | } |
||
| 91 | |||
| 92 | // si tiene las mismas páginas, añadimos los totales |
||
| 93 | $this->writeHTML($this->getInvoiceTotalsFinal($model, 'mt-20')); |
||
| 94 | } |
||
| 95 | |||
| 96 | protected function css(): string |
||
| 97 | { |
||
| 98 | return parent::css() |
||
| 99 | . '.title {border-bottom: 2px solid ' . $this->get('color1') . ';}' |
||
| 100 | . '.table-border {border-top: 1px solid ' . $this->get('color1') . '; border-bottom: 1px solid ' . $this->get('color1') . ';}' |
||
| 101 | . '.table-dual {border-top: 1px solid ' . $this->get('color1') . '; border-bottom: 1px solid ' . $this->get('color1') . ';}' |
||
| 102 | . '.table-list {border-spacing: 0px; border-top: 1px solid ' . $this->get('color1') . '; border-bottom: 1px solid ' . $this->get('color1') . ';}' |
||
| 103 | . '.table-list tr:nth-child(even) {background-color: ' . $this->get('color3') . ';}' |
||
| 104 | . '.table-list th {background-color: ' . $this->get('color1') . '; color: ' . $this->get('color2') . '; padding: 5px; text-transform: uppercase;}' |
||
| 105 | . '.table-list td {padding: 5px;}' |
||
| 106 | . '.thanks-title {' |
||
| 107 | . 'font-size: ' . $this->get('titlefontsize') . 'px; font-weight: bold; color: ' . $this->get('color1') . '; ' |
||
| 108 | . 'text-align: right; width: 50%; padding: 15px; border-right: 1px solid ' . $this->get('color1') . ';' |
||
| 109 | . '}' |
||
| 110 | . '.color-navy {color: navy;}' |
||
| 111 | . '.color-blue {color: blue;}' |
||
| 112 | . '.color-template {color: ' . $this->get('color1') .';}' |
||
| 113 | . '.thanks-text {padding: 15px;}' |
||
| 114 | . '.imagetext {margin-top: 15px; text-align: ' . $this->get('endalign') . ';}' |
||
| 115 | . '.imagefooter {text-align: ' . $this->get('footeralign') . ';}'; |
||
| 116 | } |
||
| 117 | |||
| 118 | protected function getSubjectIdFiscalStr(BusinessDocument $model): string |
||
| 119 | { |
||
| 120 | return empty($model->cifnif) ? '' : '<b>' . $model->getSubject()->tipoidfiscal . '</b>: ' . $model->cifnif; |
||
| 121 | } |
||
| 122 | |||
| 123 | protected function getInvoiceHeaderBilling($model): string |
||
| 124 | { |
||
| 125 | if ($this->format->hidebillingaddress) { |
||
| 126 | return ''; |
||
| 127 | } |
||
| 128 | |||
| 129 | $subject = $model->getSubject(); |
||
| 130 | $address = isset($model->codproveedor) && !isset($model->direccion) ? $subject->getDefaultAddress() : $model; |
||
| 131 | $customerCode = $this->get('showcustomercode') ? $model->subjectColumnValue() : ''; |
||
| 132 | $customerEmail = $this->get('showcustomeremail') && !empty($subject->email) ? '<br>' . Tools::lang()->trans('email') . ': ' . $subject->email : ''; |
||
| 133 | $break = empty($model->cifnif) ? '' : '<br/>'; |
||
| 134 | return '<td align="left" valign="top">' |
||
| 135 | . '<br/><b> ' . $this->getSubjectTitle($model) . ':</b> ' . $customerCode |
||
| 136 | . $this->getSubjectName($model) . $break . $this->getSubjectIdFiscalStr($model) |
||
| 137 | . '<br/><b>' . Tools::lang()->trans('address'). ':</b> ' .$this->combineAddress($address) . $this->getInvoiceHeaderBillingPhones($subject) |
||
| 138 | . '<br/><b>' . Tools::lang()->trans('email'). ':</b> ' .$customerEmail |
||
| 139 | . '<br/>' |
||
| 140 | . '</td>'; |
||
| 141 | } |
||
| 142 | |||
| 143 | protected function getInvoiceHeaderShipping($model): string |
||
| 160 | } |
||
| 161 | |||
| 162 | protected function getInvoiceHeaderBillingPhones($subject): string |
||
| 163 | { |
||
| 164 | if (true !== $this->get('showcustomerphones')) { |
||
| 165 | return ''; |
||
| 166 | } |
||
| 167 | |||
| 168 | $strPhones = $this->getPhones($subject->telefono1, $subject->telefono2); |
||
| 169 | if (empty($strPhones)) { |
||
| 170 | return ''; |
||
| 171 | } |
||
| 172 | |||
| 173 | return '<br/>' . $strPhones; |
||
| 174 | } |
||
| 175 | |||
| 176 | protected function headerLeft(): string |
||
| 177 | { |
||
| 178 | $i18n = Tools::lang(); |
||
| 179 | $contactData = []; |
||
| 180 | foreach (['telefono1', 'telefono2', 'email', 'web'] as $field) { |
||
| 181 | if ($this->empresa->{$field}) { |
||
| 182 | $contactData[] = $this->empresa->{$field}; |
||
| 183 | } |
||
| 184 | } |
||
| 185 | |||
| 186 | $title = $this->showHeaderTitle ? '<h1 class="title">' . $this->get('headertitle') . '</h1>' . $this->spacer() : ''; |
||
| 187 | if ($this->isSketchInvoice()) { |
||
| 188 | $title .= '<div class="color-red font-big font-bold">' . Tools::lang()->trans('invoice-is-sketch') . '</div>'; |
||
| 189 | } |
||
| 190 | |||
| 191 | $descTC = ($this->headerModel->tipocomprobante < 30) ? "<b>NCF:</b> " : "<b>e-NCF:</b> "; |
||
| 192 | $fechaVencimiento = ($this->headerModel->ncffechavencimiento !== null) ? '<b>Fecha Vencimiento:</b> ' . $this->headerModel->ncffechavencimiento : ''; |
||
| 193 | $fechaEmision = '<b>Fecha Emisión:</b> ' . $this->headerModel->fecha; |
||
| 194 | |||
| 195 | return '<table class="table-big">' |
||
| 196 | . '<tr>' |
||
| 197 | . '<td valign="top"><img src="' . $this->logoPath . '" height="' . $this->get('logosize') . '"/>' . '</td>' |
||
| 198 | . '<td align="right" valign="top">' . $title . '</td>' |
||
| 199 | . '</tr>' |
||
| 200 | . '<tr>' |
||
| 201 | . '<td align="left" valign="top">' |
||
| 202 | . '<p><b>' . $this->empresa->nombre . '</b>' |
||
| 203 | . '<br/>' . $this->empresa->tipoidfiscal . ': ' . $this->empresa->cifnif |
||
| 204 | . '<br/>' . Tools::lang()->trans('address') . ': ' . $this->combineAddress($this->empresa) . '</p>' |
||
| 205 | . '<p>' . implode(' · ', $contactData) . '</p>' |
||
| 206 | . $fechaEmision |
||
| 207 | . '</td>' |
||
| 208 | . '<td align="right" valign="top">' |
||
| 209 | . '<div class="color-template font-big font-bold">' . $this->headerModel->descripcionTipoComprobante() . '</div>' |
||
| 210 | . $descTC |
||
| 211 | . $this->headerModel->numeroncf . '<br/>' |
||
| 212 | . $fechaVencimiento . '<br/>' |
||
| 213 | . '<b>' . $i18n->trans('payment-method') . ':</b> ' |
||
| 214 | . PaymentMethodBankDataHelper::get($this->headerModel) |
||
| 215 | . '</td>' |
||
| 216 | . '</tr>' |
||
| 217 | . '</table>'; |
||
| 218 | } |
||
| 219 | protected function headerRight(): string |
||
| 220 | { |
||
| 221 | $contactData = []; |
||
| 222 | foreach (['telefono1', 'telefono2', 'email', 'web'] as $field) { |
||
| 223 | if ($this->empresa->{$field}) { |
||
| 224 | $contactData[] = $this->empresa->{$field}; |
||
| 225 | } |
||
| 226 | } |
||
| 227 | |||
| 228 | $title = $this->showHeaderTitle ? '<h1 class="title">' . $this->get('headertitle') . '</h1>' . $this->spacer() : ''; |
||
| 229 | if ($this->isSketchInvoice()) { |
||
| 230 | $title .= '<div class="color-red font-big font-bold">' . Tools::lang()->trans('invoice-is-sketch') . '</div>'; |
||
| 231 | } |
||
| 232 | |||
| 233 | return '<table class="table-big">' |
||
| 234 | . '<tr>' |
||
| 235 | . '<td> Titulo ' . $title |
||
| 236 | . '<p><b>' . $this->empresa->nombre . '</b>' |
||
| 237 | . '<br/>' . $this->empresa->tipoidfiscal . ': ' . $this->empresa->cifnif |
||
| 238 | . '<br/>' . $this->combineAddress($this->empresa) . '</p>' . $this->spacer() |
||
| 239 | . '<p>' . implode(' · ', $contactData) . '</p>' |
||
| 240 | . '</td>' |
||
| 241 | . '<td align="right"><img src="' . $this->logoPath . '" height="' . $this->get('logosize') . '"/></td>' |
||
| 242 | . '</tr>' |
||
| 243 | . '</table>'; |
||
| 244 | } |
||
| 245 | |||
| 246 | protected function getInvoiceTotalsFinal($model, $css = ''): string |
||
| 257 | } |
||
| 258 | |||
| 259 | protected function getInvoiceTotalsPartial($model, array $lines = [], string $css = ''): string |
||
| 260 | { |
||
| 261 | if ($this->format->hidetotals) { |
||
| 262 | return ''; |
||
| 263 | } |
||
| 264 | |||
| 265 | $i18n = Tools::lang(); |
||
| 266 | $trs = ''; |
||
| 267 | $fields = [ |
||
| 268 | 'netosindto' => $i18n->trans('subtotal'), |
||
| 269 | 'dtopor1' => $i18n->trans('global-dto'), |
||
| 270 | 'dtopor2' => $i18n->trans('global-dto-2'), |
||
| 271 | 'neto' => $i18n->trans('net'), |
||
| 272 | 'totaliva' => $i18n->trans('taxes'), |
||
| 273 | 'totalrecargo' => $i18n->trans('re'), |
||
| 274 | 'totalirpf' => $i18n->trans('retention'), |
||
| 275 | 'totalsuplidos' => $i18n->trans('supplied-amount'), |
||
| 276 | 'total' => $i18n->trans('total'), |
||
| 277 | ]; |
||
| 278 | |||
| 279 | $lines = empty($lines) ? $model->getLines() : $lines; |
||
| 280 | $this->getTotalsModel($model, $lines); |
||
| 281 | $taxes = $this->getTaxesRows($model, $lines); |
||
| 282 | $irpfs = $this->format->hide_breakdowns ? [] : $this->getIrpfs($model, $lines); |
||
| 283 | |||
| 284 | // pintamos los irpfs |
||
| 285 | foreach ($irpfs as $irpf) { |
||
| 286 | $trs .= '<tr>' |
||
| 287 | . '<td align="right"><b>' . $irpf['name'] . '</b>:</td>' |
||
| 288 | . '<td class="nowrap" align="right">' . Tools::money($irpf['total'], $model->coddivisa) . '</td>' |
||
| 289 | . '</tr>'; |
||
| 290 | } |
||
| 291 | |||
| 292 | // ocultamos el neto si no hay impuestos o si hay un impuesto y el neto es igual al neto sin dto |
||
| 293 | if (empty($taxes['iva']) || (count($taxes['iva']) == 1 && $model->neto == $model->netosindto)) { |
||
| 294 | unset($fields['neto']); |
||
| 295 | unset($fields['totaliva']); |
||
| 296 | } |
||
| 297 | |||
| 298 | // si tenemos marcada la opción de ocultar desgloses, eliminamos todos los campos excepto el total |
||
| 299 | if ($this->format->hide_breakdowns) { |
||
| 300 | $fields = ['total' => $i18n->trans('total')]; |
||
| 301 | } |
||
| 302 | |||
| 303 | foreach ($fields as $key => $title) { |
||
| 304 | if (empty($model->{$key}) || $key === 'totalirpf') { |
||
| 305 | continue; |
||
| 306 | } |
||
| 307 | |||
| 308 | switch ($key) { |
||
| 309 | case 'dtopor1': |
||
| 310 | case 'dtopor2': |
||
| 311 | $trs .= '<tr>' |
||
| 312 | . '<td align="right"><b>' . $title . '</b>:</td>' |
||
| 313 | . '<td class="nowrap" align="right">' . Tools::number($model->{$key}) . '%</td>' |
||
| 314 | . '</tr>'; |
||
| 315 | break; |
||
| 316 | |||
| 317 | case 'total': |
||
| 318 | $trs .= '<tr>' |
||
| 319 | . '<td class="text-right"><b>' . $title . '</b>:</td>' |
||
| 320 | . '<td class="text-right nowrap">' . Tools::money($model->{$key}, $model->coddivisa) . '</td>' |
||
| 321 | . '</tr>'; |
||
| 322 | break; |
||
| 323 | |||
| 324 | case 'netosindto': |
||
| 325 | if ($model->netosindto == $model->neto) { |
||
| 326 | break; |
||
| 327 | } |
||
| 328 | // no break |
||
| 329 | default: |
||
| 330 | $trs .= '<tr>' |
||
| 331 | . '<td align="right"><b>' . $title . '</b>:</td>' |
||
| 332 | . '<td class="nowrap" align="right">' . Tools::money($model->{$key}, $model->coddivisa) . '</td>' |
||
| 333 | . '</tr>'; |
||
| 334 | break; |
||
| 335 | } |
||
| 336 | } |
||
| 337 | |||
| 338 | return '<table class="table-big table-border ' . $css . '">' |
||
| 339 | . '<tr>' |
||
| 340 | . '<td> ' . $this->getInvoiceTaxes($model, $lines) . '</td>' |
||
| 341 | . '<td align="right" valign="top"><table>' . $trs . '</table></td>' |
||
| 342 | . '</tr>' |
||
| 343 | . '<tr>' |
||
| 344 | . '<td>' |
||
| 345 | . '</td>' |
||
| 346 | . '</tr>' |
||
| 347 | . '</table>' |
||
| 348 | . ' <b>Son:</b> ' . $this->convert_to_words($model->total) . ' pesos dominicanos' |
||
| 349 | . '<br/>'; |
||
| 350 | } |
||
| 351 | |||
| 352 | protected function getInvoiceTaxes(BusinessDocument $model, array $lines, string $class = 'table-big'): string |
||
| 353 | { |
||
| 354 | if ($this->format->hide_vat_breakdown) { |
||
| 355 | return ''; |
||
| 356 | } |
||
| 357 | |||
| 358 | $taxes = $this->getTaxesRows($model, $lines); |
||
| 359 | if (empty($taxes['iva']) && empty($model->totalirpf)) { |
||
| 360 | return ''; |
||
| 361 | } |
||
| 362 | |||
| 363 | $i18n = Tools::lang(); |
||
| 364 | |||
| 365 | $trs = ''; |
||
| 366 | foreach ($taxes['iva'] as $row) { |
||
| 367 | $trs .= '<tr>' |
||
| 368 | . '<td class="nowrap" align="left">' . Impuestos::get($row['codimpuesto'])->descripcion . '</td>' |
||
| 369 | . '<td class="nowrap" align="center">' . Tools::money($row['neto'], $model->coddivisa) . '</td>' |
||
| 370 | . '<td class="nowrap" align="center">' . Tools::number($row['iva']) . '%</td>' |
||
| 371 | . '<td class="nowrap" align="center">' . Tools::money($row['totaliva'], $model->coddivisa) . '</td>'; |
||
| 372 | |||
| 373 | if (empty($model->totalrecargo)) { |
||
| 374 | $trs .= '</tr>'; |
||
| 375 | continue; |
||
| 376 | } |
||
| 377 | |||
| 378 | $trs .= '<td class="nowrap" align="center">' . (empty($row['recargo']) ? '-' : Tools::number($row['recargo']) . '%') . '</td>' |
||
| 379 | . '<td class="nowrap" align="right">' . (empty($row['totalrecargo']) ? '-' : Tools::money($row['totalrecargo'])) . '</td>' |
||
| 380 | . '</tr>'; |
||
| 381 | } |
||
| 382 | |||
| 383 | if (empty($model->totalrecargo)) { |
||
| 384 | return '<table class="' . $class . '">' |
||
| 385 | . '<thead>' |
||
| 386 | . '<tr>' |
||
| 387 | . '<th align="left">' . $i18n->trans('tax') . '</th>' |
||
| 388 | . '<th align="center">' . $i18n->trans('tax-base') . '</th>' |
||
| 389 | . '<th align="center">' . $i18n->trans('percentage') . '</th>' |
||
| 390 | . '<th align="center">' . $i18n->trans('amount') . '</th>' |
||
| 391 | . '</tr>' |
||
| 392 | . '</thead>' |
||
| 393 | . $trs |
||
| 394 | . '</table>'; |
||
| 395 | } |
||
| 396 | |||
| 397 | return '<table class="' . $class . '">' |
||
| 398 | . '<tr>' |
||
| 399 | . '<th align="left">' . $i18n->trans('tax') . '</th>' |
||
| 400 | . '<th align="center">' . $i18n->trans('tax-base') . '</th>' |
||
| 401 | . '<th align="center">' . $i18n->trans('tax') . '</th>' |
||
| 402 | . '<th align="center">' . $i18n->trans('amount') . '</th>' |
||
| 403 | . '<th align="center">' . $i18n->trans('re') . '</th>' |
||
| 404 | . '<th align="right">' . $i18n->trans('amount') . '</th>' |
||
| 405 | . '</tr>' |
||
| 406 | . $trs |
||
| 407 | . '</table>'; |
||
| 408 | } |
||
| 409 | |||
| 410 | private function convert_to_words($number): ?string |
||
| 496 | } |
||
| 497 | } |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths