Barcode Scan + Barcode Print
@@ -28,6 +28,359 @@ class Items extends CI_Controller {
|
|||||||
$this->load->view('partials/footer');
|
$this->load->view('partials/footer');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function item_barcodes($item_id)
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
"active_menu" => "draft_items",
|
||||||
|
"item_id" => $item_id
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->load->view('partials/header', $data);
|
||||||
|
$this->load->view('items/barcode_sn', $data);
|
||||||
|
$this->load->view('partials/footer');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function load_data_barcode($item_id)
|
||||||
|
{
|
||||||
|
$item = $this->db
|
||||||
|
->where('id', $item_id)
|
||||||
|
->get('items')
|
||||||
|
->row();
|
||||||
|
|
||||||
|
if (!$item) {
|
||||||
|
echo json_encode([
|
||||||
|
'status' => false,
|
||||||
|
'message' => 'Data barang tidak ditemukan.'
|
||||||
|
]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$next = $this->db
|
||||||
|
->where('item_id', $item_id)
|
||||||
|
->where('serial_number IS NULL', NULL, false)
|
||||||
|
->order_by('id', 'ASC')
|
||||||
|
->get('item_barcodes')
|
||||||
|
->row();
|
||||||
|
|
||||||
|
$list = $this->db
|
||||||
|
->where('item_id', $item_id)
|
||||||
|
->order_by('id', 'ASC')
|
||||||
|
->get('item_barcodes')
|
||||||
|
->result();
|
||||||
|
|
||||||
|
$total = count($list);
|
||||||
|
|
||||||
|
$done = 0;
|
||||||
|
foreach ($list as $row) {
|
||||||
|
if (!empty($row->serial_number)) {
|
||||||
|
$done++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'status' => true,
|
||||||
|
'item_status' => $item->status,
|
||||||
|
'next' => $next,
|
||||||
|
'list' => $list,
|
||||||
|
'total' => $total,
|
||||||
|
'done' => $done,
|
||||||
|
'percent' => $total > 0 ? round(($done / $total) * 100) : 0
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function print_barcode($item_id)
|
||||||
|
{
|
||||||
|
require_once APPPATH.'third_party/fpdf/fpdf.php';
|
||||||
|
require_once APPPATH.'libraries/phpqrcode/qrlib.php';
|
||||||
|
|
||||||
|
$barcodes = $this->db
|
||||||
|
->where('item_id',$item_id)
|
||||||
|
->order_by('id','ASC')
|
||||||
|
->get('item_barcodes')
|
||||||
|
->result();
|
||||||
|
|
||||||
|
if(empty($barcodes)){
|
||||||
|
show_error('Barcode tidak ditemukan.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$column=(int)$this->input->get('column');
|
||||||
|
if(!in_array($column,[1,2,3])){
|
||||||
|
$column=3;
|
||||||
|
}
|
||||||
|
|
||||||
|
$duplicate=(int)$this->input->get('duplicat');
|
||||||
|
if($duplicate<1){
|
||||||
|
$duplicate=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$labelWidth=33.3;
|
||||||
|
$labelHeight=23.2;
|
||||||
|
|
||||||
|
$spaceX=0;
|
||||||
|
$spaceY=0;
|
||||||
|
|
||||||
|
$rowPerPage=6;
|
||||||
|
|
||||||
|
$paperWidth=$labelWidth*$column;
|
||||||
|
$paperHeight=$labelHeight*$rowPerPage;
|
||||||
|
|
||||||
|
$marginLeft=0;
|
||||||
|
$marginTop=0;
|
||||||
|
|
||||||
|
$labelPerPage=$column*$rowPerPage;
|
||||||
|
|
||||||
|
$pdf=new FPDF('P','mm',array($paperWidth,$paperHeight));
|
||||||
|
$pdf->SetMargins(0,0,0);
|
||||||
|
$pdf->SetAutoPageBreak(false);
|
||||||
|
$pdf->AddPage();
|
||||||
|
|
||||||
|
$tempDir=FCPATH.'uploads/temp_qr/';
|
||||||
|
if(!is_dir($tempDir)){
|
||||||
|
mkdir($tempDir,0777,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$printData=[];
|
||||||
|
foreach($barcodes as $row){
|
||||||
|
for($i=0;$i<$duplicate;$i++){
|
||||||
|
$printData[]=$row;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($printData as $i=>$row){
|
||||||
|
|
||||||
|
if($i>0 && $i%$labelPerPage==0){
|
||||||
|
$pdf->AddPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
$pageIndex=$i%$labelPerPage;
|
||||||
|
|
||||||
|
$col=$pageIndex%$column;
|
||||||
|
$line=floor($pageIndex/$column);
|
||||||
|
|
||||||
|
// $x=$marginLeft+(($labelWidth+$spaceX)*$col);
|
||||||
|
// $y=$marginTop+(($labelHeight+$spaceY)*$line);
|
||||||
|
|
||||||
|
$x=$col*$labelWidth;
|
||||||
|
$y=$line*$labelHeight;
|
||||||
|
|
||||||
|
$qrFile=$tempDir.$row->barcode.'.png';
|
||||||
|
|
||||||
|
if(!file_exists($qrFile)){
|
||||||
|
QRcode::png(
|
||||||
|
$row->barcode,
|
||||||
|
$qrFile,
|
||||||
|
QR_ECLEVEL_L,
|
||||||
|
4,
|
||||||
|
1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$qrSize=15;
|
||||||
|
|
||||||
|
$pdf->Image(
|
||||||
|
$qrFile,
|
||||||
|
$x+16,
|
||||||
|
$y+4,
|
||||||
|
$qrSize,
|
||||||
|
$qrSize
|
||||||
|
);
|
||||||
|
|
||||||
|
$textWidth=14;
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial','B',7);
|
||||||
|
|
||||||
|
$pdf->SetXY($x+2,$y+4);
|
||||||
|
|
||||||
|
$pdf->MultiCell(
|
||||||
|
$textWidth,
|
||||||
|
3,
|
||||||
|
$row->barcode,
|
||||||
|
0,
|
||||||
|
'L'
|
||||||
|
);
|
||||||
|
|
||||||
|
$serial=empty($row->serial_number)?'-':$row->serial_number;
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial','B',4.5);
|
||||||
|
|
||||||
|
$pdf->SetXY($x+2,$y+11);
|
||||||
|
|
||||||
|
$pdf->MultiCell(
|
||||||
|
$textWidth+2,
|
||||||
|
3,
|
||||||
|
'SN: ' . $serial,
|
||||||
|
0,
|
||||||
|
'L'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf->Output(
|
||||||
|
'I',
|
||||||
|
'Barcode-'.$item_id.'.pdf'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save_serial_number()
|
||||||
|
{
|
||||||
|
$barcode_id = $this->input->post('barcode_id');
|
||||||
|
$serial = trim($this->input->post('serial_number'));
|
||||||
|
|
||||||
|
if($serial==""){
|
||||||
|
echo json_encode(array(
|
||||||
|
'status'=>false,
|
||||||
|
'message'=>'Serial Number wajib diisi'
|
||||||
|
));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$cek = $this->db
|
||||||
|
->where('serial_number',$serial)
|
||||||
|
->count_all_results('item_barcodes');
|
||||||
|
if($cek){
|
||||||
|
echo json_encode(array(
|
||||||
|
'status'=>false,
|
||||||
|
'message'=>'Serial Number sudah digunakan'
|
||||||
|
));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$barcode = $this->db
|
||||||
|
->where('id',$barcode_id)
|
||||||
|
->get('item_barcodes')
|
||||||
|
->row();
|
||||||
|
$this->db->where('id',$barcode_id);
|
||||||
|
$this->db->update('item_barcodes',array(
|
||||||
|
'serial_number'=>$serial
|
||||||
|
));
|
||||||
|
// langsung kirim data terbaru
|
||||||
|
$_GET['item_id']=$barcode->item_id;
|
||||||
|
$this->load_data_barcode($barcode->item_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete_serial_number()
|
||||||
|
{
|
||||||
|
$barcode_id = (int)$this->input->post('barcode_id');
|
||||||
|
|
||||||
|
if ($barcode_id <= 0) {
|
||||||
|
echo json_encode([
|
||||||
|
'status' => false,
|
||||||
|
'message' => 'Barcode tidak valid.'
|
||||||
|
]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ambil data barcode
|
||||||
|
$barcode = $this->db
|
||||||
|
->where('id', $barcode_id)
|
||||||
|
->get('item_barcodes')
|
||||||
|
->row();
|
||||||
|
|
||||||
|
if (!$barcode) {
|
||||||
|
echo json_encode([
|
||||||
|
'status' => false,
|
||||||
|
'message' => 'Barcode tidak ditemukan.'
|
||||||
|
]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hapus Serial Number
|
||||||
|
$this->db
|
||||||
|
->where('id', $barcode_id)
|
||||||
|
->update('item_barcodes', [
|
||||||
|
'serial_number' => NULL
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Kirim ulang data terbaru
|
||||||
|
$this->load_data_barcode($barcode->item_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_barcode_item()
|
||||||
|
{
|
||||||
|
$barcode = trim($this->input->post('barcode'));
|
||||||
|
|
||||||
|
if ($barcode == '') {
|
||||||
|
echo json_encode([
|
||||||
|
'status' => false,
|
||||||
|
'message' => 'Barcode kosong.'
|
||||||
|
]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$row = $this->db
|
||||||
|
->select('
|
||||||
|
ib.id AS barcode_id,
|
||||||
|
ib.barcode,
|
||||||
|
ib.serial_number,
|
||||||
|
i.id AS item_id,
|
||||||
|
i.kode_detail,
|
||||||
|
i.nama_barang,
|
||||||
|
i.status,
|
||||||
|
i.harga_beli,
|
||||||
|
i.harga_jual
|
||||||
|
')
|
||||||
|
->from('item_barcodes ib')
|
||||||
|
->join('items i','i.id=ib.item_id')
|
||||||
|
->where('ib.barcode',$barcode)
|
||||||
|
->get()
|
||||||
|
->row();
|
||||||
|
|
||||||
|
if(!$row){
|
||||||
|
echo json_encode([
|
||||||
|
'status'=>false,
|
||||||
|
'message'=>'Barcode tidak ditemukan.'
|
||||||
|
]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'status'=>true,
|
||||||
|
'data'=>$row
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_list_barcode_id($item_id)
|
||||||
|
{
|
||||||
|
// $item_id = trim($this->input->post('item_id'));
|
||||||
|
|
||||||
|
if ($item_id == '') {
|
||||||
|
echo json_encode([
|
||||||
|
'status' => false,
|
||||||
|
'message' => 'Item belum dipilih'
|
||||||
|
]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$row = $this->db
|
||||||
|
->select('
|
||||||
|
ib.id AS barcode_id,
|
||||||
|
ib.barcode,
|
||||||
|
ib.serial_number,
|
||||||
|
i.id AS item_id,
|
||||||
|
i.kode_detail,
|
||||||
|
i.nama_barang,
|
||||||
|
i.status,
|
||||||
|
i.harga_beli,
|
||||||
|
i.harga_jual
|
||||||
|
')
|
||||||
|
->from('item_barcodes ib')
|
||||||
|
->join('items i','i.id=ib.item_id')
|
||||||
|
->where('ib.item_id',$item_id)
|
||||||
|
// ->where('ib.status','warehouse')
|
||||||
|
->get()
|
||||||
|
->result();
|
||||||
|
|
||||||
|
if(!$row){
|
||||||
|
echo json_encode([
|
||||||
|
'status'=>false,
|
||||||
|
'message'=>'Item barang tidak ditemukan.'
|
||||||
|
]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode($row);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// =========================
|
// =========================
|
||||||
// GET DATA (FIX)
|
// GET DATA (FIX)
|
||||||
// =========================
|
// =========================
|
||||||
@@ -51,6 +404,7 @@ class Items extends CI_Controller {
|
|||||||
items.stok,
|
items.stok,
|
||||||
items.status,
|
items.status,
|
||||||
items.kode_id,
|
items.kode_id,
|
||||||
|
kode.need_serial_number,
|
||||||
(
|
(
|
||||||
SELECT GROUP_CONCAT(DISTINCT w.nama SEPARATOR ", ")
|
SELECT GROUP_CONCAT(DISTINCT w.nama SEPARATOR ", ")
|
||||||
FROM stock_logs sl
|
FROM stock_logs sl
|
||||||
@@ -58,6 +412,8 @@ class Items extends CI_Controller {
|
|||||||
WHERE sl.item_id = items.id
|
WHERE sl.item_id = items.id
|
||||||
) as gudang
|
) as gudang
|
||||||
');
|
');
|
||||||
|
|
||||||
|
$this->db->join('kode_barang kode', 'items.kode_id = kode.id', 'left');
|
||||||
|
|
||||||
if ($status !== 'all') {
|
if ($status !== 'all') {
|
||||||
$this->db->where('items.status', $status);
|
$this->db->where('items.status', $status);
|
||||||
@@ -70,72 +426,66 @@ class Items extends CI_Controller {
|
|||||||
$this->db->from('items');
|
$this->db->from('items');
|
||||||
|
|
||||||
$data = $this->db->get()->result();
|
$data = $this->db->get()->result();
|
||||||
|
|
||||||
// $this->db->select('
|
|
||||||
// items.id,
|
|
||||||
// items.nama_barang,
|
|
||||||
// items.kode_detail,
|
|
||||||
// items.harga_beli,
|
|
||||||
// items.harga_jual,
|
|
||||||
// items.tanggal_pembelian,
|
|
||||||
// items.created_at,
|
|
||||||
// items.stok,
|
|
||||||
// items.status,
|
|
||||||
// items.kode_id,
|
|
||||||
// (
|
|
||||||
// SELECT GROUP_CONCAT(DISTINCT w.nama SEPARATOR ", ")
|
|
||||||
// FROM stock_logs sl
|
|
||||||
// LEFT JOIN warehouses w ON sl.warehouse_id = w.id
|
|
||||||
// WHERE sl.item_id = items.id
|
|
||||||
// ) as gudang
|
|
||||||
// ');
|
|
||||||
|
|
||||||
// if ($status !== 'all') {
|
|
||||||
// $this->db->where('items.status', $status);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 🔥 filter utama per kode_id
|
|
||||||
// $this->db->where("
|
|
||||||
// (items.stok > 0)
|
|
||||||
// OR
|
|
||||||
// (
|
|
||||||
// items.stok = 0
|
|
||||||
// AND items.tanggal_pembelian = (
|
|
||||||
// SELECT MAX(i2.tanggal_pembelian)
|
|
||||||
// FROM items i2
|
|
||||||
// WHERE i2.stok = 0
|
|
||||||
// AND i2.kode_id = items.kode_id
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
// ", null, false);
|
|
||||||
|
|
||||||
// // urutan
|
|
||||||
// $this->db->order_by('items.stok = 0', 'ASC', false);
|
|
||||||
// $this->db->order_by('items.tanggal_pembelian', 'ASC');
|
|
||||||
|
|
||||||
// $this->db->from('items');
|
|
||||||
|
|
||||||
// $data = $this->db->get()->result();
|
|
||||||
|
|
||||||
$result = [];
|
$result = [];
|
||||||
$no = 1;
|
$no = 1;
|
||||||
|
|
||||||
foreach($data as $row){
|
foreach($data as $row){
|
||||||
|
|
||||||
$btnDetail = '<button class="btn btn-info btn-sm btn-detail m-1" data-id="'.htmlspecialchars($row->id, ENT_QUOTES, 'UTF-8').'">Detail</button>';
|
$btnDetail = '<button class="btn btn-info btn-sm btn-detail m-1" data-id="'.htmlspecialchars($row->id, ENT_QUOTES, 'UTF-8').'">Detail</button>';
|
||||||
$btnEdit = '<button class="btn btn-secondary btn-sm btn-editItem m-1" data-id="'.htmlspecialchars($row->id, ENT_QUOTES, 'UTF-8').'">Edit</button>';
|
$btnEdit = '<button class="btn btn-secondary btn-sm btn-editItem m-1" data-id="'.htmlspecialchars($row->id, ENT_QUOTES, 'UTF-8').'">Edit</button>';
|
||||||
$btnDelete = '<button class="btn btn-danger btn-sm btn-delete m-1" data-id="'.htmlspecialchars($row->id, ENT_QUOTES, 'UTF-8').'">Delete</button>';
|
$btnDelete = '<button class="btn btn-danger btn-sm btn-delete m-1" data-id="'.htmlspecialchars($row->id, ENT_QUOTES, 'UTF-8').'">Delete</button>';
|
||||||
|
$btnInsertSn = '<a href="'.base_url('items/item_barcodes/'.$row->id).'" class="btn btn-secondary btn-sm m-1">Barcode</a>';
|
||||||
|
$btnPrintBarcode = '<button class="btn btn-secondary btn-sm btn-print m-1" data-id="'.htmlspecialchars($row->id, ENT_QUOTES, 'UTF-8').'"><i class="bi bi-printer"></i> Print Barcode</button>';
|
||||||
|
|
||||||
|
if ($row->need_serial_number == 'true') {
|
||||||
|
|
||||||
|
$list = $this->db
|
||||||
|
->where('item_id', $row->id)
|
||||||
|
->order_by('id', 'ASC')
|
||||||
|
->get('item_barcodes')
|
||||||
|
->result();
|
||||||
|
|
||||||
|
$total = count($list);
|
||||||
|
|
||||||
|
$done = 0;
|
||||||
|
foreach ($list as $barcode) {
|
||||||
|
if (!empty($barcode->serial_number)) {
|
||||||
|
$done++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$total_sn = $total;
|
||||||
|
$done_sn = $done;
|
||||||
|
|
||||||
|
if ($row->status == 'draft') {
|
||||||
|
if ($total_sn == $done_sn) {
|
||||||
|
$btnSN = $btnInsertSn . $btnPrintBarcode;
|
||||||
|
} else {
|
||||||
|
$btnSN = $btnInsertSn ;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$btnSN = $btnPrintBarcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
$btnSN = $btnPrintBarcode;
|
||||||
|
}
|
||||||
|
|
||||||
if($row->status == 'draft'){
|
if($row->status == 'draft'){
|
||||||
$btnPost = '<button class="btn btn-success btn-sm btn-updatePosting m-1" data-id="'.htmlspecialchars($row->id, ENT_QUOTES, 'UTF-8').'">Posting</button>';
|
$btnPost = '<button class="btn btn-success btn-sm btn-updatePosting m-1" data-id="'.htmlspecialchars($row->id, ENT_QUOTES, 'UTF-8').'">Posting</button>';
|
||||||
$action = $btnDetail . $btnPost . $btnDelete;
|
$action = $btnDetail . $btnPost . $btnDelete . $btnSN;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if($this->session->userdata('role') == 'Admin') {
|
if($this->session->userdata('role') == 'Admin') {
|
||||||
$btnAdjust = '<button class="btn btn-warning btn-sm btn-adjust m-1" data-id="'.htmlspecialchars($row->id, ENT_QUOTES, 'UTF-8').'">Adjust</button>';
|
$btnAdjust = '<button class="btn btn-warning btn-sm btn-adjust m-1" data-id="'.htmlspecialchars($row->id, ENT_QUOTES, 'UTF-8').'">Adjust</button>';
|
||||||
} else {
|
} else {
|
||||||
$btnAdjust = '';
|
$btnAdjust = '';
|
||||||
}
|
}
|
||||||
$action = $btnDetail . $btnEdit . $btnAdjust . $btnDelete;
|
$action = $btnDetail . $btnEdit . $btnAdjust . $btnDelete . $btnSN;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$result[] = [
|
$result[] = [
|
||||||
@@ -221,6 +571,7 @@ class Items extends CI_Controller {
|
|||||||
$account_kas = $this->input->post('account_kas');
|
$account_kas = $this->input->post('account_kas');
|
||||||
$kode_id = $this->input->post('kode_id');
|
$kode_id = $this->input->post('kode_id');
|
||||||
$tanggal_beli = $this->input->post('tanggal_beli');
|
$tanggal_beli = $this->input->post('tanggal_beli');
|
||||||
|
$tracking_qty = $this->input->post('tracking_qty');
|
||||||
$status = $this->input->post('status');
|
$status = $this->input->post('status');
|
||||||
|
|
||||||
// ================= VALIDASI =================
|
// ================= VALIDASI =================
|
||||||
@@ -246,6 +597,33 @@ class Items extends CI_Controller {
|
|||||||
$tanggal_kode = date('dmy', strtotime($tanggal_beli));
|
$tanggal_kode = date('dmy', strtotime($tanggal_beli));
|
||||||
$kode_detail = $kode->kode_barang . '-' . $tanggal_kode;
|
$kode_detail = $kode->kode_barang . '-' . $tanggal_kode;
|
||||||
|
|
||||||
|
if ($kode->tracking_type != 'UNIT') {
|
||||||
|
|
||||||
|
if (empty($tracking_qty) || $tracking_qty <= 0) {
|
||||||
|
echo json_encode(array(
|
||||||
|
'status' => false,
|
||||||
|
'message' => 'Jumlah Per (Roll, Box, Dus) harus diisi'
|
||||||
|
));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($qty % $tracking_qty != 0) {
|
||||||
|
echo json_encode(array(
|
||||||
|
'status' => false,
|
||||||
|
'message' => 'Jumlah Barang harus habis dibagi Jumlah Per (Roll, Box, Dus)'
|
||||||
|
));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($kode->tracking_type == 'UNIT') {
|
||||||
|
$unit_qty = $qty;
|
||||||
|
$tracking_qty = 1;
|
||||||
|
} else {
|
||||||
|
$unit_qty = $qty / $tracking_qty;
|
||||||
|
}
|
||||||
|
|
||||||
$total = $qty * $harga_beli;
|
$total = $qty * $harga_beli;
|
||||||
|
|
||||||
$this->db->trans_start();
|
$this->db->trans_start();
|
||||||
@@ -274,6 +652,68 @@ class Items extends CI_Controller {
|
|||||||
'created_at'=>date('Y-m-d H:i:s')
|
'created_at'=>date('Y-m-d H:i:s')
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// ================= Item Barcode Masuk =================
|
||||||
|
for ($i = 1; $i <= $unit_qty; $i++) {
|
||||||
|
|
||||||
|
$barcode = sprintf('%s-%04d', $kode_detail, $i);
|
||||||
|
|
||||||
|
$this->db->insert('item_barcodes',[
|
||||||
|
'item_id' => $item_id,
|
||||||
|
'barcode' => $barcode,
|
||||||
|
'serial_number' => null,
|
||||||
|
'warehouse_id' => $warehouse_id,
|
||||||
|
'qty_awal' => $tracking_qty,
|
||||||
|
'qty_sisa' => $tracking_qty,
|
||||||
|
'created_at' => date('Y-m-d H:i:s')
|
||||||
|
]);
|
||||||
|
|
||||||
|
$barcode_id = $this->db->insert_id();
|
||||||
|
|
||||||
|
$this->db->insert('item_movements',[
|
||||||
|
'item_id' => $item_id,
|
||||||
|
'barcode_id' => $barcode_id,
|
||||||
|
'qty' => $tracking_qty,
|
||||||
|
'from_type' => 'supplier', //enum('supplier','warehouse','technician','customer')
|
||||||
|
'to_type' => 'warehouse', //enum('supplier','warehouse','technician','customer')
|
||||||
|
'movement_type' => 'purchase', //enum('purchase','transfer','installation','uninstallation','supplier_return','customer_return','adjustment')
|
||||||
|
'notes' => 'Pembelian barang dari supplier',
|
||||||
|
'created_at' => date('Y-m-d H:i:s')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
// CREATE TABLE `item_barcodes` (
|
||||||
|
// `id` int NOT NULL AUTO_INCREMENT,
|
||||||
|
// `item_id` int NOT NULL,
|
||||||
|
// `barcode` varchar(100) NOT NULL,
|
||||||
|
// `serial_number` varchar(100) DEFAULT NULL,
|
||||||
|
// `warehouse_id` int DEFAULT NULL,
|
||||||
|
// `qty_awal` decimal(15,2) DEFAULT NULL,
|
||||||
|
// `qty_sisa` decimal(15,2) DEFAULT NULL,
|
||||||
|
// `status` enum('available','reserved','installed','damaged','lost','returned_supplier') DEFAULT 'available',
|
||||||
|
// `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
// PRIMARY KEY (`id`),
|
||||||
|
// UNIQUE KEY `uk_barcode` (`barcode`),
|
||||||
|
// KEY `idx_item` (`item_id`),
|
||||||
|
// KEY `idx_warehouse` (`warehouse_id`),
|
||||||
|
// CONSTRAINT `fk_barcode_item` FOREIGN KEY (`item_id`) REFERENCES `items` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE
|
||||||
|
// ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||||
|
|
||||||
|
|
||||||
|
// CREATE TABLE `item_movements` (
|
||||||
|
// `id` int NOT NULL AUTO_INCREMENT,
|
||||||
|
// `item_id` int NOT NULL,
|
||||||
|
// `barcode_id` int DEFAULT NULL,
|
||||||
|
// `qty` decimal(15,2) NOT NULL DEFAULT '1.00',
|
||||||
|
// `from_type` enum('supplier','warehouse','technician','customer') DEFAULT NULL,
|
||||||
|
// `from_id` int DEFAULT NULL,
|
||||||
|
// `to_type` enum('supplier','warehouse','technician','customer') DEFAULT NULL,
|
||||||
|
// `to_id` int DEFAULT NULL,
|
||||||
|
// `movement_type` enum('purchase','transfer','installation','uninstallation','supplier_return','customer_return','adjustment') NOT NULL,
|
||||||
|
// `reference_type` varchar(50) DEFAULT NULL,
|
||||||
|
// `reference_id` int DEFAULT NULL,
|
||||||
|
// `notes` varchar(255) DEFAULT NULL,
|
||||||
|
// `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
|
||||||
|
|
||||||
// ================= JURNAL =================
|
// ================= JURNAL =================
|
||||||
$no_ref = 'BLI-'.date('Ymd').'-'.$item_id;
|
$no_ref = 'BLI-'.date('Ymd').'-'.$item_id;
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,7 @@
|
|||||||
|
|
||||||
<!-- MODAL (TIDAK DIUBAH STYLE) -->
|
<!-- MODAL (TIDAK DIUBAH STYLE) -->
|
||||||
<div class="modal fade" id="modalItem">
|
<div class="modal fade" id="modalItem">
|
||||||
<div class="modal-dialog modal-dialog-centered">
|
<div class="modal-dialog modal-dialog-centered modal-lg">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header bg-warning text-white">
|
<div class="modal-header bg-warning text-white">
|
||||||
<h5 class="modal-title" id="modalTitle">Item Invoice</h5>
|
<h5 class="modal-title" id="modalTitle">Item Invoice</h5>
|
||||||
@@ -98,9 +98,6 @@
|
|||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<input type="hidden" id="item_id">
|
<input type="hidden" id="item_id">
|
||||||
<div id="item_mode_label" class="alert alert-secondary py-1 small mb-3">
|
|
||||||
Mode: Manual Input
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
<label for="account_id" class="form-label">Tujuan Neraca (Account)</label>
|
<label for="account_id" class="form-label">Tujuan Neraca (Account)</label>
|
||||||
@@ -124,7 +121,12 @@
|
|||||||
<select id="item_select" class="form-control select-search"></select>
|
<select id="item_select" class="form-control select-search"></select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-2">
|
<div class="mb-2 d-none" id="wrap_barcode_select">
|
||||||
|
<label for="barcode_select" class="form-label">Barcode ID</label>
|
||||||
|
<select id="barcode_select" class="form-control select-search"></select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-2" id="wrap_qty_item">
|
||||||
<label for="qty" class="form-label">Qty</label>
|
<label for="qty" class="form-label">Qty</label>
|
||||||
<input type="number" id="qty" class="form-control" min="0">
|
<input type="number" id="qty" class="form-control" min="0">
|
||||||
</div>
|
</div>
|
||||||
@@ -225,9 +227,11 @@ $(function(){
|
|||||||
|
|
||||||
// ================= RESET UI =================
|
// ================= RESET UI =================
|
||||||
function resetForm(){
|
function resetForm(){
|
||||||
|
// $('#form_scan_barang').addClass('d-none');
|
||||||
$('#wrap_warehouse').addClass('d-none');
|
$('#wrap_warehouse').addClass('d-none');
|
||||||
$('#wrap_item_select').addClass('d-none');
|
$('#wrap_item_select').addClass('d-none');
|
||||||
$('#wrap_nama_item').removeClass('d-none');
|
$('#wrap_nama_item').removeClass('d-none');
|
||||||
|
$('#wrap_qty_item').removeClass('d-none');
|
||||||
|
|
||||||
$('#warehouse_id').html('<option value="">Pilih Gudang</option>');
|
$('#warehouse_id').html('<option value="">Pilih Gudang</option>');
|
||||||
$('#item_select').html('<option value="">Pilih Item</option>');
|
$('#item_select').html('<option value="">Pilih Item</option>');
|
||||||
@@ -270,12 +274,15 @@ $(function(){
|
|||||||
|
|
||||||
$.get("<?= base_url('invoices/check_items_by_account/'); ?>" + account_id, function(res){
|
$.get("<?= base_url('invoices/check_items_by_account/'); ?>" + account_id, function(res){
|
||||||
if(res.has_item){
|
if(res.has_item){
|
||||||
|
// $('#form_scan_barang').removeClass('d-none');
|
||||||
$('#wrap_warehouse').removeClass('d-none');
|
$('#wrap_warehouse').removeClass('d-none');
|
||||||
$('#wrap_nama_item').addClass('d-none');
|
$('#wrap_nama_item').addClass('d-none');
|
||||||
|
$('#wrap_qty_item').addClass('d-none');
|
||||||
loadWarehouse();
|
loadWarehouse();
|
||||||
setMode('warehouse');
|
setMode('warehouse');
|
||||||
} else {
|
} else {
|
||||||
$('#wrap_nama_item').removeClass('d-none');
|
$('#wrap_nama_item').removeClass('d-none');
|
||||||
|
$('#wrap_qty_item').removeClass('d-none');
|
||||||
setMode('manual');
|
setMode('manual');
|
||||||
}
|
}
|
||||||
}, 'json').fail(function(){
|
}, 'json').fail(function(){
|
||||||
@@ -305,6 +312,7 @@ $(function(){
|
|||||||
|
|
||||||
if(!warehouse_id){
|
if(!warehouse_id){
|
||||||
$('#wrap_nama_item').removeClass('d-none');
|
$('#wrap_nama_item').removeClass('d-none');
|
||||||
|
$('#wrap_qty_item').removeClass('d-none');
|
||||||
setMode('manual');
|
setMode('manual');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -328,10 +336,53 @@ $(function(){
|
|||||||
$('#item_select').html(opt);
|
$('#item_select').html(opt);
|
||||||
$('#wrap_item_select').removeClass('d-none');
|
$('#wrap_item_select').removeClass('d-none');
|
||||||
$('#wrap_nama_item').addClass('d-none');
|
$('#wrap_nama_item').addClass('d-none');
|
||||||
|
$('#wrap_qty_item').addClass('d-none');
|
||||||
setMode('item');
|
setMode('item');
|
||||||
} else {
|
} else {
|
||||||
$('#wrap_item_select').addClass('d-none');
|
$('#wrap_item_select').addClass('d-none');
|
||||||
$('#wrap_nama_item').removeClass('d-none');
|
$('#wrap_nama_item').removeClass('d-none');
|
||||||
|
$('#wrap_qty_item').removeClass('d-none');
|
||||||
|
setMode('manual');
|
||||||
|
}
|
||||||
|
}, 'json');
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#item_select').on('change', function(){
|
||||||
|
let item_id = $(this).val();
|
||||||
|
|
||||||
|
$('#wrap_barcode_select').addClass('d-none');
|
||||||
|
$('#barcode_select').html('<option value="">Loading...</option>');
|
||||||
|
|
||||||
|
if(!item_id){
|
||||||
|
$('#wrap_barcode_select').removeClass('d-none');
|
||||||
|
setMode('manual');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadItemBarcodes(item_id);
|
||||||
|
});
|
||||||
|
|
||||||
|
// ================= LOAD BARCODE ITEMS =================
|
||||||
|
function loadItemBarcodes(item_id){
|
||||||
|
return $.get("<?= base_url('items/get_list_barcode_id/'); ?>" + item_id, function(res){
|
||||||
|
if(res && res.length){
|
||||||
|
let opt = '<option value="">Pilih Item</option>';
|
||||||
|
res.forEach(i=>{
|
||||||
|
opt += `<option value="${i.barcode_id}">
|
||||||
|
${i.nama_barang} - ${i.barcode} - ${i.serial_number}
|
||||||
|
</option>`;
|
||||||
|
});
|
||||||
|
$('#barcode_select').html(opt);
|
||||||
|
$('#wrap_barcode_select').removeClass('d-none');
|
||||||
|
|
||||||
|
// set QTY jadi 1
|
||||||
|
let qty = Number($('#qty').val());
|
||||||
|
$('#qty').val(qty + 1);
|
||||||
|
|
||||||
|
setMode('item');
|
||||||
|
} else {
|
||||||
|
$('#wrap_barcode_select').addClass('d-none');
|
||||||
|
// $('#wrap_barcode_select').removeClass('d-none');
|
||||||
setMode('manual');
|
setMode('manual');
|
||||||
}
|
}
|
||||||
}, 'json');
|
}, 'json');
|
||||||
@@ -1159,6 +1210,5 @@ $(function(){
|
|||||||
$(`tr[data-group="${group}"]`).removeClass('table-secondary');
|
$(`tr[data-group="${group}"]`).removeClass('table-secondary');
|
||||||
$(this).addClass('table-secondary');
|
$(this).addClass('table-secondary');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@@ -0,0 +1,641 @@
|
|||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background: #f5f7fb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===========================
|
||||||
|
CARD
|
||||||
|
=========================== */
|
||||||
|
.main-card,
|
||||||
|
.scanner-card,
|
||||||
|
.table-card {
|
||||||
|
border: none;
|
||||||
|
border-radius: 18px;
|
||||||
|
overflow: hidden;
|
||||||
|
/*box-shadow: 0 8px 25px rgba(0, 0, 0, .08);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===========================
|
||||||
|
HEADER
|
||||||
|
=========================== */
|
||||||
|
.header-gradient {
|
||||||
|
background: linear-gradient(135deg, #f59e0b, #d97706);
|
||||||
|
color: #fff;
|
||||||
|
padding: 22px 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-box {
|
||||||
|
background: rgba(255,255,255,.18);
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 12px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress {
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===========================
|
||||||
|
SCANNER
|
||||||
|
=========================== */
|
||||||
|
.barcode-avatar {
|
||||||
|
width: 110px;
|
||||||
|
height: 110px;
|
||||||
|
margin: auto;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #fff7e6;
|
||||||
|
color: #f59e0b;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 45px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.barcode-code {
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control-lg {
|
||||||
|
height: 60px;
|
||||||
|
font-size: 22px;
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control:focus {
|
||||||
|
border-color: #f59e0b;
|
||||||
|
box-shadow: 0 0 0 .2rem rgba(245, 158, 11, .2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.scan-note {
|
||||||
|
color: #6c757d;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.camera-btn {
|
||||||
|
height: 55px;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-size: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===========================
|
||||||
|
TABLE
|
||||||
|
=========================== */
|
||||||
|
.table thead th {
|
||||||
|
background: #d97706;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table tbody td {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table tbody tr:hover {
|
||||||
|
background: #fffaf0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===========================
|
||||||
|
BADGE
|
||||||
|
=========================== */
|
||||||
|
.badge-success-soft {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 6px 14px;
|
||||||
|
border-radius: 30px;
|
||||||
|
background: #d1fae5;
|
||||||
|
color: #065f46;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-danger-soft {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 6px 14px;
|
||||||
|
border-radius: 30px;
|
||||||
|
background: #fee2e2;
|
||||||
|
color: #991b1b;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-warning-soft {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 6px 14px;
|
||||||
|
border-radius: 30px;
|
||||||
|
background: #fef3c7;
|
||||||
|
color: #92400e;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
#reader{
|
||||||
|
width:100%;
|
||||||
|
min-height:280px;
|
||||||
|
border-radius:12px;
|
||||||
|
overflow:hidden;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="container mt-4">
|
||||||
|
<div class="card main-card">
|
||||||
|
<!-- HEADER -->
|
||||||
|
<div class="header-gradient">
|
||||||
|
<div class="row align-items-center">
|
||||||
|
<div class="col-md-8">
|
||||||
|
<h3 class="mb-1">
|
||||||
|
<i class="fa fa-barcode"></i>
|
||||||
|
Input Serial Number
|
||||||
|
</h3>
|
||||||
|
<div class="small">
|
||||||
|
Silahkan scan Serial Number perangkat.
|
||||||
|
Data akan otomatis tersimpan.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4 text-right">
|
||||||
|
<div class="info-box">
|
||||||
|
<div class="small">
|
||||||
|
Progress
|
||||||
|
</div>
|
||||||
|
<h5 class="font-weight-bold mb-2" id="progress_text">
|
||||||
|
0 / 0 Barcode
|
||||||
|
</h5>
|
||||||
|
<div class="progress">
|
||||||
|
<div class="progress-bar bg-success" style="width:35%"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- BODY -->
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row">
|
||||||
|
<!-- LEFT -->
|
||||||
|
<div class="col-lg-4 mb-4">
|
||||||
|
<div class="card scanner-card">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="barcode-avatar">
|
||||||
|
<i class="bi bi-qr-code-scan"></i>
|
||||||
|
</div>
|
||||||
|
<div class="text-center mt-3">
|
||||||
|
<div class="barcode-code">
|
||||||
|
ONU-250626-0007
|
||||||
|
</div>
|
||||||
|
<div class="scan-note mt-2">
|
||||||
|
Barcode yang sedang menunggu Serial Number
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<center>
|
||||||
|
<label class="font-weight-bold">
|
||||||
|
Serial Number
|
||||||
|
</label>
|
||||||
|
<!-- <input
|
||||||
|
type="text"
|
||||||
|
id="serial_number"
|
||||||
|
class="form-control form-control-lg text-center"
|
||||||
|
placeholder="Scan Serial Number"
|
||||||
|
autocomplete="off"
|
||||||
|
autofocus
|
||||||
|
>
|
||||||
|
<small class="scan-note">
|
||||||
|
Scanner akan otomatis menyimpan.
|
||||||
|
</small>
|
||||||
|
<button class="btn btn-warning btn-block camera-btn mt-4">
|
||||||
|
<i class="fa fa-camera mr-2"></i>
|
||||||
|
Scan dengan Kamera
|
||||||
|
</button> -->
|
||||||
|
<div id="scannerArea">
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="serial_number"
|
||||||
|
class="form-control form-control-lg text-center"
|
||||||
|
placeholder="Scan Serial Number"
|
||||||
|
autocomplete="off"
|
||||||
|
autofocus>
|
||||||
|
|
||||||
|
<small class="scan-note">
|
||||||
|
Scanner akan otomatis menyimpan.
|
||||||
|
</small>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-warning btn-block camera-btn mt-4"
|
||||||
|
id="btnCamera">
|
||||||
|
|
||||||
|
<i class="fa fa-camera mr-2"></i>
|
||||||
|
Scan dengan Kamera
|
||||||
|
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="cameraArea" style="display:none;">
|
||||||
|
|
||||||
|
<div id="reader"></div>
|
||||||
|
|
||||||
|
<small class="scan-note d-block mt-2">
|
||||||
|
Arahkan QR Code ke kamera.
|
||||||
|
</small>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-secondary btn-block mt-3"
|
||||||
|
id="btnCloseCamera">
|
||||||
|
|
||||||
|
Tutup Kamera
|
||||||
|
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</center>
|
||||||
|
<div class="alert alert-warning mt-3 mb-0 text-center">
|
||||||
|
<i class="fa fa-check-circle"></i>
|
||||||
|
Auto Save Aktif
|
||||||
|
</div>
|
||||||
|
<input type="hidden" id="barcode_id">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- RIGHT -->
|
||||||
|
<div class="col-lg-8">
|
||||||
|
<div class="card table-card">
|
||||||
|
<div class="card-header bg-white">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<h5 class="mb-0">
|
||||||
|
Daftar Barcode
|
||||||
|
</h5>
|
||||||
|
<span class="badge badge-warning px-3 py-2">
|
||||||
|
20 Data
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="table-responsive">
|
||||||
|
|
||||||
|
<table class="table table-hover mb-0" id="tableBarcode">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th width="60">No</th>
|
||||||
|
<th>Barcode</th>
|
||||||
|
<th>Serial Number</th>
|
||||||
|
<th width="120">Status</th>
|
||||||
|
<th width="80" class="text-center">Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>
|
||||||
|
<strong></strong>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
<td>
|
||||||
|
<span class="badge-success-soft">
|
||||||
|
<i class="fa fa-check mr-1"></i>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="text-center">
|
||||||
|
<button class="btn btn-sm btn-outline-danger">
|
||||||
|
<i class="fa fa-trash"></i>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
let ITEM_ID = `<?= $item_id; ?>` ;
|
||||||
|
let isSaving = false;
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
loadData();
|
||||||
|
$("#serial_number").focus();
|
||||||
|
$("#serial_number").on("keypress", function (e) {
|
||||||
|
if (e.which == 13) {
|
||||||
|
e.preventDefault();
|
||||||
|
if (!isSaving) {
|
||||||
|
saveSerial();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function loadData() {
|
||||||
|
$.getJSON( "<?= base_url(); ?>" + "items/load_data_barcode/" + ITEM_ID)
|
||||||
|
.done(function (r) {
|
||||||
|
render(r);
|
||||||
|
})
|
||||||
|
.fail(function () {
|
||||||
|
Swal.fire({
|
||||||
|
icon: 'error',
|
||||||
|
title: 'Oops...',
|
||||||
|
text: 'Gagal mengambil data barcode.'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveSerial() {
|
||||||
|
let serial = $("#serial_number").val().trim();
|
||||||
|
if (serial == "") {
|
||||||
|
$("#serial_number").focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
isSaving = true;
|
||||||
|
$("#serial_number")
|
||||||
|
.prop("disabled", true);
|
||||||
|
$.ajax({
|
||||||
|
url: "<?= base_url(); ?>" + "items/save_serial_number",
|
||||||
|
type: "POST",
|
||||||
|
dataType: "json",
|
||||||
|
data: {
|
||||||
|
barcode_id: $("#barcode_id").val(),
|
||||||
|
serial_number: serial
|
||||||
|
},
|
||||||
|
success: function (r) {
|
||||||
|
isSaving = false;
|
||||||
|
render(r);
|
||||||
|
},
|
||||||
|
error: function () {
|
||||||
|
isSaving = false;
|
||||||
|
$("#serial_number")
|
||||||
|
.prop("disabled", false)
|
||||||
|
.focus();
|
||||||
|
Swal.fire({
|
||||||
|
icon: "error",
|
||||||
|
title: "Error",
|
||||||
|
text: "Terjadi kesalahan pada server."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function render(r) {
|
||||||
|
|
||||||
|
if (!r.status) {
|
||||||
|
$("#serial_number")
|
||||||
|
.val("")
|
||||||
|
.prop("disabled", false)
|
||||||
|
.focus();
|
||||||
|
|
||||||
|
Swal.fire({
|
||||||
|
icon: "error",
|
||||||
|
title: "Oops...",
|
||||||
|
text: r.message
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================
|
||||||
|
// Semua SN sudah selesai
|
||||||
|
// =======================
|
||||||
|
|
||||||
|
if (r.next == null) {
|
||||||
|
|
||||||
|
$("#barcode_id").val("");
|
||||||
|
$(".barcode-code").html("SELESAI");
|
||||||
|
|
||||||
|
$(".progress-bar").css("width", "100%");
|
||||||
|
$("#progress_text").html(r.done + " / " + r.total);
|
||||||
|
|
||||||
|
if (r.item_status == "draft") {
|
||||||
|
|
||||||
|
$("#serial_number")
|
||||||
|
.val("")
|
||||||
|
.prop("disabled", false)
|
||||||
|
.attr("placeholder", "Semua SN selesai. Edit melalui daftar di bawah jika ada yang salah.")
|
||||||
|
.blur();
|
||||||
|
|
||||||
|
Swal.fire({
|
||||||
|
icon: "success",
|
||||||
|
title: "Selesai",
|
||||||
|
text: "Semua Serial Number telah diinput. Karena status barang masih Draft, Anda masih dapat mengubah Serial Number melalui daftar di bawah."
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
$("#serial_number")
|
||||||
|
.val("")
|
||||||
|
.prop("disabled", true);
|
||||||
|
|
||||||
|
Swal.fire({
|
||||||
|
icon: "success",
|
||||||
|
title: "Selesai",
|
||||||
|
text: "Semua Serial Number berhasil diinput."
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
$("#barcode_id").val(r.next.id);
|
||||||
|
$(".barcode-code").text(r.next.barcode);
|
||||||
|
|
||||||
|
$("#progress_text").text(r.done + " / " + r.total);
|
||||||
|
|
||||||
|
$(".progress-bar").css("width", r.percent + "%");
|
||||||
|
|
||||||
|
$("#serial_number")
|
||||||
|
.val("")
|
||||||
|
.prop("disabled", false)
|
||||||
|
.attr("placeholder", "Scan Serial Number")
|
||||||
|
.focus();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================
|
||||||
|
// Table
|
||||||
|
// =======================
|
||||||
|
|
||||||
|
let html = "";
|
||||||
|
|
||||||
|
$.each(r.list, function (i, v) {
|
||||||
|
|
||||||
|
html += "<tr>";
|
||||||
|
html += "<td>" + (i + 1) + "</td>";
|
||||||
|
html += "<td><strong>" + v.barcode + "</strong></td>";
|
||||||
|
html += "<td>" + (v.serial_number ? v.serial_number : "-") + "</td>";
|
||||||
|
|
||||||
|
html += "<td>";
|
||||||
|
|
||||||
|
if (v.serial_number) {
|
||||||
|
html += '<span class="badge-success-soft"><i class="fa fa-check mr-1"></i>Selesai</span>';
|
||||||
|
} else {
|
||||||
|
html += '<span class="badge-warning-soft">Menunggu</span>';
|
||||||
|
}
|
||||||
|
|
||||||
|
html += "</td>";
|
||||||
|
|
||||||
|
html += '<td class="text-center">';
|
||||||
|
|
||||||
|
if (r.item_status == "draft") {
|
||||||
|
|
||||||
|
html += '<button class="btn btn-sm btn-outline-danger btnDelete" data-id="' + v.id + '">Delete</button>';
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
html += '<button class="btn btn-sm btn-outline-secondary" disabled>Locked</button>';
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
html += "</td>";
|
||||||
|
html += "</tr>";
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#tableBarcode tbody").html(html);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// function render(r) {
|
||||||
|
// if (!r.status) {
|
||||||
|
// $("#serial_number")
|
||||||
|
// .val("")
|
||||||
|
// .prop("disabled", false)
|
||||||
|
// .focus();
|
||||||
|
// Swal.fire({
|
||||||
|
// icon: "error",
|
||||||
|
// title: "Oops...",
|
||||||
|
// text: r.message
|
||||||
|
// });
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// if (r.next == null) {
|
||||||
|
// $("#barcode_id").val("");
|
||||||
|
// $(".barcode-code").html("SELESAI");
|
||||||
|
// $("#serial_number")
|
||||||
|
// .val("")
|
||||||
|
// .prop("disabled", true);
|
||||||
|
// $(".progress-bar")
|
||||||
|
// .css("width", "100%");
|
||||||
|
// $("#progress_text").html(r.done + " / " + r.total);
|
||||||
|
// Swal.fire({
|
||||||
|
// icon: "success",
|
||||||
|
// title: "Selesai",
|
||||||
|
// text: "Semua Serial Number berhasil diinput."
|
||||||
|
// });
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// // Barcode Aktif
|
||||||
|
// $("#barcode_id").val(r.next.id);
|
||||||
|
// $(".barcode-code").text(r.next.barcode);
|
||||||
|
// // Progress
|
||||||
|
// $("#progress_text").text(r.done + " / " + r.total);
|
||||||
|
// $(".progress-bar")
|
||||||
|
// .css("width", r.percent + "%");
|
||||||
|
// // Table
|
||||||
|
// let html = "";
|
||||||
|
// $.each(r.list, function (i, v) {
|
||||||
|
// html += "<tr>";
|
||||||
|
// html += "<td>" + (i + 1) + "</td>";
|
||||||
|
// html += "<td><strong>" + v.barcode + "</strong></td>";
|
||||||
|
// html += "<td>" + (v.serial_number ? v.serial_number : "-") + "</td>";
|
||||||
|
// html += "<td>";
|
||||||
|
// if (v.serial_number) {
|
||||||
|
// html += '<span class="badge-success-soft"><i class="fa fa-check mr-1"></i>Selesai</span>';
|
||||||
|
// } else {
|
||||||
|
// html += '<span class="badge-warning-soft">Menunggu</span>';
|
||||||
|
// }
|
||||||
|
// html += "</td>";
|
||||||
|
// html += '<td class="text-center">';
|
||||||
|
// html += '<button class="btn btn-sm btn-outline-danger btnDelete" data-id="' + v.id + '">';
|
||||||
|
// html += 'Delete';
|
||||||
|
// html += '</button>';
|
||||||
|
// html += '</td>';
|
||||||
|
// html += "</tr>";
|
||||||
|
// });
|
||||||
|
// $("#tableBarcode tbody").html(html);
|
||||||
|
// // Reset Input
|
||||||
|
// $("#serial_number")
|
||||||
|
// .val("")
|
||||||
|
// .prop("disabled", false)
|
||||||
|
// .focus();
|
||||||
|
// }
|
||||||
|
|
||||||
|
$(document).on("click", ".btnDelete", function () {
|
||||||
|
let id = $(this).data("id");
|
||||||
|
Swal.fire({
|
||||||
|
title: "Hapus Serial Number?",
|
||||||
|
icon: "warning",
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonText: "Ya",
|
||||||
|
cancelButtonText: "Batal"
|
||||||
|
}).then(function (result) {
|
||||||
|
if (!result.isConfirmed) return;
|
||||||
|
$.post(
|
||||||
|
"<?= base_url(); ?>" + "items/delete_serial_number",
|
||||||
|
{
|
||||||
|
barcode_id: id
|
||||||
|
},
|
||||||
|
function (r) {
|
||||||
|
render(r);
|
||||||
|
},
|
||||||
|
"json"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
let html5QrCode=null;
|
||||||
|
|
||||||
|
$("#btnCamera").click(function(){
|
||||||
|
|
||||||
|
$("#scannerArea").hide();
|
||||||
|
$("#cameraArea").show();
|
||||||
|
|
||||||
|
html5QrCode=new Html5Qrcode("reader");
|
||||||
|
|
||||||
|
html5QrCode.start(
|
||||||
|
{
|
||||||
|
facingMode:"environment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fps:10,
|
||||||
|
qrbox:220
|
||||||
|
},
|
||||||
|
function(decodedText){
|
||||||
|
|
||||||
|
html5QrCode.stop().then(function(){
|
||||||
|
|
||||||
|
$("#cameraArea").hide();
|
||||||
|
$("#scannerArea").show();
|
||||||
|
|
||||||
|
$("#serial_number")
|
||||||
|
.val(decodedText);
|
||||||
|
|
||||||
|
saveSerial();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#btnCloseCamera").click(function(){
|
||||||
|
|
||||||
|
if(html5QrCode){
|
||||||
|
|
||||||
|
html5QrCode.stop().then(function(){
|
||||||
|
|
||||||
|
$("#cameraArea").hide();
|
||||||
|
$("#scannerArea").show();
|
||||||
|
|
||||||
|
$("#serial_number").focus();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
@@ -63,6 +63,11 @@
|
|||||||
<input type="number" id="qty" class="form-control">
|
<input type="number" id="qty" class="form-control">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="group_tracking_qty">
|
||||||
|
<label class="mt-2">Jumlah Per (Roll, Box, Dus)</label>
|
||||||
|
<input type="number" id="tracking_qty" class="form-control">
|
||||||
|
</div>
|
||||||
|
|
||||||
<label class="mt-2">Harga Beli</label>
|
<label class="mt-2">Harga Beli</label>
|
||||||
<input type="text" id="harga_beli" class="form-control format-rupiah">
|
<input type="text" id="harga_beli" class="form-control format-rupiah">
|
||||||
|
|
||||||
@@ -252,16 +257,47 @@ function loadGudangList(){
|
|||||||
},'json');
|
},'json');
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadKode(){
|
// function loadKode(){
|
||||||
$.get("<?= base_url('kodebarang/list'); ?>",res=>{
|
// $.get("<?= base_url('kodebarang/list'); ?>",res=>{
|
||||||
let opt='<option value="">-- PILIH KODE --</option>';
|
// let opt='<option value="">-- PILIH KODE --</option>';
|
||||||
res.forEach(a=>{
|
// res.forEach(a=>{
|
||||||
opt += `<option value="${a.id}">${a.kode_barang} - ${a.nama}</option>`;
|
// opt += `<option value="${a.id}" data-type="${a.tracking_type}">${a.kode_barang} - ${a.nama}</option>`;
|
||||||
|
// });
|
||||||
|
// $('#kode_barang').html(opt);
|
||||||
|
// },'json');
|
||||||
|
// }
|
||||||
|
|
||||||
|
function loadKode() {
|
||||||
|
$.get("<?= base_url('kodebarang/list'); ?>", function(res) {
|
||||||
|
|
||||||
|
let opt = '<option value="">-- PILIH KODE --</option>';
|
||||||
|
|
||||||
|
res.forEach(function(a){
|
||||||
|
opt += `
|
||||||
|
<option value="${a.id}"
|
||||||
|
data-type="${a.tracking_type}">
|
||||||
|
${a.kode_barang} - ${a.nama}
|
||||||
|
</option>
|
||||||
|
`;
|
||||||
});
|
});
|
||||||
$('#kode_barang').html(opt);
|
|
||||||
},'json');
|
$('#kode_barang').html(opt).trigger('change');
|
||||||
|
}, 'json');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$(document).on('change', '#kode_barang', function () {
|
||||||
|
|
||||||
|
let type = $(this).find(':selected').data('type');
|
||||||
|
|
||||||
|
if(type == 'QTY'){
|
||||||
|
$('#group_tracking_qty').show();
|
||||||
|
}else{
|
||||||
|
$('#group_tracking_qty').hide();
|
||||||
|
$('#tracking_qty').val('');
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
// ================= RESET FORM =================
|
// ================= RESET FORM =================
|
||||||
function resetForm(){
|
function resetForm(){
|
||||||
$('#id').val('');
|
$('#id').val('');
|
||||||
@@ -270,6 +306,8 @@ function resetForm(){
|
|||||||
$('#harga_beli').val('');
|
$('#harga_beli').val('');
|
||||||
$('#harga_jual').val('');
|
$('#harga_jual').val('');
|
||||||
$('#tanggal_beli').val('');
|
$('#tanggal_beli').val('');
|
||||||
|
$('#tracking_qty').val('');
|
||||||
|
$('#group_tracking_qty').hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================= INIT LOAD =================
|
// ================= INIT LOAD =================
|
||||||
@@ -334,6 +372,7 @@ $('#btnSimpan').click(function(){
|
|||||||
warehouse_id: $('#warehouse_id').val(),
|
warehouse_id: $('#warehouse_id').val(),
|
||||||
account_kas: $('#account_kas').val(),
|
account_kas: $('#account_kas').val(),
|
||||||
tanggal_beli: $('#tanggal_beli').val(),
|
tanggal_beli: $('#tanggal_beli').val(),
|
||||||
|
tracking_qty: $('#tracking_qty').val(),
|
||||||
status: `draft`
|
status: `draft`
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -501,6 +540,74 @@ $('#btnKeluar').click(function(){
|
|||||||
// ================= END URUSAN KELUAR ===============
|
// ================= END URUSAN KELUAR ===============
|
||||||
// =====================================================
|
// =====================================================
|
||||||
|
|
||||||
|
// ================= PRINT BARCODE =================
|
||||||
|
$(document).on('click', '.btn-print', function () {
|
||||||
|
|
||||||
|
let id = $(this).data('id');
|
||||||
|
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Cetak Barcode',
|
||||||
|
html: `
|
||||||
|
<div class="text-left">
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="print_column" class="font-weight-bold">
|
||||||
|
Jumlah Kolom
|
||||||
|
</label>
|
||||||
|
<select id="print_column" class="form-control">
|
||||||
|
<option value="1">1 Kolom</option>
|
||||||
|
<option value="2">2 Kolom</option>
|
||||||
|
<option value="3" selected>3 Kolom (Rekomendasi)</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group mb-0">
|
||||||
|
<label for="duplicat" class="font-weight-bold">
|
||||||
|
Jumlah Cetak per Barcode
|
||||||
|
</label>
|
||||||
|
<select id="duplicat" class="form-control">
|
||||||
|
<option value="1" selected>1 Label</option>
|
||||||
|
<option value="2">2 Label</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
icon: 'question',
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonText: 'Cetak',
|
||||||
|
cancelButtonText: 'Batal',
|
||||||
|
confirmButtonColor: '#f0ad4e',
|
||||||
|
preConfirm: () => {
|
||||||
|
|
||||||
|
let column = $('#print_column').val();
|
||||||
|
let duplicat = $('#duplicat').val();
|
||||||
|
|
||||||
|
return {
|
||||||
|
column: column,
|
||||||
|
duplicat: duplicat
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}).then((result) => {
|
||||||
|
|
||||||
|
if (!result.isConfirmed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.open(
|
||||||
|
"<?= base_url('items/print_barcode/'); ?>" +
|
||||||
|
id +
|
||||||
|
"?column=" + result.value.column +
|
||||||
|
"&duplicat=" + result.value.duplicat,
|
||||||
|
"_blank"
|
||||||
|
);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
// ================= DELETE =================
|
// ================= DELETE =================
|
||||||
$(document).on('click','.btn-delete',function(){
|
$(document).on('click','.btn-delete',function(){
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,7 @@
|
|||||||
<h5>Data Barang</h5>
|
<h5>Data Barang</h5>
|
||||||
<div class="text-end">
|
<div class="text-end">
|
||||||
<button class="btn btn-add bg-danger btn-out mr-2">Pengeluaran</button>
|
<button class="btn btn-add bg-danger btn-out mr-2">Pengeluaran</button>
|
||||||
<button class="btn btn-warning btn-add btn-add-item mr-2">Tambah Barang</button>
|
<!-- <button class="btn btn-warning btn-add btn-add-item mr-2">Tambah Barang</button> -->
|
||||||
<button class="btn btn-add bg-primary" id="generate_pdf">Generate PDF</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -93,7 +92,7 @@
|
|||||||
|
|
||||||
<!-- MODAL BARANAG KELUAR -->
|
<!-- MODAL BARANAG KELUAR -->
|
||||||
<div class="modal fade" id="modalKeluar">
|
<div class="modal fade" id="modalKeluar">
|
||||||
<div class="modal-dialog modal-dialog-centered">
|
<div class="modal-dialog modal-dialog-centered modal-lg">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
|
|
||||||
<div class="modal-header bg-danger text-white">
|
<div class="modal-header bg-danger text-white">
|
||||||
@@ -102,6 +101,55 @@
|
|||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
|
<center>
|
||||||
|
<div id="scannerArea">
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="serial_number"
|
||||||
|
class="form-control form-control-lg text-center"
|
||||||
|
placeholder="Scan QR Barang"
|
||||||
|
autocomplete="off"
|
||||||
|
autofocus>
|
||||||
|
|
||||||
|
<small class="scan-note">
|
||||||
|
Scanner akan otomatis menyimpan.
|
||||||
|
</small><br>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-warning btn-block camera-btn mt-4"
|
||||||
|
id="btnCamera">
|
||||||
|
|
||||||
|
<i class="fa fa-camera mr-2"></i>
|
||||||
|
Scan dengan Kamera
|
||||||
|
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="cameraArea" style="display:none;">
|
||||||
|
|
||||||
|
<div id="reader"></div>
|
||||||
|
|
||||||
|
<small class="scan-note d-block mt-2">
|
||||||
|
Arahkan QR Code ke kamera.
|
||||||
|
</small>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-secondary btn-block mt-3"
|
||||||
|
id="btnCloseCamera">
|
||||||
|
|
||||||
|
Tutup Kamera
|
||||||
|
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</center>
|
||||||
|
<div id="tableBarcode"></div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
<div id="group_account_biaya">
|
<div id="group_account_biaya">
|
||||||
<label class="mt-2">Akun Biaya</label>
|
<label class="mt-2">Akun Biaya</label>
|
||||||
<select id="account_biaya" class="form-control"></select>
|
<select id="account_biaya" class="form-control"></select>
|
||||||
@@ -112,7 +160,7 @@
|
|||||||
<input type="date" id="tanggal_keluar" class="form-control">
|
<input type="date" id="tanggal_keluar" class="form-control">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<!-- <div>
|
||||||
<label class="mt-2">Gudang</label>
|
<label class="mt-2">Gudang</label>
|
||||||
<select id="warehouse_id_keluar" class="form-control"></select>
|
<select id="warehouse_id_keluar" class="form-control"></select>
|
||||||
</div>
|
</div>
|
||||||
@@ -125,9 +173,8 @@
|
|||||||
<div class="d-none" id="group_qty_keluar">
|
<div class="d-none" id="group_qty_keluar">
|
||||||
<label class="mt-2">Jumlah Barang</label>
|
<label class="mt-2">Jumlah Barang</label>
|
||||||
<input type="number" id="qty_keluar" class="form-control">
|
<input type="number" id="qty_keluar" class="form-control">
|
||||||
</div>
|
</div> -->
|
||||||
|
<div class="mb-2" id="group_keterangan">
|
||||||
<div class="mb-2 d-none" id="group_keterangan">
|
|
||||||
<label for="keterangan" class="form-label">Keterangan</label>
|
<label for="keterangan" class="form-label">Keterangan</label>
|
||||||
<textarea class="form-control" id="keterangan_keluar" rows="3"></textarea>
|
<textarea class="form-control" id="keterangan_keluar" rows="3"></textarea>
|
||||||
</div>
|
</div>
|
||||||
@@ -196,6 +243,191 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
// URUSAN BARCODE INPUT DAN CAMSCANNER
|
||||||
|
let daftarBarang = [];
|
||||||
|
let isSaving = false;
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
$("#serial_number").focus();
|
||||||
|
$("#serial_number").keypress(function(e){
|
||||||
|
if(e.which==13){
|
||||||
|
e.preventDefault();
|
||||||
|
if(!isSaving){
|
||||||
|
getBarcodeId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function getBarcodeId(){
|
||||||
|
let barcode = ($("#serial_number").val() || "").trim();
|
||||||
|
if(barcode==""){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$.post(
|
||||||
|
"<?=base_url('items/get_barcode_item');?>",
|
||||||
|
{
|
||||||
|
barcode:barcode
|
||||||
|
},
|
||||||
|
function(r){
|
||||||
|
if(!r.status){
|
||||||
|
Swal.fire({
|
||||||
|
icon:"error",
|
||||||
|
title:"Oops...",
|
||||||
|
text:r.message
|
||||||
|
});
|
||||||
|
$("#serial_number").val("").focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let exist = daftarBarang.find(function(v){
|
||||||
|
return v.barcode_id == r.data.barcode_id;
|
||||||
|
});
|
||||||
|
|
||||||
|
if(exist){
|
||||||
|
Swal.fire({
|
||||||
|
icon: "warning",
|
||||||
|
title: "Barcode sudah discan",
|
||||||
|
timer: 1000,
|
||||||
|
showConfirmButton: false
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#serial_number").val("").focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
daftarBarang.push(r.data);
|
||||||
|
renderTable();
|
||||||
|
$("#serial_number").val("").focus();
|
||||||
|
},
|
||||||
|
"json"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderTable(){
|
||||||
|
|
||||||
|
let html='';
|
||||||
|
|
||||||
|
html+='<div class="table-responsive">';
|
||||||
|
html+='<table class="table table-bordered table-hover table-sm mb-0">';
|
||||||
|
html+='<thead>';
|
||||||
|
html+='<tr>';
|
||||||
|
html+='<th width="50">No</th>';
|
||||||
|
html+='<th width="180">Barcode</th>';
|
||||||
|
html+='<th width="150">Kode Barang</th>';
|
||||||
|
html+='<th>Nama Barang</th>';
|
||||||
|
html+='<th width="180">Serial Number</th>';
|
||||||
|
html+='<th width="80" class="text-center">Action</th>';
|
||||||
|
html+='</tr>';
|
||||||
|
html+='</thead>';
|
||||||
|
html+='<tbody>';
|
||||||
|
|
||||||
|
if(daftarBarang.length==0){
|
||||||
|
|
||||||
|
html+='<tr>';
|
||||||
|
html+='<td colspan="6" class="text-center text-muted py-4">';
|
||||||
|
html+='Belum ada barcode yang discan.';
|
||||||
|
html+='</td>';
|
||||||
|
html+='</tr>';
|
||||||
|
|
||||||
|
}else{
|
||||||
|
|
||||||
|
$.each(daftarBarang,function(i,v){
|
||||||
|
|
||||||
|
html+='<tr>';
|
||||||
|
html+='<td>'+(i+1)+'</td>';
|
||||||
|
html+='<td><strong>'+v.barcode+'</strong></td>';
|
||||||
|
html+='<td>'+v.kode_detail+'</td>';
|
||||||
|
html+='<td>'+v.nama_barang+'</td>';
|
||||||
|
html+='<td>'+(v.serial_number?v.serial_number:'-')+'</td>';
|
||||||
|
html+='<td class="text-center">';
|
||||||
|
html+='<button class="btn btn-sm btn-outline-danger btnRemove" data-id="'+v.barcode_id+'">';
|
||||||
|
html+='<i class="bi bi-trash"></i>';
|
||||||
|
html+='</button>';
|
||||||
|
html+='</td>';
|
||||||
|
html+='</tr>';
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
html+='</tbody>';
|
||||||
|
html+='</table>';
|
||||||
|
html+='</div>';
|
||||||
|
|
||||||
|
$("#tableBarcode").html(html);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).on("click",".btnRemove",function(){
|
||||||
|
|
||||||
|
let id=$(this).data("id");
|
||||||
|
|
||||||
|
daftarBarang=daftarBarang.filter(function(v){
|
||||||
|
return v.barcode_id!=id;
|
||||||
|
});
|
||||||
|
|
||||||
|
renderTable();
|
||||||
|
|
||||||
|
$("#serial_number").focus();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
let html5QrCode=null;
|
||||||
|
|
||||||
|
$("#btnCamera").click(function(){
|
||||||
|
|
||||||
|
$("#scannerArea").hide();
|
||||||
|
$("#cameraArea").show();
|
||||||
|
|
||||||
|
html5QrCode=new Html5Qrcode("reader");
|
||||||
|
|
||||||
|
html5QrCode.start(
|
||||||
|
{
|
||||||
|
facingMode:"environment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fps:10,
|
||||||
|
qrbox:220
|
||||||
|
},
|
||||||
|
function(decodedText){
|
||||||
|
|
||||||
|
html5QrCode.stop().then(function(){
|
||||||
|
|
||||||
|
$("#cameraArea").hide();
|
||||||
|
$("#scannerArea").show();
|
||||||
|
|
||||||
|
$("#serial_number")
|
||||||
|
.val(decodedText);
|
||||||
|
|
||||||
|
saveSerial();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#btnCloseCamera").click(function(){
|
||||||
|
|
||||||
|
if(html5QrCode){
|
||||||
|
|
||||||
|
html5QrCode.stop().then(function(){
|
||||||
|
|
||||||
|
$("#cameraArea").hide();
|
||||||
|
$("#scannerArea").show();
|
||||||
|
|
||||||
|
$("#serial_number").focus();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
// URUSAN BARCODE INPUT DAN CAMSCANNER
|
||||||
|
|
||||||
|
|
||||||
$(function(){
|
$(function(){
|
||||||
|
|
||||||
let action = 'add';
|
let action = 'add';
|
||||||
@@ -279,20 +511,20 @@ loadGudang();
|
|||||||
loadKas();
|
loadKas();
|
||||||
loadKode();
|
loadKode();
|
||||||
|
|
||||||
// ================= ADD =================
|
// // ================= ADD =================
|
||||||
$('.btn-add-item').click(function(){
|
// $('.btn-add-item').click(function(){
|
||||||
action='add';
|
// action='add';
|
||||||
resetForm();
|
// resetForm();
|
||||||
|
|
||||||
$('#qty').closest('div').show();
|
// $('#qty').closest('div').show();
|
||||||
$('#kode_barang').closest('div').show();
|
// $('#kode_barang').closest('div').show();
|
||||||
$('#warehouse_id').closest('div').show();
|
// $('#warehouse_id').closest('div').show();
|
||||||
$('#account_kas').closest('div').show();
|
// $('#account_kas').closest('div').show();
|
||||||
$('#modalItem').modal('show');
|
// $('#modalItem').modal('show');
|
||||||
loadGudang();
|
// loadGudang();
|
||||||
loadKas();
|
// loadKas();
|
||||||
loadKode();
|
// loadKode();
|
||||||
});
|
// });
|
||||||
|
|
||||||
// ================= EDIT =================
|
// ================= EDIT =================
|
||||||
$(document).on('click','.btn-editItem',function(){
|
$(document).on('click','.btn-editItem',function(){
|
||||||
@@ -412,6 +644,12 @@ $('.btn-out').click(function(){
|
|||||||
loadKasOut();
|
loadKasOut();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#modalKeluar').on('shown.bs.modal', function () {
|
||||||
|
setTimeout(function () {
|
||||||
|
$('#serial_number').trigger('focus').select();
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
|
||||||
$('#warehouse_id_keluar').on('change', function(){
|
$('#warehouse_id_keluar').on('change', function(){
|
||||||
let warehouse_id = $(this).val();
|
let warehouse_id = $(this).val();
|
||||||
|
|
||||||
@@ -682,26 +920,5 @@ $('#btnAdjust').click(function(){
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
//PDF GENERATE//
|
|
||||||
$('#generate_pdf').on('click', function(){
|
|
||||||
|
|
||||||
let btn = $(this);
|
|
||||||
|
|
||||||
btn.prop('disabled', true)
|
|
||||||
.html('Generate PDF...');
|
|
||||||
|
|
||||||
window.open(
|
|
||||||
|
|
||||||
"<?= base_url('generateitems/generatepdf'); ?>",
|
|
||||||
'_blank'
|
|
||||||
);
|
|
||||||
|
|
||||||
setTimeout(function(){
|
|
||||||
btn.prop('disabled', false)
|
|
||||||
.html('Generate PDF');
|
|
||||||
},1000);
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@@ -38,6 +38,8 @@
|
|||||||
<link href="https://cdn.jsdelivr.net/npm/select2@4.0.13/dist/css/select2.min.css" rel="stylesheet" />
|
<link href="https://cdn.jsdelivr.net/npm/select2@4.0.13/dist/css/select2.min.css" rel="stylesheet" />
|
||||||
<script src="https://cdn.jsdelivr.net/npm/select2@4.0.13/dist/js/select2.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/select2@4.0.13/dist/js/select2.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Camera Scanner -->
|
||||||
|
<script src="https://unpkg.com/html5-qrcode"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
|
After Width: | Height: | Size: 243 B |
|
After Width: | Height: | Size: 243 B |
|
After Width: | Height: | Size: 243 B |
|
After Width: | Height: | Size: 237 B |
|
After Width: | Height: | Size: 241 B |
|
After Width: | Height: | Size: 241 B |
|
After Width: | Height: | Size: 243 B |
|
After Width: | Height: | Size: 242 B |
|
After Width: | Height: | Size: 248 B |
|
After Width: | Height: | Size: 239 B |
|
After Width: | Height: | Size: 237 B |
|
After Width: | Height: | Size: 242 B |
|
After Width: | Height: | Size: 242 B |
|
After Width: | Height: | Size: 239 B |
|
After Width: | Height: | Size: 242 B |
|
After Width: | Height: | Size: 247 B |
|
After Width: | Height: | Size: 245 B |
|
After Width: | Height: | Size: 243 B |
|
After Width: | Height: | Size: 243 B |
|
After Width: | Height: | Size: 240 B |
|
After Width: | Height: | Size: 244 B |
|
After Width: | Height: | Size: 247 B |
|
After Width: | Height: | Size: 242 B |
|
After Width: | Height: | Size: 242 B |
|
After Width: | Height: | Size: 240 B |
|
After Width: | Height: | Size: 238 B |
|
After Width: | Height: | Size: 231 B |
|
After Width: | Height: | Size: 241 B |
|
After Width: | Height: | Size: 236 B |
|
After Width: | Height: | Size: 243 B |
|
After Width: | Height: | Size: 235 B |
|
After Width: | Height: | Size: 237 B |
|
After Width: | Height: | Size: 243 B |
|
After Width: | Height: | Size: 238 B |
|
After Width: | Height: | Size: 241 B |
|
After Width: | Height: | Size: 231 B |
|
After Width: | Height: | Size: 241 B |
|
After Width: | Height: | Size: 243 B |
|
After Width: | Height: | Size: 243 B |
|
After Width: | Height: | Size: 245 B |
|
After Width: | Height: | Size: 244 B |
|
After Width: | Height: | Size: 242 B |
|
After Width: | Height: | Size: 244 B |
|
After Width: | Height: | Size: 242 B |
|
After Width: | Height: | Size: 244 B |
|
After Width: | Height: | Size: 242 B |
|
After Width: | Height: | Size: 241 B |
|
After Width: | Height: | Size: 242 B |
|
After Width: | Height: | Size: 240 B |
|
After Width: | Height: | Size: 236 B |
|
After Width: | Height: | Size: 244 B |
|
After Width: | Height: | Size: 244 B |
|
After Width: | Height: | Size: 243 B |
|
After Width: | Height: | Size: 242 B |
|
After Width: | Height: | Size: 246 B |
|
After Width: | Height: | Size: 245 B |
|
After Width: | Height: | Size: 243 B |
|
After Width: | Height: | Size: 245 B |
|
After Width: | Height: | Size: 244 B |
|
After Width: | Height: | Size: 244 B |
|
After Width: | Height: | Size: 243 B |
|
After Width: | Height: | Size: 244 B |
|
After Width: | Height: | Size: 244 B |
|
After Width: | Height: | Size: 246 B |
|
After Width: | Height: | Size: 250 B |
|
After Width: | Height: | Size: 243 B |
|
After Width: | Height: | Size: 244 B |
|
After Width: | Height: | Size: 242 B |
|
After Width: | Height: | Size: 243 B |
|
After Width: | Height: | Size: 247 B |
|
After Width: | Height: | Size: 244 B |
|
After Width: | Height: | Size: 244 B |
|
After Width: | Height: | Size: 244 B |
|
After Width: | Height: | Size: 241 B |
|
After Width: | Height: | Size: 238 B |
|
After Width: | Height: | Size: 243 B |
|
After Width: | Height: | Size: 240 B |
|
After Width: | Height: | Size: 247 B |
|
After Width: | Height: | Size: 245 B |
|
After Width: | Height: | Size: 243 B |
|
After Width: | Height: | Size: 244 B |
|
After Width: | Height: | Size: 240 B |
|
After Width: | Height: | Size: 245 B |
|
After Width: | Height: | Size: 244 B |
|
After Width: | Height: | Size: 248 B |
|
After Width: | Height: | Size: 245 B |
|
After Width: | Height: | Size: 248 B |
|
After Width: | Height: | Size: 243 B |
|
After Width: | Height: | Size: 249 B |
|
After Width: | Height: | Size: 244 B |
|
After Width: | Height: | Size: 248 B |
|
After Width: | Height: | Size: 247 B |
|
After Width: | Height: | Size: 239 B |
|
After Width: | Height: | Size: 242 B |