Refactor company domain by removing customer-related fields and methods
- Removed OwnerCustomerID from Company entity and CompanyResponse to streamline ownership representation. - Eliminated customer assignment fields from CreateCompanyForm and ListCompaniesForm for clarity. - Updated repository and service methods to remove GetByCustomerID and CountWithCustomer, simplifying the codebase. - Adjusted Search method parameters to exclude hasCustomer filter, enhancing search functionality. - Improved API documentation by removing references to customer assignment in handler comments.
This commit is contained in:
@@ -65,9 +65,6 @@ type Company struct {
|
||||
Currency string `bson:"currency" json:"currency"` // Default: "USD"
|
||||
Timezone string `bson:"timezone" json:"timezone"` // Default: "UTC"
|
||||
|
||||
// Company ownership - which customer owns this company
|
||||
OwnerCustomerID *string `bson:"owner_customer_id,omitempty" json:"owner_customer_id,omitempty"`
|
||||
|
||||
// Audit fields
|
||||
CreatedBy *string `bson:"created_by,omitempty" json:"created_by,omitempty"`
|
||||
UpdatedBy *string `bson:"updated_by,omitempty" json:"updated_by,omitempty"`
|
||||
@@ -167,7 +164,6 @@ type CompanyResponse struct {
|
||||
Language string `json:"language"`
|
||||
Currency string `json:"currency"`
|
||||
Timezone string `json:"timezone"`
|
||||
OwnerCustomerID *string `json:"owner_customer_id,omitempty"`
|
||||
CreatedAt int64 `json:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at"`
|
||||
CreatedBy *string `json:"created_by,omitempty"`
|
||||
@@ -200,7 +196,6 @@ func (c *Company) ToResponse() *CompanyResponse {
|
||||
Language: c.Language,
|
||||
Currency: c.Currency,
|
||||
Timezone: c.Timezone,
|
||||
OwnerCustomerID: c.OwnerCustomerID,
|
||||
CreatedAt: c.CreatedAt,
|
||||
UpdatedAt: c.UpdatedAt,
|
||||
CreatedBy: c.CreatedBy,
|
||||
|
||||
@@ -26,9 +26,6 @@ type CreateCompanyForm struct {
|
||||
// Tags for categorization and search
|
||||
Tags *CompanyTagsForm `json:"tags,omitempty"`
|
||||
|
||||
// Customer assignment (for login credentials)
|
||||
CustomerID *string `json:"customer_id,omitempty" valid:"optional,uuid"`
|
||||
|
||||
// Settings
|
||||
Language *string `json:"language,omitempty" valid:"optional,in(en|ar|fr|es|de|zh|ja|ko)"`
|
||||
Currency *string `json:"currency,omitempty" valid:"optional,in(USD|EUR|GBP|JPY|CAD|AUD|CHF|CNY|INR|BRL)"`
|
||||
@@ -81,7 +78,6 @@ type ListCompaniesForm struct {
|
||||
Categories []string `query:"categories" valid:"optional"`
|
||||
Keywords []string `query:"keywords" valid:"optional"`
|
||||
Specializations []string `query:"specializations" valid:"optional"`
|
||||
HasCustomer *bool `query:"has_customer" valid:"optional"`
|
||||
EmployeeCountMin *int `query:"employee_count_min" valid:"optional,min(1)"`
|
||||
EmployeeCountMax *int `query:"employee_count_max" valid:"optional,min(1)"`
|
||||
AnnualRevenueMin *float64 `query:"annual_revenue_min" valid:"optional,min(0)"`
|
||||
@@ -106,11 +102,6 @@ type UpdateCompanyVerificationForm struct {
|
||||
ComplianceNotes *string `json:"compliance_notes,omitempty" valid:"optional,length(0|1000)"`
|
||||
}
|
||||
|
||||
// AssignCustomerForm represents the form for assigning a customer to a company
|
||||
type AssignCustomerForm struct {
|
||||
CustomerID string `json:"customer_id" valid:"required,uuid"`
|
||||
}
|
||||
|
||||
// UpdateCompanyTagsForm represents the form for updating company tags
|
||||
type UpdateCompanyTagsForm struct {
|
||||
Tags *CompanyTagsForm `json:"tags" valid:"required"`
|
||||
@@ -199,15 +190,14 @@ type CompanySearchForm struct {
|
||||
|
||||
// Company statistics DTOs
|
||||
type CompanyStatsResponse struct {
|
||||
TotalCompanies int64 `json:"total_companies"`
|
||||
ActiveCompanies int64 `json:"active_companies"`
|
||||
VerifiedCompanies int64 `json:"verified_companies"`
|
||||
CompaniesWithCustomer int64 `json:"companies_with_customer"`
|
||||
CompaniesByType map[string]int64 `json:"companies_by_type"`
|
||||
CompaniesByIndustry map[string]int64 `json:"companies_by_industry"`
|
||||
CompaniesByStatus map[string]int64 `json:"companies_by_status"`
|
||||
TopCategories []CategoryCount `json:"top_categories"`
|
||||
TopCPVCodes []CPVCodeCount `json:"top_cpv_codes"`
|
||||
TotalCompanies int64 `json:"total_companies"`
|
||||
ActiveCompanies int64 `json:"active_companies"`
|
||||
VerifiedCompanies int64 `json:"verified_companies"`
|
||||
CompaniesByType map[string]int64 `json:"companies_by_type"`
|
||||
CompaniesByIndustry map[string]int64 `json:"companies_by_industry"`
|
||||
CompaniesByStatus map[string]int64 `json:"companies_by_status"`
|
||||
TopCategories []CategoryCount `json:"top_categories"`
|
||||
TopCPVCodes []CPVCodeCount `json:"top_cpv_codes"`
|
||||
}
|
||||
|
||||
type CategoryCount struct {
|
||||
|
||||
@@ -183,7 +183,6 @@ func (h *Handler) DeleteCompany(c echo.Context) error {
|
||||
// @Param industry query string false "Filter by industry"
|
||||
// @Param is_verified query boolean false "Filter by verification status"
|
||||
// @Param is_compliant query boolean false "Filter by compliance status"
|
||||
// @Param has_customer query boolean false "Filter by customer assignment status"
|
||||
// @Param cpv_codes query array false "Filter by CPV codes"
|
||||
// @Param categories query array false "Filter by categories"
|
||||
// @Param keywords query array false "Filter by keywords"
|
||||
|
||||
@@ -17,17 +17,15 @@ type Repository interface {
|
||||
GetByName(ctx context.Context, name string) (*Company, error)
|
||||
GetByRegistrationNumber(ctx context.Context, registrationNumber string) (*Company, error)
|
||||
GetByTaxID(ctx context.Context, taxID string) (*Company, error)
|
||||
GetByCustomerID(ctx context.Context, customerID string) (*Company, error)
|
||||
Update(ctx context.Context, company *Company) error
|
||||
Delete(ctx context.Context, id string) error
|
||||
List(ctx context.Context, limit, offset int) ([]*Company, error)
|
||||
Search(ctx context.Context, search string, companyType *string, status *string, industry *string, isVerified *bool, isCompliant *bool, language *string, currency *string, hasCustomer *bool, cpvCodes []string, categories []string, keywords []string, specializations []string, employeeCountMin *int, employeeCountMax *int, annualRevenueMin *float64, annualRevenueMax *float64, foundedYearMin *int, foundedYearMax *int, limit, offset int, sortBy, sortOrder string) ([]*Company, error)
|
||||
Search(ctx context.Context, search string, companyType *string, status *string, industry *string, isVerified *bool, isCompliant *bool, language *string, currency *string, cpvCodes []string, categories []string, keywords []string, specializations []string, employeeCountMin *int, employeeCountMax *int, annualRevenueMin *float64, annualRevenueMax *float64, foundedYearMin *int, foundedYearMax *int, limit, offset int, sortBy, sortOrder string) ([]*Company, error)
|
||||
Count(ctx context.Context) (int64, error)
|
||||
CountByType(ctx context.Context, companyType CompanyType) (int64, error)
|
||||
CountByStatus(ctx context.Context, status CompanyStatus) (int64, error)
|
||||
CountByIndustry(ctx context.Context, industry string) (int64, error)
|
||||
CountVerified(ctx context.Context) (int64, error)
|
||||
CountWithCustomer(ctx context.Context) (int64, error)
|
||||
UpdateStatus(ctx context.Context, id string, status CompanyStatus) error
|
||||
UpdateVerification(ctx context.Context, id string, isVerified, isCompliant bool, complianceNotes *string) error
|
||||
UpdateTags(ctx context.Context, id string, tags *CompanyTags) error
|
||||
@@ -50,7 +48,6 @@ func NewCompanyRepository(mongoManager *mongopkg.ConnectionManager, logger logge
|
||||
*mongopkg.CreateUniqueIndex("name_idx", bson.D{{Key: "name", Value: 1}}),
|
||||
*mongopkg.CreateUniqueIndex("registration_number_idx", bson.D{{Key: "registration_number", Value: 1}}),
|
||||
*mongopkg.CreateUniqueIndex("tax_id_idx", bson.D{{Key: "tax_id", Value: 1}}),
|
||||
*mongopkg.NewIndex("customer_id_idx", bson.D{{Key: "customer_id", Value: 1}}),
|
||||
*mongopkg.NewIndex("type_idx", bson.D{{Key: "type", Value: 1}}),
|
||||
*mongopkg.NewIndex("status_idx", bson.D{{Key: "status", Value: 1}}),
|
||||
*mongopkg.NewIndex("industry_idx", bson.D{{Key: "industry", Value: 1}}),
|
||||
@@ -187,24 +184,6 @@ func (r *companyRepository) GetByTaxID(ctx context.Context, taxID string) (*Comp
|
||||
return company, nil
|
||||
}
|
||||
|
||||
// GetByCustomerID retrieves a company by customer ID
|
||||
func (r *companyRepository) GetByCustomerID(ctx context.Context, customerID string) (*Company, error) {
|
||||
filter := bson.M{"customer_id": customerID}
|
||||
company, err := r.ormRepo.FindOne(ctx, filter)
|
||||
if err != nil {
|
||||
if errors.Is(err, mongopkg.ErrDocumentNotFound) {
|
||||
return nil, errors.New("company not found")
|
||||
}
|
||||
r.logger.Error("Failed to get company by customer ID", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"customer_id": customerID,
|
||||
})
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return company, nil
|
||||
}
|
||||
|
||||
// Update updates a company
|
||||
func (r *companyRepository) Update(ctx context.Context, company *Company) error {
|
||||
// Set updated timestamp using Unix timestamp
|
||||
@@ -290,7 +269,7 @@ func (r *companyRepository) List(ctx context.Context, limit, offset int) ([]*Com
|
||||
}
|
||||
|
||||
// Search retrieves companies with search and filters
|
||||
func (r *companyRepository) Search(ctx context.Context, search string, companyType *string, status *string, industry *string, isVerified *bool, isCompliant *bool, language *string, currency *string, hasCustomer *bool, cpvCodes []string, categories []string, keywords []string, specializations []string, employeeCountMin *int, employeeCountMax *int, annualRevenueMin *float64, annualRevenueMax *float64, foundedYearMin *int, foundedYearMax *int, limit, offset int, sortBy, sortOrder string) ([]*Company, error) {
|
||||
func (r *companyRepository) Search(ctx context.Context, search string, companyType *string, status *string, industry *string, isVerified *bool, isCompliant *bool, language *string, currency *string, cpvCodes []string, categories []string, keywords []string, specializations []string, employeeCountMin *int, employeeCountMax *int, annualRevenueMin *float64, annualRevenueMax *float64, foundedYearMin *int, foundedYearMax *int, limit, offset int, sortBy, sortOrder string) ([]*Company, error) {
|
||||
// Build filter
|
||||
filter := bson.M{}
|
||||
|
||||
@@ -326,14 +305,6 @@ func (r *companyRepository) Search(ctx context.Context, search string, companyTy
|
||||
filter["currency"] = *currency
|
||||
}
|
||||
|
||||
if hasCustomer != nil {
|
||||
if *hasCustomer {
|
||||
filter["customer_id"] = bson.M{"$ne": nil}
|
||||
} else {
|
||||
filter["customer_id"] = nil
|
||||
}
|
||||
}
|
||||
|
||||
// Tag filters
|
||||
if len(cpvCodes) > 0 {
|
||||
filter["tags.cpv_codes"] = bson.M{"$in": cpvCodes}
|
||||
@@ -507,24 +478,6 @@ func (r *companyRepository) CountVerified(ctx context.Context) (int64, error) {
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// CountWithCustomer counts companies with assigned customers
|
||||
func (r *companyRepository) CountWithCustomer(ctx context.Context) (int64, error) {
|
||||
filter := bson.M{
|
||||
"customer_id": bson.M{"$ne": nil},
|
||||
"status": bson.M{"$ne": CompanyStatusInactive},
|
||||
}
|
||||
|
||||
count, err := r.ormRepo.Count(ctx, filter)
|
||||
if err != nil {
|
||||
r.logger.Error("Failed to count companies with customer", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
})
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// UpdateStatus updates company status
|
||||
func (r *companyRepository) UpdateStatus(ctx context.Context, id string, status CompanyStatus) error {
|
||||
// Get company first
|
||||
@@ -704,20 +657,18 @@ func (r *companyRepository) GetCompanyStats(ctx context.Context) (*CompanyStatsR
|
||||
totalCompanies, _ := r.Count(ctx)
|
||||
activeCompanies, _ := r.CountByStatus(ctx, CompanyStatusActive)
|
||||
verifiedCompanies, _ := r.CountVerified(ctx)
|
||||
companiesWithCustomer, _ := r.CountWithCustomer(ctx)
|
||||
|
||||
// For this implementation, we'll return basic stats
|
||||
// In a real implementation, you'd use MongoDB aggregation pipelines
|
||||
stats := &CompanyStatsResponse{
|
||||
TotalCompanies: totalCompanies,
|
||||
ActiveCompanies: activeCompanies,
|
||||
VerifiedCompanies: verifiedCompanies,
|
||||
CompaniesWithCustomer: companiesWithCustomer,
|
||||
CompaniesByType: make(map[string]int64),
|
||||
CompaniesByIndustry: make(map[string]int64),
|
||||
CompaniesByStatus: make(map[string]int64),
|
||||
TopCategories: []CategoryCount{},
|
||||
TopCPVCodes: []CPVCodeCount{},
|
||||
TotalCompanies: totalCompanies,
|
||||
ActiveCompanies: activeCompanies,
|
||||
VerifiedCompanies: verifiedCompanies,
|
||||
CompaniesByType: make(map[string]int64),
|
||||
CompaniesByIndustry: make(map[string]int64),
|
||||
CompaniesByStatus: make(map[string]int64),
|
||||
TopCategories: []CategoryCount{},
|
||||
TopCPVCodes: []CPVCodeCount{},
|
||||
}
|
||||
|
||||
return stats, nil
|
||||
|
||||
@@ -325,7 +325,7 @@ func (s *companyService) ListCompanies(ctx context.Context, form *ListCompaniesF
|
||||
}
|
||||
|
||||
// Get companies
|
||||
companies, err := s.repository.Search(ctx, search, form.Type, form.Status, form.Industry, form.IsVerified, form.IsCompliant, form.Language, form.Currency, form.HasCustomer, form.CPVCodes, form.Categories, form.Keywords, form.Specializations, form.EmployeeCountMin, form.EmployeeCountMax, form.AnnualRevenueMin, form.AnnualRevenueMax, form.FoundedYearMin, form.FoundedYearMax, limit, offset, sortBy, sortOrder)
|
||||
companies, err := s.repository.Search(ctx, search, form.Type, form.Status, form.Industry, form.IsVerified, form.IsCompliant, form.Language, form.Currency, form.CPVCodes, form.Categories, form.Keywords, form.Specializations, form.EmployeeCountMin, form.EmployeeCountMax, form.AnnualRevenueMin, form.AnnualRevenueMax, form.FoundedYearMin, form.FoundedYearMax, limit, offset, sortBy, sortOrder)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to list companies", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
@@ -371,7 +371,7 @@ func (s *companyService) SearchCompanies(ctx context.Context, form *CompanySearc
|
||||
}
|
||||
|
||||
// Get companies using search
|
||||
companies, err := s.repository.Search(ctx, query, nil, nil, form.Industry, form.IsVerified, form.IsCompliant, nil, nil, nil, form.CPVCodes, form.Categories, form.Keywords, form.Specializations, form.MinEmployees, form.MaxEmployees, form.MinRevenue, form.MaxRevenue, nil, nil, limit, offset, "created_at", "desc")
|
||||
companies, err := s.repository.Search(ctx, query, nil, nil, form.Industry, form.IsVerified, form.IsCompliant, nil, nil, form.CPVCodes, form.Categories, form.Keywords, form.Specializations, form.MinEmployees, form.MaxEmployees, form.MinRevenue, form.MaxRevenue, nil, nil, limit, offset, "created_at", "desc")
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to search companies", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
@@ -469,25 +469,6 @@ func (s *companyService) UpdateCompanyVerification(ctx context.Context, id strin
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetCompanyByCustomerID retrieves a company by customer ID
|
||||
func (s *companyService) GetCompanyByCustomerID(ctx context.Context, customerID string) (*Company, error) {
|
||||
company, err := s.repository.GetByCustomerID(ctx, customerID)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to get company by customer ID", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"customer_id": customerID,
|
||||
})
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.logger.Info("Company retrieved by customer ID successfully", map[string]interface{}{
|
||||
"company_id": company.ID,
|
||||
"customer_id": customerID,
|
||||
})
|
||||
|
||||
return company, nil
|
||||
}
|
||||
|
||||
// UpdateCompanyTags updates company tags
|
||||
func (s *companyService) UpdateCompanyTags(ctx context.Context, id string, form *UpdateCompanyTagsForm, updatedBy *string) error {
|
||||
// Get company to check if exists
|
||||
@@ -663,7 +644,7 @@ func (s *companyService) GetCompanyStats(ctx context.Context) (*CompanyStatsResp
|
||||
func (s *companyService) GetCompaniesByType(ctx context.Context, companyType CompanyType, limit, offset int) ([]*Company, int64, error) {
|
||||
// Use search method with type filter
|
||||
typeStr := string(companyType)
|
||||
companies, err := s.repository.Search(ctx, "", &typeStr, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, limit, offset, "created_at", "desc")
|
||||
companies, err := s.repository.Search(ctx, "", &typeStr, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, limit, offset, "created_at", "desc")
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to get companies by type", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
@@ -689,7 +670,7 @@ func (s *companyService) GetCompaniesByType(ctx context.Context, companyType Com
|
||||
func (s *companyService) GetCompaniesByStatus(ctx context.Context, status CompanyStatus, limit, offset int) ([]*Company, int64, error) {
|
||||
// Use search method with status filter
|
||||
statusStr := string(status)
|
||||
companies, err := s.repository.Search(ctx, "", nil, &statusStr, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, limit, offset, "created_at", "desc")
|
||||
companies, err := s.repository.Search(ctx, "", nil, &statusStr, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, limit, offset, "created_at", "desc")
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to get companies by status", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
@@ -714,7 +695,7 @@ func (s *companyService) GetCompaniesByStatus(ctx context.Context, status Compan
|
||||
// GetCompaniesByIndustry retrieves companies by industry with pagination
|
||||
func (s *companyService) GetCompaniesByIndustry(ctx context.Context, industry string, limit, offset int) ([]*Company, int64, error) {
|
||||
// Use search method with industry filter
|
||||
companies, err := s.repository.Search(ctx, "", nil, nil, &industry, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, limit, offset, "created_at", "desc")
|
||||
companies, err := s.repository.Search(ctx, "", nil, nil, &industry, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, limit, offset, "created_at", "desc")
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to get companies by industry", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
|
||||
Reference in New Issue
Block a user