2023-10-08 15:59:42 +07:00
package users
import (
"context"
"furtuna-be/internal/common/logger"
"furtuna-be/internal/entity"
"go.uber.org/zap"
"gorm.io/gorm"
)
type UserRepository struct {
db * gorm . DB
}
func NewUserRepository ( db * gorm . DB ) * UserRepository {
return & UserRepository {
db : db ,
}
}
func ( r * UserRepository ) Create ( ctx context . Context , user * entity . UserDB ) ( * entity . UserDB , error ) {
tx := r . db . Begin ( )
user . ID = 0
if err := tx . Select ( "name" , "email" , "password" , "status" , "created_by" , "nik" , "user_type" , "phone_number" ) . Create ( user ) . Error ; err != nil {
tx . Rollback ( )
logError ( ctx , "creating user" , err )
return nil , err
}
if err := tx . First ( user , user . ID ) . Error ; err != nil {
tx . Rollback ( )
logError ( ctx , "retrieving user" , err )
return nil , err
}
2024-08-04 01:14:59 +07:00
if user . UserType != "CUSTOMER" {
userRole := user . ToUserRoleDB ( )
if err := tx . Create ( userRole ) . Error ; err != nil {
tx . Rollback ( )
logError ( ctx , "creating user role" , err )
return nil , err
}
2023-10-08 15:59:42 +07:00
}
if err := tx . Commit ( ) . Error ; err != nil {
tx . Rollback ( )
logError ( ctx , "committing transaction" , err )
return nil , err
}
return user , nil
}
2024-06-03 14:40:50 +07:00
func ( r * UserRepository ) CreateWithTx ( ctx context . Context , tx * gorm . DB , user * entity . UserDB ) ( * entity . UserDB , error ) {
user . ID = 0
if err := tx . Select ( "name" , "email" , "password" , "status" , "created_by" , "nik" , "user_type" , "phone_number" ) . Create ( user ) . Error ; err != nil {
logError ( ctx , "creating user" , err )
return nil , err
}
if err := tx . First ( user , user . ID ) . Error ; err != nil {
tx . Rollback ( )
logError ( ctx , "retrieving user" , err )
return nil , err
}
userRole := user . ToUserRoleDB ( )
if err := tx . Create ( userRole ) . Error ; err != nil {
tx . Rollback ( )
logError ( ctx , "creating user role" , err )
return nil , err
}
return user , nil
}
2023-10-08 15:59:42 +07:00
func ( b * UserRepository ) GetAllUsers ( ctx context . Context , req entity . UserSearch ) ( entity . UserList , int , error ) {
var users [ ] * entity . UserDB
var total int64
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" ) .
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" ) .
2024-08-22 23:43:25 +07:00
Where ( "users.deleted_at is null" ) .
Where ( "users.user_type != ?" , "CUSTOMER" )
2023-10-08 15:59:42 +07:00
if req . Search != "" {
query = query . Where ( "users.name ILIKE ? or users.email ILIKE ? or r.role_name ILIKE ? or b.name ILIKE ? " , "%" + req . Search + "%" , "%" + req . Search + "%" , "%" + req . Search + "%" , "%" + req . Search + "%" )
}
if req . Name != "" {
query = query . Where ( "users.name ILIKE ?" , "%" + req . Name + "%" )
}
if req . RoleID > 0 {
2024-08-15 11:01:55 +07:00
query = query . Where ( "ur.role_id = ? " , req . RoleID )
}
if req . PartnerID > 0 {
query = query . Where ( "ur.partner_id = ? " , req . PartnerID )
}
if req . SiteID > 0 {
query = query . Where ( "ur.site_id = ? " , req . SiteID )
}
// Get the total count without applying the limit and offset.
if err := query . Model ( & entity . UserDB { } ) . Count ( & total ) . Error ; err != nil {
logger . ContextLogger ( ctx ) . Error ( "error when count users" , zap . Error ( err ) )
return nil , 0 , err
}
// Apply pagination.
query = query . Offset ( req . Offset ) . Limit ( req . Limit )
if err := query . Scan ( & users ) . Error ; err != nil {
logger . ContextLogger ( ctx ) . Error ( "error when get all users" , zap . Error ( err ) )
return nil , 0 , err
}
return users , int ( total ) , nil
}
2024-12-23 11:20:33 +07:00
2024-08-15 11:01:55 +07:00
func ( b * UserRepository ) GetAllCustomer ( ctx context . Context , req entity . CustomerSearch ) ( entity . CustomerList , int , error ) {
var users [ ] * entity . UserDB
var total int64
query := b . db . Table ( "users" ) .
2024-08-28 14:04:16 +07:00
Select ( "users.id, users.email, users.name, users.phone_number, users.status, users.user_type, users.created_at, users.updated_at, ur.role_id, r.role_name, ur.partner_id, b.name as partner_name" ) .
2024-08-15 11:01:55 +07:00
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" ) .
Where ( "users.deleted_at is null" ) .
2024-08-28 14:04:16 +07:00
Where ( "users.user_type = 'CUSTOMER'" )
2024-08-15 11:01:55 +07:00
if req . Search != "" {
2024-12-23 12:09:29 +07:00
query = query . Where ( "users.name ILIKE ? or users.email ILIKE ? or users.phone_number ILIKE ? or r.role_name ILIKE ? or b.name ILIKE ?" , "%" + req . Search + "%" , "%" + req . Search + "%" , "%" + req . Search + "%" , "%" + req . Search + "%" , "%" + req . Search + "%" )
2024-08-15 11:01:55 +07:00
}
if req . Name != "" {
query = query . Where ( "users.name ILIKE ?" , "%" + req . Name + "%" )
}
if req . RoleID > 0 {
2023-10-08 15:59:42 +07:00
query = query . Where ( "ur.role_id = ? " , req . RoleID )
}
if req . PartnerID > 0 {
query = query . Where ( "ur.partner_id = ? " , req . PartnerID )
}
2024-07-30 19:38:23 +07:00
if req . SiteID > 0 {
query = query . Where ( "ur.site_id = ? " , req . SiteID )
}
2023-10-08 15:59:42 +07:00
// Get the total count without applying the limit and offset.
if err := query . Model ( & entity . UserDB { } ) . Count ( & total ) . Error ; err != nil {
logger . ContextLogger ( ctx ) . Error ( "error when count users" , zap . Error ( err ) )
return nil , 0 , err
}
// Apply pagination.
query = query . Offset ( req . Offset ) . Limit ( req . Limit )
if err := query . Scan ( & users ) . Error ; err != nil {
logger . ContextLogger ( ctx ) . Error ( "error when get all users" , zap . Error ( err ) )
return nil , 0 , err
}
return users , int ( total ) , nil
}
func ( b * UserRepository ) GetUserByID ( ctx context . Context , id int64 ) ( * entity . UserDB , error ) {
var user * entity . UserDB
query := b . db . Table ( "users" ) .
2024-08-28 23:48:49 +07:00
Select ( "users.id, users.email,users.phone_number,users.nik, users.password , users.name, users.status, users.created_at, users.updated_at, ur.role_id, r.role_name, ur.partner_id, ur.site_id, b.name as partner_name" ) .
2023-10-08 15:59:42 +07:00
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" ) .
Where ( "users.id = ?" , id )
if err := query . Scan ( & user ) . Error ; err != nil {
logger . ContextLogger ( ctx ) . Error ( "error when get user" , zap . Error ( err ) )
return nil , err
}
return user , nil
}
2024-08-21 23:34:54 +07:00
func ( b * UserRepository ) GetPartnerAdmin ( ctx context . Context , partnerID int64 ) ( * entity . UserDB , error ) {
var user * entity . UserDB
partnerAdmin := 3
query := b . db . Table ( "users" ) .
Select ( "users.id, users.email,users.phone_number,users.nik, 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" ) .
Where ( "ur.partner_id = ?" , partnerID ) .
Where ( "ur.role_id = ?" , partnerAdmin )
if err := query . Scan ( & user ) . Error ; err != nil {
logger . ContextLogger ( ctx ) . Error ( "error when get user" , zap . Error ( err ) )
return nil , err
}
return user , nil
}
2023-10-08 15:59:42 +07:00
func ( b * UserRepository ) GetUserByEmail ( ctx context . Context , email string ) ( * entity . UserDB , error ) {
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" ) .
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" ) .
Where ( "users.email = ?" , email )
if err := query . Scan ( & user ) . Error ; err != nil {
logger . ContextLogger ( ctx ) . Error ( "error when get user" , zap . Error ( err ) )
return nil , err
}
return user , nil
}
func ( r * UserRepository ) UpdateUser ( ctx context . Context , user * entity . UserDB ) ( * entity . UserDB , error ) {
tx := r . db . Begin ( )
defer func ( ) {
if r := recover ( ) ; r != nil {
tx . Rollback ( )
}
} ( )
2024-08-27 23:59:25 +07:00
if err := tx . Select ( "name" , "email" , "password" , "status" , "deleted_at" , "updated_by" , "nik" , "phone_number" ) . Save ( user ) . Error ; err != nil {
2023-10-08 15:59:42 +07:00
tx . Rollback ( )
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
}
if err := tx . Commit ( ) . Error ; err != nil {
tx . Rollback ( )
logError ( ctx , "committing transaction" , err )
return nil , err
}
return user , nil
}
2024-07-30 14:18:18 +07:00
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
}
2023-10-08 15:59:42 +07:00
func logError ( ctx context . Context , action string , err error ) {
logger . ContextLogger ( ctx ) . Error ( "error when " + action , zap . Error ( err ) )
}
2024-08-02 18:35:42 +07:00
func ( r * UserRepository ) CountUsersByRoleAndSiteOrPartner ( ctx context . Context , roleID int , siteID * int64 ) ( int , error ) {
var count int64
query := r . db . Table ( "users" ) .
Joins ( "LEFT JOIN user_roles ur ON users.id = ur.user_id" ) .
Where ( "ur.role_id = ?" , roleID )
if siteID != nil {
query = query . Where ( "ur.site_id = ?" , siteID )
}
if err := query . Count ( & count ) . Error ; err != nil {
logger . ContextLogger ( ctx ) . Error ( "error when counting users by role and site/partner" , zap . Error ( err ) )
return 0 , err
}
return int ( count ) , nil
}