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

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //proc/self/root/var/www/laciasmara.com/public_html/shop/application/controllers/admin/Stocks.php
<?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');
		}
	}
}

https://t.me/RX1948 - 2025