package agent import ( "context" "errors" "fmt" "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database" dberrors "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/errors" dbtypes "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/types" rmodel "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/request_model" ) type CrmAgentService struct { dbClient database.Client } type CrmAgentServiceConfig struct { DbClient database.Client } func newCrmAgentService(cfg CrmAgentServiceConfig) *CrmAgentService { return &CrmAgentService{ dbClient: cfg.DbClient, } } func (s *CrmAgentService) GetVacancyList( ctx context.Context, request *rmodel.VacancyListGetRequest, ) (*rmodel.VacancyListGetResponse, error) { if err := request.Validate(); err != nil { return nil, fmt.Errorf("%w: %v", ErrBadRequest, err) } resp, err := s.dbClient.GetVacancyList(ctx, &dbtypes.VacancyListGetRequest{ Filters: &dbtypes.VacancyListFilters{ DistributorId: request.Filters.DistributorId, CompanyId: request.Filters.CompanyId, VacancyId: request.Filters.VacancyId, Region: request.Filters.Region, SalaryBottom: request.Filters.SalaryBottom, SalaryTop: request.Filters.SalaryTop, IsArchived: request.Filters.IsArchived, Status: dbtypes.NewVacancyStatus(request.Filters.Status.NullString()), }, Page: request.Page, PageSize: request.PageSize, }) if err != nil { return nil, fmt.Errorf("%w: error getting vacancy list: %v", s.handleDBError(err), err) } result := new(rmodel.VacancyListGetResponse).From(resp) return result, nil } func (s *CrmAgentService) GetSubmissionList( ctx context.Context, request *rmodel.SubmissionListGetRequest, ) (*rmodel.SubmissionListGetResponse, error) { if err := request.Validate(); err != nil { return nil, fmt.Errorf("%w: %v", ErrBadRequest, err) } req := dbtypes.SubmissionListGetRequest{ Filters: &dbtypes.SubmissionListGetFilters{ AgentId: &request.AgentId, }, } if request.Filters != nil { if request.Filters.VacancyId != nil { req.Filters.VacancyId = request.Filters.VacancyId } if request.Filters.Status != nil { req.Filters.Status = dbtypes.NewSubmissionStatus(request.Filters.Status.NullString()) } } resp, err := s.dbClient.GetSubmissionList(ctx, &req) if err != nil { return nil, fmt.Errorf("%w: error getting submission list: %v", s.handleDBError(err), err) } result := new(rmodel.SubmissionListGetResponse).From(resp) return result, nil } func (s *CrmAgentService) CreateSubmission( ctx context.Context, request *rmodel.SubmissionCreateRequest, ) (*rmodel.SubmissionCreateResponse, error) { if err := request.Validate(); err != nil { return nil, fmt.Errorf("%w: %v", ErrBadRequest, err) } req := dbtypes.SubmissionCreateRequest{ AgentId: request.AgentId, VacancyId: request.VacancyId, CandidateInfo: &dbtypes.CandidateInfo{ FirstName: request.CandidateInfo.FirstName, LastName: request.CandidateInfo.LastName, MiddleName: request.CandidateInfo.MiddleName, PhoneNumber: request.CandidateInfo.PhoneNumber, Email: request.CandidateInfo.Email, Birthday: request.CandidateInfo.Birthday, CvLink: request.CandidateInfo.CvLink, Resume: request.CandidateInfo.Resume, }, } resp, err := s.dbClient.CreateSubmission(ctx, &req) if err != nil { return nil, fmt.Errorf("%w: error creating submission: %v", s.handleDBError(err), err) } result := new(rmodel.SubmissionCreateResponse).From(resp) return result, nil } func (s *CrmAgentService) DeleteSubmission( ctx context.Context, request *rmodel.SubmissionDeleteRequest, ) (*rmodel.SubmissionDeleteResponse, error) { if err := request.Validate(); err != nil { return nil, fmt.Errorf("%w: %v", ErrBadRequest, err) } if _, err := s.dbClient.DeleteSubmission(ctx, &dbtypes.SubmissionDeleteRequest{ Id: request.Id, }); err != nil { return nil, fmt.Errorf("%w: error deleting submission: %v", s.handleDBError(err), err) } return &rmodel.SubmissionDeleteResponse{}, nil } func (s *CrmAgentService) GetProfile( ctx context.Context, request *rmodel.ProfileGetRequest, ) (*rmodel.ProfileGetResponse, error) { if err := request.Validate(); err != nil { return nil, fmt.Errorf("%w: %v", ErrBadRequest, err) } resp, err := s.dbClient.GetProfileById(ctx, &dbtypes.ProfileGetRequest{ Id: request.Id, }) if err != nil { return nil, fmt.Errorf("%w: error getting agent info: %v", s.handleDBError(err), err) } result := new(rmodel.ProfileGetResponse).From(resp) return result, nil } func (s *CrmAgentService) UpdateProfile( ctx context.Context, request *rmodel.ProfileUpdateRequest, ) (*rmodel.ProfileUpdateResponse, error) { if err := request.Validate(); err != nil { return nil, fmt.Errorf("%w: %v", ErrBadRequest, err) } if _, err := s.dbClient.UpdateProfile(ctx, &dbtypes.ProfileUpdateRequest{ Id: request.Id, Name: request.Name, PhoneNumber: request.PhoneNumber, Email: request.Email, }); err != nil { return nil, fmt.Errorf("%w: error updating profile: %v", s.handleDBError(err), err) } return &rmodel.ProfileUpdateResponse{}, nil } func (s *CrmAgentService) GetCompanyList( ctx context.Context, request *rmodel.CompanyListGetRequest, ) (*rmodel.CompanyListGetResponse, error) { if err := request.Validate(); err != nil { return nil, fmt.Errorf("%w: %v", ErrBadRequest, err) } resp, err := s.dbClient.GetCompanyList(ctx, &dbtypes.CompanyListGetRequest{ Id: request.Id, }) if err != nil { return nil, fmt.Errorf("%w: error getting company list: %v", ErrInternal, err) } result := new(rmodel.CompanyListGetResponse).From(resp) return result, nil } func (s *CrmAgentService) GetCompanyInfo( ctx context.Context, request *rmodel.CompanyByIdGetRequest, ) (*rmodel.CompanyByIdGetResponse, error) { if err := request.Validate(); err != nil { return nil, fmt.Errorf("%w: %v", ErrBadRequest, err) } resp, err := s.dbClient.GetCompanyById(ctx, &dbtypes.CompanyByIdGetRequest{ Id: request.UserId, CompanyId: request.CompanyId, }) if err != nil { return nil, fmt.Errorf("%w: error getting company info: %v", s.handleDBError(err), err) } result := new(rmodel.CompanyByIdGetResponse).From(resp) return result, nil } func (s *CrmAgentService) CreateCompany( ctx context.Context, request *rmodel.CompanyCreateRequest, ) (*rmodel.CompanyCreateResponse, error) { if err := request.Validate(); err != nil { return nil, fmt.Errorf("%w: %v", ErrBadRequest, err) } resp, err := s.dbClient.CreateCompany(ctx, &dbtypes.CompanyCreateRequest{ OwnerId: request.OwnerId, Name: request.Name, LegalPerson: request.LegalPerson, Description: request.Description, Website: request.Website, PhysicalAddress: request.PhysicalAddress, LegalAddress: request.LegalAddress, Inn: request.Inn, Kpp: request.Kpp, Staff: request.Staff, }) if err != nil { return nil, fmt.Errorf("%w: error creating company: %v", s.handleDBError(err), err) } result := new(rmodel.CompanyCreateResponse).From(resp) return result, nil } func (s *CrmAgentService) UpdateCompanyInfo( ctx context.Context, request *rmodel.CompanyUpdateRequest, ) (*rmodel.CompanyUpdateResponse, error) { if err := request.Validate(); err != nil { return nil, fmt.Errorf("%w: %v", ErrBadRequest, err) } if _, err := s.dbClient.UpdateCompany(ctx, &dbtypes.CompanyUpdateRequest{ Id: request.Id, Name: request.Name, LegalPerson: request.LegalPerson, Description: request.Description, Website: request.Website, PhysicalAddress: request.PhysicalAddress, LegalAddress: request.LegalAddress, Inn: request.Inn, Kpp: request.Kpp, Staff: request.Staff, }); err != nil { return nil, fmt.Errorf("%w: error updating company info: %v", s.handleDBError(err), err) } return &rmodel.CompanyUpdateResponse{}, nil } func (s *CrmAgentService) GetBalance( ctx context.Context, request *rmodel.BalanceGetRequest, ) (*rmodel.BalanceGetResponse, error) { if err := request.Validate(); err != nil { return nil, fmt.Errorf("%w: %v", ErrBadRequest, err) } resp, err := s.dbClient.GetBalance(ctx, &dbtypes.BalanceGetRequest{ OwnerId: request.OwnerId, }) if err != nil { return nil, fmt.Errorf("%w: error getting balance: %v", s.handleDBError(err), err) } result := new(rmodel.BalanceGetResponse).From(resp) return result, nil } func (s *CrmAgentService) GetTransactionList( ctx context.Context, request *rmodel.TransactionListGetRequest, ) (*rmodel.TransactionListGetResponse, error) { if err := request.Validate(); err != nil { return nil, fmt.Errorf("%w: %v", ErrBadRequest, err) } req := dbtypes.TransactionListGetRequest{ OwnerId: request.OwnerId, Page: request.Page, PageSize: request.PageSize, } if request.Filters != nil { req.Filters = new(dbtypes.TransactionListFilters) req.Filters.Type = dbtypes.NewTransactionType(request.Filters.Type.NullString()) req.Filters.Status = dbtypes.NewTransactionStatus(request.Filters.Status.NullString()) req.Filters.BankAccountId = request.Filters.BankAccountId } resp, err := s.dbClient.GetTransactionList(ctx, &req) if err != nil { return nil, fmt.Errorf("%w: error getting transactions: %v", s.handleDBError(err), err) } result := new(rmodel.TransactionListGetResponse).From(resp) return result, nil } func (s *CrmAgentService) CreateTransaction( ctx context.Context, request *rmodel.TransactionCreateRequest, ) (*rmodel.TransactionCreateResponse, error) { if err := request.Validate(); err != nil { return nil, fmt.Errorf("%w: %v", ErrBadRequest, err) } req := dbtypes.TransactionCreateRequest{ OwnerId: request.OwnerId, Amount: request.Amount, Currency: request.Currency, BankAccountId: request.BankAccountId, RequestId: request.RequestId, } if request.Payload != nil { req.Payload = &dbtypes.TransactionPayload{ Origin: request.Payload.Origin, CompanyId: request.Payload.CompanyId, CompanyName: request.Payload.CompanyName, VacancyId: request.Payload.VacancyId, VacancyName: request.Payload.VacancyName, } } resp, err := s.dbClient.CreateTransaction(ctx, &req) if err != nil { return nil, fmt.Errorf("%w: error creating transaction: %v", s.handleDBError(err), err) } result := new(rmodel.TransactionCreateResponse).From(resp) return result, nil } func (s *CrmAgentService) GetBankAccountList( ctx context.Context, request *rmodel.BankAccountListGetRequest, ) (*rmodel.BankAccountListGetResponse, error) { if err := request.Validate(); err != nil { return nil, fmt.Errorf("%w: %v", ErrBadRequest, err) } resp, err := s.dbClient.GetBankAccountList(ctx, &dbtypes.BankAccountListGetRequest{ OwnerId: request.OwnerId, }) if err != nil { return nil, fmt.Errorf("%w: error getting bank accounts: %v", s.handleDBError(err), err) } result := new(rmodel.BankAccountListGetResponse).From(resp) return result, nil } func (s *CrmAgentService) CreateBankAccount( ctx context.Context, request *rmodel.BankAccountCreateRequest, ) (*rmodel.BankAccountCreateResponse, error) { if err := request.Validate(); err != nil { return nil, fmt.Errorf("%w: %v", ErrBadRequest, err) } resp, err := s.dbClient.CreateBankAccount(ctx, &dbtypes.BankAccountCreateRequest{ OwnerId: request.OwnerId, AccountNumber: request.AccountNumber, AccountName: request.AccountName, BankName: request.BankName, Bik: request.Bik, CorrespondentAccount: request.CorrespondentAccount, IsPrimary: request.IsPrimary, }) if err != nil { return nil, fmt.Errorf("%w: error creating bank account: %v", s.handleDBError(err), err) } result := new(rmodel.BankAccountCreateResponse).From(resp) return result, nil } func (s *CrmAgentService) UpdateBankAccount( ctx context.Context, request *rmodel.BankAccountUpdateRequest, ) (*rmodel.BankAccountUpdateResponse, error) { if err := request.Validate(); err != nil { return nil, fmt.Errorf("%w: %v", ErrBadRequest, err) } if _, err := s.dbClient.UpdateBankAccount(ctx, &dbtypes.BankAccountUpdateRequest{ Id: request.Id, AccountNumber: request.AccountNumber, AccountName: request.AccountName, BankName: request.BankName, Bik: request.Bik, CorrespondentAccount: request.CorrespondentAccount, IsPrimary: request.IsPrimary, }); err != nil { return nil, fmt.Errorf("%w: error updating bank account: %v", s.handleDBError(err), err) } return &rmodel.BankAccountUpdateResponse{}, nil } func (s *CrmAgentService) DeleteBankAccount( ctx context.Context, request *rmodel.BankAccountDeleteRequest, ) (*rmodel.BankAccountDeleteResponse, error) { return nil, ErrUnimplemented } func (s *CrmAgentService) handleDBError(err error) error { switch { case errors.Is(err, dberrors.ErrBadRequest): return ErrBadRequest case errors.Is(err, dberrors.ErrForbidden): return ErrForbidden case errors.Is(err, dberrors.ErrNotFound): return ErrNotFound case errors.Is(err, dberrors.ErrInternal): return ErrInternal default: return ErrInternal } }