coati-payroll 0.0.2__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.
- coati_payroll/__init__.py +415 -0
- coati_payroll/app.py +95 -0
- coati_payroll/audit_helpers.py +904 -0
- coati_payroll/auth.py +123 -0
- coati_payroll/cli.py +1318 -0
- coati_payroll/config.py +219 -0
- coati_payroll/demo_data.py +813 -0
- coati_payroll/enums.py +278 -0
- coati_payroll/forms.py +1769 -0
- coati_payroll/formula_engine/__init__.py +81 -0
- coati_payroll/formula_engine/ast/__init__.py +110 -0
- coati_payroll/formula_engine/ast/ast_visitor.py +259 -0
- coati_payroll/formula_engine/ast/expression_evaluator.py +228 -0
- coati_payroll/formula_engine/ast/safe_operators.py +131 -0
- coati_payroll/formula_engine/ast/type_converter.py +172 -0
- coati_payroll/formula_engine/data_sources.py +752 -0
- coati_payroll/formula_engine/engine.py +247 -0
- coati_payroll/formula_engine/exceptions.py +52 -0
- coati_payroll/formula_engine/execution/__init__.py +24 -0
- coati_payroll/formula_engine/execution/execution_context.py +52 -0
- coati_payroll/formula_engine/execution/step_executor.py +62 -0
- coati_payroll/formula_engine/execution/variable_store.py +59 -0
- coati_payroll/formula_engine/novelty_codes.py +206 -0
- coati_payroll/formula_engine/results/__init__.py +20 -0
- coati_payroll/formula_engine/results/execution_result.py +59 -0
- coati_payroll/formula_engine/steps/__init__.py +30 -0
- coati_payroll/formula_engine/steps/assignment_step.py +71 -0
- coati_payroll/formula_engine/steps/base_step.py +48 -0
- coati_payroll/formula_engine/steps/calculation_step.py +42 -0
- coati_payroll/formula_engine/steps/conditional_step.py +122 -0
- coati_payroll/formula_engine/steps/step_factory.py +58 -0
- coati_payroll/formula_engine/steps/tax_lookup_step.py +45 -0
- coati_payroll/formula_engine/tables/__init__.py +24 -0
- coati_payroll/formula_engine/tables/bracket_calculator.py +51 -0
- coati_payroll/formula_engine/tables/table_lookup.py +161 -0
- coati_payroll/formula_engine/tables/tax_table.py +32 -0
- coati_payroll/formula_engine/validation/__init__.py +24 -0
- coati_payroll/formula_engine/validation/schema_validator.py +37 -0
- coati_payroll/formula_engine/validation/security_validator.py +52 -0
- coati_payroll/formula_engine/validation/tax_table_validator.py +205 -0
- coati_payroll/formula_engine_examples.py +153 -0
- coati_payroll/i18n.py +54 -0
- coati_payroll/initial_data.py +613 -0
- coati_payroll/interes_engine.py +450 -0
- coati_payroll/liquidacion_engine/__init__.py +25 -0
- coati_payroll/liquidacion_engine/engine.py +267 -0
- coati_payroll/locale_config.py +165 -0
- coati_payroll/log.py +138 -0
- coati_payroll/model.py +2410 -0
- coati_payroll/nomina_engine/__init__.py +87 -0
- coati_payroll/nomina_engine/calculators/__init__.py +30 -0
- coati_payroll/nomina_engine/calculators/benefit_calculator.py +79 -0
- coati_payroll/nomina_engine/calculators/concept_calculator.py +254 -0
- coati_payroll/nomina_engine/calculators/deduction_calculator.py +105 -0
- coati_payroll/nomina_engine/calculators/exchange_rate_calculator.py +51 -0
- coati_payroll/nomina_engine/calculators/perception_calculator.py +75 -0
- coati_payroll/nomina_engine/calculators/salary_calculator.py +86 -0
- coati_payroll/nomina_engine/domain/__init__.py +27 -0
- coati_payroll/nomina_engine/domain/calculation_items.py +52 -0
- coati_payroll/nomina_engine/domain/employee_calculation.py +53 -0
- coati_payroll/nomina_engine/domain/payroll_context.py +44 -0
- coati_payroll/nomina_engine/engine.py +188 -0
- coati_payroll/nomina_engine/processors/__init__.py +28 -0
- coati_payroll/nomina_engine/processors/accounting_processor.py +171 -0
- coati_payroll/nomina_engine/processors/accumulation_processor.py +90 -0
- coati_payroll/nomina_engine/processors/loan_processor.py +227 -0
- coati_payroll/nomina_engine/processors/novelty_processor.py +42 -0
- coati_payroll/nomina_engine/processors/vacation_processor.py +67 -0
- coati_payroll/nomina_engine/repositories/__init__.py +32 -0
- coati_payroll/nomina_engine/repositories/acumulado_repository.py +83 -0
- coati_payroll/nomina_engine/repositories/base_repository.py +40 -0
- coati_payroll/nomina_engine/repositories/config_repository.py +102 -0
- coati_payroll/nomina_engine/repositories/employee_repository.py +34 -0
- coati_payroll/nomina_engine/repositories/exchange_rate_repository.py +58 -0
- coati_payroll/nomina_engine/repositories/novelty_repository.py +54 -0
- coati_payroll/nomina_engine/repositories/planilla_repository.py +52 -0
- coati_payroll/nomina_engine/results/__init__.py +24 -0
- coati_payroll/nomina_engine/results/error_result.py +28 -0
- coati_payroll/nomina_engine/results/payroll_result.py +53 -0
- coati_payroll/nomina_engine/results/validation_result.py +39 -0
- coati_payroll/nomina_engine/services/__init__.py +22 -0
- coati_payroll/nomina_engine/services/accounting_voucher_service.py +708 -0
- coati_payroll/nomina_engine/services/employee_processing_service.py +173 -0
- coati_payroll/nomina_engine/services/payroll_execution_service.py +374 -0
- coati_payroll/nomina_engine/services/snapshot_service.py +295 -0
- coati_payroll/nomina_engine/validators/__init__.py +31 -0
- coati_payroll/nomina_engine/validators/base_validator.py +48 -0
- coati_payroll/nomina_engine/validators/currency_validator.py +50 -0
- coati_payroll/nomina_engine/validators/employee_validator.py +87 -0
- coati_payroll/nomina_engine/validators/period_validator.py +44 -0
- coati_payroll/nomina_engine/validators/planilla_validator.py +136 -0
- coati_payroll/plugin_manager.py +176 -0
- coati_payroll/queue/__init__.py +33 -0
- coati_payroll/queue/driver.py +127 -0
- coati_payroll/queue/drivers/__init__.py +22 -0
- coati_payroll/queue/drivers/dramatiq_driver.py +268 -0
- coati_payroll/queue/drivers/huey_driver.py +390 -0
- coati_payroll/queue/drivers/noop_driver.py +54 -0
- coati_payroll/queue/selector.py +121 -0
- coati_payroll/queue/tasks.py +764 -0
- coati_payroll/rate_limiting.py +83 -0
- coati_payroll/rbac.py +183 -0
- coati_payroll/report_engine.py +512 -0
- coati_payroll/report_export.py +208 -0
- coati_payroll/schema_validator.py +167 -0
- coati_payroll/security.py +77 -0
- coati_payroll/static/styles.css +1044 -0
- coati_payroll/system_reports.py +573 -0
- coati_payroll/templates/auth/login.html +189 -0
- coati_payroll/templates/base.html +283 -0
- coati_payroll/templates/index.html +227 -0
- coati_payroll/templates/macros.html +146 -0
- coati_payroll/templates/modules/calculation_rule/form.html +78 -0
- coati_payroll/templates/modules/calculation_rule/index.html +102 -0
- coati_payroll/templates/modules/calculation_rule/schema_editor.html +1159 -0
- coati_payroll/templates/modules/carga_inicial_prestacion/form.html +170 -0
- coati_payroll/templates/modules/carga_inicial_prestacion/index.html +170 -0
- coati_payroll/templates/modules/carga_inicial_prestacion/reporte.html +193 -0
- coati_payroll/templates/modules/config_calculos/index.html +44 -0
- coati_payroll/templates/modules/configuracion/index.html +90 -0
- coati_payroll/templates/modules/currency/form.html +47 -0
- coati_payroll/templates/modules/currency/index.html +64 -0
- coati_payroll/templates/modules/custom_field/form.html +62 -0
- coati_payroll/templates/modules/custom_field/index.html +78 -0
- coati_payroll/templates/modules/deduccion/form.html +1 -0
- coati_payroll/templates/modules/deduccion/index.html +1 -0
- coati_payroll/templates/modules/employee/form.html +254 -0
- coati_payroll/templates/modules/employee/index.html +76 -0
- coati_payroll/templates/modules/empresa/form.html +74 -0
- coati_payroll/templates/modules/empresa/index.html +71 -0
- coati_payroll/templates/modules/exchange_rate/form.html +47 -0
- coati_payroll/templates/modules/exchange_rate/import.html +93 -0
- coati_payroll/templates/modules/exchange_rate/index.html +114 -0
- coati_payroll/templates/modules/liquidacion/index.html +58 -0
- coati_payroll/templates/modules/liquidacion/nueva.html +51 -0
- coati_payroll/templates/modules/liquidacion/ver.html +91 -0
- coati_payroll/templates/modules/payroll_concepts/audit_log.html +146 -0
- coati_payroll/templates/modules/percepcion/form.html +1 -0
- coati_payroll/templates/modules/percepcion/index.html +1 -0
- coati_payroll/templates/modules/planilla/config.html +190 -0
- coati_payroll/templates/modules/planilla/config_deducciones.html +129 -0
- coati_payroll/templates/modules/planilla/config_empleados.html +116 -0
- coati_payroll/templates/modules/planilla/config_percepciones.html +113 -0
- coati_payroll/templates/modules/planilla/config_prestaciones.html +118 -0
- coati_payroll/templates/modules/planilla/config_reglas.html +120 -0
- coati_payroll/templates/modules/planilla/ejecutar_nomina.html +106 -0
- coati_payroll/templates/modules/planilla/form.html +197 -0
- coati_payroll/templates/modules/planilla/index.html +144 -0
- coati_payroll/templates/modules/planilla/listar_nominas.html +91 -0
- coati_payroll/templates/modules/planilla/log_nomina.html +135 -0
- coati_payroll/templates/modules/planilla/novedades/form.html +177 -0
- coati_payroll/templates/modules/planilla/novedades/index.html +170 -0
- coati_payroll/templates/modules/planilla/ver_nomina.html +477 -0
- coati_payroll/templates/modules/planilla/ver_nomina_empleado.html +231 -0
- coati_payroll/templates/modules/plugins/index.html +71 -0
- coati_payroll/templates/modules/prestacion/form.html +1 -0
- coati_payroll/templates/modules/prestacion/index.html +1 -0
- coati_payroll/templates/modules/prestacion_management/dashboard.html +150 -0
- coati_payroll/templates/modules/prestacion_management/initial_balance_bulk.html +195 -0
- coati_payroll/templates/modules/prestamo/approve.html +156 -0
- coati_payroll/templates/modules/prestamo/condonacion.html +249 -0
- coati_payroll/templates/modules/prestamo/detail.html +443 -0
- coati_payroll/templates/modules/prestamo/form.html +203 -0
- coati_payroll/templates/modules/prestamo/index.html +150 -0
- coati_payroll/templates/modules/prestamo/pago_extraordinario.html +211 -0
- coati_payroll/templates/modules/prestamo/tabla_pago_pdf.html +181 -0
- coati_payroll/templates/modules/report/admin_index.html +125 -0
- coati_payroll/templates/modules/report/detail.html +129 -0
- coati_payroll/templates/modules/report/execute.html +266 -0
- coati_payroll/templates/modules/report/index.html +95 -0
- coati_payroll/templates/modules/report/permissions.html +64 -0
- coati_payroll/templates/modules/settings/index.html +274 -0
- coati_payroll/templates/modules/shared/concept_form.html +201 -0
- coati_payroll/templates/modules/shared/concept_index.html +145 -0
- coati_payroll/templates/modules/tipo_planilla/form.html +70 -0
- coati_payroll/templates/modules/tipo_planilla/index.html +68 -0
- coati_payroll/templates/modules/user/form.html +65 -0
- coati_payroll/templates/modules/user/index.html +76 -0
- coati_payroll/templates/modules/user/profile.html +81 -0
- coati_payroll/templates/modules/vacation/account_detail.html +149 -0
- coati_payroll/templates/modules/vacation/account_form.html +52 -0
- coati_payroll/templates/modules/vacation/account_index.html +68 -0
- coati_payroll/templates/modules/vacation/dashboard.html +156 -0
- coati_payroll/templates/modules/vacation/initial_balance_bulk.html +149 -0
- coati_payroll/templates/modules/vacation/initial_balance_form.html +93 -0
- coati_payroll/templates/modules/vacation/leave_request_detail.html +158 -0
- coati_payroll/templates/modules/vacation/leave_request_form.html +61 -0
- coati_payroll/templates/modules/vacation/leave_request_index.html +98 -0
- coati_payroll/templates/modules/vacation/policy_detail.html +176 -0
- coati_payroll/templates/modules/vacation/policy_form.html +152 -0
- coati_payroll/templates/modules/vacation/policy_index.html +79 -0
- coati_payroll/templates/modules/vacation/register_taken_form.html +178 -0
- coati_payroll/translations/en/LC_MESSAGES/messages.mo +0 -0
- coati_payroll/translations/en/LC_MESSAGES/messages.po +7283 -0
- coati_payroll/translations/es/LC_MESSAGES/messages.mo +0 -0
- coati_payroll/translations/es/LC_MESSAGES/messages.po +7374 -0
- coati_payroll/vacation_service.py +451 -0
- coati_payroll/version.py +18 -0
- coati_payroll/vistas/__init__.py +64 -0
- coati_payroll/vistas/calculation_rule.py +307 -0
- coati_payroll/vistas/carga_inicial_prestacion.py +423 -0
- coati_payroll/vistas/config_calculos.py +72 -0
- coati_payroll/vistas/configuracion.py +87 -0
- coati_payroll/vistas/constants.py +17 -0
- coati_payroll/vistas/currency.py +112 -0
- coati_payroll/vistas/custom_field.py +120 -0
- coati_payroll/vistas/employee.py +305 -0
- coati_payroll/vistas/empresa.py +153 -0
- coati_payroll/vistas/exchange_rate.py +341 -0
- coati_payroll/vistas/liquidacion.py +205 -0
- coati_payroll/vistas/payroll_concepts.py +580 -0
- coati_payroll/vistas/planilla/__init__.py +38 -0
- coati_payroll/vistas/planilla/association_routes.py +238 -0
- coati_payroll/vistas/planilla/config_routes.py +158 -0
- coati_payroll/vistas/planilla/export_routes.py +175 -0
- coati_payroll/vistas/planilla/helpers/__init__.py +34 -0
- coati_payroll/vistas/planilla/helpers/association_helpers.py +161 -0
- coati_payroll/vistas/planilla/helpers/excel_helpers.py +29 -0
- coati_payroll/vistas/planilla/helpers/form_helpers.py +97 -0
- coati_payroll/vistas/planilla/nomina_routes.py +488 -0
- coati_payroll/vistas/planilla/novedad_routes.py +227 -0
- coati_payroll/vistas/planilla/routes.py +145 -0
- coati_payroll/vistas/planilla/services/__init__.py +26 -0
- coati_payroll/vistas/planilla/services/export_service.py +687 -0
- coati_payroll/vistas/planilla/services/nomina_service.py +233 -0
- coati_payroll/vistas/planilla/services/novedad_service.py +126 -0
- coati_payroll/vistas/planilla/services/planilla_service.py +34 -0
- coati_payroll/vistas/planilla/validators/__init__.py +18 -0
- coati_payroll/vistas/planilla/validators/planilla_validators.py +40 -0
- coati_payroll/vistas/plugins.py +45 -0
- coati_payroll/vistas/prestacion.py +272 -0
- coati_payroll/vistas/prestamo.py +808 -0
- coati_payroll/vistas/report.py +432 -0
- coati_payroll/vistas/settings.py +29 -0
- coati_payroll/vistas/tipo_planilla.py +134 -0
- coati_payroll/vistas/user.py +172 -0
- coati_payroll/vistas/vacation.py +1045 -0
- coati_payroll-0.0.2.dist-info/LICENSE +201 -0
- coati_payroll-0.0.2.dist-info/METADATA +581 -0
- coati_payroll-0.0.2.dist-info/RECORD +243 -0
- coati_payroll-0.0.2.dist-info/WHEEL +5 -0
- coati_payroll-0.0.2.dist-info/entry_points.txt +2 -0
- coati_payroll-0.0.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{% extends "base.html" %}
|
|
2
|
+
|
|
3
|
+
{% block content %}
|
|
4
|
+
<div class="container-fluid">
|
|
5
|
+
<div class="row mb-4">
|
|
6
|
+
<div class="col">
|
|
7
|
+
<h2><i class="bi bi-gear me-2"></i>{{ _('Configuración Global') }}</h2>
|
|
8
|
+
<p class="text-muted">{{ _('Configure las opciones generales del sistema') }}</p>
|
|
9
|
+
</div>
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
<!-- Flash messages -->
|
|
13
|
+
{% with messages = get_flashed_messages(with_categories=true) %}
|
|
14
|
+
{% if messages %}
|
|
15
|
+
{% for category, message in messages %}
|
|
16
|
+
<div class="alert alert-{{ category }} alert-dismissible fade show" role="alert">
|
|
17
|
+
{{ message }}
|
|
18
|
+
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
|
19
|
+
</div>
|
|
20
|
+
{% endfor %}
|
|
21
|
+
{% endif %}
|
|
22
|
+
{% endwith %}
|
|
23
|
+
|
|
24
|
+
<div class="row">
|
|
25
|
+
<div class="col-lg-6">
|
|
26
|
+
<div class="card">
|
|
27
|
+
<div class="card-header">
|
|
28
|
+
<h5 class="mb-0"><i class="bi bi-translate me-2"></i>{{ _('Idioma del Sistema') }}</h5>
|
|
29
|
+
</div>
|
|
30
|
+
<div class="card-body">
|
|
31
|
+
<p class="text-muted">{{ _('Seleccione el idioma predeterminado para la aplicación') }}</p>
|
|
32
|
+
|
|
33
|
+
<form method="POST" action="{{ url_for('configuracion.cambiar_idioma') }}">
|
|
34
|
+
<div class="mb-3">
|
|
35
|
+
<label for="idioma" class="form-label">{{ _('Idioma') }}</label>
|
|
36
|
+
<select class="form-select" id="idioma" name="idioma" required>
|
|
37
|
+
{% for lang in supported_languages %}
|
|
38
|
+
<option value="{{ lang }}" {% if lang == current_language %}selected{% endif %}>
|
|
39
|
+
{{ language_names[lang] }}
|
|
40
|
+
</option>
|
|
41
|
+
{% endfor %}
|
|
42
|
+
</select>
|
|
43
|
+
<div class="form-text">
|
|
44
|
+
{{ _('Los cambios se aplicarán inmediatamente') }}
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<div class="d-flex gap-2">
|
|
49
|
+
<button type="submit" class="btn btn-primary">
|
|
50
|
+
<i class="bi bi-check-circle me-1"></i>{{ _('Guardar Cambios') }}
|
|
51
|
+
</button>
|
|
52
|
+
<a href="{{ url_for('app.index') }}" class="btn btn-secondary">
|
|
53
|
+
<i class="bi bi-x-circle me-1"></i>{{ _('Cancelar') }}
|
|
54
|
+
</a>
|
|
55
|
+
</div>
|
|
56
|
+
</form>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
<div class="col-lg-6">
|
|
62
|
+
<div class="card">
|
|
63
|
+
<div class="card-header">
|
|
64
|
+
<h5 class="mb-0"><i class="bi bi-info-circle me-2"></i>{{ _('Información') }}</h5>
|
|
65
|
+
</div>
|
|
66
|
+
<div class="card-body">
|
|
67
|
+
<h6>{{ _('Idioma Actual') }}</h6>
|
|
68
|
+
<p class="lead">{{ language_names[current_language] }}</p>
|
|
69
|
+
|
|
70
|
+
<hr>
|
|
71
|
+
|
|
72
|
+
<h6>{{ _('Idiomas Disponibles') }}</h6>
|
|
73
|
+
<ul>
|
|
74
|
+
<li><strong>English</strong> - {{ _('Inglés') }}</li>
|
|
75
|
+
<li><strong>Español</strong> - {{ _('Español') }}</li>
|
|
76
|
+
</ul>
|
|
77
|
+
|
|
78
|
+
<hr>
|
|
79
|
+
|
|
80
|
+
<h6>{{ _('Variable de Entorno') }}</h6>
|
|
81
|
+
<p class="small text-muted">
|
|
82
|
+
{{ _('Puede configurar el idioma inicial usando la variable de entorno') }}
|
|
83
|
+
<code>COATI_LANG</code> ({{ _('valores: en, es') }})
|
|
84
|
+
</p>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
{% endblock %}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{% extends 'base.html' %}
|
|
2
|
+
{% from 'macros.html' import render_field, render_messages, render_form_errors %}
|
|
3
|
+
|
|
4
|
+
{% block content %}
|
|
5
|
+
<div class="container">
|
|
6
|
+
{{ render_messages() }}
|
|
7
|
+
{{ render_form_errors(form) }}
|
|
8
|
+
|
|
9
|
+
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
10
|
+
<h2>{{ title }}</h2>
|
|
11
|
+
<a href="{{ url_for('currency.index') }}" class="btn btn-secondary">
|
|
12
|
+
<i class="bi bi-arrow-left me-1"></i>{{ _('Volver') }}
|
|
13
|
+
</a>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<div class="card">
|
|
17
|
+
<div class="card-body">
|
|
18
|
+
<form method="POST" action="">
|
|
19
|
+
{{ form.hidden_tag() }}
|
|
20
|
+
|
|
21
|
+
<div class="row">
|
|
22
|
+
<div class="col-md-4">
|
|
23
|
+
{{ render_field(form.codigo) }}
|
|
24
|
+
</div>
|
|
25
|
+
<div class="col-md-4">
|
|
26
|
+
{{ render_field(form.nombre) }}
|
|
27
|
+
</div>
|
|
28
|
+
<div class="col-md-4">
|
|
29
|
+
{{ render_field(form.simbolo) }}
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<div class="row">
|
|
34
|
+
<div class="col-md-6">
|
|
35
|
+
{{ render_field(form.activo) }}
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
<div class="mt-4">
|
|
40
|
+
{{ form.submit(class="btn btn-primary") }}
|
|
41
|
+
<a href="{{ url_for('currency.index') }}" class="btn btn-secondary">{{ _('Cancelar') }}</a>
|
|
42
|
+
</div>
|
|
43
|
+
</form>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
{% endblock %}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{% extends 'base.html' %}
|
|
2
|
+
{% from 'macros.html' import render_messages, render_pagination %}
|
|
3
|
+
|
|
4
|
+
{% block content %}
|
|
5
|
+
<div class="container">
|
|
6
|
+
{{ render_messages() }}
|
|
7
|
+
|
|
8
|
+
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
9
|
+
<h2>{{ _('Monedas') }}</h2>
|
|
10
|
+
<a href="{{ url_for('currency.new') }}" class="btn btn-primary">
|
|
11
|
+
<i class="bi bi-plus-lg me-1"></i>{{ _('Nueva Moneda') }}
|
|
12
|
+
</a>
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
<div class="card">
|
|
16
|
+
<div class="card-body">
|
|
17
|
+
<div class="table-responsive">
|
|
18
|
+
<table class="table table-hover">
|
|
19
|
+
<thead>
|
|
20
|
+
<tr>
|
|
21
|
+
<th>{{ _('Código') }}</th>
|
|
22
|
+
<th>{{ _('Nombre') }}</th>
|
|
23
|
+
<th>{{ _('Símbolo') }}</th>
|
|
24
|
+
<th>{{ _('Estado') }}</th>
|
|
25
|
+
<th>{{ _('Acciones') }}</th>
|
|
26
|
+
</tr>
|
|
27
|
+
</thead>
|
|
28
|
+
<tbody>
|
|
29
|
+
{% for currency in currencies %}
|
|
30
|
+
<tr>
|
|
31
|
+
<td><strong>{{ currency.codigo }}</strong></td>
|
|
32
|
+
<td>{{ currency.nombre }}</td>
|
|
33
|
+
<td>{{ currency.simbolo or '-' }}</td>
|
|
34
|
+
<td>
|
|
35
|
+
{% if currency.activo %}
|
|
36
|
+
<span class="badge bg-success">{{ _('Activo') }}</span>
|
|
37
|
+
{% else %}
|
|
38
|
+
<span class="badge bg-warning">{{ _('Inactivo') }}</span>
|
|
39
|
+
{% endif %}
|
|
40
|
+
</td>
|
|
41
|
+
<td>
|
|
42
|
+
<a href="{{ url_for('currency.edit', id=currency.id) }}" class="btn btn-sm btn-outline-primary" title="{{ _('Editar') }}">
|
|
43
|
+
<i class="bi bi-pencil"></i>
|
|
44
|
+
</a>
|
|
45
|
+
<form action="{{ url_for('currency.delete', id=currency.id) }}" method="POST" class="d-inline" onsubmit="return confirm('{{ _('¿Está seguro de eliminar esta moneda?') }}');">
|
|
46
|
+
<button type="submit" class="btn btn-sm btn-outline-danger" title="{{ _('Eliminar') }}">
|
|
47
|
+
<i class="bi bi-trash"></i>
|
|
48
|
+
</button>
|
|
49
|
+
</form>
|
|
50
|
+
</td>
|
|
51
|
+
</tr>
|
|
52
|
+
{% else %}
|
|
53
|
+
<tr>
|
|
54
|
+
<td colspan="5" class="text-center text-muted">{{ _('No hay monedas registradas.') }}</td>
|
|
55
|
+
</tr>
|
|
56
|
+
{% endfor %}
|
|
57
|
+
</tbody>
|
|
58
|
+
</table>
|
|
59
|
+
</div>
|
|
60
|
+
{{ render_pagination(pagination, 'currency.index') }}
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
{% endblock %}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{% extends 'base.html' %}
|
|
2
|
+
{% from 'macros.html' import render_field, render_messages, render_form_errors %}
|
|
3
|
+
|
|
4
|
+
{% block content %}
|
|
5
|
+
<div class="container">
|
|
6
|
+
{{ render_messages() }}
|
|
7
|
+
{{ render_form_errors(form) }}
|
|
8
|
+
|
|
9
|
+
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
10
|
+
<h2>{{ title }}</h2>
|
|
11
|
+
<a href="{{ url_for('custom_field.index') }}" class="btn btn-secondary">
|
|
12
|
+
<i class="bi bi-arrow-left me-1"></i>{{ _('Volver') }}
|
|
13
|
+
</a>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<div class="card">
|
|
17
|
+
<div class="card-body">
|
|
18
|
+
<form method="POST" action="">
|
|
19
|
+
{{ form.hidden_tag() }}
|
|
20
|
+
|
|
21
|
+
<div class="row">
|
|
22
|
+
<div class="col-md-6">
|
|
23
|
+
{{ render_field(form.nombre_campo) }}
|
|
24
|
+
<small class="text-muted">{{ _('Use un nombre único sin espacios ni caracteres especiales (ej: numero_hijos)') }}</small>
|
|
25
|
+
</div>
|
|
26
|
+
<div class="col-md-6">
|
|
27
|
+
{{ render_field(form.etiqueta) }}
|
|
28
|
+
<small class="text-muted">{{ _('Este nombre será visible en el formulario de empleados (ej: Número de hijos)') }}</small>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<div class="row mt-3">
|
|
33
|
+
<div class="col-md-6">
|
|
34
|
+
{{ render_field(form.tipo_dato) }}
|
|
35
|
+
</div>
|
|
36
|
+
<div class="col-md-6">
|
|
37
|
+
{{ render_field(form.orden) }}
|
|
38
|
+
<small class="text-muted">{{ _('Los campos se mostrarán ordenados de menor a mayor') }}</small>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
<div class="row mt-3">
|
|
43
|
+
<div class="col-md-12">
|
|
44
|
+
{{ render_field(form.descripcion) }}
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<div class="row mt-3">
|
|
49
|
+
<div class="col-md-6">
|
|
50
|
+
{{ render_field(form.activo) }}
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
<div class="mt-4">
|
|
55
|
+
{{ form.submit(class="btn btn-primary") }}
|
|
56
|
+
<a href="{{ url_for('custom_field.index') }}" class="btn btn-secondary">{{ _('Cancelar') }}</a>
|
|
57
|
+
</div>
|
|
58
|
+
</form>
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
{% endblock %}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{% extends 'base.html' %}
|
|
2
|
+
{% from 'macros.html' import render_messages, render_pagination %}
|
|
3
|
+
|
|
4
|
+
{% block content %}
|
|
5
|
+
<div class="container">
|
|
6
|
+
{{ render_messages() }}
|
|
7
|
+
|
|
8
|
+
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
9
|
+
<h2>{{ _('Campos Personalizados de Empleado') }}</h2>
|
|
10
|
+
<a href="{{ url_for('custom_field.new') }}" class="btn btn-primary">
|
|
11
|
+
<i class="bi bi-plus-lg me-1"></i>{{ _('Nuevo Campo') }}
|
|
12
|
+
</a>
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
<div class="card">
|
|
16
|
+
<div class="card-body">
|
|
17
|
+
<div class="table-responsive">
|
|
18
|
+
<table class="table table-hover">
|
|
19
|
+
<thead>
|
|
20
|
+
<tr>
|
|
21
|
+
<th>{{ _('Orden') }}</th>
|
|
22
|
+
<th>{{ _('Nombre del Campo') }}</th>
|
|
23
|
+
<th>{{ _('Etiqueta') }}</th>
|
|
24
|
+
<th>{{ _('Tipo de Dato') }}</th>
|
|
25
|
+
<th>{{ _('Estado') }}</th>
|
|
26
|
+
<th>{{ _('Acciones') }}</th>
|
|
27
|
+
</tr>
|
|
28
|
+
</thead>
|
|
29
|
+
<tbody>
|
|
30
|
+
{% for custom_field in custom_fields %}
|
|
31
|
+
<tr>
|
|
32
|
+
<td>{{ custom_field.orden }}</td>
|
|
33
|
+
<td><strong>{{ custom_field.nombre_campo }}</strong></td>
|
|
34
|
+
<td>{{ custom_field.etiqueta }}</td>
|
|
35
|
+
<td>
|
|
36
|
+
{% if custom_field.tipo_dato == 'texto' %}
|
|
37
|
+
<span class="badge bg-info">{{ _('Texto') }}</span>
|
|
38
|
+
{% elif custom_field.tipo_dato == 'entero' %}
|
|
39
|
+
<span class="badge bg-primary">{{ _('Número entero') }}</span>
|
|
40
|
+
{% elif custom_field.tipo_dato == 'decimal' %}
|
|
41
|
+
<span class="badge bg-secondary">{{ _('Número decimal') }}</span>
|
|
42
|
+
{% elif custom_field.tipo_dato == 'booleano' %}
|
|
43
|
+
<span class="badge bg-dark">{{ _('Verdadero/Falso') }}</span>
|
|
44
|
+
{% else %}
|
|
45
|
+
{{ custom_field.tipo_dato }}
|
|
46
|
+
{% endif %}
|
|
47
|
+
</td>
|
|
48
|
+
<td>
|
|
49
|
+
{% if custom_field.activo %}
|
|
50
|
+
<span class="badge bg-success">{{ _('Activo') }}</span>
|
|
51
|
+
{% else %}
|
|
52
|
+
<span class="badge bg-warning">{{ _('Inactivo') }}</span>
|
|
53
|
+
{% endif %}
|
|
54
|
+
</td>
|
|
55
|
+
<td>
|
|
56
|
+
<a href="{{ url_for('custom_field.edit', id=custom_field.id) }}" class="btn btn-sm btn-outline-primary" title="{{ _('Editar') }}">
|
|
57
|
+
<i class="bi bi-pencil"></i>
|
|
58
|
+
</a>
|
|
59
|
+
<form action="{{ url_for('custom_field.delete', id=custom_field.id) }}" method="POST" class="d-inline" onsubmit="return confirm('{{ _('¿Está seguro de eliminar este campo personalizado?') }}');">
|
|
60
|
+
<button type="submit" class="btn btn-sm btn-outline-danger" title="{{ _('Eliminar') }}">
|
|
61
|
+
<i class="bi bi-trash"></i>
|
|
62
|
+
</button>
|
|
63
|
+
</form>
|
|
64
|
+
</td>
|
|
65
|
+
</tr>
|
|
66
|
+
{% else %}
|
|
67
|
+
<tr>
|
|
68
|
+
<td colspan="6" class="text-center text-muted">{{ _('No hay campos personalizados registrados.') }}</td>
|
|
69
|
+
</tr>
|
|
70
|
+
{% endfor %}
|
|
71
|
+
</tbody>
|
|
72
|
+
</table>
|
|
73
|
+
</div>
|
|
74
|
+
{{ render_pagination(pagination, 'custom_field.index') }}
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
{% endblock %}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{% extends "modules/shared/concept_form.html" %}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{% extends "modules/shared/concept_index.html" %}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
{% extends 'base.html' %}
|
|
2
|
+
{% from 'macros.html' import render_field, render_messages, render_form_errors %}
|
|
3
|
+
|
|
4
|
+
{% block content %}
|
|
5
|
+
<div class="container">
|
|
6
|
+
{{ render_messages() }}
|
|
7
|
+
{{ render_form_errors(form) }}
|
|
8
|
+
|
|
9
|
+
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
10
|
+
<h2>{{ title }}</h2>
|
|
11
|
+
<a href="{{ url_for('employee.index') }}" class="btn btn-secondary">
|
|
12
|
+
<i class="bi bi-arrow-left me-1"></i>{{ _('Volver') }}
|
|
13
|
+
</a>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<div class="card">
|
|
17
|
+
<div class="card-body">
|
|
18
|
+
<form method="POST" action="">
|
|
19
|
+
{{ form.hidden_tag() }}
|
|
20
|
+
|
|
21
|
+
<h5 class="mb-3">{{ _('Información Personal') }}</h5>
|
|
22
|
+
<div class="row">
|
|
23
|
+
<div class="col-md-3">
|
|
24
|
+
{{ render_field(form.primer_nombre) }}
|
|
25
|
+
</div>
|
|
26
|
+
<div class="col-md-3">
|
|
27
|
+
{{ render_field(form.segundo_nombre) }}
|
|
28
|
+
</div>
|
|
29
|
+
<div class="col-md-3">
|
|
30
|
+
{{ render_field(form.primer_apellido) }}
|
|
31
|
+
</div>
|
|
32
|
+
<div class="col-md-3">
|
|
33
|
+
{{ render_field(form.segundo_apellido) }}
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<div class="row">
|
|
38
|
+
<div class="col-md-4">
|
|
39
|
+
{{ render_field(form.tipo_identificacion) }}
|
|
40
|
+
</div>
|
|
41
|
+
<div class="col-md-4">
|
|
42
|
+
{{ render_field(form.identificacion_personal) }}
|
|
43
|
+
</div>
|
|
44
|
+
<div class="col-md-4">
|
|
45
|
+
{{ render_field(form.fecha_nacimiento) }}
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<div class="row">
|
|
50
|
+
<div class="col-md-4">
|
|
51
|
+
{{ render_field(form.id_seguridad_social) }}
|
|
52
|
+
</div>
|
|
53
|
+
<div class="col-md-4">
|
|
54
|
+
{{ render_field(form.id_fiscal) }}
|
|
55
|
+
</div>
|
|
56
|
+
<div class="col-md-4">
|
|
57
|
+
{{ render_field(form.genero) }}
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
<div class="row">
|
|
62
|
+
<div class="col-md-4">
|
|
63
|
+
{{ render_field(form.nacionalidad) }}
|
|
64
|
+
</div>
|
|
65
|
+
<div class="col-md-4">
|
|
66
|
+
{{ render_field(form.tipo_sangre) }}
|
|
67
|
+
</div>
|
|
68
|
+
<div class="col-md-4">
|
|
69
|
+
{{ render_field(form.estado_civil) }}
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<hr class="my-4">
|
|
74
|
+
<h5 class="mb-3">{{ _('Información Laboral') }}</h5>
|
|
75
|
+
|
|
76
|
+
<div class="row">
|
|
77
|
+
<div class="col-md-4">
|
|
78
|
+
{{ render_field(form.codigo_empleado) }}
|
|
79
|
+
</div>
|
|
80
|
+
<div class="col-md-4">
|
|
81
|
+
{{ render_field(form.fecha_alta) }}
|
|
82
|
+
</div>
|
|
83
|
+
<div class="col-md-4">
|
|
84
|
+
{{ render_field(form.fecha_baja) }}
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
|
|
88
|
+
<div class="row">
|
|
89
|
+
<div class="col-md-4">
|
|
90
|
+
{{ render_field(form.tipo_contrato) }}
|
|
91
|
+
</div>
|
|
92
|
+
<div class="col-md-4">
|
|
93
|
+
{{ render_field(form.cargo) }}
|
|
94
|
+
</div>
|
|
95
|
+
<div class="col-md-4">
|
|
96
|
+
{{ render_field(form.area) }}
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
|
|
100
|
+
<div class="row">
|
|
101
|
+
<div class="col-md-4">
|
|
102
|
+
{{ render_field(form.centro_costos) }}
|
|
103
|
+
</div>
|
|
104
|
+
<div class="col-md-4">
|
|
105
|
+
{{ render_field(form.salario_base) }}
|
|
106
|
+
</div>
|
|
107
|
+
<div class="col-md-4">
|
|
108
|
+
{{ render_field(form.moneda_id) }}
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
|
|
112
|
+
<div class="row">
|
|
113
|
+
<div class="col-md-4">
|
|
114
|
+
{{ render_field(form.empresa_id) }}
|
|
115
|
+
</div>
|
|
116
|
+
<div class="col-md-4">
|
|
117
|
+
{{ render_field(form.activo) }}
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
|
|
121
|
+
<hr class="my-4">
|
|
122
|
+
<h5 class="mb-3">{{ _('Información de Contacto') }}</h5>
|
|
123
|
+
|
|
124
|
+
<div class="row">
|
|
125
|
+
<div class="col-md-6">
|
|
126
|
+
{{ render_field(form.correo) }}
|
|
127
|
+
</div>
|
|
128
|
+
<div class="col-md-6">
|
|
129
|
+
{{ render_field(form.telefono) }}
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
|
|
133
|
+
<div class="row">
|
|
134
|
+
<div class="col-md-12">
|
|
135
|
+
{{ render_field(form.direccion) }}
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
|
|
139
|
+
<hr class="my-4">
|
|
140
|
+
<h5 class="mb-3">{{ _('Información Bancaria') }}</h5>
|
|
141
|
+
|
|
142
|
+
<div class="row">
|
|
143
|
+
<div class="col-md-6">
|
|
144
|
+
{{ render_field(form.banco) }}
|
|
145
|
+
</div>
|
|
146
|
+
<div class="col-md-6">
|
|
147
|
+
{{ render_field(form.numero_cuenta_bancaria) }}
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
|
|
151
|
+
<hr class="my-4">
|
|
152
|
+
<h5 class="mb-3">
|
|
153
|
+
<i class="bi bi-calendar-check me-2"></i>{{ _('Datos Iniciales de Implementación') }}
|
|
154
|
+
</h5>
|
|
155
|
+
<p class="text-muted small mb-3">{{ _('Estos campos almacenan saldos acumulados cuando el sistema se implementa a mitad de un período fiscal.') }}</p>
|
|
156
|
+
|
|
157
|
+
<div class="row">
|
|
158
|
+
<div class="col-md-4">
|
|
159
|
+
{{ render_field(form.anio_implementacion_inicial) }}
|
|
160
|
+
</div>
|
|
161
|
+
<div class="col-md-4">
|
|
162
|
+
{{ render_field(form.mes_ultimo_cierre) }}
|
|
163
|
+
</div>
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
<div class="row">
|
|
167
|
+
<div class="col-md-6">
|
|
168
|
+
{{ render_field(form.salario_acumulado) }}
|
|
169
|
+
</div>
|
|
170
|
+
<div class="col-md-6">
|
|
171
|
+
{{ render_field(form.impuesto_acumulado) }}
|
|
172
|
+
</div>
|
|
173
|
+
</div>
|
|
174
|
+
|
|
175
|
+
<p class="text-muted small mb-3">{{ _('Últimos tres salarios mensuales antes de la implementación:') }}</p>
|
|
176
|
+
<div class="row">
|
|
177
|
+
<div class="col-md-4">
|
|
178
|
+
{{ render_field(form.ultimo_salario_1) }}
|
|
179
|
+
</div>
|
|
180
|
+
<div class="col-md-4">
|
|
181
|
+
{{ render_field(form.ultimo_salario_2) }}
|
|
182
|
+
</div>
|
|
183
|
+
<div class="col-md-4">
|
|
184
|
+
{{ render_field(form.ultimo_salario_3) }}
|
|
185
|
+
</div>
|
|
186
|
+
</div>
|
|
187
|
+
|
|
188
|
+
{% if custom_fields %}
|
|
189
|
+
<hr class="my-4">
|
|
190
|
+
<h5 class="mb-3">
|
|
191
|
+
<i class="bi bi-input-cursor-text me-2"></i>{{ _('Campos Personalizados') }}
|
|
192
|
+
</h5>
|
|
193
|
+
<p class="text-muted small mb-3">{{ _('Estos campos son personalizados y pueden ser configurados desde el menú de Configuración.') }}</p>
|
|
194
|
+
|
|
195
|
+
<div class="row">
|
|
196
|
+
{% for field in custom_fields %}
|
|
197
|
+
<div class="col-md-4">
|
|
198
|
+
<div class="mb-3">
|
|
199
|
+
{% if field.tipo_dato == 'booleano' %}
|
|
200
|
+
{# Checkbox for boolean fields #}
|
|
201
|
+
<div class="form-check">
|
|
202
|
+
<input type="checkbox"
|
|
203
|
+
class="form-check-input"
|
|
204
|
+
name="custom_{{ field.nombre_campo }}"
|
|
205
|
+
id="custom_{{ field.nombre_campo }}"
|
|
206
|
+
{% if custom_values.get(field.nombre_campo) %}checked{% endif %}>
|
|
207
|
+
<label class="form-check-label" for="custom_{{ field.nombre_campo }}">
|
|
208
|
+
{{ field.etiqueta }}
|
|
209
|
+
</label>
|
|
210
|
+
</div>
|
|
211
|
+
{% else %}
|
|
212
|
+
<label class="form-label" for="custom_{{ field.nombre_campo }}">
|
|
213
|
+
{{ field.etiqueta }}
|
|
214
|
+
</label>
|
|
215
|
+
{% if field.tipo_dato == 'texto' %}
|
|
216
|
+
<input type="text"
|
|
217
|
+
class="form-control"
|
|
218
|
+
name="custom_{{ field.nombre_campo }}"
|
|
219
|
+
id="custom_{{ field.nombre_campo }}"
|
|
220
|
+
value="{{ custom_values.get(field.nombre_campo) or '' }}">
|
|
221
|
+
{% elif field.tipo_dato == 'entero' %}
|
|
222
|
+
<input type="number"
|
|
223
|
+
class="form-control"
|
|
224
|
+
name="custom_{{ field.nombre_campo }}"
|
|
225
|
+
id="custom_{{ field.nombre_campo }}"
|
|
226
|
+
step="1"
|
|
227
|
+
value="{{ custom_values.get(field.nombre_campo) or '' }}">
|
|
228
|
+
{% elif field.tipo_dato == 'decimal' %}
|
|
229
|
+
<input type="number"
|
|
230
|
+
class="form-control"
|
|
231
|
+
name="custom_{{ field.nombre_campo }}"
|
|
232
|
+
id="custom_{{ field.nombre_campo }}"
|
|
233
|
+
step="0.01"
|
|
234
|
+
value="{{ custom_values.get(field.nombre_campo) or '' }}">
|
|
235
|
+
{% endif %}
|
|
236
|
+
{% endif %}
|
|
237
|
+
{% if field.descripcion %}
|
|
238
|
+
<small class="text-muted">{{ field.descripcion }}</small>
|
|
239
|
+
{% endif %}
|
|
240
|
+
</div>
|
|
241
|
+
</div>
|
|
242
|
+
{% endfor %}
|
|
243
|
+
</div>
|
|
244
|
+
{% endif %}
|
|
245
|
+
|
|
246
|
+
<div class="mt-4">
|
|
247
|
+
{{ form.submit(class="btn btn-primary") }}
|
|
248
|
+
<a href="{{ url_for('employee.index') }}" class="btn btn-secondary">{{ _('Cancelar') }}</a>
|
|
249
|
+
</div>
|
|
250
|
+
</form>
|
|
251
|
+
</div>
|
|
252
|
+
</div>
|
|
253
|
+
</div>
|
|
254
|
+
{% endblock %}
|