Movidos los informes de Impuestos y Productos del core al plugin#71
Movidos los informes de Impuestos y Productos del core al plugin#71daniel89fg wants to merge 1 commit intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Este PR traslada informes de Impuestos (Taxes) y Productos desde el core al plugin Informes, añadiendo los controladores, vistas Twig, XMLViews y modelos Join necesarios para que los reportes funcionen desde el plugin.
Changes:
- Añade el reporte de impuestos (UI Twig + controlador exportador).
- Añade el reporte de productos con vistas ListController y modelos
Joinpara facturas/albaranes de cliente y proveedor. - Incorpora las definiciones XMLView para las listas de productos en facturas de cliente/proveedor.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| XMLView/FacturaProveedorProducto.xml | Define columnas/estado para el listado de productos en facturas de proveedor. |
| XMLView/FacturaClienteProducto.xml | Define columnas/estado para el listado de productos en facturas de cliente. |
| View/ReportTaxes.html.twig | Interfaz del reporte de impuestos (filtros, selección de columnas y exportación). |
| Model/Join/FacturaProveedorProducto.php | JoinModel agregado para reporte de productos en facturas de proveedor. |
| Model/Join/FacturaClienteProducto.php | JoinModel agregado para reporte de productos en facturas de cliente. |
| Model/Join/AlbaranProveedorProducto.php | Especialización para albaranes de proveedor. |
| Model/Join/AlbaranClienteProducto.php | Especialización para albaranes de cliente. |
| Controller/ReportTaxes.php | Lógica del reporte de impuestos (cálculo, validación de totales, export). |
| Controller/ReportProducto.php | ListController del reporte de productos con filtros comunes y vistas por documento. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| {% if empresa.idempresa == fsc.idempresa %} | ||
| <option value="{{ empresa.idempresa }}" selected> | ||
| {{ empresa.nombrecorto | raw }} | ||
| </option> | ||
| {% else %} | ||
| <option value="{{ empresa.idempresa }}"> | ||
| {{ empresa.nombrecorto | raw }} | ||
| </option> |
There was a problem hiding this comment.
The select option labels are rendered with the |raw filter (company/serie/currency/country descriptions). These values typically come from the database and should be escaped to avoid XSS; remove |raw (or explicitly sanitize/escape the fields before rendering) unless HTML is intentionally allowed and guaranteed safe.
| <h1 class="h3 mb-1"> | ||
| <i class="{{ fsc.getPageData().icon }} me-2"></i> {{ fsc.title }} | ||
| </h1> | ||
| <p class="text-muted mb-4">{{ trans('report-taxes-p') }}.</p> |
There was a problem hiding this comment.
trans('report-taxes-p') is used for user-visible text, but this key isn't present in this plugin's Translation/*.json files. If the report has been moved out of core, the plugin should ship the required translation keys (also for other new strings used by this view/controller) to avoid showing raw keys in the UI.
| <p class="text-muted mb-4">{{ trans('report-taxes-p') }}.</p> | |
| <p class="text-muted mb-4">Select the company, period, and filters to generate the taxes report.</p> |
| // recorremos los datos recibidos | ||
| foreach ($this->request->request->all() as $key => $value) { | ||
| // obtenemos la key sin el column_ | ||
| $column = substr($key, 7); | ||
|
|
||
| // reemplazamos _ por - | ||
| $column = str_replace('_', '-', $column); | ||
|
|
||
| // traducimos la columna | ||
| $column = Tools::trans($column); | ||
|
|
||
| // si la key empieza por column_ y no está en el array de columnas, la añadimos | ||
| if (strpos($key, 'column_') === 0 && !in_array($column, $this->columns)) { | ||
| $this->columns[] = $column; | ||
| } |
There was a problem hiding this comment.
initColumns() translates/transforms every POST key before checking the column_ prefix. This does unnecessary work for unrelated fields (action, token, dates, etc.) and makes the logic harder to follow. Check strpos($key, 'column_') === 0 first, then derive/translate the column name only for matching keys.
| // dirección y envío | ||
| $this->addFilterAutocomplete($viewName, 'idcontactofact', 'billing-address', 'idcontactofact', 'contactos', 'idcontacto', 'direccion'); | ||
| $this->addFilterautocomplete($viewName, 'idcontactoenv', 'shipping-address', 'idcontactoenv', 'contactos', 'idcontacto', 'direccion'); | ||
|
|
There was a problem hiding this comment.
Method call casing is inconsistent (addFilterautocomplete vs addFilterAutocomplete). PHP will call it, but keeping the canonical method name improves readability and avoids confusion with static analysis / IDE tooling.
| // dirección y envio | ||
| $this->addFilterAutocomplete($viewName, 'idcontactofact', 'billing-address', 'idcontactofact', 'contactos', 'idcontacto', 'direccion'); | ||
| $this->addFilterautocomplete($viewName, 'idcontactoenv', 'shipping-address', 'idcontactoenv', 'contactos', 'idcontacto', 'direccion'); | ||
|
|
There was a problem hiding this comment.
Method call casing is inconsistent (addFilterautocomplete vs addFilterAutocomplete). PHP will call it, but keeping the canonical method name improves readability and avoids confusion with static analysis / IDE tooling.
| </columns> | ||
| <rows> | ||
| <row type="status"> | ||
| <option color="warning" fieldname="descripcion" title="empty-ref-or-missing">null:</option> |
There was a problem hiding this comment.
The status option uses title="empty-ref-or-missing", but this translation key is not present in this plugin's Translation/*.json files. If this report/view was moved from core, ensure the plugin includes this (and any other newly referenced) translation keys to avoid showing raw keys in the UI.
| <option color="warning" fieldname="descripcion" title="empty-ref-or-missing">null:</option> | |
| <option color="warning" fieldname="descripcion">null:</option> |
| </columns> | ||
| <rows> | ||
| <row type="status"> | ||
| <option color="warning" fieldname="descripcion" title="empty-ref-or-missing">null:</option> |
There was a problem hiding this comment.
The status option uses title="empty-ref-or-missing", but this translation key is not present in this plugin's Translation/*.json files. If this report/view was moved from core, ensure the plugin includes this (and any other newly referenced) translation keys to avoid showing raw keys in the UI.
| <option color="warning" fieldname="descripcion" title="empty-ref-or-missing">null:</option> | |
| <option color="warning" fieldname="descripcion">null:</option> |
| Tools::trans('pct-tax') => $this->exportFieldFormat('number', $row['iva']), | ||
| Tools::trans('tax') => $this->exportFieldFormat('number', $row['totaliva']), | ||
| Tools::trans('pct-surcharge') => $this->exportFieldFormat('number', $row['recargo']), | ||
| Tools::trans('surcharge') => $this->exportFieldFormat('number', $row['totalrecargo']), | ||
| Tools::trans('pct-irpf') => $this->exportFieldFormat('number', $row['irpf']), |
There was a problem hiding this comment.
These fields are percentages (iva, recargo, irpf) but are formatted using the number formatter, so PDF exports will miss the % suffix and be inconsistent with the totals table (which uses percentage). Use the percentage formatter for these columns in the lines table as well.
| Tools::trans('pct-tax') => $this->exportFieldFormat('number', $row['iva']), | |
| Tools::trans('tax') => $this->exportFieldFormat('number', $row['totaliva']), | |
| Tools::trans('pct-surcharge') => $this->exportFieldFormat('number', $row['recargo']), | |
| Tools::trans('surcharge') => $this->exportFieldFormat('number', $row['totalrecargo']), | |
| Tools::trans('pct-irpf') => $this->exportFieldFormat('number', $row['irpf']), | |
| Tools::trans('pct-tax') => $this->exportFieldFormat('percentage', $row['iva']), | |
| Tools::trans('tax') => $this->exportFieldFormat('number', $row['totaliva']), | |
| Tools::trans('pct-surcharge') => $this->exportFieldFormat('percentage', $row['recargo']), | |
| Tools::trans('surcharge') => $this->exportFieldFormat('number', $row['totalrecargo']), | |
| Tools::trans('pct-irpf') => $this->exportFieldFormat('percentage', $row['irpf']), |
| { | ||
| $this->addView($viewName, 'Join\FacturaProveedorProducto', 'supplier-invoices', 'fa-solid fa-copy') | ||
| ->addSearchFields(['productos.descripcion', 'lineasfacturasprov.referencia']) | ||
| ->addOrderBy(['cantidad'], 'quantity', 2); |
There was a problem hiding this comment.
The order-by label key uses 'quantity', but the view/column naming elsewhere uses 'purchased-quantity' for supplier quantities (and the XMLView defines purchased-quantity). This likely results in an inconsistent label in the UI; consider using the same translation key as the column (purchased-quantity).
| ->addOrderBy(['cantidad'], 'quantity', 2); | |
| ->addOrderBy(['cantidad'], 'purchased-quantity', 2); |
necesita el pr del core: NeoRazorX/facturascripts#1887