feat: add all feature are maybe needed in pickup bussiness
This commit is contained in:
parent
b7a1d10898
commit
ab6f282235
|
@ -54,6 +54,8 @@ func ConnectDatabase() {
|
||||||
// =>requestpickup preparation<=
|
// =>requestpickup preparation<=
|
||||||
&model.RequestPickup{},
|
&model.RequestPickup{},
|
||||||
&model.RequestPickupItem{},
|
&model.RequestPickupItem{},
|
||||||
|
&model.PickupStatusHistory{},
|
||||||
|
&model.PickupRating{},
|
||||||
|
|
||||||
&model.Cart{},
|
&model.Cart{},
|
||||||
&model.CartItem{},
|
&model.CartItem{},
|
||||||
|
|
|
@ -5,6 +5,17 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type NearbyCollectorDTO struct {
|
||||||
|
CollectorID string `json:"collector_id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Phone string `json:"phone"`
|
||||||
|
Rating float32 `json:"rating"`
|
||||||
|
Latitude float64 `json:"latitude"`
|
||||||
|
Longitude float64 `json:"longitude"`
|
||||||
|
DistanceKm float64 `json:"distance_km"`
|
||||||
|
MatchedTrash []string `json:"matched_trash_ids"`
|
||||||
|
}
|
||||||
|
|
||||||
type RequestCollectorDTO struct {
|
type RequestCollectorDTO struct {
|
||||||
AddressId string `json:"address_id"`
|
AddressId string `json:"address_id"`
|
||||||
AvaibleTrashbyCollector []RequestAvaibleTrashbyCollector `json:"avaible_trash"`
|
AvaibleTrashbyCollector []RequestAvaibleTrashbyCollector `json:"avaible_trash"`
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package dto
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
type CreatePickupRatingDTO struct {
|
||||||
|
Rating float32 `json:"rating"`
|
||||||
|
Feedback string `json:"feedback"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CreatePickupRatingDTO) ValidateCreatePickupRatingDTO() (map[string][]string, bool) {
|
||||||
|
errors := make(map[string][]string)
|
||||||
|
|
||||||
|
if r.Rating < 1.0 || r.Rating > 5.0 {
|
||||||
|
errors["rating"] = append(errors["rating"], "Rating harus antara 1.0 sampai 5.0")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(strings.TrimSpace(r.Feedback)) > 255 {
|
||||||
|
errors["feedback"] = append(errors["feedback"], "Feedback tidak boleh lebih dari 255 karakter")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(errors) > 0 {
|
||||||
|
return errors, false
|
||||||
|
}
|
||||||
|
return nil, true
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
package dto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// type NearbyCollectorDTO struct {
|
||||||
|
// CollectorID string `json:"collector_id"`
|
||||||
|
// Name string `json:"name"`
|
||||||
|
// Phone string `json:"phone"`
|
||||||
|
// Rating float32 `json:"rating"`
|
||||||
|
// Latitude float64 `json:"latitude"`
|
||||||
|
// Longitude float64 `json:"longitude"`
|
||||||
|
// DistanceKm float64 `json:"distance_km"`
|
||||||
|
// MatchedTrash []string `json:"matched_trash_ids"`
|
||||||
|
// }
|
||||||
|
|
||||||
|
type SelectCollectorDTO struct {
|
||||||
|
CollectorID string `json:"collector_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateRequestPickupItemDTO struct {
|
||||||
|
ItemID string `json:"item_id"`
|
||||||
|
Amount float64 `json:"actual_amount"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdatePickupItemsRequest struct {
|
||||||
|
Items []UpdateRequestPickupItemDTO `json:"items"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *SelectCollectorDTO) Validate() (map[string][]string, bool) {
|
||||||
|
errors := make(map[string][]string)
|
||||||
|
|
||||||
|
if strings.TrimSpace(r.CollectorID) == "" {
|
||||||
|
errors["collector_id"] = append(errors["collector_id"], "collector_id tidak boleh kosong")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(errors) > 0 {
|
||||||
|
return errors, false
|
||||||
|
}
|
||||||
|
return nil, true
|
||||||
|
}
|
||||||
|
|
||||||
|
type AssignedPickupDTO struct {
|
||||||
|
PickupID string `json:"pickup_id"`
|
||||||
|
UserID string `json:"user_id"`
|
||||||
|
UserName string `json:"user_name"`
|
||||||
|
Latitude float64 `json:"latitude"`
|
||||||
|
Longitude float64 `json:"longitude"`
|
||||||
|
Notes string `json:"notes"`
|
||||||
|
MatchedTrash []string `json:"matched_trash"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PickupRequestForCollectorDTO struct {
|
||||||
|
PickupID string `json:"pickup_id"`
|
||||||
|
UserID string `json:"user_id"`
|
||||||
|
Latitude float64 `json:"latitude"`
|
||||||
|
Longitude float64 `json:"longitude"`
|
||||||
|
DistanceKm float64 `json:"distance_km"`
|
||||||
|
MatchedTrash []string `json:"matched_trash"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RequestPickupDTO struct {
|
||||||
|
AddressID string `json:"address_id"`
|
||||||
|
RequestMethod string `json:"request_method"` // "manual" atau "otomatis"
|
||||||
|
Notes string `json:"notes,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RequestPickupDTO) Validate() (map[string][]string, bool) {
|
||||||
|
errors := make(map[string][]string)
|
||||||
|
|
||||||
|
if strings.TrimSpace(r.AddressID) == "" {
|
||||||
|
errors["address_id"] = append(errors["address_id"], "alamat harus dipilih")
|
||||||
|
}
|
||||||
|
|
||||||
|
method := strings.ToLower(strings.TrimSpace(r.RequestMethod))
|
||||||
|
if method != "manual" && method != "otomatis" {
|
||||||
|
errors["request_method"] = append(errors["request_method"], "harus manual atau otomatis")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(errors) > 0 {
|
||||||
|
return errors, false
|
||||||
|
}
|
||||||
|
return nil, true
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"rijig/internal/services"
|
||||||
|
"rijig/utils"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PickupStatusHistoryHandler interface {
|
||||||
|
GetStatusHistory(c *fiber.Ctx) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type pickupStatusHistoryHandler struct {
|
||||||
|
service services.PickupStatusHistoryService
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPickupStatusHistoryHandler(service services.PickupStatusHistoryService) PickupStatusHistoryHandler {
|
||||||
|
return &pickupStatusHistoryHandler{service: service}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *pickupStatusHistoryHandler) GetStatusHistory(c *fiber.Ctx) error {
|
||||||
|
pickupID := c.Params("id")
|
||||||
|
if pickupID == "" {
|
||||||
|
return utils.ValidationErrorResponse(c, map[string][]string{
|
||||||
|
"pickup_id": {"pickup ID tidak boleh kosong"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
histories, err := h.service.GetStatusHistory(context.Background(), pickupID)
|
||||||
|
if err != nil {
|
||||||
|
return utils.InternalServerErrorResponse(c, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return utils.SuccessResponse(c, histories, "Riwayat status pickup berhasil diambil")
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"rijig/internal/services"
|
||||||
|
"rijig/utils"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PickupMatchingHandler interface {
|
||||||
|
GetNearbyCollectorsForPickup(c *fiber.Ctx) error
|
||||||
|
GetAvailablePickupForCollector(c *fiber.Ctx) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type pickupMatchingHandler struct {
|
||||||
|
service services.PickupMatchingService
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPickupMatchingHandler(service services.PickupMatchingService) PickupMatchingHandler {
|
||||||
|
return &pickupMatchingHandler{service: service}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *pickupMatchingHandler) GetNearbyCollectorsForPickup(c *fiber.Ctx) error {
|
||||||
|
pickupID := c.Params("pickupID")
|
||||||
|
if pickupID == "" {
|
||||||
|
return utils.ValidationErrorResponse(c, map[string][]string{
|
||||||
|
"pickup_id": {"pickup ID harus disertakan"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
collectors, err := h.service.FindNearbyCollectorsForPickup(context.Background(), pickupID)
|
||||||
|
if err != nil {
|
||||||
|
return utils.InternalServerErrorResponse(c, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return utils.SuccessResponse(c, collectors, "Data collector terdekat berhasil diambil")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *pickupMatchingHandler) GetAvailablePickupForCollector(c *fiber.Ctx) error {
|
||||||
|
collectorID := c.Locals("userID").(string)
|
||||||
|
|
||||||
|
pickups, err := h.service.FindAvailableRequestsForCollector(context.Background(), collectorID)
|
||||||
|
if err != nil {
|
||||||
|
return utils.InternalServerErrorResponse(c, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return utils.SuccessResponse(c, pickups, "Data request pickup otomatis berhasil diambil")
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"rijig/dto"
|
||||||
|
"rijig/internal/services"
|
||||||
|
"rijig/utils"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PickupRatingHandler interface {
|
||||||
|
CreateRating(c *fiber.Ctx) error
|
||||||
|
GetRatingsByCollector(c *fiber.Ctx) error
|
||||||
|
GetAverageRating(c *fiber.Ctx) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type pickupRatingHandler struct {
|
||||||
|
service services.PickupRatingService
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPickupRatingHandler(service services.PickupRatingService) PickupRatingHandler {
|
||||||
|
return &pickupRatingHandler{service: service}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *pickupRatingHandler) CreateRating(c *fiber.Ctx) error {
|
||||||
|
pickupID := c.Params("id")
|
||||||
|
userID := c.Locals("userID").(string)
|
||||||
|
collectorID := c.Query("collector_id")
|
||||||
|
|
||||||
|
var req dto.CreatePickupRatingDTO
|
||||||
|
if err := c.BodyParser(&req); err != nil {
|
||||||
|
return utils.ValidationErrorResponse(c, map[string][]string{
|
||||||
|
"body": {"Format JSON tidak valid"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if errs, ok := req.ValidateCreatePickupRatingDTO(); !ok {
|
||||||
|
return utils.ValidationErrorResponse(c, errs)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := h.service.CreateRating(context.Background(), userID, pickupID, collectorID, req)
|
||||||
|
if err != nil {
|
||||||
|
return utils.InternalServerErrorResponse(c, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return utils.SuccessResponse(c, nil, "Rating berhasil dikirim")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *pickupRatingHandler) GetRatingsByCollector(c *fiber.Ctx) error {
|
||||||
|
collectorID := c.Params("id")
|
||||||
|
ratings, err := h.service.GetRatingsByCollector(context.Background(), collectorID)
|
||||||
|
if err != nil {
|
||||||
|
return utils.InternalServerErrorResponse(c, err.Error())
|
||||||
|
}
|
||||||
|
return utils.SuccessResponse(c, ratings, "Daftar rating collector berhasil diambil")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *pickupRatingHandler) GetAverageRating(c *fiber.Ctx) error {
|
||||||
|
collectorID := c.Params("id")
|
||||||
|
avg, err := h.service.GetAverageRating(context.Background(), collectorID)
|
||||||
|
if err != nil {
|
||||||
|
return utils.InternalServerErrorResponse(c, err.Error())
|
||||||
|
}
|
||||||
|
return utils.SuccessResponse(c, fiber.Map{"average_rating": avg}, "Rata-rata rating collector")
|
||||||
|
}
|
|
@ -0,0 +1,150 @@
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"rijig/dto"
|
||||||
|
"rijig/internal/services"
|
||||||
|
"rijig/utils"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RequestPickupHandler interface {
|
||||||
|
CreateRequestPickup(c *fiber.Ctx) error
|
||||||
|
SelectCollector(c *fiber.Ctx) error
|
||||||
|
GetAssignedPickup(c *fiber.Ctx) error
|
||||||
|
ConfirmPickup(c *fiber.Ctx) error
|
||||||
|
UpdatePickupStatus(c *fiber.Ctx) error
|
||||||
|
UpdatePickupItemActualAmount(c *fiber.Ctx) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type requestPickupHandler struct {
|
||||||
|
service services.RequestPickupService
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRequestPickupHandler(service services.RequestPickupService) RequestPickupHandler {
|
||||||
|
return &requestPickupHandler{service: service}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *requestPickupHandler) CreateRequestPickup(c *fiber.Ctx) error {
|
||||||
|
userID := c.Locals("userID").(string)
|
||||||
|
|
||||||
|
var req dto.RequestPickupDTO
|
||||||
|
if err := c.BodyParser(&req); err != nil {
|
||||||
|
return utils.ValidationErrorResponse(c, map[string][]string{
|
||||||
|
"body": {"format JSON tidak valid"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if errs, ok := req.Validate(); !ok {
|
||||||
|
return utils.ValidationErrorResponse(c, errs)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := h.service.ConvertCartToRequestPickup(context.Background(), userID, req); err != nil {
|
||||||
|
return utils.InternalServerErrorResponse(c, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return utils.SuccessResponse(c, nil, "Request pickup berhasil dibuat")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *requestPickupHandler) SelectCollector(c *fiber.Ctx) error {
|
||||||
|
pickupID := c.Params("id")
|
||||||
|
if pickupID == "" {
|
||||||
|
return utils.ValidationErrorResponse(c, map[string][]string{
|
||||||
|
"pickup_id": {"pickup ID harus disertakan"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var req dto.SelectCollectorDTO
|
||||||
|
if err := c.BodyParser(&req); err != nil {
|
||||||
|
return utils.ValidationErrorResponse(c, map[string][]string{
|
||||||
|
"body": {"format JSON tidak valid"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if errs, ok := req.Validate(); !ok {
|
||||||
|
return utils.ValidationErrorResponse(c, errs)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := h.service.AssignCollectorToRequest(context.Background(), pickupID, req); err != nil {
|
||||||
|
return utils.InternalServerErrorResponse(c, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return utils.SuccessResponse(c, nil, "Collector berhasil dipilih untuk pickup")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *requestPickupHandler) GetAssignedPickup(c *fiber.Ctx) error {
|
||||||
|
collectorID := c.Locals("userID").(string)
|
||||||
|
result, err := h.service.FindRequestsAssignedToCollector(context.Background(), collectorID)
|
||||||
|
if err != nil {
|
||||||
|
return utils.InternalServerErrorResponse(c, err.Error())
|
||||||
|
}
|
||||||
|
return utils.SuccessResponse(c, result, "Data pickup yang ditugaskan berhasil diambil")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *requestPickupHandler) ConfirmPickup(c *fiber.Ctx) error {
|
||||||
|
pickupID := c.Params("id")
|
||||||
|
if pickupID == "" {
|
||||||
|
return utils.ValidationErrorResponse(c, map[string][]string{
|
||||||
|
"pickup_id": {"pickup ID wajib diisi"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
err := h.service.ConfirmPickupByCollector(context.Background(), pickupID, time.Now())
|
||||||
|
if err != nil {
|
||||||
|
return utils.InternalServerErrorResponse(c, err.Error())
|
||||||
|
}
|
||||||
|
return utils.SuccessResponse(c, nil, "Pickup berhasil dikonfirmasi oleh collector")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *requestPickupHandler) UpdatePickupStatus(c *fiber.Ctx) error {
|
||||||
|
pickupID := c.Params("id")
|
||||||
|
if pickupID == "" {
|
||||||
|
return utils.ValidationErrorResponse(c, map[string][]string{
|
||||||
|
"pickup_id": {"pickup ID tidak boleh kosong"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := h.service.UpdatePickupStatusToPickingUp(context.Background(), pickupID); err != nil {
|
||||||
|
return utils.InternalServerErrorResponse(c, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return utils.SuccessResponse(c, nil, "Status pickup berhasil diperbarui menjadi 'collector_are_picking_up'")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *requestPickupHandler) UpdatePickupItemActualAmount(c *fiber.Ctx) error {
|
||||||
|
pickupID := c.Params("id")
|
||||||
|
if pickupID == "" {
|
||||||
|
return utils.ValidationErrorResponse(c, map[string][]string{
|
||||||
|
"pickup_id": {"pickup ID tidak boleh kosong"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var req dto.UpdatePickupItemsRequest
|
||||||
|
if err := c.BodyParser(&req); err != nil {
|
||||||
|
return utils.ValidationErrorResponse(c, map[string][]string{
|
||||||
|
"body": {"format JSON tidak valid"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.Items) == 0 {
|
||||||
|
return utils.ValidationErrorResponse(c, map[string][]string{
|
||||||
|
"items": {"daftar item tidak boleh kosong"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range req.Items {
|
||||||
|
if item.ItemID == "" || item.Amount <= 0 {
|
||||||
|
return utils.ValidationErrorResponse(c, map[string][]string{
|
||||||
|
"item": {"item_id harus valid dan amount > 0"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := h.service.UpdateActualPickupItems(context.Background(), pickupID, req.Items); err != nil {
|
||||||
|
return utils.InternalServerErrorResponse(c, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return utils.SuccessResponse(c, nil, "Berat aktual dan harga berhasil diperbarui")
|
||||||
|
}
|
|
@ -4,21 +4,11 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
// "fmt"
|
|
||||||
|
|
||||||
// "log"
|
|
||||||
"rijig/config"
|
"rijig/config"
|
||||||
"rijig/model"
|
"rijig/model"
|
||||||
// "gorm.io/gorm"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type CollectorRepository interface {
|
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)
|
|
||||||
|
|
||||||
CreateCollector(ctx context.Context, collector *model.Collector) error
|
CreateCollector(ctx context.Context, collector *model.Collector) error
|
||||||
AddAvaibleTrash(ctx context.Context, trashItems []model.AvaibleTrashByCollector) error
|
AddAvaibleTrash(ctx context.Context, trashItems []model.AvaibleTrashByCollector) error
|
||||||
GetCollectorByID(ctx context.Context, collectorID string) (*model.Collector, error)
|
GetCollectorByID(ctx context.Context, collectorID string) (*model.Collector, error)
|
||||||
|
@ -27,80 +17,18 @@ type CollectorRepository interface {
|
||||||
UpdateCollector(ctx context.Context, collector *model.Collector, updates map[string]interface{}) error
|
UpdateCollector(ctx context.Context, collector *model.Collector, updates map[string]interface{}) error
|
||||||
UpdateAvaibleTrashByCollector(ctx context.Context, collectorID string, updatedTrash []model.AvaibleTrashByCollector) error
|
UpdateAvaibleTrashByCollector(ctx context.Context, collectorID string, updatedTrash []model.AvaibleTrashByCollector) error
|
||||||
DeleteAvaibleTrash(ctx context.Context, trashID string) error
|
DeleteAvaibleTrash(ctx context.Context, trashID string) error
|
||||||
|
|
||||||
|
GetActiveCollectorsWithTrashAndAddress(ctx context.Context) ([]model.Collector, error)
|
||||||
|
GetCollectorWithAddressAndTrash(ctx context.Context, collectorID string) (*model.Collector, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type collectorRepository struct {
|
type collectorRepository struct {
|
||||||
// DB *gorm.DB
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// func NewCollectorRepository(db *gorm.DB) CollectorRepository {
|
|
||||||
// return &collectorRepository{DB: db}
|
|
||||||
// }
|
|
||||||
func NewCollectorRepository() CollectorRepository {
|
func NewCollectorRepository() CollectorRepository {
|
||||||
return &collectorRepository{}
|
return &collectorRepository{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 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 {
|
func (r *collectorRepository) CreateCollector(ctx context.Context, collector *model.Collector) error {
|
||||||
return config.DB.WithContext(ctx).Create(collector).Error
|
return config.DB.WithContext(ctx).Create(collector).Error
|
||||||
}
|
}
|
||||||
|
@ -175,3 +103,35 @@ func (r *collectorRepository) DeleteAvaibleTrash(ctx context.Context, trashID st
|
||||||
return config.DB.WithContext(ctx).
|
return config.DB.WithContext(ctx).
|
||||||
Delete(&model.AvaibleTrashByCollector{}, "id = ?", trashID).Error
|
Delete(&model.AvaibleTrashByCollector{}, "id = ?", trashID).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
func (r *collectorRepository) GetActiveCollectorsWithTrashAndAddress(ctx context.Context) ([]model.Collector, error) {
|
||||||
|
var collectors []model.Collector
|
||||||
|
err := config.DB.WithContext(ctx).
|
||||||
|
Preload("User").
|
||||||
|
Preload("Address").
|
||||||
|
Preload("AvaibleTrashbyCollector.TrashCategory").
|
||||||
|
Where("job_status = ?", "active").
|
||||||
|
Find(&collectors).Error
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return collectors, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *collectorRepository) GetCollectorWithAddressAndTrash(ctx context.Context, collectorID string) (*model.Collector, error) {
|
||||||
|
var collector model.Collector
|
||||||
|
err := config.DB.WithContext(ctx).
|
||||||
|
Preload("Address").
|
||||||
|
Preload("AvaibleTrashbyCollector").
|
||||||
|
Where("id = ?", collectorID).
|
||||||
|
First(&collector).Error
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &collector, nil
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
package repositories
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"rijig/config"
|
||||||
|
"rijig/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PickupStatusHistoryRepository interface {
|
||||||
|
CreateStatusHistory(ctx context.Context, history model.PickupStatusHistory) error
|
||||||
|
GetStatusHistoryByRequestID(ctx context.Context, requestID string) ([]model.PickupStatusHistory, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type pickupStatusHistoryRepository struct{}
|
||||||
|
|
||||||
|
func NewPickupStatusHistoryRepository() PickupStatusHistoryRepository {
|
||||||
|
return &pickupStatusHistoryRepository{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *pickupStatusHistoryRepository) CreateStatusHistory(ctx context.Context, history model.PickupStatusHistory) error {
|
||||||
|
return config.DB.WithContext(ctx).Create(&history).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *pickupStatusHistoryRepository) GetStatusHistoryByRequestID(ctx context.Context, requestID string) ([]model.PickupStatusHistory, error) {
|
||||||
|
var histories []model.PickupStatusHistory
|
||||||
|
err := config.DB.WithContext(ctx).
|
||||||
|
Where("request_id = ?", requestID).
|
||||||
|
Order("changed_at asc").
|
||||||
|
Find(&histories).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return histories, nil
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package repositories
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"rijig/config"
|
||||||
|
"rijig/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PickupRatingRepository interface {
|
||||||
|
CreateRating(ctx context.Context, rating model.PickupRating) error
|
||||||
|
GetRatingsByCollector(ctx context.Context, collectorID string) ([]model.PickupRating, error)
|
||||||
|
CalculateAverageRating(ctx context.Context, collectorID string) (float32, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type pickupRatingRepository struct{}
|
||||||
|
|
||||||
|
func NewPickupRatingRepository() PickupRatingRepository {
|
||||||
|
return &pickupRatingRepository{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *pickupRatingRepository) CreateRating(ctx context.Context, rating model.PickupRating) error {
|
||||||
|
return config.DB.WithContext(ctx).Create(&rating).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *pickupRatingRepository) GetRatingsByCollector(ctx context.Context, collectorID string) ([]model.PickupRating, error) {
|
||||||
|
var ratings []model.PickupRating
|
||||||
|
err := config.DB.WithContext(ctx).
|
||||||
|
Where("collector_id = ?", collectorID).
|
||||||
|
Order("created_at desc").
|
||||||
|
Find(&ratings).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return ratings, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *pickupRatingRepository) CalculateAverageRating(ctx context.Context, collectorID string) (float32, error) {
|
||||||
|
var avg float32
|
||||||
|
err := config.DB.WithContext(ctx).
|
||||||
|
Model(&model.PickupRating{}).
|
||||||
|
Select("AVG(rating)").
|
||||||
|
Where("collector_id = ?", collectorID).
|
||||||
|
Scan(&avg).Error
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return avg, nil
|
||||||
|
}
|
|
@ -0,0 +1,143 @@
|
||||||
|
package repositories
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"rijig/config"
|
||||||
|
"rijig/dto"
|
||||||
|
"rijig/model"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RequestPickupRepository interface {
|
||||||
|
CreateRequestPickup(ctx context.Context, pickup *model.RequestPickup) error
|
||||||
|
GetPickupWithItemsAndAddress(ctx context.Context, id string) (*model.RequestPickup, error)
|
||||||
|
GetAllAutomaticRequestsWithAddress(ctx context.Context) ([]model.RequestPickup, error)
|
||||||
|
UpdateCollectorID(ctx context.Context, pickupID, collectorID string) error
|
||||||
|
GetRequestsAssignedToCollector(ctx context.Context, collectorID string) ([]model.RequestPickup, error)
|
||||||
|
UpdatePickupStatusAndConfirmationTime(ctx context.Context, pickupID string, status string, confirmedAt time.Time) error
|
||||||
|
UpdatePickupStatus(ctx context.Context, pickupID string, status string) error
|
||||||
|
UpdateRequestPickupItemsAmountAndPrice(ctx context.Context, pickupID string, items []dto.UpdateRequestPickupItemDTO) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type requestPickupRepository struct{}
|
||||||
|
|
||||||
|
func NewRequestPickupRepository() RequestPickupRepository {
|
||||||
|
return &requestPickupRepository{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *requestPickupRepository) CreateRequestPickup(ctx context.Context, pickup *model.RequestPickup) error {
|
||||||
|
return config.DB.WithContext(ctx).Create(pickup).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *requestPickupRepository) GetPickupWithItemsAndAddress(ctx context.Context, id string) (*model.RequestPickup, error) {
|
||||||
|
var pickup model.RequestPickup
|
||||||
|
err := config.DB.WithContext(ctx).
|
||||||
|
Preload("RequestItems").
|
||||||
|
Preload("Address").
|
||||||
|
Where("id = ?", id).
|
||||||
|
First(&pickup).Error
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &pickup, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *requestPickupRepository) UpdateCollectorID(ctx context.Context, pickupID, collectorID string) error {
|
||||||
|
return config.DB.WithContext(ctx).
|
||||||
|
Model(&model.RequestPickup{}).
|
||||||
|
Where("id = ?", pickupID).
|
||||||
|
Update("collector_id", collectorID).
|
||||||
|
Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *requestPickupRepository) GetAllAutomaticRequestsWithAddress(ctx context.Context) ([]model.RequestPickup, error) {
|
||||||
|
var pickups []model.RequestPickup
|
||||||
|
err := config.DB.WithContext(ctx).
|
||||||
|
Preload("RequestItems").
|
||||||
|
Preload("Address").
|
||||||
|
Where("request_method = ?", "otomatis").
|
||||||
|
Find(&pickups).Error
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return pickups, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *requestPickupRepository) GetRequestsAssignedToCollector(ctx context.Context, collectorID string) ([]model.RequestPickup, error) {
|
||||||
|
var pickups []model.RequestPickup
|
||||||
|
err := config.DB.WithContext(ctx).
|
||||||
|
Preload("User").
|
||||||
|
Preload("Address").
|
||||||
|
Preload("RequestItems").
|
||||||
|
Where("collector_id = ? AND status_pickup = ?", collectorID, "waiting_collector").
|
||||||
|
Find(&pickups).Error
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return pickups, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *requestPickupRepository) UpdatePickupStatusAndConfirmationTime(ctx context.Context, pickupID string, status string, confirmedAt time.Time) error {
|
||||||
|
return config.DB.WithContext(ctx).
|
||||||
|
Model(&model.RequestPickup{}).
|
||||||
|
Where("id = ?", pickupID).
|
||||||
|
Updates(map[string]interface{}{
|
||||||
|
"status_pickup": status,
|
||||||
|
"confirmed_by_collector_at": confirmedAt,
|
||||||
|
}).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *requestPickupRepository) UpdatePickupStatus(ctx context.Context, pickupID string, status string) error {
|
||||||
|
return config.DB.WithContext(ctx).
|
||||||
|
Model(&model.RequestPickup{}).
|
||||||
|
Where("id = ?", pickupID).
|
||||||
|
Update("status_pickup", status).
|
||||||
|
Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *requestPickupRepository) UpdateRequestPickupItemsAmountAndPrice(ctx context.Context, pickupID string, items []dto.UpdateRequestPickupItemDTO) error {
|
||||||
|
// ambil collector_id dulu dari pickup
|
||||||
|
var pickup model.RequestPickup
|
||||||
|
if err := config.DB.WithContext(ctx).
|
||||||
|
Select("collector_id").
|
||||||
|
Where("id = ?", pickupID).
|
||||||
|
First(&pickup).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range items {
|
||||||
|
var pickupItem model.RequestPickupItem
|
||||||
|
err := config.DB.WithContext(ctx).
|
||||||
|
Where("id = ? AND request_pickup_id = ?", item.ItemID, pickupID).
|
||||||
|
First(&pickupItem).Error
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var price float64
|
||||||
|
err = config.DB.WithContext(ctx).
|
||||||
|
Model(&model.AvaibleTrashByCollector{}).
|
||||||
|
Where("collector_id = ? AND trash_category_id = ?", pickup.CollectorID, pickupItem.TrashCategoryId).
|
||||||
|
Select("price").
|
||||||
|
Scan(&price).Error
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
finalPrice := item.Amount * price
|
||||||
|
err = config.DB.WithContext(ctx).
|
||||||
|
Model(&model.RequestPickupItem{}).
|
||||||
|
Where("id = ?", item.ItemID).
|
||||||
|
Updates(map[string]interface{}{
|
||||||
|
"estimated_amount": item.Amount,
|
||||||
|
"final_price": finalPrice,
|
||||||
|
}).Error
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -1,181 +1,181 @@
|
||||||
package repositories
|
package repositories
|
||||||
|
|
||||||
import (
|
// import (
|
||||||
"fmt"
|
// "fmt"
|
||||||
"rijig/model"
|
// "rijig/model"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
// "gorm.io/gorm"
|
||||||
)
|
// )
|
||||||
|
|
||||||
type RequestPickupRepository interface {
|
// type RequestPickupRepository interface {
|
||||||
CreateRequestPickup(request *model.RequestPickup) error
|
// CreateRequestPickup(request *model.RequestPickup) error
|
||||||
CreateRequestPickupItem(item *model.RequestPickupItem) error
|
// CreateRequestPickupItem(item *model.RequestPickupItem) error
|
||||||
FindRequestPickupByID(id string) (*model.RequestPickup, error)
|
// FindRequestPickupByID(id string) (*model.RequestPickup, error)
|
||||||
FindAllRequestPickups(userId string) ([]model.RequestPickup, error)
|
// FindAllRequestPickups(userId string) ([]model.RequestPickup, error)
|
||||||
FindAllAutomaticMethodRequest(requestMethod, statuspickup string) ([]model.RequestPickup, error)
|
// FindAllAutomaticMethodRequest(requestMethod, statuspickup string) ([]model.RequestPickup, error)
|
||||||
FindRequestPickupByAddressAndStatus(userId, status, method string) (*model.RequestPickup, error)
|
// FindRequestPickupByAddressAndStatus(userId, status, method string) (*model.RequestPickup, error)
|
||||||
FindRequestPickupByStatus(userId, status, method string) (*model.RequestPickup, error)
|
// FindRequestPickupByStatus(userId, status, method string) (*model.RequestPickup, error)
|
||||||
GetRequestPickupItems(requestPickupId string) ([]model.RequestPickupItem, error)
|
// GetRequestPickupItems(requestPickupId string) ([]model.RequestPickupItem, error)
|
||||||
GetAutomaticRequestPickupsForCollector() ([]model.RequestPickup, error)
|
// GetAutomaticRequestPickupsForCollector() ([]model.RequestPickup, error)
|
||||||
GetManualReqMethodforCollect(collector_id string) ([]model.RequestPickup, error)
|
// GetManualReqMethodforCollect(collector_id string) ([]model.RequestPickup, error)
|
||||||
// SelectCollectorInRequest(userId string, collectorId string) error
|
// // SelectCollectorInRequest(userId string, collectorId string) error
|
||||||
UpdateRequestPickup(id string, request *model.RequestPickup) error
|
// UpdateRequestPickup(id string, request *model.RequestPickup) error
|
||||||
DeleteRequestPickup(id string) error
|
// DeleteRequestPickup(id string) error
|
||||||
}
|
|
||||||
|
|
||||||
type requestPickupRepository struct {
|
|
||||||
DB *gorm.DB
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewRequestPickupRepository(db *gorm.DB) RequestPickupRepository {
|
|
||||||
return &requestPickupRepository{DB: db}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *requestPickupRepository) CreateRequestPickup(request *model.RequestPickup) error {
|
|
||||||
if err := r.DB.Create(request).Error; err != nil {
|
|
||||||
return fmt.Errorf("failed to create request pickup: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, item := range request.RequestItems {
|
|
||||||
item.RequestPickupId = request.ID
|
|
||||||
if err := r.DB.Create(&item).Error; err != nil {
|
|
||||||
return fmt.Errorf("failed to create request pickup item: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *requestPickupRepository) CreateRequestPickupItem(item *model.RequestPickupItem) error {
|
|
||||||
if err := r.DB.Create(item).Error; err != nil {
|
|
||||||
return fmt.Errorf("failed to create request pickup item: %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *requestPickupRepository) FindRequestPickupByID(id string) (*model.RequestPickup, error) {
|
|
||||||
var request model.RequestPickup
|
|
||||||
err := r.DB.Preload("RequestItems").First(&request, "id = ?", id).Error
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("request pickup with ID %s not found: %v", id, err)
|
|
||||||
}
|
|
||||||
return &request, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *requestPickupRepository) FindAllRequestPickups(userId string) ([]model.RequestPickup, error) {
|
|
||||||
var requests []model.RequestPickup
|
|
||||||
err := r.DB.Preload("RequestItems").Where("user_id = ?", userId).Find(&requests).Error
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to fetch all request pickups: %v", err)
|
|
||||||
}
|
|
||||||
return requests, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *requestPickupRepository) FindAllAutomaticMethodRequest(requestMethod, statuspickup string) ([]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: %v", requestMethod, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return requests, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *requestPickupRepository) FindRequestPickupByAddressAndStatus(userId, status, method string) (*model.RequestPickup, error) {
|
|
||||||
var request model.RequestPickup
|
|
||||||
err := r.DB.Preload("Address").Where("user_id = ? AND status_pickup = ? AND request_method =?", userId, status, method).First(&request).Error
|
|
||||||
if err != nil {
|
|
||||||
if err == gorm.ErrRecordNotFound {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("failed to check existing request pickup: %v", err)
|
|
||||||
}
|
|
||||||
return &request, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *requestPickupRepository) FindRequestPickupByStatus(userId, status, method string) (*model.RequestPickup, error) {
|
|
||||||
var request model.RequestPickup
|
|
||||||
err := r.DB.Where("user_id = ? AND status_pickup = ? AND request_method =?", userId, status, method).First(&request).Error
|
|
||||||
if err != nil {
|
|
||||||
if err == gorm.ErrRecordNotFound {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("failed to check existing request pickup: %v", err)
|
|
||||||
}
|
|
||||||
return &request, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *requestPickupRepository) UpdateRequestPickup(id string, request *model.RequestPickup) error {
|
|
||||||
err := r.DB.Model(&model.RequestPickup{}).Where("id = ?", id).Updates(request).Error
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to update request pickup: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// func (r *requestPickupRepository) SelectCollectorInRequest(userId string, collectorId string) error {
|
|
||||||
// var request model.RequestPickup
|
|
||||||
// err := r.DB.Model(&model.RequestPickup{}).
|
|
||||||
// Where("user_id = ? AND status_pickup = ? AND request_method = ? AND collector_id IS NULL", userId, "waiting_collector", "manual").
|
|
||||||
// First(&request).Error
|
|
||||||
// if err != nil {
|
|
||||||
// if err == gorm.ErrRecordNotFound {
|
|
||||||
// return fmt.Errorf("no matching request pickup found for user %s", userId)
|
|
||||||
// }
|
|
||||||
// return fmt.Errorf("failed to find request pickup: %v", err)
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// err = r.DB.Model(&model.RequestPickup{}).
|
// type requestPickupRepository struct {
|
||||||
// Where("id = ?", request.ID).
|
// DB *gorm.DB
|
||||||
// Update("collector_id", collectorId).
|
// }
|
||||||
// Error
|
|
||||||
// if err != nil {
|
// func NewRequestPickupRepository(db *gorm.DB) RequestPickupRepository {
|
||||||
// return fmt.Errorf("failed to update collector_id: %v", err)
|
// return &requestPickupRepository{DB: db}
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (r *requestPickupRepository) CreateRequestPickup(request *model.RequestPickup) error {
|
||||||
|
// if err := r.DB.Create(request).Error; err != nil {
|
||||||
|
// return fmt.Errorf("failed to create request pickup: %v", err)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// for _, item := range request.RequestItems {
|
||||||
|
// item.RequestPickupId = request.ID
|
||||||
|
// if err := r.DB.Create(&item).Error; err != nil {
|
||||||
|
// return fmt.Errorf("failed to create request pickup item: %v", err)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (r *requestPickupRepository) CreateRequestPickupItem(item *model.RequestPickupItem) error {
|
||||||
|
// if err := r.DB.Create(item).Error; err != nil {
|
||||||
|
// return fmt.Errorf("failed to create request pickup item: %v", err)
|
||||||
// }
|
// }
|
||||||
// return nil
|
// return nil
|
||||||
// }
|
// }
|
||||||
|
|
||||||
func (r *requestPickupRepository) DeleteRequestPickup(id string) error {
|
// func (r *requestPickupRepository) FindRequestPickupByID(id string) (*model.RequestPickup, error) {
|
||||||
|
// var request model.RequestPickup
|
||||||
|
// err := r.DB.Preload("RequestItems").First(&request, "id = ?", id).Error
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, fmt.Errorf("request pickup with ID %s not found: %v", id, err)
|
||||||
|
// }
|
||||||
|
// return &request, nil
|
||||||
|
// }
|
||||||
|
|
||||||
if err := r.DB.Where("request_pickup_id = ?", id).Delete(&model.RequestPickupItem{}).Error; err != nil {
|
// func (r *requestPickupRepository) FindAllRequestPickups(userId string) ([]model.RequestPickup, error) {
|
||||||
return fmt.Errorf("failed to delete request pickup items: %v", err)
|
// var requests []model.RequestPickup
|
||||||
}
|
// err := r.DB.Preload("RequestItems").Where("user_id = ?", userId).Find(&requests).Error
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, fmt.Errorf("failed to fetch all request pickups: %v", err)
|
||||||
|
// }
|
||||||
|
// return requests, nil
|
||||||
|
// }
|
||||||
|
|
||||||
err := r.DB.Delete(&model.RequestPickup{}, "id = ?", id).Error
|
// func (r *requestPickupRepository) FindAllAutomaticMethodRequest(requestMethod, statuspickup string) ([]model.RequestPickup, error) {
|
||||||
if err != nil {
|
// var requests []model.RequestPickup
|
||||||
return fmt.Errorf("failed to delete request pickup: %v", err)
|
// err := r.DB.Preload("RequestItems").Where("request_method = ? AND status_pickup = ?", requestMethod, statuspickup).Find(&requests).Error
|
||||||
}
|
// if err != nil {
|
||||||
return nil
|
// return nil, fmt.Errorf("error fetching request pickups with request_method %s: %v", requestMethod, err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (r *requestPickupRepository) GetAutomaticRequestPickupsForCollector() ([]model.RequestPickup, error) {
|
// return requests, nil
|
||||||
var requests []model.RequestPickup
|
// }
|
||||||
err := r.DB.Preload("Address").
|
|
||||||
Where("request_method = ? AND status_pickup = ? AND collector_id = ?", "otomatis", "waiting_collector", nil).
|
|
||||||
Find(&requests).Error
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error fetching pickup requests: %v", err)
|
|
||||||
}
|
|
||||||
return requests, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *requestPickupRepository) GetManualReqMethodforCollect(collector_id string) ([]model.RequestPickup, error) {
|
// func (r *requestPickupRepository) FindRequestPickupByAddressAndStatus(userId, status, method string) (*model.RequestPickup, error) {
|
||||||
var requests []model.RequestPickup
|
// var request model.RequestPickup
|
||||||
err := r.DB.Where("request_method = ? AND status_pickup = ? AND collector_id = ?", "otomatis", "waiting_collector", collector_id).
|
// err := r.DB.Preload("Address").Where("user_id = ? AND status_pickup = ? AND request_method =?", userId, status, method).First(&request).Error
|
||||||
Find(&requests).Error
|
// if err != nil {
|
||||||
if err != nil {
|
// if err == gorm.ErrRecordNotFound {
|
||||||
return nil, fmt.Errorf("error fetching pickup requests: %v", err)
|
// return nil, nil
|
||||||
}
|
// }
|
||||||
return requests, nil
|
// return nil, fmt.Errorf("failed to check existing request pickup: %v", err)
|
||||||
}
|
// }
|
||||||
|
// return &request, nil
|
||||||
|
// }
|
||||||
|
|
||||||
func (r *requestPickupRepository) GetRequestPickupItems(requestPickupId string) ([]model.RequestPickupItem, error) {
|
// func (r *requestPickupRepository) FindRequestPickupByStatus(userId, status, method string) (*model.RequestPickup, error) {
|
||||||
var items []model.RequestPickupItem
|
// var request model.RequestPickup
|
||||||
|
// err := r.DB.Where("user_id = ? AND status_pickup = ? AND request_method =?", userId, status, method).First(&request).Error
|
||||||
|
// if err != nil {
|
||||||
|
// if err == gorm.ErrRecordNotFound {
|
||||||
|
// return nil, nil
|
||||||
|
// }
|
||||||
|
// return nil, fmt.Errorf("failed to check existing request pickup: %v", err)
|
||||||
|
// }
|
||||||
|
// return &request, nil
|
||||||
|
// }
|
||||||
|
|
||||||
err := r.DB.Preload("TrashCategory").Where("request_pickup_id = ?", requestPickupId).Find(&items).Error
|
// func (r *requestPickupRepository) UpdateRequestPickup(id string, request *model.RequestPickup) error {
|
||||||
if err != nil {
|
// err := r.DB.Model(&model.RequestPickup{}).Where("id = ?", id).Updates(request).Error
|
||||||
return nil, fmt.Errorf("error fetching request pickup items: %v", err)
|
// if err != nil {
|
||||||
}
|
// return fmt.Errorf("failed to update request pickup: %v", err)
|
||||||
return items, nil
|
// }
|
||||||
}
|
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // func (r *requestPickupRepository) SelectCollectorInRequest(userId string, collectorId string) error {
|
||||||
|
// // var request model.RequestPickup
|
||||||
|
// // err := r.DB.Model(&model.RequestPickup{}).
|
||||||
|
// // Where("user_id = ? AND status_pickup = ? AND request_method = ? AND collector_id IS NULL", userId, "waiting_collector", "manual").
|
||||||
|
// // First(&request).Error
|
||||||
|
// // if err != nil {
|
||||||
|
// // if err == gorm.ErrRecordNotFound {
|
||||||
|
// // return fmt.Errorf("no matching request pickup found for user %s", userId)
|
||||||
|
// // }
|
||||||
|
// // return fmt.Errorf("failed to find request pickup: %v", err)
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // err = r.DB.Model(&model.RequestPickup{}).
|
||||||
|
// // Where("id = ?", request.ID).
|
||||||
|
// // Update("collector_id", collectorId).
|
||||||
|
// // Error
|
||||||
|
// // if err != nil {
|
||||||
|
// // return fmt.Errorf("failed to update collector_id: %v", err)
|
||||||
|
// // }
|
||||||
|
// // return nil
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// func (r *requestPickupRepository) DeleteRequestPickup(id string) error {
|
||||||
|
|
||||||
|
// if err := r.DB.Where("request_pickup_id = ?", id).Delete(&model.RequestPickupItem{}).Error; err != nil {
|
||||||
|
// return fmt.Errorf("failed to delete request pickup items: %v", err)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// err := r.DB.Delete(&model.RequestPickup{}, "id = ?", id).Error
|
||||||
|
// if err != nil {
|
||||||
|
// return fmt.Errorf("failed to delete request pickup: %v", err)
|
||||||
|
// }
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (r *requestPickupRepository) GetAutomaticRequestPickupsForCollector() ([]model.RequestPickup, error) {
|
||||||
|
// var requests []model.RequestPickup
|
||||||
|
// err := r.DB.Preload("Address").
|
||||||
|
// Where("request_method = ? AND status_pickup = ? AND collector_id = ?", "otomatis", "waiting_collector", nil).
|
||||||
|
// Find(&requests).Error
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, fmt.Errorf("error fetching pickup requests: %v", err)
|
||||||
|
// }
|
||||||
|
// return requests, nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (r *requestPickupRepository) GetManualReqMethodforCollect(collector_id string) ([]model.RequestPickup, error) {
|
||||||
|
// var requests []model.RequestPickup
|
||||||
|
// err := r.DB.Where("request_method = ? AND status_pickup = ? AND collector_id = ?", "otomatis", "waiting_collector", collector_id).
|
||||||
|
// Find(&requests).Error
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, fmt.Errorf("error fetching pickup requests: %v", err)
|
||||||
|
// }
|
||||||
|
// return requests, nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (r *requestPickupRepository) GetRequestPickupItems(requestPickupId string) ([]model.RequestPickupItem, error) {
|
||||||
|
// var items []model.RequestPickupItem
|
||||||
|
|
||||||
|
// err := r.DB.Preload("TrashCategory").Where("request_pickup_id = ?", requestPickupId).Find(&items).Error
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, fmt.Errorf("error fetching request pickup items: %v", err)
|
||||||
|
// }
|
||||||
|
// return items, nil
|
||||||
|
// }
|
||||||
|
|
|
@ -20,6 +20,7 @@ type TrashRepository interface {
|
||||||
FindCategoryId(id string) (*model.TrashCategory, error)
|
FindCategoryId(id string) (*model.TrashCategory, error)
|
||||||
GetTrashCategoryByName(name string) (*model.TrashCategory, error)
|
GetTrashCategoryByName(name string) (*model.TrashCategory, error)
|
||||||
GetTrashDetailByID(id string) (*model.TrashDetail, error)
|
GetTrashDetailByID(id string) (*model.TrashDetail, error)
|
||||||
|
GetTrashCategoryByID(ctx context.Context, id string) (*model.TrashCategory, error)
|
||||||
GetDetailsByCategoryID(categoryID string) ([]model.TrashDetail, error)
|
GetDetailsByCategoryID(categoryID string) ([]model.TrashDetail, error)
|
||||||
UpdateCategoryName(id string, newName string) error
|
UpdateCategoryName(id string, newName string) error
|
||||||
UpdateCategory(id string, updateTrashCategory *model.TrashCategory) (*model.TrashCategory, error)
|
UpdateCategory(id string, updateTrashCategory *model.TrashCategory) (*model.TrashCategory, error)
|
||||||
|
@ -68,6 +69,15 @@ func (r *trashRepository) GetCategoryByID(id string) (*model.TrashCategory, erro
|
||||||
return &category, nil
|
return &category, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// spesial code
|
||||||
|
func (r *trashRepository) GetTrashCategoryByID(ctx context.Context, id string) (*model.TrashCategory, error) {
|
||||||
|
var trash model.TrashCategory
|
||||||
|
if err := config.DB.WithContext(ctx).First(&trash, "id = ?", id).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &trash, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *trashRepository) FindCategoryId(id string) (*model.TrashCategory, error) {
|
func (r *trashRepository) FindCategoryId(id string) (*model.TrashCategory, error) {
|
||||||
var category model.TrashCategory
|
var category model.TrashCategory
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
"rijig/model"
|
||||||
|
"rijig/internal/repositories"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PickupStatusHistoryService interface {
|
||||||
|
LogStatusChange(ctx context.Context, requestID, status, changedByID, changedByRole string) error
|
||||||
|
GetStatusHistory(ctx context.Context, requestID string) ([]model.PickupStatusHistory, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type pickupStatusHistoryService struct {
|
||||||
|
repo repositories.PickupStatusHistoryRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPickupStatusHistoryService(repo repositories.PickupStatusHistoryRepository) PickupStatusHistoryService {
|
||||||
|
return &pickupStatusHistoryService{repo: repo}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *pickupStatusHistoryService) LogStatusChange(ctx context.Context, requestID, status, changedByID, changedByRole string) error {
|
||||||
|
history := model.PickupStatusHistory{
|
||||||
|
RequestID: requestID,
|
||||||
|
Status: status,
|
||||||
|
ChangedAt: time.Now(),
|
||||||
|
ChangedByID: changedByID,
|
||||||
|
ChangedByRole: changedByRole,
|
||||||
|
}
|
||||||
|
return s.repo.CreateStatusHistory(ctx, history)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *pickupStatusHistoryService) GetStatusHistory(ctx context.Context, requestID string) ([]model.PickupStatusHistory, error) {
|
||||||
|
return s.repo.GetStatusHistoryByRequestID(ctx, requestID)
|
||||||
|
}
|
|
@ -0,0 +1,146 @@
|
||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"rijig/dto"
|
||||||
|
"rijig/internal/repositories"
|
||||||
|
"rijig/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PickupMatchingService interface {
|
||||||
|
FindNearbyCollectorsForPickup(ctx context.Context, pickupID string) ([]dto.NearbyCollectorDTO, error)
|
||||||
|
FindAvailableRequestsForCollector(ctx context.Context, collectorID string) ([]dto.PickupRequestForCollectorDTO, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type pickupMatchingService struct {
|
||||||
|
pickupRepo repositories.RequestPickupRepository
|
||||||
|
collectorRepo repositories.CollectorRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPickupMatchingService(pickupRepo repositories.RequestPickupRepository, collectorRepo repositories.CollectorRepository) PickupMatchingService {
|
||||||
|
return &pickupMatchingService{
|
||||||
|
pickupRepo: pickupRepo,
|
||||||
|
collectorRepo: collectorRepo,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *pickupMatchingService) FindNearbyCollectorsForPickup(ctx context.Context, pickupID string) ([]dto.NearbyCollectorDTO, error) {
|
||||||
|
pickup, err := s.pickupRepo.GetPickupWithItemsAndAddress(ctx, pickupID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("pickup tidak ditemukan: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
userCoord := utils.Coord{
|
||||||
|
Lat: pickup.Address.Latitude,
|
||||||
|
Lon: pickup.Address.Longitude,
|
||||||
|
}
|
||||||
|
|
||||||
|
requestedTrash := make(map[string]bool)
|
||||||
|
for _, item := range pickup.RequestItems {
|
||||||
|
requestedTrash[item.TrashCategoryId] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
collectors, err := s.collectorRepo.GetActiveCollectorsWithTrashAndAddress(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("gagal mengambil data collector: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var result []dto.NearbyCollectorDTO
|
||||||
|
for _, col := range collectors {
|
||||||
|
coord := utils.Coord{
|
||||||
|
Lat: col.Address.Latitude,
|
||||||
|
Lon: col.Address.Longitude,
|
||||||
|
}
|
||||||
|
|
||||||
|
_, km := utils.Distance(userCoord, coord)
|
||||||
|
if km > 10 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var matchedTrash []string
|
||||||
|
for _, item := range col.AvaibleTrashByCollector {
|
||||||
|
if requestedTrash[item.TrashCategoryID] {
|
||||||
|
matchedTrash = append(matchedTrash, item.TrashCategoryID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(matchedTrash) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
result = append(result, dto.NearbyCollectorDTO{
|
||||||
|
CollectorID: col.ID,
|
||||||
|
Name: col.User.Name,
|
||||||
|
Phone: col.User.Phone,
|
||||||
|
Rating: col.Rating,
|
||||||
|
Latitude: col.Address.Latitude,
|
||||||
|
Longitude: col.Address.Longitude,
|
||||||
|
DistanceKm: km,
|
||||||
|
MatchedTrash: matchedTrash,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// terdpaat error seperti ini: "undefined: dto.PickupRequestForCollectorDTO" dan seprti ini: s.collectorRepo.GetCollectorWithAddressAndTrash undefined (type repositories.CollectorRepository has no field or method GetCollectorWithAddressAndTrash) pada kode berikut:
|
||||||
|
|
||||||
|
func (s *pickupMatchingService) FindAvailableRequestsForCollector(ctx context.Context, collectorID string) ([]dto.PickupRequestForCollectorDTO, error) {
|
||||||
|
collector, err := s.collectorRepo.GetCollectorWithAddressAndTrash(ctx, collectorID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("collector tidak ditemukan: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pickupList, err := s.pickupRepo.GetAllAutomaticRequestsWithAddress(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("gagal mengambil pickup otomatis: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
collectorCoord := utils.Coord{
|
||||||
|
Lat: collector.Address.Latitude,
|
||||||
|
Lon: collector.Address.Longitude,
|
||||||
|
}
|
||||||
|
|
||||||
|
// map trash collector
|
||||||
|
collectorTrash := make(map[string]bool)
|
||||||
|
for _, t := range collector.AvaibleTrashByCollector {
|
||||||
|
collectorTrash[t.TrashCategoryID] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
var results []dto.PickupRequestForCollectorDTO
|
||||||
|
for _, p := range pickupList {
|
||||||
|
if p.StatusPickup != "waiting_collector" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
coord := utils.Coord{
|
||||||
|
Lat: p.Address.Latitude,
|
||||||
|
Lon: p.Address.Longitude,
|
||||||
|
}
|
||||||
|
_, km := utils.Distance(collectorCoord, coord)
|
||||||
|
if km > 10 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
match := false
|
||||||
|
var matchedTrash []string
|
||||||
|
for _, item := range p.RequestItems {
|
||||||
|
if collectorTrash[item.TrashCategoryId] {
|
||||||
|
match = true
|
||||||
|
matchedTrash = append(matchedTrash, item.TrashCategoryId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if match {
|
||||||
|
results = append(results, dto.PickupRequestForCollectorDTO{
|
||||||
|
PickupID: p.ID,
|
||||||
|
UserID: p.UserId,
|
||||||
|
Latitude: p.Address.Latitude,
|
||||||
|
Longitude: p.Address.Longitude,
|
||||||
|
DistanceKm: km,
|
||||||
|
MatchedTrash: matchedTrash,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return results, nil
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
"rijig/dto"
|
||||||
|
"rijig/internal/repositories"
|
||||||
|
"rijig/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PickupRatingService interface {
|
||||||
|
CreateRating(ctx context.Context, userID, pickupID, collectorID string, input dto.CreatePickupRatingDTO) error
|
||||||
|
GetRatingsByCollector(ctx context.Context, collectorID string) ([]model.PickupRating, error)
|
||||||
|
GetAverageRating(ctx context.Context, collectorID string) (float32, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type pickupRatingService struct {
|
||||||
|
repo repositories.PickupRatingRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPickupRatingService(repo repositories.PickupRatingRepository) PickupRatingService {
|
||||||
|
return &pickupRatingService{repo: repo}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *pickupRatingService) CreateRating(ctx context.Context, userID, pickupID, collectorID string, input dto.CreatePickupRatingDTO) error {
|
||||||
|
rating := model.PickupRating{
|
||||||
|
RequestID: pickupID,
|
||||||
|
UserID: userID,
|
||||||
|
CollectorID: collectorID,
|
||||||
|
Rating: input.Rating,
|
||||||
|
Feedback: input.Feedback,
|
||||||
|
CreatedAt: time.Now(),
|
||||||
|
}
|
||||||
|
return s.repo.CreateRating(ctx, rating)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *pickupRatingService) GetRatingsByCollector(ctx context.Context, collectorID string) ([]model.PickupRating, error) {
|
||||||
|
return s.repo.GetRatingsByCollector(ctx, collectorID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *pickupRatingService) GetAverageRating(ctx context.Context, collectorID string) (float32, error) {
|
||||||
|
return s.repo.CalculateAverageRating(ctx, collectorID)
|
||||||
|
}
|
|
@ -0,0 +1,139 @@
|
||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"rijig/dto"
|
||||||
|
"rijig/internal/repositories"
|
||||||
|
"rijig/model"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RequestPickupService interface {
|
||||||
|
ConvertCartToRequestPickup(ctx context.Context, userID string, req dto.RequestPickupDTO) error
|
||||||
|
AssignCollectorToRequest(ctx context.Context, pickupID string, req dto.SelectCollectorDTO) error
|
||||||
|
FindRequestsAssignedToCollector(ctx context.Context, collectorID string) ([]dto.AssignedPickupDTO, error)
|
||||||
|
ConfirmPickupByCollector(ctx context.Context, pickupID string, confirmedAt time.Time) error
|
||||||
|
UpdatePickupStatusToPickingUp(ctx context.Context, pickupID string) error
|
||||||
|
UpdateActualPickupItems(ctx context.Context, pickupID string, items []dto.UpdateRequestPickupItemDTO) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type requestPickupService struct {
|
||||||
|
trashRepo repositories.TrashRepository
|
||||||
|
pickupRepo repositories.RequestPickupRepository
|
||||||
|
cartService CartService
|
||||||
|
historyRepo repositories.PickupStatusHistoryRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRequestPickupService(trashRepo repositories.TrashRepository, pickupRepo repositories.RequestPickupRepository, cartService CartService, historyRepo repositories.PickupStatusHistoryRepository) RequestPickupService {
|
||||||
|
return &requestPickupService{
|
||||||
|
trashRepo: trashRepo,
|
||||||
|
pickupRepo: pickupRepo,
|
||||||
|
cartService: cartService,
|
||||||
|
historyRepo: historyRepo,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *requestPickupService) ConvertCartToRequestPickup(ctx context.Context, userID string, req dto.RequestPickupDTO) error {
|
||||||
|
cart, err := s.cartService.GetCart(ctx, userID)
|
||||||
|
if err != nil || len(cart.CartItems) == 0 {
|
||||||
|
return fmt.Errorf("cart kosong atau tidak ditemukan")
|
||||||
|
}
|
||||||
|
|
||||||
|
var requestItems []model.RequestPickupItem
|
||||||
|
for _, item := range cart.CartItems {
|
||||||
|
trash, err := s.trashRepo.GetTrashCategoryByID(ctx, item.TrashID)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
subtotal := float64(item.Amount) * trash.EstimatedPrice
|
||||||
|
|
||||||
|
requestItems = append(requestItems, model.RequestPickupItem{
|
||||||
|
TrashCategoryId: item.TrashID,
|
||||||
|
EstimatedAmount: float64(item.Amount),
|
||||||
|
EstimatedPricePerKg: trash.EstimatedPrice,
|
||||||
|
EstimatedSubtotalPrice: subtotal,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(requestItems) == 0 {
|
||||||
|
return fmt.Errorf("tidak ada item valid dalam cart")
|
||||||
|
}
|
||||||
|
|
||||||
|
pickup := model.RequestPickup{
|
||||||
|
UserId: userID,
|
||||||
|
AddressId: req.AddressID,
|
||||||
|
RequestMethod: req.RequestMethod,
|
||||||
|
Notes: req.Notes,
|
||||||
|
StatusPickup: "waiting_collector",
|
||||||
|
RequestItems: requestItems,
|
||||||
|
CreatedAt: time.Now(),
|
||||||
|
UpdatedAt: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.pickupRepo.CreateRequestPickup(ctx, &pickup); err != nil {
|
||||||
|
return fmt.Errorf("gagal menyimpan request pickup: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.cartService.ClearCart(ctx, userID); err != nil {
|
||||||
|
return fmt.Errorf("request berhasil, tapi gagal hapus cart: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *requestPickupService) AssignCollectorToRequest(ctx context.Context, pickupID string, req dto.SelectCollectorDTO) error {
|
||||||
|
if req.CollectorID == "" {
|
||||||
|
return fmt.Errorf("collector_id tidak boleh kosong")
|
||||||
|
}
|
||||||
|
return s.pickupRepo.UpdateCollectorID(ctx, pickupID, req.CollectorID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *requestPickupService) FindRequestsAssignedToCollector(ctx context.Context, collectorID string) ([]dto.AssignedPickupDTO, error) {
|
||||||
|
pickups, err := s.pickupRepo.GetRequestsAssignedToCollector(ctx, collectorID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var result []dto.AssignedPickupDTO
|
||||||
|
for _, p := range pickups {
|
||||||
|
var matchedTrash []string
|
||||||
|
for _, item := range p.RequestItems {
|
||||||
|
matchedTrash = append(matchedTrash, item.TrashCategoryId)
|
||||||
|
}
|
||||||
|
|
||||||
|
result = append(result, dto.AssignedPickupDTO{
|
||||||
|
PickupID: p.ID,
|
||||||
|
UserID: p.UserId,
|
||||||
|
UserName: p.User.Name,
|
||||||
|
Latitude: p.Address.Latitude,
|
||||||
|
Longitude: p.Address.Longitude,
|
||||||
|
Notes: p.Notes,
|
||||||
|
MatchedTrash: matchedTrash,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *requestPickupService) ConfirmPickupByCollector(ctx context.Context, pickupID string, confirmedAt time.Time) error {
|
||||||
|
return s.pickupRepo.UpdatePickupStatusAndConfirmationTime(ctx, pickupID, "confirmed_by_collector", confirmedAt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *requestPickupService) UpdatePickupStatusToPickingUp(ctx context.Context, pickupID string) error {
|
||||||
|
err := s.pickupRepo.UpdatePickupStatus(ctx, pickupID, "collector_are_picking_up")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return s.historyRepo.CreateStatusHistory(ctx, model.PickupStatusHistory{
|
||||||
|
RequestID: pickupID,
|
||||||
|
Status: "collector_are_picking_up",
|
||||||
|
ChangedAt: time.Now(),
|
||||||
|
ChangedByID: "collector",
|
||||||
|
ChangedByRole: "collector",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *requestPickupService) UpdateActualPickupItems(ctx context.Context, pickupID string, items []dto.UpdateRequestPickupItemDTO) error {
|
||||||
|
return s.pickupRepo.UpdateRequestPickupItemsAmountAndPrice(ctx, pickupID, items)
|
||||||
|
}
|
|
@ -1,349 +1,349 @@
|
||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
// import (
|
||||||
"fmt"
|
// "fmt"
|
||||||
"rijig/dto"
|
// "rijig/dto"
|
||||||
"rijig/internal/repositories"
|
// "rijig/internal/repositories"
|
||||||
"rijig/model"
|
// "rijig/model"
|
||||||
"rijig/utils"
|
// "rijig/utils"
|
||||||
)
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
type requestPickupService struct {
|
|
||||||
repo repositories.RequestPickupRepository
|
|
||||||
repoColl repositories.CollectorRepository
|
|
||||||
repoAddress repositories.AddressRepository
|
|
||||||
repoTrash repositories.TrashRepository
|
|
||||||
repoUser repositories.UserProfilRepository
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewRequestPickupService(repo repositories.RequestPickupRepository,
|
|
||||||
repoColl repositories.CollectorRepository,
|
|
||||||
repoAddress repositories.AddressRepository,
|
|
||||||
repoTrash repositories.TrashRepository,
|
|
||||||
repoUser repositories.UserProfilRepository) RequestPickupService {
|
|
||||||
return &requestPickupService{repo: repo, repoColl: repoColl, repoAddress: repoAddress, repoTrash: repoTrash, repoUser: repoUser}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *requestPickupService) CreateRequestPickup(request dto.RequestPickup, UserId string) (*dto.ResponseRequestPickup, error) {
|
|
||||||
|
|
||||||
errors, valid := request.ValidateRequestPickup()
|
|
||||||
if !valid {
|
|
||||||
return nil, fmt.Errorf("validation errors: %v", errors)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := s.repoAddress.FindAddressByID(request.AddressID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("address with ID %s not found", request.AddressID)
|
|
||||||
}
|
|
||||||
|
|
||||||
existingRequest, err := s.repo.FindRequestPickupByAddressAndStatus(UserId, "waiting_collector", "otomatis")
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error checking for existing request pickup: %v", err)
|
|
||||||
}
|
|
||||||
if existingRequest != nil {
|
|
||||||
return nil, fmt.Errorf("there is already a pending pickup request for address %s", request.AddressID)
|
|
||||||
}
|
|
||||||
|
|
||||||
modelRequest := model.RequestPickup{
|
|
||||||
UserId: UserId,
|
|
||||||
AddressId: request.AddressID,
|
|
||||||
EvidenceImage: request.EvidenceImage,
|
|
||||||
RequestMethod: request.RequestMethod,
|
|
||||||
}
|
|
||||||
|
|
||||||
err = s.repo.CreateRequestPickup(&modelRequest)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to create request pickup: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
createdAt, _ := utils.FormatDateToIndonesianFormat(modelRequest.CreatedAt)
|
|
||||||
updatedAt, _ := utils.FormatDateToIndonesianFormat(modelRequest.UpdatedAt)
|
|
||||||
|
|
||||||
response := &dto.ResponseRequestPickup{
|
|
||||||
ID: modelRequest.ID,
|
|
||||||
UserId: UserId,
|
|
||||||
AddressID: modelRequest.AddressId,
|
|
||||||
EvidenceImage: modelRequest.EvidenceImage,
|
|
||||||
StatusPickup: modelRequest.StatusPickup,
|
|
||||||
CreatedAt: createdAt,
|
|
||||||
UpdatedAt: updatedAt,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, item := range request.RequestItems {
|
|
||||||
|
|
||||||
findTrashCategory, err := s.repoTrash.GetCategoryByID(item.TrashCategoryID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("trash category with ID %s not found", item.TrashCategoryID)
|
|
||||||
}
|
|
||||||
|
|
||||||
modelItem := model.RequestPickupItem{
|
|
||||||
RequestPickupId: modelRequest.ID,
|
|
||||||
TrashCategoryId: findTrashCategory.ID,
|
|
||||||
EstimatedAmount: item.EstimatedAmount,
|
|
||||||
}
|
|
||||||
err = s.repo.CreateRequestPickupItem(&modelItem)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to create request pickup item: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
response.RequestItems = append(response.RequestItems, dto.ResponseRequestPickupItem{
|
|
||||||
ID: modelItem.ID,
|
|
||||||
TrashCategory: []dto.ResponseTrashCategoryDTO{{Name: findTrashCategory.Name, Icon: findTrashCategory.Icon}},
|
|
||||||
EstimatedAmount: modelItem.EstimatedAmount,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return response, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *requestPickupService) GetRequestPickupByID(id string) (*dto.ResponseRequestPickup, error) {
|
|
||||||
|
|
||||||
request, err := s.repo.FindRequestPickupByID(id)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error fetching request pickup with ID %s: %v", id, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
createdAt, _ := utils.FormatDateToIndonesianFormat(request.CreatedAt)
|
|
||||||
updatedAt, _ := utils.FormatDateToIndonesianFormat(request.UpdatedAt)
|
|
||||||
|
|
||||||
response := &dto.ResponseRequestPickup{
|
|
||||||
ID: request.ID,
|
|
||||||
UserId: request.UserId,
|
|
||||||
AddressID: request.AddressId,
|
|
||||||
EvidenceImage: request.EvidenceImage,
|
|
||||||
StatusPickup: request.StatusPickup,
|
|
||||||
CreatedAt: createdAt,
|
|
||||||
UpdatedAt: updatedAt,
|
|
||||||
}
|
|
||||||
|
|
||||||
return response, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *requestPickupService) GetAllRequestPickups(userid string) ([]dto.ResponseRequestPickup, error) {
|
|
||||||
|
|
||||||
requests, err := s.repo.FindAllRequestPickups(userid)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error fetching all request pickups: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var response []dto.ResponseRequestPickup
|
|
||||||
for _, request := range requests {
|
|
||||||
createdAt, _ := utils.FormatDateToIndonesianFormat(request.CreatedAt)
|
|
||||||
updatedAt, _ := utils.FormatDateToIndonesianFormat(request.UpdatedAt)
|
|
||||||
response = append(response, dto.ResponseRequestPickup{
|
|
||||||
ID: request.ID,
|
|
||||||
UserId: request.UserId,
|
|
||||||
AddressID: request.AddressId,
|
|
||||||
EvidenceImage: request.EvidenceImage,
|
|
||||||
StatusPickup: request.StatusPickup,
|
|
||||||
CreatedAt: createdAt,
|
|
||||||
UpdatedAt: updatedAt,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var response []dto.ResponseRequestPickup
|
|
||||||
|
|
||||||
// for _, req := range requests {
|
|
||||||
|
|
||||||
// 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},
|
|
||||||
// )
|
// )
|
||||||
|
|
||||||
// if distance <= 20 {
|
// type RequestPickupService interface {
|
||||||
|
// // CreateRequestPickup(request dto.RequestPickup, UserId string) (*dto.ResponseRequestPickup, error)
|
||||||
// mappedRequest := dto.ResponseRequestPickup{
|
// // GetRequestPickupByID(id string) (*dto.ResponseRequestPickup, error)
|
||||||
// ID: req.ID,
|
// // GetAllRequestPickups(userid string) ([]dto.ResponseRequestPickup, error)
|
||||||
// UserId: req.UserId,
|
// // GetRequestPickupsForCollector(collectorId string) ([]dto.ResponseRequestPickup, error)
|
||||||
// AddressID: req.AddressId,
|
// // SelectCollectorInRequest(userId, collectorId string) error
|
||||||
// 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)
|
// type requestPickupService struct {
|
||||||
|
// repo repositories.RequestPickupRepository
|
||||||
|
// repoColl repositories.CollectorRepository
|
||||||
|
// repoAddress repositories.AddressRepository
|
||||||
|
// repoTrash repositories.TrashRepository
|
||||||
|
// repoUser repositories.UserProfilRepository
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func NewRequestPickupService(repo repositories.RequestPickupRepository,
|
||||||
|
// repoColl repositories.CollectorRepository,
|
||||||
|
// repoAddress repositories.AddressRepository,
|
||||||
|
// repoTrash repositories.TrashRepository,
|
||||||
|
// repoUser repositories.UserProfilRepository) RequestPickupService {
|
||||||
|
// return &requestPickupService{repo: repo, repoColl: repoColl, repoAddress: repoAddress, repoTrash: repoTrash, repoUser: repoUser}
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (s *requestPickupService) CreateRequestPickup(request dto.RequestPickup, UserId string) (*dto.ResponseRequestPickup, error) {
|
||||||
|
|
||||||
|
// errors, valid := request.ValidateRequestPickup()
|
||||||
|
// if !valid {
|
||||||
|
// return nil, fmt.Errorf("validation errors: %v", errors)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// _, err := s.repoAddress.FindAddressByID(request.AddressID)
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// return nil, fmt.Errorf("error fetching user data: %v", err)
|
// return nil, fmt.Errorf("address with ID %s not found", request.AddressID)
|
||||||
// }
|
|
||||||
// mappedRequest.User = []dto.UserResponseDTO{
|
|
||||||
// {
|
|
||||||
// Name: user.Name,
|
|
||||||
// Phone: user.Phone,
|
|
||||||
// },
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// address, err := s.repoAddress.FindAddressByID(req.AddressId)
|
// existingRequest, err := s.repo.FindRequestPickupByAddressAndStatus(UserId, "waiting_collector", "otomatis")
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// return nil, fmt.Errorf("error fetching address data: %v", err)
|
// return nil, fmt.Errorf("error checking for existing request pickup: %v", err)
|
||||||
// }
|
// }
|
||||||
// mappedRequest.Address = []dto.AddressResponseDTO{
|
// if existingRequest != nil {
|
||||||
// {
|
// return nil, fmt.Errorf("there is already a pending pickup request for address %s", request.AddressID)
|
||||||
// District: address.District,
|
|
||||||
// Village: address.Village,
|
|
||||||
// Detail: address.Detail,
|
|
||||||
// },
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// requestItems, err := s.repo.GetRequestPickupItems(req.ID)
|
// modelRequest := model.RequestPickup{
|
||||||
|
// UserId: UserId,
|
||||||
|
// AddressId: request.AddressID,
|
||||||
|
// EvidenceImage: request.EvidenceImage,
|
||||||
|
// RequestMethod: request.RequestMethod,
|
||||||
|
// }
|
||||||
|
|
||||||
|
// err = s.repo.CreateRequestPickup(&modelRequest)
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// return nil, fmt.Errorf("error fetching request items: %v", err)
|
// return nil, fmt.Errorf("failed to create request pickup: %v", err)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// var mappedRequestItems []dto.ResponseRequestPickupItem
|
// createdAt, _ := utils.FormatDateToIndonesianFormat(modelRequest.CreatedAt)
|
||||||
|
// updatedAt, _ := utils.FormatDateToIndonesianFormat(modelRequest.UpdatedAt)
|
||||||
|
|
||||||
// for _, item := range requestItems {
|
// response := &dto.ResponseRequestPickup{
|
||||||
// trashCategory, err := s.repoTrash.GetCategoryByID(item.TrashCategoryId)
|
// ID: modelRequest.ID,
|
||||||
// if err != nil {
|
// UserId: UserId,
|
||||||
// return nil, fmt.Errorf("error fetching trash category: %v", err)
|
// AddressID: modelRequest.AddressId,
|
||||||
// }
|
// EvidenceImage: modelRequest.EvidenceImage,
|
||||||
|
// StatusPickup: modelRequest.StatusPickup,
|
||||||
// mappedRequestItems = append(mappedRequestItems, dto.ResponseRequestPickupItem{
|
|
||||||
// ID: item.ID,
|
|
||||||
// TrashCategory: []dto.ResponseTrashCategoryDTO{{
|
|
||||||
// Name: trashCategory.Name,
|
|
||||||
// Icon: trashCategory.Icon,
|
|
||||||
// }},
|
|
||||||
// EstimatedAmount: item.EstimatedAmount,
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
|
|
||||||
// mappedRequest.RequestItems = mappedRequestItems
|
|
||||||
|
|
||||||
// response = append(response, mappedRequest)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return response, nil
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var response []dto.ResponseRequestPickup
|
|
||||||
|
|
||||||
// for _, req := range requests {
|
|
||||||
|
|
||||||
// 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,
|
// CreatedAt: createdAt,
|
||||||
// UpdatedAt: updatedAt,
|
// UpdatedAt: updatedAt,
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// user, err := s.repoUser.FindByID(req.UserId)
|
// for _, item := range request.RequestItems {
|
||||||
|
|
||||||
|
// findTrashCategory, err := s.repoTrash.GetCategoryByID(item.TrashCategoryID)
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// return nil, fmt.Errorf("error fetching user data: %v", err)
|
// return nil, fmt.Errorf("trash category with ID %s not found", item.TrashCategoryID)
|
||||||
// }
|
|
||||||
// mappedRequest.User = []dto.UserResponseDTO{
|
|
||||||
// {
|
|
||||||
// Name: user.Name,
|
|
||||||
// Phone: user.Phone,
|
|
||||||
// },
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// address, err := s.repoAddress.FindAddressByID(req.AddressId)
|
// modelItem := model.RequestPickupItem{
|
||||||
// if err != nil {
|
// RequestPickupId: modelRequest.ID,
|
||||||
// return nil, fmt.Errorf("error fetching address data: %v", err)
|
// TrashCategoryId: findTrashCategory.ID,
|
||||||
// }
|
|
||||||
// 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)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// mappedRequestItems = append(mappedRequestItems, dto.ResponseRequestPickupItem{
|
|
||||||
// ID: item.ID,
|
|
||||||
// TrashCategory: []dto.ResponseTrashCategoryDTO{{
|
|
||||||
// Name: trashCategory.Name,
|
|
||||||
// Icon: trashCategory.Icon,
|
|
||||||
// }},
|
|
||||||
// EstimatedAmount: item.EstimatedAmount,
|
// EstimatedAmount: item.EstimatedAmount,
|
||||||
// })
|
// }
|
||||||
|
// err = s.repo.CreateRequestPickupItem(&modelItem)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, fmt.Errorf("failed to create request pickup item: %v", err)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// mappedRequest.RequestItems = mappedRequestItems
|
// response.RequestItems = append(response.RequestItems, dto.ResponseRequestPickupItem{
|
||||||
|
// ID: modelItem.ID,
|
||||||
// response = append(response, mappedRequest)
|
// TrashCategory: []dto.ResponseTrashCategoryDTO{{Name: findTrashCategory.Name, Icon: findTrashCategory.Icon}},
|
||||||
|
// EstimatedAmount: modelItem.EstimatedAmount,
|
||||||
|
// })
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// return response, nil
|
// return response, nil
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// func (s *requestPickupService) SelectCollectorInRequest(userId, collectorId string) error {
|
// func (s *requestPickupService) GetRequestPickupByID(id string) (*dto.ResponseRequestPickup, error) {
|
||||||
|
|
||||||
// request, err := s.repo.FindRequestPickupByStatus(userId, "waiting_collector", "manual")
|
// request, err := s.repo.FindRequestPickupByID(id)
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// return fmt.Errorf("request pickup not found: %v", err)
|
// return nil, fmt.Errorf("error fetching request pickup with ID %s: %v", id, err)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// if request.StatusPickup != "waiting_collector" && request.RequestMethod != "manual" {
|
// createdAt, _ := utils.FormatDateToIndonesianFormat(request.CreatedAt)
|
||||||
// return fmt.Errorf("pickup request is not in 'waiting_collector' status and not 'manual' method")
|
// updatedAt, _ := utils.FormatDateToIndonesianFormat(request.UpdatedAt)
|
||||||
|
|
||||||
|
// response := &dto.ResponseRequestPickup{
|
||||||
|
// ID: request.ID,
|
||||||
|
// UserId: request.UserId,
|
||||||
|
// AddressID: request.AddressId,
|
||||||
|
// EvidenceImage: request.EvidenceImage,
|
||||||
|
// StatusPickup: request.StatusPickup,
|
||||||
|
// CreatedAt: createdAt,
|
||||||
|
// UpdatedAt: updatedAt,
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// collector, err := s.repoColl.FindCollectorByIdWithoutAddr(collectorId)
|
// return response, nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (s *requestPickupService) GetAllRequestPickups(userid string) ([]dto.ResponseRequestPickup, error) {
|
||||||
|
|
||||||
|
// requests, err := s.repo.FindAllRequestPickups(userid)
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// return fmt.Errorf("collector tidak ditemukan: %v", err)
|
// return nil, fmt.Errorf("error fetching all request pickups: %v", err)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// request.CollectorID = &collector.ID
|
// var response []dto.ResponseRequestPickup
|
||||||
|
// for _, request := range requests {
|
||||||
// err = s.repo.UpdateRequestPickup(request.ID, request)
|
// createdAt, _ := utils.FormatDateToIndonesianFormat(request.CreatedAt)
|
||||||
// if err != nil {
|
// updatedAt, _ := utils.FormatDateToIndonesianFormat(request.UpdatedAt)
|
||||||
// return fmt.Errorf("failed to update request pickup: %v", err)
|
// response = append(response, dto.ResponseRequestPickup{
|
||||||
|
// ID: request.ID,
|
||||||
|
// UserId: request.UserId,
|
||||||
|
// AddressID: request.AddressId,
|
||||||
|
// EvidenceImage: request.EvidenceImage,
|
||||||
|
// StatusPickup: request.StatusPickup,
|
||||||
|
// CreatedAt: createdAt,
|
||||||
|
// UpdatedAt: updatedAt,
|
||||||
|
// })
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// return nil
|
// 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)
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // var response []dto.ResponseRequestPickup
|
||||||
|
|
||||||
|
// // for _, req := range requests {
|
||||||
|
|
||||||
|
// // 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},
|
||||||
|
// // )
|
||||||
|
|
||||||
|
// // 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"),
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // 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,
|
||||||
|
// // },
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // requestItems, err := s.repo.GetRequestPickupItems(req.ID)
|
||||||
|
// // if err != nil {
|
||||||
|
// // return nil, fmt.Errorf("error fetching request items: %v", err)
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // 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)
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // mappedRequestItems = append(mappedRequestItems, dto.ResponseRequestPickupItem{
|
||||||
|
// // ID: item.ID,
|
||||||
|
// // TrashCategory: []dto.ResponseTrashCategoryDTO{{
|
||||||
|
// // Name: trashCategory.Name,
|
||||||
|
// // Icon: trashCategory.Icon,
|
||||||
|
// // }},
|
||||||
|
// // EstimatedAmount: item.EstimatedAmount,
|
||||||
|
// // })
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // mappedRequest.RequestItems = mappedRequestItems
|
||||||
|
|
||||||
|
// // response = append(response, mappedRequest)
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // return response, nil
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // 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)
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // var response []dto.ResponseRequestPickup
|
||||||
|
|
||||||
|
// // for _, req := range requests {
|
||||||
|
|
||||||
|
// // 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,
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // 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,
|
||||||
|
// // },
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // requestItems, err := s.repo.GetRequestPickupItems(req.ID)
|
||||||
|
// // if err != nil {
|
||||||
|
// // return nil, fmt.Errorf("error fetching request items: %v", err)
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // 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)
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // mappedRequestItems = append(mappedRequestItems, dto.ResponseRequestPickupItem{
|
||||||
|
// // ID: item.ID,
|
||||||
|
// // TrashCategory: []dto.ResponseTrashCategoryDTO{{
|
||||||
|
// // Name: trashCategory.Name,
|
||||||
|
// // Icon: trashCategory.Icon,
|
||||||
|
// // }},
|
||||||
|
// // EstimatedAmount: item.EstimatedAmount,
|
||||||
|
// // })
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // mappedRequest.RequestItems = mappedRequestItems
|
||||||
|
|
||||||
|
// // response = append(response, mappedRequest)
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // return response, nil
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // 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)
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // 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)
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // request.CollectorID = &collector.ID
|
||||||
|
|
||||||
|
// // err = s.repo.UpdateRequestPickup(request.ID, request)
|
||||||
|
// // if err != nil {
|
||||||
|
// // return fmt.Errorf("failed to update request pickup: %v", err)
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // return nil
|
||||||
|
// // }
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package model
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type PickupStatusHistory struct {
|
||||||
|
ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4()" json:"id"`
|
||||||
|
RequestID string `gorm:"not null" json:"request_id"`
|
||||||
|
Status string `gorm:"not null" json:"status"`
|
||||||
|
ChangedAt time.Time `gorm:"not null" json:"changed_at"`
|
||||||
|
ChangedByID string `gorm:"not null" json:"changed_by_id"`
|
||||||
|
ChangedByRole string `gorm:"not null" json:"changed_by_role"`
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package model
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type PickupRating struct {
|
||||||
|
ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4()" json:"id"`
|
||||||
|
RequestID string `gorm:"not null;unique" json:"request_id"`
|
||||||
|
UserID string `gorm:"not null" json:"user_id"`
|
||||||
|
CollectorID string `gorm:"not null" json:"collector_id"`
|
||||||
|
Rating float32 `gorm:"not null" json:"rating"`
|
||||||
|
Feedback string `json:"feedback,omitempty"`
|
||||||
|
CreatedAt time.Time `gorm:"default:current_timestamp" json:"created_at"`
|
||||||
|
}
|
|
@ -7,28 +7,30 @@ import (
|
||||||
type RequestPickup struct {
|
type RequestPickup struct {
|
||||||
ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4();unique;not null" json:"id"`
|
ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4();unique;not null" json:"id"`
|
||||||
UserId string `gorm:"not null" json:"user_id"`
|
UserId string `gorm:"not null" json:"user_id"`
|
||||||
User User `gorm:"foreignKey:UserId;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"user"`
|
User *User `gorm:"foreignKey:UserId" json:"user"`
|
||||||
AddressId string `gorm:"not null" json:"address_id"`
|
AddressId string `gorm:"not null" json:"address_id"`
|
||||||
Address Address `gorm:"foreignKey:AddressId;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"address"`
|
Address *Address `gorm:"foreignKey:AddressId" json:"address"`
|
||||||
RequestItems []RequestPickupItem `gorm:"foreignKey:RequestPickupId;constraint:OnDelete:CASCADE;" json:"request_items"`
|
RequestItems []RequestPickupItem `gorm:"foreignKey:RequestPickupId;constraint:OnDelete:CASCADE;" json:"request_items"`
|
||||||
EvidenceImage string `json:"evidence_image"`
|
|
||||||
Notes string `json:"notes"`
|
Notes string `json:"notes"`
|
||||||
StatusPickup string `gorm:"default:'waiting_collector'" json:"status_pickup"`
|
StatusPickup string `gorm:"default:'waiting_collector'" json:"status_pickup"`
|
||||||
CollectorID *string `gorm:"type:uuid" json:"collector_id,omitempty"`
|
CollectorID *string `gorm:"type:uuid" json:"collector_id,omitempty"`
|
||||||
Collector Collector `gorm:"foreignKey:CollectorID;constraint:OnDelete:CASCADE;" json:"collector"`
|
Collector *Collector `gorm:"foreignKey:CollectorID;references:ID" json:"collector,omitempty"`
|
||||||
ConfirmedByCollectorAt *time.Time `json:"confirmed_by_collector_at,omitempty"`
|
ConfirmedByCollectorAt *time.Time `json:"confirmed_by_collector_at,omitempty"`
|
||||||
RequestMethod string `gorm:"not null" json:"request_method"`
|
RequestMethod string `gorm:"not null" json:"request_method"` // manual / otomatis
|
||||||
CreatedAt time.Time `gorm:"default:current_timestamp" json:"created_at"`
|
FinalPrice float64 `json:"final_price"` // diisi setelah collector update berat
|
||||||
UpdatedAt time.Time `gorm:"default:current_timestamp" json:"updated_at"`
|
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"`
|
||||||
|
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RequestPickupItem struct {
|
type RequestPickupItem struct {
|
||||||
ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4();unique;not null" json:"id"`
|
ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4();unique;not null" json:"id"`
|
||||||
RequestPickupId string `gorm:"not null" json:"request_pickup_id"`
|
RequestPickupId string `gorm:"not null" json:"request_pickup_id"`
|
||||||
RequestPickup RequestPickup `gorm:"foreignKey:RequestPickupId;constraint:OnDelete:CASCADE;"`
|
RequestPickup *RequestPickup `gorm:"foreignKey:RequestPickupId" json:"-"`
|
||||||
TrashCategoryId string `gorm:"not null" json:"trash_category_id"`
|
TrashCategoryId string `gorm:"not null" json:"trash_category_id"`
|
||||||
TrashCategory TrashCategory `gorm:"foreignKey:TrashCategoryId;constraint:OnDelete:CASCADE;" json:"trash_category"`
|
TrashCategory *TrashCategory `gorm:"foreignKey:TrashCategoryId" json:"trash_category"`
|
||||||
EstimatedAmount float64 `gorm:"not null" json:"estimated_amount"`
|
EstimatedAmount float64 `gorm:"not null" json:"estimated_amount"`
|
||||||
|
EstimatedPricePerKg float64 `gorm:"not null" json:"estimated_price_per_kg"` // harga pada saat itu
|
||||||
|
EstimatedSubtotalPrice float64 `gorm:"not null" json:"estimated_subtotal_price"` // amount * price per kg
|
||||||
}
|
}
|
||||||
|
|
||||||
// request_method {
|
// request_method {
|
||||||
|
|
|
@ -30,8 +30,15 @@ func CollectorRouter(api fiber.Router) {
|
||||||
// Middleware Auth dan Role
|
// Middleware Auth dan Role
|
||||||
|
|
||||||
// Inisialisasi repository dan service
|
// Inisialisasi repository dan service
|
||||||
collectorRepo := repositories.NewCollectorRepository()
|
pickupRepo := repositories.NewRequestPickupRepository()
|
||||||
trashRepo := repositories.NewTrashRepository(config.DB)
|
trashRepo := repositories.NewTrashRepository(config.DB)
|
||||||
|
historyRepo := repositories.NewPickupStatusHistoryRepository()
|
||||||
|
cartService := services.NewCartService()
|
||||||
|
|
||||||
|
pickupService := services.NewRequestPickupService(trashRepo, pickupRepo, cartService, historyRepo)
|
||||||
|
pickupHandler := handler.NewRequestPickupHandler(pickupService)
|
||||||
|
collectorRepo := repositories.NewCollectorRepository()
|
||||||
|
// trashRepo := repositories.NewTrashRepository(config.DB)
|
||||||
collectorService := services.NewCollectorService(collectorRepo, trashRepo)
|
collectorService := services.NewCollectorService(collectorRepo, trashRepo)
|
||||||
collectorHandler := handler.NewCollectorHandler(collectorService)
|
collectorHandler := handler.NewCollectorHandler(collectorService)
|
||||||
|
|
||||||
|
@ -43,7 +50,9 @@ func CollectorRouter(api fiber.Router) {
|
||||||
collectors.Post("/", collectorHandler.CreateCollector) // Create collector
|
collectors.Post("/", collectorHandler.CreateCollector) // Create collector
|
||||||
collectors.Post("/:id/trash", collectorHandler.AddTrashToCollector) // Add trash to collector
|
collectors.Post("/:id/trash", collectorHandler.AddTrashToCollector) // Add trash to collector
|
||||||
collectors.Get("/:id", collectorHandler.GetCollectorByID) // Get collector by ID
|
collectors.Get("/:id", collectorHandler.GetCollectorByID) // Get collector by ID
|
||||||
collectors.Get("/", collectorHandler.GetCollectorByUserID) // Get collector by ID
|
collectors.Get("/", collectorHandler.GetCollectorByUserID)
|
||||||
|
collectors.Get("/pickup/assigned-to-me", pickupHandler.GetAssignedPickup)
|
||||||
|
// Get collector by ID
|
||||||
collectors.Patch("/:id", collectorHandler.UpdateCollector) // Update collector fields
|
collectors.Patch("/:id", collectorHandler.UpdateCollector) // Update collector fields
|
||||||
collectors.Patch("/:id/trash", collectorHandler.UpdateTrash)
|
collectors.Patch("/:id/trash", collectorHandler.UpdateTrash)
|
||||||
collectors.Patch("/:id/job-status", collectorHandler.UpdateJobStatus)
|
collectors.Patch("/:id/job-status", collectorHandler.UpdateJobStatus)
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package presentation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"rijig/internal/handler"
|
||||||
|
"rijig/internal/repositories"
|
||||||
|
"rijig/internal/services"
|
||||||
|
"rijig/middleware"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func PickupMatchingRouter(api fiber.Router) {
|
||||||
|
pickupRepo := repositories.NewRequestPickupRepository()
|
||||||
|
collectorRepo := repositories.NewCollectorRepository()
|
||||||
|
service := services.NewPickupMatchingService(pickupRepo, collectorRepo)
|
||||||
|
handler := handler.NewPickupMatchingHandler(service)
|
||||||
|
|
||||||
|
manual := api.Group("/pickup/manual")
|
||||||
|
manual.Use(middleware.AuthMiddleware)
|
||||||
|
manual.Get("/:pickupID/nearby-collectors", handler.GetNearbyCollectorsForPickup)
|
||||||
|
|
||||||
|
auto := api.Group("/pickup/otomatis")
|
||||||
|
auto.Use(middleware.AuthMiddleware)
|
||||||
|
auto.Get("/available-requests", handler.GetAvailablePickupForCollector)
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package presentation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"rijig/internal/handler"
|
||||||
|
"rijig/internal/repositories"
|
||||||
|
"rijig/internal/services"
|
||||||
|
"rijig/middleware"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func PickupRatingRouter(api fiber.Router) {
|
||||||
|
ratingRepo := repositories.NewPickupRatingRepository()
|
||||||
|
ratingService := services.NewPickupRatingService(ratingRepo)
|
||||||
|
ratingHandler := handler.NewPickupRatingHandler(ratingService)
|
||||||
|
|
||||||
|
rating := api.Group("/pickup")
|
||||||
|
rating.Use(middleware.AuthMiddleware)
|
||||||
|
rating.Post("/:id/rating", ratingHandler.CreateRating)
|
||||||
|
|
||||||
|
collector := api.Group("/collector")
|
||||||
|
collector.Get("/:id/ratings", ratingHandler.GetRatingsByCollector)
|
||||||
|
collector.Get("/:id/ratings/average", ratingHandler.GetAverageRating)
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package presentation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"rijig/config"
|
||||||
|
"rijig/internal/handler"
|
||||||
|
"rijig/internal/repositories"
|
||||||
|
"rijig/internal/services"
|
||||||
|
"rijig/middleware"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RequestPickupRouter(api fiber.Router) {
|
||||||
|
pickupRepo := repositories.NewRequestPickupRepository()
|
||||||
|
historyRepo := repositories.NewPickupStatusHistoryRepository()
|
||||||
|
trashRepo := repositories.NewTrashRepository(config.DB)
|
||||||
|
cartService := services.NewCartService()
|
||||||
|
historyService := services.NewPickupStatusHistoryService(historyRepo)
|
||||||
|
|
||||||
|
pickupService := services.NewRequestPickupService(trashRepo, pickupRepo, cartService, historyRepo)
|
||||||
|
pickupHandler := handler.NewRequestPickupHandler(pickupService)
|
||||||
|
statuspickupHandler := handler.NewPickupStatusHistoryHandler(historyService)
|
||||||
|
|
||||||
|
reqpickup := api.Group("/reqpickup")
|
||||||
|
reqpickup.Use(middleware.AuthMiddleware)
|
||||||
|
|
||||||
|
reqpickup.Post("/manual", pickupHandler.CreateRequestPickup)
|
||||||
|
reqpickup.Get("/pickup/:id/history", statuspickupHandler.GetStatusHistory)
|
||||||
|
reqpickup.Post("/otomatis", pickupHandler.CreateRequestPickup)
|
||||||
|
reqpickup.Put("/:id/select-collector", pickupHandler.SelectCollector)
|
||||||
|
reqpickup.Put("/pickup/:id/status", pickupHandler.UpdatePickupStatus)
|
||||||
|
reqpickup.Put("/pickup/:id/item/update-actual", pickupHandler.UpdatePickupItemActualAmount)
|
||||||
|
}
|
|
@ -26,7 +26,10 @@ func SetupRoutes(app *fiber.App) {
|
||||||
// || auth router || //
|
// || auth router || //
|
||||||
presentation.IdentityCardRouter(api)
|
presentation.IdentityCardRouter(api)
|
||||||
presentation.CompanyProfileRouter(api)
|
presentation.CompanyProfileRouter(api)
|
||||||
// presentation.RequestPickupRouter(api)
|
presentation.RequestPickupRouter(api)
|
||||||
|
presentation.PickupMatchingRouter(api)
|
||||||
|
presentation.PickupRatingRouter(api)
|
||||||
|
|
||||||
presentation.CollectorRouter(api)
|
presentation.CollectorRouter(api)
|
||||||
presentation.TrashCartRouter(api)
|
presentation.TrashCartRouter(api)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue