diff --git a/resources/js/components/documents/InvoiceDialog.vue b/resources/js/components/documents/InvoiceDialog.vue index 12c61aa..2281251 100644 --- a/resources/js/components/documents/InvoiceDialog.vue +++ b/resources/js/components/documents/InvoiceDialog.vue @@ -24,13 +24,14 @@ import { Input } from '@/components/ui/input'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu' import { StatusBadge, statusBadgeLabels, statusBadgeTextColor, StatusBadgeVariants } from '@/components/ui/status-badge' import LineItemTable from '@/components/documents/LineItemTable.vue' -import { Eye, FileText, CircleEllipsis, Trash, Trash2, BookUser, User, CodeXml, CalendarIcon, MessageCircleQuestion, X, CircleX, Logs, ListCheck, ClipboardCheck, ClipboardList } from "lucide-vue-next" +import { Eye, FileText, CircleEllipsis, Trash, Trash2, BookUser, User, CodeXml, CalendarIcon, MessageCircleQuestion, X, CircleX, Logs, ListCheck, ClipboardCheck, ClipboardList, Loader, Loader2 } from "lucide-vue-next" import { alertStore } from "@/stores/alertStore" import { Calendar } from "@/components/ui/calendar" import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover" import { exportPdf, exportXml } from "@/routes/invoice" import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, SheetTrigger, } from '@/components/ui/sheet' import { GrowingTextarea } from '../ui/growing-textarea' +import { toast } from "vue-sonner" const props = defineProps<{ invoiceData: Invoice | null, @@ -47,6 +48,7 @@ const isLoading = ref(false); const importContact = ref(newContact() as Contact) const importCustomer = ref(newCustomer() as Customer) const alert = alertStore() +const reminderLoading = ref(false) onMounted(async () => { const response = await axios.get('/api/paymentterms') @@ -95,6 +97,7 @@ watch(invoice, postalCode: invoice.value.customer?.billingAddress?.postalCode || "", countryCode: invoice.value.customer?.billingAddress?.countryCode || "", }, + contactSalutation: invoice.value.customer?.contacts && invoice.value.customer.contacts.length > 0 ? invoice.value.customer.contacts[0].salutation : "", contactFirstName: invoice.value.customer?.contacts && invoice.value.customer.contacts.length > 0 ? invoice.value.customer.contacts[0].firstName : "", contactLastName: invoice.value.customer?.contacts && invoice.value.customer.contacts.length > 0 ? invoice.value.customer.contacts[0].lastName : "", paymentTerms: invoice.value.customer?.paymentTerms || paymentTermsData.value.length > 0 ? paymentTermsData.value[2] : null, @@ -190,24 +193,23 @@ const saveChanges = () => { const cancelChanges = (event: Event | null) => { if (isDirty.value) { - alert.title = "Wirklich schließen?" - alert.message = "Es gibt ungespeicherte Änderungen, die dann verloren gehen." - alert.cancelText = "Abbrechen" - alert.onCancel = () => { - console.log('cancel') - event?.preventDefault() - event.returnValue = true - alert.open = false - } - alert.actionText = "Schließen" - // alert.actionVariant = "destructive" - alert.onAction = () => { - console.log('action') - emit('cancel') - isOpen.value = false - alert.open = false - } - alert.open = true + alert.show( + "Wirklich schließen?", + "Es gibt ungespeicherte Änderungen, die dann verloren gehen.", + { + actionText: "Änderungen verwerfen", + actionVariant: "destructive", + onAction: () => { + emit('cancel') + isOpen.value = false + }, + onCancel: () => { + if(!event) return + event.preventDefault() + event.returnValue = true + } + } + ) } else { emit('cancel') isOpen.value = false @@ -230,19 +232,46 @@ const downloadXml = function () { } const deleteInvoice = function () { - let confirm = window.confirm('Möchtest Du diese Rechnung wirklich löschen?') - if (!confirm) return - emit('delete', invoice.value?.id) - isOpen.value = false + alert.show( + "Möchtest Du diese Rechnung wirklich löschen?", + (invoice.value?.paymentStatus == "draft") ? null : "Nach GoBD musst Du alle Belege und Daten in unveränderter Form aufbewahren", + { + actionText: "Löschen", + actionVariant: "destructive", + onAction: () => { + emit('delete', invoice.value?.id) + isOpen.value = false + } + } + ) } const remind = function () { - // await axios call - // make button spin - // success -> set new status and save - // error -> toast if (!invoice.value) return; - window?.open('/api/invoices/' + invoice.value.id + '/remind', '_blank')?.focus(); + + alert.show( + "Zahlungserinnerung senden?", + "E-mail an " + invoice.value.customer?.contacts[0].email, + { + actionText: "Senden", + onAction: async () => { + // make button spin and disable button + reminderLoading.value = true + + // await axios call + await axios.get('/api/invoices/' + invoice.value.id + '/remind') + .then(function (response) { + toast.success("Zahlungserinnerung gesendet", { description: "daniel@vollstock.de" }) + }) + .catch(function (error) { + toast.error(error.title, { description: error.message }) + }) + .finally(() => { + reminderLoading.value = false + }) + } + } + ) } const updateTotalAmount = () => { @@ -364,7 +393,7 @@ const updateTotalAmount = () => {