167 lines
5.4 KiB
Go
167 lines
5.4 KiB
Go
package handler
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
|
|
"dealroom/internal/model"
|
|
"dealroom/internal/rbac"
|
|
"dealroom/templates"
|
|
)
|
|
|
|
func (h *Handler) handleDashboard(w http.ResponseWriter, r *http.Request) {
|
|
if r.URL.Path != "/" {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
profile := getProfile(r.Context())
|
|
deals := h.getDeals(profile)
|
|
activities := h.getActivities(profile.OrganizationID, 8)
|
|
|
|
// Count files per deal
|
|
fileCounts := make(map[string]int)
|
|
for _, d := range deals {
|
|
var count int
|
|
h.db.QueryRow("SELECT COUNT(*) FROM files WHERE deal_id = ?", d.ID).Scan(&count)
|
|
fileCounts[d.ID] = count
|
|
d.FileCount = count
|
|
}
|
|
|
|
templates.Dashboard(profile, deals, activities, fileCounts).Render(r.Context(), w)
|
|
}
|
|
|
|
func (h *Handler) handleDealRooms(w http.ResponseWriter, r *http.Request) {
|
|
profile := getProfile(r.Context())
|
|
deals := h.getDeals(profile)
|
|
for _, d := range deals {
|
|
var count int
|
|
h.db.QueryRow("SELECT COUNT(*) FROM files WHERE deal_id = ?", d.ID).Scan(&count)
|
|
d.FileCount = count
|
|
}
|
|
templates.DealRooms(profile, deals).Render(r.Context(), w)
|
|
}
|
|
|
|
func (h *Handler) handleDealRoom(w http.ResponseWriter, r *http.Request) {
|
|
profile := getProfile(r.Context())
|
|
dealID := strings.TrimPrefix(r.URL.Path, "/deals/")
|
|
if dealID == "" {
|
|
http.Redirect(w, r, "/deals", http.StatusSeeOther)
|
|
return
|
|
}
|
|
|
|
var deal model.Deal
|
|
err := h.db.QueryRow(`SELECT id, organization_id, name, description, target_company, stage, deal_size, currency, ioi_date, loi_date, exclusivity_end_date, expected_close_date, close_probability, created_by FROM deals WHERE id = ?`, dealID).Scan(
|
|
&deal.ID, &deal.OrganizationID, &deal.Name, &deal.Description, &deal.TargetCompany, &deal.Stage, &deal.DealSize, &deal.Currency, &deal.IOIDate, &deal.LOIDate, &deal.ExclusivityEnd, &deal.ExpectedCloseDate, &deal.CloseProbability, &deal.CreatedBy)
|
|
if err != nil {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
|
|
folders := h.getFolders(dealID)
|
|
files := h.getFiles(dealID)
|
|
requests := h.getRequests(dealID, profile)
|
|
|
|
templates.DealRoomDetail(profile, &deal, folders, files, requests).Render(r.Context(), w)
|
|
}
|
|
|
|
func (h *Handler) getDeals(profile *model.Profile) []*model.Deal {
|
|
rows, err := h.db.Query("SELECT id, organization_id, name, description, target_company, stage, deal_size, currency, ioi_date, loi_date, exclusivity_end_date, expected_close_date, close_probability, created_by, created_at FROM deals WHERE organization_id = ? AND is_archived = 0 ORDER BY created_at DESC", profile.OrganizationID)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
defer rows.Close()
|
|
|
|
var deals []*model.Deal
|
|
for rows.Next() {
|
|
d := &model.Deal{}
|
|
rows.Scan(&d.ID, &d.OrganizationID, &d.Name, &d.Description, &d.TargetCompany, &d.Stage, &d.DealSize, &d.Currency, &d.IOIDate, &d.LOIDate, &d.ExclusivityEnd, &d.ExpectedCloseDate, &d.CloseProbability, &d.CreatedBy, &d.CreatedAt)
|
|
deals = append(deals, d)
|
|
}
|
|
return deals
|
|
}
|
|
|
|
func (h *Handler) getFolders(dealID string) []*model.Folder {
|
|
rows, err := h.db.Query("SELECT id, deal_id, parent_id, name, description FROM folders WHERE deal_id = ? ORDER BY name", dealID)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
defer rows.Close()
|
|
|
|
var folders []*model.Folder
|
|
for rows.Next() {
|
|
f := &model.Folder{}
|
|
rows.Scan(&f.ID, &f.DealID, &f.ParentID, &f.Name, &f.Description)
|
|
folders = append(folders, f)
|
|
}
|
|
return folders
|
|
}
|
|
|
|
func (h *Handler) getFiles(dealID string) []*model.File {
|
|
rows, err := h.db.Query("SELECT id, deal_id, folder_id, name, file_size, mime_type, status, uploaded_by FROM files WHERE deal_id = ? ORDER BY name", dealID)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
defer rows.Close()
|
|
|
|
var files []*model.File
|
|
for rows.Next() {
|
|
f := &model.File{}
|
|
rows.Scan(&f.ID, &f.DealID, &f.FolderID, &f.Name, &f.FileSize, &f.MimeType, &f.Status, &f.UploadedBy)
|
|
files = append(files, f)
|
|
}
|
|
return files
|
|
}
|
|
|
|
func (h *Handler) getRequests(dealID string, profile *model.Profile) []*model.DiligenceRequest {
|
|
query := "SELECT id, deal_id, item_number, section, description, priority, atlas_status, atlas_note, confidence, buyer_comment, seller_comment, buyer_group FROM diligence_requests WHERE deal_id = ?"
|
|
args := []interface{}{dealID}
|
|
|
|
if rbac.IsBuyer(profile.Role) {
|
|
groups := rbac.BuyerGroups(profile)
|
|
if len(groups) > 0 {
|
|
placeholders := make([]string, len(groups))
|
|
for i, g := range groups {
|
|
placeholders[i] = "?"
|
|
args = append(args, g)
|
|
}
|
|
query += " AND buyer_group IN (" + strings.Join(placeholders, ",") + ")"
|
|
}
|
|
}
|
|
query += " ORDER BY item_number"
|
|
|
|
rows, err := h.db.Query(query, args...)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
defer rows.Close()
|
|
|
|
var reqs []*model.DiligenceRequest
|
|
for rows.Next() {
|
|
r := &model.DiligenceRequest{}
|
|
rows.Scan(&r.ID, &r.DealID, &r.ItemNumber, &r.Section, &r.Description, &r.Priority, &r.AtlasStatus, &r.AtlasNote, &r.Confidence, &r.BuyerComment, &r.SellerComment, &r.BuyerGroup)
|
|
reqs = append(reqs, r)
|
|
}
|
|
return reqs
|
|
}
|
|
|
|
func (h *Handler) getActivities(orgID string, limit int) []*model.DealActivity {
|
|
rows, err := h.db.Query(`
|
|
SELECT a.id, a.deal_id, a.user_id, a.activity_type, a.resource_type, a.resource_name, a.created_at, COALESCE(p.full_name, 'Unknown')
|
|
FROM deal_activity a LEFT JOIN profiles p ON a.user_id = p.id
|
|
WHERE a.organization_id = ?
|
|
ORDER BY a.created_at DESC LIMIT ?
|
|
`, orgID, limit)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
defer rows.Close()
|
|
|
|
var acts []*model.DealActivity
|
|
for rows.Next() {
|
|
a := &model.DealActivity{}
|
|
rows.Scan(&a.ID, &a.DealID, &a.UserID, &a.ActivityType, &a.ResourceType, &a.ResourceName, &a.CreatedAt, &a.UserName)
|
|
acts = append(acts, a)
|
|
}
|
|
return acts
|
|
}
|