Add 'sleep' status to Production model and update related components

- Introduced a new 'sleep' boolean field in the Production model to indicate if production is suspended.
- Updated FalukantService to include 'sleep' in the production attributes.
- Enhanced MessagesDialog and ProductionSection components to display the production status and handle branch names.
- Added corresponding translations for 'status', 'sleep', and 'active' in both German and English locale files.
This commit is contained in:
Torsten Schulz (local)
2026-01-14 15:29:53 +01:00
parent d1359ccc36
commit 02d24eccd8
6 changed files with 65 additions and 10 deletions

View File

@@ -22,7 +22,12 @@ Production.init({
startTimestamp: { startTimestamp: {
type: DataTypes.DATE, type: DataTypes.DATE,
allowNull: false, allowNull: false,
defaultValue: sequelize.literal('CURRENT_TIMESTAMP')} defaultValue: sequelize.literal('CURRENT_TIMESTAMP')},
sleep: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false,
comment: 'Produktion ist zurückgestellt'}
}, { }, {
sequelize, sequelize,
modelName: 'Production', modelName: 'Production',

View File

@@ -838,7 +838,7 @@ class FalukantService extends BaseService {
{ {
model: Production, model: Production,
as: 'productions', as: 'productions',
attributes: ['quantity', 'startTimestamp'], attributes: ['quantity', 'startTimestamp', 'sleep'],
include: [{ model: ProductType, as: 'productType', attributes: ['id', 'category', 'labelTr', 'sellCost', 'productionTime'] }] include: [{ model: ProductType, as: 'productType', attributes: ['id', 'category', 'labelTr', 'sellCost', 'productionTime'] }]
} }
], ],

View File

@@ -51,17 +51,31 @@ export default {
size: 10, size: 10,
total: 0, total: 0,
pageInput: 1, pageInput: 1,
branches: [], // Cache für Branch-Namen
}; };
}, },
methods: { methods: {
async open() { async open() {
this.page = 1; this.page = 1;
this.pageInput = 1; this.pageInput = 1;
await this.loadBranches(); // Branches laden für Branch-Namen
await this.load(); await this.load();
this.$refs.dlg.open(); this.$refs.dlg.open();
// mark unread as shown // mark unread as shown
try { await apiClient.post('/api/falukant/notifications/mark-shown'); } catch {} try { await apiClient.post('/api/falukant/notifications/mark-shown'); } catch {}
}, },
async loadBranches() {
try {
const result = await apiClient.get('/api/falukant/branches');
this.branches = result.data.map(branch => ({
id: branch.id,
cityName: branch.region.name,
}));
} catch (error) {
console.error('Error loading branches:', error);
this.branches = [];
}
},
async markAll() { async markAll() {
try { try {
await apiClient.post('/api/falukant/notifications/mark-shown'); await apiClient.post('/api/falukant/notifications/mark-shown');
@@ -268,9 +282,14 @@ export default {
formatted.value = Number(params.value); formatted.value = Number(params.value);
} }
// Filiale-Information // Filiale-Information mit Branch-Namen
if (params.branch_id !== undefined && params.branch_id !== null) { if (params.branch_id !== undefined && params.branch_id !== null) {
const branch = this.branches.find(b => b.id === params.branch_id);
if (branch && branch.cityName) {
formatted.branch_info = ` (${branch.cityName})`;
} else {
formatted.branch_info = ` (Filiale #${params.branch_id})`; formatted.branch_info = ` (Filiale #${params.branch_id})`;
}
} else { } else {
formatted.branch_info = ''; formatted.branch_info = '';
} }

View File

@@ -9,6 +9,7 @@
<th>{{ $t('falukant.branch.production.quantity') }}</th> <th>{{ $t('falukant.branch.production.quantity') }}</th>
<th>{{ $t('falukant.branch.production.ending') }}</th> <th>{{ $t('falukant.branch.production.ending') }}</th>
<th>{{ $t('falukant.branch.production.remainingTime') }}</th> <th>{{ $t('falukant.branch.production.remainingTime') }}</th>
<th>{{ $t('falukant.branch.production.status') }}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -16,7 +17,11 @@
<td>{{ $t(`falukant.product.${production.productType.labelTr}`) }}</td> <td>{{ $t(`falukant.product.${production.productType.labelTr}`) }}</td>
<td>{{ production.quantity }}</td> <td>{{ production.quantity }}</td>
<td>{{ calculateEndDateTime(production.startTimestamp, production.productType.productionTime) }}</td> <td>{{ calculateEndDateTime(production.startTimestamp, production.productType.productionTime) }}</td>
<td>{{ calculateRemainingTime(production.startTimestamp, production.productType.productionTime) }} s</td> <td>{{ production.sleep ? '-' : calculateRemainingTime(production.startTimestamp, production.productType.productionTime) + ' s' }}</td>
<td>
<span v-if="production.sleep" class="production-sleep">{{ $t('falukant.branch.production.sleep') }}</span>
<span v-else>{{ $t('falukant.branch.production.active') }}</span>
</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@@ -320,7 +320,10 @@
"current": "Laufende Produktionen", "current": "Laufende Produktionen",
"product": "Produkt", "product": "Produkt",
"remainingTime": "Verbleibende Zeit (Sekunden)", "remainingTime": "Verbleibende Zeit (Sekunden)",
"noProductions": "Keine laufenden Produktionen." "noProductions": "Keine laufenden Produktionen.",
"status": "Status",
"sleep": "Zurückgestellt",
"active": "Aktiv"
}, },
"columns": { "columns": {
"city": "Stadt", "city": "Stadt",

View File

@@ -192,8 +192,31 @@
"storage": "Storage", "storage": "Storage",
"transport": "Transport", "transport": "Transport",
"taxes": "Taxes" "taxes": "Taxes"
} },
,"taxes": { "production": {
"title": "Production",
"info": "Details about production in the branch.",
"selectProduct": "Select product",
"quantity": "Quantity",
"storageAvailable": "Free storage",
"cost": "Cost",
"duration": "Duration",
"revenue": "Revenue",
"start": "Start production",
"success": "Production started successfully!",
"error": "Error starting production.",
"minutes": "Minutes",
"ending": "Completed:",
"time": "Time",
"current": "Running productions",
"product": "Product",
"remainingTime": "Remaining time (seconds)",
"noProductions": "No running productions.",
"status": "Status",
"sleep": "Suspended",
"active": "Active"
},
"taxes": {
"title": "Taxes", "title": "Taxes",
"loading": "Loading tax data...", "loading": "Loading tax data...",
"loadingError": "Failed to load tax data: {error}", "loadingError": "Failed to load tax data: {error}",