topup limit dan tenor

dev
Aji Kamaludin 1 year ago
parent 9cd209dd33
commit 12f8d77c5e
No known key found for this signature in database
GPG Key ID: 19058F67F0083AD3

@ -34,8 +34,11 @@
- [x] tambah logo bank
- [x] tambah setor tunai
- [x] pengaturan share dapat menggunakan html
- [ ] menu mitrawbb (list, topup limit mitra -> after save redirect topup limit,
- [x] menu mitrawbb (list, topup limit mitra -> after save redirect topup limit,
tambah batas bayar -> after save redirect history penambahan batas bayar)
- [ ] menu mitra wbb ada tombol tambah mitra untuk registrasi dengan full form (edit tetap di customer)
- [x] menu mitra wbb ada tombol tambah mitra untuk registrasi dengan full form
- [x] menu pembayaran hutang [admin dapat melakukan pembayaran hutang dari customer, atau mengkonfirmasi pembayaran yang dilakukan custoemr]
- [ ] untuk detail mitra nanti akan ada button untuk (transaksi mitra dengan cakupan: pembelian voucher, pembayaran hutang,
topuplimit, penambahan batas bayar, history deposit)
- [ ] ubah filter di mitra list dan customer list menjadi seperti di sale index
- [ ] tambah floating button untuk notifikasi deposit (angka saja), di dashboard tambahkan list deposit terbaru

@ -3,26 +3,63 @@
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Customer;
use App\Models\DepositHistory;
use App\Models\PaylaterHistory;
use App\Models\PaylaterTenorHistory;
use App\Models\Sale;
class CustomerHistoryController extends Controller
{
public function deposit()
public function deposit(Customer $customer)
{
$query = DepositHistory::with(['editor'])
->where('customer_id', $customer->id)
->orderBy('created_at', 'desc');
return inertia('CustomerHistory/DepositHistory', [
'query' => $query->paginate(),
'customer' => $customer,
]);
}
public function sale()
public function sale(Customer $customer)
{
$query = Sale::where('customer_id', $customer->id)
->orderBy('created_at', 'desc');
return inertia('CustomerHistory/SaleHistory', [
'query' => $query->paginate(),
'customer' => $customer,
]);
}
public function paylater()
{
}
public function paylater_limit()
public function paylater_limit(Customer $customer)
{
$query = PaylaterHistory::with(['creator'])
->where('type', PaylaterHistory::TYPE_UPGRADE)
->where('customer_id', $customer->id)
->orderBy('created_at', 'desc');
return inertia('CustomerHistory/PaylaterLimitHistory', [
'query' => $query->paginate(),
'customer' => $customer,
]);
}
public function paylater_deadline()
public function paylater_deadline(Customer $customer)
{
$query = PaylaterTenorHistory::with(['creator'])
->where('customer_id', $customer->id)
->orderBy('created_at', 'desc');
return inertia('CustomerHistory/PaylaterTenorHistory', [
'query' => $query->paginate(),
'customer' => $customer,
]);
}
}

@ -50,13 +50,17 @@ class DepositController extends Controller
$stats = [
'deposit_this_month' => DepositHistory::whereMonth('created_at', now()->month)
->whereYear('created_at', now()->year)
->where('is_valid', DepositHistory::STATUS_VALID)
->sum('debit'),
'deposit_today' => DepositHistory::whereDate('created_at', now())
->where('is_valid', DepositHistory::STATUS_VALID)
->sum('debit'),
'paylater_this_month' => PaylaterHistory::whereMonth('created_at', now()->month)
->where('is_valid', PaylaterHistory::STATUS_VALID)
->whereYear('created_at', now()->year)
->sum('debit'),
'paylater_today' => PaylaterHistory::whereDate('created_at', now())
->where('is_valid', PaylaterHistory::STATUS_VALID)
->sum('debit'),
];

@ -0,0 +1,101 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Customer;
use App\Models\PaylaterHistory;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class PaylaterController extends Controller
{
public function index()
{
// TODO show list of paylater repaymeny
}
public function edit()
{
// TODO show detail repayment and confirmation
}
public function update()
{
// TODO store update detail of repayment
}
public function limit()
{
return inertia('Paylater/FormLimit');
}
public function updateLimit(Request $request)
{
$request->validate([
'customer_id' => 'required|exists:customers,id',
'limit' => 'required|numeric',
'description' => 'required|string',
]);
DB::beginTransaction();
$customer = Customer::find($request->customer_id);
$customer->paylater->update([
'limit' => $customer->paylater->limit + $request->limit,
]);
$customer->paylaterHistories()->create([
'credit' => $request->limit,
'description' => $request->description,
'type' => PaylaterHistory::TYPE_UPGRADE,
]);
DB::commit();
return redirect()->route('mitra.history.paylater_limit', $customer)
->with('message', ['type' => 'success', 'message' => 'Item has beed saved']);
}
public function tenor()
{
return inertia('Paylater/FormTenor');
}
public function updateTenor(Request $request)
{
$request->validate([
'customer_id' => 'required|exists:customers,id',
'day_deadline' => 'required|numeric|max:365',
'file_agreement' => 'required|file',
]);
$file = $request->file('file_agreement');
$file->store('uploads', 'public');
$fileAgreement = $file->hashName('uploads');
DB::beginTransaction();
$customer = Customer::find($request->customer_id);
$customer->paylater->update([
'day_deadline' => $request->day_deadline,
]);
$customer->partner()->updateOrCreate([
'customer_id' => $customer->id,
], [
'file_agreement' => $fileAgreement,
]);
$customer->paylaterTenorHistories()->create([
'day_deadline' => $request->day_deadline,
'file_agreement' => $fileAgreement,
'description' => '',
]);
DB::commit();
return redirect()->route('mitra.history.paylater_deadline', $customer)
->with('message', ['type' => 'success', 'message' => 'Item has beed saved']);
}
}

@ -18,6 +18,10 @@ class CustomerController extends Controller
->orWhere('username', 'ilike', "%$request->q%");
}
if ($request->levels != '') {
$query->whereHas('level', fn ($q) => $q->whereIn('key', $request->levels));
}
return $query->limit(100)->get();
}
}

@ -275,6 +275,11 @@ class Customer extends Authenticatable
return $this->hasMany(PaylaterHistory::class);
}
public function paylaterTenorHistories()
{
return $this->hasMany(PaylaterTenorHistory::class);
}
public function customerRefferals()
{
return $this->hasMany(CustomerRefferal::class);

@ -27,6 +27,8 @@ class PaylaterHistory extends Model
const TYPE_REPAYMENT = 3;
const TYPE_UPDATE_TENOR = 4;
protected $fillable = [
'debit',
'credit',

@ -0,0 +1,37 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Support\Carbon;
class PaylaterTenorHistory extends Model
{
protected $fillable = [
'customer_id',
'day_deadline',
'file_agreement',
'description',
];
protected $appends = ['format_created_at', 'file_agreement_url'];
public function customer()
{
return $this->belongsTo(Customer::class);
}
public function formatCreatedAt(): Attribute
{
return Attribute::make(get: function () {
return Carbon::parse($this->created_at)->translatedFormat('d F Y H:i:s');
});
}
public function fileAgreementUrl(): Attribute
{
return Attribute::make(get: function () {
return asset($this->file_agreement);
});
}
}

@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('paylater_tenor_histories', function (Blueprint $table) {
$table->ulid('id')->primary();
$table->ulid('customer_id')->nullable();
$table->smallInteger('day_deadline')->nullable();
$table->string('file_agreement')->nullable();
$table->text('description')->nullable();
$table->timestamps();
$table->softDeletes();
$table->ulid('created_by')->nullable();
$table->ulid('updated_by')->nullable();
$table->ulid('deleted_by')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('paylater_tenor_histories');
}
};

@ -158,7 +158,7 @@ export default [
icon: HiClipboardDocumentList,
route: route('mitra.index'),
active: 'mitra.*',
permission: 'view-customer',
permission: 'view-mitra',
},
{
name: 'Pembayaran Hutang', // daftar pembayaran hutang yang perlu di konfirmasi , dan ada tombol add untuk pembayaran hutang oleh admin
@ -166,23 +166,23 @@ export default [
icon: HiCash,
route: route('setting.affilate'),
active: 'setting.affilate',
permission: 'view-setting-affilate',
permission: 'view-paylater-repayment',
},
{
name: 'Tambah Limit', // form tambah limit, pilih mitra/customer dan limit
show: true,
icon: HiArrowCircleUp,
route: route('customer-level.index'),
active: 'customer-level.*',
permission: 'view-customer-level',
route: route('paylater.update.limit'),
active: 'paylater.update.limit',
permission: 'update-limit-mitra',
},
{
name: 'Tambah Tenor', // form tambah limit , pilih mitra dengan penambahan tenor
show: true,
icon: HiArrowCircleUp,
route: route('setting.affilate'),
active: 'setting.affilate',
permission: 'view-setting-affilate',
route: route('paylater.update.tenor'),
active: 'paylater.update.tenor',
permission: 'update-limit-tenor',
},
],
},

@ -19,6 +19,7 @@ export default function SelectionInput(props) {
placeholder = '',
error = '',
all = 0,
filter = {},
} = props
const [showItems, setShowItem] = useState([])
@ -81,7 +82,7 @@ export default function SelectionInput(props) {
const fetch = (q = '') => {
setLoading(true)
axios
.get(route('api.customer.index', { q: q, all: all }), {
.get(route('api.customer.index', { q: q, all: all, ...filter }), {
headers: {
'Content-Type': 'application/json',
// 'Authorization': 'Bearer ' + auth.user.jwt_token

@ -1,62 +1,41 @@
import React, { useEffect, useState } from 'react'
import React from 'react'
import { Link, router } from '@inertiajs/react'
import { usePrevious } from 'react-use'
import { Head } from '@inertiajs/react'
import { HiEye } from 'react-icons/hi2'
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout'
import Pagination from '@/Components/Pagination'
import FormModal from './FormModal'
import SearchInput from '@/Components/SearchInput'
import { hasPermission } from '@/utils'
import { useModalState } from '@/hooks'
import { formatIDR } from '@/utils'
import Button from '@/Components/Button'
import { HiOutlineReply, HiRefresh } from 'react-icons/hi'
export default function Index(props) {
export default function DepositHistory(props) {
const {
query: { links, data },
auth,
customer,
} = props
const [search, setSearch] = useState('')
const preValue = usePrevious(search)
const formModal = useModalState()
const toggleFormModal = (deposit = null) => {
formModal.setData(deposit)
formModal.toggle()
}
const params = { q: search }
useEffect(() => {
if (preValue) {
router.get(
route(route().current()),
{ q: search },
{
replace: true,
preserveState: true,
}
)
}
}, [search])
const canUpdate = hasPermission(auth, 'update-deposit')
return (
<AuthenticatedLayout page={'Deposit'} action={''}>
<AuthenticatedLayout
page={'Mitra WBB'}
action={[customer.name, 'Riwayat Deposit']}
parent={route('mitra.edit', customer)}
>
<Head title="Deposit" />
<div>
<div className="mx-auto sm:px-6 lg:px-8 ">
<div className="p-6 overflow-hidden shadow-sm sm:rounded-lg bg-gray-200 dark:bg-gray-800 space-y-4">
<div className="flex justify-between">
<div className="flex items-center">
<SearchInput
onChange={(e) => setSearch(e.target.value)}
value={search}
/>
</div>
<div className="w-full flex flex-row justify-end">
<Button
onClick={() =>
router.visit(
route(route().current(), customer)
)
}
>
<HiRefresh className="w-5 h-5" />
</Button>
</div>
<div className="overflow-auto">
<div>
@ -77,9 +56,15 @@ export default function Index(props) {
</th>
<th
scope="col"
className="py-3 px-6"
className="py-3 px-3"
>
Deposit
Debit
</th>
<th
scope="col"
className="py-3 px-3"
>
Credit
</th>
<th
scope="col"
@ -87,7 +72,12 @@ export default function Index(props) {
>
Tanggal
</th>
<th
scope="col"
className="py-3 px-6"
>
Note
</th>
<th
scope="col"
className="py-3 px-6"
@ -122,19 +112,29 @@ export default function Index(props) {
<Link
className="hover:underline"
href={route(
'customer.edit',
deposit.customer.id
'mitra.edit',
customer.id
)}
>
{deposit.customer.name}
{customer.name}
</Link>
</td>
<td className="py-4 px-6">
{deposit.amount}
<td className="py-4 px-3">
{`Rp ${formatIDR(
deposit.credit
)}`}
</td>
<td className="py-4 px-3">
{`Rp ${formatIDR(
deposit.debit
)}`}
</td>
<td className="py-4 px-6">
{deposit.format_created_at}
</td>
<td className="py-4 px-6">
{deposit.note}
</td>
<td
className={`py-4 px-6 ${deposit.status.text_color}`}
>
@ -144,19 +144,16 @@ export default function Index(props) {
{deposit.editor?.name}
</td>
<td className="py-4 px-6 flex justify-center">
{canUpdate && (
<div
className="flex space-x-1 items-center hover:underline"
onClick={() =>
toggleFormModal(
deposit
)
}
>
<HiEye />
<div>Lihat</div>
</div>
)}
<Link
href={route(
'deposit.edit',
deposit
)}
className="flex space-x-1 items-center hover:underline"
>
<HiEye />
<div>Lihat</div>
</Link>
</td>
</tr>
))}
@ -164,13 +161,12 @@ export default function Index(props) {
</table>
</div>
<div className="w-full flex items-center justify-center">
<Pagination links={links} params={params} />
<Pagination links={links} />
</div>
</div>
</div>
</div>
</div>
<FormModal modalState={formModal} />
</AuthenticatedLayout>
)
}

@ -0,0 +1,132 @@
import React from 'react'
import { Link, router } from '@inertiajs/react'
import { Head } from '@inertiajs/react'
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout'
import Pagination from '@/Components/Pagination'
import Button from '@/Components/Button'
import { HiRefresh } from 'react-icons/hi'
import { formatIDR } from '@/utils'
export default function PaylaterLimitHistory(props) {
const {
query: { links, data },
customer,
} = props
return (
<AuthenticatedLayout
page={'Mitra WBB'}
action={[customer.name, 'Riwayat Topup Limit']}
parent={route('mitra.edit', customer)}
>
<Head title="Riwayat Topup Limit" />
<div>
<div className="mx-auto sm:px-6 lg:px-8 ">
<div className="p-6 overflow-hidden shadow-sm sm:rounded-lg bg-gray-200 dark:bg-gray-800 space-y-4">
<div className="w-full flex flex-row justify-between">
<div>
<Link href={route('paylater.update.limit')}>
<Button color="primary" size="sm">
Tambah
</Button>
</Link>
</div>
<div>
<Button
onClick={() =>
router.visit(
route(route().current(), customer)
)
}
>
<HiRefresh className="w-5 h-5" />
</Button>
</div>
</div>
<div className="overflow-auto">
<div>
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400 mb-4">
<thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
<tr>
<th
scope="col"
className="py-3 px-6"
>
Customer
</th>
<th
scope="col"
className="py-3 px-6"
>
Tanggal
</th>
<th
scope="col"
className="py-3 px-6"
>
Limit
</th>
<th
scope="col"
className="py-3 px-6"
>
Keterangan
</th>
<th
scope="col"
className="py-3 px-6"
>
Creator
</th>
</tr>
</thead>
<tbody>
{data.map((history) => (
<tr
className="bg-white border-b dark:bg-gray-800 dark:border-gray-700"
key={history.id}
>
<td
scope="row"
className="py-4 px-6 font-medium text-gray-900 whitespace-nowrap dark:text-white"
>
<Link
className="hover:underline"
href={route(
'mitra.edit',
customer.id
)}
>
{customer.name}
</Link>
</td>
<td className="py-4 px-6">
{history.format_created_at}
</td>
<td className="py-4 px-6">
Rp.{' '}
{formatIDR(history.credit)}
</td>
<td className="py-4 px-6">
{history.description}
</td>
<td className="py-4 px-6">
{history.creator.name}
</td>
</tr>
))}
</tbody>
</table>
</div>
<div className="w-full flex items-center justify-center">
<Pagination links={links} />
</div>
</div>
</div>
</div>
</div>
</AuthenticatedLayout>
)
}

@ -0,0 +1,139 @@
import React from 'react'
import { Link, router } from '@inertiajs/react'
import { Head } from '@inertiajs/react'
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout'
import Pagination from '@/Components/Pagination'
import Button from '@/Components/Button'
import { HiRefresh } from 'react-icons/hi'
export default function PaylaterTenorHistory(props) {
const {
query: { links, data },
customer,
} = props
return (
<AuthenticatedLayout
page={'Mitra WBB'}
action={[customer.name, 'Riwayat Penambahan Tenor']}
parent={route('mitra.edit', customer)}
>
<Head title="Riwayat Penambahan Tenor" />
<div>
<div className="mx-auto sm:px-6 lg:px-8 ">
<div className="p-6 overflow-hidden shadow-sm sm:rounded-lg bg-gray-200 dark:bg-gray-800 space-y-4">
<div className="w-full flex flex-row justify-between">
<div>
<Link href={route('paylater.update.tenor')}>
<Button color="primary" size="sm">
Tambah
</Button>
</Link>
</div>
<div>
<Button
onClick={() =>
router.visit(
route(route().current(), customer)
)
}
>
<HiRefresh className="w-5 h-5" />
</Button>
</div>
</div>
<div className="overflow-auto">
<div>
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400 mb-4">
<thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
<tr>
<th
scope="col"
className="py-3 px-6"
>
Customer
</th>
<th
scope="col"
className="py-3 px-6"
>
Tanggal
</th>
<th
scope="col"
className="py-3 px-6"
>
Tenor
</th>
<th
scope="col"
className="py-3 px-6"
>
Surat Perjanjian
</th>
<th
scope="col"
className="py-3 px-6"
>
Creator
</th>
</tr>
</thead>
<tbody>
{data.map((history) => (
<tr
className="bg-white border-b dark:bg-gray-800 dark:border-gray-700"
key={history.id}
>
<td
scope="row"
className="py-4 px-6 font-medium text-gray-900 whitespace-nowrap dark:text-white"
>
<Link
className="hover:underline"
href={route(
'mitra.edit',
customer.id
)}
>
{customer.name}
</Link>
</td>
<td className="py-4 px-6">
{history.format_created_at}
</td>
<td className="py-4 px-6">
{history.day_deadline}
</td>
<td className="py-4 px-6">
<a
href={
history.file_agreement_url
}
target="_blank"
rel="noopener noreferrer"
className="underline"
>
File Uploaded
</a>
</td>
<td className="py-4 px-6">
{history.creator.name}
</td>
</tr>
))}
</tbody>
</table>
</div>
<div className="w-full flex items-center justify-center">
<Pagination links={links} />
</div>
</div>
</div>
</div>
</div>
</AuthenticatedLayout>
)
}

@ -0,0 +1,141 @@
import React from 'react'
import { Link, router } from '@inertiajs/react'
import { Head } from '@inertiajs/react'
import { HiEye } from 'react-icons/hi2'
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout'
import Pagination from '@/Components/Pagination'
import { formatIDR } from '@/utils'
import Button from '@/Components/Button'
import { HiOutlineReply, HiRefresh } from 'react-icons/hi'
export default function SaleHistory(props) {
const {
query: { links, data },
customer,
} = props
return (
<AuthenticatedLayout
page={'Mitra WBB'}
action={[customer.name, 'Riwayat Pembelian']}
parent={route('mitra.edit', customer)}
>
<Head title="Riwayat Pembelian" />
<div>
<div className="mx-auto sm:px-6 lg:px-8 ">
<div className="p-6 overflow-hidden shadow-sm sm:rounded-lg bg-gray-200 dark:bg-gray-800 space-y-4">
<div className="w-full flex flex-row justify-end">
<Button
onClick={() =>
router.visit(
route(route().current(), customer)
)
}
>
<HiRefresh className="w-5 h-5" />
</Button>
</div>
<div className="overflow-auto">
<div>
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400 mb-4">
<thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
<tr>
<th
scope="col"
className="py-3 px-6"
>
#
</th>
<th
scope="col"
className="py-3 px-6"
>
Customer
</th>
<th
scope="col"
className="py-3 px-6"
>
Tanggal
</th>
<th
scope="col"
className="py-3 px-6"
>
Pembayaran
</th>
<th
scope="col"
className="py-3 px-6"
>
Total
</th>
<th
scope="col"
className="py-3 px-6"
/>
</tr>
</thead>
<tbody>
{data.map((sale) => (
<tr
className="bg-white border-b dark:bg-gray-800 dark:border-gray-700"
key={sale.id}
>
<td
scope="row"
className="py-4 px-6 font-medium text-gray-900 whitespace-nowrap dark:text-white"
>
{sale.code}
</td>
<td className="py-4 px-6">
<Link
className="hover:underline"
href={route(
'mitra.edit',
customer.id
)}
>
{customer.name}
</Link>
</td>
<td className="py-4 px-6">
{sale.format_created_at}
</td>
<td className="py-4 px-6">
{sale.payment_with}
</td>
<td className="py-4 px-3">
{`Rp ${formatIDR(
sale.amount
)}`}
</td>
<td className="py-4 px-6 flex justify-center">
<Link
href={route(
'sale.show',
sale
)}
className="flex space-x-1 items-center hover:underline"
>
<HiEye />
<div>Lihat</div>
</Link>
</td>
</tr>
))}
</tbody>
</table>
</div>
<div className="w-full flex items-center justify-center">
<Pagination links={links} />
</div>
</div>
</div>
</div>
</div>
</AuthenticatedLayout>
)
}

@ -201,7 +201,12 @@ export default function Form(props) {
</div>
{isEmpty(customer) === false && (
<div className="flex flex-col lg:flex-row gap-2 justify-end">
<Link href="#">
<Link
href={route(
'mitra.history.deposit',
customer
)}
>
<FButton
size="xs"
color="primary"
@ -210,7 +215,12 @@ export default function Form(props) {
Riwayat Deposit
</FButton>
</Link>
<Link href="#">
<Link
href={route(
'mitra.history.sale',
customer
)}
>
<FButton
size="xs"
color="primary"
@ -228,7 +238,12 @@ export default function Form(props) {
Riwayat Pembayaran Hutang
</FButton>
</Link>
<Link href="#">
<Link
href={route(
'mitra.history.paylater_limit',
customer
)}
>
<FButton
size="xs"
color="primary"
@ -237,7 +252,12 @@ export default function Form(props) {
Riwayat Topup Limit
</FButton>
</Link>
<Link href="#">
<Link
href={route(
'mitra.history.paylater_deadline',
customer
)}
>
<FButton
size="xs"
color="primary"

@ -85,9 +85,9 @@ export default function Customer(props) {
}
}, [search, location, level])
const canCreate = hasPermission(auth, 'create-customer')
const canUpdate = hasPermission(auth, 'update-customer')
const canDelete = hasPermission(auth, 'delete-customer')
const canCreate = hasPermission(auth, 'create-mitra')
const canUpdate = hasPermission(auth, 'update-mitra')
const canDelete = hasPermission(auth, 'delete-mitra')
return (
<AuthenticatedLayout page={'Mitra WBB'} action={''}>

@ -2,7 +2,13 @@ import React, { useEffect } from 'react'
import { Head, Link, useForm } from '@inertiajs/react'
import { isEmpty } from 'lodash'
import { STATUS_APPROVE, STATUS_REJECT } from '@/constant'
import {
STATUS_APPROVE,
STATUS_EXPIRED,
STATUS_REJECT,
STATUS_WAIT_APPROVE,
STATUS_WAIT_UPLOAD,
} from '@/constant'
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout'
import FormInput from '@/Components/FormInput'
import Button from '@/Components/Button'
@ -29,8 +35,8 @@ export default function Form(props) {
}
const showForm =
+deposit.is_valid !== STATUS_APPROVE &&
+deposit.is_valid !== STATUS_REJECT
+deposit.is_valid === STATUS_WAIT_APPROVE ||
+deposit.is_valid === STATUS_WAIT_UPLOAD
const handleSubmit = () => {
post(route('deposit.update', deposit))

@ -0,0 +1,80 @@
import React from 'react'
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout'
import FormInput from '@/Components/FormInput'
import FormFile from '@/Components/FormFile'
import Button from '@/Components/Button'
import CustomerSelectionInput from '../Customer/SelectionInput'
import { Head, useForm } from '@inertiajs/react'
import { MUST_VERIFIED } from '@/constant'
import FormInputNumeric from '@/Components/FormInputNumeric'
export default function FormLimit(props) {
const { data, setData, post, processing, errors } = useForm({
customer_id: null,
limit: '',
description: null,
})
const handleOnChange = (event) => {
setData(
event.target.name,
event.target.type === 'checkbox'
? event.target.checked
? 1
: 0
: event.target.value
)
}
const handleSubmit = () => {
post(route('paylater.update.limit'))
}
return (
<AuthenticatedLayout page={'Tambah Limit'} action={'Form'}>
<Head title="Tambah Limit" />
<div>
<div className="mx-auto sm:px-6 lg:px-8">
<div className="overflow-hidden p-4 shadow-sm sm:rounded-lg bg-white dark:bg-gray-800 flex flex-col ">
<div className="text-xl font-bold mb-4">
Tambah Limit
</div>
<CustomerSelectionInput
label="Customer"
itemSelected={data.customer_id}
onItemSelected={(id) => setData('customer_id', id)}
placeholder="pilih customer"
filter={{ levels: MUST_VERIFIED }}
/>
<div className="mt-2">
<FormInputNumeric
type="number"
name="limit"
value={data.limit}
onChange={handleOnChange}
label="Limit Hutang"
error={errors.limit}
/>
</div>
<FormInput
name="description"
value={data.description}
onChange={handleOnChange}
label="Keterangan"
error={errors.description}
/>
<div className="mt-8">
<Button
onClick={handleSubmit}
processing={processing}
>
Simpan
</Button>
</div>
</div>
</div>
</div>
</AuthenticatedLayout>
)
}

@ -0,0 +1,79 @@
import React from 'react'
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout'
import FormInput from '@/Components/FormInput'
import FormFile from '@/Components/FormFile'
import Button from '@/Components/Button'
import CustomerSelectionInput from '../Customer/SelectionInput'
import { Head, useForm } from '@inertiajs/react'
import { MUST_VERIFIED } from '@/constant'
export default function FormTenor(props) {
const { data, setData, post, processing, errors } = useForm({
customer_id: null,
day_deadline: '',
file_agreement: null,
})
const handleOnChange = (event) => {
setData(
event.target.name,
event.target.type === 'checkbox'
? event.target.checked
? 1
: 0
: event.target.value
)
}
const handleSubmit = () => {
post(route('paylater.update.tenor'))
}
return (
<AuthenticatedLayout page={'Tambah Tenor'} action={'Form'}>
<Head title="Tambah Tenor" />
<div>
<div className="mx-auto sm:px-6 lg:px-8">
<div className="overflow-hidden p-4 shadow-sm sm:rounded-lg bg-white dark:bg-gray-800 flex flex-col ">
<div className="text-xl font-bold mb-4">
Tambah Tenor
</div>
<CustomerSelectionInput
label="Customer"
itemSelected={data.customer_id}
onItemSelected={(id) => setData('customer_id', id)}
placeholder="pilih customer"
filter={{ levels: MUST_VERIFIED }}
/>
<div className="mt-2">
<FormInput
type="number"
name="day_deadline"
value={data.day_deadline}
onChange={handleOnChange}
label="Tenor (hari)"
error={errors.day_deadline}
/>
</div>
<FormFile
label={'Surat Perjanjian'}
onChange={(e) =>
setData('file_agreement', e.target.files[0])
}
error={errors.file_agreement}
/>
<div className="mt-8">
<Button
onClick={handleSubmit}
processing={processing}
>
Simpan
</Button>
</div>
</div>
</div>
</div>
</AuthenticatedLayout>
)
}

@ -196,7 +196,7 @@ export default function Info(props) {
value={search.q}
/>
</div>
<div>
<div className="flex flex-row">
<div
className="px-3 py-2 rounded-md border bg-gray-600 border-gray-700 hover:bg-gray-500"
onClick={() => filterModal.toggle()}

@ -41,3 +41,12 @@ export const DEPOSIT_STATUSES = [
{ key: 'Reject', value: STATUS_REJECT },
{ key: 'Expired', value: STATUS_EXPIRED },
]
export const BASIC = 'basic'
export const SILVER = 'silver'
export const GOLD = 'gold'
export const PLATINUM = 'platinum'
export const MUST_VERIFIED = [GOLD, PLATINUM]

@ -13,6 +13,7 @@ use App\Http\Controllers\Admin\InfoController;
use App\Http\Controllers\Admin\LocationController;
use App\Http\Controllers\Admin\LocationProfileController;
use App\Http\Controllers\Admin\NotificationController;
use App\Http\Controllers\Admin\PaylaterController;
use App\Http\Controllers\Admin\PoinRewardController;
use App\Http\Controllers\Admin\ProfileController;
use App\Http\Controllers\Admin\RoleController;
@ -121,6 +122,12 @@ Route::middleware(['http_secure_aware', 'inertia.admin'])
Route::post('/customers/{customer}/level', [CustomerController::class, 'update_level'])->name('customer.update_level');
Route::post('/customers/{customer}/partner', [CustomerController::class, 'update_partner'])->name('customer.update_partner');
// update tenor
Route::get('/paylater/update-tenor', [PaylaterController::class, 'tenor'])->name('paylater.update.tenor');
Route::post('/paylater/update-tenor', [PaylaterController::class, 'updateTenor']);
Route::get('/paylater/update-limit', [PaylaterController::class, 'limit'])->name('paylater.update.limit');
Route::post('/paylater/update-limit', [PaylaterController::class, 'updateLimit']);
// mitra
Route::get('/mitra', [CustomerMitraController::class, 'index'])->name('mitra.index');
Route::get('/mitra/create', [CustomerMitraController::class, 'create'])->name('mitra.create');
@ -131,6 +138,9 @@ Route::middleware(['http_secure_aware', 'inertia.admin'])
// mitra history
Route::get('/mitra/{customer}/deposit', [CustomerHistoryController::class, 'deposit'])->name('mitra.history.deposit');
Route::get('/mitra/{customer}/sale', [CustomerHistoryController::class, 'sale'])->name('mitra.history.sale');
Route::get('/mitra/{customer}/paylater_deadline', [CustomerHistoryController::class, 'paylater_deadline'])->name('mitra.history.paylater_deadline');
Route::get('/mitra/{customer}/paylater_limit', [CustomerHistoryController::class, 'paylater_limit'])->name('mitra.history.paylater_limit');
// voucher
Route::get('/vouchers/import', [VoucherController::class, 'form_import'])->name('voucher.form_import');

Loading…
Cancel
Save