feat: Implement expense creation modal and API integration
- Added ExpenseCreateModal component for adding new expenses with form validation. - Integrated API endpoint for creating expenses, ensuring only authorized users can access it. - Updated dashboard to include functionality for adding expenses and refreshing the expense list after creation. - Enhanced UI with Vuetify components for better user experience and responsiveness.
This commit is contained in:
79
server/api/create-expense.ts
Normal file
79
server/api/create-expense.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import { requireSalesOrAdmin } from '@/server/utils/auth';
|
||||
import { getNocoDbConfiguration } from '@/server/utils/nocodb';
|
||||
import type { Expense } from '@/utils/types';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
// Ensure only sales/admin users can create expenses
|
||||
await requireSalesOrAdmin(event);
|
||||
|
||||
const body = await readBody(event);
|
||||
console.log('[create-expense] Creating expense with data:', body);
|
||||
|
||||
// Validate required fields
|
||||
const requiredFields = ['Establishment Name', 'Price', 'Category', 'Payer', 'Time'];
|
||||
for (const field of requiredFields) {
|
||||
if (!body[field]) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: `Missing required field: ${field}`
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Get NocoDB configuration
|
||||
const config = getNocoDbConfiguration();
|
||||
const expenseTableId = "mxfcefkk4dqs6uq"; // Expense table ID from nocodb.ts
|
||||
|
||||
// Prepare expense data for NocoDB
|
||||
const expenseData = {
|
||||
"Establishment Name": body["Establishment Name"],
|
||||
Price: body.Price,
|
||||
Category: body.Category,
|
||||
Payer: body.Payer,
|
||||
Time: body.Time,
|
||||
Contents: body.Contents || null,
|
||||
"Payment Method": body["Payment Method"] || "Card",
|
||||
currency: body.currency || "EUR",
|
||||
Paid: body.Paid || false
|
||||
};
|
||||
|
||||
console.log('[create-expense] Sending to NocoDB:', expenseData);
|
||||
|
||||
// Create the expense in NocoDB
|
||||
const response = await $fetch<Expense>(`${config.url}/api/v2/tables/${expenseTableId}/records`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'xc-token': config.token,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: expenseData
|
||||
});
|
||||
|
||||
console.log('[create-expense] Expense created successfully:', response.Id);
|
||||
|
||||
return response;
|
||||
|
||||
} catch (error: any) {
|
||||
console.error('[create-expense] Failed to create expense:', error);
|
||||
|
||||
if (error.statusCode === 403) {
|
||||
throw createError({
|
||||
statusCode: 403,
|
||||
statusMessage: 'Access denied. This feature requires sales team or administrator privileges.'
|
||||
});
|
||||
}
|
||||
|
||||
if (error.statusCode === 400) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: error.statusMessage
|
||||
});
|
||||
}
|
||||
|
||||
throw createError({
|
||||
statusCode: 500,
|
||||
statusMessage: 'Failed to create expense. Please try again later.'
|
||||
});
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user