Allow PF managers to manage subordinate projects
This commit is contained in:
@@ -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 == "" {
|
||||
|
||||
Reference in New Issue
Block a user