Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 25afec6e1c | |||
| f1363b153d | |||
| decf2e9f8a | |||
| 93a7dd1718 |
@@ -28,7 +28,7 @@ tmp_dir = "tmp"
|
|||||||
rerun = false
|
rerun = false
|
||||||
rerun_delay = 500
|
rerun_delay = 500
|
||||||
send_interrupt = false
|
send_interrupt = false
|
||||||
stop_on_error = false
|
stop_on_error = true
|
||||||
|
|
||||||
[color]
|
[color]
|
||||||
app = ""
|
app = ""
|
||||||
|
|||||||
@@ -9,8 +9,10 @@ import (
|
|||||||
"git.ma-al.com/goc_daniel/b2b/app/model"
|
"git.ma-al.com/goc_daniel/b2b/app/model"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/service/currencyService"
|
"git.ma-al.com/goc_daniel/b2b/app/service/currencyService"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
||||||
|
"git.ma-al.com/goc_daniel/b2b/app/utils/localeExtractor"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
|
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
||||||
|
"git.ma-al.com/goc_daniel/b2b/app/utils/query/query_params"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/response"
|
"git.ma-al.com/goc_daniel/b2b/app/utils/response"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
||||||
|
|
||||||
@@ -33,8 +35,9 @@ func NewCurrencyHandler() *CurrencyHandler {
|
|||||||
func CurrencyHandlerRoutes(r fiber.Router) fiber.Router {
|
func CurrencyHandlerRoutes(r fiber.Router) fiber.Router {
|
||||||
handler := NewCurrencyHandler()
|
handler := NewCurrencyHandler()
|
||||||
|
|
||||||
r.Post("/currency-rate", middleware.Require(perms.CurrencyWrite), handler.PostCurrencyRate)
|
r.Patch("", middleware.Require(perms.CurrencyWrite), handler.PostCurrencyRate)
|
||||||
r.Get("/currency-rate/:id", handler.GetCurrencyRate)
|
r.Get("/list", handler.List)
|
||||||
|
r.Get("/:id", handler.GetCurrencyRate)
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +53,8 @@ func (h *CurrencyHandler) PostCurrencyRate(c fiber.Ctx) error {
|
|||||||
|
|
||||||
logger.Error("failed to create currency rate",
|
logger.Error("failed to create currency rate",
|
||||||
"handler", "CurrencyHandler.PostCurrencyRate",
|
"handler", "CurrencyHandler.PostCurrencyRate",
|
||||||
|
"b2b_id_currency", currencyRate.B2bIdCurrency,
|
||||||
|
"conversion_rate", currencyRate.ConversionRate,
|
||||||
"error", err.Error(),
|
"error", err.Error(),
|
||||||
)
|
)
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||||
@@ -65,16 +69,13 @@ func (h *CurrencyHandler) GetCurrencyRate(c fiber.Ctx) error {
|
|||||||
id, err := strconv.Atoi(idStr)
|
id, err := strconv.Atoi(idStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
return c.Status(responseErrors.GetErrorStatus(err)).JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
currency, err := h.CurrencyService.GetCurrency(uint(id))
|
currency, err := h.CurrencyService.Get(uint(id))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
||||||
logger.Error("failed to get currency",
|
logger.Error("failed to get currency",
|
||||||
"handler", "CurrencyHandler.GetCurrencyRate",
|
"handler", "CurrencyHandler.GetCurrencyRate",
|
||||||
|
"b2b_id_currency", id,
|
||||||
"currency_id", id,
|
|
||||||
"error", err.Error(),
|
"error", err.Error(),
|
||||||
)
|
)
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
return c.Status(responseErrors.GetErrorStatus(err)).JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||||
@@ -82,3 +83,37 @@ func (h *CurrencyHandler) GetCurrencyRate(c fiber.Ctx) error {
|
|||||||
|
|
||||||
return c.JSON(response.Make(currency, 0, i18n.T_(c, response.Message_OK)))
|
return c.JSON(response.Make(currency, 0, i18n.T_(c, response.Message_OK)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *CurrencyHandler) List(c fiber.Ctx) error {
|
||||||
|
langId, ok := localeExtractor.GetLangID(c)
|
||||||
|
if !ok {
|
||||||
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrInvalidBody)).
|
||||||
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody)))
|
||||||
|
}
|
||||||
|
|
||||||
|
p, filt, err := query_params.ParseFilters[model.Currency](c, columnMappingCurrencies)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||||
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||||
|
}
|
||||||
|
|
||||||
|
list, err := h.CurrencyService.Find(langId, p, filt)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("failed to get currency list",
|
||||||
|
"handler", "CurrencyHandler.List",
|
||||||
|
"lang_id", langId,
|
||||||
|
"error", err.Error(),
|
||||||
|
)
|
||||||
|
return c.Status(responseErrors.GetErrorStatus(err)).JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(response.Make(&list.Items, int(list.Count), i18n.T_(c, response.Message_OK)))
|
||||||
|
}
|
||||||
|
|
||||||
|
var columnMappingCurrencies map[string]string = map[string]string{
|
||||||
|
"id": "c.id",
|
||||||
|
"ps_id_currency": "c.ps_id_currency",
|
||||||
|
"is_default": "c.is_default",
|
||||||
|
"is_active": "c.is_active",
|
||||||
|
"conversion_rate": "r.conversion_rate",
|
||||||
|
}
|
||||||
|
|||||||
@@ -150,7 +150,8 @@ func (s *Server) Setup() error {
|
|||||||
restricted.StorageHandlerRoutes(restrictedStorage)
|
restricted.StorageHandlerRoutes(restrictedStorage)
|
||||||
webdav.StorageHandlerRoutes(webdavStorage)
|
webdav.StorageHandlerRoutes(webdavStorage)
|
||||||
|
|
||||||
restricted.CurrencyHandlerRoutes(s.restricted)
|
restrictedCurrency := s.restricted.Group("/currency-rate")
|
||||||
|
restricted.CurrencyHandlerRoutes(restrictedCurrency)
|
||||||
|
|
||||||
s.api.All("*", func(c fiber.Ctx) error {
|
s.api.All("*", func(c fiber.Ctx) error {
|
||||||
return c.SendStatus(fiber.StatusNotFound)
|
return c.SendStatus(fiber.StatusNotFound)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ type Currency struct {
|
|||||||
PsIDCurrency uint `json:"ps_id_currency"`
|
PsIDCurrency uint `json:"ps_id_currency"`
|
||||||
IsDefault bool `json:"is_default"`
|
IsDefault bool `json:"is_default"`
|
||||||
IsActive bool `json:"is_active"`
|
IsActive bool `json:"is_active"`
|
||||||
ConversionRate *float64 `json:"conversion_rate,omitempty"`
|
ConversionRate *float64 `json:"conversion_rate,omitempty" gorm:"column:conversion_rate"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Currency) TableName() string {
|
func (Currency) TableName() string {
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ import (
|
|||||||
"git.ma-al.com/goc_daniel/b2b/app/model"
|
"git.ma-al.com/goc_daniel/b2b/app/model"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/query/filters"
|
"git.ma-al.com/goc_daniel/b2b/app/utils/query/filters"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/query/find"
|
"git.ma-al.com/goc_daniel/b2b/app/utils/query/find"
|
||||||
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UICurrencyRepo interface {
|
type UICurrencyRepo interface {
|
||||||
CreateConversionRate(currencyRate *model.CurrencyRate) error
|
CreateConversionRate(currencyRate *model.CurrencyRate) error
|
||||||
Get(id uint) (*model.Currency, error)
|
Get(id uint) (*model.Currency, error)
|
||||||
|
Find(langId uint, p find.Paging, filt *filters.FiltersList) (*find.Found[model.Currency], error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type CurrencyRepo struct{}
|
type CurrencyRepo struct{}
|
||||||
@@ -25,19 +27,12 @@ func (repo *CurrencyRepo) CreateConversionRate(currencyRate *model.CurrencyRate)
|
|||||||
func (repo *CurrencyRepo) Get(id uint) (*model.Currency, error) {
|
func (repo *CurrencyRepo) Get(id uint) (*model.Currency, error) {
|
||||||
var currency model.Currency
|
var currency model.Currency
|
||||||
|
|
||||||
err := db.DB.Table("b2b_currencies c").
|
err := db.DB.
|
||||||
Select("c.*, r.conversion_rate").
|
Model(&model.Currency{}).
|
||||||
Joins(`
|
Scopes(WithLatestRate()).
|
||||||
LEFT JOIN b2b_currency_rates r
|
Select("b2b_currencies.*, r.conversion_rate").
|
||||||
ON r.b2b_id_currency = c.id
|
Where("b2b_currencies.id = ?", id).
|
||||||
AND r.created_at = (
|
First(¤cy).Error
|
||||||
SELECT MAX(created_at)
|
|
||||||
FROM b2b_currency_rates
|
|
||||||
WHERE b2b_id_currency = c.id
|
|
||||||
)
|
|
||||||
`).
|
|
||||||
Where("c.id = ?", id).
|
|
||||||
Scan(¤cy).Error
|
|
||||||
|
|
||||||
return ¤cy, err
|
return ¤cy, err
|
||||||
}
|
}
|
||||||
@@ -46,8 +41,24 @@ func (repo *CurrencyRepo) Find(langId uint, p find.Paging, filt *filters.Filters
|
|||||||
|
|
||||||
found, err := find.Paginate[model.Currency](langId, p, db.DB.
|
found, err := find.Paginate[model.Currency](langId, p, db.DB.
|
||||||
Model(&model.Currency{}).
|
Model(&model.Currency{}).
|
||||||
|
Scopes(WithLatestRate()).
|
||||||
|
Select("b2b_currencies.*, r.conversion_rate").
|
||||||
Scopes(filt.All()...),
|
Scopes(filt.All()...),
|
||||||
)
|
)
|
||||||
|
|
||||||
return &found, err
|
return &found, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WithLatestRate() func(db *gorm.DB) *gorm.DB {
|
||||||
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
|
return db.Joins(`
|
||||||
|
LEFT JOIN b2b_currency_rates r
|
||||||
|
ON r.b2b_id_currency = b2b_currencies.id
|
||||||
|
AND r.created_at = (
|
||||||
|
SELECT MAX(created_at)
|
||||||
|
FROM b2b_currency_rates
|
||||||
|
WHERE b2b_id_currency = b2b_currencies.id
|
||||||
|
)
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,16 +3,22 @@ package currencyService
|
|||||||
import (
|
import (
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/model"
|
"git.ma-al.com/goc_daniel/b2b/app/model"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/repos/currencyRepo"
|
"git.ma-al.com/goc_daniel/b2b/app/repos/currencyRepo"
|
||||||
|
"git.ma-al.com/goc_daniel/b2b/app/utils/query/filters"
|
||||||
|
"git.ma-al.com/goc_daniel/b2b/app/utils/query/find"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CurrencyService struct {
|
type CurrencyService struct {
|
||||||
repo currencyRepo.UICurrencyRepo
|
repo currencyRepo.UICurrencyRepo
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CurrencyService) GetCurrency(id uint) (*model.Currency, error) {
|
func (s *CurrencyService) Get(id uint) (*model.Currency, error) {
|
||||||
return s.repo.Get(id)
|
return s.repo.Get(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *CurrencyService) Find(langId uint, p find.Paging, filt *filters.FiltersList) (*find.Found[model.Currency], error) {
|
||||||
|
return s.repo.Find(langId, p, filt)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *CurrencyService) CreateCurrencyRate(currency *model.CurrencyRate) error {
|
func (s *CurrencyService) CreateCurrencyRate(currency *model.CurrencyRate) error {
|
||||||
return s.repo.CreateConversionRate(currency)
|
return s.repo.CreateConversionRate(currency)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,11 @@ func Paginate[T any](langID uint, paging Paging, stmt *gorm.DB) (Found[T], error
|
|||||||
var items []T
|
var items []T
|
||||||
var count int64
|
var count int64
|
||||||
|
|
||||||
stmt.Count(&count)
|
countStmt := stmt.Session(&gorm.Session{}).Select("count(*)").Offset(-1).Limit(-1)
|
||||||
|
|
||||||
|
if err := countStmt.Count(&count).Error; err != nil {
|
||||||
|
return Found[T]{}, err
|
||||||
|
}
|
||||||
|
|
||||||
err := stmt.
|
err := stmt.
|
||||||
Offset(paging.Offset()).
|
Offset(paging.Offset()).
|
||||||
@@ -42,15 +46,10 @@ func Paginate[T any](langID uint, paging Paging, stmt *gorm.DB) (Found[T], error
|
|||||||
return Found[T]{}, err
|
return Found[T]{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// columnsSpec := GetColumnsSpec[T](langID)
|
|
||||||
|
|
||||||
return Found[T]{
|
return Found[T]{
|
||||||
Items: items,
|
Items: items,
|
||||||
Count: uint(count),
|
Count: uint(count),
|
||||||
// Spec: map[string]interface{}{
|
}, nil
|
||||||
// "columns": columnsSpec,
|
|
||||||
// },
|
|
||||||
}, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetColumnsSpec[T any] generates a column specification map for a given struct type T.
|
// GetColumnsSpec[T any] generates a column specification map for a given struct type T.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
info:
|
info:
|
||||||
name: currency
|
name: Currency
|
||||||
type: http
|
type: http
|
||||||
seq: 1
|
seq: 1
|
||||||
|
|
||||||
15
bruno/api_v1/currency/List.yml
Normal file
15
bruno/api_v1/currency/List.yml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
info:
|
||||||
|
name: List
|
||||||
|
type: http
|
||||||
|
seq: 3
|
||||||
|
|
||||||
|
http:
|
||||||
|
method: GET
|
||||||
|
url: "{{bas_url}}/restricted/currency-rate/list"
|
||||||
|
auth: inherit
|
||||||
|
|
||||||
|
settings:
|
||||||
|
encodeUrl: true
|
||||||
|
timeout: 0
|
||||||
|
followRedirects: true
|
||||||
|
maxRedirects: 5
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
info:
|
info:
|
||||||
name: currency-rate
|
name: Update currency rate
|
||||||
type: http
|
type: http
|
||||||
seq: 2
|
seq: 2
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: POST
|
method: PATCH
|
||||||
url: "{{bas_url}}/restricted/currency-rate"
|
url: "{{bas_url}}/restricted/currency-rate"
|
||||||
body:
|
body:
|
||||||
type: json
|
type: json
|
||||||
@@ -43,6 +43,9 @@ INSERT INTO `b2b_currencies` (`ps_id_currency`, `is_default`, `is_active`) VALUE
|
|||||||
('1','1','1'),
|
('1','1','1'),
|
||||||
('2','0','1');
|
('2','0','1');
|
||||||
|
|
||||||
|
INSERT INTO `b2b_currency_rates` (`id`, `b2b_id_currency`, `created_at`, `conversion_rate`) VALUES ('1', '1', '2026-04-17 14:32:03', '1.000000');
|
||||||
|
INSERT INTO `b2b_currency_rates` (`id`, `b2b_id_currency`, `created_at`, `conversion_rate`) VALUES ('2', '2', '2026-04-17 14:32:03', '4.600000');
|
||||||
|
|
||||||
INSERT IGNORE INTO b2b_countries
|
INSERT IGNORE INTO b2b_countries
|
||||||
(id, flag, ps_id_country, b2b_id_currency)
|
(id, flag, ps_id_country, b2b_id_currency)
|
||||||
VALUES
|
VALUES
|
||||||
|
|||||||
Reference in New Issue
Block a user