459 lines
13 KiB
Go
459 lines
13 KiB
Go
package services
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/pahmiudahgede/senggoldong/dto"
|
|
"github.com/pahmiudahgede/senggoldong/internal/repositories"
|
|
"github.com/pahmiudahgede/senggoldong/model"
|
|
"github.com/pahmiudahgede/senggoldong/utils"
|
|
)
|
|
|
|
type WilayahIndonesiaService interface {
|
|
ImportDataFromCSV() 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, int, error)
|
|
GetRegencyByID(id string, page, limit int) (*dto.RegencyResponseDTO, int, 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, int, error)
|
|
}
|
|
|
|
type wilayahIndonesiaService struct {
|
|
WilayahRepo repositories.WilayahIndonesiaRepository
|
|
}
|
|
|
|
func NewWilayahIndonesiaService(wilayahRepo repositories.WilayahIndonesiaRepository) WilayahIndonesiaService {
|
|
return &wilayahIndonesiaService{WilayahRepo: wilayahRepo}
|
|
}
|
|
|
|
func (s *wilayahIndonesiaService) ImportDataFromCSV() error {
|
|
|
|
provinces, err := utils.ReadCSV("public/document/provinces.csv")
|
|
if err != nil {
|
|
return fmt.Errorf("failed to read provinces CSV: %v", err)
|
|
}
|
|
|
|
var provinceList []model.Province
|
|
for _, record := range provinces[1:] {
|
|
province := model.Province{
|
|
ID: record[0],
|
|
Name: record[1],
|
|
}
|
|
provinceList = append(provinceList, province)
|
|
}
|
|
|
|
if err := s.WilayahRepo.ImportProvinces(provinceList); err != nil {
|
|
return fmt.Errorf("failed to import provinces: %v", err)
|
|
}
|
|
|
|
regencies, err := utils.ReadCSV("public/document/regencies.csv")
|
|
if err != nil {
|
|
return fmt.Errorf("failed to read regencies CSV: %v", err)
|
|
}
|
|
|
|
var regencyList []model.Regency
|
|
for _, record := range regencies[1:] {
|
|
regency := model.Regency{
|
|
ID: record[0],
|
|
ProvinceID: record[1],
|
|
Name: record[2],
|
|
}
|
|
regencyList = append(regencyList, regency)
|
|
}
|
|
|
|
if err := s.WilayahRepo.ImportRegencies(regencyList); err != nil {
|
|
return fmt.Errorf("failed to import regencies: %v", err)
|
|
}
|
|
|
|
districts, err := utils.ReadCSV("public/document/districts.csv")
|
|
if err != nil {
|
|
return fmt.Errorf("failed to read districts CSV: %v", err)
|
|
}
|
|
|
|
var districtList []model.District
|
|
for _, record := range districts[1:] {
|
|
district := model.District{
|
|
ID: record[0],
|
|
RegencyID: record[1],
|
|
Name: record[2],
|
|
}
|
|
districtList = append(districtList, district)
|
|
}
|
|
|
|
if err := s.WilayahRepo.ImportDistricts(districtList); err != nil {
|
|
return fmt.Errorf("failed to import districts: %v", err)
|
|
}
|
|
|
|
villages, err := utils.ReadCSV("public/document/villages.csv")
|
|
if err != nil {
|
|
return fmt.Errorf("failed to read villages CSV: %v", err)
|
|
}
|
|
|
|
var villageList []model.Village
|
|
for _, record := range villages[1:] {
|
|
village := model.Village{
|
|
ID: record[0],
|
|
DistrictID: record[1],
|
|
Name: record[2],
|
|
}
|
|
villageList = append(villageList, village)
|
|
}
|
|
|
|
if err := s.WilayahRepo.ImportVillages(villageList); err != nil {
|
|
return fmt.Errorf("failed to import villages: %v", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *wilayahIndonesiaService) GetAllProvinces(page, limit int) ([]dto.ProvinceResponseDTO, int, error) {
|
|
|
|
cacheKey := fmt.Sprintf("provinces_page:%d_limit:%d", page, limit)
|
|
cachedData, err := utils.GetJSONData(cacheKey)
|
|
if err == nil && cachedData != nil {
|
|
var provinces []dto.ProvinceResponseDTO
|
|
if data, ok := cachedData["data"].([]interface{}); ok {
|
|
for _, item := range data {
|
|
province, ok := item.(map[string]interface{})
|
|
if ok {
|
|
provinces = append(provinces, dto.ProvinceResponseDTO{
|
|
ID: province["id"].(string),
|
|
Name: province["name"].(string),
|
|
})
|
|
}
|
|
}
|
|
total := int(cachedData["total"].(float64))
|
|
return provinces, total, nil
|
|
}
|
|
}
|
|
|
|
provinces, total, err := s.WilayahRepo.FindAllProvinces(page, limit)
|
|
if err != nil {
|
|
return nil, 0, fmt.Errorf("failed to fetch provinces: %v", err)
|
|
}
|
|
|
|
var provinceDTOs []dto.ProvinceResponseDTO
|
|
for _, province := range provinces {
|
|
provinceDTOs = append(provinceDTOs, dto.ProvinceResponseDTO{
|
|
ID: province.ID,
|
|
Name: province.Name,
|
|
})
|
|
}
|
|
|
|
cacheData := map[string]interface{}{
|
|
"data": provinceDTOs,
|
|
"total": total,
|
|
}
|
|
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
|
|
if err != nil {
|
|
fmt.Printf("Error caching provinces data: %v\n", err)
|
|
}
|
|
|
|
return provinceDTOs, total, nil
|
|
}
|
|
|
|
func (s *wilayahIndonesiaService) GetProvinceByID(id string, page, limit int) (*dto.ProvinceResponseDTO, int, error) {
|
|
|
|
cacheKey := fmt.Sprintf("province:%s_page:%d_limit:%d", id, page, limit)
|
|
cachedData, err := utils.GetJSONData(cacheKey)
|
|
if err == nil && cachedData != nil {
|
|
|
|
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
|
|
}
|
|
}
|
|
}
|
|
|
|
province, totalRegencies, err := s.WilayahRepo.FindProvinceByID(id, page, limit)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
provinceDTO := dto.ProvinceResponseDTO{
|
|
ID: province.ID,
|
|
Name: province.Name,
|
|
}
|
|
|
|
var regencyDTOs []dto.RegencyResponseDTO
|
|
for _, regency := range province.Regencies {
|
|
regencyDTO := dto.RegencyResponseDTO{
|
|
ID: regency.ID,
|
|
ProvinceID: regency.ProvinceID,
|
|
Name: regency.Name,
|
|
}
|
|
regencyDTOs = append(regencyDTOs, regencyDTO)
|
|
}
|
|
|
|
provinceDTO.Regencies = regencyDTOs
|
|
|
|
cacheData := map[string]interface{}{
|
|
"data": provinceDTO,
|
|
"total_regencies": strconv.Itoa(totalRegencies),
|
|
}
|
|
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
|
|
if err != nil {
|
|
fmt.Printf("Error caching province data: %v\n", err)
|
|
}
|
|
|
|
return &provinceDTO, totalRegencies, nil
|
|
}
|
|
|
|
func (s *wilayahIndonesiaService) GetAllRegencies(page, limit int) ([]dto.RegencyResponseDTO, int, error) {
|
|
|
|
cacheKey := fmt.Sprintf("regencies_page:%d_limit:%d", page, limit)
|
|
cachedData, err := utils.GetJSONData(cacheKey)
|
|
if err == nil && cachedData != nil {
|
|
var regencies []dto.RegencyResponseDTO
|
|
if data, ok := cachedData["data"].([]interface{}); ok {
|
|
for _, item := range data {
|
|
regency, ok := item.(map[string]interface{})
|
|
if ok {
|
|
regencies = append(regencies, dto.RegencyResponseDTO{
|
|
ID: regency["id"].(string),
|
|
ProvinceID: regency["province_id"].(string),
|
|
Name: regency["name"].(string),
|
|
})
|
|
}
|
|
}
|
|
total := int(cachedData["total"].(float64))
|
|
return regencies, total, nil
|
|
}
|
|
}
|
|
|
|
regencies, total, err := s.WilayahRepo.FindAllRegencies(page, limit)
|
|
if err != nil {
|
|
return nil, 0, fmt.Errorf("failed to fetch provinces: %v", err)
|
|
}
|
|
|
|
var regencyDTOs []dto.RegencyResponseDTO
|
|
for _, regency := range regencies {
|
|
regencyDTOs = append(regencyDTOs, dto.RegencyResponseDTO{
|
|
ID: regency.ID,
|
|
ProvinceID: regency.ProvinceID,
|
|
Name: regency.Name,
|
|
})
|
|
}
|
|
|
|
cacheData := map[string]interface{}{
|
|
"data": regencyDTOs,
|
|
"total": total,
|
|
}
|
|
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
|
|
if err != nil {
|
|
fmt.Printf("Error caching regencies data: %v\n", err)
|
|
}
|
|
|
|
return regencyDTOs, total, nil
|
|
}
|
|
|
|
func (s *wilayahIndonesiaService) GetRegencyByID(id string, page, limit int) (*dto.RegencyResponseDTO, int, error) {
|
|
|
|
cacheKey := fmt.Sprintf("regency:%s_page:%d_limit:%d", id, page, limit)
|
|
cachedData, err := utils.GetJSONData(cacheKey)
|
|
if err == nil && cachedData != nil {
|
|
|
|
var regencyDTO dto.RegencyResponseDTO
|
|
if data, ok := cachedData["data"].(string); ok {
|
|
if err := json.Unmarshal([]byte(data), ®encyDTO); err == nil {
|
|
|
|
totalDistrict, _ := strconv.Atoi(cachedData["total_regencies"].(string))
|
|
return ®encyDTO, totalDistrict, nil
|
|
}
|
|
}
|
|
}
|
|
|
|
regency, totalDistrict, err := s.WilayahRepo.FindRegencyByID(id, page, limit)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
regencyDTO := dto.RegencyResponseDTO{
|
|
ID: regency.ID,
|
|
ProvinceID: regency.ProvinceID,
|
|
Name: regency.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 = districtDTOs
|
|
|
|
cacheData := map[string]interface{}{
|
|
"data": regencyDTO,
|
|
"total_regencies": strconv.Itoa(totalDistrict),
|
|
}
|
|
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
|
|
if err != nil {
|
|
fmt.Printf("Error caching province data: %v\n", err)
|
|
}
|
|
|
|
return ®encyDTO, totalDistrict, nil
|
|
}
|
|
|
|
func (s *wilayahIndonesiaService) GetAllDistricts(page, limit int) ([]dto.DistrictResponseDTO, int, error) {
|
|
|
|
cacheKey := fmt.Sprintf("district_page:%d_limit:%d", page, limit)
|
|
cachedData, err := utils.GetJSONData(cacheKey)
|
|
if err == nil && cachedData != nil {
|
|
var districts []dto.DistrictResponseDTO
|
|
if data, ok := cachedData["data"].([]interface{}); ok {
|
|
for _, item := range data {
|
|
district, ok := item.(map[string]interface{})
|
|
if ok {
|
|
districts = append(districts, dto.DistrictResponseDTO{
|
|
ID: district["id"].(string),
|
|
RegencyID: district["regency_id"].(string),
|
|
Name: district["name"].(string),
|
|
})
|
|
}
|
|
}
|
|
total := int(cachedData["total"].(float64))
|
|
return districts, total, nil
|
|
}
|
|
}
|
|
|
|
districts, total, err := s.WilayahRepo.FindAllDistricts(page, limit)
|
|
if err != nil {
|
|
return nil, 0, fmt.Errorf("failed to fetch districts: %v", err)
|
|
}
|
|
|
|
var districtsDTOs []dto.DistrictResponseDTO
|
|
for _, district := range districts {
|
|
districtsDTOs = append(districtsDTOs, dto.DistrictResponseDTO{
|
|
ID: district.ID,
|
|
RegencyID: district.RegencyID,
|
|
Name: district.Name,
|
|
})
|
|
}
|
|
|
|
cacheData := map[string]interface{}{
|
|
"data": districtsDTOs,
|
|
"total": total,
|
|
}
|
|
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
|
|
if err != nil {
|
|
fmt.Printf("Error caching districts data: %v\n", err)
|
|
}
|
|
|
|
return districtsDTOs, total, nil
|
|
}
|
|
|
|
func (s *wilayahIndonesiaService) GetDistrictByID(id string, page, limit int) (*dto.DistrictResponseDTO, int, error) {
|
|
|
|
cacheKey := fmt.Sprintf("district:%s_page:%d_limit:%d", id, page, limit)
|
|
cachedData, err := utils.GetJSONData(cacheKey)
|
|
if err == nil && cachedData != nil {
|
|
|
|
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
|
|
}
|
|
}
|
|
}
|
|
|
|
district, totalVillages, err := s.WilayahRepo.FindDistrictByID(id, page, limit)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
districtDTO := dto.DistrictResponseDTO{
|
|
ID: district.ID,
|
|
RegencyID: district.RegencyID,
|
|
Name: district.Name,
|
|
}
|
|
|
|
var villageDTOs []dto.VillageResponseDTO
|
|
for _, village := range district.Villages {
|
|
regencyDTO := dto.VillageResponseDTO{
|
|
ID: village.ID,
|
|
DistrictID: village.DistrictID,
|
|
Name: village.Name,
|
|
}
|
|
villageDTOs = append(villageDTOs, regencyDTO)
|
|
}
|
|
|
|
districtDTO.Villages = villageDTOs
|
|
|
|
cacheData := map[string]interface{}{
|
|
"data": districtDTO,
|
|
"total_villages": strconv.Itoa(totalVillages),
|
|
}
|
|
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
|
|
if err != nil {
|
|
fmt.Printf("Error caching province data: %v\n", err)
|
|
}
|
|
|
|
return &districtDTO, totalVillages, nil
|
|
}
|
|
|
|
func (s *wilayahIndonesiaService) GetAllVillages(page, limit int) ([]dto.VillageResponseDTO, int, error) {
|
|
|
|
cacheKey := fmt.Sprintf("villages_page:%d_limit:%d", page, limit)
|
|
cachedData, err := utils.GetJSONData(cacheKey)
|
|
if err == nil && cachedData != nil {
|
|
var villages []dto.VillageResponseDTO
|
|
if data, ok := cachedData["data"].([]interface{}); ok {
|
|
for _, item := range data {
|
|
village, ok := item.(map[string]interface{})
|
|
if ok {
|
|
villages = append(villages, dto.VillageResponseDTO{
|
|
ID: village["id"].(string),
|
|
DistrictID: village["district_id"].(string),
|
|
Name: village["name"].(string),
|
|
})
|
|
}
|
|
}
|
|
total := int(cachedData["total"].(float64))
|
|
return villages, total, nil
|
|
}
|
|
}
|
|
|
|
villages, total, err := s.WilayahRepo.FindAllVillages(page, limit)
|
|
if err != nil {
|
|
return nil, 0, fmt.Errorf("failed to fetch villages: %v", err)
|
|
}
|
|
|
|
var villageDTOs []dto.VillageResponseDTO
|
|
for _, village := range villages {
|
|
villageDTOs = append(villageDTOs, dto.VillageResponseDTO{
|
|
ID: village.ID,
|
|
DistrictID: village.DistrictID,
|
|
Name: village.Name,
|
|
})
|
|
}
|
|
|
|
cacheData := map[string]interface{}{
|
|
"data": villageDTOs,
|
|
"total": total,
|
|
}
|
|
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
|
|
if err != nil {
|
|
fmt.Printf("Error caching villages data: %v\n", err)
|
|
}
|
|
|
|
return villageDTOs, total, nil
|
|
}
|