1 Commits

38 changed files with 390 additions and 3281 deletions

View File

@@ -6,43 +6,14 @@
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
use Modules\Basicdata\Models\Branch;
use Modules\Lpj\Models\Branch;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
class BranchExport implements WithColumnFormatting, WithHeadings, FromCollection, WithMapping
class BranchExport implements WithColumnFormatting, WithHeadings, FromCollection, withMapping
{
protected $search;
protected $parent_id;
public function __construct($search = null, $parent_id = null)
{
$this->search = $search;
$this->parent_id = $parent_id;
}
public function collection()
{
$query = Branch::query();
if (!empty($this->search)) {
$search = strtolower($this->search);
$query->where(function ($q) use ($search) {
$q->whereRaw('LOWER(code) LIKE ?', ['%' . $search . '%'])
->orWhereRaw('LOWER(name) LIKE ?', ['%' . $search . '%'])
->orWhereRaw('LOWER(address) LIKE ?', ['%' . $search . '%'])
->orWhereHas('parent', function ($q) use ($search) {
$q->whereRaw('LOWER(name) LIKE ?', ['%' . strtolower($search) . '%']);
});
});
}
// Apply parent filter if provided
if (isset($this->parent_id) && !empty($this->parent_id)) {
$parentId = $this->parent_id;
$query->where('parent_id', $parentId);
}
return $query->get();
return Branch::all();
}
public function map($row)
@@ -52,8 +23,6 @@
$row->id,
$row->code,
$row->name,
$row->parent ? $row->parent->name : '',
$row->address,
$row->created_at
];
}
@@ -65,8 +34,6 @@
'ID',
'Code',
'Name',
'Parent Branch',
'Address',
'Created At'
];
}
@@ -76,7 +43,7 @@
{
return [
'A' => NumberFormat::FORMAT_NUMBER,
'E' => NumberFormat::FORMAT_DATE_DATETIME
'D' => NumberFormat::FORMAT_DATE_DATETIME
];
}
}

View File

@@ -6,33 +6,14 @@
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
use Modules\Basicdata\Models\Currency;
use Modules\Lpj\Models\Currency;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
class CurrencyExport implements WithColumnFormatting, WithHeadings, FromCollection, WithMapping
class CurrencyExport implements WithColumnFormatting, WithHeadings, FromCollection, withMapping
{
protected $search;
public function __construct($search = null)
{
$this->search = $search;
}
public function collection()
{
$query = Currency::query();
if (!empty($this->search)) {
$search = $this->search;
$query->where(function ($q) use ($search) {
$q->whereRaw('LOWER(code) LIKE ?', ['%' . strtolower($search) . '%'])
->orWhereRaw('LOWER(name) LIKE ?', ['%' . strtolower($search) . '%'])
->orWhereRaw('CAST(decimal_places AS TEXT) LIKE ?', ['%' . $search . '%']);
});
}
return $query->get();
return Currency::all();
}
public function map($row)
@@ -43,6 +24,8 @@
$row->code,
$row->name,
$row->decimal_places,
$row->updated_at,
$row->deleted_at,
$row->created_at
];
}
@@ -64,7 +47,7 @@
{
return [
'A' => NumberFormat::FORMAT_NUMBER,
'D' => NumberFormat::FORMAT_NUMBER,
'B' => NumberFormat::FORMAT_NUMBER,
'E' => NumberFormat::FORMAT_DATE_DATETIME
];
}

View File

@@ -6,32 +6,14 @@ use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
use Modules\Basicdata\Models\HolidayCalendar;
use Modules\Basicdata\Entities\HolidayCalendar;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
class HolidayCalendarExport implements WithColumnFormatting, WithHeadings, FromCollection, WithMapping
{
protected $search;
public function __construct($search = null)
{
$this->search = $search;
}
public function collection()
{
$query = HolidayCalendar::query();
if (!empty($this->search)) {
$search = $this->search;
$query->where(function ($q) use ($search) {
$q->whereRaw('LOWER(description) LIKE ?', ['%' . strtolower($search) . '%'])
->orWhereRaw('LOWER(type) LIKE ?', ['%' . strtolower($search) . '%'])
->orWhereRaw('CAST(date AS TEXT) LIKE ?', ['%' . $search . '%']);
});
}
return $query->get();
return HolidayCalendar::all();
}
public function map($row): array

View File

@@ -1,22 +0,0 @@
<?php
use Modules\Basicdata\Models\Currency;
/**
* Format a number as a currency string with appropriate symbol and formatting.
*
* This function retrieves currency information from the database and formats
* the provided number according to the currency's specifications.
*
* @param float|int $number The number to be formatted as currency
* @param string $currency The currency code (default: 'IDR')
* @return string The formatted currency string with symbol and proper number formatting
*/
if(!function_exists('currencyFormat')) {
function currencyFormat($number, $currency = 'IDR') {
$currency = Currency::where('code', $currency)->first();
$symbol = $currency->symbol?? '';
return $symbol . ' ' . number_format($number, $currency->decimal_places, ',', '.');
}
}

View File

@@ -1,54 +0,0 @@
<?php
use Carbon\Carbon;
use Modules\Basicdata\Models\HolidayCalendar;
/**
* Calculate the number of working days between two dates.
*
* This function counts the number of days that are not weekends and not holidays
* between the given start and end dates (inclusive).
*
* @param string|Carbon $startDate The starting date for the calculation
* @param string|Carbon $endDate The ending date for the calculation
* @return int The number of working days between the two dates
*/
if (!function_exists('workingDays')) {
function workingDays($startDate, $endDate)
{
$startDate = Carbon::parse($startDate)->startOfDay();
$endDate = Carbon::parse($endDate)->endOfDay();
$workingDay = 0;
$now = $startDate->copy();
while ($now <= $endDate) {
if (!$now->isWeekend() && !in_array($now->format('Y-m-d'), holidays())) {
$workingDay++;
}
$now->addDay();
}
return $workingDay;
}
}
/**
* Get a list of all holiday dates from the holiday calendar.
*
* This function retrieves all holiday dates from the HolidayCalendar model
* and formats them as Y-m-d strings for easy comparison in date calculations.
*
* @return array An array of holiday dates in Y-m-d format
*/
if (!function_exists('holidays')) {
function holidays()
{
return HolidayCalendar::pluck('date')->map(
function ($item) {
return Carbon::parse($item)->format('Y-m-d');
},
)->toArray();
}
}

View File

@@ -2,7 +2,6 @@
namespace Modules\Basicdata\Http\Controllers;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
use Exception;
use Illuminate\Http\Request;
@@ -13,37 +12,15 @@
class BranchController extends Controller
{
protected $user;
public function __construct()
{
// Mengatur middleware auth
$this->middleware('auth');
// Mengatur user setelah middleware auth dijalankan
$this->middleware(function ($request, $next) {
$this->user = Auth::user();
return $next($request);
});
}
public $user;
public function index()
{
// Check if the authenticated user has the required permission to view branches
if (is_null($this->user) || !$this->user->can('basic-data.read')) {
abort(403, 'Sorry! You are not allowed to view branches.');
}
return view('basicdata::branch.index');
}
public function store(BranchRequest $request)
{
// Check if the authenticated user has the required permission to create branches
if (is_null($this->user) || !$this->user->can('basic-data.create')) {
abort(403, 'Sorry! You are not allowed to create branches.');
}
$validate = $request->validated();
if ($validate) {
@@ -63,43 +40,19 @@
public function create()
{
// Check if the authenticated user has the required permission to create branches
if (is_null($this->user) || !$this->user->can('basic-data.create')) {
abort(403, 'Sorry! You are not allowed to create branches.');
}
$branches = Branch::all();
return view('basicdata::branch.create', compact('branches'));
return view('basicdata::branch.create');
}
public function edit($id)
{
// Check if the authenticated user has the required permission to update branches
if (is_null($this->user) || !$this->user->can('basic-data.update')) {
abort(403, 'Sorry! You are not allowed to update branches.');
}
$branch = Branch::findOrFail($id);
$branches = Branch::all();
return view('basicdata::branch.create', compact('branch', 'branches'));
$branch = Branch::find($id);
return view('basicdata::branch.create', compact('branch'));
}
public function update(BranchRequest $request, $id)
{
// Check if the authenticated user has the required permission to update branches
if (is_null($this->user) || !$this->user->can('basic-data.update')) {
abort(403, 'Sorry! You are not allowed to update branches.');
}
$validate = $request->validated();
// Tambahkan validasi manual untuk memeriksa parent_id
if (isset($validate['parent_id']) && $validate['parent_id'] == $id) {
return redirect()
->back()
->withInput()
->withErrors(['parent_id' => 'Cabang tidak dapat menjadi induk dari dirinya sendiri.']);
}
if ($validate) {
try {
// Update in database
@@ -118,71 +71,28 @@
public function destroy($id)
{
// Check if the authenticated user has the required permission to delete branches
if (is_null($this->user) || !$this->user->can('basic-data.delete')) {
return response()->json([
'success' => false,
'message' => 'Sorry! You are not allowed to delete branches.'
], 403);
}
try {
// Find the branch
$branch = Branch::find($id);
// Check if the branch has children
if ($branch->children()->exists()) {
return response()->json([
'success' => false,
'message' => 'Cabang dengan anak cabang tidak dapat dihapus.'
], 422);
}
// Delete from database
$branch = Branch::find($id);
$branch->delete();
return response()->json(['success' => true, 'message' => 'Branch deleted successfully']);
echo json_encode(['success' => true, 'message' => 'Branch deleted successfully']);
} catch (Exception $e) {
return response()->json(['success' => false, 'message' => 'Failed to delete branch']);
echo json_encode(['success' => false, 'message' => 'Failed to delete branch']);
}
}
public function deleteMultiple(Request $request)
{
// Check if the authenticated user has the required permission to delete branches
if (is_null($this->user) || !$this->user->can('basic-data.delete')) {
return response()->json([
'success' => false,
'message' => 'Sorry! You are not allowed to delete branches.'
], 403);
}
$ids = $request->input('ids');
// Check if any of the branches have children
$branchesWithChildren = Branch::whereIn('id', $ids)
->whereHas('children')
->get();
if ($branchesWithChildren->count() > 0) {
return response()->json([
'success' => false,
'message' => 'Beberapa cabang memiliki anak cabang dan tidak dapat dihapus.'
], 422);
}
Branch::whereIn('id', $ids)->delete();
return response()->json(['success' => true, 'message' => 'Branches deleted successfully']);
return response()->json(['message' => 'Branches deleted successfully']);
}
public function dataForDatatables(Request $request)
{
// Check if the authenticated user has the required permission to view branches
if (is_null($this->user) || !$this->user->can('basic-data.read')) {
return response()->json([
'success' => false,
'message' => 'Sorry! You are not allowed to view branches.'
], 403);
if (is_null($this->user) || !$this->user->can('branch.view')) {
//abort(403, 'Sorry! You are not allowed to view users.');
}
// Retrieve data from the database
@@ -190,25 +100,11 @@
// Apply search filter if provided
if ($request->has('search') && !empty($request->get('search'))) {
$search = json_decode($request->get('search'));
if(isset($search->search)) {
$search_ = strtolower($search->search);
$query->where(function ($q) use ($search_) {
$q->whereRaw('LOWER(code) LIKE ?', ['%' . strtolower($search_) . '%']);
$q->orWhereRaw('LOWER(name) LIKE ?', ['%' . strtolower($search_) . '%']);
$q->orWhereRaw('LOWER(address) LIKE ?', ['%' . strtolower($search_) . '%']);
$q->orWhereHas('parent', function ($q) use ($search_) {
$q->whereRaw('LOWER(name) LIKE ?', ['%' . strtolower($search_) . '%']);
$search = $request->get('search');
$query->where(function ($q) use ($search) {
$q->where('code', 'LIKE', "%$search%");
$q->orWhere('name', 'LIKE', "%$search%");
});
});
}
// Apply parent filter if provided
if (isset($search->parent_id) && !empty($search->parent_id)) {
$parentId = $search->parent_id;
$query->where('parent_id', $parentId);
}
}
// Apply sorting if provided
@@ -236,22 +132,11 @@
// Get the data for the current page
$data = $query->get();
$data = $data->map(function ($item) {
return [
'id' => $item->id,
'code' => $item->code,
'name' => $item->name,
'parent_id' => $item->parent?->name ?? null,
'address' => str_replace(']', "", $item->address),
];
});
// Calculate the page count
$pageCount = ceil($totalRecords / $request->get('size'));
// Calculate the current page number
$currentPage = $request->get('page') ?: 1;
$currentPage = 0 + 1;
// Return the response data as a JSON object
return response()->json([
@@ -265,17 +150,8 @@
]);
}
public function export(Request $request)
public function export()
{
// Check if the authenticated user has the required permission to export branches
if (is_null($this->user) || !$this->user->can('basic-data.export')) {
abort(403, 'Sorry! You are not allowed to export branches.');
}
// Get search parameter from request
$search = $request->get('search');
$parentId = $request->get('parent_id');
return Excel::download(new BranchExport($search,$parentId), 'branch.xlsx');
return Excel::download(new BranchExport, 'branch.xlsx');
}
}

View File

@@ -9,41 +9,18 @@
use Modules\Basicdata\Exports\CurrencyExport;
use Modules\Basicdata\Http\Requests\CurrencyRequest;
use Modules\Basicdata\Models\Currency;
use Illuminate\Support\Facades\Auth;
class CurrencyController extends Controller
{
protected $user;
public function __construct()
{
// Mengatur middleware auth
$this->middleware('auth');
// Mengatur user setelah middleware auth dijalankan
$this->middleware(function ($request, $next) {
$this->user = Auth::user();
return $next($request);
});
}
public $user;
public function index()
{
// Check if the authenticated user has the required permission to view currencies
if (is_null($this->user) || !$this->user->can('basic-data.read')) {
abort(403, 'Sorry! You are not allowed to view currencies.');
}
return view('basicdata::currency.index');
}
public function store(CurrencyRequest $request)
{
// Check if the authenticated user has the required permission to create currencies
if (is_null($this->user) || !$this->user->can('basic-data.create')) {
abort(403, 'Sorry! You are not allowed to create currencies.');
}
$validate = $request->validated();
if ($validate) {
@@ -63,32 +40,17 @@
public function create()
{
// Check if the authenticated user has the required permission to create currencies
if (is_null($this->user) || !$this->user->can('basic-data.create')) {
abort(403, 'Sorry! You are not allowed to create currencies.');
}
return view('basicdata::currency.create');
}
public function edit($id)
{
// Check if the authenticated user has the required permission to update currencies
if (is_null($this->user) || !$this->user->can('basic-data.update')) {
abort(403, 'Sorry! You are not allowed to update currencies.');
}
$currency = Currency::find($id);
return view('basicdata::currency.create', compact('currency'));
}
public function update(CurrencyRequest $request, $id)
{
// Check if the authenticated user has the required permission to update currencies
if (is_null($this->user) || !$this->user->can('basic-data.update')) {
abort(403, 'Sorry! You are not allowed to update currencies.');
}
$validate = $request->validated();
if ($validate) {
@@ -109,39 +71,28 @@
public function destroy($id)
{
// Check if the authenticated user has the required permission to delete currencies
if (is_null($this->user) || !$this->user->can('basic-data.delete')) {
return response()->json(['success' => false, 'message' => 'Sorry! You are not allowed to delete currencies.'], 403);
}
try {
// Delete from database
$currency = Currency::find($id);
$currency->delete();
return response()->json(['success' => true, 'message' => 'Currency deleted successfully']);
echo json_encode(['success' => true, 'message' => 'Currency deleted successfully']);
} catch (Exception $e) {
return response()->json(['success' => false, 'message' => 'Failed to delete currency']);
echo json_encode(['success' => false, 'message' => 'Failed to delete currency']);
}
}
public function deleteMultiple(Request $request)
{
// Check if the authenticated user has the required permission to delete currencies
if (is_null($this->user) || !$this->user->can('basic-data.delete')) {
return response()->json(['success' => false, 'message' => 'Sorry! You are not allowed to delete currencies.'], 403);
}
$ids = $request->input('ids');
Currency::whereIn('id', $ids)->delete();
return response()->json(['success' => true, 'message' => 'Currencies deleted successfully']);
return response()->json(['message' => 'Currencies deleted successfully']);
}
public function dataForDatatables(Request $request)
{
// Check if the authenticated user has the required permission to view currencies
if (is_null($this->user) || !$this->user->can('basic-data.read')) {
return response()->json(['success' => false, 'message' => 'Sorry! You are not allowed to view currencies.'], 403);
if (is_null($this->user) || !$this->user->can('currency.view')) {
//abort(403, 'Sorry! You are not allowed to view users.');
}
// Retrieve data from the database
@@ -152,7 +103,6 @@
$search = $request->get('search');
$query->where(function ($q) use ($search) {
$q->where('code', 'LIKE', "%$search%");
$q->orWhere('symbol', 'LIKE', "%$search%");
$q->orWhere('name', 'LIKE', "%$search%");
});
}
@@ -183,10 +133,10 @@
$data = $query->get();
// Calculate the page count
$pageCount = ceil($filteredRecords / ($request->get('size') ?: 1));
$pageCount = ceil($totalRecords / $request->get('size'));
// Calculate the current page number
$currentPage = $request->get('page') ?: 1;
$currentPage = 0 + 1;
// Return the response data as a JSON object
return response()->json([
@@ -200,16 +150,8 @@
]);
}
public function export(Request $request)
public function export()
{
// Check if the authenticated user has the required permission to export currencies
if (is_null($this->user) || !$this->user->can('basic-data.export')) {
abort(403, 'Sorry! You are not allowed to export currencies.');
}
// Get search parameter from request
$search = $request->get('search');
return Excel::download(new CurrencyExport($search), 'currency.xlsx');
return Excel::download(new CurrencyExport, 'currency.xlsx');
}
}

View File

@@ -9,42 +9,18 @@
use Modules\Basicdata\Exports\HolidayCalendarExport;
use Modules\Basicdata\Http\Requests\HolidayCalendarRequest;
use Modules\Basicdata\Models\HolidayCalendar;
use Illuminate\Support\Facades\Auth;
class HolidayCalendarController extends Controller
{
protected $user;
public function __construct()
{
// Mengatur middleware auth
$this->middleware('auth');
// Mengatur user setelah middleware auth dijalankan
$this->middleware(function ($request, $next) {
$this->user = Auth::user();
return $next($request);
});
}
public $user;
public function index()
{
// Check if the authenticated user has the required permission to view holiday calendars
if (is_null($this->user) || !$this->user->can('basic-data.read')) {
abort(403, 'Sorry! You are not allowed to view holiday calendars.');
}
return view('basicdata::holidaycalendar.index');
}
public function store(HolidayCalendarRequest $request)
{
// Check if the authenticated user has the required permission to create holiday calendars
if (is_null($this->user) || !$this->user->can('basic-data.create')) {
abort(403, 'Sorry! You are not allowed to create holiday calendars.');
}
$validate = $request->validated();
if ($validate) {
@@ -64,32 +40,17 @@
public function create()
{
// Check if the authenticated user has the required permission to create holiday calendars
if (is_null($this->user) || !$this->user->can('basic-data.create')) {
abort(403, 'Sorry! You are not allowed to create holiday calendars.');
}
return view('basicdata::holidaycalendar.create');
}
public function edit($id)
{
// Check if the authenticated user has the required permission to update holiday calendars
if (is_null($this->user) || !$this->user->can('basic-data.update')) {
abort(403, 'Sorry! You are not allowed to update holiday calendars.');
}
$holiday = HolidayCalendar::find($id);
return view('basicdata::holidaycalendar.create', compact('holiday'));
}
public function update(HolidayCalendarRequest $request, $id)
{
// Check if the authenticated user has the required permission to update holiday calendars
if (is_null($this->user) || !$this->user->can('basic-data.update')) {
abort(403, 'Sorry! You are not allowed to update holiday calendars.');
}
$validate = $request->validated();
if ($validate) {
@@ -113,11 +74,6 @@
public function destroy($id)
{
// Check if the authenticated user has the required permission to delete holiday calendars
if (is_null($this->user) || !$this->user->can('basic-data.delete')) {
abort(403, 'Sorry! You are not allowed to delete holiday calendars.');
}
try {
$holiday = HolidayCalendar::find($id);
$holiday->delete();
@@ -134,27 +90,15 @@
public function deleteMultiple(Request $request)
{
// Check if the authenticated user has the required permission to delete holiday calendars
if (is_null($this->user) || !$this->user->can('basic-data.delete')) {
return response()->json([
'success' => false,
'message' => 'Sorry! You are not allowed to delete holiday calendars.'
], 403);
}
$ids = $request->input('ids');
HolidayCalendar::whereIn('id', $ids)->delete();
return response()->json(['success' => true, 'message' => 'Holidays deleted successfully']);
return response()->json(['message' => 'Holidays deleted successfully']);
}
public function dataForDatatables(Request $request)
{
// Check if the authenticated user has the required permission to view holiday calendars
if (is_null($this->user) || !$this->user->can('basic-data.read')) {
return response()->json([
'success' => false,
'message' => 'Sorry! You are not allowed to view holiday calendars.'
], 403);
if (is_null($this->user) || !$this->user->can('currency.view')) {
//abort(403, 'Sorry! You are not allowed to view users.');
}
// Retrieve data from the database
@@ -199,7 +143,7 @@
$pageCount = ceil($totalRecords / $request->get('size'));
// Calculate the current page number
$currentPage = $request->get('page') ?: 1;
$currentPage = 0 + 1;
// Return the response data as a JSON object
return response()->json([
@@ -213,16 +157,8 @@
]);
}
public function export(Request $request)
public function export()
{
// Check if the authenticated user has the required permission to export holiday calendars
if (is_null($this->user) || !$this->user->can('basic-data.export')) {
abort(403, 'Sorry! You are not allowed to export holiday calendars.');
}
// Get search parameter from request
$search = $request->get('search');
return Excel::download(new HolidayCalendarExport($search), 'holiday_calendar.xlsx');
return Excel::download(new HolidayCalendarExport, 'holiday_calendar.xlsx');
}
}

View File

@@ -3,7 +3,6 @@
namespace Modules\Basicdata\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class BranchRequest extends FormRequest
{
@@ -15,15 +14,6 @@
{
$rules = [
'name' => 'required|string|max:255',
'parent_id' => [
'nullable',
'exists:branches,id',
function ($attribute, $value, $fail) {
if ($value == $this->route('branch')) {
$fail('Cabang tidak dapat menjadi induk dari dirinya sendiri.');
}
},
],
'status' => 'nullable|boolean',
'authorized_at' => 'nullable|datetime',
'authorized_status' => 'nullable|string|max:1',
@@ -31,23 +21,9 @@
];
if ($this->method() == 'PUT') {
$rules['code'] = [
'required',
'string',
'max:10',
Rule::unique('branches')->ignore($this->id)->where(function ($query) {
return $query->whereNull('deleted_at');
}),
];
$rules['code'] = 'required|string|max:3|unique:branches,code,' . $this->id;
} else {
$rules['code'] = [
'required',
'string',
'max:10',
Rule::unique('branches')->where(function ($query) {
return $query->whereNull('deleted_at');
}),
];
$rules['code'] = 'required|string|max:3|unique:branches,code';
}
return $rules;

View File

@@ -14,7 +14,6 @@
{
$rules = [
'name' => 'required|string|max:255',
'symbol' => 'required|string|max:10',
'decimal_places' => 'nullable|integer|between:0,3',
'status' => 'nullable|boolean',
'authorized_at' => 'nullable|datetime',
@@ -23,8 +22,7 @@
];
if ($this->method() == 'PUT') {
$id = $this->id ? (int)$this->id : null;
$rules['code'] = 'required|string|max:3|unique:currencies,code,' . $id;
$rules['code'] = 'required|string|max:3|unique:currencies,code,' . $this->id;
} else {
$rules['code'] = 'required|string|max:3|unique:currencies,code';
}
@@ -38,14 +36,6 @@
public function authorize()
: bool
{
$user = auth()->guard('web')->user();
if ($this->method() == 'PUT') {
return $user && $user->can('basic-data.update');
} elseif ($this->method() == 'POST') {
return $user && $user->can('basic-data.create');
}
return true;
}
}

View File

@@ -6,7 +6,7 @@
use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Traits\LogsActivity;
use Mattiverse\Userstamps\Traits\Userstamps;
use Wildside\Userstamps\Userstamps;
/**
@@ -46,6 +46,6 @@
public function getActivitylogOptions()
: LogOptions
{
return LogOptions::defaults()->logAll()->useLogName('Basic Data');
return LogOptions::defaults()->logAll()->useLogName('LPJ : ');
}
}

View File

@@ -2,42 +2,9 @@
namespace Modules\Basicdata\Models;
class Branch extends Base
{
protected $table = 'branches';
protected $fillable = [
'code',
'name',
'is_dalam_kota',
'address',
'mnemonic',
'customer_company',
'customer_mnemonic',
'company_group',
'curr_no',
'co_code',
'l_vendor_atm',
'l_vendor_cpc',
'status',
'authorized_at',
'authorized_status',
'authorized_by',
'parent_id'
];
/**
* Get the parent branch of this branch
*/
public function parent()
{
return $this->belongsTo(Branch::class, 'parent_id');
}
/**
* Get the child branches of this branch
*/
public function children()
{
return $this->hasMany(Branch::class, 'parent_id');
}
protected $fillable = ['code', 'name', 'status', 'authorized_at', 'authorized_status', 'authorized_by'];
}

View File

@@ -9,7 +9,6 @@
protected $fillable = [
'code',
'name',
'symbol',
'decimal_places',
'status',
'authorized_at',

View File

@@ -15,7 +15,6 @@
$table->id();
$table->string('code', 3)->unique();
$table->string('name');
$table->string('symbol')->nullable();
$table->integer('decimal_places')->default(2);
$table->boolean('status')->default(true)->nullable();
$table->timestamps();

View File

@@ -1,30 +0,0 @@
<?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('branches', function (Blueprint $table) {
$table->unsignedBigInteger('parent_id')->nullable()->after('name');
$table->foreign('parent_id')->references('id')->on('branches')->onDelete('set null');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('branches', function (Blueprint $table) {
$table->dropForeign(['parent_id']);
$table->dropColumn('parent_id');
});
}
};

View File

@@ -1,46 +0,0 @@
<?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('branches', function (Blueprint $table) {
$table->string('address')->nullable()->after('name');
$table->string('mnemonic')->nullable()->after('address');
$table->string('customer_company')->nullable()->after('mnemonic');
$table->string('customer_mnemonic')->nullable()->after('customer_company');
$table->string('company_group')->nullable()->after('customer_mnemonic');
$table->string('curr_no')->nullable()->after('company_group');
$table->string('co_code')->nullable()->after('curr_no');
$table->boolean('l_vendor_atm')->default(false)->after('co_code');
$table->boolean('l_vendor_cpc')->default(false)->after('l_vendor_atm');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('branches', function (Blueprint $table) {
$table->dropColumn([
'address',
'mnemonic',
'customer_company',
'customer_mnemonic',
'company_group',
'curr_no',
'co_code',
'l_vendor_atm',
'l_vendor_cpc'
]);
});
}
};

View File

@@ -1,27 +0,0 @@
<?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('branches', function (Blueprint $table) {
$table->boolean('is_dalam_kota')->default(true)->after('name');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('branches', function (Blueprint $table) {
$table->dropColumn('is_dalam_kota');
});
}
};

View File

@@ -12,8 +12,7 @@ class BasicdataDatabaseSeeder extends Seeder
public function run(): void
{
$this->call([
PermissionSeeder::class,
BranchesSeeder::class,
BranchSeeder::class,
CurrencySeeder::class,
HolidayCalendarSeeder::class
]);

View File

@@ -0,0 +1,24 @@
<?php
namespace Modules\Basicdata\Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class BranchSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
// ambil dari sql
try {
DB::unprepared(file_get_contents(__DIR__ . '/sql/branches.sql'));
} catch (\Exception $e) {
Log::error('Gagal import: ' . $e->getMessage());
throw $e;
}
}
}

View File

@@ -1,856 +0,0 @@
<?php
namespace Modules\Basicdata\database\seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
class BranchesSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$now = Carbon::now();
$branches = [
[
'code' => 'ID0010001',
'name' => 'PT. Bank Artha Graha',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010002',
'name' => 'SURYOPRANOTO - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010003',
'name' => 'PURI INDAH - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010005',
'name' => 'ARTHA GADING - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010006',
'name' => 'MANGGA DUA PLAZA',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010008',
'name' => 'KPO SUDIRMAN',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010009',
'name' => 'MELAWAI - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010010',
'name' => 'SUNTER - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010011',
'name' => 'TANAH ABANG - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010012',
'name' => 'BINTARO - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010015',
'name' => 'MANGGA BESAR - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010016',
'name' => 'BOROBUDUR - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010017',
'name' => 'TANGERANG - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010018',
'name' => 'BURSA EFEK IND - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010020',
'name' => 'P. JAYAKARTA - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010021',
'name' => 'JATINEGARA - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010022',
'name' => 'CINERE - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010023',
'name' => 'MITRA - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010025',
'name' => 'KLP GADING BLVD - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010026',
'name' => 'MG DUA PSR PAGI - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010027',
'name' => 'RAWAMANGUN - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010028',
'name' => 'KWITANG',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010029',
'name' => 'COKROAMINOTO - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010030',
'name' => 'ASIA AFRIKA BDG - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010031',
'name' => 'BKR Bandung - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010032',
'name' => 'SETIABUDI BDG - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010033',
'name' => 'PAJAJARAN-KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010035',
'name' => 'BUAH BATU BDG - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010036',
'name' => 'RAYA SUDIRMAN BDG -KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010037',
'name' => 'GARUT - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010038',
'name' => 'RAJAWALI - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010039',
'name' => 'Cimahi - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010050',
'name' => 'Ir.Soekarno(MERR)-KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010051',
'name' => 'PASAR ATUM SBY - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010052',
'name' => 'SURABAYA KARET -KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010053',
'name' => 'KEDUNGDORO - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010055',
'name' => 'HR MUHAMMAD SBY - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010056',
'name' => 'PRAPEN - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010057',
'name' => 'SIDOARJO KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010058',
'name' => 'PASAR TURI - KK',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010060',
'name' => 'RENON DENPASAR - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010061',
'name' => 'KUTA BALI - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010062',
'name' => 'SUNSET ROAD - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010063',
'name' => 'Diponegoro Denpasar KK',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010070',
'name' => 'PEMUDA MEDAN - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010071',
'name' => 'CEMARA ASRI MDN - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010072',
'name' => 'SUTOMO MEDAN - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010073',
'name' => 'JL CIREBON MDN - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010075',
'name' => 'ASIA MEDAN - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010080',
'name' => 'KARTINI - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010081',
'name' => 'SURYANEGARA CRB - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010082',
'name' => 'PLERED CRB - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010090',
'name' => 'MATRAMAN-KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010091',
'name' => 'CEMPAKA PUTIH - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010092',
'name' => 'CIKARANG - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010093',
'name' => 'ROXY MAS - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010095',
'name' => 'SAWAH BESAR - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010096',
'name' => 'GREENVILLE-KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010097',
'name' => 'KEBUN JERUK - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010098',
'name' => 'KOPI - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010099',
'name' => 'PANTAI IND KAPUK - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010100',
'name' => 'PLUIT KENCANA - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010101',
'name' => 'MANGGA DUA SQUARE-KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010102',
'name' => 'CIRACAS - KK',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010103',
'name' => 'DEPOK - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010105',
'name' => 'UJUNG MENTENG-KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010106',
'name' => 'CURUG-KK',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010107',
'name' => 'BSD - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010108',
'name' => 'Tzu Chi - KK',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010109',
'name' => 'KARAWANG - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010110',
'name' => 'PANDANARAN SMG - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010111',
'name' => 'GANG BESEN - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010112',
'name' => 'PEMUDA - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010120',
'name' => 'SAMRATULANGI MAN - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010121',
'name' => 'MANADO MALL - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010122',
'name' => 'CALACA MANADO - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010130',
'name' => 'MAKASSAR - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010131',
'name' => 'Veteran Makassar - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010132',
'name' => 'RATULANGI - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010150',
'name' => 'WATAMPONE - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010160',
'name' => 'BITUNG - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010170',
'name' => 'DIPONEGORO AMBON - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010171',
'name' => 'MARDIKA AMBON - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010180',
'name' => 'TERNATE - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010190',
'name' => 'KENDARI-KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010191',
'name' => 'RAROWATU BOMBANA - KK',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010192',
'name' => 'ANGATA KONAWE SLT - KK',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010200',
'name' => 'LAMPUNG-KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010201',
'name' => 'PEMUDA LAMPUNG - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010210',
'name' => 'KUPANG - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010220',
'name' => 'BATAM - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010221',
'name' => 'BATAM CENTER - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010230',
'name' => 'SAMARINDA-KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010231',
'name' => 'BERAU KALTIM - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010250',
'name' => 'BOGOR-KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010251',
'name' => 'CIPANAS-KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010260',
'name' => 'SOLO - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010270',
'name' => 'GADING SERPONG - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010272',
'name' => 'Setiabudi Kuningan KK',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010273',
'name' => 'TAMAN PALEM - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010275',
'name' => 'APART CITY HOME - KK',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010276',
'name' => 'TEBET - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010277',
'name' => 'CIPULIR - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010278',
'name' => 'PONDOK INDAH - KK',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010279',
'name' => 'WILADATIKA - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010280',
'name' => 'JABABEKA KK',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010281',
'name' => 'PEKANBARU - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010282',
'name' => 'PALEMBANG-KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010283',
'name' => 'RIAU PEKAN BARU - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010290',
'name' => 'SAYANGAN PLB - KCP',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010300',
'name' => 'PONTIANAK - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010310',
'name' => 'BANJARMASIN - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010320',
'name' => 'JAMBI - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010330',
'name' => 'PANGKAL PINANG - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010350',
'name' => 'BALIKPAPAN - KC',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010380',
'name' => 'PLAZA II INDAH - KK',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010381',
'name' => 'CIPUTAT - KK',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010383',
'name' => 'JEMBATAN LIMA - KK',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
[
'code' => 'ID0010385',
'name' => 'DAAN MOGOT - KK',
'status' => true,
'created_at' => $now,
'updated_at' => $now
],
];
DB::table('branches')->insert($branches);
}
}

View File

@@ -4,63 +4,20 @@
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
class CurrencySeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
public function run(): void
{
$now = Carbon::now();
$currencies = [
['code' => 'USD', 'name' => 'United States Dollar', 'symbol' => '$', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'EUR', 'name' => 'Euro', 'symbol' => '€', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'GBP', 'name' => 'British Pound Sterling', 'symbol' => '£', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'JPY', 'name' => 'Japanese Yen', 'symbol' => '¥', 'decimal_places' => 0, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'AUD', 'name' => 'Australian Dollar', 'symbol' => 'A$', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'CAD', 'name' => 'Canadian Dollar', 'symbol' => 'C$', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'CHF', 'name' => 'Swiss Franc', 'symbol' => 'CHF', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'CNY', 'name' => 'Chinese Yuan', 'symbol' => '¥', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'SEK', 'name' => 'Swedish Krona', 'symbol' => 'kr', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'NZD', 'name' => 'New Zealand Dollar', 'symbol' => 'NZ$', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'MXN', 'name' => 'Mexican Peso', 'symbol' => '$', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'SGD', 'name' => 'Singapore Dollar', 'symbol' => 'S$', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'HKD', 'name' => 'Hong Kong Dollar', 'symbol' => 'HK$', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'NOK', 'name' => 'Norwegian Krone', 'symbol' => 'kr', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'KRW', 'name' => 'South Korean Won', 'symbol' => '₩', 'decimal_places' => 0, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'TRY', 'name' => 'Turkish Lira', 'symbol' => '₺', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'RUB', 'name' => 'Russian Ruble', 'symbol' => '₽', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'INR', 'name' => 'Indian Rupee', 'symbol' => '₹', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'BRL', 'name' => 'Brazilian Real', 'symbol' => 'R$', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'ZAR', 'name' => 'South African Rand', 'symbol' => 'R', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'IDR', 'name' => 'Indonesian Rupiah', 'symbol' => 'Rp', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'MYR', 'name' => 'Malaysian Ringgit', 'symbol' => 'RM', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'PHP', 'name' => 'Philippine Peso', 'symbol' => '₱', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'THB', 'name' => 'Thai Baht', 'symbol' => '฿', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'PLN', 'name' => 'Polish Złoty', 'symbol' => 'zł', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'DKK', 'name' => 'Danish Krone', 'symbol' => 'kr', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'AED', 'name' => 'United Arab Emirates Dirham', 'symbol' => 'د.إ', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'ARS', 'name' => 'Argentine Peso', 'symbol' => '$', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'CLP', 'name' => 'Chilean Peso', 'symbol' => '$', 'decimal_places' => 0, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'EGP', 'name' => 'Egyptian Pound', 'symbol' => 'E£', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'KWD', 'name' => 'Kuwaiti Dinar', 'symbol' => 'د.ك', 'decimal_places' => 3, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'NGN', 'name' => 'Nigerian Naira', 'symbol' => '₦', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'QAR', 'name' => 'Qatari Riyal', 'symbol' => 'ر.ق', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'SAR', 'name' => 'Saudi Riyal', 'symbol' => 'ر.س', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'VND', 'name' => 'Vietnamese Dong', 'symbol' => '₫', 'decimal_places' => 0, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'BDT', 'name' => 'Bangladeshi Taka', 'symbol' => '৳', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'ILS', 'name' => 'Israeli New Shekel', 'symbol' => '₪', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'COP', 'name' => 'Colombian Peso', 'symbol' => '$', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'PEN', 'name' => 'Peruvian Sol', 'symbol' => 'S/', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
['code' => 'PKR', 'name' => 'Pakistani Rupee', 'symbol' => '₨', 'decimal_places' => 2, 'status' => true, 'created_at' => $now, 'updated_at' => $now],
];
// DB::table('currencies')->truncate();
DB::table('currencies')->delete();
DB::table('currencies')->insert($currencies);
try {
DB::unprepared(file_get_contents(__DIR__ . '/sql/currencies.sql'));
} catch (\Exception $e) {
Log::error('Gagal import: ' . $e->getMessage());
throw $e;
}
}
}

View File

@@ -4,213 +4,20 @@
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
class HolidayCalendarSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
public function run(): void
{
$now = Carbon::now();
$holidays = [
// Libur Nasional 2025
[
'date' => '2025-01-01',
'description' => 'Tahun Baru 2025 Masehi',
'type' => 'national_holiday',
'created_at' => $now,
'updated_at' => $now
],
[
'date' => '2025-01-27',
'description' => 'Isra Miraj Nabi Muhammad SAW',
'type' => 'national_holiday',
'created_at' => $now,
'updated_at' => $now
],
[
'date' => '2025-01-29',
'description' => 'Tahun Baru Imlek 2576 Kongzili',
'type' => 'national_holiday',
'created_at' => $now,
'updated_at' => $now
],
[
'date' => '2025-03-29',
'description' => 'Hari Suci Nyepi (Tahun Baru Saka 1947)',
'type' => 'national_holiday',
'created_at' => $now,
'updated_at' => $now
],
[
'date' => '2025-03-31',
'description' => 'Idul Fitri 1446 Hijriah',
'type' => 'national_holiday',
'created_at' => $now,
'updated_at' => $now
],
[
'date' => '2025-04-01',
'description' => 'Idul Fitri 1446 Hijriah',
'type' => 'national_holiday',
'created_at' => $now,
'updated_at' => $now
],
[
'date' => '2025-04-18',
'description' => 'Wafat Yesus Kristus',
'type' => 'national_holiday',
'created_at' => $now,
'updated_at' => $now
],
[
'date' => '2025-04-20',
'description' => 'Kebangkitan Yesus Kristus (Paskah)',
'type' => 'national_holiday',
'created_at' => $now,
'updated_at' => $now
],
[
'date' => '2025-05-01',
'description' => 'Hari Buruh Internasional',
'type' => 'national_holiday',
'created_at' => $now,
'updated_at' => $now
],
[
'date' => '2025-05-12',
'description' => 'Hari Raya Waisak 2569 BE',
'type' => 'national_holiday',
'created_at' => $now,
'updated_at' => $now
],
[
'date' => '2025-05-29',
'description' => 'Kenaikan Yesus Kristus',
'type' => 'national_holiday',
'created_at' => $now,
'updated_at' => $now
],
[
'date' => '2025-06-01',
'description' => 'Hari Lahir Pancasila',
'type' => 'national_holiday',
'created_at' => $now,
'updated_at' => $now
],
[
'date' => '2025-06-06',
'description' => 'Idul Adha 1446 Hijriah',
'type' => 'national_holiday',
'created_at' => $now,
'updated_at' => $now
],
[
'date' => '2025-06-27',
'description' => '1 Muharam Tahun Baru Islam 1447 Hijriah',
'type' => 'national_holiday',
'created_at' => $now,
'updated_at' => $now
],
[
'date' => '2025-08-17',
'description' => 'Proklamasi Kemerdekaan',
'type' => 'national_holiday',
'created_at' => $now,
'updated_at' => $now
],
[
'date' => '2025-09-05',
'description' => 'Maulid Nabi Muhammad SAW',
'type' => 'national_holiday',
'created_at' => $now,
'updated_at' => $now
],
[
'date' => '2025-12-25',
'description' => 'Kelahiran Yesus Kristus',
'type' => 'national_holiday',
'created_at' => $now,
'updated_at' => $now
],
// Cuti Bersama 2025
[
'date' => '2025-01-28',
'description' => 'Cuti Bersama Tahun Baru Imlek 2576 Kongzili',
'type' => 'collective_leave',
'created_at' => $now,
'updated_at' => $now
],
[
'date' => '2025-03-28',
'description' => 'Cuti Bersama Hari Suci Nyepi (Tahun Baru Saka 1947)',
'type' => 'collective_leave',
'created_at' => $now,
'updated_at' => $now
],
[
'date' => '2025-04-02',
'description' => 'Cuti Bersama Idul Fitri',
'type' => 'collective_leave',
'created_at' => $now,
'updated_at' => $now
],
[
'date' => '2025-04-03',
'description' => 'Cuti Bersama Idul Fitri',
'type' => 'collective_leave',
'created_at' => $now,
'updated_at' => $now
],
[
'date' => '2025-04-04',
'description' => 'Cuti Bersama Idul Fitri',
'type' => 'collective_leave',
'created_at' => $now,
'updated_at' => $now
],
[
'date' => '2025-04-07',
'description' => 'Cuti Bersama Idul Fitri',
'type' => 'collective_leave',
'created_at' => $now,
'updated_at' => $now
],
[
'date' => '2025-05-13',
'description' => 'Cuti Bersama Hari Raya Waisak 2569 BE',
'type' => 'collective_leave',
'created_at' => $now,
'updated_at' => $now
],
[
'date' => '2025-05-30',
'description' => 'Cuti Bersama Kenaikan Yesus Kristus',
'type' => 'collective_leave',
'created_at' => $now,
'updated_at' => $now
],
[
'date' => '2025-06-09',
'description' => 'Cuti Bersama Idul Adha 1446 Hijriah',
'type' => 'collective_leave',
'created_at' => $now,
'updated_at' => $now
],
[
'date' => '2025-12-26',
'description' => 'Cuti Bersama Kelahiran Yesus Kristus',
'type' => 'collective_leave',
'created_at' => $now,
'updated_at' => $now
],
];
DB::table('holiday_calendars')->insert($holidays);
try {
DB::unprepared(file_get_contents(__DIR__ . '/sql/holiday_calendars.sql'));
} catch (\Exception $e) {
Log::error('Gagal import: ' . $e->getMessage());
throw $e;
}
}
}

View File

@@ -1,32 +0,0 @@
<?php
namespace Modules\Basicdata\Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Str;
use Modules\Usermanagement\Models\PermissionGroup;
class PermissionSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run()
{
$data = $this->data();
foreach ($data as $value) {
PermissionGroup::updateOrCreate([
'name' => $value['name'],
'slug' => Str::slug($value['name'])
]);
}
}
public function data()
{
return [
['name' => 'basic-data']
];
}
}

View File

@@ -1,54 +0,0 @@
<?php
namespace Modules\Basicdata\Database\Seeders;
use Illuminate\Database\Seeder;
use Modules\Basicdata\Models\Branch;
class UpdateBranchesIsDalamKotaSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$codes = [
'0005','0012','0250','0016','0018','0279','0092','0022','0251',
'0029','0270','0096','0109','0098','2005','0008','0028','0015',
'0006','0090','0009','0023','0020','0099','0003','0010','0002',
'0273','0011','0105',
];
Branch::query()->update(['is_dalam_kota' => false]);
foreach ($codes as $code) {
Branch::where('code', 'like', '%' . $code)
->update(['is_dalam_kota' => true]);
}
$newBranches = [
[
'code' => 'ID0012005',
'name' => 'KORPORASI',
'is_dalam_kota' => true,
],
[
'code' => 'ID0010172',
'name' => 'AMBON TUAL MALUKU',
'is_dalam_kota' => false,
],
];
foreach ($newBranches as $branch) {
Branch::firstOrCreate(
['code' => $branch['code']],
[
'name' => $branch['name'],
'is_dalam_kota' => $branch['is_dalam_kota'],
]
);
}
echo "Seeder update kolom is_dalam_kota + insert data baru selesai!\n";
}
}

View File

@@ -0,0 +1,34 @@
-- phpMyAdmin SQL Dump
-- version 5.2.2
-- https://www.phpmyadmin.net/
--
-- Host: db
-- Generation Time: Jan 30, 2025 at 02:48 AM
-- Server version: 9.2.0
-- PHP Version: 8.2.27
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `myadk`
--
--
-- Dumping data for table `branches`
--
INSERT INTO `branches` (`id`, `code`, `name`, `status`, `created_at`, `updated_at`, `authorized_at`, `authorized_status`, `deleted_at`, `created_by`, `updated_by`, `deleted_by`, `authorized_by`) VALUES
(1, 'C01', 'KPNO', 1, '2025-01-24 10:37:40', '2025-01-24 10:37:40', NULL, NULL, NULL, NULL, NULL, NULL, NULL);
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

View File

@@ -0,0 +1,38 @@
-- phpMyAdmin SQL Dump
-- version 5.2.2
-- https://www.phpmyadmin.net/
--
-- Host: db
-- Generation Time: Jan 30, 2025 at 03:00 AM
-- Server version: 9.2.0
-- PHP Version: 8.2.27
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: myadk
--
--
-- Dumping data for table currencies
--
INSERT INTO currencies (id, code, name, decimal_places, status, created_at, updated_at, authorized_at, authorized_status, deleted_at, created_by, updated_by, deleted_by, authorized_by) VALUES
(1, 'IDR', 'Rupiah', 2, 1, '2025-01-28 04:43:22', '2025-01-28 04:43:22', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
(2, 'MYR', 'Ringgit', 2, 1, '2025-01-28 04:43:36', '2025-01-28 04:43:36', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
(3, 'SAR', 'Riyadh', 2, 1, '2025-01-28 04:43:53', '2025-01-28 04:43:53', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
(4, 'VND', 'Dong', 2, 1, '2025-01-28 04:44:19', '2025-01-28 04:44:19', NULL, NULL, NULL, NULL, NULL, NULL, NULL),
(5, 'THB', 'Bath', 2, 1, '2025-01-28 04:44:38', '2025-01-28 04:44:38', NULL, NULL, NULL, NULL, NULL, NULL, NULL);
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

View File

@@ -0,0 +1,46 @@
-- phpMyAdmin SQL Dump
-- version 5.2.2
-- https://www.phpmyadmin.net/
--
-- Host: db
-- Generation Time: Jan 30, 2025 at 03:26 AM
-- Server version: 9.2.0
-- PHP Version: 8.2.27
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: myadk
--
--
-- Dumping data for table holiday_calendars
--
INSERT INTO holiday_calendars (id, date, description, type, created_at, updated_at, deleted_at, created_by, updated_by, deleted_by) VALUES
(1, '2025-01-27', 'Isra Mi\'raj', 'national_holiday', '2025-01-24 10:32:13', '2025-01-24 10:32:13', NULL, NULL, NULL, NULL),
(2, '2025-01-28', 'Cuti Bersama Tahun Baru Imlek', 'collective_leave', '2025-01-24 10:33:03', '2025-01-24 10:33:03', NULL, NULL, NULL, NULL),
(3, '2025-01-29', 'Tahun Baru Imlek', 'national_holiday', '2025-01-24 10:33:15', '2025-01-24 10:33:15', NULL, NULL, NULL, NULL),
(4, '2025-03-28', 'Cuti Bersama Hari Raya Nyepi', 'collective_leave', '2025-01-30 03:18:04', '2025-01-30 03:18:27', NULL, NULL, NULL, NULL),
(5, '2025-03-29', 'Hari Raya Nyepi', 'national_holiday', '2025-01-30 03:18:48', '2025-01-30 03:18:48', NULL, NULL, NULL, NULL),
(6, '2025-03-31', 'Hari Raya Idul Fitri', 'national_holiday', '2025-01-30 03:19:56', '2025-01-30 03:19:56', NULL, NULL, NULL, NULL),
(7, '2025-04-01', 'Hari Raya Idul Fitri', 'national_holiday', '2025-01-30 03:20:12', '2025-01-30 03:20:12', NULL, NULL, NULL, NULL),
(8, '2025-04-02', 'Cuti Bersama Hari Raya Idul Fitri', 'collective_leave', '2025-01-30 03:21:27', '2025-01-30 03:21:27', NULL, NULL, NULL, NULL),
(9, '2025-04-03', 'Cuti Bersama Hari Raya Idul Fitri', 'collective_leave', '2025-01-30 03:21:53', '2025-01-30 03:21:53', NULL, NULL, NULL, NULL),
(10, '2025-04-04', 'Cuti Bersama Hari Raya Idul Fitri', 'collective_leave', '2025-01-30 03:22:30', '2025-01-30 03:22:30', NULL, NULL, NULL, NULL),
(11, '2025-04-07', 'Cuti Bersama Hari Raya Idul Fitri', 'collective_leave', '2025-01-30 03:23:07', '2025-01-30 03:23:07', NULL, NULL, NULL, NULL),
(12, '2025-04-18', 'Wafat Yesus Kristus', 'national_holiday', '2025-01-30 03:25:04', '2025-01-30 03:25:04', NULL, NULL, NULL, NULL),
(13, '2025-04-20', 'Kebangkitan Yesus Kristus', 'national_holiday', '2025-01-30 03:25:52', '2025-01-30 03:25:52', NULL, NULL, NULL, NULL);
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

View File

@@ -8,10 +8,7 @@
"providers": [
"Modules\\Basicdata\\Providers\\BasicdataServiceProvider"
],
"files": [
"app/Helpers/Currency.php",
"app/Helpers/HolidayCalendar.php"
],
"files": [],
"menu": {
"main": [],
"master": [

View File

@@ -46,40 +46,10 @@
@enderror
</div>
</div>
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">
Parent Branch
</label>
<div class="flex flex-wrap items-baseline w-full">
<select class="input @error('parent_id') border-danger bg-danger-light @enderror" name="parent_id">
<option value="">-- Select Parent Branch --</option>
@foreach($branches as $parentBranch)
@if(!isset($branch->id) || $parentBranch->id != $branch->id)
<option value="{{ $parentBranch->id }}" {{ (isset($branch->parent_id) && $branch->parent_id == $parentBranch->id) ? 'selected' : '' }}>
{{ $parentBranch->code }} - {{ $parentBranch->name }}
</option>
@endif
@endforeach
</select>
@error('parent_id')
<em class="alert text-danger text-sm">{{ $message }}</em>
@enderror
</div>
</div>
<div class="flex justify-end">
@if(isset($branch->id))
@can('basic-data.update')
<button type="submit" class="btn btn-primary">
Save
</button>
@endcan
@else
@can('basic-data.create')
<button type="submit" class="btn btn-primary">
Save
</button>
@endcan
@endif
</div>
</div>
</div>

View File

@@ -12,28 +12,16 @@
Daftar Cabang
</h3>
<div class="flex flex-wrap gap-2 lg:gap-5">
<div class="flex gap-2 lg:gap-5">
<div class="flex">
<label class="input input-sm"> <i class="ki-filled ki-magnifier"> </i>
<input placeholder="Search Branch" id="search" type="text" value="">
</label>
<select class="select select-sm" id="parent-filter" data-datatable-filter-column="parent_id">
<option value="">All Parent Branches</option>
@foreach(\Modules\Basicdata\Models\Branch::orderBy('name')->get() as $branch)
<option value="{{ $branch->id }}">{{ $branch->name }}</option>
@endforeach
</select>
</div>
<div class="flex flex-wrap gap-2 lg:gap-5">
<div class="flex flex-wrap gap-2.5">
<div class="h-[24px] border border-r-gray-200"></div>
@can('basic-data.export')
<a id="export-btn" class="btn btn-sm btn-light" href="{{ route('basicdata.branch.export') }}"> Export to Excel </a>
@endcan
@can('basic-data.create')
<a class="btn btn-sm btn-light" href="{{ route('basicdata.branch.export') }}"> Export to Excel </a>
<a class="btn btn-sm btn-primary" href="{{ route('basicdata.branch.create') }}"> Tambah Cabang </a>
@endcan
@can('basic-data.delete')
<button class="btn btn-sm btn-danger hidden" id="deleteSelected" onclick="deleteSelectedRows()">Delete Selected</button>
@endcan
</div>
</div>
</div>
@@ -53,14 +41,6 @@
<span class="sort"> <span class="sort-label"> Cabang </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[250px]" data-datatable-column="name">
<span class="sort"> <span class="sort-label"> Cabang Induk</span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[250px]" data-datatable-column="address">
<span class="sort"> <span class="sort-label"> Address</span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[50px] text-center" data-datatable-column="actions">Action</th>
</tr>
</thead>
@@ -104,7 +84,7 @@
$.ajax(`basic-data/cabang/${data}`, {
type: 'DELETE'
}).then((response) => {
swal.fire('Deleted!', 'Branch has been deleted.', 'success').then(() => {
swal.fire('Deleted!', 'User has been deleted.', 'success').then(() => {
window.location.reload();
});
}).catch((error) => {
@@ -159,9 +139,7 @@
<script type="module">
const element = document.querySelector('#branch-table');
const searchInput = document.getElementById('search');
const parentFilter = document.getElementById('parent-filter');
const deleteSelectedButton = document.getElementById('deleteSelected');
const exportBtn = document.getElementById('export-btn');
const apiUrl = element.getAttribute('data-api-url');
const dataTableOptions = {
@@ -184,92 +162,29 @@
name: {
title: 'Cabang',
},
parent_id: {
title: 'Cabang Induk',
},
address: {
title: 'Address',
},
actions: {
title: 'Status',
render: (item, data) => {
let html = `<div class="flex flex-nowrap justify-center">`;
@can('basic-data.update')
html += `<a class="btn btn-sm btn-icon btn-clear btn-info" href="basic-data/cabang/${data.id}/edit">
return `<div class="flex flex-nowrap justify-center">
<a class="btn btn-sm btn-icon btn-clear btn-info" href="basic-data/cabang/${data.id}/edit">
<i class="ki-outline ki-notepad-edit"></i>
</a>`;
@endcan
@can('basic-data.delete')
html += `<a onclick="deleteData(${data.id})" class="delete btn btn-sm btn-icon btn-clear btn-danger">
</a>
<a onclick="deleteData(${data.id})" class="delete btn btn-sm btn-icon btn-clear btn-danger">
<i class="ki-outline ki-trash"></i>
</a>`;
@endcan
html += `</div>`;
return html;
</a>
</div>`;
},
}
},
};
let dataTable = new KTDataTable(element, dataTableOptions);
// Function to apply all filters
function applyFilters() {
let filters = {};
if (searchInput.value) {
filters.search = searchInput.value;
}
if (parentFilter.value) {
filters.parent_id = parentFilter.value;
}
dataTable.search(filters);
}
// Update export URL with filters
function updateExportUrl() {
let url = new URL(exportBtn.href);
if (parentFilter.value) {
url.searchParams.set('parent_id', parentFilter.value);
} else {
url.searchParams.delete('parent_id');
}
if (searchInput.value) {
url.searchParams.set('search', searchInput.value);
} else {
url.searchParams.delete('search');
}
exportBtn.href = url.toString();
}
// Custom search functionality
searchInput.addEventListener('input', function () {
dataTable.goPage(1);
// Update export URL with search parameter
applyFilters();
updateExportUrl();
const searchValue = this.value.trim();
dataTable.search(searchValue, true);
});
// Parent branch filter functionality
parentFilter.addEventListener('change', function() {
updateExportUrl();
applyFilters();
});
exportBtn.addEventListener('click', function() {
updateExportUrl();
applyFilters();
})
function updateDeleteButtonVisibility() {
const selectedCheckboxes = document.querySelectorAll('input[data-datatable-row-check="true"]:checked');
if (selectedCheckboxes.length > 0) {
@@ -298,3 +213,4 @@
window.dataTable = dataTable;
</script>
@endpush

View File

@@ -6,12 +6,14 @@
@section('content')
<div class="w-full grid gap-5 lg:gap-7.5 mx-auto">
<form method="POST" action="{{ isset($currency->id) ? route('basicdata.currency.update', $currency->id) : route('basicdata.currency.store') }}">
@csrf
@if(isset($currency->id))
<form action="{{ route('basicdata.currency.update', $currency->id) }}" method="POST">
<input type="hidden" name="id" value="{{ $currency->id }}">
@method('PUT')
@else
<form method="POST" action="{{ route('basicdata.currency.store') }}">
@endif
@csrf
<div class="card pb-2.5">
<div class="card-header" id="basic_settings">
<h3 class="card-title">
@@ -44,17 +46,6 @@
@enderror
</div>
</div>
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">
Symbol
</label>
<div class="flex flex-wrap items-baseline w-full">
<input class="input @error('symbol') border-danger bg-danger-light @enderror" type="text" name="symbol" value="{{ $currency->symbol ?? '' }}">
@error('symbol')
<em class="alert text-danger text-sm">{{ $message }}</em>
@enderror
</div>
</div>
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">
Decimal Places
@@ -67,19 +58,9 @@
</div>
</div>
<div class="flex justify-end">
@if(isset($currency->id))
@can('basic-data.update')
<button type="submit" class="btn btn-primary">
Save
</button>
@endcan
@else
@can('basic-data.create')
<button type="submit" class="btn btn-primary">
Save
</button>
@endcan
@endif
</div>
</div>
</div>

View File

@@ -19,15 +19,9 @@
</div>
<div class="flex flex-wrap gap-2.5">
<div class="h-[24px] border border-r-gray-200"></div>
@can('basic-data.export')
<a id="export-btn" class="btn btn-sm btn-light" href="{{ route('basicdata.currency.export') }}"> Export to Excel </a>
@endcan
@can('basic-data.create')
<a class="btn btn-sm btn-light" href="{{ route('basicdata.currency.export') }}"> Export to Excel </a>
<a class="btn btn-sm btn-primary" href="{{ route('basicdata.currency.create') }}"> Tambah Mata Uang </a>
@endcan
@can('basic-data.delete')
<button class="btn btn-sm btn-danger hidden" id="deleteSelected" onclick="deleteSelectedRows()">Delete Selected</button>
@endcan
</div>
</div>
</div>
@@ -47,10 +41,6 @@
<span class="sort"> <span class="sort-label"> Mata Uang </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="symbol">
<span class="sort"> <span class="sort-label"> Symbol </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[50px]" data-datatable-column="decimal_places">
<span class="sort"> <span class="sort-label"> Decimal Places </span>
<span class="sort-icon"> </span> </span>
@@ -152,7 +142,6 @@
<script type="module">
const element = document.querySelector('#currency-table');
const searchInput = document.getElementById('search');
const exportBtn = document.getElementById('export-btn');
const deleteSelectedButton = document.getElementById('deleteSelected');
const apiUrl = element.getAttribute('data-api-url');
@@ -176,59 +165,30 @@
name: {
title: 'Mata Uang',
},
symbol: {
title: 'Symbol',
},
decimal_places: {
title: 'Decimal Places',
},
actions: {
title: 'Status',
render: (item, data) => {
let html = `<div class="flex flex-nowrap justify-center">`;
@can('basic-data.update')
html += `<a class="btn btn-sm btn-icon btn-clear btn-info" href="basic-data/mata-uang/${data.id}/edit">
return `<div class="flex flex-nowrap justify-center">
<a class="btn btn-sm btn-icon btn-clear btn-info" href="basic-data/mata-uang/${data.id}/edit">
<i class="ki-outline ki-notepad-edit"></i>
</a>`;
@endcan
@can('basic-data.delete')
html += `<a onclick="deleteData(${data.id})" class="delete btn btn-sm btn-icon btn-clear btn-danger">
</a>
<a onclick="deleteData(${data.id})" class="delete btn btn-sm btn-icon btn-clear btn-danger">
<i class="ki-outline ki-trash"></i>
</a>`;
@endcan
html += `</div>`;
return html;
</a>
</div>`;
},
}
},
};
let dataTable = new KTDataTable(element, dataTableOptions);
// Update export URL with filters
function updateExportUrl() {
let url = new URL(exportBtn.href);
if (searchInput.value) {
url.searchParams.set('search', searchInput.value);
} else {
url.searchParams.delete('search');
}
exportBtn.href = url.toString();
}
// Custom search functionality
searchInput.addEventListener('input', function () {
const searchValue = this.value.trim();
dataTable.goPage(1);
dataTable.search(searchValue, true);
// Update export URL with search parameter
updateExportUrl();
});
function updateDeleteButtonVisibility() {
@@ -259,3 +219,4 @@
window.dataTable = dataTable;
</script>
@endpush

View File

@@ -6,12 +6,14 @@
@section('content')
<div class="w-full grid gap-5 lg:gap-7.5 mx-auto">
<form method="POST" action="{{ isset($holiday->id) ? route('basicdata.holidaycalendar.update', $holiday->id) : route('basicdata.holidaycalendar.store') }}">
@csrf
@if(isset($holiday->id))
<form action="{{ route('basicdata.holidaycalendar.update', $holiday->id) }}" method="POST">
<input type="hidden" name="id" value="{{ $holiday->id }}">
@method('PUT')
@else
<form method="POST" action="{{ route('basicdata.holidaycalendar.store') }}">
@endif
@csrf
<div class="card pb-2.5">
<div class="card-header" id="basic_settings">
<h3 class="card-title">
@@ -63,19 +65,9 @@
</div>
</div>
<div class="flex justify-end">
@if(isset($holiday->id))
@can('basic-data.update')
<button type="submit" class="btn btn-primary">
Save
</button>
@endcan
@else
@can('basic-data.create')
<button type="submit" class="btn btn-primary">
Save
</button>
@endcan
@endif
</div>
</div>
</div>

View File

@@ -19,15 +19,9 @@
</div>
<div class="flex flex-wrap gap-2.5">
<div class="h-[24px] border border-r-gray-200"></div>
@can('basic-data.export')
<a id="export-btn" class="btn btn-sm btn-light" href="{{ route('basicdata.holidaycalendar.export') }}"> Export to Excel </a>
@endcan
@can('basic-data.create')
<a class="btn btn-sm btn-light" href="{{ route('basicdata.holidaycalendar.export') }}"> Export to Excel </a>
<a class="btn btn-sm btn-primary" href="{{ route('basicdata.holidaycalendar.create') }}"> Tambah Hari Libur </a>
@endcan
@can('basic-data.delete')
<button class="btn btn-sm btn-danger hidden" id="deleteSelected" onclick="deleteSelectedRows()">Delete Selected</button>
@endcan
</div>
</div>
</div>
@@ -149,7 +143,6 @@
const element = document.querySelector('#holiday-calendar-table');
const searchInput = document.getElementById('search');
const deleteSelectedButton = document.getElementById('deleteSelected');
const exportBtn = document.getElementById('export-btn');
const apiUrl = element.getAttribute('data-api-url');
const dataTableOptions = {
@@ -184,50 +177,24 @@
actions: {
title: 'Action',
render: (item, data) => {
let html = `<div class="flex flex-nowrap justify-center">`;
@can('basic-data.update')
html += `<a class="btn btn-sm btn-icon btn-clear btn-info" href="basic-data/holidaycalendar/${data.id}/edit">
return `<div class="flex flex-nowrap justify-center">
<a class="btn btn-sm btn-icon btn-clear btn-info" href="basic-data/holidaycalendar/${data.id}/edit">
<i class="ki-outline ki-notepad-edit"></i>
</a>`;
@endcan
@can('basic-data.delete')
html += `<a onclick="deleteData(${data.id})" class="delete btn btn-sm btn-icon btn-clear btn-danger">
</a>
<a onclick="deleteData(${data.id})" class="delete btn btn-sm btn-icon btn-clear btn-danger">
<i class="ki-outline ki-trash"></i>
</a>`;
@endcan
html += `</div>`;
return html;
</a>
</div>`;
},
}
},
};
let dataTable = new KTDataTable(element, dataTableOptions);
// Update export URL with filters
function updateExportUrl() {
let url = new URL(exportBtn.href);
if (searchInput.value) {
url.searchParams.set('search', searchInput.value);
} else {
url.searchParams.delete('search');
}
exportBtn.href = url.toString();
}
// Custom search functionality
searchInput.addEventListener('input', function () {
const searchValue = this.value.trim();
dataTable.goPage(1);
dataTable.search(searchValue, true);
// Update export URL with search parameter
updateExportUrl();
});
function updateDeleteButtonVisibility() {

View File

@@ -19,6 +19,7 @@
Route::middleware(['auth'])->group(function () {
Route::name('basicdata.')->prefix('basic-data')->group(function () {
Route::name('currency.')->prefix('mata-uang')->group(function () {
Route::get('restore/{id}', [CurrencyController::class, 'restore'])->name('restore');
Route::get('datatables', [CurrencyController::class, 'dataForDatatables'])->name('datatables');
Route::get('export', [CurrencyController::class, 'export'])->name('export');
Route::post('delete-multiple', [CurrencyController::class, 'deleteMultiple'])->name('deleteMultiple');
@@ -38,6 +39,7 @@
Route::name('branch.')->prefix('cabang')->group(function () {
Route::get('restore/{id}', [BranchController::class, 'restore'])->name('restore');
Route::get('datatables', [BranchController::class, 'dataForDatatables'])->name('datatables');
Route::get('export', [BranchController::class, 'export'])->name('export');
Route::post('delete-multiple', [BranchController::class, 'deleteMultiple'])->name('deleteMultiple');
@@ -56,10 +58,15 @@
]);
Route::group(['prefix' => 'holidaycalendar', 'as' => 'holidaycalendar.'], function () {
Route::get('/', [HolidayCalendarController::class, 'index'])->name('index');
Route::get('/create', [HolidayCalendarController::class, 'create'])->name('create');
Route::post('/', [HolidayCalendarController::class, 'store'])->name('store');
Route::get('/{id}/edit', [HolidayCalendarController::class, 'edit'])->name('edit');
Route::put('/{id}', [HolidayCalendarController::class, 'update'])->name('update');
Route::delete('/{id}', [HolidayCalendarController::class, 'destroy'])->name('destroy');
Route::get('/datatables', [HolidayCalendarController::class, 'dataForDatatables'])->name('datatables');
Route::get('/export', [HolidayCalendarController::class, 'export'])->name('export');
Route::post('delete-multiple', [HolidayCalendarController::class, 'deleteMultiple'])->name('deleteMultiple');
});
Route::resource('holidaycalendar', HolidayCalendarController::class);
});
});

View File

@@ -1,478 +0,0 @@
<?php
namespace Modules\Basicdata\Tests\Feature;
use Tests\TestCase;
use Modules\Basicdata\Models\Branch;
use Modules\Usermanagement\Models\User;
use Modules\Usermanagement\Models\Role;
use Modules\Usermanagement\Models\Permission;
use Modules\Usermanagement\Models\PermissionGroup;
use Illuminate\Foundation\Testing\RefreshDatabase;
use PHPUnit\Framework\Attributes\Test;
class BranchControllerTest extends TestCase
{
use RefreshDatabase;
protected $user;
protected $adminRole;
protected $branch;
protected $parentBranch;
protected function setUp(): void
{
parent::setUp();
// Create permission group first
$permissionGroup = PermissionGroup::create([
'name' => 'basic-data',
'slug' => 'basic-data'
]);
// Create permissions with permission_group_id
Permission::create([
'name' => 'basic-data.create',
'guard_name' => 'web',
'permission_group_id' => $permissionGroup->id
]);
Permission::create([
'name' => 'basic-data.read',
'guard_name' => 'web',
'permission_group_id' => $permissionGroup->id
]);
Permission::create([
'name' => 'basic-data.update',
'guard_name' => 'web',
'permission_group_id' => $permissionGroup->id
]);
Permission::create([
'name' => 'basic-data.delete',
'guard_name' => 'web',
'permission_group_id' => $permissionGroup->id
]);
Permission::create([
'name' => 'basic-data.export',
'guard_name' => 'web',
'permission_group_id' => $permissionGroup->id
]);
// Create admin role with all permissions
$this->adminRole = Role::create(['name' => 'admin', 'guard_name' => 'web']);
$this->adminRole->givePermissionTo(Permission::all());
// Create a user with admin role
$this->user = User::factory()->create();
$this->user->assignRole($this->adminRole);
// Create a parent branch for testing
$this->parentBranch = Branch::create([
'code' => 'PARENT',
'name' => 'Parent Branch'
]);
// Create a branch for testing
$this->branch = Branch::create([
'code' => 'TEST',
'name' => 'Test Branch'
]);
}
#[Test]
public function user_with_permission_can_view_branches_index()
{
$response = $this->actingAs($this->user)
->get(route('basicdata.branch.index'));
$response->assertStatus(200);
}
#[Test]
public function user_without_permission_cannot_view_branches_index()
{
// Create a role without permissions
$role = Role::create(['name' => 'viewer', 'guard_name' => 'web']);
// Create a user with the viewer role
$user = User::factory()->create();
$user->assignRole($role);
$response = $this->actingAs($user)
->get(route('basicdata.branch.index'));
$response->assertStatus(403);
}
#[Test]
public function user_with_permission_can_create_branch()
{
$response = $this->actingAs($this->user)
->get(route('basicdata.branch.create'));
$response->assertStatus(200);
}
#[Test]
public function user_without_permission_cannot_create_branch()
{
// Create a role with only read permission
$role = Role::create(['name' => 'reader', 'guard_name' => 'web']);
$role->givePermissionTo('basic-data.read');
// Create a user with the reader role
$user = User::factory()->create();
$user->assignRole($role);
$response = $this->actingAs($user)
->get(route('basicdata.branch.create'));
$response->assertStatus(403);
}
#[Test]
public function user_with_permission_can_store_branch()
{
$branchData = [
'code' => 'NEW',
'name' => 'New Branch'
];
$response = $this->actingAs($this->user)
->post(route('basicdata.branch.store'), $branchData);
$response->assertRedirect(route('basicdata.branch.index'));
$this->assertDatabaseHas('branches', $branchData);
}
#[Test]
public function user_with_permission_can_store_branch_with_parent()
{
$branchData = [
'code' => 'CHILD',
'name' => 'Child Branch',
'parent_id' => $this->parentBranch->id
];
$response = $this->actingAs($this->user)
->post(route('basicdata.branch.store'), $branchData);
$response->assertRedirect(route('basicdata.branch.index'));
$this->assertDatabaseHas('branches', $branchData);
// Verify the relationship
$childBranch = Branch::where('code', 'CHILD')->first();
$this->assertEquals($this->parentBranch->id, $childBranch->parent_id);
$this->assertTrue($childBranch->parent()->exists());
$this->assertEquals($this->parentBranch->id, $childBranch->parent->id);
}
#[Test]
public function user_without_permission_cannot_store_branch()
{
// Create a role with only read permission
$role = Role::create(['name' => 'reader', 'guard_name' => 'web']);
$role->givePermissionTo('basic-data.read');
// Create a user with the reader role
$user = User::factory()->create();
$user->assignRole($role);
$branchData = [
'code' => 'NEW',
'name' => 'New Branch'
];
$response = $this->actingAs($user)
->post(route('basicdata.branch.store'), $branchData);
$response->assertStatus(403);
$this->assertDatabaseMissing('branches', $branchData);
}
#[Test]
public function user_with_permission_can_edit_branch()
{
$response = $this->actingAs($this->user)
->get(route('basicdata.branch.edit', $this->branch->id));
$response->assertStatus(200);
}
#[Test]
public function user_without_permission_cannot_edit_branch()
{
// Create a role with only read permission
$role = Role::create(['name' => 'reader', 'guard_name' => 'web']);
$role->givePermissionTo('basic-data.read');
// Create a user with the reader role
$user = User::factory()->create();
$user->assignRole($role);
$response = $this->actingAs($user)
->get(route('basicdata.branch.edit', $this->branch->id));
$response->assertStatus(403);
}
#[Test]
public function user_with_permission_can_update_branch()
{
$updatedData = [
'code' => 'UPD',
'name' => 'Updated Branch'
];
$response = $this->actingAs($this->user)
->put(route('basicdata.branch.update', $this->branch->id), $updatedData);
$response->assertRedirect(route('basicdata.branch.index'));
$this->assertDatabaseHas('branches', $updatedData);
}
#[Test]
public function user_with_permission_can_update_branch_with_parent()
{
$updatedData = [
'code' => 'UPD',
'name' => 'Updated Branch',
'parent_id' => $this->parentBranch->id
];
$response = $this->actingAs($this->user)
->put(route('basicdata.branch.update', $this->branch->id), $updatedData);
$response->assertRedirect(route('basicdata.branch.index'));
$this->assertDatabaseHas('branches', $updatedData);
// Verify the relationship
$this->branch->refresh();
$this->assertEquals($this->parentBranch->id, $this->branch->parent_id);
$this->assertTrue($this->branch->parent()->exists());
$this->assertEquals($this->parentBranch->id, $this->branch->parent->id);
}
#[Test]
public function user_with_permission_can_remove_parent_from_branch()
{
// First set a parent
$this->branch->update(['parent_id' => $this->parentBranch->id]);
$this->assertEquals($this->parentBranch->id, $this->branch->parent_id);
// Then remove it
$updatedData = [
'code' => 'UPD',
'name' => 'Updated Branch',
'parent_id' => null
];
$response = $this->actingAs($this->user)
->put(route('basicdata.branch.update', $this->branch->id), $updatedData);
$response->assertRedirect(route('basicdata.branch.index'));
// Verify the relationship is removed
$this->branch->refresh();
$this->assertNull($this->branch->parent_id);
$this->assertFalse($this->branch->parent()->exists());
}
#[Test]
public function user_without_permission_cannot_update_branch()
{
// Create a role with only read permission
$role = Role::create(['name' => 'reader', 'guard_name' => 'web']);
$role->givePermissionTo('basic-data.read');
// Create a user with the reader role
$user = User::factory()->create();
$user->assignRole($role);
$updatedData = [
'code' => 'UPD',
'name' => 'Updated Branch'
];
$response = $this->actingAs($user)
->put(route('basicdata.branch.update', $this->branch->id), $updatedData);
$response->assertStatus(403);
$this->assertDatabaseMissing('branches', $updatedData);
}
#[Test]
public function user_with_permission_can_delete_branch()
{
$response = $this->actingAs($this->user)
->delete(route('basicdata.branch.destroy', $this->branch->id));
$response->assertJson(['success' => true]);
$this->assertSoftDeleted($this->branch);
}
#[Test]
public function user_without_permission_cannot_delete_branch()
{
// Create a role with only read permission
$role = Role::create(['name' => 'reader', 'guard_name' => 'web']);
$role->givePermissionTo('basic-data.read');
// Create a user with the reader role
$user = User::factory()->create();
$user->assignRole($role);
$response = $this->actingAs($user)
->delete(route('basicdata.branch.destroy', $this->branch->id));
$response->assertStatus(403);
$this->assertDatabaseHas('branches', ['id' => $this->branch->id, 'deleted_at' => null]);
}
#[Test]
public function user_with_permission_can_export_branches()
{
$response = $this->actingAs($this->user)
->get(route('basicdata.branch.export'));
$response->assertStatus(200);
}
#[Test]
public function user_without_permission_cannot_export_branches()
{
// Create a role with only read permission
$role = Role::create(['name' => 'reader', 'guard_name' => 'web']);
$role->givePermissionTo('basic-data.read');
// Create a user with the reader role
$user = User::factory()->create();
$user->assignRole($role);
$response = $this->actingAs($user)
->get(route('basicdata.branch.export'));
$response->assertStatus(403);
}
#[Test]
public function branch_cannot_be_its_own_parent()
{
$updatedData = [
'code' => 'SELF',
'name' => 'Self-Referencing Branch',
'parent_id' => $this->branch->id
];
$response = $this->actingAs($this->user)
->from(route('basicdata.branch.edit', $this->branch->id)) // Tambahkan ini untuk mengetahui URL sebelumnya
->put(route('basicdata.branch.update', $this->branch->id), $updatedData);
// Pastikan redirect back dengan kesalahan
$response->assertRedirect();
$response->assertSessionHasErrors('parent_id');
// Periksa bahwa parent_id tidak berubah
$this->branch->refresh();
$this->assertNull($this->branch->parent_id);
}
#[Test]
public function cannot_delete_branch_with_children()
{
// Create a child branch
$childBranch = Branch::create([
'code' => 'CHILD',
'name' => 'Child Branch',
'parent_id' => $this->parentBranch->id
]);
// Verify the relationship is established
$this->assertEquals($this->parentBranch->id, $childBranch->parent_id);
$this->assertTrue($this->parentBranch->children()->exists());
// Try to delete the parent branch
$response = $this->actingAs($this->user)
->delete(route('basicdata.branch.destroy', $this->parentBranch->id));
// Assert that the request fails with the expected message
$response->assertJson([
'success' => false,
'message' => 'Cabang dengan anak cabang tidak dapat dihapus.'
]);
$response->assertStatus(422); // Unprocessable Entity
// Verify the parent branch was not deleted
$this->assertDatabaseHas('branches', [
'id' => $this->parentBranch->id,
'deleted_at' => null
]);
}
#[Test]
public function cannot_delete_multiple_branches_if_any_has_children()
{
// Create a child branch
$childBranch = Branch::create([
'code' => 'CHILD',
'name' => 'Child Branch',
'parent_id' => $this->parentBranch->id
]);
// Create another branch without children
$anotherBranch = Branch::create([
'code' => 'ANOTHER',
'name' => 'Another Branch'
]);
// Try to delete both the parent branch and another branch
$response = $this->actingAs($this->user)
->post(route('basicdata.branch.deleteMultiple'), [
'ids' => [$this->parentBranch->id, $anotherBranch->id]
]);
// Assert that the request fails with the expected message
$response->assertJson([
'success' => false,
'message' => 'Beberapa cabang memiliki anak cabang dan tidak dapat dihapus.'
]);
$response->assertStatus(422); // Unprocessable Entity
// Verify neither branch was deleted
$this->assertDatabaseHas('branches', [
'id' => $this->parentBranch->id,
'deleted_at' => null
]);
$this->assertDatabaseHas('branches', [
'id' => $anotherBranch->id,
'deleted_at' => null
]);
}
#[Test]
public function branch_has_correct_children_relationship()
{
// Create a child branch
$childBranch = Branch::create([
'code' => 'CHILD1',
'name' => 'Child Branch 1',
'parent_id' => $this->parentBranch->id
]);
// Create another child branch
$anotherChildBranch = Branch::create([
'code' => 'CHILD2',
'name' => 'Child Branch 2',
'parent_id' => $this->parentBranch->id
]);
// Refresh parent branch
$this->parentBranch->refresh();
// Assert that the parent has two children
$this->assertEquals(2, $this->parentBranch->children()->count());
// Assert that the children collection contains the two child branches
$this->assertTrue($this->parentBranch->children->contains($childBranch));
$this->assertTrue($this->parentBranch->children->contains($anotherChildBranch));
}
}

View File

@@ -1,320 +0,0 @@
<?php
namespace Modules\Basicdata\Tests\Feature;
use Tests\TestCase;
use Modules\Basicdata\Models\Currency;
use Modules\Usermanagement\Models\User;
use Modules\Usermanagement\Models\Role;
use Modules\Usermanagement\Models\Permission;
use Modules\Usermanagement\Models\PermissionGroup;
use Illuminate\Foundation\Testing\RefreshDatabase;
use PHPUnit\Framework\Attributes\Test;
class CurrencyControllerTest extends TestCase
{
use RefreshDatabase;
protected $user;
protected $adminRole;
protected $currency;
protected function setUp(): void
{
parent::setUp();
// Create permission group first
$permissionGroup = PermissionGroup::create([
'name' => 'basic-data',
'slug' => 'basic-data'
]);
// Create permissions with permission_group_id
Permission::create([
'name' => 'basic-data.create',
'guard_name' => 'web',
'permission_group_id' => $permissionGroup->id
]);
Permission::create([
'name' => 'basic-data.read',
'guard_name' => 'web',
'permission_group_id' => $permissionGroup->id
]);
Permission::create([
'name' => 'basic-data.update',
'guard_name' => 'web',
'permission_group_id' => $permissionGroup->id
]);
Permission::create([
'name' => 'basic-data.delete',
'guard_name' => 'web',
'permission_group_id' => $permissionGroup->id
]);
Permission::create([
'name' => 'basic-data.export',
'guard_name' => 'web',
'permission_group_id' => $permissionGroup->id
]);
// Create admin role with all permissions
$this->adminRole = Role::create(['name' => 'admin', 'guard_name' => 'web']);
$this->adminRole->givePermissionTo(Permission::all());
// Create a user with admin role
$this->user = User::factory()->create();
$this->user->assignRole($this->adminRole);
// Create a currency for testing
$this->currency = Currency::create([
'code' => 'USD',
'name' => 'US Dollar',
'symbol' => '$',
'decimal_places' => 2,
'created_by' => null,
'updated_by' => null,
'deleted_by' => null,
'authorized_by' => null
]);
}
#[Test]
public function user_with_permission_can_view_currencies_index()
{
$response = $this->actingAs($this->user)
->get(route('basicdata.currency.index'));
$response->assertStatus(200);
}
#[Test]
public function user_without_permission_cannot_view_currencies_index()
{
// Create a role without permissions
$role = Role::create(['name' => 'viewer', 'guard_name' => 'web']);
// Create a user with the viewer role
$user = User::factory()->create();
$user->assignRole($role);
$response = $this->actingAs($user)
->get(route('basicdata.currency.index'));
$response->assertStatus(403);
}
#[Test]
public function user_with_permission_can_create_currency()
{
$response = $this->actingAs($this->user)
->get(route('basicdata.currency.create'));
$response->assertStatus(200);
}
#[Test]
public function user_without_permission_cannot_create_currency()
{
// Create a role with only read permission
$role = Role::create(['name' => 'reader', 'guard_name' => 'web']);
$role->givePermissionTo('basic-data.read');
// Create a user with the reader role
$user = User::factory()->create();
$user->assignRole($role);
$response = $this->actingAs($user)
->get(route('basicdata.currency.create'));
$response->assertStatus(403);
}
#[Test]
public function user_with_permission_can_store_currency()
{
$currencyData = [
'code' => 'EUR',
'name' => 'Euro',
'symbol' => '€',
'decimal_places' => 2
];
$response = $this->actingAs($this->user)
->post(route('basicdata.currency.store'), $currencyData);
$response->assertRedirect(route('basicdata.currency.index'));
// Only check the fields we're explicitly setting
$this->assertDatabaseHas('currencies', [
'code' => 'EUR',
'name' => 'Euro',
'symbol' => '€',
'decimal_places' => 2
]);
}
#[Test]
public function user_without_permission_cannot_store_currency()
{
// Create a role with only read permission
$role = Role::create(['name' => 'reader', 'guard_name' => 'web']);
$role->givePermissionTo('basic-data.read');
// Create a user with the reader role
$user = User::factory()->create();
$user->assignRole($role);
$currencyData = [
'code' => 'EUR',
'name' => 'Euro',
'symbol' => '€',
'decimal_places' => 2
];
$response = $this->actingAs($user)
->post(route('basicdata.currency.store'), $currencyData);
$response->assertStatus(403);
$this->assertDatabaseMissing('currencies', [
'code' => 'EUR',
'name' => 'Euro'
]);
}
#[Test]
public function user_with_permission_can_edit_currency()
{
$response = $this->actingAs($this->user)
->get(route('basicdata.currency.edit', $this->currency->id));
$response->assertStatus(200);
}
#[Test]
public function user_without_permission_cannot_edit_currency()
{
// Create a role with only read permission
$role = Role::create(['name' => 'reader', 'guard_name' => 'web']);
$role->givePermissionTo('basic-data.read');
// Create a user with the reader role
$user = User::factory()->create();
$user->assignRole($role);
$response = $this->actingAs($user)
->get(route('basicdata.currency.edit', $this->currency->id));
$response->assertStatus(403);
}
#[Test]
public function user_with_permission_can_update_currency()
{
$updatedData = [
'id' => $this->currency->id, // Include the ID in the request
'code' => 'GBP',
'name' => 'British Pound',
'symbol' => '£',
'decimal_places' => 2
];
$response = $this->actingAs($this->user)
->put(route('basicdata.currency.update', $this->currency->id), $updatedData);
$response->assertRedirect(route('basicdata.currency.index'));
// Only check the fields we're explicitly setting
$this->assertDatabaseHas('currencies', [
'id' => $this->currency->id,
'code' => 'GBP',
'name' => 'British Pound',
'symbol' => '£',
'decimal_places' => 2
]);
}
#[Test]
public function user_without_permission_cannot_update_currency()
{
// Create a role with only read permission
$role = Role::create(['name' => 'reader', 'guard_name' => 'web']);
$role->givePermissionTo('basic-data.read');
// Create a user with the reader role
$user = User::factory()->create();
$user->assignRole($role);
$updatedData = [
'id' => $this->currency->id, // Include the ID in the request
'code' => 'GBP',
'name' => 'British Pound',
'symbol' => '£',
'decimal_places' => 2
];
$response = $this->actingAs($user)
->put(route('basicdata.currency.update', $this->currency->id), $updatedData);
$response->assertStatus(403);
// Verify the currency wasn't updated - check that it still has the original values
$this->assertDatabaseHas('currencies', [
'id' => $this->currency->id,
'code' => 'USD', // Original value
'name' => 'US Dollar' // Original value
]);
}
#[Test]
public function user_with_permission_can_delete_currency()
{
$response = $this->actingAs($this->user)
->delete(route('basicdata.currency.destroy', $this->currency->id));
$response->assertJson(['success' => true]);
$this->assertSoftDeleted($this->currency);
}
#[Test]
public function user_without_permission_cannot_delete_currency()
{
// Create a role with only read permission
$role = Role::create(['name' => 'reader', 'guard_name' => 'web']);
$role->givePermissionTo('basic-data.read');
// Create a user with the reader role
$user = User::factory()->create();
$user->assignRole($role);
$response = $this->actingAs($user)
->delete(route('basicdata.currency.destroy', $this->currency->id));
$response->assertStatus(403);
$this->assertDatabaseHas('currencies', ['id' => $this->currency->id, 'deleted_at' => null]);
}
#[Test]
public function user_with_permission_can_export_currencies()
{
$response = $this->actingAs($this->user)
->get(route('basicdata.currency.export'));
$response->assertStatus(200);
}
#[Test]
public function user_without_permission_cannot_export_currencies()
{
// Create a role with only read permission
$role = Role::create(['name' => 'reader', 'guard_name' => 'web']);
$role->givePermissionTo('basic-data.read');
// Create a user with the reader role
$user = User::factory()->create();
$user->assignRole($role);
$response = $this->actingAs($user)
->get(route('basicdata.currency.export'));
$response->assertStatus(403);
}
}

View File

@@ -1,285 +0,0 @@
<?php
namespace Modules\Basicdata\Tests\Feature;
use Tests\TestCase;
use Modules\Basicdata\Models\HolidayCalendar;
use Modules\Usermanagement\Models\User;
use Modules\Usermanagement\Models\Role;
use Modules\Usermanagement\Models\Permission;
use Modules\Usermanagement\Models\PermissionGroup;
use Illuminate\Foundation\Testing\RefreshDatabase;
use PHPUnit\Framework\Attributes\Test;
class HolidayCalendarControllerTest extends TestCase
{
use RefreshDatabase;
protected $user;
protected $adminRole;
protected $holiday;
protected function setUp(): void
{
parent::setUp();
// Create permission group first
$permissionGroup = PermissionGroup::create([
'name' => 'basic-data',
'slug' => 'basic-data'
]);
// Create permissions with permission_group_id
Permission::create([
'name' => 'basic-data.create',
'guard_name' => 'web',
'permission_group_id' => $permissionGroup->id
]);
Permission::create([
'name' => 'basic-data.read',
'guard_name' => 'web',
'permission_group_id' => $permissionGroup->id
]);
Permission::create([
'name' => 'basic-data.update',
'guard_name' => 'web',
'permission_group_id' => $permissionGroup->id
]);
Permission::create([
'name' => 'basic-data.delete',
'guard_name' => 'web',
'permission_group_id' => $permissionGroup->id
]);
Permission::create([
'name' => 'basic-data.export',
'guard_name' => 'web',
'permission_group_id' => $permissionGroup->id
]);
// Create admin role with all permissions
$this->adminRole = Role::create(['name' => 'admin', 'guard_name' => 'web']);
$this->adminRole->givePermissionTo(Permission::all());
// Create a user with admin role
$this->user = User::factory()->create();
$this->user->assignRole($this->adminRole);
// Create a holiday calendar for testing
$this->holiday = HolidayCalendar::create([
'date' => '2023-01-01',
'description' => 'New Year',
'type' => 'national_holiday'
]);
}
#[Test]
public function user_with_permission_can_view_holidays_index()
{
$response = $this->actingAs($this->user)
->get(route('basicdata.holidaycalendar.index'));
$response->assertStatus(200);
}
#[Test]
public function user_without_permission_cannot_view_holidays_index()
{
// Create a role without permissions
$role = Role::create(['name' => 'viewer', 'guard_name' => 'web']);
// Create a user with the viewer role
$user = User::factory()->create();
$user->assignRole($role);
$response = $this->actingAs($user)
->get(route('basicdata.holidaycalendar.index'));
$response->assertStatus(403);
}
#[Test]
public function user_with_permission_can_create_holiday()
{
$response = $this->actingAs($this->user)
->get(route('basicdata.holidaycalendar.create'));
$response->assertStatus(200);
}
#[Test]
public function user_without_permission_cannot_create_holiday()
{
// Create a role with only read permission
$role = Role::create(['name' => 'reader', 'guard_name' => 'web']);
$role->givePermissionTo('basic-data.read');
// Create a user with the reader role
$user = User::factory()->create();
$user->assignRole($role);
$response = $this->actingAs($user)
->get(route('basicdata.holidaycalendar.create'));
$response->assertStatus(403);
}
#[Test]
public function user_with_permission_can_store_holiday()
{
$holidayData = [
'date' => '2023-12-25',
'description' => 'Christmas',
'type' => 'national_holiday'
];
$response = $this->actingAs($this->user)
->post(route('basicdata.holidaycalendar.store'), $holidayData);
$response->assertRedirect(route('basicdata.holidaycalendar.index'));
$this->assertDatabaseHas('holiday_calendars', $holidayData);
}
#[Test]
public function user_without_permission_cannot_store_holiday()
{
// Create a role with only read permission
$role = Role::create(['name' => 'reader', 'guard_name' => 'web']);
$role->givePermissionTo('basic-data.read');
// Create a user with the reader role
$user = User::factory()->create();
$user->assignRole($role);
$holidayData = [
'date' => '2023-12-25',
'description' => 'Christmas',
'type' => 'national_holiday'
];
$response = $this->actingAs($user)
->post(route('basicdata.holidaycalendar.store'), $holidayData);
$response->assertStatus(403);
$this->assertDatabaseMissing('holiday_calendars', $holidayData);
}
#[Test]
public function user_with_permission_can_edit_holiday()
{
$response = $this->actingAs($this->user)
->get(route('basicdata.holidaycalendar.edit', $this->holiday->id));
$response->assertStatus(200);
}
#[Test]
public function user_without_permission_cannot_edit_holiday()
{
// Create a role with only read permission
$role = Role::create(['name' => 'reader', 'guard_name' => 'web']);
$role->givePermissionTo('basic-data.read');
// Create a user with the reader role
$user = User::factory()->create();
$user->assignRole($role);
$response = $this->actingAs($user)
->get(route('basicdata.holidaycalendar.edit', $this->holiday->id));
$response->assertStatus(403);
}
#[Test]
public function user_with_permission_can_update_holiday()
{
$updatedData = [
'date' => '2023-01-01',
'description' => 'New Year Updated',
'type' => 'collective_leave'
];
$response = $this->actingAs($this->user)
->put(route('basicdata.holidaycalendar.update', $this->holiday->id), $updatedData);
$response->assertRedirect(route('basicdata.holidaycalendar.index'));
$this->assertDatabaseHas('holiday_calendars', $updatedData);
}
#[Test]
public function user_without_permission_cannot_update_holiday()
{
// Create a role with only read permission
$role = Role::create(['name' => 'reader', 'guard_name' => 'web']);
$role->givePermissionTo('basic-data.read');
// Create a user with the reader role
$user = User::factory()->create();
$user->assignRole($role);
$updatedData = [
'date' => '2023-01-01',
'description' => 'New Year Updated',
'type' => 'collective_leave'
];
$response = $this->actingAs($user)
->put(route('basicdata.holidaycalendar.update', $this->holiday->id), $updatedData);
$response->assertStatus(403);
$this->assertDatabaseMissing('holiday_calendars', $updatedData);
}
#[Test]
public function user_with_permission_can_delete_holiday()
{
$response = $this->actingAs($this->user)
->delete(route('basicdata.holidaycalendar.destroy', $this->holiday->id));
$response->assertRedirect(route('basicdata.holidaycalendar.index'));
$this->assertSoftDeleted($this->holiday);
}
#[Test]
public function user_without_permission_cannot_delete_holiday()
{
// Create a role with only read permission
$role = Role::create(['name' => 'reader', 'guard_name' => 'web']);
$role->givePermissionTo('basic-data.read');
// Create a user with the reader role
$user = User::factory()->create();
$user->assignRole($role);
$response = $this->actingAs($user)
->delete(route('basicdata.holidaycalendar.destroy', $this->holiday->id));
$response->assertStatus(403);
$this->assertDatabaseHas('holiday_calendars', ['id' => $this->holiday->id, 'deleted_at' => null]);
}
#[Test]
public function user_with_permission_can_export_holidays()
{
$response = $this->actingAs($this->user)
->get(route('basicdata.holidaycalendar.export'));
$response->assertStatus(200);
}
#[Test]
public function user_without_permission_cannot_export_holidays()
{
// Create a role with only read permission
$role = Role::create(['name' => 'reader', 'guard_name' => 'web']);
$role->givePermissionTo('basic-data.read');
// Create a user with the reader role
$user = User::factory()->create();
$user->assignRole($role);
$response = $this->actingAs($user)
->get(route('basicdata.holidaycalendar.export'));
$response->assertStatus(403);
}
}