fix: fixing wilayah api indonesia

This commit is contained in:
pahmiudahgede 2025-02-07 00:02:05 +07:00
parent 1c856773a1
commit 0dff98736c
5 changed files with 325 additions and 283 deletions

View File

@ -1,7 +1,6 @@
package handler package handler
import ( import (
"fmt"
"strconv" "strconv"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
@ -27,122 +26,163 @@ func (h *WilayahIndonesiaHandler) ImportWilayahData(c *fiber.Ctx) error {
return utils.GenericErrorResponse(c, fiber.StatusCreated, "Data imported successfully") return utils.GenericErrorResponse(c, fiber.StatusCreated, "Data imported successfully")
} }
func (h *WilayahIndonesiaHandler) GetAllProvinces(c *fiber.Ctx) error { func (h *WilayahIndonesiaHandler) GetProvinces(c *fiber.Ctx) error {
page, err := strconv.Atoi(c.Query("page", "1"))
page, err := strconv.Atoi(c.Query("page", "0"))
if err != nil { if err != nil {
page = 1 page = 0
}
limit, err := strconv.Atoi(c.Query("limit", "0"))
if err != nil {
limit = 0
} }
limit, err := strconv.Atoi(c.Query("limit", "10")) provinces, totalProvinces, err := h.WilayahService.GetAllProvinces(page, limit)
if err != nil { if err != nil {
limit = 10 return utils.GenericErrorResponse(c, fiber.StatusInternalServerError, "Failed to fetch provinces")
} }
provinces, err := h.WilayahService.GetAllProvinces(page, limit) if page > 0 && limit > 0 {
if err != nil { return utils.PaginatedResponse(c, provinces, page, limit, totalProvinces, "Provinces fetched successfully")
return utils.GenericErrorResponse(c, fiber.StatusInternalServerError, fmt.Sprintf("Failed to fetch provinces: %v", err))
} }
return utils.PaginatedResponse(c, provinces, page, limit, len(provinces), "Provinces fetched successfully") return utils.NonPaginatedResponse(c, provinces, totalProvinces, "Provinces fetched successfully")
} }
func (h *WilayahIndonesiaHandler) GetProvinceByID(c *fiber.Ctx) error { func (h *WilayahIndonesiaHandler) GetProvinceByID(c *fiber.Ctx) error {
provinceID := c.Params("id") provinceID := c.Params("id")
province, err := h.WilayahService.GetProvinceByID(provinceID) page, err := strconv.Atoi(c.Query("page", "0"))
if err != nil { if err != nil {
return utils.GenericErrorResponse(c, fiber.StatusNotFound, fmt.Sprintf("Province not found: %v", err)) page = 0
}
limit, err := strconv.Atoi(c.Query("limit", "0"))
if err != nil {
limit = 0
} }
return utils.LogResponse(c, province, "Province fetched successfully") province, totalRegencies, err := h.WilayahService.GetProvinceByID(provinceID, page, limit)
if err != nil {
return utils.GenericErrorResponse(c, fiber.StatusInternalServerError, "Failed to fetch province")
}
if page > 0 && limit > 0 {
return utils.PaginatedResponse(c, province, page, limit, totalRegencies, "Province fetched successfully")
}
return utils.NonPaginatedResponse(c, province, totalRegencies, "Province fetched successfully")
} }
func (h *WilayahIndonesiaHandler) GetAllRegencies(c *fiber.Ctx) error { func (h *WilayahIndonesiaHandler) GetAllRegencies(c *fiber.Ctx) error {
page, err := strconv.Atoi(c.Query("page", "1")) page, err := strconv.Atoi(c.Query("page", "0"))
if err != nil { if err != nil {
page = 1 page = 0
}
limit, err := strconv.Atoi(c.Query("limit", "0"))
if err != nil {
limit = 0
} }
limit, err := strconv.Atoi(c.Query("limit", "10")) regencies, totalRegencies, err := h.WilayahService.GetAllRegencies(page, limit)
if err != nil { if err != nil {
limit = 10 return utils.GenericErrorResponse(c, fiber.StatusInternalServerError, "Failed to fetch regency")
} }
regencies, err := h.WilayahService.GetAllRegencies(page, limit) if page > 0 && limit > 0 {
if err != nil { return utils.PaginatedResponse(c, regencies, page, limit, totalRegencies, "regency fetched successfully")
return utils.GenericErrorResponse(c, fiber.StatusInternalServerError, fmt.Sprintf("Failed to fetch regencies: %v", err))
} }
return utils.PaginatedResponse(c, regencies, page, limit, len(regencies), "Regencies fetched successfully") return utils.NonPaginatedResponse(c, regencies, totalRegencies, "Provinces fetched successfully")
} }
func (h *WilayahIndonesiaHandler) GetRegencyByID(c *fiber.Ctx) error { func (h *WilayahIndonesiaHandler) GetRegencyByID(c *fiber.Ctx) error {
regencyID := c.Params("id") regencyId := c.Params("id")
regency, err := h.WilayahService.GetRegencyByID(regencyID) page, err := strconv.Atoi(c.Query("page", "0"))
if err != nil { if err != nil {
return utils.GenericErrorResponse(c, fiber.StatusNotFound, fmt.Sprintf("Regency not found: %v", err)) page = 0
}
limit, err := strconv.Atoi(c.Query("limit", "0"))
if err != nil {
limit = 0
} }
return utils.LogResponse(c, regency, "Regency fetched successfully") regency, totalDistrict, err := h.WilayahService.GetRegencyByID(regencyId, page, limit)
if err != nil {
return utils.GenericErrorResponse(c, fiber.StatusInternalServerError, "Failed to fetch regency")
}
if page > 0 && limit > 0 {
return utils.PaginatedResponse(c, regency, page, limit, totalDistrict, "regency fetched successfully")
}
return utils.NonPaginatedResponse(c, regency, totalDistrict, "regency fetched successfully")
} }
func (h *WilayahIndonesiaHandler) GetAllDistricts(c *fiber.Ctx) error { func (h *WilayahIndonesiaHandler) GetAllDistricts(c *fiber.Ctx) error {
page, err := strconv.Atoi(c.Query("page", "1")) page, err := strconv.Atoi(c.Query("page", "0"))
if err != nil { if err != nil {
page = 1 page = 0
}
limit, err := strconv.Atoi(c.Query("limit", "0"))
if err != nil {
limit = 0
} }
limit, err := strconv.Atoi(c.Query("limit", "10")) districts, totalDistricts, err := h.WilayahService.GetAllDistricts(page, limit)
if err != nil { if err != nil {
limit = 10 return utils.GenericErrorResponse(c, fiber.StatusInternalServerError, "Failed to fetch districts")
} }
districts, err := h.WilayahService.GetAllDistricts(page, limit) if page > 0 && limit > 0 {
if err != nil { return utils.PaginatedResponse(c, districts, page, limit, totalDistricts, "districts fetched successfully")
return utils.GenericErrorResponse(c, fiber.StatusInternalServerError, fmt.Sprintf("Failed to fetch districts: %v", err))
} }
return utils.PaginatedResponse(c, districts, page, limit, len(districts), "Districts fetched successfully") return utils.NonPaginatedResponse(c, districts, totalDistricts, "districts fetched successfully")
} }
func (h *WilayahIndonesiaHandler) GetDistrictByID(c *fiber.Ctx) error { func (h *WilayahIndonesiaHandler) GetDistrictByID(c *fiber.Ctx) error {
districtID := c.Params("id") districtId := c.Params("id")
district, err := h.WilayahService.GetDistrictByID(districtID) page, err := strconv.Atoi(c.Query("page", "0"))
if err != nil { if err != nil {
return utils.GenericErrorResponse(c, fiber.StatusNotFound, fmt.Sprintf("District not found: %v", err)) page = 0
}
limit, err := strconv.Atoi(c.Query("limit", "0"))
if err != nil {
limit = 0
} }
return utils.LogResponse(c, district, "District fetched successfully") district, totalVillages, err := h.WilayahService.GetDistrictByID(districtId, page, limit)
if err != nil {
return utils.GenericErrorResponse(c, fiber.StatusInternalServerError, "Failed to fetch district")
}
if page > 0 && limit > 0 {
return utils.PaginatedResponse(c, district, page, limit, totalVillages, "district fetched successfully")
}
return utils.NonPaginatedResponse(c, district, totalVillages, "district fetched successfully")
} }
func (h *WilayahIndonesiaHandler) GetAllVillages(c *fiber.Ctx) error { func (h *WilayahIndonesiaHandler) GetAllVillages(c *fiber.Ctx) error {
page, err := strconv.Atoi(c.Query("page", "1")) page, err := strconv.Atoi(c.Query("page", "0"))
if err != nil { if err != nil {
page = 1 page = 0
} }
limit, err := strconv.Atoi(c.Query("limit", "0"))
limit, err := strconv.Atoi(c.Query("limit", "10"))
if err != nil { if err != nil {
limit = 10 limit = 0
} }
villages, err := h.WilayahService.GetAllVillages(page, limit) villages, totalVillages, err := h.WilayahService.GetAllVillages(page, limit)
if err != nil { if err != nil {
return utils.GenericErrorResponse(c, fiber.StatusInternalServerError, fmt.Sprintf("Failed to fetch villages: %v", err)) return utils.GenericErrorResponse(c, fiber.StatusInternalServerError, "Failed to fetch villages")
} }
return utils.PaginatedResponse(c, villages, page, limit, len(villages), "Villages fetched successfully") if page > 0 && limit > 0 {
return utils.PaginatedResponse(c, villages, page, limit, totalVillages, "villages fetched successfully")
} }
func (h *WilayahIndonesiaHandler) GetVillageByID(c *fiber.Ctx) error { return utils.NonPaginatedResponse(c, villages, totalVillages, "villages fetched successfully")
villageID := c.Params("id")
village, err := h.WilayahService.GetVillageByID(villageID)
if err != nil {
return utils.GenericErrorResponse(c, fiber.StatusNotFound, fmt.Sprintf("Village not found: %v", err))
}
return utils.LogResponse(c, village, "Village fetched successfully")
} }

View File

@ -10,18 +10,17 @@ type WilayahIndonesiaRepository interface {
ImportRegencies(regencies []model.Regency) error ImportRegencies(regencies []model.Regency) error
ImportDistricts(districts []model.District) error ImportDistricts(districts []model.District) error
ImportVillages(villages []model.Village) error ImportVillages(villages []model.Village) error
// ================================================== //
FindAllProvinces(page, limit int) ([]model.Province, int, error) FindAllProvinces(page, limit int) ([]model.Province, int, error)
FindProvinceByID(id string) (*model.Province, error) FindProvinceByID(id string, page, limit int) (*model.Province, int, error)
FindAllRegencies(page, limit int) ([]model.Regency, int, error) FindAllRegencies(page, limit int) ([]model.Regency, int, error)
FindRegencyByID(id string) (*model.Regency, error) FindRegencyByID(id string, page, limit int) (*model.Regency, int, error)
FindAllDistricts(page, limit int) ([]model.District, int, error) FindAllDistricts(page, limit int) ([]model.District, int, error)
FindDistrictByID(id string) (*model.District, error) FindDistrictByID(id string, page, limit int) (*model.District, int, error)
FindAllVillages(page, limit int) ([]model.Village, int, error) FindAllVillages(page, limit int) ([]model.Village, int, error)
FindVillageByID(id string) (*model.Village, error)
} }
type wilayahIndonesiaRepository struct { type wilayahIndonesiaRepository struct {
@ -68,127 +67,164 @@ func (r *wilayahIndonesiaRepository) ImportVillages(villages []model.Village) er
return nil return nil
} }
/*
| ============================================================ |
| ============================================================ |
*/
// FindAllProvinces with Pagination
func (r *wilayahIndonesiaRepository) FindAllProvinces(page, limit int) ([]model.Province, int, error) { func (r *wilayahIndonesiaRepository) FindAllProvinces(page, limit int) ([]model.Province, int, error) {
var provinces []model.Province var provinces []model.Province
var total int64 var total int64
// Count total provinces
err := r.DB.Model(&model.Province{}).Count(&total).Error err := r.DB.Model(&model.Province{}).Count(&total).Error
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }
// Get provinces with pagination if page > 0 && limit > 0 {
err = r.DB.Offset((page - 1) * limit).Limit(limit).Find(&provinces).Error err := r.DB.Offset((page - 1) * limit).Limit(limit).Find(&provinces).Error
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }
} else {
err := r.DB.Find(&provinces).Error
if err != nil {
return nil, 0, err
}
}
return provinces, int(total), nil return provinces, int(total), nil
} }
// FindProvinceByID func (r *wilayahIndonesiaRepository) FindProvinceByID(id string, page, limit int) (*model.Province, int, error) {
func (r *wilayahIndonesiaRepository) FindProvinceByID(id string) (*model.Province, error) {
var province model.Province var province model.Province
err := r.DB.Preload("Regencies").Where("id = ?", id).First(&province).Error
if err != nil { err := r.DB.Preload("Regencies", func(db *gorm.DB) *gorm.DB {
return nil, err if page > 0 && limit > 0 {
}
return &province, nil return db.Offset((page - 1) * limit).Limit(limit)
}
return db
}).Where("id = ?", id).First(&province).Error
if err != nil {
return nil, 0, err
}
var totalRegencies int64
r.DB.Model(&model.Regency{}).Where("province_id = ?", id).Count(&totalRegencies)
return &province, int(totalRegencies), nil
} }
// FindAllRegencies with Pagination
func (r *wilayahIndonesiaRepository) FindAllRegencies(page, limit int) ([]model.Regency, int, error) { func (r *wilayahIndonesiaRepository) FindAllRegencies(page, limit int) ([]model.Regency, int, error) {
var regencies []model.Regency var regencies []model.Regency
var total int64 var total int64
// Count total regencies
err := r.DB.Model(&model.Regency{}).Count(&total).Error err := r.DB.Model(&model.Regency{}).Count(&total).Error
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }
// Get regencies with pagination if page > 0 && limit > 0 {
err = r.DB.Offset((page - 1) * limit).Limit(limit).Preload("Districts").Find(&regencies).Error err := r.DB.Offset((page - 1) * limit).Limit(limit).Find(&regencies).Error
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }
} else {
err := r.DB.Find(&regencies).Error
if err != nil {
return nil, 0, err
}
}
return regencies, int(total), nil return regencies, int(total), nil
} }
// FindRegencyByID func (r *wilayahIndonesiaRepository) FindRegencyByID(id string, page, limit int) (*model.Regency, int, error) {
func (r *wilayahIndonesiaRepository) FindRegencyByID(id string) (*model.Regency, error) {
var regency model.Regency var regency model.Regency
err := r.DB.Preload("Districts").Where("id = ?", id).First(&regency).Error
if err != nil { err := r.DB.Preload("Districs", func(db *gorm.DB) *gorm.DB {
return nil, err if page > 0 && limit > 0 {
}
return &regency, nil return db.Offset((page - 1) * limit).Limit(limit)
}
return db
}).Where("id = ?", id).First(&regency).Error
if err != nil {
return nil, 0, err
}
var totalDistrict int64
r.DB.Model(&model.District{}).Where("regency_id = ?", id).Count(&totalDistrict)
return &regency, int(totalDistrict), nil
} }
// FindAllDistricts with Pagination
func (r *wilayahIndonesiaRepository) FindAllDistricts(page, limit int) ([]model.District, int, error) { func (r *wilayahIndonesiaRepository) FindAllDistricts(page, limit int) ([]model.District, int, error) {
var districts []model.District var district []model.District
var total int64 var total int64
// Count total districts
err := r.DB.Model(&model.District{}).Count(&total).Error err := r.DB.Model(&model.District{}).Count(&total).Error
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }
// Get districts with pagination if page > 0 && limit > 0 {
err = r.DB.Offset((page - 1) * limit).Limit(limit).Preload("Villages").Find(&districts).Error err := r.DB.Offset((page - 1) * limit).Limit(limit).Find(&district).Error
if err != nil {
return nil, 0, err
}
} else {
err := r.DB.Find(&district).Error
if err != nil {
return nil, 0, err
}
}
return district, int(total), nil
}
func (r *wilayahIndonesiaRepository) FindDistrictByID(id string, page, limit int) (*model.District, int, error) {
var district model.District
err := r.DB.Preload("Village", func(db *gorm.DB) *gorm.DB {
if page > 0 && limit > 0 {
return db.Offset((page - 1) * limit).Limit(limit)
}
return db
}).Where("id = ?", id).First(&district).Error
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }
return districts, int(total), nil var totalVillage int64
r.DB.Model(&model.Village{}).Where("district_id = ?", id).Count(&totalVillage)
return &district, int(totalVillage), nil
} }
// FindDistrictByID
func (r *wilayahIndonesiaRepository) FindDistrictByID(id string) (*model.District, error) {
var district model.District
err := r.DB.Preload("Villages").Where("id = ?", id).First(&district).Error
if err != nil {
return nil, err
}
return &district, nil
}
// FindAllVillages with Pagination
func (r *wilayahIndonesiaRepository) FindAllVillages(page, limit int) ([]model.Village, int, error) { func (r *wilayahIndonesiaRepository) FindAllVillages(page, limit int) ([]model.Village, int, error) {
var villages []model.Village var village []model.Village
var total int64 var total int64
// Count total villages
err := r.DB.Model(&model.Village{}).Count(&total).Error err := r.DB.Model(&model.Village{}).Count(&total).Error
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }
// Get villages with pagination if page > 0 && limit > 0 {
err = r.DB.Offset((page - 1) * limit).Limit(limit).Find(&villages).Error err := r.DB.Offset((page - 1) * limit).Limit(limit).Find(&village).Error
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }
} else {
return villages, int(total), nil err := r.DB.Find(&village).Error
}
// FindVillageByID
func (r *wilayahIndonesiaRepository) FindVillageByID(id string) (*model.Village, error) {
var village model.Village
err := r.DB.Where("id = ?", id).First(&village).Error
if err != nil { if err != nil {
return nil, err return nil, 0, err
} }
return &village, nil }
return village, int(total), nil
} }

View File

@ -1,7 +1,9 @@
package services package services
import ( import (
"encoding/json"
"fmt" "fmt"
"strconv"
"time" "time"
"github.com/pahmiudahgede/senggoldong/dto" "github.com/pahmiudahgede/senggoldong/dto"
@ -13,17 +15,16 @@ import (
type WilayahIndonesiaService interface { type WilayahIndonesiaService interface {
ImportDataFromCSV() error ImportDataFromCSV() error
GetAllProvinces(page, limit int) ([]dto.ProvinceResponseDTO, error) GetAllProvinces(page, limit int) ([]dto.ProvinceResponseDTO, int, error)
GetProvinceByID(id string) (*dto.ProvinceResponseDTO, error) GetProvinceByID(id string, page, limit int) (*dto.ProvinceResponseDTO, int, error)
GetAllRegencies(page, limit int) ([]dto.RegencyResponseDTO, error) GetAllRegencies(page, limit int) ([]dto.RegencyResponseDTO, int, error)
GetRegencyByID(id string) (*dto.RegencyResponseDTO, error) GetRegencyByID(id string, page, limit int) (*dto.RegencyResponseDTO, int, error)
GetAllDistricts(page, limit int) ([]dto.DistrictResponseDTO, error) GetAllDistricts(page, limit int) ([]dto.DistrictResponseDTO, int, error)
GetDistrictByID(id string) (*dto.DistrictResponseDTO, error) GetDistrictByID(id string, page, limit int) (*dto.DistrictResponseDTO, int, error)
GetAllVillages(page, limit int) ([]dto.VillageResponseDTO, error) GetAllVillages(page, limit int) ([]dto.VillageResponseDTO, int, error)
GetVillageByID(id string) (*dto.VillageResponseDTO, error)
} }
type wilayahIndonesiaService struct { type wilayahIndonesiaService struct {
@ -114,9 +115,9 @@ func (s *wilayahIndonesiaService) ImportDataFromCSV() error {
return nil return nil
} }
func (s *wilayahIndonesiaService) GetAllProvinces(page, limit int) ([]dto.ProvinceResponseDTO, error) { func (s *wilayahIndonesiaService) GetAllProvinces(page, limit int) ([]dto.ProvinceResponseDTO, int, error) {
cacheKey := fmt.Sprintf("provinces_page_%d_limit_%d", page, limit) cacheKey := fmt.Sprintf("provinces_page:%d_limit:%d", page, limit)
cachedData, err := utils.GetJSONData(cacheKey) cachedData, err := utils.GetJSONData(cacheKey)
if err == nil && cachedData != nil { if err == nil && cachedData != nil {
var provinces []dto.ProvinceResponseDTO var provinces []dto.ProvinceResponseDTO
@ -130,13 +131,14 @@ func (s *wilayahIndonesiaService) GetAllProvinces(page, limit int) ([]dto.Provin
}) })
} }
} }
return provinces, nil total := int(cachedData["total"].(float64))
return provinces, total, nil
} }
} }
provinces, total, err := s.WilayahRepo.FindAllProvinces(page, limit) provinces, total, err := s.WilayahRepo.FindAllProvinces(page, limit)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to fetch provinces: %v", err) return nil, 0, fmt.Errorf("failed to fetch provinces: %v", err)
} }
var provinceDTOs []dto.ProvinceResponseDTO var provinceDTOs []dto.ProvinceResponseDTO
@ -150,66 +152,68 @@ func (s *wilayahIndonesiaService) GetAllProvinces(page, limit int) ([]dto.Provin
cacheData := map[string]interface{}{ cacheData := map[string]interface{}{
"data": provinceDTOs, "data": provinceDTOs,
"total": total, "total": total,
"page": page,
"limit": limit,
} }
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24) err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
if err != nil { if err != nil {
fmt.Printf("Error caching provinces data to Redis: %v\n", err) fmt.Printf("Error caching provinces data: %v\n", err)
} }
return provinceDTOs, nil return provinceDTOs, total, nil
} }
func (s *wilayahIndonesiaService) GetProvinceByID(id string) (*dto.ProvinceResponseDTO, error) { func (s *wilayahIndonesiaService) GetProvinceByID(id string, page, limit int) (*dto.ProvinceResponseDTO, int, error) {
cacheKey := fmt.Sprintf("province:%s", id) cacheKey := fmt.Sprintf("province:%s_page:%d_limit:%d", id, page, limit)
cachedData, err := utils.GetJSONData(cacheKey) cachedData, err := utils.GetJSONData(cacheKey)
if err == nil && cachedData != nil { if err == nil && cachedData != nil {
var province dto.ProvinceResponseDTO
if data, ok := cachedData["data"].(map[string]interface{}); ok { var provinceDTO dto.ProvinceResponseDTO
province = dto.ProvinceResponseDTO{ if data, ok := cachedData["data"].(string); ok {
ID: data["id"].(string), if err := json.Unmarshal([]byte(data), &provinceDTO); err == nil {
Name: data["name"].(string),
totalRegencies, _ := strconv.Atoi(cachedData["total_regencies"].(string))
return &provinceDTO, totalRegencies, nil
} }
return &province, nil
} }
} }
province, err := s.WilayahRepo.FindProvinceByID(id) province, totalRegencies, err := s.WilayahRepo.FindProvinceByID(id, page, limit)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to fetch province: %v", err) return nil, 0, err
} }
provinceDTO := &dto.ProvinceResponseDTO{ provinceDTO := dto.ProvinceResponseDTO{
ID: province.ID, ID: province.ID,
Name: province.Name, Name: province.Name,
} }
regenciesDTO := []dto.RegencyResponseDTO{} var regencyDTOs []dto.RegencyResponseDTO
for _, regency := range province.Regencies { for _, regency := range province.Regencies {
regenciesDTO = append(regenciesDTO, dto.RegencyResponseDTO{ regencyDTO := dto.RegencyResponseDTO{
ID: regency.ID, ID: regency.ID,
ProvinceID: regency.ProvinceID, ProvinceID: regency.ProvinceID,
Name: regency.Name, Name: regency.Name,
})
} }
provinceDTO.Regencies = regenciesDTO regencyDTOs = append(regencyDTOs, regencyDTO)
}
provinceDTO.Regencies = regencyDTOs
cacheData := map[string]interface{}{ cacheData := map[string]interface{}{
"data": provinceDTO, "data": provinceDTO,
"total_regencies": strconv.Itoa(totalRegencies),
} }
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24) err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
if err != nil { if err != nil {
fmt.Printf("Error caching province data to Redis: %v\n", err) fmt.Printf("Error caching province data: %v\n", err)
} }
return provinceDTO, nil return &provinceDTO, totalRegencies, nil
} }
func (s *wilayahIndonesiaService) GetAllRegencies(page, limit int) ([]dto.RegencyResponseDTO, error) { func (s *wilayahIndonesiaService) GetAllRegencies(page, limit int) ([]dto.RegencyResponseDTO, int, error) {
cacheKey := fmt.Sprintf("regencies_page_%d_limit_%d", page, limit) cacheKey := fmt.Sprintf("regencies_page:%d_limit:%d", page, limit)
cachedData, err := utils.GetJSONData(cacheKey) cachedData, err := utils.GetJSONData(cacheKey)
if err == nil && cachedData != nil { if err == nil && cachedData != nil {
var regencies []dto.RegencyResponseDTO var regencies []dto.RegencyResponseDTO
@ -224,13 +228,14 @@ func (s *wilayahIndonesiaService) GetAllRegencies(page, limit int) ([]dto.Regenc
}) })
} }
} }
return regencies, nil total := int(cachedData["total"].(float64))
return regencies, total, nil
} }
} }
regencies, total, err := s.WilayahRepo.FindAllRegencies(page, limit) regencies, total, err := s.WilayahRepo.FindAllRegencies(page, limit)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to fetch regencies: %v", err) return nil, 0, fmt.Errorf("failed to fetch provinces: %v", err)
} }
var regencyDTOs []dto.RegencyResponseDTO var regencyDTOs []dto.RegencyResponseDTO
@ -245,68 +250,69 @@ func (s *wilayahIndonesiaService) GetAllRegencies(page, limit int) ([]dto.Regenc
cacheData := map[string]interface{}{ cacheData := map[string]interface{}{
"data": regencyDTOs, "data": regencyDTOs,
"total": total, "total": total,
"page": page,
"limit": limit,
} }
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24) err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
if err != nil { if err != nil {
fmt.Printf("Error caching regencies data to Redis: %v\n", err) fmt.Printf("Error caching regencies data: %v\n", err)
} }
return regencyDTOs, nil return regencyDTOs, total, nil
} }
func (s *wilayahIndonesiaService) GetRegencyByID(id string) (*dto.RegencyResponseDTO, error) { func (s *wilayahIndonesiaService) GetRegencyByID(id string, page, limit int) (*dto.RegencyResponseDTO, int, error) {
cacheKey := fmt.Sprintf("regency:%s", id) cacheKey := fmt.Sprintf("regency:%s_page:%d_limit:%d", id, page, limit)
cachedData, err := utils.GetJSONData(cacheKey) cachedData, err := utils.GetJSONData(cacheKey)
if err == nil && cachedData != nil { if err == nil && cachedData != nil {
var regency dto.RegencyResponseDTO
if data, ok := cachedData["data"].(map[string]interface{}); ok { var regencyDTO dto.RegencyResponseDTO
regency = dto.RegencyResponseDTO{ if data, ok := cachedData["data"].(string); ok {
ID: data["id"].(string), if err := json.Unmarshal([]byte(data), &regencyDTO); err == nil {
ProvinceID: data["province_id"].(string),
Name: data["name"].(string), totalDistrict, _ := strconv.Atoi(cachedData["total_regencies"].(string))
return &regencyDTO, totalDistrict, nil
} }
return &regency, nil
} }
} }
regency, err := s.WilayahRepo.FindRegencyByID(id) regency, totalDistrict, err := s.WilayahRepo.FindRegencyByID(id, page, limit)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to fetch regency: %v", err) return nil, 0, err
} }
regencyDTO := &dto.RegencyResponseDTO{ regencyDTO := dto.RegencyResponseDTO{
ID: regency.ID, ID: regency.ID,
ProvinceID: regency.ProvinceID, ProvinceID: regency.ProvinceID,
Name: regency.Name, Name: regency.Name,
} }
districtsDTO := []dto.DistrictResponseDTO{} var districtDTOs []dto.DistrictResponseDTO
for _, district := range regency.Districts { for _, regency := range regency.Districts {
districtsDTO = append(districtsDTO, dto.DistrictResponseDTO{ districtDTO := dto.DistrictResponseDTO{
ID: district.ID, ID: regency.ID,
RegencyID: district.RegencyID, RegencyID: regency.RegencyID,
Name: district.Name, Name: regency.Name,
})
} }
regencyDTO.Districts = districtsDTO districtDTOs = append(districtDTOs, districtDTO)
}
regencyDTO.Districts = districtDTOs
cacheData := map[string]interface{}{ cacheData := map[string]interface{}{
"data": regencyDTO, "data": regencyDTO,
"total_regencies": strconv.Itoa(totalDistrict),
} }
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24) err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
if err != nil { if err != nil {
fmt.Printf("Error caching regency data to Redis: %v\n", err) fmt.Printf("Error caching province data: %v\n", err)
} }
return regencyDTO, nil return &regencyDTO, totalDistrict, nil
} }
func (s *wilayahIndonesiaService) GetAllDistricts(page, limit int) ([]dto.DistrictResponseDTO, error) { func (s *wilayahIndonesiaService) GetAllDistricts(page, limit int) ([]dto.DistrictResponseDTO, int, error) {
cacheKey := fmt.Sprintf("districts_page_%d_limit_%d", page, limit) cacheKey := fmt.Sprintf("district_page:%d_limit:%d", page, limit)
cachedData, err := utils.GetJSONData(cacheKey) cachedData, err := utils.GetJSONData(cacheKey)
if err == nil && cachedData != nil { if err == nil && cachedData != nil {
var districts []dto.DistrictResponseDTO var districts []dto.DistrictResponseDTO
@ -321,18 +327,19 @@ func (s *wilayahIndonesiaService) GetAllDistricts(page, limit int) ([]dto.Distri
}) })
} }
} }
return districts, nil total := int(cachedData["total"].(float64))
return districts, total, nil
} }
} }
districts, total, err := s.WilayahRepo.FindAllDistricts(page, limit) districts, total, err := s.WilayahRepo.FindAllDistricts(page, limit)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to fetch districts: %v", err) return nil, 0, fmt.Errorf("failed to fetch districts: %v", err)
} }
var districtDTOs []dto.DistrictResponseDTO var districtsDTOs []dto.DistrictResponseDTO
for _, district := range districts { for _, district := range districts {
districtDTOs = append(districtDTOs, dto.DistrictResponseDTO{ districtsDTOs = append(districtsDTOs, dto.DistrictResponseDTO{
ID: district.ID, ID: district.ID,
RegencyID: district.RegencyID, RegencyID: district.RegencyID,
Name: district.Name, Name: district.Name,
@ -340,70 +347,71 @@ func (s *wilayahIndonesiaService) GetAllDistricts(page, limit int) ([]dto.Distri
} }
cacheData := map[string]interface{}{ cacheData := map[string]interface{}{
"data": districtDTOs, "data": districtsDTOs,
"total": total, "total": total,
"page": page,
"limit": limit,
} }
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24) err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
if err != nil { if err != nil {
fmt.Printf("Error caching districts data to Redis: %v\n", err) fmt.Printf("Error caching districts data: %v\n", err)
} }
return districtDTOs, nil return districtsDTOs, total, nil
} }
func (s *wilayahIndonesiaService) GetDistrictByID(id string) (*dto.DistrictResponseDTO, error) { func (s *wilayahIndonesiaService) GetDistrictByID(id string, page, limit int) (*dto.DistrictResponseDTO, int, error) {
cacheKey := fmt.Sprintf("district:%s", id) cacheKey := fmt.Sprintf("district:%s_page:%d_limit:%d", id, page, limit)
cachedData, err := utils.GetJSONData(cacheKey) cachedData, err := utils.GetJSONData(cacheKey)
if err == nil && cachedData != nil { if err == nil && cachedData != nil {
var district dto.DistrictResponseDTO
if data, ok := cachedData["data"].(map[string]interface{}); ok { var districtDTO dto.DistrictResponseDTO
district = dto.DistrictResponseDTO{ if data, ok := cachedData["data"].(string); ok {
ID: data["id"].(string), if err := json.Unmarshal([]byte(data), &districtDTO); err == nil {
RegencyID: data["regency_id"].(string),
Name: data["name"].(string), totalVillage, _ := strconv.Atoi(cachedData["total_village"].(string))
return &districtDTO, totalVillage, nil
} }
return &district, nil
} }
} }
district, err := s.WilayahRepo.FindDistrictByID(id) district, totalVillages, err := s.WilayahRepo.FindDistrictByID(id, page, limit)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to fetch district: %v", err) return nil, 0, err
} }
districtDTO := &dto.DistrictResponseDTO{ districtDTO := dto.DistrictResponseDTO{
ID: district.ID, ID: district.ID,
RegencyID: district.RegencyID, RegencyID: district.RegencyID,
Name: district.Name, Name: district.Name,
} }
villagesDTO := []dto.VillageResponseDTO{} var villageDTOs []dto.VillageResponseDTO
for _, village := range district.Villages { for _, village := range district.Villages {
villagesDTO = append(villagesDTO, dto.VillageResponseDTO{ regencyDTO := dto.VillageResponseDTO{
ID: village.ID, ID: village.ID,
DistrictID: village.DistrictID, DistrictID: village.DistrictID,
Name: village.Name, Name: village.Name,
})
} }
districtDTO.Villages = villagesDTO villageDTOs = append(villageDTOs, regencyDTO)
}
districtDTO.Villages = villageDTOs
cacheData := map[string]interface{}{ cacheData := map[string]interface{}{
"data": districtDTO, "data": districtDTO,
"total_villages": strconv.Itoa(totalVillages),
} }
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24) err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
if err != nil { if err != nil {
fmt.Printf("Error caching district data to Redis: %v\n", err) fmt.Printf("Error caching province data: %v\n", err)
} }
return districtDTO, nil return &districtDTO, totalVillages, nil
} }
func (s *wilayahIndonesiaService) GetAllVillages(page, limit int) ([]dto.VillageResponseDTO, error) { func (s *wilayahIndonesiaService) GetAllVillages(page, limit int) ([]dto.VillageResponseDTO, int, error) {
cacheKey := fmt.Sprintf("villages:%d:%d", page, limit) cacheKey := fmt.Sprintf("villages_page:%d_limit:%d", page, limit)
cachedData, err := utils.GetJSONData(cacheKey) cachedData, err := utils.GetJSONData(cacheKey)
if err == nil && cachedData != nil { if err == nil && cachedData != nil {
var villages []dto.VillageResponseDTO var villages []dto.VillageResponseDTO
@ -418,13 +426,14 @@ func (s *wilayahIndonesiaService) GetAllVillages(page, limit int) ([]dto.Village
}) })
} }
} }
return villages, nil total := int(cachedData["total"].(float64))
return villages, total, nil
} }
} }
villages, total, err := s.WilayahRepo.FindAllVillages(page, limit) villages, total, err := s.WilayahRepo.FindAllVillages(page, limit)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to fetch villages: %v", err) return nil, 0, fmt.Errorf("failed to fetch villages: %v", err)
} }
var villageDTOs []dto.VillageResponseDTO var villageDTOs []dto.VillageResponseDTO
@ -442,46 +451,8 @@ func (s *wilayahIndonesiaService) GetAllVillages(page, limit int) ([]dto.Village
} }
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24) err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
if err != nil { if err != nil {
fmt.Printf("Error caching village data to Redis: %v\n", err) fmt.Printf("Error caching villages data: %v\n", err)
} }
return villageDTOs, nil return villageDTOs, total, nil
}
func (s *wilayahIndonesiaService) GetVillageByID(id string) (*dto.VillageResponseDTO, error) {
cacheKey := fmt.Sprintf("village:%s", id)
cachedData, err := utils.GetJSONData(cacheKey)
if err == nil && cachedData != nil {
var villageDTO dto.VillageResponseDTO
if data, ok := cachedData["data"].(map[string]interface{}); ok {
villageDTO = dto.VillageResponseDTO{
ID: data["id"].(string),
DistrictID: data["district_id"].(string),
Name: data["name"].(string),
}
return &villageDTO, nil
}
}
village, err := s.WilayahRepo.FindVillageByID(id)
if err != nil {
return nil, fmt.Errorf("village not found: %v", err)
}
villageDTO := &dto.VillageResponseDTO{
ID: village.ID,
DistrictID: village.DistrictID,
Name: village.Name,
}
cacheData := map[string]interface{}{
"data": villageDTO,
}
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
if err != nil {
fmt.Printf("Error caching village data to Redis: %v\n", err)
}
return villageDTO, nil
} }

View File

@ -3,7 +3,6 @@ package model
type Province struct { type Province struct {
ID string `gorm:"primaryKey;type:varchar(255);not null" json:"id"` ID string `gorm:"primaryKey;type:varchar(255);not null" json:"id"`
Name string `gorm:"type:varchar(255);not null" json:"name"` Name string `gorm:"type:varchar(255);not null" json:"name"`
Regencies []Regency `gorm:"foreignKey:ProvinceID" json:"regencies"` Regencies []Regency `gorm:"foreignKey:ProvinceID" json:"regencies"`
} }
@ -11,7 +10,6 @@ type Regency struct {
ID string `gorm:"primaryKey;type:varchar(255);not null" json:"id"` ID string `gorm:"primaryKey;type:varchar(255);not null" json:"id"`
ProvinceID string `gorm:"type:varchar(255);not null" json:"province_id"` ProvinceID string `gorm:"type:varchar(255);not null" json:"province_id"`
Name string `gorm:"type:varchar(255);not null" json:"name"` Name string `gorm:"type:varchar(255);not null" json:"name"`
Province Province `gorm:"foreignKey:ProvinceID" json:"province"` Province Province `gorm:"foreignKey:ProvinceID" json:"province"`
Districts []District `gorm:"foreignKey:RegencyID" json:"districts"` Districts []District `gorm:"foreignKey:RegencyID" json:"districts"`
} }
@ -20,7 +18,6 @@ type District struct {
ID string `gorm:"primaryKey;type:varchar(255);not null" json:"id"` ID string `gorm:"primaryKey;type:varchar(255);not null" json:"id"`
RegencyID string `gorm:"type:varchar(255);not null" json:"regency_id"` RegencyID string `gorm:"type:varchar(255);not null" json:"regency_id"`
Name string `gorm:"type:varchar(255);not null" json:"name"` Name string `gorm:"type:varchar(255);not null" json:"name"`
Regency Regency `gorm:"foreignKey:RegencyID" json:"regency"` Regency Regency `gorm:"foreignKey:RegencyID" json:"regency"`
Villages []Village `gorm:"foreignKey:DistrictID" json:"villages"` Villages []Village `gorm:"foreignKey:DistrictID" json:"villages"`
} }
@ -29,6 +26,5 @@ type Village struct {
ID string `gorm:"primaryKey;type:varchar(255);not null" json:"id"` ID string `gorm:"primaryKey;type:varchar(255);not null" json:"id"`
DistrictID string `gorm:"type:varchar(255);not null" json:"district_id"` DistrictID string `gorm:"type:varchar(255);not null" json:"district_id"`
Name string `gorm:"type:varchar(255);not null" json:"name"` Name string `gorm:"type:varchar(255);not null" json:"name"`
District District `gorm:"foreignKey:DistrictID" json:"district"` District District `gorm:"foreignKey:DistrictID" json:"district"`
} }

View File

@ -18,7 +18,7 @@ func WilayahRouter(api fiber.Router) {
wilayahAPI := api.Group("/wilayah-indonesia") wilayahAPI := api.Group("/wilayah-indonesia")
wilayahAPI.Get("/provinces", middleware.AuthMiddleware, wilayahHandler.GetAllProvinces) wilayahAPI.Get("/provinces", middleware.AuthMiddleware, wilayahHandler.GetProvinces)
wilayahAPI.Get("/provinces/:id", middleware.AuthMiddleware, wilayahHandler.GetProvinceByID) wilayahAPI.Get("/provinces/:id", middleware.AuthMiddleware, wilayahHandler.GetProvinceByID)
wilayahAPI.Get("/regencies", middleware.AuthMiddleware, wilayahHandler.GetAllRegencies) wilayahAPI.Get("/regencies", middleware.AuthMiddleware, wilayahHandler.GetAllRegencies)
@ -28,7 +28,6 @@ func WilayahRouter(api fiber.Router) {
wilayahAPI.Get("/districts/:id", middleware.AuthMiddleware, wilayahHandler.GetDistrictByID) wilayahAPI.Get("/districts/:id", middleware.AuthMiddleware, wilayahHandler.GetDistrictByID)
wilayahAPI.Get("/villages", middleware.AuthMiddleware, wilayahHandler.GetAllVillages) wilayahAPI.Get("/villages", middleware.AuthMiddleware, wilayahHandler.GetAllVillages)
wilayahAPI.Get("/villages/:id", middleware.AuthMiddleware, wilayahHandler.GetVillageByID)
api.Post("/import/data-wilayah-indonesia", middleware.AuthMiddleware, middleware.RoleMiddleware(utils.RoleAdministrator), wilayahHandler.ImportWilayahData) api.Post("/import/data-wilayah-indonesia", middleware.AuthMiddleware, middleware.RoleMiddleware(utils.RoleAdministrator), wilayahHandler.ImportWilayahData)
} }