3 Commits
temp ... master

Author SHA1 Message Date
9845b01b0e Merge pull request 'feat(Basicdata): Update 'is_dalam_kota' column and add new branches' (#1) from shola into master
Reviewed-on: #1
2025-12-08 17:28:19 +07:00
Sholahuddin Al Ayubi
fec8dc083c feat(Basicdata): Update 'is_dalam_kota' column and add new branches
- Update 'is_dalam_kota' to true for existing branches based on suffix code
- Set 'is_dalam_kota' to false for branches not in the list
- Add new branches (ID0012005 - KORPORASI, ID0010172 - AMBON TUAL MALUKU)
- Seeder is idempotent and can be rerun safely

run this command:
php artisan module:seed Basicdata --class="UpdateBranchesIsDalamKotaSeeder"

php artisan module:seed --class="Modules\\Basicdata\\Database\\Seeders\\UpdateBranchesIsDalamKotaSeeder"
2025-12-08 17:19:12 +07:00
Daeng Deni Mardaeni
4c4a4a33a9 fix(export): tambahkan properti parent_id pada BranchExport
- Menambahkan properti `protected $parent_id` pada kelas **BranchExport**.
- Properti ini digunakan untuk menyimpan ID cabang induk yang akan dipakai sebagai filter saat melakukan ekspor data.
- Memastikan nilai `parent_id` diinisialisasi melalui constructor dan dideklarasikan sebagai properti kelas.
- Perbaikan ini memastikan filter berdasarkan cabang induk berfungsi dengan benar pada proses ekspor.
- Mendukung konsistensi data pada ekspor **Excel/CSV** dengan filter yang akurat.
- Meningkatkan keandalan fitur ekspor cabang dalam modul laporan.
- Mengoptimalkan integrasi antara fitur filter dan proses ekspor.
- Memperbaiki potensi bug yang muncul akibat properti tidak dideklarasikan.
- Menjamin proses ekspor lebih stabil dan sesuai dengan parameter yang diberikan.
2025-09-08 15:12:27 +07:00
6 changed files with 85 additions and 392 deletions

View File

@@ -12,6 +12,7 @@
class BranchExport implements WithColumnFormatting, WithHeadings, FromCollection, WithMapping class BranchExport implements WithColumnFormatting, WithHeadings, FromCollection, WithMapping
{ {
protected $search; protected $search;
protected $parent_id;
public function __construct($search = null, $parent_id = null) public function __construct($search = null, $parent_id = null)
{ {

View File

@@ -1,391 +0,0 @@
<?php
namespace Modules\Basicdata\Http\Controllers;
use App\Http\Controllers\Controller;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Validator;
use Mail;
use Modules\Basicdata\Emails\TestEmail;
use Rawilk\Settings\Facades\Settings;
class SettingController extends Controller
{
/**
* Get the authenticated user.
*
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
protected function getUser()
{
return \Illuminate\Support\Facades\Auth::guard('web')->user();
}
/**
* Display the settings page.
*
* @return \Illuminate\View\View
*/
public function index()
{
// Check if the authenticated user has the required permission to view settings
$user = $this->getUser();
if (is_null($user) || !$user->can('basic-data.read')) {
abort(403, 'Sorry! You are not allowed to view settings.');
}
// Get all settings or group them by category
$emailSettings = [
'mail_from_address' => Settings::get('mail_from_address', config('mail.from.address')),
'mail_from_name' => Settings::get('mail_from_name', config('mail.from.name')),
'mail_host' => Settings::get('mail_host', config('mail.mailers.smtp.host')),
'mail_port' => Settings::get('mail_port', config('mail.mailers.smtp.port')),
'mail_username' => Settings::get('mail_username', config('mail.mailers.smtp.username')),
'mail_encryption' => Settings::get('mail_encryption', config('mail.mailers.smtp.encryption')),
];
$appSettings = [
'app_name' => Settings::get('app_name', config('app.name')),
'app_url' => Settings::get('app_url', config('app.url')),
'app_timezone' => Settings::get('app_timezone', config('app.timezone')),
'app_debug' => Settings::get('app_debug', config('app.debug')),
];
$statementSettings = [
'statement_email_subject' => Settings::get('statement_email_subject', 'Your Account Statement'),
'statement_email_body' => Settings::get('statement_email_body', 'Please find attached your account statement.'),
'statement_footer_text' => Settings::get('statement_footer_text', '© ' . date('Y') . ' Bank. All rights reserved.'),
];
return view('basicdata::settings.index', compact('emailSettings', 'appSettings', 'statementSettings'));
}
/**
* Update the specified settings.
*
* @param \Illuminate\Http\Request $request
*
* @return \Illuminate\Http\RedirectResponse
*/
public function update(Request $request)
{
// Check if the authenticated user has the required permission to update settings
$user = $this->getUser();
if (is_null($user) || !$user->can('basic-data.update')) {
abort(403, 'Sorry! You are not allowed to update settings.');
}
// Validate settings based on category
$category = $request->input('category', 'general');
switch ($category) {
case 'email':
$validator = Validator::make($request->all(), [
'mail_from_address' => 'required|email',
'mail_from_name' => 'required|string|max:255',
'mail_host' => 'required|string|max:255',
'mail_port' => 'required|numeric',
'mail_username' => 'required|string|max:255',
'mail_password' => 'nullable|string',
'mail_encryption' => 'nullable|string|in:tls,ssl,',
]);
break;
case 'app':
$validator = Validator::make($request->all(), [
'app_name' => 'required|string|max:255',
'app_url' => 'required|url',
'app_timezone' => 'required|string|max:255',
'app_debug' => 'required|string|in:true,false',
]);
break;
case 'statement':
$validator = Validator::make($request->all(), [
'statement_email_subject' => 'required|string|max:255',
'statement_email_body' => 'required|string',
'statement_footer_text' => 'required|string',
]);
break;
default:
$validator = Validator::make($request->all(), []);
}
if ($validator->fails()) {
return redirect()->back()
->withErrors($validator)
->withInput();
}
// Save settings
foreach ($request->except(['_token', 'category']) as $key => $value) {
// Special handling for boolean values
if ($key === 'app_debug') {
$value = $value === 'true';
}
// Don't save empty password
if ($key === 'mail_password' && empty($value)) {
continue;
}
// Encrypt password
if ($key === 'mail_password') {
$value = encrypt($value);
}
Settings::set($key, $value);
}
// Update environment configuration
$this->updateEnvironmentConfig($category, $request);
// If mail settings were updated, update the config at runtime
if ($category === 'email') {
config([
'mail.from.address' => $request->input('mail_from_address'),
'mail.from.name' => $request->input('mail_from_name'),
'mail.mailers.smtp.host' => $request->input('mail_host'),
'mail.mailers.smtp.port' => $request->input('mail_port'),
'mail.mailers.smtp.username' => $request->input('mail_username'),
'mail.mailers.smtp.encryption' => $request->input('mail_encryption'),
]);
// If password was updated, update it in the config
if ($request->filled('mail_password')) {
config(['mail.mailers.smtp.password' => decrypt(Settings::get('mail_password'))]);
}
}
// If app settings were updated, update the config at runtime
if ($category === 'app') {
config([
'app.name' => $request->input('app_name'),
'app.url' => $request->input('app_url'),
'app.timezone' => $request->input('app_timezone'),
'app.debug' => $request->input('app_debug') === 'true',
]);
}
return redirect()->back()
->with('success', ucfirst($category) . ' settings updated successfully')
->withFragment('#' . $category);
}
/**
* Update environment configuration in .env file.
*
* @param string $category
* @param \Illuminate\Http\Request $request
*
* @return void
*/
protected function updateEnvironmentConfig($category, Request $request)
{
// Map settings keys to .env keys
$envMappings = [
'app' => [
'app_name' => 'APP_NAME',
'app_url' => 'APP_URL',
'app_timezone' => 'APP_TIMEZONE',
'app_debug' => 'APP_DEBUG',
],
'email' => [
'mail_from_address' => 'MAIL_FROM_ADDRESS',
'mail_from_name' => 'MAIL_FROM_NAME',
'mail_host' => 'MAIL_HOST',
'mail_port' => 'MAIL_PORT',
'mail_username' => 'MAIL_USERNAME',
'mail_encryption' => 'MAIL_ENCRYPTION',
],
];
// Only update .env for app and email settings
if (!isset($envMappings[$category])) {
return;
}
$envFile = base_path('.env');
$envContent = file_get_contents($envFile);
foreach ($envMappings[$category] as $settingKey => $envKey) {
if ($request->has($settingKey)) {
$value = $request->input($settingKey);
// Format value for .env file
if ($settingKey === 'app_debug') {
$value = $value === 'true' ? 'true' : 'false';
} else if (is_string($value) && str_contains($value, ' ')) {
$value = '"' . $value . '"';
}
// Update .env file
if (preg_match("/^{$envKey}=.*/m", $envContent)) {
$envContent = preg_replace("/^{$envKey}=.*/m", "{$envKey}={$value}", $envContent);
} else {
$envContent .= "\n{$envKey}={$value}";
}
}
}
// Handle mail password separately
if ($category === 'email' && $request->filled('mail_password')) {
$value = $request->input('mail_password');
if (preg_match("/^MAIL_PASSWORD=.*/m", $envContent)) {
$envContent = preg_replace("/^MAIL_PASSWORD=.*/m", "MAIL_PASSWORD={$value}", $envContent);
} else {
$envContent .= "\nMAIL_PASSWORD={$value}";
}
}
file_put_contents($envFile, $envContent);
// Clear config cache
Artisan::call('config:clear');
}
/**
* Reset settings to their default values.
*
* @param \Illuminate\Http\Request $request
*
* @return \Illuminate\Http\RedirectResponse
*/
public function reset(Request $request)
{
// Check if the authenticated user has the required permission to update settings
$user = $this->getUser();
if (is_null($user) || !$user->can('basic-data.update')) {
abort(403, 'Sorry! You are not allowed to reset settings.');
}
$category = $request->input('category', 'general');
switch ($category) {
case 'email':
$keys = [
'mail_from_address',
'mail_from_name',
'mail_host',
'mail_port',
'mail_username',
'mail_password',
'mail_encryption'
];
break;
case 'app':
$keys = [
'app_name',
'app_url',
'app_timezone',
'app_debug'
];
break;
case 'statement':
$keys = [
'statement_email_subject',
'statement_email_body',
'statement_footer_text'
];
break;
default:
$keys = [];
}
// Delete settings
foreach ($keys as $key) {
Settings::forget($key);
}
// Reset environment configuration to original values from .env file
$this->resetEnvironmentConfig($category);
return redirect()->back()
->with('success', ucfirst($category) . ' settings have been reset to default values')
->withFragment('#' . $category);
}
/**
* Reset environment configuration to original values from .env file.
*
* @param string $category
*
* @return void
*/
protected function resetEnvironmentConfig($category)
{
// Only reset .env for app and email settings
if (!in_array($category, ['app', 'email'])) {
return;
}
// Clear config cache to reload from .env
Artisan::call('config:clear');
}
/**
* Send a test email.
*
* @param \Illuminate\Http\Request $request
*
* @return \Illuminate\Http\JsonResponse
*/
public function testEmail(Request $request)
{
// Check if the authenticated user has the required permission to update settings
$user = $this->getUser();
if (is_null($user) || !$user->can('basic-data.update')) {
return response()->json([
'success' => false,
'message' => 'Sorry! You are not allowed to test email settings.',
], 403);
}
$validator = Validator::make($request->all(), [
'test_email' => 'required|email',
]);
if ($validator->fails()) {
return response()->json([
'success' => false,
'message' => 'Please enter a valid email address.',
]);
}
try {
// Get current mail settings
$config = [
'from' => [
'address' => Settings::get('mail_from_address', config('mail.from.address')),
'name' => Settings::get('mail_from_name', config('mail.from.name')),
],
'host' => Settings::get('mail_host', config('mail.mailers.smtp.host')),
'port' => Settings::get('mail_port', config('mail.mailers.smtp.port')),
'username' => Settings::get('mail_username', config('mail.mailers.smtp.username')),
'encryption' => Settings::get('mail_encryption', config('mail.mailers.smtp.encryption')),
];
// Get password if it exists
if (Settings::has('mail_password')) {
$config['password'] = decrypt(Settings::get('mail_password'));
} else {
$config['password'] = config('mail.mailers.smtp.password');
}
// Send test email
Mail::mailer('smtp')
->send(new TestEmail($request->input('test_email'), $config));
return response()->json([
'success' => true,
'message' => 'Test email sent successfully! Please check your inbox.',
]);
} catch (Exception $e) {
return response()->json([
'success' => false,
'message' => 'Failed to send test email: ' . $e->getMessage(),
]);
}
}
}

View File

@@ -8,6 +8,7 @@
protected $fillable = [ protected $fillable = [
'code', 'code',
'name', 'name',
'is_dalam_kota',
'address', 'address',
'mnemonic', 'mnemonic',
'customer_company', 'customer_company',

View File

@@ -0,0 +1,27 @@
<?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

@@ -59,7 +59,8 @@
['code' => 'PKR', 'name' => 'Pakistani Rupee', 'symbol' => '₨', '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')->truncate();
DB::table('currencies')->delete();
DB::table('currencies')->insert($currencies); DB::table('currencies')->insert($currencies);
} }
} }

View File

@@ -0,0 +1,54 @@
<?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";
}
}