Se completo la integracion del celery en la creacion de reportes
This commit is contained in:
@@ -17,10 +17,11 @@ from sqlalchemy import (
|
||||
)
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from api.v1.modules.public.reference_data.material_types.models import MaterialType
|
||||
from api.v1.modules.a76.general_catalogs.units_of_measure.models import UnitOfMeasure
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from api.v1.modules.a76.parts.models import Part
|
||||
from api.v1.modules.public.reference_data.material_types.models import MaterialType
|
||||
from api.v1.modules.a76.general_catalogs.units_of_measure.models import UnitOfMeasure
|
||||
|
||||
|
||||
class Class(Base, TenantScopedMixin, TimestampMixin):
|
||||
|
||||
@@ -12,6 +12,10 @@ from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
from api.v1.common.base_models import TenantScopedMixin, TimestampMixin
|
||||
from core.database import Base
|
||||
|
||||
# Import models referenced by TenantScopedMixin (Tenant, Company) to ensure they are loaded
|
||||
from api.v1.modules.core.tenants.models import Tenant
|
||||
from api.v1.modules.a76.general_catalogs.company.models import Company
|
||||
|
||||
# 1. GUniMedACE
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@ from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
from api.v1.common.base_models import TenantScopedMixin, TimestampMixin
|
||||
from core.database import Base
|
||||
|
||||
from api.v1.modules.a76.classes.models import Class
|
||||
from api.v1.modules.a76.general_catalogs.units_of_measure.models import UnitOfMeasure
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ..models import Item
|
||||
from ..line_financials.models import LineFinancial
|
||||
@@ -12,10 +15,6 @@ if TYPE_CHECKING:
|
||||
from ..line_customs.models import LineCustom
|
||||
from ..line_descriptions.models import LineDescription
|
||||
from ..line_references.models import LineReference
|
||||
from api.v1.modules.a76.classes.models import Class
|
||||
from api.v1.modules.a76.general_catalogs.units_of_measure.models import (
|
||||
UnitOfMeasure,
|
||||
)
|
||||
from api.v1.modules.a24.fa.fa_item_lines.models import FaLineItem
|
||||
|
||||
|
||||
@@ -35,14 +34,14 @@ class LineItem(Base, TenantScopedMixin, TimestampMixin):
|
||||
line_number: Mapped[int] = mapped_column(Integer) # LINEAIMPO/LINEAEXPO/LINEA
|
||||
|
||||
# Part identification
|
||||
part_number_id: Mapped[Optional[str]] = mapped_column(
|
||||
part_number: Mapped[Optional[str]] = mapped_column(
|
||||
ForeignKey("a76.parts.id")
|
||||
) # NUMPARTE
|
||||
component_part_number_id: Mapped[Optional[str]] = mapped_column(
|
||||
component_part_number: Mapped[Optional[str]] = mapped_column(
|
||||
ForeignKey("a76.parts.id")
|
||||
) # NUMPARTECOM
|
||||
class_id: Mapped[Optional[str]] = mapped_column(
|
||||
ForeignKey("a76.classes.id")
|
||||
class_code: Mapped[Optional[str]] = mapped_column(
|
||||
ForeignKey("a76.classes.class_code")
|
||||
) # CLASE
|
||||
|
||||
# Unit of measure
|
||||
@@ -173,7 +172,7 @@ class LineItem(Base, TenantScopedMixin, TimestampMixin):
|
||||
back_populates="line", cascade="all, delete-orphan", uselist=False
|
||||
)
|
||||
class_info: Mapped[Optional["Class"]] = relationship(
|
||||
foreign_keys=[class_id], viewonly=True
|
||||
foreign_keys=[class_code], viewonly=True
|
||||
)
|
||||
unit_of_measure_info: Mapped[Optional["UnitOfMeasure"]] = relationship(
|
||||
foreign_keys=[unit_of_measure], viewonly=True
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import base64
|
||||
import logging
|
||||
from core.celery_app import celery_app
|
||||
from celery import current_task, states
|
||||
from core.database import CoreSessionLocal
|
||||
|
||||
from .mex.service import FacturaImportacionMexService
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@celery_app.task(name="generar_pdf_factura_async")
|
||||
def generar_pdf_factura_async(invoice_id: int, company_id: int):
|
||||
@celery_app.task(name="generar_pdf_factura_async", bind=True)
|
||||
def generar_pdf_factura_async(self, invoice_id: int, company_id: int):
|
||||
"""
|
||||
Esta tarea la ejecuta el Worker. No usa FastAPI, usa directamente SQLAlchemy.
|
||||
"""
|
||||
@@ -19,6 +20,9 @@ def generar_pdf_factura_async(invoice_id: int, company_id: int):
|
||||
|
||||
# 2. Instanciamos el servicio de reportes
|
||||
service = FacturaImportacionMexService()
|
||||
|
||||
# Update state to PROCESSING
|
||||
self.update_state(state='PROCESSING', meta={'current': 1, 'total': 1, 'status': 'Generating PDF...'})
|
||||
|
||||
# 3. Generamos los bytes del PDF
|
||||
pdf_bytes, nombre, media_type = service.generar_factura_completa(
|
||||
|
||||
@@ -12,8 +12,7 @@ from sqlalchemy import Enum as SQLEnum
|
||||
from sqlalchemy import Integer, String, Text
|
||||
from sqlalchemy.orm import Mapped, relationship
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from api.v1.modules.core.user_tenant.models import UserTenant
|
||||
from api.v1.modules.core.user_tenant.models import UserTenant
|
||||
|
||||
|
||||
class TenantType(enum.Enum):
|
||||
|
||||
@@ -13,7 +13,10 @@ function formatDate(date?: string | null): string {
|
||||
});
|
||||
}
|
||||
|
||||
export function createColumns(onSuccess?: () => void): ColumnDef<Invoice>[] {
|
||||
export function createColumns(
|
||||
onSuccess?: () => void,
|
||||
onDownload?: (invoice: Invoice) => void
|
||||
): ColumnDef<Invoice>[] {
|
||||
return [
|
||||
{
|
||||
accessorKey: "operation_type",
|
||||
@@ -29,8 +32,8 @@ export function createColumns(onSuccess?: () => void): ColumnDef<Invoice>[] {
|
||||
return {
|
||||
render: () =>
|
||||
`<span class="inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${colorClass}">
|
||||
${label}
|
||||
</span>`
|
||||
${label}
|
||||
</span>`
|
||||
};
|
||||
});
|
||||
return renderSnippet(operationSnippet, { type: operationType });
|
||||
@@ -149,7 +152,6 @@ export function createColumns(onSuccess?: () => void): ColumnDef<Invoice>[] {
|
||||
accessorKey: "total_items",
|
||||
header: "Total Partidas",
|
||||
cell: ({ row }) => {
|
||||
// El total de items viene del conteo de details
|
||||
const totalItems = row.original.details?.length || 0;
|
||||
|
||||
const itemsSnippet = createRawSnippet<[{ total: number }]>((getTotal) => {
|
||||
@@ -198,7 +200,6 @@ export function createColumns(onSuccess?: () => void): ColumnDef<Invoice>[] {
|
||||
accessorKey: "logistics.weight_type",
|
||||
header: "Tipo Peso",
|
||||
cell: ({ row }) => {
|
||||
// weight_type está en logistics que es un array, tomamos el primer elemento
|
||||
const weightType = row.original.logistics?.weight_type;
|
||||
|
||||
const weightSnippet = createRawSnippet<[{ type?: string | null }]>((getType) => {
|
||||
@@ -224,8 +225,8 @@ export function createColumns(onSuccess?: () => void): ColumnDef<Invoice>[] {
|
||||
return {
|
||||
render: () =>
|
||||
`<span class="inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${colorClass}">
|
||||
${label}
|
||||
</span>`
|
||||
${label}
|
||||
</span>`
|
||||
};
|
||||
});
|
||||
return renderSnippet(updatedSnippet, { isUpdated });
|
||||
@@ -244,8 +245,8 @@ export function createColumns(onSuccess?: () => void): ColumnDef<Invoice>[] {
|
||||
return {
|
||||
render: () =>
|
||||
`<span class="inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${colorClass}">
|
||||
${label}
|
||||
</span>`
|
||||
${label}
|
||||
</span>`
|
||||
};
|
||||
});
|
||||
return renderSnippet(mixedSnippet, { isMixed });
|
||||
@@ -267,14 +268,19 @@ export function createColumns(onSuccess?: () => void): ColumnDef<Invoice>[] {
|
||||
return renderSnippet(relDocSnippet, { relDoc });
|
||||
}
|
||||
},
|
||||
// 2. MODIFICAMOS AQUÍ: Pasamos onDownload al componente
|
||||
{
|
||||
id: "actions",
|
||||
cell: ({ row }) => {
|
||||
return renderComponent(DataTableActions, { invoice: row.original, onSuccess });
|
||||
return renderComponent(DataTableActions, {
|
||||
invoice: row.original,
|
||||
onSuccess,
|
||||
onDownload
|
||||
});
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
// Mantener compatibilidad hacia atrás
|
||||
|
||||
export const columns = createColumns();
|
||||
Reference in New Issue
Block a user