diff --git a/app/Http/Controllers/Admin/CustomerHistoryController.php b/app/Http/Controllers/Admin/CustomerHistoryController.php index b6e2193..f1a1a2d 100644 --- a/app/Http/Controllers/Admin/CustomerHistoryController.php +++ b/app/Http/Controllers/Admin/CustomerHistoryController.php @@ -15,6 +15,7 @@ class CustomerHistoryController extends Controller { $query = DepositHistory::with(['editor']) ->where('customer_id', $customer->id) + ->where('type', DepositHistory::TYPE_DEPOSIT) ->orderBy('created_at', 'desc'); return inertia('CustomerHistory/DepositHistory', [ diff --git a/app/Http/Controllers/Admin/DepositController.php b/app/Http/Controllers/Admin/DepositController.php index b3670a0..22211ec 100644 --- a/app/Http/Controllers/Admin/DepositController.php +++ b/app/Http/Controllers/Admin/DepositController.php @@ -15,7 +15,8 @@ class DepositController extends Controller public function index(Request $request) { $deposits = DepositHistory::with(['customer', 'account', 'depositLocation', 'editor']) - ->where('credit', 0); + ->where('credit', 0) + ->where('type', DepositHistory::TYPE_DEPOSIT); if ($request->q != '') { $deposits->where(function ($query) use ($request) { @@ -51,16 +52,20 @@ class DepositController extends Controller 'deposit_this_month' => DepositHistory::whereMonth('created_at', now()->month) ->whereYear('created_at', now()->year) ->where('is_valid', DepositHistory::STATUS_VALID) + ->where('type', DepositHistory::TYPE_DEPOSIT) ->sum('debit'), 'deposit_today' => DepositHistory::whereDate('created_at', now()) ->where('is_valid', DepositHistory::STATUS_VALID) + ->where('type', DepositHistory::TYPE_DEPOSIT) ->sum('debit'), 'paylater_this_month' => PaylaterHistory::whereMonth('created_at', now()->month) ->where('is_valid', PaylaterHistory::STATUS_VALID) + ->where('type', DepositHistory::TYPE_DEPOSIT) ->whereYear('created_at', now()->year) ->sum('debit'), 'paylater_today' => PaylaterHistory::whereDate('created_at', now()) ->where('is_valid', PaylaterHistory::STATUS_VALID) + ->where('type', DepositHistory::TYPE_DEPOSIT) ->sum('debit'), ]; diff --git a/app/Http/Controllers/Customer/DepositController.php b/app/Http/Controllers/Customer/DepositController.php index 4bd960f..e26c6a3 100644 --- a/app/Http/Controllers/Customer/DepositController.php +++ b/app/Http/Controllers/Customer/DepositController.php @@ -42,7 +42,7 @@ class DepositController extends Controller public function create(Request $request) { $customer = $request->user('customer'); - if (! $customer->allow_transaction) { + if (!$customer->allow_transaction) { return redirect()->back() ->with('message', ['type' => 'error', 'message' => 'akun anda dibekukan tidak dapat melakukan transaksi']); } diff --git a/app/Http/Controllers/Customer/PaylaterController.php b/app/Http/Controllers/Customer/PaylaterController.php index 9847901..67b670c 100644 --- a/app/Http/Controllers/Customer/PaylaterController.php +++ b/app/Http/Controllers/Customer/PaylaterController.php @@ -3,8 +3,15 @@ namespace App\Http\Controllers\Customer; use App\Http\Controllers\Controller; +use App\Models\Customer; +use App\Models\DepositHistory; use App\Models\PaylaterHistory; +use App\Models\Setting; +use App\Services\GeneralService; +use App\Services\MidtransService; use Illuminate\Http\Request; +use Illuminate\Support\Facades\DB; +use Illuminate\Validation\Rule; class PaylaterController extends Controller { @@ -25,11 +32,67 @@ class PaylaterController extends Controller ]); } - public function create() + public function create(Request $request) { + return inertia('Paylater/Repay', [ + 'amount' => $request->user('customer')->paylater->usage, + 'payments' => GeneralService::getEnablePayment(), + ]); } - public function store() + public function store(Request $request) { + $request->validate([ + 'amount' => 'required|numeric|min:1000', + 'payment' => [ + 'required', + Rule::in([Setting::PAYMENT_MANUAL, Setting::PAYMENT_MIDTRANS, Setting::PAYMENT_CASH_DEPOSIT]), + ], + ]); + + $customer = $request->user('customer'); + + DB::beginTransaction(); + $code = GeneralService::generateDepositRepayCode(); + + $paylater = $customer->paylaterHistories()->create([ + 'credit' => $request->amount, + 'description' => $code, + 'type' => PaylaterHistory::TYPE_REPAYMENT, + ]); + + $deposit = DepositHistory::make([ + 'description' => $code, + 'related_type' => PaylaterHistory::class, + 'related_id' => $paylater->id, + 'customer_id' => $customer->id, + 'debit' => $request->amount, + 'payment_channel' => $request->payment, + 'type' => DepositHistory::TYPE_REPAYMENT, + ]); + + if (in_array($request->payment, [Setting::PAYMENT_MANUAL, Setting::PAYMENT_CASH_DEPOSIT])) { + $deposit->is_valid = DepositHistory::STATUS_WAIT_UPLOAD; + $paylater->is_valid = PaylaterHistory::STATUS_WAIT_UPLOAD; + + $deposit->save(); + } + + if ($request->payment == Setting::PAYMENT_MIDTRANS) { + $deposit->is_valid = DepositHistory::STATUS_WAIT_PAYMENT; + $paylater->is_valid = PaylaterHistory::STATUS_WAIT_PAYMENT; + + $deposit->save(); + + $token = (new MidtransService($deposit, Setting::getByKey('MIDTRANS_SERVER_KEY')))->getSnapToken(); + + $deposit->update(['payment_token' => $token]); + } + + $paylater->save(); + + DB::commit(); + + return redirect()->route('transactions.deposit.show', ['deposit' => $deposit->id, 'direct' => 'true']); } } diff --git a/app/Models/DepositHistory.php b/app/Models/DepositHistory.php index bd35247..7354340 100644 --- a/app/Models/DepositHistory.php +++ b/app/Models/DepositHistory.php @@ -22,8 +22,6 @@ class DepositHistory extends Model const STATUS_EXPIRED = 6; - const STATUS_HIDDEN = 7; - const TYPE_DEPOSIT = 0; const TYPE_REPAYMENT = 1; diff --git a/app/Models/PaylaterHistory.php b/app/Models/PaylaterHistory.php index 105c76a..2f5d4fb 100644 --- a/app/Models/PaylaterHistory.php +++ b/app/Models/PaylaterHistory.php @@ -79,10 +79,10 @@ class PaylaterHistory extends Model { return Attribute::make(get: function () { if ($this->credit == 0) { - return 'Rp' . number_format($this->debit, is_float($this->debit) ? 2 : 0, ',', '.'); + return 'Rp ' . number_format($this->debit, is_float($this->debit) ? 2 : 0, ',', '.'); } - return '-Rp' . number_format($this->credit, is_float($this->credit) ? 2 : 0, ',', '.'); + return '-Rp ' . number_format($this->credit, is_float($this->credit) ? 2 : 0, ',', '.'); }); } } diff --git a/app/Services/GeneralService.php b/app/Services/GeneralService.php index cb7ac62..1dbaea4 100644 --- a/app/Services/GeneralService.php +++ b/app/Services/GeneralService.php @@ -139,9 +139,9 @@ class GeneralService $time = explode(':', $time); foreach ($time as $t) { //00 : 00 if ($t < 10) { - $r .= '0'.(int) $t.':'; + $r .= '0' . (int) $t . ':'; } else { - $r .= $t.':'; + $r .= $t . ':'; } } @@ -154,7 +154,7 @@ class GeneralService ->whereDate('created_at', now()) ->count() + 1; - return 'Invoice #TLH'.now()->format('dmy').GeneralService::formatNumberCode($code); + return 'Invoice #TLH' . now()->format('dmy') . GeneralService::formatNumberCode($code); } public static function generateDepositCode() @@ -163,7 +163,16 @@ class GeneralService ->whereDate('created_at', now()) ->count() + 1; - return 'Invoice #DSR'.now()->format('dmy').GeneralService::formatNumberCode($code); + return 'Invoice #DSR' . now()->format('dmy') . GeneralService::formatNumberCode($code); + } + + public static function generateDepositRepayCode() + { + $code = DepositHistory::where('type', DepositHistory::TYPE_REPAYMENT) + ->whereDate('created_at', now()) + ->count() + 1; + + return 'Invoice #PLH' . now()->format('dmy') . GeneralService::formatNumberCode($code); } public static function generateSaleVoucherCode() @@ -172,14 +181,14 @@ class GeneralService ->where('payed_with', '!=', Sale::PAYED_WITH_POIN) ->count() + 1; - return 'Invoice #VCR'.now()->format('dmy').GeneralService::formatNumberCode($code); + return 'Invoice #VCR' . now()->format('dmy') . GeneralService::formatNumberCode($code); } public static function generateBonusPoinCode() { $code = PoinHistory::whereDate('created_at', now())->count() + 1; - return 'Invoice #BPN'.now()->format('dmy').GeneralService::formatNumberCode($code); + return 'Invoice #BPN' . now()->format('dmy') . GeneralService::formatNumberCode($code); } public static function generateExchangePoinCode() @@ -188,19 +197,19 @@ class GeneralService ->where('payed_with', '=', Sale::PAYED_WITH_POIN) ->count() + 1; - return 'Invoice #PVC'.now()->format('dmy').GeneralService::formatNumberCode($code); + return 'Invoice #PVC' . now()->format('dmy') . GeneralService::formatNumberCode($code); } public static function formatNumberCode($number) { if ($number < 10) { - return '000'.$number; + return '000' . $number; } if ($number < 100) { - return '00'.$number; + return '00' . $number; } if ($number < 1000) { - return '0'.$number; + return '0' . $number; } return $number; diff --git a/resources/js/Customer/Cart/IndexPartials/Payment.jsx b/resources/js/Customer/Cart/IndexPartials/Payment.jsx index c6a2a07..ae413e3 100644 --- a/resources/js/Customer/Cart/IndexPartials/Payment.jsx +++ b/resources/js/Customer/Cart/IndexPartials/Payment.jsx @@ -2,6 +2,7 @@ import React, { useState } from 'react' import { usePage, router } from '@inertiajs/react' import BottomSheet from '@/Customer/Components/BottomSheet' +import { toastError } from '@/Customer/utils' const Payment = ({ state }) => { const { @@ -18,13 +19,16 @@ const Payment = ({ state }) => { } const pay = (payment) => { + if (!payment.is_enable) { + return + } if (processing) { return } router.post( route('cart.purchase'), { - payed_with: payment, + payed_with: payment.name, }, { onBefore: () => setProcessing(true), @@ -41,7 +45,7 @@ const Payment = ({ state }) => {
pay(payment.name)} + onClick={() => pay(payment)} > {payment.display_name}
diff --git a/resources/js/Customer/Deposit/Index.jsx b/resources/js/Customer/Deposit/Index.jsx index bfa78a5..3c4b894 100644 --- a/resources/js/Customer/Deposit/Index.jsx +++ b/resources/js/Customer/Deposit/Index.jsx @@ -76,16 +76,13 @@ export default function Index(props) {
- {deposites.length <= 0 && }
- {deposites.length > 0 && ( -
- {formatIDDate(dates.startDate)} s/d{' '} - {formatIDDate(dates.endDate)} -
- )} +
+ {formatIDDate(dates.startDate)} s/d{' '} + {formatIDDate(dates.endDate)} +
{deposites.map((history) => (
+ + {deposites.length <= 0 && }
) diff --git a/resources/js/Customer/Paylater/Detail.jsx b/resources/js/Customer/Paylater/Detail.jsx index 63b0920..61547ce 100644 --- a/resources/js/Customer/Paylater/Detail.jsx +++ b/resources/js/Customer/Paylater/Detail.jsx @@ -1,6 +1,7 @@ import React from 'react' import { Head, router } from '@inertiajs/react' import { HiChevronLeft } from 'react-icons/hi2' +import { isEmpty } from 'lodash' import CustomerLayout from '@/Layouts/CustomerLayout' @@ -34,9 +35,11 @@ export default function Detail({ paylater }) {
-
- {paylater.note} -
+ {isEmpty(paylater.note) === false && ( +
+ {paylater.note} +
+ )}
diff --git a/resources/js/Customer/Paylater/Index.jsx b/resources/js/Customer/Paylater/Index.jsx index 7b6afd4..1ad3020 100644 --- a/resources/js/Customer/Paylater/Index.jsx +++ b/resources/js/Customer/Paylater/Index.jsx @@ -50,9 +50,7 @@ export default function Index({
- router.get( - route('transactions.deposit.topup') - ) + router.get(route('customer.paylater.repay')) } > Bayar Tagihan diff --git a/resources/js/Customer/Paylater/Repay.jsx b/resources/js/Customer/Paylater/Repay.jsx new file mode 100644 index 0000000..052185b --- /dev/null +++ b/resources/js/Customer/Paylater/Repay.jsx @@ -0,0 +1,174 @@ +import React from 'react' +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 Alert from '@/Components/Alert' +import FormInputNumeric from '@/Components/FormInputNumeric' + +export default function Repay({ payments, amount }) { + const { data, setData, post, processing, errors } = useForm({ + amount: amount, + payment: '', + }) + + const amounts = [amount] + + const isActiveAmount = (amount) => { + return `px-3 py-3 border shadow-sm rounded ${ + +amount === +data.amount ? 'bg-blue-700 text-white' : '' + }` + } + + const setAmount = (amount) => { + setData('amount', amount) + } + + const isActivePayment = (payment) => { + return `p-2 border shadow rounded flex flex-row items-center space-x-5 h-14 ${ + payment === data.payment ? 'bg-blue-600 text-white' : '' + }` + } + + 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.paylater.repay')) + } + + return ( + + +
+
{ + router.get(route('customer.paylater.index')) + }} + > + +
+
+
Nominal Tagihan
+
+ {amounts.map((amount) => ( +
setAmount(amount)} + > + {formatIDR(amount)} +
+ ))} +
+
+
+
+
ATAU
+
+
+
+ setData('amount', e.target.value)} + error={errors.amount} + /> +
+
+
Metode Pembayaran
+ {errors.payment && ( + Pilih metode pembayaran + )} +
+
+ {payments.length <= 0 && ( + + Sistem pembayaran non-aktif{' '} + + )} + {payments.map((payment) => ( +
+
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 pembayaran
+
+ ada disini +
+
+ +
+ + )} +
+ ))} +
+
+
+
+ {payments.length > 0 && ( +
+ Bayar +
+ )} +
+ + ) +} diff --git a/resources/js/Customer/Poin/Index.jsx b/resources/js/Customer/Poin/Index.jsx index 3bb81f9..06ef314 100644 --- a/resources/js/Customer/Poin/Index.jsx +++ b/resources/js/Customer/Poin/Index.jsx @@ -76,15 +76,12 @@ export default function Index(props) {
- {_poins.length <= 0 && }
- {_poins.length > 0 && ( -
- {formatIDDate(dates.startDate)} s/d{' '} - {formatIDDate(dates.endDate)} -
- )} +
+ {formatIDDate(dates.startDate)} s/d{' '} + {formatIDDate(dates.endDate)} +
{_poins.map((poin) => (
+ {_poins.length <= 0 && }
) diff --git a/resources/js/Customer/Trx/Index.jsx b/resources/js/Customer/Trx/Index.jsx index 9064c7b..7c30bb1 100644 --- a/resources/js/Customer/Trx/Index.jsx +++ b/resources/js/Customer/Trx/Index.jsx @@ -79,15 +79,13 @@ export default function Index(props) {
- {sales.length <= 0 && } +
- {sales.length > 0 && ( -
- {formatIDDate(dates.startDate)} s/d{' '} - {formatIDDate(dates.endDate)} -
- )} +
+ {formatIDDate(dates.startDate)} s/d{' '} + {formatIDDate(dates.endDate)} +
{sales.map((sale) => (
+ + {sales.length <= 0 && }
) diff --git a/routes/web.php b/routes/web.php index 4467a2f..4d1dff5 100644 --- a/routes/web.php +++ b/routes/web.php @@ -50,6 +50,8 @@ Route::middleware(['http_secure_aware', 'guard_should_customer', 'inertia.custom // paylater Route::get('paylater', [PaylaterController::class, 'index'])->name('customer.paylater.index'); Route::get('paylater/trx/{paylater}', [PaylaterController::class, 'show'])->name('customer.paylater.show'); + Route::get('paylater/repay', [PaylaterController::class, 'create'])->name('customer.paylater.repay'); + Route::post('paylater/repay', [PaylaterController::class, 'store']); // deposite Route::get('trx/deposit', [DepositController::class, 'index'])->name('transactions.deposit.index');