Clases
This commit is contained in:
@@ -7,9 +7,9 @@
|
||||
import * as Select from "$lib/components/ui/select";
|
||||
import { classesApi, type A76Class, type A76ClassCreate, type A76ClassUpdate } from "$lib/api/dashboard/a76/classes";
|
||||
import { materialTypesApi, type MaterialType } from "$lib/api/dashboard/refrence_data/material_types";
|
||||
import { clientsProvidersApi, type ClientProviderBasic } from "$lib/api/dashboard/a76/clients-providers";
|
||||
import { companyStore } from "$lib/stores/company.svelte";
|
||||
import { onMount } from 'svelte';
|
||||
import { LoaderCircle, Home } from 'lucide-svelte';
|
||||
|
||||
let {
|
||||
open = $bindable(false),
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
// Estado del formulario
|
||||
let formData = $state({
|
||||
client_id: item?.client_id || null,
|
||||
class_code: item?.class_code || '',
|
||||
description_es: item?.description_es || '',
|
||||
description_en: item?.description_en || '',
|
||||
@@ -43,17 +44,23 @@
|
||||
let error = $state<string | null>(null);
|
||||
let materialTypes = $state<MaterialType[]>([]);
|
||||
let loadingMaterialTypes = $state(false);
|
||||
let clients = $state<ClientProviderBasic[]>([]);
|
||||
let loadingClients = $state(false);
|
||||
|
||||
// Variables para controlar los selects
|
||||
let selectedUnitValue = $state<string>('KG');
|
||||
let selectedMaterialValue = $state<string>('');
|
||||
let selectedPhysicalReviewValue = $state<number>(0);
|
||||
|
||||
// Cargar tipos de materiales al montar
|
||||
// Cargar tipos de materiales y clientes al montar
|
||||
onMount(async () => {
|
||||
const companyId = companyStore.activeCompany?.id;
|
||||
if (!companyId) return;
|
||||
|
||||
// Cargar tipos de materiales
|
||||
loadingMaterialTypes = true;
|
||||
try {
|
||||
const response = await materialTypesApi.list(1, 100); // Cargar los primeros 100
|
||||
const response = await materialTypesApi.list(1, 100);
|
||||
if (response.data) {
|
||||
materialTypes = response.data.items;
|
||||
}
|
||||
@@ -62,12 +69,26 @@
|
||||
} finally {
|
||||
loadingMaterialTypes = false;
|
||||
}
|
||||
|
||||
// Cargar clientes
|
||||
loadingClients = true;
|
||||
try {
|
||||
const response = await clientsProvidersApi.listClients(companyId, 0, 500);
|
||||
if (response.data) {
|
||||
clients = response.data;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error loading clients:', e);
|
||||
} finally {
|
||||
loadingClients = false;
|
||||
}
|
||||
});
|
||||
|
||||
// Resetear formulario cuando cambia el item
|
||||
$effect(() => {
|
||||
if (item) {
|
||||
formData = {
|
||||
client_id: item.client_id,
|
||||
class_code: item.class_code,
|
||||
description_es: item.description_es || '',
|
||||
description_en: item.description_en || '',
|
||||
@@ -86,6 +107,7 @@
|
||||
} else {
|
||||
// Reset para modo crear
|
||||
formData = {
|
||||
client_id: null,
|
||||
class_code: '',
|
||||
description_es: '',
|
||||
description_en: '',
|
||||
@@ -122,6 +144,10 @@
|
||||
}
|
||||
|
||||
// Validaciones básicas
|
||||
if (!formData.client_id) {
|
||||
error = 'Debes seleccionar un cliente';
|
||||
return;
|
||||
}
|
||||
if (!formData.class_code.trim()) {
|
||||
error = 'El código de clase es requerido';
|
||||
return;
|
||||
@@ -152,6 +178,7 @@
|
||||
if (isEdit && item) {
|
||||
// Actualizar
|
||||
const updateData: A76ClassUpdate = {
|
||||
client_id: formData.client_id!,
|
||||
class_code: formData.class_code,
|
||||
description_es: formData.description_es || null,
|
||||
description_en: formData.description_en || null,
|
||||
@@ -165,10 +192,10 @@
|
||||
};
|
||||
response = await classesApi.update(item.id, updateData, companyId);
|
||||
} else {
|
||||
// Crear - usa el company_id como client_id
|
||||
// Crear con el client_id seleccionado
|
||||
const createData: A76ClassCreate = {
|
||||
company_id: companyId,
|
||||
client_id: companyId, // Usa el mismo company_id como client_id
|
||||
client_id: formData.client_id!,
|
||||
class_code: formData.class_code,
|
||||
description_es: formData.description_es || null,
|
||||
description_en: formData.description_en || null,
|
||||
@@ -249,7 +276,21 @@
|
||||
{#if companyStore.activeCompany}
|
||||
<div class="rounded-md bg-blue-50 border border-blue-200 p-3">
|
||||
<div class="flex items-center gap-2">
|
||||
<Home class="h-4 w-4 text-blue-600" />
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="text-blue-600"
|
||||
>
|
||||
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" />
|
||||
<polyline points="9 22 9 12 15 12 15 22" />
|
||||
</svg>
|
||||
<div>
|
||||
<p class="text-sm font-medium text-blue-900">
|
||||
{companyStore.activeCompany.name}
|
||||
@@ -262,6 +303,34 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Cliente -->
|
||||
<div class="space-y-2">
|
||||
<Label for="client_id" class="required">Cliente</Label>
|
||||
{#if loadingClients}
|
||||
<div class="flex items-center gap-2 text-sm text-muted-foreground">
|
||||
<div class="h-4 w-4 animate-spin rounded-full border-2 border-primary border-t-transparent"></div>
|
||||
Cargando clientes...
|
||||
</div>
|
||||
{:else if clients.length > 0}
|
||||
<select
|
||||
bind:value={formData.client_id}
|
||||
disabled={loading}
|
||||
class="border-input bg-background selection:bg-primary dark:bg-input/30 selection:text-primary-foreground ring-offset-background placeholder:text-muted-foreground shadow-xs flex h-9 w-full min-w-0 rounded-md border px-3 py-1 text-base outline-none transition-[color,box-shadow] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive"
|
||||
>
|
||||
<option value="">Selecciona un cliente</option>
|
||||
{#each clients as client}
|
||||
<option value={client.id}>
|
||||
{client.name} ({client.rfc})
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
||||
{:else}
|
||||
<div class="text-sm text-muted-foreground">
|
||||
No hay clientes disponibles
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<!-- Código de Clase -->
|
||||
<div class="space-y-2">
|
||||
<Label for="class_code" class="required">Código de Clase</Label>
|
||||
@@ -413,7 +482,26 @@
|
||||
</Button>
|
||||
<Button type="submit" disabled={loading}>
|
||||
{#if loading}
|
||||
<LoaderCircle class="mr-2 h-4 w-4 animate-spin" />
|
||||
<svg
|
||||
class="mr-2 h-4 w-4 animate-spin"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<circle
|
||||
class="opacity-25"
|
||||
cx="12"
|
||||
cy="12"
|
||||
r="10"
|
||||
stroke="currentColor"
|
||||
stroke-width="4"
|
||||
></circle>
|
||||
<path
|
||||
class="opacity-75"
|
||||
fill="currentColor"
|
||||
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
||||
></path>
|
||||
</svg>
|
||||
Guardando...
|
||||
{:else}
|
||||
{isEdit ? 'Actualizar' : 'Crear'}
|
||||
|
||||
Reference in New Issue
Block a user