Falukant production, family and administration enhancements

This commit is contained in:
Torsten Schulz
2025-04-14 15:17:35 +02:00
parent 90b4f51dcb
commit b15d93a798
77 changed files with 2429 additions and 1093 deletions

View File

@@ -0,0 +1,98 @@
<template>
<div class="revenue-section">
<h3>
<button @click="toggleRevenueTable">
{{ $t('falukant.branch.revenue.title') }}
{{ isRevenueTableOpen ? '' : '' }}
</button>
</h3>
<div v-if="isRevenueTableOpen" class="revenue-table">
<table>
<thead>
<tr>
<th>{{ $t('falukant.branch.revenue.product') }}</th>
<th>{{ $t('falukant.branch.revenue.knowledge') }}</th>
<th>{{ $t('falukant.branch.revenue.absolute') }}</th>
<th>{{ $t('falukant.branch.revenue.perMinute') }}</th>
<th>{{ $t('falukant.branch.revenue.profitAbsolute') }}</th>
<th>{{ $t('falukant.branch.revenue.profitPerMinute') }}</th>
</tr>
</thead>
<tbody>
<tr v-for="product in products" :key="product.id" :class="{ highlight: product.id === productWithMaxRevenuePerMinute?.id }">
<td>{{ $t(`falukant.product.${product.labelTr}`) }}</td>
<td>{{ product.knowledges && product.knowledges[0] ? product.knowledges[0].knowledge : 0 }}</td>
<td>{{ calculateProductRevenue(product).absolute }}</td>
<td>{{ calculateProductRevenue(product).perMinute }}</td>
<td>{{ calculateProductProfit(product).absolute }}</td>
<td>{{ calculateProductProfit(product).perMinute }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<script>
export default {
name: "RevenueSection",
props: {
products: { type: Array, required: true },
calculateProductRevenue: { type: Function, required: true },
calculateProductProfit: { type: Function, required: true },
},
data() {
return {
isRevenueTableOpen: false,
};
},
computed: {
productWithMaxRevenuePerMinute() {
if (!this.products || this.products.length === 0) return null;
return this.products.reduce((maxProduct, currentProduct) => {
const currentRevenue = parseFloat(this.calculateProductRevenue(currentProduct).perMinute);
const maxRevenue = maxProduct ? parseFloat(this.calculateProductRevenue(maxProduct).perMinute) : 0;
return currentRevenue > maxRevenue ? currentProduct : maxProduct;
}, null);
},
},
methods: {
toggleRevenueTable() {
this.isRevenueTableOpen = !this.isRevenueTableOpen;
},
},
};
</script>
<style scoped>
.revenue-section {
border: 1px solid #ccc;
margin: 10px 0;
border-radius: 4px;
padding: 10px;
}
.revenue-section button {
background: none;
border: none;
color: #007bff;
cursor: pointer;
font-size: 1em;
text-decoration: underline;
}
.revenue-table {
margin-top: 10px;
overflow-x: auto;
}
.revenue-table table {
width: 100%;
border-collapse: collapse;
}
th, td {
padding: 8px;
border: 1px solid #ddd;
}
.highlight {
background-color: #dfffd6;
}
</style>