package pgdb import ( "context" "database/sql" "fmt" "strings" 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" "github.com/Masterminds/squirrel" "github.com/google/uuid" ) func (c *client) GetClientValidation( ctx context.Context, request *dbtypes.ClientValidationGetRequest, ) (*dbtypes.ClientValidationGetResponse, error) { if request == nil { return nil, fmt.Errorf("%w: request is nil", dberrors.ErrBadRequest) } var ( psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar) userValidationTable = fmt.Sprintf("%s.%s", c.config.Schema, UserValidationTableName) ) getUserValidation := psql.Select( "status", "description", ). From(userValidationTable). Where(squirrel.Eq{"uid": request.UserId}) query, args, err := getUserValidation.ToSql() if err != nil { return nil, fmt.Errorf("%w: error building 'get user validation' query: %v", dberrors.ErrInternal, err) } row := c.db.QueryRowContext(ctx, query, args...) var result dbtypes.ClientValidation if err := row.Scan(&result.Status, &result.Description); err != nil { if err == sql.ErrNoRows { return nil, dberrors.ErrNotFound } return nil, fmt.Errorf("%w: error scanning row for 'get user validation' query: %v", dberrors.ErrInternal, err) } return &dbtypes.ClientValidationGetResponse{ ClientValidation: &result, }, nil } func (c *client) CreateUser( ctx context.Context, request *dbtypes.UserSaveRequest, ) (*dbtypes.UserSaveResponse, error) { if request == nil { return nil, fmt.Errorf("%w: request is nil", dberrors.ErrBadRequest) } tx, err := c.db.BeginTx(ctx, nil) if err != nil { return nil, fmt.Errorf("%w: error starting transaction: %v", dberrors.ErrInternal, err) } defer func() { _ = tx.Rollback() }() result, err := c.createUser(ctx, tx, request) if err != nil { return nil, fmt.Errorf("error creating user: %w", err) } if err := c.createUserValidationTicket(ctx, tx, request); err != nil { return nil, fmt.Errorf("error creating user validation ticket: %w", err) } resp, err := c.createCompany(ctx, tx, &dbtypes.CompanyCreateRequest{ OwnerId: request.Id, Staff: []string{ request.Id, }, }) if err != nil { return nil, fmt.Errorf("error creating company: %w", err) } var ownerId string switch request.Type { case dbtypes.UserTypeAgent: ownerId = request.Id case dbtypes.UserTypeDistributor: ownerId = resp.Id default: return nil, fmt.Errorf("%w: unknown user type: %v", dberrors.ErrBadRequest, request.Type) } balanceId := fmt.Sprintf("%sBAL", strings.ReplaceAll(uuid.NewString(), "-", "")) if err := c.createBalance(ctx, tx, &dbtypes.BalanceCreateRequest{ Id: balanceId, OwnerId: ownerId, RawBalance: 0, CleanBalance: 0, }); err != nil { return nil, fmt.Errorf("error creating balance: %w", err) } if err := tx.Commit(); err != nil { return nil, fmt.Errorf("%w: error committing transaction: %w", dberrors.ErrInternal, err) } return result, nil } func (c *client) createUser( ctx context.Context, driver Driver, request *dbtypes.UserSaveRequest, ) (*dbtypes.UserSaveResponse, error) { var ( psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar) userTable = fmt.Sprintf("%s.%s", c.config.Schema, UsersTableName) ) saveUser := psql.Insert(userTable). Columns( "uid", "name", "phone", "email", "client_type_id", ). Values( request.Id, request.FullName, request.Phone, request.Email, request.Type, ) query, args, err := saveUser.ToSql() if err != nil { return nil, fmt.Errorf("%w: error building 'save user' query: %v", dberrors.ErrInternal, err) } res, err := driver.ExecContext(ctx, query, args...) if err != nil { return nil, fmt.Errorf("%w: error executing 'save user' query: %v", dberrors.ErrInternal, err) } rowsAffected, err := res.RowsAffected() if err != nil { return nil, fmt.Errorf("%w: error getting rows affected for 'save user' query: %v", dberrors.ErrInternal, err) } if rowsAffected == 0 { return nil, dberrors.ErrInternal } return &dbtypes.UserSaveResponse{}, nil } func (c *client) createUserValidationTicket( ctx context.Context, driver Driver, request *dbtypes.UserSaveRequest, ) error { var ( psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar) userValidationTable = fmt.Sprintf("%s.%s", c.config.Schema, UserValidationTableName) ) // TODO: use normal uuid after DB reengineering ticketId := fmt.Sprintf("%sVAL", strings.ReplaceAll(uuid.NewString(), "-", "")) createUserValidation := psql.Insert(userValidationTable). Columns( "id", "uid", "status", "description", "last_update", ). Values( ticketId, request.Id, dbtypes.ClientValStatusNew, request.FullName, squirrel.Expr("CURRENT_TIMESTAMP"), ) query, args, err := createUserValidation.ToSql() if err != nil { return fmt.Errorf("%w: error building 'create user validation' query: %v", dberrors.ErrInternal, err) } res, err := driver.ExecContext(ctx, query, args...) if err != nil { return fmt.Errorf("%w: error executing 'create user validation' query: %v", dberrors.ErrInternal, err) } rowsAffected, err := res.RowsAffected() if err != nil { return fmt.Errorf("%w: error getting rows affected for 'create user validation' query: %v", dberrors.ErrInternal, err) } if rowsAffected == 0 { return dberrors.ErrInternal } return nil }