Add callback and update user role
This commit is contained in:
parent
4d402e32c9
commit
04a89c5508
@ -15,6 +15,7 @@ type Context interface {
|
|||||||
IsSuperAdmin() bool
|
IsSuperAdmin() bool
|
||||||
IsCasheer() bool
|
IsCasheer() bool
|
||||||
GetPartnerID() *int64
|
GetPartnerID() *int64
|
||||||
|
GetSiteID() *int64
|
||||||
}
|
}
|
||||||
|
|
||||||
type MyContextImpl struct {
|
type MyContextImpl struct {
|
||||||
@ -24,6 +25,7 @@ type MyContextImpl struct {
|
|||||||
requestID string
|
requestID string
|
||||||
partnerID int64
|
partnerID int64
|
||||||
roleID int
|
roleID int
|
||||||
|
siteID int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MyContextImpl) RequestedBy() int64 {
|
func (m *MyContextImpl) RequestedBy() int64 {
|
||||||
@ -45,12 +47,20 @@ func (m *MyContextImpl) GetPartnerID() *int64 {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *MyContextImpl) GetSiteID() *int64 {
|
||||||
|
if m.siteID != 0 {
|
||||||
|
return &m.siteID
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func NewMyContext(parent context.Context, claims *entity.JWTAuthClaims) (*MyContextImpl, error) {
|
func NewMyContext(parent context.Context, claims *entity.JWTAuthClaims) (*MyContextImpl, error) {
|
||||||
return &MyContextImpl{
|
return &MyContextImpl{
|
||||||
Context: parent,
|
Context: parent,
|
||||||
requestedBy: claims.UserID,
|
requestedBy: claims.UserID,
|
||||||
partnerID: claims.PartnerID,
|
partnerID: claims.PartnerID,
|
||||||
roleID: claims.Role,
|
roleID: claims.Role,
|
||||||
|
siteID: claims.SiteID,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -25,6 +25,7 @@ type UserDB struct {
|
|||||||
RoleID int64 `gorm:"column:role_id" json:"role_id"`
|
RoleID int64 `gorm:"column:role_id" json:"role_id"`
|
||||||
RoleName string `gorm:"column:role_name" json:"role_name"`
|
RoleName string `gorm:"column:role_name" json:"role_name"`
|
||||||
PartnerID *int64 `gorm:"column:partner_id" json:"partner_id"`
|
PartnerID *int64 `gorm:"column:partner_id" json:"partner_id"`
|
||||||
|
SiteID *int64 `gorm:"column:site_id" json:"site_id"`
|
||||||
PartnerName string `gorm:"column:partner_name" json:"partner_name"`
|
PartnerName string `gorm:"column:partner_name" json:"partner_name"`
|
||||||
PartnerStatus string `gorm:"column:partner_status" json:"partner_status"`
|
PartnerStatus string `gorm:"column:partner_status" json:"partner_status"`
|
||||||
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
|
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
|
||||||
@ -50,6 +51,7 @@ func (u *UserDB) ToUser() *User {
|
|||||||
RoleName: u.RoleName,
|
RoleName: u.RoleName,
|
||||||
PartnerID: u.PartnerID,
|
PartnerID: u.PartnerID,
|
||||||
PartnerName: u.PartnerName,
|
PartnerName: u.PartnerName,
|
||||||
|
SiteID: u.SiteID,
|
||||||
}
|
}
|
||||||
|
|
||||||
return userEntity
|
return userEntity
|
||||||
@ -67,6 +69,7 @@ func (u *UserDB) ToUserRoleDB() *UserRoleDB {
|
|||||||
PartnerID: u.PartnerID,
|
PartnerID: u.PartnerID,
|
||||||
CreatedAt: u.CreatedAt,
|
CreatedAt: u.CreatedAt,
|
||||||
UpdatedAt: u.UpdatedAt,
|
UpdatedAt: u.UpdatedAt,
|
||||||
|
SiteID: u.SiteID,
|
||||||
}
|
}
|
||||||
|
|
||||||
return userRole
|
return userRole
|
||||||
|
|||||||
@ -8,6 +8,7 @@ type JWTAuthClaims struct {
|
|||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
Role int `json:"role"`
|
Role int `json:"role"`
|
||||||
PartnerID int64 `json:"partner_id"`
|
PartnerID int64 `json:"partner_id"`
|
||||||
|
SiteID int64 `json:"site_id"`
|
||||||
jwt.StandardClaims
|
jwt.StandardClaims
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -44,6 +44,7 @@ type OrderItem struct {
|
|||||||
UpdatedAt time.Time `gorm:"autoUpdateTime;column:updated_at"`
|
UpdatedAt time.Time `gorm:"autoUpdateTime;column:updated_at"`
|
||||||
CreatedBy int64 `gorm:"type:int;column:created_by"`
|
CreatedBy int64 `gorm:"type:int;column:created_by"`
|
||||||
UpdatedBy int64 `gorm:"type:int;column:updated_by"`
|
UpdatedBy int64 `gorm:"type:int;column:updated_by"`
|
||||||
|
Product *Product `gorm:"foreignKey:ItemID;references:ID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (OrderItem) TableName() string {
|
func (OrderItem) TableName() string {
|
||||||
@ -75,3 +76,8 @@ func (o *Order) SetExecutePaymentStatus() {
|
|||||||
}
|
}
|
||||||
o.Status = "PENDING"
|
o.Status = "PENDING"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CallbackRequest struct {
|
||||||
|
TransactionStatus string `json:"transaction_status"`
|
||||||
|
TransactionID string `json:"transaction_id"`
|
||||||
|
}
|
||||||
|
|||||||
@ -8,8 +8,8 @@ import (
|
|||||||
|
|
||||||
type Payment struct {
|
type Payment struct {
|
||||||
ID uuid.UUID `gorm:"type:uuid;default:uuid_generate_v4();primaryKey;column:id"`
|
ID uuid.UUID `gorm:"type:uuid;default:uuid_generate_v4();primaryKey;column:id"`
|
||||||
PartnerID string `gorm:"type:varchar;not null;column:partner_id"`
|
PartnerID int64 `gorm:"type:numeric;not null;column:partner_id"`
|
||||||
OrderID string `gorm:"type:varchar;not null;column:order_id"`
|
OrderID int64 `gorm:"type:numeric;not null;column:order_id"`
|
||||||
ReferenceID string `gorm:"type:varchar;not null;column:reference_id"`
|
ReferenceID string `gorm:"type:varchar;not null;column:reference_id"`
|
||||||
Channel string `gorm:"type:varchar;not null;column:channel"`
|
Channel string `gorm:"type:varchar;not null;column:channel"`
|
||||||
PaymentType string `gorm:"type:varchar;not null;column:payment_type"`
|
PaymentType string `gorm:"type:varchar;not null;column:payment_type"`
|
||||||
|
|||||||
@ -37,6 +37,11 @@ type ProductSearch struct {
|
|||||||
Offset int
|
Offset int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ProductPOS struct {
|
||||||
|
PartnerID int64
|
||||||
|
SiteID int64
|
||||||
|
}
|
||||||
|
|
||||||
type ProductList []*ProductDB
|
type ProductList []*ProductDB
|
||||||
|
|
||||||
type ProductDB struct {
|
type ProductDB struct {
|
||||||
|
|||||||
@ -21,6 +21,7 @@ type User struct {
|
|||||||
RoleID role.Role
|
RoleID role.Role
|
||||||
RoleName string
|
RoleName string
|
||||||
PartnerID *int64
|
PartnerID *int64
|
||||||
|
SiteID *int64
|
||||||
PartnerName string
|
PartnerName string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,6 +40,7 @@ type UserRoleDB struct {
|
|||||||
UserID int64 `gorm:"column:user_id"`
|
UserID int64 `gorm:"column:user_id"`
|
||||||
RoleID int64 `gorm:"column:role_id"`
|
RoleID int64 `gorm:"column:role_id"`
|
||||||
PartnerID *int64 `gorm:"column:partner_id"`
|
PartnerID *int64 `gorm:"column:partner_id"`
|
||||||
|
SiteID *int64 `gorm:"column:site_id"`
|
||||||
CreatedAt time.Time `gorm:"column:created_at"`
|
CreatedAt time.Time `gorm:"column:created_at"`
|
||||||
UpdatedAt time.Time `gorm:"column:updated_at"`
|
UpdatedAt time.Time `gorm:"column:updated_at"`
|
||||||
}
|
}
|
||||||
@ -66,6 +68,7 @@ func (u *User) ToUserDB(createdBy int64) (*UserDB, error) {
|
|||||||
PartnerID: u.PartnerID,
|
PartnerID: u.PartnerID,
|
||||||
Status: userstatus.Active,
|
Status: userstatus.Active,
|
||||||
CreatedBy: createdBy,
|
CreatedBy: createdBy,
|
||||||
|
SiteID: u.SiteID,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
71
internal/handlers/http/midtrans/order.go
Normal file
71
internal/handlers/http/midtrans/order.go
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package mdtrns
|
||||||
|
|
||||||
|
import (
|
||||||
|
"furtuna-be/internal/handlers/request"
|
||||||
|
"furtuna-be/internal/handlers/response"
|
||||||
|
"furtuna-be/internal/services"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Handler struct {
|
||||||
|
service services.Order
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Handler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) {
|
||||||
|
route := group.Group("/midtrans")
|
||||||
|
|
||||||
|
route.POST("/callback", h.Callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHandler(service services.Order) *Handler {
|
||||||
|
return &Handler{
|
||||||
|
service: service,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Handler) Callback(c *gin.Context) {
|
||||||
|
var callbackData request.MidtransCallbackRequest
|
||||||
|
if err := c.ShouldBindJSON(&callbackData); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
validStatuses := []string{"settlement", "expire", "deny", "cancel", "capture", "failure"}
|
||||||
|
|
||||||
|
isValidStatus := false
|
||||||
|
for _, status := range validStatuses {
|
||||||
|
if callbackData.TransactionStatus == status {
|
||||||
|
isValidStatus = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !isValidStatus {
|
||||||
|
c.JSON(http.StatusOK, response.BaseResponse{
|
||||||
|
Success: true,
|
||||||
|
Status: http.StatusOK,
|
||||||
|
Message: "",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err := h.service.ProcessCallback(c, callbackData.ToEntity())
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusUnauthorized, response.BaseResponse{
|
||||||
|
Success: false,
|
||||||
|
Status: http.StatusBadRequest,
|
||||||
|
Message: err.Error(),
|
||||||
|
Data: nil,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, response.BaseResponse{
|
||||||
|
Success: true,
|
||||||
|
Status: http.StatusOK,
|
||||||
|
Message: "order",
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
@ -108,6 +108,7 @@ func MapOrderToCreateOrderResponse(orderResponse *entity.OrderResponse) response
|
|||||||
ItemID: item.ItemID,
|
ItemID: item.ItemID,
|
||||||
Quantity: item.Quantity,
|
Quantity: item.Quantity,
|
||||||
Price: item.Price,
|
Price: item.Price,
|
||||||
|
Name: item.Product.Name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,6 +134,7 @@ func MapOrderToExecuteOrderResponse(orderResponse *entity.ExecuteOrderResponse)
|
|||||||
ItemID: item.ItemID,
|
ItemID: item.ItemID,
|
||||||
Quantity: item.Quantity,
|
Quantity: item.Quantity,
|
||||||
Price: item.Price,
|
Price: item.Price,
|
||||||
|
Name: item.Product.Name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,6 +22,7 @@ func (h *Handler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) {
|
|||||||
route := group.Group("/product")
|
route := group.Group("/product")
|
||||||
|
|
||||||
route.POST("/", jwt, h.Create)
|
route.POST("/", jwt, h.Create)
|
||||||
|
route.GET("/pos", jwt, h.GetPOSProduct)
|
||||||
route.GET("/list", jwt, h.GetAll)
|
route.GET("/list", jwt, h.GetAll)
|
||||||
route.PUT("/:id", jwt, h.Update)
|
route.PUT("/:id", jwt, h.Update)
|
||||||
route.GET("/:id", jwt, h.GetByID)
|
route.GET("/:id", jwt, h.GetByID)
|
||||||
@ -157,6 +158,37 @@ func (h *Handler) GetAll(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *Handler) GetPOSProduct(c *gin.Context) {
|
||||||
|
ctx := request.GetMyContext(c)
|
||||||
|
|
||||||
|
var req request.ProductParam
|
||||||
|
if err := c.ShouldBindQuery(&req); err != nil {
|
||||||
|
response.ErrorWrapper(c, errors.ErrorBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ctx.IsCasheer() {
|
||||||
|
response.ErrorWrapper(c, errors.ErrorBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
products, err := h.service.GetProductPOS(c.Request.Context(), entity.ProductPOS{
|
||||||
|
PartnerID: *ctx.GetPartnerID(),
|
||||||
|
SiteID: *ctx.GetSiteID(),
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
response.ErrorWrapper(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, response.BaseResponse{
|
||||||
|
Success: true,
|
||||||
|
Status: http.StatusOK,
|
||||||
|
Data: h.toProductResponseList(products, int64(len(products)), req),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Delete handles the deletion of a product by ID.
|
// Delete handles the deletion of a product by ID.
|
||||||
// @Summary Delete a product by ID
|
// @Summary Delete a product by ID
|
||||||
// @Description Delete a product based on the provided ID.
|
// @Description Delete a product based on the provided ID.
|
||||||
@ -240,14 +272,18 @@ func (h *Handler) GetByID(c *gin.Context) {
|
|||||||
|
|
||||||
func (h *Handler) toProductResponse(resp *entity.Product) response.Product {
|
func (h *Handler) toProductResponse(resp *entity.Product) response.Product {
|
||||||
return response.Product{
|
return response.Product{
|
||||||
ID: resp.ID,
|
ID: resp.ID,
|
||||||
Name: resp.Name,
|
Name: resp.Name,
|
||||||
Type: resp.Type,
|
Type: resp.Type,
|
||||||
Price: resp.Price,
|
Price: resp.Price,
|
||||||
Status: resp.Status,
|
Status: resp.Status,
|
||||||
Description: resp.Description,
|
Description: resp.Description,
|
||||||
CreatedAt: resp.CreatedAt.Format(time.RFC3339),
|
CreatedAt: resp.CreatedAt.Format(time.RFC3339),
|
||||||
UpdatedAt: resp.CreatedAt.Format(time.RFC3339),
|
UpdatedAt: resp.CreatedAt.Format(time.RFC3339),
|
||||||
|
PartnerID: resp.PartnerID,
|
||||||
|
SiteID: resp.SiteID,
|
||||||
|
IsSeasonTicket: resp.IsSeasonTicket,
|
||||||
|
IsWeekendTicket: resp.IsWeekendTicket,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package user
|
package user
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"furtuna-be/internal/constants/role"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
@ -64,6 +65,11 @@ func (h *Handler) Create(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if req.RoleID == role.Casheer && req.SiteID == nil {
|
||||||
|
response.ErrorWrapper(c, errors.NewServiceException("site id is required for cashier"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
res, err := h.service.Create(ctx, req.ToEntity())
|
res, err := h.service.Create(ctx, req.ToEntity())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
response.ErrorWrapper(c, err)
|
response.ErrorWrapper(c, err)
|
||||||
|
|||||||
39
internal/handlers/request/midtrans.go
Normal file
39
internal/handlers/request/midtrans.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package request
|
||||||
|
|
||||||
|
import "furtuna-be/internal/entity"
|
||||||
|
|
||||||
|
type MidtransCallbackRequest struct {
|
||||||
|
VANumbers []VANumber `json:"va_numbers"`
|
||||||
|
TransactionTime string `json:"transaction_time"`
|
||||||
|
TransactionStatus string `json:"transaction_status"`
|
||||||
|
TransactionID string `json:"transaction_id"`
|
||||||
|
StatusMessage string `json:"status_message"`
|
||||||
|
StatusCode string `json:"status_code"`
|
||||||
|
SignatureKey string `json:"signature_key"`
|
||||||
|
SettlementTime string `json:"settlement_time"`
|
||||||
|
PaymentType string `json:"payment_type"`
|
||||||
|
OrderID string `json:"order_id"`
|
||||||
|
MerchantID string `json:"merchant_id"`
|
||||||
|
GrossAmount string `json:"gross_amount"`
|
||||||
|
FraudStatus string `json:"fraud_status"`
|
||||||
|
ExpiryTime string `json:"expiry_time"`
|
||||||
|
Currency string `json:"currency"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type VANumber struct {
|
||||||
|
VANumber string `json:"va_number"`
|
||||||
|
Bank string `json:"bank"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MidtransCallbackBank struct {
|
||||||
|
Bank string `json:"bank"`
|
||||||
|
VaNumber string `json:"va_number"`
|
||||||
|
BillerCode string `json:"biller_code"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MidtransCallbackRequest) ToEntity() *entity.CallbackRequest {
|
||||||
|
return &entity.CallbackRequest{
|
||||||
|
TransactionID: m.OrderID,
|
||||||
|
TransactionStatus: m.TransactionStatus,
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -8,14 +8,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
Name string `json:"name" validate:"required"`
|
Name string `json:"name" validate:"required"`
|
||||||
Email string `json:"email" validate:"required"`
|
Email string `json:"email" validate:"required"`
|
||||||
Password string `json:"password" validate:"required"`
|
Password string `json:"password" validate:"required"`
|
||||||
PartnerID *int64 `json:"partner_id"`
|
PartnerID *int64 `json:"partner_id"`
|
||||||
RoleID int64 `json:"role_id" validate:"required"`
|
SiteID *int64 `json:"site_id"`
|
||||||
NIK string `json:"nik"`
|
RoleID role.Role `json:"role_id" validate:"required"`
|
||||||
UserType string `json:"user_type"`
|
NIK string `json:"nik"`
|
||||||
PhoneNumber string `json:"phone_number"`
|
UserType string `json:"user_type"`
|
||||||
|
PhoneNumber string `json:"phone_number"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *User) Validate() error {
|
func (e *User) Validate() error {
|
||||||
@ -34,6 +35,7 @@ func (u *User) ToEntity() *entity.User {
|
|||||||
Password: u.Password,
|
Password: u.Password,
|
||||||
RoleID: role.Role(u.RoleID),
|
RoleID: role.Role(u.RoleID),
|
||||||
PartnerID: u.PartnerID,
|
PartnerID: u.PartnerID,
|
||||||
|
SiteID: u.SiteID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -82,4 +82,5 @@ type CreateOrderItemResponse struct {
|
|||||||
ItemID int64 `json:"item_id"`
|
ItemID int64 `json:"item_id"`
|
||||||
Quantity int64 `json:"quantity"`
|
Quantity int64 `json:"quantity"`
|
||||||
Price float64 `json:"price"`
|
Price float64 `json:"price"`
|
||||||
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,7 +26,7 @@ func (r *AuthRepository) CheckExistsUserAccount(ctx context.Context, email strin
|
|||||||
|
|
||||||
err := r.db.
|
err := r.db.
|
||||||
Table("users").
|
Table("users").
|
||||||
Select("users.*, user_roles.role_id, user_roles.partner_id, roles.role_name, partners.name as partner_name, partners.status as partner_status").
|
Select("users.*, user_roles.role_id, user_roles.partner_id, user_roles.site_id, roles.role_name, partners.name as partner_name, partners.status as partner_status").
|
||||||
Where("users.email = ?", email).
|
Where("users.email = ?", email).
|
||||||
Joins("left join user_roles on users.id = user_roles.user_id").
|
Joins("left join user_roles on users.id = user_roles.user_id").
|
||||||
Joins("left join roles on user_roles.role_id = roles.role_id").
|
Joins("left join roles on user_roles.role_id = roles.role_id").
|
||||||
|
|||||||
@ -51,6 +51,11 @@ func (c *CryptoImpl) GenerateJWT(user *entity.User) (string, error) {
|
|||||||
partnerID = *user.PartnerID
|
partnerID = *user.PartnerID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
siteID := int64(0)
|
||||||
|
if user.SiteID != nil {
|
||||||
|
siteID = *user.SiteID
|
||||||
|
}
|
||||||
|
|
||||||
claims := &entity.JWTAuthClaims{
|
claims := &entity.JWTAuthClaims{
|
||||||
StandardClaims: jwt.StandardClaims{
|
StandardClaims: jwt.StandardClaims{
|
||||||
Subject: strconv.FormatInt(user.ID, 10),
|
Subject: strconv.FormatInt(user.ID, 10),
|
||||||
@ -63,6 +68,7 @@ func (c *CryptoImpl) GenerateJWT(user *entity.User) (string, error) {
|
|||||||
Email: user.Email,
|
Email: user.Email,
|
||||||
Role: int(user.RoleID),
|
Role: int(user.RoleID),
|
||||||
PartnerID: partnerID,
|
PartnerID: partnerID,
|
||||||
|
SiteID: siteID,
|
||||||
}
|
}
|
||||||
|
|
||||||
token, err := jwt.
|
token, err := jwt.
|
||||||
|
|||||||
@ -24,7 +24,7 @@ func (r *OrderRepository) Create(ctx context.Context, order *entity.Order) (*ent
|
|||||||
logger.ContextLogger(ctx).Error("error when creating order", zap.Error(err))
|
logger.ContextLogger(ctx).Error("error when creating order", zap.Error(err))
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return order, nil
|
return r.FindByID(ctx, order.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *OrderRepository) UpdateStatus(ctx context.Context, orderID int64, status string) (*entity.Order, error) {
|
func (r *OrderRepository) UpdateStatus(ctx context.Context, orderID int64, status string) (*entity.Order, error) {
|
||||||
@ -43,13 +43,36 @@ func (r *OrderRepository) UpdateStatus(ctx context.Context, orderID int64, statu
|
|||||||
|
|
||||||
func (r *OrderRepository) FindByID(ctx context.Context, id int64) (*entity.Order, error) {
|
func (r *OrderRepository) FindByID(ctx context.Context, id int64) (*entity.Order, error) {
|
||||||
var order entity.Order
|
var order entity.Order
|
||||||
if err := r.db.WithContext(ctx).Preload("OrderItems").First(&order, id).Error; err != nil {
|
|
||||||
|
err := r.db.WithContext(ctx).Preload("OrderItems", func(db *gorm.DB) *gorm.DB {
|
||||||
|
return db.Preload("Product")
|
||||||
|
}).First(&order, id).Error
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
logger.ContextLogger(ctx).Error("error when finding order by ID", zap.Error(err))
|
logger.ContextLogger(ctx).Error("error when finding order by ID", zap.Error(err))
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &order, nil
|
return &order, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *OrderRepository) SetOrderStatus(ctx context.Context, db *gorm.DB, orderID int64, status string) error {
|
||||||
|
var order entity.Order
|
||||||
|
if err := db.WithContext(ctx).Preload("OrderItems").First(&order, orderID).Error; err != nil {
|
||||||
|
logger.ContextLogger(ctx).Error("error when finding order by ID", zap.Error(err))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
order.Status = status
|
||||||
|
|
||||||
|
if err := db.WithContext(ctx).Save(&order).Error; err != nil {
|
||||||
|
logger.ContextLogger(ctx).Error("error when updating order status", zap.Error(err))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *OrderRepository) Update(ctx context.Context, order *entity.Order) (*entity.Order, error) {
|
func (r *OrderRepository) Update(ctx context.Context, order *entity.Order) (*entity.Order, error) {
|
||||||
if err := r.db.WithContext(ctx).Save(order).Error; err != nil {
|
if err := r.db.WithContext(ctx).Save(order).Error; err != nil {
|
||||||
logger.ContextLogger(ctx).Error("error when updating order", zap.Error(err))
|
logger.ContextLogger(ctx).Error("error when updating order", zap.Error(err))
|
||||||
|
|||||||
@ -38,6 +38,14 @@ func (r *PaymentRepository) Update(ctx context.Context, payment *entity.Payment)
|
|||||||
return payment, nil
|
return payment, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *PaymentRepository) UpdateWithTx(ctx context.Context, tx *gorm.DB, payment *entity.Payment) (*entity.Payment, error) {
|
||||||
|
if err := tx.WithContext(ctx).Save(payment).Error; err != nil {
|
||||||
|
logger.ContextLogger(ctx).Error("error when updating payment", zap.Error(err))
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return payment, nil
|
||||||
|
}
|
||||||
|
|
||||||
// FindByID retrieves a payment record by its ID
|
// FindByID retrieves a payment record by its ID
|
||||||
func (r *PaymentRepository) FindByID(ctx context.Context, id uuid.UUID) (*entity.Payment, error) {
|
func (r *PaymentRepository) FindByID(ctx context.Context, id uuid.UUID) (*entity.Payment, error) {
|
||||||
payment := new(entity.Payment)
|
payment := new(entity.Payment)
|
||||||
@ -62,9 +70,9 @@ func (r *PaymentRepository) FindByOrderAndPartnerID(ctx context.Context, orderID
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FindByReferenceID retrieves a payment record by its reference ID
|
// FindByReferenceID retrieves a payment record by its reference ID
|
||||||
func (r *PaymentRepository) FindByReferenceID(ctx context.Context, referenceID string) (*entity.Payment, error) {
|
func (r *PaymentRepository) FindByReferenceID(ctx context.Context, db *gorm.DB, referenceID string) (*entity.Payment, error) {
|
||||||
payment := new(entity.Payment)
|
payment := new(entity.Payment)
|
||||||
if err := r.db.WithContext(ctx).Where("reference_id = ?", referenceID).First(payment).Error; err != nil {
|
if err := db.WithContext(ctx).Where("reference_id = ?", referenceID).First(payment).Error; err != nil {
|
||||||
logger.ContextLogger(ctx).Error("error when finding payment by reference ID", zap.Error(err))
|
logger.ContextLogger(ctx).Error("error when finding payment by reference ID", zap.Error(err))
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,6 +45,16 @@ func (b *ProductRepository) GetProductByID(ctx context.Context, id int64) (*enti
|
|||||||
return product, nil
|
return product, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *ProductRepository) GetProductByPartnerIDAndSiteID(ctx context.Context, partnerID, siteID int64) (entity.ProductList, error) {
|
||||||
|
var products []*entity.ProductDB
|
||||||
|
if err := b.db.WithContext(ctx).Where("partner_id = ? AND site_id = ?", partnerID, siteID).Find(&products).Error; err != nil {
|
||||||
|
logger.ContextLogger(ctx).Error("error when finding product by partner ID and site id", zap.Error(err))
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return products, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (b *ProductRepository) GetAllProducts(ctx context.Context, req entity.ProductSearch) (entity.ProductList, int, error) {
|
func (b *ProductRepository) GetAllProducts(ctx context.Context, req entity.ProductSearch) (entity.ProductList, int, error) {
|
||||||
var products []*entity.ProductDB
|
var products []*entity.ProductDB
|
||||||
var total int64
|
var total int64
|
||||||
|
|||||||
@ -112,6 +112,7 @@ type Product interface {
|
|||||||
CreateProduct(ctx context.Context, product *entity.ProductDB) (*entity.ProductDB, error)
|
CreateProduct(ctx context.Context, product *entity.ProductDB) (*entity.ProductDB, error)
|
||||||
UpdateProduct(ctx context.Context, product *entity.ProductDB) (*entity.ProductDB, error)
|
UpdateProduct(ctx context.Context, product *entity.ProductDB) (*entity.ProductDB, error)
|
||||||
GetProductByID(ctx context.Context, id int64) (*entity.ProductDB, error)
|
GetProductByID(ctx context.Context, id int64) (*entity.ProductDB, error)
|
||||||
|
GetProductByPartnerIDAndSiteID(ctx context.Context, partnerID, siteID int64) (entity.ProductList, error)
|
||||||
GetAllProducts(ctx context.Context, req entity.ProductSearch) (entity.ProductList, int, error)
|
GetAllProducts(ctx context.Context, req entity.ProductSearch) (entity.ProductList, int, error)
|
||||||
DeleteProduct(ctx context.Context, id int64) error
|
DeleteProduct(ctx context.Context, id int64) error
|
||||||
GetProductsByIDs(ctx context.Context, ids []int64, partnerID int64) ([]*entity.ProductDB, error)
|
GetProductsByIDs(ctx context.Context, ids []int64, partnerID int64) ([]*entity.ProductDB, error)
|
||||||
@ -121,6 +122,7 @@ type Order interface {
|
|||||||
Create(ctx context.Context, order *entity.Order) (*entity.Order, error)
|
Create(ctx context.Context, order *entity.Order) (*entity.Order, error)
|
||||||
FindByID(ctx context.Context, id int64) (*entity.Order, error)
|
FindByID(ctx context.Context, id int64) (*entity.Order, error)
|
||||||
Update(ctx context.Context, order *entity.Order) (*entity.Order, error)
|
Update(ctx context.Context, order *entity.Order) (*entity.Order, error)
|
||||||
|
SetOrderStatus(ctx context.Context, db *gorm.DB, orderID int64, status string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type OSSRepository interface {
|
type OSSRepository interface {
|
||||||
@ -154,6 +156,8 @@ type TransactionManager interface {
|
|||||||
|
|
||||||
type WalletRepository interface {
|
type WalletRepository interface {
|
||||||
Create(ctx context.Context, tx *gorm.DB, wallet *entity.Wallet) (*entity.Wallet, error)
|
Create(ctx context.Context, tx *gorm.DB, wallet *entity.Wallet) (*entity.Wallet, error)
|
||||||
|
Update(ctx context.Context, db *gorm.DB, wallet *entity.Wallet) (*entity.Wallet, error)
|
||||||
|
GetByPartnerID(ctx context.Context, db *gorm.DB, partnerID int64) (*entity.Wallet, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Midtrans interface {
|
type Midtrans interface {
|
||||||
@ -163,5 +167,7 @@ type Midtrans interface {
|
|||||||
type Payment interface {
|
type Payment interface {
|
||||||
Create(ctx context.Context, payment *entity.Payment) (*entity.Payment, error)
|
Create(ctx context.Context, payment *entity.Payment) (*entity.Payment, error)
|
||||||
Update(ctx context.Context, payment *entity.Payment) (*entity.Payment, error)
|
Update(ctx context.Context, payment *entity.Payment) (*entity.Payment, error)
|
||||||
|
UpdateWithTx(ctx context.Context, tx *gorm.DB, payment *entity.Payment) (*entity.Payment, error)
|
||||||
FindByOrderAndPartnerID(ctx context.Context, orderID, partnerID int64) (*entity.Payment, error)
|
FindByOrderAndPartnerID(ctx context.Context, orderID, partnerID int64) (*entity.Payment, error)
|
||||||
|
FindByReferenceID(ctx context.Context, db *gorm.DB, referenceID string) (*entity.Payment, error)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,14 +28,23 @@ func (r *WalletRepository) Create(ctx context.Context, tx *gorm.DB, wallet *enti
|
|||||||
return wallet, nil
|
return wallet, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *WalletRepository) Update(ctx context.Context, wallet *entity.Wallet) (*entity.Wallet, error) {
|
func (r *WalletRepository) Update(ctx context.Context, db *gorm.DB, wallet *entity.Wallet) (*entity.Wallet, error) {
|
||||||
if err := r.db.Save(wallet).Error; err != nil {
|
if err := db.Save(wallet).Error; err != nil {
|
||||||
logger.ContextLogger(ctx).Error("error when updating wallet", zap.Error(err))
|
logger.ContextLogger(ctx).Error("error when updating wallet", zap.Error(err))
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return wallet, nil
|
return wallet, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *WalletRepository) GetByPartnerID(ctx context.Context, db *gorm.DB, partnerID int64) (*entity.Wallet, error) {
|
||||||
|
wallet := new(entity.Wallet)
|
||||||
|
if err := db.WithContext(ctx).Where("partner_id = ?", partnerID).First(wallet).Error; err != nil {
|
||||||
|
logger.ContextLogger(ctx).Error("error when finding wallet by partner ID", zap.Error(err))
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return wallet, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *WalletRepository) GetByID(ctx context.Context, id int64) (*entity.Wallet, error) {
|
func (r *WalletRepository) GetByID(ctx context.Context, id int64) (*entity.Wallet, error) {
|
||||||
wallet := new(entity.Wallet)
|
wallet := new(entity.Wallet)
|
||||||
if err := r.db.First(wallet, id).Error; err != nil {
|
if err := r.db.First(wallet, id).Error; err != nil {
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package routes
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"furtuna-be/internal/handlers/http/branch"
|
"furtuna-be/internal/handlers/http/branch"
|
||||||
|
mdtrns "furtuna-be/internal/handlers/http/midtrans"
|
||||||
"furtuna-be/internal/handlers/http/order"
|
"furtuna-be/internal/handlers/http/order"
|
||||||
"furtuna-be/internal/handlers/http/oss"
|
"furtuna-be/internal/handlers/http/oss"
|
||||||
"furtuna-be/internal/handlers/http/partner"
|
"furtuna-be/internal/handlers/http/partner"
|
||||||
@ -54,6 +55,7 @@ func RegisterPrivateRoutes(app *app.Server, serviceManager *services.ServiceMana
|
|||||||
oss.NewOssHandler(serviceManager.OSSSvc),
|
oss.NewOssHandler(serviceManager.OSSSvc),
|
||||||
partner.NewHandler(serviceManager.PartnerSvc),
|
partner.NewHandler(serviceManager.PartnerSvc),
|
||||||
site.NewHandler(serviceManager.SiteSvc),
|
site.NewHandler(serviceManager.SiteSvc),
|
||||||
|
mdtrns.NewHandler(serviceManager.OrderSvc),
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, handler := range serverRoutes {
|
for _, handler := range serverRoutes {
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
package order
|
package order
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"furtuna-be/internal/common/logger"
|
"furtuna-be/internal/common/logger"
|
||||||
order2 "furtuna-be/internal/constants/order"
|
order2 "furtuna-be/internal/constants/order"
|
||||||
"furtuna-be/internal/entity"
|
"furtuna-be/internal/entity"
|
||||||
@ -16,21 +18,29 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type OrderService struct {
|
type OrderService struct {
|
||||||
repo repository.Order
|
repo repository.Order
|
||||||
crypt repository.Crypto
|
crypt repository.Crypto
|
||||||
product repository.Product
|
product repository.Product
|
||||||
midtrans repository.Midtrans
|
midtrans repository.Midtrans
|
||||||
payment repository.Payment
|
payment repository.Payment
|
||||||
|
txmanager repository.TransactionManager
|
||||||
|
wallet repository.WalletRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOrderService(repo repository.Order, product repository.Product, crypt repository.Crypto,
|
func NewOrderService(
|
||||||
midtrans repository.Midtrans, payment repository.Payment) *OrderService {
|
repo repository.Order,
|
||||||
|
product repository.Product, crypt repository.Crypto,
|
||||||
|
midtrans repository.Midtrans, payment repository.Payment,
|
||||||
|
txmanager repository.TransactionManager,
|
||||||
|
wallet repository.WalletRepository) *OrderService {
|
||||||
return &OrderService{
|
return &OrderService{
|
||||||
repo: repo,
|
repo: repo,
|
||||||
product: product,
|
product: product,
|
||||||
crypt: crypt,
|
crypt: crypt,
|
||||||
midtrans: midtrans,
|
midtrans: midtrans,
|
||||||
payment: payment,
|
payment: payment,
|
||||||
|
txmanager: txmanager,
|
||||||
|
wallet: wallet,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,6 +88,7 @@ func (s *OrderService) CreateOrder(ctx context.Context, req *entity.OrderRequest
|
|||||||
Price: productMap[item.ProductID].Price,
|
Price: productMap[item.ProductID].Price,
|
||||||
Quantity: item.Quantity,
|
Quantity: item.Quantity,
|
||||||
CreatedBy: req.CreatedBy,
|
CreatedBy: req.CreatedBy,
|
||||||
|
Product: productMap[item.ProductID].ToProduct(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +127,6 @@ func (s *OrderService) Execute(ctx context.Context, req *entity.OrderExecuteRequ
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for existing payment to handle idempotency
|
|
||||||
payment, err := s.payment.FindByOrderAndPartnerID(ctx, orderID, partnerID)
|
payment, err := s.payment.FindByOrderAndPartnerID(ctx, orderID, partnerID)
|
||||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
logger.ContextLogger(ctx).Error("error getting payment data from db", zap.Error(err))
|
logger.ContextLogger(ctx).Error("error getting payment data from db", zap.Error(err))
|
||||||
@ -199,13 +209,13 @@ func (s *OrderService) processNonCashPayment(ctx context.Context, order *entity.
|
|||||||
}
|
}
|
||||||
|
|
||||||
payment := &entity.Payment{
|
payment := &entity.Payment{
|
||||||
PartnerID: strconv.FormatInt(partnerID, 10),
|
PartnerID: partnerID,
|
||||||
OrderID: strconv.FormatInt(order.ID, 10),
|
OrderID: order.ID,
|
||||||
ReferenceID: paymentRequest.PaymentReferenceID,
|
ReferenceID: paymentRequest.PaymentReferenceID,
|
||||||
Channel: "xendit",
|
Channel: "XENDIT",
|
||||||
PaymentType: order.PaymentType,
|
PaymentType: order.PaymentType,
|
||||||
Amount: order.Amount,
|
Amount: order.Amount,
|
||||||
State: "pending",
|
State: "PENDING",
|
||||||
CreatedAt: time.Now(),
|
CreatedAt: time.Now(),
|
||||||
UpdatedAt: time.Now(),
|
UpdatedAt: time.Now(),
|
||||||
RequestMetadata: requestMetadata,
|
RequestMetadata: requestMetadata,
|
||||||
@ -219,3 +229,70 @@ func (s *OrderService) processNonCashPayment(ctx context.Context, order *entity.
|
|||||||
|
|
||||||
return paymentResponse, nil
|
return paymentResponse, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *OrderService) ProcessCallback(ctx context.Context, req *entity.CallbackRequest) error {
|
||||||
|
tx, err := s.txmanager.Begin(ctx, &sql.TxOptions{Isolation: sql.LevelSerializable})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to begin transaction: %w", err)
|
||||||
|
}
|
||||||
|
defer tx.Rollback()
|
||||||
|
|
||||||
|
err = s.processPayment(ctx, tx, req)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to process payment: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tx.Commit().Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *OrderService) processPayment(ctx context.Context, tx *gorm.DB, req *entity.CallbackRequest) error {
|
||||||
|
existingPayment, err := s.payment.FindByReferenceID(ctx, tx, req.TransactionID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to retrieve payment: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
existingPayment.State = updatePaymentState(req.TransactionStatus)
|
||||||
|
_, err = s.payment.UpdateWithTx(ctx, tx, existingPayment)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to update payment: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.updateOrderStatus(ctx, tx, existingPayment.State, existingPayment.OrderID); err != nil {
|
||||||
|
return fmt.Errorf("failed to update order status: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if existingPayment.State == "PAID" {
|
||||||
|
if err := s.updateWalletBalance(ctx, tx, existingPayment.PartnerID, existingPayment.Amount); err != nil {
|
||||||
|
return fmt.Errorf("failed to update wallet balance: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func updatePaymentState(status string) string {
|
||||||
|
switch status {
|
||||||
|
case "settlement", "capture":
|
||||||
|
return "PAID"
|
||||||
|
case "expire", "deny", "cancel", "failure":
|
||||||
|
return "EXPIRED"
|
||||||
|
default:
|
||||||
|
return status
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *OrderService) updateOrderStatus(ctx context.Context, tx *gorm.DB, status string, orderID int64) error {
|
||||||
|
if status != "PENDING" {
|
||||||
|
return s.repo.SetOrderStatus(ctx, tx, orderID, status)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *OrderService) updateWalletBalance(ctx context.Context, tx *gorm.DB, partnerID int64, amount float64) error {
|
||||||
|
wallet, err := s.wallet.GetByPartnerID(ctx, tx, partnerID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get wallet: %w", err)
|
||||||
|
}
|
||||||
|
wallet.Balance += amount
|
||||||
|
_, err = s.wallet.Update(ctx, tx, wallet)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|||||||
@ -70,6 +70,16 @@ func (s *ProductService) GetAll(ctx context.Context, search entity.ProductSearch
|
|||||||
return products.ToProductList(), total, nil
|
return products.ToProductList(), total, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *ProductService) GetProductPOS(ctx context.Context, search entity.ProductPOS) ([]*entity.Product, error) {
|
||||||
|
products, err := s.repo.GetProductByPartnerIDAndSiteID(ctx, search.PartnerID, search.SiteID)
|
||||||
|
if err != nil {
|
||||||
|
logger.ContextLogger(ctx).Error("error when get all products", zap.Error(err))
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return products.ToProductList(), nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *ProductService) Delete(ctx mycontext.Context, id int64) error {
|
func (s *ProductService) Delete(ctx mycontext.Context, id int64) error {
|
||||||
productDB, err := s.repo.GetProductByID(ctx, id)
|
productDB, err := s.repo.GetProductByID(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -41,8 +41,9 @@ func NewServiceManagerImpl(cfg *config.Config, repo *repository.RepoManagerImpl)
|
|||||||
BranchSvc: branch.NewBranchService(repo.Branch),
|
BranchSvc: branch.NewBranchService(repo.Branch),
|
||||||
StudioSvc: studio.NewStudioService(repo.Studio),
|
StudioSvc: studio.NewStudioService(repo.Studio),
|
||||||
ProductSvc: product.NewProductService(repo.Product),
|
ProductSvc: product.NewProductService(repo.Product),
|
||||||
OrderSvc: order.NewOrderService(repo.Order, repo.Product, repo.Crypto, repo.Midtrans, repo.Payment),
|
OrderSvc: order.NewOrderService(repo.Order, repo.Product,
|
||||||
OSSSvc: oss.NewOSSService(repo.OSS),
|
repo.Crypto, repo.Midtrans, repo.Payment, repo.Trx, repo.Wallet),
|
||||||
|
OSSSvc: oss.NewOSSService(repo.OSS),
|
||||||
PartnerSvc: partner.NewPartnerService(
|
PartnerSvc: partner.NewPartnerService(
|
||||||
repo.Partner, users.NewUserService(repo.User, repo.Branch), repo.Trx, repo.Wallet),
|
repo.Partner, users.NewUserService(repo.User, repo.Branch), repo.Trx, repo.Wallet),
|
||||||
SiteSvc: site.NewSiteService(repo.Site),
|
SiteSvc: site.NewSiteService(repo.Site),
|
||||||
@ -90,12 +91,14 @@ type Product interface {
|
|||||||
Update(ctx mycontext.Context, id int64, productReq *entity.Product) (*entity.Product, error)
|
Update(ctx mycontext.Context, id int64, productReq *entity.Product) (*entity.Product, error)
|
||||||
GetByID(ctx context.Context, id int64) (*entity.Product, error)
|
GetByID(ctx context.Context, id int64) (*entity.Product, error)
|
||||||
GetAll(ctx context.Context, search entity.ProductSearch) ([]*entity.Product, int, error)
|
GetAll(ctx context.Context, search entity.ProductSearch) ([]*entity.Product, int, error)
|
||||||
|
GetProductPOS(ctx context.Context, search entity.ProductPOS) ([]*entity.Product, error)
|
||||||
Delete(ctx mycontext.Context, id int64) error
|
Delete(ctx mycontext.Context, id int64) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type Order interface {
|
type Order interface {
|
||||||
CreateOrder(ctx context.Context, req *entity.OrderRequest) (*entity.OrderResponse, error)
|
CreateOrder(ctx context.Context, req *entity.OrderRequest) (*entity.OrderResponse, error)
|
||||||
Execute(ctx context.Context, req *entity.OrderExecuteRequest) (*entity.ExecuteOrderResponse, error)
|
Execute(ctx context.Context, req *entity.OrderExecuteRequest) (*entity.ExecuteOrderResponse, error)
|
||||||
|
ProcessCallback(ctx context.Context, req *entity.CallbackRequest) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type OSSService interface {
|
type OSSService interface {
|
||||||
|
|||||||
@ -9,7 +9,7 @@ metadata:
|
|||||||
nginx.ingress.kubernetes.io/ingress-class: "nginx" # Add this line
|
nginx.ingress.kubernetes.io/ingress-class: "nginx" # Add this line
|
||||||
spec:
|
spec:
|
||||||
rules:
|
rules:
|
||||||
- host: "furtuna-be.app-dev.altru.id"
|
- host: "furtuna-backend.app-dev.altru.id"
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- pathType: Prefix
|
- pathType: Prefix
|
||||||
@ -21,5 +21,5 @@ spec:
|
|||||||
number: 3300
|
number: 3300
|
||||||
tls:
|
tls:
|
||||||
- hosts:
|
- hosts:
|
||||||
- "furtuna-be.app-dev.altru.id"
|
- "furtuna-backend.app-dev.altru.id"
|
||||||
secretName: furtuna-be-app-dev-biz-id-tls
|
secretName: furtuna-backend-app-dev-biz-id-tls
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
CREATE TABLE public.payments
|
CREATE TABLE public.payments
|
||||||
(
|
(
|
||||||
id uuid NOT NULL DEFAULT uuid_generate_v4(),
|
id uuid NOT NULL DEFAULT uuid_generate_v4(),
|
||||||
partner_id varchar NOT NULL,
|
partner_id numeric NOT NULL,
|
||||||
order_id varchar NOT NULL,
|
order_id numeric NOT NULL,
|
||||||
reference_id varchar NOT NULL,
|
reference_id varchar NOT NULL,
|
||||||
channel varchar NOT NULL,
|
channel varchar NOT NULL,
|
||||||
payment_type varchar NOT NULL,
|
payment_type varchar NOT NULL,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user