c2531a005e
- Enhanced the GetByIDs method to convert string IDs to BSON ObjectIDs before querying the database, ensuring proper data type handling. - This change improves the robustness of the method by preventing potential errors related to ID format mismatches during database operations.
377 lines
9.7 KiB
Go
377 lines
9.7 KiB
Go
package company
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"time"
|
|
"tm/pkg/logger"
|
|
orm "tm/pkg/mongo"
|
|
"tm/pkg/response"
|
|
|
|
"go.mongodb.org/mongo-driver/v2/bson"
|
|
)
|
|
|
|
// Repository defines the interface for company data operations
|
|
type Repository interface {
|
|
Create(ctx context.Context, company *Company) error
|
|
Update(ctx context.Context, company *Company) error
|
|
GetByID(ctx context.Context, id string) (*Company, error)
|
|
GetByIDs(ctx context.Context, ids []string) ([]Company, error)
|
|
GetByName(ctx context.Context, name string) (*Company, error)
|
|
GetByRegistrationNumber(ctx context.Context, registrationNumber string) (*Company, error)
|
|
GetByTaxID(ctx context.Context, taxID string) (*Company, error)
|
|
Search(ctx context.Context, form *SearchForm, pagination *response.Pagination) ([]Company, int64, error)
|
|
Delete(ctx context.Context, id string) error
|
|
UpdateStatus(ctx context.Context, id string, status CompanyStatus) error
|
|
UpdateVerification(ctx context.Context, id string, isVerified, isCompliant bool, complianceNotes *string) error
|
|
}
|
|
|
|
// companyRepository implements the Repository interface using the MongoDB ORM
|
|
type companyRepository struct {
|
|
ormRepo orm.Repository[Company]
|
|
logger logger.Logger
|
|
}
|
|
|
|
// NewCompanyRepository creates a new company repository
|
|
func NewCompanyRepository(mongoManager *orm.ConnectionManager, logger logger.Logger) Repository {
|
|
// Create indexes using the ORM's index management
|
|
indexes := []orm.Index{
|
|
*orm.NewIndex("registration_number_idx", bson.D{{Key: "registration_number", Value: 1}}),
|
|
}
|
|
|
|
// Create indexes
|
|
err := mongoManager.CreateIndexes("companies", indexes)
|
|
if err != nil {
|
|
logger.Warn("Failed to create company indexes", map[string]interface{}{
|
|
"error": err.Error(),
|
|
})
|
|
}
|
|
|
|
// Create ORM repository
|
|
ormRepo := orm.NewRepository[Company](mongoManager.GetCollection("companies"), logger)
|
|
|
|
return &companyRepository{
|
|
ormRepo: ormRepo,
|
|
logger: logger,
|
|
}
|
|
}
|
|
|
|
// Create creates a new company
|
|
func (r *companyRepository) Create(ctx context.Context, company *Company) error {
|
|
// Set created/updated timestamps using Unix timestamps
|
|
now := time.Now().Unix()
|
|
company.SetCreatedAt(now)
|
|
|
|
// Use ORM to create company
|
|
err := r.ormRepo.Create(ctx, company)
|
|
if err != nil {
|
|
r.logger.Error("Failed to create company", map[string]interface{}{
|
|
"error": err.Error(),
|
|
"name": company.Name,
|
|
"registration_number": company.RegistrationNumber,
|
|
})
|
|
return err
|
|
}
|
|
|
|
r.logger.Info("Company created successfully", map[string]interface{}{
|
|
"company_id": company.ID,
|
|
"name": company.Name,
|
|
"type": company.Type,
|
|
})
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetByID retrieves a company by ID
|
|
func (r *companyRepository) GetByID(ctx context.Context, id string) (*Company, error) {
|
|
company, err := r.ormRepo.FindByID(ctx, id)
|
|
if err != nil {
|
|
if errors.Is(err, orm.ErrDocumentNotFound) {
|
|
return nil, errors.New("company not found")
|
|
}
|
|
r.logger.Error("Failed to get company by ID", map[string]interface{}{
|
|
"error": err.Error(),
|
|
"company_id": id,
|
|
})
|
|
return nil, err
|
|
}
|
|
|
|
return company, nil
|
|
}
|
|
|
|
// GetByIDs retrieves companies by IDs
|
|
func (r *companyRepository) GetByIDs(ctx context.Context, ids []string) ([]Company, error) {
|
|
objectIDs := make([]bson.ObjectID, len(ids))
|
|
for i, id := range ids {
|
|
objectID, err := bson.ObjectIDFromHex(id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
objectIDs[i] = objectID
|
|
}
|
|
|
|
companies, err := r.ormRepo.FindAll(ctx, bson.M{"_id": bson.M{"$in": objectIDs}}, orm.NewPaginationBuilder().Build())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return companies.Items, nil
|
|
}
|
|
|
|
// GetByName retrieves a company by name
|
|
func (r *companyRepository) GetByName(ctx context.Context, name string) (*Company, error) {
|
|
company, err := r.ormRepo.FindOne(ctx, bson.M{"name": name})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return company, nil
|
|
}
|
|
|
|
// GetByRegistrationNumber retrieves a company by registration number
|
|
func (r *companyRepository) GetByRegistrationNumber(ctx context.Context, registrationNumber string) (*Company, error) {
|
|
company, err := r.ormRepo.FindOne(ctx, bson.M{"registration_number": registrationNumber})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return company, nil
|
|
}
|
|
|
|
// GetByTaxID retrieves a company by tax ID
|
|
func (r *companyRepository) GetByTaxID(ctx context.Context, taxID string) (*Company, error) {
|
|
company, err := r.ormRepo.FindOne(ctx, bson.M{"tax_id": taxID})
|
|
if err != nil {
|
|
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
|
|
company.SetUpdatedAt(time.Now().Unix())
|
|
|
|
// Use ORM to update company
|
|
err := r.ormRepo.Update(ctx, company)
|
|
if err != nil {
|
|
r.logger.Error("Failed to update company", map[string]interface{}{
|
|
"error": err.Error(),
|
|
"company_id": company.ID,
|
|
})
|
|
return err
|
|
}
|
|
|
|
r.logger.Info("Company updated successfully", map[string]interface{}{
|
|
"company_id": company.ID,
|
|
"name": company.Name,
|
|
})
|
|
|
|
return nil
|
|
}
|
|
|
|
// Delete deletes a company
|
|
func (r *companyRepository) Delete(ctx context.Context, id string) error {
|
|
// Get company first
|
|
_, err := r.GetByID(ctx, id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Update in database
|
|
err = r.ormRepo.Delete(ctx, id)
|
|
if err != nil {
|
|
r.logger.Error("Failed to delete company", map[string]interface{}{
|
|
"error": err.Error(),
|
|
"company_id": id,
|
|
})
|
|
return err
|
|
}
|
|
|
|
r.logger.Info("Company deleted successfully", map[string]interface{}{
|
|
"company_id": id,
|
|
})
|
|
|
|
return nil
|
|
}
|
|
|
|
// Search retrieves companies with search and filters
|
|
func (r *companyRepository) Search(ctx context.Context, form *SearchForm, pagination *response.Pagination) ([]Company, int64, error) {
|
|
// Build filter
|
|
filter := bson.M{}
|
|
|
|
if form.Search != nil {
|
|
filter["$text"] = bson.M{"$search": *form.Search}
|
|
}
|
|
|
|
if form.Type != nil {
|
|
filter["type"] = *form.Type
|
|
}
|
|
|
|
if form.Status != nil {
|
|
filter["status"] = *form.Status
|
|
}
|
|
|
|
if form.Industry != nil {
|
|
filter["industry"] = *form.Industry
|
|
}
|
|
|
|
if form.IsVerified != nil {
|
|
filter["is_verified"] = *form.IsVerified
|
|
}
|
|
|
|
if form.IsCompliant != nil {
|
|
filter["is_compliant"] = *form.IsCompliant
|
|
}
|
|
|
|
if form.Language != nil {
|
|
filter["language"] = *form.Language
|
|
}
|
|
|
|
if form.Currency != nil {
|
|
filter["currency"] = *form.Currency
|
|
}
|
|
|
|
// Tag filters
|
|
if len(form.CPVCodes) > 0 {
|
|
filter["tags.cpv_codes"] = bson.M{"$in": form.CPVCodes}
|
|
}
|
|
|
|
if len(form.Categories) > 0 {
|
|
filter["tags.categories"] = bson.M{"$in": form.Categories}
|
|
}
|
|
|
|
if len(form.Keywords) > 0 {
|
|
filter["tags.keywords"] = bson.M{"$in": form.Keywords}
|
|
}
|
|
|
|
if len(form.Specializations) > 0 {
|
|
filter["tags.specializations"] = bson.M{"$in": form.Specializations}
|
|
}
|
|
|
|
// Range filters
|
|
if form.EmployeeCountMin != nil || form.EmployeeCountMax != nil {
|
|
rangeFilter := bson.M{}
|
|
if form.EmployeeCountMin != nil {
|
|
rangeFilter["$gte"] = *form.EmployeeCountMin
|
|
}
|
|
if form.EmployeeCountMax != nil {
|
|
rangeFilter["$lte"] = *form.EmployeeCountMax
|
|
}
|
|
filter["employee_count"] = rangeFilter
|
|
}
|
|
|
|
if form.AnnualRevenueMin != nil || form.AnnualRevenueMax != nil {
|
|
rangeFilter := bson.M{}
|
|
if form.AnnualRevenueMin != nil {
|
|
rangeFilter["$gte"] = *form.AnnualRevenueMin
|
|
}
|
|
if form.AnnualRevenueMax != nil {
|
|
rangeFilter["$lte"] = *form.AnnualRevenueMax
|
|
}
|
|
filter["annual_revenue"] = rangeFilter
|
|
}
|
|
|
|
if form.FoundedYearMin != nil || form.FoundedYearMax != nil {
|
|
rangeFilter := bson.M{}
|
|
if form.FoundedYearMin != nil {
|
|
rangeFilter["$gte"] = *form.FoundedYearMin
|
|
}
|
|
if form.FoundedYearMax != nil {
|
|
rangeFilter["$lte"] = *form.FoundedYearMax
|
|
}
|
|
filter["founded_year"] = rangeFilter
|
|
}
|
|
|
|
// Build sort
|
|
sort := "created_at"
|
|
if pagination.SortBy != "" {
|
|
sort = pagination.SortBy
|
|
}
|
|
|
|
sortOrder := "desc"
|
|
if pagination.SortOrder != "" {
|
|
sortOrder = pagination.SortOrder
|
|
}
|
|
|
|
// Build pagination
|
|
paginationBuilder := orm.NewPaginationBuilder().
|
|
Limit(pagination.Limit).
|
|
Skip(pagination.Offset).
|
|
SortBy(sort, sortOrder).
|
|
Build()
|
|
|
|
// Use ORM to find users
|
|
result, err := r.ormRepo.FindAll(ctx, filter, paginationBuilder)
|
|
if err != nil {
|
|
r.logger.Error("Failed to list users", map[string]interface{}{
|
|
"error": err.Error(),
|
|
})
|
|
return nil, 0, err
|
|
}
|
|
|
|
return result.Items, result.TotalCount, nil
|
|
}
|
|
|
|
// UpdateStatus updates company status
|
|
func (r *companyRepository) UpdateStatus(ctx context.Context, id string, status CompanyStatus) error {
|
|
// Get company first
|
|
company, err := r.GetByID(ctx, id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Update status
|
|
company.Status = status
|
|
company.SetUpdatedAt(time.Now().Unix())
|
|
|
|
// Update in database
|
|
err = r.ormRepo.Update(ctx, company)
|
|
if err != nil {
|
|
r.logger.Error("Failed to update company status", map[string]interface{}{
|
|
"error": err.Error(),
|
|
"company_id": id,
|
|
"status": status,
|
|
})
|
|
return err
|
|
}
|
|
|
|
r.logger.Info("Company status updated successfully", map[string]interface{}{
|
|
"company_id": id,
|
|
"status": status,
|
|
})
|
|
|
|
return nil
|
|
}
|
|
|
|
// UpdateVerification updates company verification status
|
|
func (r *companyRepository) UpdateVerification(ctx context.Context, id string, isVerified, isCompliant bool, complianceNotes *string) error {
|
|
// Get company first
|
|
company, err := r.GetByID(ctx, id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Update verification fields
|
|
company.IsVerified = isVerified
|
|
company.IsCompliant = isCompliant
|
|
company.ComplianceNotes = complianceNotes
|
|
company.SetUpdatedAt(time.Now().Unix())
|
|
|
|
// Update in database
|
|
err = r.ormRepo.Update(ctx, company)
|
|
if err != nil {
|
|
r.logger.Error("Failed to update company verification", map[string]interface{}{
|
|
"error": err.Error(),
|
|
"company_id": id,
|
|
})
|
|
return err
|
|
}
|
|
|
|
r.logger.Info("Company verification updated successfully", map[string]interface{}{
|
|
"company_id": id,
|
|
"is_verified": isVerified,
|
|
"is_compliant": isCompliant,
|
|
})
|
|
|
|
return nil
|
|
}
|