fix on stocks on store catalogue
This commit is contained in:
@@ -42,9 +42,11 @@ type fakeProductRepo struct {
|
||||
existingByImage *models.Products
|
||||
linked [][2]any
|
||||
|
||||
ensuredRefs []models.ProductLocationRef
|
||||
syncedRefs []models.ProductLocationRef
|
||||
categorySet map[int][2]int // productid -> {categoryid, subcategoryid}
|
||||
ensuredRefs []models.ProductLocationRef
|
||||
syncedRefs []models.ProductLocationRef
|
||||
publishedRefs []models.ProductLocationRef
|
||||
created []models.Products
|
||||
categorySet map[int][2]int // productid -> {categoryid, subcategoryid}
|
||||
}
|
||||
|
||||
func newFakeRepo() *fakeProductRepo {
|
||||
@@ -107,6 +109,26 @@ func (f *fakeProductRepo) UpdateProductCategory(productid, categoryid, subcatego
|
||||
return nil
|
||||
}
|
||||
|
||||
// Publishing what an import brought in priced.
|
||||
//
|
||||
// The gate exists to stop an UNPRICED product reaching a till; a spreadsheet
|
||||
// import carries the price, so demanding a second manual release protected
|
||||
// nothing — and cost the merchant sight of their own stock, because nothing in
|
||||
// the backend filters on `publishedat` but the store catalogue screen does.
|
||||
// A fresh import creates the snapshot; the existing cases all take the
|
||||
// re-import branch, so this only became reachable when publishing did.
|
||||
func (f *fakeProductRepo) CreateProductReturningID(product models.Products) (int, error) {
|
||||
f.calls = append(f.calls, "CreateProductReturningID")
|
||||
f.created = append(f.created, product)
|
||||
return 9001, nil
|
||||
}
|
||||
|
||||
func (f *fakeProductRepo) PublishPricedLocations(refs []models.ProductLocationRef) error {
|
||||
f.calls = append(f.calls, "PublishPricedLocations")
|
||||
f.publishedRefs = append(f.publishedRefs, refs...)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *fakeProductRepo) CreateProductLocation(input []models.Productlocations) error {
|
||||
f.calls = append(f.calls, "CreateProductLocation")
|
||||
return nil
|
||||
@@ -513,3 +535,74 @@ func TestBrowseStillHidesWhatTheShopDoesNotHave(t *testing.T) {
|
||||
t.Fatalf("browse should still offer only the stocked product, got %v", names(offered))
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
A priced import releases itself.
|
||||
|
||||
The publish gate is there to stop an unpriced product reaching a till that would
|
||||
ring it up at zero. A spreadsheet import carries the price on every row, so the
|
||||
condition is already met at import time and a second manual release could only
|
||||
ever answer "yes".
|
||||
|
||||
It was not a harmless extra click. Nothing in the backend filters on
|
||||
`publishedat` — only the merchant's own store-catalogue screen does — so on
|
||||
2026-08-31 seventeen products at R mart were on sale in the customer app, priced
|
||||
and stocked, while the shopkeeper's store catalogue showed none of them. The one
|
||||
person who could not see the stock was the one selling it.
|
||||
*/
|
||||
func TestImportPublishesWhatItPriced(t *testing.T) {
|
||||
repo := newFakeRepo()
|
||||
service := NewProductService(repo, &fakeCatalogueService{
|
||||
product: &models.CatalogueProduct{
|
||||
ID: 1, Brand: "kohinoor", ProductName: "Kohinoor Charminar Rice 5kg",
|
||||
ImageID: "kohinoor_kohinoor_charminar_rice_5kg",
|
||||
},
|
||||
})
|
||||
|
||||
if err := service.ImportCatalogueProduct([]models.ImportCatalogueProductRequest{{
|
||||
Tenantid: 1147, Locationid: 1185, Brand: "kohinoor", Catalogueid: 1,
|
||||
Categoryid: 2, Retailprice: 395, Quantity: 22, Stocktype: "in",
|
||||
}}); err != nil {
|
||||
t.Fatalf("ImportCatalogueProduct: %v", err)
|
||||
}
|
||||
|
||||
if len(repo.publishedRefs) != 1 {
|
||||
t.Fatalf("want the imported row released, got %d refs (calls: %v)",
|
||||
len(repo.publishedRefs), repo.calls)
|
||||
}
|
||||
got := repo.publishedRefs[0]
|
||||
// The branch that was imported into, and only that one. Publishing
|
||||
// tenant-wide would put products in outlets nobody chose.
|
||||
if got.Tenantid != 1147 || got.Locationid != 1185 {
|
||||
t.Errorf("released the wrong row: %+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
// Order matters: publishing addresses (tenantid, locationid, productid), and a
|
||||
// brand-new snapshot has no productid until its rows are written.
|
||||
func TestImportPublishesAfterTheRowsExist(t *testing.T) {
|
||||
repo := newFakeRepo()
|
||||
service := NewProductService(repo, &fakeCatalogueService{
|
||||
product: &models.CatalogueProduct{ID: 1, Brand: "colin", ProductName: "Colin Glass Cleaner 500ml"},
|
||||
})
|
||||
|
||||
if err := service.ImportCatalogueProduct([]models.ImportCatalogueProductRequest{{
|
||||
Tenantid: 1147, Locationid: 1185, Brand: "colin", Catalogueid: 1,
|
||||
Categoryid: 2, Retailprice: 105, Quantity: 42,
|
||||
}}); err != nil {
|
||||
t.Fatalf("ImportCatalogueProduct: %v", err)
|
||||
}
|
||||
|
||||
create, publish := -1, -1
|
||||
for i, call := range repo.calls {
|
||||
if call == "CreateProductLocation" {
|
||||
create = i
|
||||
}
|
||||
if call == "PublishPricedLocations" {
|
||||
publish = i
|
||||
}
|
||||
}
|
||||
if create < 0 || publish < 0 || publish < create {
|
||||
t.Fatalf("want CreateProductLocation before PublishPricedLocations, got %v", repo.calls)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user