<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Barber extends CI_Controller
{
    // ----------------------------------------------------------
    //  CONSTRUCTOR
    // ----------------------------------------------------------
    public function __construct()
{
    parent::__construct();
    $this->load->library('encrypt');
    $this->load->helper('az_auth');
    $this->load->helper('az_config');
    $this->load->helper('az_crud');
    $this->load->helper('az_core');
    $this->load->helper('az_surya');
    $this->load->helper('az_nws');
    $this->load->helper('az_barber');   // ← TAMBAHKAN BARIS INI
    az_check_auth('dashboard');
}

    // Penjaga: hanya admin + produksi (via hak menu history_bill_production)
    private function _guard()
    {
        $idrole = $this->session->userdata('idrole');
        $this->db->where('idrole', $idrole);
        $this->db->where('menu_name', 'history_bill_production');
        $this->db->where('access', 1);
        $this->db->where('status', 1);
        if ($this->db->count_all_results('user_role') <= 0) { show_404();}
    }
    // ----------------------------------------------------------
//  GUARD KHUSUS ADMIN (untuk laporan analisa NWS)
// ----------------------------------------------------------
private function _guard_admin()
{
    if ($this->session->userdata('role_name') != 'administrator') { show_404(); }
}

// ==========================================================
//  LANGKAH 8: tandai barang PU selesai / batal (dari Barber)
// ==========================================================
public function pu_done()
{
$this->_guard();
$id  = (int)$this->input->post('id');
$val = (int)$this->input->post('val');
if ($id <= 0) { echo json_encode(array('err_code' => 1, 'err_message' => 'ID tidak valid')); return; }
$upd = ($val === 1)
? array('status' => 1, 'updated' => date('Y-m-d H:i:s'), 'updatedby' => $this->session->userdata('username'))
: array('status' => 0, 'updated' => date('Y-m-d H:i:s'), 'updatedby' => $this->session->userdata('username'));
$this->db->where('iddstb_clean_pu', $id);
$this->db->update('dstb_clean_pu', $upd);
echo json_encode(array('err_code' => 0, 'status' => ($val === 1 ? 1 : 0)));
}

    // ==========================================================
    //  1. FORM (filter outlet + tombol Barber & Keluar)
    // ==========================================================
    public function index()
    {
        $this->_guard();
        $this->load->library('AZApp');
        $app = $this->azapp;
        $this->load->helper('az_crud');
        $this->load->helper('az_core');

        $data = array();
        $data['outlet']        = az_select_outlet('outlet', 'transaction_group');
        $data['report_url']    = app_url() . 'barber/report';
        $data['dashboard_url'] = app_url();
        $data['today_label']   = date('d/m/Y');

        $view = $this->load->view('barber/v_form', $data, true);
        $app->add_content($view);

        $data_header = array();
        $data_header['title']      = 'Pantau Barber';
        $data_header['breadcrumb'] = array('dashboard');
        $app->set_data_header($data_header);
        echo $app->render();
    }

    // ==========================================================
    //  2. LAPORAN BARBER (tab baru)
    // ==========================================================
    public function report()
    {
        $this->_guard();
        $this->load->view('sales_transaction/v_barber', $this->_brb_prep());
    }

    // ==========================================================
    //  3. AJAX: daftar pakaian untuk modal konfirmasi
    // ==========================================================
    public function get_ready_items()
    {
        $this->_guard();
        $id = (int)$this->input->post('id');
        if ($id <= 0) { echo json_encode(array('err_code' => 1, 'err_message' => 'ID tidak valid')); return; }

        $this->db->select('tg.code, c.customer_name');
        $this->db->from('transaction_group tg');
        $this->db->join('customer c', 'c.idcustomer = tg.idcustomer', 'left');
        $this->db->where('tg.idtransaction_group', $id);
        $this->db->where('tg.status', 1);
        $tg = $this->db->get()->row();
        if (!$tg) { echo json_encode(array('err_code' => 1, 'err_message' => 'Bill tidak ditemukan')); return; }

        $this->db->select('tr.idtransaction, pr.product_name, tr.trx_note, it.idcolour, it.idhue, tr.idspot');
        $this->db->from('transaction tr');
        $this->db->join('item it', 'it.iditem = tr.iditem', 'left');
        $this->db->join('product pr', 'pr.idproduct = it.idproduct', 'left');
        $this->db->where('tr.idtransaction_group', $id);
        $this->db->where('tr.status', 1);
        $this->db->order_by('tr.idtransaction ASC');
        $rows = $this->db->get()->result();

        $tot = count($rows);
        $items = array();
        $n = 0;
        foreach ($rows as $r) {
            $n++;
            $items[] = array(
                'n'            => $n,
                'tot'          => $tot,
                'product_name' => (string)$r->product_name,
                'colour'       => function_exists('az_convert_colour') ? az_convert_colour($r->idcolour) : '',
                'hue'          => function_exists('az_convert_hue')    ? az_convert_hue($r->idhue)       : '',
                'spot'         => function_exists('az_convert_spot')   ? az_convert_spot($r->idspot)     : '',
                'trx_note'     => trim((string)$r->trx_note),
            );
        }
        echo json_encode(array(
            'err_code' => 0,
            'code'     => $tg->code,
            'customer' => $tg->customer_name,
            'items'    => $items,
        ));
    }

    // ==========================================================
    //  4. AJAX: toggle siap-kirim (1) / batal (0)
    // ==========================================================
    public function toggle_ready()
    {
        $this->_guard();
        $id  = (int)$this->input->post('id');
        $val = (int)$this->input->post('val');
        if ($id <= 0) { echo json_encode(array('err_code' => 1, 'err_message' => 'ID tidak valid')); return; }

        $this->db->where('idtransaction_group', $id);
        if (!$this->db->get('transaction_group')->row()) {
            echo json_encode(array('err_code' => 1, 'err_message' => 'Bill tidak ditemukan')); return;
        }

        if ($val === 1) {
            $upd = array(
                'ready_to_deliver'    => 1,
                'ready_to_deliver_at' => date('Y-m-d H:i:s'),
                'ready_to_deliver_by' => $this->session->userdata('iduser'),
            );
            $state = 'B';
            $ready_at = date('d/m/Y H:i');
        } else {
            $upd = array(
                'ready_to_deliver'    => 0,
                'ready_to_deliver_at' => NULL,
                'ready_to_deliver_by' => NULL,
            );
            $state = 'A';
            $ready_at = '';
        }
        $this->db->where('idtransaction_group', $id);
        $this->db->update('transaction_group', $upd);

        echo json_encode(array(
            'err_code'      => 0,
            'state'         => $state,
            'ready_at'      => $ready_at,
            'ready_by_name' => (string)$this->session->userdata('name'),
            'dstb_code'     => '',
        ));
    }

// ==========================================================
//  SIMPAN PENGATURAN "BESOK" & KALENDER LIBUR
// ==========================================================
public function save_barber_setting()
{
    $this->_guard();
    az_barber_ensure_tables();
    $mode   = ($this->input->post('libur_mode') === 'manual') ? 'manual' : 'auto';
    $minggu = $this->input->post('minggu_libur') ? 1 : 0;
    $skip   = max(1, (int)$this->input->post('skip_days'));
    az_barber_set_setting('libur_mode', $mode);
    az_barber_set_setting('minggu_libur', $minggu);
    az_barber_set_setting('skip_days', $skip);
    // tambah tanggal libur (jika diisi)
    $hd = trim((string)$this->input->post('libur_date'));
    $hl = trim((string)$this->input->post('libur_label'));
    if (strlen($hd) > 0) {
        $this->db->where('libur_date', $hd);
        $this->db->where('status', 1);
        if ($this->db->count_all_results('barber_libur') == 0) {
            $this->db->insert('barber_libur', array('libur_date' => $hd, 'label' => $hl, 'status' => 1));
        }
    }
    $qs = (string)$this->input->post('back_qs');
    redirect('barber/report' . (strlen($qs) ? '?' . $qs : ''));
}

public function delete_barber_libur()
{
    $this->_guard();
    $id = (int)$this->input->get('id');
    if ($id > 0) {
        $this->db->where('idbarber_libur', $id);
        $this->db->update('barber_libur', array('status' => 0));
    }
    $qs = (string)$this->input->get('qs');
    redirect('barber/report' . (strlen($qs) ? '?' . $qs : ''));
}

    // ==========================================================
    //  QUERY + PREP LAPORAN
    // ==========================================================
    private function _brb_query($q1, $q2, $idoutlet)
    {
        $this->db->select("
            tg.idtransaction_group, tg.idoutlet, tg.code, tg.date, tg.duedate,
            tg.total_pcs, tg.note, tg.dstb_status, tg.pending_description,
            tg.ready_to_deliver, tg.ready_to_deliver_at,
            rb.name AS ready_by_name,
            c.customer_name, c.phone AS customer_phone,
            o.outlet_name,
            (SELECT dc.dstb_code FROM dstb_clean_detail dcd
               JOIN dstb_clean dc ON dc.iddstb_clean = dcd.iddstb_clean AND dc.status = 1
              WHERE dcd.idtransaction_group = tg.idtransaction_group
              ORDER BY dc.iddstb_clean DESC LIMIT 1) AS dstb_clean_code,
            (SELECT dd.dstb_note FROM dstb_clean dd
               JOIN dstb_clean_detail ddd ON ddd.iddstb_clean = dd.iddstb_clean
              WHERE ddd.idtransaction_group = tg.idtransaction_group
              ORDER BY dd.iddstb_clean DESC LIMIT 1) AS dstb_clean_note,
            (SELECT dp.dstb_note FROM dstb_process dp
               JOIN dstb_process_detail dpd ON dpd.iddstb_process = dp.iddstb_process
              WHERE dpd.idtransaction_group = tg.idtransaction_group
              ORDER BY dp.iddstb_process DESC LIMIT 1) AS dstb_process_note
        ", FALSE);

        $this->db->from('transaction_group tg');
        $this->db->join('customer c', 'tg.idcustomer = c.idcustomer', 'left');
        $this->db->join('outlet o', 'tg.idoutlet = o.idoutlet', 'left');
        $this->db->join('user rb', 'rb.iduser = tg.ready_to_deliver_by', 'left');

        $this->db->where('tg.status', 1);
        $this->db->where('(tg.pickup_date IS NULL OR tg.pickup_date = "0000-00-00 00:00:00")', NULL, FALSE);
        $this->db->where_in('tg.dstb_status', array('BARU', 'DIJEMPUT', 'DIPROSES'));

        if (strlen($q1) > 0) { $this->db->where('DATE(tg.duedate) >=', $q1); }
        if (strlen($q2) > 0) { $this->db->where('DATE(tg.duedate) <=', $q2); }
        if (strlen($idoutlet) > 0) { $this->db->where('tg.idoutlet', $idoutlet); }

        $this->db->order_by('tg.duedate ASC, tg.code ASC');
        return $this->db->get()->result();
    }

    private function _brb_items($ids)
    {
        $map = array();
        if (empty($ids)) { return $map; }
        $this->db->query("SET SESSION group_concat_max_len = 100000");
        $this->db->select("
            t.idtransaction_group,
            GROUP_CONCAT(DISTINCT p.product_name ORDER BY p.product_name SEPARATOR ', ') AS jenis,
            GROUP_CONCAT(DISTINCT CASE WHEN IFNULL(t.trx_note,'') <> '' THEN t.trx_note END SEPARATOR ' | ') AS item_notes
        ", FALSE);
        $this->db->from('transaction t');
        $this->db->join('item i', 't.iditem = i.iditem', 'left');
        $this->db->join('product p', 'i.idproduct = p.idproduct', 'left');
        $this->db->where_in('t.idtransaction_group', $ids);
        $this->db->group_by('t.idtransaction_group');
        foreach ($this->db->get()->result() as $r) {
            $map[$r->idtransaction_group] = array('jenis' => (string)$r->jenis, 'notes' => (string)$r->item_notes);
        }
        return $map;
    }

    private function _brb_topjenis($ids)
    {
        if (empty($ids)) { return array(); }
        $this->db->select('p.product_name AS name, COUNT(*) AS pcs');
        $this->db->from('transaction t');
        $this->db->join('item i', 't.iditem = i.iditem', 'left');
        $this->db->join('product p', 'i.idproduct = p.idproduct', 'left');
        $this->db->where_in('t.idtransaction_group', $ids);
        $this->db->where('p.product_name IS NOT NULL', NULL, FALSE);
        $this->db->group_by('p.product_name');
        $this->db->order_by('pcs DESC');
        $this->db->limit(10);
        return $this->db->get()->result();
    }

    private function _brb_prep()
{
    $date_1   = $this->input->get('date_1');
    $date_2   = $this->input->get('date_2');
    $idoutlet = trim((string)$this->input->get('idoutlet'));

    $today = date('Y-m-d');

    // ---- BESOK EFEKTIF + RENTANG ----
    $besok_info    = az_barber_hitung_besok($today);
    $besok_d       = $besok_info['besok'];
    $rentang_dates = $besok_info['rentang'];

    $q1 = (strlen($date_1) > 0) ? date('Y-m-d', strtotime($date_1)) : date('Y-m-d', strtotime('-30 day'));
    if (strlen($date_2) > 0) {
        $q2 = date('Y-m-d', strtotime($date_2));
        if ($q2 < $besok_d) $q2 = $besok_d;   // pastikan besok efektif + rentang selalu tercakup
    } else {
        $q2 = $besok_d;
    }

    $rows  = $this->_brb_query($q1, $q2, $idoutlet);
    $all_ids = array();
    foreach ($rows as $r) { $all_ids[] = $r->idtransaction_group; }
    $items = $this->_brb_items($all_ids);

    $g = array(
        'n_bill' => 0, 'n_pcs' => 0,
        'n_terlambat' => 0, 'pcs_terlambat' => 0,
        'n_hari_ini' => 0, 'pcs_hari_ini' => 0,
        'n_besok' => 0, 'pcs_besok' => 0,
        'n_rentang' => 0, 'pcs_rentang' => 0,
        'n_express' => 0, 'pcs_express' => 0,
        'n_proses' => 0, 'pcs_proses' => 0,
        'n_menunggu' => 0, 'pcs_menunggu' => 0,
        'n_catatan' => 0, 'n_siap' => 0, 'n_dstb' => 0,
        'sum_telat' => 0, 'max_telat' => 0,
    );
    $aging = array(
        array('label' => 'Telat 1 hari',   'n' => 0, 'pcs' => 0),
        array('label' => 'Telat 2-3 hari', 'n' => 0, 'pcs' => 0),
        array('label' => 'Telat 4+ hari',  'n' => 0, 'pcs' => 0),
    );
    $groups = array(); $order = array(); $valid_ids = array();

    foreach ($rows as $r) {
        $st  = (string)$r->dstb_status;
        $pcs = (int)$r->total_pcs;
        $masuk_raw = (strlen($r->date) && $r->date != '0000-00-00 00:00:00') ? $r->date : '';
        $masuk_d   = ($masuk_raw != '') ? date('Y-m-d', strtotime($masuk_raw)) : '';
        $seles_d   = (strlen($r->duedate) && $r->duedate != '0000-00-00 00:00:00') ? date('Y-m-d', strtotime($r->duedate)) : '';

        $is_express = false;
        if ($masuk_d != '' && $seles_d != '') {
            $diff = (strtotime($seles_d) - strtotime($masuk_d)) / 86400;
            $is_express = ($diff <= 1);
        }
        if (in_array($st, array('BARU', 'DIJEMPUT')) && !$is_express) { continue; }
        $valid_ids[] = $r->idtransaction_group;

        $is_proses    = ($st == 'DIPROSES');
        $is_menunggu  = in_array($st, array('BARU', 'DIJEMPUT'));
        $terlambat    = ($seles_d != '' && $seles_d < $today);
        $hari_ini     = ($seles_d == $today);
        $besok_flag   = ($seles_d == $besok_d);                       // besok efektif
        $rentang_flag = in_array($seles_d, $rentang_dates);           // hari dalam rentang libur
        $telat_hari   = 0;
        if ($terlambat) { $telat_hari = max(1, (int)floor((strtotime($today) - strtotime($seles_d)) / 86400)); }

        // ---- STATE AKSI PROSES ----
        $dstb_code = (string)$r->dstb_clean_code;
        $has_dstb  = (strlen($dstb_code) > 0);
        $is_ready  = (!$has_dstb && (int)$r->ready_to_deliver === 1);
        $state     = $has_dstb ? 'C' : ($is_ready ? 'B' : 'A');
        $ready_at  = '';
        if (!empty($r->ready_to_deliver_at) && $r->ready_to_deliver_at != '0000-00-00 00:00:00') {
            $ready_at = date('d/m/Y H:i', strtotime($r->ready_to_deliver_at));
        }
        $ready_by = (string)$r->ready_by_name;

        // kategori warna: telat > hari ini > besok > rentang > flat
        $cat = $terlambat ? 'late' : ($hari_ini ? 'today' : ($besok_flag ? 'besok' : ($rentang_flag ? 'rentang' : 'flat')));

        $it    = isset($items[$r->idtransaction_group]) ? $items[$r->idtransaction_group] : array('jenis' => '', 'notes' => '');
        $note  = trim((string)$r->note);
        $inote = trim((string)$it['notes']);
        $dnote_proc  = trim((string)$r->dstb_process_note);
        $dnote_clean = trim((string)$r->dstb_clean_note);
        $pnote = trim((string)$r->pending_description);
        $notes = array();
        if ($note !== '')        { $notes[] = array('i' => 'ðŸ“Œ', 't' => $note); }
        if ($inote !== '')       { $notes[] = array('i' => 'ðŸ‘•', 't' => $inote); }
        if ($dnote_proc !== '')  { $notes[] = array('i' => 'ðŸ“‹', 't' => 'DSTB Proses: ' . $dnote_proc); }
        if ($dnote_clean !== '') { $notes[] = array('i' => 'ðŸ“‹', 't' => 'DSTB Bersih: ' . $dnote_clean); }
        if ($pnote !== '')       { $notes[] = array('i' => 'âš ', 't' => $pnote); }
        $ada_catatan = (count($notes) > 0);

        $baris = array(
            'id'            => $r->idtransaction_group,
            'code'          => $r->code,
            'customer'      => $r->customer_name,
            'tgl_masuk'     => ($masuk_d != '' ? date('d/m/Y', strtotime($masuk_d)) : '-'),
            'tgl_selesai'   => ($seles_d != '' ? date('d/m/Y', strtotime($seles_d)) : '-'),
            'pcs'           => $pcs,
            'dstb'          => $st,
            'terlambat'     => $terlambat,
            'hari_ini'      => $hari_ini,
            'besok'         => $besok_flag,
            'rentang'       => $rentang_flag,
            'express'       => $is_express,
            'is_proses'     => $is_proses,
            'is_menunggu'   => $is_menunggu,
            'telat_hari'    => $telat_hari,
            'jenis'         => (string)$it['jenis'],
            'notes'         => $notes,
            'ada_catatan'   => $ada_catatan,
            'cat'           => $cat,
            'state'         => $state,
            'ready'         => $is_ready ? 1 : 0,
            'ready_at'      => $ready_at,
            'ready_by_name' => $ready_by,
            'dstb_code'     => $dstb_code,
            'has_dstb'      => $has_dstb,
        );

        $g['n_bill']++; $g['n_pcs'] += $pcs;
        if ($terlambat)   { $g['n_terlambat']++; $g['pcs_terlambat'] += $pcs; $g['sum_telat'] += $telat_hari; if ($telat_hari > $g['max_telat']) $g['max_telat'] = $telat_hari; }
        if ($hari_ini)    { $g['n_hari_ini']++;  $g['pcs_hari_ini']  += $pcs; }
        if ($besok_flag)  { $g['n_besok']++;     $g['pcs_besok']     += $pcs; }
        if ($rentang_flag){ $g['n_rentang']++;   $g['pcs_rentang']   += $pcs; }
        if ($is_express)  { $g['n_express']++;   $g['pcs_express']   += $pcs; }
        if ($is_proses)   { $g['n_proses']++;    $g['pcs_proses']    += $pcs; }
        if ($is_menunggu) { $g['n_menunggu']++;  $g['pcs_menunggu']  += $pcs; }
        if ($ada_catatan) { $g['n_catatan']++; }
        if ($state === 'B') { $g['n_siap']++; }
        if ($state === 'C') { $g['n_dstb']++; }

        if ($terlambat) {
            if ($telat_hari == 1)     { $aging[0]['n']++; $aging[0]['pcs'] += $pcs; }
            elseif ($telat_hari <= 3) { $aging[1]['n']++; $aging[1]['pcs'] += $pcs; }
            else                      { $aging[2]['n']++; $aging[2]['pcs'] += $pcs; }
        }

        $key = (isset($r->idoutlet) && $r->idoutlet !== null && $r->idoutlet !== '') ? $r->idoutlet : '0';
        if (!isset($groups[$key])) {
            $groups[$key] = array(
                'outlet_name' => (strlen($r->outlet_name) > 0 ? $r->outlet_name : '(TANPA OUTLET)'),
                'rows' => array(),
                'm' => array(
                    'n_bill' => 0, 'n_pcs' => 0,
                    'n_terlambat' => 0, 'pcs_terlambat' => 0,
                    'n_hari_ini' => 0, 'pcs_hari_ini' => 0,
                    'n_express' => 0, 'pcs_express' => 0,
                    'n_proses' => 0, 'pcs_proses' => 0,
                    'n_menunggu' => 0, 'pcs_menunggu' => 0,
                    'n_catatan' => 0, 'n_siap' => 0, 'n_dstb' => 0,
                ),
            );
            $order[] = $key;
        }
        $M = &$groups[$key];
        $M['rows'][] = $baris;
        $M['m']['n_bill']++; $M['m']['n_pcs'] += $pcs;
        if ($terlambat)  { $M['m']['n_terlambat']++; $M['m']['pcs_terlambat'] += $pcs; }
        if ($hari_ini)   { $M['m']['n_hari_ini']++;  $M['m']['pcs_hari_ini']  += $pcs; }
        if ($is_express) { $M['m']['n_express']++;   $M['m']['pcs_express']   += $pcs; }
        if ($is_proses)  { $M['m']['n_proses']++;    $M['m']['pcs_proses']    += $pcs; }
        if ($is_menunggu){ $M['m']['n_menunggu']++;  $M['m']['pcs_menunggu']  += $pcs; }
        if ($ada_catatan){ $M['m']['n_catatan']++; }
        if ($state === 'B') { $M['m']['n_siap']++; }
        if ($state === 'C') { $M['m']['n_dstb']++; }
        unset($M);
    }

    $group_list = array();
    foreach ($order as $k) {
        $G = &$groups[$k];
        usort($G['rows'], function ($a, $b) {
            $sa = ($a['state'] === 'C') ? 9 : ($a['terlambat'] ? 0 : ($a['hari_ini'] ? 1 : ($a['besok'] ? 2 : ($a['rentang'] ? 3 : ($a['express'] ? 4 : 5)))));
            $sb = ($b['state'] === 'C') ? 9 : ($b['terlambat'] ? 0 : ($b['hari_ini'] ? 1 : ($b['besok'] ? 2 : ($b['rentang'] ? 3 : ($b['express'] ? 4 : 5)))));
            if ($sa != $sb) return $sa - $sb;
            if ($a['telat_hari'] != $b['telat_hari']) return $b['telat_hari'] - $a['telat_hari'];
            return strcmp($a['code'], $b['code']);
        });
        $group_list[] = $G;
        unset($G);
    }
    usort($group_list, function ($a, $b) {
        if ($b['m']['n_terlambat'] != $a['m']['n_terlambat']) return $b['m']['n_terlambat'] - $a['m']['n_terlambat'];
        if ($b['m']['n_hari_ini'] != $a['m']['n_hari_ini']) return $b['m']['n_hari_ini'] - $a['m']['n_hari_ini'];
        return strcmp($a['outlet_name'], $b['outlet_name']);
    });

   // ---- Judul outlet ----
$outlet_title = 'SEMUA OUTLET';
if (strlen($idoutlet) > 0) {
$o = $this->db->select('outlet_name')->where('idoutlet', $idoutlet)->get('outlet')->row();
if ($o) { $outlet_title = $o->outlet_name; }
}
// ---- LANGKAH 8: BARANG PU (PROSES ULANG) sesuai filter outlet & tgl ----
$this->db->select('dstb_clean_pu.*, transaction_group.code as bill_code, customer.customer_name, product.product_name, item.item_code, transaction.trx_note');
$this->db->from('dstb_clean_pu');
$this->db->join('transaction_group', 'dstb_clean_pu.idtransaction_group = transaction_group.idtransaction_group');
$this->db->join('customer', 'transaction_group.idcustomer = customer.idcustomer', 'left');
$this->db->join('transaction', 'dstb_clean_pu.idtransaction = transaction.idtransaction');
$this->db->join('item', 'transaction.iditem = item.iditem', 'left');
$this->db->join('product', 'item.idproduct = product.idproduct', 'left');
$this->db->where_in('dstb_clean_pu.status', array(0, 1));
if (strlen($idoutlet) > 0) { $this->db->where('transaction_group.idoutlet', $idoutlet); }
$this->db->where('dstb_clean_pu.est_finish_date <=', $q2);
$this->db->order_by('dstb_clean_pu.status ASC, dstb_clean_pu.est_finish_date ASC, transaction_group.code ASC');
$pu_items = $this->db->get()->result();
return array(
'groups'        => $group_list,
'g'             => $g,
'aging'         => $aging,
'top_jenis'     => $this->_brb_topjenis($valid_ids),
'outlet_title'  => $outlet_title,
'is_all_outlet' => (strlen($idoutlet) == 0),
'date_1'        => $date_1,
'date_2'        => $date_2,
'tanggal_cetak' => date('d F Y'),
'besok_info'    => $besok_info,
'libur_list'    => az_barber_libur_list(),
'pu_items'      => $pu_items,
);
}
 // ==========================================================
//  NWS (NOTE WE ARE SORRY) — QC
// ==========================================================
private function _nws_items($id)
{
    $this->db->select('tr.idtransaction, pr.product_name');
    $this->db->from('transaction tr');
    $this->db->join('item it', 'it.iditem = tr.iditem', 'left');
    $this->db->join('product pr', 'pr.idproduct = it.idproduct', 'left');
    $this->db->where('tr.idtransaction_group', $id);
    $this->db->where('tr.status', 1);
    $this->db->order_by('tr.idtransaction ASC');
    return $this->db->get()->result();
}
private function _nws_header($id)
{
    $this->db->select('tg.code, c.customer_name');
    $this->db->from('transaction_group tg');
    $this->db->join('customer c', 'c.idcustomer = tg.idcustomer', 'left');
    $this->db->where('tg.idtransaction_group', $id);
    return $this->db->get()->row();
}
public function nws_data()
{
    $this->_guard();
    $id = (int)$this->input->post('id');
    if ($id <= 0) { echo json_encode(array('err_code'=>1,'err_message'=>'ID tidak valid')); return; }
    $tg = $this->_nws_header($id);
    if (!$tg) { echo json_encode(array('err_code'=>1,'err_message'=>'Bill tidak ditemukan')); return; }
    $rows = $this->_nws_items($id);
    $ids = array(); foreach ($rows as $r) $ids[] = $r->idtransaction;
    $nws = az_nws_group($id); $ph = az_nws_photos($ids);
    $items = array(); $n = 0; $tot = count($rows);
    foreach ($rows as $r) {
        $n++;
        $items[] = array(
            'idtransaction' => (int)$r->idtransaction, 'n' => $n, 'tot' => $tot,
            'product_name' => (string)$r->product_name,
            'notes' => isset($nws[$r->idtransaction]) ? $nws[$r->idtransaction] : array(),
            'photo' => isset($ph[$r->idtransaction]) ? $ph[$r->idtransaction] : '',
        );
    }
    echo json_encode(array('err_code'=>0,'code'=>$tg->code,'customer'=>$tg->customer_name,'items'=>$items,'options'=>az_nws_options()));
}
public function nws_save()
{
    $this->_guard();
    $id  = (int)$this->input->post('id');
    $kat = strtoupper((string)$this->input->post('kategori'));
    $pos = trim((string)$this->input->post('posisi'));
    $ket = trim((string)$this->input->post('keterangan'));
    $man = trim((string)$this->input->post('note_manual'));
    $tids = array_filter(explode(',', (string)$this->input->post('tids')));
    if (!in_array($kat, array('NODA','KUSUT','BAU','LAIN'))) { echo json_encode(array('err_code'=>1,'err_message'=>'Pilih jenis masalah dahulu.')); return; }
    if ($kat == 'LAIN' && $man == '') { echo json_encode(array('err_code'=>1,'err_message'=>'Keterangan "Lainnya" wajib diketik.')); return; }
    if (count($tids) == 0) { echo json_encode(array('err_code'=>1,'err_message'=>'Centang minimal 1 num.')); return; }
    $nummap = array(); $n = 0;
    foreach ($this->_nws_items($id) as $r) { $n++; $nummap[(int)$r->idtransaction] = $n; }
    $saved = 0;
    foreach ($tids as $tid) {
        $tid = (int)$tid; if (!isset($nummap[$tid])) continue;
        $this->db->where('idtransaction', $tid)->where('kategori', $kat)
                 ->where('posisi', $pos)->where('keterangan', $ket)
                 ->where('note_manual', $man)->where('status', 1);
        if ($this->db->count_all_results('nws') > 0) continue; // anti duplikat
        $this->db->insert('nws', array(
            'idtransaction_group' => $id, 'idtransaction' => $tid, 'num' => $nummap[$tid],
            'kategori' => $kat, 'posisi' => $pos, 'keterangan' => $ket, 'note_manual' => $man,
            'iduser' => $this->session->userdata('iduser'), 'created' => date('Y-m-d H:i:s'), 'status' => 1,
        ));
        $saved++;
    }
    echo json_encode(array('err_code'=>0,'saved'=>$saved));
}
public function nws_delete()
{
    $this->_guard();
    $nid = (int)$this->input->post('nid');
    $this->db->where('id', $nid);
    $this->db->update('nws', array('status'=>0));
    echo json_encode(array('err_code'=>0));
}
public function nws_history()
{
    $this->_guard(); az_nws_ensure();
    $this->db->select('kategori, posisi, keterangan, note_manual, MAX(id) AS mid');
    $this->db->where('status', 1);
    $this->db->group_by('kategori, posisi, keterangan, note_manual');
    $this->db->order_by('mid DESC'); $this->db->limit(15);
    echo json_encode(array('err_code'=>0,'list'=>$this->db->get('nws')->result()));
}
public function nws_photo()
{
    $this->_guard();
    $tid = (int)$this->input->post('idtransaction');
    if ($tid <= 0 || !isset($_FILES['photo']['tmp_name'])) { echo json_encode(array('err_code'=>1,'err_message'=>'File tidak valid')); return; }
    $dir = APPPATH.'assets/nws/';
    if (!is_dir($dir)) @mkdir($dir, 0777, true);
    $this->load->library('upload', array('upload_path'=>$dir,'allowed_types'=>'jpg|png|jpeg','max_size'=>'3000','encrypt_name'=>true));
    if (!$this->upload->do_upload('photo')) { echo json_encode(array('err_code'=>1,'err_message'=>$this->upload->display_errors())); return; }
    $fname = $this->upload->data('file_name');
    $this->db->where('idtransaction', $tid); $this->db->update('nws_photo', array('status'=>0));
    $this->db->insert('nws_photo', array('idtransaction'=>$tid,'photo'=>$fname,'status'=>1));
    echo json_encode(array('err_code'=>0,'photo'=>$fname));
}
public function nws_print()
{
    $this->_guard();
    $id  = (int)$this->input->get('id');
    $num = (string)$this->input->get('num');
    $tg = $this->_nws_header($id);
    if (!$tg) { show_404(); }
    $rows = $this->_nws_items($id);
    $nws = az_nws_group($id);
    $blocks = array(); $n = 0; $tot = count($rows);
    foreach ($rows as $r) {
        $n++;
        if (!isset($nws[$r->idtransaction])) continue;
        if ($num !== 'all' && (int)$num !== $n) continue;
        $blocks[] = array('num'=>$n,'tot'=>$tot,'product'=>(string)$r->product_name,'sentence'=>az_nws_sentence($nws[$r->idtransaction]));
    }
    if (count($blocks) == 0) { echo '<div style="font-family:Arial;padding:20px;">Tidak ada catatan NWS untuk dicetak.</div>'; return; }
    $this->load->view('sales_transaction/v_nws_print', array('code'=>$tg->code,'customer'=>$tg->customer_name,'blocks'=>$blocks));
} 
// ==========================================================
//  ANALISA NWS (UNTUK MANAJEMEN)
// ==========================================================
public function nws_analysis()
{
    $this->_guard_admin();
    $this->load->helper('az_nws');
    $date_1   = $this->input->get('date_1');
    $date_2   = $this->input->get('date_2');
    $idoutlet = trim((string)$this->input->get('idoutlet'));
    $q1 = (strlen($date_1) > 0) ? date('Y-m-d', strtotime($date_1)) : date('Y-m-d', strtotime('-30 day'));
    $q2 = (strlen($date_2) > 0) ? date('Y-m-d', strtotime($date_2)) : date('Y-m-d');

    // ---- ambil semua catatan NWS sesuai filter ----
    $this->db->select("n.*, tg.code, o.outlet_name, p.product_name, u.name AS user_name");
    $this->db->from('nws n');
    $this->db->join('transaction_group tg', 'tg.idtransaction_group = n.idtransaction_group', 'left');
    $this->db->join('outlet o', 'o.idoutlet = tg.idoutlet', 'left');
    $this->db->join('transaction tr', 'tr.idtransaction = n.idtransaction', 'left');
    $this->db->join('item i', 'i.iditem = tr.iditem', 'left');
    $this->db->join('product p', 'p.idproduct = i.idproduct', 'left');
    $this->db->join('user u', 'u.iduser = n.iduser', 'left');
    $this->db->where('n.status', 1);
    $this->db->where('DATE(n.created) >=', $q1);
    $this->db->where('DATE(n.created) <=', $q2);
    if (strlen($idoutlet) > 0) { $this->db->where('tg.idoutlet', $idoutlet); }
    $this->db->order_by('n.created DESC');
    $rows = $this->db->get()->result();

    // ---- agregasi ----
    $bills = array(); $nums = array();
    $by_cat = array(); $by_pos = array(); $by_ket = array();
    $by_prod = array(); $by_out = array(); $by_day = array(); $by_user = array();
    foreach ($rows as $n) {
        $bills[$n->idtransaction_group] = 1;
        $nums[$n->idtransaction] = 1;
        $by_cat[$n->kategori] = isset($by_cat[$n->kategori]) ? $by_cat[$n->kategori] + 1 : 1;
        if (strlen($n->posisi))     { $by_pos[$n->posisi]     = isset($by_pos[$n->posisi]) ? $by_pos[$n->posisi] + 1 : 1; }
        if (strlen($n->keterangan)) { $by_ket[$n->keterangan] = isset($by_ket[$n->keterangan]) ? $by_ket[$n->keterangan] + 1 : 1; }
        $pn = strlen($n->product_name) ? $n->product_name : '(tanpa jenis)';
        $by_prod[$pn] = isset($by_prod[$pn]) ? $by_prod[$pn] + 1 : 1;
        $on = strlen($n->outlet_name) ? $n->outlet_name : '(tanpa outlet)';
        $by_out[$on] = isset($by_out[$on]) ? $by_out[$on] + 1 : 1;
        $dk = date('Y-m-d', strtotime($n->created));
        $by_day[$dk] = isset($by_day[$dk]) ? $by_day[$dk] + 1 : 1;
        $un = strlen($n->user_name) ? $n->user_name : 'Sistem';
        $by_user[$un] = isset($by_user[$un]) ? $by_user[$un] + 1 : 1;
    }
    ksort($by_day);
    arsort($by_cat); arsort($by_pos); arsort($by_ket);
    arsort($by_prod); arsort($by_out); arsort($by_user);

    $g = array('notes' => count($rows), 'bills' => count($bills), 'nums' => count($nums), 'photos' => 0, 'pct_bill' => 0);

    // total bill pada periode (penyebut persentase)
    $this->db->where('status', 1);
    $this->db->where('DATE(date) >=', $q1);
    $this->db->where('DATE(date) <=', $q2);
    if (strlen($idoutlet) > 0) { $this->db->where('idoutlet', $idoutlet); }
    $total_bill = $this->db->count_all_results('transaction_group');
    $g['pct_bill'] = ($total_bill > 0) ? round($g['bills'] / $total_bill * 100, 1) : 0;

    // foto bukti
    $photo_map = array();
    if ($g['nums'] > 0) {
        $this->db->where_in('idtransaction', array_keys($nums));
        $this->db->where('status', 1);
        $g['photos'] = $this->db->count_all_results('nws_photo');
        $photo_map = az_nws_photos(array_keys($nums));
    }

    $outlet_title = 'SEMUA OUTLET';
    if (strlen($idoutlet) > 0) {
        $o = $this->db->select('outlet_name')->where('idoutlet', $idoutlet)->get('outlet')->row();
        if ($o) { $outlet_title = $o->outlet_name; }
    }

    $this->load->view('barber/v_nws_analysis', array(
        'rows' => $rows, 'g' => $g, 'total_bill' => $total_bill, 'photo_map' => $photo_map,
        'by_cat' => $by_cat, 'by_pos' => $by_pos, 'by_ket' => $by_ket,
        'by_prod' => $by_prod, 'by_out' => $by_out, 'by_day' => $by_day, 'by_user' => $by_user,
        'q1' => $q1, 'q2' => $q2, 'idoutlet' => $idoutlet,
        'outlet_title' => $outlet_title,
        'outlets' => $this->db->where('status', 1)->order_by('outlet_name')->get('outlet')->result(),
        'tanggal_cetak' => date('d F Y'),
    ));
}
}