WIP: save current pricing and pricelist changes
This commit is contained in:
124
internal/services/quote_price_levels_test.go
Normal file
124
internal/services/quote_price_levels_test.go
Normal file
@@ -0,0 +1,124 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.mchus.pro/mchus/quoteforge/internal/models"
|
||||
"git.mchus.pro/mchus/quoteforge/internal/repository"
|
||||
"github.com/glebarez/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func TestCalculatePriceLevels_WithMissingLevel(t *testing.T) {
|
||||
db := newPriceLevelsTestDB(t)
|
||||
repo := repository.NewPricelistRepository(db)
|
||||
service := NewQuoteService(nil, nil, repo, nil, nil)
|
||||
|
||||
estimate := seedPricelistWithItem(t, repo, "estimate", "CPU_X", 100)
|
||||
_ = estimate
|
||||
seedPricelistWithItem(t, repo, "warehouse", "CPU_X", 120)
|
||||
|
||||
result, err := service.CalculatePriceLevels(&PriceLevelsRequest{
|
||||
Items: []struct {
|
||||
LotName string `json:"lot_name"`
|
||||
Quantity int `json:"quantity"`
|
||||
}{
|
||||
{LotName: "CPU_X", Quantity: 2},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("CalculatePriceLevels returned error: %v", err)
|
||||
}
|
||||
if len(result.Items) != 1 {
|
||||
t.Fatalf("expected 1 item, got %d", len(result.Items))
|
||||
}
|
||||
item := result.Items[0]
|
||||
if item.EstimatePrice == nil || *item.EstimatePrice != 100 {
|
||||
t.Fatalf("expected estimate 100, got %#v", item.EstimatePrice)
|
||||
}
|
||||
if item.WarehousePrice == nil || *item.WarehousePrice != 120 {
|
||||
t.Fatalf("expected warehouse 120, got %#v", item.WarehousePrice)
|
||||
}
|
||||
if item.CompetitorPrice != nil {
|
||||
t.Fatalf("expected competitor nil, got %#v", item.CompetitorPrice)
|
||||
}
|
||||
if len(item.PriceMissing) != 1 || item.PriceMissing[0] != "competitor" {
|
||||
t.Fatalf("expected price_missing [competitor], got %#v", item.PriceMissing)
|
||||
}
|
||||
if item.DeltaWhEstimateAbs == nil || *item.DeltaWhEstimateAbs != 20 {
|
||||
t.Fatalf("expected delta abs 20, got %#v", item.DeltaWhEstimateAbs)
|
||||
}
|
||||
if item.DeltaWhEstimatePct == nil || *item.DeltaWhEstimatePct != 20 {
|
||||
t.Fatalf("expected delta pct 20, got %#v", item.DeltaWhEstimatePct)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCalculatePriceLevels_UsesExplicitPricelistIDs(t *testing.T) {
|
||||
db := newPriceLevelsTestDB(t)
|
||||
repo := repository.NewPricelistRepository(db)
|
||||
service := NewQuoteService(nil, nil, repo, nil, nil)
|
||||
|
||||
olderEstimate := seedPricelistWithItem(t, repo, "estimate", "CPU_Y", 80)
|
||||
seedPricelistWithItem(t, repo, "estimate", "CPU_Y", 90)
|
||||
|
||||
result, err := service.CalculatePriceLevels(&PriceLevelsRequest{
|
||||
Items: []struct {
|
||||
LotName string `json:"lot_name"`
|
||||
Quantity int `json:"quantity"`
|
||||
}{
|
||||
{LotName: "CPU_Y", Quantity: 1},
|
||||
},
|
||||
PricelistIDs: map[string]uint{
|
||||
"estimate": olderEstimate.ID,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("CalculatePriceLevels returned error: %v", err)
|
||||
}
|
||||
item := result.Items[0]
|
||||
if item.EstimatePrice == nil || *item.EstimatePrice != 80 {
|
||||
t.Fatalf("expected explicit estimate 80, got %#v", item.EstimatePrice)
|
||||
}
|
||||
}
|
||||
|
||||
func newPriceLevelsTestDB(t *testing.T) *gorm.DB {
|
||||
t.Helper()
|
||||
db, err := gorm.Open(sqlite.Open("file::memory:?cache=shared"), &gorm.Config{})
|
||||
if err != nil {
|
||||
t.Fatalf("open sqlite: %v", err)
|
||||
}
|
||||
if err := db.AutoMigrate(&models.Pricelist{}, &models.PricelistItem{}); err != nil {
|
||||
t.Fatalf("migrate: %v", err)
|
||||
}
|
||||
return db
|
||||
}
|
||||
|
||||
func seedPricelistWithItem(t *testing.T, repo *repository.PricelistRepository, source, lot string, price float64) *models.Pricelist {
|
||||
t.Helper()
|
||||
version, err := repo.GenerateVersionBySource(source)
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateVersionBySource: %v", err)
|
||||
}
|
||||
expiresAt := time.Now().Add(24 * time.Hour)
|
||||
pl := &models.Pricelist{
|
||||
Source: source,
|
||||
Version: version,
|
||||
CreatedBy: "test",
|
||||
IsActive: true,
|
||||
ExpiresAt: &expiresAt,
|
||||
}
|
||||
if err := repo.Create(pl); err != nil {
|
||||
t.Fatalf("create pricelist: %v", err)
|
||||
}
|
||||
if err := repo.CreateItems([]models.PricelistItem{
|
||||
{
|
||||
PricelistID: pl.ID,
|
||||
LotName: lot,
|
||||
Price: price,
|
||||
},
|
||||
}); err != nil {
|
||||
t.Fatalf("create items: %v", err)
|
||||
}
|
||||
return pl
|
||||
}
|
||||
Reference in New Issue
Block a user