refact: stress refact collector and make average price for trashcategory

This commit is contained in:
pahmiudahgede 2025-05-22 00:03:16 +07:00
parent 6df861f776
commit 226d188ece
16 changed files with 967 additions and 545 deletions

View File

@ -43,6 +43,7 @@ func ConnectDatabase() {
// =>user preparation<=
&model.User{},
&model.Collector{},
&model.AvaibleTrashByCollector{},
&model.Role{},
&model.UserPin{},
&model.Address{},

View File

@ -1,10 +1,22 @@
package dto
import "strings"
import (
"fmt"
"strings"
)
type RequestCollectorDTO struct {
UserId string `json:"user_id"`
AddressId string `json:"address_id"`
AddressId string `json:"address_id"`
AvaibleTrashbyCollector []RequestAvaibleTrashbyCollector `json:"avaible_trash"`
}
type RequestAvaibleTrashbyCollector struct {
TrashId string `json:"trash_id"`
TrashPrice float32 `json:"trash_price"`
}
type RequestAddAvaibleTrash struct {
AvaibleTrash []RequestAvaibleTrashbyCollector `json:"avaible_trash"`
}
type SelectCollectorRequest struct {
@ -24,25 +36,65 @@ func (r *SelectCollectorRequest) ValidateSelectCollectorRequest() (map[string][]
return nil, true
}
type ResponseCollectorDTO struct {
ID string `json:"collector_id"`
UserId string `json:"user_id"`
User []UserResponseDTO `json:"user,omitempty"`
AddressId string `json:"address_id"`
Address []AddressResponseDTO `json:"address,omitempty"`
JobStatus *string `json:"job_status,omitempty"`
Rating float32 `json:"rating"`
func (r *RequestAddAvaibleTrash) ValidateRequestAddAvaibleTrash() (map[string][]string, bool) {
errors := make(map[string][]string)
if len(r.AvaibleTrash) == 0 {
errors["avaible_trash"] = append(errors["avaible_trash"], "tidak boleh kosong")
}
for i, trash := range r.AvaibleTrash {
if strings.TrimSpace(trash.TrashId) == "" {
errors[fmt.Sprintf("avaible_trash[%d].trash_id", i)] = append(errors[fmt.Sprintf("avaible_trash[%d].trash_id", i)], "trash_id tidak boleh kosong")
}
if trash.TrashPrice <= 0 {
errors[fmt.Sprintf("avaible_trash[%d].trash_price", i)] = append(errors[fmt.Sprintf("avaible_trash[%d].trash_price", i)], "trash_price harus lebih dari 0")
}
}
if len(errors) > 0 {
return errors, false
}
return nil, true
}
func (r *RequestCollectorDTO) ValidateRequestColector() (map[string][]string, bool) {
type ResponseCollectorDTO struct {
ID string `json:"collector_id"`
UserId string `json:"user_id"`
User *UserResponseDTO `json:"user,omitempty"`
AddressId string `json:"address_id"`
Address *AddressResponseDTO `json:"address,omitempty"`
JobStatus *string `json:"job_status,omitempty"`
Rating float32 `json:"rating"`
AvaibleTrashbyCollector []ResponseAvaibleTrashByCollector `json:"avaible_trash"`
}
type ResponseAvaibleTrashByCollector struct {
ID string `json:"id"`
TrashId string `json:"trash_id"`
TrashName string `json:"trash_name"`
TrashIcon string `json:"trash_icon"`
TrashPrice float32 `json:"trash_price"`
}
func (r *RequestCollectorDTO) ValidateRequestCollector() (map[string][]string, bool) {
errors := make(map[string][]string)
if strings.TrimSpace(r.AddressId) == "" {
errors["address_id"] = append(errors["address_id"], "address_id harus diisi")
}
for i, trash := range r.AvaibleTrashbyCollector {
if strings.TrimSpace(trash.TrashId) == "" {
errors[fmt.Sprintf("avaible_trash[%d].trash_id", i)] = append(errors[fmt.Sprintf("avaible_trash[%d].trash_id", i)], "trash_id tidak boleh kosong")
}
if trash.TrashPrice <= 0 {
errors[fmt.Sprintf("avaible_trash[%d].trash_price", i)] = append(errors[fmt.Sprintf("avaible_trash[%d].trash_price", i)], "trash_price harus lebih dari 0")
}
}
if len(errors) > 0 {
return errors, false
}
return nil, true
}

View File

@ -33,14 +33,14 @@ type CartItemResponse struct {
}
type RequestCartItems struct {
TrashID string `json:"trashid"`
Amount float32 `json:"amount"`
TrashCategoryID string `json:"trashid"`
Amount float32 `json:"amount"`
}
func (r *RequestCartItems) ValidateRequestCartItem() (map[string][]string, bool) {
errors := make(map[string][]string)
if strings.TrimSpace(r.TrashID) == "" {
if strings.TrimSpace(r.TrashCategoryID) == "" {
errors["trashid"] = append(errors["trashid"], "trashid is required")
}
@ -58,7 +58,7 @@ type BulkRequestCartItems struct {
func (b *BulkRequestCartItems) Validate() (map[string][]string, bool) {
errors := make(map[string][]string)
for i, item := range b.Items {
if strings.TrimSpace(item.TrashID) == "" {
if strings.TrimSpace(item.TrashCategoryID) == "" {
errors[fmt.Sprintf("items[%d].trashid", i)] = append(errors[fmt.Sprintf("items[%d].trashid", i)], "trashid is required")
}
}

View File

@ -1,7 +1,7 @@
package handler
import (
"fmt"
"context"
"rijig/dto"
"rijig/internal/services"
"rijig/utils"
@ -9,62 +9,244 @@ import (
"github.com/gofiber/fiber/v2"
)
type CollectorHandler struct {
type CollectorHandler interface {
CreateCollector(c *fiber.Ctx) error
AddTrashToCollector(c *fiber.Ctx) error
GetCollectorByID(c *fiber.Ctx) error
GetCollectorByUserID(c *fiber.Ctx) error
UpdateCollector(c *fiber.Ctx) error
UpdateJobStatus(c *fiber.Ctx) error
UpdateTrash(c *fiber.Ctx) error
DeleteTrash(c *fiber.Ctx) error
}
type collectorHandler struct {
service services.CollectorService
}
func NewCollectorHandler(service services.CollectorService) *CollectorHandler {
return &CollectorHandler{service}
func NewCollectorHandler(service services.CollectorService) CollectorHandler {
return &collectorHandler{service: service}
}
func (h *CollectorHandler) ConfirmRequestPickup(c *fiber.Ctx) error {
// func (h *CollectorHandler) ConfirmRequestPickup(c *fiber.Ctx) error {
collectorId, ok := c.Locals("userID").(string)
if !ok || collectorId == "" {
// collectorId, ok := c.Locals("userID").(string)
// if !ok || collectorId == "" {
// return utils.GenericResponse(c, fiber.StatusUnauthorized, "Unauthorized: User session not found")
// }
// requestPickupId := c.Params("id")
// if requestPickupId == "" {
// return utils.ErrorResponse(c, "RequestPickup ID is required")
// }
// req, err := h.service.ConfirmRequestPickup(requestPickupId, collectorId)
// if err != nil {
// return utils.ErrorResponse(c, err.Error())
// }
// return utils.SuccessResponse(c, req, "Request pickup confirmed successfully")
// }
// func (h *CollectorHandler) GetAvaibleCollector(c *fiber.Ctx) error {
// userId := c.Locals("userID").(string)
// requests, err := h.service.FindCollectorsNearby(userId)
// if err != nil {
// return utils.ErrorResponse(c, err.Error())
// }
// return utils.SuccessResponse(c, requests, "menampilkan data collector terdekat")
// }
// func (h *CollectorHandler) ConfirmRequestManualPickup(c *fiber.Ctx) error {
// userId := c.Locals("userID").(string)
// requestId := c.Params("request_id")
// if requestId == "" {
// fmt.Println("requestid dibutuhkan")
// }
// var request dto.SelectCollectorRequest
// if err := c.BodyParser(&request); err != nil {
// return fmt.Errorf("error parsing request body: %v", err)
// }
// message, err := h.service.ConfirmRequestManualPickup(requestId, userId)
// if err != nil {
// return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Error confirming pickup: %v", err))
// }
// return utils.SuccessResponse(c, message, "berhasil konfirmasi request")
// }
func (h *collectorHandler) CreateCollector(c *fiber.Ctx) error {
var req dto.RequestCollectorDTO
if err := c.BodyParser(&req); err != nil {
return utils.ValidationErrorResponse(c, map[string][]string{
"body": {"format JSON tidak valid"},
})
}
if errs, valid := req.ValidateRequestCollector(); !valid {
return utils.ValidationErrorResponse(c, errs)
}
userID := c.Locals("userID").(string)
err := h.service.CreateCollector(context.Background(), userID, req)
if err != nil {
return utils.InternalServerErrorResponse(c, err.Error())
}
return utils.CreateResponse(c, nil, "Collector berhasil dibuat")
}
// POST /collectors/:id/trash
func (h *collectorHandler) AddTrashToCollector(c *fiber.Ctx) error {
collectorID := c.Params("id")
var req dto.RequestAddAvaibleTrash
if err := c.BodyParser(&req); err != nil {
return utils.ValidationErrorResponse(c, map[string][]string{
"body": {"format JSON tidak valid"},
})
}
if errs, valid := req.ValidateRequestAddAvaibleTrash(); !valid {
return utils.ValidationErrorResponse(c, errs)
}
err := h.service.AddTrashToCollector(context.Background(), collectorID, req)
if err != nil {
return utils.InternalServerErrorResponse(c, err.Error())
}
return utils.SuccessResponse(c, nil, "Trash berhasil ditambahkan")
}
// GET /collectors/:id
func (h *collectorHandler) GetCollectorByID(c *fiber.Ctx) error {
collectorID := c.Params("id")
result, err := h.service.GetCollectorByID(context.Background(), collectorID)
if err != nil {
return utils.ErrorResponse(c, "Collector tidak ditemukan")
}
return utils.SuccessResponse(c, result, "Data collector berhasil diambil")
}
func (h *collectorHandler) GetCollectorByUserID(c *fiber.Ctx) error {
// collectorID := c.Params("id")
userID, ok := c.Locals("userID").(string)
if !ok || userID == "" {
return utils.GenericResponse(c, fiber.StatusUnauthorized, "Unauthorized: User session not found")
}
requestPickupId := c.Params("id")
if requestPickupId == "" {
return utils.ErrorResponse(c, "RequestPickup ID is required")
}
req, err := h.service.ConfirmRequestPickup(requestPickupId, collectorId)
result, err := h.service.GetCollectorByUserID(context.Background(), userID)
if err != nil {
return utils.ErrorResponse(c, err.Error())
return utils.ErrorResponse(c, "Collector tidak ditemukan")
}
return utils.SuccessResponse(c, req, "Request pickup confirmed successfully")
return utils.SuccessResponse(c, result, "Data collector berhasil diambil")
}
func (h *CollectorHandler) GetAvaibleCollector(c *fiber.Ctx) error {
userId := c.Locals("userID").(string)
requests, err := h.service.FindCollectorsNearby(userId)
if err != nil {
return utils.ErrorResponse(c, err.Error())
// PATCH /collectors/:id
func (h *collectorHandler) UpdateCollector(c *fiber.Ctx) error {
collectorID := c.Params("id")
var req struct {
JobStatus *string `json:"job_status"`
Rating float32 `json:"rating"`
AddressID string `json:"address_id"`
}
return utils.SuccessResponse(c, requests, "menampilkan data collector terdekat")
if err := c.BodyParser(&req); err != nil {
return utils.ValidationErrorResponse(c, map[string][]string{
"body": {"format JSON tidak valid"},
})
}
if req.AddressID == "" {
return utils.ValidationErrorResponse(c, map[string][]string{
"address_id": {"tidak boleh kosong"},
})
}
err := h.service.UpdateCollector(context.Background(), collectorID, req.JobStatus, req.Rating, req.AddressID)
if err != nil {
return utils.InternalServerErrorResponse(c, err.Error())
}
return utils.SuccessResponse(c, nil, "Collector berhasil diperbarui")
}
func (h *CollectorHandler) ConfirmRequestManualPickup(c *fiber.Ctx) error {
userId := c.Locals("userID").(string)
requestId := c.Params("request_id")
if requestId == "" {
fmt.Println("requestid dibutuhkan")
func (h *collectorHandler) UpdateJobStatus(c *fiber.Ctx) error {
collectorID := c.Params("id")
var req struct {
JobStatus string `json:"job_status"`
}
var request dto.SelectCollectorRequest
if err := c.BodyParser(&request); err != nil {
return fmt.Errorf("error parsing request body: %v", err)
if err := c.BodyParser(&req); err != nil {
return utils.ValidationErrorResponse(c, map[string][]string{
"body": {"format JSON tidak valid"},
})
}
message, err := h.service.ConfirmRequestManualPickup(requestId, userId)
if req.JobStatus != "active" && req.JobStatus != "inactive" {
return utils.ValidationErrorResponse(c, map[string][]string{
"job_status": {"harus bernilai 'active' atau 'inactive'"},
})
}
err := h.service.UpdateCollector(c.Context(), collectorID, &req.JobStatus, 0, "")
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Error confirming pickup: %v", err))
return utils.InternalServerErrorResponse(c, err.Error())
}
return utils.SuccessResponse(c, message, "berhasil konfirmasi request")
return utils.SuccessResponse(c, nil, "Status collector berhasil diperbarui")
}
// PATCH /collectors/:id/trash
func (h *collectorHandler) UpdateTrash(c *fiber.Ctx) error {
collectorID := c.Params("id")
var req []dto.RequestAvaibleTrashbyCollector
if err := c.BodyParser(&req); err != nil {
return utils.ValidationErrorResponse(c, map[string][]string{
"body": {"format JSON tidak valid"},
})
}
for i, t := range req {
if t.TrashId == "" {
return utils.ValidationErrorResponse(c, map[string][]string{
"trash_id": {t.TrashId, "trash_id tidak boleh kosong pada item ke " + string(rune(i))},
})
}
if t.TrashPrice <= 0 {
return utils.ValidationErrorResponse(c, map[string][]string{
"trash_price": {"trash_price harus lebih dari 0 pada item ke " + string(rune(i))},
})
}
}
err := h.service.UpdateAvaibleTrashByCollector(context.Background(), collectorID, req)
if err != nil {
return utils.InternalServerErrorResponse(c, err.Error())
}
return utils.SuccessResponse(c, nil, "Trash berhasil diperbarui")
}
// DELETE /collectors/trash/:id
func (h *collectorHandler) DeleteTrash(c *fiber.Ctx) error {
trashID := c.Params("id")
if trashID == "" {
return utils.ValidationErrorResponse(c, map[string][]string{
"trash_id": {"tidak boleh kosong"},
})
}
err := h.service.DeleteAvaibleTrash(context.Background(), trashID)
if err != nil {
return utils.InternalServerErrorResponse(c, err.Error())
}
return utils.SuccessResponse(c, nil, "Trash berhasil dihapus")
}

View File

@ -1,92 +1,92 @@
package handler
import (
"fmt"
"rijig/dto"
"rijig/internal/services"
"rijig/utils"
// import (
// "fmt"
// "rijig/dto"
// "rijig/internal/services"
// "rijig/utils"
"github.com/gofiber/fiber/v2"
)
// "github.com/gofiber/fiber/v2"
// )
type RequestPickupHandler struct {
service services.RequestPickupService
}
// type RequestPickupHandler struct {
// service services.RequestPickupService
// }
func NewRequestPickupHandler(service services.RequestPickupService) *RequestPickupHandler {
return &RequestPickupHandler{service: service}
}
// func NewRequestPickupHandler(service services.RequestPickupService) *RequestPickupHandler {
// return &RequestPickupHandler{service: service}
// }
func (h *RequestPickupHandler) CreateRequestPickup(c *fiber.Ctx) error {
userID, ok := c.Locals("userID").(string)
if !ok || userID == "" {
return utils.GenericResponse(c, fiber.StatusUnauthorized, "Unauthorized: User session not found")
}
// func (h *RequestPickupHandler) CreateRequestPickup(c *fiber.Ctx) error {
// userID, ok := c.Locals("userID").(string)
// if !ok || userID == "" {
// return utils.GenericResponse(c, fiber.StatusUnauthorized, "Unauthorized: User session not found")
// }
var request dto.RequestPickup
// var request dto.RequestPickup
if err := c.BodyParser(&request); err != nil {
return utils.GenericResponse(c, fiber.StatusBadRequest, "Invalid request body")
}
// if err := c.BodyParser(&request); err != nil {
// return utils.GenericResponse(c, fiber.StatusBadRequest, "Invalid request body")
// }
errors, valid := request.ValidateRequestPickup()
if !valid {
return utils.ValidationErrorResponse(c, errors)
}
// errors, valid := request.ValidateRequestPickup()
// if !valid {
// return utils.ValidationErrorResponse(c, errors)
// }
response, err := h.service.CreateRequestPickup(request, userID)
if err != nil {
return utils.InternalServerErrorResponse(c, fmt.Sprintf("Error creating request pickup: %v", err))
}
// response, err := h.service.CreateRequestPickup(request, userID)
// if err != nil {
// return utils.InternalServerErrorResponse(c, fmt.Sprintf("Error creating request pickup: %v", err))
// }
return utils.SuccessResponse(c, response, "Request pickup created successfully")
}
// return utils.SuccessResponse(c, response, "Request pickup created successfully")
// }
func (h *RequestPickupHandler) GetRequestPickupByID(c *fiber.Ctx) error {
id := c.Params("id")
// func (h *RequestPickupHandler) GetRequestPickupByID(c *fiber.Ctx) error {
// id := c.Params("id")
response, err := h.service.GetRequestPickupByID(id)
if err != nil {
return utils.GenericResponse(c, fiber.StatusNotFound, fmt.Sprintf("Request pickup with ID %s not found: %v", id, err))
}
// response, err := h.service.GetRequestPickupByID(id)
// if err != nil {
// return utils.GenericResponse(c, fiber.StatusNotFound, fmt.Sprintf("Request pickup with ID %s not found: %v", id, err))
// }
return utils.SuccessResponse(c, response, "Request pickup retrieved successfully")
}
// return utils.SuccessResponse(c, response, "Request pickup retrieved successfully")
// }
func (h *RequestPickupHandler) GetRequestPickups(c *fiber.Ctx) error {
// func (h *RequestPickupHandler) GetRequestPickups(c *fiber.Ctx) error {
collectorId := c.Locals("userID").(string)
// collectorId := c.Locals("userID").(string)
requests, err := h.service.GetRequestPickupsForCollector(collectorId)
if err != nil {
return utils.ErrorResponse(c, err.Error())
}
// requests, err := h.service.GetRequestPickupsForCollector(collectorId)
// if err != nil {
// return utils.ErrorResponse(c, err.Error())
// }
return utils.SuccessResponse(c, requests, "Automatic request pickups retrieved successfully")
}
// return utils.SuccessResponse(c, requests, "Automatic request pickups retrieved successfully")
// }
func (h *RequestPickupHandler) AssignCollectorToRequest(c *fiber.Ctx) error {
userId, ok := c.Locals("userID").(string)
if !ok || userId == "" {
return utils.GenericResponse(c, fiber.StatusUnauthorized, "Unauthorized: User session not found")
}
// func (h *RequestPickupHandler) AssignCollectorToRequest(c *fiber.Ctx) error {
// userId, ok := c.Locals("userID").(string)
// if !ok || userId == "" {
// return utils.GenericResponse(c, fiber.StatusUnauthorized, "Unauthorized: User session not found")
// }
var request dto.SelectCollectorRequest
errors, valid := request.ValidateSelectCollectorRequest()
if !valid {
return utils.ValidationErrorResponse(c, errors)
}
// var request dto.SelectCollectorRequest
// errors, valid := request.ValidateSelectCollectorRequest()
// if !valid {
// return utils.ValidationErrorResponse(c, errors)
// }
if err := c.BodyParser(&request); err != nil {
return fmt.Errorf("error parsing request body: %v", err)
}
// if err := c.BodyParser(&request); err != nil {
// return fmt.Errorf("error parsing request body: %v", err)
// }
err := h.service.SelectCollectorInRequest(userId, request.Collector_id)
if err != nil {
// err := h.service.SelectCollectorInRequest(userId, request.Collector_id)
// if err != nil {
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Error assigning collector: %v", err))
}
// return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Error assigning collector: %v", err))
// }
return utils.GenericResponse(c, fiber.StatusOK, "berhasil memilih collector")
}
// return utils.GenericResponse(c, fiber.StatusOK, "berhasil memilih collector")
// }

View File

@ -1,115 +1,177 @@
package repositories
import (
"context"
"errors"
"fmt"
"log"
"rijig/model"
"gorm.io/gorm"
// "fmt"
// "log"
"rijig/config"
"rijig/model"
// "gorm.io/gorm"
)
type CollectorRepository interface {
FindActiveCollectors() ([]model.Collector, error)
FindCollectorById(collector_id string) (*model.Collector, error)
FindCollectorByIdWithoutAddr(collector_id string) (*model.Collector, error)
CreateCollector(collector *model.Collector) error
UpdateCollector(userId string, jobStatus string) (*model.Collector, error)
// FindAllAutomaticMethodRequestWithDistance(requestMethod, statuspickup string, collectorLat, collectorLon float64, maxDistance float64) ([]model.RequestPickup, error)
// FindActiveCollectors() ([]model.Collector, error)
// FindCollectorById(collector_id string) (*model.Collector, error)
// FindCollectorByIdWithoutAddr(collector_id string) (*model.Collector, error)
// CreateCollector(collector *model.Collector) error
// UpdateCollector(userId string, jobStatus string) (*model.Collector, error)
CreateCollector(ctx context.Context, collector *model.Collector) error
AddAvaibleTrash(ctx context.Context, trashItems []model.AvaibleTrashByCollector) error
GetCollectorByID(ctx context.Context, collectorID string) (*model.Collector, error)
GetCollectorByUserID(ctx context.Context, userID string) (*model.Collector, error)
GetTrashItemByID(ctx context.Context, id string) (*model.AvaibleTrashByCollector, error)
UpdateCollector(ctx context.Context, collector *model.Collector, updates map[string]interface{}) error
UpdateAvaibleTrashByCollector(ctx context.Context, collectorID string, updatedTrash []model.AvaibleTrashByCollector) error
DeleteAvaibleTrash(ctx context.Context, trashID string) error
}
type collectorRepository struct {
DB *gorm.DB
// DB *gorm.DB
}
func NewCollectorRepository(db *gorm.DB) CollectorRepository {
return &collectorRepository{DB: db}
// func NewCollectorRepository(db *gorm.DB) CollectorRepository {
// return &collectorRepository{DB: db}
// }
func NewCollectorRepository() CollectorRepository {
return &collectorRepository{}
}
func (r *collectorRepository) FindActiveCollectors() ([]model.Collector, error) {
var collectors []model.Collector
// func (r *collectorRepository) FindActiveCollectors() ([]model.Collector, error) {
// var collectors []model.Collector
err := r.DB.Preload("Address").Where("job_status = ?", "active").First(&collectors).Error
if err != nil {
return nil, fmt.Errorf("failed to fetch active collectors: %v", err)
// err := r.DB.Preload("Address").Where("job_status = ?", "active").First(&collectors).Error
// if err != nil {
// return nil, fmt.Errorf("failed to fetch active collectors: %v", err)
// }
// return collectors, nil
// }
// func (r *collectorRepository) FindCollectorById(collector_id string) (*model.Collector, error) {
// var collector model.Collector
// err := r.DB.Preload("Address").Where("user_id = ?", collector_id).First(&collector).Error
// if err != nil {
// return nil, fmt.Errorf("error fetching collector: %v", err)
// }
// fmt.Printf("menampilkan data collector %v", &collector)
// return &collector, nil
// }
// func (r *collectorRepository) FindCollectorByIdWithoutAddr(collector_id string) (*model.Collector, error) {
// var collector model.Collector
// err := r.DB.Where("user_id = ?", collector_id).First(&collector).Error
// if err != nil {
// return nil, fmt.Errorf("error fetching collector: %v", err)
// }
// fmt.Printf("menampilkan data collector %v", &collector)
// return &collector, nil
// }
// func (r *collectorRepository) CreateCollector(collector *model.Collector) error {
// if err := r.DB.Create(collector).Error; err != nil {
// return fmt.Errorf("failed to create collector: %v", err)
// }
// return nil
// }
// func (r *collectorRepository) UpdateCollector(userId string, jobStatus string) (*model.Collector, error) {
// var existingCollector model.Collector
// if err := r.DB.Where("user_id = ?", userId).First(&existingCollector).Error; err != nil {
// if errors.Is(err, gorm.ErrRecordNotFound) {
// return nil, fmt.Errorf("collector dengan user_id %s tidak ditemukan", userId)
// }
// log.Printf("Gagal mencari collector: %v", err)
// return nil, fmt.Errorf("gagal fetching collector: %w", err)
// }
// if jobStatus != "active" && jobStatus != "nonactive" {
// return nil, fmt.Errorf("invalid job status: %v", jobStatus)
// }
// if err := r.DB.Model(&existingCollector).Update("jobstatus", jobStatus).Error; err != nil {
// log.Printf("Gagal mengupdate data collector: %v", err)
// return nil, fmt.Errorf("gagal mengupdate job status untuk collector: %w", err)
// }
// return &existingCollector, nil
// }
func (r *collectorRepository) CreateCollector(ctx context.Context, collector *model.Collector) error {
return config.DB.WithContext(ctx).Create(collector).Error
}
func (r *collectorRepository) AddAvaibleTrash(ctx context.Context, trashItems []model.AvaibleTrashByCollector) error {
if len(trashItems) == 0 {
return nil
}
return collectors, nil
return config.DB.WithContext(ctx).Create(&trashItems).Error
}
func (r *collectorRepository) FindCollectorById(collector_id string) (*model.Collector, error) {
func (r *collectorRepository) GetCollectorByID(ctx context.Context, collectorID string) (*model.Collector, error) {
var collector model.Collector
err := r.DB.Preload("Address").Where("user_id = ?", collector_id).First(&collector).Error
err := config.DB.WithContext(ctx).
Preload("User").
Preload("Address").
Preload("AvaibleTrashByCollector.TrashCategory").
First(&collector, "id = ?", collectorID).Error
if err != nil {
return nil, fmt.Errorf("error fetching collector: %v", err)
return nil, err
}
fmt.Printf("menampilkan data collector %v", &collector)
return &collector, nil
}
func (r *collectorRepository) FindCollectorByIdWithoutAddr(collector_id string) (*model.Collector, error) {
func (r *collectorRepository) GetCollectorByUserID(ctx context.Context, userID string) (*model.Collector, error) {
var collector model.Collector
err := r.DB.Where("user_id = ?", collector_id).First(&collector).Error
err := config.DB.WithContext(ctx).
Preload("User").
Preload("Address").
Preload("AvaibleTrashByCollector.TrashCategory").
First(&collector, "user_id = ?", userID).Error
if err != nil {
return nil, fmt.Errorf("error fetching collector: %v", err)
return nil, err
}
fmt.Printf("menampilkan data collector %v", &collector)
return &collector, nil
}
func (r *collectorRepository) CreateCollector(collector *model.Collector) error {
if err := r.DB.Create(collector).Error; err != nil {
return fmt.Errorf("failed to create collector: %v", err)
func (r *collectorRepository) GetTrashItemByID(ctx context.Context, id string) (*model.AvaibleTrashByCollector, error) {
var item model.AvaibleTrashByCollector
if err := config.DB.WithContext(ctx).First(&item, "id = ?", id).Error; err != nil {
return nil, err
}
return &item, nil
}
func (r *collectorRepository) UpdateCollector(ctx context.Context, collector *model.Collector, updates map[string]interface{}) error {
return config.DB.WithContext(ctx).
Model(&model.Collector{}).
Where("id = ?", collector.ID).
Updates(updates).Error
}
func (r *collectorRepository) UpdateAvaibleTrashByCollector(ctx context.Context, collectorID string, updatedTrash []model.AvaibleTrashByCollector) error {
for _, trash := range updatedTrash {
err := config.DB.WithContext(ctx).
Model(&model.AvaibleTrashByCollector{}).
Where("collector_id = ? AND trash_category_id = ?", collectorID, trash.TrashCategoryID).
Update("price", trash.Price).Error
if err != nil {
return err
}
}
return nil
}
func (r *collectorRepository) UpdateCollector(userId string, jobStatus string) (*model.Collector, error) {
var existingCollector model.Collector
if err := r.DB.Where("user_id = ?", userId).First(&existingCollector).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, fmt.Errorf("collector dengan user_id %s tidak ditemukan", userId)
}
log.Printf("Gagal mencari collector: %v", err)
return nil, fmt.Errorf("gagal fetching collector: %w", err)
func (r *collectorRepository) DeleteAvaibleTrash(ctx context.Context, trashID string) error {
if trashID == "" {
return errors.New("trash_id cannot be empty")
}
if jobStatus != "active" && jobStatus != "nonactive" {
return nil, fmt.Errorf("invalid job status: %v", jobStatus)
}
if err := r.DB.Model(&existingCollector).Update("jobstatus", jobStatus).Error; err != nil {
log.Printf("Gagal mengupdate data collector: %v", err)
return nil, fmt.Errorf("gagal mengupdate job status untuk collector: %w", err)
}
return &existingCollector, nil
return config.DB.WithContext(ctx).
Delete(&model.AvaibleTrashByCollector{}, "id = ?", trashID).Error
}
// // #====experimen====#
// func (r *collectorRepository) FindAllAutomaticMethodRequestWithDistance(requestMethod, statuspickup string, collectorLat, collectorLon float64, maxDistance float64) ([]model.RequestPickup, error) {
// var requests []model.RequestPickup
// err := r.DB.Preload("RequestItems").
// Where("request_method = ? AND status_pickup = ?", requestMethod, statuspickup).
// Find(&requests).Error
// if err != nil {
// return nil, fmt.Errorf("error fetching request pickups with request_method '%s' and status '%s': %v", requestMethod, statuspickup, err)
// }
// var nearbyRequests []model.RequestPickup
// for _, request := range requests {
// address := request.Address
// requestCoord := utils.Coord{Lat: address.Latitude, Lon: address.Longitude}
// collectorCoord := utils.Coord{Lat: collectorLat, Lon: collectorLon}
// _, km := utils.Distance(requestCoord, collectorCoord)
// if km <= maxDistance {
// nearbyRequests = append(nearbyRequests, request)
// }
// }
// return nearbyRequests, nil
// }

View File

@ -1,10 +1,12 @@
package repositories
import (
"context"
"errors"
"fmt"
"log"
"rijig/config"
"rijig/model"
"gorm.io/gorm"
@ -22,6 +24,7 @@ type TrashRepository interface {
UpdateCategoryName(id string, newName string) error
UpdateCategory(id string, updateTrashCategory *model.TrashCategory) (*model.TrashCategory, error)
UpdateTrashDetail(id string, description string, price float64) error
UpdateEstimatedPrice(ctx context.Context, trashCategoryID string) error
DeleteCategory(id string) error
DeleteTrashDetail(id string) error
}
@ -131,6 +134,23 @@ func (r *trashRepository) UpdateTrashDetail(id string, description string, price
return nil
}
func (r *trashRepository) UpdateEstimatedPrice(ctx context.Context, trashCategoryID string) error {
var avg float64
err := config.DB.WithContext(ctx).
Model(&model.AvaibleTrashByCollector{}).
Where("trash_category_id = ?", trashCategoryID).
Select("AVG(price)").Scan(&avg).Error
if err != nil {
return err
}
return config.DB.WithContext(ctx).
Model(&model.TrashCategory{}).
Where("id = ?", trashCategoryID).
Update("estimated_price", avg).Error
}
func (r *trashRepository) DeleteCategory(id string) error {
if err := r.DB.Delete(&model.TrashCategory{}, "id = ?", id).Error; err != nil {
return fmt.Errorf("failed to delete category: %v", err)

View File

@ -1,151 +1,224 @@
package services
import (
"fmt"
"context"
"errors"
"rijig/dto"
"rijig/internal/repositories"
"rijig/utils"
"time"
"rijig/model"
)
type CollectorService interface {
FindCollectorsNearby(userId string) ([]dto.ResponseCollectorDTO, error)
ConfirmRequestPickup(requestId, collectorId string) (*dto.ResponseRequestPickup, error)
ConfirmRequestManualPickup(requestId, collectorId string) (any, error)
CreateCollector(ctx context.Context, userID string, req dto.RequestCollectorDTO) error
AddTrashToCollector(ctx context.Context, collectorID string, req dto.RequestAddAvaibleTrash) error
GetCollectorByID(ctx context.Context, collectorID string) (*dto.ResponseCollectorDTO, error)
GetCollectorByUserID(ctx context.Context, userID string) (*dto.ResponseCollectorDTO, error)
UpdateCollector(ctx context.Context, collectorID string, jobStatus *string, rating float32, addressID string) error
UpdateAvaibleTrashByCollector(ctx context.Context, collectorID string, updatedTrash []dto.RequestAvaibleTrashbyCollector) error
DeleteAvaibleTrash(ctx context.Context, trashID string) error
}
type collectorService struct {
repo repositories.CollectorRepository
repoColl repositories.RequestPickupRepository
repoAddress repositories.AddressRepository
repoUser repositories.UserProfilRepository
repo repositories.CollectorRepository
trashRepo repositories.TrashRepository
}
func NewCollectorService(repo repositories.CollectorRepository,
repoColl repositories.RequestPickupRepository,
repoAddress repositories.AddressRepository,
repoUser repositories.UserProfilRepository) CollectorService {
return &collectorService{repo: repo, repoColl: repoColl, repoAddress: repoAddress, repoUser: repoUser}
func NewCollectorService(repo repositories.CollectorRepository, trashRepo repositories.TrashRepository,
) CollectorService {
return &collectorService{repo: repo, trashRepo: trashRepo}
}
func (s *collectorService) FindCollectorsNearby(userId string) ([]dto.ResponseCollectorDTO, error) {
collectors, err := s.repo.FindActiveCollectors()
if err != nil {
return nil, fmt.Errorf("error fetching active collectors: %v", err)
func (s *collectorService) CreateCollector(ctx context.Context, userID string, req dto.RequestCollectorDTO) error {
collector := &model.Collector{
UserID: userID,
AddressID: req.AddressId,
JobStatus: "inactive",
Rating: 5,
}
var avaibleCollectResp []dto.ResponseCollectorDTO
for _, collector := range collectors {
request, err := s.repoColl.FindRequestPickupByAddressAndStatus(userId, "waiting_collector", "otomatis")
if err != nil {
return nil, fmt.Errorf("gagal mendapatkan data request pickup dengan userid: %v", err)
}
_, distance := utils.Distance(
utils.Coord{Lat: request.Address.Latitude, Lon: request.Address.Longitude},
utils.Coord{Lat: collector.Address.Latitude, Lon: collector.Address.Longitude},
)
if distance <= 20 {
mappedRequest := dto.ResponseCollectorDTO{
ID: collector.ID,
UserId: collector.UserID,
AddressId: collector.AddressId,
Rating: collector.Rating,
}
user, err := s.repoUser.FindByID(collector.UserID)
if err != nil {
return nil, fmt.Errorf("error fetching user data: %v", err)
}
mappedRequest.User = []dto.UserResponseDTO{
{
Name: user.Name,
Phone: user.Phone,
},
}
address, err := s.repoAddress.FindAddressByID(collector.AddressId)
if err != nil {
return nil, fmt.Errorf("error fetching address data: %v", err)
}
mappedRequest.Address = []dto.AddressResponseDTO{
{
District: address.District,
Village: address.Village,
Detail: address.Detail,
},
}
avaibleCollectResp = append(avaibleCollectResp, mappedRequest)
}
if err := s.repo.CreateCollector(ctx, collector); err != nil {
return err
}
return avaibleCollectResp, nil
var trashItems []model.AvaibleTrashByCollector
for _, item := range req.AvaibleTrashbyCollector {
trashItems = append(trashItems, model.AvaibleTrashByCollector{
CollectorID: collector.ID,
TrashCategoryID: item.TrashId,
Price: item.TrashPrice,
})
}
if err := s.repo.AddAvaibleTrash(ctx, trashItems); err != nil {
return err
}
for _, t := range trashItems {
_ = s.trashRepo.UpdateEstimatedPrice(ctx, t.TrashCategoryID)
}
return nil
}
func (s *collectorService) ConfirmRequestPickup(requestId, collectorId string) (*dto.ResponseRequestPickup, error) {
request, err := s.repoColl.FindRequestPickupByID(requestId)
if err != nil {
return nil, fmt.Errorf("request pickup not found: %v", err)
func (s *collectorService) AddTrashToCollector(ctx context.Context, collectorID string, req dto.RequestAddAvaibleTrash) error {
var trashItems []model.AvaibleTrashByCollector
for _, item := range req.AvaibleTrash {
trashItems = append(trashItems, model.AvaibleTrashByCollector{
CollectorID: collectorID,
TrashCategoryID: item.TrashId,
Price: item.TrashPrice,
})
}
if err := s.repo.AddAvaibleTrash(ctx, trashItems); err != nil {
return err
}
if request.StatusPickup != "waiting_collector" {
return nil, fmt.Errorf("pickup request is not in 'waiting_collector' status")
for _, t := range trashItems {
_ = s.trashRepo.UpdateEstimatedPrice(ctx, t.TrashCategoryID)
}
collector, err := s.repo.FindCollectorById(collectorId)
if err != nil {
return nil, fmt.Errorf("collector tidak ditemukan: %v", err)
}
request.StatusPickup = "confirmed"
request.CollectorID = &collector.ID
*request.ConfirmedByCollectorAt = time.Now()
err = s.repoColl.UpdateRequestPickup(requestId, request)
if err != nil {
return nil, fmt.Errorf("failed to update request pickup: %v", err)
}
confirmedAt, _ := utils.FormatDateToIndonesianFormat(*request.ConfirmedByCollectorAt)
response := dto.ResponseRequestPickup{
StatusPickup: request.StatusPickup,
CollectorID: *request.CollectorID,
ConfirmedByCollectorAt: confirmedAt,
}
return &response, nil
return nil
}
func (s *collectorService) ConfirmRequestManualPickup(requestId, collectorId string) (any, error) {
request, err := s.repoColl.FindRequestPickupByID(requestId)
func (s *collectorService) GetCollectorByID(ctx context.Context, collectorID string) (*dto.ResponseCollectorDTO, error) {
collector, err := s.repo.GetCollectorByID(ctx, collectorID)
if err != nil {
return nil, fmt.Errorf("collector tidak ditemukan: %v", err)
return nil, err
}
coll, err := s.repo.FindCollectorByIdWithoutAddr(collectorId)
response := &dto.ResponseCollectorDTO{
ID: collector.ID,
UserId: collector.UserID,
AddressId: collector.AddressID,
JobStatus: &collector.JobStatus,
Rating: collector.Rating,
User: &dto.UserResponseDTO{
ID: collector.User.ID,
Name: collector.User.Name,
Phone: collector.User.Phone,
},
Address: &dto.AddressResponseDTO{
Province: collector.Address.Province,
District: collector.Address.District,
Regency: collector.Address.Regency,
Village: collector.Address.Village,
PostalCode: collector.Address.PostalCode,
Latitude: collector.Address.Latitude,
Longitude: collector.Address.Longitude,
},
}
for _, item := range collector.AvaibleTrashByCollector {
response.AvaibleTrashbyCollector = append(response.AvaibleTrashbyCollector, dto.ResponseAvaibleTrashByCollector{
ID: item.ID,
TrashId: item.TrashCategory.ID,
TrashName: item.TrashCategory.Name,
TrashIcon: item.TrashCategory.Icon,
TrashPrice: item.Price,
})
}
return response, nil
}
func (s *collectorService) GetCollectorByUserID(ctx context.Context, userID string) (*dto.ResponseCollectorDTO, error) {
collector, err := s.repo.GetCollectorByUserID(ctx, userID)
if err != nil {
return nil, fmt.Errorf("%v", err)
return nil, err
}
if coll.ID != *request.CollectorID {
return nil, fmt.Errorf("collectorid tidak sesuai dengan request")
response := &dto.ResponseCollectorDTO{
ID: collector.ID,
UserId: collector.UserID,
AddressId: collector.AddressID,
JobStatus: &collector.JobStatus,
Rating: collector.Rating,
User: &dto.UserResponseDTO{
ID: collector.User.ID,
Name: collector.User.Name,
Phone: collector.User.Phone,
},
Address: &dto.AddressResponseDTO{
Province: collector.Address.Province,
District: collector.Address.District,
Regency: collector.Address.Regency,
Village: collector.Address.Village,
PostalCode: collector.Address.PostalCode,
Latitude: collector.Address.Latitude,
Longitude: collector.Address.Longitude,
},
}
request.StatusPickup = "confirmed"
*request.ConfirmedByCollectorAt = time.Now()
for _, item := range collector.AvaibleTrashByCollector {
response.AvaibleTrashbyCollector = append(response.AvaibleTrashbyCollector, dto.ResponseAvaibleTrashByCollector{
ID: item.ID,
TrashId: item.TrashCategory.ID,
TrashName: item.TrashCategory.Name,
TrashIcon: item.TrashCategory.Icon,
TrashPrice: item.Price,
})
}
err = s.repoColl.UpdateRequestPickup(requestId, request)
return response, nil
}
func (s *collectorService) UpdateCollector(ctx context.Context, collectorID string, jobStatus *string, rating float32, addressID string) error {
updates := make(map[string]interface{})
if jobStatus != nil {
updates["job_status"] = *jobStatus
}
if rating > 0 {
updates["rating"] = rating
}
if addressID != "" {
updates["address_id"] = addressID
}
if len(updates) == 0 {
return errors.New("tidak ada data yang diubah")
}
return s.repo.UpdateCollector(ctx, &model.Collector{ID: collectorID}, updates)
}
func (s *collectorService) UpdateAvaibleTrashByCollector(ctx context.Context, collectorID string, updatedTrash []dto.RequestAvaibleTrashbyCollector) error {
var updated []model.AvaibleTrashByCollector
for _, item := range updatedTrash {
updated = append(updated, model.AvaibleTrashByCollector{
CollectorID: collectorID,
TrashCategoryID: item.TrashId,
Price: item.TrashPrice,
})
}
if err := s.repo.UpdateAvaibleTrashByCollector(ctx, collectorID, updated); err != nil {
return err
}
for _, item := range updated {
_ = s.trashRepo.UpdateEstimatedPrice(ctx, item.TrashCategoryID)
}
return nil
}
func (s *collectorService) DeleteAvaibleTrash(ctx context.Context, trashID string) error {
if trashID == "" {
return errors.New("trash_id tidak boleh kosong")
}
item, err := s.repo.GetTrashItemByID(ctx, trashID)
if err != nil {
return nil, fmt.Errorf("failed to update request pickup: %v", err)
return err
}
return "berhasil konfirmasi request pickup", nil
}
if err := s.repo.DeleteAvaibleTrash(ctx, trashID); err != nil {
return err
}
return s.trashRepo.UpdateEstimatedPrice(ctx, item.TrashCategoryID)
}

View File

@ -9,11 +9,11 @@ import (
)
type RequestPickupService interface {
CreateRequestPickup(request dto.RequestPickup, UserId string) (*dto.ResponseRequestPickup, error)
GetRequestPickupByID(id string) (*dto.ResponseRequestPickup, error)
GetAllRequestPickups(userid string) ([]dto.ResponseRequestPickup, error)
GetRequestPickupsForCollector(collectorId string) ([]dto.ResponseRequestPickup, error)
SelectCollectorInRequest(userId, collectorId string) error
// CreateRequestPickup(request dto.RequestPickup, UserId string) (*dto.ResponseRequestPickup, error)
// GetRequestPickupByID(id string) (*dto.ResponseRequestPickup, error)
// GetAllRequestPickups(userid string) ([]dto.ResponseRequestPickup, error)
// GetRequestPickupsForCollector(collectorId string) ([]dto.ResponseRequestPickup, error)
// SelectCollectorInRequest(userId, collectorId string) error
}
type requestPickupService struct {
@ -152,198 +152,198 @@ func (s *requestPickupService) GetAllRequestPickups(userid string) ([]dto.Respon
return response, nil
}
func (s *requestPickupService) GetRequestPickupsForCollector(collectorId string) ([]dto.ResponseRequestPickup, error) {
requests, err := s.repo.GetAutomaticRequestPickupsForCollector()
if err != nil {
return nil, fmt.Errorf("error retrieving automatic pickup requests: %v", err)
}
// func (s *requestPickupService) GetRequestPickupsForCollector(collectorId string) ([]dto.ResponseRequestPickup, error) {
// requests, err := s.repo.GetAutomaticRequestPickupsForCollector()
// if err != nil {
// return nil, fmt.Errorf("error retrieving automatic pickup requests: %v", err)
// }
var response []dto.ResponseRequestPickup
// var response []dto.ResponseRequestPickup
for _, req := range requests {
// for _, req := range requests {
collector, err := s.repoColl.FindCollectorById(collectorId)
if err != nil {
return nil, fmt.Errorf("error fetching collector data: %v", err)
}
// collector, err := s.repoColl.FindCollectorById(collectorId)
// if err != nil {
// return nil, fmt.Errorf("error fetching collector data: %v", err)
// }
_, distance := utils.Distance(
utils.Coord{Lat: collector.Address.Latitude, Lon: collector.Address.Longitude},
utils.Coord{Lat: req.Address.Latitude, Lon: req.Address.Longitude},
)
// _, distance := utils.Distance(
// utils.Coord{Lat: collector.Address.Latitude, Lon: collector.Address.Longitude},
// utils.Coord{Lat: req.Address.Latitude, Lon: req.Address.Longitude},
// )
if distance <= 20 {
// if distance <= 20 {
mappedRequest := dto.ResponseRequestPickup{
ID: req.ID,
UserId: req.UserId,
AddressID: req.AddressId,
EvidenceImage: req.EvidenceImage,
StatusPickup: req.StatusPickup,
CreatedAt: req.CreatedAt.Format("2006-01-02 15:04:05"),
UpdatedAt: req.UpdatedAt.Format("2006-01-02 15:04:05"),
}
// mappedRequest := dto.ResponseRequestPickup{
// ID: req.ID,
// UserId: req.UserId,
// AddressID: req.AddressId,
// EvidenceImage: req.EvidenceImage,
// StatusPickup: req.StatusPickup,
// CreatedAt: req.CreatedAt.Format("2006-01-02 15:04:05"),
// UpdatedAt: req.UpdatedAt.Format("2006-01-02 15:04:05"),
// }
user, err := s.repoUser.FindByID(req.UserId)
if err != nil {
return nil, fmt.Errorf("error fetching user data: %v", err)
}
mappedRequest.User = []dto.UserResponseDTO{
{
Name: user.Name,
Phone: user.Phone,
},
}
// user, err := s.repoUser.FindByID(req.UserId)
// if err != nil {
// return nil, fmt.Errorf("error fetching user data: %v", err)
// }
// mappedRequest.User = []dto.UserResponseDTO{
// {
// Name: user.Name,
// Phone: user.Phone,
// },
// }
address, err := s.repoAddress.FindAddressByID(req.AddressId)
if err != nil {
return nil, fmt.Errorf("error fetching address data: %v", err)
}
mappedRequest.Address = []dto.AddressResponseDTO{
{
District: address.District,
Village: address.Village,
Detail: address.Detail,
},
}
// address, err := s.repoAddress.FindAddressByID(req.AddressId)
// if err != nil {
// return nil, fmt.Errorf("error fetching address data: %v", err)
// }
// mappedRequest.Address = []dto.AddressResponseDTO{
// {
// District: address.District,
// Village: address.Village,
// Detail: address.Detail,
// },
// }
requestItems, err := s.repo.GetRequestPickupItems(req.ID)
if err != nil {
return nil, fmt.Errorf("error fetching request items: %v", err)
}
// requestItems, err := s.repo.GetRequestPickupItems(req.ID)
// if err != nil {
// return nil, fmt.Errorf("error fetching request items: %v", err)
// }
var mappedRequestItems []dto.ResponseRequestPickupItem
// var mappedRequestItems []dto.ResponseRequestPickupItem
for _, item := range requestItems {
trashCategory, err := s.repoTrash.GetCategoryByID(item.TrashCategoryId)
if err != nil {
return nil, fmt.Errorf("error fetching trash category: %v", err)
}
// for _, item := range requestItems {
// trashCategory, err := s.repoTrash.GetCategoryByID(item.TrashCategoryId)
// if err != nil {
// return nil, fmt.Errorf("error fetching trash category: %v", err)
// }
mappedRequestItems = append(mappedRequestItems, dto.ResponseRequestPickupItem{
ID: item.ID,
TrashCategory: []dto.ResponseTrashCategoryDTO{{
Name: trashCategory.Name,
Icon: trashCategory.Icon,
}},
EstimatedAmount: item.EstimatedAmount,
})
}
// mappedRequestItems = append(mappedRequestItems, dto.ResponseRequestPickupItem{
// ID: item.ID,
// TrashCategory: []dto.ResponseTrashCategoryDTO{{
// Name: trashCategory.Name,
// Icon: trashCategory.Icon,
// }},
// EstimatedAmount: item.EstimatedAmount,
// })
// }
mappedRequest.RequestItems = mappedRequestItems
// mappedRequest.RequestItems = mappedRequestItems
response = append(response, mappedRequest)
}
}
// response = append(response, mappedRequest)
// }
// }
return response, nil
}
// return response, nil
// }
func (s *requestPickupService) GetManualRequestPickupsForCollector(collectorId string) ([]dto.ResponseRequestPickup, error) {
// func (s *requestPickupService) GetManualRequestPickupsForCollector(collectorId string) ([]dto.ResponseRequestPickup, error) {
collector, err := s.repoColl.FindCollectorById(collectorId)
if err != nil {
return nil, fmt.Errorf("error fetching collector data: %v", err)
}
requests, err := s.repo.GetManualReqMethodforCollect(collector.ID)
if err != nil {
return nil, fmt.Errorf("error retrieving manual pickup requests: %v", err)
}
// collector, err := s.repoColl.FindCollectorById(collectorId)
// if err != nil {
// return nil, fmt.Errorf("error fetching collector data: %v", err)
// }
// requests, err := s.repo.GetManualReqMethodforCollect(collector.ID)
// if err != nil {
// return nil, fmt.Errorf("error retrieving manual pickup requests: %v", err)
// }
var response []dto.ResponseRequestPickup
// var response []dto.ResponseRequestPickup
for _, req := range requests {
// for _, req := range requests {
createdAt, _ := utils.FormatDateToIndonesianFormat(req.CreatedAt)
updatedAt, _ := utils.FormatDateToIndonesianFormat(req.UpdatedAt)
// createdAt, _ := utils.FormatDateToIndonesianFormat(req.CreatedAt)
// updatedAt, _ := utils.FormatDateToIndonesianFormat(req.UpdatedAt)
mappedRequest := dto.ResponseRequestPickup{
ID: req.ID,
UserId: req.UserId,
AddressID: req.AddressId,
EvidenceImage: req.EvidenceImage,
StatusPickup: req.StatusPickup,
CreatedAt: createdAt,
UpdatedAt: updatedAt,
}
// mappedRequest := dto.ResponseRequestPickup{
// ID: req.ID,
// UserId: req.UserId,
// AddressID: req.AddressId,
// EvidenceImage: req.EvidenceImage,
// StatusPickup: req.StatusPickup,
// CreatedAt: createdAt,
// UpdatedAt: updatedAt,
// }
user, err := s.repoUser.FindByID(req.UserId)
if err != nil {
return nil, fmt.Errorf("error fetching user data: %v", err)
}
mappedRequest.User = []dto.UserResponseDTO{
{
Name: user.Name,
Phone: user.Phone,
},
}
// user, err := s.repoUser.FindByID(req.UserId)
// if err != nil {
// return nil, fmt.Errorf("error fetching user data: %v", err)
// }
// mappedRequest.User = []dto.UserResponseDTO{
// {
// Name: user.Name,
// Phone: user.Phone,
// },
// }
address, err := s.repoAddress.FindAddressByID(req.AddressId)
if err != nil {
return nil, fmt.Errorf("error fetching address data: %v", err)
}
mappedRequest.Address = []dto.AddressResponseDTO{
{
District: address.District,
Village: address.Village,
Detail: address.Detail,
},
}
// address, err := s.repoAddress.FindAddressByID(req.AddressId)
// if err != nil {
// return nil, fmt.Errorf("error fetching address data: %v", err)
// }
// mappedRequest.Address = []dto.AddressResponseDTO{
// {
// District: address.District,
// Village: address.Village,
// Detail: address.Detail,
// },
// }
requestItems, err := s.repo.GetRequestPickupItems(req.ID)
if err != nil {
return nil, fmt.Errorf("error fetching request items: %v", err)
}
// requestItems, err := s.repo.GetRequestPickupItems(req.ID)
// if err != nil {
// return nil, fmt.Errorf("error fetching request items: %v", err)
// }
var mappedRequestItems []dto.ResponseRequestPickupItem
// var mappedRequestItems []dto.ResponseRequestPickupItem
for _, item := range requestItems {
// for _, item := range requestItems {
trashCategory, err := s.repoTrash.GetCategoryByID(item.TrashCategoryId)
if err != nil {
return nil, fmt.Errorf("error fetching trash category: %v", err)
}
// trashCategory, err := s.repoTrash.GetCategoryByID(item.TrashCategoryId)
// if err != nil {
// return nil, fmt.Errorf("error fetching trash category: %v", err)
// }
mappedRequestItems = append(mappedRequestItems, dto.ResponseRequestPickupItem{
ID: item.ID,
TrashCategory: []dto.ResponseTrashCategoryDTO{{
Name: trashCategory.Name,
Icon: trashCategory.Icon,
}},
EstimatedAmount: item.EstimatedAmount,
})
}
// mappedRequestItems = append(mappedRequestItems, dto.ResponseRequestPickupItem{
// ID: item.ID,
// TrashCategory: []dto.ResponseTrashCategoryDTO{{
// Name: trashCategory.Name,
// Icon: trashCategory.Icon,
// }},
// EstimatedAmount: item.EstimatedAmount,
// })
// }
mappedRequest.RequestItems = mappedRequestItems
// mappedRequest.RequestItems = mappedRequestItems
response = append(response, mappedRequest)
}
// response = append(response, mappedRequest)
// }
return response, nil
}
// return response, nil
// }
func (s *requestPickupService) SelectCollectorInRequest(userId, collectorId string) error {
// func (s *requestPickupService) SelectCollectorInRequest(userId, collectorId string) error {
request, err := s.repo.FindRequestPickupByStatus(userId, "waiting_collector", "manual")
if err != nil {
return fmt.Errorf("request pickup not found: %v", err)
}
// request, err := s.repo.FindRequestPickupByStatus(userId, "waiting_collector", "manual")
// if err != nil {
// return fmt.Errorf("request pickup not found: %v", err)
// }
if request.StatusPickup != "waiting_collector" && request.RequestMethod != "manual" {
return fmt.Errorf("pickup request is not in 'waiting_collector' status and not 'manual' method")
}
// if request.StatusPickup != "waiting_collector" && request.RequestMethod != "manual" {
// return fmt.Errorf("pickup request is not in 'waiting_collector' status and not 'manual' method")
// }
collector, err := s.repoColl.FindCollectorByIdWithoutAddr(collectorId)
if err != nil {
return fmt.Errorf("collector tidak ditemukan: %v", err)
}
// collector, err := s.repoColl.FindCollectorByIdWithoutAddr(collectorId)
// if err != nil {
// return fmt.Errorf("collector tidak ditemukan: %v", err)
// }
request.CollectorID = &collector.ID
// request.CollectorID = &collector.ID
err = s.repo.UpdateRequestPickup(request.ID, request)
if err != nil {
return fmt.Errorf("failed to update request pickup: %v", err)
}
// err = s.repo.UpdateRequestPickup(request.ID, request)
// if err != nil {
// return fmt.Errorf("failed to update request pickup: %v", err)
// }
return nil
}
// return nil
// }

View File

@ -30,7 +30,7 @@ func GetCartItems(userID string) ([]dto.RequestCartItems, error) {
if err != nil {
return nil, err
}
return items, nil
}
@ -45,7 +45,7 @@ func AddOrUpdateCartItem(userID string, newItem dto.RequestCartItems) error {
updated := false
for i, item := range cartItems {
if item.TrashID == newItem.TrashID {
if item.TrashCategoryID == newItem.TrashCategoryID {
if newItem.Amount == 0 {
cartItems = append(cartItems[:i], cartItems[i+1:]...)
} else {
@ -80,14 +80,14 @@ func DeleteCartItem(userID, trashID string) error {
index := -1
for i, item := range items {
if item.TrashID == trashID {
if item.TrashCategoryID == trashID {
index = i
break
}
}
if index == -1 {
log.Printf("TrashID %s not found in cart for user %s", trashID, userID)
log.Printf("TrashCategoryID %s not found in cart for user %s", trashID, userID)
return fmt.Errorf("trashid not found")
}

View File

@ -31,9 +31,9 @@ func (s *CartService) CommitCartToDatabase(userID string) error {
var estimatedTotal float32
for _, item := range items {
trash, err := s.Repo.GetTrashCategoryByID(item.TrashID)
trash, err := s.Repo.GetTrashCategoryByID(item.TrashCategoryID)
if err != nil {
log.Printf("Trash category not found for trashID: %s", item.TrashID)
log.Printf("Trash category not found for trashID: %s", item.TrashCategoryID)
continue
}
@ -43,7 +43,7 @@ func (s *CartService) CommitCartToDatabase(userID string) error {
cartItems = append(cartItems, model.CartItem{
ID: uuid.NewString(),
TrashID: item.TrashID,
TrashCategoryID: item.TrashCategoryID,
Amount: item.Amount,
SubTotalEstimatedPrice: subTotal,
})
@ -87,7 +87,7 @@ func (s *CartService) GetCartFromRedis(userID string) (*dto.CartResponse, error)
var cartItemDTOs []dto.CartItemResponse
for _, item := range items {
trash, err := s.Repo.GetTrashCategoryByID(item.TrashID)
trash, err := s.Repo.GetTrashCategoryByID(item.TrashCategoryID)
if err != nil {
continue
}
@ -133,7 +133,7 @@ func (s *CartService) GetCart(userID string) (*dto.CartResponse, error) {
for _, item := range cartDB.CartItems {
items = append(items, dto.CartItemResponse{
ItemId: item.ID,
TrashId: item.TrashID,
TrashId: item.TrashCategoryID,
TrashIcon: item.TrashCategory.Icon,
TrashName: item.TrashCategory.Name,
Amount: item.Amount,

View File

@ -1,16 +1,25 @@
package model
import "time"
type Collector struct {
ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4();unique;not null" json:"id"`
UserID string `gorm:"not null" json:"userId"`
User User `gorm:"foreignKey:UserID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"user"`
JobStatus string `gorm:"default:inactive" json:"jobstatus"`
Rating float32 `gorm:"default:5" json:"rating"`
AddressId string `gorm:"not null" json:"address_id"`
Address Address `gorm:"foreignKey:AddressId;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"address"`
ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4();unique;not null" json:"id"`
UserID string `gorm:"not null" json:"user_id"`
User User `gorm:"foreignKey:UserID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-"`
JobStatus string `gorm:"default:inactive" json:"jobstatus"`
Rating float32 `gorm:"default:5" json:"rating"`
AddressID string `gorm:"not null" json:"address_id"`
Address Address `gorm:"foreignKey:AddressID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"address"`
AvaibleTrashByCollector []AvaibleTrashByCollector `gorm:"foreignKey:CollectorID;constraint:OnDelete:CASCADE;" json:"avaible_trash"`
CreatedAt time.Time `gorm:"default:current_timestamp" json:"created_at"`
UpdatedAt time.Time `gorm:"default:current_timestamp" json:"updated_at"`
}
// job_status {
// "active",
// "inactive"
// }
type AvaibleTrashByCollector struct {
ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4();unique;not null" json:"id"`
CollectorID string `gorm:"not null" json:"collector_id"`
Collector *Collector `gorm:"foreignKey:CollectorID;constraint:OnDelete:CASCADE;" json:"-"`
TrashCategoryID string `gorm:"not null" json:"trash_id"`
TrashCategory TrashCategory `gorm:"foreignKey:TrashCategoryID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"trash_category"`
Price float32 `json:"price"`
}

View File

@ -11,17 +11,18 @@ type Cart struct {
CartItems []CartItem `gorm:"foreignKey:CartID;constraint:OnDelete:CASCADE;" json:"cartitems"`
TotalAmount float32 `json:"totalamount"`
EstimatedTotalPrice float32 `json:"estimated_totalprice"`
CreatedAt time.Time `gorm:"autoCreateTime" json:"createdAt"`
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updatedAt"`
CreatedAt time.Time `gorm:"default:current_timestamp" json:"created_at"`
UpdatedAt time.Time `gorm:"default:current_timestamp" json:"updated_at"`
}
type CartItem struct {
ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4()" json:"id"`
CartID string `gorm:"not null" json:"-"`
TrashID string `gorm:"not null" json:"trashid"`
TrashCategory TrashCategory `gorm:"foreignKey:TrashID;constraint:OnDelete:CASCADE;" json:"trash"`
Cart *Cart `gorm:"foreignKey:CartID;constraint:OnDelete:CASCADE;" json:"-"`
TrashCategoryID string `gorm:"not null" json:"trash_id"`
TrashCategory TrashCategory `gorm:"foreignKey:TrashCategoryID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"trash_category"`
Amount float32 `json:"amount"`
SubTotalEstimatedPrice float32 `json:"subtotalestimatedprice"`
CreatedAt time.Time `gorm:"autoCreateTime" json:"createdAt"`
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updatedAt"`
CreatedAt time.Time `gorm:"default:current_timestamp" json:"created_at"`
UpdatedAt time.Time `gorm:"default:current_timestamp" json:"updated_at"`
}

View File

@ -13,18 +13,39 @@ import (
)
func CollectorRouter(api fiber.Router) {
repo := repositories.NewCollectorRepository(config.DB)
repoReq := repositories.NewRequestPickupRepository(config.DB)
repoAddress := repositories.NewAddressRepository(config.DB)
repoUser := repositories.NewUserProfilRepository(config.DB)
colectorService := services.NewCollectorService(repo, repoReq, repoAddress, repoUser)
collectorHandler := handler.NewCollectorHandler(colectorService)
// repo := repositories.NewCollectorRepository(config.DB)
// repoReq := repositories.NewRequestPickupRepository(config.DB)
// repoAddress := repositories.NewAddressRepository(config.DB)
// repoUser := repositories.NewUserProfilRepository(config.DB)
// colectorService := services.NewCollectorService(repo, repoReq, repoAddress, repoUser)
// collectorHandler := handler.NewCollectorHandler(colectorService)
collector := api.Group("/collector")
collector.Use(middleware.AuthMiddleware)
// collector := api.Group("/collector")
// collector.Use(middleware.AuthMiddleware)
collector.Put("confirmrequest/:id", collectorHandler.ConfirmRequestPickup)
collector.Put("confirm-manual/request/:request_id", collectorHandler.ConfirmRequestManualPickup)
collector.Get("/avaible", collectorHandler.GetAvaibleCollector)
// collector.Put("confirmrequest/:id", collectorHandler.ConfirmRequestPickup)
// collector.Put("confirm-manual/request/:request_id", collectorHandler.ConfirmRequestManualPickup)
// collector.Get("/avaible", collectorHandler.GetAvaibleCollector)
// Middleware Auth dan Role
// Inisialisasi repository dan service
collectorRepo := repositories.NewCollectorRepository()
trashRepo := repositories.NewTrashRepository(config.DB)
collectorService := services.NewCollectorService(collectorRepo, trashRepo)
collectorHandler := handler.NewCollectorHandler(collectorService)
// Group collector
collectors := api.Group("/collectors")
collectors.Use(middleware.AuthMiddleware)
// === Collector routes ===
collectors.Post("/", collectorHandler.CreateCollector) // Create collector
collectors.Post("/:id/trash", collectorHandler.AddTrashToCollector) // Add trash to collector
collectors.Get("/:id", collectorHandler.GetCollectorByID) // Get collector by ID
collectors.Get("/", collectorHandler.GetCollectorByUserID) // Get collector by ID
collectors.Patch("/:id", collectorHandler.UpdateCollector) // Update collector fields
collectors.Patch("/:id/trash", collectorHandler.UpdateTrash)
collectors.Patch("/:id/job-status", collectorHandler.UpdateJobStatus)
collectors.Delete("/trash/:id", collectorHandler.DeleteTrash)
}

View File

@ -1,45 +1,46 @@
package presentation
import (
"rijig/config"
"rijig/internal/handler"
"rijig/internal/repositories"
"rijig/internal/services"
"rijig/middleware"
// import (
// "rijig/config"
// "rijig/internal/handler"
// "rijig/internal/repositories"
// "rijig/internal/services"
// "rijig/middleware"
"github.com/gofiber/fiber/v2"
)
// "github.com/gofiber/fiber/v2"
// )
func RequestPickupRouter(api fiber.Router) {
// repo repositories.RequestPickupRepository
// repoColl repositories.CollectorRepository
// repoAddress repositories.AddressRepository
// repoTrash repositories.TrashRepository
// repoUser repositories.UserProfilRepository
// func RequestPickupRouter(api fiber.Router) {
// // repo repositories.RequestPickupRepository
// // repoColl repositories.CollectorRepository
// // repoAddress repositories.AddressRepository
// // repoTrash repositories.TrashRepository
// // repoUser repositories.UserProfilRepository
requestRepo := repositories.NewRequestPickupRepository(config.DB)
repoColl := repositories.NewCollectorRepository(config.DB)
repoAddress := repositories.NewAddressRepository(config.DB)
Trashrepo := repositories.NewTrashRepository(config.DB)
repouser := repositories.NewUserProfilRepository(config.DB)
// collectorRepo := repositories.NewCollectorRepository(config.DB)
// requestRepo := repositories.NewRequestPickupRepository(config.DB)
// // repoColl := repositories.NewCollectorRepository(config.DB)
// repoColl := repositories.NewCollectorRepository()
// repoAddress := repositories.NewAddressRepository(config.DB)
// Trashrepo := repositories.NewTrashRepository(config.DB)
// repouser := repositories.NewUserProfilRepository(config.DB)
// // collectorRepo := repositories.NewCollectorRepository(config.DB)
requestPickupServices := services.NewRequestPickupService(requestRepo, repoColl, repoAddress, Trashrepo, repouser)
// collectorService := services.NewCollectorService(collectorRepo, requestRepo, repoAddress)
// service services.RequestPickupService,
// collectorService services.CollectorService
// requestPickupServices := services.NewRequestPickupService(requestRepo, repoColl, repoAddress, Trashrepo, repouser)
// // collectorService := services.NewCollectorService(collectorRepo, requestRepo, repoAddress)
// // service services.RequestPickupService,
// // collectorService services.CollectorService
requestPickupHandler := handler.NewRequestPickupHandler(requestPickupServices)
// requestPickupHandler := handler.NewRequestPickupHandler(requestPickupServices)
requestPickupAPI := api.Group("/requestpickup")
requestPickupAPI.Use(middleware.AuthMiddleware)
// requestPickupAPI := api.Group("/requestpickup")
// requestPickupAPI.Use(middleware.AuthMiddleware)
requestPickupAPI.Post("/", requestPickupHandler.CreateRequestPickup)
// requestPickupAPI.Get("/get", middleware.AuthMiddleware, requestPickupHandler.GetAutomaticRequestByUser)
requestPickupAPI.Get("/get-allrequest", requestPickupHandler.GetRequestPickups)
requestPickupAPI.Patch("/select-collector", requestPickupHandler.AssignCollectorToRequest)
// requestPickupAPI.Get("/:id", requestPickupHandler.GetRequestPickupByID)
// requestPickupAPI.Get("/", requestPickupHandler.GetAllRequestPickups)
// requestPickupAPI.Put("/:id", requestPickupHandler.UpdateRequestPickup)
// requestPickupAPI.Delete("/:id", requestPickupHandler.DeleteRequestPickup)
}
// requestPickupAPI.Post("/", requestPickupHandler.CreateRequestPickup)
// // requestPickupAPI.Get("/get", middleware.AuthMiddleware, requestPickupHandler.GetAutomaticRequestByUser)
// requestPickupAPI.Get("/get-allrequest", requestPickupHandler.GetRequestPickups)
// requestPickupAPI.Patch("/select-collector", requestPickupHandler.AssignCollectorToRequest)
// // requestPickupAPI.Get("/:id", requestPickupHandler.GetRequestPickupByID)
// // requestPickupAPI.Get("/", requestPickupHandler.GetAllRequestPickups)
// // requestPickupAPI.Put("/:id", requestPickupHandler.UpdateRequestPickup)
// // requestPickupAPI.Delete("/:id", requestPickupHandler.DeleteRequestPickup)
// }

View File

@ -26,7 +26,7 @@ func SetupRoutes(app *fiber.App) {
// || auth router || //
presentation.IdentityCardRouter(api)
presentation.CompanyProfileRouter(api)
presentation.RequestPickupRouter(api)
// presentation.RequestPickupRouter(api)
presentation.CollectorRouter(api)
presentation.TrashCartRouter(api)