Добавлены новые поля в модель продукта и форму для управления складом: цена за комплект, количество комплектов, а также поля для учета движения товаров (заказано, в пути, остаток, продано). Обновлены GraphQL резолверы для поддержки новых полей. Оптимизирован интерфейс формы для улучшения пользовательского опыта.

This commit is contained in:
Bivekich
2025-08-01 11:28:28 +03:00
parent d45cdde42d
commit 52881cf302
4 changed files with 366 additions and 367 deletions

View File

@ -236,7 +236,13 @@ model Product {
article String article String
description String? description String?
price Decimal @db.Decimal(12, 2) price Decimal @db.Decimal(12, 2)
pricePerSet Decimal? @db.Decimal(12, 2)
quantity Int @default(0) quantity Int @default(0)
setQuantity Int?
ordered Int?
inTransit Int?
stock Int?
sold Int?
type ProductType @default(PRODUCT) type ProductType @default(PRODUCT)
categoryId String? categoryId String?
brand String? brand String?

View File

@ -25,7 +25,13 @@ interface Product {
article: string; article: string;
description: string; description: string;
price: number; price: number;
pricePerSet?: number;
quantity: number; quantity: number;
setQuantity?: number;
ordered?: number;
inTransit?: number;
stock?: number;
sold?: number;
type: "PRODUCT" | "CONSUMABLE"; type: "PRODUCT" | "CONSUMABLE";
category: { id: string; name: string } | null; category: { id: string; name: string } | null;
brand: string; brand: string;
@ -226,6 +232,8 @@ export function ProductForm({ product, onSave, onCancel }: ProductFormProps) {
return; return;
} }
console.log("📝 ФОРМА ДАННЫЕ ПЕРЕД ОТПРАВКОЙ:", formData);
try { try {
const input = { const input = {
name: formData.name, name: formData.name,
@ -256,10 +264,12 @@ export function ProductForm({ product, onSave, onCancel }: ProductFormProps) {
}; };
if (product) { if (product) {
await updateProduct({ console.log("📝 ОБНОВЛЕНИЕ ТОВАРА - ОТПРАВКА ЗАПРОСА:", input);
const result = await updateProduct({
variables: { id: product.id, input }, variables: { id: product.id, input },
refetchQueries: ["GetMyProducts"], refetchQueries: ["GetMyProducts"],
}); });
console.log("📝 РЕЗУЛЬТАТ ОБНОВЛЕНИЯ ТОВАРА:", result);
toast.success("Товар успешно обновлен"); toast.success("Товар успешно обновлен");
} else { } else {
console.log("📝 СОЗДАНИЕ ТОВАРА - ОТПРАВКА ЗАПРОСА:", input); console.log("📝 СОЗДАНИЕ ТОВАРА - ОТПРАВКА ЗАПРОСА:", input);
@ -279,380 +289,341 @@ export function ProductForm({ product, onSave, onCancel }: ProductFormProps) {
}; };
return ( return (
<form onSubmit={handleSubmit} className="space-y-4 pb-4"> <form onSubmit={handleSubmit} className="space-y-3">
{/* Основная информация */} {/* Верхняя часть - 2 колонки */}
<Card className="bg-white/5 backdrop-blur border-white/10 p-4"> <div className="grid grid-cols-2 gap-4">
<h3 className="text-white font-medium mb-4">Основная информация</h3> {/* Левая колонка */}
<div className="grid grid-cols-2 gap-4"> <div className="space-y-3">
<div> {/* Основная информация */}
<Label className="text-white/80 text-sm mb-2 block"> <Card className="bg-white/5 backdrop-blur border-white/10 p-3">
Название товара <span className="text-red-400">*</span> <h3 className="text-white font-medium mb-3 text-sm">Основная информация</h3>
</Label> <div className="space-y-3">
<Input <div>
value={formData.name} <Label className="text-white/80 text-xs mb-1 block">
onChange={(e) => handleInputChange("name", e.target.value)} Название товара <span className="text-red-400">*</span>
placeholder="iPhone 15 Pro Max" </Label>
className="glass-input text-white placeholder:text-white/40 h-10" <Input
required value={formData.name}
/> onChange={(e) => handleInputChange("name", e.target.value)}
</div> placeholder="iPhone 15 Pro Max"
className="glass-input text-white placeholder:text-white/40 h-8 text-sm"
required
/>
</div>
<div> <div>
<Label className="text-white/80 text-sm mb-2 block"> <Label className="text-white/80 text-xs mb-1 block">
Артикул СФ <span className="text-red-400">*</span> Артикул СФ <span className="text-red-400">*</span>
</Label> </Label>
<div className="flex gap-2"> <div className="flex gap-2">
<Input <Input
value={formData.article} value={formData.article}
onChange={(e) => { onChange={(e) => {
handleInputChange("article", e.target.value); handleInputChange("article", e.target.value);
handleInputChange("autoGenerateArticle", false); // Отключаем автогенерацию при ручном вводе handleInputChange("autoGenerateArticle", false);
}} }}
placeholder="SF-T-123456-001" placeholder="SF-T-123456-001"
className="glass-input text-white placeholder:text-white/40 h-10 flex-1" className="glass-input text-white placeholder:text-white/40 h-8 text-sm flex-1"
required required
readOnly={formData.autoGenerateArticle} readOnly={formData.autoGenerateArticle}
/> />
{!product && ( {!product && (
<Button <Button
type="button" type="button"
variant="outline" variant="outline"
size="sm" size="sm"
onClick={handleGenerateNewArticle} onClick={handleGenerateNewArticle}
className="glass-secondary text-white hover:text-white px-3 h-10" className="glass-secondary text-white hover:text-white px-2 h-8"
title="Генерировать новый артикул" title="Генерировать новый артикул"
>
<RefreshCw className="h-4 w-4" />
</Button>
)}
</div>
{formData.autoGenerateArticle && (
<p className="text-white/60 text-xs mt-1">
Артикул генерируется автоматически
</p>
)}
</div>
</div>
<div className="mt-4">
<Label className="text-white/80 text-sm mb-2 block">Описание</Label>
<textarea
value={formData.description}
onChange={(e) => handleInputChange("description", e.target.value)}
placeholder="Подробное описание товара..."
className="glass-input text-white placeholder:text-white/40 w-full resize-none"
rows={3}
/>
</div>
<div className="mt-4">
<Label className="text-white/80 text-sm mb-2 block">
Тип <span className="text-red-400">*</span>
</Label>
<Select
value={formData.type}
onValueChange={(value) => handleInputChange("type", value)}
>
<SelectTrigger className="glass-input text-white h-10">
<SelectValue placeholder="Выберите тип" />
</SelectTrigger>
<SelectContent className="glass-card">
<SelectItem value="PRODUCT" className="text-white">
Товар
</SelectItem>
<SelectItem value="CONSUMABLE" className="text-white">
Расходник
</SelectItem>
</SelectContent>
</Select>
</div>
<div className="grid grid-cols-2 gap-4 mt-4">
<div>
<Label className="text-white/80 text-sm mb-2 block">
Цена за единицу () <span className="text-red-400">*</span>
</Label>
<Input
type="number"
step="0.01"
min="0"
value={formData.price || ""}
onChange={(e) =>
handleInputChange("price", parseFloat(e.target.value) || 0)
}
placeholder="99999.99"
className="glass-input text-white placeholder:text-white/40 h-10"
required
/>
</div>
<div>
<Label className="text-white/80 text-sm mb-2 block">
Цена за комплект ()
</Label>
<Input
type="number"
step="0.01"
min="0"
value={formData.pricePerSet || ""}
onChange={(e) =>
handleInputChange("pricePerSet", parseFloat(e.target.value) || 0)
}
placeholder="299999.99"
className="glass-input text-white placeholder:text-white/40 h-10"
/>
</div>
</div>
<div className="grid grid-cols-2 gap-4 mt-4">
<div>
<Label className="text-white/80 text-sm mb-2 block">
Количество предметов
</Label>
<Input
type="number"
min="0"
value={formData.quantity || ""}
onChange={(e) =>
handleInputChange("quantity", parseInt(e.target.value) || 0)
}
placeholder="100"
className="glass-input text-white placeholder:text-white/40 h-10"
/>
</div>
<div>
<Label className="text-white/80 text-sm mb-2 block">
Количество комплектов
</Label>
<Input
type="number"
min="0"
value={formData.setQuantity || ""}
onChange={(e) =>
handleInputChange("setQuantity", parseInt(e.target.value) || 0)
}
placeholder="10"
className="glass-input text-white placeholder:text-white/40 h-10"
/>
</div>
</div>
</Card>
{/* Категоризация */}
<Card className="bg-white/5 backdrop-blur border-white/10 p-4">
<h3 className="text-white font-medium mb-4">Категоризация</h3>
<div className="grid grid-cols-2 gap-4">
<div>
<Label className="text-white/80 text-sm mb-2 block">
Категория
</Label>
<Select
value={formData.categoryId}
onValueChange={(value) => handleInputChange("categoryId", value)}
>
<SelectTrigger className="glass-input text-white h-10">
<SelectValue placeholder="Выберите категорию" />
</SelectTrigger>
<SelectContent className="glass-card">
<SelectItem value="none">Без категории</SelectItem>
{categoriesData?.categories?.map(
(category: { id: string; name: string }) => (
<SelectItem
key={category.id}
value={category.id}
className="text-white"
> >
{category.name} <RefreshCw className="h-3 w-3" />
</SelectItem> </Button>
) )}
)} </div>
</SelectContent> {formData.autoGenerateArticle && (
</Select> <p className="text-white/60 text-xs mt-1">Автогенерация</p>
</div>
<div>
<Label className="text-white/80 text-sm mb-2 block">Бренд</Label>
<Input
value={formData.brand}
onChange={(e) => handleInputChange("brand", e.target.value)}
placeholder="Apple"
className="glass-input text-white placeholder:text-white/40 h-10"
/>
</div>
</div>
</Card>
{/* Характеристики */}
<Card className="bg-white/5 backdrop-blur border-white/10 p-4">
<h3 className="text-white font-medium mb-4">Характеристики</h3>
<div className="grid grid-cols-2 gap-4">
<div>
<Label className="text-white/80 text-sm mb-2 block">Цвет</Label>
<Input
value={formData.color}
onChange={(e) => handleInputChange("color", e.target.value)}
placeholder="Синий"
className="glass-input text-white placeholder:text-white/40 h-10"
/>
</div>
<div>
<Label className="text-white/80 text-sm mb-2 block">Размер</Label>
<Input
value={formData.size}
onChange={(e) => handleInputChange("size", e.target.value)}
placeholder="L, XL, 42"
className="glass-input text-white placeholder:text-white/40 h-10"
/>
</div>
<div>
<Label className="text-white/80 text-sm mb-2 block">Вес (кг)</Label>
<Input
type="number"
step="0.001"
min="0"
value={formData.weight || ""}
onChange={(e) =>
handleInputChange("weight", parseFloat(e.target.value) || 0)
}
placeholder="0.221"
className="glass-input text-white placeholder:text-white/40 h-10"
/>
</div>
<div>
<Label className="text-white/80 text-sm mb-2 block">Габариты</Label>
<Input
value={formData.dimensions}
onChange={(e) => handleInputChange("dimensions", e.target.value)}
placeholder="159.9 × 76.7 × 8.25 мм"
className="glass-input text-white placeholder:text-white/40 h-10"
/>
</div>
</div>
<div className="mt-4">
<Label className="text-white/80 text-sm mb-2 block">Материал</Label>
<Input
value={formData.material}
onChange={(e) => handleInputChange("material", e.target.value)}
placeholder="Титан, стекло"
className="glass-input text-white placeholder:text-white/40 h-10"
/>
</div>
</Card>
{/* Изображения */}
<Card className="bg-white/5 backdrop-blur border-white/10 p-4">
<h3 className="text-white font-medium mb-4">Изображения товара</h3>
{/* Кнопка загрузки */}
<div className="mb-4">
<input
ref={fileInputRef}
type="file"
accept="image/*"
multiple
onChange={(e) =>
e.target.files && handleImageUpload(e.target.files)
}
className="hidden"
/>
<Button
type="button"
variant="outline"
onClick={() => fileInputRef.current?.click()}
disabled={isUploading}
className="glass-secondary text-white hover:text-white cursor-pointer"
>
<Upload className="h-4 w-4 mr-2" />
{isUploading ? "Загрузка..." : "Добавить изображения"}
</Button>
</div>
{/* Галерея изображений */}
{formData.images.length > 0 && (
<div className="grid grid-cols-3 gap-4">
{formData.images.map((imageUrl, index) => (
<div key={index} className="relative group">
{uploadingImages.has(index) ? (
<div className="aspect-square bg-white/10 rounded-lg flex items-center justify-center">
<div className="animate-spin rounded-full h-8 w-8 border-2 border-white border-t-transparent"></div>
</div>
) : imageUrl ? (
<>
<Image
src={imageUrl}
alt={`Товар ${index + 1}`}
width={200}
height={150}
className="w-full aspect-square object-contain rounded-lg bg-white/5"
/>
{/* Индикатор главного изображения */}
{formData.mainImage === imageUrl && (
<div className="absolute top-2 left-2">
<Star className="h-5 w-5 text-yellow-400 fill-current" />
</div>
)}
{/* Кнопки управления */}
<div className="absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity flex gap-1">
{formData.mainImage !== imageUrl && (
<Button
type="button"
size="sm"
variant="outline"
onClick={() => handleSetMainImage(imageUrl)}
className="p-1 h-7 w-7 bg-white/20 border-white/30 hover:bg-white/30"
>
<Star className="h-3 w-3 text-white" />
</Button>
)}
<Button
type="button"
size="sm"
variant="outline"
onClick={() => handleRemoveImage(index)}
className="p-1 h-7 w-7 bg-red-500/20 border-red-400/30 hover:bg-red-500/30"
>
<X className="h-3 w-3 text-white" />
</Button>
</div>
</>
) : (
<div className="aspect-square bg-white/10 rounded-lg flex items-center justify-center">
<div className="text-white/40 text-sm">Нет изображения</div>
</div>
)} )}
</div> </div>
))}
</div> <div className="flex gap-2 relative">
)} <div className="flex-1">
</Card> <Label className="text-white/80 text-xs mb-1 block">
Тип <span className="text-red-400">*</span>
</Label>
<div className="flex border border-white/10 rounded-lg overflow-hidden h-8">
<Button
type="button"
onClick={() => handleInputChange("type", "PRODUCT")}
className={`flex-1 h-full rounded-none text-xs border-0 ${
formData.type === 'PRODUCT'
? 'bg-blue-500/20 text-blue-300 hover:bg-blue-500/30'
: 'bg-transparent text-white/70 hover:text-white hover:bg-white/5'
}`}
>
Товар
</Button>
<Button
type="button"
onClick={() => handleInputChange("type", "CONSUMABLE")}
className={`flex-1 h-full rounded-none border-l border-white/10 text-xs border-t-0 border-r-0 border-b-0 ${
formData.type === 'CONSUMABLE'
? 'bg-orange-500/20 text-orange-300 hover:bg-orange-500/30'
: 'bg-transparent text-white/70 hover:text-white hover:bg-white/5'
}`}
>
Расходник
</Button>
</div>
</div>
<div className="flex-1">
<Label className="text-white/80 text-xs mb-1 block">Категория</Label>
<Select
value={formData.categoryId}
onValueChange={(value) => handleInputChange("categoryId", value)}
>
<SelectTrigger className="glass-input text-white h-8 text-sm">
<SelectValue placeholder="Категория" />
</SelectTrigger>
<SelectContent className="glass-card" side="bottom" align="end">
<SelectItem value="none">Без категории</SelectItem>
{categoriesData?.categories?.map(
(category: { id: string; name: string }) => (
<SelectItem key={category.id} value={category.id} className="text-white">
{category.name}
</SelectItem>
)
)}
</SelectContent>
</Select>
</div>
</div>
<div>
<Label className="text-white/80 text-xs mb-1 block">Описание</Label>
<textarea
value={formData.description}
onChange={(e) => handleInputChange("description", e.target.value)}
placeholder="Описание товара..."
className="glass-input text-white placeholder:text-white/40 w-full resize-none text-sm h-16"
style={{
background: 'rgba(255, 255, 255, 0.05)',
border: '1px solid rgba(255, 255, 255, 0.1)',
borderRadius: '0.5rem',
padding: '0.5rem'
}}
/>
</div>
</div>
</Card>
{/* Ценообразование */}
<Card className="bg-white/5 backdrop-blur border-white/10 p-3">
<h3 className="text-white font-medium mb-3 text-sm">Ценообразование</h3>
<div className="grid grid-cols-2 gap-2">
<div>
<Label className="text-white/80 text-xs mb-1 block">Кол-во предметов</Label>
<Input
type="number"
value={formData.quantity || ""}
onChange={(e) => handleInputChange("quantity", parseInt(e.target.value) || 0)}
className="glass-input text-white h-8 text-sm"
/>
</div>
<div>
<Label className="text-white/80 text-xs mb-1 block">
Цена за ед. () <span className="text-red-400">*</span>
</Label>
<Input
type="number"
step="0.01"
value={formData.price || ""}
onChange={(e) => handleInputChange("price", parseFloat(e.target.value) || 0)}
className="glass-input text-white h-8 text-sm"
required
/>
</div>
<div>
<Label className="text-white/80 text-xs mb-1 block">Кол-во комплектов</Label>
<Input
type="number"
value={formData.setQuantity || ""}
onChange={(e) => handleInputChange("setQuantity", parseInt(e.target.value) || 0)}
className="glass-input text-white h-8 text-sm"
/>
</div>
<div>
<Label className="text-white/80 text-xs mb-1 block">Цена за компл. ()</Label>
<Input
type="number"
step="0.01"
value={formData.pricePerSet || ""}
onChange={(e) => handleInputChange("pricePerSet", parseFloat(e.target.value) || 0)}
className="glass-input text-white h-8 text-sm"
/>
</div>
</div>
</Card>
</div>
{/* Правая колонка */}
<div className="space-y-3">
{/* Характеристики */}
<Card className="bg-white/5 backdrop-blur border-white/10 p-3">
<h3 className="text-white font-medium mb-3 text-sm">Характеристики</h3>
<div className="grid grid-cols-2 gap-2">
<div>
<Label className="text-white/80 text-xs mb-1 block">Бренд</Label>
<Input
value={formData.brand}
onChange={(e) => handleInputChange("brand", e.target.value)}
className="glass-input text-white h-8 text-sm"
/>
</div>
<div>
<Label className="text-white/80 text-xs mb-1 block">Цвет</Label>
<Input
value={formData.color}
onChange={(e) => handleInputChange("color", e.target.value)}
className="glass-input text-white h-8 text-sm"
/>
</div>
<div>
<Label className="text-white/80 text-xs mb-1 block">Размер</Label>
<Input
value={formData.size}
onChange={(e) => handleInputChange("size", e.target.value)}
className="glass-input text-white h-8 text-sm"
/>
</div>
<div>
<Label className="text-white/80 text-xs mb-1 block">Вес (кг)</Label>
<Input
type="number"
step="0.001"
value={formData.weight || ""}
onChange={(e) => handleInputChange("weight", parseFloat(e.target.value) || 0)}
className="glass-input text-white h-8 text-sm"
/>
</div>
<div className="col-span-2">
<Label className="text-white/80 text-xs mb-1 block">Габариты</Label>
<Input
value={formData.dimensions}
onChange={(e) => handleInputChange("dimensions", e.target.value)}
placeholder="159.9 × 76.7 × 8.25 мм"
className="glass-input text-white h-8 text-sm"
/>
</div>
<div className="col-span-2">
<Label className="text-white/80 text-xs mb-1 block">Материал</Label>
<Input
value={formData.material}
onChange={(e) => handleInputChange("material", e.target.value)}
placeholder="Титан, стекло"
className="glass-input text-white h-8 text-sm"
/>
</div>
</div>
</Card>
{/* Изображения */}
<Card className="bg-white/5 backdrop-blur border-white/10 p-3">
<div className="flex items-center justify-between mb-3">
<h3 className="text-white font-medium text-sm">Изображения</h3>
<input
ref={fileInputRef}
type="file"
accept="image/*"
multiple
onChange={(e) => e.target.files && handleImageUpload(e.target.files)}
className="hidden"
/>
<Button
type="button"
variant="outline"
size="sm"
onClick={() => fileInputRef.current?.click()}
disabled={isUploading}
className="glass-secondary text-white hover:text-white h-7 px-2 text-xs"
>
<Upload className="h-3 w-3 mr-1" />
Загрузить
</Button>
</div>
{formData.images.length > 0 && (
<div className="grid grid-cols-4 gap-2">
{formData.images.slice(0, 8).map((imageUrl, index) => (
<div key={index} className="relative group">
{uploadingImages.has(index) ? (
<div className="aspect-square bg-white/10 rounded flex items-center justify-center">
<div className="animate-spin rounded-full h-4 w-4 border border-white border-t-transparent"></div>
</div>
) : imageUrl ? (
<>
<Image
src={imageUrl}
alt={`${index + 1}`}
width={60}
height={60}
className="w-full aspect-square object-contain rounded bg-white/5"
/>
{formData.mainImage === imageUrl && (
<Star className="absolute top-1 left-1 h-3 w-3 text-yellow-400 fill-current" />
)}
<div className="absolute top-1 right-1 opacity-0 group-hover:opacity-100 transition-opacity flex gap-1">
{formData.mainImage !== imageUrl && (
<Button
type="button"
size="sm"
variant="outline"
onClick={() => handleSetMainImage(imageUrl)}
className="p-0 h-4 w-4 bg-white/20 border-white/30 hover:bg-white/30"
>
<Star className="h-2 w-2 text-white" />
</Button>
)}
<Button
type="button"
size="sm"
variant="outline"
onClick={() => handleRemoveImage(index)}
className="p-0 h-4 w-4 bg-red-500/20 border-red-400/30 hover:bg-red-500/30"
>
<X className="h-2 w-2 text-white" />
</Button>
</div>
</>
) : (
<div className="aspect-square bg-white/10 rounded flex items-center justify-center">
<div className="text-white/40 text-xs">Нет</div>
</div>
)}
</div>
))}
</div>
)}
</Card>
</div>
</div>
{/* Кнопки управления */} {/* Кнопки управления */}
<div className="flex gap-3 pt-4"> <div className="flex gap-3 pt-2">
<Button <Button
type="button" type="button"
variant="outline" variant="outline"
onClick={onCancel} onClick={onCancel}
className="flex-1 border-purple-400/30 text-purple-200 hover:bg-purple-500/10 hover:border-purple-300 transition-all duration-300" className="flex-1 border-purple-400/30 text-purple-200 hover:bg-purple-500/10 hover:border-purple-300 transition-all duration-300 h-9"
> >
Отмена Отмена
</Button> </Button>
<Button <Button
type="submit" type="submit"
disabled={loading || isUploading} disabled={loading || isUploading}
className="flex-1 bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-500 hover:to-pink-500 text-white border-0 shadow-lg shadow-purple-500/25 hover:shadow-purple-500/40 transition-all duration-300" className="flex-1 bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-500 hover:to-pink-500 text-white border-0 shadow-lg shadow-purple-500/25 hover:shadow-purple-500/40 transition-all duration-300 h-9"
> >
{loading {loading ? "Сохранение..." : product ? "Сохранить изменения" : "Создать товар"}
? "Сохранение..."
: product
? "Сохранить изменения"
: "Создать товар"}
</Button> </Button>
</div> </div>
</form> </form>

View File

@ -182,21 +182,19 @@ export function WarehouseDashboard() {
Добавить товар/расходник Добавить товар/расходник
</Button> </Button>
</DialogTrigger> </DialogTrigger>
<DialogContent className="glass-card max-w-4xl h-[90vh] flex flex-col"> <DialogContent className="glass-card !w-[90vw] !max-w-[90vw] max-h-[95vh]" style={{ width: '90vw', maxWidth: '90vw' }}>
<DialogHeader className="flex-shrink-0"> <DialogHeader>
<DialogTitle className="text-white"> <DialogTitle className="text-white">
{editingProduct {editingProduct
? "Редактировать товар/расходник" ? "Редактировать товар/расходник"
: "Добавить товар/расходник"} : "Добавить товар/расходник"}
</DialogTitle> </DialogTitle>
</DialogHeader> </DialogHeader>
<div className="flex-1 overflow-y-auto pr-2"> <ProductForm
<ProductForm product={editingProduct}
product={editingProduct} onSave={handleProductSaved}
onSave={handleProductSaved} onCancel={() => setIsDialogOpen(false)}
onCancel={() => setIsDialogOpen(false)} />
/>
</div>
</DialogContent> </DialogContent>
</Dialog> </Dialog>
</div> </div>

View File

@ -4134,7 +4134,13 @@ export const resolvers = {
article: string; article: string;
description?: string; description?: string;
price: number; price: number;
pricePerSet?: number;
quantity: number; quantity: number;
setQuantity?: number;
ordered?: number;
inTransit?: number;
stock?: number;
sold?: number;
type?: "PRODUCT" | "CONSUMABLE"; type?: "PRODUCT" | "CONSUMABLE";
categoryId?: string; categoryId?: string;
brand?: string; brand?: string;
@ -4211,7 +4217,13 @@ export const resolvers = {
article: args.input.article, article: args.input.article,
description: args.input.description, description: args.input.description,
price: args.input.price, price: args.input.price,
pricePerSet: args.input.pricePerSet,
quantity: args.input.quantity, quantity: args.input.quantity,
setQuantity: args.input.setQuantity,
ordered: args.input.ordered,
inTransit: args.input.inTransit,
stock: args.input.stock,
sold: args.input.sold,
type: args.input.type || "PRODUCT", type: args.input.type || "PRODUCT",
categoryId: args.input.categoryId, categoryId: args.input.categoryId,
brand: args.input.brand, brand: args.input.brand,
@ -4265,7 +4277,13 @@ export const resolvers = {
article: string; article: string;
description?: string; description?: string;
price: number; price: number;
pricePerSet?: number;
quantity: number; quantity: number;
setQuantity?: number;
ordered?: number;
inTransit?: number;
stock?: number;
sold?: number;
type?: "PRODUCT" | "CONSUMABLE"; type?: "PRODUCT" | "CONSUMABLE";
categoryId?: string; categoryId?: string;
brand?: string; brand?: string;
@ -4334,7 +4352,13 @@ export const resolvers = {
article: args.input.article, article: args.input.article,
description: args.input.description, description: args.input.description,
price: args.input.price, price: args.input.price,
pricePerSet: args.input.pricePerSet,
quantity: args.input.quantity, quantity: args.input.quantity,
setQuantity: args.input.setQuantity,
ordered: args.input.ordered,
inTransit: args.input.inTransit,
stock: args.input.stock,
sold: args.input.sold,
...(args.input.type && { type: args.input.type }), ...(args.input.type && { type: args.input.type }),
categoryId: args.input.categoryId, categoryId: args.input.categoryId,
brand: args.input.brand, brand: args.input.brand,