Remove obsolete customer endpoint and update related documentation
- Deleted the `/admin/v1/customers/{id}/with-companies` endpoint from the API documentation and Swagger files to streamline the API structure.
- Updated the router to remove the corresponding route registration for the deprecated endpoint.
- Enhanced the company repository and service to support batch retrieval of companies by IDs, improving efficiency in data handling.
- Adjusted customer service methods to utilize the new batch retrieval functionality for loading companies associated with customers.
- Improved logging practices to provide better traceability for company retrieval operations.
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
mongopkg "tm/pkg/mongo"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
// Repository defines the interface for company data operations
|
||||
@@ -17,6 +18,7 @@ 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)
|
||||
GetByIDs(ctx context.Context, ids []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)
|
||||
@@ -184,6 +186,54 @@ func (r *companyRepository) GetByTaxID(ctx context.Context, taxID string) (*Comp
|
||||
return company, nil
|
||||
}
|
||||
|
||||
// GetByIDs retrieves multiple companies by their IDs
|
||||
func (r *companyRepository) GetByIDs(ctx context.Context, ids []string) ([]*Company, error) {
|
||||
if len(ids) == 0 {
|
||||
return []*Company{}, nil
|
||||
}
|
||||
|
||||
// Convert string IDs to ObjectIDs for MongoDB query
|
||||
objectIDs := make([]interface{}, len(ids))
|
||||
for i, id := range ids {
|
||||
objectID, err := primitive.ObjectIDFromHex(id)
|
||||
if err != nil {
|
||||
r.logger.Warn("Invalid company ID format", map[string]interface{}{
|
||||
"id": id,
|
||||
"error": err.Error(),
|
||||
})
|
||||
continue
|
||||
}
|
||||
objectIDs[i] = objectID
|
||||
}
|
||||
|
||||
if len(objectIDs) == 0 {
|
||||
return []*Company{}, nil
|
||||
}
|
||||
|
||||
filter := bson.M{"_id": bson.M{"$in": objectIDs}}
|
||||
companies, err := r.ormRepo.FindMany(ctx, filter, len(ids))
|
||||
if err != nil {
|
||||
r.logger.Error("Failed to get companies by IDs", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"ids": ids,
|
||||
})
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Convert to pointer slice
|
||||
result := make([]*Company, len(companies))
|
||||
for i := range companies {
|
||||
result[i] = &companies[i]
|
||||
}
|
||||
|
||||
r.logger.Info("Retrieved companies by IDs", map[string]interface{}{
|
||||
"requested_count": len(ids),
|
||||
"found_count": len(result),
|
||||
})
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// Update updates a company
|
||||
func (r *companyRepository) Update(ctx context.Context, company *Company) error {
|
||||
// Set updated timestamp using Unix timestamp
|
||||
|
||||
@@ -13,6 +13,7 @@ type Service interface {
|
||||
// Core company operations
|
||||
CreateCompany(ctx context.Context, form *CreateCompanyForm, createdBy *string) (*Company, error)
|
||||
GetCompanyByID(ctx context.Context, id string) (*Company, error)
|
||||
GetCompaniesByIDs(ctx context.Context, ids []string) ([]*Company, error)
|
||||
UpdateCompany(ctx context.Context, id string, form *UpdateCompanyForm, updatedBy *string) (*Company, error)
|
||||
DeleteCompany(ctx context.Context, id string, deletedBy *string) error
|
||||
|
||||
@@ -144,6 +145,29 @@ func (s *companyService) GetCompanyByID(ctx context.Context, id string) (*Compan
|
||||
return company, nil
|
||||
}
|
||||
|
||||
// GetCompaniesByIDs retrieves multiple companies by their IDs
|
||||
func (s *companyService) GetCompaniesByIDs(ctx context.Context, ids []string) ([]*Company, error) {
|
||||
if len(ids) == 0 {
|
||||
return []*Company{}, nil
|
||||
}
|
||||
|
||||
companies, err := s.repository.GetByIDs(ctx, ids)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to get companies by IDs", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"ids": ids,
|
||||
})
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.logger.Info("Companies retrieved successfully", map[string]interface{}{
|
||||
"requested_count": len(ids),
|
||||
"found_count": len(companies),
|
||||
})
|
||||
|
||||
return companies, nil
|
||||
}
|
||||
|
||||
// UpdateCompany updates a company
|
||||
func (s *companyService) UpdateCompany(ctx context.Context, id string, form *UpdateCompanyForm, updatedBy *string) (*Company, error) {
|
||||
// Get existing company
|
||||
|
||||
@@ -84,33 +84,6 @@ func (h *Handler) CreateCustomer(c echo.Context) error {
|
||||
func (h *Handler) GetCustomerByID(c echo.Context) error {
|
||||
idStr := c.Param("id")
|
||||
|
||||
customer, err := h.service.GetCustomerByID(c.Request().Context(), idStr)
|
||||
if err != nil {
|
||||
if err.Error() == "customer not found" {
|
||||
return response.NotFound(c, "Customer not found")
|
||||
}
|
||||
return response.InternalServerError(c, "Failed to get customer")
|
||||
}
|
||||
|
||||
return response.Success(c, customer.ToResponse(), "Customer retrieved successfully")
|
||||
}
|
||||
|
||||
// GetCustomerByIDWithCompanies retrieves a customer by ID with companies (Web Panel)
|
||||
// @Summary Get customer by ID with companies
|
||||
// @Description Retrieve detailed customer information by customer ID including assigned companies
|
||||
// @Tags Admin-Customers
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "Customer ID"
|
||||
// @Success 200 {object} response.APIResponse{data=CustomerResponse} "Customer retrieved successfully"
|
||||
// @Failure 400 {object} response.APIResponse "Bad request - Invalid customer ID"
|
||||
// @Failure 404 {object} response.APIResponse "Not found - Customer not found"
|
||||
// @Failure 500 {object} response.APIResponse "Internal server error"
|
||||
// @Security BearerAuth
|
||||
// @Router /admin/v1/customers/{id}/with-companies [get]
|
||||
func (h *Handler) GetCustomerByIDWithCompanies(c echo.Context) error {
|
||||
idStr := c.Param("id")
|
||||
|
||||
customer, err := h.service.GetCustomerByIDWithCompanies(c.Request().Context(), idStr)
|
||||
if err != nil {
|
||||
if err.Error() == "customer not found" {
|
||||
@@ -234,7 +207,7 @@ func (h *Handler) ListCustomers(c echo.Context) error {
|
||||
return response.ValidationError(c, "Invalid request data", err.Error())
|
||||
}
|
||||
|
||||
result, err := h.service.ListCustomers(c.Request().Context(), form)
|
||||
result, err := h.service.ListCustomersWithCompanies(c.Request().Context(), form)
|
||||
if err != nil {
|
||||
return response.InternalServerError(c, "Failed to list customers")
|
||||
}
|
||||
|
||||
@@ -1280,24 +1280,35 @@ func (s *customerService) getDefaultTimezone(timezone *string) string {
|
||||
|
||||
// loadCompaniesForCustomer loads company summaries for a customer
|
||||
func (s *customerService) loadCompaniesForCustomer(ctx context.Context, customer *Customer) ([]*CompanySummary, error) {
|
||||
var companies []*CompanySummary
|
||||
if len(customer.CompanyIDs) == 0 {
|
||||
return []*CompanySummary{}, nil
|
||||
}
|
||||
|
||||
// Load companies from CompanyIDs
|
||||
for _, companyID := range customer.CompanyIDs {
|
||||
company, err := s.companyService.GetCompanyByID(ctx, companyID)
|
||||
if err != nil {
|
||||
s.logger.Warn("Failed to load company for customer", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"customer_id": customer.ID,
|
||||
"company_id": companyID,
|
||||
})
|
||||
continue // Skip companies that can't be loaded
|
||||
}
|
||||
companies = append(companies, &CompanySummary{
|
||||
// Load companies in batch using the new GetCompaniesByIDs method
|
||||
companies, err := s.companyService.GetCompaniesByIDs(ctx, customer.CompanyIDs)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to load companies for customer", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"customer_id": customer.ID,
|
||||
"company_ids": customer.CompanyIDs,
|
||||
})
|
||||
return []*CompanySummary{}, err
|
||||
}
|
||||
|
||||
// Convert to CompanySummary format
|
||||
var companySummaries []*CompanySummary
|
||||
for _, company := range companies {
|
||||
companySummaries = append(companySummaries, &CompanySummary{
|
||||
ID: company.ID.Hex(),
|
||||
Name: company.Name,
|
||||
})
|
||||
}
|
||||
|
||||
return companies, nil
|
||||
s.logger.Info("Companies loaded for customer", map[string]interface{}{
|
||||
"customer_id": customer.ID,
|
||||
"requested_count": len(customer.CompanyIDs),
|
||||
"loaded_count": len(companySummaries),
|
||||
})
|
||||
|
||||
return companySummaries, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user