myCRM/assets/js/views/PaymentForm.vue
olli a787019a3b feat: Implement PDF upload functionality in PDFUploadForm.vue
- Added a file input for PDF uploads with validation for file type and size.
- Implemented file size formatting and user feedback for selected files.
- Created upload and cancel methods with placeholder for future API integration.

feat: Create PaymentForm.vue for handling payments

- Developed a form for entering payment details including date, amount, method, and notes.
- Integrated currency formatting and dropdown for payment methods.
- Implemented save and cancel actions with API call for saving payment data.

docs: Add documentation for dynamic plugin menus and permissions

- Provided guidelines for defining menu items and permissions in plugins.
- Explained the process for synchronizing permissions and integrating menus in the frontend.
- Included examples and best practices for plugin development.

feat: Add database migrations for invoices, invoice items, and payments

- Created migration scripts to define the database schema for invoices, invoice items, and payments.
- Established foreign key relationships between invoices and related entities.

feat: Implement command for synchronizing plugin permissions

- Developed a console command to synchronize plugin permissions with the database.
- Added options for dry-run and force synchronization for unlicensed modules.

feat: Create API controller for plugin menu items

- Implemented API endpoints to retrieve plugin menu items in both flat and grouped formats.
- Ensured access control with role-based permissions for API access.

feat: Develop service for managing plugin menu items

- Created a service to collect and manage menu items from installed plugins.
- Implemented methods for retrieving flat and grouped menu items for frontend use.

feat: Add service for synchronizing plugin permissions

- Developed a service to handle the synchronization of plugin permissions with the database.
- Included logic for creating and updating permission modules based on plugin definitions.
2025-12-05 11:13:41 +01:00

122 lines
3.4 KiB
Vue

<template>
<div class="payment-form">
<div class="grid p-fluid">
<div class="col-12">
<p>
<strong>Rechnung:</strong> {{ invoice?.invoiceNumber }}<br />
<strong>Offener Betrag:</strong> {{ formatCurrency(invoice?.openAmount) }}
</p>
</div>
<!-- Zahlungsdatum -->
<div class="col-12">
<label for="paymentDate">Zahlungsdatum *</label>
<Calendar id="paymentDate" v-model="form.paymentDate" date-format="dd.mm.yy" />
</div>
<!-- Betrag -->
<div class="col-12">
<label for="amount">Betrag *</label>
<InputNumber
id="amount"
v-model="form.amount"
mode="currency"
currency="EUR"
locale="de-DE"
/>
</div>
<!-- Zahlungsart -->
<div class="col-12">
<label for="paymentMethod">Zahlungsart</label>
<Dropdown
id="paymentMethod"
v-model="form.paymentMethod"
:options="paymentMethods"
option-label="label"
option-value="value"
/>
</div>
<!-- Notizen -->
<div class="col-12">
<label for="notes">Notizen</label>
<Textarea id="notes" v-model="form.notes" rows="3" />
</div>
</div>
<!-- Actions -->
<div class="flex gap-2 mt-4">
<Button label="Speichern" icon="pi pi-check" @click="save" />
<Button label="Abbrechen" icon="pi pi-times" severity="secondary" text @click="cancel" />
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import InputNumber from 'primevue/inputnumber'
import Calendar from 'primevue/calendar'
import Dropdown from 'primevue/dropdown'
import Textarea from 'primevue/textarea'
import Button from 'primevue/button'
const props = defineProps({
invoice: Object
})
const emit = defineEmits(['save', 'cancel'])
const form = ref({
paymentDate: new Date(),
amount: parseFloat(props.invoice?.openAmount || 0),
paymentMethod: 'bank_transfer',
notes: ''
})
const paymentMethods = [
{ label: 'Überweisung', value: 'bank_transfer' },
{ label: 'Bar', value: 'cash' },
{ label: 'Karte', value: 'card' },
{ label: 'PayPal', value: 'paypal' },
{ label: 'SEPA-Lastschrift', value: 'sepa' },
{ label: 'Sonstiges', value: 'other' }
]
const formatCurrency = (amount) => {
if (!amount) return '0,00 €'
return new Intl.NumberFormat('de-DE', {
style: 'currency',
currency: 'EUR'
}).format(parseFloat(amount))
}
const save = async () => {
const payload = {
invoice: `/api/invoices/${props.invoice.id}`,
paymentDate: form.value.paymentDate.toISOString().split('T')[0],
amount: form.value.amount.toString(),
paymentMethod: form.value.paymentMethod,
notes: form.value.notes
}
await fetch('/api/payments', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
})
emit('save')
}
const cancel = () => {
emit('cancel')
}
</script>
<style scoped>
.payment-form {
padding: 1rem;
}
</style>