484f89e2ee
NPM Installation / build (16.x, ubuntu-latest) (push) Waiting to run
NPM Installation / build (16.x, windows-latest) (push) Waiting to run
NPM Installation / build (17.x, ubuntu-latest) (push) Waiting to run
NPM Installation / build (17.x, windows-latest) (push) Waiting to run
NPM Installation / build (18.x, ubuntu-latest) (push) Waiting to run
NPM Installation / build (18.x, windows-latest) (push) Waiting to run
22 lines
6.0 KiB
Vue
22 lines
6.0 KiB
Vue
<script setup>
|
|
import { onMounted, reactive, ref } from 'vue'
|
|
import BaseResponsiveDataView from '@/components/base/BaseResponsiveDataView.vue'
|
|
import { createVoucherAgent, deleteVoucherAgent, getVoucherAgents, getVoucherOptions, updateVoucherAgent } from '@/services/voucherService'
|
|
import { showConfirm, showError, showSuccess } from '@/utils/swal'
|
|
|
|
const loading = ref(true), loaded = ref(false), saving = ref(false), modal = ref(false), editing = ref(null), items = ref([]), users = ref([])
|
|
const query = ref({ page: 1, per_page: 10 }), pagination = ref({ current_page: 1, last_page: 1, per_page: 10, total: 0 }), form = reactive({})
|
|
const columns = [{ key: 'agent_code', label: 'Kode Agen' }, { key: 'user_label', label: 'User' }, { key: 'type_label', label: 'Kategori' }, { key: 'pricing_label', label: 'Parameter Harga' }, { key: 'limit_label', label: 'Limit/Piutang' }, { key: 'status', label: 'Status' }]
|
|
const actions = [{ key: 'edit', label: 'Edit', color: 'success' }, { key: 'delete', label: 'Nonaktifkan', color: 'danger' }]
|
|
const money = (v) => `Rp ${Number(v || 0).toLocaleString('id-ID')}`
|
|
const defaults = () => ({ user_id: '', agent_code: '', payment_type: 'prepaid', price_mode: 'discount', discount_percent: 0, commission_percent: 0, credit_limit: 0, status: 'active', notes: '' })
|
|
function normalize(x) { return { ...x, user_label: x.user?.name || '-', type_label: x.payment_type === 'prepaid' ? 'Deposit Dahulu' : 'Jual Dulu, Bayar Kemudian', pricing_label: x.price_mode === 'discount' ? `Diskon ${x.discount_percent}%` : `Komisi ${x.commission_percent}%`, limit_label: x.payment_type === 'postpaid' ? `${money(x.outstanding_balance)} / ${money(x.credit_limit)}` : 'Menggunakan saldo dompet' } }
|
|
async function fetchData(params = query.value) { query.value = { ...query.value, ...params }; loading.value = true; try { const r = await getVoucherAgents(query.value), rows = r?.data?.data || []; items.value = rows.map(normalize); pagination.value = { current_page: r?.data?.current_page || 1, last_page: r?.data?.last_page || 1, per_page: r?.data?.per_page || 10, total: r?.data?.total || 0 } } catch (e) { showError(e?.response?.data?.message || 'Gagal memuat agen voucher.') } finally { loading.value = false; loaded.value = true } }
|
|
async function open(item = null) { editing.value = item; Object.keys(form).forEach((key) => delete form[key]); Object.assign(form, defaults(), item || {}); try { users.value = (await getVoucherOptions('agents'))?.data?.users || []; modal.value = true } catch (e) { showError(e?.response?.data?.message || 'Gagal memuat user tenant.') } }
|
|
async function save() { if (!form.user_id) return showError('User agen wajib dipilih.'); saving.value = true; try { if (editing.value) await updateVoucherAgent(editing.value.id, form); else await createVoucherAgent(form); modal.value = false; showSuccess('Agen voucher berhasil disimpan.'); await fetchData() } catch (e) { showError(e?.response?.data?.message || 'Agen voucher gagal disimpan.') } finally { saving.value = false } }
|
|
async function action({ action, item }) { if (action === 'edit') return open(item); const result = await showConfirm('Nonaktifkan Agen', `Nonaktifkan agen ${item.user_label}?`); if (!result.isConfirmed) return; try { await deleteVoucherAgent(item.id); showSuccess('Agen berhasil dinonaktifkan.'); await fetchData() } catch (e) { showError(e?.response?.data?.message || 'Agen gagal dinonaktifkan.') } }
|
|
onMounted(fetchData)
|
|
</script>
|
|
<template><div class="brdvx-page-container"><div class="brdvx-page-header d-flex justify-content-between align-items-center"><div><h5 class="mb-0 fw-semibold">Agen Voucher</h5><small class="text-body-secondary">Atur agen deposit dan agen dengan fasilitas kredit</small></div><CButton color="primary" size="sm" @click="open()">+ Tambah Agen</CButton></div><div v-if="loading && !loaded" class="brdvx-loading-state"><CSpinner color="primary" /><p class="brdvx-loading-text">Memuat data...</p></div><BaseResponsiveDataView v-else :columns="columns" :items="items" :actions="actions" server-side :pagination="pagination" :loading="loading" @query-change="fetchData" @action-click="action" /></div>
|
|
<CModal :visible="modal" @close="modal = false"><CModalHeader><CModalTitle>{{ editing ? 'Edit' : 'Tambah' }} Agen Voucher</CModalTitle></CModalHeader><CModalBody><CFormLabel>User Tenant</CFormLabel><CFormSelect v-model="form.user_id" :disabled="Boolean(editing)" class="mb-3"><option value="">Pilih user</option><option v-for="user in users" :key="user.id" :value="user.id">{{ user.name }} · {{ user.username }}</option></CFormSelect><CFormLabel>Kode Agen</CFormLabel><CFormInput v-model="form.agent_code" placeholder="Otomatis jika dikosongkan" class="mb-3" /><CFormLabel>Kategori Pembayaran</CFormLabel><CFormSelect v-model="form.payment_type" class="mb-3"><option value="prepaid">Deposit dahulu, lalu beli voucher</option><option value="postpaid">Jual voucher dahulu, bayar kemudian</option></CFormSelect><CFormLabel>Skema Harga</CFormLabel><CFormSelect v-model="form.price_mode" class="mb-3"><option value="discount">Diskon harga beli</option><option value="commission">Komisi penjualan</option></CFormSelect><CRow class="g-3"><CCol :md="6"><CFormLabel>Diskon (%)</CFormLabel><CFormInput v-model.number="form.discount_percent" type="number" min="0" max="100" /></CCol><CCol :md="6"><CFormLabel>Komisi (%)</CFormLabel><CFormInput v-model.number="form.commission_percent" type="number" min="0" max="100" /></CCol><CCol v-if="form.payment_type === 'postpaid'" :xs="12"><CFormLabel>Limit Kredit</CFormLabel><CFormInput v-model.number="form.credit_limit" type="number" min="0" /></CCol></CRow><CFormLabel class="mt-3">Status</CFormLabel><CFormSelect v-model="form.status" class="mb-3"><option value="active">Aktif</option><option value="inactive">Nonaktif</option><option value="suspended">Ditangguhkan</option></CFormSelect><CFormLabel>Catatan</CFormLabel><CFormTextarea v-model="form.notes" rows="2" /></CModalBody><CModalFooter><CButton color="secondary" @click="modal = false">Batal</CButton><CButton color="primary" :disabled="saving" @click="save">Simpan</CButton></CModalFooter></CModal></template>
|