feat: складские цены и «только наличие» — настройки уровня проекта

Добавлен чекбокс «Складские цены» (по аналогии с «Аренда»), управляющий
показом складских цен во всех ценовых интерфейсах конфигурации, включая
CSV-экспорт. «Только наличие» перенесён из настроек цен конфигурации в
настройки проекта и активен только при включённых складских ценах.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Mikhail Chusavitin
2026-08-12 17:05:39 +03:00
co-authored by Claude Sonnet 5
parent 18282452a1
commit 9629521495
18 changed files with 244 additions and 166 deletions
+11 -6
View File
@@ -238,11 +238,18 @@ func (h *ExportHandler) ExportConfigPricingCSV(c *gin.Context) {
return
}
var project *models.Project
if config.ProjectUUID != nil && *config.ProjectUUID != "" {
if p, err := h.projectService.GetByUUID(*config.ProjectUUID, h.dbUsername); err == nil {
project = p
}
}
opts := services.ProjectPricingExportOptions{
IncludeLOT: req.IncludeLOT,
IncludeBOM: req.IncludeBOM,
IncludeEstimate: req.IncludeEstimate,
IncludeStock: req.IncludeStock,
IncludeStock: req.IncludeStock && project != nil && project.ShowStockPrices,
IncludeCompetitor: req.IncludeCompetitor,
Basis: req.Basis,
SaleMarkup: req.SaleMarkup,
@@ -260,10 +267,8 @@ func (h *ExportHandler) ExportConfigPricingCSV(c *gin.Context) {
}
projectCode := config.Name
if config.ProjectUUID != nil && *config.ProjectUUID != "" {
if project, err := h.projectService.GetByUUID(*config.ProjectUUID, h.dbUsername); err == nil && project != nil {
projectCode = project.Code
}
if project != nil {
projectCode = project.Code
}
filename := fmt.Sprintf("%s (%s) %s %s SPEC.csv",
@@ -309,7 +314,7 @@ func (h *ExportHandler) ExportProjectPricingCSV(c *gin.Context) {
IncludeLOT: req.IncludeLOT,
IncludeBOM: req.IncludeBOM,
IncludeEstimate: req.IncludeEstimate,
IncludeStock: req.IncludeStock,
IncludeStock: req.IncludeStock && project.ShowStockPrices,
IncludeCompetitor: req.IncludeCompetitor,
Basis: req.Basis,
SaleMarkup: req.SaleMarkup,
@@ -19,7 +19,6 @@ func TestConfigurationConvertersPreserveBusinessFields(t *testing.T) {
WarehousePricelistID: &warehouseID,
CompetitorPricelistID: &competitorID,
DisablePriceRefresh: true,
OnlyInStock: true,
}
local := ConfigurationToLocal(cfg)
@@ -57,7 +56,6 @@ func TestConfigurationSnapshotPreservesBusinessFields(t *testing.T) {
WarehousePricelistID: &warehouseID,
CompetitorPricelistID: &competitorID,
DisablePriceRefresh: true,
OnlyInStock: true,
VendorSpec: VendorSpec{
{
SortOrder: 10,
@@ -110,7 +108,6 @@ func TestConfigurationFingerprintIncludesPricingSelectorsAndVendorSpec(t *testin
WarehousePricelistID: &warehouseID,
CompetitorPricelistID: &competitorID,
DisablePriceRefresh: true,
OnlyInStock: true,
VendorSpec: VendorSpec{
{
SortOrder: 10,
+27 -25
View File
@@ -73,7 +73,6 @@ func ConfigurationToLocal(cfg *models.Configuration) *LocalConfiguration {
ConfigType: cfg.ConfigType,
VendorSpec: modelVendorSpecToLocal(cfg.VendorSpec),
DisablePriceRefresh: cfg.DisablePriceRefresh,
OnlyInStock: cfg.OnlyInStock,
RentalItems: modelRentalItemsToLocal(cfg.RentalItems),
RentalUpliftPercent: cfg.RentalUpliftPercent,
Line: cfg.Line,
@@ -124,7 +123,6 @@ func LocalToConfiguration(local *LocalConfiguration) *models.Configuration {
ConfigType: local.ConfigType,
VendorSpec: localVendorSpecToModel(local.VendorSpec),
DisablePriceRefresh: local.DisablePriceRefresh,
OnlyInStock: local.OnlyInStock,
RentalItems: localRentalItemsToModel(local.RentalItems),
RentalUpliftPercent: local.RentalUpliftPercent,
Line: local.Line,
@@ -259,18 +257,20 @@ func localRentalItemsToModel(items RentalItemConditions) models.RentalItemCondit
func ProjectToLocal(project *models.Project) *LocalProject {
local := &LocalProject{
UUID: project.UUID,
OwnerUsername: project.OwnerUsername,
Code: project.Code,
Variant: project.Variant,
Name: project.Name,
TrackerURL: project.TrackerURL,
IsActive: project.IsActive,
IsSystem: project.IsSystem,
RentalEnabled: project.RentalEnabled,
CreatedAt: project.CreatedAt,
UpdatedAt: project.UpdatedAt,
SyncStatus: "pending",
UUID: project.UUID,
OwnerUsername: project.OwnerUsername,
Code: project.Code,
Variant: project.Variant,
Name: project.Name,
TrackerURL: project.TrackerURL,
IsActive: project.IsActive,
IsSystem: project.IsSystem,
RentalEnabled: project.RentalEnabled,
ShowStockPrices: project.ShowStockPrices,
OnlyInStock: project.OnlyInStock,
CreatedAt: project.CreatedAt,
UpdatedAt: project.UpdatedAt,
SyncStatus: "pending",
}
if project.ID > 0 {
serverID := project.ID
@@ -281,17 +281,19 @@ func ProjectToLocal(project *models.Project) *LocalProject {
func LocalToProject(local *LocalProject) *models.Project {
project := &models.Project{
UUID: local.UUID,
OwnerUsername: local.OwnerUsername,
Code: local.Code,
Variant: local.Variant,
Name: local.Name,
TrackerURL: local.TrackerURL,
IsActive: local.IsActive,
IsSystem: local.IsSystem,
RentalEnabled: local.RentalEnabled,
CreatedAt: local.CreatedAt,
UpdatedAt: local.UpdatedAt,
UUID: local.UUID,
OwnerUsername: local.OwnerUsername,
Code: local.Code,
Variant: local.Variant,
Name: local.Name,
TrackerURL: local.TrackerURL,
IsActive: local.IsActive,
IsSystem: local.IsSystem,
RentalEnabled: local.RentalEnabled,
ShowStockPrices: local.ShowStockPrices,
OnlyInStock: local.OnlyInStock,
CreatedAt: local.CreatedAt,
UpdatedAt: local.UpdatedAt,
}
if local.ServerID != nil {
project.ID = *local.ServerID
+2
View File
@@ -212,6 +212,8 @@ CREATE TABLE local_projects (
is_active INTEGER NOT NULL DEFAULT 1,
is_system INTEGER NOT NULL DEFAULT 0,
rental_enabled INTEGER NOT NULL DEFAULT 0,
show_stock_prices INTEGER NOT NULL DEFAULT 0,
only_in_stock INTEGER NOT NULL DEFAULT 0,
created_at DATETIME,
updated_at DATETIME,
synced_at DATETIME NULL,
+21
View File
@@ -139,6 +139,11 @@ var localMigrations = []localMigration{
name: "Add price_quality to local_pricelist_items",
run: addLocalPricelistItemPriceQuality,
},
{
id: "2026_08_12_local_project_stock_settings",
name: "Add show_stock_prices and only_in_stock to local_projects",
run: addLocalProjectStockSettings,
},
}
func addLocalPricelistItemPriceQuality(tx *gorm.DB) error {
@@ -249,6 +254,22 @@ func addLocalProjectRentalEnabled(tx *gorm.DB) error {
return nil
}
func addLocalProjectStockSettings(tx *gorm.DB) error {
stmts := []string{
`ALTER TABLE local_projects ADD COLUMN show_stock_prices INTEGER NOT NULL DEFAULT 0`,
`ALTER TABLE local_projects ADD COLUMN only_in_stock INTEGER NOT NULL DEFAULT 0`,
}
for _, stmt := range stmts {
if err := tx.Exec(stmt).Error; err != nil {
if !strings.Contains(strings.ToLower(err.Error()), "duplicate") &&
!strings.Contains(strings.ToLower(err.Error()), "exists") {
return err
}
}
}
return nil
}
type localPartnumberCatalogRow struct {
Partnumber string
LotsJSON LocalPartnumberBookLots
+17 -16
View File
@@ -111,7 +111,6 @@ type LocalConfiguration struct {
WarehousePricelistID *uint `gorm:"index" json:"warehouse_pricelist_id,omitempty"`
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"`
@@ -133,21 +132,23 @@ func (LocalConfiguration) TableName() string {
}
type LocalProject struct {
ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
UUID string `gorm:"uniqueIndex;not null" json:"uuid"`
ServerID *uint `json:"server_id,omitempty"`
OwnerUsername string `gorm:"not null;index" json:"owner_username"`
Code string `gorm:"not null;index:idx_local_projects_code_variant,priority:1" json:"code"`
Variant string `gorm:"default:'';index:idx_local_projects_code_variant,priority:2" json:"variant"`
Name *string `json:"name,omitempty"`
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"`
SyncStatus string `gorm:"default:'local'" json:"sync_status"` // local/synced/pending
ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
UUID string `gorm:"uniqueIndex;not null" json:"uuid"`
ServerID *uint `json:"server_id,omitempty"`
OwnerUsername string `gorm:"not null;index" json:"owner_username"`
Code string `gorm:"not null;index:idx_local_projects_code_variant,priority:1" json:"code"`
Variant string `gorm:"default:'';index:idx_local_projects_code_variant,priority:2" json:"variant"`
Name *string `json:"name,omitempty"`
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"`
ShowStockPrices bool `gorm:"default:false" json:"show_stock_prices"`
OnlyInStock bool `gorm:"default:false" json:"only_in_stock"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
SyncedAt *time.Time `json:"synced_at,omitempty"`
SyncStatus string `gorm:"default:'local'" json:"sync_status"` // local/synced/pending
}
func (LocalProject) TableName() string {
+20 -25
View File
@@ -30,7 +30,6 @@ func BuildConfigurationSnapshot(localCfg *LocalConfiguration) (string, error) {
"warehouse_pricelist_id": localCfg.WarehousePricelistID,
"competitor_pricelist_id": localCfg.CompetitorPricelistID,
"disable_price_refresh": localCfg.DisablePriceRefresh,
"only_in_stock": localCfg.OnlyInStock,
"rental_items": localCfg.RentalItems,
"rental_uplift_percent": localCfg.RentalUpliftPercent,
"vendor_spec": localCfg.VendorSpec,
@@ -54,30 +53,29 @@ func BuildConfigurationSnapshot(localCfg *LocalConfiguration) (string, error) {
// DecodeConfigurationSnapshot returns editable fields from one saved snapshot.
func DecodeConfigurationSnapshot(data string) (*LocalConfiguration, error) {
var snapshot struct {
ProjectUUID *string `json:"project_uuid"`
IsActive *bool `json:"is_active"`
Name string `json:"name"`
Items LocalConfigItems `json:"items"`
TotalPrice *float64 `json:"total_price"`
CustomPrice *float64 `json:"custom_price"`
Notes string `json:"notes"`
IsTemplate bool `json:"is_template"`
ServerCount int `json:"server_count"`
ServerModel string `json:"server_model"`
SupportCode string `json:"support_code"`
Article string `json:"article"`
PricelistID *uint `json:"pricelist_id"`
WarehousePricelistID *uint `json:"warehouse_pricelist_id"`
CompetitorPricelistID *uint `json:"competitor_pricelist_id"`
ProjectUUID *string `json:"project_uuid"`
IsActive *bool `json:"is_active"`
Name string `json:"name"`
Items LocalConfigItems `json:"items"`
TotalPrice *float64 `json:"total_price"`
CustomPrice *float64 `json:"custom_price"`
Notes string `json:"notes"`
IsTemplate bool `json:"is_template"`
ServerCount int `json:"server_count"`
ServerModel string `json:"server_model"`
SupportCode string `json:"support_code"`
Article string `json:"article"`
PricelistID *uint `json:"pricelist_id"`
WarehousePricelistID *uint `json:"warehouse_pricelist_id"`
CompetitorPricelistID *uint `json:"competitor_pricelist_id"`
DisablePriceRefresh bool `json:"disable_price_refresh"`
OnlyInStock bool `json:"only_in_stock"`
RentalItems RentalItemConditions `json:"rental_items"`
RentalUpliftPercent float64 `json:"rental_uplift_percent"`
VendorSpec VendorSpec `json:"vendor_spec"`
Line int `json:"line"`
PriceUpdatedAt *time.Time `json:"price_updated_at"`
OriginalUserID uint `json:"original_user_id"`
OriginalUsername string `json:"original_username"`
VendorSpec VendorSpec `json:"vendor_spec"`
Line int `json:"line"`
PriceUpdatedAt *time.Time `json:"price_updated_at"`
OriginalUserID uint `json:"original_user_id"`
OriginalUsername string `json:"original_username"`
}
if err := json.Unmarshal([]byte(data), &snapshot); err != nil {
@@ -106,7 +104,6 @@ func DecodeConfigurationSnapshot(data string) (*LocalConfiguration, error) {
WarehousePricelistID: snapshot.WarehousePricelistID,
CompetitorPricelistID: snapshot.CompetitorPricelistID,
DisablePriceRefresh: snapshot.DisablePriceRefresh,
OnlyInStock: snapshot.OnlyInStock,
RentalItems: snapshot.RentalItems,
RentalUpliftPercent: snapshot.RentalUpliftPercent,
VendorSpec: snapshot.VendorSpec,
@@ -126,7 +123,6 @@ type configurationSpecPriceFingerprint struct {
WarehousePricelistID *uint `json:"warehouse_pricelist_id,omitempty"`
CompetitorPricelistID *uint `json:"competitor_pricelist_id,omitempty"`
DisablePriceRefresh bool `json:"disable_price_refresh"`
OnlyInStock bool `json:"only_in_stock"`
RentalItems RentalItemConditions `json:"rental_items,omitempty"`
RentalUpliftPercent float64 `json:"rental_uplift_percent"`
VendorSpec VendorSpec `json:"vendor_spec,omitempty"`
@@ -174,7 +170,6 @@ func BuildConfigurationSpecPriceFingerprint(localCfg *LocalConfiguration) (strin
WarehousePricelistID: localCfg.WarehousePricelistID,
CompetitorPricelistID: localCfg.CompetitorPricelistID,
DisablePriceRefresh: localCfg.DisablePriceRefresh,
OnlyInStock: localCfg.OnlyInStock,
RentalItems: rentalItems,
RentalUpliftPercent: localCfg.RentalUpliftPercent,
VendorSpec: localCfg.VendorSpec,
+27 -29
View File
@@ -126,38 +126,36 @@ func (v *VendorSpec) Scan(value interface{}) error {
}
type Configuration struct {
ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
UUID string `gorm:"size:36;uniqueIndex;not null" json:"uuid"`
UserID *uint `json:"user_id,omitempty"` // Legacy field, no longer required for ownership
OwnerUsername string `gorm:"size:100;not null;default:'';index" json:"owner_username"`
ProjectUUID *string `gorm:"size:36;index" json:"project_uuid,omitempty"`
AppVersion string `gorm:"size:64" json:"app_version,omitempty"`
Name string `gorm:"size:200;not null" json:"name"`
Items ConfigItems `gorm:"type:json;not null" json:"items"`
TotalPrice *float64 `gorm:"type:decimal(12,2)" json:"total_price"`
CustomPrice *float64 `gorm:"type:decimal(12,2)" json:"custom_price"`
Notes string `gorm:"type:text" json:"notes"`
IsTemplate bool `gorm:"default:false" json:"is_template"`
ServerCount int `gorm:"default:1" json:"server_count"`
ServerModel string `gorm:"size:100" json:"server_model,omitempty"`
SupportCode string `gorm:"size:20" json:"support_code,omitempty"`
Article string `gorm:"size:80" json:"article,omitempty"`
PricelistID *uint `gorm:"index" json:"pricelist_id,omitempty"`
WarehousePricelistID *uint `gorm:"index" json:"warehouse_pricelist_id,omitempty"`
CompetitorPricelistID *uint `gorm:"index" json:"competitor_pricelist_id,omitempty"`
VendorSpec VendorSpec `gorm:"type:json" json:"vendor_spec,omitempty"`
ConfigType string `gorm:"size:20;default:server" json:"config_type"` // "server" | "storage"
DisablePriceRefresh bool `gorm:"default:false" json:"disable_price_refresh"`
OnlyInStock bool `gorm:"default:false" json:"only_in_stock"`
ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
UUID string `gorm:"size:36;uniqueIndex;not null" json:"uuid"`
UserID *uint `json:"user_id,omitempty"` // Legacy field, no longer required for ownership
OwnerUsername string `gorm:"size:100;not null;default:'';index" json:"owner_username"`
ProjectUUID *string `gorm:"size:36;index" json:"project_uuid,omitempty"`
AppVersion string `gorm:"size:64" json:"app_version,omitempty"`
Name string `gorm:"size:200;not null" json:"name"`
Items ConfigItems `gorm:"type:json;not null" json:"items"`
TotalPrice *float64 `gorm:"type:decimal(12,2)" json:"total_price"`
CustomPrice *float64 `gorm:"type:decimal(12,2)" json:"custom_price"`
Notes string `gorm:"type:text" json:"notes"`
IsTemplate bool `gorm:"default:false" json:"is_template"`
ServerCount int `gorm:"default:1" json:"server_count"`
ServerModel string `gorm:"size:100" json:"server_model,omitempty"`
SupportCode string `gorm:"size:20" json:"support_code,omitempty"`
Article string `gorm:"size:80" json:"article,omitempty"`
PricelistID *uint `gorm:"index" json:"pricelist_id,omitempty"`
WarehousePricelistID *uint `gorm:"index" json:"warehouse_pricelist_id,omitempty"`
CompetitorPricelistID *uint `gorm:"index" json:"competitor_pricelist_id,omitempty"`
VendorSpec VendorSpec `gorm:"type:json" json:"vendor_spec,omitempty"`
ConfigType string `gorm:"size:20;default:server" json:"config_type"` // "server" | "storage"
DisablePriceRefresh bool `gorm:"default:false" json:"disable_price_refresh"`
RentalItems RentalItemConditions `gorm:"type:json" json:"rental_items,omitempty"`
RentalUpliftPercent float64 `gorm:"type:decimal(8,2);default:0" json:"rental_uplift_percent"`
Line int `gorm:"column:line_no;index" json:"line"`
PriceUpdatedAt *time.Time `gorm:"type:timestamp" json:"price_updated_at,omitempty"`
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"`
CurrentVersionNo int `gorm:"-" json:"current_version_no,omitempty"`
RentalUpliftPercent float64 `gorm:"type:decimal(8,2);default:0" json:"rental_uplift_percent"`
Line int `gorm:"column:line_no;index" json:"line"`
PriceUpdatedAt *time.Time `gorm:"type:timestamp" json:"price_updated_at,omitempty"`
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"`
CurrentVersionNo int `gorm:"-" json:"current_version_no,omitempty"`
}
func (Configuration) TableName() string {
return "qt_configurations"
}
+14 -12
View File
@@ -3,18 +3,20 @@ package models
import "time"
type Project struct {
ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
UUID string `gorm:"size:36;uniqueIndex;not null" json:"uuid"`
OwnerUsername string `gorm:"size:100;not null;index" json:"owner_username"`
Code string `gorm:"size:100;not null;index:idx_qt_projects_code_variant,priority:1" json:"code"`
Variant string `gorm:"size:100;not null;default:'';index:idx_qt_projects_code_variant,priority:2" json:"variant"`
Name *string `gorm:"size:200" json:"name,omitempty"`
TrackerURL string `gorm:"size:500" 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 `gorm:"autoCreateTime" json:"created_at"`
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"`
ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
UUID string `gorm:"size:36;uniqueIndex;not null" json:"uuid"`
OwnerUsername string `gorm:"size:100;not null;index" json:"owner_username"`
Code string `gorm:"size:100;not null;index:idx_qt_projects_code_variant,priority:1" json:"code"`
Variant string `gorm:"size:100;not null;default:'';index:idx_qt_projects_code_variant,priority:2" json:"variant"`
Name *string `gorm:"size:200" json:"name,omitempty"`
TrackerURL string `gorm:"size:500" 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"`
ShowStockPrices bool `gorm:"default:false" json:"show_stock_prices"`
OnlyInStock bool `gorm:"default:false" json:"only_in_stock"`
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"`
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"`
}
func (Project) TableName() string {
+2
View File
@@ -39,6 +39,8 @@ func (r *ProjectRepository) UpsertByUUID(project *models.Project) error {
"is_active",
"is_system",
"rental_enabled",
"show_stock_prices",
"only_in_stock",
"updated_at",
}),
}).Create(project).Error; err != nil {
-1
View File
@@ -34,7 +34,6 @@ type CreateConfigRequest struct {
CompetitorPricelistID *uint `json:"competitor_pricelist_id,omitempty"`
ConfigType string `json:"config_type,omitempty"` // "server" | "storage"
DisablePriceRefresh bool `json:"disable_price_refresh"`
OnlyInStock bool `json:"only_in_stock"`
}
type ArticlePreviewRequest struct {
-6
View File
@@ -103,7 +103,6 @@ func (s *LocalConfigurationService) Create(ownerUsername string, req *CreateConf
CompetitorPricelistID: req.CompetitorPricelistID,
ConfigType: req.ConfigType,
DisablePriceRefresh: req.DisablePriceRefresh,
OnlyInStock: req.OnlyInStock,
CreatedAt: time.Now(),
}
if cfg.ConfigType == "" {
@@ -204,7 +203,6 @@ func (s *LocalConfigurationService) Update(uuid string, ownerUsername string, re
localCfg.WarehousePricelistID = req.WarehousePricelistID
localCfg.CompetitorPricelistID = req.CompetitorPricelistID
localCfg.DisablePriceRefresh = req.DisablePriceRefresh
localCfg.OnlyInStock = req.OnlyInStock
localCfg.UpdatedAt = time.Now()
localCfg.SyncStatus = "pending"
@@ -328,7 +326,6 @@ func (s *LocalConfigurationService) CloneToProject(configUUID string, ownerUsern
WarehousePricelistID: original.WarehousePricelistID,
CompetitorPricelistID: original.CompetitorPricelistID,
DisablePriceRefresh: original.DisablePriceRefresh,
OnlyInStock: original.OnlyInStock,
CreatedAt: time.Now(),
}
@@ -566,7 +563,6 @@ func (s *LocalConfigurationService) UpdateNoAuth(uuid string, req *CreateConfigR
localCfg.WarehousePricelistID = req.WarehousePricelistID
localCfg.CompetitorPricelistID = req.CompetitorPricelistID
localCfg.DisablePriceRefresh = req.DisablePriceRefresh
localCfg.OnlyInStock = req.OnlyInStock
localCfg.UpdatedAt = time.Now()
localCfg.SyncStatus = "pending"
@@ -685,7 +681,6 @@ func (s *LocalConfigurationService) CloneNoAuthToProjectFromVersion(configUUID s
WarehousePricelistID: original.WarehousePricelistID,
CompetitorPricelistID: original.CompetitorPricelistID,
DisablePriceRefresh: original.DisablePriceRefresh,
OnlyInStock: original.OnlyInStock,
CreatedAt: time.Now(),
}
@@ -1648,7 +1643,6 @@ func (s *LocalConfigurationService) rollbackToVersion(configurationUUID string,
current.WarehousePricelistID = rollbackData.WarehousePricelistID
current.CompetitorPricelistID = rollbackData.CompetitorPricelistID
current.DisablePriceRefresh = rollbackData.DisablePriceRefresh
current.OnlyInStock = rollbackData.OnlyInStock
current.VendorSpec = rollbackData.VendorSpec
if rollbackData.Line > 0 {
current.Line = rollbackData.Line
@@ -154,7 +154,6 @@ func TestUpdateNoAuthCreatesRevisionWhenPricingSettingsChanged(t *testing.T) {
Items: models.ConfigItems{{LotName: "CPU_A", Quantity: 1, UnitPrice: 1000}},
ServerCount: 1,
DisablePriceRefresh: true,
OnlyInStock: true,
}); err != nil {
t.Fatalf("update pricing settings: %v", err)
}
+13 -5
View File
@@ -46,11 +46,13 @@ type CreateProjectRequest struct {
}
type UpdateProjectRequest struct {
Code *string `json:"code,omitempty"`
Variant *string `json:"variant,omitempty"`
Name *string `json:"name,omitempty"`
TrackerURL *string `json:"tracker_url,omitempty"`
RentalEnabled *bool `json:"rental_enabled,omitempty"`
Code *string `json:"code,omitempty"`
Variant *string `json:"variant,omitempty"`
Name *string `json:"name,omitempty"`
TrackerURL *string `json:"tracker_url,omitempty"`
RentalEnabled *bool `json:"rental_enabled,omitempty"`
ShowStockPrices *bool `json:"show_stock_prices,omitempty"`
OnlyInStock *bool `json:"only_in_stock,omitempty"`
}
type ProjectConfigurationsResult struct {
@@ -152,6 +154,12 @@ func (s *ProjectService) Update(projectUUID, ownerUsername string, req *UpdatePr
if req.RentalEnabled != nil {
localProject.RentalEnabled = *req.RentalEnabled
}
if req.ShowStockPrices != nil {
localProject.ShowStockPrices = *req.ShowStockPrices
}
if req.OnlyInStock != nil {
localProject.OnlyInStock = *req.OnlyInStock
}
localProject.UpdatedAt = time.Now()
localProject.SyncStatus = "pending"
if err := s.localDB.SaveProject(localProject); err != nil {
+2
View File
@@ -218,6 +218,8 @@ func (s *Service) ImportProjectsToLocal() (*ProjectImportResult, error) {
existing.IsActive = project.IsActive
existing.IsSystem = project.IsSystem
existing.RentalEnabled = project.RentalEnabled
existing.ShowStockPrices = project.ShowStockPrices
existing.OnlyInStock = project.OnlyInStock
existing.CreatedAt = project.CreatedAt
existing.UpdatedAt = project.UpdatedAt
serverID := project.ID