add new url scraping data and create tab data lists
This commit is contained in:
@@ -54,4 +54,86 @@ class PbgTask extends Model
|
||||
public function attachments(){
|
||||
return $this->hasMany(PbgTaskAttachment::class, 'pbg_task_id', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data lists associated with this PBG task (One to Many)
|
||||
* One pbg_task can have many data lists
|
||||
*/
|
||||
public function dataLists()
|
||||
{
|
||||
return $this->hasMany(PbgTaskDetailDataList::class, 'pbg_task_uuid', 'uuid');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get only data lists with files
|
||||
*/
|
||||
public function dataListsWithFiles()
|
||||
{
|
||||
return $this->hasMany(PbgTaskDetailDataList::class, 'pbg_task_uuid', 'uuid')
|
||||
->whereNotNull('file')
|
||||
->where('file', '!=', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data lists by status
|
||||
*/
|
||||
public function dataListsByStatus($status)
|
||||
{
|
||||
return $this->hasMany(PbgTaskDetailDataList::class, 'pbg_task_uuid', 'uuid')
|
||||
->where('status', $status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data lists by data type
|
||||
*/
|
||||
public function dataListsByType($dataType)
|
||||
{
|
||||
return $this->hasMany(PbgTaskDetailDataList::class, 'pbg_task_uuid', 'uuid')
|
||||
->where('data_type', $dataType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create or update data lists from API response
|
||||
*/
|
||||
public function syncDataLists(array $dataLists): void
|
||||
{
|
||||
foreach ($dataLists as $listData) {
|
||||
PbgTaskDetailDataList::updateOrCreate(
|
||||
['uid' => $listData['uid']],
|
||||
[
|
||||
'name' => $listData['name'] ?? null,
|
||||
'description' => $listData['description'] ?? null,
|
||||
'status' => $listData['status'] ?? null,
|
||||
'status_name' => $listData['status_name'] ?? null,
|
||||
'data_type' => $listData['data_type'] ?? null,
|
||||
'data_type_name' => $listData['data_type_name'] ?? null,
|
||||
'file' => $listData['file'] ?? null,
|
||||
'note' => $listData['note'] ?? null,
|
||||
'pbg_task_uuid' => $this->uuid,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data lists count by status
|
||||
*/
|
||||
public function getDataListsCountByStatusAttribute()
|
||||
{
|
||||
return $this->dataLists()
|
||||
->selectRaw('status, COUNT(*) as count')
|
||||
->groupBy('status')
|
||||
->pluck('count', 'status');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data lists count by data type
|
||||
*/
|
||||
public function getDataListsCountByTypeAttribute()
|
||||
{
|
||||
return $this->dataLists()
|
||||
->selectRaw('data_type, COUNT(*) as count')
|
||||
->groupBy('data_type')
|
||||
->pluck('count', 'data_type');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,6 +141,8 @@ class PbgTaskDetail extends Model
|
||||
return $this->belongsTo(PbgTask::class, 'pbg_task_uid', 'uuid');
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create or update PbgTaskDetail from API response
|
||||
*/
|
||||
@@ -249,4 +251,6 @@ class PbgTaskDetail extends Model
|
||||
$detailData
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
161
app/Models/PbgTaskDetailDataList.php
Normal file
161
app/Models/PbgTaskDetailDataList.php
Normal file
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class PbgTaskDetailDataList extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'pbg_task_detail_data_lists';
|
||||
|
||||
protected $fillable = [
|
||||
'uid',
|
||||
'name',
|
||||
'description',
|
||||
'status',
|
||||
'status_name',
|
||||
'data_type',
|
||||
'data_type_name',
|
||||
'file',
|
||||
'note',
|
||||
'pbg_task_uuid',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'status' => 'integer',
|
||||
'data_type' => 'integer',
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
];
|
||||
|
||||
/**
|
||||
* Relationship to PbgTask (Many to One)
|
||||
* Many data lists belong to one pbg_task
|
||||
*/
|
||||
public function pbgTask()
|
||||
{
|
||||
return $this->belongsTo(PbgTask::class, 'pbg_task_uuid', 'uuid');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the full file path
|
||||
*/
|
||||
public function getFilePathAttribute()
|
||||
{
|
||||
return $this->file ? storage_path('app/public/' . $this->file) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file URL
|
||||
*/
|
||||
public function getFileUrlAttribute()
|
||||
{
|
||||
return $this->file ? asset('storage/' . $this->file) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if file exists
|
||||
*/
|
||||
public function hasFile()
|
||||
{
|
||||
return !empty($this->file) && file_exists($this->getFilePathAttribute());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get status badge color based on status
|
||||
*/
|
||||
public function getStatusBadgeAttribute()
|
||||
{
|
||||
return match($this->status) {
|
||||
1 => 'success', // Sesuai
|
||||
0 => 'danger', // Tidak Sesuai
|
||||
default => 'secondary'
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope: Filter by status
|
||||
*/
|
||||
public function scopeByStatus($query, $status)
|
||||
{
|
||||
return $query->where('status', $status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope: Filter by data type
|
||||
*/
|
||||
public function scopeByDataType($query, $dataType)
|
||||
{
|
||||
return $query->where('data_type', $dataType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope: With files only
|
||||
*/
|
||||
public function scopeWithFiles($query)
|
||||
{
|
||||
return $query->whereNotNull('file')->where('file', '!=', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope: Search by name or description
|
||||
*/
|
||||
public function scopeSearch($query, $search)
|
||||
{
|
||||
return $query->where(function ($q) use ($search) {
|
||||
$q->where('name', 'LIKE', "%{$search}%")
|
||||
->orWhere('description', 'LIKE', "%{$search}%")
|
||||
->orWhere('status_name', 'LIKE', "%{$search}%")
|
||||
->orWhere('data_type_name', 'LIKE', "%{$search}%");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file extension from file path
|
||||
*/
|
||||
public function getFileExtensionAttribute()
|
||||
{
|
||||
if (!$this->file) {
|
||||
return null;
|
||||
}
|
||||
return strtoupper(pathinfo($this->file, PATHINFO_EXTENSION));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get filename from file path
|
||||
*/
|
||||
public function getFileNameAttribute()
|
||||
{
|
||||
if (!$this->file) {
|
||||
return null;
|
||||
}
|
||||
return basename($this->file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get formatted created date
|
||||
*/
|
||||
public function getFormattedCreatedAtAttribute()
|
||||
{
|
||||
return $this->created_at ? $this->created_at->format('d M Y, H:i') : '-';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get truncated description
|
||||
*/
|
||||
public function getTruncatedDescriptionAttribute()
|
||||
{
|
||||
return $this->description ? \Str::limit($this->description, 80) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get truncated note
|
||||
*/
|
||||
public function getTruncatedNoteAttribute()
|
||||
{
|
||||
return $this->note ? \Str::limit($this->note, 100) : null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user