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 {
if req.Name != "" {
u.Name = req.Name
}
@ -127,8 +126,12 @@ func (u *UserDB) ToUpdatedUser(req User) error {
u.Email = req.Email
}
if *req.PartnerID > 0 {
u.PartnerID = req.PartnerID
if req.PhoneNumber != "" {
u.PhoneNumber = req.PhoneNumber
}
if req.NIK != "" {
u.NIK = req.NIK
}
if req.RoleID > 0 {

View File

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

View File

@ -107,13 +107,7 @@ func (h *Handler) Update(c *gin.Context) {
return
}
validate := validator.New()
if err := validate.Struct(req); err != nil {
response.ErrorWrapper(c, err)
return
}
updatedPartner, err := h.service.Update(ctx, PartnerID, req.ToEntity())
updatedPartner, err := h.service.Update(ctx, req.ToEntityUpdate(PartnerID))
if err != nil {
response.ErrorWrapper(c, err)
return
@ -242,15 +236,18 @@ func (h *Handler) GetByID(c *gin.Context) {
func (h *Handler) toPartnerResponse(resp *entity.Partner) response.Partner {
return response.Partner{
ID: &resp.ID,
Name: resp.Name,
Status: resp.Status,
CreatedAt: resp.CreatedAt.Format(time.RFC3339),
UpdatedAt: resp.CreatedAt.Format(time.RFC3339),
Balance: resp.Balance,
AdminName: resp.AdminName,
AdminPhoneNumber: resp.AdminPhoneNumber,
AdminEmail: resp.AdminEmail,
ID: &resp.ID,
Name: resp.Name,
Status: resp.Status,
CreatedAt: resp.CreatedAt.Format(time.RFC3339),
UpdatedAt: resp.CreatedAt.Format(time.RFC3339),
Balance: resp.Balance,
AdminName: resp.AdminName,
AdminPhoneNumber: resp.AdminPhoneNumber,
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 {
Name string `json:"name"`
Address string `json:"address"`
Status string `json:"status"`
Email string `json:"email"`
PhoneNumber string `json:"phone_number"`
ID int64 `json:"id"`
Name string `json:"name"`
Address string `json:"address"`
Status string `json:"status"`
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 {
Name string `json:"name" validate:"required"`
Address string `json:"address"`
Username string `json:"username" validate:"required"`
FullName string `json:"full_name"`
Email string `json:"email"`
Email string `json:"email" validate:"required"`
Address string `json:"address" validate:"required"`
FullName string `json:"full_name" validate:"required"`
Password string `json:"password" validate:"required"`
NIK string `json:"nik"`
PhoneNumber string `json:"phone_number"`
BankName string `json:"bank_name"`
BankAccountNumber string `json:"bank_account_number"`
BankAccountHolderName string `json:"bank_account_holder_name"`
PhoneNumber string `json:"phone_number" validate:"required"`
BankName string `json:"bank_name" validate:"required"`
BankAccountNumber string `json:"bank_account_number" validate:"required"`
BankAccountHolderName string `json:"bank_account_holder_name" validate:"required"`
Status string `json:"status"`
}
func (e *CreatePartnerRequest) ToEntity() *entity.CreatePartnerRequest {
return &entity.CreatePartnerRequest{
Name: e.Name,
Address: e.Address,
Username: e.Username,
FullName: e.FullName,
Email: e.Email,
Password: e.Password,
@ -55,6 +62,7 @@ func (e *CreatePartnerRequest) ToEntity() *entity.CreatePartnerRequest {
BankName: e.BankName,
BankAccountNumber: e.BankAccountNumber,
BankAccountHolderName: e.BankAccountHolderName,
Status: e.Status,
}
}
@ -65,3 +73,21 @@ func (e *Partner) ToEntity() *entity.Partner {
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
type Partner struct {
ID *int64 `json:"id"`
Name string `json:"name"`
Status string `json:"status"`
Address string `json:"address,omitempty"`
CreatedAt string `json:"created_at,omitempty"`
UpdatedAt string `json:"updated_at,omitempty"`
AdminName string `json:"admin_name"`
AdminPhoneNumber string `json:"admin_phone_number"`
AdminEmail string `json:"admin_email"`
Balance float64 `json:"balance"`
ID *int64 `json:"id"`
Name string `json:"name"`
Status string `json:"status"`
Address string `json:"address,omitempty"`
CreatedAt string `json:"created_at,omitempty"`
UpdatedAt string `json:"updated_at,omitempty"`
AdminName string `json:"admin_name"`
AdminPhoneNumber string `json:"admin_phone_number"`
AdminEmail string `json:"admin_email"`
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 {

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) {
Partner := new(entity.PartnerDB)
if err := b.db.First(Partner, id).Error; err != nil {
Partner := new(entity.PartnerDBSearch)
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))
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) {

View File

@ -103,6 +103,7 @@ type User interface {
GetUserByID(ctx context.Context, id int64) (*entity.UserDB, error)
GetUserByEmail(ctx context.Context, email string) (*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 {

View File

@ -122,7 +122,7 @@ func (b *UserRepository) GetUserByID(ctx context.Context, id int64) (*entity.Use
var user *entity.UserDB
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 roles r ON ur.role_id = r.role_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
}
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) {
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
}
func (s *PartnerService) Update(ctx mycontext.Context, id int64, PartnerReq *entity.Partner) (*entity.Partner, error) {
existingPartner, err := s.repo.GetByID(ctx, id)
func (s *PartnerService) Update(ctx mycontext.Context, req *entity.PartnerUpdate) (*entity.Partner, error) {
existingPartner, err := s.repo.GetByID(ctx, req.ID)
if err != nil {
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 {
logger.ContextLogger(ctx).Error("error when update Partner", zap.Error(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
}

View File

@ -72,6 +72,7 @@ type User interface {
CreateWithTx(ctx mycontext.Context, tx *gorm.DB, userReq *entity.User) (*entity.User, error)
GetAll(ctx mycontext.Context, search entity.UserSearch) ([]*entity.User, int, 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)
Delete(ctx mycontext.Context, id int64) error
}
@ -115,7 +116,7 @@ type OSSService interface {
type Partner interface {
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)
GetAll(ctx context.Context, search entity.PartnerSearch) ([]*entity.Partner, int, error)
Delete(ctx mycontext.Context, id int64) error

View File

@ -1,6 +1,7 @@
package users
import (
"errors"
"fmt"
"furtuna-be/internal/common/mycontext"
"gorm.io/gorm"
@ -101,6 +102,10 @@ func (s *UserService) Update(ctx mycontext.Context, id int64, userReq *entity.Us
return nil, err
}
if existingUser == nil {
return nil, errors.New("user not found")
}
//if changed branch
if *userReq.PartnerID > 0 {
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
}
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 {
userDB, err := s.repo.GetUserByID(ctx, id)
if err != nil {