Update Mitra

This commit is contained in:
aditya.siregar 2024-07-30 14:18:18 +07:00
parent efac497db7
commit f3fbe9ba10
11 changed files with 260 additions and 66 deletions

View File

@ -118,7 +118,6 @@ func (b *UserList) ToUserList() []*User {
} }
func (u *UserDB) ToUpdatedUser(req User) error { func (u *UserDB) ToUpdatedUser(req User) error {
if req.Name != "" { if req.Name != "" {
u.Name = req.Name u.Name = req.Name
} }
@ -127,8 +126,12 @@ func (u *UserDB) ToUpdatedUser(req User) error {
u.Email = req.Email u.Email = req.Email
} }
if *req.PartnerID > 0 { if req.PhoneNumber != "" {
u.PartnerID = req.PartnerID u.PhoneNumber = req.PhoneNumber
}
if req.NIK != "" {
u.NIK = req.NIK
} }
if req.RoleID > 0 { if req.RoleID > 0 {

View File

@ -2,13 +2,13 @@ package entity
import ( import (
"furtuna-be/internal/constants/role" "furtuna-be/internal/constants/role"
"furtuna-be/internal/constants/userstatus"
"time" "time"
) )
type CreatePartnerRequest struct { type CreatePartnerRequest struct {
Name string `json:"name" validate:"required"` Name string `json:"name" validate:"required"`
Address string `json:"address"` Address string `json:"address"`
Username string `json:"username" validate:"required"`
FullName string `json:"full_name"` FullName string `json:"full_name"`
Email string `json:"email"` Email string `json:"email"`
Password string `json:"password" validate:"required"` Password string `json:"password" validate:"required"`
@ -16,6 +16,7 @@ type CreatePartnerRequest struct {
PhoneNumber string `json:"phone_number"` PhoneNumber string `json:"phone_number"`
BankName string `json:"bank_name"` BankName string `json:"bank_name"`
BankAccountNumber string `json:"bank_account_number"` BankAccountNumber string `json:"bank_account_number"`
Status string `json:"status"`
BankAccountHolderName string `json:"bank_account_holder_name"` BankAccountHolderName string `json:"bank_account_holder_name"`
} }
@ -40,6 +41,35 @@ type Partner struct {
AdminEmail string `gorm:"-"` AdminEmail string `gorm:"-"`
} }
type PartnerUpdate struct {
ID int64
Email string
Name string
Status string
Address string
PhoneNumber string
BankName string
BankAccountHolderNumber string
BankAccountHolderName string
NIK string
AdminUserID int64
AdminName string
Password string
}
func (c *PartnerUpdate) ToUserAdmin(partnerID *int64) *User {
return &User{
ID: c.AdminUserID,
Name: c.Name,
Password: c.Password,
Email: c.Email,
NIK: c.NIK,
PhoneNumber: c.PhoneNumber,
Status: userstatus.UserStatus(c.Status),
PartnerID: partnerID,
}
}
func (Partner) TableName() string { func (Partner) TableName() string {
return "partners" return "partners"
} }
@ -77,17 +107,20 @@ func (PartnerDB) TableName() string {
func (e *PartnerDB) ToPartner() *Partner { func (e *PartnerDB) ToPartner() *Partner {
return &Partner{ return &Partner{
ID: e.ID, ID: e.ID,
Name: e.Name, Name: e.Name,
Status: e.Status, Status: e.Status,
Address: e.Address, Address: e.Address,
CreatedAt: e.CreatedAt, CreatedAt: e.CreatedAt,
UpdatedAt: e.UpdatedAt, UpdatedAt: e.UpdatedAt,
CreatedBy: e.CreatedBy, CreatedBy: e.CreatedBy,
Balance: e.Balance, Balance: e.Balance,
AdminEmail: e.AdminEmail, AdminEmail: e.AdminEmail,
AdminPhoneNumber: e.AdminPhoneNumber, AdminPhoneNumber: e.AdminPhoneNumber,
AdminName: e.AdminName, AdminName: e.AdminName,
BankAccountHolderName: e.BankAccountHolderName,
BankName: e.BankName,
BankAccountNumber: e.BankAccountNumber,
} }
} }
@ -113,6 +146,50 @@ func (o *PartnerDB) ToUpdatedPartner(updatedBy int64, req Partner) {
if req.Address != "" { if req.Address != "" {
o.Address = req.Address o.Address = req.Address
} }
if req.BankAccountNumber != "" {
o.BankAccountNumber = req.BankAccountNumber
}
if req.BankAccountHolderName != "" {
o.BankAccountHolderName = req.BankAccountHolderName
}
if req.Status != "" {
o.Status = req.Status
}
}
func (o *PartnerDB) ToUpdatedPartnerData(updatedBy int64, req PartnerUpdate) {
o.UpdatedBy = updatedBy
if req.Name != "" {
o.Name = req.Name
}
if req.Status != "" {
o.Status = req.Status
}
if req.Address != "" {
o.Address = req.Address
}
if req.BankName != "" {
o.BankName = req.BankName
}
if req.BankAccountHolderNumber != "" {
o.BankAccountNumber = req.BankAccountHolderNumber
}
if req.BankAccountHolderName != "" {
o.BankAccountHolderName = req.BankAccountHolderName
}
if req.Status != "" {
o.Status = req.Status
}
} }
func (o *PartnerDB) SetDeleted(updatedBy int64) { func (o *PartnerDB) SetDeleted(updatedBy int64) {
@ -128,7 +205,7 @@ func (c *CreatePartnerRequest) ToUserAdmin(partnerID int64) *User {
Email: c.Email, Email: c.Email,
NIK: c.NIK, NIK: c.NIK,
PhoneNumber: c.PhoneNumber, PhoneNumber: c.PhoneNumber,
Status: "active", Status: "Active",
RoleID: role.PartnerAdmin, RoleID: role.PartnerAdmin,
PartnerID: &partnerID, PartnerID: &partnerID,
} }
@ -141,7 +218,7 @@ func (e *CreatePartnerRequest) ToPartnerDB(createdBy int64) *PartnerDB {
return &PartnerDB{ return &PartnerDB{
Partner: Partner{ Partner: Partner{
Name: e.Name, Name: e.Name,
Status: "inactive", Status: e.Status,
Address: e.Address, Address: e.Address,
CreatedBy: createdBy, CreatedBy: createdBy,
CreatedAt: time.Now(), CreatedAt: time.Now(),

View File

@ -107,13 +107,7 @@ func (h *Handler) Update(c *gin.Context) {
return return
} }
validate := validator.New() updatedPartner, err := h.service.Update(ctx, req.ToEntityUpdate(PartnerID))
if err := validate.Struct(req); err != nil {
response.ErrorWrapper(c, err)
return
}
updatedPartner, err := h.service.Update(ctx, PartnerID, req.ToEntity())
if err != nil { if err != nil {
response.ErrorWrapper(c, err) response.ErrorWrapper(c, err)
return return
@ -242,15 +236,18 @@ func (h *Handler) GetByID(c *gin.Context) {
func (h *Handler) toPartnerResponse(resp *entity.Partner) response.Partner { func (h *Handler) toPartnerResponse(resp *entity.Partner) response.Partner {
return response.Partner{ return response.Partner{
ID: &resp.ID, ID: &resp.ID,
Name: resp.Name, Name: resp.Name,
Status: resp.Status, Status: resp.Status,
CreatedAt: resp.CreatedAt.Format(time.RFC3339), CreatedAt: resp.CreatedAt.Format(time.RFC3339),
UpdatedAt: resp.CreatedAt.Format(time.RFC3339), UpdatedAt: resp.CreatedAt.Format(time.RFC3339),
Balance: resp.Balance, Balance: resp.Balance,
AdminName: resp.AdminName, AdminName: resp.AdminName,
AdminPhoneNumber: resp.AdminPhoneNumber, AdminPhoneNumber: resp.AdminPhoneNumber,
AdminEmail: resp.AdminEmail, AdminEmail: resp.AdminEmail,
BankAccountName: resp.BankName,
BankAccountHolderName: resp.BankAccountHolderName,
BankAccountHolderNumber: resp.BankAccountNumber,
} }
} }

View File

@ -21,32 +21,39 @@ func (p *PartnerParam) ToEntity() entity.PartnerSearch {
} }
type Partner struct { type Partner struct {
Name string `json:"name"` ID int64 `json:"id"`
Address string `json:"address"` Name string `json:"name"`
Status string `json:"status"` Address string `json:"address"`
Email string `json:"email"` Status string `json:"status"`
PhoneNumber string `json:"phone_number"` Email string `json:"email"`
PhoneNumber string `json:"phone_number"`
Password string `json:"password"`
AdminUserID int64 `json:"admin_user_id"`
AdminName string `json:"admin_name"`
BankName string `json:"bank_name"`
BankAccountHolderNumber string `json:"bank_account_holder_number"`
BankAccountHolderName string `json:"bank_account_holder_name"`
NIK string `json:"nik"`
} }
type CreatePartnerRequest struct { type CreatePartnerRequest struct {
Name string `json:"name" validate:"required"` Name string `json:"name" validate:"required"`
Address string `json:"address"` Email string `json:"email" validate:"required"`
Username string `json:"username" validate:"required"` Address string `json:"address" validate:"required"`
FullName string `json:"full_name"` FullName string `json:"full_name" validate:"required"`
Email string `json:"email"`
Password string `json:"password" validate:"required"` Password string `json:"password" validate:"required"`
NIK string `json:"nik"` NIK string `json:"nik"`
PhoneNumber string `json:"phone_number"` PhoneNumber string `json:"phone_number" validate:"required"`
BankName string `json:"bank_name"` BankName string `json:"bank_name" validate:"required"`
BankAccountNumber string `json:"bank_account_number"` BankAccountNumber string `json:"bank_account_number" validate:"required"`
BankAccountHolderName string `json:"bank_account_holder_name"` BankAccountHolderName string `json:"bank_account_holder_name" validate:"required"`
Status string `json:"status"`
} }
func (e *CreatePartnerRequest) ToEntity() *entity.CreatePartnerRequest { func (e *CreatePartnerRequest) ToEntity() *entity.CreatePartnerRequest {
return &entity.CreatePartnerRequest{ return &entity.CreatePartnerRequest{
Name: e.Name, Name: e.Name,
Address: e.Address, Address: e.Address,
Username: e.Username,
FullName: e.FullName, FullName: e.FullName,
Email: e.Email, Email: e.Email,
Password: e.Password, Password: e.Password,
@ -55,6 +62,7 @@ func (e *CreatePartnerRequest) ToEntity() *entity.CreatePartnerRequest {
BankName: e.BankName, BankName: e.BankName,
BankAccountNumber: e.BankAccountNumber, BankAccountNumber: e.BankAccountNumber,
BankAccountHolderName: e.BankAccountHolderName, BankAccountHolderName: e.BankAccountHolderName,
Status: e.Status,
} }
} }
@ -65,3 +73,21 @@ func (e *Partner) ToEntity() *entity.Partner {
Status: e.Status, Status: e.Status,
} }
} }
func (e *Partner) ToEntityUpdate(partnerID int64) *entity.PartnerUpdate {
return &entity.PartnerUpdate{
ID: partnerID,
Name: e.Name,
Email: e.Email,
Address: e.Address,
Status: e.Status,
PhoneNumber: e.PhoneNumber,
BankName: e.BankName,
BankAccountHolderNumber: e.BankAccountHolderNumber,
BankAccountHolderName: e.BankAccountHolderName,
NIK: e.NIK,
AdminName: e.AdminName,
Password: e.Password,
AdminUserID: e.AdminUserID,
}
}

View File

@ -1,16 +1,19 @@
package response package response
type Partner struct { type Partner struct {
ID *int64 `json:"id"` ID *int64 `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Status string `json:"status"` Status string `json:"status"`
Address string `json:"address,omitempty"` Address string `json:"address,omitempty"`
CreatedAt string `json:"created_at,omitempty"` CreatedAt string `json:"created_at,omitempty"`
UpdatedAt string `json:"updated_at,omitempty"` UpdatedAt string `json:"updated_at,omitempty"`
AdminName string `json:"admin_name"` AdminName string `json:"admin_name"`
AdminPhoneNumber string `json:"admin_phone_number"` AdminPhoneNumber string `json:"admin_phone_number"`
AdminEmail string `json:"admin_email"` AdminEmail string `json:"admin_email"`
Balance float64 `json:"balance"` Balance float64 `json:"balance"`
BankAccountName string `json:"bank_account_name"`
BankAccountHolderName string `json:"bank_account_holder_name"`
BankAccountHolderNumber string `json:"bank_account_holder_number"`
} }
type PartnerList struct { type PartnerList struct {

View File

@ -54,12 +54,25 @@ func (b *PartnerRepository) UpdateWithTx(ctx context.Context, tx *gorm.DB, Partn
} }
func (b *PartnerRepository) GetByID(ctx context.Context, id int64) (*entity.PartnerDB, error) { func (b *PartnerRepository) GetByID(ctx context.Context, id int64) (*entity.PartnerDB, error) {
Partner := new(entity.PartnerDB) Partner := new(entity.PartnerDBSearch)
if err := b.db.First(Partner, id).Error; err != nil {
query := b.db.Table("partners p").
Select("p.*, w.balance as wallet_balance, u.name as admin_name, u.email as admin_email, u.phone_number as admin_phone_number").
Joins("LEFT JOIN wallets w ON w.partner_id = p.id").
Joins("LEFT JOIN users u ON p.admin_user_id = u.id").
Where("p.id = ? AND p.deleted_at IS NULL", id)
if err := query.First(&Partner).Error; err != nil {
logger.ContextLogger(ctx).Error("error when get by id Partner", zap.Error(err)) logger.ContextLogger(ctx).Error("error when get by id Partner", zap.Error(err))
return nil, err return nil, err
} }
return Partner, nil
Partner.Partner.Balance = Partner.WalletBalance
Partner.Partner.AdminName = Partner.AdminName
Partner.Partner.AdminPhoneNumber = Partner.AdminPhoneNumber
Partner.Partner.AdminEmail = Partner.AdminEmail
return &entity.PartnerDB{Partner.Partner}, nil
} }
func (b *PartnerRepository) GetAll(ctx context.Context, req entity.PartnerSearch) (entity.PartnerList, int, error) { func (b *PartnerRepository) GetAll(ctx context.Context, req entity.PartnerSearch) (entity.PartnerList, int, error) {

View File

@ -103,6 +103,7 @@ type User interface {
GetUserByID(ctx context.Context, id int64) (*entity.UserDB, error) GetUserByID(ctx context.Context, id int64) (*entity.UserDB, error)
GetUserByEmail(ctx context.Context, email string) (*entity.UserDB, error) GetUserByEmail(ctx context.Context, email string) (*entity.UserDB, error)
UpdateUser(ctx context.Context, user *entity.UserDB) (*entity.UserDB, error) UpdateUser(ctx context.Context, user *entity.UserDB) (*entity.UserDB, error)
UpdateUserWithTx(ctx context.Context, tx *gorm.DB, user *entity.UserDB) (*entity.UserDB, error)
} }
type Branch interface { type Branch interface {

View File

@ -122,7 +122,7 @@ func (b *UserRepository) GetUserByID(ctx context.Context, id int64) (*entity.Use
var user *entity.UserDB var user *entity.UserDB
query := b.db.Table("users"). query := b.db.Table("users").
Select("users.id, users.email, users.name, users.status, users.created_at, users.updated_at, ur.role_id, r.role_name, ur.partner_id, b.name as partner_name"). Select("users.id, users.email, users.password , users.name, users.status, users.created_at, users.updated_at, ur.role_id, r.role_name, ur.partner_id, b.name as partner_name").
Joins("LEFT JOIN user_roles ur ON users.id = ur.user_id"). Joins("LEFT JOIN user_roles ur ON users.id = ur.user_id").
Joins("LEFT JOIN roles r ON ur.role_id = r.role_id"). Joins("LEFT JOIN roles r ON ur.role_id = r.role_id").
Joins("LEFT JOIN partners b ON ur.partner_id = b.id"). Joins("LEFT JOIN partners b ON ur.partner_id = b.id").
@ -184,6 +184,22 @@ func (r *UserRepository) UpdateUser(ctx context.Context, user *entity.UserDB) (*
return user, nil return user, nil
} }
func (r *UserRepository) UpdateUserWithTx(ctx context.Context, tx *gorm.DB, user *entity.UserDB) (*entity.UserDB, error) {
if err := tx.Select("name", "email", "nik", "phone_number", "password", "status", "deleted_at", "updated_by").Save(user).Error; err != nil {
logError(ctx, "update user", err)
return nil, err
}
userRole := user.ToUserRoleDB()
if err := tx.Model(userRole).Where("user_id = ?", user.ID).Updates(userRole).Error; err != nil {
tx.Rollback()
logError(ctx, "update user role", err)
return nil, err
}
return user, nil
}
func logError(ctx context.Context, action string, err error) { func logError(ctx context.Context, action string, err error) {
logger.ContextLogger(ctx).Error("error when "+action, zap.Error(err)) logger.ContextLogger(ctx).Error("error when "+action, zap.Error(err))
} }

View File

@ -76,20 +76,44 @@ func (s *PartnerService) Create(ctx mycontext.Context, partnerReq *entity.Create
return partnerDB.ToPartner(), nil return partnerDB.ToPartner(), nil
} }
func (s *PartnerService) Update(ctx mycontext.Context, id int64, PartnerReq *entity.Partner) (*entity.Partner, error) { func (s *PartnerService) Update(ctx mycontext.Context, req *entity.PartnerUpdate) (*entity.Partner, error) {
existingPartner, err := s.repo.GetByID(ctx, id) existingPartner, err := s.repo.GetByID(ctx, req.ID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
existingPartner.ToUpdatedPartnerData(ctx.RequestedBy(), *req)
existingPartner.ToUpdatedPartner(ctx.RequestedBy(), *PartnerReq) tx, err := s.trx.Begin(ctx)
if err != nil {
logger.ContextLogger(ctx).Error("error when starting transaction", zap.Error(err))
return nil, err
}
updatedPartnerDB, err := s.repo.Update(ctx, existingPartner.ToPartnerDB()) defer func() {
if r := recover(); r != nil {
s.trx.Rollback(tx)
panic(r)
} else if err != nil {
s.trx.Rollback(tx)
} else {
err = s.trx.Commit(tx).Error
}
}()
updatedPartnerDB, err := s.repo.UpdateWithTx(ctx, tx, existingPartner.ToPartnerDB())
if err != nil { if err != nil {
logger.ContextLogger(ctx).Error("error when update Partner", zap.Error(err)) logger.ContextLogger(ctx).Error("error when update Partner", zap.Error(err))
return nil, err return nil, err
} }
if req.AdminUserID != 0 {
adminUser := req.ToUserAdmin(&req.ID)
if adminUser, err = s.userSvc.UpdateWithTx(ctx, tx, adminUser); err != nil {
logger.ContextLogger(ctx).Error("error when creating admin user", zap.Error(err))
return nil, err
}
}
return updatedPartnerDB.ToPartner(), nil return updatedPartnerDB.ToPartner(), nil
} }

View File

@ -72,6 +72,7 @@ type User interface {
CreateWithTx(ctx mycontext.Context, tx *gorm.DB, userReq *entity.User) (*entity.User, error) CreateWithTx(ctx mycontext.Context, tx *gorm.DB, userReq *entity.User) (*entity.User, error)
GetAll(ctx mycontext.Context, search entity.UserSearch) ([]*entity.User, int, error) GetAll(ctx mycontext.Context, search entity.UserSearch) ([]*entity.User, int, error)
Update(ctx mycontext.Context, id int64, userReq *entity.User) (*entity.User, error) Update(ctx mycontext.Context, id int64, userReq *entity.User) (*entity.User, error)
UpdateWithTx(ctx mycontext.Context, tx *gorm.DB, req *entity.User) (*entity.User, error)
GetByID(ctx mycontext.Context, id int64) (*entity.User, error) GetByID(ctx mycontext.Context, id int64) (*entity.User, error)
Delete(ctx mycontext.Context, id int64) error Delete(ctx mycontext.Context, id int64) error
} }
@ -115,7 +116,7 @@ type OSSService interface {
type Partner interface { type Partner interface {
Create(ctx mycontext.Context, branchReq *entity.CreatePartnerRequest) (*entity.Partner, error) Create(ctx mycontext.Context, branchReq *entity.CreatePartnerRequest) (*entity.Partner, error)
Update(ctx mycontext.Context, id int64, branchReq *entity.Partner) (*entity.Partner, error) Update(ctx mycontext.Context, branchReq *entity.PartnerUpdate) (*entity.Partner, error)
GetByID(ctx context.Context, id int64) (*entity.Partner, error) GetByID(ctx context.Context, id int64) (*entity.Partner, error)
GetAll(ctx context.Context, search entity.PartnerSearch) ([]*entity.Partner, int, error) GetAll(ctx context.Context, search entity.PartnerSearch) ([]*entity.Partner, int, error)
Delete(ctx mycontext.Context, id int64) error Delete(ctx mycontext.Context, id int64) error

View File

@ -1,6 +1,7 @@
package users package users
import ( import (
"errors"
"fmt" "fmt"
"furtuna-be/internal/common/mycontext" "furtuna-be/internal/common/mycontext"
"gorm.io/gorm" "gorm.io/gorm"
@ -101,6 +102,10 @@ func (s *UserService) Update(ctx mycontext.Context, id int64, userReq *entity.Us
return nil, err return nil, err
} }
if existingUser == nil {
return nil, errors.New("user not found")
}
//if changed branch //if changed branch
if *userReq.PartnerID > 0 { if *userReq.PartnerID > 0 {
branch, err := s.branchRepo.GetBranchByID(ctx, *userReq.PartnerID) branch, err := s.branchRepo.GetBranchByID(ctx, *userReq.PartnerID)
@ -125,6 +130,34 @@ func (s *UserService) Update(ctx mycontext.Context, id int64, userReq *entity.Us
return updatedUserDB.ToUser(), nil return updatedUserDB.ToUser(), nil
} }
func (s *UserService) UpdateWithTx(ctx mycontext.Context, tx *gorm.DB, req *entity.User) (*entity.User, error) {
existingUser, err := s.repo.GetUserByID(ctx, req.ID)
if err != nil {
return nil, err
}
if existingUser == nil {
return nil, errors.New("user not found")
}
if *existingUser.PartnerID != *req.PartnerID {
return nil, errors.New("invalid request")
}
err = existingUser.ToUpdatedUser(*req)
if err != nil {
return nil, err
}
updatedUserDB, err := s.repo.UpdateUserWithTx(ctx, tx, existingUser)
if err != nil {
logger.ContextLogger(ctx).Error("error when update user", zap.Error(err))
return nil, err
}
return updatedUserDB.ToUser(), nil
}
func (s *UserService) Delete(ctx mycontext.Context, id int64) error { func (s *UserService) Delete(ctx mycontext.Context, id int64) error {
userDB, err := s.repo.GetUserByID(ctx, id) userDB, err := s.repo.GetUserByID(ctx, id)
if err != nil { if err != nil {