Update besar apk finance
This commit is contained in:
@@ -8,6 +8,12 @@ class PeralatanTeknisi_model extends CI_Model {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
private function companyId()
|
||||
{
|
||||
$companyId = (int) $this->session->userdata('company_id');
|
||||
return $companyId > 0 ? $companyId : 1;
|
||||
}
|
||||
|
||||
public function get_teknisi_list()
|
||||
{
|
||||
return $this->db
|
||||
@@ -15,8 +21,9 @@ class PeralatanTeknisi_model extends CI_Model {
|
||||
->from('k_employees e')
|
||||
->join('k_positions p', 'p.id = e.position_id', 'left')
|
||||
->join('k_departments d', 'd.id = e.department_id', 'left')
|
||||
->where('e.company_id', $this->companyId())
|
||||
->where('e.is_active', 1)
|
||||
->where('(e.resign_date IS NULL OR e.resign_date = \'0000-00-00\')')
|
||||
->where_in('LOWER(p.position_name)', ['teknisi', 'noc'])
|
||||
->order_by('e.full_name', 'ASC')
|
||||
->get()
|
||||
->result();
|
||||
@@ -42,6 +49,8 @@ class PeralatanTeknisi_model extends CI_Model {
|
||||
->join('items i', 'i.id = it.item_id', 'left')
|
||||
->join('k_employees ke', 'ke.id = it.user_id', 'left');
|
||||
|
||||
$this->db->where('i.company_id', $this->companyId());
|
||||
|
||||
if ($user_id) {
|
||||
$this->db->where('it.user_id', $user_id);
|
||||
}
|
||||
@@ -65,6 +74,7 @@ class PeralatanTeknisi_model extends CI_Model {
|
||||
->from('item_barcodes ib')
|
||||
->join('items i', 'i.id = ib.item_id', 'left')
|
||||
->where('ib.barcode', $barcode)
|
||||
->where('i.company_id', $this->companyId())
|
||||
->where('ib.qty_sisa >', 0)
|
||||
->get()
|
||||
->row();
|
||||
@@ -75,6 +85,7 @@ class PeralatanTeknisi_model extends CI_Model {
|
||||
->from('item_barcodes ib')
|
||||
->join('items i', 'i.id = ib.item_id', 'left')
|
||||
->where('ib.serial_number', $barcode)
|
||||
->where('i.company_id', $this->companyId())
|
||||
->where('ib.qty_sisa >', 0)
|
||||
->get()
|
||||
->row();
|
||||
@@ -89,8 +100,10 @@ class PeralatanTeknisi_model extends CI_Model {
|
||||
->select('it.user_id, ke.full_name, ke.employee_code')
|
||||
->from('item_technician it')
|
||||
->join('k_employees ke', 'ke.id = it.user_id', 'left')
|
||||
->join('items i', 'i.id = it.item_id', 'inner')
|
||||
->where('it.barcode', $barcode)
|
||||
->where('it.status', 'active')
|
||||
->where('i.company_id', $this->companyId())
|
||||
->get()
|
||||
->row();
|
||||
}
|
||||
@@ -106,31 +119,36 @@ class PeralatanTeknisi_model extends CI_Model {
|
||||
$barcode = trim($barcode);
|
||||
if ($barcode == '') continue;
|
||||
|
||||
$item = $this->db
|
||||
->select('it.*, ib.id as barcode_id, tec.full_name as teknisi_name')
|
||||
->from('item_technician it')
|
||||
->join('item_barcodes ib', 'ib.barcode = it.barcode', 'left')
|
||||
->join('k_employees tec', 'tec.id = it.user_id', 'left')
|
||||
->where('it.barcode', $barcode)
|
||||
->where('it.status', 'active')
|
||||
->get()
|
||||
->row();
|
||||
$item = $this->db->query(
|
||||
"SELECT it.*, ib.id AS barcode_id, ib.warehouse_id, ib.qty_sisa, tec.full_name AS teknisi_name
|
||||
FROM item_technician it
|
||||
JOIN item_barcodes ib ON ib.barcode = it.barcode
|
||||
JOIN items i ON i.id = it.item_id AND i.company_id = ?
|
||||
LEFT JOIN k_employees tec ON tec.id = it.user_id
|
||||
WHERE it.barcode = ? AND it.status = 'active'
|
||||
FOR UPDATE",
|
||||
[$this->companyId(), $barcode]
|
||||
)->row();
|
||||
|
||||
if (!$item) {
|
||||
$errors[] = "Barcode $barcode tidak ditemukan atau sudah dikembalikan";
|
||||
continue;
|
||||
}
|
||||
|
||||
$assigned=(float)($item->assigned_qty?:$item->qty_sisa);$carried=(float)$item->carried_qty;$installed=(float)$item->installed_qty;
|
||||
if($carried>0&&$installed>0){$errors[]="Barcode $barcode memiliki status sebagian dibawa dan sebagian dipasang; gunakan Detail Teknisi untuk menentukan jumlah dan asal pengembalian";continue;}
|
||||
$source=$installed>0?'installed':'carried';$qty=$assigned;
|
||||
|
||||
$this->db->insert('item_movements', [
|
||||
'item_id' => $item->item_id,
|
||||
'barcode_id' => $item->barcode_id,
|
||||
'qty' => 1,
|
||||
'from_type' => 'technician',
|
||||
'from_id' => $item->user_id,
|
||||
'qty' => $qty,
|
||||
'from_type' => $source === 'installed' ? 'customer' : 'technician',
|
||||
'from_id' => $source === 'installed' ? $item->customer_id : $item->user_id,
|
||||
'to_type' => 'warehouse',
|
||||
'to_id' => null,
|
||||
'to_id' => $item->warehouse_id,
|
||||
'movement_type' => 'transfer',
|
||||
'notes' => 'Pengembalian dari: ' . $item->teknisi_name . ' ke gudang',
|
||||
'notes' => (($item->usage_status??'carried') === 'installed' ? 'Pengembalian dari customer melalui teknisi: ' : 'Pengembalian dari teknisi: ') . $item->teknisi_name . ' ke gudang',
|
||||
'created_at' => $now
|
||||
]);
|
||||
|
||||
@@ -139,9 +157,14 @@ class PeralatanTeknisi_model extends CI_Model {
|
||||
->where('status', 'active')
|
||||
->update('item_technician', [
|
||||
'status' => 'inactive',
|
||||
'assigned_qty' => 0,
|
||||
'carried_qty' => 0,
|
||||
'installed_qty' => 0,
|
||||
'deleted_at' => $now
|
||||
]);
|
||||
|
||||
$this->db->insert('technician_item_status_logs',array('company_id'=>$this->companyId(),'user_id'=>$item->user_id,'item_id'=>$item->item_id,'barcode_id'=>$item->barcode_id,'barcode'=>$item->barcode,'from_status'=>$source,'to_status'=>'returned','qty'=>$qty,'customer_id'=>$source==='installed'?$item->customer_id:null,'event_date'=>date('Y-m-d'),'notes'=>'Pengembalian batch ke gudang','created_by'=>(int)$this->session->userdata('user_id'),'created_at'=>$now));
|
||||
|
||||
if ($item->barcode_id) {
|
||||
$this->db
|
||||
->where('id', $item->barcode_id)
|
||||
@@ -171,8 +194,10 @@ class PeralatanTeknisi_model extends CI_Model {
|
||||
return $this->db
|
||||
->select("DATE(it.created_at) as tanggal")
|
||||
->from('item_technician it')
|
||||
->join('items i', 'i.id = it.item_id', 'inner')
|
||||
->where('it.user_id', $user_id)
|
||||
->where('it.status', 'active')
|
||||
->where('i.company_id', $this->companyId())
|
||||
->group_by("DATE(it.created_at)")
|
||||
->order_by("DATE(it.created_at)", "DESC")
|
||||
->get()
|
||||
@@ -189,22 +214,34 @@ class PeralatanTeknisi_model extends CI_Model {
|
||||
->select('id, full_name, employee_code')
|
||||
->from('k_employees')
|
||||
->where('id', $user_id)
|
||||
->where('company_id', $this->companyId())
|
||||
->get()
|
||||
->row();
|
||||
|
||||
if (!$technician) {
|
||||
return ['status' => false, 'message' => 'Teknisi tidak ditemukan pada perusahaan aktif.'];
|
||||
}
|
||||
|
||||
$this->db->trans_start();
|
||||
|
||||
foreach ($barcodes as $barcode) {
|
||||
$barcode = trim($barcode);
|
||||
if ($barcode == '') continue;
|
||||
|
||||
$barcode_row = $this->db
|
||||
->select('ib.id as barcode_id, ib.item_id, ib.barcode')
|
||||
->from('item_barcodes ib')
|
||||
->where('ib.barcode', $barcode)
|
||||
->where_not_in('ib.status', ['damaged', 'lost', 'returned_supplier', 'sold_out'])
|
||||
->get()
|
||||
->row();
|
||||
$barcode_row = $this->db->query(
|
||||
"SELECT ib.id AS barcode_id, ib.item_id, ib.barcode, ib.warehouse_id,ib.qty_sisa,
|
||||
COALESCE(k.tracking_type,'QTY') tracking_type
|
||||
FROM item_barcodes ib
|
||||
JOIN items i ON i.id = ib.item_id AND i.company_id = ?
|
||||
LEFT JOIN kode_barang k ON k.id=i.kode_id
|
||||
WHERE ib.barcode = ?
|
||||
AND ib.status = 'available'
|
||||
AND ib.qty_sisa > 0
|
||||
AND COALESCE(ib.reserved_qty, 0) = 0
|
||||
AND COALESCE(ib.return_reserved_qty, 0) = 0
|
||||
FOR UPDATE",
|
||||
[$this->companyId(), $barcode]
|
||||
)->row();
|
||||
|
||||
if (!$barcode_row) {
|
||||
$errors[] = "Barcode $barcode tidak valid atau tidak tersedia";
|
||||
@@ -228,9 +265,14 @@ class PeralatanTeknisi_model extends CI_Model {
|
||||
|
||||
$this->db->insert('item_technician', [
|
||||
'user_id' => $user_id,
|
||||
'company_id' => $this->companyId(),
|
||||
'barcode' => $barcode_row->barcode,
|
||||
'item_id' => $barcode_row->item_id,
|
||||
'status' => 'active',
|
||||
'usage_status' => 'carried',
|
||||
'assigned_qty' => (float)$barcode_row->qty_sisa,
|
||||
'carried_qty' => (float)$barcode_row->qty_sisa,
|
||||
'installed_qty' => 0,
|
||||
'created_at' => $now
|
||||
]);
|
||||
|
||||
@@ -242,7 +284,7 @@ class PeralatanTeknisi_model extends CI_Model {
|
||||
->row();
|
||||
|
||||
$from_type = 'warehouse';
|
||||
$from_id = null;
|
||||
$from_id = $barcode_row->warehouse_id;
|
||||
if ($last_movement) {
|
||||
$from_type = $last_movement->to_type;
|
||||
$from_id = $last_movement->to_id;
|
||||
@@ -251,7 +293,7 @@ class PeralatanTeknisi_model extends CI_Model {
|
||||
$this->db->insert('item_movements', [
|
||||
'item_id' => $barcode_row->item_id,
|
||||
'barcode_id' => $barcode_row->barcode_id,
|
||||
'qty' => 1,
|
||||
'qty' => (float)$barcode_row->qty_sisa,
|
||||
'from_type' => $from_type,
|
||||
'from_id' => $from_id,
|
||||
'to_type' => 'technician',
|
||||
@@ -307,6 +349,7 @@ class PeralatanTeknisi_model extends CI_Model {
|
||||
->from('k_employees e')
|
||||
->join('k_positions p', 'p.id = e.position_id', 'left')
|
||||
->join('k_departments d', 'd.id = e.department_id', 'left')
|
||||
->where('e.company_id', $this->companyId())
|
||||
->where('(e.resign_date IS NULL OR e.resign_date = \'0000-00-00\')')
|
||||
->where_in('LOWER(p.position_name)', ['teknisi', 'noc']);
|
||||
|
||||
@@ -336,6 +379,7 @@ class PeralatanTeknisi_model extends CI_Model {
|
||||
$this->db
|
||||
->from('k_employees e')
|
||||
->join('k_positions p', 'p.id = e.position_id', 'left')
|
||||
->where('e.company_id', $this->companyId())
|
||||
->where('(e.resign_date IS NULL OR e.resign_date = \'0000-00-00\')')
|
||||
->where_in('LOWER(p.position_name)', ['teknisi', 'noc']);
|
||||
|
||||
@@ -348,6 +392,7 @@ class PeralatanTeknisi_model extends CI_Model {
|
||||
->from('k_employees e')
|
||||
->join('k_positions p', 'p.id = e.position_id', 'left')
|
||||
->join('k_departments d', 'd.id = e.department_id', 'left')
|
||||
->where('e.company_id', $this->companyId())
|
||||
->where('(e.resign_date IS NULL OR e.resign_date = \'0000-00-00\')')
|
||||
->where_in('LOWER(p.position_name)', ['teknisi', 'noc']);
|
||||
|
||||
@@ -370,6 +415,7 @@ class PeralatanTeknisi_model extends CI_Model {
|
||||
->join('k_positions p', 'p.id = e.position_id', 'left')
|
||||
->join('k_departments d', 'd.id = e.department_id', 'left')
|
||||
->where('e.id', $user_id)
|
||||
->where('e.company_id', $this->companyId())
|
||||
->get()
|
||||
->row();
|
||||
}
|
||||
@@ -387,17 +433,32 @@ class PeralatanTeknisi_model extends CI_Model {
|
||||
$this->db
|
||||
->select("
|
||||
it.barcode,
|
||||
it.user_id,
|
||||
i.nama_barang,
|
||||
ib.serial_number,
|
||||
ib.qty_sisa,
|
||||
COALESCE(k.tracking_type, 'QTY') tracking_type,
|
||||
COALESCE(NULLIF(it.assigned_qty,0),ib.qty_sisa) assigned_qty,
|
||||
COALESCE(it.carried_qty,CASE WHEN COALESCE(it.usage_status,'carried')='carried' THEN ib.qty_sisa ELSE 0 END) carried_qty,
|
||||
COALESCE(it.installed_qty,CASE WHEN it.usage_status='installed' THEN ib.qty_sisa ELSE 0 END) installed_qty,
|
||||
it.status,
|
||||
COALESCE(it.usage_status, 'carried') usage_status,
|
||||
it.usage_date,
|
||||
it.customer_id,
|
||||
c.nama customer_name,
|
||||
ib.id barcode_id,
|
||||
COALESCE((SELECT MAX(l.attachment_id) FROM technician_item_status_logs l WHERE l.company_id=it.company_id AND l.barcode_id=ib.id),
|
||||
(SELECT MAX(ta.id) FROM transaction_attachments ta WHERE ta.entity_type='technician_installation' AND ta.entity_id=ib.id)) proof_id,
|
||||
DATE_FORMAT(it.created_at, '%d/%m/%Y') as tanggal
|
||||
")
|
||||
->from('item_technician it')
|
||||
->join('items i', 'i.id = it.item_id', 'left')
|
||||
->join('kode_barang k', 'k.id = i.kode_id', 'left')
|
||||
->join('item_barcodes ib', 'ib.barcode = it.barcode', 'left')
|
||||
->join('customers c', 'c.id = it.customer_id', 'left')
|
||||
->where('it.user_id', $user_id)
|
||||
->where('it.status', 'active');
|
||||
->where('it.status', 'active')
|
||||
->where('i.company_id', $this->companyId());
|
||||
|
||||
if (!empty($search)) {
|
||||
$this->db->group_start()
|
||||
@@ -424,8 +485,10 @@ class PeralatanTeknisi_model extends CI_Model {
|
||||
{
|
||||
$this->db
|
||||
->from('item_technician it')
|
||||
->join('items i', 'i.id = it.item_id', 'inner')
|
||||
->where('it.user_id', $user_id)
|
||||
->where('it.status', 'active');
|
||||
->where('it.status', 'active')
|
||||
->where('i.company_id', $this->companyId());
|
||||
|
||||
return $this->db->count_all_results();
|
||||
}
|
||||
@@ -437,7 +500,8 @@ class PeralatanTeknisi_model extends CI_Model {
|
||||
->join('items i', 'i.id = it.item_id', 'left')
|
||||
->join('item_barcodes ib', 'ib.barcode = it.barcode', 'left')
|
||||
->where('it.user_id', $user_id)
|
||||
->where('it.status', 'active');
|
||||
->where('it.status', 'active')
|
||||
->where('i.company_id', $this->companyId());
|
||||
|
||||
if (!empty($search)) {
|
||||
$this->db->group_start()
|
||||
@@ -469,9 +533,10 @@ class PeralatanTeknisi_model extends CI_Model {
|
||||
->join('item_barcodes ib', 'ib.id = im.barcode_id', 'left')
|
||||
->join('k_employees from_ke', 'from_ke.id = im.from_id', 'left')
|
||||
->join('k_employees to_ke', 'to_ke.id = im.to_id', 'left')
|
||||
->where('im.movement_type', 'installation')
|
||||
->where_in('im.movement_type', ['installation', 'transfer'])
|
||||
->where('im.from_type', 'technician')
|
||||
->where('im.to_type', 'technician')
|
||||
->where('i.company_id', $this->companyId())
|
||||
->order_by('im.created_at', 'DESC')
|
||||
->limit(200)
|
||||
->get()
|
||||
@@ -496,6 +561,7 @@ class PeralatanTeknisi_model extends CI_Model {
|
||||
->join('items i', 'i.id = it.item_id', 'left')
|
||||
->join('k_employees ke', 'ke.id = it.user_id', 'left')
|
||||
->where('it.barcode', $barcode)
|
||||
->where('i.company_id', $this->companyId())
|
||||
->get()
|
||||
->row();
|
||||
}
|
||||
@@ -515,7 +581,8 @@ class PeralatanTeknisi_model extends CI_Model {
|
||||
->join('items i', 'i.id = it.item_id', 'left')
|
||||
->join('item_barcodes ib', 'ib.barcode = it.barcode', 'left')
|
||||
->where('it.user_id', $user_id)
|
||||
->where('it.status', 'active');
|
||||
->where('it.status', 'active')
|
||||
->where('i.company_id', $this->companyId());
|
||||
|
||||
if ($tanggal AND $tanggal != 'all') {
|
||||
$this->db->where('DATE(it.created_at)', $tanggal);
|
||||
@@ -534,23 +601,108 @@ class PeralatanTeknisi_model extends CI_Model {
|
||||
|
||||
public function get_log_barang()
|
||||
{
|
||||
return $this->db
|
||||
return $this->get_log_barang_filtered(array());
|
||||
}
|
||||
|
||||
public function get_log_barang_filtered(array $filters)
|
||||
{
|
||||
$this->db
|
||||
->select("
|
||||
it.barcode,
|
||||
it.item_id,
|
||||
it.user_id,
|
||||
it.status,
|
||||
COALESCE(it.usage_status, 'carried') usage_status,
|
||||
COALESCE(it.assigned_qty,0) assigned_qty,
|
||||
COALESCE(it.carried_qty,0) carried_qty,
|
||||
COALESCE(it.installed_qty,0) installed_qty,
|
||||
it.usage_date,
|
||||
it.customer_id,
|
||||
it.usage_notes,
|
||||
it.created_at,
|
||||
it.deleted_at,
|
||||
ke.full_name as teknisi_name,
|
||||
ke.employee_code,
|
||||
c.nama customer_name,
|
||||
i.kode_detail as item_code,
|
||||
i.nama_barang
|
||||
i.nama_barang,
|
||||
ib.serial_number,
|
||||
ib.qty_sisa,
|
||||
(SELECT COUNT(*) FROM transaction_attachments ta WHERE ta.entity_type='technician_installation' AND ta.entity_id=ib.id) attachment_count
|
||||
")
|
||||
->from('item_technician it')
|
||||
->join('k_employees ke', 'ke.id = it.user_id', 'left')
|
||||
->join('items i', 'i.id = it.item_id', 'left')
|
||||
->join('item_barcodes ib', 'ib.barcode = it.barcode', 'left')
|
||||
->join('customers c', 'c.id = it.customer_id', 'left')
|
||||
->where('i.company_id', $this->companyId());
|
||||
if(!empty($filters['user_id']))$this->db->where('it.user_id',(int)$filters['user_id']);
|
||||
if(!empty($filters['customer_id']))$this->db->where('it.customer_id',(int)$filters['customer_id']);
|
||||
$status=trim((string)($filters['status']??''));
|
||||
if($status==='returned'){
|
||||
$this->db->where('it.status','inactive');
|
||||
}elseif($status==='installed'){
|
||||
$this->db->where('it.status','active')->where('it.installed_qty >',0);
|
||||
}elseif($status==='carried'){
|
||||
$this->db->where('it.status','active')->where('it.carried_qty >',0);
|
||||
}
|
||||
$from=trim((string)($filters['date_from']??''));$to=trim((string)($filters['date_to']??''));
|
||||
if($from!==''||$to!==''){
|
||||
$from=$from!==''?$from:'1900-01-01';$to=$to!==''?$to:'2999-12-31';
|
||||
$this->db->group_start()->where("DATE(it.created_at) BETWEEN ".$this->db->escape($from).' AND '.$this->db->escape($to),null,false)->or_where("it.usage_date BETWEEN ".$this->db->escape($from).' AND '.$this->db->escape($to),null,false)->or_where("DATE(it.deleted_at) BETWEEN ".$this->db->escape($from).' AND '.$this->db->escape($to),null,false)->group_end();
|
||||
}
|
||||
return $this->db
|
||||
->order_by('it.created_at', 'DESC')
|
||||
->get()
|
||||
->result();
|
||||
}
|
||||
|
||||
public function change_item_status($barcode,$userId,array $data,$actorId)
|
||||
{
|
||||
$barcode=trim((string)$barcode);$company=$this->companyId();$now=date('Y-m-d H:i:s');
|
||||
$this->db->trans_begin();
|
||||
try{
|
||||
$key=trim((string)($data['idempotency_key']??''));
|
||||
if($key!==''){$duplicate=$this->db->where(array('company_id'=>$company,'idempotency_key'=>$key))->get('technician_item_status_logs')->row();if($duplicate){$this->db->trans_commit();return array('duplicate'=>true,'log_id'=>(int)$duplicate->id,'qty'=>(float)$duplicate->qty,'status'=>$duplicate->to_status);}}
|
||||
$row=$this->db->query("SELECT it.*,ib.id barcode_id,ib.qty_sisa,ib.warehouse_id,i.nama_barang,e.full_name technician_name,COALESCE(k.tracking_type,'QTY') tracking_type FROM item_technician it JOIN item_barcodes ib ON ib.barcode=it.barcode JOIN items i ON i.id=it.item_id JOIN k_employees e ON e.id=it.user_id LEFT JOIN kode_barang k ON k.id=i.kode_id WHERE it.company_id=? AND it.user_id=? AND it.barcode=? AND it.status='active' FOR UPDATE",array($company,(int)$userId,$barcode))->row();
|
||||
if(!$row)throw new RuntimeException('Barang aktif pada teknisi tidak ditemukan.');
|
||||
|
||||
$target=(string)$data['status'];$tracking=strtoupper((string)$row->tracking_type)==='UNIT'?'UNIT':'QTY';
|
||||
$assigned=(float)$row->assigned_qty;$carried=(float)$row->carried_qty;$installed=(float)$row->installed_qty;
|
||||
if($assigned<=0){$assigned=(float)$row->qty_sisa;if(($row->usage_status??'carried')==='installed')$installed=$assigned;else$carried=$assigned;}
|
||||
$qty=$tracking==='UNIT'?1:(float)($data['qty']??0);
|
||||
if($qty<=0)throw new RuntimeException('Jumlah yang diubah wajib lebih dari 0.');
|
||||
|
||||
$source='';$customerId=null;$customerName='-';
|
||||
if($target==='installed'){$source='carried';$available=$carried;$customerId=(int)($data['customer_id']??0);if($customerId<1)throw new RuntimeException('Customer wajib dipilih untuk status Dipasang.');$customer=$this->db->select('id,nama')->where(array('id'=>$customerId,'company_id'=>$company))->get('customers')->row();if(!$customer)throw new RuntimeException('Customer tidak ditemukan pada perusahaan aktif.');$customerName=$customer->nama;if($installed>0&&!empty($row->customer_id)&&(int)$row->customer_id!==$customerId)throw new RuntimeException('Sebagian barcode ini sudah dipasang pada customer lain. Kembalikan dahulu ke teknisi sebelum memilih customer berbeda.');}
|
||||
elseif($target==='carried'){$source='installed';$available=$installed;$customerId=(int)$row->customer_id;if($customerId<1)throw new RuntimeException('Customer asal pemasangan tidak ditemukan.');$customer=$this->db->select('nama')->where(array('id'=>$customerId,'company_id'=>$company))->get('customers')->row();$customerName=$customer?$customer->nama:'-';}
|
||||
elseif($target==='warehouse'){$source=(string)($data['source_status']??'');if(!in_array($source,array('carried','installed'),true)){if($carried>0&&$installed<=0)$source='carried';elseif($installed>0&&$carried<=0)$source='installed';else throw new RuntimeException('Pilih asal barang yang akan dikembalikan ke gudang.');}$available=$source==='installed'?$installed:$carried;if($source==='installed'){$customerId=(int)$row->customer_id;$customer=$customerId?$this->db->select('nama')->where(array('id'=>$customerId,'company_id'=>$company))->get('customers')->row():null;$customerName=$customer?$customer->nama:'-';}}
|
||||
else throw new RuntimeException('Status tujuan tidak valid.');
|
||||
if($qty>$available+0.00001)throw new RuntimeException('Jumlah melebihi saldo status asal ('.number_format($available,4,',','.').').');
|
||||
|
||||
if($source==='carried')$carried-=$qty;else$installed-=$qty;
|
||||
if($target==='installed')$installed+=$qty;elseif($target==='carried')$carried+=$qty;else$assigned-=$qty;
|
||||
$carried=max(0,$carried);$installed=max(0,$installed);$assigned=max(0,$assigned);
|
||||
$usage=$installed>0&&$carried>0?'mixed':($installed>0?'installed':'carried');$inactive=$assigned<=0.00001;
|
||||
$update=array('assigned_qty'=>$assigned,'carried_qty'=>$carried,'installed_qty'=>$installed,'usage_status'=>$usage,'usage_date'=>$installed>0?($target==='installed'?$data['date']:$row->usage_date):null,'customer_id'=>$installed>0?$customerId:null,'usage_notes'=>$data['notes'],'updated_by'=>(int)$actorId,'updated_at'=>$now);
|
||||
if($inactive){$update['status']='inactive';$update['deleted_at']=$now;}
|
||||
$this->db->where(array('company_id'=>$company,'user_id'=>(int)$userId,'barcode'=>$barcode,'status'=>'active'))->update('item_technician',$update);
|
||||
|
||||
$labels=array('carried'=>'Dibawa Teknisi','installed'=>'Dipasang di Customer','warehouse'=>'Dikembalikan ke Gudang');
|
||||
$notes='[AUTO] Perubahan status peralatan | Barang '.$row->nama_barang.' | Barcode '.$row->barcode.' | Teknisi '.$row->technician_name.' | Dari '.$labels[$source].' ke '.$labels[$target].' | Qty '.number_format($qty,4,',','.').' | Tanggal '.$data['date'].' | Customer '.$customerName.' | Keterangan '.$data['notes'];
|
||||
$movement=array('item_id'=>$row->item_id,'barcode_id'=>$row->barcode_id,'qty'=>$qty,'from_type'=>$source==='installed'?'customer':'technician','from_id'=>$source==='installed'?$customerId:$row->user_id,'to_type'=>$target==='installed'?'customer':($target==='carried'?'technician':'warehouse'),'to_id'=>$target==='installed'?$customerId:($target==='carried'?$row->user_id:$row->warehouse_id),'movement_type'=>$target==='installed'?'installation':($target==='carried'?'uninstallation':'transfer'),'notes'=>mb_substr($notes,0,250),'created_at'=>$now);
|
||||
$this->db->insert('item_movements',$movement);
|
||||
$this->db->insert('technician_item_status_logs',array('company_id'=>$company,'user_id'=>(int)$userId,'item_id'=>$row->item_id,'barcode_id'=>$row->barcode_id,'barcode'=>$row->barcode,'from_status'=>$source,'to_status'=>$target==='warehouse'?'returned':$target,'qty'=>$qty,'customer_id'=>$customerId?:null,'event_date'=>$data['date'],'notes'=>$data['notes'],'idempotency_key'=>$key?:null,'created_by'=>(int)$actorId,'created_at'=>$now));
|
||||
$logId=(int)$this->db->insert_id();
|
||||
$this->db->where('id',$row->barcode_id)->update('item_barcodes',array('status'=>$inactive?'available':'installed'));
|
||||
if($this->db->trans_status()===false)throw new RuntimeException('Perubahan status barang gagal disimpan.');
|
||||
$this->db->trans_commit();
|
||||
return array('log_id'=>$logId,'barcode_id'=>(int)$row->barcode_id,'status'=>$target,'qty'=>$qty,'customer_name'=>$customerName,'technician_name'=>$row->technician_name,'remaining_qty'=>$assigned);
|
||||
}catch(Throwable$e){$this->db->trans_rollback();throw$e;}
|
||||
}
|
||||
|
||||
public function get_status_history($userId)
|
||||
{
|
||||
return $this->db->select('l.*,i.kode_detail,i.nama_barang,c.nama customer_name,u.nama actor_name')->from('technician_item_status_logs l')->join('items i','i.id=l.item_id','left')->join('customers c','c.id=l.customer_id','left')->join('users u','u.id=l.created_by','left')->where(array('l.company_id'=>$this->companyId(),'l.user_id'=>(int)$userId))->order_by('l.event_date','DESC')->order_by('l.id','DESC')->get()->result();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user