fix(indirect): make preferredSupplierId required + editable after creation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
louis 2026-06-26 11:48:20 +04:00
parent ee55c031ae
commit cd7f3cb4e7
5 changed files with 21 additions and 2 deletions

View File

@ -84,7 +84,7 @@ export interface CreateIndirectPRInput {
estimatedPrice?: number | null;
expenseCodeId: number;
budgetPeriod: string; // YYYY-MM
preferredSupplierId?: number | null;
preferredSupplierId: number;
priority?: 'LOW' | 'NORMAL' | 'HIGH' | 'URGENT';
requiredByDate?: string | null;
notes?: string | null;

View File

@ -612,6 +612,7 @@ export function IndirectPurchasesTab() {
<Form.Item
name="preferredSupplierId"
label="Поставщик (IND_)"
rules={[{ required: true, message: 'Выберите поставщика' }]}
>
<Select
allowClear
@ -811,6 +812,7 @@ export function IndirectPurchasesTab() {
estimatedPrice: vals.estimatedPrice,
deliveryCost: vals.deliveryCost,
notes: vals.notes,
preferredSupplierId: vals.preferredSupplierId,
} as any);
message.success('Сохранено');
setEditingPR(false);
@ -820,6 +822,14 @@ export function IndirectPurchasesTab() {
} catch { message.error('Ошибка сохранения'); }
finally { setActionLoading(false); }
}}>
<Form.Item name="preferredSupplierId" label="Поставщик" rules={[{ required: true, message: 'Выберите поставщика' }]}>
<Select
showSearch
optionFilterProp="label"
placeholder="Выберите поставщика"
options={suppliers.map((s) => ({ value: s.id, label: s.companyName }))}
/>
</Form.Item>
<Form.Item name="quantity" label="Количество" rules={[{ required: true }]}>
<InputNumber style={{ width: '100%' }} min={0.01} />
</Form.Item>
@ -862,6 +872,7 @@ export function IndirectPurchasesTab() {
estimatedPrice: selectedPR.estimatedPrice ? Number(selectedPR.estimatedPrice) : null,
deliveryCost: (selectedPR as any).deliveryCost ? Number((selectedPR as any).deliveryCost) : null,
notes: selectedPR.notes ?? '',
preferredSupplierId: (selectedPR as any).preferredSupplierId ?? undefined,
});
setEditingPR(true);
}}>

View File

@ -12,7 +12,7 @@ export const createIndirectPRSchema = z.object({
estimatedPrice: z.number().min(0).optional().nullable(),
expenseCodeId: z.number().int().positive('Статья расходов обязательна'),
budgetPeriod: z.string().regex(/^\d{4}-\d{2}$/, 'Период должен быть в формате YYYY-MM'),
preferredSupplierId: z.number().int().positive().optional().nullable(),
preferredSupplierId: z.number().int().positive({ message: 'Выберите поставщика' }),
priority: z.enum(PURCHASE_PRIORITIES).default('NORMAL'),
requiredByDate: z.coerce.date().optional().nullable(),
notes: z.string().optional().nullable(),

View File

@ -33,6 +33,7 @@ export const updatePurchaseRequirementSchema = z.object({
requiredByDate: z.coerce.date().optional().nullable(),
notes: z.string().optional().nullable(),
supplierHintId: z.number().int().positive().optional().nullable(),
preferredSupplierId: z.number().int().positive().optional().nullable(),
inStock: z.boolean().optional(),
});

View File

@ -233,6 +233,13 @@ export class PurchaseService {
if ((input as any).deliveryCost !== undefined) {
data.deliveryCost = (input as any).deliveryCost != null ? Number((input as any).deliveryCost) : null;
}
if (input.preferredSupplierId !== undefined) {
if (input.preferredSupplierId != null) {
const supplier = await this.prisma.supplier.findUnique({ where: { id: input.preferredSupplierId } });
if (!supplier) httpError(404, 'Поставщик не найден');
}
data.preferredSupplierId = input.preferredSupplierId;
}
if ((input as any).isTemplate !== undefined) data.isTemplate = (input as any).isTemplate;
if ((input as any).templateName !== undefined) data.templateName = (input as any).templateName;