diff --git a/backend/src/api/dto/base.go b/backend/src/api/dto/base.go new file mode 100644 index 0000000..d0314d0 --- /dev/null +++ b/backend/src/api/dto/base.go @@ -0,0 +1,7 @@ +package dto + +type LocationDto struct { + Country string `json:"country"` + State string `json:"state"` + City string `json:"city"` +} diff --git a/backend/src/api/dto/post.go b/backend/src/api/dto/post.go new file mode 100644 index 0000000..07bf682 --- /dev/null +++ b/backend/src/api/dto/post.go @@ -0,0 +1,27 @@ +package dto + +type PostDto struct { + Title string `json:"title"` + Description string `json:"description"` + PropertyId uint `json:"propertyId"` +} + +type PostCreationDto struct { + Title string `json:"title"` + Description string `json:"description"` +} + +type PostCommentDto struct { + Id uint `json:"id"` + Description string `json:"description"` +} + +type PostCommentCreationDto struct { + Description string `json:"description"` + PostId uint `json:"postId"` +} + +type AnnounceCreationDto struct { + Property PropertyCreationDto `json:"property"` + Post PostCommentCreationDto `json:"post"` +} diff --git a/backend/src/api/dto/property.dto.go b/backend/src/api/dto/property.dto.go deleted file mode 100644 index b3b7450..0000000 --- a/backend/src/api/dto/property.dto.go +++ /dev/null @@ -1,14 +0,0 @@ -package dto - -type PropertyDto struct { - Owner UserDetail `json:"owner"` - CurrentCurrency string `json:"currentCurrency"` - CurrentPrice float32 `json:"currentPrice"` -} - -type PropertyDetailDto struct { - NumberOfRooms int `json:"numberOfRooms"` - NumberOfBathrooms int `json:"numberOfBathrooms"` - NumberOfKitchens int `json:"numberOfKitchens"` - NumberOfParkingSpaces int `json:"numberOfParkingSpaces"` -} diff --git a/backend/src/api/dto/property.go b/backend/src/api/dto/property.go new file mode 100644 index 0000000..8414c7a --- /dev/null +++ b/backend/src/api/dto/property.go @@ -0,0 +1,23 @@ +package dto + +type PropertyDto struct { + Owner UserDetail `json:"owner"` + CurrentCurrency string `json:"currentCurrency"` + CurrentPrice float32 `json:"currentPrice"` + PropertyDetail PropertyDetailDto `json:"propertyDetail"` + Location LocationDto `json:"location"` + Announcement PostDto `json:"announcement"` +} + +type PropertyCreationDto struct { + OwnerId uint `json:"ownerId"` + CurrentCurrency string `json:"currentCurrency"` + CurrentPrice float32 `json:"currentPrice"` +} + +type PropertyDetailDto struct { + NumberOfRooms int `json:"numberOfRooms"` + NumberOfBathrooms int `json:"numberOfBathrooms"` + NumberOfKitchens int `json:"numberOfKitchens"` + NumberOfParkingSpaces int `json:"numberOfParkingSpaces"` +} diff --git a/backend/src/api/handler/property_handler.go b/backend/src/api/handler/property_handler.go index 166ea46..01982b6 100644 --- a/backend/src/api/handler/property_handler.go +++ b/backend/src/api/handler/property_handler.go @@ -28,3 +28,7 @@ func (handler *PropertyHandler) GetAllByCategory(context *gin.Context, category context.JSON(http.StatusOK, response2.GenerateResponse(authDetail, true)) } + +func (handler *PropertyHandler) CreateProperty(context *gin.Context) { + +} diff --git a/backend/src/data/database/migration/1_init.go b/backend/src/data/database/migration/1_init.go index 1e9a4ba..79a465d 100644 --- a/backend/src/data/database/migration/1_init.go +++ b/backend/src/data/database/migration/1_init.go @@ -37,7 +37,7 @@ func createAllTables(database *gorm.DB) { addTable(database, &tables, model2.PropertyCategory{}) addTable(database, &tables, model2.Property{}) - addTable(database, &tables, model2.PropertyDetails{}) + addTable(database, &tables, model2.PropertyDetail{}) addTable(database, &tables, model2.PropertyPrice{}) addTable(database, &tables, model2.Post{}) diff --git a/backend/src/data/model/post.go b/backend/src/data/model/post.go index 1b19bac..6257fc3 100644 --- a/backend/src/data/model/post.go +++ b/backend/src/data/model/post.go @@ -11,6 +11,8 @@ type Post struct { type PostComment struct { BaseModel Description string `gorm:"type:string; size:512; not null;"` + UserId uint + User User `gorm:"foreignKey:UserId; constraint:OnUpdate:NO ACTION; OnDelete:NO ACTION;"` PostId uint Post Post `gorm:"foreignKey:PostId; constraint:OnUpdate:NO ACTION; OnDelete:NO ACTION;"` } diff --git a/backend/src/data/model/property.go b/backend/src/data/model/property.go index 793f72a..4de5b2c 100644 --- a/backend/src/data/model/property.go +++ b/backend/src/data/model/property.go @@ -9,7 +9,7 @@ type Property struct { OwnerId uint Owner User `gorm:"foreignKey:OwnerId; constraint:OnUpdate:NO ACTION; OnDelete:NO ACTION;"` CityId uint - City User `gorm:"foreignKey:CityId; constraint:OnUpdate:NO ACTION; OnDelete:NO ACTION;"` + City City `gorm:"foreignKey:CityId; constraint:OnUpdate:NO ACTION; OnDelete:NO ACTION;"` CurrentCurrency string `gorm:"size:4; type:string; not null;"` CurrentPrice float32 `gorm:"type:decimal(10,2); not null;"` Prices *[]PropertyPrice @@ -25,7 +25,7 @@ type PropertyCategory struct { Properties *[]Property } -type PropertyDetails struct { +type PropertyDetail struct { BaseModel NumberOfRooms int `gorm:"type:int; not null;"` NumberOfBathrooms int `gorm:"type:int; not null;"` diff --git a/backend/src/data/repository/property_detail_repository.go b/backend/src/data/repository/property_detail_repository.go new file mode 100644 index 0000000..566ddd6 --- /dev/null +++ b/backend/src/data/repository/property_detail_repository.go @@ -0,0 +1,37 @@ +package repository + +import ( + "github.com/Stefan923/go-estate-market/data/database" + "github.com/Stefan923/go-estate-market/data/model" + "github.com/Stefan923/go-estate-market/metrics" + "reflect" +) + +type PropertyDetailRepository struct { + BaseRepository[model.PropertyDetail] +} + +func NewPropertyDetailRepository() *PropertyDetailRepository { + return &PropertyDetailRepository{ + BaseRepository: BaseRepository[model.PropertyDetail]{ + Database: database.GetDatabase(), + Preloads: []PreloadSetting{}, + }, + } +} + +func (repository *PropertyDetailRepository) FindByPropertyId(propertyId uint) (*model.PropertyDetail, error) { + var propertyDetail *model.PropertyDetail + + err := repository.Database. + Where("property_id = ? and deleted_at is null", propertyId). + First(propertyDetail). + Error + if err != nil { + metrics.DatabaseCallCounter.WithLabelValues(reflect.TypeOf(*propertyDetail).String(), "FindByPropertyId", "Failed").Inc() + return nil, err + } + + metrics.DatabaseCallCounter.WithLabelValues(reflect.TypeOf(*propertyDetail).String(), "FindByPropertyId", "Success").Inc() + return propertyDetail, nil +} diff --git a/backend/src/data/repository/property_repository.go b/backend/src/data/repository/property_repository.go index f5ed1bd..7fb0d2d 100644 --- a/backend/src/data/repository/property_repository.go +++ b/backend/src/data/repository/property_repository.go @@ -16,7 +16,13 @@ func NewPropertyRepository() *PropertyRepository { BaseRepository: BaseRepository[model.Property]{ Database: database.GetDatabase(), Preloads: []PreloadSetting{ - {EntityName: "Category"}, + {EntityName: "PropertyCategory"}, + {EntityName: "UserAccount"}, + {EntityName: "User"}, + {EntityName: "Country"}, + {EntityName: "State"}, + {EntityName: "City"}, + {EntityName: "Post"}, }, }, } diff --git a/backend/src/service/property_service.go b/backend/src/service/property_service.go index af32188..dd6db0f 100644 --- a/backend/src/service/property_service.go +++ b/backend/src/service/property_service.go @@ -1,14 +1,17 @@ package service import ( + "github.com/Stefan923/go-estate-market/api/dto" "github.com/Stefan923/go-estate-market/data/model" "github.com/Stefan923/go-estate-market/data/pagination" "github.com/Stefan923/go-estate-market/data/repository" + error3 "github.com/Stefan923/go-estate-market/error" ) type PropertyService struct { BaseService[model.Property, model.Property, model.Property, model.Property] - propertyRepository *repository.PropertyRepository + propertyRepository *repository.PropertyRepository + propertyDetailRepository *repository.PropertyDetailRepository } func NewPropertyService() *PropertyService { @@ -17,10 +20,54 @@ func NewPropertyService() *PropertyService { BaseService: BaseService[model.Property, model.Property, model.Property, model.Property]{ Repository: &propertyRepository.BaseRepository, }, - propertyRepository: propertyRepository, + propertyRepository: propertyRepository, + propertyDetailRepository: repository.NewPropertyDetailRepository(), } } -func (service *PropertyService) GetAllByCategory(category string, pageInfo *pagination.PageInfo) (*pagination.Page[model.Property], error) { - return service.propertyRepository.FindAllByCategory(category, pageInfo) +func (service *PropertyService) GetAllByCategory(category string, pageInfo *pagination.PageInfo) (*pagination.Page[dto.PropertyDto], error) { + properties, err := service.propertyRepository.FindAllByCategory(category, pageInfo) + if err != nil { + return nil, &error3.InternalError{EndUserMessage: error3.RecordNotFound} + } + + var mappedProperties *pagination.Page[dto.PropertyDto] + for _, property := range *properties.Elements { + propertyDetail, err := service.propertyDetailRepository.FindByPropertyId(property.Id) + if err != nil { + return nil, &error3.InternalError{EndUserMessage: error3.RecordNotFound} + } + + mappedProperty := dto.PropertyDto{ + Owner: dto.UserDetail{ + Email: property.Owner.UserAccount.Email, + FirstName: property.Owner.FirstName, + LastName: property.Owner.LastName, + }, + CurrentCurrency: property.CurrentCurrency, + CurrentPrice: property.CurrentPrice, + PropertyDetail: dto.PropertyDetailDto{ + NumberOfRooms: propertyDetail.NumberOfRooms, + NumberOfBathrooms: propertyDetail.NumberOfBathrooms, + NumberOfKitchens: propertyDetail.NumberOfKitchens, + NumberOfParkingSpaces: propertyDetail.NumberOfParkingSpaces, + }, + Location: dto.LocationDto{ + Country: property.City.State.Country.Name, + State: property.City.State.Name, + City: property.City.Name, + }, + Announcement: dto.PostDto{ + Title: property.Announcement.Title, + Description: property.Announcement.Description, + PropertyId: property.Id, + }, + } + *mappedProperties.Elements = append(*mappedProperties.Elements, mappedProperty) + } + + mappedProperties.PageNumber = properties.PageNumber + mappedProperties.PageSize = properties.PageSize + + return mappedProperties, nil }