feat: расчёт стоимости платного тестирования/аренды GPU-серверов

Новая вкладка «Аренда» в конфигураторе (доступна для проектов с флагом
rental_enabled): расчёт по методичке "Регламент расчёта стоимости
платного тестирования и аренды GPU-серверов" — Разовый + Еженедельный
платёж по каждому компоненту (New/БУ чекбоксом), с аплифтом к Estimate.

Заодно: поддержка (support_code) в Base-вкладке теперь добавляется как
обычный LOT в спеку (SVC_{срок}y{уровень}_{платформа}) через
autocomplete-пикер вместо выпадающего списка — партномер собирается
тем же lot_name-based механизмом, что и для GPU/CPU/памяти, справочная
цена по регламенту техподдержки хранится в qt_settings.support_pricing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Mikhail Chusavitin
2026-07-22 13:34:07 +03:00
co-authored by Claude Sonnet 5
parent b48436de93
commit 7edb80e498
25 changed files with 1052 additions and 71 deletions
+28
View File
@@ -74,6 +74,8 @@ func ConfigurationToLocal(cfg *models.Configuration) *LocalConfiguration {
VendorSpec: modelVendorSpecToLocal(cfg.VendorSpec),
DisablePriceRefresh: cfg.DisablePriceRefresh,
OnlyInStock: cfg.OnlyInStock,
RentalItems: modelRentalItemsToLocal(cfg.RentalItems),
RentalUpliftPercent: cfg.RentalUpliftPercent,
Line: cfg.Line,
PriceUpdatedAt: cfg.PriceUpdatedAt,
CreatedAt: cfg.CreatedAt,
@@ -123,6 +125,8 @@ func LocalToConfiguration(local *LocalConfiguration) *models.Configuration {
VendorSpec: localVendorSpecToModel(local.VendorSpec),
DisablePriceRefresh: local.DisablePriceRefresh,
OnlyInStock: local.OnlyInStock,
RentalItems: localRentalItemsToModel(local.RentalItems),
RentalUpliftPercent: local.RentalUpliftPercent,
Line: local.Line,
PriceUpdatedAt: local.PriceUpdatedAt,
CreatedAt: local.CreatedAt,
@@ -231,6 +235,28 @@ func localVendorSpecToModel(spec VendorSpec) models.VendorSpec {
return out
}
func modelRentalItemsToLocal(items models.RentalItemConditions) RentalItemConditions {
if len(items) == 0 {
return nil
}
out := make(RentalItemConditions, len(items))
for i, item := range items {
out[i] = RentalItemCondition{LotName: item.LotName, Condition: item.Condition}
}
return out
}
func localRentalItemsToModel(items RentalItemConditions) models.RentalItemConditions {
if len(items) == 0 {
return nil
}
out := make(models.RentalItemConditions, len(items))
for i, item := range items {
out[i] = models.RentalItemCondition{LotName: item.LotName, Condition: item.Condition}
}
return out
}
func ProjectToLocal(project *models.Project) *LocalProject {
local := &LocalProject{
UUID: project.UUID,
@@ -241,6 +267,7 @@ func ProjectToLocal(project *models.Project) *LocalProject {
TrackerURL: project.TrackerURL,
IsActive: project.IsActive,
IsSystem: project.IsSystem,
RentalEnabled: project.RentalEnabled,
CreatedAt: project.CreatedAt,
UpdatedAt: project.UpdatedAt,
SyncStatus: "pending",
@@ -262,6 +289,7 @@ func LocalToProject(local *LocalProject) *models.Project {
TrackerURL: local.TrackerURL,
IsActive: local.IsActive,
IsSystem: local.IsSystem,
RentalEnabled: local.RentalEnabled,
CreatedAt: local.CreatedAt,
UpdatedAt: local.UpdatedAt,
}