Update monitoring PF competitor tracking
This commit is contained in:
@@ -33,6 +33,8 @@ func (s Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
s.accessMe(w, r)
|
||||
case path == "/api/v1/summary" && r.Method == http.MethodGet:
|
||||
s.summary(w, r)
|
||||
case path == "/api/v1/team/overview" && r.Method == http.MethodGet:
|
||||
s.teamOverview(w, r)
|
||||
case path == "/api/v1/employees":
|
||||
s.employees(w, r)
|
||||
case strings.HasPrefix(path, "/api/v1/employees/"):
|
||||
@@ -86,6 +88,7 @@ func (s Server) accessMe(w http.ResponseWriter, r *http.Request) {
|
||||
"is_admin": isAdmin(r),
|
||||
"portal_user_id": nullablePlain(portalID),
|
||||
"telegram_linked": emp != nil && emp.TGChatID != nil && *emp.TGChatID != "",
|
||||
"can_view_team": canViewTeam(r),
|
||||
"employee": emp,
|
||||
"telegram_bot_username": nullablePlain(botUsername),
|
||||
"telegram_start_command": command,
|
||||
@@ -110,6 +113,19 @@ func (s Server) summary(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(w, http.StatusOK, out)
|
||||
}
|
||||
|
||||
func (s Server) teamOverview(w http.ResponseWriter, r *http.Request) {
|
||||
if !canViewTeam(r) {
|
||||
writeError(w, http.StatusNotFound, "not found")
|
||||
return
|
||||
}
|
||||
items, err := s.App.TeamOverview(r.Context(), subordinatePortalIDs(r), isAdmin(r))
|
||||
if err != nil {
|
||||
writeError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusOK, items)
|
||||
}
|
||||
|
||||
func (s Server) employees(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
@@ -352,45 +368,13 @@ func (s Server) listingItem(w http.ResponseWriter, r *http.Request, path string)
|
||||
writeError(w, http.StatusMethodNotAllowed, "method not allowed")
|
||||
return
|
||||
}
|
||||
deleted, err := s.App.DeleteListing(r.Context(), emp.ID, id)
|
||||
if err != nil {
|
||||
if err := s.App.DeleteListing(r.Context(), emp.ID, id); err != nil {
|
||||
writeError(w, http.StatusNotFound, "listing not found")
|
||||
return
|
||||
}
|
||||
if deleted.OwnerChatID != nil && *deleted.OwnerChatID != "" {
|
||||
_ = s.App.TG.SendMessage(r.Context(), *deleted.OwnerChatID, formatDeletedListingMessage(deleted))
|
||||
}
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
||||
func formatDeletedListingMessage(deleted *DeletedListing) string {
|
||||
listing := deleted.Listing
|
||||
title := "без названия"
|
||||
if listing.Title != nil && *listing.Title != "" {
|
||||
title = *listing.Title
|
||||
}
|
||||
price := "—"
|
||||
if listing.CurrentPrice != nil {
|
||||
currency := "AED"
|
||||
if listing.Currency != nil && *listing.Currency != "" {
|
||||
currency = *listing.Currency
|
||||
}
|
||||
price = strconv.FormatFloat(*listing.CurrentPrice, 'f', 0, 64) + " " + currency
|
||||
}
|
||||
permit := "—"
|
||||
if listing.PermitNumber != nil && *listing.PermitNumber != "" {
|
||||
permit = *listing.PermitNumber
|
||||
}
|
||||
return "🏠 <b>" + deleted.ProjectTitle + "</b>\n" +
|
||||
"Тип: " + deleted.ProjectDeal + " · Изменений: 1\n" +
|
||||
"——————————\n" +
|
||||
"🗑️ <b>Удален конкурент</b> — " + listing.Source + "\n" +
|
||||
title + "\n" +
|
||||
"Последняя цена: " + price + "\n" +
|
||||
"Permit: <code>" + permit + "</code>\n" +
|
||||
listing.URL
|
||||
}
|
||||
|
||||
func (s Server) requireEmployee(w http.ResponseWriter, r *http.Request) (*Employee, bool) {
|
||||
emp, err := s.App.CurrentEmployee(r.Context(), portalUserID(r), true)
|
||||
if errors.Is(err, ErrTelegramRequired) {
|
||||
@@ -412,6 +396,26 @@ func isAdmin(r *http.Request) bool {
|
||||
return r.Header.Get("X-User-Is-Admin") == "1"
|
||||
}
|
||||
|
||||
func canViewTeam(r *http.Request) bool {
|
||||
return isAdmin(r) || r.Header.Get("X-User-Is-Department-Head") == "1"
|
||||
}
|
||||
|
||||
func subordinatePortalIDs(r *http.Request) []string {
|
||||
raw := strings.TrimSpace(r.Header.Get("X-User-Subordinates"))
|
||||
if raw == "" {
|
||||
return []string{}
|
||||
}
|
||||
parts := strings.Split(raw, ",")
|
||||
out := make([]string, 0, len(parts))
|
||||
for _, part := range parts {
|
||||
id := strings.TrimSpace(part)
|
||||
if id != "" {
|
||||
out = append(out, id)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func nullablePlain(value string) *string {
|
||||
if strings.TrimSpace(value) == "" {
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user