Direct payments for invoices
Events can be moved to archive and moved back Fixed validation
This commit is contained in:
@@ -5,6 +5,7 @@ import Modal from "../../../Views/Components/Modal.vue";
|
||||
import {onMounted, reactive, ref} from "vue";
|
||||
import ExpenseAccounting from "./Partials/newInvoice/expense-accounting.vue";
|
||||
import TravelExpenseAccounting from "./Partials/newInvoice/travel-expense-accounting.vue";
|
||||
import DirectPayment from "./Partials/newInvoice/direct-payment.vue";
|
||||
|
||||
const props = defineProps({
|
||||
currentEvents: Object,
|
||||
@@ -42,6 +43,24 @@ const invoiceType = ref('');
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="eventId === 0"
|
||||
class="invoice-type-layer" style="width: calc(100% - 60px); margin: auto"
|
||||
@click="isOpen = true;invoiceType='direct-payment'"
|
||||
>
|
||||
<TextResource textName="NEW_DIRECT_PAYMENT" />
|
||||
</div>
|
||||
|
||||
<DirectPayment v-if="invoiceType === 'direct-payment' && eventId !== 0"
|
||||
:eventId="eventId"
|
||||
:userName="props.userName"
|
||||
:userEmail="props.userEmail"
|
||||
:userTelephone="props.userTelephone"
|
||||
:userAccountIban="props.userAccountIban"
|
||||
:userAccountOwner="props.userAccountOwner"
|
||||
:userId="props.userId"
|
||||
/>
|
||||
|
||||
<ExpenseAccounting v-if="invoiceType === 'expense-accounting' && eventId !== 0"
|
||||
:eventId="eventId"
|
||||
:userName="props.userName"
|
||||
@@ -62,7 +81,7 @@ const invoiceType = ref('');
|
||||
:userId="props.userId"
|
||||
/>
|
||||
|
||||
<Modal :show="isOpen" title="Veranstaltung auswählen" @close="isOpen = false">
|
||||
<Modal :show="isOpen" title="Veranstaltung auswählen" @close="isOpen = false" width="450px">
|
||||
<select v-model="eventId" @change="isOpen=false" style="width: 100%">
|
||||
<option value="0" disabled>Bitte auswählen</option>
|
||||
<optgroup label="Laufende Tätigkeiten">
|
||||
|
||||
@@ -97,7 +97,7 @@ const emit = defineEmits(["accept", "deny", "fix", "reopen"])
|
||||
<td>{{props.data.accountIban}}</td>
|
||||
<td>Buchungsinformationen:</td>
|
||||
<td v-if="props.data.donation">Als Spende gebucht</td>
|
||||
<td v-else-if="props.data.alreadyPaid">Beleg ohne Auszahlung</td>
|
||||
<td v-else-if="props.data.externalPayment">Rechnungszahlung</td>
|
||||
<td v-else>Klassische Auszahlung</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -81,7 +81,7 @@ const emit = defineEmits(["accept", "deny", "fix", "reopen"])
|
||||
<td>{{props.data.accountIban}}</td>
|
||||
<td>Buchungsinformationen:</td>
|
||||
<td v-if="props.data.donation">Als Spende gebucht</td>
|
||||
<td v-else-if="props.data.alreadyPaid">Beleg ohne Auszahlung</td>
|
||||
<td v-else-if="props.data.externalPayment">Rechnungszahlung</td>
|
||||
<td v-else>Klassische Auszahlung</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
</td>
|
||||
<td style="width: 150px;">
|
||||
<Icon v-if="invoice.donation" name="hand-holding-dollar" style="color: #ffffff; background-color: green" />
|
||||
<Icon v-if="invoice.alreadyPaid" name="comments-dollar" style="color: #ffffff; background-color: green" />
|
||||
<Icon v-if="invoice.externalPayment" name="comments-dollar" style="color: #ffffff; background-color: green" />
|
||||
</td>
|
||||
<td>
|
||||
{{invoice.contactName}}<br />
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
<script setup>
|
||||
|
||||
import { ref, onMounted, reactive } from 'vue'
|
||||
import {checkFilesize} from "../../../../../../resources/js/components/InvoiceUploadChecks.js";
|
||||
import RefundData from "./refund-data.vue";
|
||||
import AmountInput from "../../../../../Views/Components/AmountInput.vue";
|
||||
import {useAjax} from "../../../../../../resources/js/components/ajaxHandler.js";
|
||||
import InfoIcon from '../../../../../Views/Components/InfoIcon.vue'
|
||||
import {toast} from "vue3-toastify";
|
||||
import PaymentData from "./payment-data.vue";
|
||||
|
||||
|
||||
|
||||
const data = defineProps({
|
||||
eventId: Number,
|
||||
userName: String,
|
||||
userEmail: String,
|
||||
userTelephone: String,
|
||||
userAccountIban: String,
|
||||
userAccountOwner: String,
|
||||
})
|
||||
|
||||
|
||||
const { request } = useAjax();
|
||||
const amount = ref(0.00);
|
||||
const invoiceType = ref(null);
|
||||
const otherText = ref('');
|
||||
const receipt = ref(null)
|
||||
const finalStep = ref(false)
|
||||
|
||||
const invoiceTypeCollection = reactive({
|
||||
invoiceTypes: {}
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
const response = await fetch('/api/v1/core/retrieve-invoice-types');
|
||||
const data = await response.json();
|
||||
Object.assign(invoiceTypeCollection, data);
|
||||
});
|
||||
|
||||
|
||||
function handleFileChange(event) {
|
||||
if (checkFilesize('receipt')) {
|
||||
receipt.value = event.target.files[0]
|
||||
finalStep.value = true
|
||||
} else {
|
||||
event.target.value = null
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<fieldset>
|
||||
<legend><span style="font-weight: bolder;">Was ist der Anlass der Rechnung</span></legend>
|
||||
|
||||
<p v-for="availableInvoiceType in invoiceTypeCollection.invoiceTypes">
|
||||
<input
|
||||
name="invpice_type"
|
||||
type="radio"
|
||||
:value="availableInvoiceType.slug"
|
||||
:id="'invoice_type_' + availableInvoiceType.slug"
|
||||
v-model="invoiceType"
|
||||
>
|
||||
<label :for="'invoice_type_' + availableInvoiceType.slug">{{ availableInvoiceType.name }}</label>
|
||||
<InfoIcon :text="'INFO_INVOICE_TYPE_' + availableInvoiceType.slug" /><br />
|
||||
</p>
|
||||
|
||||
|
||||
<label for="invoice_type_other">
|
||||
<input
|
||||
type="text"
|
||||
class="width-full"
|
||||
name="kostengruppe_sonstiges"
|
||||
placeholder="Sonstige"
|
||||
for="invoice_type_other"
|
||||
v-model="otherText"
|
||||
@focus="invoiceType = 'other'"
|
||||
/>
|
||||
</label>
|
||||
|
||||
</fieldset><br /><br />
|
||||
|
||||
<fieldset>
|
||||
<legend><span style="font-weight: bolder;">Wie hoch ist der Betrag</span></legend>
|
||||
<AmountInput v-model="amount" class="width-small" id="amount" name="amount" /> Euro
|
||||
<info-icon></info-icon><br /><br />
|
||||
|
||||
<input
|
||||
v-if="amount != '' && invoiceType !== null"
|
||||
class="mareike-button"
|
||||
onclick="document.getElementById('receipt').click();"
|
||||
type="button"
|
||||
value="Beleg auswählen und fortfahren" />
|
||||
<input accept="application/pdf" type="file" id="receipt" name="receipt" @change="handleFileChange"
|
||||
style="display: none"/>
|
||||
</fieldset><br />
|
||||
|
||||
|
||||
|
||||
<PaymentData
|
||||
v-if="finalStep"
|
||||
:eventId="data.eventId"
|
||||
:invoice-type="invoiceType"
|
||||
:amount="amount"
|
||||
:other-text="otherText"
|
||||
:userName="data.userName"
|
||||
:userEmail="data.userEmail"
|
||||
:userTelephone="data.userTelephone"
|
||||
:userAccountIban="data.userAccountIban"
|
||||
:userAccountOwner="data.userAccountOwner"
|
||||
:receipt="receipt"
|
||||
travelReason=""
|
||||
@close="finalStep = false"
|
||||
/>
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import Modal from "../../../../../Views/Components/Modal.vue";
|
||||
import IbanInput from "../../../../../Views/Components/IbanInput.vue";
|
||||
import {useAjax} from "../../../../../../resources/js/components/ajaxHandler.js";
|
||||
import TextResource from "../../../../../Views/Components/TextResource.vue";
|
||||
import {invoiceCheckContactName} from "../../../../../../resources/js/components/InvoiceUploadChecks.js";
|
||||
import {toast} from "vue3-toastify";
|
||||
import ErrorText from "../../../../../Views/Components/ErrorText.vue";
|
||||
|
||||
const { request } = useAjax();
|
||||
|
||||
const emit = defineEmits(['close'])
|
||||
|
||||
|
||||
const props = defineProps({
|
||||
eventId: Number,
|
||||
invoiceType: String,
|
||||
amount: [String, Number],
|
||||
otherText: String,
|
||||
receipt: File,
|
||||
userName: String,
|
||||
userEmail: String,
|
||||
userTelephone: String,
|
||||
userAccountOwner: String,
|
||||
userAccountIban: String,
|
||||
havePassengers: Number,
|
||||
materialTransportation: Boolean,
|
||||
travelReason: String,
|
||||
})
|
||||
|
||||
const finalStep = ref(true)
|
||||
const userName = ref(props.userName)
|
||||
const userEmail = ref(props.userEmail)
|
||||
const userTelephone = ref(props.userTelephone)
|
||||
const userIban = ref('')
|
||||
const userAccountOwner = ref('')
|
||||
const paymentPurpose = ref('')
|
||||
const sending = ref(false)
|
||||
const success = ref(false)
|
||||
const decision = ref('')
|
||||
const errorMsg = ref('')
|
||||
const confirmation = ref(null)
|
||||
const receiptError = ref('')
|
||||
|
||||
async function sendData() {
|
||||
if (!userName.value) return
|
||||
|
||||
sending.value = true
|
||||
errorMsg.value = ''
|
||||
success.value = false
|
||||
|
||||
const formData = new FormData()
|
||||
|
||||
formData.append('name', userName.value)
|
||||
formData.append('email', userEmail.value)
|
||||
formData.append('telephone', userTelephone.value)
|
||||
formData.append('amount', props.amount)
|
||||
formData.append('otherText', props.otherText)
|
||||
formData.append('decision', decision.value)
|
||||
formData.append('accountOwner', userAccountOwner.value)
|
||||
formData.append('accountIban', userIban.value)
|
||||
formData.append('paymentPurpose', paymentPurpose.value)
|
||||
formData.append('havePassengers', props.havePassengers ? 1 : 0)
|
||||
formData.append('materialTransportation', props.materialTransportation ? 1 : 0)
|
||||
formData.append('travelReason', props.travelReason)
|
||||
|
||||
if (props.receipt) {
|
||||
formData.append('receipt', props.receipt)
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
const response = await request('/api/v1/invoice/new/' + props.eventId + '/' + props.invoiceType, {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
|
||||
if (response.status === 'success') {
|
||||
window.location.href = '/';
|
||||
} else {
|
||||
receiptError.value = response.message;
|
||||
}
|
||||
} catch (err) {
|
||||
toast.error(result.message);
|
||||
} finally {
|
||||
sending.value = false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal :show="finalStep" title='Bitte gib deine Daten ein' @close="emit('close')" width="600px">
|
||||
<label>
|
||||
<strong>Dein Name Name (kein Pfadiname):</strong>
|
||||
</label><br />
|
||||
<input
|
||||
type="text"
|
||||
@keyup="invoiceCheckContactName();"
|
||||
id="contact_name"
|
||||
name="contact_name" v-model="userName"
|
||||
style="font-size: 14pt; width: 550px;" /><br /><br />
|
||||
|
||||
<label v-if="userName !== ''">
|
||||
<strong>E-Mail-Adresse (Für Rückfragen):</strong>
|
||||
</label><br />
|
||||
<input
|
||||
v-if="userName !== ''"
|
||||
type="email"
|
||||
name="contact_email"
|
||||
v-model="userEmail"
|
||||
style="font-size: 14pt; width: 550px;" /><br /><br />
|
||||
|
||||
<label v-if="userName !== ''">
|
||||
<strong>Telefonnummer (für Rückfragen):</strong>
|
||||
</label><br />
|
||||
<input
|
||||
v-if="userName !== ''"
|
||||
type="text"
|
||||
id="contact_telephone"
|
||||
name="contact_telephone" v-model="userTelephone"
|
||||
style="font-size: 14pt; width: 550px;" /><br /><br />
|
||||
|
||||
<span id="confirm_payment" v-if="userEmail !== '' && userTelephone !== ''">
|
||||
<label>
|
||||
<strong>Zahlungsempfänger*in:</strong>
|
||||
</label><br />
|
||||
<input type="text" name="account_owner" id="account_owner" v-model="userAccountOwner" style="font-size: 14pt; width: 550px;" /><br /><br />
|
||||
|
||||
<label>
|
||||
<strong>IBAN:</strong>
|
||||
</label><br />
|
||||
<IbanInput id="account_iban" name="account_iban" v-model="userIban" style="font-size: 14pt; width: 550px;" /><br /><br />
|
||||
|
||||
<label>
|
||||
<strong>Überweisungstext (laut Rechnung):</strong>
|
||||
</label><br />
|
||||
<input
|
||||
type="text"
|
||||
id="payment_purpose"
|
||||
name="payment_purpose"
|
||||
v-model="paymentPurpose"
|
||||
style="font-size: 14pt; width: 550px;"
|
||||
/><br /><br />
|
||||
<ErrorText :message="receiptError" />
|
||||
|
||||
<span v-if="paymentPurpose != '' && userAccountOwner != '' && userIban && userIban.length === 27"><br />
|
||||
<input type="radio" name="confirmation_radio" value="payment" id="confirmation_radio_payment" v-model="confirmation">
|
||||
<TextResource belongsTo="confirmation_radio_payment" textName="CONFIRMATION_DIRECT_PAYMENT" /><br /><br />
|
||||
<input type="button" v-if="confirmation !== null && !sending" @click="sendData" value="Beleg einreichen" />
|
||||
</span>
|
||||
</span>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* optional styling */
|
||||
</style>
|
||||
|
||||
@@ -6,6 +6,7 @@ import {useAjax} from "../../../../../../resources/js/components/ajaxHandler.js"
|
||||
import TextResource from "../../../../../Views/Components/TextResource.vue";
|
||||
import {invoiceCheckContactName} from "../../../../../../resources/js/components/InvoiceUploadChecks.js";
|
||||
import {toast} from "vue3-toastify";
|
||||
import ErrorText from "../../../../../Views/Components/ErrorText.vue";
|
||||
|
||||
const { request } = useAjax();
|
||||
|
||||
@@ -39,7 +40,7 @@ const success = ref(false)
|
||||
const decision = ref('')
|
||||
const errorMsg = ref('')
|
||||
const confirmation = ref(null)
|
||||
|
||||
const receiptError = ref('')
|
||||
|
||||
async function sendData() {
|
||||
if (!userName.value) return
|
||||
@@ -75,6 +76,8 @@ async function sendData() {
|
||||
|
||||
if (response.status === 'success') {
|
||||
window.location.href = '/';
|
||||
} else {
|
||||
receiptError.value = response.message;
|
||||
}
|
||||
} catch (err) {
|
||||
toast.error(result.message);
|
||||
@@ -87,7 +90,7 @@ async function sendData() {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal :show="finalStep" title='Bitte gib deine Daten ein' @close="emit('close')">
|
||||
<Modal :show="finalStep" title='Bitte gib deine Daten ein' @close="emit('close')" width="600px">
|
||||
<label>
|
||||
<strong>Dein Name Name (kein Pfadiname):</strong>
|
||||
</label><br />
|
||||
@@ -143,7 +146,7 @@ async function sendData() {
|
||||
<strong>IBAN:</strong>
|
||||
</label><br />
|
||||
<IbanInput id="account_iban" name="account_iban" v-model="userIban" style="font-size: 14pt; width: 550px;" /><br /><br />
|
||||
|
||||
<ErrorText :message="receiptError" />
|
||||
<span v-if="userAccountOwner != '' && userIban && userIban.length === 27"><br />
|
||||
<input type="radio" name="confirmation_radio" value="payment" id="confirmation_radio_payment" v-model="confirmation">
|
||||
<TextResource belongsTo="confirmation_radio_payment" textName="CONFIRMATION_PAYMENT" /><br /><br />
|
||||
|
||||
Reference in New Issue
Block a user