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 : /proc/self/root/var/www/laciasmara.com/public_html/shop/application/controllers/admin/ |
Upload File : |
<?php if (!defined('BASEPATH')) exit('No direct script access allowed'); class Stocks extends Admin_Controller { //this property is used for validating existing category title on call back edit category private $product_current_id; function __construct() { parent::__construct(); $this->load->helper('form'); $this->load->model('product_m'); $this->load->model('log_m'); $this->load->model('transfer_stock_m'); $this->load->model('Transfer_stock_detail_m'); $this->load->model('configuration_m'); } // Activity public function activity() { $data['userdata'] = $this->session->userdata(); $data['title'] = 'Aktivitas Stok | Laciasmara'; $this->load->view('admin_new/layouts/header', $data); $this->load->view('admin_new/stocks/activity'); $this->load->view('admin_new/layouts/footer'); } public function get_stock_activities() { // Validasi input $dateFilter = $this->input->get('date_filter', true); $startDate = $this->input->get('start_date', true); $endDate = $this->input->get('end_date', 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); $this->db->select(' al.*, od.sku as product_sku, od.attributes, o.id_orders, o.phone, c.name, c.email, p.id_products, p.title as product_name, b.brand '); $this->db->from('activity_logs al'); $this->db->join('orders o', 'o.id_orders = al.record_id', 'left'); $this->db->join('customers c', 'c.id_customers = o.customer_id', 'left'); $this->db->join('orders_detail od', 'od.orders_id = al.record_id AND od.item_id = CAST(SUBSTRING_INDEX(al.description, "(ID: ", -1) AS UNSIGNED)', 'left'); $this->db->join('products p', 'p.id_products = od.product_id', 'left'); $this->db->join('brands b', 'b.id_brands = p.brand_id', 'left'); $this->db->where('al.action_type', 'UPDATE_STOCK'); // Filter berdasarkan tanggal if ($dateFilter) { switch ($dateFilter) { case 'today': $this->db->where('DATE(al.timestamp) = CURDATE()'); break; case 'yesterday': $this->db->where('DATE(al.timestamp) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)'); break; case 'last7days': $this->db->where('al.timestamp >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)'); break; case 'last30days': $this->db->where('al.timestamp >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)'); break; case 'thisMonth': $this->db->where('MONTH(al.timestamp) = MONTH(CURDATE()) AND YEAR(al.timestamp) = YEAR(CURDATE())'); break; case 'thisYear': $this->db->where('YEAR(al.timestamp) = YEAR(CURDATE())'); break; case 'custom': if (!empty($startDate) && !empty($endDate)) { $this->db->where('al.timestamp >=', $startDate); $this->db->where('al.timestamp <=', $endDate); } break; } } // Filter berdasarkan pencarian if (!empty($searchTerm)) { $this->db->group_start(); $this->db->like('p.title', $searchTerm); $this->db->or_like('c.name', $searchTerm); $this->db->or_like('c.email', $searchTerm); $this->db->or_like('al.description', $searchTerm); $this->db->or_like('al.record_id', $searchTerm); $this->db->group_end(); } $this->db->order_by('al.timestamp', 'DESC'); $this->db->group_by('al.log_id'); // Tambahkan group by untuk menghindari duplikasi // Hitung total records $totalQuery = clone $this->db; $total = $totalQuery->count_all_results(); // Reset query builder untuk query utama $this->db->limit($limit, $offset); $query = $this->db->get(); $activities = $query->result(); $response = $activities; // Set header untuk JSON dan keluarkan data $this->output ->set_content_type('application/json') ->set_output(json_encode($response)); } public function transfer() { // Validasi method POST if ($this->input->server('REQUEST_METHOD') !== 'POST') { show_404(); return; } // Sanitize input data $warehouse_from = $this->security->xss_clean($this->input->post('warehouse_from')); $warehouse_to = $this->security->xss_clean($this->input->post('warehouse_to')); $shipping_method = $this->security->xss_clean($this->input->post('shippingMethod')); $admin_note = $this->security->xss_clean($this->input->post('adminNote')); // Parse JSON data produk $selected_products_json = $this->input->post('selected_products_data'); // Debug log log_message('debug', 'Raw selected_products_data: ' . $selected_products_json); // Validasi input dasar if (empty($warehouse_from) || empty($warehouse_to) || empty($shipping_method)) { $this->session->set_flashdata('error', 'Data tidak lengkap. Pastikan semua field wajib telah diisi.'); redirect('admin/stocks/transfer-stock'); return; } // Validasi warehouse tidak boleh sama if ($warehouse_from == $warehouse_to) { $this->session->set_flashdata('error', 'Gudang asal dan tujuan tidak boleh sama.'); redirect('admin/stocks/transfer-stock'); return; } // Parse dan validasi data produk if (empty($selected_products_json)) { $this->session->set_flashdata('error', 'Data produk tidak ditemukan. Silakan pilih produk yang akan ditransfer.'); redirect('admin/stocks/transfer-stock'); return; } $products = json_decode($selected_products_json, true); if (json_last_error() !== JSON_ERROR_NONE) { log_message('error', 'JSON decode error: ' . json_last_error_msg()); $this->session->set_flashdata('error', 'Format data produk tidak valid.'); redirect('admin/stocks/transfer-stock'); return; } if (empty($products) || !is_array($products)) { $this->session->set_flashdata('error', 'Tidak ada produk yang dipilih untuk ditransfer.'); redirect('admin/stocks/transfer-stock'); return; } // Debug log log_message('debug', 'Parsed products data: ' . print_r($products, true)); // Validasi warehouse tujuan exists $warehouse = $this->db->get_where('warehouse', ['id' => $warehouse_to])->row(); if (!$warehouse) { $this->session->set_flashdata('error', 'Warehouse tujuan tidak ditemukan.'); redirect('admin/stocks/transfer-stock'); return; } // Get warehouse asal data $warehouse_from_data = $this->db->get_where('warehouse', ['id' => $warehouse_from])->row(); if (!$warehouse_from_data) { $this->session->set_flashdata('error', 'Warehouse asal tidak ditemukan.'); redirect('admin/stocks/transfer-stock'); return; } $warehouse_to_name = $warehouse->name; $warehouse_from_name = $warehouse_from_data->name; // Validasi stok sebelum memulai transaksi $validation_errors = []; foreach ($products as $index => $item) { // Validasi data produk if (empty($item['id_detail']) || empty($item['qty']) || !is_numeric($item['qty'])) { $validation_errors[] = "Data produk tidak valid pada item ke-" . ($index + 1); continue; } $qty = (int)$item['qty']; if ($qty <= 0) { $validation_errors[] = "Jumlah tidak valid untuk produk: " . ($item['product'] ?? 'Unknown'); continue; } // Cek stok available $this->db->select('s.stock, p.title as product_name'); $this->db->from('stock s'); $this->db->join('product_details pd', 's.id_product_detail = pd.id'); $this->db->join('products p', 'pd.product_id = p.id_products'); $this->db->where('s.id_product_detail', $item['id_detail']); $this->db->where('s.warehouse_id', $warehouse_from); $stock_query = $this->db->get(); $current_stock = $stock_query->row(); if (!$current_stock) { $validation_errors[] = "Produk tidak ditemukan di gudang asal: " . ($item['product'] ?? 'Unknown'); continue; } if ($current_stock->stock < $qty) { $validation_errors[] = "Stok tidak mencukupi untuk produk: " . $current_stock->product_name . " (Available: " . $current_stock->stock . ", Required: " . $qty . ")"; continue; } } // Jika ada error validasi, tampilkan dan return if (!empty($validation_errors)) { $error_message = "Transfer stock gagal:\n" . implode("\n", $validation_errors); $this->session->set_flashdata('error', $error_message); redirect('admin/stocks/transfer-stock'); return; } // Start database transaction $this->db->trans_start(); try { // Insert transfer stock data $transfer_data = [ 'out_warehouse_id' => $warehouse_from, 'in_warehouse_id' => $warehouse_to, 'status' => 2, // Terkirim 'recipient_name' => $warehouse->name, 'address' => $warehouse->address, 'district' => $warehouse->id_district, 'subdistrict' => $warehouse->id_subdistrict, 'province' => $warehouse->id_province, 'phone' => $warehouse->phone, 'created' => date("Y-m-d H:i:s"), 'shipping_type' => $shipping_method, 'no_resi' => null, 'shipping_fee' => 0, 'admin_note' => $admin_note ]; $transfer_id = $this->transfer_stock_m->add_transfer_stock($transfer_data); if (!$transfer_id) { throw new Exception('Gagal membuat record transfer stock'); } // Process each product $processed_products = []; foreach ($products as $item) { $qty = (int)$item['qty']; // Get current stock data $this->db->select('s.stock, s.stock_keep, s.stock_reject, s.stock_sample, p.title as product_name'); $this->db->from('stock s'); $this->db->join('product_details pd', 's.id_product_detail = pd.id'); $this->db->join('products p', 'pd.product_id = p.id_products'); $this->db->where('s.id_product_detail', $item['id_detail']); $this->db->where('s.warehouse_id', $warehouse_from); $existing_stock_query = $this->db->get(); $existing_stock = $existing_stock_query->row(); if (!$existing_stock) { throw new Exception('Stock data tidak ditemukan untuk produk: ' . $item['product']); } $old_stock = $existing_stock->stock; $new_stock = $old_stock - $qty; // Final validation (double check) if ($new_stock < 0) { throw new Exception('Stok tidak mencukupi untuk produk: ' . $existing_stock->product_name); } // Insert transfer detail $transfer_detail_data = [ 'id_transfer_stock' => $transfer_id, 'product_detail_id' => $item['id_detail'], 'product_id' => $item['id_products'] ?? null, 'item_name' => $existing_stock->product_name, 'quantity' => $qty, 'sku' => $item['sku'] ?? '', 'attributes' => $item['atribut'] ?? '', 'warehouse_id' => $warehouse_from, 'warehouse_id_target' => $warehouse_to ]; $this->db->insert('transfer_stock_detail', $transfer_detail_data); if ($this->db->affected_rows() == 0) { throw new Exception('Gagal menyimpan detail transfer untuk produk: ' . $existing_stock->product_name); } // Store processed product info for logging $processed_products[] = [ 'id_detail' => $item['id_detail'], 'product_name' => $existing_stock->product_name, 'old_stock' => $old_stock, 'new_stock' => $new_stock, 'qty' => $qty ]; } // Update stock after all validations and inserts are successful $this->processStockTransfer($transfer_id, $warehouse_from, $warehouse_to); // Log all stock updates $this->load->model('log_m'); $username = $this->session->userdata('name') ?: 'System'; foreach ($processed_products as $product_info) { $description = "Stok produk {$product_info['product_name']} (ID: {$product_info['id_detail']}) telah ditransfer dari {$product_info['old_stock']} menjadi {$product_info['new_stock']} oleh {$username} dari gudang {$warehouse_from_name} ke gudang {$warehouse_to_name}."; $this->log_m->log_stock_update( null, // order_id tidak diperlukan $product_info['id_detail'], // product_id diisi dengan id product_detail $product_info['product_name'], $product_info['old_stock'], $product_info['new_stock'], base_url('admin/stocks/stock-product?tab=all'), // reference_url $description, // description 'stock', // field yang diupdate 'stock' // tipe operasi ); } // Log user activity $user_id = $this->session->userdata('user_id'); if ($user_id) { log_activity($user_id, 'User transfer stock (Transfer ID: ' . $transfer_id . ', Products: ' . count($processed_products) . ')'); } // Complete transaction $this->db->trans_complete(); if ($this->db->trans_status() === FALSE) { throw new Exception('Database transaction failed'); } // Success response $this->session->set_flashdata('success', 'Transfer stock berhasil. Transfer ID: ' . $transfer_id . ', Total produk: ' . count($processed_products)); redirect('admin/stocks/list-transfer-stock'); } catch (Exception $e) { // Rollback transaction on any error $this->db->trans_rollback(); log_message('error', 'Stock transfer failed: ' . $e->getMessage()); log_message('error', 'Transfer data: ' . print_r([ 'warehouse_from' => $warehouse_from, 'warehouse_to' => $warehouse_to, 'products_count' => count($products), 'products' => $products ], true)); $this->session->set_flashdata('error', 'Transfer stock gagal: ' . $e->getMessage()); redirect('admin/stocks/transfer-stock'); return; } } public function get_transfers_stock() { $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; // Build main query $this->db->select(' ts.id_transfer_stock, ts.out_warehouse_id, ts.in_warehouse_id, ts.status, ts.recipient_name, ts.address, ts.district, ts.subdistrict, ts.province, ts.postcode, ts.phone, ts.email, ts.shipping_fee, ts.admin_note, ts.shipping_type, ts.no_resi, ts.created, ts.cancel_date, ts.sent_date, w_out.name as out_warehouse_name, w_in.name as in_warehouse_name '); $this->db->from('transfer_stock ts'); $this->db->join('warehouse w_out', 'ts.out_warehouse_id = w_out.id', 'left'); $this->db->join('warehouse w_in', 'ts.in_warehouse_id = w_in.id', 'left'); // Apply filter based on tab // 0 = pending // 1 = proses // 2 = terkirim // 3 = diterima // 4 = batal if ($tab) { switch ($tab) { case 'pending': $this->db->where('ts.status', 0); break; case 'cancelled': $this->db->where('ts.status', 4); break; case 'processing': $this->db->where('ts.status', 1); break; case 'done': $this->db->where_in('ts.status', [2, 3]); break; } } // Apply sorting by created date (newest first) $this->db->order_by('ts.created', 'DESC'); // Apply pagination $this->db->limit($limit, $offset); // Execute query $query = $this->db->get(); $all_transfers = $query->result(); // Post-processing: Get transfer details for each transfer foreach ($all_transfers as $transfer) { // Get transfer details including product information $this->db->select(' tsd.id_transfer_stock_detail, tsd.product_id, tsd.quantity, tsd.status, tsd.product_detail_id, tsd.item_name, tsd.sku, tsd.attributes, tsd.warehouse_id, tsd.warehouse_id_target, w_source.name as warehouse_name, w_target.name as warehouse_target_name, pi.image as product_image '); $this->db->from('transfer_stock_detail tsd'); $this->db->join('warehouse w_source', 'tsd.warehouse_id = w_source.id', 'left'); $this->db->join('warehouse w_target', 'tsd.warehouse_id_target = w_target.id', 'left'); $this->db->join('product_images pi', 'tsd.product_detail_id = pi.product_details_id AND pi.priority = 1 AND pi.status = 1', 'left'); $this->db->where('tsd.id_transfer_stock', $transfer->id_transfer_stock); $details_query = $this->db->get(); $transfer->items = $details_query->result(); // Calculate total items $transfer->total_items = 0; foreach ($transfer->items as $item) { $transfer->total_items += $item->quantity; } // Format dates $transfer->created_formatted = date('d M Y H:i', strtotime($transfer->created)); if ($transfer->sent_date) { $transfer->sent_date_formatted = date('d M Y', strtotime($transfer->sent_date)); } if ($transfer->cancel_date) { $transfer->cancel_date_formatted = date('d M Y', strtotime($transfer->cancel_date)); } // Set status text switch ($transfer->status) { case 0: $transfer->status_text = 'Pending'; $transfer->status_class = 'bg-yellow-100 text-yellow-700 px-2 py-1 rounded'; break; case 1: $transfer->status_text = 'Diproses'; $transfer->status_class = 'bg-blue-100 text-blue-700 px-2 py-1 rounded'; break; case 2: $transfer->status_text = 'Terkirim'; $transfer->status_class = 'bg-green-100 text-green-700 px-2 py-1 rounded'; break; case 3: $transfer->status_text = 'Diterima'; $transfer->status_class = 'bg-gray-100 text-gray-700 px-2 py-1 rounded'; break; case 4: $transfer->status_text = 'Dibatalkan'; $transfer->status_class = 'bg-red-100 text-red-700 px-2 py-1 rounded'; break; default: $transfer->status_text = 'Unknown'; $transfer->status_class = 'bg-gray-300 text-gray-800 px-2 py-1 rounded'; } } // Count total records for pagination if ($tab) { switch ($tab) { case 'pending': $this->db->where('status', 0); break; case 'cancelled': $this->db->where('status', 4); break; case 'processing': $this->db->where('status', 1); break; case 'done': $this->db->where_in('status', [2, 3]); break; } } $total_records = $this->db->count_all_results('transfer_stock'); $total_pages = ceil($total_records / $limit); // Return JSON response echo json_encode($all_transfers); } public function updateResi() { if (!$this->input->is_ajax_request()) { show_error('No direct script access allowed', 403); return; } // Ambil data dari POST $transfer_id = $this->input->post('transfer_id', true); $no_resi = $this->input->post('no_resi', true); // Validasi input if (empty($transfer_id) || empty($no_resi) || $no_resi === '-') { $response = [ 'success' => false, 'message' => 'Data tidak lengkap', 'csrf_hash' => $this->security->get_csrf_hash() ]; echo json_encode($response); return; } $this->db->trans_begin(); try { // Ambil payment_type dan no_resi sebelum update $this->db->select('status, no_resi, shipping_fee'); $this->db->where('id_transfer_stock', $transfer_id); $query = $this->db->get('transfer_stock'); $transfer_data = $query->row(); if ($query->num_rows() > 0) { $old_status = $transfer_data->status; // Simpan payment_type sebagai old_status $old_resi = $transfer_data->no_resi; // Simpan no_resi sebelum update } else { throw new Exception('Gagal mengambil data pesanan sebelum update'); } // Update table tranfer detail $transfers_data = [ 'no_resi' => $no_resi, 'status' => 2, // Set status menjadi 'Terkirim' 'sent_date' => date('Y-m-d'), ]; $this->db->where('id_transfer_stock', $transfer_id); $update_transfers = $this->db->update('transfer_stock', $transfers_data); if (!$update_transfers) { throw new Exception('Gagal mengupdate nomor resi di tabel orders'); } $this->db->trans_commit(); $response = [ 'success' => true, 'message' => 'Nomor resi berhasil diperbarui.', 'csrf_hash' => $this->security->get_csrf_hash() ]; } catch (Exception $e) { // Rollback transaksi jika ada error $this->db->trans_rollback(); $response = [ 'success' => false, 'message' => $e->getMessage(), 'csrf_hash' => $this->security->get_csrf_hash() ]; } echo json_encode($response); } public function updateTransferStatus() { if (!$this->input->is_ajax_request()) { show_error('No direct script access allowed', 403); return; } $transfer_id = $this->input->post('transfer_id', true); $status = $this->input->post('status', true); // Validasi input if (empty($transfer_id) || empty($status) || $status === '-') { $response = [ 'success' => false, 'message' => 'Data tidak lengkap', 'csrf_hash' => $this->security->get_csrf_hash() ]; echo json_encode($response); return; } $this->db->trans_begin(); try { $this->db->select('*'); $this->db->where('id_transfer_stock', $transfer_id); $query = $this->db->get('transfer_stock'); if ($query->num_rows() === 0) { throw new Exception('Gagal mengambil data pesanan sebelum update'); } $transfer_data = $query->row(); $old_status = $transfer_data->status; $warehouse_from_id = $transfer_data->out_warehouse_id; $warehouse_to_id = $transfer_data->in_warehouse_id; // Persiapan data dasar untuk update $transfers_data = [ 'status' => $status, ]; // 0 = pending // 1 = proses // 2 = terkirim // 3 = diterima // 4 = batal switch ($status) { case '1': // PROSES // Memindahkan stok dari gudang asal ke gudang tujuan $this->processStockTransfer($transfer_id, $warehouse_from_id, $warehouse_to_id); break; case '2': // TERKIRIM break; case '3': // DITERIMA break; case '4': // BATAL // Return stock ke inventory $this->returnStockToInventory($transfer_id, $warehouse_from_id, $warehouse_to_id); break; } // Update tabel orders $this->db->where('id_transfer_stock', $transfer_id); $update_orders = $this->db->update('transfer_stock', $transfers_data); if (!$update_orders) { throw new Exception('Gagal mengupdate status pesanan'); } // Commit transaksi jika semua berhasil $this->db->trans_commit(); $response = [ 'success' => true, 'message' => 'Status transfer berhasil diperbarui', 'csrf_hash' => $this->security->get_csrf_hash() ]; } catch (Exception $e) { // Rollback transaksi jika ada error $this->db->trans_rollback(); $response = [ 'success' => false, 'message' => $e->getMessage(), 'csrf_hash' => $this->security->get_csrf_hash() ]; } // Kirim response dalam format JSON echo json_encode($response); } private function processStockTransfer($transfer_id, $warehouse_from_id, $warehouse_to_id) { log_message('debug', "processStockTransfer: Memproses Transfer ID: {$transfer_id}"); // Ambil detail transfer $this->db->select('*'); $this->db->where('id_transfer_stock', $transfer_id); $transfer_details = $this->db->get('transfer_stock_detail')->result(); log_message('debug', "Total Item: " . count($transfer_details)); $user_name = $this->session->userdata('name'); foreach ($transfer_details as $item) { log_message('debug', "Memindahkan stok untuk produk ID: {$item->product_id} - Item ID: {$item->product_detail_id}"); // Cek stok di gudang asal (warehouse_from_id) $this->db->select('stock, id') ->from('stock') ->where('id_product', $item->product_id) ->where('id_product_detail', $item->product_detail_id) ->where('warehouse_id', $warehouse_from_id); $from_stock = $this->db->get()->row(); if (!$from_stock) { log_message('error', "Stock data tidak ditemukan untuk Produk ID: {$item->product_id} di gudang asal"); continue; } // Quantity yang akan dipindahkan $qty = $item->quantity; if ($qty > 0 && $from_stock->stock >= $qty) { // Update stok di gudang asal (warehouse_from_id) - mengurangi stok $old_stock_from = $from_stock->stock; $new_stock_from = $old_stock_from - $qty; log_message('debug', "Gudang Asal - Stok Sebelumnya: {$old_stock_from}, Stok Baru: {$new_stock_from}"); $this->db->where('id_product', $item->product_id); $this->db->where('id_product_detail', $item->product_detail_id); $this->db->where('warehouse_id', $warehouse_from_id); $this->db->update('stock', ['stock' => $new_stock_from]); log_message('debug', "Stock gudang asal diperbarui di database."); // Catat pergerakan stok untuk gudang asal $this->db->insert('stock_movement', [ 'stock_id' => $from_stock->id, 'type' => '-', 'stock_change' => (int)$qty, 'remark' => "Transfer Stock dengan ID: {$transfer_id} - Mengurangi {$qty} unit dari gudang asal.", 'total' => $new_stock_from, 'name' => $user_name ]); log_message('debug', "Stock movement untuk gudang asal dicatat."); // Cek apakah stok sudah ada di gudang tujuan $this->db->select('stock, id') ->from('stock') ->where('id_product', $item->product_id) ->where('id_product_detail', $item->product_detail_id) ->where('warehouse_id', $warehouse_to_id); $to_stock = $this->db->get()->row(); if ($to_stock) { // Update stok di gudang tujuan (warehouse_to_id) - menambah stok $old_stock_to = $to_stock->stock; $new_stock_to = $old_stock_to + $qty; log_message('debug', "Gudang Tujuan - Stok Sebelumnya: {$old_stock_to}, Stok Baru: {$new_stock_to}"); $this->db->where('id_product', $item->product_id); $this->db->where('id_product_detail', $item->product_detail_id); $this->db->where('warehouse_id', $warehouse_to_id); $this->db->update('stock', ['stock' => $new_stock_to]); log_message('debug', "Stock gudang tujuan diperbarui di database."); // Catat pergerakan stok untuk gudang tujuan $this->db->insert('stock_movement', [ 'stock_id' => $to_stock->id, 'type' => '+', 'stock_change' => (int)$qty, 'remark' => "Transfer Stock dengan ID: {$transfer_id} - Menambah {$qty} unit ke gudang tujuan.", 'total' => $new_stock_to, 'name' => $user_name ]); log_message('debug', "Stock movement untuk gudang tujuan dicatat."); } else { // Buat entri stok baru di gudang tujuan jika belum ada $this->db->insert('stock', [ 'id_product' => $item->product_id, 'id_product_detail' => $item->product_detail_id, 'warehouse_id' => $warehouse_to_id, 'stock' => $qty ]); $new_stock_id = $this->db->insert_id(); log_message('debug', "Stock baru dibuat di gudang tujuan dengan ID: {$new_stock_id}"); // Catat pergerakan stok untuk gudang tujuan $this->db->insert('stock_movement', [ 'stock_id' => $new_stock_id, 'type' => '+', 'stock_change' => (int)$qty, 'remark' => "Transfer Stock dengan ID: {$transfer_id} - Menambah {$qty} unit ke gudang tujuan (stok baru).", 'total' => $qty, 'name' => $user_name ]); log_message('debug', "Stock movement untuk gudang tujuan baru dicatat."); } } else { log_message('warning', "Stok di gudang asal tidak mencukupi untuk transfer. Produk ID: {$item->product_id}, Stok tersedia: {$from_stock->stock}, Jumlah diminta: {$qty}"); throw new Exception("Stok produk tidak mencukupi untuk melakukan transfer."); } } } private function returnStockToInventory($transfer_id, $warehouse_from_id, $warehouse_to_id) { log_message('debug', "returnStockToInventory: Memproses Transfer ID: {$transfer_id}"); // Ambil detail transfer $this->db->select('*'); $this->db->where('id_transfer_stock', $transfer_id); $transfer_details = $this->db->get('transfer_stock_detail')->result(); log_message('debug', "Total Item: " . count($transfer_details)); $user_name = $this->session->userdata('name'); foreach ($transfer_details as $item) { log_message('debug', "Mengembalikan stok untuk produk ID: {$item->product_id} - Item ID: {$item->product_detail_id}"); // Cek stok di gudang asal (warehouse_from_id) $this->db->select('stock, id') ->from('stock') ->where('id_product', $item->product_id) ->where('id_product_detail', $item->product_detail_id) ->where('warehouse_id', $warehouse_from_id); $from_stock = $this->db->get()->row(); if (!$from_stock) { log_message('error', "Stock data tidak ditemukan untuk Produk ID: {$item->product_id} di gudang asal"); continue; } // Quantity yang akan dikembalikan $qty = $item->quantity; if ($qty > 0) { // Update stok di gudang asal (warehouse_from_id) $old_stock_from = $from_stock->stock; $new_stock_from = $old_stock_from + $qty; log_message('debug', "Gudang Asal - Stok Sebelumnya: {$old_stock_from}, Stok Baru: {$new_stock_from}"); $this->db->where('id_product', $item->product_id); $this->db->where('id_product_detail', $item->product_detail_id); $this->db->where('warehouse_id', $warehouse_from_id); $this->db->update('stock', ['stock' => $new_stock_from]); log_message('debug', "Stock gudang asal diperbarui di database."); // Catat pergerakan stok untuk gudang asal $this->db->insert('stock_movement', [ 'stock_id' => $from_stock->id, 'type' => '+', 'stock_change' => (int)$qty, 'remark' => "Pembatalan Transfer Stock dengan ID: {$transfer_id} - Mengembalikan {$qty} unit ke gudang asal.", 'total' => $new_stock_from, 'name' => $user_name ]); log_message('debug', "Stock movement untuk gudang asal dicatat."); // Cek stok di gudang tujuan (warehouse_to_id) jika stok sudah berubah $this->db->select('stock, id') ->from('stock') ->where('id_product', $item->product_id) ->where('id_product_detail', $item->product_detail_id) ->where('warehouse_id', $warehouse_to_id); $to_stock = $this->db->get()->row(); if ($to_stock && $to_stock->stock >= $qty) { // Update stok di gudang tujuan (warehouse_to_id) $old_stock_to = $to_stock->stock; $new_stock_to = $old_stock_to - $qty; log_message('debug', "Gudang Tujuan - Stok Sebelumnya: {$old_stock_to}, Stok Baru: {$new_stock_to}"); $this->db->where('id_product', $item->product_id); $this->db->where('id_product_detail', $item->product_detail_id); $this->db->where('warehouse_id', $warehouse_to_id); $this->db->update('stock', ['stock' => $new_stock_to]); log_message('debug', "Stock gudang tujuan diperbarui di database."); // Catat pergerakan stok untuk gudang tujuan $this->db->insert('stock_movement', [ 'stock_id' => $to_stock->id, 'type' => '-', 'stock_change' => (int)$qty, 'remark' => "Pembatalan Transfer Stock dengan ID: {$transfer_id} - Mengurangi {$qty} unit dari gudang tujuan.", 'total' => $new_stock_to, 'name' => $user_name ]); log_message('debug', "Stock movement untuk gudang tujuan dicatat."); } else { log_message('warning', "Stok di gudang tujuan tidak mencukupi atau belum ada untuk dikurangi."); } } } } public function get_products_stock() { // Ambil parameter GET dengan validasi dasar $tab = $this->input->get('tab', true); $isEmptyStockOnly = filter_var($this->input->get('isEmptyStockOnly', true), FILTER_VALIDATE_BOOLEAN); $isLowStock = filter_var($this->input->get('isLowStock', true), FILTER_VALIDATE_BOOLEAN); $hasKeepStock = filter_var($this->input->get('hasKeepStock', true), FILTER_VALIDATE_BOOLEAN); $noKeepStock = filter_var($this->input->get('noKeepStock', true), FILTER_VALIDATE_BOOLEAN); $hasRejectStock = filter_var($this->input->get('hasRejectStock', true), FILTER_VALIDATE_BOOLEAN); $noRejectStock = filter_var($this->input->get('noRejectStock', true), FILTER_VALIDATE_BOOLEAN); $isRestock = filter_var($this->input->get('isRestock', true), FILTER_VALIDATE_BOOLEAN); $noRestock = filter_var($this->input->get('noRestock', true), FILTER_VALIDATE_BOOLEAN); $notsetRestock = filter_var($this->input->get('notsetRestock', true), FILTER_VALIDATE_BOOLEAN); $brandId = $this->input->get('merk', true); $categoryId = $this->input->get('kategori', true); $warehouse = $this->input->get('warehouse', true); $warehouseId = !empty($warehouse) ? intval($warehouse) : 1; // Added intval for security $searchTerm = $this->input->get('search', true); // Query utama untuk mendapatkan produk $this->db->select(' p.title, p.alias, p.product_status, p.id_products, p.created_at, pd.id as product_detail_id, MIN(pd.price) as min_price, MAX(pd.price) as max_price, CASE WHEN COUNT(pd.id) > 1 THEN "-" ELSE MAX(pd.sku) END as sku, pi.image as image, s.stock as total_stock, s.stock_keep as total_stock_keep, s.stock_reject as total_stock_reject, s.stock_sample as total_stock_sample, b.brand as brand_title, s.warehouse_id, w.name as warehouse_name '); $this->db->from('products p'); $this->db->join('product_details pd', 'pd.product_id = p.id_products', 'left'); $this->db->join('stock s', "pd.id = s.id_product_detail AND s.warehouse_id = {$warehouseId}", 'left'); $this->db->join('brands b', 'p.brand_id = b.id_brands', 'left'); $this->db->join('product_images pi', 'pi.product_details_id = pd.id AND pi.priority = 1 AND pi.status = 1', 'left'); $this->db->join('category_product cp', 'cp.id_product = p.id_products', 'left'); $this->db->join('warehouse w', 's.warehouse_id = w.id', 'left'); // JOIN tambahan untuk search varian if (!empty($searchTerm)) { $this->db->join('product_combination pc_search', 'pc_search.product_details_id = pd.id', 'left'); $this->db->join('product_attributes pa_search', 'pc_search.attribute_id = pa_search.id', 'left'); $this->db->join('product_attributes_detail pad_search', 'pc_search.attribute_detail_id = pad_search.id', 'left'); } $this->db->where('p.deleted_at', null); // Modified search condition to include variant search if (!empty($searchTerm)) { $this->db->group_start(); $this->db->like('p.title', $searchTerm); $this->db->or_like('b.brand', $searchTerm); $this->db->or_like('w.name', $searchTerm); $this->db->or_like('pd.sku', $searchTerm); // Tambahan pencarian untuk varian $this->db->or_like('pa_search.product_attribute', $searchTerm); $this->db->or_like('pad_search.attribute_detail', $searchTerm); $this->db->group_end(); } // Filter berdasarkan status produk if ($tab === 'active') { $this->db->where('p.product_status', '1'); } elseif ($tab === 'inactive') { $this->db->where('p.product_status', '0'); } // 1. **Filter untuk produk dengan stok kosong** if ($isEmptyStockOnly) { $this->db->having('total_stock = 0'); } // 2. **Filter untuk produk dengan stok rendah (≤ 5)** if ($isLowStock) { $this->db->having('total_stock > 0 AND total_stock < 5'); } // **Filter Keep Stock** if ($hasKeepStock) { $this->db->where("EXISTS ( SELECT 1 FROM stock s_keep WHERE s_keep.id_product_detail = pd.id AND s_keep.stock_keep > 0 AND s_keep.warehouse_id = {$warehouseId} )"); } if ($noKeepStock) { $this->db->where("NOT EXISTS ( SELECT 1 FROM stock s_keep WHERE s_keep.id_product_detail = pd.id AND s_keep.stock_keep > 0 AND s_keep.warehouse_id = {$warehouseId} )"); } if ($hasRejectStock) { $this->db->where("EXISTS ( SELECT 1 FROM stock s_reject WHERE s_reject.id_product_detail = pd.id AND s_reject.stock_reject > 0 AND s_reject.warehouse_id = {$warehouseId} )"); } if ($noRejectStock) { $this->db->where("NOT EXISTS ( SELECT 1 FROM stock s_reject WHERE s_reject.id_product_detail = pd.id AND s_reject.stock_reject > 0 AND s_reject.warehouse_id = {$warehouseId} )"); } // **Filter Restock Status dari Products Table** if ($isRestock) { $this->db->where('p.restock', 'yes'); } if ($noRestock) { $this->db->where('p.restock', 'no'); } if ($notsetRestock) { $this->db->where('p.restock', 'notset'); } // Brand if (!empty($brandId)) { $this->db->where('p.brand_id', $brandId); } // Category if (!empty($categoryId)) { $this->db->where('cp.id_category', $categoryId); } if (!empty($warehouse)) { $this->db->where('s.warehouse_id', $warehouseId); } $this->db->group_by('p.id_products'); $query = $this->db->get(); $all_products = $query->result(); $filtered_products = []; // Post-processing foreach ($all_products as $product) { // Process price range if (!empty($product->min_price) && !empty($product->max_price)) { $product->price = ($product->min_price == $product->max_price) ? $product->min_price : $product->min_price . ' - ' . $product->max_price; } else { $product->price = 'N/A'; } unset($product->min_price, $product->max_price); // Ambil detail produk dengan variannya $this->db->select(' pd.id as product_detail_id, pd.sku, pd.price, COALESCE(s.stock, 0) as stock, COALESCE(s.stock_keep, 0) as stock_keep, COALESCE(s.stock_reject, 0) as stock_reject, COALESCE(s.stock_sample, 0) as stock_sample, pd.discounted_price, GROUP_CONCAT( CONCAT_WS(": ", pa.product_attribute, pad.attribute_detail) SEPARATOR ", " ) as variants, pa.product_attribute as attribute, pad.attribute_detail as attribute_detail, s.warehouse_id, w.name as warehouse_name '); $this->db->from('product_details pd'); $this->db->join('product_combination pc', 'pc.product_details_id = pd.id', 'left'); $this->db->join('product_attributes pa', 'pc.attribute_id = pa.id', 'left'); $this->db->join('product_attributes_detail pad', 'pc.attribute_detail_id = pad.id', 'left'); $this->db->join('stock s', "pd.id = s.id_product_detail AND s.warehouse_id = {$warehouseId}", 'left'); $this->db->join('warehouse w', 's.warehouse_id = w.id', 'left'); $this->db->where('pd.product_id', $product->id_products); $this->db->group_by('pd.id'); $this->db->order_by('pd.id', 'ASC'); $variants_query = $this->db->get(); $product->variants = $variants_query->result(); // Filter variants by warehouse $product->variants = array_filter($product->variants, function ($variant) { return !is_null($variant->warehouse_id); }); // Jika produk masih memiliki varian setelah filtering, tambahkan ke hasil akhir if (!empty($product->variants)) { $filtered_products[] = $product; } } // Fixed: Return filtered_products instead of all_products echo json_encode($filtered_products); } // Update Stock // public function updateStock() // { // // Cek apakah ini AJAX request // if (!$this->input->is_ajax_request()) { // show_error('No direct script access allowed', 403); // return; // } // // Log semua data POST untuk debugging // log_message('debug', 'Received POST Data: ' . json_encode($this->input->post())); // // Ambil data dari POST // $product_detail_id = $this->input->post('product_detail_id'); // $warehouse_id = $this->input->post('warehouse_id'); // $stock_type = $this->input->post('stock_type'); // $new_value = intval($this->input->post('new_value')); // // Validasi data yang diperlukan // if (!$product_detail_id || !$warehouse_id || !$stock_type) { // log_message('error', 'Missing required data for stock update'); // echo json_encode(["success" => false, "message" => "Missing required data"]); // return; // } // // Siapkan data update berdasarkan stock_type // $update_data = array(); // switch ($stock_type) { // case 'stock': // $update_data['stock'] = $new_value; // break; // case 'stock_keep': // $update_data['stock_keep'] = $new_value; // break; // case 'stock_reject': // $update_data['stock_reject'] = $new_value; // break; // case 'stock_sample': // $update_data['stock_sample'] = $new_value; // break; // default: // log_message('error', 'Invalid stock type: ' . $stock_type); // echo json_encode(["success" => false, "message" => "Invalid stock type"]); // return; // } // // Log data yang akan diupdate // log_message('debug', 'Updating stock with data: ' . json_encode($update_data)); // try { // // Update stok produk // $this->db->where('id_product_detail', $product_detail_id); // $this->db->where('warehouse_id', $warehouse_id); // $update = $this->db->update('stock', $update_data); // // Cek apakah update berhasil // if ($update) { // log_message('debug', 'Stock updated successfully for product_detail_id: ' . $product_detail_id); // echo json_encode([ // "success" => true, // "message" => "Stock updated successfully", // "updated_data" => $update_data // ]); // } else { // // Cek apakah data exists // $exists = $this->db->where('id_product_detail', $product_detail_id) // ->where('warehouse_id', $warehouse_id) // ->get('stock') // ->num_rows(); // if ($exists == 0) { // // Jika data tidak ada, insert baru // $insert_data = array( // 'id_product_detail' => $product_detail_id, // 'warehouse_id' => $warehouse_id, // 'stock' => 0, // 'stock_keep' => 0, // 'stock_reject' => 0, // 'stock_sample' => 0 // ); // $insert_data[$stock_type] = $new_value; // $insert = $this->db->insert('stock', $insert_data); // if ($insert) { // echo json_encode([ // "success" => true, // "message" => "New stock record created successfully", // "updated_data" => $insert_data // ]); // return; // } // } // log_message('error', 'Failed to update stock for product_detail_id: ' . $product_detail_id); // log_message('error', 'Database Error: ' . json_encode($this->db->error())); // echo json_encode([ // "success" => false, // "message" => "Failed to update stock" // ]); // } // } catch (Exception $e) { // log_message('error', 'Exception during stock update: ' . $e->getMessage()); // echo json_encode([ // "success" => false, // "message" => "Error updating stock" // ]); // } // } public function updateStock() { // Cek apakah ini AJAX request if (!$this->input->is_ajax_request()) { show_error('No direct script access allowed', 403); return; } // Log semua data POST untuk debugging log_message('debug', 'Received POST Data: ' . json_encode($this->input->post())); // Ambil data dari POST $product_detail_id = $this->input->post('product_detail_id'); $warehouse_id = $this->input->post('warehouse_id'); $stock_type = $this->input->post('stock_type'); $new_value = intval($this->input->post('new_value')); // Validasi data yang diperlukan if (!$product_detail_id || !$warehouse_id || !$stock_type) { log_message('error', 'Missing required data for stock update'); echo json_encode(["success" => false, "message" => "Missing required data"]); return; } // Siapkan data update berdasarkan stock_type $update_data = array(); switch ($stock_type) { case 'stock': $update_data['stock'] = $new_value; break; case 'stock_keep': $update_data['stock_keep'] = $new_value; break; case 'stock_reject': $update_data['stock_reject'] = $new_value; break; case 'stock_sample': $update_data['stock_sample'] = $new_value; break; default: log_message('error', 'Invalid stock type: ' . $stock_type); echo json_encode(["success" => false, "message" => "Invalid stock type"]); return; } // Log data yang akan diupdate log_message('debug', 'Updating stock with data: ' . json_encode($update_data)); try { // Ambil data produk dan nama produk sebelum update $this->db->select('p.title as product_name, s.stock, s.stock_keep, s.stock_reject, s.stock_sample'); $this->db->from('stock s'); $this->db->join('product_details pd', 's.id_product_detail = pd.id'); $this->db->join('products p', 'pd.product_id = p.id_products'); $this->db->where('s.id_product_detail', $product_detail_id); $this->db->where('s.warehouse_id', 1); $existing_stock_query = $this->db->get(); $existing_stock = $existing_stock_query->row(); // Tentukan old_stock berdasarkan stock_type $old_stock = 0; switch ($stock_type) { case 'stock': $old_stock = $existing_stock ? $existing_stock->stock : 0; break; case 'stock_keep': $old_stock = $existing_stock ? $existing_stock->stock_keep : 0; break; case 'stock_reject': $old_stock = $existing_stock ? $existing_stock->stock_reject : 0; break; case 'stock_sample': $old_stock = $existing_stock ? $existing_stock->stock_sample : 0; break; } // Update stok produk $this->db->where('id_product_detail', $product_detail_id); $this->db->where('warehouse_id', $warehouse_id); $update = $this->db->update('stock', $update_data); // Cek apakah update berhasil if ($update) { // Ambil nama produk $product_name = $existing_stock ? $existing_stock->product_name : 'Produk Tidak Diketahui'; $username = $this->session->userdata('name'); $description = "Stok produk {$product_name} (ID: {$product_detail_id}) telah diperbarui dari {$old_stock} menjadi {$new_value} oleh {$username}."; // Log perubahan stok $this->load->model('log_m'); $this->log_m->log_stock_update( null, // order_id tidak diperlukan $product_detail_id, // product_id diisi dengan id product_detail $product_name, $old_stock, $new_value, null, // reference_url $description, // description akan dibuat otomatis $stock_type, // field yang diupdate 'stock' ); log_message('debug', 'Stock updated successfully for product_detail_id: ' . $product_detail_id); echo json_encode([ "success" => true, "message" => "Stock updated successfully", "updated_data" => $update_data ]); } else { // Cek apakah data exists $exists = $this->db->where('id_product_detail', $product_detail_id) ->where('warehouse_id', $warehouse_id) ->get('stock') ->num_rows(); if ($exists == 0) { // Jika data tidak ada, insert baru $insert_data = array( 'id_product_detail' => $product_detail_id, 'warehouse_id' => $warehouse_id, 'stock' => 0, 'stock_keep' => 0, 'stock_reject' => 0, 'stock_sample' => 0 ); $insert_data[$stock_type] = $new_value; $insert = $this->db->insert('stock', $insert_data); if ($insert) { // Ambil nama produk untuk insert baru $this->db->select('p.title as product_name'); $this->db->from('product_details pd'); $this->db->join('products p', 'pd.product_id = p.id'); $this->db->where('pd.id', $product_detail_id); $product_query = $this->db->get(); $product = $product_query->row(); $product_name = $product ? $product->product_name : 'Produk Tidak Diketahui'; $username = $this->session->userdata('name'); $description = "Stok produk {$product_name} (ID: {$product_detail_id}) telah diperbarui dari {$old_stock} menjadi {$new_value} oleh {$username}."; // Log perubahan stok untuk insert baru $this->load->model('log_m'); $this->log_m->log_stock_update( null, // order_id tidak diperlukan $product_detail_id, // product_id diisi dengan id product_detail $product_name, 0, // old_stock $new_value, null, // reference_url $description, // description akan dibuat otomatis $stock_type, // field yang diupdate 'stock' ); echo json_encode([ "success" => true, "message" => "New stock record created successfully", "updated_data" => $insert_data ]); return; } } log_message('error', 'Failed to update stock for product_detail_id: ' . $product_detail_id); log_message('error', 'Database Error: ' . json_encode($this->db->error())); echo json_encode([ "success" => false, "message" => "Failed to update stock" ]); } } catch (Exception $e) { log_message('error', 'Exception during stock update: ' . $e->getMessage()); echo json_encode([ "success" => false, "message" => "Error updating stock" ]); } } // Old function index() { // Add pagination $this->load->helper('pagination_helper'); add_pagination(base_url() . 'admin/stocks/index', $this->product_m->record_count(), 10000, 4); // Check if the warehouse filter is set $selected_warehouse = $this->input->get('warehouse'); $data['selected_warehouse'] = $selected_warehouse; // First query: Get low stock products specifically from warehouse 1 (gudang utama) $low_stock_query = $this->db->select('p.id_products, p.title, p.product_status, p.brand_id, pd.sku, p.restock, pad.attribute_detail, b.brand, COALESCE(SUM(s.stock), 0) as total_stock, COALESCE(SUM(s.stock_keep), 0) as total_stock_keep, COALESCE(SUM(s.stock_reject), 0) as total_stock_reject') ->from('products p') ->join('product_combination pc', 'p.id_products = pc.product_id', 'inner') ->join('product_attributes_detail pad', 'pc.attribute_detail_id = pad.id', 'inner') ->join('product_details pd', 'pc.product_details_id = pd.id', 'inner') ->join('brands b', 'p.brand_id = b.id_brands', 'inner') ->join('stock s', 'pd.id = s.id_product_detail', 'left') ->where('s.warehouse_id', 1) // Always use warehouse_id = 1 for low stock check ->group_by('p.id_products, p.title, p.product_status, p.brand_id, pd.sku, pad.attribute_detail, b.brand') ->having('(COALESCE(SUM(s.stock), 0) + COALESCE(SUM(s.stock_reject), 0)) < 10') ->order_by('total_stock', 'ASC') ->get() ->result(); // Filter active products from low stock products $low_stock_active_products = array_filter($low_stock_query, function ($product) { return $product->product_status == 1; }); // Second query: Get all products based on selected warehouse filter $this->db->select('p.id_products, p.title, p.product_status, p.restock, p.brand_id, pd.sku, pad.attribute_detail, b.brand, ts.total_stock, ts.total_stock_keep, ts.total_stock_reject'); $this->db->from('products p'); $this->db->join('product_combination pc', 'p.id_products = pc.product_id', 'inner'); $this->db->join('product_attributes_detail pad', 'pc.attribute_detail_id = pad.id', 'inner'); $this->db->join('product_details pd', 'pc.product_details_id = pd.id', 'inner'); $this->db->join('brands b', 'p.brand_id = b.id_brands', 'inner'); // Subquery for total stock based on selected warehouse $subquery = "(SELECT id_product_detail, SUM(stock) AS total_stock, SUM(stock_keep) AS total_stock_keep, SUM(stock_reject) AS total_stock_reject FROM stock"; if (!empty($selected_warehouse)) { $subquery .= " WHERE warehouse_id = $selected_warehouse"; } $subquery .= " GROUP BY id_product_detail) ts"; $this->db->join($subquery, 'pd.id = ts.id_product_detail', 'left'); if (!empty($selected_warehouse)) { $this->db->where("EXISTS (SELECT 1 FROM stock s WHERE s.id_product_detail = pd.id AND s.warehouse_id = $selected_warehouse)", NULL, FALSE); } $min_stock = $this->input->get('min_stock'); $max_stock = $this->input->get('max_stock'); if (!empty($min_stock)) { $this->db->having('ts.total_stock >=', $min_stock); } if (!empty($max_stock)) { $this->db->having('ts.total_stock <=', $max_stock); } // Keep this line $data['products'] = $this->db->get()->result(); $data['low_stock_active_products'] = $low_stock_active_products; $data['use_pagination'] = 'yes'; // Get warehouses for the dropdown $this->db->select('id, name') ->from('warehouse') ->order_by('priority', 'ASC'); $data['warehouses'] = $this->db->get()->result(); // Load view $data['subview'] = 'admin/stocks/index'; $this->load->view('admin/templates/header', $this->data_header); $this->load->view('admin/_layout_main', $data); $this->load->view('admin/templates/footer'); } function get($product_id = NULL) { if ($product_id == NULL) { redirect(base_url('admin/stocks')); } $this->db->select('*'); $this->db->from('products'); $this->db->where('id_products', $product_id); $this->data['product'] = $this->db->get()->row(); $this->data['use_pagination'] = 'no'; //get warehouse $this->db->select('id, name')->from('warehouse')->order_by('priority', 'ASC'); $this->data['warehouses'] = $this->db->get()->result(); //load view $this->data['subview'] = 'admin/stocks/view'; $this->load->view('admin/templates/header', $this->data_header); $this->load->view('admin/_layout_main', $this->data); $this->load->view('admin/templates/footer'); } function stock_low() { // Add pagination $this->load->helper('pagination_helper'); add_pagination(base_url() . 'admin/stocks/index', $this->product_m->record_count(), 10000, 4); // Get all brands for the dropdown $this->db->select('id_brands, brand')->from('brands')->order_by('brand', 'ASC'); $this->data['brands'] = $this->db->get()->result(); // Check if the brand filter is set $selected_brand = $this->input->get('brand'); // Get brand from query parameter // Prepare query with brand filter $this->db->select('p.id_products, p.title, pd.sku, pad.attribute_detail, s.stock, s.stock_keep') ->from('stock s') ->join('products p', 's.id_product = p.id_products', 'inner') ->join('product_combination pc', 's.id_product_detail = pc.product_details_id', 'inner') ->join('product_attributes_detail pad', 'pc.attribute_detail_id = pad.id', 'inner') ->join('product_details pd', 'pc.product_details_id = pd.id', 'inner') ->where('s.stock <', 10); // Menambahkan kondisi WHERE untuk stock di bawah 10 if (!empty($selected_brand)) { // If brand is selected, filter by brand $this->db->where('p.brand_id', $selected_brand); } $this->db->order_by('p.title', 'ASC'); $this->data['products'] = $this->db->get()->result(); $this->data['use_pagination'] = 'yes'; //get warehouse $this->db->select('id, name')->from('warehouse')->order_by('priority', 'ASC'); $this->data['warehouses'] = $this->db->get()->result(); // Load view $this->data['subview'] = 'admin/stocks/stock_low'; $this->load->view('admin/templates/header', $this->data_header); $this->load->view('admin/_layout_main', $this->data); $this->load->view('admin/templates/footer'); } function callajax_setval_mutasi() { $id_product_detail = $this->input->post('id_product_detail'); $query_pd = $this->db->get_where('product_details', array( "id" => $id_product_detail, )); $id_product = $query_pd->row()->product_id; $query_stock = $this->db->get_where('stock', array( "id_product" => $id_product, "id_product_detail" => $id_product_detail, )); $data_output = []; $counter_stock = -1; if ($query_stock->num_rows() > 0) { foreach ($query_stock->result() as $key_stock) { $query_stock_mov = $this->db->select("sm.*, s.warehouse_id")->from("stock_movement sm") ->join('stock s', 'sm.stock_id=s.id') ->where("sm.stock_id", $key_stock->id) ->order_by('sm.datetime', 'asc') ->get(); foreach ($query_stock_mov->result() as $key) { $counter_stock++; $newDate = date("d M Y h:i:s", strtotime($key->datetime)); $data_output[$counter_stock] = array( "warehouse_id" => $key->warehouse_id, "val" => array( 'tanggal' => $newDate, 'nama' => $key->name, 'mutasi' => $key->type . $key->stock_change, 'total' => $key->total, 'keterangan' => $key->remark, ), ); } } // echo "<pre>"; // var_dump($data_output); exit(); } echo json_encode(array( 'data' => $data_output, )); } function callajax_setval_mutasi_keep() { $id_product_detail = $this->input->post('id_product_detail'); $query_pd = $this->db->get_where('product_details', array( "id" => $id_product_detail, )); $id_product = $query_pd->row()->product_id; $query_stock = $this->db->get_where('stock', array( "id_product" => $id_product, "id_product_detail" => $id_product_detail, )); $data_output = []; $counter_stock = -1; if ($query_stock->num_rows() > 0) { foreach ($query_stock->result() as $key_stock) { $query_stock_mov = $this->db->select("sm.*, s.warehouse_id")->from("stock_movement_keep sm") ->join('stock s', 'sm.stock_id=s.id') ->where("sm.stock_id", $key_stock->id) ->order_by('sm.datetime', 'asc') ->get(); foreach ($query_stock_mov->result() as $key) { $counter_stock++; $newDate = date("d M Y h:i:s", strtotime($key->datetime)); $data_output[$counter_stock] = array( "warehouse_id" => $key->warehouse_id, "val" => array( 'tanggal' => $newDate, 'nama' => $key->name, 'mutasi' => $key->type . $key->stock_change, 'total' => $key->total, 'total_jual' => $key->total_jual, 'keterangan' => $key->remark, ), ); } } // echo "<pre>"; // var_dump($data_output); exit(); } echo json_encode(array( 'data' => $data_output, )); } function callajax_setval_mutasi_reject() { $id_product_detail = $this->input->post('id_product_detail'); $query_pd = $this->db->get_where('product_details', array( "id" => $id_product_detail, )); $id_product = $query_pd->row()->product_id; $query_stock = $this->db->get_where('stock', array( "id_product" => $id_product, "id_product_detail" => $id_product_detail, )); $data_output = []; $counter_stock = -1; if ($query_stock->num_rows() > 0) { foreach ($query_stock->result() as $key_stock) { $query_stock_mov = $this->db->select("sm.*, s.warehouse_id")->from("stock_movement_reject sm") ->join('stock s', 'sm.stock_id=s.id') ->where("sm.stock_id", $key_stock->id) ->order_by('sm.datetime', 'asc') ->get(); foreach ($query_stock_mov->result() as $key) { $counter_stock++; $newDate = date("d M Y h:i:s", strtotime($key->datetime)); $data_output[$counter_stock] = array( "warehouse_id" => $key->warehouse_id, "val" => array( 'tanggal' => $newDate, 'nama' => $key->name, 'mutasi' => $key->type . $key->stock_change, 'total' => $key->total, 'keterangan' => $key->remark, ), ); } } // echo "<pre>"; // var_dump($data_output); exit(); } echo json_encode(array( 'data' => $data_output, )); } public function transfer_stock() { //pagination in action. 100 results per page $this->load->library('pagination'); $config['base_url'] = base_url() . 'admin/stocks/transfer_stocks_index'; $config['per_page'] = 100; $config["uri_segment"] = 4; //fetch all stocks $config['total_rows'] = $this->transfer_stock_m->record_count(); $this->pagination->initialize($config); $this->data['transfer_stock'] = $this->transfer_stock_m->get_all_transfer_stock( $config["per_page"], $this->uri->segment(4) ); $this->data['total_transfer_stock'] = $this->transfer_stock_m->record_count(); //load view $this->data['subview'] = 'admin/stocks/transfer_stocks_index'; $this->load->view('admin/templates/header', $this->data_header); $this->load->view('admin/_layout_main', $this->data); $this->load->view('admin/templates/footer'); } public function Report_export() { // Ambil data transfer_stock_detail $this->data['transfer_stock_detail'] = $this->Transfer_stock_detail_m->get_transfer_stock_detail_data(); $this->data['subview'] = 'admin/stocks/transfer_stocks_export'; $this->load->view('admin/templates/header', $this->data_header); $this->load->view('admin/_layout_main', $this->data); $this->load->view('admin/templates/footer'); } function ajax_get_address_warehouse() { $id = (int) $this->input->post('id'); $data['warehouse'] = $this->db->select('*')->from('warehouse')->where('warehouse.id', $id)->get()->result(); $this->load->view('admin/stocks/ajax_get_address_warehouse', $data); } function ajax_get_product_detail() { $id = (int) $this->input->post('id_product_detail'); // $id_marketplace = (int) $this->input->post('id_marketplace'); $id_warehouse = (int) $this->input->post('id_warehouse'); $data['stock'] = $this->db->select("p.id_products, pc.product_details_id ,pc.attribute_detail_id , p.title,pa.product_attribute,pad.attribute_detail, pd.sku,pd.price, pd.discounted_price, s.stock") ->from("product_combination pc, products p, product_details pd, product_attributes pa, product_attributes_detail pad, stock s") ->where("pc.product_id = p.id_products and pc.product_details_id = pd.id and pa.id = pc.attribute_id and pad.id = pc.attribute_detail_id and s.id_product_detail = pc.product_details_id") ->where("pc.product_details_id", $id) ->where("s.warehouse_id", $id_warehouse)->get()->row(); echo json_encode($data); } public function add_transfer_stock() { $this->data['products'] = $this->db->select('p.id_products, pd.id as product_details_id, p.title, GROUP_CONCAT(pad.attribute_detail SEPARATOR ", ") AS attributes_name') ->from('product_combination pc') ->join('products p', 'pc.product_id = p.id_products') ->join('product_details pd', 'pc.product_details_id = pd.id') ->join('product_attributes pa', 'pa.id = pc.attribute_id') ->join('product_attributes_detail pad', 'pad.id = pc.attribute_detail_id') ->order_by('title', 'ASC') ->group_by('pd.id') ->get()->result(); $this->data['warehouses'] = $this->db->select('*')->from('warehouse')->order_by('id', 'ASC')->get()->result(); $this->data['metode_pengiriman'] = $this->db->select('*')->from('shipment_method')->order_by('id', 'ASC')->get()->result(); $config = $this->transfer_stock_m->add_transfer_rules; $this->load->library('form_validation'); $this->form_validation->set_error_delimiters('<div class="error">', '</div>'); //above is to add class to form validation error, to be styled $this->form_validation->set_rules($config); $this->form_validation->set_error_delimiters('<div class="error">', '</div>'); if ($this->form_validation->run($this) == TRUE) { /*get customer info detail*/ $warehouse_id = $this->security->xss_clean($this->input->post('warehouse_id')); $warehouse_id_tujuan = $this->security->xss_clean($this->input->post('warehouse_id2')); $warehouse = $this->db->select('*')->from('warehouse')->where('id', $warehouse_id_tujuan)->get()->row(); /*get marketplace name*/ $product = $this->security->xss_clean($this->input->post('id_product_detail')); $count_product = count($product); $quantitas_beli = $this->security->xss_clean($this->input->post('kuantitas')); $kurir_id = $this->security->xss_clean($this->input->post('kurir_id')); /*cek product dan qty kosong*/ if ($product != 0) { for ($a = 0; $a < $count_product; $a++) { if ($quantitas_beli[$a] == "" || $quantitas_beli[$a] == 0) { $this->session->set_flashdata('success', '<br><p style="background:red; color:white; padding:5px; font-weight:bold;">Not Set Product Quantity</p>'); redirect('admin/stocks/add_transfer_stock'); } } } else { $this->session->set_flashdata('success', '<br><p style="background:red; color:white; padding:5px; font-weight:bold;">Not Product Found</p>'); redirect('admin/stocks/add_transfer_stock'); } $transfer = array( 'out_warehouse_id' => $warehouse_id, 'in_warehouse_id' => $warehouse_id_tujuan, 'status' => 0, 'recipient_name' => $warehouse->name, 'address' => $warehouse->address, 'district' => $warehouse->id_district, 'subdistrict' => $warehouse->id_subdistrict, 'province' => $warehouse->id_province, 'phone' => $warehouse->phone, 'phone' => $warehouse->phone, 'created' => date("Y-m-d H:i:s"), 'cancel_date' => null, 'sent_date' => null, 'shipping_type' => $kurir_id, 'no_resi' => null, 'shipping_fee' => $this->input->post('shipping_fee'), 'admin_note' => $this->security->xss_clean($this->input->post('admin_note')) ); $transfer_id = (int) $this->transfer_stock_m->add_transfer_stock($transfer); /*insert into order detail*/ for ($c = 0; $c < $count_product; $c++) { $product_item = $this->db->select('p.id_products, pc.product_details_id ,pc.attribute_detail_id , p.title,pa.product_attribute,pad.attribute_detail, pd.sku,pd.price, s.stock, s.warehouse_id') ->from('product_combination pc, products p, product_details pd, product_attributes pa, product_attributes_detail pad, stock s') ->where('pc.product_id = p.id_products and pc.product_details_id = pd.id and pa.id = pc.attribute_id and pad.id = pc.attribute_detail_id and s.id_product_detail = pc.product_details_id') ->where('pc.product_details_id', $product[$c]) ->get()->row(); /*$shipping_fee_info = calculate_shipping_fee(3, 1, $product[$c], $quantitas_beli[$c], $customer->shipping_id_subdistrict);*/ $transfer_stock_detail = array( 'id_transfer_stock' => $transfer_id, 'product_detail_id' => $product[$c], 'product_id' => $product_item->id_products, 'item_name' => $product_item->title, 'quantity' => $quantitas_beli[$c], 'sku' => $product_item->sku, 'attributes' => $product_item->attribute_detail, 'warehouse_id' => $warehouse_id, 'warehouse_id_target' => $warehouse_id_tujuan, ); $this->db->insert('transfer_stock_detail', $transfer_stock_detail); } /*insert into order detail*/ /*kurangi stock pada warehouse*/ for ($d = 0; $d < $count_product; $d++) { $curent_stock = $this->db->select('stock')->from('stock')->where('id_product_detail', $product[$d])->where('warehouse_id', $warehouse_id)->get()->row(); $warehouse = $this->db->select('*')->from('warehouse')->where('id', $warehouse_id)->get()->row(); if ($warehouse->warehouse_type == 'virtual') { $final_stock = array( 'stock_virtual' => $curent_stock->stock_virtual - $quantitas_beli[$d], ); $this->db->where('id_product_detail', $product[$d]); $this->db->where('warehouse_id', $warehouse_id); $this->db->update('stock', $final_stock); } else { $final_stock = array( 'stock' => $curent_stock->stock - $quantitas_beli[$d], ); $this->db->where('id_product_detail', $product[$d]); $this->db->where('warehouse_id', $warehouse_id); $this->db->update('stock', $final_stock); // insert mov stock $id_stock = $this->db->select('id')->from('stock')->where('id_product_detail', $product[$d])->where('warehouse_id', $warehouse_id)->get()->row(); $last_stock = $curent_stock->stock - $quantitas_beli[$d]; $this->db->select('name')->from('users')->where('id', $this->session->userdata('admin')['id']); $user_name = $this->db->get()->row()->name; $insert_mov_stock = array( 'stock_id' => $id_stock->id, 'type' => '-', 'stock_change' => $quantitas_beli[$d], 'remark' => 'Transfer Stock: ' . $transfer_id, 'total' => $last_stock, 'name' => $user_name, 'datetime' => date("Y-m-d H:i:s"), ); $this->db->insert('stock_movement', $insert_mov_stock); } } /*insert shipping session to shipping table*/ $user_id = $this->session->userdata('admin')['id']; $activity = 'User transfer stock (' . $transfer_id . ')'; log_activity($user_id, $activity); $this->session->set_flashdata('success', '<br><p style="background:green; color:white; padding:5px; font-weight:bold;">Add transfer stock successful</p>'); redirect('admin/stocks/transfer_stock'); } //load view $this->data['subview'] = 'admin/stocks/add_transfer_stock'; $this->load->view('admin/templates/header', $this->data_header); $this->load->view('admin/_layout_main', $this->data); $this->load->view('admin/templates/footer'); } function add_note($id) { if (!isset($_POST['add_note'])) { show_404(); } if ($id == NULL) { show_404(); } //check if id is exist $this->db->select('id_transfer_stock')->from('transfer_stock')->where('id_transfer_stock', $id); $count_id = $this->db->get()->num_rows(); if ($count_id == 0) { show_404(); } $data = array( 'admin_note' => $this->security->xss_clean($this->input->post('admin_note')) ); $this->db->where('id_transfer_stock', $id); $this->db->update('transfer_stock', $data); $this->session->set_flashdata('success', "<br><p style='background:green; color:white; padding:5px; font-weight:bold;'>Update Note Success.</p>"); redirect('admin/stocks/view_transfer_stock/' . $id); } function update_resi($id) { if (!isset($_POST['resi'])) { show_404(); } if ($id == NULL) { show_404(); } //load library security $this->load->library('security'); //check if id is exist $this->db->select('id_transfer_stock')->from('transfer_stock')->where('id_transfer_stock', $id); $count_id = $this->db->get()->num_rows(); if ($count_id == 0) { show_404(); } $data = array( 'status' => 2, 'sent_date' => date('Y-m-d'), 'no_resi' => $this->security->xss_clean($this->input->post('resi')) ); $this->db->where('id_transfer_stock', $id); $this->db->update('transfer_stock', $data); //logging $user_id = $this->session->userdata('admin')['id']; $activity = 'User mengupdate resi dan merubah status transfer stock menjadi terkirim (' . $id . ')'; log_activity($user_id, $activity); $this->session->set_flashdata('success', '<br><p style="background:green; color:white; padding:5px; font-weight:bold;">Status transfer stock berhasil diupdate</p>'); redirect('admin/stocks/view_transfer_stock/' . $id); } public function generate_deliveryreceipt($id) { if ($id == NULL) { redirect('admin/stocks'); } $count_transfer = $this->db->select('id_transfer_stock')->from('transfer_stock')->where('id_transfer_stock', $id)->get()->num_rows(); if ($count_transfer < 1) { redirect('admin/stocks'); } //get website info $pdf_data['website_data'] = $this->db->select('logo, website_name')->from('configuration')->where('id_configuration', 1)->get()->row(); //add PDF attachment DOMPDF $pdf_data['title'] = 'Transfer Stock Delivery Receipt No: ' . $id; //get order $this->db->select('*')->from('transfer_stock')->where('id_transfer_stock', $id); $pdf_data['transfer_stock'] = $this->db->get()->row(); if ($count_transfer > 0) { // get order detail $pdf_data['transfer_stock_detail'] = $this->db->select('*')->from('transfer_stock_detail')->where('id_transfer_stock', $id)->get()->result(); //Print Pdf Delivery Receipt $this->load->library('dompdf_gen'); $html = $this->load->view('pdf/deliveryreceipttfs', $pdf_data, true); $this->dompdf->loadHtml($html); $this->dompdf->setPaper('A4', 'portrait'); $this->dompdf->render(); $this->dompdf->stream('deliveryreceipt.pdf', array("Attachment" => 0)); $output = $this->dompdf->output(); $file_to_save = 'uploads/pdf/deliveryreceipt.pdf'; file_put_contents($file_to_save, $output); } else { redirect('admin/stocks'); } } //to VIEW and EDIT order in admin public function view_transfer_stock($id) { if ($id == null) { redirect('admin/stocks'); } //get stocks $this->db->select('id_transfer_stock')->from('transfer_stock')->where('id_transfer_stock', $id); $current_order_count = $this->db->get()->num_rows(); if ($current_order_count < 1) { show_404(); } $this->db->select('*')->from('transfer_stock')->where('id_transfer_stock', $id); $current_transfer_stock = $this->db->get()->row(); if (isset($_POST['status'])) { /* if($this->order_m->cek_order($id,$_POST['status']) == FALSE){ $this->session->set_flashdata('success', '<br><p style="background:green; color:white; padding:5px; font-weight:bold;">Order telah diproses</p>'); redirect('admin/stocks/view_transfer_stock/' . $id); } */ //var_dump($this->input->post('status')); exit(); if ($this->input->post('status') == 1) { //Status Process $data = array( 'status' => 1 ); $this->db->where('id_transfer_stock', $id); $this->db->update('transfer_stock', $data); //logging $user_id = $this->session->userdata('admin')['id']; $activity = 'User mengubah status transfer stock ' . $id . ' menjadi Proses'; log_activity($user_id, $activity); $this->session->set_flashdata('success', '<br><p style="background:green; color:white; padding:5px; font-weight:bold;">Status transfer stock berhasil diupdate</p>'); redirect('admin/stocks/view_transfer_stock/' . $id); } if ($this->input->post('status') == 2) { //Status Sent $data = array( 'status' => 2, 'sent_date' => date('Y-m-d') ); $this->db->where('id_transfer_stock', $id); $this->db->update('transfer_stock', $data); //logging $user_id = $this->session->userdata('admin')['id']; $activity = 'User mengubah status transfer stock' . $id . ' menjadi Terkirim'; log_activity($user_id, $activity); $this->session->set_flashdata('success', '<br><p style="background:green; color:white; padding:5px; font-weight:bold;">Status transfer stock berhasil diupdate</p>'); redirect('admin/stocks/view_transfer_stock/' . $id); } if ($this->input->post('status') == 3) { //Status Arrive $data = array( 'status' => 3 ); $this->db->where('id_transfer_stock', $id); $this->db->update('transfer_stock', $data); $transfer_stock_details = $this->Transfer_stock_detail_m->get_transfer_stock_detail($id); foreach ($transfer_stock_details as $item) { $current_stock = $this->db->select('stock')->from('stock')->where('id_product_detail', $item->product_detail_id)->where('warehouse_id', $item->warehouse_id_target)->get()->row(); if ($current_stock == null) { $insert_mov_stock = array( 'id_product' => $item->product_id, 'id_product_detail' => $item->product_detail_id, 'warehouse_id' => $item->warehouse_id_target, 'stock' => 0, ); $this->db->insert('stock', $insert_mov_stock); $final_stock = array( 'stock' => 0 + $item->quantity, ); } else { $final_stock = array( 'stock' => $current_stock->stock + $item->quantity, ); } $this->db->where('id_product_detail', $item->product_detail_id); $this->db->where('warehouse_id', $item->warehouse_id_target); $this->db->update('stock', $final_stock); // insert mov stock $id_stock = $this->db->select('id')->from('stock')->where('id_product_detail', $item->product_detail_id)->where('warehouse_id', $item->warehouse_id_target)->get()->row(); $last_stock = $current_stock->stock + $item->quantity; $this->db->select('name')->from('users')->where('id', $this->session->userdata('admin')['id']); $user_name = $this->db->get()->row()->name; $insert_mov_stock = array( 'stock_id' => $id_stock->id, 'type' => '+', 'stock_change' => $item->quantity, 'remark' => 'Transfer Stock: ' . $id, 'total' => $last_stock, 'name' => $user_name, 'datetime' => date("Y-m-d H:i:s"), ); $this->db->insert('stock_movement', $insert_mov_stock); } //logging $user_id = $this->session->userdata('admin')['id']; $activity = 'User mengubah status transfer stock' . $id . ' menjadi diterima'; log_activity($user_id, $activity); $this->session->set_flashdata('success', '<br><p style="background:green; color:white; padding:5px; font-weight:bold;">Status Transfer Stock berhasil diupdate</p>'); redirect('admin/stocks/view_transfer_stock/' . $id); } if ($this->input->post('status') == 4) { //Status Cancel $data = array( 'status' => 4, 'cancel_date' => date('Y-m-d') ); $this->db->where('id_transfer_stock', $id); $this->db->update('transfer_stock', $data); $transfer_stock_details = $this->Transfer_stock_detail_m->get_transfer_stock_detail($id); foreach ($transfer_stock_details as $item) { $current_stock = $this->db->select('stock')->from('stock')->where('id_product_detail', $item->product_detail_id)->where('warehouse_id', $item->warehouse_id)->get()->row(); if ($current_stock == null) { $insert_mov_stock = array( 'id_product' => $item->product_id, 'id_product_detail' => $item->product_detail_id, 'warehouse_id' => $item->warehouse_id, 'stock' => 0, ); $this->db->insert('stock', $insert_mov_stock); $final_stock = array( 'stock' => 0 + $item->quantity, ); } else { $final_stock = array( 'stock' => $current_stock->stock + $item->quantity, ); } $this->db->where('id_product_detail', $item->product_detail_id); $this->db->where('warehouse_id', $item->warehouse_id); $this->db->update('stock', $final_stock); // insert mov stock $id_stock = $this->db->select('id')->from('stock')->where('id_product_detail', $item->product_detail_id)->where('warehouse_id', $item->warehouse_id)->get()->row(); $new_stock = $current_stock->stock + $item->quantity; $this->db->select('name')->from('users')->where('id', $this->session->userdata('admin')['id']); $user_name = $this->db->get()->row()->name; $insert_mov_stock = array( 'stock_id' => $id_stock->id, 'type' => '+', 'stock_change' => $item->quantity, 'remark' => 'Cancel Transfer Stock: ' . $id . ' (' . $new_stock . ')', 'total' => $new_stock, 'name' => $user_name, 'datetime' => date("Y-m-d H:i:s"), ); $this->db->insert('stock_movement', $insert_mov_stock); } //logging $user_id = $this->session->userdata('admin')['id']; $activity = 'User mengubah status transfer stock ' . $id . ' menjadi Batal'; log_activity($user_id, $activity); $this->session->set_flashdata('success', '<br><p style="background:green; color:white; padding:5px; font-weight:bold;">Status transfer stock berhasil diupdate</p>'); redirect('admin/stocks/view_transfer_stock/' . $id); } } //get order detail and customer detail $this->data['transfer_stock'] = $this->transfer_stock_m->get_transfer_stock($id); $this->data['transfer_stock_detail'] = $this->Transfer_stock_detail_m->get_transfer_stock_detail($id); $this->data['subview'] = 'admin/stocks/view_transfer_stock'; $this->load->view('admin/templates/header', $this->data_header); $this->load->view('admin/_layout_main', $this->data); $this->load->view('admin/templates/footer'); } function ajax_add_stock() { if (!$this->input->is_ajax_request()) { exit('No direct script access allowed'); } $id_product = $this->input->post('id_product'); $id_product_detail = $this->input->post('id_product_detail'); foreach ($this->input->post('stock')['stock_amount'] as $warehouse_id => $stock) { //check if current combination of product_id, $product__detail_id and $warehouse_id already exist. $this->db->select('*')->from('stock')->where('id_product', $id_product)->where('id_product_detail', $id_product_detail)->where('warehouse_id', $warehouse_id); $stock_data = $this->db->get()->result(); if (count($stock_data) == 0) { //stock data not available, so we add to new stock if ($stock > 0) { $add_data = array( 'id_product' => $id_product, 'id_product_detail' => $id_product_detail, 'warehouse_id' => $warehouse_id, 'stock' => $stock ); $this->db->insert('stock', $add_data); $stock_id = $this->db->insert_id(); //update stock_movement_table $movement_data = array( 'stock_id' => $stock_id, 'type' => '+', 'stock_change' => $stock, ); //get remark $this->db->select('name')->from('users')->where('id', $this->session->userdata('admin')['id']); $user_name = $this->db->get()->row()->name; $movement_data['remark'] = ''; $movement_data['name'] = $user_name; $movement_data['total'] = $stock; foreach ($this->input->post('stock')['remark'] as $warehouse_id2 => $remark) { if ($warehouse_id == $warehouse_id2) { $movement_data['remark'] = $remark; break; } } $this->db->insert('stock_movement', $movement_data); } } else { if ($stock > 0) { //stock data already available, so we add to current stock foreach ($stock_data as $item) { $current_stock = $item->stock; $new_stock = $current_stock + $stock; $update_data = array( 'stock' => $new_stock ); $this->db->where('id_product', $id_product); $this->db->where('id_product_detail', $id_product_detail); $this->db->where('warehouse_id', $warehouse_id); $this->db->update('stock', $update_data); //get $stock_id $stock_id = $item->id; //update stock_movement_table $movement_data = array( 'stock_id' => $stock_id, 'type' => '+', 'stock_change' => $stock, ); //get remark $this->db->select('name')->from('users')->where('id', $this->session->userdata('admin')['id']); $user_name = $this->db->get()->row()->name; $movement_data['remark'] = ''; $movement_data['name'] = $user_name; $movement_data['total'] = $new_stock; foreach ($this->input->post('stock')['remark'] as $warehouse_id2 => $remark) { if ($warehouse_id == $warehouse_id2) { $movement_data['remark'] = $remark; break; } } $this->db->insert('stock_movement', $movement_data); } } } } $this->db->select('stock, warehouse_id')->from('stock')->where('id_product', $id_product)->where('id_product_detail', $id_product_detail); $all_stocks = $this->db->get()->result_array(); $user_id = $this->session->userdata('admin')['id']; // Query untuk mengambil title dari tabel product $this->db->select('title'); $this->db->from('products'); $this->db->where('id_products', $id_product); $query_product = $this->db->get(); $product_data = $query_product->row(); // Query untuk mengambil sku dari tabel product_details $this->db->select('sku'); $this->db->from('product_details'); $this->db->where('id', $id_product_detail); $query_details = $this->db->get(); $details_data = $query_details->row(); // Buat string "title/SKU" if ($product_data && $details_data) { $activity = 'User menambah stok (' . $product_data->title . '/' . $details_data->sku . ') secara manual'; } else { // Handle jika data produk atau detail produk tidak ditemukan $activity = 'User menambah stok (' . $id_product . '/' . $id_product_detail . ') secara manual'; } log_activity($user_id, $activity); $ajax_data = array( 'stock_data' => $all_stocks, 'id_product' => $id_product, 'id_product_detail' => $id_product_detail, 'message' => 'STOK BERHASIL DITAMBAHKAN' ); echo json_encode($ajax_data); } function ajax_add_stock_keep() { if (!$this->input->is_ajax_request()) { exit('No direct script access allowed'); } $id_product = $this->input->post('id_product'); $id_product_detail = $this->input->post('id_product_detail'); foreach ($this->input->post('stock')['stock_amount'] as $warehouse_id => $stock) { //check if current combination of product_id, $product__detail_id and $warehouse_id already exist. $this->db->select('*')->from('stock')->where('id_product', $id_product)->where('id_product_detail', $id_product_detail)->where('warehouse_id', $warehouse_id); $stock_data = $this->db->get()->result(); if (count($stock_data) == 0) { //stock data not available, so we add to new stock if ($stock > 0) { $add_data = array( 'id_product' => $id_product, 'id_product_detail' => $id_product_detail, 'warehouse_id' => $warehouse_id, 'stock_keep' => $stock ); $this->db->insert('stock', $add_data); $stock_id = $this->db->insert_id(); //update stock_movement_table $movement_data = array( 'stock_id' => $stock_id, 'type' => '+', 'stock_change' => $stock, ); //get remark $this->db->select('name')->from('users')->where('id', $this->session->userdata('admin')['id']); $user_name = $this->db->get()->row()->name; $movement_data['remark'] = ''; $movement_data['name'] = $user_name; $movement_data['total'] = $stock; $movement_data['total_jual'] = 0; foreach ($this->input->post('stock')['remark'] as $warehouse_id2 => $remark) { if ($warehouse_id == $warehouse_id2) { $movement_data['remark'] = $remark; break; } } $this->db->insert('stock_movement_keep', $movement_data); } } else { if ($stock > 0) { //stock data already available, so we add to current stock foreach ($stock_data as $item) { $current_stock = $item->stock_keep; $current_stock_real = $item->stock; $new_stock = $current_stock + $stock; $stock_jual = $current_stock_real - $current_stock; $update_data = array( 'stock_keep' => $new_stock, 'stock' => $stock_jual ); $this->db->where('id_product', $id_product); $this->db->where('id_product_detail', $id_product_detail); $this->db->where('warehouse_id', $warehouse_id); $this->db->update('stock', $update_data); //get $stock_id $stock_id = $item->id; //update stock_movement_table $movement_data = array( 'stock_id' => $stock_id, 'type' => '+', 'stock_change' => $stock, ); //get remark $this->db->select('name')->from('users')->where('id', $this->session->userdata('admin')['id']); $user_name = $this->db->get()->row()->name; $movement_data['remark'] = ''; $movement_data['name'] = $user_name; $movement_data['total'] = $new_stock; $movement_data['total_jual'] = $stock_jual; foreach ($this->input->post('stock')['remark'] as $warehouse_id2 => $remark) { if ($warehouse_id == $warehouse_id2) { $movement_data['remark'] = $remark; break; } } $this->db->insert('stock_movement_keep', $movement_data); } } } } $this->db->select('stock_keep, warehouse_id')->from('stock')->where('id_product', $id_product)->where('id_product_detail', $id_product_detail); $all_stocks = $this->db->get()->result_array(); $user_id = $this->session->userdata('admin')['id']; // Query untuk mengambil title dari tabel product $this->db->select('title'); $this->db->from('products'); $this->db->where('id_products', $id_product); $query_product = $this->db->get(); $product_data = $query_product->row(); // Query untuk mengambil sku dari tabel product_details $this->db->select('sku'); $this->db->from('product_details'); $this->db->where('id', $id_product_detail); $query_details = $this->db->get(); $details_data = $query_details->row(); // Buat string "title/SKU" if ($product_data && $details_data) { $activity = 'User menambah stok keep (' . $product_data->title . '/' . $details_data->sku . ') secara manual'; } else { // Handle jika data produk atau detail produk tidak ditemukan $activity = 'User menambah stok keep (' . $id_product . '/' . $id_product_detail . ') secara manual'; } log_activity($user_id, $activity); $ajax_data = array( 'stock_data' => $all_stocks, 'id_product' => $id_product, 'id_product_detail' => $id_product_detail, 'message' => 'STOK KEEP BERHASIL DITAMBAHKAN' ); echo json_encode($ajax_data); } function ajax_add_stock_reject() { if (!$this->input->is_ajax_request()) { exit('No direct script access allowed'); } $id_product = $this->input->post('id_product'); $id_product_detail = $this->input->post('id_product_detail'); foreach ($this->input->post('stock')['stock_amount'] as $warehouse_id => $stock) { //check if current combination of product_id, $product__detail_id and $warehouse_id already exist. $this->db->select('*')->from('stock')->where('id_product', $id_product)->where('id_product_detail', $id_product_detail)->where('warehouse_id', $warehouse_id); $stock_data = $this->db->get()->result(); if (count($stock_data) == 0) { //stock data not available, so we add to new stock if ($stock > 0) { $add_data = array( 'id_product' => $id_product, 'id_product_detail' => $id_product_detail, 'warehouse_id' => $warehouse_id, 'stock_reject' => $stock ); $this->db->insert('stock', $add_data); $stock_id = $this->db->insert_id(); //update stock_movement_table $movement_data = array( 'stock_id' => $stock_id, 'type' => '+', 'stock_change' => $stock, ); //get remark $this->db->select('name')->from('users')->where('id', $this->session->userdata('admin')['id']); $user_name = $this->db->get()->row()->name; $movement_data['remark'] = ''; $movement_data['name'] = $user_name; $movement_data['total'] = $stock; $movement_data['total_jual'] = 0; foreach ($this->input->post('stock')['remark'] as $warehouse_id2 => $remark) { if ($warehouse_id == $warehouse_id2) { $movement_data['remark'] = $remark; break; } } $this->db->insert('stock_movement_reject', $movement_data); } } else { if ($stock > 0) { //stock data already available, so we add to current stock foreach ($stock_data as $item) { $current_stock = $item->stock_reject; $current_stock_real = $item->stock; $new_stock = $current_stock + $stock; $stock_jual = $current_stock_real - $new_stock; $update_data = array( 'stock_reject' => $new_stock ); $this->db->where('id_product', $id_product); $this->db->where('id_product_detail', $id_product_detail); $this->db->where('warehouse_id', $warehouse_id); $this->db->update('stock', $update_data); //get $stock_id $stock_id = $item->id; //update stock_movement_table $movement_data = array( 'stock_id' => $stock_id, 'type' => '+', 'stock_change' => $stock, ); //get remark $this->db->select('name')->from('users')->where('id', $this->session->userdata('admin')['id']); $user_name = $this->db->get()->row()->name; $movement_data['remark'] = ''; $movement_data['name'] = $user_name; $movement_data['total'] = $new_stock; $movement_data['total_jual'] = $stock_jual; foreach ($this->input->post('stock')['remark'] as $warehouse_id2 => $remark) { if ($warehouse_id == $warehouse_id2) { $movement_data['remark'] = $remark; break; } } $this->db->insert('stock_movement_reject', $movement_data); } } } } $this->db->select('stock_reject, warehouse_id')->from('stock')->where('id_product', $id_product)->where('id_product_detail', $id_product_detail); $all_stocks = $this->db->get()->result_array(); $user_id = $this->session->userdata('admin')['id']; // Query untuk mengambil title dari tabel product $this->db->select('title'); $this->db->from('products'); $this->db->where('id_products', $id_product); $query_product = $this->db->get(); $product_data = $query_product->row(); // Query untuk mengambil sku dari tabel product_details $this->db->select('sku'); $this->db->from('product_details'); $this->db->where('id', $id_product_detail); $query_details = $this->db->get(); $details_data = $query_details->row(); // Buat string "title/SKU" if ($product_data && $details_data) { $activity = 'User menambah stok reject (' . $product_data->title . '/' . $details_data->sku . ') secara manual'; } else { // Handle jika data produk atau detail produk tidak ditemukan $activity = 'User menambah stok reject (' . $id_product . '/' . $id_product_detail . ') secara manual'; } log_activity($user_id, $activity); $ajax_data = array( 'stock_data' => $all_stocks, 'id_product' => $id_product, 'id_product_detail' => $id_product_detail, 'message' => 'STOK REJECT BERHASIL DITAMBAHKAN' ); echo json_encode($ajax_data); } function ajax_minus_stock() { if (!$this->input->is_ajax_request()) { exit('No direct script access allowed'); } $id_product = $this->input->post('id_product'); $id_product_detail = $this->input->post('id_product_detail'); foreach ($this->input->post('stock')['stock_amount'] as $warehouse_id => $stock) { //check if current combination of product_id, $product__detail_id and $warehouse_id already exist. $this->db->select('*')->from('stock')->where('id_product', $id_product)->where('id_product_detail', $id_product_detail)->where('warehouse_id', $warehouse_id); $stock_data = $this->db->get()->result(); if (count($stock_data) > 0) { if ($stock > 0) { //stock data already available, so we minus to current stock foreach ($stock_data as $item) { $current_stock = $item->stock; $new_stock = $current_stock - $stock; $update_data = array( 'stock' => $new_stock ); $this->db->where('id_product', $id_product); $this->db->where('id_product_detail', $id_product_detail); $this->db->where('warehouse_id', $warehouse_id); $this->db->update('stock', $update_data); //get $stock_id $stock_id = $item->id; //update stock_movement_table $movement_data = array( 'stock_id' => $stock_id, 'type' => '-', 'stock_change' => $stock, ); //get remark $this->db->select('name')->from('users')->where('id', $this->session->userdata('admin')['id']); $user_name = $this->db->get()->row()->name; $movement_data['remark'] = ''; $movement_data['name'] = $user_name; $movement_data['total'] = $new_stock; foreach ($this->input->post('stock')['remark'] as $warehouse_id2 => $remark) { if ($warehouse_id == $warehouse_id2) { $movement_data['remark'] = $remark; break; } } $this->db->insert('stock_movement', $movement_data); } } } } $this->db->select('stock, warehouse_id')->from('stock')->where('id_product', $id_product)->where('id_product_detail', $id_product_detail); $all_stocks = $this->db->get()->result_array(); //logging $user_id = $this->session->userdata('admin')['id']; // Query untuk mengambil title dari tabel product $this->db->select('title'); $this->db->from('products'); $this->db->where('id_products', $id_product); $query_product = $this->db->get(); $product_data = $query_product->row(); // Query untuk mengambil sku dari tabel product_details $this->db->select('sku'); $this->db->from('product_details'); $this->db->where('id', $id_product_detail); $query_details = $this->db->get(); $details_data = $query_details->row(); // Buat string "title/SKU" if ($product_data && $details_data) { $activity = 'User mengurangi stok (' . $product_data->title . '/' . $details_data->sku . ') secara manual'; } else { // Handle jika data produk atau detail produk tidak ditemukan $activity = 'User mengurangi stok (' . $id_product . '/' . $id_product_detail . ') secara manual'; } log_activity($user_id, $activity); $ajax_data = array( 'stock_data' => $all_stocks, 'id_product' => $id_product, 'id_product_detail' => $id_product_detail, 'message' => 'STOK BERHASIL DIKURANGI' ); echo json_encode($ajax_data); } function ajax_minus_stock_keep() { if (!$this->input->is_ajax_request()) { exit('No direct script access allowed'); } $id_product = $this->input->post('id_product'); $id_product_detail = $this->input->post('id_product_detail'); foreach ($this->input->post('stock')['stock_amount'] as $warehouse_id => $stock) { //check if current combination of product_id, $product__detail_id and $warehouse_id already exist. $this->db->select('*')->from('stock')->where('id_product', $id_product)->where('id_product_detail', $id_product_detail)->where('warehouse_id', $warehouse_id); $stock_data = $this->db->get()->result(); if (count($stock_data) > 0) { if ($stock > 0) { //stock data already available, so we minus to current stock foreach ($stock_data as $item) { $current_stock = $item->stock_keep; $stock_real = $item->stock; $new_stock = $current_stock - $stock; $new_stock_jual = $stock_real + $new_stock; $update_data = array( 'stock_keep' => $new_stock, 'stock' => $new_stock_jual ); $this->db->where('id_product', $id_product); $this->db->where('id_product_detail', $id_product_detail); $this->db->where('warehouse_id', $warehouse_id); $this->db->update('stock', $update_data); //get $stock_id $stock_id = $item->id; //update stock_movement_table $movement_data = array( 'stock_id' => $stock_id, 'type' => '-', 'stock_change' => $stock, ); //get remark $this->db->select('name')->from('users')->where('id', $this->session->userdata('admin')['id']); $user_name = $this->db->get()->row()->name; $movement_data['remark'] = ''; $movement_data['name'] = $user_name; $movement_data['total'] = $new_stock; $movement_data['total_jual'] = $new_stock_jual; foreach ($this->input->post('stock')['remark'] as $warehouse_id2 => $remark) { if ($warehouse_id == $warehouse_id2) { $movement_data['remark'] = $remark; break; } } $this->db->insert('stock_movement_keep', $movement_data); } } } } $this->db->select('stock, warehouse_id')->from('stock')->where('id_product', $id_product)->where('id_product_detail', $id_product_detail); $all_stocks = $this->db->get()->result_array(); //logging $user_id = $this->session->userdata('admin')['id']; // Query untuk mengambil title dari tabel product $this->db->select('title'); $this->db->from('products'); $this->db->where('id_products', $id_product); $query_product = $this->db->get(); $product_data = $query_product->row(); // Query untuk mengambil sku dari tabel product_details $this->db->select('sku'); $this->db->from('product_details'); $this->db->where('id', $id_product_detail); $query_details = $this->db->get(); $details_data = $query_details->row(); // Buat string "title/SKU" if ($product_data && $details_data) { $activity = 'User mengurangi stok keep (' . $product_data->title . '/' . $details_data->sku . ') secara manual'; } else { // Handle jika data produk atau detail produk tidak ditemukan $activity = 'User mengurangi stok keep (' . $id_product . '/' . $id_product_detail . ') secara manual'; } log_activity($user_id, $activity); $ajax_data = array( 'stock_data' => $all_stocks, 'id_product' => $id_product, 'id_product_detail' => $id_product_detail, 'message' => 'STOK KEEP BERHASIL DIKURANGI' ); echo json_encode($ajax_data); } function ajax_minus_stock_reject() { if (!$this->input->is_ajax_request()) { exit('No direct script access allowed'); } $id_product = $this->input->post('id_product'); $id_product_detail = $this->input->post('id_product_detail'); foreach ($this->input->post('stock')['stock_amount'] as $warehouse_id => $stock) { //check if current combination of product_id, $product__detail_id and $warehouse_id already exist. $this->db->select('*')->from('stock')->where('id_product', $id_product)->where('id_product_detail', $id_product_detail)->where('warehouse_id', $warehouse_id); $stock_data = $this->db->get()->result(); if (count($stock_data) > 0) { if ($stock > 0) { //stock data already available, so we minus to current stock foreach ($stock_data as $item) { $current_stock = $item->stock_reject; $stock_real = $item->stock; $new_stock = $current_stock - $stock; $new_stock_jual = $stock_real - $new_stock; $update_data = array( 'stock_reject' => $new_stock ); $this->db->where('id_product', $id_product); $this->db->where('id_product_detail', $id_product_detail); $this->db->where('warehouse_id', $warehouse_id); $this->db->update('stock', $update_data); //get $stock_id $stock_id = $item->id; //update stock_movement_table $movement_data = array( 'stock_id' => $stock_id, 'type' => '-', 'stock_change' => $stock, ); //get remark $this->db->select('name')->from('users')->where('id', $this->session->userdata('admin')['id']); $user_name = $this->db->get()->row()->name; $movement_data['remark'] = ''; $movement_data['name'] = $user_name; $movement_data['total'] = $new_stock; $movement_data['total_jual'] = $new_stock_jual; foreach ($this->input->post('stock')['remark'] as $warehouse_id2 => $remark) { if ($warehouse_id == $warehouse_id2) { $movement_data['remark'] = $remark; break; } } $this->db->insert('stock_movement_reject', $movement_data); } } } } $this->db->select('stock, warehouse_id')->from('stock')->where('id_product', $id_product)->where('id_product_detail', $id_product_detail); $all_stocks = $this->db->get()->result_array(); //logging $user_id = $this->session->userdata('admin')['id']; // Query untuk mengambil title dari tabel product $this->db->select('title'); $this->db->from('products'); $this->db->where('id_products', $id_product); $query_product = $this->db->get(); $product_data = $query_product->row(); // Query untuk mengambil sku dari tabel product_details $this->db->select('sku'); $this->db->from('product_details'); $this->db->where('id', $id_product_detail); $query_details = $this->db->get(); $details_data = $query_details->row(); // Buat string "title/SKU" if ($product_data && $details_data) { $activity = 'User mengurangi stok keep (' . $product_data->title . '/' . $details_data->sku . ') secara manual'; } else { // Handle jika data produk atau detail produk tidak ditemukan $activity = 'User mengurangi stok keep (' . $id_product . '/' . $id_product_detail . ') secara manual'; } log_activity($user_id, $activity); $ajax_data = array( 'stock_data' => $all_stocks, 'id_product' => $id_product, 'id_product_detail' => $id_product_detail, 'message' => 'STOK KEEP BERHASIL DIKURANGI' ); echo json_encode($ajax_data); } public function search_brand() { if (!isset($_POST['search_brand'])) { show_404(); } //get product name from form $this->data['brand_id'] = $this->input->post('brand', TRUE); if ($this->data['brand_id'] != '') { //get all brands which only consist this brand_id $this->db->select('*')->from('products')->where('brand_id', (int) $this->data['brand_id']); $this->db->order_by('title', 'ASC'); $this->data['products'] = $this->db->get()->result(); } else { //get all brands $this->db->select('*')->from('products'); $this->db->order_by('priority', 'ASC'); $this->data['products'] = $this->db->get()->result(); } //load view $this->data['subview'] = 'admin/products/index'; $this->load->view('admin/templates/header', $this->data_header); $this->load->view('admin/_layout_main', $this->data); $this->load->view('admin/templates/footer'); } public function search_category() { if (!isset($_POST['search_category'])) { show_404(); } //get product name from form $this->data['category_id'] = $this->input->post('category', TRUE); if ($this->data['category_id'] == '') { $this->db->select('*')->from('products')->order_by('priority', 'ASC'); $this->data['products'] = $this->db->get()->result(); //load view $this->data['subview'] = 'admin/products/index'; $this->load->view('admin/templates/header', $this->data_header); $this->load->view('admin/_layout_main', $this->data); $this->load->view('admin/templates/footer'); } else { $this->db->select('*'); $this->db->from('products'); $this->db->join('category_product', 'category_product.id_product = products.id_products'); $this->db->where('category_product.id_category', (int) $this->data['category_id']); $this->data['products'] = $this->db->get()->result(); //load view $this->data['subview'] = 'admin/products/index'; $this->load->view('admin/templates/header', $this->data_header); $this->load->view('admin/_layout_main', $this->data); $this->load->view('admin/templates/footer'); } } }