mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
[FIX/BE-US] changes role to user and query
This commit is contained in:
@@ -24,6 +24,10 @@ type AuthContext struct {
|
|||||||
User *entity.User
|
User *entity.User
|
||||||
Roles []sso.Role
|
Roles []sso.Role
|
||||||
Permissions map[string]struct{}
|
Permissions map[string]struct{}
|
||||||
|
UserAreaIDs []uint
|
||||||
|
UserLocationIDs []uint
|
||||||
|
UserAllArea bool
|
||||||
|
UserAllLocation bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auth validates the incoming request against the central SSO access token and
|
// Auth validates the incoming request against the central SSO access token and
|
||||||
@@ -67,10 +71,15 @@ func Auth(userService service.UserService, requiredScopes ...string) fiber.Handl
|
|||||||
|
|
||||||
var roles []sso.Role
|
var roles []sso.Role
|
||||||
permissions := make(map[string]struct{})
|
permissions := make(map[string]struct{})
|
||||||
|
var profile *sso.UserProfile
|
||||||
if verification.UserID != 0 {
|
if verification.UserID != 0 {
|
||||||
if profile, err := sso.FetchProfile(c.Context(), token, verification); err != nil {
|
if p, err := sso.FetchProfile(c.Context(), token, verification); err != nil {
|
||||||
utils.Log.WithError(err).Warn("auth: failed to fetch sso profile")
|
utils.Log.WithError(err).Warn("auth: failed to fetch sso profile")
|
||||||
} else if profile != nil {
|
} else {
|
||||||
|
profile = p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if profile != nil {
|
||||||
roles = profile.Roles
|
roles = profile.Roles
|
||||||
for _, perm := range profile.PermissionNames() {
|
for _, perm := range profile.PermissionNames() {
|
||||||
if perm != "" {
|
if perm != "" {
|
||||||
@@ -78,7 +87,6 @@ func Auth(userService service.UserService, requiredScopes ...string) fiber.Handl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ctx := &AuthContext{
|
ctx := &AuthContext{
|
||||||
Token: token,
|
Token: token,
|
||||||
@@ -86,6 +94,16 @@ func Auth(userService service.UserService, requiredScopes ...string) fiber.Handl
|
|||||||
User: user,
|
User: user,
|
||||||
Roles: roles,
|
Roles: roles,
|
||||||
Permissions: permissions,
|
Permissions: permissions,
|
||||||
|
UserAreaIDs: nil,
|
||||||
|
UserLocationIDs: nil,
|
||||||
|
UserAllArea: false,
|
||||||
|
UserAllLocation: false,
|
||||||
|
}
|
||||||
|
if profile != nil {
|
||||||
|
ctx.UserAreaIDs = profile.AreaIDs
|
||||||
|
ctx.UserLocationIDs = profile.LocationIDs
|
||||||
|
ctx.UserAllArea = profile.AllArea
|
||||||
|
ctx.UserAllLocation = profile.AllLocation
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Locals(authContextLocalsKey, ctx)
|
c.Locals(authContextLocalsKey, ctx)
|
||||||
|
|||||||
+398
-101
@@ -2,12 +2,10 @@ package middleware
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
|
||||||
"gitlab.com/mbugroup/lti-api.git/internal/config"
|
|
||||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -86,48 +84,24 @@ func ResolveLocationScope(c *fiber.Ctx, db *gorm.DB) (ScopeFilter, error) {
|
|||||||
|
|
||||||
func collectRoleScope(c *fiber.Ctx) (roleScope, error) {
|
func collectRoleScope(c *fiber.Ctx) (roleScope, error) {
|
||||||
ctx, ok := AuthDetails(c)
|
ctx, ok := AuthDetails(c)
|
||||||
if !ok || ctx == nil || len(ctx.Roles) == 0 {
|
if !ok || ctx == nil {
|
||||||
return roleScope{}, nil
|
return roleScope{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
clientAlias := resolveClientAlias(ctx)
|
userAreaIDs := uniqueUint(ctx.UserAreaIDs)
|
||||||
|
userLocationIDs := uniqueUint(ctx.UserLocationIDs)
|
||||||
scope := roleScope{}
|
userScope := roleScope{
|
||||||
areaSet := make(map[uint]struct{})
|
allArea: ctx.UserAllArea,
|
||||||
locationSet := make(map[uint]struct{})
|
allLocation: ctx.UserAllLocation,
|
||||||
|
areaIDs: userAreaIDs,
|
||||||
for _, role := range ctx.Roles {
|
locationIDs: userLocationIDs,
|
||||||
if clientAlias != "" && !strings.EqualFold(strings.TrimSpace(role.ClientAlias), clientAlias) {
|
hasAnyScopes: ctx.UserAllArea || ctx.UserAllLocation || len(userAreaIDs) > 0 || len(userLocationIDs) > 0,
|
||||||
continue
|
|
||||||
}
|
|
||||||
scope.hasAnyScopes = true
|
|
||||||
if role.AllArea {
|
|
||||||
scope.allArea = true
|
|
||||||
}
|
|
||||||
if role.AllLocation {
|
|
||||||
scope.allLocation = true
|
|
||||||
}
|
|
||||||
for _, id := range role.AreaIDs {
|
|
||||||
if id == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
areaSet[id] = struct{}{}
|
|
||||||
}
|
|
||||||
for _, id := range role.LocationIDs {
|
|
||||||
if id == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
locationSet[id] = struct{}{}
|
|
||||||
}
|
}
|
||||||
|
if userScope.hasAnyScopes {
|
||||||
|
return userScope, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.areaIDs = keysUint(areaSet)
|
return roleScope{}, nil
|
||||||
scope.locationIDs = keysUint(locationSet)
|
|
||||||
|
|
||||||
scope.hasAnyScopes = scope.hasAnyScopes &&
|
|
||||||
(scope.allArea || scope.allLocation || len(scope.areaIDs) > 0 || len(scope.locationIDs) > 0)
|
|
||||||
|
|
||||||
return scope, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func areaIDsByLocationIDs(db *gorm.DB, locationIDs []uint) ([]uint, error) {
|
func areaIDsByLocationIDs(db *gorm.DB, locationIDs []uint) ([]uint, error) {
|
||||||
@@ -204,70 +178,7 @@ func uniqueUint(ids []uint) []uint {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func keysUint(set map[uint]struct{}) []uint {
|
|
||||||
if len(set) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
out := make([]uint, 0, len(set))
|
|
||||||
for id := range set {
|
|
||||||
out = append(out, id)
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
func resolveClientAlias(ctx *AuthContext) string {
|
|
||||||
if ctx == nil || ctx.Verification == nil || ctx.Verification.Claims == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
scopes := ctx.Verification.Claims.Scopes()
|
|
||||||
if len(scopes) == 0 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
seen := make(map[string]struct{})
|
|
||||||
for _, scope := range scopes {
|
|
||||||
scope = strings.ToLower(strings.TrimSpace(scope))
|
|
||||||
if scope == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
prefix := scope
|
|
||||||
if idx := strings.IndexAny(prefix, ".:"); idx > 0 {
|
|
||||||
prefix = prefix[:idx]
|
|
||||||
}
|
|
||||||
prefix = strings.TrimSpace(prefix)
|
|
||||||
if prefix == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if alias := matchAlias(prefix); alias != "" {
|
|
||||||
seen[alias] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(seen) != 1 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
for alias := range seen {
|
|
||||||
return alias
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func matchAlias(alias string) string {
|
|
||||||
alias = strings.ToLower(strings.TrimSpace(alias))
|
|
||||||
if alias == "" {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
if _, ok := config.SSOClients[alias]; ok {
|
|
||||||
return alias
|
|
||||||
}
|
|
||||||
for key := range config.SSOClients {
|
|
||||||
if strings.EqualFold(key, alias) {
|
|
||||||
return strings.ToLower(strings.TrimSpace(key))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func ApplyScopeFilter(db *gorm.DB, scope ScopeFilter, column string) *gorm.DB {
|
func ApplyScopeFilter(db *gorm.DB, scope ScopeFilter, column string) *gorm.DB {
|
||||||
if db == nil || !scope.Restrict {
|
if db == nil || !scope.Restrict {
|
||||||
@@ -278,3 +189,389 @@ func ApplyScopeFilter(db *gorm.DB, scope ScopeFilter, column string) *gorm.DB {
|
|||||||
}
|
}
|
||||||
return db.Where(column+" IN ?", scope.IDs)
|
return db.Where(column+" IN ?", scope.IDs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func EnsureWarehouseAccess(c *fiber.Ctx, db *gorm.DB, warehouseID uint) error {
|
||||||
|
if warehouseID == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid warehouse id")
|
||||||
|
}
|
||||||
|
if db == nil {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Database not configured")
|
||||||
|
}
|
||||||
|
|
||||||
|
scope, err := ResolveLocationScope(c, db)
|
||||||
|
if err != nil || !scope.Restrict {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(scope.IDs) == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Warehouse not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
var count int64
|
||||||
|
if err := ApplyScopeFilter(
|
||||||
|
db.WithContext(c.Context()).
|
||||||
|
Model(&entity.Warehouse{}).
|
||||||
|
Where("id = ?", warehouseID),
|
||||||
|
scope,
|
||||||
|
"warehouses.location_id",
|
||||||
|
).Count(&count).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if count == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Warehouse not found")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func EnsureAreaAccess(c *fiber.Ctx, db *gorm.DB, areaID uint) error {
|
||||||
|
if areaID == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid area id")
|
||||||
|
}
|
||||||
|
if db == nil {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Database not configured")
|
||||||
|
}
|
||||||
|
|
||||||
|
scope, err := ResolveAreaScope(c, db)
|
||||||
|
if err != nil || !scope.Restrict {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(scope.IDs) == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Area not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
var count int64
|
||||||
|
if err := ApplyScopeFilter(
|
||||||
|
db.WithContext(c.Context()).
|
||||||
|
Model(&entity.Area{}).
|
||||||
|
Where("id = ?", areaID),
|
||||||
|
scope,
|
||||||
|
"areas.id",
|
||||||
|
).Count(&count).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if count == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Area not found")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func EnsureLocationAccess(c *fiber.Ctx, db *gorm.DB, locationID uint) error {
|
||||||
|
if locationID == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid location id")
|
||||||
|
}
|
||||||
|
if db == nil {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Database not configured")
|
||||||
|
}
|
||||||
|
|
||||||
|
scope, err := ResolveLocationScope(c, db)
|
||||||
|
if err != nil || !scope.Restrict {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(scope.IDs) == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Location not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
var count int64
|
||||||
|
if err := ApplyScopeFilter(
|
||||||
|
db.WithContext(c.Context()).
|
||||||
|
Model(&entity.Location{}).
|
||||||
|
Where("id = ?", locationID),
|
||||||
|
scope,
|
||||||
|
"locations.id",
|
||||||
|
).Count(&count).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if count == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Location not found")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func EnsureKandangAccess(c *fiber.Ctx, db *gorm.DB, kandangID uint) error {
|
||||||
|
if kandangID == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid kandang id")
|
||||||
|
}
|
||||||
|
if db == nil {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Database not configured")
|
||||||
|
}
|
||||||
|
|
||||||
|
scope, err := ResolveLocationScope(c, db)
|
||||||
|
if err != nil || !scope.Restrict {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(scope.IDs) == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Kandang not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
var count int64
|
||||||
|
if err := ApplyScopeFilter(
|
||||||
|
db.WithContext(c.Context()).
|
||||||
|
Model(&entity.Kandang{}).
|
||||||
|
Where("id = ?", kandangID),
|
||||||
|
scope,
|
||||||
|
"kandangs.location_id",
|
||||||
|
).Count(&count).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if count == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Kandang not found")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func EnsureProductWarehouseAccess(c *fiber.Ctx, db *gorm.DB, productWarehouseID uint) error {
|
||||||
|
if productWarehouseID == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid product warehouse id")
|
||||||
|
}
|
||||||
|
if db == nil {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Database not configured")
|
||||||
|
}
|
||||||
|
|
||||||
|
scope, err := ResolveLocationScope(c, db)
|
||||||
|
if err != nil || !scope.Restrict {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(scope.IDs) == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Product warehouse not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
var count int64
|
||||||
|
q := db.WithContext(c.Context()).
|
||||||
|
Table("product_warehouses pw").
|
||||||
|
Joins("JOIN warehouses w ON w.id = pw.warehouse_id").
|
||||||
|
Where("pw.id = ?", productWarehouseID)
|
||||||
|
q = ApplyScopeFilter(q, scope, "w.location_id")
|
||||||
|
if err := q.Count(&count).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if count == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Product warehouse not found")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func EnsureStockLogAccess(c *fiber.Ctx, db *gorm.DB, stockLogID uint) error {
|
||||||
|
if stockLogID == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid stock log id")
|
||||||
|
}
|
||||||
|
if db == nil {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Database not configured")
|
||||||
|
}
|
||||||
|
|
||||||
|
scope, err := ResolveLocationScope(c, db)
|
||||||
|
if err != nil || !scope.Restrict {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(scope.IDs) == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Stock log not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
var count int64
|
||||||
|
q := db.WithContext(c.Context()).
|
||||||
|
Table("stock_logs sl").
|
||||||
|
Joins("JOIN product_warehouses pw ON pw.id = sl.product_warehouse_id").
|
||||||
|
Joins("JOIN warehouses w ON w.id = pw.warehouse_id").
|
||||||
|
Where("sl.id = ?", stockLogID)
|
||||||
|
q = ApplyScopeFilter(q, scope, "w.location_id")
|
||||||
|
if err := q.Count(&count).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if count == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Stock log not found")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func EnsureMarketingAccess(c *fiber.Ctx, db *gorm.DB, marketingID uint) error {
|
||||||
|
if marketingID == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid marketing id")
|
||||||
|
}
|
||||||
|
if db == nil {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Database not configured")
|
||||||
|
}
|
||||||
|
|
||||||
|
scope, err := ResolveLocationScope(c, db)
|
||||||
|
if err != nil || !scope.Restrict {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(scope.IDs) == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Marketing not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
var count int64
|
||||||
|
q := db.WithContext(c.Context()).
|
||||||
|
Table("marketings m").
|
||||||
|
Joins("JOIN marketing_products mp ON mp.marketing_id = m.id").
|
||||||
|
Joins("JOIN product_warehouses pw ON pw.id = mp.product_warehouse_id").
|
||||||
|
Joins("JOIN warehouses w ON w.id = pw.warehouse_id").
|
||||||
|
Where("m.id = ?", marketingID)
|
||||||
|
q = ApplyScopeFilter(q, scope, "w.location_id")
|
||||||
|
if err := q.Count(&count).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if count == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Marketing not found")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func EnsureRecordingAccess(c *fiber.Ctx, db *gorm.DB, recordingID uint) error {
|
||||||
|
if recordingID == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid recording id")
|
||||||
|
}
|
||||||
|
if db == nil {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Database not configured")
|
||||||
|
}
|
||||||
|
|
||||||
|
scope, err := ResolveLocationScope(c, db)
|
||||||
|
if err != nil || !scope.Restrict {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(scope.IDs) == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Recording not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
var count int64
|
||||||
|
q := db.WithContext(c.Context()).
|
||||||
|
Table("recordings r").
|
||||||
|
Joins("JOIN project_flock_kandangs pfk ON pfk.id = r.project_flock_kandangs_id").
|
||||||
|
Joins("JOIN project_flocks pf ON pf.id = pfk.project_flock_id").
|
||||||
|
Where("r.id = ?", recordingID)
|
||||||
|
q = ApplyScopeFilter(q, scope, "pf.location_id")
|
||||||
|
if err := q.Count(&count).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if count == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Recording not found")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func EnsureUniformityAccess(c *fiber.Ctx, db *gorm.DB, uniformityID uint) error {
|
||||||
|
if uniformityID == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid uniformity id")
|
||||||
|
}
|
||||||
|
if db == nil {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Database not configured")
|
||||||
|
}
|
||||||
|
|
||||||
|
scope, err := ResolveLocationScope(c, db)
|
||||||
|
if err != nil || !scope.Restrict {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(scope.IDs) == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Uniformity not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
var count int64
|
||||||
|
q := db.WithContext(c.Context()).
|
||||||
|
Table("project_flock_kandang_uniformities u").
|
||||||
|
Joins("JOIN project_flock_kandangs pfk ON pfk.id = u.project_flock_kandang_id").
|
||||||
|
Joins("JOIN project_flocks pf ON pf.id = pfk.project_flock_id").
|
||||||
|
Where("u.id = ?", uniformityID)
|
||||||
|
q = ApplyScopeFilter(q, scope, "pf.location_id")
|
||||||
|
if err := q.Count(&count).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if count == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Uniformity not found")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func EnsureLayingTransferAccess(c *fiber.Ctx, db *gorm.DB, transferID uint) error {
|
||||||
|
if transferID == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid transfer id")
|
||||||
|
}
|
||||||
|
if db == nil {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Database not configured")
|
||||||
|
}
|
||||||
|
|
||||||
|
scope, err := ResolveLocationScope(c, db)
|
||||||
|
if err != nil || !scope.Restrict {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(scope.IDs) == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Transfer not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
var count int64
|
||||||
|
q := db.WithContext(c.Context()).
|
||||||
|
Table("laying_transfers lt").
|
||||||
|
Joins("JOIN project_flocks pf_from ON pf_from.id = lt.from_project_flock_id").
|
||||||
|
Joins("JOIN project_flocks pf_to ON pf_to.id = lt.to_project_flock_id").
|
||||||
|
Where("lt.id = ?", transferID).
|
||||||
|
Where("(pf_from.location_id IN ? OR pf_to.location_id IN ?)", scope.IDs, scope.IDs)
|
||||||
|
if err := q.Count(&count).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if count == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Transfer not found")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func EnsureProjectFlockAccess(c *fiber.Ctx, db *gorm.DB, projectFlockID uint) error {
|
||||||
|
if projectFlockID == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid project flock id")
|
||||||
|
}
|
||||||
|
if db == nil {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Database not configured")
|
||||||
|
}
|
||||||
|
|
||||||
|
scope, err := ResolveLocationScope(c, db)
|
||||||
|
if err != nil || !scope.Restrict {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(scope.IDs) == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Project Flock not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
var count int64
|
||||||
|
if err := ApplyScopeFilter(
|
||||||
|
db.WithContext(c.Context()).
|
||||||
|
Model(&entity.ProjectFlock{}).
|
||||||
|
Where("id = ?", projectFlockID),
|
||||||
|
scope,
|
||||||
|
"project_flocks.location_id",
|
||||||
|
).Count(&count).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if count == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Project Flock not found")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func EnsureProjectFlockKandangAccess(c *fiber.Ctx, db *gorm.DB, projectFlockID, projectFlockKandangID uint) error {
|
||||||
|
if projectFlockKandangID == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "Invalid project flock kandang id")
|
||||||
|
}
|
||||||
|
if db == nil {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Database not configured")
|
||||||
|
}
|
||||||
|
|
||||||
|
scope, err := ResolveLocationScope(c, db)
|
||||||
|
if err != nil || !scope.Restrict {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(scope.IDs) == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Project Flock Kandang not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
var count int64
|
||||||
|
q := db.WithContext(c.Context()).
|
||||||
|
Table("project_flock_kandangs").
|
||||||
|
Joins("JOIN project_flocks ON project_flocks.id = project_flock_kandangs.project_flock_id").
|
||||||
|
Where("project_flock_kandangs.id = ?", projectFlockKandangID)
|
||||||
|
if projectFlockID > 0 {
|
||||||
|
q = q.Where("project_flock_kandangs.project_flock_id = ?", projectFlockID)
|
||||||
|
}
|
||||||
|
q = ApplyScopeFilter(q, scope, "project_flocks.location_id")
|
||||||
|
if err := q.Count(&count).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if count == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "Project Flock Kandang not found")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
|
|
||||||
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
||||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||||
|
m "gitlab.com/mbugroup/lti-api.git/internal/middleware"
|
||||||
"gitlab.com/mbugroup/lti-api.git/internal/modules/closings/dto"
|
"gitlab.com/mbugroup/lti-api.git/internal/modules/closings/dto"
|
||||||
repository "gitlab.com/mbugroup/lti-api.git/internal/modules/closings/repositories"
|
repository "gitlab.com/mbugroup/lti-api.git/internal/modules/closings/repositories"
|
||||||
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/closings/validations"
|
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/closings/validations"
|
||||||
@@ -98,10 +99,16 @@ func (s closingService) GetAll(c *fiber.Ctx, params *validation.Query) ([]dto.Cl
|
|||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scope, err := m.ResolveLocationScope(c, s.Repository.DB())
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
offset := (params.Page - 1) * params.Limit
|
offset := (params.Page - 1) * params.Limit
|
||||||
|
|
||||||
closings, total, err := s.Repository.GetAll(c.Context(), offset, params.Limit, func(db *gorm.DB) *gorm.DB {
|
closings, total, err := s.Repository.GetAll(c.Context(), offset, params.Limit, func(db *gorm.DB) *gorm.DB {
|
||||||
db = s.withClosingRelations(db)
|
db = s.withClosingRelations(db)
|
||||||
|
db = m.ApplyScopeFilter(db, scope, "project_flocks.location_id")
|
||||||
if params.Search != "" {
|
if params.Search != "" {
|
||||||
return db.Where("flock_name ILIKE ?", "%"+params.Search+"%")
|
return db.Where("flock_name ILIKE ?", "%"+params.Search+"%")
|
||||||
}
|
}
|
||||||
@@ -128,6 +135,10 @@ func (s closingService) GetAll(c *fiber.Ctx, params *validation.Query) ([]dto.Cl
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s closingService) GetProjectFlockByID(c *fiber.Ctx, id uint) (*entity.ProjectFlock, error) {
|
func (s closingService) GetProjectFlockByID(c *fiber.Ctx, id uint) (*entity.ProjectFlock, error) {
|
||||||
|
if err := m.EnsureProjectFlockAccess(c, s.Repository.DB(), id); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
projectFlock, err := s.ProjectFlockRepo.GetByID(c.Context(), id, s.withRelations)
|
projectFlock, err := s.ProjectFlockRepo.GetByID(c.Context(), id, s.withRelations)
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return nil, fiber.NewError(fiber.StatusNotFound, "Project Flock not found")
|
return nil, fiber.NewError(fiber.StatusNotFound, "Project Flock not found")
|
||||||
@@ -139,6 +150,13 @@ func (s closingService) GetProjectFlockByID(c *fiber.Ctx, id uint) (*entity.Proj
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s closingService) GetPenjualan(c *fiber.Ctx, projectFlockID uint, projectFlockKandangID *uint) ([]entity.MarketingDeliveryProduct, error) {
|
func (s closingService) GetPenjualan(c *fiber.Ctx, projectFlockID uint, projectFlockKandangID *uint) ([]entity.MarketingDeliveryProduct, error) {
|
||||||
|
if projectFlockKandangID != nil {
|
||||||
|
if err := m.EnsureProjectFlockKandangAccess(c, s.Repository.DB(), projectFlockID, *projectFlockKandangID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else if err := m.EnsureProjectFlockAccess(c, s.Repository.DB(), projectFlockID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
realisasi, err := s.MarketingDeliveryProductRepo.GetClosingPenjualan(c.Context(), projectFlockID, projectFlockKandangID)
|
realisasi, err := s.MarketingDeliveryProductRepo.GetClosingPenjualan(c.Context(), projectFlockID, projectFlockKandangID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -152,8 +170,8 @@ func (s closingService) GetPenjualan(c *fiber.Ctx, projectFlockID uint, projectF
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s closingService) GetClosingSummary(c *fiber.Ctx, projectFlockID uint, kandangID *uint) (any, error) {
|
func (s closingService) GetClosingSummary(c *fiber.Ctx, projectFlockID uint, kandangID *uint) (any, error) {
|
||||||
if projectFlockID == 0 {
|
if err := m.EnsureProjectFlockAccess(c, s.Repository.DB(), projectFlockID); err != nil {
|
||||||
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid project flock id")
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if kandangID != nil {
|
if kandangID != nil {
|
||||||
@@ -299,8 +317,8 @@ func (s closingService) getClosingSummaryByKandang(ctx context.Context, projectF
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s closingService) GetClosingSapronak(c *fiber.Ctx, projectFlockID uint, params *validation.ClosingSapronakQuery) ([]dto.ClosingSapronakItemDTO, int64, error) {
|
func (s closingService) GetClosingSapronak(c *fiber.Ctx, projectFlockID uint, params *validation.ClosingSapronakQuery) ([]dto.ClosingSapronakItemDTO, int64, error) {
|
||||||
if projectFlockID == 0 {
|
if err := m.EnsureProjectFlockAccess(c, s.Repository.DB(), projectFlockID); err != nil {
|
||||||
return nil, 0, fiber.NewError(fiber.StatusBadRequest, "Invalid project flock id")
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if params == nil {
|
if params == nil {
|
||||||
@@ -322,14 +340,6 @@ func (s closingService) GetClosingSapronak(c *fiber.Ctx, projectFlockID uint, pa
|
|||||||
return nil, 0, fiber.NewError(fiber.StatusBadRequest, "type must be either incoming or outgoing")
|
return nil, 0, fiber.NewError(fiber.StatusBadRequest, "type must be either incoming or outgoing")
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := s.Repository.GetByID(c.Context(), projectFlockID, nil); err != nil {
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
return nil, 0, fiber.NewError(fiber.StatusNotFound, "Project flock tidak ditemukan")
|
|
||||||
}
|
|
||||||
s.Log.Errorf("Failed get project flock %d for sapronak closing: %+v", projectFlockID, err)
|
|
||||||
return nil, 0, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch project flock")
|
|
||||||
}
|
|
||||||
|
|
||||||
warehouseIDs, err := s.getWarehouseIDsByProjectFlock(c.Context(), projectFlockID)
|
warehouseIDs, err := s.getWarehouseIDsByProjectFlock(c.Context(), projectFlockID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Log.Errorf("Failed to fetch warehouses for project flock %d: %+v", projectFlockID, err)
|
s.Log.Errorf("Failed to fetch warehouses for project flock %d: %+v", projectFlockID, err)
|
||||||
@@ -490,6 +500,14 @@ func (s closingService) getApprovalStatuses(ctx context.Context, projectFlockID
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s closingService) GetOverhead(c *fiber.Ctx, projectFlockID uint, projectFlockKandangID *uint) (*dto.OverheadListDTO, error) {
|
func (s closingService) GetOverhead(c *fiber.Ctx, projectFlockID uint, projectFlockKandangID *uint) (*dto.OverheadListDTO, error) {
|
||||||
|
if projectFlockKandangID != nil {
|
||||||
|
if err := m.EnsureProjectFlockKandangAccess(c, s.Repository.DB(), projectFlockID, *projectFlockKandangID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else if err := m.EnsureProjectFlockAccess(c, s.Repository.DB(), projectFlockID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
budgets, err := s.ProjectBudgetRepo.GetByProjectFlockID(c.Context(), projectFlockID)
|
budgets, err := s.ProjectBudgetRepo.GetByProjectFlockID(c.Context(), projectFlockID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -578,6 +596,9 @@ func (s closingService) GetOverhead(c *fiber.Ctx, projectFlockID uint, projectFl
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s closingService) GetClosingKeuangan(c *fiber.Ctx, projectFlockID uint) (*dto.ReportResponse, error) {
|
func (s closingService) GetClosingKeuangan(c *fiber.Ctx, projectFlockID uint) (*dto.ReportResponse, error) {
|
||||||
|
if err := m.EnsureProjectFlockAccess(c, s.Repository.DB(), projectFlockID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
if err := commonSvc.EnsureRelations(c.Context(),
|
if err := commonSvc.EnsureRelations(c.Context(),
|
||||||
commonSvc.RelationCheck{Name: "Project Flock", ID: &projectFlockID, Exists: s.ProjectFlockRepo.IdExists},
|
commonSvc.RelationCheck{Name: "Project Flock", ID: &projectFlockID, Exists: s.ProjectFlockRepo.IdExists},
|
||||||
@@ -654,8 +675,12 @@ func (s closingService) GetClosingKeuangan(c *fiber.Ctx, projectFlockID uint) (*
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s closingService) GetExpeditionHPP(c *fiber.Ctx, projectFlockID uint, projectFlockKandangID *uint) (*dto.ExpeditionHPPDTO, error) {
|
func (s closingService) GetExpeditionHPP(c *fiber.Ctx, projectFlockID uint, projectFlockKandangID *uint) (*dto.ExpeditionHPPDTO, error) {
|
||||||
if projectFlockID == 0 {
|
if projectFlockKandangID != nil {
|
||||||
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid project flock id")
|
if err := m.EnsureProjectFlockKandangAccess(c, s.Repository.DB(), projectFlockID, *projectFlockKandangID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else if err := m.EnsureProjectFlockAccess(c, s.Repository.DB(), projectFlockID); err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
rows, err := s.Repository.GetExpeditionHPP(c.Context(), projectFlockID, projectFlockKandangID)
|
rows, err := s.Repository.GetExpeditionHPP(c.Context(), projectFlockID, projectFlockKandangID)
|
||||||
@@ -686,8 +711,8 @@ func (s closingService) GetExpeditionHPP(c *fiber.Ctx, projectFlockID uint, proj
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s closingService) GetClosingDataProduksi(c *fiber.Ctx, projectFlockID uint, kandangID *uint) (*dto.ClosingProductionReportDTO, error) {
|
func (s closingService) GetClosingDataProduksi(c *fiber.Ctx, projectFlockID uint, kandangID *uint) (*dto.ClosingProductionReportDTO, error) {
|
||||||
if projectFlockID == 0 {
|
if err := m.EnsureProjectFlockAccess(c, s.Repository.DB(), projectFlockID); err != nil {
|
||||||
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid project flock id")
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
projectFlockKandangIDs, err := s.getProjectFlockKandangIDs(c.Context(), projectFlockID, kandangID)
|
projectFlockKandangIDs, err := s.getProjectFlockKandangIDs(c.Context(), projectFlockID, kandangID)
|
||||||
|
|||||||
@@ -74,6 +74,10 @@ func (s *adjustmentService) withRelations(db *gorm.DB) *gorm.DB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *adjustmentService) GetOne(c *fiber.Ctx, id uint) (*entity.StockLog, error) {
|
func (s *adjustmentService) GetOne(c *fiber.Ctx, id uint) (*entity.StockLog, error) {
|
||||||
|
if err := m.EnsureStockLogAccess(c, s.StockLogsRepository.DB(), id); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
stockLog, err := s.StockLogsRepository.GetByID(c.Context(), id, func(db *gorm.DB) *gorm.DB {
|
stockLog, err := s.StockLogsRepository.GetByID(c.Context(), id, func(db *gorm.DB) *gorm.DB {
|
||||||
return s.withRelations(db).Preload("ProductWarehouse.Product.ProductCategory")
|
return s.withRelations(db).Preload("ProductWarehouse.Product.ProductCategory")
|
||||||
})
|
})
|
||||||
@@ -101,6 +105,11 @@ func (s *adjustmentService) Adjustment(c *fiber.Ctx, req *validation.Create) (*e
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := m.EnsureWarehouseAccess(c, s.WarehouseRepo.DB(), uint(req.WarehouseID)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
if err := common.EnsureRelations(c.Context(),
|
if err := common.EnsureRelations(c.Context(),
|
||||||
common.RelationCheck{Name: "Product", ID: &req.ProductID, Exists: s.ProductRepo.IdExists},
|
common.RelationCheck{Name: "Product", ID: &req.ProductID, Exists: s.ProductRepo.IdExists},
|
||||||
common.RelationCheck{Name: "Warehouse", ID: &req.WarehouseID, Exists: s.WarehouseRepo.IdExists},
|
common.RelationCheck{Name: "Warehouse", ID: &req.WarehouseID, Exists: s.WarehouseRepo.IdExists},
|
||||||
@@ -279,6 +288,11 @@ func (s *adjustmentService) AdjustmentHistory(c *fiber.Ctx, query *validation.Qu
|
|||||||
if query.WarehouseID > 0 && !isWarehousesExist {
|
if query.WarehouseID > 0 && !isWarehousesExist {
|
||||||
return nil, 0, fiber.NewError(fiber.StatusNotFound, "Warehouse not found")
|
return nil, 0, fiber.NewError(fiber.StatusNotFound, "Warehouse not found")
|
||||||
}
|
}
|
||||||
|
if query.WarehouseID > 0 {
|
||||||
|
if err := m.EnsureWarehouseAccess(c, s.WarehouseRepo.DB(), uint(query.WarehouseID)); err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
isProductsExist, err := s.ProductRepo.IdExists(c.Context(), uint(query.ProductID))
|
isProductsExist, err := s.ProductRepo.IdExists(c.Context(), uint(query.ProductID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -290,7 +304,19 @@ func (s *adjustmentService) AdjustmentHistory(c *fiber.Ctx, query *validation.Qu
|
|||||||
}
|
}
|
||||||
|
|
||||||
stockLogs, total, err := s.StockLogsRepository.GetAll(c.Context(), offset, query.Limit, func(db *gorm.DB) *gorm.DB {
|
stockLogs, total, err := s.StockLogsRepository.GetAll(c.Context(), offset, query.Limit, func(db *gorm.DB) *gorm.DB {
|
||||||
|
scope, err := m.ResolveLocationScope(c, s.StockLogsRepository.DB())
|
||||||
|
if err != nil {
|
||||||
|
return db.Where("1 = 0")
|
||||||
|
}
|
||||||
|
if scope.Restrict {
|
||||||
|
if len(scope.IDs) == 0 {
|
||||||
|
return db.Where("1 = 0")
|
||||||
|
}
|
||||||
|
db = db.
|
||||||
|
Joins("JOIN product_warehouses pw ON pw.id = stock_logs.product_warehouse_id").
|
||||||
|
Joins("JOIN warehouses w ON w.id = pw.warehouse_id")
|
||||||
|
db = m.ApplyScopeFilter(db, scope, "w.location_id")
|
||||||
|
}
|
||||||
db = s.withRelations(db)
|
db = s.withRelations(db)
|
||||||
|
|
||||||
db = db.Where("loggable_type = ?", string(utils.StockLogTypeAdjustment))
|
db = db.Where("loggable_type = ?", string(utils.StockLogTypeAdjustment))
|
||||||
|
|||||||
@@ -140,6 +140,15 @@ func (r *MarketingDeliveryProductRepositoryImpl) GetAllWithFilters(ctx context.C
|
|||||||
Joins("JOIN marketings ON marketings.id = marketing_products.marketing_id").
|
Joins("JOIN marketings ON marketings.id = marketing_products.marketing_id").
|
||||||
Where("marketing_delivery_products.delivery_date IS NOT NULL")
|
Where("marketing_delivery_products.delivery_date IS NOT NULL")
|
||||||
|
|
||||||
|
if len(filters.AllowedLocationIDs) > 0 {
|
||||||
|
if !containsJoin(db, "product_warehouses") {
|
||||||
|
db = db.Joins("JOIN product_warehouses ON product_warehouses.id = marketing_products.product_warehouse_id")
|
||||||
|
}
|
||||||
|
db = db.Joins("JOIN project_flock_kandangs ON project_flock_kandangs.id = product_warehouses.project_flock_kandang_id").
|
||||||
|
Joins("JOIN project_flocks ON project_flocks.id = project_flock_kandangs.project_flock_id").
|
||||||
|
Where("project_flocks.location_id IN ?", filters.AllowedLocationIDs)
|
||||||
|
}
|
||||||
|
|
||||||
if filters.ProductId > 0 || filters.WarehouseId > 0 || filters.Search != "" || filters.MarketingType != "" {
|
if filters.ProductId > 0 || filters.WarehouseId > 0 || filters.Search != "" || filters.MarketingType != "" {
|
||||||
db = db.Joins("LEFT JOIN product_warehouses ON product_warehouses.id = marketing_products.product_warehouse_id")
|
db = db.Joins("LEFT JOIN product_warehouses ON product_warehouses.id = marketing_products.product_warehouse_id")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,6 +67,10 @@ func (s deliveryOrdersService) withRelations(db *gorm.DB) *gorm.DB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s deliveryOrdersService) getMarketingWithDeliveries(c *fiber.Ctx, marketingId uint) (*dto.MarketingDetailDTO, error) {
|
func (s deliveryOrdersService) getMarketingWithDeliveries(c *fiber.Ctx, marketingId uint) (*dto.MarketingDetailDTO, error) {
|
||||||
|
if err := m.EnsureMarketingAccess(c, s.MarketingRepo.DB(), marketingId); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
marketing, err := s.MarketingRepo.GetByID(c.Context(), marketingId, s.withRelations)
|
marketing, err := s.MarketingRepo.GetByID(c.Context(), marketingId, s.withRelations)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch marketing")
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch marketing")
|
||||||
@@ -91,6 +95,11 @@ func (s deliveryOrdersService) GetAll(c *fiber.Ctx, params *validation.DeliveryO
|
|||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scope, err := m.ResolveLocationScope(c, s.MarketingRepo.DB())
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
offset := (params.Page - 1) * params.Limit
|
offset := (params.Page - 1) * params.Limit
|
||||||
|
|
||||||
marketings, total, err := s.MarketingRepo.GetAll(c.Context(), offset, params.Limit, func(db *gorm.DB) *gorm.DB {
|
marketings, total, err := s.MarketingRepo.GetAll(c.Context(), offset, params.Limit, func(db *gorm.DB) *gorm.DB {
|
||||||
@@ -102,6 +111,18 @@ func (s deliveryOrdersService) GetAll(c *fiber.Ctx, params *validation.DeliveryO
|
|||||||
Preload("Products.ProductWarehouse.Warehouse").
|
Preload("Products.ProductWarehouse.Warehouse").
|
||||||
Preload("Products.DeliveryProduct")
|
Preload("Products.DeliveryProduct")
|
||||||
|
|
||||||
|
if scope.Restrict {
|
||||||
|
if len(scope.IDs) == 0 {
|
||||||
|
return db.Where("1 = 0")
|
||||||
|
}
|
||||||
|
db = db.
|
||||||
|
Joins("JOIN marketing_products mp ON mp.marketing_id = marketings.id").
|
||||||
|
Joins("JOIN product_warehouses pw ON pw.id = mp.product_warehouse_id").
|
||||||
|
Joins("JOIN warehouses w ON w.id = pw.warehouse_id").
|
||||||
|
Where("w.location_id IN ?", scope.IDs).
|
||||||
|
Distinct("marketings.*")
|
||||||
|
}
|
||||||
|
|
||||||
if params.MarketingId != 0 {
|
if params.MarketingId != 0 {
|
||||||
return db.Where("id = ?", params.MarketingId)
|
return db.Where("id = ?", params.MarketingId)
|
||||||
}
|
}
|
||||||
@@ -130,6 +151,9 @@ func (s deliveryOrdersService) GetAll(c *fiber.Ctx, params *validation.DeliveryO
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s deliveryOrdersService) GetOne(c *fiber.Ctx, id uint) (*dto.MarketingDetailDTO, error) {
|
func (s deliveryOrdersService) GetOne(c *fiber.Ctx, id uint) (*dto.MarketingDetailDTO, error) {
|
||||||
|
if err := m.EnsureMarketingAccess(c, s.MarketingRepo.DB(), id); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
marketing, err := s.MarketingRepo.GetByID(c.Context(), id, s.withRelations)
|
marketing, err := s.MarketingRepo.GetByID(c.Context(), id, s.withRelations)
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
@@ -169,6 +193,10 @@ func (s *deliveryOrdersService) CreateOne(c *fiber.Ctx, req *validation.Delivery
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := m.EnsureMarketingAccess(c, s.MarketingRepo.DB(), req.MarketingId); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
if err := commonSvc.EnsureRelations(c.Context(),
|
if err := commonSvc.EnsureRelations(c.Context(),
|
||||||
commonSvc.RelationCheck{Name: "Marketing", ID: &req.MarketingId, Exists: s.MarketingRepo.IdExists},
|
commonSvc.RelationCheck{Name: "Marketing", ID: &req.MarketingId, Exists: s.MarketingRepo.IdExists},
|
||||||
); err != nil {
|
); err != nil {
|
||||||
@@ -303,6 +331,10 @@ func (s deliveryOrdersService) UpdateOne(c *fiber.Ctx, req *validation.DeliveryO
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := m.EnsureMarketingAccess(c, s.MarketingRepo.DB(), id); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
if err := commonSvc.EnsureRelations(c.Context(),
|
if err := commonSvc.EnsureRelations(c.Context(),
|
||||||
commonSvc.RelationCheck{Name: "Marketing", ID: &id, Exists: s.MarketingRepo.IdExists},
|
commonSvc.RelationCheck{Name: "Marketing", ID: &id, Exists: s.MarketingRepo.IdExists},
|
||||||
); err != nil {
|
); err != nil {
|
||||||
|
|||||||
@@ -70,6 +70,10 @@ func (s salesOrdersService) withRelations(db *gorm.DB) *gorm.DB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s salesOrdersService) getOne(c *fiber.Ctx, id uint) (*entity.Marketing, error) {
|
func (s salesOrdersService) getOne(c *fiber.Ctx, id uint) (*entity.Marketing, error) {
|
||||||
|
if err := m.EnsureMarketingAccess(c, s.MarketingRepo.DB(), id); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
marketing, err := s.MarketingRepo.GetByID(c.Context(), id, s.withRelations)
|
marketing, err := s.MarketingRepo.GetByID(c.Context(), id, s.withRelations)
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return nil, fiber.NewError(fiber.StatusNotFound, "SalesOrders not found")
|
return nil, fiber.NewError(fiber.StatusNotFound, "SalesOrders not found")
|
||||||
@@ -108,6 +112,9 @@ func (s *salesOrdersService) CreateOne(c *fiber.Ctx, req *validation.Create) (*e
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, item := range req.MarketingProducts {
|
for _, item := range req.MarketingProducts {
|
||||||
|
if err := m.EnsureProductWarehouseAccess(c, s.MarketingRepo.DB(), item.ProductWarehouseId); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
if err := commonSvc.EnsureRelations(c.Context(),
|
if err := commonSvc.EnsureRelations(c.Context(),
|
||||||
commonSvc.RelationCheck{Name: "ProductWarehouse", ID: &item.ProductWarehouseId, Exists: s.ProductWarehouseRepo.IdExists},
|
commonSvc.RelationCheck{Name: "ProductWarehouse", ID: &item.ProductWarehouseId, Exists: s.ProductWarehouseRepo.IdExists},
|
||||||
); err != nil {
|
); err != nil {
|
||||||
@@ -197,6 +204,10 @@ func (s salesOrdersService) UpdateOne(c *fiber.Ctx, req *validation.Update, id u
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := m.EnsureMarketingAccess(c, s.MarketingRepo.DB(), id); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
actorID, err := m.ActorIDFromContext(c)
|
actorID, err := m.ActorIDFromContext(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -220,6 +231,9 @@ func (s salesOrdersService) UpdateOne(c *fiber.Ctx, req *validation.Update, id u
|
|||||||
|
|
||||||
if len(req.MarketingProducts) > 0 {
|
if len(req.MarketingProducts) > 0 {
|
||||||
for _, item := range req.MarketingProducts {
|
for _, item := range req.MarketingProducts {
|
||||||
|
if err := m.EnsureProductWarehouseAccess(c, s.MarketingRepo.DB(), item.ProductWarehouseId); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
if err := commonSvc.EnsureRelations(c.Context(),
|
if err := commonSvc.EnsureRelations(c.Context(),
|
||||||
commonSvc.RelationCheck{Name: "ProductWarehouse", ID: &item.ProductWarehouseId, Exists: s.ProductWarehouseRepo.IdExists},
|
commonSvc.RelationCheck{Name: "ProductWarehouse", ID: &item.ProductWarehouseId, Exists: s.ProductWarehouseRepo.IdExists},
|
||||||
); err != nil {
|
); err != nil {
|
||||||
@@ -391,6 +405,10 @@ func (s salesOrdersService) UpdateOne(c *fiber.Ctx, req *validation.Update, id u
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s salesOrdersService) DeleteOne(c *fiber.Ctx, id uint) error {
|
func (s salesOrdersService) DeleteOne(c *fiber.Ctx, id uint) error {
|
||||||
|
if err := m.EnsureMarketingAccess(c, s.MarketingRepo.DB(), id); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
marketing, err := s.MarketingRepo.GetByID(c.Context(), id, s.withRelations)
|
marketing, err := s.MarketingRepo.GetByID(c.Context(), id, s.withRelations)
|
||||||
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
@@ -455,6 +473,12 @@ func (s salesOrdersService) Approval(c *fiber.Ctx, req *validation.Approve) ([]e
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, id := range req.ApprovableIds {
|
||||||
|
if err := m.EnsureMarketingAccess(c, s.MarketingRepo.DB(), id); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
actorID, err := m.ActorIDFromContext(c)
|
actorID, err := m.ActorIDFromContext(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -103,6 +103,9 @@ func (s *kandangService) CreateOne(c *fiber.Ctx, req *validation.Create) (*entit
|
|||||||
if err := s.Validate.Struct(req); err != nil {
|
if err := s.Validate.Struct(req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if err := m.EnsureLocationAccess(c, s.Repository.DB(), req.LocationId); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
if exists, err := s.Repository.NameExists(c.Context(), req.Name, nil); err != nil {
|
if exists, err := s.Repository.NameExists(c.Context(), req.Name, nil); err != nil {
|
||||||
s.Log.Errorf("Failed to check kandang name: %+v", err)
|
s.Log.Errorf("Failed to check kandang name: %+v", err)
|
||||||
@@ -177,6 +180,14 @@ func (s kandangService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uint)
|
|||||||
if err := s.Validate.Struct(req); err != nil {
|
if err := s.Validate.Struct(req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if err := m.EnsureKandangAccess(c, s.Repository.DB(), id); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if req.LocationId != nil {
|
||||||
|
if err := m.EnsureLocationAccess(c, s.Repository.DB(), *req.LocationId); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
existing, err := s.Repository.GetByID(c.Context(), id, nil)
|
existing, err := s.Repository.GetByID(c.Context(), id, nil)
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
@@ -268,6 +279,10 @@ func (s kandangService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uint)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s kandangService) DeleteOne(c *fiber.Ctx, id uint) error {
|
func (s kandangService) DeleteOne(c *fiber.Ctx, id uint) error {
|
||||||
|
if err := m.EnsureKandangAccess(c, s.Repository.DB(), id); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if err := s.Repository.DeleteOne(c.Context(), id); err != nil {
|
if err := s.Repository.DeleteOne(c.Context(), id); err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return fiber.NewError(fiber.StatusNotFound, "Kandang not found")
|
return fiber.NewError(fiber.StatusNotFound, "Kandang not found")
|
||||||
|
|||||||
@@ -128,6 +128,19 @@ func (s *warehouseService) CreateOne(c *fiber.Ctx, req *validation.Create) (*ent
|
|||||||
if err := validateWarehouseTypeRequirements(typ, &req.AreaId, req.LocationId, req.KandangId); err != nil {
|
if err := validateWarehouseTypeRequirements(typ, &req.AreaId, req.LocationId, req.KandangId); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if err := m.EnsureAreaAccess(c, s.Repository.DB(), req.AreaId); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if req.LocationId != nil {
|
||||||
|
if err := m.EnsureLocationAccess(c, s.Repository.DB(), *req.LocationId); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if req.KandangId != nil {
|
||||||
|
if err := m.EnsureKandangAccess(c, s.Repository.DB(), *req.KandangId); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//? Check relation area, location, and kandang
|
//? Check relation area, location, and kandang
|
||||||
if err := common.EnsureRelations(c.Context(),
|
if err := common.EnsureRelations(c.Context(),
|
||||||
@@ -166,6 +179,21 @@ func (s warehouseService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uin
|
|||||||
if err := s.Validate.Struct(req); err != nil {
|
if err := s.Validate.Struct(req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if req.AreaId != nil {
|
||||||
|
if err := m.EnsureAreaAccess(c, s.Repository.DB(), *req.AreaId); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if req.LocationId != nil {
|
||||||
|
if err := m.EnsureLocationAccess(c, s.Repository.DB(), *req.LocationId); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if req.KandangId != nil {
|
||||||
|
if err := m.EnsureKandangAccess(c, s.Repository.DB(), *req.KandangId); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
existing, err := s.GetOne(c, id)
|
existing, err := s.GetOne(c, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -243,6 +271,10 @@ func (s warehouseService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uin
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s warehouseService) DeleteOne(c *fiber.Ctx, id uint) error {
|
func (s warehouseService) DeleteOne(c *fiber.Ctx, id uint) error {
|
||||||
|
if err := m.EnsureWarehouseAccess(c, s.Repository.DB(), id); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if err := s.Repository.DeleteOne(c.Context(), id); err != nil {
|
if err := s.Repository.DeleteOne(c.Context(), id); err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return fiber.NewError(fiber.StatusNotFound, "Warehouse not found")
|
return fiber.NewError(fiber.StatusNotFound, "Warehouse not found")
|
||||||
|
|||||||
@@ -101,6 +101,16 @@ func (s recordingService) GetAll(c *fiber.Ctx, params *validation.Query) ([]enti
|
|||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scope, err := m.ResolveLocationScope(c, s.Repository.DB())
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
if params.ProjectFlockKandangId != 0 {
|
||||||
|
if err := m.EnsureProjectFlockKandangAccess(c, s.Repository.DB(), 0, params.ProjectFlockKandangId); err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
limit := params.Limit
|
limit := params.Limit
|
||||||
if limit == 0 {
|
if limit == 0 {
|
||||||
limit = 10
|
limit = 10
|
||||||
@@ -113,6 +123,15 @@ func (s recordingService) GetAll(c *fiber.Ctx, params *validation.Query) ([]enti
|
|||||||
|
|
||||||
recordings, total, err := s.Repository.GetAll(c.Context(), offset, limit, func(db *gorm.DB) *gorm.DB {
|
recordings, total, err := s.Repository.GetAll(c.Context(), offset, limit, func(db *gorm.DB) *gorm.DB {
|
||||||
db = s.Repository.WithRelations(db)
|
db = s.Repository.WithRelations(db)
|
||||||
|
if scope.Restrict {
|
||||||
|
if len(scope.IDs) == 0 {
|
||||||
|
return db.Where("1 = 0")
|
||||||
|
}
|
||||||
|
db = db.
|
||||||
|
Joins("JOIN project_flock_kandangs pfk ON pfk.id = recordings.project_flock_kandangs_id").
|
||||||
|
Joins("JOIN project_flocks pf ON pf.id = pfk.project_flock_id")
|
||||||
|
db = m.ApplyScopeFilter(db, scope, "pf.location_id")
|
||||||
|
}
|
||||||
if params.ProjectFlockKandangId != 0 {
|
if params.ProjectFlockKandangId != 0 {
|
||||||
db = db.Where("project_flock_kandangs_id = ?", params.ProjectFlockKandangId)
|
db = db.Where("project_flock_kandangs_id = ?", params.ProjectFlockKandangId)
|
||||||
}
|
}
|
||||||
@@ -133,6 +152,10 @@ func (s recordingService) GetAll(c *fiber.Ctx, params *validation.Query) ([]enti
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s recordingService) GetOne(c *fiber.Ctx, id uint) (*entity.Recording, error) {
|
func (s recordingService) GetOne(c *fiber.Ctx, id uint) (*entity.Recording, error) {
|
||||||
|
if err := m.EnsureRecordingAccess(c, s.Repository.DB(), id); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
recording, err := s.Repository.GetByID(c.Context(), id, func(db *gorm.DB) *gorm.DB {
|
recording, err := s.Repository.GetByID(c.Context(), id, func(db *gorm.DB) *gorm.DB {
|
||||||
return s.Repository.WithRelations(db)
|
return s.Repository.WithRelations(db)
|
||||||
})
|
})
|
||||||
@@ -156,6 +179,9 @@ func (s recordingService) GetNextDay(c *fiber.Ctx, projectFlockKandangId uint) (
|
|||||||
if projectFlockKandangId == 0 {
|
if projectFlockKandangId == 0 {
|
||||||
return 0, fiber.NewError(fiber.StatusBadRequest, "project_flock_kandang_id is required")
|
return 0, fiber.NewError(fiber.StatusBadRequest, "project_flock_kandang_id is required")
|
||||||
}
|
}
|
||||||
|
if err := m.EnsureProjectFlockKandangAccess(c, s.Repository.DB(), 0, projectFlockKandangId); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
db := s.Repository.DB().WithContext(c.Context())
|
db := s.Repository.DB().WithContext(c.Context())
|
||||||
next, err := s.Repository.GenerateNextDay(db, projectFlockKandangId)
|
next, err := s.Repository.GenerateNextDay(db, projectFlockKandangId)
|
||||||
@@ -171,6 +197,9 @@ func (s *recordingService) CreateOne(c *fiber.Ctx, req *validation.Create) (*ent
|
|||||||
if err := s.Validate.Struct(req); err != nil {
|
if err := s.Validate.Struct(req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if err := m.EnsureProjectFlockKandangAccess(c, s.Repository.DB(), 0, req.ProjectFlockKandangId); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
ctx := c.Context()
|
ctx := c.Context()
|
||||||
recordTime := time.Now().UTC()
|
recordTime := time.Now().UTC()
|
||||||
@@ -320,6 +349,9 @@ func (s recordingService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uin
|
|||||||
if err := s.Validate.Struct(req); err != nil {
|
if err := s.Validate.Struct(req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if err := m.EnsureRecordingAccess(c, s.Repository.DB(), id); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
if req.Stocks == nil && req.Depletions == nil && req.Eggs == nil {
|
if req.Stocks == nil && req.Depletions == nil && req.Eggs == nil {
|
||||||
return s.GetOne(c, id)
|
return s.GetOne(c, id)
|
||||||
@@ -535,6 +567,11 @@ func (s recordingService) Approval(c *fiber.Ctx, req *validation.Approve) ([]ent
|
|||||||
if err := s.Validate.Struct(req); err != nil {
|
if err := s.Validate.Struct(req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
for _, id := range req.ApprovableIds {
|
||||||
|
if err := m.EnsureRecordingAccess(c, s.Repository.DB(), id); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
actionValue := strings.ToUpper(strings.TrimSpace(req.Action))
|
actionValue := strings.ToUpper(strings.TrimSpace(req.Action))
|
||||||
var action entity.ApprovalAction
|
var action entity.ApprovalAction
|
||||||
@@ -612,6 +649,9 @@ func (s recordingService) Approval(c *fiber.Ctx, req *validation.Approve) ([]ent
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s recordingService) DeleteOne(c *fiber.Ctx, id uint) error {
|
func (s recordingService) DeleteOne(c *fiber.Ctx, id uint) error {
|
||||||
|
if err := m.EnsureRecordingAccess(c, s.Repository.DB(), id); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
ctx := c.Context()
|
ctx := c.Context()
|
||||||
|
|
||||||
return s.Repository.DB().WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
return s.Repository.DB().WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||||
|
|||||||
@@ -107,10 +107,25 @@ func (s transferLayingService) GetAll(c *fiber.Ctx, params *validation.Query) ([
|
|||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scope, err := m.ResolveLocationScope(c, s.Repository.DB())
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
offset := (params.Page - 1) * params.Limit
|
offset := (params.Page - 1) * params.Limit
|
||||||
|
|
||||||
transferLayings, total, err := s.Repository.GetAll(c.Context(), offset, params.Limit, func(db *gorm.DB) *gorm.DB {
|
transferLayings, total, err := s.Repository.GetAll(c.Context(), offset, params.Limit, func(db *gorm.DB) *gorm.DB {
|
||||||
db = s.withRelations(db)
|
db = s.withRelations(db)
|
||||||
|
if scope.Restrict {
|
||||||
|
if len(scope.IDs) == 0 {
|
||||||
|
return db.Where("1 = 0")
|
||||||
|
}
|
||||||
|
db = db.
|
||||||
|
Joins("JOIN project_flocks pf_from ON pf_from.id = laying_transfers.from_project_flock_id").
|
||||||
|
Joins("JOIN project_flocks pf_to ON pf_to.id = laying_transfers.to_project_flock_id").
|
||||||
|
Where("(pf_from.location_id IN ? OR pf_to.location_id IN ?)", scope.IDs, scope.IDs).
|
||||||
|
Distinct("laying_transfers.*")
|
||||||
|
}
|
||||||
db = db.Order("created_at DESC")
|
db = db.Order("created_at DESC")
|
||||||
return db
|
return db
|
||||||
})
|
})
|
||||||
@@ -134,6 +149,10 @@ func (s transferLayingService) GetAll(c *fiber.Ctx, params *validation.Query) ([
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s transferLayingService) GetOne(c *fiber.Ctx, id uint) (*entity.LayingTransfer, error) {
|
func (s transferLayingService) GetOne(c *fiber.Ctx, id uint) (*entity.LayingTransfer, error) {
|
||||||
|
if err := m.EnsureLayingTransferAccess(c, s.Repository.DB(), id); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
transferLaying, err := s.Repository.GetByID(c.Context(), id, s.withRelations)
|
transferLaying, err := s.Repository.GetByID(c.Context(), id, s.withRelations)
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return nil, fiber.NewError(fiber.StatusNotFound, "TransferLaying not found")
|
return nil, fiber.NewError(fiber.StatusNotFound, "TransferLaying not found")
|
||||||
@@ -167,6 +186,12 @@ func (s *transferLayingService) CreateOne(c *fiber.Ctx, req *validation.Create)
|
|||||||
if err := s.Validate.Struct(req); err != nil {
|
if err := s.Validate.Struct(req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if err := m.EnsureProjectFlockAccess(c, s.Repository.DB(), req.SourceProjectFlockId); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := m.EnsureProjectFlockAccess(c, s.Repository.DB(), req.TargetProjectFlockId); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
actorID, err := m.ActorIDFromContext(c)
|
actorID, err := m.ActorIDFromContext(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -375,6 +400,15 @@ func (s *transferLayingService) UpdateOne(c *fiber.Ctx, req *validation.Update,
|
|||||||
if err := s.Validate.Struct(req); err != nil {
|
if err := s.Validate.Struct(req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if err := m.EnsureLayingTransferAccess(c, s.Repository.DB(), id); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := m.EnsureProjectFlockAccess(c, s.Repository.DB(), req.SourceProjectFlockId); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := m.EnsureProjectFlockAccess(c, s.Repository.DB(), req.TargetProjectFlockId); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
existingTransfer, err := s.Repository.GetByID(c.Context(), id, func(db *gorm.DB) *gorm.DB {
|
existingTransfer, err := s.Repository.GetByID(c.Context(), id, func(db *gorm.DB) *gorm.DB {
|
||||||
return db.Preload("Sources.ProductWarehouse").Preload("Targets")
|
return db.Preload("Sources.ProductWarehouse").Preload("Targets")
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
|
|
||||||
type UniformityRepository interface {
|
type UniformityRepository interface {
|
||||||
repository.BaseRepository[entity.ProjectFlockKandangUniformity]
|
repository.BaseRepository[entity.ProjectFlockKandangUniformity]
|
||||||
GetAllWithFilters(ctx context.Context, offset, limit int, params *validation.Query) ([]entity.ProjectFlockKandangUniformity, int64, error)
|
GetAllWithFilters(ctx context.Context, offset, limit int, params *validation.Query, modifiers ...func(*gorm.DB) *gorm.DB) ([]entity.ProjectFlockKandangUniformity, int64, error)
|
||||||
WithDefaultRelations() func(*gorm.DB) *gorm.DB
|
WithDefaultRelations() func(*gorm.DB) *gorm.DB
|
||||||
DeleteByProjectFlockKandangIDs(ctx context.Context, projectFlockKandangIDs []uint) error
|
DeleteByProjectFlockKandangIDs(ctx context.Context, projectFlockKandangIDs []uint) error
|
||||||
}
|
}
|
||||||
@@ -27,9 +27,15 @@ func NewUniformityRepository(db *gorm.DB) UniformityRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *UniformityRepositoryImpl) GetAllWithFilters(ctx context.Context, offset, limit int, params *validation.Query) ([]entity.ProjectFlockKandangUniformity, int64, error) {
|
func (r *UniformityRepositoryImpl) GetAllWithFilters(ctx context.Context, offset, limit int, params *validation.Query, modifiers ...func(*gorm.DB) *gorm.DB) ([]entity.ProjectFlockKandangUniformity, int64, error) {
|
||||||
return r.GetAll(ctx, offset, limit, func(db *gorm.DB) *gorm.DB {
|
return r.GetAll(ctx, offset, limit, func(db *gorm.DB) *gorm.DB {
|
||||||
return r.applyQueryFilters(r.WithDefaultRelations()(db), params)
|
db = r.applyQueryFilters(r.WithDefaultRelations()(db), params)
|
||||||
|
for _, modifier := range modifiers {
|
||||||
|
if modifier != nil {
|
||||||
|
db = modifier(db)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return db
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -87,8 +87,24 @@ func (s uniformityService) GetAll(c *fiber.Ctx, params *validation.Query) ([]ent
|
|||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scope, err := m.ResolveLocationScope(c, s.Repository.DB())
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
offset := (params.Page - 1) * params.Limit
|
offset := (params.Page - 1) * params.Limit
|
||||||
uniformitys, total, err := s.Repository.GetAllWithFilters(c.Context(), offset, params.Limit, params)
|
uniformitys, total, err := s.Repository.GetAllWithFilters(c.Context(), offset, params.Limit, params, func(db *gorm.DB) *gorm.DB {
|
||||||
|
if scope.Restrict {
|
||||||
|
if len(scope.IDs) == 0 {
|
||||||
|
return db.Where("1 = 0")
|
||||||
|
}
|
||||||
|
db = db.
|
||||||
|
Joins("JOIN project_flock_kandangs pfk ON pfk.id = project_flock_kandang_uniformities.project_flock_kandang_id").
|
||||||
|
Joins("JOIN project_flocks pf ON pf.id = pfk.project_flock_id")
|
||||||
|
db = m.ApplyScopeFilter(db, scope, "pf.location_id")
|
||||||
|
}
|
||||||
|
return db
|
||||||
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Log.Errorf("Failed to get uniformitys: %+v", err)
|
s.Log.Errorf("Failed to get uniformitys: %+v", err)
|
||||||
@@ -101,6 +117,10 @@ func (s uniformityService) GetAll(c *fiber.Ctx, params *validation.Query) ([]ent
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s uniformityService) GetOne(c *fiber.Ctx, id uint) (*entity.ProjectFlockKandangUniformity, error) {
|
func (s uniformityService) GetOne(c *fiber.Ctx, id uint) (*entity.ProjectFlockKandangUniformity, error) {
|
||||||
|
if err := m.EnsureUniformityAccess(c, s.Repository.DB(), id); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
uniformity, err := s.Repository.GetByID(c.Context(), id, s.Repository.WithDefaultRelations())
|
uniformity, err := s.Repository.GetByID(c.Context(), id, s.Repository.WithDefaultRelations())
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return nil, fiber.NewError(fiber.StatusNotFound, "Uniformity not found")
|
return nil, fiber.NewError(fiber.StatusNotFound, "Uniformity not found")
|
||||||
@@ -326,6 +346,9 @@ func (s *uniformityService) CreateOne(c *fiber.Ctx, req *validation.Create, file
|
|||||||
if err := s.Validate.Struct(req); err != nil {
|
if err := s.Validate.Struct(req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if err := m.EnsureProjectFlockKandangAccess(c, s.Repository.DB(), 0, req.ProjectFlockKandangId); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
if s.ProjectFlockKandangRepo == nil {
|
if s.ProjectFlockKandangRepo == nil {
|
||||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Project flock kandang repository not available")
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Project flock kandang repository not available")
|
||||||
}
|
}
|
||||||
@@ -439,6 +462,9 @@ func (s uniformityService) UpdateOne(c *fiber.Ctx, req *validation.Update, id ui
|
|||||||
if err := s.Validate.Struct(req); err != nil {
|
if err := s.Validate.Struct(req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if err := m.EnsureUniformityAccess(c, s.Repository.DB(), id); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
updateBody := make(map[string]any)
|
updateBody := make(map[string]any)
|
||||||
var uniformDate *time.Time
|
var uniformDate *time.Time
|
||||||
@@ -627,6 +653,10 @@ func (s *uniformityService) ensureUniqueUniformity(ctx context.Context, id uint,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s uniformityService) DeleteOne(c *fiber.Ctx, id uint) error {
|
func (s uniformityService) DeleteOne(c *fiber.Ctx, id uint) error {
|
||||||
|
if err := m.EnsureUniformityAccess(c, s.Repository.DB(), id); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if err := s.Repository.DeleteOne(c.Context(), id); err != nil {
|
if err := s.Repository.DeleteOne(c.Context(), id); err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return fiber.NewError(fiber.StatusNotFound, "Uniformity not found")
|
return fiber.NewError(fiber.StatusNotFound, "Uniformity not found")
|
||||||
@@ -657,6 +687,11 @@ func (s uniformityService) Approval(c *fiber.Ctx, req *validation.Approve) ([]en
|
|||||||
if len(ids) == 0 {
|
if len(ids) == 0 {
|
||||||
return nil, fiber.NewError(fiber.StatusBadRequest, "approvable_ids must contain at least one id")
|
return nil, fiber.NewError(fiber.StatusBadRequest, "approvable_ids must contain at least one id")
|
||||||
}
|
}
|
||||||
|
for _, id := range ids {
|
||||||
|
if err := m.EnsureUniformityAccess(c, s.Repository.DB(), id); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
step := utils.UniformityStepPengajuan
|
step := utils.UniformityStepPengajuan
|
||||||
if action == entity.ApprovalActionApproved {
|
if action == entity.ApprovalActionApproved {
|
||||||
|
|||||||
@@ -106,6 +106,18 @@ func (c *RepportController) GetMarketing(ctx *fiber.Ctx) error {
|
|||||||
SortOrder: ctx.Query("sort_order", ""),
|
SortOrder: ctx.Query("sort_order", ""),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
locationScope, err := m.ResolveLocationScope(ctx, c.RepportService.DB())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if locationScope.Restrict {
|
||||||
|
allowed := toInt64Slice(locationScope.IDs)
|
||||||
|
if len(allowed) == 0 {
|
||||||
|
allowed = []int64{-1}
|
||||||
|
}
|
||||||
|
query.AllowedLocationIDs = allowed
|
||||||
|
}
|
||||||
|
|
||||||
if query.Page < 1 || query.Limit < 1 {
|
if query.Page < 1 || query.Limit < 1 {
|
||||||
return fiber.NewError(fiber.StatusBadRequest, "page and limit must be greater than 0")
|
return fiber.NewError(fiber.StatusBadRequest, "page and limit must be greater than 0")
|
||||||
}
|
}
|
||||||
@@ -283,6 +295,10 @@ func (c *RepportController) GetProductionResult(ctx *fiber.Ctx) error {
|
|||||||
ProjectFlockKandangID: uint(projectFlockKandangID),
|
ProjectFlockKandangID: uint(projectFlockKandangID),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := m.EnsureProjectFlockKandangAccess(ctx, c.RepportService.DB(), 0, query.ProjectFlockKandangID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if query.Page < 1 || query.Limit < 1 {
|
if query.Page < 1 || query.Limit < 1 {
|
||||||
return fiber.NewError(fiber.StatusBadRequest, "page and limit must be greater than 0")
|
return fiber.NewError(fiber.StatusBadRequest, "page and limit must be greater than 0")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ type MarketingQuery struct {
|
|||||||
EndDate string `query:"end_date" validate:"omitempty,datetime=2006-01-02"`
|
EndDate string `query:"end_date" validate:"omitempty,datetime=2006-01-02"`
|
||||||
SortBy string `query:"sort_by" validate:"omitempty,oneof=so_date realization_date customer warehouse product sales_person vehicle_number sales_amount hpp_amount qty average_weight total_weight sales_price hpp_price aging_days"`
|
SortBy string `query:"sort_by" validate:"omitempty,oneof=so_date realization_date customer warehouse product sales_person vehicle_number sales_amount hpp_amount qty average_weight total_weight sales_price hpp_price aging_days"`
|
||||||
SortOrder string `query:"sort_order" validate:"omitempty,oneof=asc desc"`
|
SortOrder string `query:"sort_order" validate:"omitempty,oneof=asc desc"`
|
||||||
|
AllowedLocationIDs []int64 `query:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PurchaseSupplierQuery struct {
|
type PurchaseSupplierQuery struct {
|
||||||
|
|||||||
@@ -39,6 +39,10 @@ type UserProfile struct {
|
|||||||
UserID uint
|
UserID uint
|
||||||
Roles []Role
|
Roles []Role
|
||||||
Permissions []Permission
|
Permissions []Permission
|
||||||
|
AreaIDs []uint
|
||||||
|
LocationIDs []uint
|
||||||
|
AllArea bool
|
||||||
|
AllLocation bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Role describes a role assignment from the SSO profile response.
|
// Role describes a role assignment from the SSO profile response.
|
||||||
@@ -49,10 +53,6 @@ type Role struct {
|
|||||||
ClientID uint
|
ClientID uint
|
||||||
ClientAlias string
|
ClientAlias string
|
||||||
ClientName string
|
ClientName string
|
||||||
AllArea bool
|
|
||||||
AllLocation bool
|
|
||||||
AreaIDs []uint
|
|
||||||
LocationIDs []uint
|
|
||||||
Permissions []Permission
|
Permissions []Permission
|
||||||
RawReference json.RawMessage `json:"-"`
|
RawReference json.RawMessage `json:"-"`
|
||||||
}
|
}
|
||||||
@@ -149,6 +149,10 @@ func fetchProfileFromSSO(ctx context.Context, token string) (*UserProfile, error
|
|||||||
}
|
}
|
||||||
|
|
||||||
roles := envelope.getRoles()
|
roles := envelope.getRoles()
|
||||||
|
areaIDs := envelope.getAreaIDs()
|
||||||
|
locationIDs := envelope.getLocationIDs()
|
||||||
|
allArea := envelope.getAllArea()
|
||||||
|
allLocation := envelope.getAllLocation()
|
||||||
profile := &UserProfile{}
|
profile := &UserProfile{}
|
||||||
|
|
||||||
// Attempt to infer user id if provided.
|
// Attempt to infer user id if provided.
|
||||||
@@ -166,10 +170,6 @@ func fetchProfileFromSSO(ctx context.Context, token string) (*UserProfile, error
|
|||||||
ClientAlias: strings.TrimSpace(r.Client.Alias),
|
ClientAlias: strings.TrimSpace(r.Client.Alias),
|
||||||
ClientName: strings.TrimSpace(r.Client.Name),
|
ClientName: strings.TrimSpace(r.Client.Name),
|
||||||
ClientID: uint(r.Client.ID),
|
ClientID: uint(r.Client.ID),
|
||||||
AllArea: r.AllArea,
|
|
||||||
AllLocation: r.AllLocation,
|
|
||||||
AreaIDs: r.AreaIDs,
|
|
||||||
LocationIDs: r.LocationIDs,
|
|
||||||
}
|
}
|
||||||
rolePerms := make([]Permission, 0, len(r.Permissions))
|
rolePerms := make([]Permission, 0, len(r.Permissions))
|
||||||
for _, p := range r.Permissions {
|
for _, p := range r.Permissions {
|
||||||
@@ -191,6 +191,10 @@ func fetchProfileFromSSO(ctx context.Context, token string) (*UserProfile, error
|
|||||||
}
|
}
|
||||||
profile.Roles = convertedRoles
|
profile.Roles = convertedRoles
|
||||||
profile.Permissions = perms
|
profile.Permissions = perms
|
||||||
|
profile.AreaIDs = areaIDs
|
||||||
|
profile.LocationIDs = locationIDs
|
||||||
|
profile.AllArea = allArea
|
||||||
|
profile.AllLocation = allLocation
|
||||||
|
|
||||||
return profile, nil
|
return profile, nil
|
||||||
}
|
}
|
||||||
@@ -268,9 +272,17 @@ func canonicalPermissionName(name string) string {
|
|||||||
// userInfoEnvelope handles the varying shapes returned by the SSO userinfo endpoint.
|
// userInfoEnvelope handles the varying shapes returned by the SSO userinfo endpoint.
|
||||||
type userInfoEnvelope struct {
|
type userInfoEnvelope struct {
|
||||||
Roles []userInfoRole `json:"roles"`
|
Roles []userInfoRole `json:"roles"`
|
||||||
|
AreaIDs []uint `json:"area_ids"`
|
||||||
|
LocationIDs []uint `json:"location_ids"`
|
||||||
|
AllArea bool `json:"all_area"`
|
||||||
|
AllLocation bool `json:"all_location"`
|
||||||
Data *struct {
|
Data *struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
Roles []userInfoRole `json:"roles"`
|
Roles []userInfoRole `json:"roles"`
|
||||||
|
AreaIDs []uint `json:"area_ids"`
|
||||||
|
LocationIDs []uint `json:"location_ids"`
|
||||||
|
AllArea bool `json:"all_area"`
|
||||||
|
AllLocation bool `json:"all_location"`
|
||||||
} `json:"data"`
|
} `json:"data"`
|
||||||
User *struct {
|
User *struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
@@ -292,14 +304,50 @@ func (e *userInfoEnvelope) getRoles() []userInfoRole {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *userInfoEnvelope) getAreaIDs() []uint {
|
||||||
|
if len(e.AreaIDs) > 0 {
|
||||||
|
return e.AreaIDs
|
||||||
|
}
|
||||||
|
if e.Data != nil && len(e.Data.AreaIDs) > 0 {
|
||||||
|
return e.Data.AreaIDs
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *userInfoEnvelope) getLocationIDs() []uint {
|
||||||
|
if len(e.LocationIDs) > 0 {
|
||||||
|
return e.LocationIDs
|
||||||
|
}
|
||||||
|
if e.Data != nil && len(e.Data.LocationIDs) > 0 {
|
||||||
|
return e.Data.LocationIDs
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *userInfoEnvelope) getAllArea() bool {
|
||||||
|
if e.AllArea {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if e.Data != nil && e.Data.AllArea {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *userInfoEnvelope) getAllLocation() bool {
|
||||||
|
if e.AllLocation {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if e.Data != nil && e.Data.AllLocation {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
type userInfoRole struct {
|
type userInfoRole struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
Key string `json:"key"`
|
Key string `json:"key"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
AllArea bool `json:"all_area"`
|
|
||||||
AllLocation bool `json:"all_location"`
|
|
||||||
AreaIDs []uint `json:"area_ids"`
|
|
||||||
LocationIDs []uint `json:"location_ids"`
|
|
||||||
Client userInfoClient `json:"client"`
|
Client userInfoClient `json:"client"`
|
||||||
Permissions []userInfoPermRaw `json:"permissions"`
|
Permissions []userInfoPermRaw `json:"permissions"`
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user