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
import (
"fmt"
"strconv"
"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")
}
func (h *WilayahIndonesiaHandler) GetAllProvinces(c *fiber.Ctx) error {
page, err := strconv.Atoi(c.Query("page", "1"))
func (h *WilayahIndonesiaHandler) GetProvinces(c *fiber.Ctx) error {
page, err := strconv.Atoi(c.Query("page", "0"))
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 {
limit = 10
return utils.GenericErrorResponse(c, fiber.StatusInternalServerError, "Failed to fetch provinces")
}
provinces, err := h.WilayahService.GetAllProvinces(page, limit)
if err != nil {
return utils.GenericErrorResponse(c, fiber.StatusInternalServerError, fmt.Sprintf("Failed to fetch provinces: %v", err))
if page > 0 && limit > 0 {
return utils.PaginatedResponse(c, provinces, page, limit, totalProvinces, "Provinces fetched successfully")
}
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 {
provinceID := c.Params("id")
province, err := h.WilayahService.GetProvinceByID(provinceID)
page, err := strconv.Atoi(c.Query("page", "0"))
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 {
page, err := strconv.Atoi(c.Query("page", "1"))
page, err := strconv.Atoi(c.Query("page", "0"))
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 {
limit = 10
return utils.GenericErrorResponse(c, fiber.StatusInternalServerError, "Failed to fetch regency")
}
regencies, err := h.WilayahService.GetAllRegencies(page, limit)
if err != nil {
return utils.GenericErrorResponse(c, fiber.StatusInternalServerError, fmt.Sprintf("Failed to fetch regencies: %v", err))
if page > 0 && limit > 0 {
return utils.PaginatedResponse(c, regencies, page, limit, totalRegencies, "regency fetched successfully")
}
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 {
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 {
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 {
page, err := strconv.Atoi(c.Query("page", "1"))
page, err := strconv.Atoi(c.Query("page", "0"))
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 {
limit = 10
return utils.GenericErrorResponse(c, fiber.StatusInternalServerError, "Failed to fetch districts")
}
districts, err := h.WilayahService.GetAllDistricts(page, limit)
if err != nil {
return utils.GenericErrorResponse(c, fiber.StatusInternalServerError, fmt.Sprintf("Failed to fetch districts: %v", err))
if page > 0 && limit > 0 {
return utils.PaginatedResponse(c, districts, page, limit, totalDistricts, "districts fetched successfully")
}
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 {
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 {
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 {
page, err := strconv.Atoi(c.Query("page", "1"))
page, err := strconv.Atoi(c.Query("page", "0"))
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"))
villages, totalVillages, err := h.WilayahService.GetAllVillages(page, limit)
if err != nil {
limit = 10
return utils.GenericErrorResponse(c, fiber.StatusInternalServerError, "Failed to fetch villages")
}
villages, err := h.WilayahService.GetAllVillages(page, limit)
if err != nil {
return utils.GenericErrorResponse(c, fiber.StatusInternalServerError, fmt.Sprintf("Failed to fetch villages: %v", err))
if page > 0 && limit > 0 {
return utils.PaginatedResponse(c, villages, page, limit, totalVillages, "villages fetched successfully")
}
return utils.PaginatedResponse(c, villages, page, limit, len(villages), "Villages fetched successfully")
}
func (h *WilayahIndonesiaHandler) GetVillageByID(c *fiber.Ctx) error {
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")
return utils.NonPaginatedResponse(c, villages, totalVillages, "villages fetched successfully")
}

View File

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

View File

@ -1,7 +1,9 @@
package services
import (
"encoding/json"
"fmt"
"strconv"
"time"
"github.com/pahmiudahgede/senggoldong/dto"
@ -13,17 +15,16 @@ import (
type WilayahIndonesiaService interface {
ImportDataFromCSV() error
GetAllProvinces(page, limit int) ([]dto.ProvinceResponseDTO, error)
GetProvinceByID(id string) (*dto.ProvinceResponseDTO, error)
GetAllProvinces(page, limit int) ([]dto.ProvinceResponseDTO, int, error)
GetProvinceByID(id string, page, limit int) (*dto.ProvinceResponseDTO, int, error)
GetAllRegencies(page, limit int) ([]dto.RegencyResponseDTO, error)
GetRegencyByID(id string) (*dto.RegencyResponseDTO, error)
GetAllRegencies(page, limit int) ([]dto.RegencyResponseDTO, int, error)
GetRegencyByID(id string, page, limit int) (*dto.RegencyResponseDTO, int, error)
GetAllDistricts(page, limit int) ([]dto.DistrictResponseDTO, error)
GetDistrictByID(id string) (*dto.DistrictResponseDTO, error)
GetAllDistricts(page, limit int) ([]dto.DistrictResponseDTO, int, error)
GetDistrictByID(id string, page, limit int) (*dto.DistrictResponseDTO, int, error)
GetAllVillages(page, limit int) ([]dto.VillageResponseDTO, error)
GetVillageByID(id string) (*dto.VillageResponseDTO, error)
GetAllVillages(page, limit int) ([]dto.VillageResponseDTO, int, error)
}
type wilayahIndonesiaService struct {
@ -114,9 +115,9 @@ func (s *wilayahIndonesiaService) ImportDataFromCSV() error {
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)
if err == nil && cachedData != nil {
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)
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
@ -150,66 +152,68 @@ func (s *wilayahIndonesiaService) GetAllProvinces(page, limit int) ([]dto.Provin
cacheData := map[string]interface{}{
"data": provinceDTOs,
"total": total,
"page": page,
"limit": limit,
}
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
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)
if err == nil && cachedData != nil {
var province dto.ProvinceResponseDTO
if data, ok := cachedData["data"].(map[string]interface{}); ok {
province = dto.ProvinceResponseDTO{
ID: data["id"].(string),
Name: data["name"].(string),
var provinceDTO dto.ProvinceResponseDTO
if data, ok := cachedData["data"].(string); ok {
if err := json.Unmarshal([]byte(data), &provinceDTO); err == nil {
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 {
return nil, fmt.Errorf("failed to fetch province: %v", err)
return nil, 0, err
}
provinceDTO := &dto.ProvinceResponseDTO{
provinceDTO := dto.ProvinceResponseDTO{
ID: province.ID,
Name: province.Name,
}
regenciesDTO := []dto.RegencyResponseDTO{}
var regencyDTOs []dto.RegencyResponseDTO
for _, regency := range province.Regencies {
regenciesDTO = append(regenciesDTO, dto.RegencyResponseDTO{
regencyDTO := dto.RegencyResponseDTO{
ID: regency.ID,
ProvinceID: regency.ProvinceID,
Name: regency.Name,
})
}
regencyDTOs = append(regencyDTOs, regencyDTO)
}
provinceDTO.Regencies = regenciesDTO
provinceDTO.Regencies = regencyDTOs
cacheData := map[string]interface{}{
"data": provinceDTO,
"data": provinceDTO,
"total_regencies": strconv.Itoa(totalRegencies),
}
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
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)
if err == nil && cachedData != nil {
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)
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
@ -245,68 +250,69 @@ func (s *wilayahIndonesiaService) GetAllRegencies(page, limit int) ([]dto.Regenc
cacheData := map[string]interface{}{
"data": regencyDTOs,
"total": total,
"page": page,
"limit": limit,
}
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
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)
if err == nil && cachedData != nil {
var regency dto.RegencyResponseDTO
if data, ok := cachedData["data"].(map[string]interface{}); ok {
regency = dto.RegencyResponseDTO{
ID: data["id"].(string),
ProvinceID: data["province_id"].(string),
Name: data["name"].(string),
var regencyDTO dto.RegencyResponseDTO
if data, ok := cachedData["data"].(string); ok {
if err := json.Unmarshal([]byte(data), &regencyDTO); err == nil {
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 {
return nil, fmt.Errorf("failed to fetch regency: %v", err)
return nil, 0, err
}
regencyDTO := &dto.RegencyResponseDTO{
regencyDTO := dto.RegencyResponseDTO{
ID: regency.ID,
ProvinceID: regency.ProvinceID,
Name: regency.Name,
}
districtsDTO := []dto.DistrictResponseDTO{}
for _, district := range regency.Districts {
districtsDTO = append(districtsDTO, dto.DistrictResponseDTO{
ID: district.ID,
RegencyID: district.RegencyID,
Name: district.Name,
})
var districtDTOs []dto.DistrictResponseDTO
for _, regency := range regency.Districts {
districtDTO := dto.DistrictResponseDTO{
ID: regency.ID,
RegencyID: regency.RegencyID,
Name: regency.Name,
}
districtDTOs = append(districtDTOs, districtDTO)
}
regencyDTO.Districts = districtsDTO
regencyDTO.Districts = districtDTOs
cacheData := map[string]interface{}{
"data": regencyDTO,
"data": regencyDTO,
"total_regencies": strconv.Itoa(totalDistrict),
}
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
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)
if err == nil && cachedData != nil {
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)
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 {
districtDTOs = append(districtDTOs, dto.DistrictResponseDTO{
districtsDTOs = append(districtsDTOs, dto.DistrictResponseDTO{
ID: district.ID,
RegencyID: district.RegencyID,
Name: district.Name,
@ -340,70 +347,71 @@ func (s *wilayahIndonesiaService) GetAllDistricts(page, limit int) ([]dto.Distri
}
cacheData := map[string]interface{}{
"data": districtDTOs,
"data": districtsDTOs,
"total": total,
"page": page,
"limit": limit,
}
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
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)
if err == nil && cachedData != nil {
var district dto.DistrictResponseDTO
if data, ok := cachedData["data"].(map[string]interface{}); ok {
district = dto.DistrictResponseDTO{
ID: data["id"].(string),
RegencyID: data["regency_id"].(string),
Name: data["name"].(string),
var districtDTO dto.DistrictResponseDTO
if data, ok := cachedData["data"].(string); ok {
if err := json.Unmarshal([]byte(data), &districtDTO); err == nil {
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 {
return nil, fmt.Errorf("failed to fetch district: %v", err)
return nil, 0, err
}
districtDTO := &dto.DistrictResponseDTO{
districtDTO := dto.DistrictResponseDTO{
ID: district.ID,
RegencyID: district.RegencyID,
Name: district.Name,
}
villagesDTO := []dto.VillageResponseDTO{}
var villageDTOs []dto.VillageResponseDTO
for _, village := range district.Villages {
villagesDTO = append(villagesDTO, dto.VillageResponseDTO{
regencyDTO := dto.VillageResponseDTO{
ID: village.ID,
DistrictID: village.DistrictID,
Name: village.Name,
})
}
villageDTOs = append(villageDTOs, regencyDTO)
}
districtDTO.Villages = villagesDTO
districtDTO.Villages = villageDTOs
cacheData := map[string]interface{}{
"data": districtDTO,
"data": districtDTO,
"total_villages": strconv.Itoa(totalVillages),
}
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
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)
if err == nil && cachedData != nil {
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)
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
@ -442,46 +451,8 @@ func (s *wilayahIndonesiaService) GetAllVillages(page, limit int) ([]dto.Village
}
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
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
}
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
return villageDTOs, total, nil
}

View File

@ -1,34 +1,30 @@
package model
type Province struct {
ID string `gorm:"primaryKey;type:varchar(255);not null" json:"id"`
Name string `gorm:"type:varchar(255);not null" json:"name"`
ID string `gorm:"primaryKey;type:varchar(255);not null" json:"id"`
Name string `gorm:"type:varchar(255);not null" json:"name"`
Regencies []Regency `gorm:"foreignKey:ProvinceID" json:"regencies"`
}
type Regency struct {
ID string `gorm:"primaryKey;type:varchar(255);not null" json:"id"`
ProvinceID string `gorm:"type:varchar(255);not null" json:"province_id"`
Name string `gorm:"type:varchar(255);not null" json:"name"`
Province Province `gorm:"foreignKey:ProvinceID" json:"province"`
Districts []District `gorm:"foreignKey:RegencyID" json:"districts"`
ID string `gorm:"primaryKey;type:varchar(255);not null" json:"id"`
ProvinceID string `gorm:"type:varchar(255);not null" json:"province_id"`
Name string `gorm:"type:varchar(255);not null" json:"name"`
Province Province `gorm:"foreignKey:ProvinceID" json:"province"`
Districts []District `gorm:"foreignKey:RegencyID" json:"districts"`
}
type District struct {
ID string `gorm:"primaryKey;type:varchar(255);not null" json:"id"`
RegencyID string `gorm:"type:varchar(255);not null" json:"regency_id"`
Name string `gorm:"type:varchar(255);not null" json:"name"`
Regency Regency `gorm:"foreignKey:RegencyID" json:"regency"`
Villages []Village `gorm:"foreignKey:DistrictID" json:"villages"`
ID string `gorm:"primaryKey;type:varchar(255);not null" json:"id"`
RegencyID string `gorm:"type:varchar(255);not null" json:"regency_id"`
Name string `gorm:"type:varchar(255);not null" json:"name"`
Regency Regency `gorm:"foreignKey:RegencyID" json:"regency"`
Villages []Village `gorm:"foreignKey:DistrictID" json:"villages"`
}
type Village struct {
ID string `gorm:"primaryKey;type:varchar(255);not null" json:"id"`
DistrictID string `gorm:"type:varchar(255);not null" json:"district_id"`
Name string `gorm:"type:varchar(255);not null" json:"name"`
District District `gorm:"foreignKey:DistrictID" json:"district"`
ID string `gorm:"primaryKey;type:varchar(255);not null" json:"id"`
DistrictID string `gorm:"type:varchar(255);not null" json:"district_id"`
Name string `gorm:"type:varchar(255);not null" json:"name"`
District District `gorm:"foreignKey:DistrictID" json:"district"`
}

View File

@ -18,7 +18,7 @@ func WilayahRouter(api fiber.Router) {
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("/regencies", middleware.AuthMiddleware, wilayahHandler.GetAllRegencies)
@ -28,7 +28,6 @@ func WilayahRouter(api fiber.Router) {
wilayahAPI.Get("/districts/:id", middleware.AuthMiddleware, wilayahHandler.GetDistrictByID)
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)
}