<?php
namespace App\Models\article;

use App\Models\common\CodeModel;
use CodeIgniter\Model;

class ReceiptModel extends Model
{
    // 지역 목록 조회
    public function getAreaList($sido = '', $gugun = '')
    {

        if (!empty($gugun)) {
            $gugun = substr($gugun, '0', '5');

            $sql = "SELECT a.region_cd, TRIM(REPLACE(a.region_nm, b.region_nm, '')) region_nm" .
                " FROM region_codes a" .
                " LEFT JOIN region_codes b ON b.region_cd = CONCAT(SUBSTR(a.region_cd,1,5),'00000')" .
                " WHERE a.region_cd LIKE concat(?, '%')" .
                " AND a.region_cd NOT LIKE '%00000'" .
                " AND a.region_cd LIKE '%00'" .
                " AND a.use_yn = 'Y'" .
                " ORDER BY a.region_nm ASC";

            $query = $this->db->query($sql, [$gugun]);

        } else if (!empty($sido)) {
            $chk_sido = substr($sido, '0', '2');

            if ($chk_sido === '36') {
                $sido = substr($sido, '0', '4');
                $sql = "SELECT a.region_cd, TRIM(REPLACE(a.region_nm, b.region_nm, '')) region_nm " .
                    "FROM region_codes a " .
                    "LEFT JOIN region_codes b ON b.region_cd = CONCAT(SUBSTR(a.region_cd,1,4),'000000') " .
                    "WHERE a.region_cd LIKE concat(?, '%') " .
                    "AND a.region_cd NOT LIKE '%000000' " .
                    "AND a.region_cd LIKE '%00' " .
                    "AND a.use_yn = 'Y' " .
                    "AND EXISTS (SELECT 'x' FROM region_codes c WHERE c.region_cd LIKE CONCAT(SUBSTR(a.region_cd,1,5),'%') AND c.region_cd > CONCAT(SUBSTR(a.region_cd,1,5),'00000')) " .
                    "ORDER BY a.region_nm ASC";
            } else {
                $sido = substr($sido, '0', '2');
                $sql = "SELECT a.region_cd, TRIM(REPLACE(a.region_nm, b.region_nm, '')) region_nm" .
                    " FROM region_codes a" .
                    " LEFT JOIN region_codes b ON b.region_cd = CONCAT(SUBSTR(a.region_cd,1,2),'00000000')" .
                    " WHERE a.region_cd LIKE concat(?, '%')" .
                    " AND a.region_cd NOT LIKE '%00000000'" .
                    " AND a.region_cd LIKE '%00000'" .
                    " AND a.use_yn = 'Y'" .
                    " AND EXISTS (SELECT 'x' FROM region_codes c WHERE c.region_cd LIKE CONCAT(SUBSTR(a.region_cd,1,5),'%') AND c.region_cd > CONCAT(SUBSTR(a.region_cd,1,5),'00000'))" .
                    " ORDER BY a.region_nm ASC";
            }

            $query = $this->db->query($sql, [$sido]);
        } else {
            $sql = "SELECT a.region_cd, a.region_nm " .
                "FROM region_codes a " .
                "WHERE (a.region_cd LIKE '%00000000' " .
                "AND a.use_yn = 'Y') " .
                "OR region_cd = 3611000000;";

            $query = $this->db->query($sql);
        }


        return $query->getResultArray();
    }

    // 소속본부조회
    public function getBonbuList()
    {
        $sql = "SELECT dept_sq, pdept_sq, dept_nm, dept_desc, dept_head, use_yn, depth, insert_tm, insert_usr, update_tm, update_usr, lft, rgt" .
            "  FROM departments" .
            " WHERE depth = 1" .
            "   AND use_yn = 'Y'" .
            " ORDER BY lft";

        $query = $this->db->query($sql);


        return $query->getResultArray();
    }

    // 소속팀 조회
    public function getTeamList()
    {
        $sql = "SELECT dept_sq, pdept_sq, dept_nm" .
            "  FROM departments" .
            " WHERE depth = 2" .
            "   AND use_yn = 'Y'" .
            " ORDER BY dept_nm";

        $query = $this->db->query($sql);


        return $query->getResultArray();
    }

    // 유저 조회
    public function getUserList()
    {
        $sql = "SELECT 
                    a.usr_sq, a.usr_id, a.usr_nm, a.dept_sq
                FROM users a
                WHERE 
                        a.usr_level IN ('3','4','40','5','50','6','60','61','62','7','8','70')
                        AND a.use_yn = 'Y'
                        AND EXISTS (
                        SELECT 'x' FROM departments a1 INNER JOIN departments a2 ON a2.lft BETWEEN a1.lft AND a1.rgt AND a2.use_yn = 'Y' 
                        WHERE 1=1 AND a2.dept_sq = a.dept_sq AND a1.use_yn = 'Y'
                )
                ORDER BY a.usr_level DESC, a.usr_nm ASC ";

        $query = $this->db->query($sql);

        return $query->getResultArray();
    }

    public function getSrchUserInfo($usr_id)
    {
        $sql = "SELECT a.usr_sq, a.usr_id, b.dept_sq, b.pdept_sq FROM users a
                JOIN departments b ON b.dept_sq = a.dept_sq
                WHERE a.usr_id = ? AND a.use_yn = 'Y'";

        $data = [$usr_id];
        $query = $this->db->query($sql, $data);
        $row = $query->getRowArray();

        return $row;
    }

    /**
     * 부서검색(상세)
     */
    public function getDeptDetail($dept_sq)
    {
        $sql = "SELECT dept_sq, pdept_sq, dept_nm, dept_desc, dept_head, use_yn, depth, insert_tm, insert_usr, update_tm, update_usr, lft, rgt" .
            "  FROM departments" .
            " WHERE dept_sq = ?";

        $data = [$dept_sq];
        $query = $this->db->query($sql, $data);
        $row = $query->getRowArray();

        return $row;
    }

    /**
     * 하위 부서 검색
     */
    public function getChildDept($dept)
    {
        $sql = "SELECT dept_sq, pdept_sq, dept_nm, dept_desc, dept_head, use_yn, depth, insert_tm, insert_usr, update_tm, update_usr, lft, rgt" .
            "  FROM departments" .
            " WHERE lft >= ?" .
            "   AND rgt <= ?" .
            " ORDER BY lft ASC";

        $data = [$dept['lft'], $dept['rgt']];
        $query = $this->db->query($sql, $data);

        return $query->getResultArray();
    }

    /**
     * 사용자 상세정보
     */
    public function getUserDetail($usr_sq)
    {
        $builder = $this->db->table('users a');

        $builder->select("
            a.usr_sq,
            a.dept_sq,
            a.usr_id,
            a.usr_nm,
            a.usr_level,
            a.usr_tel1,
            a.usr_tel2,
            b.dept_nm
        ", false);

        $builder->join('departments b', 'a.dept_sq = b.dept_sq', 'left');
        $builder->where('a.usr_sq', $usr_sq);

        return $builder->get()->getRowArray();

    }

    public function getTotalCount($data)
    {
        $usr_sq = session('usr_sq');
        $usr_level = session('usr_level');
        $dept_sq = session('dept_sq');

        $builder = $this->db->table('receipt a');

        $builder->select("COUNT(*) AS cnt", false);

        $builder->join('result b', 'b.rcpt_sq = a.rcpt_sq', 'inner');
        $builder->join('region_codes c', 'a.rcpt_dong = c.region_cd', 'left');
        $builder->join('departments d', 'b.dept_sq = d.dept_sq', 'left');
        $builder->join('users u', 'b.usr_sq = u.usr_sq', 'left');
        $builder->join('result_imgs e', "e.rsrv_sq = b.rsrv_sq AND e.img_type = 'I1' AND e.use_yn = 'Y'", 'left');
        $builder->join('receipt_transimage_log l', 'a.rcpt_key = l.rcpt_key', 'left');


        $login_dept_info = $this->getDeptDetail($dept_sq);	// 로그인 사용자 소속부서정보
        $child_dept = [];													// 하위조직 목록
        if (strcmp($usr_level, '40') == 0) {
            $child = $this->getChildDept($login_dept_info);
            if (!empty($child)) {
                foreach ($child as $child) {
                    $child_dept[] = $child['dept_sq'];
                }
            }
        }

        if ((int) $usr_level >= 4 && $usr_level != '45') {
            if (!empty($child_dept)) {
                $builder->whereIn('b.dept_sq', $child_dept);
            } else {
                $builder->where('b.usr_sq', $usr_sq);
            }
        }

        $builder->where('a.rcpt_tm >= DATE_ADD(CURDATE(), INTERVAL -3 MONTH)', null, false);
        $builder->where('b.use_yn', 'Y');

        if (!empty($data['rcpt_atclno'])) {
            $builder->where('a.rcpt_atclno', $data['rcpt_atclno']);
        } else {
            if ($data['schDateGb'] == '2') {
                $builder->where('a.rcpt_tm >=', $data['sdate'] . ' 00:00:00');
                $builder->where('a.rcpt_tm <=', $data['edate'] . ' 23:59:59');
            } else {
                $builder->where('b.rsrv_date >=', $data['sdate'] . ' 00:00:00');
                $builder->where('b.rsrv_date <=', $data['edate'] . ' 23:59:59');
            }

            // 지역
            if (!empty($data['dong'])) {
                $builder->where('a.rcpt_dong', $data['dong']);
            } else {
                if (!empty($data['gugun'])) {
                    $builder->like('a.rcpt_gugun', substr($data['gugun'], 0, 5), 'after');
                } else {
                    if (!empty($data['sido'])) {
                        $builder->like('a.rcpt_gugun', substr($data['sido'], 0, 2), 'after');
                    }
                }
            }

            // 관할조직
            if (!empty($data['bonbu'])) {
                $builder->where('d.pdept_sq', $data['bonbu']);
            }

            if (!empty($data['team'])) {
                $builder->where('d.dept_sq', $data['team']);
            }

            if (!empty($data['user'])) {
                $builder->where('d.usr_sq', $data['user']);
            }

            // 거래구분
            if (!empty($data['rcpt_product_info1'])) {
                $builder->where('a.rcpt_product_info1', $data['rcpt_product_info1']);
            }

            // 현재상태
            if (!empty($data['rcpt_stat1'])) {
                $builder->like('a.rcpt_stat', $data['rcpt_stat1'], 'after');
            }

            if (!empty($data['rcpt_stat2'])) {
                $builder->like('a.rcpt_stat', $data['rcpt_stat2'], 'after');
            }

            if (!empty($data['rcpt_stat3'])) {
                $builder->where('a.rcpt_stat', $data['rcpt_stat3']);
            }

            // 중개사명
            if (!empty($data['agent_nm'])) {
                $builder->like('a.agent_nm', $data['agent_nm'], 'both');
            }

            // 동영상촬영여부
            if (!empty($data['exp_movie_yn'])) {
                $builder->where('a.exp_movie_yn', $data['exp_movie_yn']);
            }

            // 홍보확인서여부
            if ($data['conf_img_yn'] == 'Y') {
                $builder->where('e.rsrv_sq IS NOT NULL', null, false);
            } else if ($data['conf_img_yn'] == 'N') {
                $builder->where('e.rsrv_sq IS NULL', null, false);
            }

            // 분양권
            if ($data['parcel_out_yn'] == 'Y') {
                $builder->where('a.parcel_out_yn', 'Y');
            } else if ($data['parcel_out_yn'] == 'N') {
                $builder->where('a.parcel_out_yn', 'N');
            }

            // CP ID
            if (!empty($data['rcpt_cpid'])) {
                if (strcmp($data['rcpt_cpid'], 'naver') == 0) {
                    $builder->where('a.rcpt_cpid =', '');
                } else if (strcmp($data['rcpt_cpid'], 'cleancente') == 0) {
                    $builder->where("a.rcpt_cpid !=", "");
                } else {
                    $builder->where('a.rcpt_cpid', $data['rcpt_cpid']);
                }
            }

            // 매물종류
            if (!empty($data['rcpt_product'])) {
                $builder->where('a.parcel_out_yn', $data['rcpt_product']);
            }

            // 면적확인
            if ($data['exp_spc_yn'] == 'Y') {
                $builder->where('a.parcel_out_yn', 'Y');
            } else if ($data['exp_spc_yn'] == 'N') {
                $builder->where('a.parcel_out_yn', 'N');
            }

            // 체크리스트
            if ($data['check_list_img_yn'] == 'Y') {
                $builder->where('a.check_list_img_yn', 'Y');
            } else if ($data['check_list_img_yn'] == 'N') {
                $builder->where('a.check_list_img_yn', 'N');
            }

            // 평면도유무
            if ($data['ground_plan_yn'] == 'Y') {
                $builder->where('exists (select \'x\' from result_imgs imgs where imgs.rsrv_sq = b.rsrv_sq and imgs.img_type = \'I5\' and imgs.use_yn=\'Y\')', NULL, FALSE);
            } else if ($data['ground_plan_yn'] == 'N') {
                $builder->where('not exists (select \'x\' from result_imgs imgs where imgs.rsrv_sq = b.rsrv_sq and imgs.img_type = \'I5\' and imgs.use_yn=\'Y\')', NULL, FALSE);
            }

            // 평면도요청
            if (!empty($data['ground_plan'])) {
                $builder->where('a.ground_plan', $data['ground_plan']);
            }

            // 직거래
            if ($data['direct_trad_yn'] == "Y") {
                $builder->where('a.direct_trad_yn', 'Y');
            } else if ($data['direct_trad_yn'] == "N") {
                $builder->where('a.direct_trad_yn', 'N');
            }

            // 360촬영여부
            if ($data['image_360_yn'] == "Y") {
                $builder->where('a.image_360_yn', 'Y');
            } else if ($data['image_360_yn'] == "N") {
                $builder->where('a.image_360_yn', 'N');
            }

            // 검증방식
            if (!empty($data['isSiteVRVerification'])) {
                $builder->where('a.isSiteVRVerification', $data['isSiteVRVerification']);
            }

            // 프로모션
            if (!empty($data['isPromotionApply'])) {
                $builder->where('a.isPromotionApply', $data['isPromotionApply']);
            }

            if (!empty($data['srchTxt'])) {
                // 중개사
                if ($data['srchType'] == '1') {
                    $builder->groupStart()
                        ->like('a.agent_nm', $data['srchTxt'])
                        ->orLike('a.sellr_nm', $data['srchTxt'])
                        ->groupEnd();

                    // 주소                        
                } else if ($data['srchType'] == '2') {
                    $builder->groupStart()
                        ->like('a.rcpt_dtl_addr', $data['srchTxt'])
                        ->orLike('a.rcpt_hscp_nm', $data['srchTxt'])
                        ->orLike('a.rcpt_jibun_addr', $data['srchTxt'])
                        ->groupEnd();

                    // 사업자번호        
                } else if ($data['srchType'] == '3') {
                    $builder->like('a.image_360_yn', $data['srchTxt'], 'both');
                } else {
                    $builder->groupStart()
                        ->like('a.agent_nm', $data['srchTxt'])
                        ->orLike('a.sellr_nm', $data['srchTxt'])
                        ->groupEnd();

                    $builder->groupStart()
                        ->like('a.rcpt_dtl_addr', $data['srchTxt'])
                        ->orLike('a.rcpt_hscp_nm', $data['srchTxt'])
                        ->orLike('a.rcpt_jibun_addr', $data['srchTxt'])
                        ->groupEnd();

                    $builder->like('a.image_360_yn', $data['srchTxt'], 'both');
                }
            }

        }

        $row = $builder->get()->getRowArray();
        // log_message('debug', '[getTotalCount] SQL = ' . $this->db->getLastQuery());
        
        return (int) ($row['cnt'] ?? 0);
    }


    public function getResultList($start, $end, $data)
    {
        $usr_sq = session('usr_sq');
        $usr_level = session('usr_level');
        $dept_sq = session('dept_sq');

        $builder = $this->db->table('receipt a');

        $builder->select("
                                    a.rcpt_sq,
                                    a.comp_sq,
                                    a.rcpt_rating,
                                    a.rcpt_key,
                                    a.rcpt_atclno,
                                    a.rcpt_floor,
                                    a.rcpt_floor2,
                                    a.rcpt_type,
                                    a.rcpt_product,
                                    a.rcpt_product_nm,
                                    a.rcpt_product_area,
                                    a.rcpt_product_price,
                                    a.rcpt_deal_type,
                                    a.rcpt_product_info1,
                                    a.rcpt_product_info2,
                                    a.rcpt_product_info3,
                                    a.rcpt_product_info4,
                                    a.rcpt_product_info5,
                                    a.rcpt_office,
                                    (CASE WHEN a.rcpt_agent IS NULL THEN 'N' ELSE 'Y' END) AS rcpt_agent,
                                    a.rcpt_sido,
                                    a.rcpt_gugun,
                                    IFNULL(a.rcpt_dong, '') AS rcpt_dong,
                                    IFNULL(a.rcpt_bunji, '') AS rcpt_bunji,
                                    IFNULL(a.rcpt_ho, '') AS rcpt_ho,
                                    a.rcpt_tm,
                                    a.rcpt_stat,
                                    a.rcpt_x,
                                    a.rcpt_y,
                                    a.rcpt_exps_type,
                                    a.cust_nm,
                                    a.cust_tel1,
                                    a.cust_tel2,
                                    a.rcpt_hscp_nm,
                                    a.cust_zip,
                                    a.cust_addr1,
                                    a.cust_addr2,
                                    a.remark,
                                    a.cupnNo,
                                    a.rcpt_cpid,
                                    a.agent_id,
                                    a.agent_nm,
                                    a.agent_head,
                                    a.agent_head_tel,
                                    a.agent_contact,
                                    a.agent_contact_tel,
                                    a.agent_fax,
                                    DATE_FORMAT(COALESCE(b.rsrv_date, a.rsrv_date), '%Y-%m-%d') AS rsrv_date,
                                    COALESCE(b.rsrv_tm_ap, a.rsrv_tm_ap) AS rsrv_tm_ap,
                                    a.insert_usr,
                                    a.insert_tm,
                                    a.update_usr,
                                    a.update_tm,
                                    a.svc_type1,
                                    a.svc_type2,
                                    a.reconf_yn,
                                    a.agent_tel,
                                    a.sply_spc,
                                    a.excls_spc,
                                    a.room_cnt,
                                    a.exp_spc_yn,
                                    a.spc_stat,
                                    a.parcel_out_yn,
                                    a.rcpt_hscp_nm,
                                    b.rsrv_sq,
                                    b.dept_sq,
                                    b.usr_sq,
                                    b.rsrv_tm_hour,
                                    b.result_cd1,
                                    b.result_cd2,
                                    b.result_cd3,
                                    get_code_name('RECEIPT_STATUS1', b.result_cd1) AS result_cd1_nm,
                                    get_code_name('RECEIPT_STATUS2', b.result_cd2) AS result_cd2_nm,
                                    get_code_name('RECEIPT_STATUS3', b.result_cd3) AS result_cd3_nm,
                                    b.result_msg,
                                    b.photo_save_dt,
                                    b.rsrv_delay_dt,
                                    b.rsrv_cplt_dt,
                                    b.check_dt,
                                    b.check_cplt_dt,
                                    (CASE (SELECT 'x' FROM result_record WHERE rsrv_sq = b.rsrv_sq AND use_yn = 'Y')
                                        WHEN 'x' THEN 'Y' ELSE 'N' END) AS rec_yn,
                                    get_code_name('RECEIPT_STATUS1', SUBSTRING(a.rcpt_stat, 1, 2)) AS rcpt_stat_nm,
                                    c.region_nm AS addr,
                                    IFNULL(a.rcpt_dtl_addr, '') AS rcpt_dtl_addr,
                                    IFNULL(a.rcpt_li_addr, '') AS rcpt_li_addr,
                                    IFNULL(a.rcpt_jibun_addr, '') AS rcpt_jibun_addr,
                                    IFNULL(a.rcpt_etc_addr, '') AS rcpt_etc_addr,
                                    d.pdept_sq,
                                    d.dept_nm,
                                    b.resYn,
                                    u.usr_nm,
                                    a.rcpt_exps_type,
                                    a.exp_photo_yn,
                                    a.exp_movie_yn,
                                    a.ground_plan,
                                    CASE (SELECT COUNT(1) FROM result_imgs WHERE rsrv_sq = b.rsrv_sq AND img_type = 'I1' AND use_yn = 'Y')
                                        WHEN 0 THEN 'N' ELSE 'Y' END AS conf_img_yn,
                                    CASE (SELECT COUNT(1) FROM result_imgs WHERE rsrv_sq = b.rsrv_sq AND img_type = 'I5' AND use_yn = 'Y')
                                        WHEN 0 THEN 'N' ELSE 'Y' END AS ground_plan_yn,
                                    a.direct_trad_yn,
                                    a.sellr_nm,
                                    a.image_360_yn,
                                    a.check_list_img_yn,
                                    l.exposedImageCnt,
                                    l.transferedImagesCnt,
                                    a.isSiteVRVerification,
                                    a.isPromotionApply
                                ", false);

        $builder->join('result b', 'b.rcpt_sq = a.rcpt_sq', 'inner');
        $builder->join('region_codes c', 'a.rcpt_dong = c.region_cd', 'left outer');
        $builder->join('departments d', 'b.dept_sq = d.dept_sq', 'left outer');
        $builder->join('users u', 'b.usr_sq = u.usr_sq', 'left outer');
        $builder->join('result_imgs e', "e.rsrv_sq = b.rsrv_sq AND e.img_type = 'I1' AND e.use_yn = 'Y'", 'left outer');
        $builder->join('receipt_transimage_log l', 'a.rcpt_key = l.rcpt_key', 'left outer');


        $login_dept_info = $this->getDeptDetail($dept_sq);	// 로그인 사용자 소속부서정보
        $child_dept = [];													// 하위조직 목록
        if (strcmp($usr_level, '40') == 0) {
            $child = $this->getChildDept($login_dept_info);
            if (!empty($child)) {
                foreach ($child as $child) {
                    $child_dept[] = $child['dept_sq'];
                }
            }
        }

        if ((int) $usr_level >= 4 && $usr_level != '45') {
            if (!empty($child_dept)) {
                $builder->whereIn('b.dept_sq', $child_dept);
            } else {
                $builder->where('b.usr_sq', $usr_sq);
            }
        }

        $builder->where('a.rcpt_tm >= DATE_ADD(CURDATE(), INTERVAL -3 MONTH)', null, false);
        $builder->where('b.use_yn', 'Y');

        if (!empty($data['rcpt_atclno'])) {
            $builder->where('a.rcpt_atclno', $data['rcpt_atclno']);
        } else {
            if ($data['schDateGb'] == '2') {
                $builder->where('a.rcpt_tm >=', $data['sdate'] . ' 00:00:00');
                $builder->where('a.rcpt_tm <=', $data['edate'] . ' 23:59:59');
            } else {
                $builder->where('b.rsrv_date >=', $data['sdate'] );
                $builder->where('b.rsrv_date <=', $data['edate'] );
            }

            // 지역
            if (!empty($data['dong'])) {
                $builder->where('a.rcpt_dong', $data['dong']);
            } else {
                if (!empty($data['gugun'])) {
                    $builder->like('a.rcpt_gugun', substr($data['gugun'], 0, 5), 'after');
                } else {
                    if (!empty($data['sido'])) {
                        $builder->like('a.rcpt_gugun', substr($data['sido'], 0, 2), 'after');
                    }
                }
            }

            // 관할조직
            if (!empty($data['bonbu'])) {
                $builder->where('d.pdept_sq', $data['bonbu']);
            }

            if (!empty($data['team'])) {
                $builder->where('d.dept_sq', $data['team']);
            }

            if (!empty($data['user'])) {
                $builder->where('d.usr_sq', $data['user']);
            }

            // 거래구분
            if (!empty($data['rcpt_product_info1'])) {
                $builder->where('a.rcpt_product_info1', $data['rcpt_product_info1']);
            }

            // 현재상태
            if (!empty($data['rcpt_stat1'])) {
                $builder->like('a.rcpt_stat', $data['rcpt_stat1'], 'after');
            }

            if (!empty($data['rcpt_stat2'])) {
                $builder->like('a.rcpt_stat', $data['rcpt_stat2'], 'after');
            }

            if (!empty($data['rcpt_stat3'])) {
                $builder->where('a.rcpt_stat', $data['rcpt_stat3']);
            }

            // 중개사명
            if (!empty($data['agent_nm'])) {
                $builder->like('a.agent_nm', $data['agent_nm'], 'both');
            }

            // 동영상촬영여부
            if (!empty($data['exp_movie_yn'])) {
                $builder->where('a.exp_movie_yn', $data['exp_movie_yn']);
            }

            // 홍보확인서여부
            if ($data['conf_img_yn'] == 'Y') {
                $builder->where('e.rsrv_sq IS NOT NULL', null, false);
            } else if ($data['conf_img_yn'] == 'N') {
                $builder->where('e.rsrv_sq IS NULL', null, false);
            }

            // 분양권
            if ($data['parcel_out_yn'] == 'Y') {
                $builder->where('a.parcel_out_yn', 'Y');
            } else if ($data['parcel_out_yn'] == 'N') {
                $builder->where('a.parcel_out_yn', 'N');
            }

            // CP ID
            if (!empty($data['rcpt_cpid'])) {
                if (strcmp($data['rcpt_cpid'], 'naver') == 0) {
                    $builder->where('a.rcpt_cpid =', '');
                } else if (strcmp($data['rcpt_cpid'], 'cleancente') == 0) {
                    $builder->where("a.rcpt_cpid !=", "");
                } else {
                    $builder->where('a.rcpt_cpid', $data['rcpt_cpid']);
                }
            }

            // 매물종류
            if (!empty($data['rcpt_product'])) {
                $builder->where('a.parcel_out_yn', $data['rcpt_product']);
            }

            // 면적확인
            if ($data['exp_spc_yn'] == 'Y') {
                $builder->where('a.parcel_out_yn', 'Y');
            } else if ($data['exp_spc_yn'] == 'N') {
                $builder->where('a.parcel_out_yn', 'N');
            }

            // 체크리스트
            if ($data['check_list_img_yn'] == 'Y') {
                $builder->where('a.check_list_img_yn', 'Y');
            } else if ($data['check_list_img_yn'] == 'N') {
                $builder->where('a.check_list_img_yn', 'N');
            }

            // 평면도유무
            if ($data['ground_plan_yn'] == 'Y') {
                $builder->where('exists (select \'x\' from result_imgs imgs where imgs.rsrv_sq = b.rsrv_sq and imgs.img_type = \'I5\' and imgs.use_yn=\'Y\')', NULL, FALSE);
            } else if ($data['ground_plan_yn'] == 'N') {
                $builder->where('not exists (select \'x\' from result_imgs imgs where imgs.rsrv_sq = b.rsrv_sq and imgs.img_type = \'I5\' and imgs.use_yn=\'Y\')', NULL, FALSE);
            }

            // 평면도요청
            if (!empty($data['ground_plan'])) {
                $builder->where('a.ground_plan', $data['ground_plan']);
            }

            // 직거래
            if ($data['direct_trad_yn'] == "Y") {
                $builder->where('a.direct_trad_yn', 'Y');
            } else if ($data['direct_trad_yn'] == "N") {
                $builder->where('a.direct_trad_yn', 'N');
            }

            // 360촬영여부
            if ($data['image_360_yn'] == "Y") {
                $builder->where('a.image_360_yn', 'Y');
            } else if ($data['image_360_yn'] == "N") {
                $builder->where('a.image_360_yn', 'N');
            }

            // 검증방식
            if (!empty($data['isSiteVRVerification'])) {
                $builder->where('a.isSiteVRVerification', $data['isSiteVRVerification']);
            }

            // 프로모션
            if (!empty($data['isPromotionApply'])) {
                $builder->where('a.isPromotionApply', $data['isPromotionApply']);
            }

            if (!empty($data['srchTxt'])) {
                // 중개사
                if ($data['srchType'] == '1') {
                    $builder->groupStart()
                        ->like('a.agent_nm', $data['srchTxt'])
                        ->orLike('a.sellr_nm', $data['srchTxt'])
                        ->groupEnd();

                    // 주소                        
                } else if ($data['srchType'] == '2') {
                    $builder->groupStart()
                        ->like('a.rcpt_dtl_addr', $data['srchTxt'])
                        ->orLike('a.rcpt_hscp_nm', $data['srchTxt'])
                        ->orLike('a.rcpt_jibun_addr', $data['srchTxt'])
                        ->groupEnd();

                    // 사업자번호        
                } else if ($data['srchType'] == '3') {
                    $builder->like('a.image_360_yn', $data['srchTxt'], 'both');
                } else {
                    $builder->groupStart()
                        ->like('a.agent_nm', $data['srchTxt'])
                        ->orLike('a.sellr_nm', $data['srchTxt'])
                        ->groupEnd();

                    $builder->groupStart()
                        ->like('a.rcpt_dtl_addr', $data['srchTxt'])
                        ->orLike('a.rcpt_hscp_nm', $data['srchTxt'])
                        ->orLike('a.rcpt_jibun_addr', $data['srchTxt'])
                        ->groupEnd();

                    $builder->like('a.image_360_yn', $data['srchTxt'], 'both');
                }
            }

        }


        $builder->orderBy('a.rcpt_atclno', 'DESC');

        $builder->limit($end, $start);

        $result = $builder->get()->getResultArray();
        
        // log_message('debug', '[getResultList] SQL = ' . $this->db->getLastQuery());
        // log_message('info', '[getResultList] Result count = ' . count($result));

        return $result;

    }



    // 엑셀다운로드
    public function getExcelList($data)
    {
        $usr_sq = session('usr_sq');
        $usr_level = session('usr_level');
        $dept_sq = session('dept_sq');

        $builder = $this->db->table('receipt a');

        $builder->select("
                                get_code_name('RECEIPT_STATUS1', b.result_cd1)	AS '현재상태',
                                CASE WHEN b.result_cd1 = '90' THEN get_code_name('RECEIPT_STATUS2', b.result_cd2) ELSE '' END AS '매물ID',
                                CASE WHEN b.result_cd1 = '90' THEN get_code_name('RECEIPT_STATUS3', b.result_cd3) ELSE '' END AS '접수(등록)일자',
                                a.rcpt_atclno AS '예약일자',
                                a.insert_tm  '방문희망시간',
                                CONCAT(b.rsrv_date, ' ', b.rsrv_tm_ap) AS '촬영완료일자',
                                b.rsrv_tm_hour AS '중개사명',
                                b.photo_save_dt AS '대표전화',
                                '' AS '담당자전화',
                                a.agent_head_tel AS '연락가능전화',
                                '' AS '중개사ID',
                                a.rcpt_cpid  'CP ID',
                                CASE
                                    WHEN IFNULL(a.rcpt_jibun_addr, '') = '' THEN
                                        CASE
                                            WHEN IFNULL(a.rcpt_hscp_nm, '') = '' THEN
                                                CONCAT(c.region_nm, ' ', a.rcpt_dtl_addr, ' ', a.rcpt_ho)
                                            ELSE
                                                CONCAT(c.region_nm, ' ', a.rcpt_hscp_nm, ' ', a.rcpt_dtl_addr, ' ', a.rcpt_ho)
                                        END
                                    ELSE
                                        CASE
                                            WHEN IFNULL(a.rcpt_li_addr, '') != '' THEN
                                                CONCAT(c.region_nm, ' ', a.rcpt_li_addr, ' ', a.rcpt_jibun_addr, ' ', a.rcpt_etc_addr)
                                            ELSE
                                                CONCAT(c.region_nm, ' ', a.rcpt_jibun_addr, ' ', a.rcpt_etc_addr)
                                        END
                                END AS '주소',
                                CONCAT(a.rcpt_floor, '/', a.rcpt_floor2) AS '층',
                                a.rcpt_product_nm AS '매물종류',
                                a.rcpt_product_info1 AS '거래구분',
                                d.dept_nm AS '관할조직(팀)',
                                u.usr_nm AS '방문담당',
                                a.rcpt_exps_type AS '노출옵션',
                                CASE (SELECT COUNT(1) FROM result_imgs WHERE rsrv_sq = b.rsrv_sq AND img_type = 'I1' AND use_yn = 'Y')
                                                                        WHEN 0 THEN 'N' ELSE 'Y' END AS '홍보확인서',
                                a.exp_movie_yn AS '동영상촬영',
                                a.exp_spc_yn AS '면적확인',
                                b.resYn AS '거주여부',
                                (CASE (SELECT 'x' FROM result_record WHERE rsrv_sq = b.rsrv_sq AND use_yn = 'Y')
                                                                        WHEN 'x' THEN 'Y' ELSE 'N' END) AS '녹취여부',
                                a.excls_spc AS '전용면적',
                                a.sply_spc AS '공급면적',
                                a.cupnNo AS '쿠폰번호',
                                a.image_360_yn AS '360촬영여부',
                                a.rcpt_y AS '경도',
                                a.rcpt_y AS '위도',
                                a.check_list_img_yn AS '체크리스트',
                                l.transferedImagesCnt AS '전달이미지',
                                l.exposedImageCnt AS '노출이미지'
                                ", false);

        $builder->join('result b', 'b.rcpt_sq = a.rcpt_sq', 'inner');
        $builder->join('region_codes c', 'a.rcpt_dong = c.region_cd', 'left');
        $builder->join('departments d', 'b.dept_sq = d.dept_sq', 'left');
        $builder->join('users u', 'b.usr_sq = u.usr_sq', 'left');
        $builder->join('result_imgs e', "e.rsrv_sq = b.rsrv_sq AND e.img_type = 'I1' AND e.use_yn = 'Y'", 'left');
        $builder->join('receipt_transimage_log l', 'a.rcpt_key = l.rcpt_key', 'left');


        $login_dept_info = $this->getDeptDetail($dept_sq);	// 로그인 사용자 소속부서정보
        $child_dept = [];													// 하위조직 목록
        if (strcmp($usr_level, '40') == 0) {
            $child = $this->getChildDept($login_dept_info);
            if (!empty($child)) {
                foreach ($child as $child) {
                    $child_dept[] = $child['dept_sq'];
                }
            }
        }

        if ((int) $usr_level >= 4 && $usr_level != '45') {
            if (!empty($child_dept)) {
                $builder->whereIn('b.dept_sq', $child_dept);
            } else {
                $builder->where('b.usr_sq', $usr_sq);
            }
        }

        $builder->where('a.rcpt_tm >= DATE_ADD(CURDATE(), INTERVAL -3 MONTH)', null, false);
        $builder->where('b.use_yn', 'Y');

        if (!empty($data['rcpt_atclno'])) {
            $builder->where('a.rcpt_atclno', $data['rcpt_atclno']);
        } else {
            if ($data['schDateGb'] == '2') {
                $builder->where('a.rcpt_tm >=', $data['sdate'] . ' 00:00:00');
                $builder->where('a.rcpt_tm <=', $data['edate'] . ' 23:59:59');
            } else {
                $builder->where('b.rsrv_date >=', $data['sdate'] . ' 00:00:00');
                $builder->where('b.rsrv_date <=', $data['edate'] . ' 23:59:59');
            }

            // 지역
            if (!empty($data['dong'])) {
                $builder->where('a.rcpt_dong', $data['dong']);
            } else {
                if (!empty($data['gugun'])) {
                    $builder->like('a.rcpt_gugun', substr($data['gugun'], 0, 5), 'after');
                } else {
                    if (!empty($data['sido'])) {
                        $builder->like('a.rcpt_gugun', substr($data['sido'], 0, 2), 'after');
                    }
                }
            }

            // 관할조직
            if (!empty($data['bonbu'])) {
                $builder->where('d.pdept_sq', $data['bonbu']);
            }

            if (!empty($data['team'])) {
                $builder->where('d.dept_sq', $data['team']);
            }

            if (!empty($data['user'])) {
                $builder->where('d.usr_sq', $data['user']);
            }

            // 거래구분
            if (!empty($data['rcpt_product_info1'])) {
                $builder->where('a.rcpt_product_info1', $data['rcpt_product_info1']);
            }

            // 현재상태
            if (!empty($data['rcpt_stat1'])) {
                $builder->like('a.rcpt_stat', $data['rcpt_stat1'], 'after');
            }

            if (!empty($data['rcpt_stat2'])) {
                $builder->like('a.rcpt_stat', $data['rcpt_stat2'], 'after');
            }

            if (!empty($data['rcpt_stat3'])) {
                $builder->where('a.rcpt_stat', $data['rcpt_stat3']);
            }

            // 중개사명
            if (!empty($data['agent_nm'])) {
                $builder->like('a.agent_nm', $data['agent_nm'], 'both');
            }

            // 동영상촬영여부
            if (!empty($data['exp_movie_yn'])) {
                $builder->where('a.exp_movie_yn', $data['exp_movie_yn']);
            }

            // 홍보확인서여부
            if ($data['conf_img_yn'] == 'Y') {
                $builder->where('e.rsrv_sq IS NOT NULL', null, false);
            } else if ($data['conf_img_yn'] == 'N') {
                $builder->where('e.rsrv_sq IS NULL', null, false);
            }

            // 분양권
            if ($data['parcel_out_yn'] == 'Y') {
                $builder->where('a.parcel_out_yn', 'Y');
            } else if ($data['parcel_out_yn'] == 'N') {
                $builder->where('a.parcel_out_yn', 'N');
            }

            // CP ID
            if (!empty($data['rcpt_cpid'])) {
                if (strcmp($data['rcpt_cpid'], 'naver') == 0) {
                    $builder->where('a.rcpt_cpid =', '');
                } else if (strcmp($data['rcpt_cpid'], 'cleancente') == 0) {
                    $builder->where("a.rcpt_cpid !=", "");
                } else {
                    $builder->where('a.rcpt_cpid', $data['rcpt_cpid']);
                }
            }

            // 매물종류
            if (!empty($data['rcpt_product'])) {
                $builder->where('a.parcel_out_yn', $data['rcpt_product']);
            }

            // 면적확인
            if ($data['exp_spc_yn'] == 'Y') {
                $builder->where('a.parcel_out_yn', 'Y');
            } else if ($data['exp_spc_yn'] == 'N') {
                $builder->where('a.parcel_out_yn', 'N');
            }

            // 체크리스트
            if ($data['check_list_img_yn'] == 'Y') {
                $builder->where('a.check_list_img_yn', 'Y');
            } else if ($data['check_list_img_yn'] == 'N') {
                $builder->where('a.check_list_img_yn', 'N');
            }

            // 평면도유무
            if ($data['ground_plan_yn'] == 'Y') {
                $builder->where('exists (select \'x\' from result_imgs imgs where imgs.rsrv_sq = b.rsrv_sq and imgs.img_type = \'I5\' and imgs.use_yn=\'Y\')', NULL, FALSE);
            } else if ($data['ground_plan_yn'] == 'N') {
                $builder->where('not exists (select \'x\' from result_imgs imgs where imgs.rsrv_sq = b.rsrv_sq and imgs.img_type = \'I5\' and imgs.use_yn=\'Y\')', NULL, FALSE);
            }

            // 평면도요청
            if (!empty($data['ground_plan'])) {
                $builder->where('a.ground_plan', $data['ground_plan']);
            }

            // 직거래
            if ($data['direct_trad_yn'] == "Y") {
                $builder->where('a.direct_trad_yn', 'Y');
            } else if ($data['direct_trad_yn'] == "N") {
                $builder->where('a.direct_trad_yn', 'N');
            }

            // 360촬영여부
            if ($data['image_360_yn'] == "Y") {
                $builder->where('a.image_360_yn', 'Y');
            } else if ($data['image_360_yn'] == "N") {
                $builder->where('a.image_360_yn', 'N');
            }

            // 검증방식
            if (!empty($data['isSiteVRVerification'])) {
                $builder->where('a.isSiteVRVerification', $data['isSiteVRVerification']);
            }

            // 프로모션
            if (!empty($data['isPromotionApply'])) {
                $builder->where('a.isPromotionApply', $data['isPromotionApply']);
            }

            if (!empty($data['srchTxt'])) {
                // 중개사
                if ($data['srchType'] == '1') {
                    $builder->groupStart()
                        ->like('a.agent_nm', $data['srchTxt'])
                        ->orLike('a.sellr_nm', $data['srchTxt'])
                        ->groupEnd();

                    // 주소                        
                } else if ($data['srchType'] == '2') {
                    $builder->groupStart()
                        ->like('a.rcpt_dtl_addr', $data['srchTxt'])
                        ->orLike('a.rcpt_hscp_nm', $data['srchTxt'])
                        ->orLike('a.rcpt_jibun_addr', $data['srchTxt'])
                        ->groupEnd();

                    // 사업자번호        
                } else if ($data['srchType'] == '3') {
                    $builder->like('a.image_360_yn', $data['srchTxt'], 'both');
                } else {
                    $builder->groupStart()
                        ->like('a.agent_nm', $data['srchTxt'])
                        ->orLike('a.sellr_nm', $data['srchTxt'])
                        ->groupEnd();

                    $builder->groupStart()
                        ->like('a.rcpt_dtl_addr', $data['srchTxt'])
                        ->orLike('a.rcpt_hscp_nm', $data['srchTxt'])
                        ->orLike('a.rcpt_jibun_addr', $data['srchTxt'])
                        ->groupEnd();

                    $builder->like('a.image_360_yn', $data['srchTxt'], 'both');
                }
            }

        }


        $builder->orderBy('a.rcpt_atclno', 'DESC');


        // log_message('debug', '[getResultList] SQL = ' . $builder->getCompiledSelect());

        return $builder->get()->getResultArray();
    }

    // 상세
    public function getDetail($id)
    {

        $builder = $this->db->table('receipt a');

        $builder->select("
                                a.rcpt_sq
			   	                ,a.comp_sq
			   	                ,a.excls_spc
			                    ,a.rcpt_rating
			                    ,a.rcpt_key
			   	                ,a.rcpt_atclno
			                    ,a.rcpt_type
			                    ,a.rcpt_product
			                    ,a.rcpt_product_nm
			                    ,a.rcpt_product_area
			                    ,a.rcpt_product_price
			   	                , a.rcpt_deal_type
			                    ,a.rcpt_product_info1
			                    ,a.rcpt_product_info2
			                    ,a.rcpt_product_info3
			                    ,a.rcpt_product_info4
			                    ,a.rcpt_product_info5
			                    ,a.rcpt_office
			                    ,(CASE WHEN a.rcpt_agent IS NULL THEN 'N' ELSE 'Y' END) as rcpt_agent
			                    ,a.rcpt_sido
			                    ,a.rcpt_gugun
			                    ,a.rcpt_dong
                                ,c.region_nm AS addr
			                    ,a.rcpt_dtl_addr
			                    ,a.rcpt_li_addr
			                    ,a.rcpt_jibun_addr
			                    ,a.rcpt_etc_addr
			                    ,a.rcpt_ref_addr
			                    ,a.rcpt_ho
			                    ,a.rcpt_hscp_nm
			   	                ,a.rcpt_floor
			   	                ,a.rcpt_floor2
			   	                ,a.chg_floor_yn
			                    ,a.rcpt_tm
			                    ,a.rcpt_stat
			                    ,a.rcpt_x
			                    ,a.rcpt_y
			   	                ,a.rcpt_living_yn
			                    ,a.cust_nm
			                    ,a.cust_tel1
			                    ,a.cust_tel2
			                    ,a.cust_zip
			                    ,a.cust_addr1
			                    ,a.cust_addr2
			                    ,a.remark rcpt_remark
			   	                , a.rcpt_cpid
			                    ,a.agent_id
			                    ,a.agent_nm
			                    ,a.agent_head
			                    ,a.agent_head_tel
			                    ,a.agent_contact
			                    ,a.agent_contact_tel
			                    ,a.agent_fax
			                    ,a.agent_tel
			                    ,a.excls_spc
			                    ,a.excls_spc1
			                    ,a.excls_spc2
			                    ,a.sply_spc
			                    ,a.share_spc
			                    ,a.share_spc1
			                    ,a.share_spc2
			                    ,a.share_spc3
			                    ,a.share_spc4
			                    ,a.share_spc5
			                    ,a.room_cnt
			                    ,a.tot_spc
			                    ,a.tot_spc1
			                    ,a.tot_spc2
			                    ,a.grnd_spc
			                    ,a.grnd_spc1
			                    ,a.grnd_spc2
			                    ,a.grnd_spc3
			                    ,a.grnd_spc4
			                    ,a.grnd_spc5
			                    ,a.spc_stat
			                    ,a.exp_spc_yn
			                    ,DATE_FORMAT(COALESCE(b.rsrv_date, a.rsrv_date), '%Y-%m-%d') AS rsrv_date
			                    ,COALESCE(b.rsrv_tm_ap, a.rsrv_tm_ap) as rsrv_tm_ap
			                    ,a.insert_usr
			                    ,a.insert_tm
			                    ,a.update_usr
			                    ,a.update_tm
			                    ,a.svc_type1
			                    ,a.svc_type2
			                    ,a.reconf_yn
			                    ,a.cupnNo
			                    ,b.rsrv_sq
			   	                ,b.dept_sq
			                    ,b.usr_sq
			   	                ,b.req_rec_yn
			   	                ,b.rec_yn
			   	                ,b.rec_tel
			   	                ,b.rec_nm
			   	                ,b.remark
			                    ,b.rsrv_tm_hour
			                    ,b.result_cd1
			   	                ,get_code_name('RECEIPT_STATUS1', b.result_cd1) AS result_cd1_nm
			                    ,b.result_cd2
			   	                ,get_code_name('RECEIPT_STATUS2', b.result_cd2) AS result_cd2_nm
			   	                ,b.result_cd3
			   	                ,get_code_name('RECEIPT_STATUS3', b.result_cd3) AS result_cd3_nm
			                    ,b.result_msg
			   	                ,b.rsrv_save_dt
			   	                ,b.photo_save_dt
			   	                ,DATE_FORMAT(b.photo_save_dt, '%Y-%m-%d') as photo_save_dt_dt
			   	                ,DATE_FORMAT(b.photo_save_dt, '%H:%i:%s') as photo_save_dt_tm
			   	                ,b.assign_save_dt
			   	                ,b.result_save_dt
			   	                ,b.request_msg
			   	                ,b.rsrv_delay_dt
			   	                ,DATE_FORMAT(b.rsrv_delay_dt, '%Y-%m-%d') as rsrv_delay_dt_dt
			   	                ,DATE_FORMAT(b.rsrv_delay_dt, '%H:%i:%s') as rsrv_delay_dt_tm
			   	                ,b.rsrv_cplt_dt
			   	                ,DATE_FORMAT(b.rsrv_cplt_dt, '%Y-%m-%d') as rsrv_cplt_dt_dt
			   	                ,DATE_FORMAT(b.rsrv_cplt_dt, '%H:%i:%s') as rsrv_cplt_dt_tm
			   	                ,b.check_dt
			   	                ,DATE_FORMAT(b.check_dt, '%Y-%m-%d') as check_dt_dt
			   	                ,DATE_FORMAT(b.check_dt, '%H:%i:%s') as check_dt_tm
			   	                ,b.check_cplt_dt
			   	                ,DATE_FORMAT(b.check_cplt_dt, '%Y-%m-%d') as check_cplt_dt_dt
			   	                ,DATE_FORMAT(b.check_cplt_dt, '%H:%i:%s') as check_cplt_dt_tm
			   	                ,b.cancel_dt
			   	                ,DATE_FORMAT(b.cancel_dt, '%Y-%m-%d') as cancel_dt_dt
			   	                ,DATE_FORMAT(b.cancel_dt, '%H:%i:%s') as cancel_dt_tm
			   	                ,b.check_delay_dt
			   	                ,DATE_FORMAT(b.check_delay_dt, '%Y-%m-%d') as check_delay_dt_dt
			   	                ,DATE_FORMAT(b.check_delay_dt, '%H:%i:%s') as check_delay_dt_tm
			   	                ,b.check_fail_dt
			   	                ,DATE_FORMAT(b.check_fail_dt, '%Y-%m-%d') as check_fail_dt_dt
			   	                ,DATE_FORMAT(b.check_fail_dt, '%H:%i:%s') as check_fail_dt_tm
			                    ,get_code_name('RECEIPT_STATUS3', a.rcpt_stat) AS rcpt_stat_nm
			                    ,DATE_FORMAT(a.insert_tm, '%Y년 %m월 %d일') as insert_tm2
			                    ,DATE_FORMAT(a.rsrv_date, '%Y-%m-%d') as rsrv_date2	
			                    ,c.dept_sq as region_dept_sq
			   	                ,c.usr_sq as region_usr_sq
			   	                ,d.pdept_sq
			   	                ,d.dept_nm
			   	                ,a.rcpt_exps_type
			   	                ,a.exp_photo_yn
			   	                ,a.exp_movie_yn
			   	                ,b.resYn
			   	                ,DATE_ADD(a.insert_tm, INTERVAL +3 MONTH) as months
			   	                ,b.dbUsageAgrYn
			   	                ,a.trade_type
			   	                , a.rcpt_hscp_no
			   	                , a.rcpt_ptp_nm
			   	                , a.rcpt_ptp_no
			   	                , a.modify_yn
			   	                , a.ground_plan
			   	                ,a.direct_trad_yn
			   	                ,a.sellr_nm
			   	                ,a.sellr_tel_no
			   	                ,a.virAddr_yn
			   	                ,a.isSiteVRVerification
			   	                ,a.isPromotionApply
			   	                ,DATE_FORMAT(b.vr_check_cplt_dt, '%Y-%m-%d') as vr_check_cplt_dt_dt
			   	                ,DATE_FORMAT(b.vr_check_cplt_dt, '%H:%i:%s') as vr_check_cplt_dt_dm
                                ", false);

        $builder->join('result b', 'b.rcpt_sq = a.rcpt_sq', 'inner');
        $builder->join('region_codes c', 'a.rcpt_dong = c.region_cd', 'left');
        $builder->join('departments d', 'b.dept_sq = d.dept_sq', 'left');


        $builder->where('a.rcpt_key', $id);

        return $builder->get()->getRowArray();
    }

    /**
     * 사용자의 지정일자에 배정된 목록을 가져온다. (시간, 위치만...)
     */
    public function getAssignReceiptListByUser($rsrv_date, $usr_sq, $arrExcept = [])
    {
        $sql = "SELECT a.rcpt_key, a.rcpt_atclno, a.rcpt_x, a.rcpt_y, b.rsrv_tm_ap, b.rsrv_tm_hour" .
            " FROM receipt a" .
            " INNER JOIN result b ON b.rcpt_sq = a.rcpt_sq AND b.usr_sq = ? AND b.rsrv_date = ?" .
            " WHERE a.rcpt_key not in (?)";
        $except_rcptKey = implode(',', $arrExcept);
        $data = array($usr_sq, $rsrv_date, $except_rcptKey);
        $query = $this->db->query($sql, $data);
        $res = $query->getResultArray();


        return $res;
    }

    public function getDupleGP($rcpt_key, $rcpt_sido, $rcpt_gugun, $rcpt_dong, $rcpt_hscp_nm, $rcpt_dtl_addr, $rcpt_ho)
    {
        $sql = "select rcpt_sq, c.rcpt_key, c.photo_save_dt from" .
            " (select a.rcpt_sq, b.rsrv_sq, a.rcpt_key, b.photo_save_dt " .
            " from receipt a " .
            " LEFT OUTER JOIN result b ON b.rcpt_sq = a.rcpt_sq " .
            " where a.rcpt_sido = ? " .
            " and a.rcpt_gugun = ? " .
            " and a.rcpt_dong = ? " .
            " and a.rcpt_hscp_nm = ? " .
            " and a.rcpt_dtl_addr = ? " .
            " and a.rcpt_ho = ? " .
            " and a.insert_tm >= DATE_ADD(CURDATE(), INTERVAL -3 MONTH) " .
            " and a.rcpt_key != ? " .
            " and b.result_cd3 = 600000) c " .
            " LEFT OUTER JOIN result_imgs d ON c.rsrv_sq = d.rsrv_sq " .
            " where d.img_type = 'I5'";

        $data = [
            $rcpt_sido,
            $rcpt_gugun,
            $rcpt_dong,
            $rcpt_hscp_nm,
            $rcpt_dtl_addr,
            $rcpt_ho,
            $rcpt_key
        ];

        $res = $this->db->query($sql, $data);
        return $res->getResultArray();
    }

    public function getDupleGP_na($rcpt_key, $rcpt_sido, $rcpt_gugun, $rcpt_dong, $rcpt_hscp_nm, $rcpt_dtl_addr, $rcpt_li_addr, $rcpt_jibun_addr, $rcpt_etc_addr)
    {
        $sql = "select rcpt_sq, c.rcpt_key, c.photo_save_dt from" .
            " (select a.rcpt_sq, b.rsrv_sq, a.rcpt_key, b.photo_save_dt " .
            " from receipt a " .
            " LEFT OUTER JOIN result b ON b.rcpt_sq = a.rcpt_sq " .
            " where a.rcpt_sido = ? " .
            " and a.rcpt_gugun = ? " .
            " and a.rcpt_dong = ? " .
            " and a.rcpt_hscp_nm = ? " .
            " and a.rcpt_li_addr = ? " .
            " and a.rcpt_jibun_addr = ? " .
            " and a.rcpt_etc_addr = ? " .
            " and a.insert_tm >= DATE_ADD(CURDATE(), INTERVAL -3 MONTH) " .
            " and a.rcpt_key != ? " .
            " and b.result_cd3 = 600000) c " .
            " LEFT OUTER JOIN result_imgs d ON c.rsrv_sq = d.rsrv_sq " .
            " where d.img_type = 'I5'";

        $data = [
            $rcpt_sido,
            $rcpt_gugun,
            $rcpt_dong,
            $rcpt_hscp_nm,
            isset($rpct_li_addr) ? $rpct_li_addr : '',
            $rcpt_jibun_addr,
            $rcpt_etc_addr,
            $rcpt_key
        ];

        $res = $this->db->query($sql, $data);
        return $res->getResultArray();
    }

    // 정보변경이력
    public function getHistory($id)
    {
        // $id가 숫자면 rcpt_sq로 간주, 아니면 rcpt_key로 간주
        if (is_numeric($id) && strpos($id, '-') === false) {
            // 순수 숫자면 rcpt_sq로 직접 사용
            $rcpt_sq = $id;
        } else {
            // rcpt_key로 간주하고 rcpt_sq 조회
            $sql = "SELECT rcpt_sq FROM receipt WHERE rcpt_key = ?";
            $query = $this->db->query($sql, [$id]);
            $row = $query->getRow();
            if ($row) {
                $rcpt_sq = $row->rcpt_sq;
            } else {
                log_message('warning', "[ReceiptModel::getHistory] rcpt_key '{$id}'에 해당하는 receipt를 찾을 수 없습니다.");
                return [];
            }
        }

        $sql = "SELECT seq" .
            "      ,rcpt_sq" .
            "      ,rcpt_stat" .
            "      ,get_code_name('RECEIPT_STATUS3', rcpt_stat) AS rcpt_stat_nm" .
            "      ,changed_type" .
            "      ,get_code_name('CHANGED_TYPE', changed_type) AS changed_type_nm" .
            "      ,changed_id" .
            "      ,remark" .
            "      ,DATE_FORMAT(changed_tm, '%Y.%m.%d %H:%i:%s') as changed_tm" .
            "  FROM changed_history" .
            " WHERE rcpt_sq = ?" .
            " ORDER BY changed_tm DESC";

        $data = [$rcpt_sq];
        $query = $this->db->query($sql, $data);

        return $query->getResultArray();
    }

    public function getAptGround($rcpt_dong)
    {

        $sql = "SELECT                           ";
        $sql .= "*                                ";
        $sql .= "FROM apt_ground                  ";
        $sql .= "WHERE region_cd = ?              ";

        $data = [$rcpt_dong];

        $query = $this->db->query($sql, $data);

        return $query->getResultArray();

    }

    // 시간대별통계
    public function getUsrRsrvDateTmCount($id)
    {
        $sql = "SELECT b.usr_sq, b.rsrv_date FROM receipt a INNER JOIN result b ON a.rcpt_sq = b.rcpt_sq WHERE a.rcpt_key = ?";
        $data = [$id];
        $query = $this->db->query($sql, $data);
        $row = $query->getRowArray();

        if (!empty($row['usr_sq'])) {
            $sql2 = "SELECT usr_sq, rsrv_tm_ap, rsrv_tm_hour, COUNT(rsrv_tm_hour) as cnt" .
                "  FROM result" .
                " WHERE rsrv_date = ?" .
                "   AND usr_sq = ?" .
                " GROUP BY usr_sq, rsrv_tm_ap, rsrv_tm_hour" .
                " ORDER BY rsrv_tm_ap, rsrv_tm_hour";

            $data2 = [$row['rsrv_date'], $row['usr_sq']];
        } else {
            $sql2 = "SELECT usr_sq, rsrv_tm_ap, rsrv_tm_hour, COUNT(rsrv_tm_hour) as cnt" .
                "  FROM result" .
                " WHERE rsrv_date = ?" .
                "   AND usr_sq = (SELECT b.usr_sq FROM receipt a, region_codes b WHERE a.rcpt_dong = b.region_cd AND a.rcpt_key = ?)" .
                " GROUP BY usr_sq, rsrv_tm_ap, rsrv_tm_hour" .
                " ORDER BY rsrv_tm_ap, rsrv_tm_hour";

            $data2 = [$row['rsrv_date'], $id];
        }

        $query2 = $this->db->query($sql2, $data2);

        return $query2->getResultArray();
    }

    // 체크리스트 결과 조회
    public function getChecklist($rsrv_sq)
    {
        $sql = "select rsrv_sq, elevator_yn, maintenance_fee, elevator_cctv_yn, building_in_cctv_yn, building_ou_cctv_yn, heating_type, security_dept_yn, parking_lot_yn, interphone_yn, building_security_yn, window_direction, living_room_yn, balcony_yn, balcony_ext_yn, restroom_cnt, bath_yn, showerbooth_yn, utility_yn, built_in_chest_yn, airconditioner_yn, shoe_chest_yn, dress_room_yn, gas_stove_yn, refrigerator_yn, sink_yn, washing_machine_yn, insert_usr, insert_tm from result_check where rsrv_sq = ?";
        $data = [$rsrv_sq];
        $query = $this->db->query($sql, $data);
        $row = $query->getRowArray();
        return $row;
    }

    public function getImageList2($rsrv_sq)
    {
        $sql = "SELECT * " .
            "  FROM result_imgs" .
            " WHERE rsrv_sq = ?" .
            "   AND use_yn = 'Y'" .
            " ORDER BY rsrv_sq, view_odr";

        $data = [$rsrv_sq];
        $query = $this->db->query($sql, $data);
        return $query->getResultArray();
    }

    public function getImageListByType($rsrv_sq, $img_type)
    {
        $sql = "SELECT * " .
            "  FROM result_imgs" .
            " WHERE rsrv_sq = ?" .
            "   AND img_type = ?" .
            "   AND use_yn = 'Y'" .
            " ORDER BY view_odr";

        $data = [$rsrv_sq, $img_type];
        $query = $this->db->query($sql, $data);
        return $query->getResultArray();
    }

    public function getImageCountByType($rsrv_sq)
    {
        $sql = "SELECT img_type, COUNT(*) img_cnt" .
            " FROM result_imgs" .
            " WHERE rsrv_sq = ?" .
            " AND use_yn = 'Y'" .
            " GROUP BY img_type";
        $data = [$rsrv_sq];
        $query = $this->db->query($sql, $data);
        return $query->getResultArray();
    }

    // 녹취파일정보
    public function getRecordInfo($rsrv_sq)
    {
        $sql = "SELECT record_sq, rsrv_sq, use_yn, record_path, record_filenm, record_orignm, record_size, record_tel, record_nm, record_dt, remark, insert_usr, DATE_FORMAT(insert_tm, '%Y-%m-%d %H:%i') as insert_tm, update_usr, update_tm" .
            "  FROM result_record" .
            " WHERE rsrv_sq = ?" .
            "   AND use_yn = 'Y'" .
            "   AND record_sq = (SELECT MAX(record_sq)" .
            "                      FROM result_record" .
            "                     WHERE rsrv_sq = ?" .
            "                       AND use_yn = 'Y')";
        $data = array(
            $rsrv_sq,
            $rsrv_sq
        );
        $query = $this->db->query($sql, $data);
        $row = $query->getRowArray();

        return $row;
    }

    // 연락처 저장
    public function saveTel($rcpt_sq, $tel)
    {
        $this->db->transStart();
        $usr_id = session('usr_id');

        $sql = "SELECT rcpt_stat, agent_tel  FROM receipt WHERE rcpt_sq = ?";
        $data = [$rcpt_sq];
        $query = $this->db->query($sql, $data);
        $row = $query->getRowArray();

        $sql = "UPDATE receipt" .
            " SET agent_tel = ?" .
            " WHERE rcpt_sq = ?";
        $data = [$tel, $rcpt_sq];


        if ($query = $this->db->query($sql, $data) === false) {
            return [
                'success' => false,
                'msg' => '저장실패',
            ];
        }

        $this->saveChangedHistory($rcpt_sq, $row['rcpt_stat'], 'C20', $usr_id, $row['agent_tel']);

        $this->db->transComplete();

        return [
            'success' => true,
        ];
    }

    // 거주여부 저장
    public function saveResDB($rcpt_sq, $rsrv_sq, $resYn, $dbUsageAgrYn)
    {
        $this->db->transStart();
        $usr_id = session('usr_id');

        // 변경 전 데이터와 현재 상태 조회
        $sql = "SELECT r.result_cd3, r.resYn, r.dbUsageAgrYn, rc.rcpt_stat 
                FROM result r
                LEFT JOIN receipt rc ON rc.rcpt_sq = r.rcpt_sq
                WHERE r.rsrv_sq = ?";
        $data = array($rsrv_sq);
        $query = $this->db->query($sql, $data);
        $row = $query->getRowArray();

        $sql = "UPDATE result" .
            " SET resYn = ?" .
            " ,dbUsageAgrYn = ?" .
            " WHERE rsrv_sq = ?" .
            " AND rcpt_sq = ?";
        $data = array($resYn, $dbUsageAgrYn, $rsrv_sq, $rcpt_sq);

        if ($this->db->query($sql, $data) === false) {
            return [
                'success' => false,
                'msg' => '저장실패',
            ];
        }

        // 정보변경 이력 저장 (변경 전 → 변경 후)
        $before = "거주:" . ($row['resYn'] ?? 'N') . ", DB동의:" . ($row['dbUsageAgrYn'] ?? 'N');
        $after = "거주:" . $resYn . ", DB동의:" . $dbUsageAgrYn;
        $remark = $before . " => " . $after;
        $rcpt_stat = $row['rcpt_stat'] ?? $row['result_cd3'] ?? '100000';
        
        $this->saveChangedHistory($rcpt_sq, $rcpt_stat, 'C36', $usr_id, $remark);

        $this->db->transComplete();

        return [
            'success' => true,
        ];
    }

    // 평면도요청 저장
    public function saveGround($rcpt_sq, $ground_plan)
    {
        $this->db->transStart();
        $usr_id = session('usr_id');

        // 변경 전 데이터 조회
        $sql = "SELECT ground_plan, rcpt_stat FROM receipt WHERE rcpt_sq = ?";
        $query = $this->db->query($sql, [$rcpt_sq]);
        $row = $query->getRowArray();

        $sql = "UPDATE receipt" .
            " SET ground_plan = ?" .
            " WHERE rcpt_sq = ?";

        $data = [$ground_plan, $rcpt_sq];

        if ($this->db->query($sql, $data) === false) {
            return [
                'success' => false,
                'msg' => '저장실패',
            ];
        }

        // 정보변경 이력 저장
        $remark = "평면도요청: " . ($row['ground_plan'] ?? 'N') . " => " . $ground_plan;
        $this->saveChangedHistory($rcpt_sq, $row['rcpt_stat'], 'C37', $usr_id, $remark);

        $this->db->transComplete();

        return [
            'success' => true,
        ];
    }

    // 동영상촬영여부 저장
    public function saveRequestMovie($rcpt_sq, $rsrv_sq, $exp_movie_yn)
    {
        $this->db->transStart();
        $usr_id = session('usr_id');

        $sql = "SELECT a.result_cd3, b.exp_movie_yn FROM result a INNER JOIN receipt b ON b.rcpt_sq = a.rcpt_sq WHERE rsrv_sq = ?";
        $data = [$rsrv_sq];
        $query = $this->db->query($sql, $data);
        $row = $query->getRowArray();

        $sql = "UPDATE receipt" .
            " SET exp_movie_yn = ?" .
            " WHERE rcpt_sq = ?";
        $data = [$exp_movie_yn, $rcpt_sq];


        if ($this->db->query($sql, $data) === false) {
            return [
                'success' => false,
                'msg' => '저장실패',
            ];
        }

        $this->saveChangedHistory($rcpt_sq, $row['result_cd3'], 'C24', $usr_id, $row['exp_movie_yn'] . ' => ' . $exp_movie_yn);

        $this->db->transComplete();

        return [
            'success' => true,
        ];

    }

    // 중개사메모 저장
    public function saveRequestMessage($rcpt_sq, $rsrv_sq, $request_msg)
    {
        $this->db->transStart();
        $usr_id = session('usr_id');

        if (empty($rsrv_sq)) {
            $sql = "SELECT rsrv_sq FROM result WHERE rcpt_sq = ? ORDER BY rsrv_sq DESC LIMIT 1";
            $data = [$rcpt_sq];
            $query = $this->db->query($sql, $data);
            $row = $query->getResultArray();

            $rsrv_sq = $row['rsrv_sq'];
        }

        $sql = "SELECT result_cd3, request_msg FROM result WHERE rsrv_sq = ?";
        $data = [$rsrv_sq];
        $query = $this->db->query($sql, $data);
        $row = $query->getResultArray();

        $sql = "UPDATE result" .
            " SET request_msg = ?" .
            " WHERE rsrv_sq = ?" .
            " AND rcpt_sq = ?";
        $data = [
            'request_msg' => $request_msg,
            'rsrv_sq' => $rsrv_sq,
            'rcpt_sq' => $rcpt_sq
        ];


        if ($this->db->query($sql, $data) === false) {
            return [
                'success' => false,
                'msg' => '저장실패',
            ];
        }

        $memo = "메모변경";
        $this->saveChangedHistory($rcpt_sq, $row['result_cd3'], 'C19', $usr_id, $memo);

        $this->db->transComplete();

        return [
            'success' => true,
        ];
    }


    // 문자발송
    public function sendSms($dest_phone, $dest_name, $send_phone, $send_name, $msg_type, $rsrv_sq, $rcpt_sq, $cd, $data)
    {
        $this->db->transStart();

        $usr_id = session('usr_id');


        $sql = "SELECT DATE_FORMAT(NOW(), '%Y%m%d-%H%i%s') as cmid, NOW() as currDttm FROM DUAL";
        $query = $this->db->query($sql);
        $row = $query->getRowArray();

        $cmid = $row['cmid'];
        $currDate = $row['currDttm'];

        $category = 'SMS_MSG_TYPE';
        if ($data['comp_sq'] == '2') {
            $category = 'SMS_MSG_TYPE2';
        }

        $codeModel = new CodeModel();
        $code = $codeModel->getCodeDetail($category, $cd);

        $subject = $code['category_nm'];

        if ($cd === "S10") {
            $body = sprintf($code['cd_nm'], $data['rcpt_atclno'], $data['agent_nm'], $data['addr'], $data['rcpt_hscp_nm'], $data['rcpt_dtl_addr'], $data['rcpt_ho']);
        } else {
            $body = $code['cd_nm'];
        }

        $body = str_replace('#매물번호#', $data['rcpt_atclno'], $code['cd_nm']);

        $msg_length = strlen(iconv('UTF-8', 'EUCKR', $body));
        if ($msg_length > 80 && $msg_type == 0) {
            $msg_type = 5;
        }

        $param = [
            //'cmid' => $cmid,
            'dest_phone' => $dest_phone,
            'dest_name' => $dest_name,
            'send_phone' => $send_phone,
            'send_name' => $send_name,
            'subject' => $subject,
            'msg_body' => $body,
            'msg_type' => $msg_type,
            'request_time' => $currDate,
            'send_time' => $currDate,
            'etc1' => $rsrv_sq,
            'etc2' => $cd
        ];

        $this->db->transStart();
        $this->db->table('ums_data')->insert($param);
        $this->db->table('ums_log')->insert($param);

        $remark = "문자 발송 - " . $subject . "(" . $dest_phone . ")";
        $this->saveChangedHistory($rcpt_sq, $data['rcpt_stat'], 'C8', $usr_id, $remark);
        $this->db->transComplete();

        if ($this->db->transStatus() === false) {
            return [
                'success' => false,
                'msg' => '저장실패',
            ];
        } else {
            return [
                'success' => true,
            ];
        }

    }

    public function saveChangedHistory($rcpt_sq, $rcpt_stat, $changed_type, $usr_id, $remark)
    {
        $sql = "INSERT INTO changed_history" .
            " (rcpt_sq, rcpt_stat, changed_type, changed_id, changed_tm, remark)" .
            " VALUES" .
            " (?, ?, ?, ?, now(), ?)";
        $data = [
            $rcpt_sq,
            $rcpt_stat,
            $changed_type,
            $usr_id,
            $remark
        ];
        $res = $this->db->query($sql, $data);
    }


    // 거주인정보저장
    public function saveRecInfo($data)
    {
        $usr_id = session('usr_id');
        $usr_sq = session('usr_sq');

        $this->db->transStart();

        $detail = $this->getDetail($data['rcpt_key']);

        !empty($data['file']) ? $rec_yn = "Y" : $rec_yn = "N";

        $param = [
            $rec_yn,
            $data['rec_tel'],
            $data['rec_nm'],
            $data['rec_remark'],
            $usr_sq,
            $data['rsrv_sq'],
        ];

        $sql = "UPDATE result SET
                rec_yn = ? ";
        if ($rec_yn == "Y") {
            $sql .= ", record_cplt_dt = NOW()";
        }
        $sql .= ", rec_tel = ?
                , rec_nm = ?
                , remark = ?
                , update_tm = NOW()
                , update_usr = ?
                WHERE rsrv_sq = ?
                ";

        if ($this->db->query($sql, $param) === false) {
            return [
                'success' => false,
                'msg' => '저장실패',
            ];
        }


        if (!empty($data['file'])) {
            $rec_sql = "SELECT * FROM result_record WHERE rsrv_sq = ? AND use_yn = 'Y'";
            $rec_data = array($data['rsrv_sq']);
            $query = $this->db->query($rec_sql, $rec_data);
            $preData = $query->getRowArray();


            $f = $data['file'];

            $sql = "INSERT INTO result_record
                    (rsrv_sq, use_yn, record_path, record_filenm, record_orignm, record_size, record_tel, record_nm, record_dt, remark, insert_usr, insert_tm, cloud_upload_yn)
                    VALUES
                    (?, 'Y', ?, ?, ?, ?, ?, ?, NOW(), ?, ?, NOW(), 'Y')
                    ";
            $param = [
                $data['rsrv_sq'],
                $f['upload_path'],
                $f['file_name'],
                $f['origin_name'],
                $f['size'],
                $data['rec_tel'],
                $data['rec_nm'],
                $data['rec_remark'],
                $usr_sq
            ];

            $this->db->query($sql, $param);

            // 이전 데이터 미사용 처리
            if (!empty($preData)) {
                $rec_sql = "UPDATE result_record SET use_yn = 'N' WHERE record_sq = ? AND rsrv_sq = ?";
                $this->db->query($rec_sql, [$preData['record_sq'], $data['rsrv_sq']]);

                $remark = "녹취파일 업로드 - " . $preData['record_nm'] . "(" . $preData['record_tel'] . ") -> " . $data['rec_nm'] . "(" . $data['rec_tel'] . ")";
            } else {
                $remark = "녹취파일 업로드 - " . $data['rec_nm'] . "(" . $data['rec_tel'] . ")";
            }

            $this->saveChangedHistory($data['rcpt_sq'], $detail['rcpt_stat'], 'C15', $usr_id, $remark);

        }

        if (!empty($detail['rec_tel'])) {
            $remark = "거주인정보변경 - " . $detail['rec_nm'] . "(" . $detail['rec_tel'] . ") -> " . $data['rec_nm'] . "(" . $data['rec_tel'] . ")";
        } else {
            $remark = "거주인정보변경 - " . $data['rec_nm'] . "(" . $data['rec_tel'] . ")";
        }

        $this->saveChangedHistory($data['rcpt_sq'], $detail['rcpt_stat'], 'C15', $usr_id, $remark);

        $this->db->transComplete();

        // 저장 후 최신 거주인 정보 반환
        $record = $this->getRecordInfo($data['rsrv_sq']);

        return [
            'success' => true,
            'rec_tel' => $data['rec_tel'],
            'rec_nm' => $data['rec_nm'],
            'remark' => $data['rec_remark'],
            'record' => $record
        ];
    }

    // 거주인 정보 조회
    public function getRecInfoByRcptSq($rcpt_sq)
    {
        try {
            // 기존 getDetail 메서드 활용 (이미 최적화된 쿼리)
            $data = $this->getDetail($rcpt_sq);
            
            if (empty($data)) {
                log_message('error', '[ReceiptModel::getRecInfoByRcptSq] Receipt not found for rcpt_sq: ' . $rcpt_sq);
                return null;
            }

            // 녹취파일 정보 조회 (기존 getRecordInfo 활용)
            $record = null;
            if (!empty($data['rsrv_sq'])) {
                $record = $this->getRecordInfo($data['rsrv_sq']);
            }

            return [
                'rec_tel' => $data['rec_tel'] ?? '',
                'rec_nm' => $data['rec_nm'] ?? '',
                'remark' => $data['remark'] ?? '',
                'record' => $record ?: null
            ];
        } catch (\Exception $e) {
            log_message('error', '[ReceiptModel::getRecInfoByRcptSq] Exception: ' . $e->getMessage());
            throw $e;
        }
    }

    // 워터마크 조회
    public function getWatermarkList($rcpt_cpid)
    {
        $builder = $this->db->table('watermark');

        $builder->select('cpid, wm_type, wm_img_path, wm_img_height, wm_img_width, wm_position, wm_img_opacity, wm_space, text_font, text_color, text_opacity, text_size, text_pixel, img_width_min, img_width_max');

        $builder->where('cpid', $rcpt_cpid);


        $row = $builder->get()->getResultArray();
        return $row;
    }

    // 업로드정보 저장
    public function saveImg($param)
    {
        $this->db->transStart();

        $usr_id = session('usr_id');
        $usr_sq = session('usr_sq');

        $receipt = $param['receipt'];

        // 실제 클라우드 업로드 성공 여부를 파라미터에서 받아옴 (기본값 'Y')
        $cloud_upload_yn = $param['cloud_upload_yn'] ?? 'Y';

        if ($param['img_type'] == 'I6' || $param['img_type'] == 'I7') {
            $yn_sql = "update receipt " .
                " set exp_spc_yn = 'Y' " .
                " where rcpt_sq = ? ";
            $yn_data = [$param['rcpt_sq']];
            $this->db->query($yn_sql, $yn_data);
        } else if ($param['img_type'] == 'I8') {
            $yn_sql = "update receipt " .
                " set exp_spc_yn = 'Y' " .
                " where rcpt_sq = ? ";
            $yn_data = [$param['rcpt_sq']];
            $this->db->query($yn_sql, $yn_data);
        } else if ($param['img_type'] == 'I9') {
            $yn_sql = "update receipt " .
                " set image_360_yn = 'Y' " .
                " where rcpt_sq = ? ";
            $yn_data = [$param['rcpt_sq']];
            $this->db->query($yn_sql, $yn_data);
        } else if ($param['img_type'] == 'I11') {
            $yn_sql = "update receipt " .
                " set check_list_img_yn = 'Y' " .
                " where rcpt_sq = ? ";
            $yn_data = [$param['rcpt_sq']];
            $this->db->query($yn_sql, $yn_data);
        }

        //한장의 사진만 업로드하는것들은 UPDATE -> INSERT
        $img_list = ['I1', 'I2', 'I5', 'I6', 'I7', 'V1', 'I10', 'I11'];

        // 주소가 rcpt_jibun_addr 있을때는 그 주소로 
        $addr_nm = $receipt['addr'];
        if ($receipt['rcpt_jibun_addr']) {
            $img_hannm = '컨펌스_' . $addr_nm . ' ' . $receipt['rcpt_jibun_addr'] . ' ' . $receipt['rcpt_etc_addr'] . '_' . $receipt['excls_spc'] . '.jpeg';
        } else {
            $img_hannm = '컨펌스_' . $addr_nm . ' ' . $receipt['rcpt_dtl_addr'] . ' ' . $receipt['rcpt_ho'] . '_' . $receipt['excls_spc'] . '.jpeg';
        }

        if (in_array($param['img_type'], $img_list)) {
            //업데이트할게없어도 에러가 안난다 단지 row(s)affected 가 0 일뿐
            $sql = "UPDATE result_imgs" .
                "   SET use_yn = 'N'" .
                " WHERE rsrv_sq = ?" .
                "   AND img_type = ?" .
                "   AND use_yn = 'Y'";
            $data = [$param['rsrv_sq'], $param['img_type']];
            $this->db->query($sql, $data);

            //새로운 이미지 생성
            $sql = "INSERT INTO result_imgs(rsrv_sq, use_yn, img_type, view_odr, img_path, img_filenm, img_nm, img_size, img_width, img_height, insert_usr, insert_tm, meta_data, img_hannm , cloud_upload_yn )" .
                "VALUES				   (?, 'Y', ?, 1, ?, ?, ?, ?, ?, ?, ?, NOW(), ?,? , ?)";
            $data = [
                $param['rsrv_sq'],
                $param['img_type'],
                $param['upload_path'],
                $param['file_name'],
                $param['origin_name'],
                $param['size'],
                $param['width'],
                $param['height'],
                $usr_sq,
                isset($param['meta_data']) ? $param['meta_data'] : null,
                $img_hannm,
                $cloud_upload_yn
            ];
            $res = $this->db->query($sql, $data);
        } else {
            $odr_sql = "SELECT COALESCE(MAX(view_odr), 0) + 1 as seq FROM result_imgs WHERE rsrv_sq = ? AND img_type = ? AND use_yn = 'Y'";
            $odr_data = array($param['rsrv_sq'], $param['img_type']);
            $query = $this->db->query($odr_sql, $odr_data);
            $row = $query->getRowArray();
            $view_odr = $row['seq'];

            $sql = "INSERT INTO result_imgs(rsrv_sq, use_yn, img_type, view_odr, img_path, img_filenm, img_nm, img_size, img_width, img_height, insert_usr, insert_tm, meta_data, img_hannm , cloud_upload_yn )" .
                "VALUES				   (?, 'Y', ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), ?,?, ?)";

            $data = [
                $param['rsrv_sq'],
                $param['img_type'],
                $view_odr,
                $param['upload_path'],
                $param['file_name'],
                $param['origin_name'],
                $param['size'],
                $param['width'],
                $param['height'],
                $usr_sq,
                isset($param['meta_data']) ? $param['meta_data'] : null,
                $img_hannm,
                $cloud_upload_yn
            ];
            $res = $this->db->query($sql, $data);
        }

        if ($res) {
            switch ($param['img_type']) {
                case 'I1':
                    $remark = "홍보확인서 사진 업로드";
                    break;
                case 'I2':
                    $remark = "현장확인 내역서 사진 업로드";
                    break;
                case 'I3':
                    $remark = "건물외관 사진 업르도";
                    break;
                case 'I4':
                    $remark = "매물사진 업로드";
                    break;
                case 'I5':
                    $remark = "평면도 업로드";
                    break;
                case 'I6':
                    $remark = "전용면적 파일 업로드";
                    break;
                case 'I7':
                    $remark = "공용면적 파일 업로드";
                    break;
                case 'I8':
                    $remark = "분양권 파일 업로드";
                    break;
                case 'I9':
                    $remark = "360이미지 업로드";
                    break;
                case 'I10':
                    $remark = "촬영동의서 사진 업로드";
                    break;
                case 'I11':
                    $remark = "체크리스트 사진 업로드";
                    break;
                case 'V1':
                    $remark = "동영상 업로드";
                    break;
            }


            $this->saveChangedHistory($param['rcpt_sq'], $receipt['rcpt_stat'], 'C16', $usr_id, $remark);

            $this->db->transComplete();

            return [
                'success' => true,
            ];
        } else {
            return [
                'success' => false,
                'msg' => '저장실패',
            ];
        }

    }

    // 파일정보조회
    public function getUploadFileInfo($img_sq)
    {
        $sql = "SELECT * FROM result_imgs WHERE img_sq = ?";

        $query = $this->db->query($sql, [$img_sq]);
        $row = $query->getRowArray();

        return $row;

    }

    // 업로드파일 삭제
    public function removeUploadFile($rcpt_sq, $img_sq)
    {
        $this->db->transStart();

        $usr_id = session('usr_id');

        // 이미지정보 조회
        $row = $this->getUploadFileInfo($img_sq);

        if (empty($row)) {
            $this->db->transComplete();
            // 파일이 이미 삭제된 경우 성공으로 처리 (중복 삭제 요청 방지)
            log_message('info', "[removeUploadFile] 파일 정보 없음 (이미 삭제됨): img_sq={$img_sq}");
            return [
                'success' => true,
                'msg' => '이미 삭제된 파일입니다',
            ];
        }

        if ($row['img_type'] == 'I6' || $row['img_type'] == 'I7') {
            $yn_sql = "update receipt " .
                " set exp_spc_yn = 'N' " .
                " where rcpt_sq = ? ";
            $yn_data = [$rcpt_sq];
            $this->db->query($yn_sql, $yn_data);
        } else if ($row['img_type'] == 'I8') {
            $yn_sql = "UPDATE receipt" .
                " SET parcel_out_yn = CASE (SELECT COUNT('x')" .
                " 							FROM result_imgs " .
                " 							WHERE rsrv_sq = (SELECT rsrv_sq FROM result_imgs WHERE img_sq = ? AND img_type = 'I8')" .
                " 							AND use_yn = 'Y'" .
                " 							AND img_type = 'I8') WHEN 0 THEN 'N' ELSE 'Y' END" .
                " WHERE rcpt_sq = ? ";
            $yn_data = [$img_sq, $rcpt_sq];
            $this->db->query($yn_sql, $yn_data);
        } else if ($row['img_type'] == 'I9') {
            $yn_sql = "UPDATE receipt" .
                " SET image_360_yn = (" .
                "		CASE (SELECT COUNT(1)" .
                "			  FROM result_imgs" .
                "		      WHERE rsrv_sq = (SELECT rsrv_sq FROM result_imgs WHERE img_sq = ? AND img_type = 'I9')" .
                "			  AND img_type = 'I9' AND use_yn = 'Y')" .
                "		WHEN 0 THEN 'N'" .
                "		ELSE 'Y'" .
                "		END" .
                " 		)" .
                " WHERE rcpt_sq = ?";
            $yn_data = [$img_sq, $rcpt_sq];
            $this->db->query($yn_sql, $yn_data);
        } else if ($row['img_type'] == 'I11') {
            $yn_sql = "update receipt " .
                " set check_list_img_yn = 'N' " .
                " where rcpt_sq = ? ";
            $yn_data = [$rcpt_sq];
            $this->db->query($yn_sql, $yn_data);
        }

        //삭제이미지보다 순번이 높은거는 순번 업데이트
        $sql = "UPDATE result_imgs SET view_odr = view_odr - 1 WHERE rsrv_sq = ? AND img_type = ? AND view_odr > ? AND use_yn = 'Y'";
        $data = [$row['rsrv_sq'], $row['img_type'], $row['view_odr']];

        $this->db->query($sql, $data);

        //이미지 삭제
        $sql = "DELETE FROM result_imgs WHERE img_sq = ?";
        $data = [$img_sq];

        $deleteResult = $this->db->query($sql, $data);

        if (in_array($row['img_type'], ['I1', 'I2', 'I8', 'I10', 'I11'])) {
            $remark = "";
            switch ($row['img_type']) {
                case 'I1':
                    $remark = "홍보확인서 사진 삭제";
                    break;
                case 'I2':
                    $remark = "현장확인 내역서 사진 삭제";
                    break;
                case 'I8':
                    $remark = "분양권 파일 삭제";
                    break;
                case 'I10':
                    $remark = "촬영동의서 사진 삭제";
                    break;
                case 'I11':
                    $remark = "체크리스트 사진 삭제";
                    break;
            }

            // 상태값을 가져오기위한 쿼리 해오기
            $sql = "SELECT rcpt_stat FROM receipt WHERE rcpt_sq = ?";
            $data = [$rcpt_sq];
            $query = $this->db->query($sql, $data);
            $rowStat = $query->getRowArray();

            $this->saveChangedHistory($rcpt_sq, $rowStat['rcpt_stat'], 'C31', $usr_id, $remark);
        }

        $this->db->transComplete();

        if ($deleteResult === false || $this->db->transStatus() === false) {
            return [
                'success' => false,
                'msg' => '삭제실패',
            ];
        }

        return [
            'success' => true,
        ];
    }
    
    // 이미지 순서 업데이트
    public function updateImageOrder($rcpt_sq, $img_type, $orderData)
    {
        log_message('info', '[ReceiptModel::updateImageOrder] 시작 - rcpt_sq: ' . $rcpt_sq . ', img_type: ' . $img_type . ', 개수: ' . count($orderData));
        
        $this->db->transStart();
        
        try {
            $updateCount = 0;
            foreach ($orderData as $item) {
                $img_sq = $item['img_sq'] ?? null;
                $view_odr = $item['view_odr'] ?? null;
                
                if (!$img_sq || !$view_odr) {
                    log_message('warning', '[ReceiptModel::updateImageOrder] 스킵 - img_sq 또는 view_odr 없음');
                    continue;
                }
                
                $sql = "UPDATE result_imgs SET view_odr = ? WHERE img_sq = ? AND img_type = ?";
                $data = [$view_odr, $img_sq, $img_type];
                
                log_message('debug', '[ReceiptModel::updateImageOrder] 업데이트 - img_sq: ' . $img_sq . ', view_odr: ' . $view_odr);
                
                $result = $this->db->query($sql, $data);
                if ($result) {
                    $updateCount++;
                }
            }
            
            $this->db->transComplete();
            
            if ($this->db->transStatus() === false) {
                log_message('error', '[ReceiptModel::updateImageOrder] 트랜잭션 실패');
                return [
                    'success' => false,
                    'msg' => '순서 업데이트 실패',
                ];
            }
            
            log_message('info', '[ReceiptModel::updateImageOrder] 완료 - 업데이트 수: ' . $updateCount);
            
            return [
                'success' => true,
            ];
            
        } catch (\Exception $e) {
            log_message('error', '[ReceiptModel::updateImageOrder] Exception: ' . $e->getMessage());
            
            return [
                'success' => false,
                'msg' => '순서 업데이트 중 오류 발생: ' . $e->getMessage(),
            ];
        }
    }

    // 촬영위치 저장
    public function saveImgLocation($img_sq, $rsrv_sq, $location)
    {
        $sql = "UPDATE result_imgs" .
            " SET img_location = ?" .
            " WHERE img_sq = ?" .
            " AND rsrv_sq = ?";

        $data = [$location, $img_sq, $rsrv_sq];

        if ($this->db->query($sql, $data) === false) {
            return [
                'success' => false,
                'msg' => '저장실패',
            ];
        } else {
            return [
                'success' => true,
            ];

        }
    }

    /**
     * 배정자 등록
     */
    public function assignRegist($rcpt_sq, $rsrv_date, $rsrv_tm_ap, $rsrv_tm_hour, $dept_sq, $usr_sq, $receipt)
    {
        // 세션정보
        $usr_id = session('usr_id');
        $reg_usr_sq = session('usr_sq');

        $this->db->transStart();

        // 변경전 기존 데이터 가져오기
        $org_sql = "SELECT * FROM result WHERE rcpt_sq = ?";
        $query = $this->db->query($org_sql, [$rcpt_sq]);
        $row = $query->getRowArray();

        // 예약확인
        $sql1 = "UPDATE result" .
            "   SET rsrv_date = ?" .
            "      ,rsrv_tm_ap = ?" .
            "      ,rsrv_tm_hour = ?" .
            "      ,rsrv_save_dt = now()" .
            "      ,update_tm = now()" .
            "      ,update_usr = ?" .
            " WHERE rcpt_sq = ?";

        $data1 = [
            $rsrv_date,
            $rsrv_tm_ap,
            $rsrv_tm_hour,
            $reg_usr_sq,
            $rcpt_sq
        ];

        if ($this->db->query($sql1, $data1) === false) {
            return [
                'success' => false,
                'msg' => '저장 실패',
            ];
        }

        // 배정
        $sql2 = "UPDATE result" .
            "   SET dept_sq = ?" .
            "      ,usr_sq = ?" .
            "      ,result_cd1 = 20" .
            "      ,result_cd2 = 2000" .
            "      ,result_cd3 = 200000" .
            "      ,update_usr = ?" .
            "      ,update_tm = now()" .
            "      ,assign_save_dt = now()" .
            "      ,rsrv_cplt_dt = now()" .
            " WHERE rcpt_sq = ?";

        $data2 = [
            $dept_sq,
            $usr_sq,
            $reg_usr_sq,
            $rcpt_sq
        ];

        if ($this->db->query($sql2, $data2) === false) {
            return [
                'success' => false,
                'msg' => '저장 실패',
            ];
        }

        // 매물상태 변경
        $rcpt_sql = "UPDATE receipt" .
            "   SET rcpt_stat = 200000" .
            " WHERE rcpt_sq = ?";
        $this->db->query($rcpt_sql, [$rcpt_sq]);

        // 정보변경이력 저장
        if (!empty($row)) {
            $remark = "{$row['rsrv_date']} {$row['rsrv_tm_ap']} {$row['rsrv_tm_hour']}시 -> {$rsrv_date} {$rsrv_tm_ap} {$rsrv_tm_hour}시";
        } else {
            $remark = "{$receipt['rsrv_date']} {$receipt['rsrv_tm_ap']} -> {$rsrv_date} {$rsrv_tm_hour}";
        }

        $this->saveChangedHistory($rcpt_sq, '200000', 'C11', $usr_id, $remark);

        $this->db->transComplete();


        return [
            'success' => true,
        ];
    }


    /**
     * 취소
     */
    public function rsrvcancel($rcpt_sq, $rsrv_sq, $result_cd2, $result_cd3, $result_msg, $receipt)
    {
        // 세션정보
        $usr_id = session('usr_id');
        $usr_sq = session('usr_sq');
        $usr_nm = session('usr_nm');

        // 변경전 기존 데이터 가져오기
        $org_sql = "SELECT * FROM result WHERE rcpt_sq = ?";
        $query = $this->db->query($org_sql, [$rcpt_sq]);
        $row = $query->getRowArray();

        $this->db->transStart();

        if ($result_cd2 == "9050") {
            $sql = "UPDATE result" .
                "   SET result_cd1 = '90'" .
                "      ,result_cd2 = ?" .
                "      ,result_cd3 = ?" .
                "      ,result_msg = ?" .
                "      ,check_fail_dt = now()" .
                "      ,update_usr = ?" .
                "      ,update_tm = now()" .
                " WHERE rsrv_sq = ?";
        } else {
            $sql = "UPDATE result" .
                "   SET result_cd1 = '90'" .
                "      ,result_cd2 = ?" .
                "      ,result_cd3 = ?" .
                "      ,result_msg = ?" .
                "      ,cancel_dt = now()" .
                "      ,update_usr = ?" .
                "      ,update_tm = now()" .
                " WHERE rsrv_sq = ?";
        }

        $data = [
            $result_cd2,
            $result_cd3,
            $result_msg,
            $usr_sq,
            $rsrv_sq
        ];

        $res = $this->db->query($sql, $data);

        if (!$res) {
            $return = [
                'success' => false,
                'msg' => '저장실패',
            ];
        } else {
            // 매물상태 변경
            $rcpt_sql = "UPDATE receipt" .
                "   SET rcpt_stat = ?" .
                " WHERE rcpt_sq = ?";
            $rcpt_data = [$result_cd3, $rcpt_sq];
            $this->db->query($rcpt_sql, $rcpt_data);

            // 정보변경이력 저장
            if (!empty($row['result_msg'])) {
                $remark = $row['result_msg'] . " -> " . $result_msg;
            } else {
                $remark = $result_msg;
            }
            $this->saveChangedHistory($rcpt_sq, $result_cd3, 'C5', $usr_id, $remark);

            // 문자발송
            if ($result_cd2 == "9010" || $result_cd2 == "9020") {
                // 접수취소, 예약취소
                $this->sendSms($receipt['agent_head_tel'], $receipt['agent_nm'], '1600-5749', $usr_nm, 0, $rsrv_sq, $rcpt_sq, 'S2', $receipt);
            } else if ($result_cd2 == "9030") {
                // 방문전 취소
                $this->sendSms($receipt['agent_head_tel'], $receipt['agent_nm'], '1600-5749', $usr_nm, 0, $rsrv_sq, $rcpt_sq, 'S4', $receipt);
            } else if ($result_cd2 == "9040") {
                // 방문후 취소
                $this->sendSms($receipt['agent_head_tel'], $receipt['agent_nm'], '1600-5749', $usr_nm, 0, $rsrv_sq, $rcpt_sq, 'S5', $receipt);
                $this->sendSms($receipt['agent_head_tel'], $receipt['agent_nm'], '1600-5749', $usr_nm, 0, $rsrv_sq, $rcpt_sq, 'S5-1', $receipt);
            } else if ($result_cd2 == "9045") {
                // 촬영후 취소
                $this->sendSms($receipt['agent_head_tel'], $receipt['agent_nm'], '1600-5749', $usr_nm, 0, $rsrv_sq, $rcpt_sq, 'S6', $receipt);
            }

            if ($result_cd3 == "905010") {
                // 거주인녹취실패 취소(검수실패)
                $this->sendSms($receipt['agent_head_tel'], $receipt['agent_nm'], '1600-5749', $usr_nm, 0, $rsrv_sq, $rcpt_sq, 'S9', $receipt);
                $this->sendSms($receipt['agent_head_tel'], $receipt['agent_nm'], '1600-5749', $usr_nm, 0, $rsrv_sq, $rcpt_sq, 'S9-1', $receipt);
            } else if ($result_cd3 == "905020") {
                // 홍보확인서 미수취 취소(검수실패)
                $this->sendSms($receipt['agent_head_tel'], $receipt['agent_nm'], '1600-5749', $usr_nm, 0, $rsrv_sq, $rcpt_sq, 'S11', $receipt);
                $this->sendSms($receipt['agent_head_tel'], $receipt['agent_nm'], '1600-5749', $usr_nm, 0, $rsrv_sq, $rcpt_sq, 'S11-1', $receipt);
            }

            $return = [
                'success' => true,
            ];
        }

        $this->db->transComplete();

        return $return;
    }
}