Compare commits
7 Commits
2acbe703eb
...
dbf7aca078
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dbf7aca078 | ||
|
|
b99a5010a7 | ||
|
|
8a581da1d8 | ||
|
|
41738753f0 | ||
|
|
33561692b6 | ||
|
|
31cfe21695 | ||
|
|
36bd75bbeb |
@@ -7,6 +7,25 @@ type roles struct {
|
|||||||
Admin int8
|
Admin int8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type licences struct {
|
||||||
|
AM string
|
||||||
|
A1 string
|
||||||
|
A2 string
|
||||||
|
A string
|
||||||
|
B string
|
||||||
|
C1 string
|
||||||
|
C string
|
||||||
|
D1 string
|
||||||
|
D string
|
||||||
|
BE string
|
||||||
|
C1E string
|
||||||
|
CE string
|
||||||
|
D1E string
|
||||||
|
DE string
|
||||||
|
L string
|
||||||
|
T string
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
UnverifiedStatus = iota + 1
|
UnverifiedStatus = iota + 1
|
||||||
VerifiedStatus
|
VerifiedStatus
|
||||||
@@ -29,6 +48,25 @@ var Roles = roles{
|
|||||||
Admin: 8,
|
Admin: 8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var Licences = licences{
|
||||||
|
AM: "AM",
|
||||||
|
A1: "A1",
|
||||||
|
A2: "A2",
|
||||||
|
A: "A",
|
||||||
|
B: "B",
|
||||||
|
C1: "C1",
|
||||||
|
C: "C",
|
||||||
|
D1: "D1",
|
||||||
|
D: "D",
|
||||||
|
BE: "BE",
|
||||||
|
C1E: "C1E",
|
||||||
|
CE: "CE",
|
||||||
|
D1E: "D1E",
|
||||||
|
DE: "DE",
|
||||||
|
L: "L",
|
||||||
|
T: "T",
|
||||||
|
}
|
||||||
|
|
||||||
const PRIV_VIEW = 1
|
const PRIV_VIEW = 1
|
||||||
const PRIV_ADD = 2
|
const PRIV_ADD = 2
|
||||||
const PRIV_EDIT = 4
|
const PRIV_EDIT = 4
|
||||||
|
|||||||
@@ -98,8 +98,9 @@ func TestSuite(t *testing.T) {
|
|||||||
var subscriptionRepo repositories.SubscriptionModelsRepositoryInterface = &repositories.SubscriptionModelsRepository{}
|
var subscriptionRepo repositories.SubscriptionModelsRepositoryInterface = &repositories.SubscriptionModelsRepository{}
|
||||||
membershipService := &services.MembershipService{Repo: membershipRepo, SubscriptionRepo: subscriptionRepo}
|
membershipService := &services.MembershipService{Repo: membershipRepo, SubscriptionRepo: subscriptionRepo}
|
||||||
|
|
||||||
|
var licenceRepo repositories.DriversLicenceInterface = &repositories.DriversLicenceRepository{}
|
||||||
var userRepo repositories.UserRepositoryInterface = &repositories.UserRepository{}
|
var userRepo repositories.UserRepositoryInterface = &repositories.UserRepository{}
|
||||||
userService := &services.UserService{Repo: userRepo}
|
userService := &services.UserService{Repo: userRepo, Licences: licenceRepo}
|
||||||
|
|
||||||
Uc = &UserController{Service: userService, EmailService: emailService, ConsentService: consentService, BankAccountService: bankAccountService, MembershipService: membershipService}
|
Uc = &UserController{Service: userService, EmailService: emailService, ConsentService: consentService, BankAccountService: bankAccountService, MembershipService: membershipService}
|
||||||
Mc = &MembershipController{Service: *membershipService}
|
Mc = &MembershipController{Service: *membershipService}
|
||||||
@@ -133,9 +134,9 @@ func TestSuite(t *testing.T) {
|
|||||||
log.Fatalf("Failed to stop SMTP Mockup Server: %#v", err)
|
log.Fatalf("Failed to stop SMTP Mockup Server: %#v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := deleteTestDB("test.db"); err != nil {
|
// if err := deleteTestDB("test.db"); err != nil {
|
||||||
log.Fatalf("Failed to tear down DB: %#v", err)
|
// log.Fatalf("Failed to tear down DB: %#v", err)
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
func initSubscriptionPlans() error {
|
func initSubscriptionPlans() error {
|
||||||
@@ -221,6 +222,7 @@ func getBaseUser() models.User {
|
|||||||
Phone: "01738484993",
|
Phone: "01738484993",
|
||||||
BankAccount: models.BankAccount{IBAN: "DE89370400440532013000"},
|
BankAccount: models.BankAccount{IBAN: "DE89370400440532013000"},
|
||||||
Membership: models.Membership{SubscriptionModel: models.SubscriptionModel{Name: "Basic"}},
|
Membership: models.Membership{SubscriptionModel: models.SubscriptionModel{Name: "Basic"}},
|
||||||
|
DriversLicence: models.DriversLicence{},
|
||||||
ProfilePicture: "",
|
ProfilePicture: "",
|
||||||
Password: "password123",
|
Password: "password123",
|
||||||
Company: "",
|
Company: "",
|
||||||
|
|||||||
@@ -61,6 +61,18 @@ func (uc *UserController) UpdateHandler(c *gin.Context) {
|
|||||||
c.JSON(http.StatusForbidden, gin.H{"error": "You are not authorized to update this user"})
|
c.JSON(http.StatusForbidden, gin.H{"error": "You are not authorized to update this user"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if user.Membership.SubscriptionModel.Name == "" {
|
||||||
|
logger.Error.Printf("No subscription model provided: %v", user.Email)
|
||||||
|
c.JSON(http.StatusNotAcceptable, gin.H{"error": "No subscription model provided"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
selectedModel, err := uc.MembershipService.GetModelByName(&user.Membership.SubscriptionModel.Name)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error.Printf("%v:No subscription model found: %#v", user.Email, err)
|
||||||
|
c.JSON(http.StatusNotFound, gin.H{"error": "Not a valid subscription model"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
user.Membership.SubscriptionModel = *selectedModel
|
||||||
// TODO: If it's not an admin, prevent changes to critical fields
|
// TODO: If it's not an admin, prevent changes to critical fields
|
||||||
// if userRole != constants.Roles.Admin {
|
// if userRole != constants.Roles.Admin {
|
||||||
// existingUser, err := uc.Service.GetUserByID(jwtUserID)
|
// existingUser, err := uc.Service.GetUserByID(jwtUserID)
|
||||||
@@ -111,7 +123,17 @@ func (uc *UserController) CurrentUserHandler(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, user.Safe())
|
subscriptions, err := uc.MembershipService.GetSubscriptions(nil)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error.Printf("Error retrieving subscriptions: %v", err)
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Error retrieving subscriptions."})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, gin.H{
|
||||||
|
"user": user.Safe(),
|
||||||
|
"subscriptions": subscriptions,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (uc *UserController) LogoutHandler(c *gin.Context) {
|
func (uc *UserController) LogoutHandler(c *gin.Context) {
|
||||||
@@ -187,7 +209,6 @@ func (uc *UserController) RegisterUser(c *gin.Context) {
|
|||||||
c.JSON(http.StatusNotAcceptable, gin.H{"error": "No subscription model provided"})
|
c.JSON(http.StatusNotAcceptable, gin.H{"error": "No subscription model provided"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
logger.Error.Printf("user.membership: %#v", regData.User.Membership)
|
|
||||||
selectedModel, err := uc.MembershipService.GetModelByName(®Data.User.Membership.SubscriptionModel.Name)
|
selectedModel, err := uc.MembershipService.GetModelByName(®Data.User.Membership.SubscriptionModel.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error.Printf("%v:No subscription model found: %#v", regData.User.Email, err)
|
logger.Error.Printf("%v:No subscription model found: %#v", regData.User.Email, err)
|
||||||
@@ -195,7 +216,6 @@ func (uc *UserController) RegisterUser(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
regData.User.Membership.SubscriptionModel = *selectedModel
|
regData.User.Membership.SubscriptionModel = *selectedModel
|
||||||
// logger.Info.Printf("REGISTERING user: %#v", regData.User)
|
|
||||||
|
|
||||||
regData.User.RoleID = constants.Roles.Member
|
regData.User.RoleID = constants.Roles.Member
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import (
|
|||||||
"GoMembership/internal/constants"
|
"GoMembership/internal/constants"
|
||||||
"GoMembership/internal/middlewares"
|
"GoMembership/internal/middlewares"
|
||||||
"GoMembership/internal/models"
|
"GoMembership/internal/models"
|
||||||
|
"GoMembership/internal/repositories"
|
||||||
"GoMembership/internal/utils"
|
"GoMembership/internal/utils"
|
||||||
"GoMembership/pkg/logger"
|
"GoMembership/pkg/logger"
|
||||||
|
|
||||||
@@ -285,7 +286,7 @@ func testCurrentUserHandler(t *testing.T, loginEmail string, loginCookie http.Co
|
|||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
logger.Error.Print("==============================================================")
|
logger.Error.Print("==============================================================")
|
||||||
logger.Error.Printf("Testing : %v", tt.name)
|
logger.Error.Printf("CurrentUser Testing : %v", tt.name)
|
||||||
logger.Error.Print("==============================================================")
|
logger.Error.Print("==============================================================")
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
|
||||||
@@ -303,11 +304,14 @@ func testCurrentUserHandler(t *testing.T, loginEmail string, loginCookie http.Co
|
|||||||
assert.Equal(t, tt.expectedStatus, w.Code)
|
assert.Equal(t, tt.expectedStatus, w.Code)
|
||||||
|
|
||||||
if tt.expectedStatus == http.StatusOK {
|
if tt.expectedStatus == http.StatusOK {
|
||||||
var response models.User
|
var response struct {
|
||||||
|
User models.User `json:"user"`
|
||||||
|
Subscriptions []models.SubscriptionModel `json:"subscriptions"`
|
||||||
|
}
|
||||||
err := json.Unmarshal(w.Body.Bytes(), &response)
|
err := json.Unmarshal(w.Body.Bytes(), &response)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
// logger.Error.Printf("response: %#v", response)
|
||||||
assert.Equal(t, tt.expectedUserMail, response.Email)
|
assert.Equal(t, tt.expectedUserMail, response.User.Email)
|
||||||
var newCookie *http.Cookie
|
var newCookie *http.Cookie
|
||||||
for _, cookie := range w.Result().Cookies() {
|
for _, cookie := range w.Result().Cookies() {
|
||||||
if cookie.Name == "jwt" {
|
if cookie.Name == "jwt" {
|
||||||
@@ -346,6 +350,18 @@ func validateUser(assert bool, wantDBData map[string]interface{}) error {
|
|||||||
return fmt.Errorf("User entry query didn't met expectation: %v != %#v", assert, *users)
|
return fmt.Errorf("User entry query didn't met expectation: %v != %#v", assert, *users)
|
||||||
}
|
}
|
||||||
if assert {
|
if assert {
|
||||||
|
user := (*users)[0]
|
||||||
|
// Check for mandate reference
|
||||||
|
if user.BankAccount.MandateReference == "" {
|
||||||
|
return fmt.Errorf("Mandate reference not generated for user: %s", user.Email)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate mandate reference format
|
||||||
|
expected := user.GenerateMandateReference()
|
||||||
|
if !strings.HasPrefix(user.BankAccount.MandateReference, expected) {
|
||||||
|
return fmt.Errorf("Mandate reference is invalid. Expected: %s, Got: %s", expected, user.BankAccount.MandateReference)
|
||||||
|
}
|
||||||
|
|
||||||
//check for email delivery
|
//check for email delivery
|
||||||
messages := utils.SMTPGetMessages()
|
messages := utils.SMTPGetMessages()
|
||||||
for _, message := range messages {
|
for _, message := range messages {
|
||||||
@@ -355,12 +371,12 @@ func validateUser(assert bool, wantDBData map[string]interface{}) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if strings.Contains(mail.Subject, constants.MailRegistrationSubject) {
|
if strings.Contains(mail.Subject, constants.MailRegistrationSubject) {
|
||||||
if err := checkRegistrationMail(mail, &(*users)[0]); err != nil {
|
if err := checkRegistrationMail(mail, &user); err != nil {
|
||||||
logger.Error.Printf("Error in checkRegistrationMail: %#v", err)
|
logger.Error.Printf("Error in checkRegistrationMail: %#v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else if strings.Contains(mail.Subject, constants.MailVerificationSubject) {
|
} else if strings.Contains(mail.Subject, constants.MailVerificationSubject) {
|
||||||
if err := checkVerificationMail(mail, &(*users)[0]); err != nil {
|
if err := checkVerificationMail(mail, &user); err != nil {
|
||||||
logger.Error.Printf("Error in checkVerificationMail: %#v", err)
|
logger.Error.Printf("Error in checkVerificationMail: %#v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -413,16 +429,6 @@ func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) {
|
|||||||
},
|
},
|
||||||
expectedStatus: http.StatusAccepted,
|
expectedStatus: http.StatusAccepted,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "Password Update",
|
|
||||||
setupCookie: func(req *http.Request) {
|
|
||||||
req.AddCookie(&loginCookie)
|
|
||||||
},
|
|
||||||
updateFunc: func(u *models.User) {
|
|
||||||
u.Password = "NewPassword"
|
|
||||||
},
|
|
||||||
expectedStatus: http.StatusAccepted,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "Valid Update, invalid cookie",
|
name: "Valid Update, invalid cookie",
|
||||||
setupCookie: func(req *http.Request) {
|
setupCookie: func(req *http.Request) {
|
||||||
@@ -444,11 +450,80 @@ func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) {
|
|||||||
},
|
},
|
||||||
updateFunc: func(u *models.User) {
|
updateFunc: func(u *models.User) {
|
||||||
u.Password = ""
|
u.Password = ""
|
||||||
|
u.FirstName = "John Updated"
|
||||||
|
u.LastName = "Doe Updated"
|
||||||
|
u.Phone = "01738484994"
|
||||||
u.Email = "invalid-email"
|
u.Email = "invalid-email"
|
||||||
},
|
},
|
||||||
expectedStatus: http.StatusBadRequest,
|
expectedStatus: http.StatusBadRequest,
|
||||||
expectedError: "Invalid user data",
|
expectedError: "Invalid user data",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Change LicenceNumber",
|
||||||
|
setupCookie: func(req *http.Request) {
|
||||||
|
req.AddCookie(&loginCookie)
|
||||||
|
},
|
||||||
|
updateFunc: func(u *models.User) {
|
||||||
|
u.Password = ""
|
||||||
|
u.FirstName = "John Updated"
|
||||||
|
u.LastName = "Doe Updated"
|
||||||
|
u.Phone = "01738484994"
|
||||||
|
u.DriversLicence.LicenceNumber = "NEWNUMBER"
|
||||||
|
},
|
||||||
|
expectedStatus: http.StatusAccepted,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Add category",
|
||||||
|
setupCookie: func(req *http.Request) {
|
||||||
|
req.AddCookie(&loginCookie)
|
||||||
|
},
|
||||||
|
updateFunc: func(u *models.User) {
|
||||||
|
u.Password = ""
|
||||||
|
u.FirstName = "John Updated"
|
||||||
|
u.LastName = "Doe Updated"
|
||||||
|
u.Phone = "01738484994"
|
||||||
|
u.DriversLicence.LicenceNumber = "NEWNUMBER"
|
||||||
|
var licenceRepo repositories.DriversLicenceInterface = &repositories.DriversLicenceRepository{}
|
||||||
|
category, err := licenceRepo.FindCategoryByName("B")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
u.DriversLicence.LicenceCategories = []models.LicenceCategory{category}
|
||||||
|
},
|
||||||
|
expectedStatus: http.StatusAccepted,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Add 2 categories",
|
||||||
|
setupCookie: func(req *http.Request) {
|
||||||
|
req.AddCookie(&loginCookie)
|
||||||
|
},
|
||||||
|
updateFunc: func(u *models.User) {
|
||||||
|
u.Password = ""
|
||||||
|
u.FirstName = "John Updated"
|
||||||
|
u.LastName = "Doe Updated"
|
||||||
|
u.Phone = "01738484994"
|
||||||
|
u.DriversLicence.LicenceNumber = "NEWNUMBER"
|
||||||
|
var licenceRepo repositories.DriversLicenceInterface = &repositories.DriversLicenceRepository{}
|
||||||
|
category, err := licenceRepo.FindCategoryByName("B")
|
||||||
|
category2, err := licenceRepo.FindCategoryByName("BE")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
u.DriversLicence.LicenceCategories = []models.LicenceCategory{category, category2}
|
||||||
|
},
|
||||||
|
expectedStatus: http.StatusAccepted,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Delete all categories",
|
||||||
|
setupCookie: func(req *http.Request) {
|
||||||
|
req.AddCookie(&loginCookie)
|
||||||
|
},
|
||||||
|
updateFunc: func(u *models.User) {
|
||||||
|
u.Password = ""
|
||||||
|
u.FirstName = "John Updated"
|
||||||
|
u.LastName = "Doe Updated"
|
||||||
|
u.Phone = "01738484994"
|
||||||
|
u.DriversLicence.LicenceNumber = "NEWNUMBER"
|
||||||
|
u.DriversLicence.LicenceCategories = []models.LicenceCategory{}
|
||||||
|
},
|
||||||
|
expectedStatus: http.StatusAccepted,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "User ID mismatch while not admin",
|
name: "User ID mismatch while not admin",
|
||||||
setupCookie: func(req *http.Request) {
|
setupCookie: func(req *http.Request) {
|
||||||
@@ -457,11 +532,28 @@ func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) {
|
|||||||
updateFunc: func(u *models.User) {
|
updateFunc: func(u *models.User) {
|
||||||
u.Password = ""
|
u.Password = ""
|
||||||
u.ID = 1
|
u.ID = 1
|
||||||
|
u.LastName = "Doe Updated"
|
||||||
|
u.Phone = "01738484994"
|
||||||
|
u.DriversLicence.LicenceNumber = "NEWNUMBER"
|
||||||
u.FirstName = "John Missing ID"
|
u.FirstName = "John Missing ID"
|
||||||
},
|
},
|
||||||
expectedStatus: http.StatusForbidden,
|
expectedStatus: http.StatusForbidden,
|
||||||
expectedError: "You are not authorized to update this user",
|
expectedError: "You are not authorized to update this user",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Password Update",
|
||||||
|
setupCookie: func(req *http.Request) {
|
||||||
|
req.AddCookie(&loginCookie)
|
||||||
|
},
|
||||||
|
updateFunc: func(u *models.User) {
|
||||||
|
u.Password = ""
|
||||||
|
u.LastName = "Doe Updated"
|
||||||
|
u.Phone = "01738484994"
|
||||||
|
u.DriversLicence.LicenceNumber = "NEWNUMBER"
|
||||||
|
u.Password = "NewPassword"
|
||||||
|
},
|
||||||
|
expectedStatus: http.StatusAccepted,
|
||||||
|
},
|
||||||
// {
|
// {
|
||||||
// name: "Non-existent User",
|
// name: "Non-existent User",
|
||||||
// setupCookie: func(req *http.Request) {
|
// setupCookie: func(req *http.Request) {
|
||||||
@@ -476,7 +568,6 @@ func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) {
|
|||||||
// expectedError: "User not found",
|
// expectedError: "User not found",
|
||||||
// },
|
// },
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
logger.Error.Print("==============================================================")
|
logger.Error.Print("==============================================================")
|
||||||
logger.Error.Printf("Update Testing : %v", tt.name)
|
logger.Error.Printf("Update Testing : %v", tt.name)
|
||||||
@@ -485,13 +576,13 @@ func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) {
|
|||||||
// Create a copy of the user and apply the updates
|
// Create a copy of the user and apply the updates
|
||||||
updatedUser := user
|
updatedUser := user
|
||||||
tt.updateFunc(&updatedUser)
|
tt.updateFunc(&updatedUser)
|
||||||
|
|
||||||
// Convert user to JSON
|
// Convert user to JSON
|
||||||
jsonData, err := json.Marshal(updatedUser)
|
jsonData, err := json.Marshal(updatedUser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to marshal user data: %v", err)
|
t.Fatalf("Failed to marshal user data: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.Error.Printf("Updated User: %#v", updatedUser)
|
||||||
// Create request
|
// Create request
|
||||||
req, _ := http.NewRequest("PUT", "/users/"+strconv.FormatUint(uint64(user.ID), 10), bytes.NewBuffer(jsonData))
|
req, _ := http.NewRequest("PUT", "/users/"+strconv.FormatUint(uint64(user.ID), 10), bytes.NewBuffer(jsonData))
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
@@ -523,20 +614,59 @@ func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) {
|
|||||||
|
|
||||||
// Verify the update in the database
|
// Verify the update in the database
|
||||||
updatedUserFromDB, err := Uc.Service.GetUserByID(user.ID)
|
updatedUserFromDB, err := Uc.Service.GetUserByID(user.ID)
|
||||||
updatedUserFromDB.UpdatedAt = updatedUser.UpdatedAt
|
assert.NoError(t, err)
|
||||||
updatedUserFromDB.Membership.UpdatedAt = updatedUser.Membership.UpdatedAt
|
|
||||||
updatedUserFromDB.BankAccount.UpdatedAt = updatedUser.BankAccount.UpdatedAt
|
|
||||||
updatedUserFromDB.Verification.UpdatedAt = updatedUser.Verification.UpdatedAt
|
|
||||||
updatedUserFromDB.Membership.SubscriptionModel.UpdatedAt = updatedUser.Membership.SubscriptionModel.UpdatedAt
|
|
||||||
if updatedUser.Password == "" {
|
if updatedUser.Password == "" {
|
||||||
assert.Equal(t, user.Password, (*updatedUserFromDB).Password)
|
assert.Equal(t, user.Password, (*updatedUserFromDB).Password)
|
||||||
} else {
|
} else {
|
||||||
assert.NotEqual(t, user.Password, (*updatedUserFromDB).Password)
|
assert.NotEqual(t, user.Password, (*updatedUserFromDB).Password)
|
||||||
updatedUser.Password = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updatedUserFromDB.Password = ""
|
updatedUserFromDB.Password = ""
|
||||||
assert.NoError(t, err)
|
updatedUser.Password = ""
|
||||||
assert.Equal(t, updatedUser, *updatedUserFromDB, "Updated user in DB does not match expected user")
|
assert.Equal(t, updatedUser.FirstName, updatedUserFromDB.FirstName, "FirstName mismatch")
|
||||||
|
assert.Equal(t, updatedUser.LastName, updatedUserFromDB.LastName, "LastName mismatch")
|
||||||
|
assert.Equal(t, updatedUser.Email, updatedUserFromDB.Email, "Email mismatch")
|
||||||
|
assert.Equal(t, updatedUser.DateOfBirth, updatedUserFromDB.DateOfBirth, "DateOfBirth mismatch")
|
||||||
|
assert.Equal(t, updatedUser.Company, updatedUserFromDB.Company, "Company mismatch")
|
||||||
|
assert.Equal(t, updatedUser.Phone, updatedUserFromDB.Phone, "Phone mismatch")
|
||||||
|
assert.Equal(t, updatedUser.Notes, updatedUserFromDB.Notes, "Notes mismatch")
|
||||||
|
assert.Equal(t, updatedUser.ProfilePicture, updatedUserFromDB.ProfilePicture, "ProfilePicture mismatch")
|
||||||
|
assert.Equal(t, updatedUser.Address, updatedUserFromDB.Address, "Address mismatch")
|
||||||
|
assert.Equal(t, updatedUser.ZipCode, updatedUserFromDB.ZipCode, "ZipCode mismatch")
|
||||||
|
assert.Equal(t, updatedUser.City, updatedUserFromDB.City, "City mismatch")
|
||||||
|
assert.Equal(t, updatedUser.PaymentStatus, updatedUserFromDB.PaymentStatus, "PaymentStatus mismatch")
|
||||||
|
assert.Equal(t, updatedUser.Status, updatedUserFromDB.Status, "Status mismatch")
|
||||||
|
assert.Equal(t, updatedUser.RoleID, updatedUserFromDB.RoleID, "RoleID mismatch")
|
||||||
|
|
||||||
|
// For nested structs, you might want to compare individual fields
|
||||||
|
assert.Equal(t, updatedUser.BankAccount.Bank, updatedUserFromDB.BankAccount.Bank, "BankAccount.Bank mismatch")
|
||||||
|
assert.Equal(t, updatedUser.BankAccount.AccountHolderName, updatedUserFromDB.BankAccount.AccountHolderName, "BankAccount.AccountHolderName mismatch")
|
||||||
|
assert.Equal(t, updatedUser.BankAccount.IBAN, updatedUserFromDB.BankAccount.IBAN, "BankAccount.IBAN mismatch")
|
||||||
|
assert.Equal(t, updatedUser.BankAccount.BIC, updatedUserFromDB.BankAccount.BIC, "BankAccount.BIC mismatch")
|
||||||
|
assert.Equal(t, updatedUser.BankAccount.MandateReference, updatedUserFromDB.BankAccount.MandateReference, "BankAccount.MandateReference mismatch")
|
||||||
|
|
||||||
|
assert.Equal(t, updatedUser.Membership.StartDate, updatedUserFromDB.Membership.StartDate, "Membership.StartDate mismatch")
|
||||||
|
assert.Equal(t, updatedUser.Membership.EndDate, updatedUserFromDB.Membership.EndDate, "Membership.EndDate mismatch")
|
||||||
|
assert.Equal(t, updatedUser.Membership.Status, updatedUserFromDB.Membership.Status, "Membership.Status mismatch")
|
||||||
|
assert.Equal(t, updatedUser.Membership.SubscriptionModelID, updatedUserFromDB.Membership.SubscriptionModelID, "Membership.SubscriptionModelID mismatch")
|
||||||
|
assert.Equal(t, updatedUser.Membership.ParentMembershipID, updatedUserFromDB.Membership.ParentMembershipID, "Membership.ParentMembershipID mismatch")
|
||||||
|
|
||||||
|
assert.Equal(t, updatedUser.DriversLicence.Status, updatedUserFromDB.DriversLicence.Status, "DriversLicence.Status mismatch")
|
||||||
|
assert.Equal(t, updatedUser.DriversLicence.LicenceNumber, updatedUserFromDB.DriversLicence.LicenceNumber, "DriversLicence.LicenceNumber mismatch")
|
||||||
|
assert.Equal(t, updatedUser.DriversLicence.IssuedDate, updatedUserFromDB.DriversLicence.IssuedDate, "DriversLicence.IssuedDate mismatch")
|
||||||
|
assert.Equal(t, updatedUser.DriversLicence.ExpirationDate, updatedUserFromDB.DriversLicence.ExpirationDate, "DriversLicence.ExpirationDate mismatch")
|
||||||
|
assert.Equal(t, updatedUser.DriversLicence.IssuingCountry, updatedUserFromDB.DriversLicence.IssuingCountry, "DriversLicence.IssuingCountry mismatch")
|
||||||
|
|
||||||
|
// For slices or more complex nested structures, you might want to use deep equality checks
|
||||||
|
assert.ElementsMatch(t, updatedUser.Consents, updatedUserFromDB.Consents, "Consents mismatch")
|
||||||
|
if len(updatedUser.DriversLicence.LicenceCategories) > 0 {
|
||||||
|
for i := range updatedUser.DriversLicence.LicenceCategories {
|
||||||
|
assert.Equal(t, updatedUser.DriversLicence.LicenceCategories[i].Category, updatedUserFromDB.DriversLicence.LicenceCategories[i].Category, "LicenceCategory Category mismatch at index %d", i)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert.Emptyf(t, updatedUserFromDB.DriversLicence.LicenceCategories, "Categories aren't empty when they should")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -822,7 +952,7 @@ func getTestUsers() []RegisterUserTest {
|
|||||||
{
|
{
|
||||||
Name: "Correct Entry should pass",
|
Name: "Correct Entry should pass",
|
||||||
WantResponse: http.StatusCreated,
|
WantResponse: http.StatusCreated,
|
||||||
WantDBData: map[string]interface{}{"Email": "john.doe@example.com"},
|
WantDBData: map[string]interface{}{"email": "john.doe@example.com"},
|
||||||
Assert: true,
|
Assert: true,
|
||||||
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User { return user })),
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User { return user })),
|
||||||
},
|
},
|
||||||
@@ -839,7 +969,7 @@ func getTestUsers() []RegisterUserTest {
|
|||||||
{
|
{
|
||||||
Name: "Company present should pass",
|
Name: "Company present should pass",
|
||||||
WantResponse: http.StatusCreated,
|
WantResponse: http.StatusCreated,
|
||||||
WantDBData: map[string]interface{}{"Email": "john.doe2@example.com"},
|
WantDBData: map[string]interface{}{"email": "john.doe2@example.com"},
|
||||||
Assert: true,
|
Assert: true,
|
||||||
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
||||||
user.Email = "john.doe2@example.com"
|
user.Email = "john.doe2@example.com"
|
||||||
@@ -850,7 +980,7 @@ func getTestUsers() []RegisterUserTest {
|
|||||||
{
|
{
|
||||||
Name: "Subscription constraints not entered; should fail",
|
Name: "Subscription constraints not entered; should fail",
|
||||||
WantResponse: http.StatusNotAcceptable,
|
WantResponse: http.StatusNotAcceptable,
|
||||||
WantDBData: map[string]interface{}{"Email": "john.junior.doe@example.com"},
|
WantDBData: map[string]interface{}{"email": "john.junior.doe@example.com"},
|
||||||
Assert: false,
|
Assert: false,
|
||||||
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
||||||
user.Email = "john.junior.doe@example.com"
|
user.Email = "john.junior.doe@example.com"
|
||||||
@@ -861,7 +991,7 @@ func getTestUsers() []RegisterUserTest {
|
|||||||
{
|
{
|
||||||
Name: "Subscription constraints wrong; should fail",
|
Name: "Subscription constraints wrong; should fail",
|
||||||
WantResponse: http.StatusNotAcceptable,
|
WantResponse: http.StatusNotAcceptable,
|
||||||
WantDBData: map[string]interface{}{"Email": "john.junior.doe@example.com"},
|
WantDBData: map[string]interface{}{"email": "john.junior.doe@example.com"},
|
||||||
Assert: false,
|
Assert: false,
|
||||||
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
||||||
user.Email = "john.junior.doe@example.com"
|
user.Email = "john.junior.doe@example.com"
|
||||||
@@ -873,7 +1003,7 @@ func getTestUsers() []RegisterUserTest {
|
|||||||
{
|
{
|
||||||
Name: "Subscription constraints correct, should pass",
|
Name: "Subscription constraints correct, should pass",
|
||||||
WantResponse: http.StatusCreated,
|
WantResponse: http.StatusCreated,
|
||||||
WantDBData: map[string]interface{}{"Email": "john.junior.doe@example.com"},
|
WantDBData: map[string]interface{}{"email": "john.junior.doe@example.com"},
|
||||||
Assert: true,
|
Assert: true,
|
||||||
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
||||||
user.Email = "john.junior.doe@example.com"
|
user.Email = "john.junior.doe@example.com"
|
||||||
@@ -882,5 +1012,16 @@ func getTestUsers() []RegisterUserTest {
|
|||||||
return user
|
return user
|
||||||
})),
|
})),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "Correct Entry with Mandate Reference",
|
||||||
|
WantResponse: http.StatusCreated,
|
||||||
|
WantDBData: map[string]interface{}{"email": "john.mandate@example.com"},
|
||||||
|
Assert: true,
|
||||||
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
||||||
|
user.Email = "john.mandate@example.com"
|
||||||
|
user.BankAccount.IBAN = "DE89370400440532013000"
|
||||||
|
return user
|
||||||
|
})),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ func Open(dbPath string, adminMail string) error {
|
|||||||
&models.Membership{},
|
&models.Membership{},
|
||||||
&models.Consent{},
|
&models.Consent{},
|
||||||
&models.Verification{},
|
&models.Verification{},
|
||||||
|
&models.DriversLicence{},
|
||||||
|
&models.LicenceCategory{},
|
||||||
&models.BankAccount{}); err != nil {
|
&models.BankAccount{}); err != nil {
|
||||||
logger.Error.Fatalf("Couldn't create database: %v", err)
|
logger.Error.Fatalf("Couldn't create database: %v", err)
|
||||||
return err
|
return err
|
||||||
@@ -51,6 +53,13 @@ func Open(dbPath string, adminMail string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
categories := createLicenceCategories()
|
||||||
|
for _, model := range categories {
|
||||||
|
result := db.Create(&model)
|
||||||
|
if result.Error != nil {
|
||||||
|
return result.Error
|
||||||
|
}
|
||||||
|
}
|
||||||
admin, err := createAdmin(adminMail, createdModel.ID)
|
admin, err := createAdmin(adminMail, createdModel.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -73,6 +82,28 @@ func createSubscriptionModels() []models.SubscriptionModel {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createLicenceCategories() []models.LicenceCategory {
|
||||||
|
return []models.LicenceCategory{
|
||||||
|
{Category: "AM"},
|
||||||
|
{Category: "A1"},
|
||||||
|
{Category: "A2"},
|
||||||
|
{Category: "A"},
|
||||||
|
{Category: "B"},
|
||||||
|
{Category: "C1"},
|
||||||
|
{Category: "C"},
|
||||||
|
{Category: "D1"},
|
||||||
|
{Category: "D"},
|
||||||
|
{Category: "BE"},
|
||||||
|
{Category: "C1E"},
|
||||||
|
{Category: "CE"},
|
||||||
|
{Category: "D1E"},
|
||||||
|
{Category: "DE"},
|
||||||
|
{Category: "R"},
|
||||||
|
{Category: "L"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Landing page to create an admin
|
// TODO: Landing page to create an admin
|
||||||
|
|
||||||
func createAdmin(userMail string, subscriptionModelID uint) (*models.User, error) {
|
func createAdmin(userMail string, subscriptionModelID uint) (*models.User, error) {
|
||||||
|
|||||||
27
internal/models/drivers_licence.go
Normal file
27
internal/models/drivers_licence.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DriversLicence struct {
|
||||||
|
gorm.Model
|
||||||
|
Status int8 `json:"licence_status" validate:"omitempty,number"`
|
||||||
|
LicenceNumber string `json:"licence_number" validate:"safe_content"`
|
||||||
|
IssuedDate time.Time `json:"licence_issued_date" validate:"omitempty,lte"`
|
||||||
|
ExpirationDate time.Time `json:"licence_expiration_date" validate:"omitempty,gt"`
|
||||||
|
IssuingCountry string `json:"licence_country" validate:"safe_content"`
|
||||||
|
LicenceCategories []LicenceCategory `json:"licence_categories" gorm:"many2many:licence_2_categories"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type LicenceCategory struct {
|
||||||
|
gorm.Model
|
||||||
|
Category string `json:"licence_category" validate:"safe_content"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// func (d *DriversLicence) BeforeCreate(tx *gorm.DB) (err error) {
|
||||||
|
// d.Status = constants.UnverifiedStatus
|
||||||
|
// return
|
||||||
|
// }
|
||||||
@@ -7,7 +7,7 @@ type Membership struct {
|
|||||||
UpdatedAt time.Time
|
UpdatedAt time.Time
|
||||||
StartDate time.Time `json:"start_date"`
|
StartDate time.Time `json:"start_date"`
|
||||||
EndDate time.Time `json:"end_date"`
|
EndDate time.Time `json:"end_date"`
|
||||||
Status string `json:"status" validate:"safe_content"`
|
Status int8 `json:"status" validate:"safe_content"`
|
||||||
SubscriptionModel SubscriptionModel `gorm:"foreignKey:SubscriptionModelID" json:"subscription_model"`
|
SubscriptionModel SubscriptionModel `gorm:"foreignKey:SubscriptionModelID" json:"subscription_model"`
|
||||||
SubscriptionModelID uint `json:"subsription_model_id"`
|
SubscriptionModelID uint `json:"subsription_model_id"`
|
||||||
ParentMembershipID uint `json:"parent_member_id" validate:"omitempty,omitnil,number"`
|
ParentMembershipID uint `json:"parent_member_id" validate:"omitempty,omitnil,number"`
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"GoMembership/internal/constants"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/alexedwards/argon2id"
|
"github.com/alexedwards/argon2id"
|
||||||
@@ -9,36 +9,45 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
DateOfBirth time.Time `gorm:"not null" json:"date_of_birth" validate:"required,age"`
|
|
||||||
Company string `json:"company" validate:"omitempty,omitnil,safe_content"`
|
|
||||||
Phone string `json:"phone" validate:"omitempty,omitnil,safe_content"`
|
|
||||||
Notes *string `json:"notes,safe_content"`
|
|
||||||
FirstName string `gorm:"not null" json:"first_name" validate:"required,safe_content"`
|
|
||||||
Password string `json:"password" validate:"required_unless=RoleID 0,safe_content"`
|
|
||||||
Email string `gorm:"unique;not null" json:"email" validate:"required,email,safe_content"`
|
|
||||||
LastName string `gorm:"not null" json:"last_name" validate:"required,safe_content"`
|
|
||||||
ProfilePicture string `json:"profile_picture" validate:"omitempty,omitnil,image,safe_content"`
|
|
||||||
Address string `gorm:"not null" json:"address" validate:"required,safe_content"`
|
|
||||||
ZipCode string `gorm:"not null" json:"zip_code" validate:"required,alphanum,safe_content"`
|
|
||||||
City string `form:"not null" json:"city" validate:"required,alphaunicode,safe_content"`
|
|
||||||
Consents []Consent `gorm:"constraint:OnUpdate:CASCADE"`
|
|
||||||
BankAccount BankAccount `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"bank_account"`
|
|
||||||
Verification Verification `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
|
|
||||||
Membership Membership `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"membership"`
|
|
||||||
ID int64 `gorm:"primaryKey" json:"id"`
|
|
||||||
PaymentStatus int8 `json:"payment_status"`
|
|
||||||
Status int8 `json:"status"`
|
|
||||||
RoleID int8 `json:"role_id"`
|
|
||||||
gorm.Model
|
gorm.Model
|
||||||
|
DateOfBirth time.Time `gorm:"not null" json:"date_of_birth" validate:"required,age"`
|
||||||
|
Company string `json:"company" validate:"omitempty,omitnil,safe_content"`
|
||||||
|
Phone string `json:"phone" validate:"omitempty,omitnil,safe_content"`
|
||||||
|
Notes string `json:"notes" validate:"safe_content"`
|
||||||
|
FirstName string `gorm:"not null" json:"first_name" validate:"required,safe_content"`
|
||||||
|
Password string `json:"password" validate:"required_unless=RoleID 0,safe_content"`
|
||||||
|
Email string `gorm:"unique;not null" json:"email" validate:"required,email,safe_content"`
|
||||||
|
LastName string `gorm:"not null" json:"last_name" validate:"required,safe_content"`
|
||||||
|
ProfilePicture string `json:"profile_picture" validate:"omitempty,omitnil,image,safe_content"`
|
||||||
|
Address string `gorm:"not null" json:"address" validate:"required,safe_content"`
|
||||||
|
ZipCode string `gorm:"not null" json:"zip_code" validate:"required,alphanum,safe_content"`
|
||||||
|
City string `form:"not null" json:"city" validate:"required,alphaunicode,safe_content"`
|
||||||
|
Consents []Consent `gorm:"constraint:OnUpdate:CASCADE"`
|
||||||
|
BankAccount BankAccount `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"bank_account"`
|
||||||
|
BankAccountID uint
|
||||||
|
Verification Verification `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
|
||||||
|
VerificationID uint
|
||||||
|
Membership Membership `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"membership"`
|
||||||
|
MembershipID uint
|
||||||
|
DriversLicence DriversLicence `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"drivers_licence"`
|
||||||
|
DriversLicenceID uint
|
||||||
|
ID uint `json:"id"`
|
||||||
|
PaymentStatus int8 `json:"payment_status"`
|
||||||
|
Status int8 `json:"status"`
|
||||||
|
RoleID int8 `json:"role_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// BeforeCreate sets the default value for Status
|
func (u *User) AfterCreate(tx *gorm.DB) (err error) {
|
||||||
func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
|
if u.BankAccount.ID != 0 && u.BankAccount.MandateReference == "" {
|
||||||
if u.Status == 0 { // Assuming 0 is an unset value
|
mandateReference := u.GenerateMandateReference()
|
||||||
u.Status = constants.UnverifiedStatus
|
|
||||||
u.PaymentStatus = constants.AwaitingPaymentStatus
|
return tx.Model(&u.BankAccount).Update("MandateReference", mandateReference).Error
|
||||||
}
|
}
|
||||||
return
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *User) GenerateMandateReference() string {
|
||||||
|
return fmt.Sprintf("%s%d%s", time.Now().Format("20060102"), u.ID, u.BankAccount.IBAN)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *User) PasswordMatches(plaintextPassword string) (bool, error) {
|
func (u *User) PasswordMatches(plaintextPassword string) (bool, error) {
|
||||||
|
|||||||
25
internal/repositories/drivers_licence_repository.go
Normal file
25
internal/repositories/drivers_licence_repository.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package repositories
|
||||||
|
|
||||||
|
import (
|
||||||
|
"GoMembership/internal/database"
|
||||||
|
"GoMembership/internal/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DriversLicenceInterface interface {
|
||||||
|
FindCategoryByName(categoryName string) (models.LicenceCategory, error)
|
||||||
|
FindCategoriesByIDs(ids []uint) ([]models.LicenceCategory, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type DriversLicenceRepository struct{}
|
||||||
|
|
||||||
|
func (r *DriversLicenceRepository) FindCategoriesByIDs(ids []uint) ([]models.LicenceCategory, error) {
|
||||||
|
var categories []models.LicenceCategory
|
||||||
|
err := database.DB.Where("id IN ?", ids).Find(&categories).Error
|
||||||
|
return categories, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *DriversLicenceRepository) FindCategoryByName(categoryName string) (models.LicenceCategory, error) {
|
||||||
|
var category models.LicenceCategory
|
||||||
|
err := database.DB.Where("category = ?", categoryName).First(&category).Error
|
||||||
|
return category, err
|
||||||
|
}
|
||||||
@@ -68,12 +68,10 @@ func (ur *UserRepository) UpdateUser(user *models.User) (*models.User, error) {
|
|||||||
func (ur *UserRepository) GetUsers(where map[string]interface{}) (*[]models.User, error) {
|
func (ur *UserRepository) GetUsers(where map[string]interface{}) (*[]models.User, error) {
|
||||||
var users []models.User
|
var users []models.User
|
||||||
result := database.DB.
|
result := database.DB.
|
||||||
Preload("Consents").
|
Preload(clause.Associations).
|
||||||
Preload("BankAccount").
|
Preload("Membership.SubscriptionModel").
|
||||||
Preload("Verification").
|
Preload("DriversLicence.LicenceCategories").
|
||||||
Preload("Membership", func(db *gorm.DB) *gorm.DB {
|
Where(where).Find(&users)
|
||||||
return db.Preload("SubscriptionModel")
|
|
||||||
}).Where(where).Find(&users)
|
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
if result.Error == gorm.ErrRecordNotFound {
|
if result.Error == gorm.ErrRecordNotFound {
|
||||||
return nil, gorm.ErrRecordNotFound
|
return nil, gorm.ErrRecordNotFound
|
||||||
@@ -86,12 +84,10 @@ func (ur *UserRepository) GetUsers(where map[string]interface{}) (*[]models.User
|
|||||||
func (ur *UserRepository) GetUserByID(userID *uint) (*models.User, error) {
|
func (ur *UserRepository) GetUserByID(userID *uint) (*models.User, error) {
|
||||||
var user models.User
|
var user models.User
|
||||||
result := database.DB.
|
result := database.DB.
|
||||||
Preload("Consents").
|
Preload(clause.Associations).
|
||||||
Preload("BankAccount").
|
Preload("Membership.SubscriptionModel").
|
||||||
Preload("Verification").
|
Preload("DriversLicence.LicenceCategories").
|
||||||
Preload("Membership", func(db *gorm.DB) *gorm.DB {
|
First(&user, userID)
|
||||||
return db.Preload("SubscriptionModel")
|
|
||||||
}).First(&user, userID)
|
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
if result.Error == gorm.ErrRecordNotFound {
|
if result.Error == gorm.ErrRecordNotFound {
|
||||||
return nil, gorm.ErrRecordNotFound
|
return nil, gorm.ErrRecordNotFound
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ func Run() {
|
|||||||
membershipService := &services.MembershipService{Repo: membershipRepo, SubscriptionRepo: subscriptionRepo}
|
membershipService := &services.MembershipService{Repo: membershipRepo, SubscriptionRepo: subscriptionRepo}
|
||||||
|
|
||||||
var userRepo repositories.UserRepositoryInterface = &repositories.UserRepository{}
|
var userRepo repositories.UserRepositoryInterface = &repositories.UserRepository{}
|
||||||
userService := &services.UserService{Repo: userRepo}
|
var licenceRepo repositories.DriversLicenceInterface = &repositories.DriversLicenceRepository{}
|
||||||
|
userService := &services.UserService{Repo: userRepo, Licences: licenceRepo}
|
||||||
|
|
||||||
userController := &controllers.UserController{Service: userService, EmailService: emailService, ConsentService: consentService, BankAccountService: bankAccountService, MembershipService: membershipService}
|
userController := &controllers.UserController{Service: userService, EmailService: emailService, ConsentService: consentService, BankAccountService: bankAccountService, MembershipService: membershipService}
|
||||||
membershipController := &controllers.MembershipController{Service: *membershipService}
|
membershipController := &controllers.MembershipController{Service: *membershipService}
|
||||||
|
|||||||
@@ -1,49 +1,12 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"GoMembership/internal/models"
|
|
||||||
"GoMembership/internal/repositories"
|
"GoMembership/internal/repositories"
|
||||||
"crypto/rand"
|
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type BankAccountServiceInterface interface {
|
type BankAccountServiceInterface interface {
|
||||||
RegisterBankAccount(bankAccount *models.BankAccount) (int64, error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type BankAccountService struct {
|
type BankAccountService struct {
|
||||||
Repo repositories.BankAccountRepositoryInterface
|
Repo repositories.BankAccountRepositoryInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (service *BankAccountService) RegisterBankAccount(bankAccount *models.BankAccount) (int64, error) {
|
|
||||||
bankAccount.MandateDateSigned = time.Now()
|
|
||||||
ref, err := generateSEPAMandateReference(strconv.FormatInt(bankAccount.UserID, 10))
|
|
||||||
if err != nil {
|
|
||||||
return -1, err
|
|
||||||
}
|
|
||||||
bankAccount.MandateReference = ref
|
|
||||||
|
|
||||||
return service.Repo.CreateBankAccount(bankAccount)
|
|
||||||
}
|
|
||||||
|
|
||||||
func generateUniqueID(length int) (string, error) {
|
|
||||||
bytes := make([]byte, length)
|
|
||||||
_, err := rand.Read(bytes)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return hex.EncodeToString(bytes), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func generateSEPAMandateReference(userID string) (string, error) {
|
|
||||||
today := time.Now().Format("20060102") // Format YYYYMMDD
|
|
||||||
uniqueID, err := generateUniqueID(4) // 4 Bytes = 8 Hex-Zeichen
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
mandateReference := fmt.Sprintf("%s-%s-%s", userID, today, uniqueID)
|
|
||||||
return mandateReference, nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -60,6 +60,9 @@ func (service *MembershipService) GetModelByName(modelname *string) (*models.Sub
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (service *MembershipService) GetSubscriptions(where map[string]interface{}) (*[]models.SubscriptionModel, error) {
|
func (service *MembershipService) GetSubscriptions(where map[string]interface{}) (*[]models.SubscriptionModel, error) {
|
||||||
|
if where == nil {
|
||||||
|
where = map[string]interface{}{}
|
||||||
|
}
|
||||||
return service.SubscriptionRepo.GetSubscriptions(where)
|
return service.SubscriptionRepo.GetSubscriptions(where)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ type UserServiceInterface interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type UserService struct {
|
type UserService struct {
|
||||||
Repo repositories.UserRepositoryInterface
|
Repo repositories.UserRepositoryInterface
|
||||||
|
Licences repositories.DriversLicenceInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (service *UserService) UpdateUser(user *models.User, userRole int8) (*models.User, error) {
|
func (service *UserService) UpdateUser(user *models.User, userRole int8) (*models.User, error) {
|
||||||
@@ -69,6 +70,8 @@ func (service *UserService) RegisterUser(user *models.User) (uint, string, error
|
|||||||
user.Status = constants.UnverifiedStatus
|
user.Status = constants.UnverifiedStatus
|
||||||
user.CreatedAt = time.Now()
|
user.CreatedAt = time.Now()
|
||||||
user.UpdatedAt = time.Now()
|
user.UpdatedAt = time.Now()
|
||||||
|
user.PaymentStatus = constants.AwaitingPaymentStatus
|
||||||
|
user.BankAccount.MandateDateSigned = time.Now()
|
||||||
id, err := service.Repo.CreateUser(user)
|
id, err := service.Repo.CreateUser(user)
|
||||||
|
|
||||||
if err != nil && strings.Contains(err.Error(), "UNIQUE constraint failed") {
|
if err != nil && strings.Contains(err.Error(), "UNIQUE constraint failed") {
|
||||||
|
|||||||
Reference in New Issue
Block a user