Peach's CODE peach

공부한 내용을 정리중입니다. 틀린 내용이 있을 수 있습니다 : )

코딩하는 딱복

[API] 공공데이터포털-특일 정보 본문

API 📜

[API] 공공데이터포털-특일 정보

yundi 2024. 4. 4. 14:10

오늘은 고객사에서 상품을 주문하면 공휴일이나 주말일 때는 다음 영업일로 상품 발송 예정일을 띄워주고 싶다고 해서 공휴일 API를 사용해보았다.

 

물론 고객사 자체 휴무일이나 택배사 관련으로 휴무일을 지정해야한다면 휴무일을 다룰 수 있도록 개발하면 좋겠지만 고객사에서는 그것까진 필요하지 않다고 하니,, 공휴일 데이터를 가져와서 DB에 넣어주고 결제완료된 날짜를 가져와 공휴일인지 체크하도록 구현했다.

 

샘플코드에 여러 언어가 있어 사용하기에는 간편했다!

 

한국천문연구원_특일 정보

(천문우주정보)국경일정보, 공휴일정보, 기념일정보, 24절기정보, 잡절정보를 조회하는 서비스 입니다. 활용시 날짜, 순번, 특일정보의 분류, 공공기관 휴일 여부, 명칭을 확인할 수 있습니다.

www.data.go.kr

 

📦 Component

   
    protected $service_key = '발급받은키';
   
    public $data = array();
   
    public function __construct () {
       
    }
   
    public function __destruct () {
       
    }
        /**
     * holiday
     *
     * 공휴일 데이터 리턴
     *
     * @param   int     $year     4 length
     * @param   int     $month    2 length
     */
    public function holiday ($year,$month) {
        $path = $content = $day = '';
        $data = $xml = $json = $list = array();
       
        $month = sprintf('%02d',$month);
       
        $path = $this->url.'getHoliDeInfo?serviceKey='.$this->service_key.'&solYear='.$year.'&solMonth='.$month;
        $content = file_get_contents($path);
        $xml = simplexml_load_string($content,null,LIBXML_NOCDATA);
        $json = json_encode($xml);
        $list = json_decode($json,TRUE);
       
        if ($list['body']['totalCount'] == 1) {
            $day = mb_substr($list['body']['items']['item']['locdate'],6,2,'UTF-8');
           
            $this->data[$day][] = $data['data'][$day][] = array(
                'date'=>$year.'-'.$month.'-'.$day,
                'name'=>$list['body']['items']['item']['dateName'],
                'category'=>'holiday'
            );
        } else if ($list['body']['totalCount'] > 0) {
            foreach ($list['body']['items']['item'] as $row) {
                $day = mb_substr($row['locdate'],6,2,'UTF-8');
               
                $this->data[$day][] = $data['data'][$day][] = array(
                    'date'=>$year.'-'.$month.'-'.$day,
                    'name'=>$row['dateName'],
                    'category'=>'holiday'
                );
            }
        }
       
        return $data;
    }

데이터를 가공해서 날짜, 공휴일 이름, 카테고리가 들어갈 수 있게 해두었다.

 

🎮 Controller

class HolidayController extends \Controller\Api\Controller
{
    public function index()
    {
        $db = \App::load('DB');
        $holidayData = new HolidayData();
        $allHolidayData = array();

        // 시작 연도와 월
        $startYear = 2024;
        $startMonth = 1;

        // 종료 연도와 월
        $endYear = 2025;
        $endMonth = 12;

        for ($year = $startYear; $year <= $endYear; $year++) {
            // 시작 연도일 때는 시작 월부터, 종료 연도일 때는 종료 월까지 반복
            $start = ($year == $startYear) ? $startMonth : 1;
            $end = ($year == $endYear) ? $endMonth : 12;

            for ($month = $start; $month <= $end; $month++) {
                $allHolidayData[] = $holidayData->holiday($year, $month);
            }
        }
        foreach ($allHolidayData as $item) {
            foreach ($item['data'] as $day => $data) {
                foreach ($data as $info) {
                    $date = $info['date']; // 날짜
                    $name = $info['name']; // 이름

                    $sql = "INSERT INTO asmo_calendar (holiday, name) VALUES ('$date', '$name')";
                    $db->query($sql);
                }
            }
        }
    }
}

컨트롤러를 만들다 보니 카테고리는 필요 없을 것 같아서 DB에 따로 넣어주진 않았다..

데이터는 25년도까지만 존재했다!

🛢️  DB

DB에 저장 완료!

뭔가 코드가 깔끔하지 않은 것 같지만,,, 물어볼 사람이 없는 나는 오늘도 혼자 해결하고,,, 성장하는중,,,, ?

 

이제 결제가 완료되었을 때 발송 예정일을 넣기 위한 메소드를 Order 컴포넌트에 만들어 주고 이 메소드를 불러서 사용하면 끝이다!

    //20240328 lyj 배송 예정일 계산하기
    public function insertDeliveryDt($orderNo)
    {
        $sql = "SELECT paymentDt FROM es_order WHERE orderNo = '".$orderNo."'";
        list($paymentDt) = $this->db->query_fetch($sql);

        //결제 날자를 날짜와 시간으로 분리
        $paymentDateTime = $paymentDt['paymentDt'];
        list($paymentDate, $paymentTime) = explode(' ', $paymentDateTime);

        //결제일이 무슨 요일인지 확인 (토,일은 각각 6,7 이다.)
        $weekday = date('N', strtotime($paymentDate));

        //공휴일 테이블에 결제날짜가 있는지 확인한다.
        $sql_str= "SELECT sno FROM asmo_calendar WHERE holiday = '".$paymentDate."'";
        list($isHoilday) = $this->db->query_fetch($sql_str);

        //결제날짜가 공휴일이 아닌 평일 오후 1시 이전결제일 때
        if(($weekday >= 1 && $weekday <= 5) && ($paymentTime <= '13:00:59') && !$isHoilday) {
            $deliveryDate = date('Y-m-d');
        } else {
            // 결제날짜가 주말, 공휴일, 오후1시 이후 일 때 다음 영업일로 배송 예정일 설정
            $nextDay = strtotime($paymentDate . '+1 day');
            while (true) {
                // 다음 날짜가 주말이나 공휴일인 경우 다음 날짜로 이동
                $nextDayDate = date('Y-m-d', $nextDay);
                $nextDayWeekday = date('N', $nextDay);
                $sql_str = "SELECT sno FROM asmo_calendar WHERE holiday = '".$nextDayDate."'";
                list($isHoliday) = $this->db->query_fetch($sql_str);
                if ($nextDayWeekday >= 6 || $isHoliday) {
                    // 주말이나 공휴일이면 다음 날짜로 이동
                    $nextDay = strtotime($nextDayDate . '+1 day');
                } else {
                    break;
                }
            }
            $deliveryDate = date('Y-m-d', $nextDay);
        }

        //다음 상품 배송 예정일
        $nextMonth = strtotime($paymentDate . '+1 month');
        while (true) {
            // 다음 날짜가 주말이나 공휴일인 경우 다음 날짜로 이동
            $nextMonthDate = date('Y-m-d', $nextMonth);
            $nextMonthWeekday = date('N', $nextMonth);
            $sql_str = "SELECT sno FROM asmo_calendar WHERE holiday = '".$nextMonthDate."'";
            list($isHoliday) = $this->db->query_fetch($sql_str);
            if ($nextMonthWeekday >= 6 || $isHoliday) {
                // 주말이나 공휴일이면 다음 날짜로 이동
                $nextMonth = strtotime($nextMonthDate . '+1 day');
            } else {
                break;
            }
        }
        $deliveryDtNextMonth = date('Y-m-d', $nextMonth);

        //주문테이블 업데이트
        $sql_str2 = "UPDATE es_order SET
                originDeliveryDt = '".$deliveryDate."',
                realDeliveryDt = '".$deliveryDtNextMonth."'
                WHERE orderNo='".$orderNo."'";

        $this->db->query($sql_str2);
    }

 

학원 다닐 때 기본에 충실하겠다고 api 사용을 안해봤는데,, 회사와서 나름 조금씩 사용하니까 재밌는 것 같다 ㅎㅎ

'API 📜' 카테고리의 다른 글

[API] 카카오맵 사용하기  (0) 2024.02.21