diff --git a/TODO.md b/TODO.md index 829af7f..d27214a 100644 --- a/TODO.md +++ b/TODO.md @@ -2,12 +2,12 @@ ## Front +- [x] mengubah metode pembayaran deposit dengan daftar bank seperti deposit dan tampil logo bank - [ ] tampilan keranjang jadi lebih seperti tokped dengan metode pembayaran deposit atau hutang jika tersedia -- [ ] tampilan transaksi deposit, hutang (mitra wbb), dan poin jadi satu tampilan -- [ ] mengubah metode pembayaran deposit dengan daftar bank seperti deposit dan tampil logo bank +- [x] tampilan transaksi deposit, hutang (mitra wbb), dan poin jadi satu tampilan - [ ] tambah metode topup deposit dengan setor tunai kantor wbb -- [ ] tambah screen untuk daftar setor tunai kantor wbb -- [ ] halaman untuk menampilkan level customer +- [x] tambah screen untuk daftar setor tunai kantor wbb +- [x] halaman untuk menampilkan level customer - [ ] expired time 2jam di deposit manual maupun kantor wbb - [ ] ubah username dan password di detail transaksi dengan kode voucher saja - [ ] [BUG] pembelian voucher lebih dari 1 mendapat kode yang sama diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/Admin/AccountController.php similarity index 97% rename from app/Http/Controllers/AccountController.php rename to app/Http/Controllers/Admin/AccountController.php index 821c100..ffe293c 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/Admin/AccountController.php @@ -1,7 +1,8 @@ file('logo'); $file->store('uploads', 'public'); - + Account::create([ 'name' => $request->name, 'bank_name' => $request->bank_name, diff --git a/app/Http/Controllers/BannerController.php b/app/Http/Controllers/Admin/BannerController.php similarity index 96% rename from app/Http/Controllers/BannerController.php rename to app/Http/Controllers/Admin/BannerController.php index afb3471..632fe3f 100644 --- a/app/Http/Controllers/BannerController.php +++ b/app/Http/Controllers/Admin/BannerController.php @@ -1,7 +1,8 @@ where('credit', 0) ->orderBy('is_valid', 'desc') ->orderBy('updated_at', 'desc'); @@ -50,9 +51,14 @@ class DepositController extends Controller ], ]); + if ($request->status == DepositHistory::STATUS_REJECT) { + $request->validate(['reject_reason' => 'required|string']); + } + DB::beginTransaction(); $deposit->update([ 'is_valid' => $request->status, + 'note' => $request->reject_reason ]); if ($request->status == DepositHistory::STATUS_VALID) { $deposit->update_customer_balance(); diff --git a/app/Http/Controllers/DepositLocationController.php b/app/Http/Controllers/Admin/DepositLocationController.php similarity index 88% rename from app/Http/Controllers/DepositLocationController.php rename to app/Http/Controllers/Admin/DepositLocationController.php index 6bb952b..9ebde67 100644 --- a/app/Http/Controllers/DepositLocationController.php +++ b/app/Http/Controllers/Admin/DepositLocationController.php @@ -1,8 +1,10 @@ $request->gmap_url, 'image' => $file->hashName('uploads'), 'description' => $request->description, - 'open_hour' => $request->open_hour, - 'close_hour' => $request->close_hour, + 'open_hour' => GeneralService::parserToHour($request->open_hour), + 'close_hour' => GeneralService::parserToHour($request->close_hour), 'is_active' => $request->is_active, ]); @@ -88,8 +90,8 @@ class DepositLocationController extends Controller 'gmap_url' => $request->gmap_url, 'image' => $location->image, 'description' => $request->description, - 'open_hour' => $request->open_hour, - 'close_hour' => $request->close_hour, + 'open_hour' => GeneralService::parserToHour($request->open_hour), + 'close_hour' => GeneralService::parserToHour($request->close_hour), 'is_active' => $request->is_active, ]); diff --git a/app/Http/Controllers/GeneralController.php b/app/Http/Controllers/Admin/GeneralController.php similarity index 98% rename from app/Http/Controllers/GeneralController.php rename to app/Http/Controllers/Admin/GeneralController.php index 6017890..44eeff1 100644 --- a/app/Http/Controllers/GeneralController.php +++ b/app/Http/Controllers/Admin/GeneralController.php @@ -1,7 +1,8 @@ validate([ 'OPEN_WEBSITE_NAME' => 'required|string', 'SHARE_TEXT' => 'required|string', + 'ENABLE_CASH_DEPOSIT' => 'required|in:0,1', + 'ENABLE_MANUAL_TRANSFER' => 'required|in:0,1', + 'MAX_MANUAL_TRANSFER_TIMEOUT' => 'required|numeric', + 'MANUAL_TRANSFER_OPEN_HOUR' => 'required|string', + 'MANUAL_TRANSFER_CLOSE_HOUR' => 'required|string', + 'MAX_POINT_EXPIRED' => 'required|numeric', ]); DB::beginTransaction(); - foreach ($request->input() as $key => $value) { + $inputs = $request->except(['MANUAL_TRANSFER_OPEN_HOUR', 'MANUAL_TRANSFER_CLOSE_HOUR']); + foreach ($inputs as $key => $value) { Setting::where('key', $key)->update(['value' => $value]); } + $hours = $request->only(['MANUAL_TRANSFER_OPEN_HOUR', 'MANUAL_TRANSFER_CLOSE_HOUR']); + foreach ($hours as $key => $value) { + Setting::where('key', $key)->update(['value' => GeneralService::parserToHour($value)]); + } + Cache::flush(); DB::commit(); diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/Admin/UserController.php similarity index 95% rename from app/Http/Controllers/UserController.php rename to app/Http/Controllers/Admin/UserController.php index be274ba..ce85b01 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/Admin/UserController.php @@ -1,7 +1,8 @@ validate([ 'name' => 'required|string|max:255', - 'email' => 'required|email|unique:users,email,'.$user->id, + 'email' => 'required|email|unique:users,email,' . $user->id, 'password' => 'nullable|string|max:255', 'username' => 'required|alpha_dash|unique:users,username,' . $user->id, 'phone_wa' => 'required|string', diff --git a/app/Http/Controllers/VerificationController.php b/app/Http/Controllers/Admin/VerificationController.php similarity index 95% rename from app/Http/Controllers/VerificationController.php rename to app/Http/Controllers/Admin/VerificationController.php index ec41881..4a5959b 100644 --- a/app/Http/Controllers/VerificationController.php +++ b/app/Http/Controllers/Admin/VerificationController.php @@ -1,7 +1,8 @@ remove('carts'); - return redirect()->route('transactions.show', $sale) + return redirect()->route('transactions.sale.show', $sale) ->with('message', ['type' => 'success', 'message' => 'pembelian berhasil']); } } diff --git a/app/Http/Controllers/Customer/DepositController.php b/app/Http/Controllers/Customer/DepositController.php index 512dd52..cc51f1d 100644 --- a/app/Http/Controllers/Customer/DepositController.php +++ b/app/Http/Controllers/Customer/DepositController.php @@ -20,7 +20,8 @@ class DepositController extends Controller { $histories = DepositHistory::where('customer_id', auth()->id()) ->orderBy('updated_at', 'desc') - ->orderBy('is_valid', 'desc'); + ->orderBy('is_valid', 'desc') + ->where('type', DepositHistory::TYPE_DEPOSIT); return inertia('Deposit/Index', [ 'histories' => $histories->paginate(20), @@ -40,7 +41,7 @@ class DepositController extends Controller 'amount' => 'required|numeric|min:10000', 'payment' => [ 'required', - Rule::in([Setting::PAYMENT_MANUAL, Setting::PAYMENT_MIDTRANS]), + Rule::in([Setting::PAYMENT_MANUAL, Setting::PAYMENT_MIDTRANS, Setting::PAYMENT_CASH_DEPOSIT]), ], ]); @@ -48,11 +49,11 @@ class DepositController extends Controller $deposit = DepositHistory::make([ 'customer_id' => auth()->id(), 'debit' => $request->amount, - 'description' => 'Top Up #'.Str::random(5), 'payment_channel' => $request->payment, + 'type' => DepositHistory::TYPE_DEPOSIT, ]); - if ($request->payment == Setting::PAYMENT_MANUAL) { + if (in_array($request->payment, [Setting::PAYMENT_MANUAL, Setting::PAYMENT_CASH_DEPOSIT])) { $deposit->is_valid = DepositHistory::STATUS_WAIT_UPLOAD; $deposit->save(); } @@ -65,17 +66,18 @@ class DepositController extends Controller $deposit->update(['payment_token' => $token]); } + $deposit->create_notification(); DB::commit(); - return redirect()->route('customer.deposit.show', ['deposit' => $deposit->id, 'direct' => 'true']); + return redirect()->route('transactions.deposit.show', ['deposit' => $deposit->id, 'direct' => 'true']); } public function show(Request $request, DepositHistory $deposit) { return inertia('Deposit/Detail', [ - 'deposit' => $deposit, + 'deposit' => $deposit->load(['account']), 'accounts' => Account::get(), 'midtrans_client_key' => Setting::getByKey('MIDTRANS_CLIENT_KEY'), 'is_production' => app()->isProduction(), @@ -131,7 +133,7 @@ class DepositController extends Controller DB::commit(); - return redirect()->route('customer.deposit.show', ['deposit' => $deposit->id]); + return redirect()->route('transactions.deposit.show', ['deposit' => $deposit->id]); } public function mindtrans_notification(Request $request) diff --git a/app/Http/Controllers/Customer/DepositLocationController.php b/app/Http/Controllers/Customer/DepositLocationController.php new file mode 100644 index 0000000..a200a3b --- /dev/null +++ b/app/Http/Controllers/Customer/DepositLocationController.php @@ -0,0 +1,17 @@ + DepositLocation::orderBy('updated_at', 'desc')->paginate(20), + ]); + } +} diff --git a/app/Http/Controllers/Customer/PoinController.php b/app/Http/Controllers/Customer/PoinController.php index 060fdff..f0a4820 100644 --- a/app/Http/Controllers/Customer/PoinController.php +++ b/app/Http/Controllers/Customer/PoinController.php @@ -3,7 +3,7 @@ namespace App\Http\Controllers\Customer; use App\Http\Controllers\Controller; -use App\Models\poinHistory; +use App\Models\PoinHistory; class PoinController extends Controller { @@ -17,7 +17,7 @@ class PoinController extends Controller ]); } - public function show(poinHistory $poin) + public function show(PoinHistory $poin) { return inertia('Poin/Detail', [ 'poin' => $poin, diff --git a/app/Http/Controllers/Customer/PoinExchangeController.php b/app/Http/Controllers/Customer/PoinExchangeController.php index a342c99..26c7895 100644 --- a/app/Http/Controllers/Customer/PoinExchangeController.php +++ b/app/Http/Controllers/Customer/PoinExchangeController.php @@ -84,7 +84,7 @@ class PoinExchangeController extends Controller $poin->update_customer_balance(); DB::commit(); - return redirect()->route('transactions.show', $sale) + return redirect()->route('transactions.sale.show', $sale) ->with('message', ['type' => 'success', 'message' => 'penukaran berhasil']); } } diff --git a/app/Models/DepositHistory.php b/app/Models/DepositHistory.php index 738bdba..081a466 100644 --- a/app/Models/DepositHistory.php +++ b/app/Models/DepositHistory.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Services\GeneralService; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Support\Carbon; @@ -19,10 +20,15 @@ class DepositHistory extends Model const STATUS_REJECT = 5; + const TYPE_DEPOSIT = 0; + + const TYPE_REPAYMENT = 1; + protected $fillable = [ 'debit', 'credit', 'description', + 'note', 'customer_id', 'related_type', 'related_id', @@ -34,6 +40,7 @@ class DepositHistory extends Model 'payment_response', 'payment_channel', 'payment_type', + 'type', ]; protected $appends = [ @@ -44,6 +51,17 @@ class DepositHistory extends Model 'image_prove_url', ]; + protected static function booted(): void + { + static::creating(function (DepositHistory $model) { + if ($model->description == null) { + if ($model->type == DepositHistory::TYPE_DEPOSIT) { + $model->description = GeneralService::generateDepositCode(); + } + } + }); + } + public function status(): Attribute { return Attribute::make(get: function () { @@ -109,6 +127,17 @@ class DepositHistory extends Model public function create_notification() { if ($this->payment_channel == Setting::PAYMENT_MANUAL) { + $status = ''; + if ($this->is_valid == self::STATUS_WAIT_APPROVE) { + $status = ' (bukti bayar di upload, membutuhkan konfirmasi)'; + } + Notification::create([ + 'entity_type' => User::class, + 'description' => $this->customer->fullname . ' melakukan deposit transfer manual sebesar : ' . $this->amount . $status, + ]); + } + + if ($this->payment_channel == Setting::PAYMENT_CASH_DEPOSIT) { $status = ''; if ($this->is_valid == self::STATUS_WAIT_APPROVE) { $status = ' (bukti bayar di upload, membutuhkan konfirmasi)'; diff --git a/app/Models/DepositLocation.php b/app/Models/DepositLocation.php index 126a2c9..46957d6 100644 --- a/app/Models/DepositLocation.php +++ b/app/Models/DepositLocation.php @@ -33,22 +33,7 @@ class DepositLocation extends Model protected function operationalHour(): Attribute { return Attribute::make(get: function () { - return $this->parser($this->open_hour) . ' - ' . $this->parser($this->close_hour); + return $this->open_hour . ' - ' . $this->close_hour; }); } - - private function parser($time) - { - $r = ''; - $time = explode(':', $time); - foreach ($time as $t) { - if ($t == 0) { - $r .= '00:'; - } else { - $r .= $t . ':'; - } - } - - return substr($r, 0, -1); - } } diff --git a/app/Models/Setting.php b/app/Models/Setting.php index e7a021a..b65c5d2 100644 --- a/app/Models/Setting.php +++ b/app/Models/Setting.php @@ -19,6 +19,8 @@ class Setting extends Model const PAYMENT_PAYLATER = 'PAYLATER'; + const PAYMENT_CASH_DEPOSIT = 'CASH_DEPOSIT'; + protected $fillable = [ 'key', 'value', diff --git a/app/Models/Voucher.php b/app/Models/Voucher.php index 7801412..71b33bf 100644 --- a/app/Models/Voucher.php +++ b/app/Models/Voucher.php @@ -37,7 +37,7 @@ class Voucher extends Model { if (count(self::$instance) == 0) { self::$instance = [ - 'customer' => Customer::find(auth()->id()) + 'customer' => Customer::find(auth()->guard('customer')->id()) ]; } diff --git a/app/Services/GeneralService.php b/app/Services/GeneralService.php index c176a1f..fcac01d 100644 --- a/app/Services/GeneralService.php +++ b/app/Services/GeneralService.php @@ -2,7 +2,11 @@ namespace App\Services; +use App\Models\DepositHistory; +use App\Models\DepositLocation; use App\Models\Setting; +use Illuminate\Support\Carbon; +use Illuminate\Support\Str; class GeneralService { @@ -55,13 +59,51 @@ class GeneralService public static function getEnablePayment() { - $payment = [ - ['name' => Setting::PAYMENT_MANUAL, 'logo' => null, 'display_name' => 'Transfer Manual'], - ]; + $payment = []; $midtrans_enable = Setting::getByKey('MIDTRANS_ENABLED'); if ($midtrans_enable == 1) { - $payment[] = ['name' => Setting::PAYMENT_MIDTRANS, 'logo' => asset(Setting::getByKey('MIDTRANS_LOGO'))]; + $payment[] = [ + 'name' => Setting::PAYMENT_MIDTRANS, + 'logo' => asset(Setting::getByKey('MIDTRANS_LOGO')), + 'display_name' => 'Midtrans', + 'admin_fee' => Setting::getByKey('MIDTRANS_ADMIN_FEE'), + ]; + } + + $enable = Setting::getByKey('ENABLE_MANUAL_TRANSFER'); + if ($enable == 1) { + $openHour = Carbon::createFromFormat('H:i', Setting::getByKey('MANUAL_TRANSFER_OPEN_HOUR')); + $closeHour = Carbon::createFromFormat('H:i', Setting::getByKey('MANUAL_TRANSFER_CLOSE_HOUR')); + if (now()->between($openHour, $closeHour)) { + $payment[] = [ + 'name' => Setting::PAYMENT_MANUAL, + 'logo' => null, + 'display_name' => 'Transfer Manual', + 'admin_fee' => 0 + ]; + } + } + + $enable = Setting::getByKey('ENABLE_CASH_DEPOSIT'); + if ($enable == 1) { + $locations = DepositLocation::all(); // 30 partner + $enables = []; + + foreach ($locations as $location) { + $openHour = Carbon::createFromFormat('H:i', $location->open_hour); + $closeHour = Carbon::createFromFormat('H:i', $location->close_hour); + $enables[] = now()->between($openHour, $closeHour); + } + + if (in_array(true, $enables)) { + $payment[] = [ + 'name' => Setting::PAYMENT_CASH_DEPOSIT, + 'logo' => null, + 'display_name' => 'Setor Tunai di Kantor WBB', + 'admin_fee' => 0 + ]; + } } return $payment; @@ -73,4 +115,40 @@ class GeneralService // poin // paylater } + + public static function parserToHour($time) + { + $r = ''; + $time = explode(':', $time); + foreach ($time as $t) { //00 : 00 + if ($t < 10) { + $r .= '0' . (int) $t . ':'; + } else { + $r .= $t . ':'; + } + } + + return substr($r, 0, -1); + } + + public static function generateDepositCode() + { + $code = DepositHistory::where('type', DepositHistory::TYPE_DEPOSIT)->count() + 1; + + return 'Invoice #DSR' . now()->format('dmy') . GeneralService::formatNumberCode($code); + } + + public static function formatNumberCode($number) + { + if ($number < 10) { + return '000' . $number; + } + if ($number < 100) { + return '00' . $number; + } + if ($number < 1000) { + return '0' . $number; + } + return $number; + } } diff --git a/app/Services/MidtransService.php b/app/Services/MidtransService.php index 4f5df54..849a2e1 100644 --- a/app/Services/MidtransService.php +++ b/app/Services/MidtransService.php @@ -3,6 +3,7 @@ namespace App\Services; use App\Models\DepositHistory; +use App\Models\Setting; use Midtrans\Config; use Midtrans\Snap; @@ -22,17 +23,31 @@ class MidtransService public function getSnapToken() { + $items = [ + [ + 'id' => $this->deposit->id, + 'price' => $this->deposit->debit, + 'quantity' => 1, + 'name' => $this->deposit->description, + ] + ]; + + $adminFee = Setting::getByKey('MIDTRANS_ADMIN_FEE'); + if ($adminFee > 0) { + $items[] = [ + 'id' => 'tambahan_biaya_admin', + 'price' => $adminFee, + 'quantity' => 1, + 'name' => 'tambahan_biaya_admin', + ]; + } + $params = [ 'transaction_details' => [ 'order_id' => $this->deposit->id, 'gross_amount' => $this->deposit->debit, ], - 'item_details' => [[ - 'id' => $this->deposit->id, - 'price' => $this->deposit->debit, - 'quantity' => 1, - 'name' => $this->deposit->description, - ]], + 'item_details' => $items, 'customer_details' => [ 'name' => $this->deposit->customer->fullname, 'email' => $this->deposit->customer->email, @@ -40,7 +55,7 @@ class MidtransService 'address' => $this->deposit->customer->address, ], 'callbacks' => [ - 'finish' => route('customer.deposit.show', ['deposit' => $this->deposit->id]), + 'finish' => route('transactions.deposit.show', ['deposit' => $this->deposit->id]), ], ]; diff --git a/database/migrations/2023_05_24_130646_create_deposit_histories_table.php b/database/migrations/2023_05_24_130646_create_deposit_histories_table.php index 2deb771..0bf3cd3 100644 --- a/database/migrations/2023_05_24_130646_create_deposit_histories_table.php +++ b/database/migrations/2023_05_24_130646_create_deposit_histories_table.php @@ -16,12 +16,14 @@ return new class extends Migration $table->decimal('debit', 20, 2)->default(0); $table->decimal('credit', 20, 2)->default(0); - $table->text('description')->nullable(); + $table->string('description')->nullable(); + $table->text('note')->nullable(); $table->ulid('customer_id')->nullable(); $table->ulid('account_id')->nullable(); $table->string('related_type')->nullable(); $table->string('related_id')->nullable(); $table->smallInteger('is_valid')->default(0); + $table->smallInteger('type')->default(0); $table->string('image_prove')->nullable(); $table->string('payment_channel')->nullable(); $table->string('payment_token')->nullable(); diff --git a/database/seeders/DummySeeder.php b/database/seeders/DummySeeder.php index 9c6f1cd..82b1e6c 100644 --- a/database/seeders/DummySeeder.php +++ b/database/seeders/DummySeeder.php @@ -60,8 +60,9 @@ class DummySeeder extends Seeder public function account() { $banks = [ - ['name' => 'BTPN', 'bank_name' => 'BTPN', 'holder_name' => 'Aji Kamaludin', 'account_number' => '187391738129', 'logo' => 'sample/logo-jenius.png'], - ['name' => 'Jago', 'bank_name' => 'Bank Jago', 'holder_name' => 'Aji Kamaludin', 'account_number' => '718297389172', 'logo' => 'sample/logo-jago.png'], + ['name' => 'BTPN', 'bank_name' => 'BTPN', 'holder_name' => 'Aji Kamaludin', 'account_number' => '187391738129', 'logo' => 'sample/logo-jenius.png', 'admin_fee' => 0], + ['name' => 'Jago', 'bank_name' => 'Bank Jago', 'holder_name' => 'Aji Kamaludin', 'account_number' => '718297389172', 'logo' => 'sample/logo-jago.png', 'admin_fee' => 2500], + ['name' => 'BNI', 'bank_name' => 'Bank Negara Indoneisa', 'holder_name' => 'Aji Kamaludin', 'account_number' => '718297389172', 'logo' => 'sample/logo-bni.png', 'admin_fee' => 6500], ]; foreach ($banks as $bank) { @@ -70,7 +71,8 @@ class DummySeeder extends Seeder 'bank_name' => $bank['bank_name'], 'holder_name' => $bank['holder_name'], 'account_number' => $bank['account_number'], - 'logo' => $bank['logo'] + 'logo' => $bank['logo'], + 'admin_fee' => $bank['admin_fee'] ]); } } diff --git a/database/seeders/InstallationSeed.php b/database/seeders/InstallationSeed.php index f3773c7..46d0a82 100644 --- a/database/seeders/InstallationSeed.php +++ b/database/seeders/InstallationSeed.php @@ -22,8 +22,7 @@ class InstallationSeed extends Seeder $settings = [ // general ['key' => 'OPEN_WEBSITE_NAME', 'value' => 'Welcome to Voucher App', 'type' => 'text'], - ['key' => 'SHARE_TEXT', 'value' => '', 'type' => 'text'], - + ['key' => 'SHARE_TEXT', 'value' => '

Baru Beli Voucher nih

', 'type' => 'text'], // affilate ['key' => 'AFFILATE_ENABLED', 'value' => '0', 'type' => 'checkbox'], @@ -41,9 +40,9 @@ class InstallationSeed extends Seeder ['key' => 'MIDTRANS_ADMIN_FEE', 'value' => '2500', 'type' => 'text'], // deposit - ['key' => 'ENABLE_CASH_DEPOSIT', 'value' => '0', 'type' => 'text'], - ['key' => 'ENABLE_MANUAL_TRANSFER', 'value' => '0', 'type' => 'text'], - ['key' => 'MAX_MANUAL_TRANSFER_TIMEOUT', 'value' => '2', 'type' => 'text'], //dalam jam + ['key' => 'ENABLE_CASH_DEPOSIT', 'value' => '0', 'type' => 'text'], // deposit by location (on/off) + ['key' => 'ENABLE_MANUAL_TRANSFER', 'value' => '0', 'type' => 'text'], // transfer manual (on/off) + ['key' => 'MAX_MANUAL_TRANSFER_TIMEOUT', 'value' => '2', 'type' => 'text'], // dalam jam ['key' => 'MANUAL_TRANSFER_OPEN_HOUR', 'value' => '06:00', 'type' => 'text'], ['key' => 'MANUAL_TRANSFER_CLOSE_HOUR', 'value' => '23:00', 'type' => 'text'], ['key' => 'MAX_POINT_EXPIRED', 'value' => '90', 'type' => 'text'], //dalam hari diff --git a/public/sample/logo-bni.png b/public/sample/logo-bni.png new file mode 100644 index 0000000..1686ee7 Binary files /dev/null and b/public/sample/logo-bni.png differ diff --git a/resources/js/Components/Checkbox.jsx b/resources/js/Components/Checkbox.jsx index a4b3095..cc1031f 100644 --- a/resources/js/Components/Checkbox.jsx +++ b/resources/js/Components/Checkbox.jsx @@ -1,26 +1,35 @@ -import React from "react"; +import React from 'react' -export default function Checkbox({ value, name, onChange, label = '', error, disabled = false }) { +export default function Checkbox({ + value, + name, + onChange, + label = '', + error, + disabled = false, +}) { return ( <>
- + className="w-4 h-4 text-blue-600 bg-gray-100 rounded border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600" + /> {label !== '' && ( )} -
{error && ( -

{error}

+

+ {error} +

)} ) -} \ No newline at end of file +} diff --git a/resources/js/Customer/Cart/Index.jsx b/resources/js/Customer/Cart/Index.jsx index 9a2ef9b..4584cd3 100644 --- a/resources/js/Customer/Cart/Index.jsx +++ b/resources/js/Customer/Cart/Index.jsx @@ -29,7 +29,7 @@ export default function Index({ } const handleTopUp = () => { - router.get(route('customer.deposit.topup')) + router.get(route('transactions.deposit.topup')) } return ( diff --git a/resources/js/Customer/Components/HeaderTrx.jsx b/resources/js/Customer/Components/HeaderTrx.jsx new file mode 100644 index 0000000..2cf7bca --- /dev/null +++ b/resources/js/Customer/Components/HeaderTrx.jsx @@ -0,0 +1,75 @@ +import { usePage, router, Link } from '@inertiajs/react' + +export default function HeaderTrx({ enable = 'deposit' }) { + const { + props: { + auth: { user }, + }, + } = usePage() + return ( + <> +
+
{user.fullname}
+
+
+
+
+ Rp {user.display_deposit} +
+
+
+
+ router.get(route('transactions.deposit.topup')) + } + > + Top Up +
+
+
+
+
+
{user.display_poin} poin
+
+ ( kadaluarsa pada 20 juni 2023 ) +
+
+
+
+
+ + Deposit + + + Pembelian + + + Poin + +
+
+ + ) +} diff --git a/resources/js/Customer/Deposit/Detail.jsx b/resources/js/Customer/Deposit/Detail.jsx index 85368f2..16728df 100644 --- a/resources/js/Customer/Deposit/Detail.jsx +++ b/resources/js/Customer/Deposit/Detail.jsx @@ -1,17 +1,19 @@ import React, { useState, useEffect } from 'react' import { Head, router, useForm, usePage } from '@inertiajs/react' +import { isEmpty } from 'lodash' import { HiChevronLeft, - HiClipboard, HiClipboardDocumentList, + HiOutlineClipboardDocumentCheck, + HiOutlineClipboardDocumentList, } from 'react-icons/hi2' +import { toastSuccess } from '../utils' import CustomerLayout from '@/Layouts/CustomerLayout' -import { formatIDR } from '@/utils' import FormFile from '@/Components/FormFile' -import { isEmpty } from 'lodash' import Alert from '@/Components/Alert' -import { toast } from 'react-toastify' +import { formatIDR } from '@/utils' +import { STATUS_REJECT } from '@/constant' const PayButton = () => { const { @@ -106,6 +108,7 @@ const FormUpload = () => { props: { accounts, deposit, flash }, } = usePage() + const [imageUrl, setImageUrl] = useState(deposit.image_prove_url) const [account, setAccount] = useState(null) const { data, setData, errors, processing, post } = useForm({ account_id: '', @@ -117,6 +120,7 @@ const FormUpload = () => { if (id === '') { setData('account_id', '') setAccount(null) + return } const account = accounts.find((acc) => acc.id === id) setData('account_id', account.id) @@ -124,15 +128,17 @@ const FormUpload = () => { } const handleCopyToClipboard = (text) => { - toast.success('copied to clipboard') - navigator.clipboard.writeText(account.account_number) + toastSuccess('copied to clipboard') + navigator.clipboard.writeText(text) } const handleSubmit = () => { if (processing) { return } - post(route('customer.deposit.update', deposit), { + post(route('transactions.deposit.update', deposit), { + replace: true, + preserveState: true, onSuccess: () => setTimeout( () => router.get(route(route().current(), deposit)), @@ -141,6 +147,31 @@ const FormUpload = () => { }) } + useEffect(() => { + if (deposit.account !== null) { + handleSelectAccount(deposit.account.id) + } + }, [deposit]) + + if (isEmpty(imageUrl) == false) { + return ( +
+
Bukti Transfer
+ bukti transfer +
setImageUrl(null)} + > + Ubah Bukti Transfer +
+
+ ) + } + return (
@@ -149,26 +180,59 @@ const FormUpload = () => { {flash.message.message} -
Bank
- +
Bank
+ + {account !== null ? ( +
+
handleSelectAccount(account.id)} + > +
+ logo bank +
+
+ {account.name} - {account.bank_name} +
+
+
handleSelectAccount('')} + > +
Ubah
+
+
+ ) : ( +
+ {accounts.map((account) => ( +
handleSelectAccount(account.id)} + > +
+ logo bank +
+
+ {account.name} - {account.bank_name} +
+
+ ))} +
+ )}
- {data.account_id !== '' && ( + {account !== null && ( <>
-
-
Silahkan transfer nominal di atas ke
+
{account.bank_name} @@ -189,28 +253,90 @@ const FormUpload = () => { } >
Nomor Rekening :
-
+
{account.account_number}
- +
+
Rincian
+ + + + + + + + + + + + + + handleCopyToClipboard( + +account.admin_fee + + +deposit.debit + ) + } + > + + + + + + +
+ Jumlah Deposit + : + + {deposit.amount} + + +
Biaya Admin: + + {+account.admin_fee === 0 ? ( + 'Gratis' + ) : ( + <> + Rp.{' '} + {formatIDR( + +account.admin_fee + )} + + )} + + +
Total Transfer : + + Rp.{' '} + {formatIDR( + +account.admin_fee + + +deposit.debit + )} + + + +
+
+
Bukti Transfer
+ {isEmpty(data.image_url) == false && ( + bukti transfer + )} +
setData('image', e.target.files[0])} error={errors.image} - preview={ - isEmpty(data.image_url) == false && ( - bukti transfer - ) - } /> +
+ upload gambar dalam ekstensi jpg, png, jpeg +
{ } const ActionSection = ({ deposit }) => { + if (deposit.is_valid === STATUS_REJECT) { + return ( +
+
+
+ {deposit.note} +
+
+
+ ) + } return (
{deposit.payment_channel === 'MIDTRANS' ? ( @@ -244,7 +381,7 @@ export default function Detail({ deposit }) {
{ - router.get(route('customer.deposit.index')) + router.get(route('transactions.deposit.index')) }} > diff --git a/resources/js/Customer/Deposit/Index.jsx b/resources/js/Customer/Deposit/Index.jsx index e816873..4c21529 100644 --- a/resources/js/Customer/Deposit/Index.jsx +++ b/resources/js/Customer/Deposit/Index.jsx @@ -1,7 +1,8 @@ import React, { useState } from 'react' import { Head, router } from '@inertiajs/react' import CustomerLayout from '@/Layouts/CustomerLayout' -import { formatIDR } from '@/utils' +import { HiOutlineQuestionMarkCircle } from 'react-icons/hi2' +import HeaderTrx from '../Components/HeaderTrx' export default function Index({ auth: { user }, @@ -28,31 +29,9 @@ export default function Index({
-
-
{user.fullname}
-
-
-
-
- Saldo -
-
- Rp {user.display_deposit} -
-
-
-
- router.get(route('customer.deposit.topup')) - } - > - Top Up -
-
-
+
-
+
{deposites.map((history) => (
router.get( route( - 'customer.deposit.show', + 'transactions.deposit.show', history.id ) ) @@ -80,7 +59,7 @@ export default function Index({
{+history.is_valid !== 0 && (
{history.status.text}
diff --git a/resources/js/Customer/Deposit/Topup.jsx b/resources/js/Customer/Deposit/Topup.jsx index b56d903..b6a44b9 100644 --- a/resources/js/Customer/Deposit/Topup.jsx +++ b/resources/js/Customer/Deposit/Topup.jsx @@ -1,11 +1,11 @@ import React from 'react' -import { Head, router, useForm } from '@inertiajs/react' -import { HiChevronLeft } from 'react-icons/hi2' +import { Head, Link, router, useForm } from '@inertiajs/react' +import { HiCheck, HiChevronLeft, HiQuestionMarkCircle } from 'react-icons/hi2' +import { formatIDR } from '@/utils' +import { CASH_DEPOSIT } from '@/Customer/utils' import CustomerLayout from '@/Layouts/CustomerLayout' -import FormInput from '@/Components/FormInput' import Alert from '@/Components/Alert' -import { formatIDR } from '@/utils' import FormInputNumeric from '@/Components/FormInputNumeric' export default function Topup({ payments }) { @@ -33,11 +33,21 @@ export default function Topup({ payments }) { }` } + const isActivePaymentAdminFee = (payment) => { + return `text-xs ${ + payment === data.payment ? 'text-white' : 'text-gray-400' + }` + } + + const handleSetPayment = (payment) => { + setData('payment', payment.name) + } + const handleSubmit = () => { if (processing) { return } - post(route('customer.deposit.topup')) + post(route('transactions.deposit.topup')) } return ( @@ -47,7 +57,7 @@ export default function Topup({ payments }) {
{ - router.get(route('customer.deposit.index')) + router.get(route('transactions.deposit.index')) }} > @@ -86,33 +96,78 @@ export default function Topup({ payments }) { )}
+ {payments.length <= 0 && ( + + Sistem pembayaran non-aktif{' '} + + )} {payments.map((payment) => (
setData('payment', payment.name)} > - - {payment.logo === null ? ( -

{payment.display_name}

- ) : ( - +
handleSetPayment(payment)} + > + {payment.name === data.payment ? ( +
+ +
+ ) : ( +
+ )} +
+ {payment.logo === null ? ( +

{payment.display_name}

+ ) : ( + + )} + {+payment.admin_fee !== 0 && ( +

+ biaya admin:{' '} + {formatIDR(payment.admin_fee)} +

+ )} +
+
+ {payment.name === CASH_DEPOSIT && ( + +
Daftar lokasi setor tunai
+
+ ada disini +
+
+ +
+ )}
))}
-
-
- Bayar -
+
+ {payments.length > 0 && ( +
+ Bayar +
+ )}
) diff --git a/resources/js/Customer/DepositLocation/Index.jsx b/resources/js/Customer/DepositLocation/Index.jsx new file mode 100644 index 0000000..85425db --- /dev/null +++ b/resources/js/Customer/DepositLocation/Index.jsx @@ -0,0 +1,104 @@ +import React, { useState } from 'react' +import { Head, router } from '@inertiajs/react' +import CustomerLayout from '@/Layouts/CustomerLayout' +import { HiChevronLeft } from 'react-icons/hi2' +import { BsWhatsapp } from 'react-icons/bs' +import { GrMap } from 'react-icons/gr' + +export default function Index({ locations: { data, next_page_url } }) { + const [locations, setLocations] = useState(data) + + const handleNextPage = () => { + router.get( + next_page_url, + {}, + { + replace: true, + preserveState: true, + only: ['locations'], + onSuccess: (res) => { + setLocations(locations.concat(res.props.locations.data)) + }, + } + ) + } + return ( + + +
+
{ + router.get(route('transactions.deposit.topup')) + }} + > +
+ +
+
+ Lokasi Setor Tunai +
+
+
+ {locations.map((location) => ( +
+ +
+
{location.name}
+ +
+ Alamat : {location.address} +
+
+ Jam Buka :{' '} + + {location.operational_hour} + +
+ +
+
+ ))} + {next_page_url !== null && ( +
+ Load more +
+ )} +
+
+
+ ) +} diff --git a/resources/js/Customer/Index/Partials/BalanceBanner.jsx b/resources/js/Customer/Index/Partials/BalanceBanner.jsx index 7a60dc9..d5a7493 100644 --- a/resources/js/Customer/Index/Partials/BalanceBanner.jsx +++ b/resources/js/Customer/Index/Partials/BalanceBanner.jsx @@ -9,7 +9,9 @@ export default function BalanceBanner({ user }) {
router.get(route('customer.deposit.index'))} + onClick={() => + router.get(route('transactions.deposit.index')) + } >
diff --git a/resources/js/Customer/Paylater/Index.jsx b/resources/js/Customer/Paylater/Index.jsx index 05ac5e0..5dff9fd 100644 --- a/resources/js/Customer/Paylater/Index.jsx +++ b/resources/js/Customer/Paylater/Index.jsx @@ -50,7 +50,9 @@ export default function Index({
- router.get(route('customer.deposit.topup')) + router.get( + route('transactions.deposit.topup') + ) } > Bayar Tagihan diff --git a/resources/js/Customer/Poin/Detail.jsx b/resources/js/Customer/Poin/Detail.jsx index 115e469..361ece9 100644 --- a/resources/js/Customer/Poin/Detail.jsx +++ b/resources/js/Customer/Poin/Detail.jsx @@ -12,7 +12,7 @@ export default function Detail({ poin }) {
{ - router.get(route('customer.poin.index')) + router.get(route('transactions.poin.index')) }} > diff --git a/resources/js/Customer/Poin/Index.jsx b/resources/js/Customer/Poin/Index.jsx index 269f14b..4289b46 100644 --- a/resources/js/Customer/Poin/Index.jsx +++ b/resources/js/Customer/Poin/Index.jsx @@ -1,6 +1,19 @@ import React, { useState } from 'react' import { Head, router } from '@inertiajs/react' import CustomerLayout from '@/Layouts/CustomerLayout' +import HeaderTrx from '../Components/HeaderTrx' + +const EmptyHere = () => { + return ( +
+
Transaksi kosong
+
+ Yuk kumpulkan poin sebanyak banyaknya dengan share link refferal + kamu +
+
+ ) +} export default function Index({ auth: { user }, @@ -27,19 +40,8 @@ export default function Index({
-
-
{user.fullname}
-
-
-
-
- poin -
-
- {user.display_poin} -
-
-
+ + {_poins.length <= 0 && }
{_poins.map((poin) => ( @@ -48,7 +50,7 @@ export default function Index({ className="flex flex-row pb-2 items-center justify-between border-b" onClick={() => router.get( - route('customer.poin.show', poin.id) + route('transactions.poin.show', poin.id) ) } > diff --git a/resources/js/Customer/Profile/Form.jsx b/resources/js/Customer/Profile/Form.jsx index 55e6ffc..388d37c 100644 --- a/resources/js/Customer/Profile/Form.jsx +++ b/resources/js/Customer/Profile/Form.jsx @@ -138,6 +138,12 @@ export default function Index({ auth: { user }, flash }) { label="password confirm" />
+
+
email
+
+ {user.email} +
+
+
- -
- - )} + {+data.is_valid !== STATUS_APPROVE && + +data.is_valid !== STATUS_REJECT && ( + <> +
+
Status
+ + {errors.status && ( +
+ {errors.status} +
+ )} +
+ {+data.status === STATUS_REJECT && ( + + )} +
+ + +
+ + )} ) } diff --git a/resources/js/Pages/DepositHistory/Index.jsx b/resources/js/Pages/DepositHistory/Index.jsx index cf154e4..c78caf8 100644 --- a/resources/js/Pages/DepositHistory/Index.jsx +++ b/resources/js/Pages/DepositHistory/Index.jsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from 'react' -import { router } from '@inertiajs/react' +import { Link, router } from '@inertiajs/react' import { usePrevious } from 'react-use' import { Head } from '@inertiajs/react' import { HiEye } from 'react-icons/hi2' @@ -63,6 +63,12 @@ export default function Index(props) { + + +
+ # + Tanggal - Deskripsi + Status - Status + Approver - {deposit.customer.name} + {deposit.description} - {deposit.amount} + + {deposit.customer.name} + - {deposit.format_created_at} + {deposit.amount} - {deposit.description} + {deposit.format_created_at} {deposit.status.text} + {deposit.editor?.name} + {canUpdate && (
{ @@ -27,11 +45,7 @@ export default function General(props) { } const handleSubmit = () => { - post(route('setting.update'), { - onSuccess: () => { - setTimeout(() => router.get(route(route().current())), 3000) - }, - }) + post(route('setting.update')) } return ( @@ -55,6 +69,7 @@ export default function General(props) { label="Nama Website" error={errors.OPEN_WEBSITE_NAME} /> +
+
+ + + +
+
+ + setData( + 'MANUAL_TRANSFER_OPEN_HOUR', + h + ) + } + label="Jam Buka" + error={errors.MANUAL_TRANSFER_OPEN_HOUR} + /> +
+
-
+
+ + setData( + 'MANUAL_TRANSFER_CLOSE_HOUR', + h + ) + } + label="Jam Tutup" + error={ + errors.MANUAL_TRANSFER_CLOSE_HOUR + } + /> +
+
+ +