Files
FEDEO/frontend/components/personalComposing.vue
2026-03-22 13:53:29 +01:00

172 lines
4.5 KiB
Vue

<script setup>
import { v4 as uuidv4 } from 'uuid';
const props = defineProps({
item: {
type: Object,
required: true
}
})
const hourrates = ref([])
const units = ref([])
const hourrateSearchInput = {
placeholder: 'Stundensatz suchen...'
}
const setup = async () => {
hourrates.value = await useEntities("hourrates").select()
units.value = await useEntities("units").selectSpecial()
}
setup()
const addRowToPersonalComposition = () => {
if(!props.item.personalComposition) props.item.personalComposition = []
props.item.personalComposition.push({
id: uuidv4(),
unit: 6,
quantity: 1,
price: 0,
name: "Standard"
})
calculateTotalPersonalPrice()
}
const removeRowFromPersonalComposition = (id) => {
props.item.personalComposition = props.item.personalComposition.filter((item) => item.id !== id)
calculateTotalPersonalPrice()
}
const calculateTotalPersonalPrice = () => {
let total = 0
props.item.personalComposition.forEach((item) => {
let rowSum = item.quantity * item.price
total += rowSum
})
props.item.sellingPriceComposed.worker = Number(total.toFixed(2))
props.item.sellingPriceComposed.total = Number((props.item.sellingPriceComposed.worker + props.item.sellingPriceComposed.material).toFixed(2))
}
const setRowData = (row) => {
let hourrate = hourrates.value.find(i => i.id === row.hourrate)
row.purchasePrice = hourrate.purchasePrice
row.price = hourrate.sellingPrice
calculateTotalPersonalPrice()
}
</script>
<template>
<UCard class="w-full">
<UButton
@click="addRowToPersonalComposition"
>
+ Stundensatz
</UButton>
<div class="mt-3 overflow-x-auto">
<table class="w-full min-w-[52rem] table-fixed">
<thead>
<tr class="border-b border-gray-200 dark:border-gray-800">
<th class="px-2 py-2 text-left font-medium">Name</th>
<th class="px-2 py-2 text-left font-medium">Menge</th>
<th class="px-2 py-2 text-left font-medium">Einheit</th>
<th class="px-2 py-2 text-left font-medium">Einkaufspreis</th>
<th class="px-2 py-2 text-left font-medium">Verkaufspreis</th>
<th class="w-12 px-2 py-2"></th>
</tr>
</thead>
<tbody>
<tr
v-for="row in props.item.personalComposition"
:key="row.id"
class="border-b border-gray-100 align-top dark:border-gray-800"
>
<td class="px-2 py-2">
<USelectMenu
class="w-full"
:items="hourrates"
label-key="name"
value-key="id"
:search-input="hourrateSearchInput"
:filter-fields="['name']"
v-model="row.hourrate"
:color="row.hourrate ? 'primary' : 'error'"
@update:model-value="setRowData(row)"
>
<template #default>
{{ hourrates.find(i => i.id === row.hourrate)?.name || 'Kein Stundensatz ausgewählt' }}
</template>
</USelectMenu>
</td>
<td class="px-2 py-2">
<UInput
class="w-full"
type="number"
v-model="row.quantity"
:step="units.find(i => i.id === row.unit) ? units.find(i => i.id === row.unit).step : 1"
@change="calculateTotalPersonalPrice"
/>
</td>
<td class="px-2 py-2">
<USelectMenu
class="w-full"
:items="units"
disabled
label-key="name"
value-key="id"
v-model="row.unit"
>
<template #default>
{{ units.find(i => i.id === row.unit)?.name || 'Einheit' }}
</template>
</USelectMenu>
</td>
<td class="px-2 py-2">
<UInput
class="w-full"
type="number"
v-model="row.purchasePrice"
step="0.01"
@change="calculateTotalPersonalPrice"
/>
</td>
<td class="px-2 py-2">
<UInput
class="w-full"
type="number"
v-model="row.price"
step="0.01"
@change="calculateTotalPersonalPrice"
/>
</td>
<td class="px-2 py-2">
<UButton
icon="i-heroicons-x-mark"
@click="removeRowFromPersonalComposition(row.id)"
variant="outline"
color="error"
/>
</td>
</tr>
</tbody>
</table>
</div>
</UCard>
</template>
<style scoped>
td {
margin-bottom: 0.5em;
}
</style>