Allow PF managers to manage subordinate projects
All checks were successful
CI / go (push) Successful in 22s
CI / python (push) Successful in 1s
Build and Deploy / build-and-deploy (push) Successful in 34s

This commit is contained in:
Grendgi
2026-06-11 16:56:23 +03:00
parent c763ff423d
commit 974090df4f
2 changed files with 160 additions and 29 deletions

View File

@@ -64,6 +64,27 @@ func (a *App) ListEmployees(ctx context.Context, isAdmin bool, current *Employee
return scanEmployees(rows)
}
func (a *App) ListEmployeesByPortalUserIDs(ctx context.Context, portalUserIDs []string) ([]Employee, error) {
ids := uniqueNonEmpty(portalUserIDs)
if len(ids) == 0 {
return []Employee{}, nil
}
args := make([]any, 0, len(ids))
placeholders := make([]string, 0, len(ids))
for _, id := range ids {
args = append(args, id)
placeholders = append(placeholders, "?")
}
rows, err := a.DB.QueryContext(ctx, employeeSelect()+`
WHERE e.portal_user_id IN (`+strings.Join(placeholders, ",")+`)
ORDER BY e.name COLLATE NOCASE`, args...)
if err != nil {
return nil, err
}
defer closeRows(rows)
return scanEmployees(rows)
}
type EmployeePayload struct {
Name string `json:"name"`
PortalUserID *string `json:"portal_user_id"`
@@ -218,16 +239,34 @@ func scanEmployees(rows *sql.Rows) ([]Employee, error) {
return items, rows.Err()
}
func uniqueNonEmpty(values []string) []string {
seen := map[string]struct{}{}
out := []string{}
for _, value := range values {
value = strings.TrimSpace(value)
if value == "" {
continue
}
if _, ok := seen[value]; ok {
continue
}
seen[value] = struct{}{}
out = append(out, value)
}
return out
}
type ProjectPayload struct {
Title string `json:"title"`
DealType string `json:"deal_type"`
OurPrice *float64 `json:"our_price"`
Notes *string `json:"notes"`
DLDPermit *string `json:"dld_permit"`
Building *string `json:"building"`
Bedrooms *int64 `json:"bedrooms"`
SizeSqft *float64 `json:"size_sqft"`
OurURL *string `json:"our_url"`
Title string `json:"title"`
DealType string `json:"deal_type"`
OurPrice *float64 `json:"our_price"`
Notes *string `json:"notes"`
DLDPermit *string `json:"dld_permit"`
Building *string `json:"building"`
Bedrooms *int64 `json:"bedrooms"`
SizeSqft *float64 `json:"size_sqft"`
OurURL *string `json:"our_url"`
OwnerPortalUserID *string `json:"owner_portal_user_id"`
}
func (a *App) Summary(ctx context.Context, emp *Employee) (map[string]any, error) {
@@ -295,6 +334,17 @@ func (a *App) ProjectByID(ctx context.Context, ownerID, projectID int64, detail
return p, nil
}
func (a *App) ProjectOwner(ctx context.Context, projectID int64) (*Employee, error) {
row := a.DB.QueryRowContext(ctx, employeeSelect()+`
JOIN projects p ON p.owner_id = e.id
WHERE p.id = ?`, projectID)
emp, err := scanEmployee(row)
if errors.Is(err, sql.ErrNoRows) {
return nil, ErrNotFound
}
return emp, err
}
func (a *App) CreateProject(ctx context.Context, ownerID int64, p ProjectPayload) (*Project, error) {
title := cleanString(p.Title)
if title == "" {