create page tax with data, upload and export group by subdistrict

This commit is contained in:
arifal hidayat
2025-08-05 01:30:37 +07:00
parent 456eec83dc
commit 7135876ebc
18 changed files with 780 additions and 3 deletions

View File

@@ -0,0 +1,59 @@
<?php
namespace App\Exports;
use App\Models\Tax;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithTitle;
use Maatwebsite\Excel\Concerns\WithHeadings;
class TaxSubdistrictSheetExport implements FromCollection, WithTitle, WithHeadings
{
protected $subdistrict;
public function __construct(string $subdistrict)
{
$this->subdistrict = $subdistrict;
}
public function collection()
{
return Tax::where('subdistrict', $this->subdistrict)
->select(
'tax_code',
'tax_no',
'npwpd',
'wp_name',
'business_name',
'address',
'start_validity',
'end_validity',
'tax_value',
'subdistrict',
'village'
)->get();
}
public function headings(): array
{
return [
'Kode',
'No',
'NPWPD',
'Nama WP',
'Nama Usaha',
'Alamat Usaha',
'Tanggal Mulai Berlaku',
'Tanggal Berakhir Berlaku',
'Nilai Pajak',
'Kecamatan',
'Desa'
];
}
public function title(): string
{
return mb_substr($this->subdistrict, 0, 31);
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace App\Exports;
use App\Models\Tax;
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
class TaxationsExport implements WithMultipleSheets
{
public function sheets(): array
{
$sheets = [];
// Ambil semua subdistrict unik
$subdistricts = Tax::select('subdistrict')->distinct()->pluck('subdistrict');
foreach ($subdistricts as $subdistrict) {
$sheets[] = new TaxSubdistrictSheetExport($subdistrict);
}
return $sheets;
}
}

View File

@@ -9,6 +9,7 @@ use App\Http\Resources\CustomersResource;
use App\Imports\CustomersImport; use App\Imports\CustomersImport;
use App\Models\Customer; use App\Models\Customer;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Maatwebsite\Excel\Facades\Excel; use Maatwebsite\Excel\Facades\Excel;
class CustomersController extends Controller class CustomersController extends Controller
@@ -120,7 +121,7 @@ class CustomersController extends Controller
'message' => 'File uploaded successfully', 'message' => 'File uploaded successfully',
]); ]);
}catch(\Exception $e){ }catch(\Exception $e){
\Log::info($e->getMessage()); Log::info($e->getMessage());
return response()->json([ return response()->json([
'error' => 'Failed to upload file', 'error' => 'Failed to upload file',
'message' => $e->getMessage() 'message' => $e->getMessage()

View File

@@ -0,0 +1,63 @@
<?php
namespace App\Http\Controllers\Api;
use App\Exports\TaxationsExport;
use App\Http\Controllers\Controller;
use App\Http\Requests\ExcelUploadRequest;
use App\Http\Resources\TaxationsResource;
use App\Imports\TaxationsImport;
use Illuminate\Http\Request;
use App\Models\Tax;
use Illuminate\Support\Facades\Log;
use Maatwebsite\Excel\Facades\Excel;
class TaxationsController extends Controller
{
public function index(Request $request)
{
try{
$query = Tax::query()->orderBy('id', 'desc');
if($request->has('search') && !empty($request->get('search'))){
$query->where('tax_no', 'like', '%'. $request->get('search') . '%')
->orWhere('wp_name', 'like', '%'. $request->get('search') . '%')
->orWhere('business_name', 'like', '%'. $request->get('search') . '%');
}
return TaxationsResource::collection($query->paginate(config('app.paginate_per_page', 50)));
}catch(\Exception $e){
Log::info($e->getMessage());
return response()->json([
'error' => 'Failed to get data',
'message' => $e->getMessage()
], 500);
}
}
public function upload(ExcelUploadRequest $request)
{
try{
if(!$request->hasFile('file')){
return response()->json([
'error' => 'No file provided'
], 400);
}
$file = $request->file('file');
Excel::import(new TaxationsImport, $file);
return response()->json(['message' => 'File uploaded successfully'], 200);
}catch(\Exception $e){
Log::info($e->getMessage());
return response()->json([
'error' => 'Failed to upload file',
'message' => $e->getMessage()
], 500);
}
}
public function export(Request $request)
{
return Excel::download(new TaxationsExport, 'pajak_per_kecamatan.xlsx');
}
}

View File

@@ -0,0 +1,75 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class TaxationController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index(Request $request)
{
$menuId = $request->query('menu_id') ?? $request->input('menu_id');
$permissions = $this->permissions[$menuId]?? []; // Avoid undefined index error
$creator = $permissions['allow_create'] ?? 0;
$updater = $permissions['allow_update'] ?? 0;
$destroyer = $permissions['allow_destroy'] ?? 0;
return view('taxation.index', compact('creator', 'updater', 'destroyer', 'menuId'));
}
public function upload(Request $request)
{
$menuId = $request->query('menu_id') ?? $request->input('menu_id');
return view('taxation.upload', compact('menuId'));
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*/
public function show(string $id)
{
//
}
/**
* Show the form for editing the specified resource.
*/
public function edit(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)
{
//
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class TaxationsResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return parent::toArray($request);
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace App\Imports;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\WithBatchInserts;
use Maatwebsite\Excel\Concerns\WithChunkReading;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Models\Tax;
class TaxationsImport implements ToCollection, WithMultipleSheets, WithChunkReading, WithBatchInserts, ShouldQueue, WithHeadingRow
{
/**
* @param Collection $collection
*/
public function collection(Collection $collection)
{
$batchData = [];
$batchSize = 1000;
foreach ($collection as $row) {
$masaPajak = trim($row['masa_pajak']) ?? '';
$masaParts = explode('-', $masaPajak);
$startValidity = null;
$endValidity = null;
if (count($masaParts) === 2) {
$startValidity = \Carbon\Carbon::createFromFormat('d/m/Y', trim($masaParts[0]))->format('Y-m-d');
$endValidity = \Carbon\Carbon::createFromFormat('d/m/Y', trim($masaParts[1]))->format('Y-m-d');
}
$batchData[] = [
'tax_code' => trim($row['kode']) ?? '',
'tax_no' => trim($row['no']) ?? '',
'npwpd' => trim($row['npwpd']) ?? '',
'wp_name' => trim($row['nama_wp']) ?? '',
'business_name' => trim($row['nama_usaha']) ?? '',
'address' => trim($row['alamat_usaha']) ?? '',
'start_validity' => $startValidity,
'end_validity' => $endValidity,
'tax_value' => (float) str_replace(',', '', trim($row['nilai_pajak']) ?? '0'),
'subdistrict' => trim($row['kecamatan']) ?? '',
'village' => trim($row['desa']) ?? '',
];
if (count($batchData) >= $batchSize) {
Tax::upsert($batchData, ['tax_no'], ['tax_code', 'tax_no', 'npwpd', 'wp_name', 'business_name', 'address', 'start_validity', 'end_validity', 'tax_value', 'subdistrict', 'village']);
$batchData = [];
}
}
if (!empty($batchData)) {
Tax::upsert($batchData, ['tax_no'], ['tax_code', 'tax_no', 'npwpd', 'wp_name', 'business_name', 'address', 'start_validity', 'end_validity', 'tax_value', 'subdistrict', 'village']);
}
}
public function sheets(): array {
return [
0 => $this
];
}
public function chunkSize(): int
{
return 1000;
}
public function batchSize(): int
{
return 1000;
}
}

23
app/Models/Tax.php Normal file
View File

@@ -0,0 +1,23 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Tax extends Model
{
protected $table = 'taxs';
protected $fillable = [
'tax_code',
'tax_no',
'npwpd',
'wp_name',
'business_name',
'address',
'start_validity',
'end_validity',
'tax_value',
'subdistrict',
'village',
];
}

View File

@@ -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::create('taxs', function (Blueprint $table) {
$table->id();
$table->string('tax_code');
$table->string('tax_no')->unique();
$table->string('npwpd');
$table->string('wp_name');
$table->string('business_name');
$table->text('address');
$table->date('start_validity');
$table->date('end_validity');
$table->decimal('tax_value', 12, 2);
$table->string('subdistrict');
$table->string('village');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('taxs');
}
};

View File

@@ -270,6 +270,21 @@ class MenuSeeder extends Seeder
], ],
] ]
], ],
[
"name" => "Pajak",
"url" => "/tax",
"icon" => "mingcute:coin-line",
"parent_id" => null,
"sort_order" => 10,
"children" => [
[
"name" => "Data Pajak",
"url" => "taxation",
"icon" => null,
"sort_order" => 1,
]
]
]
]; ];
foreach ($menus as $menuData) { foreach ($menus as $menuData) {

View File

@@ -25,7 +25,8 @@ class UsersRoleMenuSeeder extends Seeder
'Menu', 'Role', 'Setting Dashboard', 'PBG', 'Reklame', 'Usaha atau Industri', 'Pariwisata', 'Menu', 'Role', 'Setting Dashboard', 'PBG', 'Reklame', 'Usaha atau Industri', 'Pariwisata',
'Lap Pariwisata', 'UMKM', 'Dashboard Potensi', 'Tata Ruang', 'PDAM', 'PETA', 'Lap Pariwisata', 'UMKM', 'Dashboard Potensi', 'Tata Ruang', 'PDAM', 'PETA',
'Lap Pimpinan', 'Dalam Sistem', 'Luar Sistem', 'Google Sheets', 'TPA TPT', 'Lap Pimpinan', 'Dalam Sistem', 'Luar Sistem', 'Google Sheets', 'TPA TPT',
'Approval Pejabat', 'Undangan', 'Rekap Pembayaran', 'Lap Rekap Data Pembayaran', 'Lap PBG (PTSP)', 'Lap Pertumbuhan' 'Approval Pejabat', 'Undangan', 'Rekap Pembayaran', 'Lap Rekap Data Pembayaran', 'Lap PBG (PTSP)', 'Lap Pertumbuhan',
'Pajak', 'Data Pajak'
])->get()->keyBy('name'); ])->get()->keyBy('name');
// Define access levels for each role // Define access levels for each role

View File

@@ -0,0 +1,168 @@
import { Grid } from "gridjs/dist/gridjs.umd.js";
import "gridjs/dist/gridjs.umd.js";
import GlobalConfig from "../global-config";
import { addThousandSeparators } from "../global-config";
class Taxation {
constructor() {
this.toastMessage = document.getElementById("toast-message");
this.toastElement = document.getElementById("toastNotification");
this.toast = new bootstrap.Toast(this.toastElement);
this.table = null;
this.initTableTaxation();
// this.initEvents();
this.handleExportToExcel();
}
handleExportToExcel() {
const button = document.getElementById("btn-export-excel");
if (!button) {
console.error("Button not found: #btn-export-excel");
return;
}
const exportUrl = button.getAttribute("data-url");
button.addEventListener("click", function () {
button.disabled = true;
fetch(exportUrl, {
method: "GET",
credentials: "include",
headers: {
Authorization:
"Bearer " +
document
.querySelector('meta[name="api-token"]')
.getAttribute("content"),
},
})
.then(function (response) {
if (!response.ok) {
throw new Error(
"Error fetching data: " + response.statusText
);
}
return response.blob();
})
.then(function (blob) {
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "laporan-rekap-data-pembayaran.xlsx";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
})
.catch(function (error) {
console.error("Error fetching data:", error);
})
.finally(function () {
button.disabled = false;
});
});
}
initEvents() {
document.body.addEventListener("click", async (event) => {
const deleteButton = event.target.closest(".btn-delete-taxation");
if (deleteButton) {
event.preventDefault();
await this.handleDelete(deleteButton);
}
});
}
initTableTaxation() {
let tableContainer = document.getElementById("table-taxation");
if (!tableContainer) {
console.error("Table container not found!");
return;
}
// Clear previous table content
tableContainer.innerHTML = "";
this.table = new Grid({
columns: [
"ID",
{ name: "Tax No" },
{ name: "Tax Code" },
{ name: "WP Name" },
{ name: "Business Name" },
{ name: "Address" },
{ name: "Start Validity" },
{ name: "End Validity" },
{ name: "Tax Value" },
{ name: "Subdistrict" },
{ name: "Village" },
],
pagination: {
limit: 50,
server: {
url: (prev, page) => {
let separator = prev.includes("?") ? "&" : "?";
return `${prev}${separator}page=${page + 1}`;
},
},
},
sort: true,
search: {
server: {
url: (prev, keyword) => {
let separator = prev.includes("?") ? "&" : "?";
return `${prev}${separator}search=${encodeURIComponent(
keyword
)}`;
},
},
debounceTimeout: 1000,
},
server: {
url: `${GlobalConfig.apiHost}/api/taxs`,
headers: {
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`,
"Content-Type": "application/json",
},
then: (data) => {
if (!data || !data.data) {
console.warn("⚠️ No data received from API");
return [];
}
return data.data.map((item) => {
return [
item.id,
item.tax_no,
item.tax_code,
item.wp_name,
item.business_name,
item.address,
item.start_validity,
item.end_validity,
addThousandSeparators(item.tax_value),
item.subdistrict,
item.village,
];
});
},
total: (data) => {
let totalRecords = data?.meta?.total || 0;
return totalRecords;
},
catch: (error) => {
console.error("❌ Error fetching data:", error);
},
},
}).render(tableContainer);
}
}
document.addEventListener("DOMContentLoaded", function (e) {
new Taxation();
});

View File

@@ -0,0 +1,79 @@
import { Dropzone } from "dropzone";
Dropzone.autoDiscover = false;
class UploadTaxation {
constructor() {
this.spatialDropzone = null;
this.formElement = document.getElementById("formUploadTaxation");
this.uploadButton = document.getElementById("submit-upload");
this.spinner = document.getElementById("spinner");
if (!this.formElement) {
console.error("Element formUploadTaxation tidak ditemukan!");
}
}
init() {
this.initDropzone();
this.setupUploadButton();
}
initDropzone() {
const toastNotification = document.getElementById("toastNotification");
const toast = new bootstrap.Toast(toastNotification);
let menuId = document.getElementById("menuId").value;
var previewTemplate,
dropzonePreviewNode = document.querySelector(
"#dropzone-preview-list"
);
(dropzonePreviewNode.id = ""),
dropzonePreviewNode &&
((previewTemplate = dropzonePreviewNode.parentNode.innerHTML),
dropzonePreviewNode.parentNode.removeChild(dropzonePreviewNode),
(this.spatialDropzone = new Dropzone(".dropzone", {
url: this.formElement.action,
method: "post",
acceptedFiles: ".xls,.xlsx",
previewTemplate: previewTemplate,
previewsContainer: "#dropzone-preview",
autoProcessQueue: false,
headers: {
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`,
},
init: function () {
this.on("success", function (file, response) {
document.getElementById("toast-message").innerText =
response.message;
toast.show();
setTimeout(() => {
window.location.href = `/tax?menu_id=${menuId}`;
}, 2000);
});
this.on("error", function (file, errorMessage) {
document.getElementById("toast-message").innerText =
errorMessage.message;
toast.show();
this.uploadButton.disabled = false;
this.spinner.classList.add("d-none");
});
},
})));
}
setupUploadButton() {
this.uploadButton.addEventListener("click", (e) => {
if (this.spatialDropzone.files.length > 0) {
this.spatialDropzone.processQueue();
this.uploadButton.disabled = true;
this.spinner.classList.remove("d-none");
} else {
return;
}
});
}
}
document.addEventListener("DOMContentLoaded", function (e) {
new UploadTaxation().init();
});

View File

@@ -0,0 +1,38 @@
@extends('layouts.vertical', ['subtitle' => 'Pajak'])
@section('css')
@vite(['node_modules/gridjs/dist/theme/mermaid.min.css'])
@endsection
@section('content')
@include('layouts.partials/page-title', ['title' => 'Pajak', 'subtitle' => 'Data Pajak'])
<x-toast-notification />
<div class="row">
<div class="col-12">
<div class="card w-100">
<div class="card-header d-flex justify-content-end align-items-center">
<div class="d-flex gap-2">
<button class="btn btn-sm bg-black text-white d-flex align-items-center content-center gap-2" id="btn-export-excel" data-url="{{ route('api.taxs.export', ['menu_id' => $menuId]) }}">
<span>.xlsx</span>
<iconify-icon icon="mingcute:file-export-line" width="20" height="20" class="d-flex align-items-center"></iconify-icon>
</button>
</div>
</div>
<div class="card-body">
<div class="d-flex flex-wrap justify-content-end align-items-center mb-2">
<a href="{{ route('taxation.upload', ['menu_id' => $menuId]) }}" class="btn btn-primary btn-sm d-block d-sm-inline w-auto">Upload</a>
</div>
<div>
<div id="table-taxation"></div>
</div>
</div>
</div>
</div>
</div>
@endsection
@section('scripts')
@vite(['resources/js/taxation/index.js'])
@endsection

View File

@@ -0,0 +1,81 @@
@extends('layouts.vertical', ['subtitle' => 'Pajak'])
@section('content')
@include('layouts.partials/page-title', ['title' => 'Pajak', 'subtitle' => 'Upload'])
<x-toast-notification />
<input type="hidden" id="menuId" value="{{ $menuId ?? 0 }}">
<div class="row">
<div class="col-xl-12">
<div class="card">
<div class="card-header">
<h5 class="card-title">Upload Data Pajak</h5>
<p class="card-subtitle">
Please upload a file with the extension <strong>.xls or .xlsx</strong> with a maximum size of <strong>10 MB</strong>.
<br>
For <strong>.xls</strong> and <strong>.xlsx</strong> files, ensure that the data is contained within a <strong>single sheet</strong> with the following columns:
<strong>kode, no, npwpd, nama_wp, nama_usaha, alamat_usaha, masa_pajak, nilai_pajak, kecamatan, desa</strong>
</p>
</div>
<div class="card-body">
<div class="mb-3">
<div class="dropzone">
<form id="formUploadTaxation" action="{{ route('api.taxs.upload') }}" method="post" enctype="multipart/form-data">
<div class="fallback">
<!-- <input id="file-dropzone" type="file" name="file" accept=".xlsx,.xls" multiple/> -->
</div>
</form>
<div class="dz-message needsclick">
<i class="h1 bx bx-cloud-upload"></i>
<h3>Drop files here or click to upload.</h3>
</div>
</div>
<ul class="list-unstyled mb-0" id="dropzone-preview">
<li class="mt-2" id="dropzone-preview-list">
<!-- This is used as the file preview template -->
<div class="border rounded">
<div class="d-flex align-items-center p-2">
<div class="flex-shrink-0 me-3">
<div class="avatar-sm bg-light rounded">
<img data-dz-thumbnail class="img-fluid rounded d-block" src="#"
alt="" />
</div>
</div>
<div class="flex-grow-1">
<div class="pt-1">
<h5 class="fs-14 mb-1" data-dz-name>&nbsp;
</h5>
<p class="fs-13 text-muted mb-0" data-dz-size></p>
<strong class="error text-danger" data-dz-errormessage></strong>
</div>
</div>
<div class="flex-shrink-0 ms-3">
<button data-dz-remove class="btn btn-sm btn-danger">Delete</button>
</div>
</div>
</div>
</li>
</ul>
<!-- end dropzon-preview -->
</div>
<div class="d-flex justify-content-end">
<button id="submit-upload" class="btn btn-primary">
<span id="spinner" class="spinner-border spinner-border-sm me-1 d-none" role="status" aria-hidden="true"></span>
Upload Files
</button>
</div>
</div> <!-- end card body -->
</div> <!-- end card -->
</div> <!-- end col -->
</div> <!-- end row -->
@endsection
@section('scripts')
@vite(['resources/js/taxation/upload.js'])
@endsection

View File

@@ -28,7 +28,7 @@ use App\Http\Controllers\Api\UmkmController;
use App\Http\Controllers\Api\TourismController; use App\Http\Controllers\Api\TourismController;
use App\Http\Controllers\Api\SpatialPlanningController; use App\Http\Controllers\Api\SpatialPlanningController;
use App\Http\Controllers\Api\ChatbotController; use App\Http\Controllers\Api\ChatbotController;
use App\Http\Controllers\Api\TaxationsController;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
Route::post('/login', [UsersController::class, 'login'])->name('api.user.login'); Route::post('/login', [UsersController::class, 'login'])->name('api.user.login');
@@ -194,5 +194,11 @@ Route::group(['middleware' => 'auth:sanctum'], function (){
Route::get('/growth','index')->name('api.growth'); Route::get('/growth','index')->name('api.growth');
}); });
Route::controller(TaxationsController::class)->group(function (){
Route::get('/taxs', 'index')->name('api.taxs');
Route::post('/taxs/upload', 'upload')->name('api.taxs.upload');
Route::get('/taxs/export', 'export')->name('api.taxs.export');
});
// TODO: Implement new retribution calculation API endpoints using the new schema // TODO: Implement new retribution calculation API endpoints using the new schema
}); });

View File

@@ -31,6 +31,7 @@ use App\Http\Controllers\Data\GoogleSheetsController;
use App\Http\Controllers\Report\ReportTourismController; use App\Http\Controllers\Report\ReportTourismController;
use App\Http\Controllers\Chatbot\ChatbotController; use App\Http\Controllers\Chatbot\ChatbotController;
use App\Http\Controllers\ChatbotPimpinan\ChatbotPimpinanController; use App\Http\Controllers\ChatbotPimpinan\ChatbotPimpinanController;
use App\Http\Controllers\TaxationController;
use App\Http\Controllers\TpatptsController; use App\Http\Controllers\TpatptsController;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
@@ -186,4 +187,10 @@ Route::group(['middleware' => 'auth'], function(){
Route::group(['prefix' => '/tools'], function (){ Route::group(['prefix' => '/tools'], function (){
Route::get('/invitations', [InvitationsController::class, 'index'])->name('invitations'); Route::get('/invitations', [InvitationsController::class, 'index'])->name('invitations');
}); });
// taxation
Route::group(['prefix' => '/tax'], function (){
Route::get('/', [TaxationController::class, 'index'])->name('taxation');
Route::get('/upload', [TaxationController::class, 'upload'])->name('taxation.upload');
});
}); });

View File

@@ -148,6 +148,9 @@ export default defineConfig({
"resources/js/report-pbg-ptsp/index.js", "resources/js/report-pbg-ptsp/index.js",
"resources/js/tpa-tpt/index.js", "resources/js/tpa-tpt/index.js",
"resources/js/report-payment-recaps/index.js", "resources/js/report-payment-recaps/index.js",
// taxation
"resources/js/taxation/index.js",
"resources/js/taxation/upload.js",
], ],
refresh: true, refresh: true,
}), }),