Files
tm_back/internal/company/repository.go
T
n.nakhostin 5d721705b7 Update MongoDB Driver and Configuration for Company Entities
- Updated the MongoDB driver from v1.17.4 to v2.3.0, ensuring compatibility with the latest features and improvements.
- Refactored company-related entity and repository files to utilize the new driver, replacing `primitive.ObjectID` with `bson.ObjectID` for ID handling.
- Adjusted the configuration in `.drone.yml` to include the `main` branch in the trigger settings, enhancing CI/CD pipeline flexibility.
2025-09-09 18:53:39 +03:30

368 lines
9.5 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) {
companies, err := r.ormRepo.FindAll(ctx, bson.M{"_id": bson.M{"$in": ids}}, 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
}