443 lines
12 KiB
Go
443 lines
12 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/Caknoooo/go-gin-clean-starter/database/entities"
|
|
"github.com/google/uuid"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type (
|
|
UserRepository interface {
|
|
Register(ctx context.Context, tx *gorm.DB, user entities.M_User) (entities.M_User, error)
|
|
GetUserById(ctx context.Context, tx *gorm.DB, userId string) (entities.M_User, error)
|
|
GetUserByEmail(ctx context.Context, tx *gorm.DB, email string) (entities.M_User, error)
|
|
GetUserByUsername(ctx context.Context, tx *gorm.DB, username string) (entities.M_User, error)
|
|
CheckEmail(ctx context.Context, tx *gorm.DB, email string) (entities.M_User, bool, error)
|
|
CheckUsername(ctx context.Context, tx *gorm.DB, username string) (entities.M_User, bool, error)
|
|
Update(ctx context.Context, tx *gorm.DB, user entities.M_User) (entities.M_User, error)
|
|
Delete(ctx context.Context, tx *gorm.DB, userId string) error
|
|
SwitchRole(ctx context.Context, tx *gorm.DB, userId string, roleId string) (entities.M_User, error)
|
|
GetAll(ctx context.Context, tx *gorm.DB) ([]entities.M_User, error)
|
|
GetUserWarehouses(ctx context.Context, tx *gorm.DB, userId string) ([]entities.MWarehouseEntity, error)
|
|
SwitchWarehouse(ctx context.Context, tx *gorm.DB, userId string, warehouseId string) (entities.M_User, error)
|
|
AssignWarehousesToUser(ctx context.Context, tx *gorm.DB, userId string, warehouseIds []string) (entities.M_User, error)
|
|
RemoveWarehousesFromUser(ctx context.Context, tx *gorm.DB, userId string, warehouseIds []string) (entities.M_User, error)
|
|
ClearUserWarehouses(ctx context.Context, tx *gorm.DB, userId string) error
|
|
AddUserWarehouses(ctx context.Context, tx *gorm.DB, userId string, warehouseIds []string) error
|
|
AddUserWarehouse(ctx context.Context, tx *gorm.DB, userId string, warehouseId string) error
|
|
RemoveUserWarehouse(ctx context.Context, tx *gorm.DB, userId string, warehouseId string) error
|
|
BulkCreate(ctx context.Context, tx *gorm.DB, users []entities.M_User) error
|
|
}
|
|
|
|
userRepository struct {
|
|
db *gorm.DB
|
|
}
|
|
)
|
|
|
|
// BulkCreate implements UserRepository.
|
|
func (r *userRepository) BulkCreate(ctx context.Context, tx *gorm.DB, users []entities.M_User) error {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
if err := tx.WithContext(ctx).Create(&users).Error; err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetUserWarehouses implements UserRepository.
|
|
func (r *userRepository) GetUserWarehouses(ctx context.Context, tx *gorm.DB, userId string) ([]entities.MWarehouseEntity, error) {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
|
|
var user entities.M_User
|
|
// Preload relasi UserWarehouses dan Warehouse
|
|
if err := tx.WithContext(ctx).
|
|
Preload("UserWarehouses.Warehouse").
|
|
Where("id = ?", userId).
|
|
Take(&user).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var warehouses []entities.MWarehouseEntity
|
|
for _, uw := range user.UserWarehouses {
|
|
warehouses = append(warehouses, uw.Warehouse)
|
|
}
|
|
|
|
return warehouses, nil
|
|
}
|
|
|
|
// AddUserWarehouse implements UserRepository.
|
|
func (r *userRepository) AddUserWarehouse(ctx context.Context, tx *gorm.DB, userId string, warehouseId string) error {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
|
|
uid := uuid.MustParse(userId)
|
|
wid := uuid.MustParse(warehouseId)
|
|
|
|
// Hapus dulu relasi yang sama jika ada
|
|
if err := tx.WithContext(ctx).
|
|
Where("user_id = ? AND warehouse_id = ?", uid, wid).
|
|
Delete(&entities.MUserWarehouseEntity{}).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
// Insert relasi baru
|
|
entity := entities.MUserWarehouseEntity{
|
|
ID: uuid.New(),
|
|
UserID: uid,
|
|
WarehouseID: wid,
|
|
}
|
|
|
|
if err := tx.WithContext(ctx).Create(&entity).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// RemoveUserWarehouse implements UserRepository.
|
|
func (r *userRepository) RemoveUserWarehouse(ctx context.Context, tx *gorm.DB, userId string, warehouseId string) error {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
|
|
// Delete specific warehouse relation
|
|
if err := tx.WithContext(ctx).
|
|
Where("user_id = ? AND warehouse_id = ?", userId, warehouseId).
|
|
Delete(&entities.MUserWarehouseEntity{}).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *userRepository) ClearUserWarehouses(ctx context.Context, tx *gorm.DB, userId string) error {
|
|
return tx.WithContext(ctx).
|
|
Where("user_id = ?", userId).
|
|
Delete(&entities.MUserWarehouseEntity{}).Error
|
|
}
|
|
|
|
func (r *userRepository) AddUserWarehouses(ctx context.Context, tx *gorm.DB, userId string, warehouseIds []string) error {
|
|
|
|
assignments := make([]entities.MUserWarehouseEntity, 0, len(warehouseIds))
|
|
|
|
uid := uuid.MustParse(userId)
|
|
|
|
for _, wid := range warehouseIds {
|
|
assignments = append(assignments, entities.MUserWarehouseEntity{
|
|
ID: uuid.New(),
|
|
UserID: uid,
|
|
WarehouseID: uuid.MustParse(wid),
|
|
})
|
|
}
|
|
|
|
return tx.WithContext(ctx).Create(&assignments).Error
|
|
}
|
|
|
|
// AssignWarehousesToUser implements UserRepository.
|
|
func (r *userRepository) AssignWarehousesToUser(ctx context.Context, tx *gorm.DB, userId string, warehouseIds []string) (entities.M_User, error) {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
|
|
// Remove duplicates
|
|
warehouseMap := make(map[string]struct{})
|
|
for _, wid := range warehouseIds {
|
|
warehouseMap[wid] = struct{}{}
|
|
}
|
|
var uniqueWarehouseIds []string
|
|
for wid := range warehouseMap {
|
|
uniqueWarehouseIds = append(uniqueWarehouseIds, wid)
|
|
}
|
|
|
|
// Prepare assignments
|
|
var assignments []entities.MUserWarehouseEntity
|
|
for _, wid := range uniqueWarehouseIds {
|
|
assignments = append(assignments, entities.MUserWarehouseEntity{
|
|
ID: uuid.New(),
|
|
UserID: uuid.MustParse(userId),
|
|
WarehouseID: uuid.MustParse(wid),
|
|
})
|
|
}
|
|
|
|
// Insert assignments, ignore duplicates due to unique index
|
|
if err := tx.WithContext(ctx).Create(&assignments).Error; err != nil {
|
|
return entities.M_User{}, err
|
|
}
|
|
|
|
// Reload user with updated warehouses
|
|
var user entities.M_User
|
|
if err := tx.WithContext(ctx).
|
|
Preload("Client").
|
|
Preload("Roles").
|
|
Preload("Warehouses").
|
|
Where("id = ?", userId).
|
|
Take(&user).Error; err != nil {
|
|
return entities.M_User{}, err
|
|
}
|
|
|
|
return user, nil
|
|
}
|
|
|
|
// RemoveWarehousesFromUser implements UserRepository.
|
|
func (r *userRepository) RemoveWarehousesFromUser(ctx context.Context, tx *gorm.DB, userId string, warehouseIds []string) (entities.M_User, error) {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
|
|
// Remove assignments
|
|
if err := tx.WithContext(ctx).
|
|
Where("user_id = ? AND warehouse_id IN ?", userId, warehouseIds).
|
|
Delete(&entities.MUserWarehouseEntity{}).Error; err != nil {
|
|
return entities.M_User{}, err
|
|
}
|
|
|
|
// Reload user with updated warehouses
|
|
var user entities.M_User
|
|
if err := tx.WithContext(ctx).
|
|
Preload("Client").
|
|
Preload("Roles").
|
|
Preload("Warehouses").
|
|
Where("id = ?", userId).
|
|
Take(&user).Error; err != nil {
|
|
return entities.M_User{}, err
|
|
}
|
|
|
|
return user, nil
|
|
}
|
|
|
|
// SwitchWarehouse implements UserRepository.
|
|
func (r *userRepository) SwitchWarehouse(ctx context.Context, tx *gorm.DB, userId string, warehouseId string) (entities.M_User, error) {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
|
|
var user entities.M_User
|
|
// Get user with warehouses
|
|
if err := tx.WithContext(ctx).
|
|
Preload("Warehouses").
|
|
Where("id = ?", userId).
|
|
Take(&user).Error; err != nil {
|
|
return entities.M_User{}, err
|
|
}
|
|
|
|
var warehouse entities.MWarehouseEntity
|
|
if err := tx.WithContext(ctx).
|
|
Where("id = ?", warehouseId).
|
|
Take(&warehouse).Error; err != nil {
|
|
return entities.M_User{}, err
|
|
}
|
|
|
|
// Remove all existing warehouse relations for this user
|
|
if err := tx.WithContext(ctx).
|
|
Where("user_id = ?", userId).
|
|
Delete(&entities.MUserWarehouseEntity{}).Error; err != nil {
|
|
return entities.M_User{}, err
|
|
}
|
|
|
|
// Add new warehouse relation
|
|
newUserWarehouse := entities.MUserWarehouseEntity{
|
|
UserID: user.ID,
|
|
WarehouseID: warehouse.ID,
|
|
}
|
|
if err := tx.WithContext(ctx).Create(&newUserWarehouse).Error; err != nil {
|
|
return entities.M_User{}, err
|
|
}
|
|
|
|
// Reload user with updated warehouses
|
|
if err := tx.WithContext(ctx).
|
|
Preload("Warehouses").
|
|
Where("id = ?", userId).
|
|
Take(&user).Error; err != nil {
|
|
return entities.M_User{}, err
|
|
}
|
|
|
|
return user, nil
|
|
}
|
|
|
|
// GetAll implements UserRepository.
|
|
func (r *userRepository) GetAll(ctx context.Context, tx *gorm.DB) ([]entities.M_User, error) {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
|
|
var users []entities.M_User
|
|
if err := tx.WithContext(ctx).
|
|
Preload("Client").
|
|
Preload("Roles").
|
|
Find(&users).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return users, nil
|
|
}
|
|
|
|
// CheckUsername implements UserRepository.
|
|
func (r *userRepository) CheckUsername(ctx context.Context, tx *gorm.DB, username string) (entities.M_User, bool, error) {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
|
|
var user entities.M_User
|
|
if err := tx.WithContext(ctx).Where("username = ?", username).Take(&user).Error; err != nil {
|
|
return entities.M_User{}, false, err
|
|
}
|
|
|
|
return user, true, nil
|
|
}
|
|
|
|
// GetUserByUsername implements UserRepository.
|
|
func (r *userRepository) GetUserByUsername(ctx context.Context, tx *gorm.DB, username string) (entities.M_User, error) {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
|
|
var user entities.M_User
|
|
if err := tx.WithContext(ctx).
|
|
Preload("Roles").
|
|
Preload("Client").
|
|
Preload("Warehouses").
|
|
Where("username = ?", username).
|
|
Take(&user).Error; err != nil {
|
|
return entities.M_User{}, err
|
|
}
|
|
|
|
return user, nil
|
|
}
|
|
|
|
// SwitchRole implements UserRepository.
|
|
func (r *userRepository) SwitchRole(ctx context.Context, tx *gorm.DB, userId string, roleId string) (entities.M_User, error) {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
var user entities.M_User
|
|
// Preload UserRoles dan Role di dalamnya
|
|
if err := tx.WithContext(ctx).
|
|
Where("id = ?", userId).
|
|
Preload("UserRoles.Role").
|
|
Take(&user).Error; err != nil {
|
|
return entities.M_User{}, err
|
|
}
|
|
var role entities.M_Role
|
|
if err := tx.WithContext(ctx).Where("id = ?", roleId).Take(&role).Error; err != nil {
|
|
return entities.M_User{}, err
|
|
}
|
|
// Ganti semua role user dengan role baru (hapus yang lama, insert yang baru)
|
|
if err := tx.WithContext(ctx).
|
|
Where("user_id = ?", userId).
|
|
Delete(&entities.M_User_Role{}).Error; err != nil {
|
|
return entities.M_User{}, err
|
|
}
|
|
newUserRole := entities.M_User_Role{
|
|
UserID: user.ID,
|
|
RoleID: role.ID,
|
|
}
|
|
if err := tx.WithContext(ctx).Create(&newUserRole).Error; err != nil {
|
|
return entities.M_User{}, err
|
|
}
|
|
// Ambil ulang user beserta roles-nya
|
|
if err := tx.WithContext(ctx).
|
|
Where("id = ?", userId).
|
|
Preload("UserRoles.Role").
|
|
Take(&user).Error; err != nil {
|
|
return entities.M_User{}, err
|
|
}
|
|
return user, nil
|
|
}
|
|
|
|
func (r *userRepository) Register(ctx context.Context, tx *gorm.DB, user entities.M_User) (entities.M_User, error) {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
|
|
if err := tx.WithContext(ctx).Create(&user).Error; err != nil {
|
|
return entities.M_User{}, err
|
|
}
|
|
|
|
return user, nil
|
|
}
|
|
|
|
func (r *userRepository) GetUserById(ctx context.Context, tx *gorm.DB, userId string) (entities.M_User, error) {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
|
|
var user entities.M_User
|
|
if err := tx.WithContext(ctx).
|
|
Preload("Client").
|
|
Preload("Roles").
|
|
Preload("Warehouses").
|
|
Where("id = ?", userId).
|
|
Take(&user).Error; err != nil {
|
|
return entities.M_User{}, err
|
|
}
|
|
|
|
return user, nil
|
|
}
|
|
|
|
func (r *userRepository) GetUserByEmail(ctx context.Context, tx *gorm.DB, email string) (entities.M_User, error) {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
|
|
var user entities.M_User
|
|
if err := tx.WithContext(ctx).
|
|
Preload("Client").
|
|
Preload("Roles").
|
|
Preload("Warehouses").
|
|
Where("email = ?", email).
|
|
Take(&user).Error; err != nil {
|
|
return entities.M_User{}, err
|
|
}
|
|
|
|
return user, nil
|
|
}
|
|
|
|
func (r *userRepository) CheckEmail(ctx context.Context, tx *gorm.DB, email string) (entities.M_User, bool, error) {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
|
|
var user entities.M_User
|
|
if err := tx.WithContext(ctx).Where("email = ?", email).Take(&user).Error; err != nil {
|
|
return entities.M_User{}, false, err
|
|
}
|
|
|
|
return user, true, nil
|
|
}
|
|
|
|
func (r *userRepository) Update(ctx context.Context, tx *gorm.DB, user entities.M_User) (entities.M_User, error) {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
|
|
if err := tx.WithContext(ctx).Updates(&user).Error; err != nil {
|
|
return entities.M_User{}, err
|
|
}
|
|
|
|
return user, nil
|
|
}
|
|
|
|
func (r *userRepository) Delete(ctx context.Context, tx *gorm.DB, userId string) error {
|
|
if tx == nil {
|
|
tx = r.db
|
|
}
|
|
|
|
if err := tx.WithContext(ctx).Delete(&entities.M_User{}, "id = ?", userId).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func NewUserRepository(db *gorm.DB) UserRepository {
|
|
return &userRepository{
|
|
db: db,
|
|
}
|
|
}
|