mirror of
https://origin.cursor.com/mrdevmx/panels.git
synced 2026-10-09 14:53:18 +00:00
119 lines
4.3 KiB
Vue
119 lines
4.3 KiB
Vue
<template>
|
|
<Dialog
|
|
:visible="visible"
|
|
header="Registrar préstamo"
|
|
modal
|
|
:style="{ width: '28rem' }"
|
|
@update:visible="emit('update:visible', $event)"
|
|
>
|
|
<p v-if="personName" class="muted mb-3">{{ personName }}</p>
|
|
<FormField label="Monto a entregar" required>
|
|
<InputNumber v-model="loanAmount" mode="currency" currency="MXN" locale="es-MX" class="w-full" />
|
|
</FormField>
|
|
<div class="loan-switch">
|
|
<ToggleSwitch v-model="loanCommissionOn" />
|
|
<span>Comisión {{ loanCommissionPct }}%</span>
|
|
</div>
|
|
<FormField v-if="loanCommissionOn" label="Porcentaje" class="mt-2">
|
|
<InputNumber v-model="loanCommissionPct" suffix=" %" :min="0" :max="100" :max-fraction-digits="2" class="w-full" />
|
|
</FormField>
|
|
<Message v-if="loanIsSmall" severity="secondary" :closable="false" class="mt-3">
|
|
Préstamo chico (tope {{ money(loanSmallMax) }}): 1 exhibición el sábado de la semana siguiente.
|
|
Recibe {{ money(loanAmount) }}; se descuenta {{ money(loanAmount + (loanCommissionOn ? loanAmount * loanCommissionPct / 100 : 0)) }}.
|
|
</Message>
|
|
<template v-else>
|
|
<FormField label="Plan" class="mt-3">
|
|
<Select v-model="loanPlan" :options="planOpts" option-label="label" option-value="value" class="w-full" />
|
|
</FormField>
|
|
<FormField v-if="loanPlan === 'installments'" label="Cuotas" class="mt-2">
|
|
<InputNumber v-model="loanInstallments" :min="2" :max="24" class="w-full" />
|
|
</FormField>
|
|
</template>
|
|
<template #footer>
|
|
<Button label="Cancelar" text @click="emit('update:visible', false)" />
|
|
<Button label="Registrar" icon="pi pi-check" :disabled="loanAmount <= 0 || saving || !workerId" :loading="saving" @click="save" />
|
|
</template>
|
|
</Dialog>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import FormField from "~/components/padron/FormField.vue";
|
|
|
|
const props = defineProps<{
|
|
visible: boolean;
|
|
workerId?: number;
|
|
personName?: string;
|
|
}>();
|
|
const emit = defineEmits<{ "update:visible": [boolean]; saved: [number] }>();
|
|
const { api, download } = useApi();
|
|
const toast = useToast();
|
|
|
|
const loanAmount = ref(0);
|
|
const loanCommissionOn = ref(true);
|
|
const loanCommissionPct = ref(10);
|
|
const loanSmallMax = ref(500);
|
|
const loanPlan = ref<"single" | "installments">("single");
|
|
const loanInstallments = ref(4);
|
|
const saving = ref(false);
|
|
const planOpts = [
|
|
{ label: "1 exhibición", value: "single" },
|
|
{ label: "Varias cuotas", value: "installments" },
|
|
];
|
|
const loanIsSmall = computed(() => loanAmount.value > 0 && loanAmount.value <= loanSmallMax.value);
|
|
|
|
function money(value: number) {
|
|
return value.toLocaleString("es-MX", { style: "currency", currency: "MXN", maximumFractionDigits: 0 });
|
|
}
|
|
|
|
async function loadSettings() {
|
|
const payrollSettings = await api<{
|
|
settings: { loan_commission_enabled: number; loan_commission_pct: number; loan_small_max: number };
|
|
}>("/v1/payroll/settings");
|
|
loanCommissionOn.value = Boolean(payrollSettings.settings.loan_commission_enabled);
|
|
loanCommissionPct.value = Number(payrollSettings.settings.loan_commission_pct);
|
|
loanSmallMax.value = Number(payrollSettings.settings.loan_small_max);
|
|
}
|
|
|
|
async function save() {
|
|
if (!props.workerId || loanAmount.value <= 0) return;
|
|
saving.value = true;
|
|
try {
|
|
const created = await api<{ id: number }>("/v1/loans", {
|
|
method: "POST",
|
|
json: {
|
|
worker_id: props.workerId,
|
|
delivered: loanAmount.value,
|
|
commission_enabled: loanCommissionOn.value,
|
|
commission_pct: loanCommissionPct.value,
|
|
plan: loanIsSmall.value ? "single" : loanPlan.value,
|
|
installments_n: loanIsSmall.value ? 1 : loanInstallments.value,
|
|
},
|
|
});
|
|
loanAmount.value = 0;
|
|
toast.add({ severity: "success", summary: "Préstamo registrado", life: 1800 });
|
|
emit("update:visible", false);
|
|
emit("saved", created.id);
|
|
if (created.id) download(`/v1/loans/${created.id}/recibo`, `prestamo-aceptacion-${created.id}.pdf`);
|
|
} finally {
|
|
saving.value = false;
|
|
}
|
|
}
|
|
|
|
watch(() => props.visible, async (open) => {
|
|
if (!open) return;
|
|
loanAmount.value = 0;
|
|
loanPlan.value = "single";
|
|
loanInstallments.value = 4;
|
|
await loadSettings();
|
|
});
|
|
</script>
|
|
|
|
<style scoped>
|
|
.loan-switch {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
margin-top: 12px;
|
|
font-size: 0.9rem;
|
|
}
|
|
</style>
|