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:
co-authored by
Claude Sonnet 5
parent
b48436de93
commit
7edb80e498
@@ -112,6 +112,8 @@ type LocalConfiguration struct {
|
||||
CompetitorPricelistID *uint `gorm:"index" json:"competitor_pricelist_id,omitempty"`
|
||||
DisablePriceRefresh bool `gorm:"default:false" json:"disable_price_refresh"`
|
||||
OnlyInStock bool `gorm:"default:false" json:"only_in_stock"`
|
||||
RentalItems RentalItemConditions `gorm:"type:text" json:"rental_items,omitempty"`
|
||||
RentalUpliftPercent float64 `gorm:"default:0" json:"rental_uplift_percent"`
|
||||
VendorSpec VendorSpec `gorm:"type:text" json:"vendor_spec,omitempty"`
|
||||
Line int `gorm:"column:line_no;index" json:"line"`
|
||||
PriceUpdatedAt *time.Time `gorm:"type:timestamp" json:"price_updated_at,omitempty"`
|
||||
@@ -141,6 +143,7 @@ type LocalProject struct {
|
||||
TrackerURL string `json:"tracker_url"`
|
||||
IsActive bool `gorm:"default:true;index" json:"is_active"`
|
||||
IsSystem bool `gorm:"default:false;index" json:"is_system"`
|
||||
RentalEnabled bool `gorm:"default:false" json:"rental_enabled"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
SyncedAt *time.Time `json:"synced_at,omitempty"`
|
||||
@@ -298,6 +301,39 @@ func (LocalPartnumberBookItem) TableName() string {
|
||||
return "local_partnumber_book_items"
|
||||
}
|
||||
|
||||
// RentalItemCondition tracks New/БУ condition per component for a single
|
||||
// configuration's Аренда (rental) tab. Independent of the lot's catalog data.
|
||||
type RentalItemCondition struct {
|
||||
LotName string `json:"lot_name"`
|
||||
Condition string `json:"condition"` // "new" or "used"
|
||||
}
|
||||
|
||||
type RentalItemConditions []RentalItemCondition
|
||||
|
||||
func (r RentalItemConditions) Value() (driver.Value, error) {
|
||||
if r == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return json.Marshal(r)
|
||||
}
|
||||
|
||||
func (r *RentalItemConditions) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
*r = nil
|
||||
return nil
|
||||
}
|
||||
var bytes []byte
|
||||
switch v := value.(type) {
|
||||
case []byte:
|
||||
bytes = v
|
||||
case string:
|
||||
bytes = []byte(v)
|
||||
default:
|
||||
return errors.New("type assertion failed for RentalItemConditions")
|
||||
}
|
||||
return json.Unmarshal(bytes, r)
|
||||
}
|
||||
|
||||
// VendorSpecItem represents a single row in a vendor BOM specification
|
||||
type VendorSpecItem struct {
|
||||
SortOrder int `json:"sort_order"`
|
||||
|
||||
Reference in New Issue
Block a user