This commit is contained in:
2024-03-18 20:50:20 +01:00
parent e4a41d9126
commit 6ef8573032
12 changed files with 527 additions and 1229 deletions

View File

@@ -337,6 +337,10 @@ let links = [
label: "Mitarbeiter",
to: "/profiles",
icon: "i-heroicons-clipboard-document-list"
},{
label: "Bankkonten",
to: "/settings/banking",
icon: "i-heroicons-clipboard-document-list"
},{
label: "Firmeneinstellungen",
to: "/settings/tenant",

View File

@@ -1,11 +0,0 @@
<script setup>
</script>
<template>
</template>
<style scoped>
</style>

View File

@@ -1,84 +1,150 @@
<template>
<div id="main">
<!-- TODO: Kontakte erstellen und dem Kunden zuweisen -->
<UDashboardNavbar title="Bankbuchungen">
<!--<InputGroup>
<UButton @click="router.push(`/banking/accounts/create/`)">+ Kontakt</UButton>
<UInput
v-model="searchString"
placeholder="Suche..."
/>
</InputGroup>-->
<Toolbar>
<UButton
@click="router.push('/banking/newAccount')"
</UDashboardNavbar>
<UDashboardToolbar>
<template #left>
<USelectMenu
:options="dataStore.bankAccounts"
v-model="filterAccount"
option-attribute="iban"
multiple
by="id"
>
+ Konto
</UButton>
</Toolbar>
<template #label>
Konto
</template>
</USelectMenu>
</template>
<template #right>
<USelectMenu
v-model="selectedColumns"
icon="i-heroicons-adjustments-horizontal-solid"
:options="templateColumns"
multiple
class="hidden lg:block"
by="key"
>
<template #label>
Spalten
</template>
</USelectMenu>
</template>
</UDashboardToolbar>
<UTable
:rows="filteredRows"
:columns="columns"
class="w-full"
:ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
@select="(i) => {selectedStatement = i; showStatementModal = true}"
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Buchungen anzuzeigen' }"
>
<template #account-data="{row}">
{{row.account ? (dataStore.getBankAccountById(row.account).name ? dataStore.getBankAccountById(row.account).name :dataStore.getBankAccountById(row.account).iban) : ""}}
</template>
<template #valueDate-data="{row}">
{{dayjs(row.valueDate).format("DD.MM.YY")}}
</template>
<template #amount-data="{row}">
<span
v-if="row.amount >= 0"
class="text-primary-500"
>{{String(row.amount.toFixed(2)).replace(".",",")}} </span>
<span
v-else-if="row.amount < 0"
class="text-rose-500"
>{{String(row.amount.toFixed(2)).replace(".",",")}} </span>
</template>
<template #partner-data="{row}">
<span
v-if="row.amount < 0"
>
{{row.credName}}
</span>
<span
v-else-if="row.amount > 0"
>
{{row.debName}}
</span>
</template>
</UTable>
<USlideover
v-model="showStatementModal"
>
<UCard class="h-full">
<template #header>
<span v-if="selectedStatement.amount > 0">
{{selectedStatement.debName}}
</span>
<span v-else-if="selectedStatement.amount < 0">
{{selectedStatement.credName}}
</span>
</template>
<UTable
:rows="filteredRows"
:columns="itemColumns"
@select="selectItem"
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Noch keine Einträge' }"
>
<div class="truncate">
<p>Betrag: {{String(selectedStatement.amount.toFixed(2)).replace(".",",")}} </p>
<p>Buchungsdatum: {{dayjs(selectedStatement.date).format("DD.MM.YYYY")}}</p>
<p>Werstellungsdatum: {{dayjs(selectedStatement.valueDate).format("DD.MM.YYYY")}}</p>
<p>Partner: {{selectedStatement.amount > 0 ? selectedStatement.debName : selectedStatement.credName}}</p>
<p>Partner IBAN: {{selectedStatement.amount > 0 ? selectedStatement.debIban : selectedStatement.credIban}}</p>
<p>Konto: {{selectedStatement.account}}</p>
<p class="text-wrap">Beschreibung: <br>{{selectedStatement.text}}</p>
</div>
</UCard>
</UTable>
</div>
</USlideover>
</template>
<script setup>
import dayjs from "dayjs";
definePageMeta({
middleware: "auth"
})
const dataStore = useDataStore()
const router = useRouter()
const mode = ref("show")
const itemColumns = [
const selectedStatement = ref(null)
const showStatementModal = ref(false)
const templateColumns = [
{
key: "iban",
label: "IBAN",
key: "account",
label: "Konto",
sortable: true
},{
key: "valueDate",
label: "Valuta",
sortable: true
},
{
key: "bankId",
label: "Bank",
key: "amount",
label: "Betrag",
sortable: true
},
{
key: "ownerName",
label: "Besitzer",
key: "partner",
label: "Name",
sortable: true
},
{
key: "text",
label: "Beschreibung",
sortable: true
}
]
const selectItem = (item) => {
router.push(`/banking/statements/${item.id} `)
}
const selectedColumns = ref(templateColumns)
const columns = computed(() => templateColumns.filter((column) => selectedColumns.value.includes(column)))
const searchString = ref('')
const filterAccount = ref(dataStore.bankAccounts || [])
const filteredRows = computed(() => {
dataStore.bankAccounts = dataStore.bankAccounts.filter(account => account.used)
if(!searchString.value) {
return dataStore.bankAccounts
}
return dataStore.bankAccounts.filter(item => {
return Object.values(item).some((value) => {
return String(value).toLowerCase().includes(searchString.value.toLowerCase())
})
})
return useSearch(searchString.value, dataStore.bankStatements.filter(i => filterAccount.value.find(x => x.id === i.account)))
})
</script>

View File

@@ -1,83 +0,0 @@
<script setup>
import axios from "axios";
const bankingStore = useBankingStore()
const dataStore = useDataStore()
const newAccounts = ref([])
const selectedInstitution = ref("")
const institutions = ref([])
const setupPage = async () => {
const {data,error} = await axios({
url:`http://localhost:3002/banking/institutions`,
method: "GET"
})
console.log(data)
console.log(error)
institutions.value = data
}
const createLink = async () => {
const {data,error} = await axios({
method: "POST",
url:`http://localhost:3002/banking/link?tenant=${dataStore.currentTenant}&institution_id=${selectedInstitution.value}`,
})
console.log(data)
console.log(error)
if(data.link) {
window.open(data.link,"_blank")
}
}
setupPage()
</script>
<template>
<UDashboardNavbar
title="Neues Bankkonto anbinden"
>
</UDashboardNavbar>
<UDashboardToolbar>
<template #right>
<UButton
@click="createLink"
>
Weiter
</UButton>
</template>
</UDashboardToolbar>
<UForm class="p-5">
<UFormGroup
label="Bank auswählen:"
>
<USelectMenu
:options="institutions"
searchable
v-model="selectedInstitution"
value-attribute="id"
option-attribute="name"
/>
</UFormGroup>
</UForm>
</template>
<style scoped>
</style>

View File

@@ -370,6 +370,7 @@ setupPage()
</UTable>
<DocumentList :documents="dataStore.getDocumentsByProjectId(currentItem.id)"/>
{{dataStore.getDocumentsByProjectId(currentItem.id)}}
</div>

View File

@@ -0,0 +1,190 @@
<script setup>
import axios from "axios";
const dataStore = useDataStore()
const route = useRoute()
const supabase = useSupabaseClient()
const toast = useToast()
const showAddBankRequisition = ref(false)
const bicBankToAdd = ref("")
const bankData = ref({})
const reqData = ref({})
const setupPage = async () => {
if(route.query.reqId) {
const {data,error} = await axios({
url:`http://localhost:3002/banking/requisitions/${route.query.reqId}`,
method: "GET"
})
if(data) {
reqData.value = data
}
}
}
const checkBIC = async () => {
const {data,error} = await axios({
url:`http://localhost:3002/banking/institutions/${bicBankToAdd.value}`,
method: "GET",
})
if(data) {
bankData.value = data
}
console.log(data)
console.log(error)
}
const generateLink = async () => {
const {data,error} = await axios({
url:`http://localhost:3002/banking/link?tenant=${dataStore.currentTenant}&institution_id=${bankData.value.id}`,
method: "POST",
})
console.log(data)
console.log(error)
if(data) {
await navigateTo(data.link, {
open: {
target: "_blank"
}
})
}
}
const addAccount = async (account) => {
let accountData = {
accountId: account.id,
ownerName: account.owner_name,
iban: account.iban,
tenant: dataStore.currentTenant,
bankId: account.institution_id
}
const {data,error} = await supabase.from("bankaccounts").insert(accountData).select()
if(error) {
toast.add({title: "Es gab einen Fehler bei hinzufügen des Accounts", color:"rose"})
} else if(data) {
toast.add({title: "Account erfolgreich hinzugefügt"})
}
}
setupPage()
</script>
<template>
<UDashboardNavbar title="Bankkonten">
<template #right>
<UButton
@click="showAddBankRequisition = true"
>
+ Bankverbindung
</UButton>
<USlideover
v-model="showAddBankRequisition"
>
<UCard
class="h-full"
>
<template #header>
<p>Bankverbindung hinzufügen</p>
</template>
<UFormGroup
label="BIC:"
class="flex-auto"
>
<InputGroup class="w-full">
<UInput
v-model="bicBankToAdd"
class="flex-auto"
/>
<UButton
@click="checkBIC"
>
Check
</UButton>
</InputGroup>
</UFormGroup>
<UAlert
v-if="bankData.id && bankData.countries.includes('DE')"
title="Bank gefunden"
icon="i-heroicons-check"
color="primary"
variant="outline"
class="mt-3"
/>
<UButton
@click="generateLink"
class="mt-3"
>
Verbinden
</UButton>
</UCard>
</USlideover>
</template>
</UDashboardNavbar>
<div
v-for="account in reqData.accounts"
class="p-2 m-3 flex justify-between"
>
{{account.iban}} - {{account.owner_name}}
<UButton
@click="addAccount(account)"
v-if="!dataStore.bankAccounts.find(i => i.accountId === account.id)"
>
+ Konto
</UButton>
</div>
<!-- <UButton @click="setupPage">Setup</UButton>
<div v-if="route.query.reqId">
{{reqData}}
</div>-->
<UTable
:rows="dataStore.bankAccounts"
:columns="[
{
key: 'name',
label: 'Name'
},{
key: 'iban',
label: 'IBAN'
},{
key: 'bankId',
label: 'Bank'
},{
key: 'ownerName',
label: 'Kontoinhaber'
},{
key: 'balance',
label: 'Saldo'
},
]"
>
</UTable>
</template>
<style scoped>
</style>

View File

@@ -1113,6 +1113,10 @@ export const useDataStore = defineStore('data', () => {
return inventoryitems.value.find(item => item.id === itemId)
})
const getBankAccountById = computed(() => (itemId) => {
return bankAccounts.value.find(item => item.id === itemId)
})
const getProjectById = computed(() => (itemId) => {
if(projects.value.find(i => i.id === itemId)) {
let project = projects.value.find(project => project.id === itemId)
@@ -1279,6 +1283,7 @@ export const useDataStore = defineStore('data', () => {
getPlantById,
getCreatedDocumentById,
getInventoryItemById,
getBankAccountById,
}