9 Commits

Author SHA1 Message Date
931840c243 Merge pull request 'expand orders' (#75) from expand_orders into main
Reviewed-on: #75
2026-04-16 14:25:59 +00:00
Daniel Goc
d73dad8975 merge and small bugfix 2026-04-16 15:02:38 +02:00
Daniel Goc
7995177fe1 Merge branch 'main' of ssh://git.ma-al.com:8822/goc_daniel/b2b into expand_orders 2026-04-16 15:01:45 +02:00
70e0e23ace Merge pull request 'feat: implement logger' (#74) from logger into main
Reviewed-on: #74
Reviewed-by: goc_daniel <goc_daniel@ma-al.com>
2026-04-16 13:00:47 +00:00
9961d90fa7 feat: implement logger 2026-04-16 14:46:09 +02:00
Daniel Goc
f435a8839b expand orders 2026-04-16 11:47:55 +02:00
7bce04e05a Merge pull request 'is_oem' (#72) from is_oem into main
Reviewed-on: #72
Reviewed-by: Wiktor Dudzic <dudzic_wiktor@ma-al.com>
2026-04-15 11:32:43 +00:00
Daniel Goc
754bf2fe01 Merge branch 'main' of ssh://git.ma-al.com:8822/goc_daniel/b2b into is_oem 2026-04-15 13:20:26 +02:00
Daniel Goc
2ca07f03ce expanded by is_oem 2026-04-15 13:19:28 +02:00
43 changed files with 811 additions and 111 deletions

5
.env
View File

@@ -63,4 +63,7 @@ FILE_MAAL_PL_PASSWORD=1FnwqcEgIUjQHjt1
IMAGE_PREFIX=https://www.naluconcept.com # remove prefix to serv them from same host as presta IMAGE_PREFIX=https://www.naluconcept.com # remove prefix to serv them from same host as presta
CORS_ORGIN=https://www.naluconcept.com CORS_ORGIN=https://www.naluconcept.com
DSN=root:Maal12345678@tcp(localhost:3306)/nalu DSN=root:Maal12345678@tcp(localhost:3306)/nalu
LOG_LEVEL=warn
LOG_COLORIZE=true

View File

@@ -4,8 +4,11 @@ import (
"log" "log"
"os" "os"
"git.ma-al.com/goc_daniel/b2b/app/config"
"git.ma-al.com/goc_daniel/b2b/app/delivery/web" "git.ma-al.com/goc_daniel/b2b/app/delivery/web"
"git.ma-al.com/goc_daniel/b2b/app/service/langsService" "git.ma-al.com/goc_daniel/b2b/app/service/langsService"
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
"git.ma-al.com/goc_daniel/b2b/app/utils/version" "git.ma-al.com/goc_daniel/b2b/app/utils/version"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@@ -21,6 +24,8 @@ var (
return return
} }
logger.Init("b2b", nil, config.Get().Log.LogLevel, config.Get().Log.LogColorize)
// Create and setup the server // Create and setup the server
server := web.New() server := web.New()

View File

@@ -28,6 +28,7 @@ type Config struct {
Cors CorsConfig Cors CorsConfig
MeiliSearch MeiliSearchConfig MeiliSearch MeiliSearchConfig
Storage StorageConfig Storage StorageConfig
Log LogConfig
} }
type I18n struct { type I18n struct {
@@ -87,6 +88,11 @@ type AppConfig struct {
BaseURL string `env:"APP_BASE_URL,http://localhost:5173"` BaseURL string `env:"APP_BASE_URL,http://localhost:5173"`
} }
type LogConfig struct {
LogLevel string `env:"LOG_LEVEL,warn"`
LogColorize bool `env:"LOG_COLORIZE,true"`
}
type EmailConfig struct { type EmailConfig struct {
SMTPHost string `env:"EMAIL_SMTP_HOST,localhost"` SMTPHost string `env:"EMAIL_SMTP_HOST,localhost"`
SMTPPort int `env:"EMAIL_SMTP_PORT,587"` SMTPPort int `env:"EMAIL_SMTP_PORT,587"`
@@ -209,6 +215,11 @@ func load() *Config {
if err != nil { if err != nil {
slog.Error("not possible to load env variables for storage : ", err.Error(), "") slog.Error("not possible to load env variables for storage : ", err.Error(), "")
} }
err = loadEnv(&cfg.Log)
if err != nil {
slog.Error("not possible to load env variables for logger : ", err.Error(), "")
}
cfg.Storage.RootFolder = ResolveRelativePath(cfg.Storage.RootFolder) cfg.Storage.RootFolder = ResolveRelativePath(cfg.Storage.RootFolder)
return cfg return cfg

View File

@@ -1,7 +1,6 @@
package public package public
import ( import (
"log"
"strconv" "strconv"
"time" "time"
@@ -11,6 +10,7 @@ import (
"git.ma-al.com/goc_daniel/b2b/app/service/authService" "git.ma-al.com/goc_daniel/b2b/app/service/authService"
constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data" constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data"
"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/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/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"
@@ -178,7 +178,13 @@ func (h *AuthHandler) ForgotPassword(c fiber.Ctx) error {
// Request password reset - always return success to prevent email enumeration // Request password reset - always return success to prevent email enumeration
err := h.authService.RequestPasswordReset(req.Email) err := h.authService.RequestPasswordReset(req.Email)
if err != nil { if err != nil {
log.Printf("Password reset request error: %v", err)
logger.Warn("password reset request failed",
"handler", "AuthHandler.ForgotPassword",
"email", req.Email,
"error", err.Error(),
)
} }
return c.JSON(fiber.Map{ return c.JSON(fiber.Map{
@@ -307,7 +313,6 @@ func (h *AuthHandler) Register(c fiber.Ctx) error {
// Attempt registration // Attempt registration
err := h.authService.Register(&req) err := h.authService.Register(&req)
if err != nil { if err != nil {
log.Printf("Register error: %v", err)
return c.Status(responseErrors.GetErrorStatus(err)).JSON(fiber.Map{ return c.Status(responseErrors.GetErrorStatus(err)).JSON(fiber.Map{
"error": responseErrors.GetErrorCode(c, err), "error": responseErrors.GetErrorCode(c, err),
}) })
@@ -447,7 +452,6 @@ func (h *AuthHandler) GoogleCallback(c fiber.Ctx) error {
response, rawRefreshToken, err := h.authService.HandleGoogleCallback(code) response, rawRefreshToken, err := h.authService.HandleGoogleCallback(code)
if err != nil { if err != nil {
log.Printf("Google OAuth callback error: %v", err)
return c.Status(responseErrors.GetErrorStatus(err)).JSON(fiber.Map{ return c.Status(responseErrors.GetErrorStatus(err)).JSON(fiber.Map{
"error": responseErrors.GetErrorCode(c, err), "error": responseErrors.GetErrorCode(c, err),
}) })

View File

@@ -6,6 +6,7 @@ import (
"git.ma-al.com/goc_daniel/b2b/app/service/addressesService" "git.ma-al.com/goc_daniel/b2b/app/service/addressesService"
"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/localeExtractor"
"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/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"
@@ -45,6 +46,13 @@ func (h *AddressesHandler) GetTemplate(c fiber.Ctx) error {
template, err := h.addressesService.GetTemplate(uint(country_id)) template, err := h.addressesService.GetTemplate(uint(country_id))
if err != nil { if err != nil {
logger.Error("failed to get address template",
"handler", "AddressesHandler.GetTemplate",
"country_id", country_id,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -74,6 +82,13 @@ func (h *AddressesHandler) AddNewAddress(c fiber.Ctx) error {
err = h.addressesService.AddNewAddress(userID, address_info, uint(country_id)) err = h.addressesService.AddNewAddress(userID, address_info, uint(country_id))
if err != nil { if err != nil {
logger.Error("failed to add new address",
"handler", "AddressesHandler.AddNewAddress",
"user_id", userID,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -110,6 +125,14 @@ func (h *AddressesHandler) ModifyAddress(c fiber.Ctx) error {
err = h.addressesService.ModifyAddress(userID, uint(address_id), address_info, uint(country_id)) err = h.addressesService.ModifyAddress(userID, uint(address_id), address_info, uint(country_id))
if err != nil { if err != nil {
logger.Error("failed to modify address",
"handler", "AddressesHandler.ModifyAddress",
"user_id", userID,
"address_id", address_id,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -126,6 +149,13 @@ func (h *AddressesHandler) RetrieveAddressesInfo(c fiber.Ctx) error {
addresses, err := h.addressesService.RetrieveAddresses(userID) addresses, err := h.addressesService.RetrieveAddresses(userID)
if err != nil { if err != nil {
logger.Error("failed to retrieve addresses",
"handler", "AddressesHandler.RetrieveAddressesInfo",
"user_id", userID,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -149,6 +179,14 @@ func (h *AddressesHandler) DeleteAddress(c fiber.Ctx) error {
err = h.addressesService.DeleteAddress(userID, uint(address_id)) err = h.addressesService.DeleteAddress(userID, uint(address_id))
if err != nil { if err != nil {
logger.Error("failed to delete address",
"handler", "AddressesHandler.DeleteAddress",
"user_id", userID,
"address_id", address_id,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }

View File

@@ -6,6 +6,7 @@ import (
"git.ma-al.com/goc_daniel/b2b/app/service/cartsService" "git.ma-al.com/goc_daniel/b2b/app/service/cartsService"
"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/localeExtractor"
"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/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"
@@ -46,8 +47,16 @@ func (h *CartsHandler) AddNewCart(c fiber.Ctx) error {
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody)))
} }
new_cart, err := h.cartsService.CreateNewCart(userID) name := c.Query("name")
new_cart, err := h.cartsService.CreateNewCart(userID, name)
if err != nil { if err != nil {
logger.Error("failed to create cart",
"handler", "CartsHandler.AddNewCart",
"user_id", userID,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -71,6 +80,14 @@ func (h *CartsHandler) RemoveCart(c fiber.Ctx) error {
err = h.cartsService.RemoveCart(userID, uint(cart_id)) err = h.cartsService.RemoveCart(userID, uint(cart_id))
if err != nil { if err != nil {
logger.Error("failed to remove cart",
"handler", "CartsHandler.RemoveCart",
"user_id", userID,
"cart_id", cart_id,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -96,6 +113,14 @@ func (h *CartsHandler) ChangeCartName(c fiber.Ctx) error {
err = h.cartsService.UpdateCartName(userID, uint(cart_id), new_name) err = h.cartsService.UpdateCartName(userID, uint(cart_id), new_name)
if err != nil { if err != nil {
logger.Error("failed to update cart name",
"handler", "CartsHandler.ChangeCartName",
"user_id", userID,
"cart_id", cart_id,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -112,6 +137,13 @@ func (h *CartsHandler) RetrieveCartsInfo(c fiber.Ctx) error {
carts_info, err := h.cartsService.RetrieveCartsInfo(userID) carts_info, err := h.cartsService.RetrieveCartsInfo(userID)
if err != nil { if err != nil {
logger.Error("failed to retrieve carts info",
"handler", "CartsHandler.RetrieveCartsInfo",
"user_id", userID,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -135,6 +167,14 @@ func (h *CartsHandler) RetrieveCart(c fiber.Ctx) error {
cart, err := h.cartsService.RetrieveCart(userID, uint(cart_id)) cart, err := h.cartsService.RetrieveCart(userID, uint(cart_id))
if err != nil { if err != nil {
logger.Error("failed to retrieve cart",
"handler", "CartsHandler.RetrieveCart",
"user_id", userID,
"cart_id", cart_id,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -194,6 +234,15 @@ func (h *CartsHandler) AddProduct(c fiber.Ctx) error {
err = h.cartsService.AddProduct(userID, uint(cart_id), uint(product_id), product_attribute_id, amount, set_amount) err = h.cartsService.AddProduct(userID, uint(cart_id), uint(product_id), product_attribute_id, amount, set_amount)
if err != nil { if err != nil {
logger.Error("failed to add product to cart",
"handler", "CartsHandler.AddProduct",
"user_id", userID,
"cart_id", cart_id,
"product_id", product_id,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -239,6 +288,15 @@ func (h *CartsHandler) RemoveProduct(c fiber.Ctx) error {
err = h.cartsService.RemoveProduct(userID, uint(cart_id), uint(product_id), product_attribute_id) err = h.cartsService.RemoveProduct(userID, uint(cart_id), uint(product_id), product_attribute_id)
if err != nil { if err != nil {
logger.Error("failed to remove product from cart",
"handler", "CartsHandler.RemoveProduct",
"user_id", userID,
"cart_id", cart_id,
"product_id", product_id,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }

View File

@@ -9,6 +9,7 @@ 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/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/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"
@@ -46,6 +47,12 @@ func (h *CurrencyHandler) PostCurrencyRate(c fiber.Ctx) error {
err := h.CurrencyService.CreateCurrencyRate(&currencyRate) err := h.CurrencyService.CreateCurrencyRate(&currencyRate)
if err != nil { if err != nil {
logger.Error("failed to create currency rate",
"handler", "CurrencyHandler.PostCurrencyRate",
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -63,6 +70,13 @@ func (h *CurrencyHandler) GetCurrencyRate(c fiber.Ctx) error {
currency, err := h.CurrencyService.GetCurrency(uint(id)) currency, err := h.CurrencyService.GetCurrency(uint(id))
if err != nil { if err != nil {
logger.Error("failed to get currency",
"handler", "CurrencyHandler.GetCurrencyRate",
"currency_id", id,
"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)))
} }

View File

@@ -9,6 +9,7 @@ import (
"git.ma-al.com/goc_daniel/b2b/app/service/customerService" "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/i18n"
"git.ma-al.com/goc_daniel/b2b/app/utils/localeExtractor" "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/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/query/query_params"
"git.ma-al.com/goc_daniel/b2b/app/utils/response" "git.ma-al.com/goc_daniel/b2b/app/utils/response"
@@ -64,6 +65,13 @@ func (h *customerHandler) customerData(fc fiber.Ctx) error {
customer, err := h.service.GetById(customerId) customer, err := h.service.GetById(customerId)
if err != nil { if err != nil {
logger.Error("failed to get customer",
"handler", "customerHandler.customerData",
"customer_id", customerId,
"error", err.Error(),
)
return fc.Status(responseErrors.GetErrorStatus(err)). return fc.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, err)))
} }
@@ -88,6 +96,12 @@ func (h *customerHandler) listCustomers(fc fiber.Ctx) error {
customer, err := h.service.Find(user.LangID, p, filt, search) customer, err := h.service.Find(user.LangID, p, filt, search)
if err != nil { if err != nil {
logger.Error("failed to list customers",
"handler", "customerHandler.listCustomers",
"error", err.Error(),
)
return fc.Status(responseErrors.GetErrorStatus(err)). return fc.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, err)))
} }
@@ -120,6 +134,13 @@ func (h *customerHandler) setCustomerNoVatStatus(fc fiber.Ctx) error {
} }
if err := h.service.SetCustomerNoVatStatus(req.CustomerID, req.IsNoVat); err != nil { if err := h.service.SetCustomerNoVatStatus(req.CustomerID, req.IsNoVat); err != nil {
logger.Error("failed to set customer no vat status",
"handler", "customerHandler.setCustomerNoVatStatus",
"customer_id", req.CustomerID,
"error", err.Error(),
)
return fc.Status(responseErrors.GetErrorStatus(err)). return fc.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, err)))
} }

View File

@@ -3,6 +3,7 @@ package restricted
import ( import (
"git.ma-al.com/goc_daniel/b2b/app/service/localeSelectorService" "git.ma-al.com/goc_daniel/b2b/app/service/localeSelectorService"
"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/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/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"
@@ -34,6 +35,12 @@ func LocaleSelectorHandlerRoutes(r fiber.Router) fiber.Router {
func (h *LocaleSelectorHandler) GetLanguages(c fiber.Ctx) error { func (h *LocaleSelectorHandler) GetLanguages(c fiber.Ctx) error {
languages, err := h.localeSelectorService.GetLanguages() languages, err := h.localeSelectorService.GetLanguages()
if err != nil { if err != nil {
logger.Error("failed to get languages",
"handler", "LocaleSelectorHandler.GetLanguages",
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -44,6 +51,12 @@ func (h *LocaleSelectorHandler) GetLanguages(c fiber.Ctx) error {
func (h *LocaleSelectorHandler) GetCountries(c fiber.Ctx) error { func (h *LocaleSelectorHandler) GetCountries(c fiber.Ctx) error {
countries, err := h.localeSelectorService.GetCountriesAndCurrencies() countries, err := h.localeSelectorService.GetCountriesAndCurrencies()
if err != nil { if err != nil {
logger.Error("failed to get countries",
"handler", "LocaleSelectorHandler.GetCountries",
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }

View File

@@ -6,6 +6,7 @@ import (
"git.ma-al.com/goc_daniel/b2b/app/service/menuService" "git.ma-al.com/goc_daniel/b2b/app/service/menuService"
"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/localeExtractor"
"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/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"
@@ -49,6 +50,12 @@ func (h *MenuHandler) GetCategoryTree(c fiber.Ctx) error {
category_tree, err := h.menuService.GetCategoryTree(uint(root_category_id), lang_id) category_tree, err := h.menuService.GetCategoryTree(uint(root_category_id), lang_id)
if err != nil { if err != nil {
logger.Error("failed to get category tree",
"handler", "MenuHandler.GetCategoryTree",
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -79,6 +86,12 @@ func (h *MenuHandler) GetBreadcrumb(c fiber.Ctx) error {
breadcrumb, err := h.menuService.GetBreadcrumb(uint(root_category_id), uint(category_id), lang_id) breadcrumb, err := h.menuService.GetBreadcrumb(uint(root_category_id), uint(category_id), lang_id)
if err != nil { if err != nil {
logger.Error("failed to get breadcrumb",
"handler", "MenuHandler.GetBreadcrumb",
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -94,6 +107,12 @@ func (h *MenuHandler) GetTopMenu(c fiber.Ctx) error {
} }
menu, err := h.menuService.GetTopMenu(customer.LangID, customer.RoleID) menu, err := h.menuService.GetTopMenu(customer.LangID, customer.RoleID)
if err != nil { if err != nil {
logger.Error("failed to get top menu",
"handler", "MenuHandler.GetTopMenu",
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }

View File

@@ -7,6 +7,7 @@ import (
"git.ma-al.com/goc_daniel/b2b/app/service/orderService" "git.ma-al.com/goc_daniel/b2b/app/service/orderService"
"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/localeExtractor"
"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/query/query_params"
"git.ma-al.com/goc_daniel/b2b/app/utils/response" "git.ma-al.com/goc_daniel/b2b/app/utils/response"
@@ -53,6 +54,12 @@ func (h *OrdersHandler) ListOrders(c fiber.Ctx) error {
list, err := h.ordersService.Find(user, paging, filters) list, err := h.ordersService.Find(user, paging, filters)
if err != nil { if err != nil {
logger.Error("failed to list orders",
"handler", "OrdersHandler.ListOrders",
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -66,6 +73,11 @@ var columnMappingListOrders map[string]string = map[string]string{
"name": "b2b_customer_orders.name", "name": "b2b_customer_orders.name",
"country_id": "b2b_customer_orders.country_id", "country_id": "b2b_customer_orders.country_id",
"status": "b2b_customer_orders.status", "status": "b2b_customer_orders.status",
"base_price": "b2b_customer_orders.base_price",
"tax_incl": "b2b_customer_orders.tax_incl",
"tax_excl": "b2b_customer_orders.tax_excl",
"created_at": "b2b_customer_orders.created_at",
"updated_at": "b2b_customer_orders.updated_at",
} }
func (h *OrdersHandler) PlaceNewOrder(c fiber.Ctx) error { func (h *OrdersHandler) PlaceNewOrder(c fiber.Ctx) error {
@@ -99,6 +111,13 @@ func (h *OrdersHandler) PlaceNewOrder(c fiber.Ctx) error {
err = h.ordersService.PlaceNewOrder(userID, uint(cart_id), name, uint(country_id), address_info) err = h.ordersService.PlaceNewOrder(userID, uint(cart_id), name, uint(country_id), address_info)
if err != nil { if err != nil {
logger.Error("failed to place order",
"handler", "OrdersHandler.PlaceNewOrder",
"user_id", userID,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -136,6 +155,13 @@ func (h *OrdersHandler) ChangeOrderAddress(c fiber.Ctx) error {
err = h.ordersService.ChangeOrderAddress(user, uint(order_id), uint(country_id), address_info) err = h.ordersService.ChangeOrderAddress(user, uint(order_id), uint(country_id), address_info)
if err != nil { if err != nil {
logger.Error("failed to change order address",
"handler", "OrdersHandler.ChangeOrderAddress",
"order_id", order_id,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -163,6 +189,13 @@ func (h *OrdersHandler) ChangeOrderStatus(c fiber.Ctx) error {
err = h.ordersService.ChangeOrderStatus(user, uint(order_id), status) err = h.ordersService.ChangeOrderStatus(user, uint(order_id), status)
if err != nil { if err != nil {
logger.Error("failed to change order status",
"handler", "OrdersHandler.ChangeOrderStatus",
"order_id", order_id,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }

View File

@@ -9,6 +9,7 @@ import (
constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data" constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data"
"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/localeExtractor"
"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/query/query_params"
"git.ma-al.com/goc_daniel/b2b/app/utils/response" "git.ma-al.com/goc_daniel/b2b/app/utils/response"
@@ -74,6 +75,15 @@ func (h *ProductsHandler) GetProductJson(c fiber.Ctx) error {
} }
productJson, err := h.productService.Get(uint(p_id_product), customer.LangID, customer.ID, uint(b2b_id_country), uint(p_quantity)) productJson, err := h.productService.Get(uint(p_id_product), customer.LangID, customer.ID, uint(b2b_id_country), uint(p_quantity))
if err != nil { if err != nil {
logger.Error("failed to get product",
"handler", "ProductsHandler.GetProductJson",
"product_id", p_id_product,
"lang_id", customer.LangID,
"customer_id", customer.ID,
"b2b_id_country", b2b_id_country,
"quantity", p_quantity,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -96,6 +106,13 @@ func (h *ProductsHandler) ListProducts(c fiber.Ctx) error {
list, err := h.productService.Find(customer.LangID, customer.ID, paging, filters, customer, constdata.DEFAULT_PRODUCT_QUANTITY, constdata.SHOP_ID) list, err := h.productService.Find(customer.LangID, customer.ID, paging, filters, customer, constdata.DEFAULT_PRODUCT_QUANTITY, constdata.SHOP_ID)
if err != nil { if err != nil {
logger.Error("failed to list products",
"handler", "ProductsHandler.ListProducts",
"lang_id", customer.LangID,
"customer_id", customer.ID,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -112,6 +129,7 @@ var columnMappingListProducts map[string]string = map[string]string{
"quantity": "bp.quantity", "quantity": "bp.quantity",
"is_favorite": "bp.is_favorite", "is_favorite": "bp.is_favorite",
"is_new": "bp.is_new", "is_new": "bp.is_new",
"is_oem": "bp.is_oem",
} }
func (h *ProductsHandler) AddToFavorites(c fiber.Ctx) error { func (h *ProductsHandler) AddToFavorites(c fiber.Ctx) error {
@@ -131,6 +149,13 @@ func (h *ProductsHandler) AddToFavorites(c fiber.Ctx) error {
err = h.productService.AddToFavorites(userID, uint(productID)) err = h.productService.AddToFavorites(userID, uint(productID))
if err != nil { if err != nil {
logger.Error("failed to add to favorites",
"handler", "ProductsHandler.AddToFavorites",
"user_id", userID,
"product_id", productID,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -155,6 +180,12 @@ func (h *ProductsHandler) RemoveFromFavorites(c fiber.Ctx) error {
err = h.productService.RemoveFromFavorites(userID, uint(productID)) err = h.productService.RemoveFromFavorites(userID, uint(productID))
if err != nil { if err != nil {
logger.Error("failed to remove from favorites",
"handler", "ProductsHandler.RemoveFromFavorites",
"user_id", userID,
"product_id", productID,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -179,6 +210,15 @@ func (h *ProductsHandler) ListProductVariants(c fiber.Ctx) error {
list, err := h.productService.GetProductAttributes(customer.LangID, uint(productID), constdata.SHOP_ID, customer.ID, customer.CountryID, constdata.DEFAULT_PRODUCT_QUANTITY) list, err := h.productService.GetProductAttributes(customer.LangID, uint(productID), constdata.SHOP_ID, customer.ID, customer.CountryID, constdata.DEFAULT_PRODUCT_QUANTITY)
if err != nil { if err != nil {
logger.Error("failed to list product variants",
"handler", "ProductsHandler.ListProductVariants",
"product_id", productID,
"customer_id", customer.ID,
"lang_id", customer.LangID,
"country_id", customer.CountryID,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }

View File

@@ -9,6 +9,7 @@ import (
"git.ma-al.com/goc_daniel/b2b/app/service/productTranslationService" "git.ma-al.com/goc_daniel/b2b/app/service/productTranslationService"
"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/localeExtractor"
"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/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"
@@ -66,6 +67,13 @@ func (h *ProductTranslationHandler) GetProductDescription(c fiber.Ctx) error {
description, err := h.productTranslationService.GetProductDescription(userID, uint(productID), uint(productLangID)) description, err := h.productTranslationService.GetProductDescription(userID, uint(productID), uint(productLangID))
if err != nil { if err != nil {
logger.Error("failed to get product description",
"handler", "ProductTranslationHandler.GetProductDescription",
"product_id", productID,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -103,6 +111,13 @@ func (h *ProductTranslationHandler) SaveProductDescription(c fiber.Ctx) error {
err = h.productTranslationService.SaveProductDescription(userID, uint(productID), uint(productLangID), updates) err = h.productTranslationService.SaveProductDescription(userID, uint(productID), uint(productLangID), updates)
if err != nil { if err != nil {
logger.Error("failed to save product description",
"handler", "ProductTranslationHandler.SaveProductDescription",
"product_id", productID,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -147,6 +162,13 @@ func (h *ProductTranslationHandler) TranslateProductDescription(c fiber.Ctx) err
description, err := h.productTranslationService.TranslateProductDescription(userID, uint(productID), uint(productFromLangID), uint(productToLangID), aiModel) description, err := h.productTranslationService.TranslateProductDescription(userID, uint(productID), uint(productFromLangID), uint(productToLangID), aiModel)
if err != nil { if err != nil {
logger.Error("failed to translate product description",
"handler", "ProductTranslationHandler.TranslateProductDescription",
"product_id", productID,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }

View File

@@ -2,7 +2,6 @@ package restricted
import ( import (
"encoding/json" "encoding/json"
"fmt"
"git.ma-al.com/goc_daniel/b2b/app/delivery/middleware" "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/delivery/middleware/perms"
@@ -10,6 +9,7 @@ import (
searchservice "git.ma-al.com/goc_daniel/b2b/app/service/searchService" searchservice "git.ma-al.com/goc_daniel/b2b/app/service/searchService"
"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/localeExtractor"
"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/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"
@@ -47,7 +47,13 @@ func (h *MeiliSearchHandler) CreateIndex(c fiber.Ctx) error {
err := h.meiliService.CreateIndex(id_lang) err := h.meiliService.CreateIndex(id_lang)
if err != nil { if err != nil {
fmt.Printf("CreateIndex error: %v\n", err)
logger.Error("failed to create search index",
"handler", "MeiliSearchHandler.CreateIndex",
"lang_id", id_lang,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -72,6 +78,13 @@ func (h *MeiliSearchHandler) Search(c fiber.Ctx) error {
result, err := h.searchService.Search(index, c.Body(), id_lang) result, err := h.searchService.Search(index, c.Body(), id_lang)
if err != nil { if err != nil {
logger.Error("failed to search",
"handler", "MeiliSearchHandler.Search",
"index", index,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -80,6 +93,13 @@ func (h *MeiliSearchHandler) Search(c fiber.Ctx) error {
if createErr := h.meiliService.CreateIndex(id_lang); createErr == nil { if createErr := h.meiliService.CreateIndex(id_lang); createErr == nil {
result, err = h.searchService.Search(index, c.Body(), id_lang) result, err = h.searchService.Search(index, c.Body(), id_lang)
if err != nil { if err != nil {
logger.Error("failed to search after index creation",
"handler", "MeiliSearchHandler.Search",
"index", index,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -100,6 +120,13 @@ func (h *MeiliSearchHandler) GetSettings(c fiber.Ctx) error {
result, err := h.searchService.GetIndexSettings(index) result, err := h.searchService.GetIndexSettings(index)
if err != nil { if err != nil {
logger.Error("failed to get index settings",
"handler", "MeiliSearchHandler.GetSettings",
"index", index,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }

View File

@@ -9,6 +9,7 @@ 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/specificPriceService" "git.ma-al.com/goc_daniel/b2b/app/service/specificPriceService"
"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/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/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"
@@ -51,6 +52,12 @@ func (h *SpecificPriceHandler) Create(c fiber.Ctx) error {
result, err := h.SpecificPriceService.Create(c.Context(), &pr) result, err := h.SpecificPriceService.Create(c.Context(), &pr)
if err != nil { if err != nil {
logger.Error("failed to create specific price",
"handler", "SpecificPriceHandler.Create",
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -74,6 +81,13 @@ func (h *SpecificPriceHandler) Update(c fiber.Ctx) error {
result, err := h.SpecificPriceService.Update(c.Context(), id, &pr) result, err := h.SpecificPriceService.Update(c.Context(), id, &pr)
if err != nil { if err != nil {
logger.Error("failed to update specific price",
"handler", "SpecificPriceHandler.Update",
"specific_price_id", id,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -84,6 +98,12 @@ func (h *SpecificPriceHandler) Update(c fiber.Ctx) error {
func (h *SpecificPriceHandler) List(c fiber.Ctx) error { func (h *SpecificPriceHandler) List(c fiber.Ctx) error {
result, err := h.SpecificPriceService.List(c.Context()) result, err := h.SpecificPriceService.List(c.Context())
if err != nil { if err != nil {
logger.Error("failed to list specific prices",
"handler", "SpecificPriceHandler.List",
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -101,6 +121,13 @@ func (h *SpecificPriceHandler) GetByID(c fiber.Ctx) error {
result, err := h.SpecificPriceService.GetByID(c.Context(), id) result, err := h.SpecificPriceService.GetByID(c.Context(), id)
if err != nil { if err != nil {
logger.Error("failed to get specific price",
"handler", "SpecificPriceHandler.GetByID",
"specific_price_id", id,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -118,6 +145,13 @@ func (h *SpecificPriceHandler) Activate(c fiber.Ctx) error {
err = h.SpecificPriceService.SetActive(c.Context(), id, true) err = h.SpecificPriceService.SetActive(c.Context(), id, true)
if err != nil { if err != nil {
logger.Error("failed to activate specific price",
"handler", "SpecificPriceHandler.Activate",
"specific_price_id", id,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -135,6 +169,13 @@ func (h *SpecificPriceHandler) Deactivate(c fiber.Ctx) error {
err = h.SpecificPriceService.SetActive(c.Context(), id, false) err = h.SpecificPriceService.SetActive(c.Context(), id, false)
if err != nil { if err != nil {
logger.Error("failed to deactivate specific price",
"handler", "SpecificPriceHandler.Deactivate",
"specific_price_id", id,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -152,6 +193,13 @@ func (h *SpecificPriceHandler) Delete(c fiber.Ctx) error {
err = h.SpecificPriceService.Delete(c.Context(), id) err = h.SpecificPriceService.Delete(c.Context(), id)
if err != nil { if err != nil {
logger.Error("failed to delete specific price",
"handler", "SpecificPriceHandler.Delete",
"specific_price_id", id,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }

View File

@@ -9,6 +9,7 @@ import (
"git.ma-al.com/goc_daniel/b2b/app/service/storageService" "git.ma-al.com/goc_daniel/b2b/app/service/storageService"
"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/localeExtractor"
"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/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"
@@ -52,6 +53,12 @@ func (h *StorageHandler) ListContent(c fiber.Ctx) error {
entries_in_list, err := h.storageService.ListContent(abs_path) entries_in_list, err := h.storageService.ListContent(abs_path)
if err != nil { if err != nil {
logger.Error("failed to list storage content",
"handler", "StorageHandler.ListContent",
"path", abs_path,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -68,6 +75,12 @@ func (h *StorageHandler) DownloadFile(c fiber.Ctx) error {
f, filename, filesize, err := h.storageService.DownloadFilePrep(abs_path) f, filename, filesize, err := h.storageService.DownloadFilePrep(abs_path)
if err != nil { if err != nil {
logger.Error("failed to prepare file download",
"handler", "StorageHandler.DownloadFile",
"path", abs_path,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }
@@ -87,6 +100,12 @@ func (h *StorageHandler) CreateNewWebdavToken(c fiber.Ctx) error {
new_token, err := h.storageService.NewWebdavToken(userID) new_token, err := h.storageService.NewWebdavToken(userID)
if err != nil { if err != nil {
logger.Error("failed to create webdav token",
"handler", "StorageHandler.CreateNewWebdavToken",
"user_id", userID,
"error", err.Error(),
)
return c.Status(responseErrors.GetErrorStatus(err)). return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
} }

View File

@@ -1,5 +1,7 @@
package model package model
import "time"
type CustomerOrder struct { type CustomerOrder struct {
OrderID uint `gorm:"column:order_id;primaryKey;autoIncrement" json:"order_id"` OrderID uint `gorm:"column:order_id;primaryKey;autoIncrement" json:"order_id"`
UserID uint `gorm:"column:user_id;not null;index" json:"user_id"` UserID uint `gorm:"column:user_id;not null;index" json:"user_id"`
@@ -8,6 +10,11 @@ type CustomerOrder struct {
AddressString string `gorm:"column:address_string;not null" json:"address_string"` AddressString string `gorm:"column:address_string;not null" json:"address_string"`
AddressUnparsed *AddressUnparsed `gorm:"-" json:"address_unparsed"` AddressUnparsed *AddressUnparsed `gorm:"-" json:"address_unparsed"`
Status string `gorm:"column:status;size:50;not null" json:"status"` Status string `gorm:"column:status;size:50;not null" json:"status"`
BasePrice float64 `gorm:"column:base_price;type:decimal(10,2);not null" json:"base_price"`
TaxIncl float64 `gorm:"column:tax_incl;type:decimal(10,2);not null" json:"tax_incl"`
TaxExcl float64 `gorm:"column:tax_excl;type:decimal(10,2);not null" json:"tax_excl"`
CreatedAt time.Time `gorm:"column:created_at;not null" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at;not null" json:"updated_at"`
Products []OrderProduct `gorm:"foreignKey:OrderID;references:OrderID" json:"products"` Products []OrderProduct `gorm:"foreignKey:OrderID;references:OrderID" json:"products"`
} }

View File

@@ -12,7 +12,8 @@ type ProductInList struct {
PriceTaxExcl float64 `gorm:"column:price_tax_excl" json:"price_tax_excl"` PriceTaxExcl float64 `gorm:"column:price_tax_excl" json:"price_tax_excl"`
PriceTaxIncl float64 `gorm:"column:price_tax_incl" json:"price_tax_incl"` PriceTaxIncl float64 `gorm:"column:price_tax_incl" json:"price_tax_incl"`
IsFavorite bool `gorm:"column:is_favorite" json:"is_favorite"` IsFavorite bool `gorm:"column:is_favorite" json:"is_favorite"`
IsNew uint `gorm:"column:is_new" json:"is_new"` IsNew bool `gorm:"column:is_new" json:"is_new"`
IsOEM bool `gorm:"column:is_oem" json:"is_oem"`
} }
type ProductFilters struct { type ProductFilters struct {

View File

@@ -12,7 +12,7 @@ import (
type UICartsRepo interface { type UICartsRepo interface {
CartsAmount(user_id uint) (uint, error) CartsAmount(user_id uint) (uint, error)
CreateNewCart(user_id uint) (model.CustomerCart, error) CreateNewCart(user_id uint, name string) (model.CustomerCart, error)
RemoveCart(user_id uint, cart_id uint) error RemoveCart(user_id uint, cart_id uint) error
UserHasCart(user_id uint, cart_id uint) (bool, error) UserHasCart(user_id uint, cart_id uint) (bool, error)
UpdateCartName(user_id uint, cart_id uint, new_name string) error UpdateCartName(user_id uint, cart_id uint, new_name string) error
@@ -42,10 +42,7 @@ func (repo *CartsRepo) CartsAmount(user_id uint) (uint, error) {
return amt, err return amt, err
} }
func (repo *CartsRepo) CreateNewCart(user_id uint) (model.CustomerCart, error) { func (repo *CartsRepo) CreateNewCart(user_id uint, name string) (model.CustomerCart, error) {
var name string
name = constdata.DEFAULT_NEW_CART_NAME
cart := model.CustomerCart{ cart := model.CustomerCart{
UserID: user_id, UserID: user_id,
Name: &name, Name: &name,

View File

@@ -1,6 +1,8 @@
package ordersRepo package ordersRepo
import ( import (
"time"
"git.ma-al.com/goc_daniel/b2b/app/db" "git.ma-al.com/goc_daniel/b2b/app/db"
"git.ma-al.com/goc_daniel/b2b/app/model" "git.ma-al.com/goc_daniel/b2b/app/model"
constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data" constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data"
@@ -11,7 +13,7 @@ import (
type UIOrdersRepo interface { type UIOrdersRepo interface {
UserHasOrder(user_id uint, order_id uint) (bool, error) UserHasOrder(user_id uint, order_id uint) (bool, error)
Find(user_id uint, p find.Paging, filt *filters.FiltersList) (*find.Found[model.CustomerOrder], error) Find(user_id uint, p find.Paging, filt *filters.FiltersList) (*find.Found[model.CustomerOrder], error)
PlaceNewOrder(cart *model.CustomerCart, name string, country_id uint, address_info string) error PlaceNewOrder(cart *model.CustomerCart, name string, country_id uint, address_info string, base_price float64, tax_incl float64, tax_excl float64) error
ChangeOrderAddress(order_id uint, country_id uint, address_info string) error ChangeOrderAddress(order_id uint, country_id uint, address_info string) error
ChangeOrderStatus(order_id uint, status string) error ChangeOrderStatus(order_id uint, status string) error
} }
@@ -69,7 +71,7 @@ func (repo *OrdersRepo) Find(user_id uint, p find.Paging, filt *filters.FiltersL
}, nil }, nil
} }
func (repo *OrdersRepo) PlaceNewOrder(cart *model.CustomerCart, name string, country_id uint, address_info string) error { func (repo *OrdersRepo) PlaceNewOrder(cart *model.CustomerCart, name string, country_id uint, address_info string, base_price float64, tax_incl float64, tax_excl float64) error {
order := model.CustomerOrder{ order := model.CustomerOrder{
UserID: cart.UserID, UserID: cart.UserID,
Name: name, Name: name,
@@ -87,6 +89,12 @@ func (repo *OrdersRepo) PlaceNewOrder(cart *model.CustomerCart, name string, cou
}) })
} }
order.CreatedAt = time.Now()
order.UpdatedAt = time.Now()
order.BasePrice = base_price
order.TaxIncl = tax_incl
order.TaxExcl = tax_excl
return db.DB.Create(&order).Error return db.DB.Create(&order).Error
} }
@@ -97,6 +105,7 @@ func (repo *OrdersRepo) ChangeOrderAddress(order_id uint, country_id uint, addre
Updates(map[string]interface{}{ Updates(map[string]interface{}{
"country_id": country_id, "country_id": country_id,
"address_string": address_info, "address_string": address_info,
"updated_at": time.Now(),
}). }).
Error Error
} }
@@ -105,6 +114,9 @@ func (repo *OrdersRepo) ChangeOrderStatus(order_id uint, status string) error {
return db.DB. return db.DB.
Table("b2b_customer_orders"). Table("b2b_customer_orders").
Where("order_id = ?", order_id). Where("order_id = ?", order_id).
Update("status", status). Updates(map[string]interface{}{
"status": status,
"updated_at": time.Now(),
}).
Error Error
} }

View File

@@ -122,6 +122,19 @@ func (repo *ProductsRepo) Find(langID uint, userID uint, p find.Paging, filt *fi
Group("product_id"), Group("product_id"),
}, },
}, },
{
Name: "oems",
Subquery: exclause.Subquery{
DB: db.DB.
Table("b2b_oems").
Select(`
product_id AS product_id,
COUNT(*) > 0 AS is_customers_oem
`).
Where("user_id = ?", userID).
Group("product_id"),
},
},
{ {
Name: "new_product_days", Name: "new_product_days",
Subquery: exclause.Subquery{ Subquery: exclause.Subquery{
@@ -150,6 +163,7 @@ func (repo *ProductsRepo) Find(langID uint, userID uint, p find.Paging, filt *fi
pl.name AS name, pl.name AS name,
ps.id_category_default AS category_id, ps.id_category_default AS category_id,
p.reference AS reference, p.reference AS reference,
p.is_oem AS is_oem,
sa.quantity AS quantity, sa.quantity AS quantity,
COALESCE(f.is_favorite, 0) AS is_favorite, COALESCE(f.is_favorite, 0) AS is_favorite,
CASE CASE
@@ -166,7 +180,9 @@ func (repo *ProductsRepo) Find(langID uint, userID uint, p find.Paging, filt *fi
Joins("LEFT JOIN favorites f ON f.product_id = ps.id_product"). Joins("LEFT JOIN favorites f ON f.product_id = ps.id_product").
Joins("LEFT JOIN ps_stock_available sa ON sa.id_product = ps.id_product AND sa.id_product_attribute = 0"). Joins("LEFT JOIN ps_stock_available sa ON sa.id_product = ps.id_product AND sa.id_product_attribute = 0").
Joins("LEFT JOIN new_product_days npd ON 1 = 1"). Joins("LEFT JOIN new_product_days npd ON 1 = 1").
Joins("LEFT JOIN oems ON oems.product_id = ps.id_product").
Where("ps.active = ?", 1). Where("ps.active = ?", 1).
Where("(p.is_oem = 0 OR oems.is_customers_oem > 0)").
Group("ps.id_product"), Group("ps.id_product"),
}, },
}, },
@@ -182,7 +198,8 @@ func (repo *ProductsRepo) Find(langID uint, userID uint, p find.Paging, filt *fi
COALESCE(v.variants_number, 0) AS variants_number, COALESCE(v.variants_number, 0) AS variants_number,
bp.quantity AS quantity, bp.quantity AS quantity,
bp.is_favorite AS is_favorite, bp.is_favorite AS is_favorite,
bp.is_new AS is_new bp.is_new AS is_new,
bp.is_oem AS is_oem
`, config.Get().Image.ImagePrefix). `, config.Get().Image.ImagePrefix).
Joins("JOIN ps_product_lang pl ON pl.id_product = bp.product_id AND pl.id_lang = ?", langID). Joins("JOIN ps_product_lang pl ON pl.id_product = bp.product_id AND pl.id_lang = ?", langID).
Joins("JOIN ps_image_shop ims ON ims.id_product = bp.product_id AND ims.cover = 1"). Joins("JOIN ps_image_shop ims ON ims.id_product = bp.product_id AND ims.cover = 1").

View File

@@ -15,6 +15,7 @@ import (
roleRepo "git.ma-al.com/goc_daniel/b2b/app/repos/rolesRepo" roleRepo "git.ma-al.com/goc_daniel/b2b/app/repos/rolesRepo"
"git.ma-al.com/goc_daniel/b2b/app/service/emailService" "git.ma-al.com/goc_daniel/b2b/app/service/emailService"
constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data" constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data"
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors" "git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
"github.com/dlclark/regexp2" "github.com/dlclark/regexp2"
@@ -68,22 +69,47 @@ func (s *AuthService) Login(req *model.LoginRequest) (*model.AuthResponse, strin
// Find user by email // Find user by email
if err := s.db.Preload("Role.Permissions").Where("email = ?", req.Email).First(&user).Error; err != nil { if err := s.db.Preload("Role.Permissions").Where("email = ?", req.Email).First(&user).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
logger.Info("login failed - invalid credentials",
"service", "AuthService.Login",
"email", req.Email,
"reason", "user not found",
)
return nil, "", responseErrors.ErrInvalidCredentials return nil, "", responseErrors.ErrInvalidCredentials
} }
logger.Error("login failed - database error",
"service", "AuthService.Login",
"email", req.Email,
"error", err.Error(),
)
return nil, "", fmt.Errorf("database error: %w", err) return nil, "", fmt.Errorf("database error: %w", err)
} }
// Check if user is active // Check if user is active
if !user.IsActive { if !user.IsActive {
logger.Info("login failed - user inactive",
"service", "AuthService.Login",
"email", req.Email,
"reason", "user account is inactive",
)
return nil, "", responseErrors.ErrUserInactive return nil, "", responseErrors.ErrUserInactive
} }
// Check if email is verified // Check if email is verified
if !user.EmailVerified { if !user.EmailVerified {
logger.Info("login failed - email not verified",
"service", "AuthService.Login",
"email", req.Email,
"reason", "email not verified",
)
return nil, "", responseErrors.ErrEmailNotVerified return nil, "", responseErrors.ErrEmailNotVerified
} }
// Verify password // Verify password
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.Password)); err != nil { if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.Password)); err != nil {
logger.Info("login failed - invalid credentials",
"service", "AuthService.Login",
"email", req.Email,
"reason", "wrong password",
)
return nil, "", responseErrors.ErrInvalidCredentials return nil, "", responseErrors.ErrInvalidCredentials
} }
@@ -94,22 +120,38 @@ func (s *AuthService) Login(req *model.LoginRequest) (*model.AuthResponse, strin
if req.LangID != nil { if req.LangID != nil {
_, err := s.GetLangISOCode(*req.LangID) _, err := s.GetLangISOCode(*req.LangID)
if err != nil { if err != nil {
logger.Warn("login failed - invalid language ID",
"service", "AuthService.Login",
"email", req.Email,
"reason", "invalid language ID",
)
return nil, "", responseErrors.ErrBadLangID return nil, "", responseErrors.ErrBadLangID
} }
user.LangID = *req.LangID user.LangID = *req.LangID
} }
user.Country = nil
s.db.Save(&user) s.db.Save(&user)
// Generate access token (JWT) // Generate access token (JWT)
accessToken, err := s.generateAccessToken(&user) accessToken, err := s.generateAccessToken(&user)
if err != nil { if err != nil {
logger.Error("login failed - token generation error",
"service", "AuthService.Login",
"email", req.Email,
"error", err.Error(),
)
return nil, "", fmt.Errorf("failed to generate access token: %w", err) return nil, "", fmt.Errorf("failed to generate access token: %w", err)
} }
// Generate opaque refresh token and store in DB // Generate opaque refresh token and store in DB
rawRefreshToken, err := s.createRefreshToken(user.ID) rawRefreshToken, err := s.createRefreshToken(user.ID)
if err != nil { if err != nil {
logger.Error("login failed - refresh token creation error",
"service", "AuthService.Login",
"email", req.Email,
"error", err.Error(),
)
return nil, "", fmt.Errorf("failed to create refresh token: %w", err) return nil, "", fmt.Errorf("failed to create refresh token: %w", err)
} }
@@ -170,6 +212,11 @@ func (s *AuthService) Register(req *model.RegisterRequest) error {
} }
if err := s.db.Create(&user).Error; err != nil { if err := s.db.Create(&user).Error; err != nil {
logger.Error("registration failed - database error",
"service", "AuthService.Register",
"email", req.Email,
"error", err.Error(),
)
return fmt.Errorf("failed to create user: %w", err) return fmt.Errorf("failed to create user: %w", err)
} }
@@ -181,8 +228,11 @@ func (s *AuthService) Register(req *model.RegisterRequest) error {
} }
if err := s.email.SendVerificationEmail(user.Email, user.EmailVerificationToken, baseURL, lang); err != nil { if err := s.email.SendVerificationEmail(user.Email, user.EmailVerificationToken, baseURL, lang); err != nil {
// Log error but don't fail registration - user can request resend logger.Warn("failed to send verification email",
_ = err "service", "AuthService.Register",
"email", req.Email,
"error", err.Error(),
)
} }
return nil return nil
@@ -210,6 +260,7 @@ func (s *AuthService) CompleteRegistration(req *model.CompleteRegistrationReques
user.EmailVerificationToken = "" user.EmailVerificationToken = ""
user.EmailVerificationExpires = nil user.EmailVerificationExpires = nil
user.Country = nil
if err := s.db.Save(&user).Error; err != nil { if err := s.db.Save(&user).Error; err != nil {
return nil, "", fmt.Errorf("failed to update user: %w", err) return nil, "", fmt.Errorf("failed to update user: %w", err)
} }
@@ -278,6 +329,7 @@ func (s *AuthService) RequestPasswordReset(emailAddr string) error {
user.PasswordResetToken = token user.PasswordResetToken = token
user.PasswordResetExpires = &expiresAt user.PasswordResetExpires = &expiresAt
user.LastPasswordResetRequest = &now user.LastPasswordResetRequest = &now
user.Country = nil
if err := s.db.Save(&user).Error; err != nil { if err := s.db.Save(&user).Error; err != nil {
return fmt.Errorf("failed to save reset token: %w", err) return fmt.Errorf("failed to save reset token: %w", err)
} }
@@ -304,6 +356,10 @@ func (s *AuthService) ResetPassword(token, newPassword string) error {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
return responseErrors.ErrInvalidResetToken return responseErrors.ErrInvalidResetToken
} }
logger.Error("password reset failed - database error",
"service", "AuthService.ResetPassword",
"error", err.Error(),
)
return fmt.Errorf("database error: %w", err) return fmt.Errorf("database error: %w", err)
} }
@@ -328,7 +384,12 @@ func (s *AuthService) ResetPassword(token, newPassword string) error {
user.PasswordResetToken = "" user.PasswordResetToken = ""
user.PasswordResetExpires = nil user.PasswordResetExpires = nil
user.Country = nil
if err := s.db.Save(&user).Error; err != nil { if err := s.db.Save(&user).Error; err != nil {
logger.Error("password reset failed - database error",
"service", "AuthService.ResetPassword",
"error", err.Error(),
)
return fmt.Errorf("failed to update password: %w", err) return fmt.Errorf("failed to update password: %w", err)
} }
@@ -539,6 +600,7 @@ func (s *AuthService) UpdateJWTToken(user *model.Customer) (string, error) {
} }
// Save the updated user // Save the updated user
user.Country = nil
if err := s.db.Save(user).Error; err != nil { if err := s.db.Save(user).Error; err != nil {
return "", fmt.Errorf("database error: %w", err) return "", fmt.Errorf("database error: %w", err)
} }

View File

@@ -8,10 +8,12 @@ import (
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"strings"
"time" "time"
"git.ma-al.com/goc_daniel/b2b/app/config" "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/model"
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors" "git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
"git.ma-al.com/goc_daniel/b2b/app/view" "git.ma-al.com/goc_daniel/b2b/app/view"
"golang.org/x/oauth2" "golang.org/x/oauth2"
@@ -77,12 +79,20 @@ func (s *AuthService) HandleGoogleCallback(code string) (*model.AuthResponse, st
// Find or create user // Find or create user
user, err := s.findOrCreateGoogleUser(userInfo) user, err := s.findOrCreateGoogleUser(userInfo)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "database") {
logger.Error("google oauth callback failed - database error",
"service", "AuthService.HandleGoogleCallback",
"email", userInfo.Email,
"error", err.Error(),
)
}
return nil, "", err return nil, "", err
} }
// Update last login // Update last login
now := time.Now() now := time.Now()
user.LastLoginAt = &now user.LastLoginAt = &now
user.Country = nil
s.db.Save(user) s.db.Save(user)
// Generate access token (JWT) // Generate access token (JWT)

View File

@@ -4,6 +4,7 @@ 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/cartsRepo" "git.ma-al.com/goc_daniel/b2b/app/repos/cartsRepo"
constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data" constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data"
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors" "git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
) )
@@ -17,7 +18,7 @@ func New() *CartsService {
} }
} }
func (s *CartsService) CreateNewCart(user_id uint) (model.CustomerCart, error) { func (s *CartsService) CreateNewCart(user_id uint, name string) (model.CustomerCart, error) {
var cart model.CustomerCart var cart model.CustomerCart
customers_carts_amount, err := s.repo.CartsAmount(user_id) customers_carts_amount, err := s.repo.CartsAmount(user_id)
@@ -28,8 +29,21 @@ func (s *CartsService) CreateNewCart(user_id uint) (model.CustomerCart, error) {
return cart, responseErrors.ErrMaxAmtOfCartsReached return cart, responseErrors.ErrMaxAmtOfCartsReached
} }
if name == "" {
name = constdata.DEFAULT_NEW_CART_NAME
}
// create new cart for customer // create new cart for customer
cart, err = s.repo.CreateNewCart(user_id) cart, err = s.repo.CreateNewCart(user_id, name)
if err != nil {
return cart, err
}
logger.Info("cart created",
"service", "cartsService",
"user_id", user_id,
"cart_id", cart.CartID,
)
return cart, nil return cart, nil
} }

View File

@@ -231,21 +231,54 @@ func (s *MenuService) GetTopMenu(languageId uint, roleId uint) ([]*model.B2BTopM
func (s *MenuService) appendAdditional(all_categories *[]model.ScannedCategory, id_lang uint, iso_code string) { func (s *MenuService) appendAdditional(all_categories *[]model.ScannedCategory, id_lang uint, iso_code string) {
for i := 0; i < len(*all_categories); i++ { for i := 0; i < len(*all_categories); i++ {
(*all_categories)[i].Filter = "category_id_in=" + strconv.Itoa(int((*all_categories)[i].CategoryID)) (*all_categories)[i].Filter = "category_id_eq=" + strconv.Itoa(int((*all_categories)[i].CategoryID))
} }
var additional model.ScannedCategory // the new products category
additional.CategoryID = 10001 var new_products_category model.ScannedCategory
additional.Name = "New Products" new_products_category.CategoryID = constdata.ADDITIONAL_CATEGORIES_INDEX + 1
additional.Active = 1 new_products_category.Name = "New Products"
additional.Position = 10 new_products_category.Active = 1
additional.ParentID = 2 new_products_category.Position = 10
additional.IsRoot = 0 new_products_category.ParentID = 2
additional.LinkRewrite = i18n.T___(id_lang, "category.new_products") new_products_category.IsRoot = 0
additional.IsoCode = iso_code new_products_category.LinkRewrite = i18n.T___(id_lang, "category.new_products")
new_products_category.IsoCode = iso_code
additional.Visited = false new_products_category.Visited = false
additional.Filter = "is_new_in=true" new_products_category.Filter = "is_new_eq=true"
*all_categories = append(*all_categories, additional) *all_categories = append(*all_categories, new_products_category)
// the oem products category
var oem_products_category model.ScannedCategory
oem_products_category.CategoryID = constdata.ADDITIONAL_CATEGORIES_INDEX + 2
oem_products_category.Name = "OEM Products"
oem_products_category.Active = 1
oem_products_category.Position = 11
oem_products_category.ParentID = 2
oem_products_category.IsRoot = 0
oem_products_category.LinkRewrite = i18n.T___(id_lang, "category.oem_products")
oem_products_category.IsoCode = iso_code
oem_products_category.Visited = false
oem_products_category.Filter = "is_oem_eq=true"
*all_categories = append(*all_categories, oem_products_category)
// the favorite products category
var favorite_products_category model.ScannedCategory
favorite_products_category.CategoryID = constdata.ADDITIONAL_CATEGORIES_INDEX + 3
favorite_products_category.Name = "Favourite Products" // British English version.
favorite_products_category.Active = 1
favorite_products_category.Position = 12
favorite_products_category.ParentID = 2
favorite_products_category.IsRoot = 0
favorite_products_category.LinkRewrite = i18n.T___(id_lang, "category.favorite_products")
favorite_products_category.IsoCode = iso_code
favorite_products_category.Visited = false
favorite_products_category.Filter = "is_favorite_eq=true"
*all_categories = append(*all_categories, favorite_products_category)
} }

View File

@@ -1,15 +1,17 @@
package orderService package orderService
import ( import (
"fmt"
"strconv" "strconv"
"git.ma-al.com/goc_daniel/b2b/app/delivery/middleware/perms" "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/model"
"git.ma-al.com/goc_daniel/b2b/app/repos/cartsRepo" "git.ma-al.com/goc_daniel/b2b/app/repos/cartsRepo"
"git.ma-al.com/goc_daniel/b2b/app/repos/ordersRepo" "git.ma-al.com/goc_daniel/b2b/app/repos/ordersRepo"
"git.ma-al.com/goc_daniel/b2b/app/repos/productsRepo"
"git.ma-al.com/goc_daniel/b2b/app/service/addressesService" "git.ma-al.com/goc_daniel/b2b/app/service/addressesService"
"git.ma-al.com/goc_daniel/b2b/app/service/emailService" "git.ma-al.com/goc_daniel/b2b/app/service/emailService"
constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data"
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
"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"
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors" "git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
@@ -18,6 +20,7 @@ import (
type OrderService struct { type OrderService struct {
ordersRepo ordersRepo.UIOrdersRepo ordersRepo ordersRepo.UIOrdersRepo
cartsRepo cartsRepo.UICartsRepo cartsRepo cartsRepo.UICartsRepo
productsRepo productsRepo.UIProductsRepo
addressesService *addressesService.AddressesService addressesService *addressesService.AddressesService
emailService *emailService.EmailService emailService *emailService.EmailService
} }
@@ -26,6 +29,7 @@ func New() *OrderService {
return &OrderService{ return &OrderService{
ordersRepo: ordersRepo.New(), ordersRepo: ordersRepo.New(),
cartsRepo: cartsRepo.New(), cartsRepo: cartsRepo.New(),
productsRepo: productsRepo.New(),
addressesService: addressesService.New(), addressesService: addressesService.New(),
emailService: emailService.NewEmailService(), emailService: emailService.NewEmailService(),
} }
@@ -45,9 +49,12 @@ func (s *OrderService) Find(user *model.Customer, p find.Paging, filt *filters.F
for i := 0; i < len(list.Items); i++ { for i := 0; i < len(list.Items); i++ {
address_unparsed, err := s.addressesService.ValidateAddressJson(list.Items[i].AddressString, list.Items[i].CountryID) address_unparsed, err := s.addressesService.ValidateAddressJson(list.Items[i].AddressString, list.Items[i].CountryID)
// log such errors
if err != nil { if err != nil {
fmt.Printf("err: %v\n", err) logger.Warn("failed to validate address",
"service", "orderService",
"order_id", list.Items[i].OrderID,
"error", err.Error(),
)
} }
list.Items[i].AddressUnparsed = &address_unparsed list.Items[i].AddressUnparsed = &address_unparsed
@@ -82,8 +89,10 @@ func (s *OrderService) PlaceNewOrder(user_id uint, cart_id uint, name string, co
name = *cart.Name name = *cart.Name
} }
base_price, tax_incl, tax_excl, err := s.getOrderTotalPrice(user_id, cart_id, country_id)
// all checks passed // all checks passed
err = s.ordersRepo.PlaceNewOrder(cart, name, country_id, address_info) err = s.ordersRepo.PlaceNewOrder(cart, name, country_id, address_info, base_price, tax_incl, tax_excl)
if err != nil { if err != nil {
return err return err
} }
@@ -92,16 +101,23 @@ func (s *OrderService) PlaceNewOrder(user_id uint, cart_id uint, name string, co
// if no error is returned, remove the cart. This should be smooth // if no error is returned, remove the cart. This should be smooth
err = s.cartsRepo.RemoveCart(user_id, cart_id) err = s.cartsRepo.RemoveCart(user_id, cart_id)
if err != nil { if err != nil {
// Log error but don't fail placing order logger.Warn("failed to remove cart after order placement",
_ = err "service", "orderService",
"user_id", user_id,
"cart_id", cart_id,
"error", err.Error(),
)
} }
// send email to admin // send email to admin
go func(user_id uint) { go func(user_id uint) {
err := s.emailService.SendNewOrderPlacedNotification(user_id) err := s.emailService.SendNewOrderPlacedNotification(user_id)
if err != nil { if err != nil {
// Log error but don't fail placing order logger.Warn("failed to send new order notification",
_ = err "service", "orderService",
"user_id", user_id,
"error", err.Error(),
)
} }
}(user_id) }(user_id)
@@ -143,3 +159,27 @@ func (s *OrderService) ChangeOrderStatus(user *model.Customer, order_id uint, st
return s.ordersRepo.ChangeOrderStatus(order_id, status) return s.ordersRepo.ChangeOrderStatus(order_id, status)
} }
func (s *OrderService) getOrderTotalPrice(user_id uint, cart_id uint, country_id uint) (float64, float64, float64, error) {
cart, err := s.cartsRepo.RetrieveCart(user_id, cart_id)
if err != nil {
return 0.0, 0.0, 0.0, err
}
base_price := 0.0
tax_incl := 0.0
tax_excl := 0.0
for _, product := range cart.Products {
prices, err := s.productsRepo.GetPrice(product.ProductID, product.ProductAttributeID, constdata.SHOP_ID, user_id, country_id, product.Amount)
if err != nil {
return 0.0, 0.0, 0.0, err
}
base_price += prices.Base
tax_incl += prices.FinalTaxIncl
tax_excl += prices.FinalTaxExcl
}
return base_price, tax_incl, tax_excl, nil
}

View File

@@ -9,6 +9,7 @@ const ADMIN_NOTIFICATION_LANGUAGE = 2
// CATEGORY_TREE_ROOT_ID corresponds to id_category in ps_category which has is_root_category=1 // CATEGORY_TREE_ROOT_ID corresponds to id_category in ps_category which has is_root_category=1
const CATEGORY_TREE_ROOT_ID = 2 const CATEGORY_TREE_ROOT_ID = 2
const ADDITIONAL_CATEGORIES_INDEX = 10000
// since arrays can not be const // since arrays can not be const
var CATEGORY_BLACKLIST = []uint{250} var CATEGORY_BLACKLIST = []uint{250}

151
app/utils/logger/logger.go Normal file
View File

@@ -0,0 +1,151 @@
package logger
import (
"context"
"fmt"
"io"
"log/slog"
"os"
"strings"
)
var L *slog.Logger
const (
reset = "\033[0m"
red = "\033[31m"
yellow = "\033[33m"
green = "\033[32m"
blue = "\033[36m"
gray = "\033[90m"
)
type consoleHandler struct {
w io.Writer
colorize bool
}
func (h *consoleHandler) Enabled(ctx context.Context, level slog.Level) bool {
return true
}
func (h *consoleHandler) Handle(ctx context.Context, r slog.Record) error {
level := r.Level.String()
color := reset
switch r.Level {
case slog.LevelError:
color = red
case slog.LevelWarn:
color = yellow
case slog.LevelInfo:
color = blue
case slog.LevelDebug:
color = gray
}
var msg string
if h.colorize {
msg = fmt.Sprintf("%s%s%s %s%s%s %s%s%s",
reset, r.Time.Format("15:04:05"), reset,
color, level, reset,
reset, r.Message, reset)
} else {
msg = fmt.Sprintf("%s %s %s", r.Time.Format("15:04:05"), level, r.Message)
}
var pairs []string
r.Attrs(func(attr slog.Attr) bool {
if h.colorize {
pairs = append(pairs, fmt.Sprintf("%s%s=%s%v%s", green, attr.Key, reset, attr.Value, reset))
} else {
pairs = append(pairs, fmt.Sprintf("%s=%v", attr.Key, attr.Value))
}
return true
})
if len(pairs) > 0 {
msg += " " + strings.Join(pairs, " ")
}
fmt.Fprintln(h.w, msg)
return nil
}
func (h *consoleHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
return &consoleHandler{w: h.w, colorize: h.colorize}
}
func (h *consoleHandler) WithGroup(name string) slog.Handler {
return &consoleHandler{w: h.w, colorize: h.colorize}
}
func Init(service string, output io.Writer, level string, colorize bool) {
if output == nil {
output = os.Stderr
}
var lvl slog.Level
switch level {
case "debug":
lvl = slog.LevelDebug
case "warn":
lvl = slog.LevelWarn
case "error":
lvl = slog.LevelError
default:
lvl = slog.LevelInfo
}
if colorize {
L = slog.New(&consoleHandler{w: output, colorize: true}).With("service", service, "level", lvl.String())
} else {
L = slog.New(slog.NewJSONHandler(output, &slog.HandlerOptions{
Level: lvl,
AddSource: false,
ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
if a.Key == slog.TimeKey && groups == nil {
a.Key = "timestamp"
}
if a.Key == slog.LevelKey {
a.Key = "level"
}
if a.Key == slog.MessageKey {
a.Key = "message"
}
return a
},
})).With("service", service)
}
}
func Info(msg string, args ...any) {
if L != nil {
L.Info(msg, args...)
}
}
func Warn(msg string, args ...any) {
if L != nil {
L.Warn(msg, args...)
}
}
func Error(msg string, args ...any) {
if L != nil {
L.Error(msg, args...)
}
}
func Debug(msg string, args ...any) {
if L != nil {
L.Debug(msg, args...)
}
}
func With(args ...any) *slog.Logger {
if L == nil {
return nil
}
return L.With(args...)
}

View File

@@ -95,4 +95,6 @@ type Product struct {
Category string `gorm:"column:category" json:"category"` Category string `gorm:"column:category" json:"category"`
IsFavorite bool `gorm:"column:is_favorite" json:"is_favorite"` IsFavorite bool `gorm:"column:is_favorite" json:"is_favorite"`
IsOEM bool `gorm:"column:is_oem" json:"is_oem"`
IsNew bool `gorm:"column:is_new" json:"is_new"`
} }

View File

@@ -5,7 +5,7 @@ info:
http: http:
method: GET method: GET
url: "{{bas_url}}/restricted/product/list?p=1&elems=30&reference=~NC100" url: "{{bas_url}}/restricted/product/list?p=1&elems=30&reference=~NC100&is_new_eq=0&is_favorite_eq=false&is_oem_eq=FALSE"
params: params:
- name: p - name: p
value: "1" value: "1"
@@ -27,11 +27,12 @@ http:
- name: is_new_eq - name: is_new_eq
value: "0" value: "0"
type: query type: query
disabled: true
- name: is_favorite_eq - name: is_favorite_eq
value: "false" value: "false"
type: query type: query
disabled: true - name: is_oem_eq
value: "FALSE"
type: query
body: body:
type: json type: json
data: "" data: ""

View File

@@ -1,7 +1,7 @@
info: info:
name: addresses name: addresses
type: folder type: folder
seq: 10 seq: 9
request: request:
auth: inherit auth: inherit

View File

@@ -5,15 +5,14 @@ info:
http: http:
method: POST method: POST
url: http://localhost:3000/api/v1/public/auth/update-choice?lang_id=0&country_id=1 url: http://localhost:3000/api/v1/public/auth/update-choice?lang_id=1&country_id=1
params: params:
- name: lang_id - name: lang_id
value: "0" value: "1"
type: query type: query
- name: country_id - name: country_id
value: "1" value: "1"
type: query type: query
auth: inherit
settings: settings:
encodeUrl: true encodeUrl: true

View File

@@ -5,7 +5,11 @@ info:
http: http:
method: GET method: GET
url: http://localhost:3000/api/v1/restricted/carts/add-new-cart url: http://localhost:3000/api/v1/restricted/carts/add-new-cart?name=carttt
params:
- name: name
value: carttt
type: query
auth: inherit auth: inherit
settings: settings:

View File

@@ -5,7 +5,7 @@ info:
http: http:
method: GET method: GET
url: http://localhost:3000/api/v1/restricted/carts/add-product-to-cart?cart_id=1&product_id=51&product_attribute_id=1115&amount=1&set_amount=true url: http://localhost:3000/api/v1/restricted/carts/add-product-to-cart?cart_id=1&product_id=51&product_attribute_id=1115&amount=2&set_amount=true
params: params:
- name: cart_id - name: cart_id
value: "1" value: "1"
@@ -17,7 +17,7 @@ http:
value: "1115" value: "1115"
type: query type: query
- name: amount - name: amount
value: "1" value: "2"
type: query type: query
- name: set_amount - name: set_amount
value: "true" value: "true"

View File

@@ -1,7 +0,0 @@
info:
name: list
type: folder
seq: 3
request:
auth: inherit

View File

@@ -1,24 +0,0 @@
info:
name: list-products
type: http
seq: 1
http:
method: GET
url: http://localhost:3000/api/v1/restricted/list/list-products?p=1&elems=10&target_user_id=2
params:
- name: p
value: "1"
type: query
- name: elems
value: "10"
type: query
- name: target_user_id
value: "2"
type: query
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -1,21 +0,0 @@
info:
name: list-users
type: http
seq: 1
http:
method: GET
url: http://localhost:3000/api/v1/restricted/list/list-users?p=1&elems=10
params:
- name: p
value: "1"
type: query
- name: elems
value: "10"
type: query
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -1,7 +1,7 @@
info: info:
name: orders name: orders
type: folder type: folder
seq: 11 seq: 10
request: request:
auth: inherit auth: inherit

View File

@@ -1,7 +1,7 @@
info: info:
name: product-translation name: product-translation
type: folder type: folder
seq: 2 seq: 3
request: request:
auth: inherit auth: inherit

View File

@@ -1,7 +1,7 @@
info: info:
name: storage-old name: storage-old
type: folder type: folder
seq: 1 seq: 2
request: request:
auth: inherit auth: inherit

View File

@@ -1,7 +1,7 @@
info: info:
name: storage-restricted name: storage-restricted
type: folder type: folder
seq: 9 seq: 8
request: request:
auth: inherit auth: inherit

View File

@@ -113,7 +113,7 @@ CREATE TABLE IF NOT EXISTS b2b_customers (
created_at DATETIME(6) NULL, created_at DATETIME(6) NULL,
updated_at DATETIME(6) NULL, updated_at DATETIME(6) NULL,
deleted_at DATETIME(6) NULL, deleted_at DATETIME(6) NULL,
is_no_vat TINYINT(1) NULL DEFAULT 0 is_no_vat TINYINT(1) NOT NULL DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE UNIQUE INDEX IF NOT EXISTS idx_customers_email CREATE UNIQUE INDEX IF NOT EXISTS idx_customers_email
@@ -162,6 +162,16 @@ CREATE TABLE IF NOT EXISTS b2b_favorites (
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4; ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
-- oems
CREATE TABLE IF NOT EXISTS b2b_oems (
user_id BIGINT UNSIGNED NOT NULL,
product_id INT UNSIGNED NOT NULL,
PRIMARY KEY (user_id, product_id),
CONSTRAINT fk_oems_customer FOREIGN KEY (user_id) REFERENCES b2b_customers(id) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT fk_oems_product FOREIGN KEY (product_id) REFERENCES ps_product(id_product) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
-- refresh_tokens -- refresh_tokens
CREATE TABLE IF NOT EXISTS b2b_refresh_tokens ( CREATE TABLE IF NOT EXISTS b2b_refresh_tokens (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
@@ -241,6 +251,11 @@ CREATE TABLE IF NOT EXISTS b2b_customer_orders (
country_id BIGINT UNSIGNED NOT NULL, country_id BIGINT UNSIGNED NOT NULL,
address_string TEXT NOT NULL, address_string TEXT NOT NULL,
status VARCHAR(50) NOT NULL, status VARCHAR(50) NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
base_price DECIMAL(10, 2) NOT NULL,
tax_incl DECIMAL(10, 2) NOT NULL,
tax_excl DECIMAL(10, 2) NOT NULL,
CONSTRAINT fk_customer_orders_customers FOREIGN KEY (user_id) REFERENCES b2b_customers(id) ON DELETE NO ACTION ON UPDATE CASCADE, CONSTRAINT fk_customer_orders_customers FOREIGN KEY (user_id) REFERENCES b2b_customers(id) ON DELETE NO ACTION ON UPDATE CASCADE,
CONSTRAINT fk_customer_orders_countries FOREIGN KEY (country_id) REFERENCES b2b_countries(id) ON DELETE NO ACTION ON UPDATE CASCADE CONSTRAINT fk_customer_orders_countries FOREIGN KEY (country_id) REFERENCES b2b_countries(id) ON DELETE NO ACTION ON UPDATE CASCADE
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4; ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;

View File

@@ -384,10 +384,19 @@ BEGIN
m.name AS manufacturer, m.name AS manufacturer,
cl.name AS category, cl.name AS category,
p.is_oem,
EXISTS( EXISTS(
SELECT 1 FROM b2b_favorites f SELECT 1 FROM b2b_favorites f
WHERE f.user_id = p_id_customer AND f.product_id = p_id_product WHERE f.user_id = p_id_customer AND f.product_id = p_id_product
) AS is_favorite ) AS is_favorite,
CASE
WHEN ps.date_add >= DATE_SUB(
NOW(),
INTERVAL COALESCE(CAST(ps_configuration.value AS SIGNED), 20) DAY
) AND ps.active = 1
THEN 1
ELSE 0
END AS is_new
@@ -405,6 +414,8 @@ BEGIN
AND cl.id_shop = p_id_shop AND cl.id_shop = p_id_shop
LEFT JOIN ps_manufacturer m LEFT JOIN ps_manufacturer m
ON m.id_manufacturer = p.id_manufacturer ON m.id_manufacturer = p.id_manufacturer
LEFT JOIN ps_configuration
ON ps_configuration.name = 'PS_NB_DAYS_NEW_PRODUCT'
WHERE p.id_product = p_id_product WHERE p.id_product = p_id_product
LIMIT 1; LIMIT 1;