coati-payroll 0.0.12__py3-none-any.whl → 0.0.13__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of coati-payroll might be problematic. Click here for more details.

Files changed (244) hide show
  1. coati_payroll/__init__.py +7 -17
  2. coati_payroll/app.py +2 -13
  3. coati_payroll/audit_helpers.py +2 -13
  4. coati_payroll/auth.py +2 -13
  5. coati_payroll/cli.py +17 -14
  6. coati_payroll/config.py +2 -13
  7. coati_payroll/demo_data.py +2 -13
  8. coati_payroll/enums.py +2 -13
  9. coati_payroll/forms.py +7 -13
  10. coati_payroll/formula_engine/__init__.py +14 -13
  11. coati_payroll/formula_engine/ast/__init__.py +16 -1
  12. coati_payroll/formula_engine/ast/ast_visitor.py +15 -17
  13. coati_payroll/formula_engine/ast/expression_evaluator.py +12 -14
  14. coati_payroll/formula_engine/ast/safe_operators.py +16 -15
  15. coati_payroll/formula_engine/ast/type_converter.py +17 -17
  16. coati_payroll/formula_engine/data_sources.py +3 -13
  17. coati_payroll/formula_engine/engine.py +12 -13
  18. coati_payroll/formula_engine/exceptions.py +13 -13
  19. coati_payroll/formula_engine/execution/__init__.py +15 -13
  20. coati_payroll/formula_engine/execution/execution_context.py +12 -13
  21. coati_payroll/formula_engine/execution/step_executor.py +12 -14
  22. coati_payroll/formula_engine/execution/variable_store.py +13 -13
  23. coati_payroll/formula_engine/novelty_codes.py +3 -13
  24. coati_payroll/formula_engine/results/__init__.py +14 -13
  25. coati_payroll/formula_engine/results/execution_result.py +47 -35
  26. coati_payroll/formula_engine/steps/__init__.py +14 -14
  27. coati_payroll/formula_engine/steps/assignment_step.py +12 -13
  28. coati_payroll/formula_engine/steps/base_step.py +13 -13
  29. coati_payroll/formula_engine/steps/calculation_step.py +12 -13
  30. coati_payroll/formula_engine/steps/conditional_step.py +12 -13
  31. coati_payroll/formula_engine/steps/step_factory.py +11 -13
  32. coati_payroll/formula_engine/steps/tax_lookup_step.py +12 -13
  33. coati_payroll/formula_engine/tables/__init__.py +14 -13
  34. coati_payroll/formula_engine/tables/bracket_calculator.py +12 -13
  35. coati_payroll/formula_engine/tables/table_lookup.py +12 -14
  36. coati_payroll/formula_engine/tables/tax_table.py +13 -13
  37. coati_payroll/formula_engine/validation/__init__.py +14 -13
  38. coati_payroll/formula_engine/validation/schema_validator.py +12 -14
  39. coati_payroll/formula_engine/validation/security_validator.py +12 -13
  40. coati_payroll/formula_engine/validation/tax_table_validator.py +12 -13
  41. coati_payroll/formula_engine_examples.py +2 -13
  42. coati_payroll/i18n.py +2 -13
  43. coati_payroll/initial_data.py +2 -13
  44. coati_payroll/interes_engine.py +2 -13
  45. coati_payroll/liquidacion_engine/__init__.py +2 -13
  46. coati_payroll/liquidacion_engine/engine.py +2 -13
  47. coati_payroll/locale_config.py +2 -13
  48. coati_payroll/migrations/20260125_032900_initial_migration.py +2 -14
  49. coati_payroll/migrations/__init__.py +2 -13
  50. coati_payroll/model.py +83 -82
  51. coati_payroll/nomina_engine/__init__.py +2 -13
  52. coati_payroll/nomina_engine/calculators/__init__.py +2 -13
  53. coati_payroll/nomina_engine/calculators/benefit_calculator.py +2 -13
  54. coati_payroll/nomina_engine/calculators/concept_calculator.py +2 -1
  55. coati_payroll/nomina_engine/calculators/deduction_calculator.py +2 -13
  56. coati_payroll/nomina_engine/calculators/exchange_rate_calculator.py +2 -13
  57. coati_payroll/nomina_engine/calculators/perception_calculator.py +2 -13
  58. coati_payroll/nomina_engine/calculators/salary_calculator.py +2 -13
  59. coati_payroll/nomina_engine/domain/__init__.py +2 -13
  60. coati_payroll/nomina_engine/domain/calculation_items.py +2 -13
  61. coati_payroll/nomina_engine/domain/employee_calculation.py +2 -13
  62. coati_payroll/nomina_engine/domain/payroll_context.py +2 -13
  63. coati_payroll/nomina_engine/engine.py +2 -13
  64. coati_payroll/nomina_engine/processors/__init__.py +2 -13
  65. coati_payroll/nomina_engine/processors/accounting_processor.py +2 -13
  66. coati_payroll/nomina_engine/processors/accumulation_processor.py +2 -13
  67. coati_payroll/nomina_engine/processors/loan_processor.py +2 -13
  68. coati_payroll/nomina_engine/processors/novelty_processor.py +2 -13
  69. coati_payroll/nomina_engine/processors/vacation_processor.py +2 -13
  70. coati_payroll/nomina_engine/repositories/__init__.py +2 -13
  71. coati_payroll/nomina_engine/repositories/acumulado_repository.py +2 -13
  72. coati_payroll/nomina_engine/repositories/base_repository.py +2 -13
  73. coati_payroll/nomina_engine/repositories/config_repository.py +2 -13
  74. coati_payroll/nomina_engine/repositories/employee_repository.py +2 -13
  75. coati_payroll/nomina_engine/repositories/exchange_rate_repository.py +2 -13
  76. coati_payroll/nomina_engine/repositories/novelty_repository.py +2 -13
  77. coati_payroll/nomina_engine/repositories/planilla_repository.py +2 -13
  78. coati_payroll/nomina_engine/results/__init__.py +2 -13
  79. coati_payroll/nomina_engine/results/error_result.py +2 -13
  80. coati_payroll/nomina_engine/results/payroll_result.py +2 -13
  81. coati_payroll/nomina_engine/results/validation_result.py +2 -13
  82. coati_payroll/nomina_engine/services/__init__.py +2 -13
  83. coati_payroll/nomina_engine/services/accounting_voucher_service.py +2 -13
  84. coati_payroll/nomina_engine/services/employee_processing_service.py +2 -13
  85. coati_payroll/nomina_engine/services/payroll_execution_service.py +2 -13
  86. coati_payroll/nomina_engine/validators/__init__.py +2 -13
  87. coati_payroll/nomina_engine/validators/base_validator.py +2 -13
  88. coati_payroll/nomina_engine/validators/currency_validator.py +2 -13
  89. coati_payroll/nomina_engine/validators/employee_validator.py +2 -13
  90. coati_payroll/nomina_engine/validators/period_validator.py +2 -13
  91. coati_payroll/nomina_engine/validators/planilla_validator.py +2 -13
  92. coati_payroll/queue/__init__.py +2 -13
  93. coati_payroll/queue/driver.py +2 -13
  94. coati_payroll/queue/drivers/__init__.py +2 -13
  95. coati_payroll/queue/drivers/dramatiq_driver.py +9 -16
  96. coati_payroll/queue/drivers/huey_driver.py +2 -13
  97. coati_payroll/queue/drivers/noop_driver.py +2 -13
  98. coati_payroll/queue/selector.py +2 -13
  99. coati_payroll/queue/tasks.py +13 -20
  100. coati_payroll/rate_limiting.py +2 -13
  101. coati_payroll/rbac.py +12 -19
  102. coati_payroll/report_engine.py +2 -13
  103. coati_payroll/report_export.py +2 -13
  104. coati_payroll/schema_validator.py +2 -13
  105. coati_payroll/security.py +2 -13
  106. coati_payroll/static/schema_editor.js +862 -0
  107. coati_payroll/static/styles.css +5 -0
  108. coati_payroll/system_reports.py +2 -13
  109. coati_payroll/templates/auth/login.html +5 -0
  110. coati_payroll/templates/base.html +5 -1
  111. coati_payroll/templates/index.html +5 -0
  112. coati_payroll/templates/macros.html +5 -0
  113. coati_payroll/templates/modules/calculation_rule/form.html +5 -0
  114. coati_payroll/templates/modules/calculation_rule/index.html +5 -0
  115. coati_payroll/templates/modules/calculation_rule/schema_editor.html +292 -974
  116. coati_payroll/templates/modules/carga_inicial_prestacion/form.html +5 -0
  117. coati_payroll/templates/modules/carga_inicial_prestacion/index.html +5 -0
  118. coati_payroll/templates/modules/carga_inicial_prestacion/reporte.html +5 -0
  119. coati_payroll/templates/modules/config_calculos/index.html +5 -0
  120. coati_payroll/templates/modules/configuracion/index.html +24 -27
  121. coati_payroll/templates/modules/currency/form.html +5 -0
  122. coati_payroll/templates/modules/currency/index.html +5 -0
  123. coati_payroll/templates/modules/custom_field/form.html +5 -0
  124. coati_payroll/templates/modules/custom_field/index.html +5 -0
  125. coati_payroll/templates/modules/deduccion/form.html +5 -0
  126. coati_payroll/templates/modules/deduccion/index.html +5 -0
  127. coati_payroll/templates/modules/employee/form.html +5 -0
  128. coati_payroll/templates/modules/employee/index.html +5 -0
  129. coati_payroll/templates/modules/empresa/form.html +5 -0
  130. coati_payroll/templates/modules/empresa/index.html +5 -0
  131. coati_payroll/templates/modules/exchange_rate/form.html +5 -0
  132. coati_payroll/templates/modules/exchange_rate/import.html +5 -0
  133. coati_payroll/templates/modules/exchange_rate/index.html +5 -0
  134. coati_payroll/templates/modules/liquidacion/index.html +5 -0
  135. coati_payroll/templates/modules/liquidacion/nueva.html +5 -0
  136. coati_payroll/templates/modules/liquidacion/ver.html +5 -0
  137. coati_payroll/templates/modules/payroll_concepts/audit_log.html +5 -0
  138. coati_payroll/templates/modules/percepcion/form.html +5 -0
  139. coati_payroll/templates/modules/percepcion/index.html +5 -0
  140. coati_payroll/templates/modules/planilla/config.html +5 -0
  141. coati_payroll/templates/modules/planilla/config_deducciones.html +5 -0
  142. coati_payroll/templates/modules/planilla/config_empleados.html +5 -0
  143. coati_payroll/templates/modules/planilla/config_percepciones.html +5 -0
  144. coati_payroll/templates/modules/planilla/config_prestaciones.html +5 -0
  145. coati_payroll/templates/modules/planilla/config_reglas.html +5 -0
  146. coati_payroll/templates/modules/planilla/ejecutar_nomina.html +5 -0
  147. coati_payroll/templates/modules/planilla/form.html +5 -0
  148. coati_payroll/templates/modules/planilla/index.html +5 -0
  149. coati_payroll/templates/modules/planilla/listar_nominas.html +5 -0
  150. coati_payroll/templates/modules/planilla/log_nomina.html +5 -0
  151. coati_payroll/templates/modules/planilla/novedades/form.html +5 -0
  152. coati_payroll/templates/modules/planilla/novedades/index.html +5 -0
  153. coati_payroll/templates/modules/planilla/ver_nomina.html +5 -0
  154. coati_payroll/templates/modules/planilla/ver_nomina_empleado.html +5 -0
  155. coati_payroll/templates/modules/plugins/index.html +5 -0
  156. coati_payroll/templates/modules/prestacion/form.html +5 -0
  157. coati_payroll/templates/modules/prestacion/index.html +5 -0
  158. coati_payroll/templates/modules/prestacion_management/dashboard.html +5 -0
  159. coati_payroll/templates/modules/prestacion_management/initial_balance_bulk.html +5 -0
  160. coati_payroll/templates/modules/prestamo/approve.html +5 -0
  161. coati_payroll/templates/modules/prestamo/condonacion.html +5 -0
  162. coati_payroll/templates/modules/prestamo/detail.html +5 -0
  163. coati_payroll/templates/modules/prestamo/form.html +5 -0
  164. coati_payroll/templates/modules/prestamo/index.html +5 -0
  165. coati_payroll/templates/modules/prestamo/pago_extraordinario.html +5 -0
  166. coati_payroll/templates/modules/prestamo/tabla_pago_pdf.html +5 -0
  167. coati_payroll/templates/modules/report/admin_index.html +5 -0
  168. coati_payroll/templates/modules/report/detail.html +5 -0
  169. coati_payroll/templates/modules/report/execute.html +5 -0
  170. coati_payroll/templates/modules/report/index.html +5 -0
  171. coati_payroll/templates/modules/report/permissions.html +5 -0
  172. coati_payroll/templates/modules/settings/index.html +5 -0
  173. coati_payroll/templates/modules/shared/concept_form.html +19 -12
  174. coati_payroll/templates/modules/shared/concept_index.html +39 -27
  175. coati_payroll/templates/modules/tipo_planilla/form.html +5 -0
  176. coati_payroll/templates/modules/tipo_planilla/index.html +5 -0
  177. coati_payroll/templates/modules/user/form.html +5 -0
  178. coati_payroll/templates/modules/user/index.html +5 -0
  179. coati_payroll/templates/modules/user/profile.html +5 -0
  180. coati_payroll/templates/modules/vacation/account_detail.html +5 -0
  181. coati_payroll/templates/modules/vacation/account_form.html +5 -0
  182. coati_payroll/templates/modules/vacation/account_index.html +5 -0
  183. coati_payroll/templates/modules/vacation/dashboard.html +5 -0
  184. coati_payroll/templates/modules/vacation/initial_balance_bulk.html +5 -0
  185. coati_payroll/templates/modules/vacation/initial_balance_form.html +5 -0
  186. coati_payroll/templates/modules/vacation/leave_request_detail.html +5 -0
  187. coati_payroll/templates/modules/vacation/leave_request_form.html +5 -0
  188. coati_payroll/templates/modules/vacation/leave_request_index.html +5 -0
  189. coati_payroll/templates/modules/vacation/policy_detail.html +5 -0
  190. coati_payroll/templates/modules/vacation/policy_form.html +5 -0
  191. coati_payroll/templates/modules/vacation/policy_index.html +5 -0
  192. coati_payroll/templates/modules/vacation/register_taken_form.html +5 -0
  193. coati_payroll/translations/en/LC_MESSAGES/messages.mo +0 -0
  194. coati_payroll/translations/en/LC_MESSAGES/messages.po +2963 -3561
  195. coati_payroll/vacation_service.py +2 -13
  196. coati_payroll/version.py +3 -14
  197. coati_payroll/vistas/__init__.py +2 -13
  198. coati_payroll/vistas/calculation_rule.py +14 -24
  199. coati_payroll/vistas/carga_inicial_prestacion.py +2 -13
  200. coati_payroll/vistas/config_calculos.py +2 -13
  201. coati_payroll/vistas/configuracion.py +29 -39
  202. coati_payroll/vistas/constants.py +2 -13
  203. coati_payroll/vistas/currency.py +2 -13
  204. coati_payroll/vistas/custom_field.py +2 -13
  205. coati_payroll/vistas/employee.py +2 -13
  206. coati_payroll/vistas/empresa.py +2 -13
  207. coati_payroll/vistas/exchange_rate.py +2 -13
  208. coati_payroll/vistas/liquidacion.py +2 -13
  209. coati_payroll/vistas/payroll_concepts.py +2 -13
  210. coati_payroll/vistas/planilla/__init__.py +2 -13
  211. coati_payroll/vistas/planilla/association_routes.py +8 -17
  212. coati_payroll/vistas/planilla/config_routes.py +2 -13
  213. coati_payroll/vistas/planilla/export_routes.py +28 -35
  214. coati_payroll/vistas/planilla/helpers/__init__.py +2 -13
  215. coati_payroll/vistas/planilla/helpers/association_helpers.py +2 -13
  216. coati_payroll/vistas/planilla/helpers/excel_helpers.py +2 -13
  217. coati_payroll/vistas/planilla/helpers/form_helpers.py +2 -13
  218. coati_payroll/vistas/planilla/nomina_routes.py +2 -13
  219. coati_payroll/vistas/planilla/novedad_routes.py +2 -13
  220. coati_payroll/vistas/planilla/routes.py +2 -13
  221. coati_payroll/vistas/planilla/services/__init__.py +2 -13
  222. coati_payroll/vistas/planilla/services/export_service.py +4 -15
  223. coati_payroll/vistas/planilla/services/nomina_service.py +2 -13
  224. coati_payroll/vistas/planilla/services/novedad_service.py +3 -16
  225. coati_payroll/vistas/planilla/services/planilla_service.py +2 -13
  226. coati_payroll/vistas/planilla/validators/__init__.py +2 -13
  227. coati_payroll/vistas/planilla/validators/planilla_validators.py +2 -13
  228. coati_payroll/vistas/prestacion.py +2 -13
  229. coati_payroll/vistas/prestamo.py +2 -13
  230. coati_payroll/vistas/report.py +2 -13
  231. coati_payroll/vistas/settings.py +2 -13
  232. coati_payroll/vistas/tipo_planilla.py +2 -13
  233. coati_payroll/vistas/user.py +2 -13
  234. coati_payroll/vistas/vacation.py +15 -13
  235. coati_payroll/wsgi_server.py +37 -0
  236. {coati_payroll-0.0.12.dist-info → coati_payroll-0.0.13.dist-info}/METADATA +11 -4
  237. coati_payroll-0.0.13.dist-info/RECORD +248 -0
  238. coati_payroll/translations/es/LC_MESSAGES/messages.mo +0 -0
  239. coati_payroll/translations/es/LC_MESSAGES/messages.po +0 -7374
  240. coati_payroll-0.0.12.dist-info/RECORD +0 -248
  241. {coati_payroll-0.0.12.dist-info → coati_payroll-0.0.13.dist-info}/LICENSE +0 -0
  242. {coati_payroll-0.0.12.dist-info → coati_payroll-0.0.13.dist-info}/WHEEL +0 -0
  243. {coati_payroll-0.0.12.dist-info → coati_payroll-0.0.13.dist-info}/entry_points.txt +0 -0
  244. {coati_payroll-0.0.12.dist-info → coati_payroll-0.0.13.dist-info}/top_level.txt +0 -0
coati_payroll/model.py CHANGED
@@ -1,16 +1,5 @@
1
- # Copyright 2025 BMO Soluciones, S.A.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # SPDX-FileCopyrightText: 2025 - 2026 BMO Soluciones, S.A.
14
3
  """Data model for the payroll module."""
15
4
 
16
5
  from __future__ import annotations
@@ -68,6 +57,18 @@ def utc_now() -> datetime:
68
57
  return datetime.now(timezone.utc)
69
58
 
70
59
 
60
+ # Foreign Key Constants
61
+ FK_MONEDA_ID = "moneda.id"
62
+ FK_EMPRESA_ID = "empresa.id"
63
+ FK_PLANILLA_ID = "planilla.id"
64
+ FK_PERCEPCION_ID = "percepcion.id"
65
+ FK_DEDUCCION_ID = "deduccion.id"
66
+ FK_PRESTACION_ID = "prestacion.id"
67
+ FK_EMPLEADO_ID = "empleado.id"
68
+ FK_NOMINA_ID = "nomina.id"
69
+ FK_REPORT_ID = "report.id"
70
+
71
+
71
72
  # Utiliza orjon para serializar/deserializar JSON
72
73
  class OrjsonType(TypeDecorator):
73
74
  impl = JSON
@@ -215,8 +216,8 @@ class TipoCambio(database.Model, BaseTabla):
215
216
  )
216
217
 
217
218
  fecha = database.Column(database.Date, nullable=False, default=date.today, index=True)
218
- moneda_origen_id = database.Column(database.String(26), database.ForeignKey("moneda.id"), nullable=False)
219
- moneda_destino_id = database.Column(database.String(26), database.ForeignKey("moneda.id"), nullable=False)
219
+ moneda_origen_id = database.Column(database.String(26), database.ForeignKey(FK_MONEDA_ID), nullable=False)
220
+ moneda_destino_id = database.Column(database.String(26), database.ForeignKey(FK_MONEDA_ID), nullable=False)
220
221
  tasa = database.Column(database.Numeric(24, 10), nullable=False)
221
222
 
222
223
  moneda_origen = database.relationship(
@@ -269,11 +270,11 @@ class Empleado(database.Model, BaseTabla):
269
270
  salario_base = database.Column(database.Numeric(14, 2), nullable=False, default=Decimal("0.00"))
270
271
 
271
272
  # Moneda del sueldo: FK hacia moneda.id (consistencia)
272
- moneda_id = database.Column(database.String(26), database.ForeignKey("moneda.id"), nullable=True)
273
+ moneda_id = database.Column(database.String(26), database.ForeignKey(FK_MONEDA_ID), nullable=True)
273
274
  moneda = database.relationship("Moneda", back_populates="empleados")
274
275
 
275
276
  # Empresa a la que pertenece el empleado
276
- empresa_id = database.Column(database.String(26), database.ForeignKey("empresa.id"), nullable=True)
277
+ empresa_id = database.Column(database.String(26), database.ForeignKey(FK_EMPRESA_ID), nullable=True)
277
278
  empresa = database.relationship("Empresa", back_populates="empleados")
278
279
 
279
280
  correo = database.Column(database.String(150), nullable=True, index=True)
@@ -390,11 +391,11 @@ class Planilla(database.Model, BaseTabla):
390
391
  tipo_planilla_id = database.Column(database.String(26), database.ForeignKey("tipo_planilla.id"), nullable=False)
391
392
  tipo_planilla = database.relationship("TipoPlanilla", back_populates="planillas")
392
393
 
393
- moneda_id = database.Column(database.String(26), database.ForeignKey("moneda.id"), nullable=False)
394
+ moneda_id = database.Column(database.String(26), database.ForeignKey(FK_MONEDA_ID), nullable=False)
394
395
  moneda = database.relationship("Moneda", back_populates="planillas")
395
396
 
396
397
  # Empresa a la que pertenece la planilla
397
- empresa_id = database.Column(database.String(26), database.ForeignKey("empresa.id"), nullable=True)
398
+ empresa_id = database.Column(database.String(26), database.ForeignKey(FK_EMPRESA_ID), nullable=True)
398
399
  empresa = database.relationship("Empresa", back_populates="planillas")
399
400
 
400
401
  # Período Fiscal
@@ -684,8 +685,8 @@ class PlanillaIngreso(database.Model, BaseTabla):
684
685
  __tablename__ = "planilla_ingreso"
685
686
  __table_args__ = (database.UniqueConstraint("planilla_id", "percepcion_id", name="uq_planilla_percepcion"),)
686
687
 
687
- planilla_id = database.Column(database.String(26), database.ForeignKey("planilla.id"), nullable=False)
688
- percepcion_id = database.Column(database.String(26), database.ForeignKey("percepcion.id"), nullable=False)
688
+ planilla_id = database.Column(database.String(26), database.ForeignKey(FK_PLANILLA_ID), nullable=False)
689
+ percepcion_id = database.Column(database.String(26), database.ForeignKey(FK_PERCEPCION_ID), nullable=False)
689
690
 
690
691
  orden = database.Column(database.Integer, nullable=True, default=0)
691
692
  editable = database.Column(database.Boolean(), default=True)
@@ -717,8 +718,8 @@ class PlanillaDeduccion(database.Model, BaseTabla):
717
718
  __tablename__ = "planilla_deduccion"
718
719
  __table_args__ = (database.UniqueConstraint("planilla_id", "deduccion_id", name="uq_planilla_deduccion"),)
719
720
 
720
- planilla_id = database.Column(database.String(26), database.ForeignKey("planilla.id"), nullable=False)
721
- deduccion_id = database.Column(database.String(26), database.ForeignKey("deduccion.id"), nullable=False)
721
+ planilla_id = database.Column(database.String(26), database.ForeignKey(FK_PLANILLA_ID), nullable=False)
722
+ deduccion_id = database.Column(database.String(26), database.ForeignKey(FK_DEDUCCION_ID), nullable=False)
722
723
 
723
724
  # Priority order for applying deductions (lower = higher priority)
724
725
  prioridad = database.Column(database.Integer, nullable=False, default=100)
@@ -745,8 +746,8 @@ class PlanillaPrestacion(database.Model, BaseTabla):
745
746
  __tablename__ = "planilla_prestacion"
746
747
  __table_args__ = (database.UniqueConstraint("planilla_id", "prestacion_id", name="uq_planilla_prestacion"),)
747
748
 
748
- planilla_id = database.Column(database.String(26), database.ForeignKey("planilla.id"), nullable=False)
749
- prestacion_id = database.Column(database.String(26), database.ForeignKey("prestacion.id"), nullable=False)
749
+ planilla_id = database.Column(database.String(26), database.ForeignKey(FK_PLANILLA_ID), nullable=False)
750
+ prestacion_id = database.Column(database.String(26), database.ForeignKey(FK_PRESTACION_ID), nullable=False)
750
751
 
751
752
  orden = database.Column(database.Integer, nullable=True, default=0)
752
753
  editable = database.Column(database.Boolean(), default=True)
@@ -768,7 +769,7 @@ class PlanillaReglaCalculo(database.Model, BaseTabla):
768
769
  __tablename__ = "planilla_regla_calculo"
769
770
  __table_args__ = (database.UniqueConstraint("planilla_id", "regla_calculo_id", name="uq_planilla_regla"),)
770
771
 
771
- planilla_id = database.Column(database.String(26), database.ForeignKey("planilla.id"), nullable=False)
772
+ planilla_id = database.Column(database.String(26), database.ForeignKey(FK_PLANILLA_ID), nullable=False)
772
773
  regla_calculo_id = database.Column(database.String(26), database.ForeignKey("regla_calculo.id"), nullable=False)
773
774
 
774
775
  # Order of execution (important for dependent calculations)
@@ -788,8 +789,8 @@ class PlanillaEmpleado(database.Model, BaseTabla):
788
789
  __tablename__ = "planilla_empleado"
789
790
  __table_args__ = (database.UniqueConstraint("planilla_id", "empleado_id", name="uq_planilla_empleado"),)
790
791
 
791
- planilla_id = database.Column(database.String(26), database.ForeignKey("planilla.id"), nullable=False)
792
- empleado_id = database.Column(database.String(26), database.ForeignKey("empleado.id"), nullable=False)
792
+ planilla_id = database.Column(database.String(26), database.ForeignKey(FK_PLANILLA_ID), nullable=False)
793
+ empleado_id = database.Column(database.String(26), database.ForeignKey(FK_EMPLEADO_ID), nullable=False)
793
794
 
794
795
  activo = database.Column(database.Boolean(), default=True)
795
796
  fecha_inicio = database.Column(database.Date, nullable=False, default=date.today)
@@ -803,7 +804,7 @@ class PlanillaEmpleado(database.Model, BaseTabla):
803
804
  class Nomina(database.Model, BaseTabla):
804
805
  __tablename__ = "nomina"
805
806
 
806
- planilla_id = database.Column(database.String(26), database.ForeignKey("planilla.id"), nullable=False)
807
+ planilla_id = database.Column(database.String(26), database.ForeignKey(FK_PLANILLA_ID), nullable=False)
807
808
  fecha_generacion = database.Column(database.DateTime, nullable=False, default=utc_now)
808
809
  periodo_inicio = database.Column(database.Date, nullable=False)
809
810
  periodo_fin = database.Column(database.Date, nullable=False)
@@ -867,8 +868,8 @@ class Nomina(database.Model, BaseTabla):
867
868
  class NominaEmpleado(database.Model, BaseTabla):
868
869
  __tablename__ = "nomina_empleado"
869
870
 
870
- nomina_id = database.Column(database.String(26), database.ForeignKey("nomina.id"), nullable=False)
871
- empleado_id = database.Column(database.String(26), database.ForeignKey("empleado.id"), nullable=False)
871
+ nomina_id = database.Column(database.String(26), database.ForeignKey(FK_NOMINA_ID), nullable=False)
872
+ empleado_id = database.Column(database.String(26), database.ForeignKey(FK_EMPLEADO_ID), nullable=False)
872
873
 
873
874
  salario_bruto = database.Column(database.Numeric(14, 2), nullable=True, default=Decimal("0.00"))
874
875
  total_ingresos = database.Column(database.Numeric(14, 2), nullable=True, default=Decimal("0.00"))
@@ -876,7 +877,7 @@ class NominaEmpleado(database.Model, BaseTabla):
876
877
  salario_neto = database.Column(database.Numeric(14, 2), nullable=True, default=Decimal("0.00"))
877
878
 
878
879
  # datos para auditoria/moneda
879
- moneda_origen_id = database.Column(database.String(26), database.ForeignKey("moneda.id"), nullable=True)
880
+ moneda_origen_id = database.Column(database.String(26), database.ForeignKey(FK_MONEDA_ID), nullable=True)
880
881
  tipo_cambio_aplicado = database.Column(database.Numeric(24, 10), nullable=True)
881
882
 
882
883
  nomina = database.relationship("Nomina", back_populates="nomina_empleados")
@@ -905,9 +906,9 @@ class NominaDetalle(database.Model, BaseTabla):
905
906
  orden = database.Column(database.Integer, nullable=True, default=0)
906
907
 
907
908
  # referencias opcionales a catálogo original (si aplica)
908
- percepcion_id = database.Column(database.String(26), database.ForeignKey("percepcion.id"), nullable=True)
909
- deduccion_id = database.Column(database.String(26), database.ForeignKey("deduccion.id"), nullable=True)
910
- prestacion_id = database.Column(database.String(26), database.ForeignKey("prestacion.id"), nullable=True)
909
+ percepcion_id = database.Column(database.String(26), database.ForeignKey(FK_PERCEPCION_ID), nullable=True)
910
+ deduccion_id = database.Column(database.String(26), database.ForeignKey(FK_DEDUCCION_ID), nullable=True)
911
+ prestacion_id = database.Column(database.String(26), database.ForeignKey(FK_PRESTACION_ID), nullable=True)
911
912
 
912
913
  nomina_empleado = database.relationship("NominaEmpleado", back_populates="nomina_detalles")
913
914
  percepcion = database.relationship("Percepcion", back_populates="nomina_detalles", foreign_keys=[percepcion_id])
@@ -928,7 +929,7 @@ class LiquidacionConcepto(database.Model, BaseTabla):
928
929
  class Liquidacion(database.Model, BaseTabla):
929
930
  __tablename__ = "liquidacion"
930
931
 
931
- empleado_id = database.Column(database.String(26), database.ForeignKey("empleado.id"), nullable=False, index=True)
932
+ empleado_id = database.Column(database.String(26), database.ForeignKey(FK_EMPLEADO_ID), nullable=False, index=True)
932
933
  concepto_id = database.Column(
933
934
  database.String(26), database.ForeignKey("liquidacion_concepto.id"), nullable=True, index=True
934
935
  )
@@ -963,9 +964,9 @@ class LiquidacionDetalle(database.Model, BaseTabla):
963
964
  monto = database.Column(database.Numeric(14, 2), nullable=False, default=Decimal("0.00"))
964
965
  orden = database.Column(database.Integer, nullable=True, default=0)
965
966
 
966
- percepcion_id = database.Column(database.String(26), database.ForeignKey("percepcion.id"), nullable=True)
967
- deduccion_id = database.Column(database.String(26), database.ForeignKey("deduccion.id"), nullable=True)
968
- prestacion_id = database.Column(database.String(26), database.ForeignKey("prestacion.id"), nullable=True)
967
+ percepcion_id = database.Column(database.String(26), database.ForeignKey(FK_PERCEPCION_ID), nullable=True)
968
+ deduccion_id = database.Column(database.String(26), database.ForeignKey(FK_DEDUCCION_ID), nullable=True)
969
+ prestacion_id = database.Column(database.String(26), database.ForeignKey(FK_PRESTACION_ID), nullable=True)
969
970
 
970
971
  liquidacion = database.relationship("Liquidacion", back_populates="detalles")
971
972
  percepcion = database.relationship("Percepcion", foreign_keys=[percepcion_id])
@@ -977,9 +978,9 @@ class NominaNovedad(database.Model, BaseTabla):
977
978
  __tablename__ = "nomina_novedad"
978
979
 
979
980
  # FK a la ejecución de Nómina (el ID que solicitaste)
980
- nomina_id = database.Column(database.String(26), database.ForeignKey("nomina.id"), nullable=False)
981
+ nomina_id = database.Column(database.String(26), database.ForeignKey(FK_NOMINA_ID), nullable=False)
981
982
  # FK al empleado afectado
982
- empleado_id = database.Column(database.String(26), database.ForeignKey("empleado.id"), nullable=False)
983
+ empleado_id = database.Column(database.String(26), database.ForeignKey(FK_EMPLEADO_ID), nullable=False)
983
984
 
984
985
  tipo_valor = database.Column(database.String(20), nullable=True) # horas | dias | cantidad | monto | porcentaje
985
986
 
@@ -993,8 +994,8 @@ class NominaNovedad(database.Model, BaseTabla):
993
994
  fecha_novedad = database.Column(database.Date, nullable=True)
994
995
 
995
996
  # Referencia opcional al maestro para saber qué regla aplica
996
- percepcion_id = database.Column(database.String(26), database.ForeignKey("percepcion.id"), nullable=True)
997
- deduccion_id = database.Column(database.String(26), database.ForeignKey("deduccion.id"), nullable=True)
997
+ percepcion_id = database.Column(database.String(26), database.ForeignKey(FK_PERCEPCION_ID), nullable=True)
998
+ deduccion_id = database.Column(database.String(26), database.ForeignKey(FK_DEDUCCION_ID), nullable=True)
998
999
 
999
1000
  # ---- Vacation Module Integration ----
1000
1001
  # Flag to mark this novelty as vacation/time-off
@@ -1035,12 +1036,12 @@ class ComprobanteContable(database.Model, BaseTabla):
1035
1036
 
1036
1037
  __tablename__ = "comprobante_contable"
1037
1038
 
1038
- nomina_id = database.Column(database.String(26), database.ForeignKey("nomina.id"), nullable=False, unique=True)
1039
+ nomina_id = database.Column(database.String(26), database.ForeignKey(FK_NOMINA_ID), nullable=False, unique=True)
1039
1040
 
1040
1041
  # Header information
1041
1042
  fecha_calculo = database.Column(database.Date, nullable=False, default=date.today)
1042
1043
  concepto = database.Column(database.String(255), nullable=True) # Description/concept of the voucher
1043
- moneda_id = database.Column(database.String(26), database.ForeignKey("moneda.id"), nullable=True)
1044
+ moneda_id = database.Column(database.String(26), database.ForeignKey(FK_MONEDA_ID), nullable=True)
1044
1045
 
1045
1046
  # Summary totals (calculated from lines)
1046
1047
  total_debitos = database.Column(database.Numeric(14, 2), nullable=False, default=Decimal("0.00"))
@@ -1094,7 +1095,7 @@ class ComprobanteContableLinea(database.Model, BaseTabla):
1094
1095
  )
1095
1096
 
1096
1097
  # Employee information for audit trail (denormalized for easier reporting)
1097
- empleado_id = database.Column(database.String(26), database.ForeignKey("empleado.id"), nullable=False, index=True)
1098
+ empleado_id = database.Column(database.String(26), database.ForeignKey(FK_EMPLEADO_ID), nullable=False, index=True)
1098
1099
  empleado_codigo = database.Column(database.String(20), nullable=False, index=True)
1099
1100
  empleado_nombre = database.Column(database.String(255), nullable=False)
1100
1101
 
@@ -1134,7 +1135,7 @@ class HistorialSalario(database.Model, BaseTabla):
1134
1135
 
1135
1136
  empleado_id = database.Column(
1136
1137
  database.String(26),
1137
- database.ForeignKey("empleado.id"),
1138
+ database.ForeignKey(FK_EMPLEADO_ID),
1138
1139
  nullable=False,
1139
1140
  index=True,
1140
1141
  )
@@ -1169,7 +1170,7 @@ class VacacionEmpleado(database.Model, BaseTabla):
1169
1170
 
1170
1171
  empleado_id = database.Column(
1171
1172
  database.String(26),
1172
- database.ForeignKey("empleado.id"),
1173
+ database.ForeignKey(FK_EMPLEADO_ID),
1173
1174
  nullable=False,
1174
1175
  index=True,
1175
1176
  )
@@ -1195,7 +1196,7 @@ class VacacionDescansada(database.Model, BaseTabla):
1195
1196
 
1196
1197
  empleado_id = database.Column(
1197
1198
  database.String(26),
1198
- database.ForeignKey("empleado.id"),
1199
+ database.ForeignKey(FK_EMPLEADO_ID),
1199
1200
  nullable=False,
1200
1201
  index=True,
1201
1202
  )
@@ -1224,7 +1225,7 @@ class TablaImpuesto(database.Model, BaseTabla):
1224
1225
 
1225
1226
  deduccion_id = database.Column(
1226
1227
  database.String(26),
1227
- database.ForeignKey("deduccion.id"),
1228
+ database.ForeignKey(FK_DEDUCCION_ID),
1228
1229
  nullable=False,
1229
1230
  index=True,
1230
1231
  )
@@ -1252,11 +1253,11 @@ class Adelanto(database.Model, BaseTabla):
1252
1253
 
1253
1254
  empleado_id = database.Column(
1254
1255
  database.String(26),
1255
- database.ForeignKey("empleado.id"),
1256
+ database.ForeignKey(FK_EMPLEADO_ID),
1256
1257
  nullable=False,
1257
1258
  index=True,
1258
1259
  )
1259
- deduccion_id = database.Column(database.String(26), database.ForeignKey("deduccion.id"), nullable=True)
1260
+ deduccion_id = database.Column(database.String(26), database.ForeignKey(FK_DEDUCCION_ID), nullable=True)
1260
1261
 
1261
1262
  # Tipo: prestamo o adelanto
1262
1263
  tipo = database.Column(database.String(20), nullable=False, default="adelanto") # adelanto, prestamo
@@ -1272,7 +1273,7 @@ class Adelanto(database.Model, BaseTabla):
1272
1273
  saldo_pendiente = database.Column(database.Numeric(14, 2), nullable=False, default=Decimal("0.00"))
1273
1274
 
1274
1275
  # Currency support - loan can be in different currency than payroll
1275
- moneda_id = database.Column(database.String(26), database.ForeignKey("moneda.id"), nullable=True)
1276
+ moneda_id = database.Column(database.String(26), database.ForeignKey(FK_MONEDA_ID), nullable=True)
1276
1277
  # Track amounts in both loan currency and payroll currency
1277
1278
  monto_deducido_moneda_planilla = database.Column(database.Numeric(14, 2), nullable=True, default=Decimal("0.00"))
1278
1279
  monto_aplicado_moneda_prestamo = database.Column(database.Numeric(14, 2), nullable=True, default=Decimal("0.00"))
@@ -1335,7 +1336,7 @@ class AdelantoAbono(database.Model, BaseTabla):
1335
1336
  nullable=False,
1336
1337
  index=True,
1337
1338
  )
1338
- nomina_id = database.Column(database.String(26), database.ForeignKey("nomina.id"), nullable=True)
1339
+ nomina_id = database.Column(database.String(26), database.ForeignKey(FK_NOMINA_ID), nullable=True)
1339
1340
  liquidacion_id = database.Column(database.String(26), database.ForeignKey("liquidacion.id"), nullable=True)
1340
1341
  fecha_abono = database.Column(database.Date, nullable=False, default=date.today)
1341
1342
  monto_abonado = database.Column(database.Numeric(14, 2), nullable=False, default=Decimal("0.00"))
@@ -1395,7 +1396,7 @@ class InteresAdelanto(database.Model, BaseTabla):
1395
1396
  nullable=False,
1396
1397
  index=True,
1397
1398
  )
1398
- nomina_id = database.Column(database.String(26), database.ForeignKey("nomina.id"), nullable=True)
1399
+ nomina_id = database.Column(database.String(26), database.ForeignKey(FK_NOMINA_ID), nullable=True)
1399
1400
 
1400
1401
  # Calculation period
1401
1402
  fecha_desde = database.Column(database.Date, nullable=False)
@@ -1501,9 +1502,9 @@ class ReglaCalculo(database.Model, BaseTabla):
1501
1502
  activo = database.Column(database.Boolean(), default=True, nullable=False)
1502
1503
 
1503
1504
  # Optional relationship to specific deduction/perception/benefit
1504
- deduccion_id = database.Column(database.String(26), database.ForeignKey("deduccion.id"), nullable=True)
1505
- percepcion_id = database.Column(database.String(26), database.ForeignKey("percepcion.id"), nullable=True)
1506
- prestacion_id = database.Column(database.String(26), database.ForeignKey("prestacion.id"), nullable=True)
1505
+ deduccion_id = database.Column(database.String(26), database.ForeignKey(FK_DEDUCCION_ID), nullable=True)
1506
+ percepcion_id = database.Column(database.String(26), database.ForeignKey(FK_PERCEPCION_ID), nullable=True)
1507
+ prestacion_id = database.Column(database.String(26), database.ForeignKey(FK_PRESTACION_ID), nullable=True)
1507
1508
 
1508
1509
  # Audit and governance fields
1509
1510
  estado_aprobacion = database.Column(database.String(20), nullable=False, default="borrador", index=True)
@@ -1557,7 +1558,7 @@ class AcumuladoAnual(database.Model, BaseTabla):
1557
1558
 
1558
1559
  empleado_id = database.Column(
1559
1560
  database.String(26),
1560
- database.ForeignKey("empleado.id"),
1561
+ database.ForeignKey(FK_EMPLEADO_ID),
1561
1562
  nullable=False,
1562
1563
  index=True,
1563
1564
  )
@@ -1574,7 +1575,7 @@ class AcumuladoAnual(database.Model, BaseTabla):
1574
1575
  # Each company tracks accumulated values separately as they are distinct legal entities
1575
1576
  empresa_id = database.Column(
1576
1577
  database.String(26),
1577
- database.ForeignKey("empresa.id"),
1578
+ database.ForeignKey(FK_EMPRESA_ID),
1578
1579
  nullable=False,
1579
1580
  index=True,
1580
1581
  )
@@ -1656,7 +1657,7 @@ class ConfiguracionCalculos(database.Model, BaseTabla):
1656
1657
  __table_args__ = (database.UniqueConstraint("empresa_id", "pais_id", name="uq_config_empresa_pais"),)
1657
1658
 
1658
1659
  # Optional relationships - can be None for global defaults
1659
- empresa_id = database.Column(database.String(26), database.ForeignKey("empresa.id"), nullable=True, index=True)
1660
+ empresa_id = database.Column(database.String(26), database.ForeignKey(FK_EMPRESA_ID), nullable=True, index=True)
1660
1661
  pais_id = database.Column(database.String(26), nullable=True, index=True) # Future: ForeignKey("pais.id")
1661
1662
 
1662
1663
  # Días base para nómina
@@ -1726,13 +1727,13 @@ class PrestacionAcumulada(database.Model, BaseTabla):
1726
1727
 
1727
1728
  empleado_id = database.Column(
1728
1729
  database.String(26),
1729
- database.ForeignKey("empleado.id"),
1730
+ database.ForeignKey(FK_EMPLEADO_ID),
1730
1731
  nullable=False,
1731
1732
  index=True,
1732
1733
  )
1733
1734
  prestacion_id = database.Column(
1734
1735
  database.String(26),
1735
- database.ForeignKey("prestacion.id"),
1736
+ database.ForeignKey(FK_PRESTACION_ID),
1736
1737
  nullable=False,
1737
1738
  index=True,
1738
1739
  )
@@ -1748,7 +1749,7 @@ class PrestacionAcumulada(database.Model, BaseTabla):
1748
1749
  mes = database.Column(database.Integer, nullable=False) # 1-12
1749
1750
 
1750
1751
  # Currency tracking
1751
- moneda_id = database.Column(database.String(26), database.ForeignKey("moneda.id"), nullable=False)
1752
+ moneda_id = database.Column(database.String(26), database.ForeignKey(FK_MONEDA_ID), nullable=False)
1752
1753
 
1753
1754
  # Transaction amounts
1754
1755
  # For audit clarity, we store the transaction amount and running balance separately
@@ -1763,7 +1764,7 @@ class PrestacionAcumulada(database.Model, BaseTabla):
1763
1764
  ) # Balance after this transaction
1764
1765
 
1765
1766
  # Reference to source document that created this transaction
1766
- nomina_id = database.Column(database.String(26), database.ForeignKey("nomina.id"), nullable=True)
1767
+ nomina_id = database.Column(database.String(26), database.ForeignKey(FK_NOMINA_ID), nullable=True)
1767
1768
  carga_inicial_id = database.Column(
1768
1769
  database.String(26), database.ForeignKey("carga_inicial_prestacion.id"), nullable=True
1769
1770
  )
@@ -1772,7 +1773,7 @@ class PrestacionAcumulada(database.Model, BaseTabla):
1772
1773
  # Balances accumulate per company as they are distinct legal entities
1773
1774
  empresa_id = database.Column(
1774
1775
  database.String(26),
1775
- database.ForeignKey("empresa.id"),
1776
+ database.ForeignKey(FK_EMPRESA_ID),
1776
1777
  nullable=True,
1777
1778
  index=True,
1778
1779
  )
@@ -1821,13 +1822,13 @@ class CargaInicialPrestacion(database.Model, BaseTabla):
1821
1822
 
1822
1823
  empleado_id = database.Column(
1823
1824
  database.String(26),
1824
- database.ForeignKey("empleado.id"),
1825
+ database.ForeignKey(FK_EMPLEADO_ID),
1825
1826
  nullable=False,
1826
1827
  index=True,
1827
1828
  )
1828
1829
  prestacion_id = database.Column(
1829
1830
  database.String(26),
1830
- database.ForeignKey("prestacion.id"),
1831
+ database.ForeignKey(FK_PRESTACION_ID),
1831
1832
  nullable=False,
1832
1833
  index=True,
1833
1834
  )
@@ -1837,7 +1838,7 @@ class CargaInicialPrestacion(database.Model, BaseTabla):
1837
1838
  mes_corte = database.Column(database.Integer, nullable=False) # 1-12
1838
1839
 
1839
1840
  # Currency and exchange rate
1840
- moneda_id = database.Column(database.String(26), database.ForeignKey("moneda.id"), nullable=False)
1841
+ moneda_id = database.Column(database.String(26), database.ForeignKey(FK_MONEDA_ID), nullable=False)
1841
1842
  saldo_acumulado = database.Column(database.Numeric(14, 2), nullable=False, default=Decimal("0.00"))
1842
1843
  tipo_cambio = database.Column(database.Numeric(24, 10), nullable=True, default=Decimal("1.0000000000"))
1843
1844
  saldo_convertido = database.Column(database.Numeric(14, 2), nullable=False, default=Decimal("0.00"))
@@ -1892,11 +1893,11 @@ class VacationPolicy(database.Model, BaseTabla):
1892
1893
 
1893
1894
  # Payroll association (primary) - policies are tied to specific payrolls
1894
1895
  # This allows different vacation rules for different payrolls in consolidated companies
1895
- planilla_id = database.Column(database.String(26), database.ForeignKey("planilla.id"), nullable=True, index=True)
1896
+ planilla_id = database.Column(database.String(26), database.ForeignKey(FK_PLANILLA_ID), nullable=True, index=True)
1896
1897
  planilla = database.relationship("Planilla", backref="vacation_policies")
1897
1898
 
1898
1899
  # Company association (secondary, optional) - for policies that apply to entire company
1899
- empresa_id = database.Column(database.String(26), database.ForeignKey("empresa.id"), nullable=True, index=True)
1900
+ empresa_id = database.Column(database.String(26), database.ForeignKey(FK_EMPRESA_ID), nullable=True, index=True)
1900
1901
  empresa = database.relationship("Empresa")
1901
1902
 
1902
1903
  # Status
@@ -1997,7 +1998,7 @@ class VacationAccount(database.Model, BaseTabla):
1997
1998
  )
1998
1999
 
1999
2000
  # Employee and policy association
2000
- empleado_id = database.Column(database.String(26), database.ForeignKey("empleado.id"), nullable=False, index=True)
2001
+ empleado_id = database.Column(database.String(26), database.ForeignKey(FK_EMPLEADO_ID), nullable=False, index=True)
2001
2002
  empleado = database.relationship("Empleado")
2002
2003
 
2003
2004
  policy_id = database.Column(
@@ -2047,7 +2048,7 @@ class VacationLedger(database.Model, BaseTabla):
2047
2048
  account = database.relationship("VacationAccount", back_populates="ledger_entries")
2048
2049
 
2049
2050
  # Employee reference (for easier querying)
2050
- empleado_id = database.Column(database.String(26), database.ForeignKey("empleado.id"), nullable=False)
2051
+ empleado_id = database.Column(database.String(26), database.ForeignKey(FK_EMPLEADO_ID), nullable=False)
2051
2052
  empleado = database.relationship("Empleado")
2052
2053
 
2053
2054
  # Transaction details
@@ -2091,7 +2092,7 @@ class VacationNovelty(database.Model, BaseTabla):
2091
2092
  )
2092
2093
 
2093
2094
  # Employee and account
2094
- empleado_id = database.Column(database.String(26), database.ForeignKey("empleado.id"), nullable=False, index=True)
2095
+ empleado_id = database.Column(database.String(26), database.ForeignKey(FK_EMPLEADO_ID), nullable=False, index=True)
2095
2096
  empleado = database.relationship("Empleado")
2096
2097
 
2097
2098
  account_id = database.Column(
@@ -2186,7 +2187,7 @@ class ReportRole(database.Model, BaseTabla):
2186
2187
  __table_args__ = (database.UniqueConstraint("report_id", "role", name="uq_report_role"),)
2187
2188
 
2188
2189
  # Foreign key to report
2189
- report_id = database.Column(database.String(26), database.ForeignKey("report.id"), nullable=False)
2190
+ report_id = database.Column(database.String(26), database.ForeignKey(FK_REPORT_ID), nullable=False)
2190
2191
  report = database.relationship("Report", back_populates="permissions")
2191
2192
 
2192
2193
  # User role (admin, hhrr, audit)
@@ -2208,7 +2209,7 @@ class ReportExecution(database.Model, BaseTabla):
2208
2209
  __tablename__ = "report_execution"
2209
2210
 
2210
2211
  # Foreign key to report
2211
- report_id = database.Column(database.String(26), database.ForeignKey("report.id"), nullable=False)
2212
+ report_id = database.Column(database.String(26), database.ForeignKey(FK_REPORT_ID), nullable=False)
2212
2213
  report = database.relationship("Report", back_populates="executions")
2213
2214
 
2214
2215
  # Execution status
@@ -2248,7 +2249,7 @@ class ReportAudit(database.Model, BaseTabla):
2248
2249
  __tablename__ = "report_audit"
2249
2250
 
2250
2251
  # Foreign key to report
2251
- report_id = database.Column(database.String(26), database.ForeignKey("report.id"), nullable=False)
2252
+ report_id = database.Column(database.String(26), database.ForeignKey(FK_REPORT_ID), nullable=False)
2252
2253
  report = database.relationship("Report", back_populates="audit_entries")
2253
2254
 
2254
2255
  # Action performed
@@ -2275,9 +2276,9 @@ class ConceptoAuditLog(database.Model, BaseTabla):
2275
2276
  __tablename__ = "concepto_audit_log"
2276
2277
 
2277
2278
  # Foreign keys to the concepts (only one will be set)
2278
- percepcion_id = database.Column(database.String(26), database.ForeignKey("percepcion.id"), nullable=True)
2279
- deduccion_id = database.Column(database.String(26), database.ForeignKey("deduccion.id"), nullable=True)
2280
- prestacion_id = database.Column(database.String(26), database.ForeignKey("prestacion.id"), nullable=True)
2279
+ percepcion_id = database.Column(database.String(26), database.ForeignKey(FK_PERCEPCION_ID), nullable=True)
2280
+ deduccion_id = database.Column(database.String(26), database.ForeignKey(FK_DEDUCCION_ID), nullable=True)
2281
+ prestacion_id = database.Column(database.String(26), database.ForeignKey(FK_PRESTACION_ID), nullable=True)
2281
2282
 
2282
2283
  # Type of concept (for easier filtering)
2283
2284
  tipo_concepto = database.Column(
@@ -2318,7 +2319,7 @@ class PlanillaAuditLog(database.Model, BaseTabla):
2318
2319
  __tablename__ = "planilla_audit_log"
2319
2320
 
2320
2321
  # Foreign key to planilla
2321
- planilla_id = database.Column(database.String(26), database.ForeignKey("planilla.id"), nullable=False)
2322
+ planilla_id = database.Column(database.String(26), database.ForeignKey(FK_PLANILLA_ID), nullable=False)
2322
2323
 
2323
2324
  # Action performed
2324
2325
  accion = database.Column(
@@ -2352,7 +2353,7 @@ class NominaAuditLog(database.Model, BaseTabla):
2352
2353
  __tablename__ = "nomina_audit_log"
2353
2354
 
2354
2355
  # Foreign key to nomina
2355
- nomina_id = database.Column(database.String(26), database.ForeignKey("nomina.id"), nullable=False)
2356
+ nomina_id = database.Column(database.String(26), database.ForeignKey(FK_NOMINA_ID), nullable=False)
2356
2357
 
2357
2358
  # Action performed
2358
2359
  accion = database.Column(
@@ -1,16 +1,5 @@
1
- # Copyright 2025 BMO Soluciones, S.A.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # SPDX-FileCopyrightText: 2025 - 2026 BMO Soluciones, S.A.
14
3
  """Payroll execution engine - Domain-driven architecture.
15
4
 
16
5
  This module provides a modular payroll execution engine organized by domain.
@@ -1,16 +1,5 @@
1
- # Copyright 2025 BMO Soluciones, S.A.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # SPDX-FileCopyrightText: 2025 - 2026 BMO Soluciones, S.A.
14
3
  """Calculators for payroll processing."""
15
4
 
16
5
  from .concept_calculator import ConceptCalculator
@@ -1,16 +1,5 @@
1
- # Copyright 2025 BMO Soluciones, S.A.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # SPDX-FileCopyrightText: 2025 - 2026 BMO Soluciones, S.A.
14
3
  """Benefit calculator for payroll processing."""
15
4
 
16
5
  from __future__ import annotations
@@ -1,4 +1,5 @@
1
- # Copyright 2025 BMO Soluciones, S.A.
1
+ # SPDX-License-Identifier: Apache-2.0 \r\n # SPDX-FileCopyrightText: 2025 - 2026 BMO Soluciones, S.A.
2
+ # Copyright 2025 - 2026 BMO Soluciones, S.A.
2
3
  #
3
4
  # Licensed under the Apache License, Version 2.0 (the "License");
4
5
  # you may not use this file except in compliance with the License.
@@ -1,16 +1,5 @@
1
- # Copyright 2025 BMO Soluciones, S.A.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # SPDX-FileCopyrightText: 2025 - 2026 BMO Soluciones, S.A.
14
3
  """Deduction calculator for payroll processing."""
15
4
 
16
5
  from __future__ import annotations
@@ -1,16 +1,5 @@
1
- # Copyright 2025 BMO Soluciones, S.A.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # SPDX-FileCopyrightText: 2025 - 2026 BMO Soluciones, S.A.
14
3
  """Exchange rate calculator for payroll processing."""
15
4
 
16
5
  from __future__ import annotations
@@ -1,16 +1,5 @@
1
- # Copyright 2025 BMO Soluciones, S.A.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # SPDX-FileCopyrightText: 2025 - 2026 BMO Soluciones, S.A.
14
3
  """Perception calculator for payroll processing."""
15
4
 
16
5
  from __future__ import annotations