Refactor pedimento-related interfaces and forms to standardize date and payment fields
- Updated `PedimentoDates`, `PedimentoPayments`, `PedimentoTransportMeans`, and `PedimentoValidation` interfaces to include new fields and rename existing ones for consistency. - Modified forms in Svelte components to reflect the updated interfaces, including new input fields for various dates and payment details. - Enhanced status handling in the dashboard to accommodate new status options and improve user feedback. - Implemented token validation on the server-side to ensure secure access to the dashboard. - Cleaned up login logic to prevent redirection loops when tokens are present but potentially expired.
This commit is contained in:
@@ -1,11 +1,10 @@
|
||||
"""
|
||||
Modelos ORM para gestión de clientes y proveedores
|
||||
"""
|
||||
from sqlalchemy import Column, Integer, String, DateTime, Boolean, Text, SmallInteger, Numeric, ForeignKey
|
||||
from sqlalchemy import Column, Integer, String, SmallInteger, Numeric, ForeignKey
|
||||
from sqlalchemy.sql import func
|
||||
from sqlalchemy.orm import relationship
|
||||
from core.database import Base
|
||||
import enum
|
||||
|
||||
|
||||
class ClientProvider(Base):
|
||||
@@ -17,7 +16,7 @@ class ClientProvider(Base):
|
||||
|
||||
# Primary key
|
||||
client_id = Column(String(8), primary_key=True, nullable=False)
|
||||
|
||||
|
||||
# Basic information
|
||||
type_nat_foreign = Column(String(1), nullable=True) # TIPO NACIONAL/EXTRANJERO
|
||||
name = Column(String(256), nullable=True)
|
||||
@@ -36,15 +35,15 @@ class ClientProvider(Base):
|
||||
enabled_disabled = Column(SmallInteger, nullable=True)
|
||||
|
||||
# Relationships
|
||||
address = relationship("GClientProviderAddress", back_populates="client_provider", uselist=False, cascade="all, delete-orphan")
|
||||
programs = relationship("GClientProviderPrograms", back_populates="client_provider", uselist=False, cascade="all, delete-orphan")
|
||||
address = relationship("ClientProviderAddress", back_populates="client_provider", uselist=False, cascade="all, delete-orphan")
|
||||
programs = relationship("ClientProviderPrograms", back_populates="client_provider", uselist=False, cascade="all, delete-orphan")
|
||||
|
||||
|
||||
class GClientProviderAddress(Base):
|
||||
class ClientProviderAddress(Base):
|
||||
"""
|
||||
Modelo para la tabla GClientesPro_Direccion - Dirección de clientes y proveedores
|
||||
"""
|
||||
__tablename__ = "gclient_provider_address"
|
||||
__tablename__ = "client_provider_address"
|
||||
__table_args__ = {"schema": "a76"}
|
||||
|
||||
# Primary key (foreign key)
|
||||
@@ -70,11 +69,11 @@ class GClientProviderAddress(Base):
|
||||
client_provider = relationship("ClientProvider", back_populates="address")
|
||||
|
||||
|
||||
class GClientProviderPrograms(Base):
|
||||
class ClientProviderPrograms(Base):
|
||||
"""
|
||||
Modelo para la tabla GClientesPro_Programas - Programas de clientes y proveedores
|
||||
"""
|
||||
__tablename__ = "gclient_provider_programs"
|
||||
__tablename__ = "client_provider_programs"
|
||||
__table_args__ = {"schema": "a76"}
|
||||
|
||||
# Primary key (foreign key)
|
||||
|
||||
@@ -8,7 +8,7 @@ from fastapi import HTTPException
|
||||
from typing import List, Optional
|
||||
import logging
|
||||
|
||||
from .models import ClientProvider, GClientProviderAddress, GClientProviderPrograms
|
||||
from .models import ClientProvider, ClientProviderAddress, ClientProviderPrograms
|
||||
from .dto import (
|
||||
ClientProviderCreateDTO,
|
||||
ClientProviderUpdateDTO,
|
||||
@@ -72,7 +72,7 @@ class ClientProviderService:
|
||||
|
||||
# Crear dirección si se proporciona
|
||||
if client_data.address:
|
||||
db_address = GClientProviderAddress(
|
||||
db_address = ClientProviderAddress(
|
||||
client_id=client_data.client_id,
|
||||
**client_data.address.model_dump(exclude_unset=True)
|
||||
)
|
||||
@@ -80,7 +80,7 @@ class ClientProviderService:
|
||||
|
||||
# Crear programas si se proporciona
|
||||
if client_data.programs:
|
||||
db_programs = GClientProviderPrograms(
|
||||
db_programs = ClientProviderPrograms(
|
||||
client_id=client_data.client_id,
|
||||
**client_data.programs.model_dump(exclude_unset=True)
|
||||
)
|
||||
@@ -207,7 +207,7 @@ class ClientProviderService:
|
||||
|
||||
# Actualizar dirección
|
||||
if client_data.address:
|
||||
address = self.db.query(GClientProviderAddress).filter(GClientProviderAddress.client_id == client_id).first()
|
||||
address = self.db.query(ClientProviderAddress).filter(ClientProviderAddress.client_id == client_id).first()
|
||||
if address:
|
||||
# Actualizar dirección existente
|
||||
address_data = client_data.address.model_dump(exclude_unset=True)
|
||||
@@ -215,7 +215,7 @@ class ClientProviderService:
|
||||
setattr(address, field, value)
|
||||
else:
|
||||
# Crear nueva dirección
|
||||
address = GClientProviderAddress(
|
||||
address = ClientProviderAddress(
|
||||
client_id=client_id,
|
||||
**client_data.address.model_dump(exclude_unset=True)
|
||||
)
|
||||
@@ -223,7 +223,7 @@ class ClientProviderService:
|
||||
|
||||
# Actualizar programas
|
||||
if client_data.programs:
|
||||
programs = self.db.query(GClientProviderPrograms).filter(GClientProviderPrograms.client_id == client_id).first()
|
||||
programs = self.db.query(ClientProviderPrograms).filter(ClientProviderPrograms.client_id == client_id).first()
|
||||
if programs:
|
||||
# Actualizar programas existentes
|
||||
programs_data = client_data.programs.model_dump(exclude_unset=True)
|
||||
@@ -231,7 +231,7 @@ class ClientProviderService:
|
||||
setattr(programs, field, value)
|
||||
else:
|
||||
# Crear nuevos programas
|
||||
programs = GClientProviderPrograms(
|
||||
programs = ClientProviderPrograms(
|
||||
client_id=client_id,
|
||||
**client_data.programs.model_dump(exclude_unset=True)
|
||||
)
|
||||
|
||||
@@ -7,11 +7,11 @@ from core.database import Base
|
||||
import enum
|
||||
|
||||
|
||||
class GCompany(Base):
|
||||
class Company(Base):
|
||||
"""
|
||||
Modelo para la tabla GCompany - Información de la empresa
|
||||
Modelo para la tabla Company - Información de la empresa
|
||||
"""
|
||||
__tablename__ = "gcompany"
|
||||
__tablename__ = "company"
|
||||
__table_args__ = {"schema": "a76"}
|
||||
|
||||
# Primary key
|
||||
|
||||
@@ -7,7 +7,7 @@ from fastapi import HTTPException
|
||||
from typing import List, Optional
|
||||
import logging
|
||||
|
||||
from .models import GCompany
|
||||
from .models import Company
|
||||
from .dto import CompanyCreateDTO, CompanyUpdateDTO, CompanyResponseDTO
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -34,12 +34,12 @@ class CompanyService:
|
||||
"""
|
||||
try:
|
||||
# Verificar que no exista ya una empresa (solo puede haber una por el consecutivo único)
|
||||
existing = self.db.query(GCompany).filter(GCompany.consecutive == True).first()
|
||||
existing = self.db.query(Company).filter(Company.consecutive == True).first()
|
||||
if existing:
|
||||
raise HTTPException(status_code=400, detail="A company is already registered in the system")
|
||||
|
||||
# Crear empresa
|
||||
db_company = GCompany(
|
||||
db_company = Company(
|
||||
id=company_data.id,
|
||||
consecutive=company_data.consecutive,
|
||||
name=company_data.name,
|
||||
@@ -98,7 +98,7 @@ class CompanyService:
|
||||
Returns:
|
||||
CompanyResponseDTO o None si no existe
|
||||
"""
|
||||
company = self.db.query(GCompany).filter(GCompany.consecutive == True).first()
|
||||
company = self.db.query(Company).filter(Company.consecutive == True).first()
|
||||
if not company:
|
||||
return None
|
||||
return CompanyResponseDTO.model_validate(company)
|
||||
@@ -113,7 +113,7 @@ class CompanyService:
|
||||
Returns:
|
||||
CompanyResponseDTO o None si no existe
|
||||
"""
|
||||
company = self.db.query(GCompany).filter(GCompany.id == company_id).first()
|
||||
company = self.db.query(Company).filter(Company.id == company_id).first()
|
||||
if not company:
|
||||
return None
|
||||
return CompanyResponseDTO.model_validate(company)
|
||||
@@ -129,7 +129,7 @@ class CompanyService:
|
||||
Returns:
|
||||
CompanyResponseDTO actualizada o None si no existe
|
||||
"""
|
||||
company = self.db.query(GCompany).filter(GCompany.id == company_id).first()
|
||||
company = self.db.query(Company).filter(Company.id == company_id).first()
|
||||
if not company:
|
||||
return None
|
||||
|
||||
@@ -158,7 +158,7 @@ class CompanyService:
|
||||
Returns:
|
||||
True si se eliminó, False si no existe
|
||||
"""
|
||||
company = self.db.query(GCompany).filter(GCompany.id == company_id).first()
|
||||
company = self.db.query(Company).filter(Company.id == company_id).first()
|
||||
if not company:
|
||||
return False
|
||||
|
||||
@@ -179,6 +179,6 @@ class CompanyService:
|
||||
Returns:
|
||||
True si existe una empresa, False en caso contrario
|
||||
"""
|
||||
return self.db.query(GCompany).filter(GCompany.consecutive == True).first() is not None
|
||||
return self.db.query(Company).filter(Company.consecutive == True).first() is not None
|
||||
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@ from datetime import datetime, time
|
||||
|
||||
class PedimentoDatesBase(BaseModel):
|
||||
"""Base schema for Pedimento Dates"""
|
||||
pedimento_id: int = Field(..., description="Pedimento ID")
|
||||
tenant_id: int = Field(..., description="Tenant ID")
|
||||
entry_date: Optional[datetime] = Field(None, description="Entry date")
|
||||
pedimento_date: Optional[datetime] = Field(None, description="Pedimento date")
|
||||
payment_date: Optional[datetime] = Field(None, description="Payment date")
|
||||
@@ -45,6 +43,8 @@ class PedimentoDatesUpdate(BaseModel):
|
||||
class PedimentoDatesResponse(PedimentoDatesBase):
|
||||
"""Schema for Pedimento Dates response"""
|
||||
id: int
|
||||
pedimento_id: int = Field(..., description="Pedimento ID")
|
||||
tenant_id: int = Field(..., description="Tenant ID")
|
||||
created_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""
|
||||
Routes for PedimentoDates CRUD operations
|
||||
"""
|
||||
import logging
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy.orm import Session
|
||||
from core.database import get_core_db
|
||||
@@ -15,7 +16,7 @@ from ..dtos.pedimento_dates import (
|
||||
|
||||
|
||||
router = APIRouter(prefix="/{pedimento_id}/dates")
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@router.get("/", response_model=PedimentoDatesResponse)
|
||||
async def get_dates(
|
||||
@@ -36,8 +37,7 @@ async def get_dates(
|
||||
|
||||
|
||||
@router.post("/", response_model=PedimentoDatesResponse, status_code=201)
|
||||
async def create_dates(
|
||||
pedimento_id: int,
|
||||
async def create_dates(
|
||||
data: PedimentoDatesCreate,
|
||||
db: Session = Depends(get_core_db),
|
||||
current_user: dict = Depends(get_current_user)
|
||||
@@ -46,11 +46,7 @@ async def create_dates(
|
||||
tenant_id = get_tenant_from_token(current_user)
|
||||
if not tenant_id:
|
||||
raise HTTPException(status_code=400, detail="Tenant ID not found in token")
|
||||
|
||||
# Ensure pedimento_id matches
|
||||
if data.pedimento_id != pedimento_id:
|
||||
raise HTTPException(status_code=400, detail="Pedimento ID mismatch")
|
||||
|
||||
|
||||
dates = PedimentoDatesService.create(db, data, tenant_id)
|
||||
return dates
|
||||
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
"""
|
||||
Service layer for PedimentoDates CRUD operations
|
||||
"""
|
||||
import logging
|
||||
from typing import Optional
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from ..models.pedimento_dates import PedimentoDates
|
||||
from ..dtos.pedimento_dates import PedimentoDatesCreate, PedimentoDatesUpdate
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class PedimentoDatesService:
|
||||
"""Service class for PedimentoDates business logic"""
|
||||
|
||||
@@ -12,10 +12,10 @@ Se han actualizado todos los modelos en `api/v1/modules/a76/` para usar el schem
|
||||
|
||||
| Módulo | Tabla | Schema | Estado |
|
||||
|--------|-------|---------|---------|
|
||||
| **Company** | `gcompany` | `a76` | ✅ Actualizada |
|
||||
| **Company** | `company` | `a76` | ✅ Actualizada |
|
||||
| **Client & Provider** | `client_provider` | `a76` | ✅ Actualizada |
|
||||
| **Client & Provider** | `gclient_provider_address` | `a76` | ✅ Actualizada |
|
||||
| **Client & Provider** | `gclient_provider_programs` | `a76` | ✅ Actualizada |
|
||||
| **Client & Provider** | `client_provider_address` | `a76` | ✅ Actualizada |
|
||||
| **Client & Provider** | `client_provider_programs` | `a76` | ✅ Actualizada |
|
||||
| **GParts** | `parts` | `a76` | ✅ Actualizada |
|
||||
| **Class** | `classes` | `a76` | ✅ Actualizada |
|
||||
| **Licenses** | `licenses` | `a76` | ✅ Ya estaba |
|
||||
@@ -27,12 +27,12 @@ Se han actualizado todos los modelos en `api/v1/modules/a76/` para usar el schem
|
||||
#### 1. Configuración de Schema
|
||||
```python
|
||||
# ANTES
|
||||
class GCompany(Base):
|
||||
__tablename__ = "gcompany"
|
||||
class Company(Base):
|
||||
__tablename__ = "company"
|
||||
|
||||
# DESPUÉS
|
||||
class GCompany(Base):
|
||||
__tablename__ = "gcompany"
|
||||
class Company(Base):
|
||||
__tablename__ = "company"
|
||||
__table_args__ = {"schema": "a76"}
|
||||
```
|
||||
|
||||
@@ -59,10 +59,10 @@ PostgreSQL Database
|
||||
├── tenants
|
||||
├── licenses
|
||||
├── license_usage
|
||||
├── gcompany
|
||||
├── company
|
||||
├── client_provider
|
||||
├── gclient_provider_address
|
||||
├── gclient_provider_programs
|
||||
├── client_provider_address
|
||||
├── client_provider_programs
|
||||
├── parts
|
||||
└── classes
|
||||
```
|
||||
|
||||
@@ -8,22 +8,48 @@ export interface PedimentoDates {
|
||||
pedimento_id: number;
|
||||
tenant_id: number;
|
||||
entry_date?: string | null;
|
||||
presentation_date?: string | null;
|
||||
pedimento_date?: string | null;
|
||||
payment_date?: string | null;
|
||||
rectification_payment_date?: string | null;
|
||||
extraction_date?: string | null;
|
||||
submission_date?: string | null;
|
||||
eucan_date?: string | null;
|
||||
original_date?: string | null;
|
||||
start_date?: string | null;
|
||||
end_date?: string | null;
|
||||
capture_date?: string | null;
|
||||
capture_time?: string | null;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface CreatePedimentoDatesData {
|
||||
entry_date?: string | null;
|
||||
presentation_date?: string | null;
|
||||
pedimento_date?: string | null;
|
||||
payment_date?: string | null;
|
||||
rectification_payment_date?: string | null;
|
||||
extraction_date?: string | null;
|
||||
submission_date?: string | null;
|
||||
eucan_date?: string | null;
|
||||
original_date?: string | null;
|
||||
start_date?: string | null;
|
||||
end_date?: string | null;
|
||||
capture_date?: string | null;
|
||||
capture_time?: string | null;
|
||||
}
|
||||
|
||||
export interface UpdatePedimentoDatesData {
|
||||
entry_date?: string | null;
|
||||
presentation_date?: string | null;
|
||||
pedimento_date?: string | null;
|
||||
payment_date?: string | null;
|
||||
rectification_payment_date?: string | null;
|
||||
extraction_date?: string | null;
|
||||
submission_date?: string | null;
|
||||
eucan_date?: string | null;
|
||||
original_date?: string | null;
|
||||
start_date?: string | null;
|
||||
end_date?: string | null;
|
||||
capture_date?: string | null;
|
||||
capture_time?: string | null;
|
||||
}
|
||||
|
||||
export const pedimentoDatesApi = {
|
||||
|
||||
@@ -7,20 +7,49 @@ export interface PedimentoPayments {
|
||||
id: number;
|
||||
pedimento_id: number;
|
||||
tenant_id: number;
|
||||
payment_form?: string | null;
|
||||
bank_identifier?: string | null;
|
||||
acknowledgment?: string | null;
|
||||
operation_number?: string | null;
|
||||
bank_code?: number | null;
|
||||
cashier?: string | null;
|
||||
date?: string | null;
|
||||
time?: string | null;
|
||||
shift?: string | null;
|
||||
total_cash_paid?: number | null;
|
||||
total_contributions?: number | null;
|
||||
counter_payment?: number | null;
|
||||
pece_code?: string | null;
|
||||
payment_id?: number | null;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface CreatePedimentoPaymentsData {
|
||||
payment_form?: string | null;
|
||||
bank_identifier?: string | null;
|
||||
acknowledgment?: string | null;
|
||||
operation_number?: string | null;
|
||||
bank_code?: number | null;
|
||||
cashier?: string | null;
|
||||
date?: string | null;
|
||||
time?: string | null;
|
||||
shift?: string | null;
|
||||
total_cash_paid?: number | null;
|
||||
total_contributions?: number | null;
|
||||
counter_payment?: number | null;
|
||||
pece_code?: string | null;
|
||||
payment_id?: number | null;
|
||||
}
|
||||
|
||||
export interface UpdatePedimentoPaymentsData {
|
||||
payment_form?: string | null;
|
||||
bank_identifier?: string | null;
|
||||
acknowledgment?: string | null;
|
||||
operation_number?: string | null;
|
||||
bank_code?: number | null;
|
||||
cashier?: string | null;
|
||||
date?: string | null;
|
||||
time?: string | null;
|
||||
shift?: string | null;
|
||||
total_cash_paid?: number | null;
|
||||
total_contributions?: number | null;
|
||||
counter_payment?: number | null;
|
||||
pece_code?: string | null;
|
||||
payment_id?: number | null;
|
||||
}
|
||||
|
||||
export const pedimentoPaymentsApi = {
|
||||
|
||||
@@ -7,26 +7,25 @@ export interface PedimentoTransportMeans {
|
||||
id: number;
|
||||
pedimento_id: number;
|
||||
tenant_id: number;
|
||||
arrival_key?: string | null;
|
||||
arrival_data?: string | null;
|
||||
departure_key?: string | null;
|
||||
departure_data?: string | null;
|
||||
destination?: number | null;
|
||||
entry_exit?: string | null;
|
||||
arrival?: string | null;
|
||||
departure?: string | null;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface CreatePedimentoTransportMeansData {
|
||||
arrival_key?: string | null;
|
||||
arrival_data?: string | null;
|
||||
departure_key?: string | null;
|
||||
departure_data?: string | null;
|
||||
destination?: number | null;
|
||||
entry_exit?: string | null;
|
||||
arrival?: string | null;
|
||||
departure?: string | null;
|
||||
}
|
||||
|
||||
export interface UpdatePedimentoTransportMeansData {
|
||||
arrival_key?: string | null;
|
||||
arrival_data?: string | null;
|
||||
departure_key?: string | null;
|
||||
departure_data?: string | null;
|
||||
destination?: number | null;
|
||||
entry_exit?: string | null;
|
||||
arrival?: string | null;
|
||||
departure?: string | null;
|
||||
}
|
||||
|
||||
export const pedimentoTransportApi = {
|
||||
|
||||
@@ -7,17 +7,37 @@ export interface PedimentoValidation {
|
||||
id: number;
|
||||
pedimento_id: number;
|
||||
tenant_id: number;
|
||||
document?: string | null;
|
||||
validator?: string | null;
|
||||
validation_ack?: string | null;
|
||||
pre_ack?: string | null;
|
||||
line_signature?: string | null;
|
||||
electronic_signature?: string | null;
|
||||
certificate_number?: string | null;
|
||||
validator_id?: number | null;
|
||||
responsible_id?: number | null;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface CreatePedimentoValidationData {
|
||||
document?: string | null;
|
||||
validator?: string | null;
|
||||
validation_ack?: string | null;
|
||||
pre_ack?: string | null;
|
||||
line_signature?: string | null;
|
||||
electronic_signature?: string | null;
|
||||
certificate_number?: string | null;
|
||||
validator_id?: number | null;
|
||||
responsible_id?: number | null;
|
||||
}
|
||||
|
||||
export interface UpdatePedimentoValidationData {
|
||||
document?: string | null;
|
||||
validator?: string | null;
|
||||
validation_ack?: string | null;
|
||||
pre_ack?: string | null;
|
||||
line_signature?: string | null;
|
||||
electronic_signature?: string | null;
|
||||
certificate_number?: string | null;
|
||||
validator_id?: number | null;
|
||||
responsible_id?: number | null;
|
||||
}
|
||||
|
||||
export const pedimentoValidationApi = {
|
||||
|
||||
@@ -67,15 +67,40 @@ function formatDate(date?: string | null): string {
|
||||
function getStatusColor(status?: string | null): string {
|
||||
if (!status) return 'bg-gray-100 text-gray-800';
|
||||
|
||||
const statusLower = status.toLowerCase();
|
||||
if (statusLower.includes('activo') || statusLower.includes('completado')) {
|
||||
const statusUpper = status.toUpperCase();
|
||||
|
||||
// Estados completados/exitosos - Verde
|
||||
if (statusUpper === 'VALIDADO' || statusUpper === 'PAGADO' || statusUpper === 'CARTA CUPO') {
|
||||
return 'bg-green-100 text-green-800';
|
||||
} else if (statusLower.includes('pendiente') || statusLower.includes('proceso')) {
|
||||
}
|
||||
|
||||
// Estados en espera/proceso - Amarillo
|
||||
if (statusUpper.startsWith('ESPERA')) {
|
||||
return 'bg-yellow-100 text-yellow-800';
|
||||
} else if (statusLower.includes('cancelado') || statusLower.includes('rechazado')) {
|
||||
}
|
||||
|
||||
// Estados con firma - Azul
|
||||
if (statusUpper === 'CON FIRMA DE PREVIO') {
|
||||
return 'bg-blue-100 text-blue-800';
|
||||
}
|
||||
|
||||
// Estados modificables/editables - Índigo
|
||||
if (statusUpper === 'MODIFICABLE') {
|
||||
return 'bg-indigo-100 text-indigo-800';
|
||||
}
|
||||
|
||||
// Estados de borrado - Naranja
|
||||
if (statusUpper.includes('BORRADA')) {
|
||||
return 'bg-orange-100 text-orange-800';
|
||||
}
|
||||
|
||||
// Estados cancelados/desistidos - Rojo
|
||||
if (statusUpper === 'DESISTIO') {
|
||||
return 'bg-red-100 text-red-800';
|
||||
}
|
||||
return 'bg-blue-100 text-blue-800';
|
||||
|
||||
// Default - Gris
|
||||
return 'bg-gray-100 text-gray-800';
|
||||
}
|
||||
|
||||
export function createColumns(onSuccess?: () => void): ColumnDef<Pedimento>[] {
|
||||
@@ -131,17 +156,20 @@ export function createColumns(onSuccess?: () => void): ColumnDef<Pedimento>[] {
|
||||
cell: ({ row }) => {
|
||||
const status = row.original.status;
|
||||
const colorClass = getStatusColor(status);
|
||||
const formattedStatus = status
|
||||
? status.charAt(0).toUpperCase() + status.slice(1).toLowerCase()
|
||||
: 'N/A';
|
||||
|
||||
const statusSnippet = createRawSnippet<[{ status?: string | null; colorClass: string }]>((getStatus) => {
|
||||
const statusSnippet = createRawSnippet<[{ status: string; colorClass: string }]>((getStatus) => {
|
||||
const { status, colorClass } = getStatus();
|
||||
return {
|
||||
render: () =>
|
||||
`<span class="inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${colorClass}">
|
||||
${status || 'N/A'}
|
||||
${status}
|
||||
</span>`
|
||||
};
|
||||
});
|
||||
return renderSnippet(statusSnippet, { status, colorClass });
|
||||
return renderSnippet(statusSnippet, { status: formattedStatus, colorClass });
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -27,8 +27,17 @@
|
||||
if (!pedimentoId) {
|
||||
formData = {
|
||||
entry_date: '',
|
||||
presentation_date: '',
|
||||
payment_date: ''
|
||||
pedimento_date: '',
|
||||
payment_date: '',
|
||||
rectification_payment_date: '',
|
||||
extraction_date: '',
|
||||
submission_date: '',
|
||||
eucan_date: '',
|
||||
original_date: '',
|
||||
start_date: '',
|
||||
end_date: '',
|
||||
capture_date: '',
|
||||
capture_time: ''
|
||||
};
|
||||
exists = false;
|
||||
loading = false;
|
||||
@@ -44,15 +53,33 @@
|
||||
exists = false;
|
||||
formData = {
|
||||
entry_date: '',
|
||||
presentation_date: '',
|
||||
payment_date: ''
|
||||
pedimento_date: '',
|
||||
payment_date: '',
|
||||
rectification_payment_date: '',
|
||||
extraction_date: '',
|
||||
submission_date: '',
|
||||
eucan_date: '',
|
||||
original_date: '',
|
||||
start_date: '',
|
||||
end_date: '',
|
||||
capture_date: '',
|
||||
capture_time: ''
|
||||
};
|
||||
} else if (response.data) {
|
||||
exists = true;
|
||||
formData = {
|
||||
entry_date: response.data.entry_date ? response.data.entry_date.substring(0, 10) : '',
|
||||
presentation_date: response.data.presentation_date ? response.data.presentation_date.substring(0, 10) : '',
|
||||
payment_date: response.data.payment_date ? response.data.payment_date.substring(0, 10) : ''
|
||||
pedimento_date: response.data.pedimento_date ? response.data.pedimento_date.substring(0, 10) : '',
|
||||
payment_date: response.data.payment_date ? response.data.payment_date.substring(0, 10) : '',
|
||||
rectification_payment_date: response.data.rectification_payment_date ? response.data.rectification_payment_date.substring(0, 10) : '',
|
||||
extraction_date: response.data.extraction_date ? response.data.extraction_date.substring(0, 10) : '',
|
||||
submission_date: response.data.submission_date ? response.data.submission_date.substring(0, 10) : '',
|
||||
eucan_date: response.data.eucan_date ? response.data.eucan_date.substring(0, 10) : '',
|
||||
original_date: response.data.original_date ? response.data.original_date.substring(0, 10) : '',
|
||||
start_date: response.data.start_date ? response.data.start_date.substring(0, 10) : '',
|
||||
end_date: response.data.end_date ? response.data.end_date.substring(0, 10) : '',
|
||||
capture_date: response.data.capture_date ? response.data.capture_date.substring(0, 10) : '',
|
||||
capture_time: response.data.capture_time || ''
|
||||
};
|
||||
}
|
||||
} catch (e) {
|
||||
@@ -60,8 +87,17 @@
|
||||
exists = false;
|
||||
formData = {
|
||||
entry_date: '',
|
||||
presentation_date: '',
|
||||
payment_date: ''
|
||||
pedimento_date: '',
|
||||
payment_date: '',
|
||||
rectification_payment_date: '',
|
||||
extraction_date: '',
|
||||
submission_date: '',
|
||||
eucan_date: '',
|
||||
original_date: '',
|
||||
start_date: '',
|
||||
end_date: '',
|
||||
capture_date: '',
|
||||
capture_time: ''
|
||||
};
|
||||
} finally {
|
||||
loading = false;
|
||||
@@ -85,7 +121,7 @@
|
||||
</div>
|
||||
{:else}
|
||||
<div class="space-y-6">
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
<!-- Fecha de Entrada -->
|
||||
<div class="space-y-2">
|
||||
<Label for="entry_date">Fecha de Entrada</Label>
|
||||
@@ -98,11 +134,11 @@
|
||||
|
||||
<!-- Fecha de Presentación -->
|
||||
<div class="space-y-2">
|
||||
<Label for="presentation_date">Fecha de Presentación</Label>
|
||||
<Label for="pedimento_date">Fecha de Presentación</Label>
|
||||
<Input
|
||||
id="presentation_date"
|
||||
id="pedimento_date"
|
||||
type="date"
|
||||
bind:value={formData.presentation_date}
|
||||
bind:value={formData.pedimento_date}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -115,6 +151,96 @@
|
||||
bind:value={formData.payment_date}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Fecha de Pago Rectificación -->
|
||||
<div class="space-y-2">
|
||||
<Label for="rectification_payment_date">Fecha de Pago Rectificación</Label>
|
||||
<Input
|
||||
id="rectification_payment_date"
|
||||
type="date"
|
||||
bind:value={formData.rectification_payment_date}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Fecha de Extracción -->
|
||||
<div class="space-y-2">
|
||||
<Label for="extraction_date">Fecha de Extracción</Label>
|
||||
<Input
|
||||
id="extraction_date"
|
||||
type="date"
|
||||
bind:value={formData.extraction_date}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Fecha de Presentación (Submission) -->
|
||||
<div class="space-y-2">
|
||||
<Label for="submission_date">Fecha de Envío</Label>
|
||||
<Input
|
||||
id="submission_date"
|
||||
type="date"
|
||||
bind:value={formData.submission_date}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Fecha EUCAN -->
|
||||
<div class="space-y-2">
|
||||
<Label for="eucan_date">Fecha EUCAN</Label>
|
||||
<Input
|
||||
id="eucan_date"
|
||||
type="date"
|
||||
bind:value={formData.eucan_date}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Fecha Original -->
|
||||
<div class="space-y-2">
|
||||
<Label for="original_date">Fecha Original</Label>
|
||||
<Input
|
||||
id="original_date"
|
||||
type="date"
|
||||
bind:value={formData.original_date}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Fecha de Inicio -->
|
||||
<div class="space-y-2">
|
||||
<Label for="start_date">Fecha de Inicio</Label>
|
||||
<Input
|
||||
id="start_date"
|
||||
type="date"
|
||||
bind:value={formData.start_date}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Fecha de Fin -->
|
||||
<div class="space-y-2">
|
||||
<Label for="end_date">Fecha de Fin</Label>
|
||||
<Input
|
||||
id="end_date"
|
||||
type="date"
|
||||
bind:value={formData.end_date}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Fecha de Captura -->
|
||||
<div class="space-y-2">
|
||||
<Label for="capture_date">Fecha de Captura</Label>
|
||||
<Input
|
||||
id="capture_date"
|
||||
type="date"
|
||||
bind:value={formData.capture_date}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Hora de Captura -->
|
||||
<div class="space-y-2">
|
||||
<Label for="capture_time">Hora de Captura</Label>
|
||||
<Input
|
||||
id="capture_time"
|
||||
type="time"
|
||||
bind:value={formData.capture_time}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -33,11 +33,21 @@
|
||||
}
|
||||
|
||||
const statusOptions = [
|
||||
{ value: 'Activo', label: 'Activo' },
|
||||
{ value: 'Pendiente', label: 'Pendiente' },
|
||||
{ value: 'En Proceso', label: 'En Proceso' },
|
||||
{ value: 'Completado', label: 'Completado' },
|
||||
{ value: 'Cancelado', label: 'Cancelado' }
|
||||
{ value: 'MODIFICABLE', label: 'Modificable' },
|
||||
{ value: 'ESPERA FIRMA PREVIO', label: 'Espera de firma previo' },
|
||||
{ value: 'ESPERA VALIDACION', label: 'Espera validacion' },
|
||||
{ value: 'VALIDADO', label: 'Validado' },
|
||||
{ value: 'ESPERA BORRAR FIRMA PREVIO', label: 'Espera borrar firma previo' },
|
||||
{ value: 'ESPERA BORRAR FIRMA VALIDACION', label: 'Espera borrar firma validacion ' },
|
||||
{ value: 'ESPERA PAGO', label: 'Espera pago' },
|
||||
{ value: 'CON FIRMA DE PREVIO', label: 'Con firma de previo' },
|
||||
{ value: 'F DE PREVIO BORRADA', label: 'Forma de previo borrada' },
|
||||
{ value: 'F VALIDACION BORRADA', label: 'Forma validacion borrada' },
|
||||
{ value: 'PAGADO', label: 'Pagado' },
|
||||
{ value: 'DESISTIO', label: 'Desistio' },
|
||||
{ value: 'ESPERA CARTA CUPO', label: 'Espera carta cupo' },
|
||||
{ value: 'CARTA CUPO', label: 'Carta cupo' },
|
||||
{ value: 'ESPERA CANCELAR CARTA CUPO', label: 'Espera cancelar carta cupo' }
|
||||
];
|
||||
</script>
|
||||
|
||||
@@ -160,7 +170,7 @@
|
||||
<Input
|
||||
id="regime"
|
||||
bind:value={formData.regime}
|
||||
placeholder="Ej: IMP"
|
||||
placeholder="Ej: IMD"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -26,8 +26,18 @@
|
||||
// Si no hay pedimentoId (modo creación), inicializar vacío
|
||||
if (!pedimentoId) {
|
||||
formData = {
|
||||
payment_form: '',
|
||||
bank_identifier: ''
|
||||
acknowledgment: '',
|
||||
operation_number: '',
|
||||
bank_code: null,
|
||||
cashier: '',
|
||||
date: '',
|
||||
time: '',
|
||||
shift: '',
|
||||
total_cash_paid: null,
|
||||
total_contributions: null,
|
||||
counter_payment: null,
|
||||
pece_code: '',
|
||||
payment_id: null
|
||||
};
|
||||
exists = false;
|
||||
loading = false;
|
||||
@@ -42,22 +52,52 @@
|
||||
// No existe o hay error - inicializar vacío
|
||||
exists = false;
|
||||
formData = {
|
||||
payment_form: '',
|
||||
bank_identifier: ''
|
||||
acknowledgment: '',
|
||||
operation_number: '',
|
||||
bank_code: null,
|
||||
cashier: '',
|
||||
date: '',
|
||||
time: '',
|
||||
shift: '',
|
||||
total_cash_paid: null,
|
||||
total_contributions: null,
|
||||
counter_payment: null,
|
||||
pece_code: '',
|
||||
payment_id: null
|
||||
};
|
||||
} else if (response.data) {
|
||||
exists = true;
|
||||
formData = {
|
||||
payment_form: response.data.payment_form || '',
|
||||
bank_identifier: response.data.bank_identifier || ''
|
||||
acknowledgment: response.data.acknowledgment || '',
|
||||
operation_number: response.data.operation_number || '',
|
||||
bank_code: response.data.bank_code || null,
|
||||
cashier: response.data.cashier || '',
|
||||
date: response.data.date || '',
|
||||
time: response.data.time || '',
|
||||
shift: response.data.shift || '',
|
||||
total_cash_paid: response.data.total_cash_paid || null,
|
||||
total_contributions: response.data.total_contributions || null,
|
||||
counter_payment: response.data.counter_payment || null,
|
||||
pece_code: response.data.pece_code || '',
|
||||
payment_id: response.data.payment_id || null
|
||||
};
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error loading payments:', e);
|
||||
exists = false;
|
||||
formData = {
|
||||
payment_form: '',
|
||||
bank_identifier: ''
|
||||
acknowledgment: '',
|
||||
operation_number: '',
|
||||
bank_code: null,
|
||||
cashier: '',
|
||||
date: '',
|
||||
time: '',
|
||||
shift: '',
|
||||
total_cash_paid: null,
|
||||
total_contributions: null,
|
||||
counter_payment: null,
|
||||
pece_code: '',
|
||||
payment_id: null
|
||||
};
|
||||
} finally {
|
||||
loading = false;
|
||||
@@ -80,24 +120,134 @@
|
||||
</div>
|
||||
{:else}
|
||||
<div class="space-y-6">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<!-- Forma de Pago -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
<!-- Acuse -->
|
||||
<div class="space-y-2">
|
||||
<Label for="payment_form">Forma de Pago</Label>
|
||||
<Label for="acknowledgment">Acuse</Label>
|
||||
<Input
|
||||
id="payment_form"
|
||||
bind:value={formData.payment_form}
|
||||
placeholder="Ej: Efectivo, Transferencia"
|
||||
id="acknowledgment"
|
||||
bind:value={formData.acknowledgment}
|
||||
placeholder="Máx. 20 caracteres"
|
||||
maxlength={20}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Identificador Bancario -->
|
||||
<!-- Número de Operación -->
|
||||
<div class="space-y-2">
|
||||
<Label for="bank_identifier">Identificador Bancario</Label>
|
||||
<Label for="operation_number">Número de Operación</Label>
|
||||
<Input
|
||||
id="bank_identifier"
|
||||
bind:value={formData.bank_identifier}
|
||||
placeholder="Ej: 012345678901234567"
|
||||
id="operation_number"
|
||||
bind:value={formData.operation_number}
|
||||
placeholder="Máx. 14 caracteres"
|
||||
maxlength={14}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Código de Banco -->
|
||||
<div class="space-y-2">
|
||||
<Label for="bank_code">Código de Banco</Label>
|
||||
<Input
|
||||
id="bank_code"
|
||||
type="number"
|
||||
bind:value={formData.bank_code}
|
||||
placeholder="Código numérico"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Cajero -->
|
||||
<div class="space-y-2">
|
||||
<Label for="cashier">Cajero</Label>
|
||||
<Input
|
||||
id="cashier"
|
||||
bind:value={formData.cashier}
|
||||
placeholder="Máx. 2 caracteres"
|
||||
maxlength={2}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Fecha -->
|
||||
<div class="space-y-2">
|
||||
<Label for="date">Fecha</Label>
|
||||
<Input
|
||||
id="date"
|
||||
type="date"
|
||||
bind:value={formData.date}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Hora -->
|
||||
<div class="space-y-2">
|
||||
<Label for="time">Hora</Label>
|
||||
<Input
|
||||
id="time"
|
||||
type="time"
|
||||
bind:value={formData.time}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Turno -->
|
||||
<div class="space-y-2">
|
||||
<Label for="shift">Turno</Label>
|
||||
<Input
|
||||
id="shift"
|
||||
bind:value={formData.shift}
|
||||
placeholder="1 carácter"
|
||||
maxlength={1}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Total Efectivo Pagado -->
|
||||
<div class="space-y-2">
|
||||
<Label for="total_cash_paid">Total Efectivo Pagado</Label>
|
||||
<Input
|
||||
id="total_cash_paid"
|
||||
type="number"
|
||||
bind:value={formData.total_cash_paid}
|
||||
placeholder="Monto en efectivo"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Total Contribuciones -->
|
||||
<div class="space-y-2">
|
||||
<Label for="total_contributions">Total Contribuciones</Label>
|
||||
<Input
|
||||
id="total_contributions"
|
||||
type="number"
|
||||
bind:value={formData.total_contributions}
|
||||
placeholder="Monto total"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Pago en Ventanilla -->
|
||||
<div class="space-y-2">
|
||||
<Label for="counter_payment">Pago en Ventanilla</Label>
|
||||
<Input
|
||||
id="counter_payment"
|
||||
type="number"
|
||||
bind:value={formData.counter_payment}
|
||||
placeholder="Monto"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Código PECE -->
|
||||
<div class="space-y-2">
|
||||
<Label for="pece_code">Código PECE</Label>
|
||||
<Input
|
||||
id="pece_code"
|
||||
bind:value={formData.pece_code}
|
||||
placeholder="Máx. 5 caracteres"
|
||||
maxlength={5}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- ID de Pago -->
|
||||
<div class="space-y-2">
|
||||
<Label for="payment_id">ID de Pago</Label>
|
||||
<Input
|
||||
id="payment_id"
|
||||
type="number"
|
||||
bind:value={formData.payment_id}
|
||||
placeholder="Identificador"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -26,10 +26,10 @@
|
||||
// Si no hay pedimentoId (modo creación), inicializar vacío
|
||||
if (!pedimentoId) {
|
||||
formData = {
|
||||
arrival_key: '',
|
||||
arrival_data: '',
|
||||
departure_key: '',
|
||||
departure_data: ''
|
||||
destination: null,
|
||||
entry_exit: '',
|
||||
arrival: '',
|
||||
departure: ''
|
||||
};
|
||||
exists = false;
|
||||
loading = false;
|
||||
@@ -44,28 +44,28 @@
|
||||
// No existe o hay error - inicializar vacío
|
||||
exists = false;
|
||||
formData = {
|
||||
arrival_key: '',
|
||||
arrival_data: '',
|
||||
departure_key: '',
|
||||
departure_data: ''
|
||||
destination: null,
|
||||
entry_exit: '',
|
||||
arrival: '',
|
||||
departure: ''
|
||||
};
|
||||
} else if (response.data) {
|
||||
exists = true;
|
||||
formData = {
|
||||
arrival_key: response.data.arrival_key || '',
|
||||
arrival_data: response.data.arrival_data || '',
|
||||
departure_key: response.data.departure_key || '',
|
||||
departure_data: response.data.departure_data || ''
|
||||
destination: response.data.destination || null,
|
||||
entry_exit: response.data.entry_exit || '',
|
||||
arrival: response.data.arrival || '',
|
||||
departure: response.data.departure || ''
|
||||
};
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error loading transport:', e);
|
||||
exists = false;
|
||||
formData = {
|
||||
arrival_key: '',
|
||||
arrival_data: '',
|
||||
departure_key: '',
|
||||
departure_data: ''
|
||||
destination: null,
|
||||
entry_exit: '',
|
||||
arrival: '',
|
||||
departure: ''
|
||||
};
|
||||
} finally {
|
||||
loading = false;
|
||||
@@ -91,43 +91,47 @@
|
||||
{:else}
|
||||
<div class="space-y-6">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<!-- Clave de Llegada -->
|
||||
<!-- Destino -->
|
||||
<div class="space-y-2">
|
||||
<Label for="arrival_key">Clave de Llegada</Label>
|
||||
<Label for="destination">Destino</Label>
|
||||
<Input
|
||||
id="arrival_key"
|
||||
bind:value={formData.arrival_key}
|
||||
placeholder="Ej: 01"
|
||||
id="destination"
|
||||
type="number"
|
||||
bind:value={formData.destination}
|
||||
placeholder="Código de destino"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Datos de Llegada -->
|
||||
<!-- Entrada/Salida -->
|
||||
<div class="space-y-2">
|
||||
<Label for="arrival_data">Datos de Llegada</Label>
|
||||
<Label for="entry_exit">Entrada/Salida</Label>
|
||||
<Input
|
||||
id="arrival_data"
|
||||
bind:value={formData.arrival_data}
|
||||
placeholder="Ej: Información adicional"
|
||||
id="entry_exit"
|
||||
bind:value={formData.entry_exit}
|
||||
placeholder="Máx. 2 caracteres"
|
||||
maxlength={2}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Clave de Salida -->
|
||||
<!-- Llegada -->
|
||||
<div class="space-y-2">
|
||||
<Label for="departure_key">Clave de Salida</Label>
|
||||
<Label for="arrival">Llegada</Label>
|
||||
<Input
|
||||
id="departure_key"
|
||||
bind:value={formData.departure_key}
|
||||
placeholder="Ej: 02"
|
||||
id="arrival"
|
||||
bind:value={formData.arrival}
|
||||
placeholder="Máx. 2 caracteres"
|
||||
maxlength={2}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Datos de Salida -->
|
||||
<!-- Salida -->
|
||||
<div class="space-y-2">
|
||||
<Label for="departure_data">Datos de Salida</Label>
|
||||
<Label for="departure">Salida</Label>
|
||||
<Input
|
||||
id="departure_data"
|
||||
bind:value={formData.departure_data}
|
||||
placeholder="Ej: Información adicional"
|
||||
id="departure"
|
||||
bind:value={formData.departure}
|
||||
placeholder="Máx. 2 caracteres"
|
||||
maxlength={2}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import * as Card from '$lib/components/ui/card';
|
||||
import { Input } from '$lib/components/ui/input';
|
||||
import { Label } from '$lib/components/ui/label';
|
||||
import { Textarea } from '$lib/components/ui/textarea';
|
||||
import { Skeleton } from '$lib/components/ui/skeleton';
|
||||
@@ -26,7 +27,14 @@
|
||||
// Si no hay pedimentoId (modo creación), inicializar vacío
|
||||
if (!pedimentoId) {
|
||||
formData = {
|
||||
document: ''
|
||||
validator: '',
|
||||
validation_ack: '',
|
||||
pre_ack: '',
|
||||
line_signature: '',
|
||||
electronic_signature: '',
|
||||
certificate_number: '',
|
||||
validator_id: null,
|
||||
responsible_id: null
|
||||
};
|
||||
exists = false;
|
||||
loading = false;
|
||||
@@ -41,19 +49,40 @@
|
||||
// No existe o hay error - inicializar vacío
|
||||
exists = false;
|
||||
formData = {
|
||||
document: ''
|
||||
validator: '',
|
||||
validation_ack: '',
|
||||
pre_ack: '',
|
||||
line_signature: '',
|
||||
electronic_signature: '',
|
||||
certificate_number: '',
|
||||
validator_id: null,
|
||||
responsible_id: null
|
||||
};
|
||||
} else if (response.data) {
|
||||
exists = true;
|
||||
formData = {
|
||||
document: response.data.document || ''
|
||||
validator: response.data.validator || '',
|
||||
validation_ack: response.data.validation_ack || '',
|
||||
pre_ack: response.data.pre_ack || '',
|
||||
line_signature: response.data.line_signature || '',
|
||||
electronic_signature: response.data.electronic_signature || '',
|
||||
certificate_number: response.data.certificate_number || '',
|
||||
validator_id: response.data.validator_id || null,
|
||||
responsible_id: response.data.responsible_id || null
|
||||
};
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error loading validation:', e);
|
||||
exists = false;
|
||||
formData = {
|
||||
document: ''
|
||||
validator: '',
|
||||
validation_ack: '',
|
||||
pre_ack: '',
|
||||
line_signature: '',
|
||||
electronic_signature: '',
|
||||
certificate_number: '',
|
||||
validator_id: null,
|
||||
responsible_id: null
|
||||
};
|
||||
} finally {
|
||||
loading = false;
|
||||
@@ -71,21 +100,105 @@
|
||||
<Card.Content>
|
||||
{#if loading}
|
||||
<div class="space-y-4">
|
||||
<Skeleton class="h-10 w-full" />
|
||||
<Skeleton class="h-10 w-full" />
|
||||
<Skeleton class="h-32 w-full" />
|
||||
<Skeleton class="h-32 w-full" />
|
||||
</div>
|
||||
{:else}
|
||||
<div class="space-y-6">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
<!-- Validador -->
|
||||
<div class="space-y-2">
|
||||
<Label for="validator">Validador</Label>
|
||||
<Input
|
||||
id="validator"
|
||||
bind:value={formData.validator}
|
||||
placeholder="Máx. 3 caracteres"
|
||||
maxlength={3}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Acuse de Validación -->
|
||||
<div class="space-y-2">
|
||||
<Label for="validation_ack">Acuse de Validación</Label>
|
||||
<Input
|
||||
id="validation_ack"
|
||||
bind:value={formData.validation_ack}
|
||||
placeholder="Máx. 8 caracteres"
|
||||
maxlength={8}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Pre-acuse -->
|
||||
<div class="space-y-2">
|
||||
<Label for="pre_ack">Pre-acuse</Label>
|
||||
<Input
|
||||
id="pre_ack"
|
||||
bind:value={formData.pre_ack}
|
||||
placeholder="Máx. 8 caracteres"
|
||||
maxlength={8}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Número de Certificado -->
|
||||
<div class="space-y-2">
|
||||
<Label for="certificate_number">Número de Certificado</Label>
|
||||
<Input
|
||||
id="certificate_number"
|
||||
bind:value={formData.certificate_number}
|
||||
placeholder="Máx. 99 caracteres"
|
||||
maxlength={99}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- ID de Validador -->
|
||||
<div class="space-y-2">
|
||||
<Label for="validator_id">ID de Validador</Label>
|
||||
<Input
|
||||
id="validator_id"
|
||||
type="number"
|
||||
bind:value={formData.validator_id}
|
||||
placeholder="Identificador numérico"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- ID de Responsable -->
|
||||
<div class="space-y-2">
|
||||
<Label for="responsible_id">ID de Responsable</Label>
|
||||
<Input
|
||||
id="responsible_id"
|
||||
type="number"
|
||||
bind:value={formData.responsible_id}
|
||||
placeholder="Identificador numérico"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Firma de Línea -->
|
||||
<div class="space-y-2">
|
||||
<Label for="document">Documento de Validación</Label>
|
||||
<Label for="line_signature">Firma de Línea</Label>
|
||||
<Input
|
||||
id="line_signature"
|
||||
bind:value={formData.line_signature}
|
||||
placeholder="Máx. 50 caracteres"
|
||||
maxlength={50}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Firma Electrónica -->
|
||||
<div class="space-y-2">
|
||||
<Label for="electronic_signature">Firma Electrónica</Label>
|
||||
<Textarea
|
||||
id="document"
|
||||
bind:value={formData.document}
|
||||
placeholder="Ingresa el documento o referencia de validación..."
|
||||
id="electronic_signature"
|
||||
bind:value={formData.electronic_signature}
|
||||
placeholder="Ingresa la firma electrónica..."
|
||||
rows={6}
|
||||
class="resize-none"
|
||||
class="resize-none font-mono text-sm"
|
||||
maxlength={999}
|
||||
/>
|
||||
<p class="text-sm text-muted-foreground">
|
||||
Ingresa el número de documento, referencia o cualquier información relevante para la validación del pedimento.
|
||||
Firma electrónica del pedimento (máximo 999 caracteres).
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<div
|
||||
class="bg-sidebar-primary text-sidebar-primary-foreground flex aspect-square size-8 items-center justify-center rounded-lg"
|
||||
>
|
||||
<activeTeam.logo class="size-4" />
|
||||
<activeTeam.logo class="size-4 text-white" />
|
||||
</div>
|
||||
<div class="grid flex-1 text-left text-sm leading-tight">
|
||||
<span class="truncate font-medium">
|
||||
|
||||
@@ -1,12 +1,45 @@
|
||||
import { redirect } from '@sveltejs/kit';
|
||||
import type { PageServerLoad } from './$types';
|
||||
|
||||
export const load: PageServerLoad = async ({ cookies }) => {
|
||||
export const load: PageServerLoad = async ({ cookies, fetch }) => {
|
||||
const token = cookies.get('access_token');
|
||||
|
||||
// Si está autenticado, redirigir al dashboard
|
||||
// Si hay token, validar que sea válido antes de redirigir
|
||||
if (token) {
|
||||
throw redirect(303, '/dashboard');
|
||||
try {
|
||||
// Configurar la URL de la API
|
||||
let apiUrl = process.env.INTERNAL_API_URL;
|
||||
if (!apiUrl) {
|
||||
apiUrl = import.meta.env.VITE_API_URL;
|
||||
apiUrl = apiUrl?.replace('localhost', 'backend').replace('127.0.0.1', 'backend');
|
||||
}
|
||||
|
||||
const baseUrl = apiUrl?.endsWith('/') ? apiUrl : `${apiUrl}/`;
|
||||
|
||||
// Verificar si el token es válido
|
||||
const response = await fetch(`${baseUrl}v1/auth/me`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
|
||||
// Solo redirigir al dashboard si el token es válido
|
||||
if (response.ok) {
|
||||
throw redirect(303, '/dashboard');
|
||||
} else {
|
||||
// Token inválido, limpiar cookies y mostrar la página pública
|
||||
cookies.delete('access_token', { path: '/' });
|
||||
cookies.delete('refresh_token', { path: '/' });
|
||||
}
|
||||
} catch (error) {
|
||||
// Si es un redirect, re-lanzarlo
|
||||
if (error && typeof error === 'object' && 'status' in error && 'location' in error) {
|
||||
throw error;
|
||||
}
|
||||
// Para otros errores, limpiar cookies y continuar
|
||||
cookies.delete('access_token', { path: '/' });
|
||||
cookies.delete('refresh_token', { path: '/' });
|
||||
}
|
||||
}
|
||||
|
||||
// Si no está autenticado, mostrar la página principal pública
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
<div class="flex items-center gap-2 px-4">
|
||||
<Sidebar.Trigger class="-ml-1" />
|
||||
<Separator orientation="vertical" class="mr-2 data-[orientation=vertical]:h-4" />
|
||||
<!--
|
||||
<Breadcrumb.Root>
|
||||
<Breadcrumb.List>
|
||||
<Breadcrumb.Item class="hidden md:block">
|
||||
@@ -32,6 +33,7 @@
|
||||
</Breadcrumb.Item>
|
||||
</Breadcrumb.List>
|
||||
</Breadcrumb.Root>
|
||||
-->
|
||||
</div>
|
||||
</header>
|
||||
<div class="flex flex-1 flex-col gap-4 p-4 pt-0">
|
||||
|
||||
@@ -171,11 +171,21 @@
|
||||
// Opciones de status para el filtro
|
||||
const statusOptions = [
|
||||
{ value: "", label: "Todos" },
|
||||
{ value: "Activo", label: "Activo" },
|
||||
{ value: "Pendiente", label: "Pendiente" },
|
||||
{ value: "En Proceso", label: "En Proceso" },
|
||||
{ value: "Completado", label: "Completado" },
|
||||
{ value: "Cancelado", label: "Cancelado" }
|
||||
{ value: 'MODIFICABLE', label: 'Modificable' },
|
||||
{ value: 'ESPERA FIRMA PREVIO', label: 'Espera de firma previo' },
|
||||
{ value: 'ESPERA VALIDACION', label: 'Espera validacion' },
|
||||
{ value: 'VALIDADO', label: 'Validado' },
|
||||
{ value: 'ESPERA BORRAR FIRMA PREVIO', label: 'Espera borrar firma previo' },
|
||||
{ value: 'ESPERA BORRAR FIRMA VALIDACION', label: 'Espera borrar firma validacion ' },
|
||||
{ value: 'ESPERA PAGO', label: 'Espera pago' },
|
||||
{ value: 'CON FIRMA DE PREVIO', label: 'Con firma de previo' },
|
||||
{ value: 'F DE PREVIO BORRADA', label: 'Forma de previo borrada' },
|
||||
{ value: 'F VALIDACION BORRADA', label: 'Forma validacion borrada' },
|
||||
{ value: 'PAGADO', label: 'Pagado' },
|
||||
{ value: 'DESISTIO', label: 'Desistio' },
|
||||
{ value: 'ESPERA CARTA CUPO', label: 'Espera carta cupo' },
|
||||
{ value: 'CARTA CUPO', label: 'Carta cupo' },
|
||||
{ value: 'ESPERA CANCELAR CARTA CUPO', label: 'Espera cancelar carta cupo' }
|
||||
];
|
||||
|
||||
// Crear columnas con el callback onSuccess
|
||||
|
||||
@@ -105,10 +105,10 @@
|
||||
}
|
||||
|
||||
// 2. Guardar fechas
|
||||
if (datesFormData && (datesFormData.entry_date || datesFormData.presentation_date || datesFormData.payment_date)) {
|
||||
if (datesFormData && (datesFormData.entry_date || datesFormData.pedimento_date || datesFormData.payment_date)) {
|
||||
const payload = {
|
||||
entry_date: datesFormData.entry_date || null,
|
||||
presentation_date: datesFormData.presentation_date || null,
|
||||
pedimento_date: datesFormData.pedimento_date || null,
|
||||
payment_date: datesFormData.payment_date || null
|
||||
};
|
||||
|
||||
|
||||
@@ -2,20 +2,15 @@ import { redirect, fail } from '@sveltejs/kit';
|
||||
import type { Actions, PageServerLoad } from './$types';
|
||||
|
||||
export const load: PageServerLoad = async ({ cookies, url }) => {
|
||||
const token = cookies.get('access_token');
|
||||
|
||||
// Si hay un parámetro 'logout' en la URL, limpiar las cookies
|
||||
if (url.searchParams.has('logout')) {
|
||||
cookies.delete('access_token', { path: '/' });
|
||||
cookies.delete('refresh_token', { path: '/' });
|
||||
return {};
|
||||
}
|
||||
|
||||
// Si está autenticado, redirigir al dashboard
|
||||
if (token) {
|
||||
throw redirect(303, '/dashboard');
|
||||
}
|
||||
|
||||
// Si no está autenticado, permitir acceso al login
|
||||
// Permitir acceso al login sin redirigir automáticamente
|
||||
// Esto evita bucles de redirección cuando el token existe pero puede estar expirado
|
||||
return {};
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user