feat&fix: fixing debug and add confirmed feature for request pickup
This commit is contained in:
parent
47ccae326a
commit
61dda3f4eb
|
@ -42,6 +42,7 @@ func ConnectDatabase() {
|
||||||
// ==============main feature==============
|
// ==============main feature==============
|
||||||
// =>user preparation<=
|
// =>user preparation<=
|
||||||
&model.User{},
|
&model.User{},
|
||||||
|
&model.Collector{},
|
||||||
&model.Role{},
|
&model.Role{},
|
||||||
&model.UserPin{},
|
&model.UserPin{},
|
||||||
&model.Address{},
|
&model.Address{},
|
||||||
|
|
|
@ -11,8 +11,8 @@ type AddressResponseDTO struct {
|
||||||
Village string `json:"village"`
|
Village string `json:"village"`
|
||||||
PostalCode string `json:"postalCode"`
|
PostalCode string `json:"postalCode"`
|
||||||
Detail string `json:"detail"`
|
Detail string `json:"detail"`
|
||||||
Latitude string `json:"latitude"`
|
Latitude float64 `json:"latitude"`
|
||||||
Longitude string `json:"longitude"`
|
Longitude float64 `json:"longitude"`
|
||||||
CreatedAt string `json:"createdAt"`
|
CreatedAt string `json:"createdAt"`
|
||||||
UpdatedAt string `json:"updatedAt"`
|
UpdatedAt string `json:"updatedAt"`
|
||||||
}
|
}
|
||||||
|
@ -24,8 +24,8 @@ type CreateAddressDTO struct {
|
||||||
Village string `json:"village_id"`
|
Village string `json:"village_id"`
|
||||||
PostalCode string `json:"postalCode"`
|
PostalCode string `json:"postalCode"`
|
||||||
Detail string `json:"detail"`
|
Detail string `json:"detail"`
|
||||||
Latitude string `json:"latitude"`
|
Latitude float64 `json:"latitude"`
|
||||||
Longitude string `json:"longitude"`
|
Longitude float64 `json:"longitude"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *CreateAddressDTO) ValidateAddress() (map[string][]string, bool) {
|
func (r *CreateAddressDTO) ValidateAddress() (map[string][]string, bool) {
|
||||||
|
@ -34,28 +34,35 @@ func (r *CreateAddressDTO) ValidateAddress() (map[string][]string, bool) {
|
||||||
if strings.TrimSpace(r.Province) == "" {
|
if strings.TrimSpace(r.Province) == "" {
|
||||||
errors["province_id"] = append(errors["province_id"], "Province ID is required")
|
errors["province_id"] = append(errors["province_id"], "Province ID is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.TrimSpace(r.Regency) == "" {
|
if strings.TrimSpace(r.Regency) == "" {
|
||||||
errors["regency_id"] = append(errors["regency_id"], "Regency ID is required")
|
errors["regency_id"] = append(errors["regency_id"], "Regency ID is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.TrimSpace(r.District) == "" {
|
if strings.TrimSpace(r.District) == "" {
|
||||||
errors["district_id"] = append(errors["district_id"], "District ID is required")
|
errors["district_id"] = append(errors["district_id"], "District ID is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.TrimSpace(r.Village) == "" {
|
if strings.TrimSpace(r.Village) == "" {
|
||||||
errors["village_id"] = append(errors["village_id"], "Village ID is required")
|
errors["village_id"] = append(errors["village_id"], "Village ID is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.TrimSpace(r.PostalCode) == "" {
|
if strings.TrimSpace(r.PostalCode) == "" {
|
||||||
errors["postalCode"] = append(errors["village_id"], "PostalCode ID is required")
|
errors["postalCode"] = append(errors["postalCode"], "PostalCode is required")
|
||||||
} else if len(r.PostalCode) < 5 {
|
} else if len(r.PostalCode) < 5 {
|
||||||
errors["postalCode"] = append(errors["postalCode"], "kode pos belum sesuai")
|
errors["postalCode"] = append(errors["postalCode"], "PostalCode must be at least 5 characters")
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.TrimSpace(r.Detail) == "" {
|
if strings.TrimSpace(r.Detail) == "" {
|
||||||
errors["detail"] = append(errors["detail"], "Detail address is required")
|
errors["detail"] = append(errors["detail"], "Detail address is required")
|
||||||
}
|
}
|
||||||
if strings.TrimSpace(r.Latitude) == "" {
|
|
||||||
errors["latitude"] = append(errors["latitude"], "Geographic coordinates are required")
|
if r.Latitude == 0 {
|
||||||
|
errors["latitude"] = append(errors["latitude"], "Latitude is required")
|
||||||
}
|
}
|
||||||
if strings.TrimSpace(r.Longitude) == "" {
|
|
||||||
errors["longitude"] = append(errors["longitude"], "Geographic coordinates are required")
|
if r.Longitude == 0 {
|
||||||
|
errors["longitude"] = append(errors["longitude"], "Longitude is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(errors) > 0 {
|
if len(errors) > 0 {
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
package dto
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
type RequestCollectorDTO struct {
|
||||||
|
UserId string `json:"user_id"`
|
||||||
|
AddressId string `json:"address_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResponseCollectorDTO struct {
|
||||||
|
ID string `json:"collector_id"`
|
||||||
|
UserId string `json:"user_id"`
|
||||||
|
AddressId string `json:"address_id"`
|
||||||
|
JobStatus string `json:"job_status"`
|
||||||
|
Rating float32 `json:"rating"`
|
||||||
|
// CreatedAt string `json:"createdAt"`
|
||||||
|
// UpdatedAt string `json:"updatedAt"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RequestCollectorDTO) ValidateRequestColector() (map[string][]string, bool) {
|
||||||
|
errors := make(map[string][]string)
|
||||||
|
|
||||||
|
if strings.TrimSpace(r.AddressId) == "" {
|
||||||
|
errors["address_id"] = append(errors["address_id"], "address_id harus diisi")
|
||||||
|
}
|
||||||
|
if len(errors) > 0 {
|
||||||
|
return errors, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, true
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ type RequestPickup struct {
|
||||||
RequestItems []RequestPickupItem `json:"request_items"`
|
RequestItems []RequestPickupItem `json:"request_items"`
|
||||||
EvidenceImage string `json:"evidence_image"`
|
EvidenceImage string `json:"evidence_image"`
|
||||||
AddressID string `json:"address_id"`
|
AddressID string `json:"address_id"`
|
||||||
|
RequestMethod string `json:"request_method"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RequestPickupItem struct {
|
type RequestPickupItem struct {
|
||||||
|
@ -17,14 +18,16 @@ type RequestPickupItem struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResponseRequestPickup struct {
|
type ResponseRequestPickup struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id,omitempty"`
|
||||||
UserId string `json:"user_id"`
|
UserId string `json:"user_id,omitempty"`
|
||||||
AddressID string `json:"address_id"`
|
AddressID string `json:"address_id,omitempty"`
|
||||||
EvidenceImage string `json:"evidence_image"`
|
EvidenceImage string `json:"evidence_image,omitempty"`
|
||||||
StatusPickup string `json:"status_pickup"`
|
StatusPickup string `json:"status_pickup,omitempty"`
|
||||||
CreatedAt string `json:"created_at"`
|
CollectorID string `json:"collectorid,omitempty"`
|
||||||
UpdatedAt string `json:"updated_at"`
|
ConfirmedByCollectorAt string `json:"confirmedat,omitempty"`
|
||||||
RequestItems []ResponseRequestPickupItem `json:"request_items"`
|
CreatedAt string `json:"created_at,omitempty"`
|
||||||
|
UpdatedAt string `json:"updated_at,omitempty"`
|
||||||
|
RequestItems []ResponseRequestPickupItem `json:"request_items,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResponseRequestPickupItem struct {
|
type ResponseRequestPickupItem struct {
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -14,7 +14,6 @@ require (
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/umahmood/haversine v0.0.0-20151105152445-808ab04add26 // indirect
|
|
||||||
golang.org/x/term v0.30.0 // indirect
|
golang.org/x/term v0.30.0 // indirect
|
||||||
rsc.io/qr v0.2.0 // indirect
|
rsc.io/qr v0.2.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -72,8 +72,6 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/umahmood/haversine v0.0.0-20151105152445-808ab04add26 h1:UFHFmFfixpmfRBcxuu+LA9l8MdURWVdVNUHxO5n1d2w=
|
|
||||||
github.com/umahmood/haversine v0.0.0-20151105152445-808ab04add26/go.mod h1:IGhd0qMDsUa9acVjsbsT7bu3ktadtGOHI79+idTew/M=
|
|
||||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||||
github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA=
|
github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA=
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"rijig/internal/services"
|
||||||
|
"rijig/utils"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CollectorHandler struct {
|
||||||
|
service services.CollectorService
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCollectorHandler(service services.CollectorService) *CollectorHandler {
|
||||||
|
return &CollectorHandler{service}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *CollectorHandler) ConfirmRequestPickup(c *fiber.Ctx) error {
|
||||||
|
|
||||||
|
collectorId, ok := c.Locals("userID").(string)
|
||||||
|
if !ok || collectorId == "" {
|
||||||
|
return utils.GenericResponse(c, fiber.StatusUnauthorized, "Unauthorized: User session not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
requestPickupId := c.Params("id")
|
||||||
|
if requestPickupId == "" {
|
||||||
|
return utils.ErrorResponse(c, "RequestPickup ID is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := h.service.ConfirmRequestPickup(requestPickupId, collectorId)
|
||||||
|
if err != nil {
|
||||||
|
return utils.ErrorResponse(c, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return utils.SuccessResponse(c, req, "Request pickup confirmed successfully")
|
||||||
|
}
|
|
@ -53,49 +53,32 @@ func (h *RequestPickupHandler) GetRequestPickupByID(c *fiber.Ctx) error {
|
||||||
return utils.SuccessResponse(c, response, "Request pickup retrieved successfully")
|
return utils.SuccessResponse(c, response, "Request pickup retrieved successfully")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *RequestPickupHandler) GetAllRequestPickups(c *fiber.Ctx) error {
|
// func (h *RequestPickupHandler) GetAutomaticRequestByUser(c *fiber.Ctx) error {
|
||||||
|
|
||||||
response, err := h.service.GetAllRequestPickups()
|
// collectorId, ok := c.Locals("userID").(string)
|
||||||
|
// if !ok || collectorId == "" {
|
||||||
|
// return utils.ErrorResponse(c, "Unauthorized: User session not found")
|
||||||
|
// }
|
||||||
|
|
||||||
|
// requestPickups, err := h.service.GetAllAutomaticRequestPickup(collectorId)
|
||||||
|
// if err != nil {
|
||||||
|
|
||||||
|
// return utils.ErrorResponse(c, err.Error())
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return utils.SuccessResponse(c, requestPickups, "Request pickups fetched successfully")
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (h *RequestPickupHandler) GetRequestPickups(c *fiber.Ctx) error {
|
||||||
|
// Get userID from Locals
|
||||||
|
collectorId := c.Locals("userID").(string)
|
||||||
|
|
||||||
|
// Call service layer to get the request pickups
|
||||||
|
requests, err := h.service.GetRequestPickupsForCollector(collectorId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return utils.InternalServerErrorResponse(c, fmt.Sprintf("Error fetching all request pickups: %v", err))
|
return utils.ErrorResponse(c, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.SuccessResponse(c, response, "All request pickups retrieved successfully")
|
// Return response
|
||||||
}
|
return utils.SuccessResponse(c, requests, "Automatic request pickups retrieved successfully")
|
||||||
|
|
||||||
func (h *RequestPickupHandler) UpdateRequestPickup(c *fiber.Ctx) error {
|
|
||||||
userID, ok := c.Locals("userID").(string)
|
|
||||||
if !ok || userID == "" {
|
|
||||||
return utils.GenericResponse(c, fiber.StatusUnauthorized, "Unauthorized: User session not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
id := c.Params("id")
|
|
||||||
var request dto.RequestPickup
|
|
||||||
|
|
||||||
if err := c.BodyParser(&request); err != nil {
|
|
||||||
return utils.GenericResponse(c, fiber.StatusBadRequest, "Invalid request body")
|
|
||||||
}
|
|
||||||
|
|
||||||
errors, valid := request.ValidateRequestPickup()
|
|
||||||
if !valid {
|
|
||||||
return utils.ValidationErrorResponse(c, errors)
|
|
||||||
}
|
|
||||||
|
|
||||||
response, err := h.service.UpdateRequestPickup(id, request)
|
|
||||||
if err != nil {
|
|
||||||
return utils.InternalServerErrorResponse(c, fmt.Sprintf("Error updating request pickup: %v", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
return utils.SuccessResponse(c, response, "Request pickup updated successfully")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *RequestPickupHandler) DeleteRequestPickup(c *fiber.Ctx) error {
|
|
||||||
id := c.Params("id")
|
|
||||||
|
|
||||||
err := h.service.DeleteRequestPickup(id)
|
|
||||||
if err != nil {
|
|
||||||
return utils.GenericResponse(c, fiber.StatusNotFound, fmt.Sprintf("Request pickup with ID %s not found: %v", id, err))
|
|
||||||
}
|
|
||||||
|
|
||||||
return utils.GenericResponse(c, fiber.StatusOK, "Request pickup deleted successfully")
|
|
||||||
}
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
package repositories
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"rijig/model"
|
||||||
|
"rijig/utils"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CollectorRepository interface {
|
||||||
|
FindActiveCollectors() ([]model.Collector, error)
|
||||||
|
FindCollectorById(collector_id string) (*model.Collector, error)
|
||||||
|
CreateCollector(collector *model.Collector) error
|
||||||
|
UpdateCollector(userId string, jobStatus string) (*model.Collector, error)
|
||||||
|
FindAllAutomaticMethodRequestWithDistance(requestMethod, statuspickup string, collectorLat, collectorLon float64, maxDistance float64) ([]model.RequestPickup, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type collectorRepository struct {
|
||||||
|
DB *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCollectorRepository(db *gorm.DB) CollectorRepository {
|
||||||
|
return &collectorRepository{DB: db}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *collectorRepository) FindActiveCollectors() ([]model.Collector, error) {
|
||||||
|
var collectors []model.Collector
|
||||||
|
|
||||||
|
err := r.DB.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.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
|
||||||
|
}
|
||||||
|
|
||||||
|
// #====experimen====#
|
||||||
|
func (r *collectorRepository) FindAllAutomaticMethodRequestWithDistance(requestMethod, statuspickup string, collectorLat, collectorLon float64, maxDistance float64) ([]model.RequestPickup, error) {
|
||||||
|
var requests []model.RequestPickup
|
||||||
|
|
||||||
|
err := r.DB.Preload("RequestItems").
|
||||||
|
Where("request_method = ? AND status_pickup = ?", requestMethod, statuspickup).
|
||||||
|
Find(&requests).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error fetching request pickups with request_method '%s' and status '%s': %v", requestMethod, statuspickup, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var nearbyRequests []model.RequestPickup
|
||||||
|
for _, request := range requests {
|
||||||
|
address := request.Address
|
||||||
|
|
||||||
|
requestCoord := utils.Coord{Lat: address.Latitude, Lon: address.Longitude}
|
||||||
|
collectorCoord := utils.Coord{Lat: collectorLat, Lon: collectorLon}
|
||||||
|
_, km := utils.Distance(requestCoord, collectorCoord)
|
||||||
|
|
||||||
|
if km <= maxDistance {
|
||||||
|
nearbyRequests = append(nearbyRequests, request)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nearbyRequests, nil
|
||||||
|
}
|
|
@ -11,11 +11,13 @@ 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() ([]model.RequestPickup, error)
|
FindAllRequestPickups(userId string) ([]model.RequestPickup, error)
|
||||||
|
FindAllAutomaticMethodRequest(requestMethod, statuspickup string) ([]model.RequestPickup, error)
|
||||||
|
FindRequestPickupByAddressAndStatus(userId, status string) (*model.RequestPickup, error)
|
||||||
|
GetRequestPickupItems(requestPickupId string) ([]model.RequestPickupItem, error)
|
||||||
|
GetAutomaticRequestPickupsForCollector(collectorId string) ([]model.RequestPickup, error)
|
||||||
UpdateRequestPickup(id string, request *model.RequestPickup) error
|
UpdateRequestPickup(id string, request *model.RequestPickup) error
|
||||||
DeleteRequestPickup(id string) error
|
DeleteRequestPickup(id string) error
|
||||||
FindRequestPickupByAddressAndCategory(addressID string, trashCategoryID string) (*model.RequestPickup, error)
|
|
||||||
FindRequestPickupByAddressAndStatus(userId, status string) (*model.RequestPickup, error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type requestPickupRepository struct {
|
type requestPickupRepository struct {
|
||||||
|
@ -57,20 +59,43 @@ func (r *requestPickupRepository) FindRequestPickupByID(id string) (*model.Reque
|
||||||
return &request, nil
|
return &request, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *requestPickupRepository) FindAllRequestPickups() ([]model.RequestPickup, error) {
|
func (r *requestPickupRepository) FindAllRequestPickups(userId string) ([]model.RequestPickup, error) {
|
||||||
var requests []model.RequestPickup
|
var requests []model.RequestPickup
|
||||||
err := r.DB.Preload("RequestItems").Find(&requests).Error
|
err := r.DB.Preload("RequestItems").Where("user_id = ?", userId).Find(&requests).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to fetch all request pickups: %v", err)
|
return nil, fmt.Errorf("failed to fetch all request pickups: %v", err)
|
||||||
}
|
}
|
||||||
return requests, nil
|
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 string) (*model.RequestPickup, error) {
|
||||||
|
var request model.RequestPickup
|
||||||
|
err := r.DB.Where("user_id = ? AND status_pickup = ?", userId, status).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 {
|
func (r *requestPickupRepository) UpdateRequestPickup(id string, request *model.RequestPickup) error {
|
||||||
err := r.DB.Model(&model.RequestPickup{}).Where("id = ?", id).Updates(request).Error
|
err := r.DB.Model(&model.RequestPickup{}).Where("id = ?", id).Updates(request).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to update request pickup: %v", err)
|
return fmt.Errorf("failed to update request pickup: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,28 +112,25 @@ func (r *requestPickupRepository) DeleteRequestPickup(id string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *requestPickupRepository) FindRequestPickupByAddressAndCategory(addressID string, trashCategoryID string) (*model.RequestPickup, error) {
|
func (r *requestPickupRepository) GetAutomaticRequestPickupsForCollector(collectorId string) ([]model.RequestPickup, error) {
|
||||||
var request model.RequestPickup
|
var requests []model.RequestPickup
|
||||||
err := r.DB.Joins("JOIN request_pickup_items ON request_pickups.id = request_pickup_items.request_pickup_id").
|
|
||||||
Where("request_pickups.address_id = ? AND request_pickup_items.trash_category_id = ?", addressID, trashCategoryID).
|
err := r.DB.Preload("Address").
|
||||||
First(&request).Error
|
Where("request_method = ? AND status_pickup = ?", "otomatis", "waiting_collector").
|
||||||
|
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 nil, fmt.Errorf("error checking request pickup for address %s and category %s: %v", addressID, trashCategoryID, err)
|
|
||||||
}
|
|
||||||
return &request, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *requestPickupRepository) FindRequestPickupByAddressAndStatus(userId, status string) (*model.RequestPickup, error) {
|
return requests, nil
|
||||||
var request model.RequestPickup
|
}
|
||||||
err := r.DB.Where("user_id = ? AND status_pickup = ?", userId, status).First(&request).Error
|
|
||||||
|
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 {
|
if err != nil {
|
||||||
if err == gorm.ErrRecordNotFound {
|
return nil, fmt.Errorf("error fetching request pickup items: %v", err)
|
||||||
return nil, nil
|
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("failed to check existing request pickup: %v", err)
|
return items, nil
|
||||||
}
|
|
||||||
return &request, nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,8 +155,8 @@ func (s *addressService) GetAddressByUserID(userID string) ([]dto.AddressRespons
|
||||||
Village: addressData["village"].(string),
|
Village: addressData["village"].(string),
|
||||||
PostalCode: addressData["postalCode"].(string),
|
PostalCode: addressData["postalCode"].(string),
|
||||||
Detail: addressData["detail"].(string),
|
Detail: addressData["detail"].(string),
|
||||||
Latitude: addressData["latitude"].(string),
|
Latitude: addressData["latitude"].(float64),
|
||||||
Longitude: addressData["longitude"].(string),
|
Longitude: addressData["longitude"].(float64),
|
||||||
CreatedAt: addressData["createdAt"].(string),
|
CreatedAt: addressData["createdAt"].(string),
|
||||||
UpdatedAt: addressData["updatedAt"].(string),
|
UpdatedAt: addressData["updatedAt"].(string),
|
||||||
})
|
})
|
||||||
|
@ -227,8 +227,8 @@ func (s *addressService) GetAddressByID(userID, id string) (*dto.AddressResponse
|
||||||
Village: addressData["village"].(string),
|
Village: addressData["village"].(string),
|
||||||
PostalCode: addressData["postalCode"].(string),
|
PostalCode: addressData["postalCode"].(string),
|
||||||
Detail: addressData["detail"].(string),
|
Detail: addressData["detail"].(string),
|
||||||
Latitude: addressData["latitude"].(string),
|
Latitude: addressData["latitude"].(float64),
|
||||||
Longitude: addressData["longitude"].(string),
|
Longitude: addressData["longitude"].(float64),
|
||||||
CreatedAt: addressData["createdAt"].(string),
|
CreatedAt: addressData["createdAt"].(string),
|
||||||
UpdatedAt: addressData["updatedAt"].(string),
|
UpdatedAt: addressData["updatedAt"].(string),
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,9 +67,10 @@ func (s *authPengepulService) checkOTPRequestCooldown(phone string) error {
|
||||||
|
|
||||||
func (s *authPengepulService) sendOTP(phone string) error {
|
func (s *authPengepulService) sendOTP(phone string) error {
|
||||||
otp := generateOTP()
|
otp := generateOTP()
|
||||||
if err := config.SendWhatsAppMessage(phone, fmt.Sprintf("Your OTP is: %s", otp)); err != nil {
|
fmt.Printf("ur otp is:%s", otp)
|
||||||
return err
|
// if err := config.SendWhatsAppMessage(phone, fmt.Sprintf("Your OTP is: %s", otp)); err != nil {
|
||||||
}
|
// return err
|
||||||
|
// }
|
||||||
|
|
||||||
if err := utils.SetStringData("otp:"+phone, otp, 10*time.Minute); err != nil {
|
if err := utils.SetStringData("otp:"+phone, otp, 10*time.Minute); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"rijig/dto"
|
||||||
|
"rijig/internal/repositories"
|
||||||
|
"rijig/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CollectorService interface {
|
||||||
|
FindCollectorsNearby(userId string) ([]dto.ResponseCollectorDTO, error)
|
||||||
|
ConfirmRequestPickup(requestId, collectorId string) (*dto.ResponseRequestPickup, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type collectorService struct {
|
||||||
|
repo repositories.CollectorRepository
|
||||||
|
repoReq repositories.RequestPickupRepository
|
||||||
|
repoAddress repositories.AddressRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCollectorService(repo repositories.CollectorRepository,
|
||||||
|
repoReq repositories.RequestPickupRepository,
|
||||||
|
repoAddress repositories.AddressRepository) CollectorService {
|
||||||
|
return &collectorService{repo: repo, repoReq: repoReq, repoAddress: repoAddress}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *collectorService) FindCollectorsNearby(userId string) ([]dto.ResponseCollectorDTO, error) {
|
||||||
|
collectors, err := s.repo.FindActiveCollectors()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error fetching active collectors: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
request, err := s.repoReq.FindRequestPickupByAddressAndStatus(userId, "waiting_collector")
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("gagal mendapatkan data request pickup dengan userid: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
reqpickaddress, err := s.repoAddress.FindAddressByID(request.AddressId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error fetching address for request pickup %s: %v", request.ID, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var nearbyCollectorsResponse []dto.ResponseCollectorDTO
|
||||||
|
var maxDistance = 10.0
|
||||||
|
|
||||||
|
for _, collector := range collectors {
|
||||||
|
|
||||||
|
address, err := s.repoAddress.FindAddressByID(collector.AddressId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error fetching address for collector %s: %v", collector.ID, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
collectorCoord := utils.Coord{Lat: reqpickaddress.Latitude, Lon: reqpickaddress.Longitude}
|
||||||
|
userCoord := utils.Coord{Lat: address.Latitude, Lon: address.Longitude}
|
||||||
|
|
||||||
|
_, km := utils.Distance(collectorCoord, userCoord)
|
||||||
|
|
||||||
|
if km <= maxDistance {
|
||||||
|
|
||||||
|
nearbyCollectorsResponse = append(nearbyCollectorsResponse, dto.ResponseCollectorDTO{
|
||||||
|
ID: collector.ID,
|
||||||
|
AddressId: collector.User.Name,
|
||||||
|
Rating: collector.Rating,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(nearbyCollectorsResponse) == 0 {
|
||||||
|
return nil, fmt.Errorf("no request pickups found within %v km", maxDistance)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nearbyCollectorsResponse, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *collectorService) ConfirmRequestPickup(requestId, collectorId string) (*dto.ResponseRequestPickup, error) {
|
||||||
|
|
||||||
|
request, err := s.repoReq.FindRequestPickupByID(requestId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("request pickup not found: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if request.StatusPickup != "waiting_collector" {
|
||||||
|
return nil, fmt.Errorf("pickup request is not in 'waiting_collector' status")
|
||||||
|
}
|
||||||
|
|
||||||
|
collector, err := s.repo.FindCollectorById(collectorId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("collector tidak ditemukan: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
request.StatusPickup = "confirmed"
|
||||||
|
request.CollectorID = &collector.ID
|
||||||
|
|
||||||
|
err = s.repoReq.UpdateRequestPickup(requestId, request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to update request pickup: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
confirmedAt, _ := utils.FormatDateToIndonesianFormat(request.ConfirmedByCollectorAt)
|
||||||
|
|
||||||
|
response := dto.ResponseRequestPickup{
|
||||||
|
StatusPickup: request.StatusPickup,
|
||||||
|
CollectorID: *request.CollectorID,
|
||||||
|
ConfirmedByCollectorAt: confirmedAt,
|
||||||
|
}
|
||||||
|
|
||||||
|
return &response, nil
|
||||||
|
}
|
|
@ -5,18 +5,22 @@ import (
|
||||||
"rijig/dto"
|
"rijig/dto"
|
||||||
"rijig/internal/repositories"
|
"rijig/internal/repositories"
|
||||||
"rijig/model"
|
"rijig/model"
|
||||||
|
"rijig/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RequestPickupService interface {
|
type RequestPickupService interface {
|
||||||
CreateRequestPickup(request dto.RequestPickup, UserId string) (*dto.ResponseRequestPickup, error)
|
CreateRequestPickup(request dto.RequestPickup, UserId string) (*dto.ResponseRequestPickup, error)
|
||||||
GetRequestPickupByID(id string) (*dto.ResponseRequestPickup, error)
|
GetRequestPickupByID(id string) (*dto.ResponseRequestPickup, error)
|
||||||
GetAllRequestPickups() ([]dto.ResponseRequestPickup, error)
|
GetAllRequestPickups(userid string) ([]dto.ResponseRequestPickup, error)
|
||||||
UpdateRequestPickup(id string, request dto.RequestPickup) (*dto.ResponseRequestPickup, error)
|
// GetAllAutomaticRequestPickups(collector_id string) ([]dto.ResponseRequestPickup, error)
|
||||||
DeleteRequestPickup(id string) error
|
// GetAllAutomaticRequestPickup(collectorId string) ([]dto.ResponseRequestPickup, error)
|
||||||
|
|
||||||
|
GetRequestPickupsForCollector(collectorId string) ([]dto.ResponseRequestPickup, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type requestPickupService struct {
|
type requestPickupService struct {
|
||||||
repo repositories.RequestPickupRepository
|
repo repositories.RequestPickupRepository
|
||||||
|
repoReq repositories.CollectorRepository
|
||||||
repoAddress repositories.AddressRepository
|
repoAddress repositories.AddressRepository
|
||||||
repoTrash repositories.TrashRepository
|
repoTrash repositories.TrashRepository
|
||||||
}
|
}
|
||||||
|
@ -34,12 +38,12 @@ func (s *requestPickupService) CreateRequestPickup(request dto.RequestPickup, Us
|
||||||
return nil, fmt.Errorf("validation errors: %v", errors)
|
return nil, fmt.Errorf("validation errors: %v", errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
findAddress, err := s.repoAddress.FindAddressByID(request.AddressID)
|
_, err := s.repoAddress.FindAddressByID(request.AddressID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("address with ID %s not found", request.AddressID)
|
return nil, fmt.Errorf("address with ID %s not found", request.AddressID)
|
||||||
}
|
}
|
||||||
|
|
||||||
existingRequest, err := s.repo.FindRequestPickupByAddressAndStatus(UserId, "waiting_pengepul")
|
existingRequest, err := s.repo.FindRequestPickupByAddressAndStatus(UserId, "waiting_collector")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error checking for existing request pickup: %v", err)
|
return nil, fmt.Errorf("error checking for existing request pickup: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -49,8 +53,9 @@ func (s *requestPickupService) CreateRequestPickup(request dto.RequestPickup, Us
|
||||||
|
|
||||||
modelRequest := model.RequestPickup{
|
modelRequest := model.RequestPickup{
|
||||||
UserId: UserId,
|
UserId: UserId,
|
||||||
AddressId: findAddress.ID,
|
AddressId: request.AddressID,
|
||||||
EvidenceImage: request.EvidenceImage,
|
EvidenceImage: request.EvidenceImage,
|
||||||
|
RequestMethod: request.RequestMethod,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.repo.CreateRequestPickup(&modelRequest)
|
err = s.repo.CreateRequestPickup(&modelRequest)
|
||||||
|
@ -58,14 +63,17 @@ func (s *requestPickupService) CreateRequestPickup(request dto.RequestPickup, Us
|
||||||
return nil, fmt.Errorf("failed to create request pickup: %v", err)
|
return nil, fmt.Errorf("failed to create request pickup: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createdAt, _ := utils.FormatDateToIndonesianFormat(modelRequest.CreatedAt)
|
||||||
|
updatedAt, _ := utils.FormatDateToIndonesianFormat(modelRequest.UpdatedAt)
|
||||||
|
|
||||||
response := &dto.ResponseRequestPickup{
|
response := &dto.ResponseRequestPickup{
|
||||||
ID: modelRequest.ID,
|
ID: modelRequest.ID,
|
||||||
UserId: UserId,
|
UserId: UserId,
|
||||||
AddressID: modelRequest.AddressId,
|
AddressID: modelRequest.AddressId,
|
||||||
EvidenceImage: modelRequest.EvidenceImage,
|
EvidenceImage: modelRequest.EvidenceImage,
|
||||||
StatusPickup: modelRequest.StatusPickup,
|
StatusPickup: modelRequest.StatusPickup,
|
||||||
CreatedAt: modelRequest.CreatedAt.Format("2006-01-02 15:04:05"),
|
CreatedAt: createdAt,
|
||||||
UpdatedAt: modelRequest.UpdatedAt.Format("2006-01-02 15:04:05"),
|
UpdatedAt: updatedAt,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, item := range request.RequestItems {
|
for _, item := range request.RequestItems {
|
||||||
|
@ -102,80 +110,94 @@ func (s *requestPickupService) GetRequestPickupByID(id string) (*dto.ResponseReq
|
||||||
return nil, fmt.Errorf("error fetching request pickup with ID %s: %v", id, err)
|
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{
|
response := &dto.ResponseRequestPickup{
|
||||||
ID: request.ID,
|
ID: request.ID,
|
||||||
UserId: request.UserId,
|
UserId: request.UserId,
|
||||||
AddressID: request.AddressId,
|
AddressID: request.AddressId,
|
||||||
EvidenceImage: request.EvidenceImage,
|
EvidenceImage: request.EvidenceImage,
|
||||||
StatusPickup: request.StatusPickup,
|
StatusPickup: request.StatusPickup,
|
||||||
CreatedAt: request.CreatedAt.Format("2006-01-02 15:04:05"),
|
CreatedAt: createdAt,
|
||||||
UpdatedAt: request.UpdatedAt.Format("2006-01-02 15:04:05"),
|
UpdatedAt: updatedAt,
|
||||||
}
|
}
|
||||||
|
|
||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *requestPickupService) GetAllRequestPickups() ([]dto.ResponseRequestPickup, error) {
|
func (s *requestPickupService) GetAllRequestPickups(userid string) ([]dto.ResponseRequestPickup, error) {
|
||||||
|
|
||||||
requests, err := s.repo.FindAllRequestPickups()
|
requests, err := s.repo.FindAllRequestPickups(userid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error fetching all request pickups: %v", err)
|
return nil, fmt.Errorf("error fetching all request pickups: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var response []dto.ResponseRequestPickup
|
var response []dto.ResponseRequestPickup
|
||||||
for _, request := range requests {
|
for _, request := range requests {
|
||||||
|
createdAt, _ := utils.FormatDateToIndonesianFormat(request.CreatedAt)
|
||||||
|
updatedAt, _ := utils.FormatDateToIndonesianFormat(request.UpdatedAt)
|
||||||
response = append(response, dto.ResponseRequestPickup{
|
response = append(response, dto.ResponseRequestPickup{
|
||||||
ID: request.ID,
|
ID: request.ID,
|
||||||
UserId: request.UserId,
|
UserId: request.UserId,
|
||||||
AddressID: request.AddressId,
|
AddressID: request.AddressId,
|
||||||
EvidenceImage: request.EvidenceImage,
|
EvidenceImage: request.EvidenceImage,
|
||||||
StatusPickup: request.StatusPickup,
|
StatusPickup: request.StatusPickup,
|
||||||
CreatedAt: request.CreatedAt.Format("2006-01-02 15:04:05"),
|
CreatedAt: createdAt,
|
||||||
UpdatedAt: request.UpdatedAt.Format("2006-01-02 15:04:05"),
|
UpdatedAt: updatedAt,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *requestPickupService) UpdateRequestPickup(id string, request dto.RequestPickup) (*dto.ResponseRequestPickup, error) {
|
func (s *requestPickupService) GetRequestPickupsForCollector(collectorId string) ([]dto.ResponseRequestPickup, error) {
|
||||||
|
|
||||||
errors, valid := request.ValidateRequestPickup()
|
requests, err := s.repo.GetAutomaticRequestPickupsForCollector(collectorId)
|
||||||
if !valid {
|
|
||||||
return nil, fmt.Errorf("validation errors: %v", errors)
|
|
||||||
}
|
|
||||||
|
|
||||||
existingRequest, err := s.repo.FindRequestPickupByID(id)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("request pickup with ID %s not found: %v", id, err)
|
return nil, fmt.Errorf("error retrieving automatic pickup requests: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
existingRequest.EvidenceImage = request.EvidenceImage
|
var response []dto.ResponseRequestPickup
|
||||||
|
|
||||||
err = s.repo.UpdateRequestPickup(id, existingRequest)
|
for _, req := range requests {
|
||||||
|
|
||||||
|
_, distance := utils.Distance(
|
||||||
|
utils.Coord{Lat: req.Address.Latitude, Lon: req.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"),
|
||||||
|
}
|
||||||
|
|
||||||
|
requestItems, err := s.repo.GetRequestPickupItems(req.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to update request pickup: %v", err)
|
return nil, fmt.Errorf("error fetching request items: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
response := &dto.ResponseRequestPickup{
|
var mappedRequestItems []dto.ResponseRequestPickupItem
|
||||||
ID: existingRequest.ID,
|
for _, item := range requestItems {
|
||||||
UserId: existingRequest.UserId,
|
mappedRequestItems = append(mappedRequestItems, dto.ResponseRequestPickupItem{
|
||||||
AddressID: existingRequest.AddressId,
|
ID: item.ID,
|
||||||
EvidenceImage: existingRequest.EvidenceImage,
|
TrashCategoryName: item.TrashCategory.Name,
|
||||||
StatusPickup: existingRequest.StatusPickup,
|
EstimatedAmount: item.EstimatedAmount,
|
||||||
CreatedAt: existingRequest.CreatedAt.Format("2006-01-02 15:04:05"),
|
})
|
||||||
UpdatedAt: existingRequest.UpdatedAt.Format("2006-01-02 15:04:05"),
|
}
|
||||||
|
|
||||||
|
mappedRequest.RequestItems = mappedRequestItems
|
||||||
|
|
||||||
|
response = append(response, mappedRequest)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *requestPickupService) DeleteRequestPickup(id string) error {
|
|
||||||
|
|
||||||
err := s.repo.DeleteRequestPickup(id)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to delete request pickup with ID %s: %v", id, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -12,8 +12,8 @@ type Address struct {
|
||||||
Village string `gorm:"not null" json:"village"`
|
Village string `gorm:"not null" json:"village"`
|
||||||
PostalCode string `gorm:"not null" json:"postalCode"`
|
PostalCode string `gorm:"not null" json:"postalCode"`
|
||||||
Detail string `gorm:"not null" json:"detail"`
|
Detail string `gorm:"not null" json:"detail"`
|
||||||
Latitude string `gorm:"not null" json:"latitude"`
|
Latitude float64 `gorm:"not null" json:"latitude"`
|
||||||
Longitude string `gorm:"not null" json:"longitude"`
|
Longitude float64 `gorm:"not null" json:"longitude"`
|
||||||
CreatedAt time.Time `gorm:"default:current_timestamp" json:"createdAt"`
|
CreatedAt time.Time `gorm:"default:current_timestamp" json:"createdAt"`
|
||||||
UpdatedAt time.Time `gorm:"default:current_timestamp" json:"updatedAt"`
|
UpdatedAt time.Time `gorm:"default:current_timestamp" json:"updatedAt"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package model
|
||||||
|
|
||||||
|
type Collector struct {
|
||||||
|
ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4();unique;not null" json:"id"`
|
||||||
|
UserID string `gorm:"not null" json:"userId"`
|
||||||
|
User User `gorm:"foreignKey:UserID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"user"`
|
||||||
|
JobStatus string `gorm:"default:nonactive" json:"jobstatus"`
|
||||||
|
Rating float32 `gorm:"default:5" json:"rating"`
|
||||||
|
AddressId string `gorm:"not null" json:"address_id"`
|
||||||
|
Address Address `gorm:"foreignKey:AddressId;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"address"`
|
||||||
|
}
|
|
@ -7,10 +7,15 @@ 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"`
|
||||||
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"`
|
||||||
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"`
|
EvidenceImage string `json:"evidence_image"`
|
||||||
StatusPickup string `gorm:"default:'waiting_pengepul'" json:"status_pickup"`
|
StatusPickup string `gorm:"default:'waiting_collector'" json:"status_pickup"`
|
||||||
|
CollectorID *string `gorm:"type:uuid" json:"collector_id,omitempty"`
|
||||||
|
ConfirmedByCollectorAt time.Time `gorm:"default:current_timestamp" json:"confirmed_by_collector_at,omitempty"`
|
||||||
|
RequestMethod string `gorm:"not null" json:"request_method"`
|
||||||
CreatedAt time.Time `gorm:"default:current_timestamp" json:"created_at"`
|
CreatedAt time.Time `gorm:"default:current_timestamp" json:"created_at"`
|
||||||
UpdatedAt time.Time `gorm:"default:current_timestamp" json:"updated_at"`
|
UpdatedAt time.Time `gorm:"default:current_timestamp" json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
@ -18,7 +23,8 @@ type RequestPickup struct {
|
||||||
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;"`
|
||||||
TrashCategoryId string `gorm:"not null" json:"trash_category_id"`
|
TrashCategoryId string `gorm:"not null" json:"trash_category_id"`
|
||||||
TrashDetailId string `json:"trash_detail_id,omitempty"`
|
TrashCategory TrashCategory `gorm:"foreignKey:TrashCategoryId;constraint:OnDelete:CASCADE;"`
|
||||||
EstimatedAmount float64 `gorm:"not null" json:"estimated_amount"`
|
EstimatedAmount float64 `gorm:"not null" json:"estimated_amount"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package presentation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"rijig/config"
|
||||||
|
"rijig/internal/handler"
|
||||||
|
"rijig/internal/repositories"
|
||||||
|
"rijig/internal/services"
|
||||||
|
"rijig/middleware"
|
||||||
|
"rijig/utils"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CollectorRouter(api fiber.Router) {
|
||||||
|
repo := repositories.NewCollectorRepository(config.DB)
|
||||||
|
repoReq := repositories.NewRequestPickupRepository(config.DB)
|
||||||
|
repoAddress := repositories.NewAddressRepository(config.DB)
|
||||||
|
colectorService := services.NewCollectorService(repo, repoReq, repoAddress)
|
||||||
|
collectorHandler := handler.NewCollectorHandler(colectorService)
|
||||||
|
|
||||||
|
collector := api.Group("/collector")
|
||||||
|
collector.Use(middleware.AuthMiddleware, middleware.RoleMiddleware(utils.RolePengepul))
|
||||||
|
|
||||||
|
collector.Put("confirmrequest/:id", collectorHandler.ConfirmRequestPickup)
|
||||||
|
|
||||||
|
}
|
|
@ -15,8 +15,12 @@ func RequestPickupRouter(api fiber.Router) {
|
||||||
requestRepo := repositories.NewRequestPickupRepository(config.DB)
|
requestRepo := repositories.NewRequestPickupRepository(config.DB)
|
||||||
repoTrash := repositories.NewTrashRepository(config.DB)
|
repoTrash := repositories.NewTrashRepository(config.DB)
|
||||||
repoAddress := repositories.NewAddressRepository(config.DB)
|
repoAddress := repositories.NewAddressRepository(config.DB)
|
||||||
|
// collectorRepo := repositories.NewCollectorRepository(config.DB)
|
||||||
|
|
||||||
requestPickupServices := services.NewRequestPickupService(requestRepo, repoAddress, repoTrash)
|
requestPickupServices := services.NewRequestPickupService(requestRepo, repoAddress, repoTrash)
|
||||||
|
// collectorService := services.NewCollectorService(collectorRepo, requestRepo, repoAddress)
|
||||||
|
// service services.RequestPickupService,
|
||||||
|
// collectorService services.CollectorService
|
||||||
|
|
||||||
requestPickupHandler := handler.NewRequestPickupHandler(requestPickupServices)
|
requestPickupHandler := handler.NewRequestPickupHandler(requestPickupServices)
|
||||||
|
|
||||||
|
@ -24,6 +28,8 @@ func RequestPickupRouter(api fiber.Router) {
|
||||||
requestPickupAPI.Use(middleware.AuthMiddleware)
|
requestPickupAPI.Use(middleware.AuthMiddleware)
|
||||||
|
|
||||||
requestPickupAPI.Post("/", requestPickupHandler.CreateRequestPickup)
|
requestPickupAPI.Post("/", requestPickupHandler.CreateRequestPickup)
|
||||||
|
// requestPickupAPI.Get("/get", middleware.AuthMiddleware, requestPickupHandler.GetAutomaticRequestByUser)
|
||||||
|
requestPickupAPI.Get("/get-allrequest", requestPickupHandler.GetRequestPickups)
|
||||||
// requestPickupAPI.Get("/:id", requestPickupHandler.GetRequestPickupByID)
|
// requestPickupAPI.Get("/:id", requestPickupHandler.GetRequestPickupByID)
|
||||||
// requestPickupAPI.Get("/", requestPickupHandler.GetAllRequestPickups)
|
// requestPickupAPI.Get("/", requestPickupHandler.GetAllRequestPickups)
|
||||||
// requestPickupAPI.Put("/:id", requestPickupHandler.UpdateRequestPickup)
|
// requestPickupAPI.Put("/:id", requestPickupHandler.UpdateRequestPickup)
|
||||||
|
|
|
@ -26,6 +26,7 @@ func SetupRoutes(app *fiber.App) {
|
||||||
presentation.IdentityCardRouter(api)
|
presentation.IdentityCardRouter(api)
|
||||||
presentation.CompanyProfileRouter(api)
|
presentation.CompanyProfileRouter(api)
|
||||||
presentation.RequestPickupRouter(api)
|
presentation.RequestPickupRouter(api)
|
||||||
|
presentation.CollectorRouter(api)
|
||||||
|
|
||||||
presentation.UserProfileRouter(api)
|
presentation.UserProfileRouter(api)
|
||||||
presentation.UserPinRouter(api)
|
presentation.UserPinRouter(api)
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
earthRadiusMi = 3958
|
||||||
|
earthRaidusKm = 6371
|
||||||
|
)
|
||||||
|
|
||||||
|
type Coord struct {
|
||||||
|
Lat float64
|
||||||
|
Lon float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func degreesToRadians(d float64) float64 {
|
||||||
|
return d * math.Pi / 180
|
||||||
|
}
|
||||||
|
|
||||||
|
func Distance(p, q Coord) (mi, km float64) {
|
||||||
|
lat1 := degreesToRadians(p.Lat)
|
||||||
|
lon1 := degreesToRadians(p.Lon)
|
||||||
|
lat2 := degreesToRadians(q.Lat)
|
||||||
|
lon2 := degreesToRadians(q.Lon)
|
||||||
|
|
||||||
|
diffLat := lat2 - lat1
|
||||||
|
diffLon := lon2 - lon1
|
||||||
|
|
||||||
|
a := math.Pow(math.Sin(diffLat/2), 2) + math.Cos(lat1)*math.Cos(lat2)*
|
||||||
|
math.Pow(math.Sin(diffLon/2), 2)
|
||||||
|
|
||||||
|
c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))
|
||||||
|
|
||||||
|
mi = c * earthRadiusMi
|
||||||
|
km = c * earthRaidusKm
|
||||||
|
|
||||||
|
return mi, km
|
||||||
|
}
|
Loading…
Reference in New Issue