DONE: settle disable vote for voter with saham under 500, fix issue on...
This commit is contained in:
@@ -163,6 +163,14 @@
|
||||
<span v-else class="label label-warning">Menunggu pengesahan</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Saham (RM)</th>
|
||||
<td>{{ formatRmDisplay(selectedVoter.saham) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Yuran (RM)</th>
|
||||
<td>{{ formatRmDisplay(selectedVoter.yuran) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Status Undi</th>
|
||||
<td>
|
||||
@@ -170,6 +178,9 @@
|
||||
:class="Number(selectedVoter.votes_count) > 0 ? 'label-success' : 'label-default'">
|
||||
{{ Number(selectedVoter.votes_count) > 0 ? 'Ya' : 'Tidak' }}
|
||||
</span>
|
||||
<span v-if="selectedVoterShowsNoVoteEligibleNote"
|
||||
class="label label-info" style="margin-left: 6px;">Tidak layak
|
||||
mengundi (saham)</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -206,14 +217,15 @@
|
||||
<div class="col-md-4">
|
||||
<label>Rujukan (optional)</label>
|
||||
<input type="text" class="form-control" v-model.trim="payoutReference"
|
||||
maxlength="80" />
|
||||
maxlength="80" placeholder="Wakil/Sendiri" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row" style="margin-top: 10px;">
|
||||
<div class="col-md-12">
|
||||
<label>Nota (optional)</label>
|
||||
<input type="text" class="form-control" v-model.trim="payoutNote" />
|
||||
<input type="text" class="form-control" v-model.trim="payoutNote"
|
||||
placeholder="Nama Wakil" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -251,7 +263,13 @@
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body" v-if="verifyModalVoter">
|
||||
<p class="kehadiran-verify-lead">
|
||||
<p class="kehadiran-verify-lead" v-if="verifyModalVoterNeedsLowSahamNote">
|
||||
Pengundi fizikal ini mempunyai saham di bawah <strong>RM 500</strong> dan
|
||||
<strong>tidak dibenarkan mengundi</strong>. Sahkan pendaftaran untuk mengesahkan
|
||||
kehadiran
|
||||
di kaunter dan membolehkan mereka menuntut elaun tunai (mengikut peraturan portal).
|
||||
</p>
|
||||
<p class="kehadiran-verify-lead" v-else>
|
||||
Sahkan bahawa pengundi ini hadir di kaunter. Selepas ini, pengundi boleh mengundi.
|
||||
</p>
|
||||
<table class="table table-condensed table-bordered kehadiran-verify-summary">
|
||||
@@ -272,6 +290,14 @@
|
||||
<th>Unit</th>
|
||||
<td>{{ verifyModalVoter.unit }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Saham (RM)</th>
|
||||
<td>{{ formatRmDisplay(verifyModalVoter.saham) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Yuran (RM)</th>
|
||||
<td>{{ formatRmDisplay(verifyModalVoter.yuran) }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="alert alert-danger" v-if="verifyModalError" style="margin-bottom: 0;">
|
||||
@@ -615,19 +641,53 @@ export default {
|
||||
canPayCash: function (voter) {
|
||||
if (!voter) return false;
|
||||
if (this.isCashPaid(voter)) return false;
|
||||
// Must be fizikal, must have voted
|
||||
return Number(voter.kehadiran) === 1 && Number(voter.votes_count) > 0;
|
||||
if (Number(voter.kehadiran) !== 1) return false;
|
||||
if (Number(voter.votes_count) > 0) return true;
|
||||
return this.canClaimAllowanceWithoutVoteAdmin(voter);
|
||||
},
|
||||
|
||||
openDetail: function (item) {
|
||||
this.detailError = '';
|
||||
this.selectedVoter = Object.assign({}, item);
|
||||
this.claimCodeInput = '';
|
||||
this.payoutReference = '';
|
||||
this.payoutNote = '';
|
||||
this.payoutReference =
|
||||
item.cash_payout_reference != null && item.cash_payout_reference !== undefined
|
||||
? String(item.cash_payout_reference)
|
||||
: '';
|
||||
this.payoutNote =
|
||||
item.cash_payout_note != null && item.cash_payout_note !== undefined
|
||||
? String(item.cash_payout_note)
|
||||
: '';
|
||||
this.util.showModal('#allowance-modal');
|
||||
},
|
||||
|
||||
/** Saham / Yuran — same RM formatting as voter portal. */
|
||||
formatRmDisplay: function (val) {
|
||||
if (val === null || val === undefined || val === '') {
|
||||
return '—';
|
||||
}
|
||||
var n = Number(val);
|
||||
if (Number.isNaN(n)) {
|
||||
return String(val);
|
||||
}
|
||||
return n.toLocaleString('en-MY', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
||||
},
|
||||
|
||||
canClaimAllowanceWithoutVoteAdmin: function (voter) {
|
||||
if (!voter || Number(voter.kehadiran) !== 1) {
|
||||
return false;
|
||||
}
|
||||
if (Number(voter.votes_count) > 0) {
|
||||
return false;
|
||||
}
|
||||
var s = Number(voter.saham);
|
||||
var canVoteBySaham = !Number.isNaN(s) && s >= 500;
|
||||
var canProceed =
|
||||
Number(voter.kehadiran) !== 0 &&
|
||||
(Number(voter.kehadiran) !== 1 || voter.fizikal_registration_verified_at);
|
||||
return canProceed && !canVoteBySaham;
|
||||
},
|
||||
|
||||
payCash: function () {
|
||||
if (!this.selectedVoter) return;
|
||||
this.detailError = '';
|
||||
@@ -660,8 +720,17 @@ export default {
|
||||
this.refreshVoter();
|
||||
// keep modal open but reflect paid state (best effort)
|
||||
if (response && response.data && response.data.payout) {
|
||||
this.selectedVoter.cash_paid_at = response.data.payout.paid_at;
|
||||
this.selectedVoter.cash_payout_id = response.data.payout.id;
|
||||
var p = response.data.payout;
|
||||
this.selectedVoter.cash_paid_at = p.paid_at;
|
||||
this.selectedVoter.cash_payout_id = p.id;
|
||||
if (p.reference != null) {
|
||||
this.selectedVoter.cash_payout_reference = p.reference;
|
||||
this.payoutReference = p.reference ? String(p.reference) : '';
|
||||
}
|
||||
if (p.note != null) {
|
||||
this.selectedVoter.cash_payout_note = p.note;
|
||||
this.payoutNote = p.note ? String(p.note) : '';
|
||||
}
|
||||
} else {
|
||||
this.selectedVoter.cash_paid_at = (new Date()).toISOString();
|
||||
}
|
||||
@@ -703,6 +772,10 @@ export default {
|
||||
this.refreshVoter();
|
||||
this.selectedVoter.cash_paid_at = null;
|
||||
this.selectedVoter.cash_payout_id = null;
|
||||
this.selectedVoter.cash_payout_reference = null;
|
||||
this.selectedVoter.cash_payout_note = null;
|
||||
this.payoutReference = '';
|
||||
this.payoutNote = '';
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
@@ -787,6 +860,19 @@ export default {
|
||||
return this.$route.query.fizikal_reg ? this.$route.query.fizikal_reg : null;
|
||||
},
|
||||
|
||||
verifyModalVoterNeedsLowSahamNote: function () {
|
||||
if (!this.verifyModalVoter) return false;
|
||||
var v = this.verifyModalVoter;
|
||||
if (Number(v.kehadiran) !== 1) return false;
|
||||
var s = Number(v.saham);
|
||||
return !Number.isNaN(s) && s < 500;
|
||||
},
|
||||
|
||||
selectedVoterShowsNoVoteEligibleNote: function () {
|
||||
if (!this.selectedVoter) return false;
|
||||
return this.canClaimAllowanceWithoutVoteAdmin(this.selectedVoter);
|
||||
},
|
||||
|
||||
// Calculate total attendance percentage
|
||||
attendancePercentage() {
|
||||
// Count total members who attended physically (Fizikal)
|
||||
|
||||
Reference in New Issue
Block a user