Merge branch 'main' of ssh://git.ma-al.com:8822/goc_daniel/b2b into storage

This commit is contained in:
Daniel Goc
2026-04-08 13:19:45 +02:00
57 changed files with 1839 additions and 276 deletions

View File

@@ -0,0 +1,70 @@
package restricted
import (
"strconv"
"git.ma-al.com/goc_daniel/b2b/app/config"
"git.ma-al.com/goc_daniel/b2b/app/delivery/middleware"
"git.ma-al.com/goc_daniel/b2b/app/delivery/middleware/perms"
"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/utils/i18n"
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
"git.ma-al.com/goc_daniel/b2b/app/utils/response"
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
"github.com/gofiber/fiber/v3"
)
type CurrencyHandler struct {
CurrencyService *currencyService.CurrencyService
config *config.Config
}
func NewCurrencyHandler() *CurrencyHandler {
currencyService := currencyService.New()
return &CurrencyHandler{
CurrencyService: currencyService,
config: config.Get(),
}
}
func CurrencyHandlerRoutes(r fiber.Router) fiber.Router {
handler := NewCurrencyHandler()
r.Post("/currency-rate", middleware.Require(perms.CurrencyWrite), handler.PostCurrencyRate)
r.Get("/currency-rate/:id", handler.GetCurrencyRate)
return r
}
func (h *CurrencyHandler) PostCurrencyRate(c fiber.Ctx) error {
var currencyRate model.CurrencyRate
if err := c.Bind().Body(&currencyRate); err != nil {
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrJSONBody)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrJSONBody)))
}
err := h.CurrencyService.CreateCurrencyRate(&currencyRate)
if err != nil {
return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
}
return c.JSON(response.Make(nullable.GetNil(""), 1, i18n.T_(c, response.Message_OK)))
}
func (h *CurrencyHandler) GetCurrencyRate(c fiber.Ctx) error {
idStr := c.Params("id")
id, err := strconv.Atoi(idStr)
if err != nil {
return c.Status(responseErrors.GetErrorStatus(err)).JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
}
currency, err := h.CurrencyService.GetCurrency(uint(id))
if err != nil {
return c.Status(responseErrors.GetErrorStatus(err)).JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
}
return c.JSON(response.Make(currency, 0, i18n.T_(c, response.Message_OK)))
}

View File

@@ -0,0 +1,111 @@
package restricted
import (
"strconv"
"git.ma-al.com/goc_daniel/b2b/app/delivery/middleware/perms"
"git.ma-al.com/goc_daniel/b2b/app/model"
"git.ma-al.com/goc_daniel/b2b/app/service/customerService"
"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/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/responseErrors"
"github.com/gofiber/fiber/v3"
)
type customerHandler struct {
service *customerService.CustomerService
}
func NewCustomerHandler() *customerHandler {
customerService := customerService.New()
return &customerHandler{
service: customerService,
}
}
func CustomerHandlerRoutes(r fiber.Router) fiber.Router {
handler := NewCustomerHandler()
r.Get("", handler.customerData)
r.Get("/list", handler.listCustomers)
return r
}
func (h *customerHandler) customerData(fc fiber.Ctx) error {
var customerId uint
user, ok := localeExtractor.GetCustomer(fc)
if !ok || user == nil {
return fc.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, responseErrors.ErrBadAttribute)))
}
customerIdStr := fc.Query("id")
if customerIdStr != "" {
id, err := strconv.ParseUint(customerIdStr, 10, 64)
if err != nil {
return fiber.ErrBadRequest
}
if user.ID != uint(id) && !user.HasPermission(perms.UserReadAny) {
return fc.Status(fiber.StatusForbidden).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, responseErrors.ErrForbidden)))
}
customerId = uint(id)
} else {
customerId = user.ID
}
customer, err := h.service.GetById(customerId)
if err != nil {
return fc.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, err)))
}
return fc.JSON(response.Make(&customer, 0, i18n.T_(fc, response.Message_OK)))
}
func (h *customerHandler) listCustomers(fc fiber.Ctx) error {
user, ok := localeExtractor.GetCustomer(fc)
if !ok || user == nil {
return fc.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, responseErrors.ErrBadAttribute)))
}
if !user.HasPermission(perms.UserReadAny) {
return fc.Status(fiber.StatusForbidden).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, responseErrors.ErrForbidden)))
}
p, filt, err := query_params.ParseFilters[model.Customer](fc, columnMappingListUsers)
if err != nil {
return fc.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, err)))
}
search := fc.Query("search")
if search != "" {
if !user.HasPermission(perms.UserReadAny) {
return fc.Status(fiber.StatusForbidden).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, responseErrors.ErrForbidden)))
}
}
customer, err := h.service.Find(user.LangID, p, filt, search)
if err != nil {
return fc.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, err)))
}
return fc.JSON(response.Make(&customer, 0, i18n.T_(fc, response.Message_OK)))
}
var columnMappingListUsers map[string]string = map[string]string{
"user_id": "users.id",
"email": "users.email",
"first_name": "users.first_name",
"last_name": "users.last_name",
}

View File

@@ -87,12 +87,12 @@ func (h *MenuHandler) GetBreadcrumb(c fiber.Ctx) error {
}
func (h *MenuHandler) GetTopMenu(c fiber.Ctx) error {
lang_id, ok := localeExtractor.GetLangID(c)
if !ok {
customer, ok := localeExtractor.GetCustomer(c)
if !ok || customer == nil {
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
}
menu, err := h.menuService.GetTopMenu(lang_id)
menu, err := h.menuService.GetTopMenu(customer.LangID, customer.RoleID)
if err != nil {
return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))

View File

@@ -1,9 +1,11 @@
package restricted
import (
"strconv"
"git.ma-al.com/goc_daniel/b2b/app/config"
"git.ma-al.com/goc_daniel/b2b/app/model"
"git.ma-al.com/goc_daniel/b2b/app/service/listService"
"git.ma-al.com/goc_daniel/b2b/app/service/productService"
"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/nullable"
@@ -13,31 +15,69 @@ import (
"github.com/gofiber/fiber/v3"
)
// ListHandler handles endpoints that list various things (e.g. products or users)
type ListHandler struct {
listService *listService.ListService
config *config.Config
type ProductsHandler struct {
productService *productService.ProductService
config *config.Config
}
// NewListHandler creates a new ListHandler instance
func NewListHandler() *ListHandler {
listService := listService.New()
return &ListHandler{
listService: listService,
config: config.Get(),
// NewListProductsHandler creates a new ListProductsHandler instance
func NewProductsHandler() *ProductsHandler {
productService := productService.New()
return &ProductsHandler{
productService: productService,
config: config.Get(),
}
}
func ListHandlerRoutes(r fiber.Router) fiber.Router {
handler := NewListHandler()
func ProductsHandlerRoutes(r fiber.Router) fiber.Router {
handler := NewProductsHandler()
r.Get("/list-products", handler.ListProducts)
r.Get("/list-users", handler.ListUsers)
r.Get("/:id/:country_id/:quantity", handler.GetProductJson)
r.Get("/list", handler.ListProducts)
return r
}
func (h *ListHandler) ListProducts(c fiber.Ctx) error {
func (h *ProductsHandler) GetProductJson(c fiber.Ctx) error {
idStr := c.Params("id")
p_id_product, err := strconv.Atoi(idStr)
if err != nil {
return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
}
country_idStr := c.Params("country_id")
b2b_id_country, err := strconv.Atoi(country_idStr)
if err != nil {
return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
}
quantityStr := c.Params("quantity")
p_quantity, err := strconv.Atoi(quantityStr)
if err != nil {
return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
}
customer, ok := localeExtractor.GetCustomer(c)
if !ok || customer == nil {
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
}
productJson, err := h.productService.GetJSON(p_id_product, int(customer.LangID), int(customer.ID), b2b_id_country, p_quantity)
if err != nil {
return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
}
return c.JSON(response.Make(&productJson, 1, i18n.T_(c, response.Message_OK)))
}
func (h *ProductsHandler) ListProducts(c fiber.Ctx) error {
paging, filters, err := query_params.ParseFilters[model.Product](c, columnMappingListProducts)
if err != nil {
return c.Status(responseErrors.GetErrorStatus(err)).
@@ -50,7 +90,7 @@ func (h *ListHandler) ListProducts(c fiber.Ctx) error {
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
}
list, err := h.listService.ListProducts(id_lang, paging, filters)
list, err := h.productService.Find(id_lang, paging, filters)
if err != nil {
return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
@@ -67,33 +107,3 @@ var columnMappingListProducts map[string]string = map[string]string{
"category_id": "cp.id_category",
"quantity": "sa.quantity",
}
func (h *ListHandler) ListUsers(c fiber.Ctx) error {
paging, filters, err := query_params.ParseFilters[model.Customer](c, columnMappingListUsers)
if err != nil {
return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
}
id_lang, ok := localeExtractor.GetLangID(c)
if !ok {
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
}
list, err := h.listService.ListUsers(id_lang, paging, filters)
if err != nil {
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 columnMappingListUsers map[string]string = map[string]string{
"user_id": "users.id",
"email": "users.email",
"first_name": "users.first_name",
"second_name": "users.second_name",
"role": "users.role",
}

View File

@@ -105,13 +105,15 @@ func (s *Server) Setup() error {
menuRouting := s.public.Group("/menu")
public.RoutingHandlerRoutes(menuRouting)
pCustomer := s.restricted.Group("/customer")
restricted.CustomerHandlerRoutes(pCustomer)
// product translation routes (restricted)
productTranslation := s.restricted.Group("/product-translation")
restricted.ProductTranslationHandlerRoutes(productTranslation)
// lists of things routes (restricted)
list := s.restricted.Group("/list")
restricted.ListHandlerRoutes(list)
product := s.restricted.Group("/product")
restricted.ProductsHandlerRoutes(product)
// locale selector (restricted)
// this is basically for changing user's selected language and country
@@ -136,6 +138,8 @@ func (s *Server) Setup() error {
restricted.StorageHandlerRoutes(restrictedStorage)
webdav.StorageHandlerRoutes(webdavStorage)
restricted.CurrencyHandlerRoutes(s.restricted)
s.api.All("*", func(c fiber.Ctx) error {
return c.SendStatus(fiber.StatusNotFound)
})