Compare commits
34 Commits
feature/um
...
feat/sync-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
154b7f40df | ||
|
|
59e9431b2d | ||
|
|
074edc607d | ||
|
|
625d182d81 | ||
|
|
4d32d4a110 | ||
|
|
ac2f37d549 | ||
|
|
a9afb47f08 | ||
|
|
9efb6c346e | ||
|
|
6ba62da5ca | ||
|
|
ba95c185de | ||
|
|
b4b34b503e | ||
|
|
1a15bc03f8 | ||
|
|
2bf4b8b327 | ||
|
|
cb90f69d1e | ||
|
|
6307417ae3 | ||
|
|
55dc0751d3 | ||
|
|
97ffd322a1 | ||
|
|
6fb59e58e9 | ||
|
|
7e99d547c8 | ||
|
|
65f82c9bfd | ||
|
|
44ebc20d3c | ||
|
|
b60bbd4290 | ||
|
|
29b705b59c | ||
|
|
95ab8eff7f | ||
|
|
bfc2f7f1f9 | ||
|
|
50f1757a64 | ||
|
|
d54edb7783 | ||
|
|
3309664bae | ||
|
|
4eac6ab83d | ||
|
|
604e0d8479 | ||
|
|
99e99fa2e6 | ||
|
|
ff324014f6 | ||
|
|
7d06e12de8 | ||
|
|
f38d518f96 |
@@ -4,6 +4,7 @@ APP_KEY=
|
|||||||
APP_DEBUG=true
|
APP_DEBUG=true
|
||||||
APP_TIMEZONE=UTC
|
APP_TIMEZONE=UTC
|
||||||
APP_URL=http://localhost
|
APP_URL=http://localhost
|
||||||
|
API_URL=http://localhost:8000
|
||||||
|
|
||||||
APP_LOCALE=en
|
APP_LOCALE=en
|
||||||
APP_FALLBACK_LOCALE=en
|
APP_FALLBACK_LOCALE=en
|
||||||
@@ -65,6 +66,5 @@ AWS_USE_PATH_STYLE_ENDPOINT=false
|
|||||||
|
|
||||||
VITE_APP_NAME="${APP_NAME}"
|
VITE_APP_NAME="${APP_NAME}"
|
||||||
|
|
||||||
SIMBG_HOST="xxxxxx"
|
API_KEY_GOOGLE="xxxxx"
|
||||||
SIMBG_EMAIL="xxxxxx"
|
SPREAD_SHEET_ID="xxxxx"
|
||||||
SIMBG_PASSWORD="xxxxx"
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Console\Commands;
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
use App\ServiceSIMBG;
|
use App\Services\ServiceSIMBG;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use \Illuminate\Support\Facades\Log;
|
use \Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
@@ -25,10 +25,16 @@ class ExecuteScraping extends Command
|
|||||||
/**
|
/**
|
||||||
* Execute the console command.
|
* Execute the console command.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
private $service_simbg;
|
||||||
|
|
||||||
|
public function __construct(ServiceSIMBG $service_simbg){
|
||||||
|
$this->service_simbg = $service_simbg;
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
Log::info("running scheduler daily scraping");
|
Log::info("running scheduler daily scraping");
|
||||||
$service = new ServiceSIMBG();
|
$this->service_simbg->syncTaskList();
|
||||||
$service->syncTaskList();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,63 +11,162 @@ class DashboardController extends Controller
|
|||||||
{
|
{
|
||||||
use GlobalApiResponse;
|
use GlobalApiResponse;
|
||||||
|
|
||||||
public function businnessDocument(Request $request){
|
public function businnessDocument(Request $request)
|
||||||
$businessData = DB::table('pbg_task')
|
{
|
||||||
->leftJoin('pbg_task_retributions', 'pbg_task.uuid', '=', 'pbg_task_retributions.pbg_task_uid')
|
$request->validate([
|
||||||
->select(
|
"year" => "required|integer"
|
||||||
DB::raw('COUNT(DISTINCT pbg_task.id) as task_count'),
|
]);
|
||||||
DB::raw('SUM(pbg_task_retributions.nilai_retribusi_bangunan) as total_retribution')
|
|
||||||
)
|
$current_year = $request->get('year');
|
||||||
->where(function ($query) {
|
|
||||||
$query->where("pbg_task.function_type", "LIKE", "sebagai tempat usaha%");
|
$startOfYear = "$current_year-01-01 00:00:00";
|
||||||
})
|
$endOfYear = "$current_year-12-31 23:59:59";
|
||||||
->first();
|
$query = once(function () use ($startOfYear, $endOfYear) {
|
||||||
$taskCount = $businessData->task_count;
|
return DB::table('pbg_task AS pt')
|
||||||
$taskTotal = $businessData->total_retribution;
|
->leftJoin('pbg_task_google_sheet AS ptgs', 'pt.registration_number', '=', 'ptgs.no_registrasi')
|
||||||
$result = [
|
->leftJoin('pbg_task_retributions AS ptr', 'pt.uuid', '=', 'ptr.pbg_task_uid')
|
||||||
|
->whereBetween("pt.task_created_at", [$startOfYear, $endOfYear])
|
||||||
|
->where(function ($query) {
|
||||||
|
$query->whereRaw('LOWER(TRIM(ptgs.status_verifikasi)) != ?', [strtolower(trim('Selesai Verifikasi'))])
|
||||||
|
->orWhereNull('ptgs.status_verifikasi');
|
||||||
|
})
|
||||||
|
->where(function ($query) {
|
||||||
|
$query->whereRaw('LOWER(TRIM(pt.function_type)) = ?', [strtolower(trim('Sebagai Tempat Usaha'))]);
|
||||||
|
})
|
||||||
|
->selectRaw('COUNT(pt.id) AS total_data,
|
||||||
|
SUM(ptr.nilai_retribusi_bangunan) AS total_retribution')
|
||||||
|
->first();
|
||||||
|
});
|
||||||
|
|
||||||
|
$taskCount = $query->total_data ?? 0;
|
||||||
|
$taskTotal = $query->total_retribution ?? 0;
|
||||||
|
|
||||||
|
return $this->resSuccess([
|
||||||
"count" => $taskCount,
|
"count" => $taskCount,
|
||||||
"series" => [$taskCount],
|
|
||||||
"total" => $taskTotal
|
"total" => $taskTotal
|
||||||
];
|
]);
|
||||||
return $this->resSuccess($result);
|
|
||||||
}
|
}
|
||||||
public function nonBusinnessDocument(Request $request){
|
public function nonBusinnessDocument(Request $request){
|
||||||
$businessData = DB::table('pbg_task')
|
$request->validate([
|
||||||
->leftJoin('pbg_task_retributions', 'pbg_task.uuid', '=', 'pbg_task_retributions.pbg_task_uid')
|
"year" => "required|integer"
|
||||||
->select(
|
]);
|
||||||
DB::raw('COUNT(DISTINCT pbg_task.id) as task_count'),
|
|
||||||
DB::raw('SUM(pbg_task_retributions.nilai_retribusi_bangunan) as total_retribution')
|
$current_year = $request->get('year');
|
||||||
)
|
|
||||||
|
$startOfYear = "$current_year-01-01 00:00:00";
|
||||||
|
$endOfYear = "$current_year-12-31 23:59:59";
|
||||||
|
|
||||||
|
$query = once( function () use ($startOfYear, $endOfYear) {
|
||||||
|
return DB::table('pbg_task AS pt')
|
||||||
|
->leftJoin('pbg_task_google_sheet AS ptgs', 'pt.registration_number', '=', 'ptgs.no_registrasi')
|
||||||
|
->leftJoin('pbg_task_retributions AS ptr', 'pt.uuid', '=', 'ptr.pbg_task_uid') // Join ke pbg_task_retributions
|
||||||
|
->whereBetween("pt.task_created_at", [$startOfYear, $endOfYear])
|
||||||
->where(function ($query) {
|
->where(function ($query) {
|
||||||
$query->where("pbg_task.function_type", "NOT LIKE", "sebagai tempat usaha%")
|
$query->whereRaw('LOWER(TRIM(ptgs.status_verifikasi)) != ?', [strtolower(trim('Selesai Verifikasi'))])
|
||||||
->orWhereNull("pbg_task.function_type");
|
->orWhereNull('ptgs.status_verifikasi'); // Include NULL values
|
||||||
})
|
})
|
||||||
|
->where(function ($query) {
|
||||||
|
$query->whereRaw('LOWER(TRIM(pt.function_type)) != ?', [strtolower(trim('Sebagai Tempat Usaha'))])
|
||||||
|
->orWhereNull('pt.function_type'); // Include NULL values
|
||||||
|
})
|
||||||
|
->selectRaw('COUNT(pt.id) AS total_data,
|
||||||
|
SUM(ptr.nilai_retribusi_bangunan) AS total_retribution') // Menambahkan SUM dari pbg_task_retributions
|
||||||
->first();
|
->first();
|
||||||
$taskCount = $businessData->task_count;
|
});
|
||||||
$taskTotal = $businessData->total_retribution;
|
$taskCount = $query->total_data ?? 0;
|
||||||
$result = [
|
$taskTotal = $query->total_retribution ?? 0;
|
||||||
|
return $this->resSuccess([
|
||||||
"count" => $taskCount,
|
"count" => $taskCount,
|
||||||
"series" => [$taskCount],
|
|
||||||
"total" => $taskTotal
|
"total" => $taskTotal
|
||||||
];
|
]);
|
||||||
return $this->resSuccess($result);
|
|
||||||
}
|
}
|
||||||
public function allTaskDocuments(){
|
public function allTaskDocuments(Request $request){
|
||||||
$query = DB::table('pbg_task')
|
$request->validate([
|
||||||
->leftJoin('pbg_task_retributions', 'pbg_task.uuid', '=', 'pbg_task_retributions.pbg_task_uid')
|
"year" => "required|integer"
|
||||||
|
]);
|
||||||
|
|
||||||
|
$current_year = $request->get('year');
|
||||||
|
|
||||||
|
$startOfYear = "$current_year-01-01 00:00:00";
|
||||||
|
$endOfYear = "$current_year-12-31 23:59:59";
|
||||||
|
$query = once( function () use ($startOfYear, $endOfYear) {
|
||||||
|
return DB::table('pbg_task as pt')
|
||||||
|
->leftJoin('pbg_task_retributions as ptr', 'pt.uuid', '=', 'ptr.pbg_task_uid')
|
||||||
|
->whereBetween("pt.task_created_at", [$startOfYear, $endOfYear])
|
||||||
->select(
|
->select(
|
||||||
DB::raw('COUNT(DISTINCT pbg_task.id) as task_count'),
|
DB::raw('COUNT(DISTINCT pt.id) as task_count'),
|
||||||
DB::raw('SUM(pbg_task_retributions.nilai_retribusi_bangunan) as total_retribution')
|
DB::raw('SUM(ptr.nilai_retribusi_bangunan) as total_retribution')
|
||||||
)
|
)
|
||||||
->first();
|
->first();
|
||||||
$taskCount = $query->task_count;
|
});
|
||||||
$taskTotal = $query->total_retribution;
|
$taskCount = $query->task_count ?? 0;
|
||||||
$result = [
|
$taskTotal = $query->total_retribution ?? 0;
|
||||||
|
return $this->resSuccess([
|
||||||
"count" => $taskCount,
|
"count" => $taskCount,
|
||||||
"series" => [$taskCount],
|
|
||||||
"total" => $taskTotal
|
"total" => $taskTotal
|
||||||
];
|
]);
|
||||||
return $this->resSuccess($result);
|
}
|
||||||
|
|
||||||
|
public function verificationDocuments(Request $request){
|
||||||
|
$request->validate([
|
||||||
|
"year" => "required|integer"
|
||||||
|
]);
|
||||||
|
|
||||||
|
$current_year = $request->get('year');
|
||||||
|
|
||||||
|
$startOfYear = "$current_year-01-01 00:00:00";
|
||||||
|
$endOfYear = "$current_year-12-31 23:59:59";
|
||||||
|
$query = once( function () use ($startOfYear, $endOfYear){
|
||||||
|
return DB::table('pbg_task AS pt')
|
||||||
|
->leftJoin('pbg_task_google_sheet AS ptgs', 'pt.registration_number', '=', 'ptgs.no_registrasi')
|
||||||
|
->leftJoin('pbg_task_retributions AS ptr', 'pt.uuid', '=', 'ptr.pbg_task_uid')
|
||||||
|
->whereBetween("pt.task_created_at", [$startOfYear, $endOfYear])
|
||||||
|
->whereRaw('LOWER(TRIM(ptgs.status_verifikasi)) = ?', [strtolower(trim('Selesai Verifikasi'))])
|
||||||
|
->selectRaw('COUNT(pt.id) AS total_data,
|
||||||
|
SUM(ptr.nilai_retribusi_bangunan) AS total_retribution')
|
||||||
|
->first();
|
||||||
|
});
|
||||||
|
|
||||||
|
$taskCount = $query->total_data ?? 0;
|
||||||
|
$taskTotal = $query->total_retribution ?? 0;
|
||||||
|
|
||||||
|
return $this->resSuccess([
|
||||||
|
"count"=> $taskCount,
|
||||||
|
"total"=> $taskTotal
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function nonVerificationDocuments(Request $request){
|
||||||
|
$request->validate([
|
||||||
|
"year" => "required|integer"
|
||||||
|
]);
|
||||||
|
|
||||||
|
$current_year = $request->get('year');
|
||||||
|
|
||||||
|
$startOfYear = "$current_year-01-01 00:00:00";
|
||||||
|
$endOfYear = "$current_year-12-31 23:59:59";
|
||||||
|
|
||||||
|
$query = once(function () use ($startOfYear, $endOfYear) {
|
||||||
|
return DB::table('pbg_task AS pt')
|
||||||
|
->leftJoin('pbg_task_google_sheet AS ptgs', 'pt.registration_number', '=', 'ptgs.no_registrasi')
|
||||||
|
->leftJoin('pbg_task_retributions AS ptr', 'pt.uuid', '=', 'ptr.pbg_task_uid') // Join tabel pbg_task_retributions
|
||||||
|
->whereBetween("pt.task_created_at", [$startOfYear, $endOfYear])
|
||||||
|
->where(function ($query) {
|
||||||
|
$query->whereRaw('LOWER(TRIM(ptgs.status_verifikasi)) != ?', [strtolower(trim('Selesai Verifikasi'))])
|
||||||
|
->orWhereNull('ptgs.status_verifikasi'); // Include NULL values
|
||||||
|
})
|
||||||
|
->selectRaw('COUNT(pt.id) AS total_data,
|
||||||
|
SUM(ptr.nilai_retribusi_bangunan) AS total_retribution') // Menambahkan SUM dari pbg_task_retributions
|
||||||
|
->first();
|
||||||
|
});
|
||||||
|
|
||||||
|
$taskCount = $query->total_data ?? 0;
|
||||||
|
$taskTotal = $query->total_retribution ?? 0;
|
||||||
|
|
||||||
|
return $this->resSuccess([
|
||||||
|
"count"=> $taskCount,
|
||||||
|
"total"=> $taskTotal
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function pbgTaskDocuments(Request $request){
|
public function pbgTaskDocuments(Request $request){
|
||||||
|
|||||||
104
app/Http/Controllers/Api/DataSettingController.php
Normal file
104
app/Http/Controllers/Api/DataSettingController.php
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Requests\DataSettingRequest;
|
||||||
|
use App\Http\Resources\DataSettingResource;
|
||||||
|
use App\Models\DataSetting;
|
||||||
|
use App\Traits\GlobalApiResponse;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class DataSettingController extends Controller
|
||||||
|
{
|
||||||
|
use GlobalApiResponse;
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$query = DataSetting::query()->orderBy('id', 'desc');
|
||||||
|
if ($request->has("search") && !empty($request->get("search"))) {
|
||||||
|
$query = $query->where("key", $request->get("search"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return DataSettingResource::collection($query->paginate());
|
||||||
|
} catch (Exception $e) {
|
||||||
|
return $this->resError($e->getMessage(), $e->getTrace());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*/
|
||||||
|
public function store(DataSettingRequest $request)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$data = DataSetting::create($request->validated());
|
||||||
|
$result = [
|
||||||
|
"success" => true,
|
||||||
|
"message" => "Data Setting created successfully",
|
||||||
|
"data" => new DataSettingResource($data)
|
||||||
|
];
|
||||||
|
return $this->resSuccess($result);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
return $this->resError($e->getMessage(), $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*/
|
||||||
|
public function show(string $id)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$setting = DataSetting::findOrFail($id);
|
||||||
|
$result = [
|
||||||
|
"setting" => true,
|
||||||
|
"message" => "Data setting successfully",
|
||||||
|
"data" => new DataSettingResource($setting)
|
||||||
|
];
|
||||||
|
return $this->resSuccess($result);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
return $this->resError($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*/
|
||||||
|
public function update(DataSettingRequest $request, string $id)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$data = DataSetting::findOrFail($id);
|
||||||
|
$data->update($request->validated());
|
||||||
|
$result = [
|
||||||
|
"success" => true,
|
||||||
|
"message" => "Data Setting updated successfully"
|
||||||
|
];
|
||||||
|
return $this->resSuccess($result);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
return $this->resError($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*/
|
||||||
|
public function destroy(string $id)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$setting = DataSetting::findOrFail($id);
|
||||||
|
$setting->delete();
|
||||||
|
$result = [
|
||||||
|
"success" => true,
|
||||||
|
"message" => "Data Setting deleted successfully"
|
||||||
|
];
|
||||||
|
return $this->resSuccess($result);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
return $this->resError($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
61
app/Http/Controllers/Api/GoogleSheetController.php
Normal file
61
app/Http/Controllers/Api/GoogleSheetController.php
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Services\GoogleSheetService;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class GoogleSheetController extends Controller
|
||||||
|
{
|
||||||
|
protected $googleSheetService;
|
||||||
|
public function __construct(GoogleSheetService $googleSheetService){
|
||||||
|
$this->googleSheetService = $googleSheetService;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$dataCollection = $this->googleSheetService->getSheetDataCollection();
|
||||||
|
$result = [
|
||||||
|
"last_row" => $this->googleSheetService->getLastRowByColumn("C"),
|
||||||
|
"last_column" => $this->googleSheetService->getLastColumn(),
|
||||||
|
"header" => $this->googleSheetService->getHeader(),
|
||||||
|
"data_collection" => $dataCollection
|
||||||
|
];
|
||||||
|
return response()->json($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*/
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*/
|
||||||
|
public function show(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*/
|
||||||
|
public function update(Request $request, string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*/
|
||||||
|
public function destroy(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
56
app/Http/Controllers/Api/MenusController.php
Normal file
56
app/Http/Controllers/Api/MenusController.php
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Menu;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class MenusController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$query = Menu::query();
|
||||||
|
|
||||||
|
if($request->has("search") && !empty($request->get("search"))){
|
||||||
|
$query = $query->where("name", "like", "%".$request->get("search")."%");
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json($query->paginate());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*/
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*/
|
||||||
|
public function show(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*/
|
||||||
|
public function update(Request $request, string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*/
|
||||||
|
public function destroy(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
363
app/Http/Controllers/Api/PbgTaskController.php
Normal file
363
app/Http/Controllers/Api/PbgTaskController.php
Normal file
@@ -0,0 +1,363 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Enums\ImportDatasourceStatus;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Requests\PbgTaskMultiStepRequest;
|
||||||
|
use App\Http\Resources\PbgTaskResource;
|
||||||
|
use App\Models\DataSetting;
|
||||||
|
use App\Models\ImportDatasource;
|
||||||
|
use App\Models\PbgTask;
|
||||||
|
use App\Models\PbgTaskGoogleSheet;
|
||||||
|
use App\Services\GoogleSheetService;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class PbgTaskController extends Controller
|
||||||
|
{
|
||||||
|
protected $googleSheetService;
|
||||||
|
public function __construct(GoogleSheetService $googleSheetService){
|
||||||
|
$this->googleSheetService = $googleSheetService;
|
||||||
|
}
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*/
|
||||||
|
public function store(PbgTaskMultiStepRequest $request)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$data = PbgTask::create([
|
||||||
|
"uuid" => $request->input("step1Form.uuid"),
|
||||||
|
"name" => $request->input("step1Form.name"),
|
||||||
|
"owner_name" => $request->input("step1Form.owner_name"),
|
||||||
|
"application_type" => $request->input("step1Form.application_type"),
|
||||||
|
"application_type_name" => $request->input("step1Form.application_type_name"),
|
||||||
|
"condition" => $request->input("step1Form.condition"),
|
||||||
|
"registration_number" => $request->input("step1Form.registration_number"),
|
||||||
|
"document_number" => $request->input("step1Form.document_number"),
|
||||||
|
"address" => $request->input("step1Form.address"),
|
||||||
|
"status" => $request->input("step1Form.status"),
|
||||||
|
"status_name" => $request->input("step1Form.status_name"),
|
||||||
|
"slf_status" => $request->input("step1Form.slf_status"),
|
||||||
|
"slf_status_name" => $request->input("step1Form.slf_status_name"),
|
||||||
|
"function_type" => $request->input("step1Form.function_type"),
|
||||||
|
"consultation_type" => $request->input("step1Form.consultation_type"),
|
||||||
|
"due_date" => $request->input("step1Form.due_date"),
|
||||||
|
"land_certificate_phase" => $request->input("step1Form.land_certificate_phase"),
|
||||||
|
"task_created_at" => $request->input("step1Form.task_created_at"),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
"success" => true,
|
||||||
|
"message" => "Step 1 berhasil disimpan!",
|
||||||
|
"data" => $data
|
||||||
|
], 201);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return response()->json([
|
||||||
|
"success" => false,
|
||||||
|
"message" => "Gagal menyimpan data",
|
||||||
|
"error" => $e->getMessage()
|
||||||
|
], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*/
|
||||||
|
public function show(string $id)
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
$pbg_task = PbgTask::with(['pbg_task_retributions','pbg_task_index_integrations','pbg_task_retributions.pbg_task_prasarana'])->findOrFail($id);
|
||||||
|
return response()->json([
|
||||||
|
"success"=> true,
|
||||||
|
"message"=> "Data ditemukan",
|
||||||
|
"data"=> $pbg_task
|
||||||
|
]);
|
||||||
|
}catch(\Exception $e){
|
||||||
|
return response()->json([
|
||||||
|
"success"=> false,
|
||||||
|
"message"=> $e->getMessage(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*/
|
||||||
|
public function update(Request $request, string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*/
|
||||||
|
public function destroy(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function validatePbgTask(Request $request){
|
||||||
|
return $request->validate([
|
||||||
|
"uuid" => $request->input("step1Form.uuid"),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function syncPbgFromGoogleSheet(){
|
||||||
|
$import_datasource = ImportDatasource::create([
|
||||||
|
"message" => "initialization",
|
||||||
|
"response_body" => null,
|
||||||
|
"status" => ImportDatasourceStatus::Processing->value,
|
||||||
|
]);
|
||||||
|
try{
|
||||||
|
$totalRowCount = $this->googleSheetService->getLastRowByColumn("C");
|
||||||
|
$sheetData = $this->googleSheetService->getSheetDataCollection($totalRowCount);
|
||||||
|
$sheet_big_data = $this->googleSheetService->get_data_by_sheet();
|
||||||
|
$data_setting_result = []; // Initialize result storage
|
||||||
|
|
||||||
|
$found_section = null; // Track which section is found
|
||||||
|
|
||||||
|
foreach ($sheet_big_data as $row) {
|
||||||
|
// Check for section headers
|
||||||
|
if (in_array("•PROSES PENERBITAN:", $row)) {
|
||||||
|
$found_section = "MENUNGGU_KLIK_DPMPTSP";
|
||||||
|
} elseif (in_array("•BERKAS AKTUAL TERVERIFIKASI DINAS TEKNIS 2024:", $row)) {
|
||||||
|
$found_section = "REALISASI_TERBIT_PBG";
|
||||||
|
} elseif (in_array("•TERPROSES DI DPUTR: belum selesai rekomtek'", $row)) {
|
||||||
|
$found_section = "PROSES_DINAS_TEKNIS";
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a section is found and we reach "Grand Total", save the corresponding values
|
||||||
|
if ($found_section && isset($row[0]) && trim($row[0]) === "Grand Total") {
|
||||||
|
if ($found_section === "MENUNGGU_KLIK_DPMPTSP") {
|
||||||
|
$data_setting_result["MENUNGGU_KLIK_DPMPTSP_COUNT"] = $row[2] ?? null;
|
||||||
|
$data_setting_result["MENUNGGU_KLIK_DPMPTSP_SUM"] = $row[3] ?? null;
|
||||||
|
} elseif ($found_section === "REALISASI_TERBIT_PBG") {
|
||||||
|
$data_setting_result["REALISASI_TERBIT_PBG_COUNT"] = $row[2] ?? null;
|
||||||
|
$data_setting_result["REALISASI_TERBIT_PBG_SUM"] = $row[4] ?? null;
|
||||||
|
} elseif ($found_section === "PROSES_DINAS_TEKNIS") {
|
||||||
|
$data_setting_result["PROSES_DINAS_TEKNIS_COUNT"] = $row[2] ?? null;
|
||||||
|
$data_setting_result["PROSES_DINAS_TEKNIS_SUM"] = $row[3] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset section tracking after capturing "Grand Total"
|
||||||
|
$found_section = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($data_setting_result as $key => $value) {
|
||||||
|
DataSetting::updateOrInsert(
|
||||||
|
["key" => $key], // Find by key
|
||||||
|
["value" => $value] // Update or insert value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$mapToUpsert = [];
|
||||||
|
$count = 0;
|
||||||
|
|
||||||
|
foreach($sheetData as $data){
|
||||||
|
$mapToUpsert[] =
|
||||||
|
[
|
||||||
|
'no_registrasi' => $data['no__registrasi'] ?? null,
|
||||||
|
'jenis_konsultasi' => $data['jenis_konsultasi'] ?? null,
|
||||||
|
'fungsi_bg' => $data['fungsi_bg'] ?? null,
|
||||||
|
'tgl_permohonan' => $this->convertToDate($data['tgl_permohonan']),
|
||||||
|
'status_verifikasi' => $data['status_verifikasi'] ?? null,
|
||||||
|
'status_permohonan' => $this->convertToDate($data['status_permohonan']),
|
||||||
|
'alamat_pemilik' => $data['alamat_pemilik'] ?? null,
|
||||||
|
'no_hp' => $data['no__hp'] ?? null,
|
||||||
|
'email' => $data['e_mail'] ?? null,
|
||||||
|
'tanggal_catatan' => $this->convertToDate($data['tanggal_catatan']),
|
||||||
|
'catatan_kekurangan_dokumen' => $data['catatan_kekurangan_dokumen'] ?? null,
|
||||||
|
'gambar' => $data['gambar'] ?? null,
|
||||||
|
'krk_kkpr' => $data['krk_kkpr'] ?? null,
|
||||||
|
'no_krk' => $data['no__krk'] ?? null,
|
||||||
|
'lh' => $data['lh'] ?? null,
|
||||||
|
'ska' => $data['ska'] ?? null,
|
||||||
|
'keterangan' => $data['keterangan'] ?? null,
|
||||||
|
'helpdesk' => $data['helpdesk'] ?? null,
|
||||||
|
'pj' => $data['pj'] ?? null,
|
||||||
|
'kepemilikan' => $data['kepemilikan'] ?? null,
|
||||||
|
'potensi_taru' => $data['potensi_taru'] ?? null,
|
||||||
|
'validasi_dinas' => $data['validasi_dinas'] ?? null,
|
||||||
|
'kategori_retribusi' => $data['kategori_retribusi'] ?? null,
|
||||||
|
'no_urut_ba_tpt' => $data['no__urut_ba_tpt__2024_0001_'] ?? null,
|
||||||
|
'tanggal_ba_tpt' => $this->convertToDate($data['tanggal_ba_tpt']),
|
||||||
|
'no_urut_ba_tpa' => $data['no__urut_ba_tpa'] ?? null,
|
||||||
|
'tanggal_ba_tpa' => $this->convertToDate($data['tanggal_ba_tpa']),
|
||||||
|
'no_urut_skrd' => $data['no__urut_skrd__2024_0001_'] ?? null,
|
||||||
|
'tanggal_skrd' => $this->convertToDate($data['tanggal_skrd']),
|
||||||
|
'ptsp' => $data['ptsp'] ?? null,
|
||||||
|
'selesai_terbit' => $data['selesai_terbit'] ?? null,
|
||||||
|
'tanggal_pembayaran' => $this->convertToDate($data['tanggal_pembayaran__yyyy_mm_dd_']),
|
||||||
|
'format_sts' => $data['format_sts'] ?? null,
|
||||||
|
'tahun_terbit' => (int) $data['tahun_terbit'] ?? null,
|
||||||
|
'tahun_berjalan' => (int) $data['tahun_berjalan'] ?? null,
|
||||||
|
'kelurahan' => $data['kelurahan'] ?? null,
|
||||||
|
'kecamatan' => $data['kecamatan'] ?? null,
|
||||||
|
'lb' => $this->convertToDecimal($data['lb']) ?? null,
|
||||||
|
'tb' => $this->convertToDecimal($data['tb']) ?? null,
|
||||||
|
'jlb' => (int) $data['jlb'] ?? null,
|
||||||
|
'unit' => (int) $data['unit'] ?? null,
|
||||||
|
'usulan_retribusi' => (int) $data['usulan_retribusi'] ?? null,
|
||||||
|
'nilai_retribusi_keseluruhan_simbg' => $this->convertToDecimal($data['nilai_retribusi_keseluruhan__simbg_']) ?? null,
|
||||||
|
'nilai_retribusi_keseluruhan_pad' => $this->convertToDecimal($data['nilai_retribusi_keseluruhan__pad_']) ?? null,
|
||||||
|
'denda' => $this->convertToDecimal($data['denda']) ?? null,
|
||||||
|
'latitude' => $data['latitude'] ?? null,
|
||||||
|
'longitude' => $data['longitude'] ?? null,
|
||||||
|
'nik_nib' => $data['nik_nib'] ?? null,
|
||||||
|
'dok_tanah' => $data['dok__tanah'] ?? null,
|
||||||
|
'temuan' => $data['temuan'] ?? null,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
DB::beginTransaction();
|
||||||
|
|
||||||
|
$batchSize = 1000;
|
||||||
|
$chunks = array_chunk($mapToUpsert, $batchSize);
|
||||||
|
|
||||||
|
foreach($chunks as $chunk){
|
||||||
|
PbgTaskGoogleSheet::upsert($chunk, ["no_registrasi"],[
|
||||||
|
'jenis_konsultasi',
|
||||||
|
'nama_pemilik',
|
||||||
|
'lokasi_bg',
|
||||||
|
'fungsi_bg',
|
||||||
|
'nama_bangunan',
|
||||||
|
'tgl_permohonan',
|
||||||
|
'status_verifikasi',
|
||||||
|
'status_permohonan',
|
||||||
|
'alamat_pemilik',
|
||||||
|
'no_hp',
|
||||||
|
'email',
|
||||||
|
'tanggal_catatan',
|
||||||
|
'catatan_kekurangan_dokumen',
|
||||||
|
'gambar',
|
||||||
|
'krk_kkpr',
|
||||||
|
'no_krk',
|
||||||
|
'lh',
|
||||||
|
'ska',
|
||||||
|
'keterangan',
|
||||||
|
'helpdesk',
|
||||||
|
'pj',
|
||||||
|
'kepemilikan',
|
||||||
|
'potensi_taru',
|
||||||
|
'validasi_dinas',
|
||||||
|
'kategori_retribusi',
|
||||||
|
'no_urut_ba_tpt',
|
||||||
|
'tanggal_ba_tpt',
|
||||||
|
'no_urut_ba_tpa',
|
||||||
|
'tanggal_ba_tpa',
|
||||||
|
'no_urut_skrd',
|
||||||
|
'tanggal_skrd',
|
||||||
|
'ptsp',
|
||||||
|
'selesai_terbit',
|
||||||
|
'tanggal_pembayaran',
|
||||||
|
'format_sts',
|
||||||
|
'tahun_terbit',
|
||||||
|
'tahun_berjalan',
|
||||||
|
'kelurahan',
|
||||||
|
'kecamatan',
|
||||||
|
'lb',
|
||||||
|
'tb',
|
||||||
|
'jlb',
|
||||||
|
'unit',
|
||||||
|
'usulan_retribusi',
|
||||||
|
'nilai_retribusi_keseluruhan_simbg',
|
||||||
|
'nilai_retribusi_keseluruhan_pad',
|
||||||
|
'denda',
|
||||||
|
'latitude',
|
||||||
|
'longitude',
|
||||||
|
'nik_nib',
|
||||||
|
'dok_tanah',
|
||||||
|
'temuan',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$total_data = count($mapToUpsert);
|
||||||
|
|
||||||
|
$import_datasource->update([
|
||||||
|
"message" => "Successfully processed: {$total_data}",
|
||||||
|
"status" => ImportDatasourceStatus::Success->value,
|
||||||
|
]);
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
"success" => true,
|
||||||
|
"message" => "Data berhasil disimpan ke database"
|
||||||
|
], 200);
|
||||||
|
}catch(\Exception $ex){
|
||||||
|
DB::rollBack();
|
||||||
|
$import_datasource->update([
|
||||||
|
"message" => "Failed to importing",
|
||||||
|
"response_body" => $ex->getMessage(),
|
||||||
|
"status" => ImportDatasourceStatus::Failed->value,
|
||||||
|
]);
|
||||||
|
return response()->json([
|
||||||
|
"success" => false,
|
||||||
|
"message" => "Gagal menyimpan data",
|
||||||
|
"error" => $ex->getMessage()
|
||||||
|
], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function convertToDecimal(?string $value): ?float
|
||||||
|
{
|
||||||
|
if (empty($value)) {
|
||||||
|
return null; // Return null if the input is empty
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove all non-numeric characters except comma and dot
|
||||||
|
$value = preg_replace('/[^0-9,\.]/', '', $value);
|
||||||
|
|
||||||
|
// If the number contains both dot (.) and comma (,)
|
||||||
|
if (strpos($value, '.') !== false && strpos($value, ',') !== false) {
|
||||||
|
$value = str_replace('.', '', $value); // Remove thousands separator
|
||||||
|
$value = str_replace(',', '.', $value); // Convert decimal separator to dot
|
||||||
|
}
|
||||||
|
// If only a dot is present (assumed as thousands separator)
|
||||||
|
elseif (strpos($value, '.') !== false) {
|
||||||
|
$value = str_replace('.', '', $value); // Remove all dots (treat as thousands separators)
|
||||||
|
}
|
||||||
|
// If only a comma is present (assumed as decimal separator)
|
||||||
|
elseif (strpos($value, ',') !== false) {
|
||||||
|
$value = str_replace(',', '.', $value); // Convert comma to dot (decimal separator)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the value is numeric before returning
|
||||||
|
return is_numeric($value) ? (float) number_format((float) $value, 2, '.', '') : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function convertToInteger($value) {
|
||||||
|
// Check if the value is an empty string, and return null if true
|
||||||
|
if (trim($value) === "") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, cast to integer
|
||||||
|
return (int) $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function convertToDate($dateString)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// Check if the string is empty
|
||||||
|
if (empty($dateString)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to parse the date string
|
||||||
|
$date = Carbon::parse($dateString);
|
||||||
|
|
||||||
|
// Return the Carbon instance
|
||||||
|
return $date->format('Y-m-d');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
// Return null if an error occurs during parsing
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,9 +14,10 @@ class RequestAssignmentController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function index(Request $request)
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
$query = PbgTask::query();
|
$query = PbgTask::query()->orderBy('id', 'desc');
|
||||||
if($request->has('search') && !empty($request->get("search"))){
|
if($request->has('search') && !empty($request->get("search"))){
|
||||||
$query->where('name', 'LIKE', '%'.$request->get('search').'%');
|
$query->where('name', 'LIKE', '%'.$request->get('search').'%')
|
||||||
|
->orWhere('registration_number', 'LIKE', '%'.$request->get('search').'%');
|
||||||
}
|
}
|
||||||
return RequestAssignmentResouce::collection($query->paginate());
|
return RequestAssignmentResouce::collection($query->paginate());
|
||||||
}
|
}
|
||||||
|
|||||||
56
app/Http/Controllers/Api/RolesController.php
Normal file
56
app/Http/Controllers/Api/RolesController.php
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Role;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class RolesController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$query = Role::query();
|
||||||
|
|
||||||
|
if($request->has('search') && !empty($request->get('search'))){
|
||||||
|
$query = $query->where('name', 'like', '%'. $request->get('search') . '%');
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json($query->paginate());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*/
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*/
|
||||||
|
public function show(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*/
|
||||||
|
public function update(Request $request, string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*/
|
||||||
|
public function destroy(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,11 +3,19 @@
|
|||||||
namespace App\Http\Controllers\Dashboards;
|
namespace App\Http\Controllers\Dashboards;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\ImportDatasource;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class BigDataController extends Controller
|
class BigDataController extends Controller
|
||||||
{
|
{
|
||||||
public function index(){
|
public function index(){
|
||||||
return view('dashboards.bigdata');
|
$latest_import_datasource = ImportDatasource::latest()->first();
|
||||||
|
$latest_created = $latest_import_datasource ?
|
||||||
|
$latest_import_datasource->created_at->format("j F Y H:i:s") : null;
|
||||||
|
return view('dashboards.bigdata', compact('latest_created'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function pbg(){
|
||||||
|
return view('index');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
119
app/Http/Controllers/DataSettingController.php
Normal file
119
app/Http/Controllers/DataSettingController.php
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Requests\DataSettingRequest;
|
||||||
|
use App\Models\DataSetting;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Facades\Request;
|
||||||
|
|
||||||
|
class DataSettingController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return view("data-settings.index");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*/
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
return view("data-settings.create");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*/
|
||||||
|
public function store(DataSettingRequest $request)
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
DB::beginTransaction();
|
||||||
|
DataSetting::create($request->validated());
|
||||||
|
DB::commit();
|
||||||
|
return response()->json(['message' => 'Successfully created'],201);
|
||||||
|
}catch(Exception $ex){
|
||||||
|
DB::rollBack();
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Failed to create data setting',
|
||||||
|
'error' => $ex->getMessage()
|
||||||
|
], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*/
|
||||||
|
public function show(DataSetting $dataSetting)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
*/
|
||||||
|
public function edit(string $id)
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
$data = DataSetting::findOrFail($id);
|
||||||
|
if(empty($data)){
|
||||||
|
return redirect()->route('data-settings.index')->with('error', 'Invalid id');
|
||||||
|
}
|
||||||
|
return view("data-settings.edit", compact("data"));
|
||||||
|
}catch(Exception $ex){
|
||||||
|
return redirect()->route("data-settings.index")->with("error", "Invalid id");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*/
|
||||||
|
public function update(DataSettingRequest $request,string $id)
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
DB::beginTransaction();
|
||||||
|
$data = DataSetting::findOrFail($id);
|
||||||
|
$data->update($request->validated());
|
||||||
|
DB::commit();
|
||||||
|
return response()->json(['message' => 'Successfully updated'], 200);
|
||||||
|
}catch(Exception $ex){
|
||||||
|
DB::rollBack();
|
||||||
|
return response()->json(['message' => $ex->getMessage()],500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*/
|
||||||
|
public function destroy(string $id)
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
DB::beginTransaction();
|
||||||
|
DataSetting::findOrFail($id)->delete();
|
||||||
|
DB::commit();
|
||||||
|
return response()->json(['success' => true, 'message' => 'Item deleted successfully.'], 200);
|
||||||
|
}catch(Exception $e){
|
||||||
|
DB::rollBack();
|
||||||
|
Log::error($e->getMessage());
|
||||||
|
return response()->json(['success' => false, 'message' => 'Failed to delete item.'], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValueSetting(Request $request){
|
||||||
|
try{
|
||||||
|
$data = DataSetting::where('key', $request->key_name)->first();
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'message' => "Successfully retrieved data",
|
||||||
|
"data"=> $data
|
||||||
|
]);
|
||||||
|
}catch(Exception $e){
|
||||||
|
return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,10 @@
|
|||||||
namespace App\Http\Controllers\Master;
|
namespace App\Http\Controllers\Master;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Role;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
use Illuminate\Validation\Rules;
|
use Illuminate\Validation\Rules;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
@@ -22,7 +25,8 @@ class UsersController extends Controller
|
|||||||
return view('master.users.index', compact('users'));
|
return view('master.users.index', compact('users'));
|
||||||
}
|
}
|
||||||
public function create(){
|
public function create(){
|
||||||
return view('master.users.create');
|
$roles = Role::all();
|
||||||
|
return view('master.users.create', compact('roles'));
|
||||||
}
|
}
|
||||||
public function store(Request $request){
|
public function store(Request $request){
|
||||||
$request->validate([
|
$request->validate([
|
||||||
@@ -31,21 +35,29 @@ class UsersController extends Controller
|
|||||||
'password' => ['required', 'confirmed', 'max:255'],
|
'password' => ['required', 'confirmed', 'max:255'],
|
||||||
'firstname' => ['required', 'string', 'max:255'],
|
'firstname' => ['required', 'string', 'max:255'],
|
||||||
'lastname' => ['required', 'string', 'max:255'],
|
'lastname' => ['required', 'string', 'max:255'],
|
||||||
'position' => ['required', 'string', 'max:255']
|
'position' => ['required', 'string', 'max:255'],
|
||||||
|
'role_id' => 'required|exists:roles,id'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// dd($request);
|
DB::beginTransaction();
|
||||||
|
try{
|
||||||
|
$user = User::create([
|
||||||
|
'name' => $request->name,
|
||||||
|
'email' => $request->email,
|
||||||
|
'password' => Hash::make($request->password),
|
||||||
|
'firstname' => $request->firstname,
|
||||||
|
'lastname' => $request->lastname,
|
||||||
|
'position' => $request->position
|
||||||
|
]);
|
||||||
|
|
||||||
$user = User::create([
|
$user->roles()->attach($request->role_id);
|
||||||
'name' => $request->name,
|
|
||||||
'email' => $request->email,
|
|
||||||
'password' => Hash::make($request->password),
|
|
||||||
'firstname' => $request->firstname,
|
|
||||||
'lastname' => $request->lastname,
|
|
||||||
'position' => $request->position
|
|
||||||
]);
|
|
||||||
|
|
||||||
return redirect()->route('users.index')->with('success','Successfully registered');
|
DB::commit();
|
||||||
|
return response()->json(['message' => 'Successfully created'],201);
|
||||||
|
}catch(\Exception $e){
|
||||||
|
DB::rollBack();
|
||||||
|
return response()->json(['message' => $e->getMessage()],500);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
public function show($id){
|
public function show($id){
|
||||||
$user = User::find($id);
|
$user = User::find($id);
|
||||||
@@ -53,24 +65,40 @@ class UsersController extends Controller
|
|||||||
}
|
}
|
||||||
public function edit($id){
|
public function edit($id){
|
||||||
$user = User::find($id);
|
$user = User::find($id);
|
||||||
return view('master.users.edit', compact('user'));
|
$roles = Role::all();
|
||||||
|
return view('master.users.edit', compact('user', 'roles'));
|
||||||
}
|
}
|
||||||
public function update(Request $request, $id){
|
public function update(Request $request, $id){
|
||||||
$user = User::find($id);
|
$user = User::find($id);
|
||||||
$validate = $request->validate([
|
$validatedData = $request->validate([
|
||||||
'name' => ['required', 'string', 'max:255'],
|
'name' => ['required', 'string', 'max:255'],
|
||||||
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
|
'email' => ['required', 'string', 'email', 'max:255', Rule::unique('users')->ignore($id)],
|
||||||
'password' => ['required', 'confirmed', Rules\Password::defaults()],
|
|
||||||
'firstname' => ['required', 'string', 'max:255'],
|
'firstname' => ['required', 'string', 'max:255'],
|
||||||
'lastname' => ['required', 'string', 'max:255'],
|
'lastname' => ['required', 'string', 'max:255'],
|
||||||
'position' => ['required', 'string', 'max:255']
|
'position' => ['required', 'string', 'max:255'],
|
||||||
|
'role_id' => ['required', 'exists:roles,id'],
|
||||||
]);
|
]);
|
||||||
$user->update($validate);
|
try{
|
||||||
return redirect()->route('master.users')->with('success', 'Successfully');
|
DB::beginTransaction();
|
||||||
|
$updateData = [
|
||||||
|
'name' => $validatedData['name'],
|
||||||
|
'email' => $validatedData['email'],
|
||||||
|
'firstname' => $validatedData['firstname'],
|
||||||
|
'lastname' => $validatedData['lastname'],
|
||||||
|
'position' => $validatedData['position'],
|
||||||
|
];
|
||||||
|
$user->update($updateData);
|
||||||
|
$user->roles()->sync([$request->role_id]);
|
||||||
|
DB::commit();
|
||||||
|
return response()->json(['message' => 'Successfully updated'],200);
|
||||||
|
}catch(\Exception $e){
|
||||||
|
DB::rollBack();
|
||||||
|
return response()->json(['message' => $e->getMessage()],500);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public function destroy($id){
|
public function destroy($id){
|
||||||
$user = User::find($id);
|
$user = User::find($id);
|
||||||
$user->delete();
|
$user->delete();
|
||||||
return redirect()->route('master.users')->with('success','Successfully deleted');
|
return redirect()->route('users.index')->with('success','Successfully deleted');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
113
app/Http/Controllers/MenusController.php
Normal file
113
app/Http/Controllers/MenusController.php
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Requests\MenuRequest;
|
||||||
|
use App\Models\Menu;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class MenusController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return view('menus.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*/
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
$parent_menus = Menu::whereNull('parent_id')->get();
|
||||||
|
return view("menus.create", compact('parent_menus'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*/
|
||||||
|
public function store(MenuRequest $request)
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
$validated_menu = $request->validated();
|
||||||
|
DB::beginTransaction();
|
||||||
|
Menu::create($validated_menu);
|
||||||
|
DB::commit();
|
||||||
|
return response()->json(['message' => 'Successfully created'], 200);
|
||||||
|
}catch(\Exception $e){
|
||||||
|
DB::rollBack();
|
||||||
|
\Log::error('Menu creation failed: ' . $e->getMessage()); // Log the error for debugging
|
||||||
|
return response()->json(['message'=> $e->getMessage()],500);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*/
|
||||||
|
public function show(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
*/
|
||||||
|
public function edit(string $id)
|
||||||
|
{
|
||||||
|
$menu = Menu::findOrFail($id);
|
||||||
|
$parent_menus = Menu::whereNull('parent_id')->where('id','!=',$id)->get();
|
||||||
|
return view("menus.edit", compact('menu','parent_menus'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*/
|
||||||
|
public function update(MenuRequest $request, string $id)
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
$validate_menu = $request->validated();
|
||||||
|
$menu = Menu::findOrFail($id);
|
||||||
|
DB::beginTransaction();
|
||||||
|
$menu->update($validate_menu);
|
||||||
|
DB::commit();
|
||||||
|
return response()->json(['message' => 'Successfully updated'], 200);
|
||||||
|
}catch(\Exception $e){
|
||||||
|
DB::rollBack();
|
||||||
|
\Log::error('Menu update failed: '. $e->getMessage()); // Log the error for debugging
|
||||||
|
return response()->json(['message' => $e->getMessage()],500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*/
|
||||||
|
public function destroy(string $id)
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
DB::beginTransaction();
|
||||||
|
$menu = Menu::findOrFail($id);
|
||||||
|
$this->deleteChildren($menu);
|
||||||
|
$menu->roles()->detach();
|
||||||
|
$menu->delete();
|
||||||
|
DB::commit();
|
||||||
|
return response()->json(['success' => true, 'message' => 'Successfully deleted']);
|
||||||
|
}catch(\Exception $e){
|
||||||
|
DB::rollBack();
|
||||||
|
\Log::error('failed delete menu'. $e->getMessage());
|
||||||
|
return response()->json(['success' => false, 'message' => 'Something went wrong! Please try again.']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function deleteChildren($menu)
|
||||||
|
{
|
||||||
|
foreach ($menu->children as $child) {
|
||||||
|
$this->deleteChildren($child); // Recursively delete its children
|
||||||
|
$child->roles()->detach(); // Detach roles before deleting
|
||||||
|
$child->delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace App\Http\Controllers\RequestAssignment;
|
namespace App\Http\Controllers\RequestAssignment;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\PbgTask;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class PbgTaskController extends Controller
|
class PbgTaskController extends Controller
|
||||||
@@ -12,7 +13,7 @@ class PbgTaskController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
return view('request-assignment.index');
|
return view('pbg_task.index');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -20,7 +21,7 @@ class PbgTaskController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function create()
|
public function create()
|
||||||
{
|
{
|
||||||
//
|
return view("pbg_task.create");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,7 +29,7 @@ class PbgTaskController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
//
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -36,7 +37,8 @@ class PbgTaskController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function show(string $id)
|
public function show(string $id)
|
||||||
{
|
{
|
||||||
//
|
$data = PbgTask::with(['pbg_task_retributions','pbg_task_index_integrations', 'pbg_task_retributions.pbg_task_prasarana'])->findOrFail($id);
|
||||||
|
return view("pbg_task.show", compact("data"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,7 +46,7 @@ class PbgTaskController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function edit(string $id)
|
public function edit(string $id)
|
||||||
{
|
{
|
||||||
//
|
return view("pbg_task.edit");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
146
app/Http/Controllers/RolesController.php
Normal file
146
app/Http/Controllers/RolesController.php
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Requests\RoleRequest;
|
||||||
|
use App\Models\Menu;
|
||||||
|
use App\Models\Role;
|
||||||
|
use App\Models\RoleMenu;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class RolesController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return view("roles.index");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*/
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
return view("roles.create");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*/
|
||||||
|
public function store(RoleRequest $request)
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
$validate_role = $request->validated();
|
||||||
|
|
||||||
|
DB::beginTransaction();
|
||||||
|
Role::create($validate_role);
|
||||||
|
DB::commit();
|
||||||
|
return response()->json(['message' => 'Role created successfully'], 201);
|
||||||
|
}
|
||||||
|
catch(\Exception $e){
|
||||||
|
DB::rollBack();
|
||||||
|
return response()->json(['message' => $e->getMessage()], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*/
|
||||||
|
public function show(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
*/
|
||||||
|
public function edit(string $id)
|
||||||
|
{
|
||||||
|
$role = Role::findOrFail($id);
|
||||||
|
return view("roles.edit", compact('role'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*/
|
||||||
|
public function update(RoleRequest $request, string $id)
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
$validate_role = $request->validated();
|
||||||
|
$role = Role::findOrFail($id);
|
||||||
|
|
||||||
|
DB::beginTransaction();
|
||||||
|
$role->update($validate_role);
|
||||||
|
DB::commit();
|
||||||
|
return response()->json(['message' => 'Role updated successfully'], 200);
|
||||||
|
}catch(\Exception $e){
|
||||||
|
DB::rollBack();
|
||||||
|
return response()->json(['message' => $e->getMessage()], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*/
|
||||||
|
public function destroy(string $id)
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
DB::beginTransaction();
|
||||||
|
Role::findOrFail($id)->delete();
|
||||||
|
DB::commit();
|
||||||
|
return response()->json(['success' => true, "message" => "Successfully deleted"]);
|
||||||
|
}catch(\Exception $e){
|
||||||
|
DB::rollBack();
|
||||||
|
return response()->json(['success' => false, "message" => $e->getMessage()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function menu_permission(string $role_id){
|
||||||
|
try{
|
||||||
|
$role = Role::findOrFail($role_id);
|
||||||
|
$menus = Menu::all();
|
||||||
|
$role_menus = RoleMenu::where('role_id', $role_id)->get() ?? collect();
|
||||||
|
return view('roles.role_menu', compact('role', 'menus', 'role_menus'));
|
||||||
|
}catch(\Exception $e){
|
||||||
|
return redirect()->back()->with("error", $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update_menu_permission(Request $request, string $role_id){
|
||||||
|
try{
|
||||||
|
$validateData = $request->validate([
|
||||||
|
"permissions" => "array",
|
||||||
|
"permissions.*.allow_show" => "nullable|boolean",
|
||||||
|
"permissions.*.allow_create" => "nullable|boolean",
|
||||||
|
"permissions.*.allow_update" => "nullable|boolean",
|
||||||
|
"permissions.*.allow_destroy" => "nullable|boolean"
|
||||||
|
]);
|
||||||
|
|
||||||
|
$role = Role::find($role_id);
|
||||||
|
|
||||||
|
$permissionsArray = [];
|
||||||
|
foreach ($validateData['permissions'] as $menu_id => $permission) {
|
||||||
|
$permissionsArray[$menu_id] = [
|
||||||
|
"allow_show" => (int) ($permission["allow_show"] ?? 0),
|
||||||
|
"allow_create" => (int) ($permission["allow_create"] ?? 0),
|
||||||
|
"allow_update" => (int) ($permission["allow_update"] ?? 0),
|
||||||
|
"allow_destroy" => (int) ($permission["allow_destroy"] ?? 0),
|
||||||
|
"updated_at" => now(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sync will update existing records and insert new ones
|
||||||
|
$role->menus()->sync($permissionsArray);
|
||||||
|
|
||||||
|
return redirect()->route("role-menu.permission", $role_id)->with('success','Menu Permission updated successfully');
|
||||||
|
}catch(\Exception $e){
|
||||||
|
Log::error("Error updating role_menu:", ["error" => $e->getMessage()]);
|
||||||
|
return redirect()->route("role-menu.permission", $role_id)->with("error", $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,30 +15,4 @@ class RoutingController extends Controller
|
|||||||
return redirect('auth.signin');
|
return redirect('auth.signin');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Display a view based on first route param
|
|
||||||
*
|
|
||||||
* @return \Illuminate\Http\Response
|
|
||||||
*/
|
|
||||||
public function root(Request $request, $first)
|
|
||||||
{
|
|
||||||
return view($first);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* second level route
|
|
||||||
*/
|
|
||||||
public function secondLevel(Request $request, $first, $second)
|
|
||||||
{
|
|
||||||
return view($first . '.' . $second);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* third level route
|
|
||||||
*/
|
|
||||||
public function thirdLevel(Request $request, $first, $second, $third)
|
|
||||||
{
|
|
||||||
return view($first . '.' . $second . '.' . $third);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,37 +3,43 @@
|
|||||||
namespace App\Http\Controllers\Settings;
|
namespace App\Http\Controllers\Settings;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\ServiceSIMBG;
|
use App\Services\ServiceSIMBG;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Exception;
|
use Exception;
|
||||||
class SyncronizeController extends Controller
|
class SyncronizeController extends Controller
|
||||||
{
|
{
|
||||||
|
protected $service_simbg;
|
||||||
|
public function __construct(ServiceSIMBG $service_simbg){
|
||||||
|
$this->service_simbg = $service_simbg;
|
||||||
|
}
|
||||||
public function index(Request $request){
|
public function index(Request $request){
|
||||||
return view('settings.syncronize.index');
|
return view('settings.syncronize.index');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function syncPbgTask(){
|
public function syncPbgTask(){
|
||||||
$res = (new ServiceSIMBG())->syncTaskList();
|
$res = $this->service_simbg->syncTaskList();
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function syncronizeTask(Request $request){
|
public function syncronizeTask(Request $request){
|
||||||
$res = (new ServiceSIMBG())->syncTaskList();
|
$res = $this->service_simbg->syncTaskList();
|
||||||
return redirect()->back()->with('success', 'Processing completed successfully');
|
return redirect()->back()->with('success', 'Processing completed successfully');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUserToken(){
|
public function getUserToken(){
|
||||||
$res = (new ServiceSIMBG())->getToken();
|
$res = $this->service_simbg->getToken();
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function syncIndexIntegration($uuid){
|
public function syncIndexIntegration(Request $request, $uuid){
|
||||||
$res = (new ServiceSIMBG())->syncIndexIntegration($uuid);
|
$token = $request->get('token');
|
||||||
|
$res = $this->service_simbg->syncIndexIntegration($uuid, $token);
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function syncTaskDetailSubmit($uuid){
|
public function syncTaskDetailSubmit(Request $request, $uuid){
|
||||||
$res = (new ServiceSIMBG())->syncTaskDetailSubmit($uuid);
|
$token = $request->get('token');
|
||||||
|
$res = $this->service_simbg->syncTaskDetailSubmit($uuid, $token);
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
31
app/Http/Requests/DataSettingRequest.php
Normal file
31
app/Http/Requests/DataSettingRequest.php
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class DataSettingRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*/
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
$id = $this->route('data_setting');
|
||||||
|
return [
|
||||||
|
"key" => "required|unique:data_settings,key," . $id,
|
||||||
|
"value" => "required",
|
||||||
|
"type" => "nullable",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
32
app/Http/Requests/MenuRequest.php
Normal file
32
app/Http/Requests/MenuRequest.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class MenuRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*/
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => ['required','string','max:255'],
|
||||||
|
'url' => ['nullable','string','max:255'],
|
||||||
|
'icon' => ['nullable','string','max:255'],
|
||||||
|
'parent_id' => ['nullable','exists:menus,id'],
|
||||||
|
'sort_order' => ['required','integer'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
62
app/Http/Requests/PbgTaskMultiStepRequest.php
Normal file
62
app/Http/Requests/PbgTaskMultiStepRequest.php
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class PbgTaskMultiStepRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*/
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
// rules step 1
|
||||||
|
"step1Form.uuid" => "required",
|
||||||
|
"step1Form.name" => "nullable|string|max:255",
|
||||||
|
"step1Form.owner_name" => "nullable|string|max:255",
|
||||||
|
"step1Form.application_type" => "nullable|string|max:255",
|
||||||
|
"step1Form.application_type_name" => "nullable|string|max:255",
|
||||||
|
"step1Form.condition" => "nullable|string|max:255",
|
||||||
|
"step1Form.registration_number" => "nullable|string|max:255",
|
||||||
|
"step1Form.document_number" => "nullable|string|max:255",
|
||||||
|
"step1Form.address" => "nullable|string|max:255",
|
||||||
|
"step1Form.status" => "nullable|integer",
|
||||||
|
"step1Form.status_name" => "nullable|string|max:255",
|
||||||
|
"step1Form.slf_status" => "nullable|string|max:255",
|
||||||
|
"step1Form.slf_status_name" => "nullable|string|max:255",
|
||||||
|
"step1Form.function_type" => "nullable|string|max:255",
|
||||||
|
"step1Form.consultation_type" => "nullable|string|max:255",
|
||||||
|
"step1Form.due_date" => "nullable|date",
|
||||||
|
"step1Form.land_certificate_phase" => "nullable|boolean",
|
||||||
|
"step1Form.task_created_at" => "nullable|date",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function messages()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
// message step 1
|
||||||
|
"step1Form.uuid.required" => "UUID wajib diisi.",
|
||||||
|
"step1Form.uuid.uuid" => "Format UUID tidak valid.",
|
||||||
|
"step1Form.name.max" => "Nama tidak boleh lebih dari 255 karakter.",
|
||||||
|
"step1Form.owner_name.max" => "Nama pemilik tidak boleh lebih dari 255 karakter.",
|
||||||
|
"step1Form.registration_number.max" => "Nomor registrasi tidak boleh lebih dari 255 karakter.",
|
||||||
|
"step1Form.document_number.max" => "Nomor dokumen tidak boleh lebih dari 255 karakter.",
|
||||||
|
"step1Form.status.integer" => "Status harus berupa angka.",
|
||||||
|
"step1Form.due_date.date" => "Tanggal jatuh tempo tidak valid.",
|
||||||
|
"step1Form.land_certificate_phase.boolean" => "Fase sertifikat tanah harus berupa true/false.",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
30
app/Http/Requests/RoleRequest.php
Normal file
30
app/Http/Requests/RoleRequest.php
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class RoleRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*/
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
$roleId = $this->route('role');
|
||||||
|
return [
|
||||||
|
'name' => 'required|string|max:255|unique:roles,name,' . ($roleId ?? 'NULL') . ',id',
|
||||||
|
'description' => 'nullable|string',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
26
app/Http/Resources/DataSettingResource.php
Normal file
26
app/Http/Resources/DataSettingResource.php
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class DataSettingResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'key' => $this->key,
|
||||||
|
'value' => $this->value,
|
||||||
|
'type' => $this->type,
|
||||||
|
'created_at' => $this->created_at->toDateTimeString(),
|
||||||
|
'updated_at' => $this->updated_at->toDateTimeString(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,6 +23,7 @@ class UserResource extends JsonResource
|
|||||||
'position' => $this->position,
|
'position' => $this->position,
|
||||||
'firstname' => $this->firstname,
|
'firstname' => $this->firstname,
|
||||||
'lastname' => $this->lastname,
|
'lastname' => $this->lastname,
|
||||||
|
'roles' => $this->roles->pluck('name'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
125
app/Models/BigdataResume.php
Normal file
125
app/Models/BigdataResume.php
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class BigdataResume extends Model
|
||||||
|
{
|
||||||
|
protected $table = "bigdata_resumes";
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'import_datasource_id',
|
||||||
|
'potention_count',
|
||||||
|
'potention_sum',
|
||||||
|
'non_verified_count',
|
||||||
|
'non_verified_sum',
|
||||||
|
'verified_count',
|
||||||
|
'verified_sum',
|
||||||
|
'business_count',
|
||||||
|
'business_sum',
|
||||||
|
'non_business_count',
|
||||||
|
'non_business_sum',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function importDatasource()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(ImportDatasource::class, 'import_datasource_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function generateResumeData($import_datasource_id){
|
||||||
|
$query_verified = once( function () {
|
||||||
|
return DB::table('pbg_task AS pt')
|
||||||
|
->leftJoin('pbg_task_google_sheet AS ptgs', 'pt.registration_number', '=', 'ptgs.no_registrasi')
|
||||||
|
->leftJoin('pbg_task_retributions AS ptr', 'pt.uuid', '=', 'ptr.pbg_task_uid')
|
||||||
|
->whereRaw('LOWER(TRIM(ptgs.status_verifikasi)) = ?', [strtolower(trim('Selesai Verifikasi'))])
|
||||||
|
->selectRaw('COUNT(pt.id) AS total_data,
|
||||||
|
SUM(ptr.nilai_retribusi_bangunan) AS total_retribution')
|
||||||
|
->first();
|
||||||
|
});
|
||||||
|
|
||||||
|
$verified_count = $query_verified->total_data ?? 0;
|
||||||
|
$verified_total = $query_verified->total_retribution ?? 0;
|
||||||
|
|
||||||
|
$query_business = once(function () {
|
||||||
|
return DB::table('pbg_task AS pt')
|
||||||
|
->leftJoin('pbg_task_google_sheet AS ptgs', 'pt.registration_number', '=', 'ptgs.no_registrasi')
|
||||||
|
->leftJoin('pbg_task_retributions AS ptr', 'pt.uuid', '=', 'ptr.pbg_task_uid')
|
||||||
|
->where(function ($query) {
|
||||||
|
$query->whereRaw('LOWER(TRIM(ptgs.status_verifikasi)) != ?', [strtolower(trim('Selesai Verifikasi'))])
|
||||||
|
->orWhereNull('ptgs.status_verifikasi');
|
||||||
|
})
|
||||||
|
->where(function ($query) {
|
||||||
|
$query->whereRaw('LOWER(TRIM(pt.function_type)) = ?', [strtolower(trim('Sebagai Tempat Usaha'))]);
|
||||||
|
})
|
||||||
|
->selectRaw('COUNT(pt.id) AS total_data,
|
||||||
|
SUM(ptr.nilai_retribusi_bangunan) AS total_retribution')
|
||||||
|
->first();
|
||||||
|
});
|
||||||
|
|
||||||
|
$business_count = $query_business->total_data ?? 0;
|
||||||
|
$business_total = $query_business->total_retribution ?? 0;
|
||||||
|
|
||||||
|
$query_non_business = once( function () {
|
||||||
|
return DB::table('pbg_task AS pt')
|
||||||
|
->leftJoin('pbg_task_google_sheet AS ptgs', 'pt.registration_number', '=', 'ptgs.no_registrasi')
|
||||||
|
->leftJoin('pbg_task_retributions AS ptr', 'pt.uuid', '=', 'ptr.pbg_task_uid') // Join ke pbg_task_retributions
|
||||||
|
->where(function ($query) {
|
||||||
|
$query->whereRaw('LOWER(TRIM(ptgs.status_verifikasi)) != ?', [strtolower(trim('Selesai Verifikasi'))])
|
||||||
|
->orWhereNull('ptgs.status_verifikasi'); // Include NULL values
|
||||||
|
})
|
||||||
|
->where(function ($query) {
|
||||||
|
$query->whereRaw('LOWER(TRIM(pt.function_type)) != ?', [strtolower(trim('Sebagai Tempat Usaha'))])
|
||||||
|
->orWhereNull('pt.function_type'); // Include NULL values
|
||||||
|
})
|
||||||
|
->selectRaw('COUNT(pt.id) AS total_data,
|
||||||
|
SUM(ptr.nilai_retribusi_bangunan) AS total_retribution') // Menambahkan SUM dari pbg_task_retributions
|
||||||
|
->first();
|
||||||
|
});
|
||||||
|
$non_business_count = $query_non_business->total_data ?? 0;
|
||||||
|
$non_business_total = $query_non_business->total_retribution ?? 0;
|
||||||
|
|
||||||
|
$query_non_verified = once(function () {
|
||||||
|
return DB::table('pbg_task AS pt')
|
||||||
|
->leftJoin('pbg_task_google_sheet AS ptgs', 'pt.registration_number', '=', 'ptgs.no_registrasi')
|
||||||
|
->leftJoin('pbg_task_retributions AS ptr', 'pt.uuid', '=', 'ptr.pbg_task_uid') // Join tabel pbg_task_retributions
|
||||||
|
->where(function ($query) {
|
||||||
|
$query->whereRaw('LOWER(TRIM(ptgs.status_verifikasi)) != ?', [strtolower(trim('Selesai Verifikasi'))])
|
||||||
|
->orWhereNull('ptgs.status_verifikasi'); // Include NULL values
|
||||||
|
})
|
||||||
|
->selectRaw('COUNT(pt.id) AS total_data,
|
||||||
|
SUM(ptr.nilai_retribusi_bangunan) AS total_retribution') // Menambahkan SUM dari pbg_task_retributions
|
||||||
|
->first();
|
||||||
|
});
|
||||||
|
|
||||||
|
$non_verified_count = $query_non_verified->total_data ?? 0;
|
||||||
|
$non_verified_total = $query_non_verified->total_retribution ?? 0;
|
||||||
|
|
||||||
|
$query_potention = once( function () {
|
||||||
|
return DB::table('pbg_task as pt')
|
||||||
|
->leftJoin('pbg_task_retributions as ptr', 'pt.uuid', '=', 'ptr.pbg_task_uid')
|
||||||
|
->select(
|
||||||
|
DB::raw('COUNT(DISTINCT pt.id) as task_count'),
|
||||||
|
DB::raw('SUM(ptr.nilai_retribusi_bangunan) as total_retribution')
|
||||||
|
)
|
||||||
|
->first();
|
||||||
|
});
|
||||||
|
$potention_count = $query_potention->task_count ?? 0;
|
||||||
|
$potention_total = $query_potention->total_retribution ?? 0;
|
||||||
|
|
||||||
|
return self::create([
|
||||||
|
'import_datasource_id' => $import_datasource_id,
|
||||||
|
'potention_count' => $potention_count ?? 0,
|
||||||
|
'potention_sum' => $potention_total ?? 0.00,
|
||||||
|
'non_verified_count' => $non_verified_count ?? 0,
|
||||||
|
'non_verified_sum' => $non_verified_total ?? 0.00,
|
||||||
|
'verified_count' => $verified_count ?? 0,
|
||||||
|
'verified_sum' => $verified_total ?? 0.00,
|
||||||
|
'business_count' => $business_count ?? 0,
|
||||||
|
'business_sum' => $business_total ?? 0.00,
|
||||||
|
'non_business_count' => $non_business_count ?? 0,
|
||||||
|
'non_business_sum' => $non_business_total ?? 0.00,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
15
app/Models/DataSetting.php
Normal file
15
app/Models/DataSetting.php
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class DataSetting extends Model
|
||||||
|
{
|
||||||
|
protected $table = "data_settings";
|
||||||
|
protected $fillable = [
|
||||||
|
"key",
|
||||||
|
"value",
|
||||||
|
"type"
|
||||||
|
];
|
||||||
|
}
|
||||||
25
app/Models/Menu.php
Normal file
25
app/Models/Menu.php
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class Menu extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'menus';
|
||||||
|
protected $fillable = [
|
||||||
|
'name',
|
||||||
|
'url',
|
||||||
|
'icon',
|
||||||
|
'parent_id',
|
||||||
|
'sort_order'
|
||||||
|
];
|
||||||
|
|
||||||
|
public function roles(){
|
||||||
|
return $this->belongsToMany(Role::class, 'role_menu')->withTimestamps();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function children(){
|
||||||
|
return $this->hasMany(Menu::class,'parent_id');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,7 +30,11 @@ class PbgTask extends Model
|
|||||||
'task_created_at'
|
'task_created_at'
|
||||||
];
|
];
|
||||||
|
|
||||||
public function retributions(){
|
public function pbg_task_retributions(){
|
||||||
return $this->hasOne(PbgTaskRetributions::class, 'pbg_task_uid', 'uuid');
|
return $this->hasOne(PbgTaskRetributions::class, 'pbg_task_uid', 'uuid');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function pbg_task_index_integrations(){
|
||||||
|
return $this->hasOne(PbgTaskIndexIntegrations::class, 'pbg_task_uid', 'uuid');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
68
app/Models/PbgTaskGoogleSheet.php
Normal file
68
app/Models/PbgTaskGoogleSheet.php
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class PbgTaskGoogleSheet extends Model
|
||||||
|
{
|
||||||
|
protected $table = "pbg_task_google_sheet";
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'jenis_konsultasi',
|
||||||
|
'no_registrasi',
|
||||||
|
'nama_pemilik',
|
||||||
|
'lokasi_bg',
|
||||||
|
'fungsi_bg',
|
||||||
|
'nama_bangunan',
|
||||||
|
'tgl_permohonan',
|
||||||
|
'status_verifikasi',
|
||||||
|
'status_permohonan',
|
||||||
|
'alamat_pemilik',
|
||||||
|
'no_hp',
|
||||||
|
'email',
|
||||||
|
'tanggal_catatan',
|
||||||
|
'catatan_kekurangan_dokumen',
|
||||||
|
'gambar',
|
||||||
|
'krk_kkpr',
|
||||||
|
'no_krk',
|
||||||
|
'lh',
|
||||||
|
'ska',
|
||||||
|
'keterangan',
|
||||||
|
'helpdesk',
|
||||||
|
'pj',
|
||||||
|
'kepemilikan',
|
||||||
|
'potensi_taru',
|
||||||
|
'validasi_dinas',
|
||||||
|
'kategori_retribusi',
|
||||||
|
'no_urut_ba_tpt',
|
||||||
|
'tanggal_ba_tpt',
|
||||||
|
'no_urut_ba_tpa',
|
||||||
|
'tanggal_ba_tpa',
|
||||||
|
'no_urut_skrd',
|
||||||
|
'tanggal_skrd',
|
||||||
|
'ptsp',
|
||||||
|
'selesai_terbit',
|
||||||
|
'tanggal_pembayaran',
|
||||||
|
'format_sts',
|
||||||
|
'tahun_terbit',
|
||||||
|
'tahun_berjalan',
|
||||||
|
'kelurahan',
|
||||||
|
'kecamatan',
|
||||||
|
'lb',
|
||||||
|
'tb',
|
||||||
|
'jlb',
|
||||||
|
'unit',
|
||||||
|
'usulan_retribusi',
|
||||||
|
'nilai_retribusi_keseluruhan_simbg',
|
||||||
|
'nilai_retribusi_keseluruhan_pad',
|
||||||
|
'denda',
|
||||||
|
'latitude',
|
||||||
|
'longitude',
|
||||||
|
'nik_nib',
|
||||||
|
'dok_tanah',
|
||||||
|
'temuan',
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -21,4 +21,8 @@ class PbgTaskIndexIntegrations extends Model
|
|||||||
'indeks_terintegrasi',
|
'indeks_terintegrasi',
|
||||||
'total',
|
'total',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public function pbg_task(){
|
||||||
|
return $this->belongsTo(PbgTask::class, 'pbg_task_uid', 'uuid');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,5 +20,10 @@ class PbgTaskPrasarana extends Model
|
|||||||
'quantity',
|
'quantity',
|
||||||
'unit',
|
'unit',
|
||||||
'index_prasarana',
|
'index_prasarana',
|
||||||
|
'pbg_task_retribution_id'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public function pbg_task_retributions(){
|
||||||
|
return $this->hasMany(PbgTaskRetributions::class, 'pbg_task_retribution_id', 'id');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,11 @@ class PbgTaskRetributions extends Model
|
|||||||
'pbg_task_uid'
|
'pbg_task_uid'
|
||||||
];
|
];
|
||||||
|
|
||||||
public function task(){
|
public function pbg_task(){
|
||||||
return $this->belongsTo(PbgTask::class, 'pbg_task_uid', 'uuid');
|
return $this->belongsTo(PbgTask::class, 'pbg_task_uid', 'uuid');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function pbg_task_prasarana(){
|
||||||
|
return $this->hasMany(PbgTaskPrasarana::class, 'pbg_task_retribution_id', 'id');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
22
app/Models/Role.php
Normal file
22
app/Models/Role.php
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class Role extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'roles';
|
||||||
|
protected $fillable = [
|
||||||
|
'name',
|
||||||
|
'description'
|
||||||
|
];
|
||||||
|
|
||||||
|
public function users(){
|
||||||
|
return $this->belongsToMany(User::class,'user_role')->withTimestamps();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function menus(){
|
||||||
|
return $this->belongsToMany(Menu::class,'role_menu')->withTimestamps();
|
||||||
|
}
|
||||||
|
}
|
||||||
30
app/Models/RoleMenu.php
Normal file
30
app/Models/RoleMenu.php
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class RoleMenu extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'role_menu';
|
||||||
|
protected $primary = ['role_id', 'menu_id'];
|
||||||
|
public $incrementing = false;
|
||||||
|
protected $fillable = [
|
||||||
|
'role_id',
|
||||||
|
'menu_id',
|
||||||
|
'allow_show',
|
||||||
|
'allow_create',
|
||||||
|
'allow_update',
|
||||||
|
'allow_destroy',
|
||||||
|
];
|
||||||
|
|
||||||
|
public $timestamps = true;
|
||||||
|
|
||||||
|
public function role(){
|
||||||
|
return $this->belongsTo(Role::class, 'role_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function menu(){
|
||||||
|
return $this->belongsTo(Menu::class,'menu_id');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -49,4 +49,8 @@ class User extends Authenticatable
|
|||||||
'password' => 'hashed',
|
'password' => 'hashed',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function roles(){
|
||||||
|
return $this->belongsToMany(Role::class, 'user_role')->withTimestamps();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,11 @@
|
|||||||
|
|
||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use App\Models\Menu;
|
||||||
use App\View\Components\Circle;
|
use App\View\Components\Circle;
|
||||||
|
use Auth;
|
||||||
use Illuminate\Support\Facades\Blade;
|
use Illuminate\Support\Facades\Blade;
|
||||||
|
use Illuminate\Support\Facades\View;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
|
||||||
@@ -23,5 +26,26 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
public function boot(): void
|
public function boot(): void
|
||||||
{
|
{
|
||||||
Blade::component('circle', Circle::class);
|
Blade::component('circle', Circle::class);
|
||||||
|
|
||||||
|
View::composer('layouts.partials.sidebar', function ($view){
|
||||||
|
$user = Auth::user();
|
||||||
|
|
||||||
|
if($user){
|
||||||
|
$menus = Menu::whereHas('roles', function ($query) use ($user){
|
||||||
|
$query->where('roles.id', $user->roles->pluck('id'));
|
||||||
|
})
|
||||||
|
->with(['children' => function ($query) {
|
||||||
|
$query->whereHas('roles', function ($subQuery) {
|
||||||
|
$subQuery->where('role_menu.allow_show', 1);
|
||||||
|
});
|
||||||
|
}])
|
||||||
|
->orderBy('sort_order', 'asc')
|
||||||
|
->get();
|
||||||
|
}else{
|
||||||
|
$menus = collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
$view->with('menus', $menus);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,296 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App;
|
|
||||||
|
|
||||||
use App\Enums\ImportDatasourceStatus;
|
|
||||||
use App\Models\GlobalSetting;
|
|
||||||
use App\Models\ImportDatasource;
|
|
||||||
use App\Models\PbgTaskIndexIntegrations;
|
|
||||||
use App\Models\PbgTaskPrasarana;
|
|
||||||
use App\Models\PbgTaskRetributions;
|
|
||||||
use Exception;
|
|
||||||
use App\Models\PbgTask;
|
|
||||||
use App\Traits\GlobalApiResponse;
|
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
use Carbon\Carbon;
|
|
||||||
|
|
||||||
class ServiceSIMBG
|
|
||||||
{
|
|
||||||
use GlobalApiResponse;
|
|
||||||
private $email;
|
|
||||||
private $password;
|
|
||||||
private $simbg_host;
|
|
||||||
private $fetch_per_page;
|
|
||||||
/**
|
|
||||||
* Create a new class instance.
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->email = trim((string) GlobalSetting::where('key','SIMBG_EMAIL')->first()->value);
|
|
||||||
$this->password = trim((string) GlobalSetting::where('key','SIMBG_PASSWORD')->first()->value);
|
|
||||||
$this->simbg_host = trim((string)GlobalSetting::where('key','SIMBG_HOST')->first()->value);
|
|
||||||
$this->fetch_per_page = trim((string)GlobalSetting::where('key','FETCH_PER_PAGE')->first()->value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getToken(){
|
|
||||||
$clientHelper = new ServiceClient($this->simbg_host);
|
|
||||||
$url = "/api/user/v1/auth/login/";
|
|
||||||
$body = [
|
|
||||||
'email' => $this->email,
|
|
||||||
'password' => $this->password,
|
|
||||||
];
|
|
||||||
|
|
||||||
$res = $clientHelper->post($url, $body);
|
|
||||||
if(!$res->original['success']){
|
|
||||||
Log::error("Token not retrieved ", ['response' => $res]);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return $res;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function syncIndexIntegration($uuid, $token)
|
|
||||||
{
|
|
||||||
$clientHelper = new ServiceClient($this->simbg_host);
|
|
||||||
$url = "/api/pbg/v1/detail/" . $uuid . "/retribution/indeks-terintegrasi/";
|
|
||||||
|
|
||||||
$headers = [
|
|
||||||
'Authorization' => "Bearer " . $token,
|
|
||||||
];
|
|
||||||
|
|
||||||
$res = $clientHelper->get($url, $headers);
|
|
||||||
|
|
||||||
if (empty($res->original['success']) || !$res->original['success']) {
|
|
||||||
// Log error
|
|
||||||
Log::error("API response indicates failure", ['url' => $url, 'uuid' => $uuid]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = $res->original['data']['data'] ?? null;
|
|
||||||
if (!$data) {
|
|
||||||
Log::error("No valid data returned from API", ['url' => $url, 'uuid' => $uuid]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$resultData = PbgTaskIndexIntegrations::updateOrCreate(
|
|
||||||
['pbg_task_uid' => $uuid],
|
|
||||||
[
|
|
||||||
'indeks_fungsi_bangunan' => $data['indeks_fungsi_bangunan'] ?? null,
|
|
||||||
'indeks_parameter_kompleksitas' => $data['indeks_parameter_kompleksitas'] ?? null,
|
|
||||||
'indeks_parameter_permanensi' => $data['indeks_parameter_permanensi'] ?? null,
|
|
||||||
'indeks_parameter_ketinggian' => $data['indeks_parameter_ketinggian'] ?? null,
|
|
||||||
'faktor_kepemilikan' => $data['faktor_kepemilikan'] ?? null,
|
|
||||||
'indeks_terintegrasi' => $data['indeks_terintegrasi'] ?? null,
|
|
||||||
'total' => $data['total'] ?? null,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
// Log success
|
|
||||||
if ($resultData->wasRecentlyCreated) {
|
|
||||||
Log::info("integration created successfully", ['uuid' => $uuid]);
|
|
||||||
} else {
|
|
||||||
Log::info("integration updated successfully", ['uuid' => $uuid]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function syncTaskList()
|
|
||||||
{
|
|
||||||
$clientHelper = new ServiceClient($this->simbg_host);
|
|
||||||
$initResToken = $this->getToken();
|
|
||||||
|
|
||||||
$importDatasource = ImportDatasource::create([
|
|
||||||
'status' => ImportDatasourceStatus::Processing->value,
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (empty($initResToken->original['data']['token']['access'])) {
|
|
||||||
$importDatasource->update([
|
|
||||||
'status' => ImportDatasourceStatus::Failed->value,
|
|
||||||
'message' => 'Failed to retrieve token'
|
|
||||||
]);
|
|
||||||
return $this->resError("Failed to retrieve token");
|
|
||||||
}
|
|
||||||
|
|
||||||
$apiToken = $initResToken->original['data']['token']['access'];
|
|
||||||
$headers = ['Authorization' => "Bearer " . $apiToken];
|
|
||||||
|
|
||||||
$url = "/api/pbg/v1/list/?page=1&size={$this->fetch_per_page}&sort=ASC";
|
|
||||||
$initialResponse = $clientHelper->get($url, $headers);
|
|
||||||
|
|
||||||
$totalPage = $initialResponse->original['data']['total_page'] ?? 0;
|
|
||||||
if ($totalPage == 0) {
|
|
||||||
$importDatasource->update([
|
|
||||||
'status' => ImportDatasourceStatus::Failed->value,
|
|
||||||
'message' => 'Invalid response: no total_page'
|
|
||||||
]);
|
|
||||||
return $this->resError("Invalid response from API");
|
|
||||||
}
|
|
||||||
|
|
||||||
$savedCount = $failedCount = 0;
|
|
||||||
|
|
||||||
for ($currentPage = 1; $currentPage <= $totalPage; $currentPage++) {
|
|
||||||
$pageUrl = "/api/pbg/v1/list/?page={$currentPage}&size={$this->fetch_per_page}&sort=ASC";
|
|
||||||
$getToken = $this->getToken();
|
|
||||||
if (empty($getToken->original['data']['token']['access'])) {
|
|
||||||
$importDatasource->update([
|
|
||||||
'status' => ImportDatasourceStatus::Failed->value,
|
|
||||||
'message' => 'Failed to retrieve token'
|
|
||||||
]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$token = $getToken->original['data']['token']['access'];
|
|
||||||
$headers = ['Authorization' => "Bearer " . $token];
|
|
||||||
$response = $clientHelper->get($pageUrl, $headers);
|
|
||||||
$tasks = $response->original['data']['data'] ?? [];
|
|
||||||
|
|
||||||
if (empty($tasks)) {
|
|
||||||
$importDatasource->update([
|
|
||||||
'status' => ImportDatasourceStatus::Failed->value,
|
|
||||||
'message' => 'No data found on page'
|
|
||||||
]);
|
|
||||||
Log::warning("No data found on page", ['page' => $currentPage]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log::info("executed page", ['page' => $currentPage, 'total' => $totalPage]);
|
|
||||||
|
|
||||||
$tasksCollective = [];
|
|
||||||
foreach ($tasks as $item) {
|
|
||||||
try {
|
|
||||||
$tasksCollective[] = [
|
|
||||||
'uuid' => $item['uid'],
|
|
||||||
'name' => $item['name'],
|
|
||||||
'owner_name' => $item['owner_name'],
|
|
||||||
'application_type' => $item['application_type'],
|
|
||||||
'application_type_name' => $item['application_type_name'],
|
|
||||||
'condition' => $item['condition'],
|
|
||||||
'registration_number' => $item['registration_number'],
|
|
||||||
'document_number' => $item['document_number'],
|
|
||||||
'address' => $item['address'],
|
|
||||||
'status' => $item['status'],
|
|
||||||
'status_name' => $item['status_name'],
|
|
||||||
'slf_status' => $item['slf_status'] ?? null,
|
|
||||||
'slf_status_name' => $item['slf_status_name'] ?? null,
|
|
||||||
'function_type' => $item['function_type'],
|
|
||||||
'consultation_type' => $item['consultation_type'],
|
|
||||||
'due_date' => $item['due_date'],
|
|
||||||
'land_certificate_phase' => $item['land_certificate_phase'],
|
|
||||||
'task_created_at' => isset($item['created_at']) ? Carbon::parse($item['created_at'])->format('Y-m-d H:i:s') : null,
|
|
||||||
'updated_at' => now(),
|
|
||||||
'created_at' => now(),
|
|
||||||
];
|
|
||||||
|
|
||||||
$this->syncIndexIntegration($item['uid'], $token);
|
|
||||||
$this->syncTaskDetailSubmit($item['uid'], $token);
|
|
||||||
$savedCount++;
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$failedCount++;
|
|
||||||
$importDatasource->update([
|
|
||||||
'status' => ImportDatasourceStatus::Failed->value,
|
|
||||||
'message' => "Successfully processed: $savedCount, Failed: $failedCount"
|
|
||||||
]);
|
|
||||||
Log::error("Failed to process task", [
|
|
||||||
'error' => $e->getMessage(),
|
|
||||||
'task' => $item,
|
|
||||||
]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PbgTask::upsert($tasksCollective, ['uuid'], [
|
|
||||||
'name', 'owner_name', 'application_type', 'application_type_name', 'condition',
|
|
||||||
'registration_number', 'document_number', 'address', 'status', 'status_name',
|
|
||||||
'slf_status', 'slf_status_name', 'function_type', 'consultation_type', 'due_date',
|
|
||||||
'land_certificate_phase', 'task_created_at', 'updated_at'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$importDatasource->update([
|
|
||||||
'status' => ImportDatasourceStatus::Success->value,
|
|
||||||
'message' => "Successfully processed: $savedCount, Failed: $failedCount"
|
|
||||||
]);
|
|
||||||
|
|
||||||
Log::info("syncTaskList completed", ['savedCount' => $savedCount, 'failedCount' => $failedCount]);
|
|
||||||
|
|
||||||
return $this->resSuccess(['savedCount' => $savedCount, 'failedCount' => $failedCount]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function syncTaskDetailSubmit($uuid, $token)
|
|
||||||
{
|
|
||||||
$clientHelper = new ServiceClient($this->simbg_host);
|
|
||||||
|
|
||||||
$url = "/api/pbg/v1/detail/" . $uuid . "/retribution/submit/";
|
|
||||||
$headers = [
|
|
||||||
'Authorization' => "Bearer " . $token,
|
|
||||||
];
|
|
||||||
|
|
||||||
$res = $clientHelper->get($url, $headers);
|
|
||||||
|
|
||||||
if (empty($res->original['success']) || !$res->original['success']) {
|
|
||||||
// Log error
|
|
||||||
Log::error("API response indicates failure", ['url' => $url, 'uuid' => $uuid]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = $res->original['data']['data'] ?? [];
|
|
||||||
if (empty($data)) {
|
|
||||||
Log::error("No data returned from API", ['url' => $url, 'uuid' => $uuid]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$detailCreatedAt = isset($data['created_at'])
|
|
||||||
? Carbon::parse($data['created_at'])->format('Y-m-d H:i:s')
|
|
||||||
: null;
|
|
||||||
|
|
||||||
$detailUpdatedAt = isset($data['updated_at'])
|
|
||||||
? Carbon::parse($data['updated_at'])->format('Y-m-d H:i:s')
|
|
||||||
: null;
|
|
||||||
|
|
||||||
PbgTaskRetributions::updateOrCreate(
|
|
||||||
['detail_id' => $data['id']],
|
|
||||||
[
|
|
||||||
'detail_uid' => $data['uid'] ?? null,
|
|
||||||
'detail_created_at' => $detailCreatedAt ?? null,
|
|
||||||
'detail_updated_at' => $detailUpdatedAt ?? null,
|
|
||||||
'luas_bangunan' => $data['luas_bangunan'] ?? null,
|
|
||||||
'indeks_lokalitas' => $data['indeks_lokalitas'] ?? null,
|
|
||||||
'wilayah_shst' => $data['wilayah_shst'] ?? null,
|
|
||||||
'kegiatan_id' => $data['kegiatan']['id'] ?? null,
|
|
||||||
'kegiatan_name' => $data['kegiatan']['name'] ?? null,
|
|
||||||
'nilai_shst' => $data['nilai_shst'] ?? null,
|
|
||||||
'indeks_terintegrasi' => $data['indeks_terintegrasi'] ?? null,
|
|
||||||
'indeks_bg_terbangun' => $data['indeks_bg_terbangun'] ?? null,
|
|
||||||
'nilai_retribusi_bangunan' => $data['nilai_retribusi_bangunan'] ?? null,
|
|
||||||
'nilai_prasarana' => $data['nilai_prasarana'] ?? null,
|
|
||||||
'created_by' => $data['created_by'] ?? null,
|
|
||||||
'pbg_document' => $data['pbg_document'] ?? null,
|
|
||||||
'underpayment' => $data['underpayment'] ?? null,
|
|
||||||
'skrd_amount' => $data['skrd_amount'] ?? null,
|
|
||||||
'pbg_task_uid' => $uuid,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
$prasaranaData = $data['prasarana'] ?? [];
|
|
||||||
if (!empty($prasaranaData)) {
|
|
||||||
$insertData = array_map(fn($item) => [
|
|
||||||
'pbg_task_uid' => $uuid,
|
|
||||||
'prasarana_id' => $item['id'] ?? null,
|
|
||||||
'prasarana_type' => $item['prasarana_type'] ?? null,
|
|
||||||
'building_type' => $item['building_type'] ?? null,
|
|
||||||
'total' => $item['total'] ?? null,
|
|
||||||
'quantity' => $item['quantity'] ?? null,
|
|
||||||
'unit' => $item['unit'] ?? null,
|
|
||||||
'index_prasarana' => $item['index_prasarana'] ?? null,
|
|
||||||
], $prasaranaData);
|
|
||||||
|
|
||||||
// Use bulk insert or upsert for faster database operation
|
|
||||||
PbgTaskPrasarana::upsert($insertData, ['pbg_task_uid', 'prasarana_id']);
|
|
||||||
}
|
|
||||||
|
|
||||||
Log::info("retribution and prasarana successfully", ['uuid' => $uuid]);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
152
app/Services/GoogleSheetService.php
Normal file
152
app/Services/GoogleSheetService.php
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services;
|
||||||
|
|
||||||
|
use Google_Client;
|
||||||
|
use Google_Service_Sheets;
|
||||||
|
|
||||||
|
class GoogleSheetService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create a new class instance.
|
||||||
|
*/
|
||||||
|
protected $client;
|
||||||
|
protected $service;
|
||||||
|
protected $spreadsheetID;
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->client = new Google_Client();
|
||||||
|
$this->client->setApplicationName("Sibedas Google Sheets API");
|
||||||
|
$this->client->setScopes([Google_Service_Sheets::SPREADSHEETS_READONLY]);
|
||||||
|
$this->client->setAuthConfig(storage_path("app/teak-banner-450003-s8-ea05661d9db0.json"));
|
||||||
|
$this->client->setAccessType("offline");
|
||||||
|
|
||||||
|
$this->service = new Google_Service_Sheets($this->client);
|
||||||
|
$this->spreadsheetID = env("SPREAD_SHEET_ID");
|
||||||
|
|
||||||
|
$this->service_sheets = new Google_Service_Sheets($this->client);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSheetData($range){
|
||||||
|
$response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range);
|
||||||
|
return $response->getValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLastRowByColumn($column = "A")
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
// Ambil spreadsheet
|
||||||
|
$spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID);
|
||||||
|
$sheets = $spreadsheet->getSheets();
|
||||||
|
|
||||||
|
if (!empty($sheets)) {
|
||||||
|
// Ambil nama sheet pertama dengan benar
|
||||||
|
$firstSheetTitle = $sheets[0]->getProperties()->getTitle();
|
||||||
|
|
||||||
|
// ✅ Format range harus benar!
|
||||||
|
$range = "{$firstSheetTitle}!{$column}:{$column}";
|
||||||
|
|
||||||
|
// Ambil data dari kolom yang diminta
|
||||||
|
$response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range);
|
||||||
|
$values = $response->getValues();
|
||||||
|
|
||||||
|
// Cek nilai terakhir yang tidak kosong
|
||||||
|
$lastRow = 0;
|
||||||
|
if (!empty($values)) {
|
||||||
|
foreach ($values as $index => $row) {
|
||||||
|
if (!empty($row[0])) { // Jika ada data, update lastRow
|
||||||
|
$lastRow = $index + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $lastRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}catch(\Exception $e){
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function getHeader()
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
$spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID);
|
||||||
|
$sheets = $spreadsheet->getSheets();
|
||||||
|
|
||||||
|
// Ambil nama sheet pertama
|
||||||
|
$firstSheetTitle = $sheets[0]->getProperties()->getTitle();
|
||||||
|
|
||||||
|
// Ambil data dari baris pertama (header)
|
||||||
|
$range = "{$firstSheetTitle}!1:1";
|
||||||
|
$response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range);
|
||||||
|
$values = $response->getValues();
|
||||||
|
|
||||||
|
// Kembalikan header (baris pertama)
|
||||||
|
return !empty($values) ? $values[0] : [];
|
||||||
|
}catch(\Exception $e){
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLastColumn()
|
||||||
|
{
|
||||||
|
$spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID);
|
||||||
|
$sheets = $spreadsheet->getSheets();
|
||||||
|
|
||||||
|
// Ambil nama sheet pertama
|
||||||
|
$firstSheetTitle = $sheets[0]->getProperties()->getTitle();
|
||||||
|
|
||||||
|
// Ambil baris pertama untuk mendapatkan jumlah kolom yang terisi
|
||||||
|
$range = "{$firstSheetTitle}!1:1";
|
||||||
|
$response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range);
|
||||||
|
$values = $response->getValues();
|
||||||
|
|
||||||
|
// Hitung jumlah kolom yang memiliki nilai
|
||||||
|
return !empty($values) ? count(array_filter($values[0], fn($value) => $value !== "")) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSheetDataCollection($totalRow = 10){
|
||||||
|
try{
|
||||||
|
$spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID);
|
||||||
|
$sheets = $spreadsheet->getSheets();
|
||||||
|
$firstSheetTitle = $sheets[0]->getProperties()->getTitle();
|
||||||
|
|
||||||
|
$header = $this->getHeader();
|
||||||
|
$header = array_map(function($columnHeader) {
|
||||||
|
// Trim spaces first, then replace non-alphanumeric characters with underscores
|
||||||
|
$columnHeader = trim($columnHeader);
|
||||||
|
return strtolower(preg_replace('/[^A-Za-z0-9_]/', '_', $columnHeader));
|
||||||
|
}, $header);
|
||||||
|
$range = "{$firstSheetTitle}!2:{$totalRow}";
|
||||||
|
|
||||||
|
$response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range);
|
||||||
|
$values = $response->getValues();
|
||||||
|
|
||||||
|
$mappedData = [];
|
||||||
|
if (!empty($values)) {
|
||||||
|
foreach ($values as $row) {
|
||||||
|
$rowData = [];
|
||||||
|
foreach ($header as $index => $columnHeader) {
|
||||||
|
// Map header to the corresponding value from the row
|
||||||
|
$rowData[$columnHeader] = isset($row[$index]) ? $row[$index] : null;
|
||||||
|
}
|
||||||
|
$mappedData[] = $rowData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $mappedData;
|
||||||
|
}catch(\Exception $e){
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function get_data_by_sheet($no_sheet = 1){
|
||||||
|
$spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID);
|
||||||
|
$sheets = $spreadsheet->getSheets();
|
||||||
|
$sheetTitle = $sheets[$no_sheet]->getProperties()->getTitle();
|
||||||
|
$range = "{$sheetTitle}";
|
||||||
|
$response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range);
|
||||||
|
$values = $response->getValues();
|
||||||
|
return!empty($values)? $values : [];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App;
|
namespace App\Services;
|
||||||
use App\Traits\GlobalApiResponse;
|
use App\Traits\GlobalApiResponse;
|
||||||
use GuzzleHttp\Client;
|
use GuzzleHttp\Client;
|
||||||
use Exception;
|
use Exception;
|
||||||
@@ -26,7 +26,7 @@ class ServiceClient
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function makeRequest($url, $method = 'GET', $body = null, $headers = [], $timeout = 300){
|
public function makeRequest($url, $method = 'GET', $body = null, $headers = [], $timeout = 14400){
|
||||||
try {
|
try {
|
||||||
|
|
||||||
$headers = array_merge($this->headers, $headers);
|
$headers = array_merge($this->headers, $headers);
|
||||||
@@ -42,10 +42,17 @@ class ServiceClient
|
|||||||
}
|
}
|
||||||
|
|
||||||
$response = $this->client->request($method, $this->baseUrl . $url, $options);
|
$response = $this->client->request($method, $this->baseUrl . $url, $options);
|
||||||
|
$responseBody = (string) $response->getBody();
|
||||||
|
|
||||||
$resultResponse = json_decode($response->getBody(), true);
|
if (!str_contains($response->getHeaderLine('Content-Type'), 'application/json')) {
|
||||||
|
\Log::error('Unexpected response format: ' . $responseBody);
|
||||||
|
return $this->resError('API response is not JSON');
|
||||||
|
}
|
||||||
|
|
||||||
|
$resultResponse = json_decode($responseBody, true, 512, JSON_THROW_ON_ERROR);
|
||||||
return $this->resSuccess($resultResponse);
|
return $this->resSuccess($resultResponse);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
|
\Log::error('error from client service'. $e->getMessage());
|
||||||
return $this->resError($e->getMessage());
|
return $this->resError($e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
315
app/Services/ServiceSIMBG.php
Normal file
315
app/Services/ServiceSIMBG.php
Normal file
@@ -0,0 +1,315 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services;
|
||||||
|
|
||||||
|
use App\Enums\ImportDatasourceStatus;
|
||||||
|
use App\Models\BigdataResume;
|
||||||
|
use App\Models\GlobalSetting;
|
||||||
|
use App\Models\ImportDatasource;
|
||||||
|
use App\Models\PbgTaskIndexIntegrations;
|
||||||
|
use App\Models\PbgTaskPrasarana;
|
||||||
|
use App\Models\PbgTaskRetributions;
|
||||||
|
use Exception;
|
||||||
|
use App\Models\PbgTask;
|
||||||
|
use App\Traits\GlobalApiResponse;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use App\Services\ServiceClient;
|
||||||
|
|
||||||
|
class ServiceSIMBG
|
||||||
|
{
|
||||||
|
use GlobalApiResponse;
|
||||||
|
private $email;
|
||||||
|
private $password;
|
||||||
|
private $simbg_host;
|
||||||
|
private $fetch_per_page;
|
||||||
|
private $service_client;
|
||||||
|
/**
|
||||||
|
* Create a new class instance.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$settings = GlobalSetting::whereIn('key', [
|
||||||
|
'SIMBG_EMAIL', 'SIMBG_PASSWORD', 'SIMBG_HOST', 'FETCH_PER_PAGE'
|
||||||
|
])->pluck('value', 'key');
|
||||||
|
|
||||||
|
$this->email = trim((string) ($settings['SIMBG_EMAIL'] ?? ""));
|
||||||
|
$this->password = trim((string) ($settings['SIMBG_PASSWORD'] ?? ""));
|
||||||
|
$this->simbg_host = trim((string) ($settings['SIMBG_HOST'] ?? ""));
|
||||||
|
$this->fetch_per_page = trim((string) ($settings['FETCH_PER_PAGE'] ?? ""));
|
||||||
|
|
||||||
|
$this->service_client = new ServiceClient($this->simbg_host);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToken(){
|
||||||
|
try{
|
||||||
|
$url = "/api/user/v1/auth/login/";
|
||||||
|
$body = [
|
||||||
|
'email' => $this->email,
|
||||||
|
'password' => $this->password,
|
||||||
|
];
|
||||||
|
|
||||||
|
$res = $this->service_client->post($url, $body);
|
||||||
|
if(!$res->original['success']){
|
||||||
|
Log::error("Token not retrieved ", ['response' => $res]);
|
||||||
|
throw new Exception("Token not retrieved.");
|
||||||
|
}
|
||||||
|
return $res;
|
||||||
|
}catch(Exception $e){
|
||||||
|
Log::error("Error on method get token ", ['response' => $e->getMessage()]);
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function syncIndexIntegration($uuid, $token)
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
$url = "/api/pbg/v1/detail/" . $uuid . "/retribution/indeks-terintegrasi/";
|
||||||
|
|
||||||
|
$headers = [
|
||||||
|
'Authorization' => "Bearer " . $token,
|
||||||
|
];
|
||||||
|
|
||||||
|
$res = $this->service_client->get($url, $headers);
|
||||||
|
|
||||||
|
if (empty($res->original['success']) || !$res->original['success']) {
|
||||||
|
// Log error
|
||||||
|
Log::error("API response indicates failure", ['url' => $url, 'uuid' => $uuid]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $res->original['data']['data'] ?? null;
|
||||||
|
if (!$data) {
|
||||||
|
Log::error("No valid data returned from API", ['url' => $url, 'uuid' => $uuid]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$resultData = PbgTaskIndexIntegrations::updateOrCreate(
|
||||||
|
['pbg_task_uid' => $uuid],
|
||||||
|
[
|
||||||
|
'indeks_fungsi_bangunan' => $data['indeks_fungsi_bangunan'] ?? null,
|
||||||
|
'indeks_parameter_kompleksitas' => $data['indeks_parameter_kompleksitas'] ?? null,
|
||||||
|
'indeks_parameter_permanensi' => $data['indeks_parameter_permanensi'] ?? null,
|
||||||
|
'indeks_parameter_ketinggian' => $data['indeks_parameter_ketinggian'] ?? null,
|
||||||
|
'faktor_kepemilikan' => $data['faktor_kepemilikan'] ?? null,
|
||||||
|
'indeks_terintegrasi' => $data['indeks_terintegrasi'] ?? null,
|
||||||
|
'total' => $data['total'] ?? null,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}catch (Exception $e){
|
||||||
|
Log::error('error when sync index integration ', ['index integration'=> $e->getMessage()]);
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function syncTaskList()
|
||||||
|
{
|
||||||
|
$initResToken = $this->getToken();
|
||||||
|
|
||||||
|
$importDatasource = ImportDatasource::create([
|
||||||
|
'status' => ImportDatasourceStatus::Processing->value,
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (empty($initResToken->original['data']['token']['access'])) {
|
||||||
|
$importDatasource->update([
|
||||||
|
'status' => ImportDatasourceStatus::Failed->value,
|
||||||
|
'message' => 'Failed to retrieve token'
|
||||||
|
]);
|
||||||
|
return $this->resError("Failed to retrieve token");
|
||||||
|
}
|
||||||
|
|
||||||
|
$apiToken = $initResToken->original['data']['token']['access'];
|
||||||
|
$headers = ['Authorization' => "Bearer " . $apiToken];
|
||||||
|
|
||||||
|
$url = "/api/pbg/v1/list/?page=1&size={$this->fetch_per_page}&sort=ASC";
|
||||||
|
$initialResponse = $this->service_client->get($url, $headers);
|
||||||
|
|
||||||
|
$totalPage = $initialResponse->original['data']['total_page'] ?? 0;
|
||||||
|
if ($totalPage == 0) {
|
||||||
|
$importDatasource->update([
|
||||||
|
'status' => ImportDatasourceStatus::Failed->value,
|
||||||
|
'message' => 'Invalid response: no total_page'
|
||||||
|
]);
|
||||||
|
return $this->resError("Invalid response from API");
|
||||||
|
}
|
||||||
|
|
||||||
|
$savedCount = $failedCount = 0;
|
||||||
|
|
||||||
|
for ($currentPage = 1; $currentPage <= $totalPage; $currentPage++) {
|
||||||
|
$pageUrl = "/api/pbg/v1/list/?page={$currentPage}&size={$this->fetch_per_page}&sort=ASC";
|
||||||
|
$getToken = $this->getToken();
|
||||||
|
Log::info("response index integration", ['currentPage' => $currentPage]);
|
||||||
|
if (empty($getToken->original['data']['token']['access'])) {
|
||||||
|
$importDatasource->update([
|
||||||
|
'status' => ImportDatasourceStatus::Failed->value,
|
||||||
|
'message' => 'Failed to retrieve token'
|
||||||
|
]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$token = $getToken->original['data']['token']['access'];
|
||||||
|
$headers = ['Authorization' => "Bearer " . $token];
|
||||||
|
$response = $this->service_client->get($pageUrl, $headers);
|
||||||
|
$tasks = $response->original['data']['data'] ?? [];
|
||||||
|
|
||||||
|
if (empty($tasks)) {
|
||||||
|
$importDatasource->update([
|
||||||
|
'status' => ImportDatasourceStatus::Failed->value,
|
||||||
|
'message' => 'No data found on page'
|
||||||
|
]);
|
||||||
|
Log::warning("No data found on page", ['page' => $currentPage]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::info("executed page", ['page' => $currentPage, 'total' => $totalPage]);
|
||||||
|
|
||||||
|
$tasksCollective = [];
|
||||||
|
foreach ($tasks as $item) {
|
||||||
|
try {
|
||||||
|
$tasksCollective[] = [
|
||||||
|
'uuid' => $item['uid'],
|
||||||
|
'name' => $item['name'],
|
||||||
|
'owner_name' => $item['owner_name'],
|
||||||
|
'application_type' => $item['application_type'],
|
||||||
|
'application_type_name' => $item['application_type_name'],
|
||||||
|
'condition' => $item['condition'],
|
||||||
|
'registration_number' => $item['registration_number'],
|
||||||
|
'document_number' => $item['document_number'],
|
||||||
|
'address' => $item['address'],
|
||||||
|
'status' => $item['status'],
|
||||||
|
'status_name' => $item['status_name'],
|
||||||
|
'slf_status' => $item['slf_status'] ?? null,
|
||||||
|
'slf_status_name' => $item['slf_status_name'] ?? null,
|
||||||
|
'function_type' => $item['function_type'],
|
||||||
|
'consultation_type' => $item['consultation_type'],
|
||||||
|
'due_date' => $item['due_date'],
|
||||||
|
'land_certificate_phase' => $item['land_certificate_phase'],
|
||||||
|
'task_created_at' => isset($item['created_at']) ? Carbon::parse($item['created_at'])->format('Y-m-d H:i:s') : null,
|
||||||
|
'updated_at' => now(),
|
||||||
|
'created_at' => now(),
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->syncIndexIntegration($item['uid'], $token);
|
||||||
|
|
||||||
|
$this->syncTaskDetailSubmit($item['uid'], $token);
|
||||||
|
|
||||||
|
$savedCount++;
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$failedCount++;
|
||||||
|
$importDatasource->update([
|
||||||
|
'status' => ImportDatasourceStatus::Failed->value,
|
||||||
|
'message' => "Successfully processed: $savedCount, Failed: $failedCount"
|
||||||
|
]);
|
||||||
|
Log::error("Failed to process task", [
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'task' => $item,
|
||||||
|
]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PbgTask::upsert($tasksCollective, ['uuid'], [
|
||||||
|
'name', 'owner_name', 'application_type', 'application_type_name', 'condition',
|
||||||
|
'registration_number', 'document_number', 'address', 'status', 'status_name',
|
||||||
|
'slf_status', 'slf_status_name', 'function_type', 'consultation_type', 'due_date',
|
||||||
|
'land_certificate_phase', 'task_created_at', 'updated_at'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$importDatasource->update([
|
||||||
|
'status' => ImportDatasourceStatus::Success->value,
|
||||||
|
'message' => "Successfully processed: $savedCount, Failed: $failedCount"
|
||||||
|
]);
|
||||||
|
|
||||||
|
BigdataResume::generateResumeData($importDatasource->id);
|
||||||
|
|
||||||
|
Log::info("syncTaskList completed", ['savedCount' => $savedCount, 'failedCount' => $failedCount]);
|
||||||
|
|
||||||
|
return $this->resSuccess(['savedCount' => $savedCount, 'failedCount' => $failedCount]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function syncTaskDetailSubmit($uuid, $token)
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
$url = "/api/pbg/v1/detail/" . $uuid . "/retribution/submit/";
|
||||||
|
$headers = [
|
||||||
|
'Authorization' => "Bearer " . $token,
|
||||||
|
];
|
||||||
|
|
||||||
|
$res = $this->service_client->get($url, $headers);
|
||||||
|
|
||||||
|
if (empty($res->original['success']) || !$res->original['success']) {
|
||||||
|
// Log error
|
||||||
|
Log::error("API response indicates failure", ['url' => $url, 'uuid' => $uuid]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $res->original['data']['data'] ?? [];
|
||||||
|
if (empty($data)) {
|
||||||
|
Log::error("No data returned from API", ['url' => $url, 'uuid' => $uuid]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$detailCreatedAt = isset($data['created_at'])
|
||||||
|
? Carbon::parse($data['created_at'])->format('Y-m-d H:i:s')
|
||||||
|
: null;
|
||||||
|
|
||||||
|
$detailUpdatedAt = isset($data['updated_at'])
|
||||||
|
? Carbon::parse($data['updated_at'])->format('Y-m-d H:i:s')
|
||||||
|
: null;
|
||||||
|
|
||||||
|
$pbg_task_retributions = PbgTaskRetributions::updateOrCreate(
|
||||||
|
['detail_id' => $data['id']],
|
||||||
|
[
|
||||||
|
'detail_uid' => $data['uid'] ?? null,
|
||||||
|
'detail_created_at' => $detailCreatedAt ?? null,
|
||||||
|
'detail_updated_at' => $detailUpdatedAt ?? null,
|
||||||
|
'luas_bangunan' => $data['luas_bangunan'] ?? null,
|
||||||
|
'indeks_lokalitas' => $data['indeks_lokalitas'] ?? null,
|
||||||
|
'wilayah_shst' => $data['wilayah_shst'] ?? null,
|
||||||
|
'kegiatan_id' => $data['kegiatan']['id'] ?? null,
|
||||||
|
'kegiatan_name' => $data['kegiatan']['name'] ?? null,
|
||||||
|
'nilai_shst' => $data['nilai_shst'] ?? null,
|
||||||
|
'indeks_terintegrasi' => $data['indeks_terintegrasi'] ?? null,
|
||||||
|
'indeks_bg_terbangun' => $data['indeks_bg_terbangun'] ?? null,
|
||||||
|
'nilai_retribusi_bangunan' => $data['nilai_retribusi_bangunan'] ?? null,
|
||||||
|
'nilai_prasarana' => $data['nilai_prasarana'] ?? null,
|
||||||
|
'created_by' => $data['created_by'] ?? null,
|
||||||
|
'pbg_document' => $data['pbg_document'] ?? null,
|
||||||
|
'underpayment' => $data['underpayment'] ?? null,
|
||||||
|
'skrd_amount' => $data['skrd_amount'] ?? null,
|
||||||
|
'pbg_task_uid' => $uuid,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$pbg_task_retribution_id = $pbg_task_retributions->id;
|
||||||
|
|
||||||
|
$prasaranaData = $data['prasarana'] ?? [];
|
||||||
|
if (!empty($prasaranaData)) {
|
||||||
|
$insertData = array_map(fn($item) => [
|
||||||
|
'pbg_task_uid' => $uuid,
|
||||||
|
'pbg_task_retribution_id' => $pbg_task_retribution_id,
|
||||||
|
'prasarana_id' => $item['id'] ?? null,
|
||||||
|
'prasarana_type' => $item['prasarana_type'] ?? null,
|
||||||
|
'building_type' => $item['building_type'] ?? null,
|
||||||
|
'total' => $item['total'] ?? null,
|
||||||
|
'quantity' => $item['quantity'] ?? null,
|
||||||
|
'unit' => $item['unit'] ?? null,
|
||||||
|
'index_prasarana' => $item['index_prasarana'] ?? null,
|
||||||
|
], $prasaranaData);
|
||||||
|
|
||||||
|
// Use bulk insert or upsert for faster database operation
|
||||||
|
PbgTaskPrasarana::upsert($insertData, ['prasarana_id']);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}catch(Exception $e){
|
||||||
|
Log::error("Failed to sync task detail submit", ['error' => $e->getMessage(), 'uuid' => $uuid]);
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
25
app/View/Components/ModalConfirmation.php
Normal file
25
app/View/Components/ModalConfirmation.php
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\View\Components;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Contracts\View\View;
|
||||||
|
use Illuminate\View\Component;
|
||||||
|
|
||||||
|
class ModalConfirmation extends Component
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create a new component instance.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the view / contents that represent the component.
|
||||||
|
*/
|
||||||
|
public function render(): View|Closure|string
|
||||||
|
{
|
||||||
|
return view('components.modal-confirmation');
|
||||||
|
}
|
||||||
|
}
|
||||||
25
app/View/Components/ToastNotification.php
Normal file
25
app/View/Components/ToastNotification.php
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\View\Components;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Contracts\View\View;
|
||||||
|
use Illuminate\View\Component;
|
||||||
|
|
||||||
|
class ToastNotification extends Component
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create a new component instance.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the view / contents that represent the component.
|
||||||
|
*/
|
||||||
|
public function render(): View|Closure|string
|
||||||
|
{
|
||||||
|
return view('components.toast-notification');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,10 +3,14 @@
|
|||||||
"name": "laravel/laravel",
|
"name": "laravel/laravel",
|
||||||
"type": "project",
|
"type": "project",
|
||||||
"description": "The skeleton application for the Laravel framework.",
|
"description": "The skeleton application for the Laravel framework.",
|
||||||
"keywords": ["laravel", "framework"],
|
"keywords": [
|
||||||
|
"laravel",
|
||||||
|
"framework"
|
||||||
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.2",
|
"php": "^8.2",
|
||||||
|
"google/apiclient": "^2.12",
|
||||||
"guzzlehttp/guzzle": "^7.9",
|
"guzzlehttp/guzzle": "^7.9",
|
||||||
"laravel/framework": "^11.31",
|
"laravel/framework": "^11.31",
|
||||||
"laravel/sanctum": "^4.0",
|
"laravel/sanctum": "^4.0",
|
||||||
|
|||||||
1381
composer.lock
generated
Executable file → Normal file
1381
composer.lock
generated
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
@@ -123,4 +123,5 @@ return [
|
|||||||
'store' => env('APP_MAINTENANCE_STORE', 'database'),
|
'store' => env('APP_MAINTENANCE_STORE', 'database'),
|
||||||
],
|
],
|
||||||
|
|
||||||
|
'api_url' => env('API_URL', 'http://localhost:8000')
|
||||||
];
|
];
|
||||||
|
|||||||
52
config/laravel-code-generator.php
Normal file
52
config/laravel-code-generator.php
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| CodeGenerator config overrides
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| It is a good idea to separate your configuration form the code-generator's
|
||||||
|
| own configuration. This way you won't lose any settings/preference
|
||||||
|
| you have when upgrading to a new version of the package.
|
||||||
|
|
|
||||||
|
| Additionally, you will always know any the configuration difference between
|
||||||
|
| the default config than your own.
|
||||||
|
|
|
||||||
|
| To override the setting that is found in the 'config/default.php' file, you'll
|
||||||
|
| need to create identical key here with a different value
|
||||||
|
|
|
||||||
|
| IMPORTANT: When overriding an option that is an array, the configurations
|
||||||
|
| are merged together using php's array_merge() function. This means that
|
||||||
|
| any option that you list here will take presence during a conflict in keys.
|
||||||
|
|
|
||||||
|
| EXAMPLE: The following addition to this file, will add another entry in
|
||||||
|
| the common_definitions collection
|
||||||
|
|
|
||||||
|
| 'common_definitions' =>
|
||||||
|
| [
|
||||||
|
| [
|
||||||
|
| 'match' => '*_at',
|
||||||
|
| 'set' => [
|
||||||
|
| 'css-class' => 'datetime-picker',
|
||||||
|
| ],
|
||||||
|
| ],
|
||||||
|
| ],
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| The default path of where the uploaded files live.
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| You can use Laravel Storage filesystem. By default, the code-generator
|
||||||
|
| uses the default file system.
|
||||||
|
| For more info about Laravel's file system visit
|
||||||
|
| https://laravel.com/docs/5.5/filesystem
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
'files_upload_path' => 'uploads',
|
||||||
|
|
||||||
|
];
|
||||||
92138
database/inject-data-seeder/villages_202502082240.sql
Normal file
92138
database/inject-data-seeder/villages_202502082240.sql
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('data_settings', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('key')->unique();
|
||||||
|
$table->string('value');
|
||||||
|
$table->string('type')->nullable()->default('integer');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('data_settings');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('pbg_task_google_sheet', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('jenis_konsultasi')->nullable();
|
||||||
|
$table->string('no_registrasi')->nullable()->unique();
|
||||||
|
$table->string('nama_pemilik')->nullable();
|
||||||
|
$table->text('lokasi_bg')->nullable();
|
||||||
|
$table->string('fungsi_bg')->nullable();
|
||||||
|
$table->string('nama_bangunan')->nullable();
|
||||||
|
$table->date('tgl_permohonan')->nullable();
|
||||||
|
$table->string('status_verifikasi')->nullable();
|
||||||
|
$table->string('status_permohonan')->nullable();
|
||||||
|
$table->text('alamat_pemilik')->nullable();
|
||||||
|
$table->string('no_hp')->nullable();
|
||||||
|
$table->string('email')->nullable();
|
||||||
|
$table->date('tanggal_catatan')->nullable();
|
||||||
|
$table->text('catatan_kekurangan_dokumen')->nullable();
|
||||||
|
$table->string('gambar')->nullable();
|
||||||
|
$table->string('krk_kkpr')->nullable();
|
||||||
|
$table->string('no_krk')->nullable();
|
||||||
|
$table->string('lh')->nullable();
|
||||||
|
$table->string('ska')->nullable();
|
||||||
|
$table->text('keterangan')->nullable();
|
||||||
|
$table->string('helpdesk')->nullable();
|
||||||
|
$table->string('pj')->nullable();
|
||||||
|
$table->string('kepemilikan')->nullable();
|
||||||
|
$table->string('potensi_taru')->nullable();
|
||||||
|
$table->string('validasi_dinas')->nullable();
|
||||||
|
$table->string('kategori_retribusi')->nullable();
|
||||||
|
$table->string('no_urut_ba_tpt')->nullable();
|
||||||
|
$table->date('tanggal_ba_tpt')->nullable();
|
||||||
|
$table->string('no_urut_ba_tpa')->nullable();
|
||||||
|
$table->date('tanggal_ba_tpa')->nullable();
|
||||||
|
$table->string('no_urut_skrd')->nullable();
|
||||||
|
$table->date('tanggal_skrd')->nullable();
|
||||||
|
$table->string('ptsp')->nullable();
|
||||||
|
$table->string('selesai_terbit')->nullable();
|
||||||
|
$table->date('tanggal_pembayaran')->nullable();
|
||||||
|
$table->string('format_sts')->nullable();
|
||||||
|
$table->integer('tahun_terbit')->nullable();
|
||||||
|
$table->integer('tahun_berjalan')->nullable();
|
||||||
|
$table->string('kelurahan')->nullable();
|
||||||
|
$table->string('kecamatan')->nullable();
|
||||||
|
$table->decimal('lb', 20,2)->nullable();
|
||||||
|
$table->decimal('tb', 20, 2)->nullable();
|
||||||
|
$table->integer('jlb')->nullable();
|
||||||
|
$table->integer('unit')->nullable();
|
||||||
|
$table->integer('usulan_retribusi')->nullable();
|
||||||
|
$table->decimal('nilai_retribusi_keseluruhan_simbg', 20, 2)->nullable();
|
||||||
|
$table->decimal('nilai_retribusi_keseluruhan_pad', 20, 2)->nullable();
|
||||||
|
$table->decimal('denda', 20, 2)->nullable();
|
||||||
|
$table->string('latitude')->nullable();
|
||||||
|
$table->string('longitude')->nullable();
|
||||||
|
$table->string('nik_nib')->nullable();
|
||||||
|
$table->string('dok_tanah')->nullable();
|
||||||
|
$table->text('temuan')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('pbg_task_google_sheet');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('pbg_task', function (Blueprint $table) {
|
||||||
|
$constraintExists = DB::select("
|
||||||
|
SELECT COUNT(*) as count
|
||||||
|
FROM information_schema.statistics
|
||||||
|
WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'pbg_task'
|
||||||
|
AND index_name = 'pbg_task_uuid_unique'
|
||||||
|
");
|
||||||
|
|
||||||
|
if ($constraintExists[0]->count > 0) {
|
||||||
|
$table->dropUnique('pbg_task_uuid_unique');
|
||||||
|
}
|
||||||
|
$table->string('uuid')->nullable()->unique()->change();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('pbg_task', function (Blueprint $table) {
|
||||||
|
$table->dropUnique('pbg_task_uuid_unique');
|
||||||
|
$table->string('uuid')->nullable()->change();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('pbg_task_index_integrations', function (Blueprint $table) {
|
||||||
|
$constraintExists = DB::select("
|
||||||
|
SELECT COUNT(*) as count
|
||||||
|
FROM information_schema.statistics
|
||||||
|
WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'pbg_task_index_integrations'
|
||||||
|
AND index_name = 'pbg_task_index_integrations_pbg_task_uid_unique'
|
||||||
|
");
|
||||||
|
|
||||||
|
if ($constraintExists[0]->count > 0) {
|
||||||
|
$table->dropUnique('pbg_task_index_integrations_pbg_task_uid_unique');
|
||||||
|
}
|
||||||
|
$table->string('pbg_task_uid')->unique()->change();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('pbg_task_index_integrations', function (Blueprint $table) {
|
||||||
|
$table->dropUnique('pbg_task_index_integrations_pbg_task_uid_unique');
|
||||||
|
$table->string('pbg_task_uid')->unique()->change();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('pbg_task_retributions', function (Blueprint $table) {
|
||||||
|
$constraintExists = DB::select("
|
||||||
|
SELECT COUNT(*) as count
|
||||||
|
FROM information_schema.statistics
|
||||||
|
WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'pbg_task_retributions'
|
||||||
|
AND index_name = 'pbg_task_retributions_detail_id_unique'
|
||||||
|
");
|
||||||
|
|
||||||
|
if ($constraintExists[0]->count > 0) {
|
||||||
|
$table->dropUnique('pbg_task_retributions_detail_id_unique');
|
||||||
|
}
|
||||||
|
$table->string('detail_id')->unique()->change();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('pbg_task_retributions', function (Blueprint $table) {
|
||||||
|
$table->dropUnique('pbg_task_retributions_detail_id_unique');
|
||||||
|
$table->string('detail_id')->unique()->change();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('pbg_task_prasarana', function (Blueprint $table) {
|
||||||
|
$constraintExists = DB::select("
|
||||||
|
SELECT COUNT(*) as count
|
||||||
|
FROM information_schema.statistics
|
||||||
|
WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'pbg_task_prasarana'
|
||||||
|
AND index_name = 'pbg_task_prasarana_prasarana_id_unique'
|
||||||
|
");
|
||||||
|
|
||||||
|
if ($constraintExists[0]->count > 0) {
|
||||||
|
$table->dropUnique('pbg_task_prasarana_prasarana_id_unique');
|
||||||
|
}
|
||||||
|
$table->integer('prasarana_id')->nullable()->unique()->change();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('pbg_task_prasarana', function (Blueprint $table) {
|
||||||
|
$table->dropUnique('pbg_task_prasarana_prasarana_id_unique');
|
||||||
|
$table->integer('prasarana_id')->nullable()->unique()->change();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('pbg_task_prasarana', function (Blueprint $table) {
|
||||||
|
$table->unsignedBigInteger('pbg_task_retribution_id')->nullable(); // nullable in case some records do not match
|
||||||
|
|
||||||
|
// Step 2: Define the foreign key relation from `table3` to `table2`
|
||||||
|
$table->foreign('pbg_task_retribution_id')->references('id')->on('pbg_task_retributions')->onDelete('cascade');
|
||||||
|
});
|
||||||
|
|
||||||
|
\DB::table('pbg_task_prasarana')
|
||||||
|
->join('pbg_task', 'pbg_task.uuid', '=', 'pbg_task_prasarana.pbg_task_uid') // Relating pbg_task_prasarana to pbg_task
|
||||||
|
->join('pbg_task_retributions', 'pbg_task_retributions.pbg_task_uid', '=', 'pbg_task.uuid') // Relating pbg_task_retributions to pbg_task
|
||||||
|
->whereNotNull('pbg_task_retributions.id') // Ensure the `pbg_task_retributions` id exists
|
||||||
|
->update(['pbg_task_prasarana.pbg_task_retribution_id' => \DB::raw('pbg_task_retributions.id')]); // Set the foreign key
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('pbg_task_prasarana', function (Blueprint $table) {
|
||||||
|
$table->dropForeign(['pbg_task_retribution_id']);
|
||||||
|
$table->dropColumn('pbg_task_retribution_id');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
29
database/migrations/2025_02_10_104053_create_roles_table.php
Normal file
29
database/migrations/2025_02_10_104053_create_roles_table.php
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('roles', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('name')->unique();
|
||||||
|
$table->text('description')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('roles');
|
||||||
|
}
|
||||||
|
};
|
||||||
33
database/migrations/2025_02_10_104254_create_menus_table.php
Normal file
33
database/migrations/2025_02_10_104254_create_menus_table.php
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('menus', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('name');
|
||||||
|
$table->string('url');
|
||||||
|
$table->string('icon')->nullable();
|
||||||
|
$table->unsignedBigInteger('parent_id')->nullable();
|
||||||
|
$table->integer('sort_order')->default(0);
|
||||||
|
$table->foreign('parent_id')->references('id')->on('menus')->onDelete('set null');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('menus');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('user_role', function (Blueprint $table) {
|
||||||
|
$table->foreignId('user_id')->constrained()->onDelete('cascade');
|
||||||
|
$table->foreignId('role_id')->constrained()->onDelete('cascade');
|
||||||
|
$table->primary(['user_id', 'role_id']);
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('user_role');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('role_menu', function (Blueprint $table) {
|
||||||
|
$table->foreignId('role_id')->constrained()->cascadeOnDelete();
|
||||||
|
$table->foreignId('menu_id')->constrained()->cascadeOnDelete();
|
||||||
|
$table->primary(['role_id', 'menu_id']);
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('role_menu');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('role_menu', function (Blueprint $table) {
|
||||||
|
$table->boolean('allow_show')->default(true)->after('menu_id');
|
||||||
|
$table->boolean('allow_create')->default(true)->after('allow_show');
|
||||||
|
$table->boolean('allow_update')->default(true)->after('allow_create');
|
||||||
|
$table->boolean('allow_destroy')->default(true)->after('allow_update');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('role_menu', function (Blueprint $table) {
|
||||||
|
$table->dropColumn(['allow_show','allow_create', 'allow_update', 'allow_destroy']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('bigdata_resumes', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->unsignedBigInteger('import_datasource_id');
|
||||||
|
$table->integer('potention_count')->default(0);
|
||||||
|
$table->decimal('potention_sum', 20, 2)->default(0);
|
||||||
|
$table->integer('non_verified_count')->default(0);
|
||||||
|
$table->decimal('non_verified_sum', 20, 2)->default(0);
|
||||||
|
$table->integer('verified_count')->default(0);
|
||||||
|
$table->decimal('verified_sum', 20, 2)->default(0);
|
||||||
|
$table->integer('business_count')->default(0);
|
||||||
|
$table->decimal('business_sum', 20, 2)->default(0);
|
||||||
|
$table->integer('non_business_count')->default(0);
|
||||||
|
$table->decimal('non_business_sum', 20, 2)->default(0);
|
||||||
|
$table->timestamps();
|
||||||
|
$table->foreign('import_datasource_id')->references('id')->on('import_datasources')->onDelete('cascade');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('bigdata_resumes');
|
||||||
|
}
|
||||||
|
};
|
||||||
70
database/seeders/DataSettingSeeder.php
Normal file
70
database/seeders/DataSettingSeeder.php
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use App\Models\DataSetting;
|
||||||
|
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
|
class DataSettingSeeder extends Seeder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the database seeds.
|
||||||
|
*/
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
$data_settings = [
|
||||||
|
[
|
||||||
|
"key" => "TARGET_PAD",
|
||||||
|
"value" => "50000000000",
|
||||||
|
"type" => "integer"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"key" => "TATA_RUANG",
|
||||||
|
"value" => "10000000000",
|
||||||
|
"type" => "integer"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"key" => "REALISASI_TERBIT_PBG_SUM",
|
||||||
|
"value" => "1507253788",
|
||||||
|
"type" => "integer"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"key" => "REALISASI_TERBIT_PBG_COUNT",
|
||||||
|
"value" => "88",
|
||||||
|
"type" => "integer"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"key" => "MENUNGGU_KLIK_DPMPTSP_SUM",
|
||||||
|
"value" => "83457536",
|
||||||
|
"type" => "integer"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"key" => "MENUNGGU_KLIK_DPMPTSP_COUNT",
|
||||||
|
"value" => "266",
|
||||||
|
"type" => "integer"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"key" => "PROSES_DINAS_TEKNIS_SUM",
|
||||||
|
"value" => "83457536",
|
||||||
|
"type" => "integer"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"key" => "PROSES_DINAS_TEKNIS_COUNT",
|
||||||
|
"value" => "11",
|
||||||
|
"type" => "integer"
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($data_settings as $setting) {
|
||||||
|
DataSetting::updateOrCreate([
|
||||||
|
"key" => $setting["key"],
|
||||||
|
],[
|
||||||
|
"value" => $setting["value"],
|
||||||
|
"type" => $setting["type"],
|
||||||
|
"created_at" => now(),
|
||||||
|
"updated_at" => now(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
204
database/seeders/UsersRoleMenuSeeder.php
Normal file
204
database/seeders/UsersRoleMenuSeeder.php
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use App\Models\Menu;
|
||||||
|
use App\Models\Role;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
|
class UsersRoleMenuSeeder extends Seeder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the database seeds.
|
||||||
|
*/
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
$roles = [
|
||||||
|
[
|
||||||
|
"name" => "superadmin",
|
||||||
|
"description" => "show all menus for super admins",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "admin",
|
||||||
|
"description" => "show only necessary menus for admins",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "operator",
|
||||||
|
"description" => "show only necessary menus for operators",
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
Role::upsert($roles, ['name']);
|
||||||
|
|
||||||
|
$parent_menus = [
|
||||||
|
[
|
||||||
|
"name" => "Dashboard",
|
||||||
|
"url" => "/dashboard",
|
||||||
|
"icon" => "mingcute:home-3-line",
|
||||||
|
"parent_id" => null,
|
||||||
|
"sort_order" => 1,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Master",
|
||||||
|
"url" => "/master",
|
||||||
|
"icon" => "mingcute:cylinder-line",
|
||||||
|
"parent_id" => null,
|
||||||
|
"sort_order" => 2,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Settings",
|
||||||
|
"url" => "/settings",
|
||||||
|
"icon" => "mingcute:settings-6-line",
|
||||||
|
"parent_id" => null,
|
||||||
|
"sort_order" => 3,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Data Settings",
|
||||||
|
"url" => "/data-settings",
|
||||||
|
"icon" => "mingcute:settings-1-line",
|
||||||
|
"parent_id" => null,
|
||||||
|
"sort_order" => 4,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Data",
|
||||||
|
"url" => "/data",
|
||||||
|
"icon" => "mingcute:task-line",
|
||||||
|
"parent_id" => null,
|
||||||
|
"sort_order" => 5,
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($parent_menus as $parent_menu) {
|
||||||
|
Menu::firstOrCreate(['name' => $parent_menu['name']], $parent_menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach Menus to Roles
|
||||||
|
$superadmin = Role::where('name', 'superadmin')->first();
|
||||||
|
$admin = Role::where('name', 'admin')->first();
|
||||||
|
$operator = Role::where('name', 'operator')->first();
|
||||||
|
|
||||||
|
$dashboard = Menu::where('name', 'Dashboard')->first();
|
||||||
|
$master = Menu::where('name', 'Master')->first();
|
||||||
|
$settings = Menu::where('name', 'Settings')->first();
|
||||||
|
$dataSettings = Menu::where('name', 'Data Settings')->first();
|
||||||
|
$data = Menu::where('name', 'Data')->first();
|
||||||
|
|
||||||
|
// create children menu
|
||||||
|
$children_menus = [
|
||||||
|
[
|
||||||
|
"name" => "Dashboard Pimpinan",
|
||||||
|
"url" => "dashboard.home",
|
||||||
|
"icon" => null,
|
||||||
|
"parent_id" => $dashboard->id,
|
||||||
|
"sort_order" => 1,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Dashboard PBG",
|
||||||
|
"url" => "dashboard.pbg",
|
||||||
|
"icon" => null,
|
||||||
|
"parent_id" => $dashboard->id,
|
||||||
|
"sort_order" => 2,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Users",
|
||||||
|
"url" => "users.index",
|
||||||
|
"icon" => null,
|
||||||
|
"parent_id" => $master->id,
|
||||||
|
"sort_order" => 1,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Syncronize",
|
||||||
|
"url" => "settings.syncronize",
|
||||||
|
"icon" => null,
|
||||||
|
"parent_id" => $settings->id,
|
||||||
|
"sort_order" => 1,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Menu",
|
||||||
|
"url" => "menus.index",
|
||||||
|
"icon" => null,
|
||||||
|
"parent_id" => $settings->id,
|
||||||
|
"sort_order" => 2,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Role",
|
||||||
|
"url" => "roles.index",
|
||||||
|
"icon" => null,
|
||||||
|
"parent_id" => $settings->id,
|
||||||
|
"sort_order" => 3,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Setting Dashboard",
|
||||||
|
"url" => "data-settings.index",
|
||||||
|
"icon" => null,
|
||||||
|
"parent_id" => $dataSettings->id,
|
||||||
|
"sort_order" => 1,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "PBG",
|
||||||
|
"url" => "pbg-task.index",
|
||||||
|
"icon" => null,
|
||||||
|
"parent_id" => $data->id,
|
||||||
|
"sort_order" => 1,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"name" => "Reklame",
|
||||||
|
"url" => "advertisements.index",
|
||||||
|
"icon" => null,
|
||||||
|
"parent_id" => $data->id,
|
||||||
|
"sort_order" => 1,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($children_menus as $child_menu) {
|
||||||
|
Menu::firstOrCreate(['name' => $child_menu['name']], $child_menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
$dashboard_pimpinan = Menu::where('name', 'Dashboard Pimpinan')->first();
|
||||||
|
$dashboard_pbg = Menu::where('name', 'Dashboard PBG')->first();
|
||||||
|
$users = Menu::where('name', 'Users')->first();
|
||||||
|
$syncronize = Menu::where('name', 'Syncronize')->first();
|
||||||
|
$setting_menu = Menu::where('name', 'Menu')->first();
|
||||||
|
$setting_role = Menu::where('name', 'Role')->first();
|
||||||
|
$setting_dashboard = Menu::where('name', 'Setting Dashboard')->first();
|
||||||
|
$setting_pbg = Menu::where('name', 'PBG')->first();
|
||||||
|
$reklame = Menu::where('name', 'Reklame')->first();
|
||||||
|
|
||||||
|
// Superadmin gets all menus
|
||||||
|
$superadmin->menus()->sync([
|
||||||
|
// parent
|
||||||
|
$dashboard->id => ["allow_show" => true, "allow_create" => false, "allow_update" => false, "allow_destroy" => false],
|
||||||
|
$master->id => ["allow_show" => true, "allow_create" => false, "allow_update" => false, "allow_destroy" => false],
|
||||||
|
$settings->id => ["allow_show" => true, "allow_create" => false, "allow_update" => false, "allow_destroy" => false],
|
||||||
|
$dataSettings->id => ["allow_show" => true, "allow_create" => false, "allow_update" => false, "allow_destroy" => false],
|
||||||
|
$data->id => ["allow_show" => true, "allow_create" => false, "allow_update" => false, "allow_destroy" => false],
|
||||||
|
// children
|
||||||
|
$dashboard_pimpinan->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
||||||
|
$dashboard_pbg->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
||||||
|
$users->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
||||||
|
$syncronize->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
||||||
|
$setting_menu->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
||||||
|
$setting_role->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
||||||
|
$setting_dashboard->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
||||||
|
$setting_pbg->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
||||||
|
$reklame->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Admin gets limited menus
|
||||||
|
$admin->menus()->sync([
|
||||||
|
$dashboard->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
||||||
|
$master->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
||||||
|
$settings->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Operator gets only basic menus with full permissions
|
||||||
|
$operator->menus()->sync([
|
||||||
|
$dashboard->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
||||||
|
$data->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true],
|
||||||
|
]);
|
||||||
|
// Attach User to role super admin
|
||||||
|
User::findOrFail(1)->roles()->sync([$superadmin->id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
5906
package-lock.json
generated
5906
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
65
package.json
65
package.json
@@ -1,34 +1,35 @@
|
|||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"dev": "vite"
|
"dev": "vite"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.20",
|
||||||
"axios": "^1.7.4",
|
"axios": "^1.7.4",
|
||||||
"concurrently": "^9.0.1",
|
"concurrently": "^9.0.1",
|
||||||
"laravel-vite-plugin": "^1.0",
|
"laravel-vite-plugin": "^1.0",
|
||||||
"postcss": "^8.4.47",
|
"postcss": "^8.4.47",
|
||||||
"sass": "^1.81.1",
|
"sass": "^1.81.1",
|
||||||
"tailwindcss": "^3.4.13",
|
"tailwindcss": "^3.4.13",
|
||||||
"vite": "^5.0"
|
"vite": "^5.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"apexcharts": "^3.44.2",
|
"apexcharts": "^3.44.2",
|
||||||
"bootstrap": "^5.3.3",
|
"big.js": "^6.2.2",
|
||||||
"countup.js": "^2.3.2",
|
"bootstrap": "^5.3.3",
|
||||||
"dropzone": "^5.9.0",
|
"countup.js": "^2.3.2",
|
||||||
"flatpickr": "^4.6.13",
|
"dropzone": "^5.9.0",
|
||||||
"gmaps": "^0.4.25",
|
"flatpickr": "^4.6.13",
|
||||||
"gridjs": "^5.1.0",
|
"gmaps": "^0.4.25",
|
||||||
"iconify-icon": "^2.1.0",
|
"gridjs": "^5.1.0",
|
||||||
"jsvectormap": "^1.5.1",
|
"iconify-icon": "^2.1.0",
|
||||||
"moment": "^2.29.4",
|
"jsvectormap": "^1.5.1",
|
||||||
"node-waves": "^0.7.6",
|
"moment": "^2.29.4",
|
||||||
"quill": "^1.3.7",
|
"node-waves": "^0.7.6",
|
||||||
"simplebar": "^5.3.9",
|
"quill": "^1.3.7",
|
||||||
"wnumb": "^1.2.0"
|
"simplebar": "^5.3.9",
|
||||||
}
|
"wnumb": "^1.2.0"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
408
public/build/.vite/manifest.json
Normal file
408
public/build/.vite/manifest.json
Normal file
@@ -0,0 +1,408 @@
|
|||||||
|
{
|
||||||
|
"__commonjsHelpers-C4iS2aBk.js": {
|
||||||
|
"file": "assets/_commonjsHelpers-C4iS2aBk.js",
|
||||||
|
"name": "_commonjsHelpers"
|
||||||
|
},
|
||||||
|
"_apexcharts.common-7mov3gaG.js": {
|
||||||
|
"file": "assets/apexcharts.common-7mov3gaG.js",
|
||||||
|
"name": "apexcharts.common",
|
||||||
|
"imports": [
|
||||||
|
"__commonjsHelpers-C4iS2aBk.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_dropzone-B5tMhgFp.js": {
|
||||||
|
"file": "assets/dropzone-B5tMhgFp.js",
|
||||||
|
"name": "dropzone"
|
||||||
|
},
|
||||||
|
"_global-config-9uDKFQ8j.js": {
|
||||||
|
"file": "assets/global-config-9uDKFQ8j.js",
|
||||||
|
"name": "global-config"
|
||||||
|
},
|
||||||
|
"_gridjs.umd-BiCNXlqL.js": {
|
||||||
|
"file": "assets/gridjs.umd-BiCNXlqL.js",
|
||||||
|
"name": "gridjs.umd",
|
||||||
|
"imports": [
|
||||||
|
"__commonjsHelpers-C4iS2aBk.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_world-BH8KG5u4.js": {
|
||||||
|
"file": "assets/world-BH8KG5u4.js",
|
||||||
|
"name": "world",
|
||||||
|
"imports": [
|
||||||
|
"__commonjsHelpers-C4iS2aBk.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/flatpickr/dist/flatpickr.min.css": {
|
||||||
|
"file": "assets/flatpickr-CksuuEqD.css",
|
||||||
|
"src": "node_modules/flatpickr/dist/flatpickr.min.css",
|
||||||
|
"isEntry": true
|
||||||
|
},
|
||||||
|
"node_modules/flatpickr/dist/themes/dark.css": {
|
||||||
|
"file": "assets/dark-CLxH30By.css",
|
||||||
|
"src": "node_modules/flatpickr/dist/themes/dark.css",
|
||||||
|
"isEntry": true
|
||||||
|
},
|
||||||
|
"node_modules/gridjs/dist/theme/mermaid.css": {
|
||||||
|
"file": "assets/mermaid-B5wPN5RC.css",
|
||||||
|
"src": "node_modules/gridjs/dist/theme/mermaid.css",
|
||||||
|
"isEntry": true
|
||||||
|
},
|
||||||
|
"node_modules/gridjs/dist/theme/mermaid.min.css": {
|
||||||
|
"file": "assets/mermaid-1KsrsKla.css",
|
||||||
|
"src": "node_modules/gridjs/dist/theme/mermaid.min.css",
|
||||||
|
"isEntry": true
|
||||||
|
},
|
||||||
|
"node_modules/quill/dist/quill.bubble.css": {
|
||||||
|
"file": "assets/quill-BzaoboQ1.css",
|
||||||
|
"src": "node_modules/quill/dist/quill.bubble.css",
|
||||||
|
"isEntry": true
|
||||||
|
},
|
||||||
|
"node_modules/quill/dist/quill.snow.css": {
|
||||||
|
"file": "assets/quill-D-Ncpkvi.css",
|
||||||
|
"src": "node_modules/quill/dist/quill.snow.css",
|
||||||
|
"isEntry": true
|
||||||
|
},
|
||||||
|
"public/images/bg-dashboard.jpg": {
|
||||||
|
"file": "assets/bg-dashboard-CUwt8_jP.jpg",
|
||||||
|
"src": "public/images/bg-dashboard.jpg"
|
||||||
|
},
|
||||||
|
"resources/fonts/boxicons.eot": {
|
||||||
|
"file": "assets/boxicons-0t2gX1vj.eot",
|
||||||
|
"src": "resources/fonts/boxicons.eot"
|
||||||
|
},
|
||||||
|
"resources/fonts/boxicons.svg": {
|
||||||
|
"file": "assets/boxicons-KSR1BgPC.svg",
|
||||||
|
"src": "resources/fonts/boxicons.svg"
|
||||||
|
},
|
||||||
|
"resources/fonts/boxicons.ttf": {
|
||||||
|
"file": "assets/boxicons-BEZXjQG5.ttf",
|
||||||
|
"src": "resources/fonts/boxicons.ttf"
|
||||||
|
},
|
||||||
|
"resources/fonts/boxicons.woff": {
|
||||||
|
"file": "assets/boxicons-CEgI8ccS.woff",
|
||||||
|
"src": "resources/fonts/boxicons.woff"
|
||||||
|
},
|
||||||
|
"resources/fonts/boxicons.woff2": {
|
||||||
|
"file": "assets/boxicons-C7pETWQJ.woff2",
|
||||||
|
"src": "resources/fonts/boxicons.woff2"
|
||||||
|
},
|
||||||
|
"resources/js/app.js": {
|
||||||
|
"file": "assets/app-Wz_4hh3O.js",
|
||||||
|
"name": "app",
|
||||||
|
"src": "resources/js/app.js",
|
||||||
|
"isEntry": true,
|
||||||
|
"imports": [
|
||||||
|
"__commonjsHelpers-C4iS2aBk.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resources/js/config.js": {
|
||||||
|
"file": "assets/config-DqV4EBmE.js",
|
||||||
|
"name": "config",
|
||||||
|
"src": "resources/js/config.js",
|
||||||
|
"isEntry": true
|
||||||
|
},
|
||||||
|
"resources/js/dashboards/bigdata.js": {
|
||||||
|
"file": "assets/bigdata-Cyb9tZIY.js",
|
||||||
|
"name": "bigdata",
|
||||||
|
"src": "resources/js/dashboards/bigdata.js",
|
||||||
|
"isEntry": true,
|
||||||
|
"imports": [
|
||||||
|
"_global-config-9uDKFQ8j.js"
|
||||||
|
],
|
||||||
|
"css": [
|
||||||
|
"assets/flatpickr-CksuuEqD.css"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resources/js/data-settings/create.js": {
|
||||||
|
"file": "assets/create-C1IbeTHP.js",
|
||||||
|
"name": "create",
|
||||||
|
"src": "resources/js/data-settings/create.js",
|
||||||
|
"isEntry": true
|
||||||
|
},
|
||||||
|
"resources/js/data-settings/index.js": {
|
||||||
|
"file": "assets/index-BOfsbw53.js",
|
||||||
|
"name": "index",
|
||||||
|
"src": "resources/js/data-settings/index.js",
|
||||||
|
"isEntry": true,
|
||||||
|
"imports": [
|
||||||
|
"_gridjs.umd-BiCNXlqL.js",
|
||||||
|
"_global-config-9uDKFQ8j.js",
|
||||||
|
"__commonjsHelpers-C4iS2aBk.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resources/js/data-settings/update.js": {
|
||||||
|
"file": "assets/update-nNw3P4hj.js",
|
||||||
|
"name": "update",
|
||||||
|
"src": "resources/js/data-settings/update.js",
|
||||||
|
"isEntry": true
|
||||||
|
},
|
||||||
|
"resources/js/data/advertisements/data-advertisements.js": {
|
||||||
|
"file": "assets/data-advertisements-C_ZfB4RA.js",
|
||||||
|
"name": "data-advertisements",
|
||||||
|
"src": "resources/js/data/advertisements/data-advertisements.js",
|
||||||
|
"isEntry": true,
|
||||||
|
"imports": [
|
||||||
|
"_gridjs.umd-BiCNXlqL.js",
|
||||||
|
"_global-config-9uDKFQ8j.js",
|
||||||
|
"__commonjsHelpers-C4iS2aBk.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resources/js/data/advertisements/form-create-update.js": {
|
||||||
|
"file": "assets/form-create-update-CyN97GsU.js",
|
||||||
|
"name": "form-create-update",
|
||||||
|
"src": "resources/js/data/advertisements/form-create-update.js",
|
||||||
|
"isEntry": true,
|
||||||
|
"imports": [
|
||||||
|
"_global-config-9uDKFQ8j.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resources/js/data/advertisements/form-upload.js": {
|
||||||
|
"file": "assets/form-upload-Ci7Kyzc7.js",
|
||||||
|
"name": "form-upload",
|
||||||
|
"src": "resources/js/data/advertisements/form-upload.js",
|
||||||
|
"isEntry": true,
|
||||||
|
"imports": [
|
||||||
|
"_dropzone-B5tMhgFp.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resources/js/master/users/create.js": {
|
||||||
|
"file": "assets/create-RO4xgm-f.js",
|
||||||
|
"name": "create",
|
||||||
|
"src": "resources/js/master/users/create.js",
|
||||||
|
"isEntry": true
|
||||||
|
},
|
||||||
|
"resources/js/master/users/update.js": {
|
||||||
|
"file": "assets/update-DhoG4v8r.js",
|
||||||
|
"name": "update",
|
||||||
|
"src": "resources/js/master/users/update.js",
|
||||||
|
"isEntry": true
|
||||||
|
},
|
||||||
|
"resources/js/master/users/users.js": {
|
||||||
|
"file": "assets/users-jfWUOWyP.js",
|
||||||
|
"name": "users",
|
||||||
|
"src": "resources/js/master/users/users.js",
|
||||||
|
"isEntry": true,
|
||||||
|
"imports": [
|
||||||
|
"_gridjs.umd-BiCNXlqL.js",
|
||||||
|
"_global-config-9uDKFQ8j.js",
|
||||||
|
"__commonjsHelpers-C4iS2aBk.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resources/js/menus/create.js": {
|
||||||
|
"file": "assets/create-ChUgh-yc.js",
|
||||||
|
"name": "create",
|
||||||
|
"src": "resources/js/menus/create.js",
|
||||||
|
"isEntry": true
|
||||||
|
},
|
||||||
|
"resources/js/menus/index.js": {
|
||||||
|
"file": "assets/index-C4xA1kYa.js",
|
||||||
|
"name": "index",
|
||||||
|
"src": "resources/js/menus/index.js",
|
||||||
|
"isEntry": true,
|
||||||
|
"imports": [
|
||||||
|
"_gridjs.umd-BiCNXlqL.js",
|
||||||
|
"_global-config-9uDKFQ8j.js",
|
||||||
|
"__commonjsHelpers-C4iS2aBk.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resources/js/menus/update.js": {
|
||||||
|
"file": "assets/update-8JQOGES4.js",
|
||||||
|
"name": "update",
|
||||||
|
"src": "resources/js/menus/update.js",
|
||||||
|
"isEntry": true
|
||||||
|
},
|
||||||
|
"resources/js/pages/chart.js": {
|
||||||
|
"file": "assets/chart-DQBoD9wk.js",
|
||||||
|
"name": "chart",
|
||||||
|
"src": "resources/js/pages/chart.js",
|
||||||
|
"isEntry": true,
|
||||||
|
"imports": [
|
||||||
|
"_apexcharts.common-7mov3gaG.js",
|
||||||
|
"__commonjsHelpers-C4iS2aBk.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resources/js/pages/dashboard.js": {
|
||||||
|
"file": "assets/dashboard-nkb3Omy9.js",
|
||||||
|
"name": "dashboard",
|
||||||
|
"src": "resources/js/pages/dashboard.js",
|
||||||
|
"isEntry": true,
|
||||||
|
"imports": [
|
||||||
|
"_apexcharts.common-7mov3gaG.js",
|
||||||
|
"_world-BH8KG5u4.js",
|
||||||
|
"__commonjsHelpers-C4iS2aBk.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resources/js/pages/form-fileupload.js": {
|
||||||
|
"file": "assets/form-fileupload-DGbdX8GT.js",
|
||||||
|
"name": "form-fileupload",
|
||||||
|
"src": "resources/js/pages/form-fileupload.js",
|
||||||
|
"isEntry": true,
|
||||||
|
"imports": [
|
||||||
|
"_dropzone-B5tMhgFp.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resources/js/pages/form-flatepicker.js": {
|
||||||
|
"file": "assets/form-flatepicker-ChSlk6xC.js",
|
||||||
|
"name": "form-flatepicker",
|
||||||
|
"src": "resources/js/pages/form-flatepicker.js",
|
||||||
|
"isEntry": true,
|
||||||
|
"imports": [
|
||||||
|
"__commonjsHelpers-C4iS2aBk.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resources/js/pages/form-quilljs.js": {
|
||||||
|
"file": "assets/form-quilljs-pSObT4Ti.js",
|
||||||
|
"name": "form-quilljs",
|
||||||
|
"src": "resources/js/pages/form-quilljs.js",
|
||||||
|
"isEntry": true,
|
||||||
|
"imports": [
|
||||||
|
"__commonjsHelpers-C4iS2aBk.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resources/js/pages/maps-canada.js": {
|
||||||
|
"file": "assets/maps-canada-Btz07hSk.js",
|
||||||
|
"name": "maps-canada",
|
||||||
|
"src": "resources/js/pages/maps-canada.js",
|
||||||
|
"isEntry": true
|
||||||
|
},
|
||||||
|
"resources/js/pages/maps-google.js": {
|
||||||
|
"file": "assets/maps-google-KamR_rNw.js",
|
||||||
|
"name": "maps-google",
|
||||||
|
"src": "resources/js/pages/maps-google.js",
|
||||||
|
"isEntry": true,
|
||||||
|
"imports": [
|
||||||
|
"__commonjsHelpers-C4iS2aBk.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resources/js/pages/maps-iraq.js": {
|
||||||
|
"file": "assets/maps-iraq-Blhf9V_8.js",
|
||||||
|
"name": "maps-iraq",
|
||||||
|
"src": "resources/js/pages/maps-iraq.js",
|
||||||
|
"isEntry": true
|
||||||
|
},
|
||||||
|
"resources/js/pages/maps-russia.js": {
|
||||||
|
"file": "assets/maps-russia-C3XucoMP.js",
|
||||||
|
"name": "maps-russia",
|
||||||
|
"src": "resources/js/pages/maps-russia.js",
|
||||||
|
"isEntry": true
|
||||||
|
},
|
||||||
|
"resources/js/pages/maps-spain.js": {
|
||||||
|
"file": "assets/maps-spain-CdBIHB66.js",
|
||||||
|
"name": "maps-spain",
|
||||||
|
"src": "resources/js/pages/maps-spain.js",
|
||||||
|
"isEntry": true
|
||||||
|
},
|
||||||
|
"resources/js/pages/maps-vector.js": {
|
||||||
|
"file": "assets/maps-vector-C2WpvMU7.js",
|
||||||
|
"name": "maps-vector",
|
||||||
|
"src": "resources/js/pages/maps-vector.js",
|
||||||
|
"isEntry": true,
|
||||||
|
"imports": [
|
||||||
|
"_world-BH8KG5u4.js",
|
||||||
|
"__commonjsHelpers-C4iS2aBk.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resources/js/pages/table-gridjs.js": {
|
||||||
|
"file": "assets/table-gridjs-BQh80cFh.js",
|
||||||
|
"name": "table-gridjs",
|
||||||
|
"src": "resources/js/pages/table-gridjs.js",
|
||||||
|
"isEntry": true,
|
||||||
|
"imports": [
|
||||||
|
"_gridjs.umd-BiCNXlqL.js",
|
||||||
|
"__commonjsHelpers-C4iS2aBk.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resources/js/pbg-task/index.js": {
|
||||||
|
"file": "assets/index-CqcfkvSL.js",
|
||||||
|
"name": "index",
|
||||||
|
"src": "resources/js/pbg-task/index.js",
|
||||||
|
"isEntry": true,
|
||||||
|
"imports": [
|
||||||
|
"_gridjs.umd-BiCNXlqL.js",
|
||||||
|
"_global-config-9uDKFQ8j.js",
|
||||||
|
"__commonjsHelpers-C4iS2aBk.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resources/js/roles/create.js": {
|
||||||
|
"file": "assets/create-Dd-lHOwF.js",
|
||||||
|
"name": "create",
|
||||||
|
"src": "resources/js/roles/create.js",
|
||||||
|
"isEntry": true
|
||||||
|
},
|
||||||
|
"resources/js/roles/index.js": {
|
||||||
|
"file": "assets/index-C_kI_q7O.js",
|
||||||
|
"name": "index",
|
||||||
|
"src": "resources/js/roles/index.js",
|
||||||
|
"isEntry": true,
|
||||||
|
"imports": [
|
||||||
|
"_gridjs.umd-BiCNXlqL.js",
|
||||||
|
"_global-config-9uDKFQ8j.js",
|
||||||
|
"__commonjsHelpers-C4iS2aBk.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resources/js/roles/role_menu.js": {
|
||||||
|
"file": "assets/role_menu-BuFAi1wM.js",
|
||||||
|
"name": "role_menu",
|
||||||
|
"src": "resources/js/roles/role_menu.js",
|
||||||
|
"isEntry": true
|
||||||
|
},
|
||||||
|
"resources/js/roles/update.js": {
|
||||||
|
"file": "assets/update-CapXnAP8.js",
|
||||||
|
"name": "update",
|
||||||
|
"src": "resources/js/roles/update.js",
|
||||||
|
"isEntry": true
|
||||||
|
},
|
||||||
|
"resources/js/settings/general/general-settings.js": {
|
||||||
|
"file": "assets/general-settings-BoJeYQk1.js",
|
||||||
|
"name": "general-settings",
|
||||||
|
"src": "resources/js/settings/general/general-settings.js",
|
||||||
|
"isEntry": true,
|
||||||
|
"imports": [
|
||||||
|
"_gridjs.umd-BiCNXlqL.js",
|
||||||
|
"_global-config-9uDKFQ8j.js",
|
||||||
|
"__commonjsHelpers-C4iS2aBk.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resources/js/settings/syncronize/syncronize.js": {
|
||||||
|
"file": "assets/syncronize-DjtcngRb.js",
|
||||||
|
"name": "syncronize",
|
||||||
|
"src": "resources/js/settings/syncronize/syncronize.js",
|
||||||
|
"isEntry": true,
|
||||||
|
"imports": [
|
||||||
|
"_gridjs.umd-BiCNXlqL.js",
|
||||||
|
"_global-config-9uDKFQ8j.js",
|
||||||
|
"__commonjsHelpers-C4iS2aBk.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resources/js/tables/common-table.js": {
|
||||||
|
"file": "assets/common-table-KF_NVAIE.js",
|
||||||
|
"name": "common-table",
|
||||||
|
"src": "resources/js/tables/common-table.js",
|
||||||
|
"isEntry": true,
|
||||||
|
"imports": [
|
||||||
|
"_gridjs.umd-BiCNXlqL.js",
|
||||||
|
"_global-config-9uDKFQ8j.js",
|
||||||
|
"__commonjsHelpers-C4iS2aBk.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"resources/scss/components/_circle.scss": {
|
||||||
|
"file": "assets/_circle-DgPqpfJw.css",
|
||||||
|
"src": "resources/scss/components/_circle.scss",
|
||||||
|
"isEntry": true
|
||||||
|
},
|
||||||
|
"resources/scss/dashboards/_bigdata.scss": {
|
||||||
|
"file": "assets/_bigdata-Syu0AGbZ.css",
|
||||||
|
"src": "resources/scss/dashboards/_bigdata.scss",
|
||||||
|
"isEntry": true
|
||||||
|
},
|
||||||
|
"resources/scss/icons.scss": {
|
||||||
|
"file": "assets/icons-CHxf0fE3.css",
|
||||||
|
"src": "resources/scss/icons.scss",
|
||||||
|
"isEntry": true
|
||||||
|
},
|
||||||
|
"resources/scss/style.scss": {
|
||||||
|
"file": "assets/style-H92i7DXd.css",
|
||||||
|
"src": "resources/scss/style.scss",
|
||||||
|
"isEntry": true
|
||||||
|
}
|
||||||
|
}
|
||||||
1
public/build/assets/_commonjsHelpers-C4iS2aBk.js
Normal file
1
public/build/assets/_commonjsHelpers-C4iS2aBk.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
var u=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function f(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function l(e){if(e.__esModule)return e;var r=e.default;if(typeof r=="function"){var t=function o(){return this instanceof o?Reflect.construct(r,arguments,this.constructor):r.apply(this,arguments)};t.prototype=r.prototype}else t={};return Object.defineProperty(t,"__esModule",{value:!0}),Object.keys(e).forEach(function(o){var n=Object.getOwnPropertyDescriptor(e,o);Object.defineProperty(t,o,n.get?n:{enumerable:!0,get:function(){return e[o]}})}),t}export{f as a,u as c,l as g};
|
||||||
808
public/build/assets/apexcharts.common-7mov3gaG.js
Normal file
808
public/build/assets/apexcharts.common-7mov3gaG.js
Normal file
File diff suppressed because one or more lines are too long
18
public/build/assets/app-Wz_4hh3O.js
Normal file
18
public/build/assets/app-Wz_4hh3O.js
Normal file
File diff suppressed because one or more lines are too long
BIN
public/build/assets/boxicons-0t2gX1vj.eot
Normal file
BIN
public/build/assets/boxicons-0t2gX1vj.eot
Normal file
Binary file not shown.
BIN
public/build/assets/boxicons-BEZXjQG5.ttf
Normal file
BIN
public/build/assets/boxicons-BEZXjQG5.ttf
Normal file
Binary file not shown.
BIN
public/build/assets/boxicons-C7pETWQJ.woff2
Normal file
BIN
public/build/assets/boxicons-C7pETWQJ.woff2
Normal file
Binary file not shown.
BIN
public/build/assets/boxicons-CEgI8ccS.woff
Normal file
BIN
public/build/assets/boxicons-CEgI8ccS.woff
Normal file
Binary file not shown.
1653
public/build/assets/boxicons-KSR1BgPC.svg
Normal file
1653
public/build/assets/boxicons-KSR1BgPC.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 1.2 MiB |
10
public/build/assets/chart-DQBoD9wk.js
Normal file
10
public/build/assets/chart-DQBoD9wk.js
Normal file
File diff suppressed because one or more lines are too long
1
public/build/assets/config-DqV4EBmE.js
Normal file
1
public/build/assets/config-DqV4EBmE.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
(function(){var i=sessionStorage.getItem("__DARKONE_CONFIG__"),e=document.getElementsByTagName("html")[0],a={theme:"light",topbar:{color:"light"},menu:{size:"default",color:"light"}};document.getElementsByTagName("html")[0];var t=Object.assign(JSON.parse(JSON.stringify(a)),{});(t=Object.assign(JSON.parse(JSON.stringify(a)),{})).theme=e.getAttribute("data-bs-theme")||a.theme,t.topbar.color=e.getAttribute("data-topbar-color")||a.topbar.color,t.menu.color=e.getAttribute("data-sidebar-color")||a.menu.color,t.menu.size=e.getAttribute("data-sidebar-size")||a.menu.size,window.defaultConfig=JSON.parse(JSON.stringify(t)),i!==null&&(t=JSON.parse(i)),(window.config=t)&&(e.setAttribute("data-bs-theme",t.theme),e.setAttribute("data-topbar-color",t.topbar.color),e.setAttribute("data-sidebar-color",t.menu.color),window.innerWidth<=1140?e.setAttribute("data-sidebar-size","hidden"):e.setAttribute("data-sidebar-size",t.menu.size))})();
|
||||||
1
public/build/assets/dark-CLxH30By.css
Normal file
1
public/build/assets/dark-CLxH30By.css
Normal file
File diff suppressed because one or more lines are too long
1
public/build/assets/dashboard-nkb3Omy9.js
Normal file
1
public/build/assets/dashboard-nkb3Omy9.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{A as t}from"./apexcharts.common-7mov3gaG.js";import{j as i}from"./world-BH8KG5u4.js";import"./_commonjsHelpers-C4iS2aBk.js";var r={chart:{type:"area",height:50,sparkline:{enabled:!0}},series:[{data:[25,28,32,38,43,55,60,48,42,51,35]}],stroke:{width:2,curve:"smooth"},markers:{size:0},colors:["#7e67fe"],tooltip:{fixed:{enabled:!1},x:{show:!1},y:{title:{formatter:function(e){return""}}},marker:{show:!1}},fill:{opacity:[1],type:["gradient"],gradient:{type:"vertical",inverseColors:!1,opacityFrom:.5,opacityTo:0,stops:[0,100]}}};new t(document.querySelector("#chart01"),r).render();var r={chart:{type:"area",height:50,sparkline:{enabled:!0}},series:[{data:[87,54,4,76,31,95,70,92,53,9,6]}],stroke:{width:2,curve:"smooth"},markers:{size:0},colors:["#7e67fe"],tooltip:{fixed:{enabled:!1},x:{show:!1},y:{title:{formatter:function(e){return""}}},marker:{show:!1}},fill:{opacity:[1],type:["gradient"],gradient:{type:"vertical",inverseColors:!1,opacityFrom:.5,opacityTo:0,stops:[0,100]}}};new t(document.querySelector("#chart02"),r).render();var r={chart:{type:"area",height:50,sparkline:{enabled:!0}},series:[{data:[41,42,35,42,6,12,13,22,42,94,95]}],stroke:{width:2,curve:"smooth"},markers:{size:0},colors:["#7e67fe"],tooltip:{fixed:{enabled:!1},x:{show:!1},y:{title:{formatter:function(e){return""}}},marker:{show:!1}},fill:{opacity:[1],type:["gradient"],gradient:{type:"vertical",inverseColors:!1,opacityFrom:.5,opacityTo:0,stops:[0,100]}}};new t(document.querySelector("#chart03"),r).render();var r={chart:{type:"area",height:50,sparkline:{enabled:!0}},series:[{data:[8,41,40,48,77,35,0,77,63,100,71]}],stroke:{width:2,curve:"smooth"},markers:{size:0},colors:["#7e67fe"],tooltip:{fixed:{enabled:!1},x:{show:!1},y:{title:{formatter:function(e){return""}}},marker:{show:!1}},fill:{opacity:[1],type:["gradient"],gradient:{type:"vertical",inverseColors:!1,opacityFrom:.5,opacityTo:0,stops:[0,100]}}};new t(document.querySelector("#chart04"),r).render();var a={chart:{height:180,type:"donut"},series:[44.25,52.68,45.98],legend:{show:!1},stroke:{width:0},plotOptions:{pie:{donut:{size:"70%",labels:{show:!1,total:{showAlways:!0,show:!0}}}}},labels:["Direct","Affilliate","Sponsored"],colors:["#7e67fe","#17c553","#7942ed"],dataLabels:{enabled:!1},responsive:[{breakpoint:480,options:{chart:{width:200}}}],fill:{type:"gradient"}},o=new t(document.querySelector("#conversions"),a);o.render();var a={series:[{name:"Page Views",type:"bar",data:[34,65,46,68,49,61,42,44,78,52,63,67]},{name:"Clicks",type:"area",data:[8,12,7,17,21,11,5,9,7,29,12,35]},{name:"Revenue",type:"area",data:[12,16,11,22,28,25,15,29,35,45,42,48]}],chart:{height:330,type:"line",toolbar:{show:!1}},stroke:{dashArray:[0,0,2],width:[0,2,2],curve:"smooth"},fill:{opacity:[1,1,1],type:["solid","gradient","gradient"],gradient:{type:"vertical",inverseColors:!1,opacityFrom:.5,opacityTo:0,stops:[0,90]}},markers:{size:[0,0],strokeWidth:2,hover:{size:4}},xaxis:{categories:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],axisTicks:{show:!1},axisBorder:{show:!1}},yaxis:{min:0,axisBorder:{show:!1}},grid:{show:!0,strokeDashArray:3,xaxis:{lines:{show:!1}},yaxis:{lines:{show:!0}},padding:{top:0,right:-2,bottom:10,left:10}},legend:{show:!0,horizontalAlign:"center",offsetX:0,offsetY:5,markers:{width:9,height:9,radius:6},itemMargin:{horizontal:10,vertical:0}},plotOptions:{bar:{columnWidth:"30%",barHeight:"70%",borderRadius:3}},colors:["#7e67fe","#17c553","#7942ed"],tooltip:{shared:!0,y:[{formatter:function(e){return typeof e<"u"?e.toFixed(1)+"k":e}},{formatter:function(e){return typeof e<"u"?e.toFixed(1)+"k":e}}]}},o=new t(document.querySelector("#dash-performance-chart"),a);o.render();class n{initWorldMapMarker(){new i({map:"world",selector:"#world-map-markers",zoomOnScroll:!0,zoomButtons:!1,markersSelectable:!0,markers:[{name:"Canada",coords:[56.1304,-106.3468]},{name:"Brazil",coords:[-14.235,-51.9253]},{name:"Russia",coords:[61,105]},{name:"China",coords:[35.8617,104.1954]},{name:"United States",coords:[37.0902,-95.7129]}],markerStyle:{initial:{fill:"#7f56da"},selected:{fill:"#1bb394"}},labels:{markers:{render:s=>s.name}},regionStyle:{initial:{fill:"rgba(169,183,197, 0.3)",fillOpacity:1}}})}init(){this.initWorldMapMarker()}}document.addEventListener("DOMContentLoaded",function(e){new n().init()});
|
||||||
1
public/build/assets/flatpickr-CksuuEqD.css
Normal file
1
public/build/assets/flatpickr-CksuuEqD.css
Normal file
File diff suppressed because one or more lines are too long
18
public/build/assets/form-flatepicker-ChSlk6xC.js
Normal file
18
public/build/assets/form-flatepicker-ChSlk6xC.js
Normal file
File diff suppressed because one or more lines are too long
41
public/build/assets/form-quilljs-pSObT4Ti.js
Normal file
41
public/build/assets/form-quilljs-pSObT4Ti.js
Normal file
File diff suppressed because one or more lines are too long
1
public/build/assets/icons-CHxf0fE3.css
Normal file
1
public/build/assets/icons-CHxf0fE3.css
Normal file
File diff suppressed because one or more lines are too long
1
public/build/assets/maps-canada-Btz07hSk.js
Normal file
1
public/build/assets/maps-canada-Btz07hSk.js
Normal file
File diff suppressed because one or more lines are too long
7
public/build/assets/maps-google-KamR_rNw.js
Normal file
7
public/build/assets/maps-google-KamR_rNw.js
Normal file
File diff suppressed because one or more lines are too long
1
public/build/assets/maps-iraq-Blhf9V_8.js
Normal file
1
public/build/assets/maps-iraq-Blhf9V_8.js
Normal file
File diff suppressed because one or more lines are too long
1
public/build/assets/maps-russia-C3XucoMP.js
Normal file
1
public/build/assets/maps-russia-C3XucoMP.js
Normal file
File diff suppressed because one or more lines are too long
1
public/build/assets/maps-spain-CdBIHB66.js
Normal file
1
public/build/assets/maps-spain-CdBIHB66.js
Normal file
File diff suppressed because one or more lines are too long
1
public/build/assets/maps-vector-C2WpvMU7.js
Normal file
1
public/build/assets/maps-vector-C2WpvMU7.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import{j as a}from"./world-BH8KG5u4.js";import"./_commonjsHelpers-C4iS2aBk.js";class r{initWorldMapMarker(){new a({map:"world",selector:"#world-map-markers",zoomOnScroll:!1,zoomButtons:!0,markersSelectable:!0,markers:[{name:"Greenland",coords:[72,-42]},{name:"Canada",coords:[56.1304,-106.3468]},{name:"Brazil",coords:[-14.235,-51.9253]},{name:"Egypt",coords:[26.8206,30.8025]},{name:"Russia",coords:[61,105]},{name:"China",coords:[35.8617,104.1954]},{name:"United States",coords:[37.0902,-95.7129]},{name:"Norway",coords:[60.472024,8.468946]},{name:"Ukraine",coords:[48.379433,31.16558]}],markerStyle:{initial:{fill:"#5B8DEC"},selected:{fill:"#ed5565"}},labels:{markers:{render:i=>i.name}},regionStyle:{initial:{fill:"rgba(169,183,197, 0.2)",fillOpacity:1}}})}initCanadaVectorMap(){new a({map:"canada",selector:"#canada-vector-map",zoomOnScroll:!1,regionStyle:{initial:{fill:"#1e84c4"}}})}initRussiaVectorMap(){new a({map:"russia",selector:"#russia-vector-map",zoomOnScroll:!1,regionStyle:{initial:{fill:"#1bb394"}}})}initIraqVectorMap(){new a({map:"iraq",selector:"#iraq-vector-map",zoomOnScroll:!1,regionStyle:{initial:{fill:"#f8ac59"}}})}initSpainVectorMap(){new a({map:"spain",selector:"#spain-vector-map",zoomOnScroll:!1,regionStyle:{initial:{fill:"#23c6c8"}}})}initUsaVectorMap(){new a({map:"us_merc_en",selector:"#usa-vector-map",regionStyle:{initial:{fill:"#ffe381"}}})}init(){this.initWorldMapMarker(),this.initCanadaVectorMap(),this.initRussiaVectorMap(),this.initIraqVectorMap(),this.initSpainVectorMap()}}document.addEventListener("DOMContentLoaded",function(e){new r().init()});
|
||||||
1
public/build/assets/mermaid-1KsrsKla.css
Normal file
1
public/build/assets/mermaid-1KsrsKla.css
Normal file
File diff suppressed because one or more lines are too long
1
public/build/assets/mermaid-B5wPN5RC.css
Normal file
1
public/build/assets/mermaid-B5wPN5RC.css
Normal file
File diff suppressed because one or more lines are too long
6
public/build/assets/quill-BzaoboQ1.css
Normal file
6
public/build/assets/quill-BzaoboQ1.css
Normal file
File diff suppressed because one or more lines are too long
6
public/build/assets/quill-D-Ncpkvi.css
Normal file
6
public/build/assets/quill-D-Ncpkvi.css
Normal file
File diff suppressed because one or more lines are too long
2
public/build/assets/world-BH8KG5u4.js
Normal file
2
public/build/assets/world-BH8KG5u4.js
Normal file
File diff suppressed because one or more lines are too long
BIN
public/images/bg-dashboard.jpg
Normal file
BIN
public/images/bg-dashboard.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 126 KiB |
@@ -4,6 +4,8 @@ use Illuminate\Http\Request;
|
|||||||
|
|
||||||
define('LARAVEL_START', microtime(true));
|
define('LARAVEL_START', microtime(true));
|
||||||
|
|
||||||
|
ini_set('max_execution_time',14400);
|
||||||
|
|
||||||
// Determine if the application is in maintenance mode...
|
// Determine if the application is in maintenance mode...
|
||||||
if (file_exists($maintenance = __DIR__.'/../storage/framework/maintenance.php')) {
|
if (file_exists($maintenance = __DIR__.'/../storage/framework/maintenance.php')) {
|
||||||
require $maintenance;
|
require $maintenance;
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
|
import bootstrap from "bootstrap/dist/js/bootstrap";
|
||||||
import bootstrap from 'bootstrap/dist/js/bootstrap'
|
|
||||||
window.bootstrap = bootstrap;
|
window.bootstrap = bootstrap;
|
||||||
import 'iconify-icon';
|
import "iconify-icon";
|
||||||
import 'simplebar/dist/simplebar'
|
import "simplebar/dist/simplebar";
|
||||||
|
|
||||||
class Components {
|
class Components {
|
||||||
initBootstrapComponents() {
|
initBootstrapComponents() {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
57
resources/js/data-settings/create.js
Normal file
57
resources/js/data-settings/create.js
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
document.addEventListener("DOMContentLoaded", function (e) {
|
||||||
|
const toastNotification = document.getElementById("toastNotification");
|
||||||
|
const toast = new bootstrap.Toast(toastNotification);
|
||||||
|
document
|
||||||
|
.getElementById("btnCreateDataSettings")
|
||||||
|
.addEventListener("click", async function () {
|
||||||
|
let submitButton = this;
|
||||||
|
let spinner = document.getElementById("spinner");
|
||||||
|
let form = document.getElementById("formDataSettings");
|
||||||
|
|
||||||
|
if (!form) {
|
||||||
|
console.error("Form element not found!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Get form data
|
||||||
|
let formData = new FormData(form);
|
||||||
|
|
||||||
|
// Disable button and show spinner
|
||||||
|
submitButton.disabled = true;
|
||||||
|
spinner.classList.remove("d-none");
|
||||||
|
|
||||||
|
try {
|
||||||
|
let response = await fetch(form.action, {
|
||||||
|
method: "POST",
|
||||||
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"X-CSRF-TOKEN": document
|
||||||
|
.querySelector('meta[name="csrf-token"]')
|
||||||
|
.getAttribute("content"),
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: formData,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
let result = await response.json();
|
||||||
|
document.getElementById("toast-message").innerText =
|
||||||
|
result.message;
|
||||||
|
toast.show();
|
||||||
|
setTimeout(() => {
|
||||||
|
window.location.href = "/data-settings";
|
||||||
|
}, 2000);
|
||||||
|
} else {
|
||||||
|
let error = await response.json();
|
||||||
|
document.getElementById("toast-message").innerText =
|
||||||
|
error.message;
|
||||||
|
toast.show();
|
||||||
|
console.error("Error:", error);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Request failed:", error);
|
||||||
|
document.getElementById("toast-message").innerText =
|
||||||
|
error.message;
|
||||||
|
toast.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
214
resources/js/data-settings/index.js
Normal file
214
resources/js/data-settings/index.js
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
import { Grid } from "gridjs/dist/gridjs.umd.js";
|
||||||
|
import gridjs from "gridjs/dist/gridjs.umd.js";
|
||||||
|
import "gridjs/dist/gridjs.umd.js";
|
||||||
|
import GlobalConfig from "../global-config.js";
|
||||||
|
|
||||||
|
class DataSettings {
|
||||||
|
constructor() {
|
||||||
|
this.table = null; // Store Grid.js instance
|
||||||
|
}
|
||||||
|
init() {
|
||||||
|
this.getFetchApiData();
|
||||||
|
}
|
||||||
|
|
||||||
|
getFetchApiData() {
|
||||||
|
let tableContainer = document.getElementById("table-data-settings");
|
||||||
|
|
||||||
|
if (this.table) {
|
||||||
|
// If table exists, update its data instead of recreating
|
||||||
|
this.table
|
||||||
|
.updateConfig({
|
||||||
|
server: {
|
||||||
|
url: `${GlobalConfig.apiHost}/api/api-data-settings`,
|
||||||
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${document
|
||||||
|
.querySelector('meta[name="api-token"]')
|
||||||
|
.getAttribute("content")}`,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
then: (data) =>
|
||||||
|
data.data.map((item) => [
|
||||||
|
item.id,
|
||||||
|
item.key,
|
||||||
|
item.value,
|
||||||
|
item.created_at,
|
||||||
|
item.id,
|
||||||
|
]),
|
||||||
|
total: (data) => data.meta.total,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.forceRender();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.table = new Grid({
|
||||||
|
columns: [
|
||||||
|
"ID",
|
||||||
|
"Key",
|
||||||
|
"Value",
|
||||||
|
"Created",
|
||||||
|
{
|
||||||
|
name: "Actions",
|
||||||
|
width: "120px",
|
||||||
|
formatter: function (cell) {
|
||||||
|
return gridjs.html(`
|
||||||
|
<div class="d-flex justify-content-center gap-2">
|
||||||
|
<a href="/data-settings/${cell}/edit" class="btn btn-yellow btn-sm d-inline-flex align-items-center justify-content-center">
|
||||||
|
<i class='bx bx-edit'></i>
|
||||||
|
</a>
|
||||||
|
<button class="btn btn-sm btn-red d-inline-flex align-items-center justify-content-centerbtn-delete-data-settings" data-id="${cell}">
|
||||||
|
<i class='bx bxs-trash' ></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
search: {
|
||||||
|
server: {
|
||||||
|
url: (prev, keyword) => `${prev}?search=${keyword}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pagination: {
|
||||||
|
limit: 15,
|
||||||
|
server: {
|
||||||
|
url: (prev, page) =>
|
||||||
|
`${prev}${prev.includes("?") ? "&" : "?"}page=${
|
||||||
|
page + 1
|
||||||
|
}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
sort: true,
|
||||||
|
server: {
|
||||||
|
url: `${GlobalConfig.apiHost}/api/api-data-settings`,
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${document
|
||||||
|
.querySelector('meta[name="api-token"]')
|
||||||
|
.getAttribute("content")}`,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
then: (data) =>
|
||||||
|
data.data.map((item) => [
|
||||||
|
item.id,
|
||||||
|
item.key,
|
||||||
|
item.value,
|
||||||
|
item.created_at,
|
||||||
|
item.id,
|
||||||
|
]),
|
||||||
|
total: (data) => data.meta.total,
|
||||||
|
},
|
||||||
|
}).render(tableContainer);
|
||||||
|
|
||||||
|
document.addEventListener("click", this.handleDelete.bind(this));
|
||||||
|
}
|
||||||
|
handleDelete(event) {
|
||||||
|
if (event.target.classList.contains("btn-delete-data-settings")) {
|
||||||
|
event.preventDefault();
|
||||||
|
const id = event.target.getAttribute("data-id");
|
||||||
|
let modalElement = document.getElementById("modalConfirmation");
|
||||||
|
let toastMessage = document.getElementById("toast-message");
|
||||||
|
|
||||||
|
if (!modalElement) {
|
||||||
|
console.error("Modal element not found!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let modal = new bootstrap.Modal(modalElement);
|
||||||
|
let btnSaveConfirmation = document.getElementById(
|
||||||
|
"btnSaveConfirmation"
|
||||||
|
);
|
||||||
|
let toastElement = document.getElementById("toastNotification");
|
||||||
|
let toast = new bootstrap.Toast(toastElement);
|
||||||
|
|
||||||
|
// Remove previous event listeners to avoid multiple bindings
|
||||||
|
btnSaveConfirmation.replaceWith(
|
||||||
|
btnSaveConfirmation.cloneNode(true)
|
||||||
|
);
|
||||||
|
btnSaveConfirmation = document.getElementById(
|
||||||
|
"btnSaveConfirmation"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Set the role ID on the confirm button inside the modal
|
||||||
|
btnSaveConfirmation.setAttribute("data-settings-id", id);
|
||||||
|
|
||||||
|
// Show the modal
|
||||||
|
modal.show();
|
||||||
|
|
||||||
|
btnSaveConfirmation.addEventListener("click", async () => {
|
||||||
|
let dataSettingId =
|
||||||
|
btnSaveConfirmation.getAttribute("data-settings-id");
|
||||||
|
|
||||||
|
try {
|
||||||
|
let response = await fetch(
|
||||||
|
`/data-settings/${dataSettingId}`,
|
||||||
|
{
|
||||||
|
method: "DELETE",
|
||||||
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"X-CSRF-TOKEN": document
|
||||||
|
.querySelector('meta[name="csrf-token"]')
|
||||||
|
.getAttribute("content"),
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
let result = await response.json();
|
||||||
|
toastMessage.innerText =
|
||||||
|
result.message || "Deleted successfully!";
|
||||||
|
toast.show();
|
||||||
|
|
||||||
|
// Hide modal
|
||||||
|
modal.hide();
|
||||||
|
|
||||||
|
// Refresh Grid.js table
|
||||||
|
this.refreshDataSettings();
|
||||||
|
} else {
|
||||||
|
let error = await response.json();
|
||||||
|
console.error("Delete failed:", error);
|
||||||
|
toastMessage.innerText =
|
||||||
|
error.message || "Delete failed!";
|
||||||
|
toast.show();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error deleting item:", error);
|
||||||
|
toastMessage.innerText = "An error occurred!";
|
||||||
|
toast.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshDataSettings() {
|
||||||
|
if (this.table) {
|
||||||
|
this.table
|
||||||
|
.updateConfig({
|
||||||
|
server: {
|
||||||
|
url: `${GlobalConfig.apiHost}/api/api-data-settings`,
|
||||||
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${document
|
||||||
|
.querySelector('meta[name="api-token"]')
|
||||||
|
.getAttribute("content")}`,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
then: (data) =>
|
||||||
|
data.data.map((item) => [
|
||||||
|
item.id,
|
||||||
|
item.key,
|
||||||
|
item.value,
|
||||||
|
item.created_at,
|
||||||
|
item.id,
|
||||||
|
]),
|
||||||
|
total: (data) => data.meta.total,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.forceRender();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.addEventListener("DOMContentLoaded", function (e) {
|
||||||
|
new DataSettings().init();
|
||||||
|
});
|
||||||
53
resources/js/data-settings/update.js
Normal file
53
resources/js/data-settings/update.js
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
document.addEventListener("DOMContentLoaded", function (e) {
|
||||||
|
let form = document.getElementById("formUpdateDataSettings");
|
||||||
|
let submitButton = document.getElementById("btnUpdateDataSettings");
|
||||||
|
let spinner = document.getElementById("spinner");
|
||||||
|
let toastMessage = document.getElementById("toast-message");
|
||||||
|
let toast = new bootstrap.Toast(
|
||||||
|
document.getElementById("toastNotification")
|
||||||
|
);
|
||||||
|
submitButton.addEventListener("click", async function () {
|
||||||
|
let submitButton = this;
|
||||||
|
|
||||||
|
if (!form) {
|
||||||
|
console.error("Form element not found!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Get form data
|
||||||
|
let formData = new FormData(form);
|
||||||
|
|
||||||
|
// Disable button and show spinner
|
||||||
|
submitButton.disabled = true;
|
||||||
|
spinner.classList.remove("d-none");
|
||||||
|
|
||||||
|
try {
|
||||||
|
let response = await fetch(form.action, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"X-CSRF-TOKEN": document
|
||||||
|
.querySelector('meta[name="csrf-token"]')
|
||||||
|
.getAttribute("content"),
|
||||||
|
},
|
||||||
|
body: formData,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
let result = await response.json();
|
||||||
|
toastMessage.innerText = result.message;
|
||||||
|
toast.show();
|
||||||
|
setTimeout(() => {
|
||||||
|
window.location.href = "/data-settings";
|
||||||
|
}, 2000);
|
||||||
|
} else {
|
||||||
|
let error = await response.json();
|
||||||
|
toastMessage.innerText = error.message;
|
||||||
|
toast.show();
|
||||||
|
console.error("Error:", error);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Request failed:", error);
|
||||||
|
toastMessage.innerText = error.message;
|
||||||
|
toast.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,12 +1,24 @@
|
|||||||
const GlobalConfig = {
|
export default GlobalConfig = window.GlobalConfig;
|
||||||
apiHost: 'http://localhost:8000'
|
|
||||||
};
|
|
||||||
|
|
||||||
export default GlobalConfig;
|
export function addThousandSeparators(value, fractionDigits = 2) {
|
||||||
|
if (!value) return null; // Handle empty or null values
|
||||||
|
|
||||||
export function addThousandSeparators(number, fractionDigits = 2) {
|
// Remove any non-numeric characters except commas and dots
|
||||||
return new Intl.NumberFormat('en-US', {
|
value = value.replace(/[^0-9,.]/g, "");
|
||||||
minimumFractionDigits: fractionDigits,
|
|
||||||
maximumFractionDigits: fractionDigits,
|
// If the value contains multiple dots, assume dots are thousand separators
|
||||||
}).format(number);
|
if ((value.match(/\./g) || []).length > 1) {
|
||||||
|
value = value.replace(/\./g, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to a proper decimal number
|
||||||
|
let number = parseFloat(value.replace(",", "."));
|
||||||
|
|
||||||
|
if (isNaN(number)) return null; // Return null if conversion fails
|
||||||
|
|
||||||
|
// Format the number with thousand separators
|
||||||
|
return new Intl.NumberFormat("en-US", {
|
||||||
|
minimumFractionDigits: fractionDigits,
|
||||||
|
maximumFractionDigits: fractionDigits,
|
||||||
|
}).format(number);
|
||||||
}
|
}
|
||||||
55
resources/js/master/users/create.js
Normal file
55
resources/js/master/users/create.js
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
document.addEventListener("DOMContentLoaded", function (e) {
|
||||||
|
const toastNotification = document.getElementById("toastNotification");
|
||||||
|
const toast = new bootstrap.Toast(toastNotification);
|
||||||
|
document
|
||||||
|
.getElementById("btnCreateUsers")
|
||||||
|
.addEventListener("click", async function () {
|
||||||
|
let submitButton = this;
|
||||||
|
let spinner = document.getElementById("spinner");
|
||||||
|
let form = document.getElementById("formCreateUsers");
|
||||||
|
|
||||||
|
if (!form) {
|
||||||
|
console.error("Form element not found!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Get form data
|
||||||
|
let formData = new FormData(form);
|
||||||
|
|
||||||
|
// Disable button and show spinner
|
||||||
|
submitButton.disabled = true;
|
||||||
|
spinner.classList.remove("d-none");
|
||||||
|
|
||||||
|
try {
|
||||||
|
let response = await fetch(form.action, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"X-CSRF-TOKEN": document
|
||||||
|
.querySelector('meta[name="csrf-token"]')
|
||||||
|
.getAttribute("content"),
|
||||||
|
},
|
||||||
|
body: formData,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
let result = await response.json();
|
||||||
|
document.getElementById("toast-message").innerText =
|
||||||
|
result.message;
|
||||||
|
toast.show();
|
||||||
|
setTimeout(() => {
|
||||||
|
window.location.href = "/master/users";
|
||||||
|
}, 2000);
|
||||||
|
} else {
|
||||||
|
let error = await response.json();
|
||||||
|
document.getElementById("toast-message").innerText =
|
||||||
|
error.message;
|
||||||
|
toast.show();
|
||||||
|
console.error("Error:", error);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Request failed:", error);
|
||||||
|
document.getElementById("toast-message").innerText =
|
||||||
|
error.message;
|
||||||
|
toast.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user