mirror of
https://github.com/3ybactuk/marketplace-go-service-project.git
synced 2025-10-30 14:03:45 +03:00
[hw-3] loms service
This commit is contained in:
114
loms/internal/domain/repository/stocks/in_memory_repository.go
Normal file
114
loms/internal/domain/repository/stocks/in_memory_repository.go
Normal file
@@ -0,0 +1,114 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
"encoding/json"
|
||||
"sync"
|
||||
|
||||
"route256/loms/internal/domain/entity"
|
||||
"route256/loms/internal/domain/model"
|
||||
)
|
||||
|
||||
//go:embed stock-data.json
|
||||
var stockData []byte
|
||||
|
||||
type storage = map[entity.Sku]*entity.Stock
|
||||
|
||||
type InMemoryRepository struct {
|
||||
storage storage
|
||||
mx sync.RWMutex
|
||||
}
|
||||
|
||||
func NewInMemoryRepository(cap int) (*InMemoryRepository, error) {
|
||||
var rows []struct {
|
||||
Sku entity.Sku `json:"sku"`
|
||||
TotalCount uint32 `json:"total_count"`
|
||||
Reserved uint32 `json:"reserved"`
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(stockData, &rows); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repo := &InMemoryRepository{
|
||||
storage: make(storage, cap),
|
||||
}
|
||||
|
||||
for _, r := range rows {
|
||||
repo.storage[r.Sku] = &entity.Stock{
|
||||
Item: entity.OrderItem{
|
||||
ID: r.Sku,
|
||||
Count: r.TotalCount,
|
||||
},
|
||||
Reserved: r.Reserved,
|
||||
}
|
||||
}
|
||||
|
||||
return repo, nil
|
||||
}
|
||||
|
||||
func (r *InMemoryRepository) StockReserve(_ context.Context, stock *entity.Stock) error {
|
||||
r.mx.Lock()
|
||||
defer r.mx.Unlock()
|
||||
|
||||
if _, ok := r.storage[stock.Item.ID]; !ok {
|
||||
return model.ErrNotEnoughStocks
|
||||
}
|
||||
|
||||
if r.storage[stock.Item.ID].Item.Count < stock.Reserved {
|
||||
return model.ErrNotEnoughStocks
|
||||
}
|
||||
|
||||
r.storage[stock.Item.ID].Item.Count -= stock.Reserved
|
||||
r.storage[stock.Item.ID].Reserved += stock.Reserved
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *InMemoryRepository) StockReserveRemove(_ context.Context, stock *entity.Stock) error {
|
||||
r.mx.Lock()
|
||||
defer r.mx.Unlock()
|
||||
|
||||
if _, ok := r.storage[stock.Item.ID]; !ok {
|
||||
return model.ErrUnknownStock
|
||||
}
|
||||
|
||||
if r.storage[stock.Item.ID].Reserved < stock.Reserved {
|
||||
return model.ErrNotEnoughStocks
|
||||
}
|
||||
|
||||
r.storage[stock.Item.ID].Reserved -= stock.Reserved
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *InMemoryRepository) StockCancel(_ context.Context, stock *entity.Stock) error {
|
||||
r.mx.Lock()
|
||||
defer r.mx.Unlock()
|
||||
|
||||
if _, ok := r.storage[stock.Item.ID]; !ok {
|
||||
return model.ErrUnknownStock
|
||||
}
|
||||
|
||||
if r.storage[stock.Item.ID].Reserved < stock.Reserved {
|
||||
return model.ErrNotEnoughStocks
|
||||
}
|
||||
|
||||
r.storage[stock.Item.ID].Reserved -= stock.Reserved
|
||||
r.storage[stock.Item.ID].Item.Count += stock.Reserved
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *InMemoryRepository) StockGetByID(_ context.Context, sku entity.Sku) (*entity.Stock, error) {
|
||||
r.mx.Lock()
|
||||
defer r.mx.Unlock()
|
||||
|
||||
stock, ok := r.storage[sku]
|
||||
if !ok {
|
||||
return nil, model.ErrUnknownStock
|
||||
}
|
||||
|
||||
return stock, nil
|
||||
}
|
||||
37
loms/internal/domain/repository/stocks/stock-data.json
Normal file
37
loms/internal/domain/repository/stocks/stock-data.json
Normal file
@@ -0,0 +1,37 @@
|
||||
[
|
||||
{
|
||||
"sku": 139275865,
|
||||
"total_count": 65534,
|
||||
"reserved": 0
|
||||
},
|
||||
{
|
||||
"sku": 2956315,
|
||||
"total_count": 100,
|
||||
"reserved": 30
|
||||
},
|
||||
{
|
||||
"sku": 1076963,
|
||||
"total_count": 100,
|
||||
"reserved": 35
|
||||
},
|
||||
{
|
||||
"sku": 135717466,
|
||||
"total_count": 100,
|
||||
"reserved": 20
|
||||
},
|
||||
{
|
||||
"sku": 135937324,
|
||||
"total_count": 100,
|
||||
"reserved": 30
|
||||
},
|
||||
{
|
||||
"sku": 1625903,
|
||||
"total_count": 10000,
|
||||
"reserved": 0
|
||||
},
|
||||
{
|
||||
"sku": 1148162,
|
||||
"total_count": 100,
|
||||
"reserved": 0
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user