refactor(line_items): reorganize imports and clean up whitespace in models.py
This commit is contained in:
@@ -1,6 +1,14 @@
|
||||
from decimal import Decimal
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
from sqlalchemy import Boolean, String, Integer, Numeric, SmallInteger, ForeignKey, ForeignKeyConstraint
|
||||
from sqlalchemy import (
|
||||
Boolean,
|
||||
String,
|
||||
Integer,
|
||||
Numeric,
|
||||
SmallInteger,
|
||||
ForeignKey,
|
||||
ForeignKeyConstraint,
|
||||
)
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
from api.v1.common.base_models import TenantScopedMixin, TimestampMixin
|
||||
from core.database import Base
|
||||
@@ -25,9 +33,7 @@ class LineItem(Base, TenantScopedMixin, TimestampMixin):
|
||||
"""
|
||||
|
||||
__tablename__ = "item_lines"
|
||||
__table_args__ = (
|
||||
{"schema": "a76"},
|
||||
)
|
||||
__table_args__ = ({"schema": "a76"},)
|
||||
|
||||
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
|
||||
item_id: Mapped[int] = mapped_column(ForeignKey("a76.items.id"))
|
||||
@@ -68,7 +74,7 @@ class LineItem(Base, TenantScopedMixin, TimestampMixin):
|
||||
|
||||
# FDA
|
||||
has_fda_code: Mapped[Optional[bool]] = mapped_column(Boolean) # LLEVACODFDA
|
||||
fda_key: Mapped[Optional[str]] = mapped_column(String(10)) # CLAVEFDA
|
||||
fda_key: Mapped[Optional[str]] = mapped_column(String(10)) # CLAVEFDA
|
||||
|
||||
# Special flags
|
||||
is_military_mcia: Mapped[Optional[bool]] = mapped_column(Boolean) # ESMCIAMILITAR
|
||||
@@ -173,14 +179,17 @@ class LineItem(Base, TenantScopedMixin, TimestampMixin):
|
||||
)
|
||||
class_info: Mapped[Optional["Class"]] = relationship(
|
||||
"api.v1.modules.a76.classes.models.Class",
|
||||
foreign_keys=[class_id],
|
||||
viewonly=True
|
||||
foreign_keys=[class_id],
|
||||
viewonly=True,
|
||||
)
|
||||
unit_of_measure_info: Mapped[Optional["UnitOfMeasure"]] = relationship(
|
||||
"api.v1.modules.a76.general_catalogs.units_of_measure.models.UnitOfMeasure",
|
||||
foreign_keys=[unit_of_measure],
|
||||
viewonly=True
|
||||
foreign_keys=[unit_of_measure],
|
||||
viewonly=True,
|
||||
)
|
||||
fa_data: Mapped[Optional["FaLineItem"]] = relationship(
|
||||
"FaLineItem", back_populates="master_info", cascade="all, delete-orphan", uselist=False
|
||||
"FaLineItem",
|
||||
back_populates="master_info",
|
||||
cascade="all, delete-orphan",
|
||||
uselist=False,
|
||||
)
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { browser } from '$app/environment';
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/stores';
|
||||
import { clientsProvidersApi, type ClientProvider } from '$lib/api/dashboard/a76/clients-providers';
|
||||
import { Button } from '$lib/components/ui/button';
|
||||
import { Input } from '$lib/components/ui/input';
|
||||
@@ -11,32 +14,6 @@
|
||||
import type { ApiError } from '$lib/utils/error-handler';
|
||||
|
||||
// Los datos iniciales vienen del servidor
|
||||
let { data }: { data: PageData } = $props();
|
||||
|
||||
// Estado para el diálogo de crear
|
||||
let showCreateDialog = $state(false);
|
||||
|
||||
// Estado para el filtro de tipo
|
||||
let selectedType = $state<string>($page.url.searchParams.get('type') || 'both');
|
||||
|
||||
// Actualizar URL cuando cambia el filtro
|
||||
function handleTypeChange(value: string) {
|
||||
selectedType = value;
|
||||
const url = new URL(window.location.href);
|
||||
if (value === 'both') {
|
||||
url.searchParams.delete('type');
|
||||
} else {
|
||||
url.searchParams.set('type', value);
|
||||
}
|
||||
goto(url.toString(), { keepFocus: true, noScroll: true, replaceState: true });
|
||||
reloadData();
|
||||
}
|
||||
|
||||
// Sincronizar token de cookies a localStorage al montar el componente
|
||||
import { browser } from '$app/environment';
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/stores';
|
||||
|
||||
let { data }: { data: any } = $props();
|
||||
|
||||
// State
|
||||
@@ -45,7 +22,7 @@
|
||||
let isLoading = $state(false);
|
||||
|
||||
// Server-side filtering/pagination parameters
|
||||
let currentPage = $state(1);
|
||||
let currentPage = $state(data.page || 1);
|
||||
let pageSize = $state(50);
|
||||
let totalItems = $state(data.total || 0);
|
||||
|
||||
@@ -54,6 +31,10 @@
|
||||
let searchRfc = $state('');
|
||||
let searchType = $state<string>($page.url.searchParams.get('type') || 'both');
|
||||
|
||||
// Estado para el diálogo de crear
|
||||
let showCreateDialog = $state(false);
|
||||
let error = $state<string | ApiError | null>(data.error || null);
|
||||
|
||||
// --- Lifecycle ---
|
||||
|
||||
onMount(() => {
|
||||
@@ -76,28 +57,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
// Estado para infinite scroll
|
||||
let allItems = $state<ClientProvider[]>(data.items || []);
|
||||
let currentPage = $state(data.page || 1);
|
||||
let pageSize = $state(50);
|
||||
let totalItems = $state(data.total || 0);
|
||||
let loading = $state(false);
|
||||
let hasMore = $derived(allItems.length < totalItems);
|
||||
let error = $state<string | ApiError | null>(data.error || null);
|
||||
|
||||
async function loadMore() {
|
||||
if (loading || !hasMore || !companyStore.activeCompany) return;
|
||||
|
||||
loading = true;
|
||||
error = null;
|
||||
|
||||
try {
|
||||
const response = await clientsProvidersApi.list(
|
||||
companyStore.activeCompany.id,
|
||||
currentPage + 1,
|
||||
pageSize,
|
||||
selectedType !== 'both' ? { type: selectedType } : undefined
|
||||
);
|
||||
// --- Actions ---
|
||||
|
||||
async function loadItems(pageToLoad = 1) {
|
||||
|
||||
Reference in New Issue
Block a user