Update Tender Approval Status to Include Submitted State and Revise API Documentation

- Changed the approval status from "approved" to "submitted" in various locations, including entity definitions, forms, and service methods, to accurately reflect the tender approval process.
- Updated API documentation in Swagger JSON, YAML, and Go files to describe the new status options ("submitted" and "rejected") and their corresponding descriptions.
- Enhanced the tender approval statistics structures to include a count for submitted tenders, improving the overall data model for tender management.
- These changes ensure clarity in the tender approval workflow and enhance the usability of the API for clients interacting with tender approvals.
This commit is contained in:
n.nakhostin
2025-08-25 13:51:14 +03:30
parent 0e14a11daf
commit 3024998e7e
9 changed files with 89 additions and 88 deletions
+8 -8
View File
@@ -9,8 +9,8 @@ import (
type ApprovalStatus string
const (
ApprovalStatusApproved ApprovalStatus = "approved" // Company approved the tender
ApprovalStatusRejected ApprovalStatus = "rejected" // Company rejected the tender
ApprovalStatusSubmitted ApprovalStatus = "submitted" // Company submitted the tender
ApprovalStatusRejected ApprovalStatus = "rejected" // Company rejected the tender
)
// SubmissionMode represents the submission mode of a tender by a company
@@ -121,9 +121,9 @@ func (ta *TenderApproval) GetID() string {
return ta.ID.Hex()
}
// IsApproved returns true if the tender was approved
func (ta *TenderApproval) IsApproved() bool {
return ta.Status == ApprovalStatusApproved
// IsSubmitted returns true if the tender was submitted
func (ta *TenderApproval) IsSubmitted() bool {
return ta.Status == ApprovalStatusSubmitted
}
// IsRejected returns true if the tender was rejected
@@ -133,12 +133,12 @@ func (ta *TenderApproval) IsRejected() bool {
// HasDecision returns true if a decision has been made
func (ta *TenderApproval) HasDecision() bool {
return ta.Status == ApprovalStatusApproved || ta.Status == ApprovalStatusRejected
return ta.Status == ApprovalStatusSubmitted || ta.Status == ApprovalStatusRejected
}
// Approve approves the tender with optional notes
func (ta *TenderApproval) Approve() {
ta.Status = ApprovalStatusApproved
func (ta *TenderApproval) Submit() {
ta.Status = ApprovalStatusSubmitted
ta.CreatedAt = time.Now().Unix()
}
+9 -9
View File
@@ -4,13 +4,13 @@ package tender_approval
type CreateTenderApprovalForm struct {
TenderID string `json:"tender_id" valid:"required"`
SubmissionMode SubmissionMode `json:"submission_mode" valid:"required,in(self-apply|partnership)"`
Status ApprovalStatus `json:"status,omitempty" valid:"optional,in(approved|rejected)"`
Status ApprovalStatus `json:"status,omitempty" valid:"optional,in(submitted|rejected)"`
}
// UpdateTenderApprovalForm represents the form for updating a tender approval
type UpdateTenderApprovalForm struct {
SubmissionMode *string `json:"submission_mode,omitempty" valid:"optional,in(self-apply|partnership)"`
Status *string `json:"status,omitempty" valid:"optional,in(approved|rejected)"`
Status *string `json:"status,omitempty" valid:"optional,in(submitted|rejected)"`
}
// ListTenderApprovalsForm represents the form for listing tender approvals with filters
@@ -61,17 +61,17 @@ type TenderApprovalSearchForm struct {
// TenderApproval statistics DTOs
type TenderApprovalStatsResponse struct {
TotalApprovals int64 `json:"total_approvals"`
ApprovedTenders int64 `json:"approved_tenders"`
RejectedTenders int64 `json:"rejected_tenders"`
LastUpdated int64 `json:"last_updated"`
TotalApprovals int64 `json:"total_approvals"`
SubmittedTenders int64 `json:"submitted_tenders"`
RejectedTenders int64 `json:"rejected_tenders"`
LastUpdated int64 `json:"last_updated"`
}
// CompanyTenderApprovalStatsResponse represents company-specific tender approval statistics
type CompanyTenderApprovalStatsResponse struct {
CompanyID string `json:"company_id"`
TotalApprovals int64 `json:"total_approvals"`
ApprovedTenders int64 `json:"approved_tenders"`
SubmittedTenders int64 `json:"submitted_tenders"`
RejectedTenders int64 `json:"rejected_tenders"`
SelfApplyCount int64 `json:"self_apply_count"`
PartnershipCount int64 `json:"partnership_count"`
@@ -81,7 +81,7 @@ type CompanyTenderApprovalStatsResponse struct {
// ToggleTenderApprovalForm represents the form for toggling a tender approval
type ToggleTenderApprovalForm struct {
TenderID string `json:"tender_id" valid:"required"`
Status ApprovalStatus `json:"status" valid:"required,in(approved|rejected)"`
Status ApprovalStatus `json:"status" valid:"required,in(submitted|rejected)"`
SubmissionMode SubmissionMode `json:"submission_mode" valid:"required,in(self-apply|partnership)"`
}
@@ -95,7 +95,7 @@ type CompanyTenderApprovalStatsRequest struct {
type AggregatedCompanyStatsResponse struct {
TotalCompanies int64 `json:"total_companies"`
TotalApprovals int64 `json:"total_approvals"`
TotalApprovedTenders int64 `json:"total_approved_tenders"`
TotalSubmittedTenders int64 `json:"total_submitted_tenders"`
TotalRejectedTenders int64 `json:"total_rejected_tenders"`
TotalSelfApplyCount int64 `json:"total_self_apply_count"`
TotalPartnershipCount int64 `json:"total_partnership_count"`
+7 -7
View File
@@ -130,7 +130,7 @@ func (h *Handler) GetTenderApprovalByTenderAndCompany(c echo.Context) error {
// @Accept json
// @Produce json
// @Param submission_mode query string false "Filter by submission mode Enums(self-apply, partnership)"
// @Param status query string false "Filter by status Enums(approved, rejected)"
// @Param status query string false "Filter by status Enums(submitted, rejected)"
// @Success 200 {object} response.APIResponse{data=[]TenderApprovalWithTenderResponse} "Tender approvals retrieved successfully"
// @Failure 400 {object} response.APIResponse "Bad request - Invalid company ID"
// @Failure 500 {object} response.APIResponse "Internal server error"
@@ -160,8 +160,8 @@ func (h *Handler) PublicGetTenderApprovals(c echo.Context) error {
var status *ApprovalStatus
if statusStr != "" {
statusVal := ApprovalStatus(statusStr)
if statusVal != ApprovalStatusApproved && statusVal != ApprovalStatusRejected {
return response.BadRequest(c, "Invalid status value", "Must be 'approved' or 'rejected'")
if statusVal != ApprovalStatusSubmitted && statusVal != ApprovalStatusRejected {
return response.BadRequest(c, "Invalid status value", "Must be 'submitted' or 'rejected'")
}
status = &statusVal
}
@@ -258,11 +258,11 @@ func (h *Handler) GetCompanyTenderApprovalStats(c echo.Context) error {
// GetTenderApprovalsByStatus retrieves tender approvals by status
// @Summary Get tender approvals by status
// @Description Retrieve tender approvals filtered by their status (approved, rejected)
// @Description Retrieve tender approvals filtered by their status (submitted, rejected)
// @Tags Admin-TenderApprovals
// @Accept json
// @Produce json
// @Param status path string true "Tender approval status" Enums(approved, rejected)
// @Param status path string true "Tender approval status" Enums(submitted, rejected)
// @Param limit query integer false "Number of approvals per page (1-100)" minimum(1) maximum(100) default(20)
// @Param offset query integer false "Number of approvals to skip for pagination" minimum(0) default(0)
// @Success 200 {object} response.APIResponse{data=[]TenderApprovalResponse,meta=response.Meta} "Tender approvals retrieved successfully"
@@ -275,8 +275,8 @@ func (h *Handler) GetTenderApprovalsByStatus(c echo.Context) error {
status := ApprovalStatus(statusStr)
// Validate status
if status != ApprovalStatusApproved && status != ApprovalStatusRejected {
return response.BadRequest(c, "Invalid tender approval status", "Must be approved or rejected")
if status != ApprovalStatusSubmitted && status != ApprovalStatusRejected {
return response.BadRequest(c, "Invalid tender approval status", "Must be submitted or rejected")
}
limit := 20
+10 -10
View File
@@ -475,14 +475,14 @@ func (r *tenderApprovalRepository) CountByCompanyID(ctx context.Context, company
func (r *tenderApprovalRepository) GetTenderApprovalStats(ctx context.Context) (*TenderApprovalStatsResponse, error) {
// Get basic counts
totalApprovals, _ := r.Count(ctx)
approvedTenders, _ := r.CountByStatus(ctx, ApprovalStatusApproved)
submittedTenders, _ := r.CountByStatus(ctx, ApprovalStatusSubmitted)
rejectedTenders, _ := r.CountByStatus(ctx, ApprovalStatusRejected)
stats := &TenderApprovalStatsResponse{
TotalApprovals: totalApprovals,
ApprovedTenders: approvedTenders,
RejectedTenders: rejectedTenders,
LastUpdated: time.Now().Unix(),
TotalApprovals: totalApprovals,
SubmittedTenders: submittedTenders,
RejectedTenders: rejectedTenders,
LastUpdated: time.Now().Unix(),
}
return stats, nil
@@ -494,23 +494,23 @@ func (r *tenderApprovalRepository) GetCompanyTenderApprovalStats(ctx context.Con
totalApprovals, _ := r.CountByCompanyID(ctx, companyID)
// Count by status for this company
approvedFilter := bson.M{"company_id": companyID, "status": string(ApprovalStatusApproved)}
approvedTenders, _ := r.ormRepo.Count(ctx, approvedFilter)
submittedFilter := bson.M{"company_id": companyID, "status": string(ApprovalStatusSubmitted)}
submittedTenders, _ := r.ormRepo.Count(ctx, submittedFilter)
rejectedFilter := bson.M{"company_id": companyID, "status": string(ApprovalStatusRejected)}
rejectedTenders, _ := r.ormRepo.Count(ctx, rejectedFilter)
// Count by submission mode for this company
selfApplyFilter := bson.M{"company_id": companyID, "status": string(ApprovalStatusApproved), "submission_mode": string(SubmissionModeSelfApply)}
selfApplyFilter := bson.M{"company_id": companyID, "status": string(ApprovalStatusSubmitted), "submission_mode": string(SubmissionModeSelfApply)}
selfApplyCount, _ := r.ormRepo.Count(ctx, selfApplyFilter)
partnershipFilter := bson.M{"company_id": companyID, "status": string(ApprovalStatusApproved), "submission_mode": string(SubmissionModePartnership)}
partnershipFilter := bson.M{"company_id": companyID, "status": string(ApprovalStatusSubmitted), "submission_mode": string(SubmissionModePartnership)}
partnershipCount, _ := r.ormRepo.Count(ctx, partnershipFilter)
stats := &CompanyTenderApprovalStatsResponse{
CompanyID: companyID,
TotalApprovals: totalApprovals,
ApprovedTenders: approvedTenders,
SubmittedTenders: submittedTenders,
RejectedTenders: rejectedTenders,
SelfApplyCount: selfApplyCount,
PartnershipCount: partnershipCount,
+11 -11
View File
@@ -694,12 +694,12 @@ func (s *tenderApprovalService) GetAggregatedCompanyStats(ctx context.Context) (
// In a real implementation, you might want to get stats for all companies
// and aggregate them properly
stats := &AggregatedCompanyStatsResponse{
TotalCompanies: 1, // This should be calculated from actual company data
TotalApprovals: generalStats.TotalApprovals,
TotalApprovedTenders: generalStats.ApprovedTenders,
TotalRejectedTenders: generalStats.RejectedTenders,
CompanyStats: []*CompanyTenderApprovalStatsResponse{}, // Empty for now
LastUpdated: time.Now().Unix(),
TotalCompanies: 1, // This should be calculated from actual company data
TotalApprovals: generalStats.TotalApprovals,
TotalSubmittedTenders: generalStats.SubmittedTenders,
TotalRejectedTenders: generalStats.RejectedTenders,
CompanyStats: []*CompanyTenderApprovalStatsResponse{}, // Empty for now
LastUpdated: time.Now().Unix(),
}
s.logger.Info("Aggregated company stats retrieved successfully", map[string]interface{}{
@@ -1004,8 +1004,8 @@ func (s *tenderApprovalService) ToggleTenderApproval(ctx context.Context, req *T
return nil, err
}
if req.Status == ApprovalStatusApproved {
existing.Status = "unapproved"
if req.Status == ApprovalStatusSubmitted {
existing.Status = "unsubmitted"
} else {
existing.Status = "unrejected"
}
@@ -1024,10 +1024,10 @@ func (s *tenderApprovalService) ToggleTenderApproval(ctx context.Context, req *T
return existing.ToResponseWithTender(nil), nil
}
if existing.Status == ApprovalStatusApproved {
if existing.Status == ApprovalStatusSubmitted {
existing.Reject()
} else {
existing.Approve()
existing.Submit()
}
err = s.repository.Update(ctx, existing)
@@ -1055,7 +1055,7 @@ func (s *tenderApprovalService) GetCompanyTenderApprovalStats(ctx context.Contex
s.logger.Info("Company tender approval stats retrieved successfully", map[string]interface{}{
"company_id": companyID,
"total_approvals": stats.TotalApprovals,
"approved_tenders": stats.ApprovedTenders,
"submitted_tenders": stats.SubmittedTenders,
"rejected_tenders": stats.RejectedTenders,
"self_apply_count": stats.SelfApplyCount,
"partnership_count": stats.PartnershipCount,
+1 -1
View File
@@ -48,7 +48,7 @@ func IsValidSubmissionMode(mode string) bool {
// IsValidStatus validates if the approval status is valid
func IsValidStatus(status string) bool {
validStatuses := []string{
string(ApprovalStatusApproved),
string(ApprovalStatusSubmitted),
string(ApprovalStatusRejected),
}