diff --git a/app/Http/Controllers/LineItemController.php b/app/Http/Controllers/LineItemController.php
index e1ee58f..6f93efb 100644
--- a/app/Http/Controllers/LineItemController.php
+++ b/app/Http/Controllers/LineItemController.php
@@ -57,10 +57,9 @@ public function index($invoiceId)
* ;"Hosting";"Annual hosting";1.500,50;"lump sum";1.200,00
*
* @param Request $request The HTTP request with the CSV file
- * @param int $invoiceId The ID of the invoice for which the items will be imported
* @return \Illuminate\Http\JsonResponse A JSON response with the imported items or an error message
*/
- public function importFromCsv(Request $request, $invoiceId)
+ public function importFromCsv(Request $request)
{
$request->validate([
'csv' => 'required|file|mimes:csv,txt'
@@ -133,16 +132,22 @@ public function importFromCsv(Request $request, $invoiceId)
}
$lineItems[] = [
- 'invoice_id' => $invoiceId,
+ 'id' => 0,
+ 'invoice_id' => 0,
'position' => $position,
'is_section' => false,
'title' => $itemData['title'],
'description' => $itemData['description'] ?? '',
'quantity' => (float)$quantity,
'unit_id' => $unit->id,
+ 'unit' => [
+ 'id' => $unit->id,
+ 'name' => $unit->name,
+ 'symbol' => $unit->symbol,
+ 'created_at' => $unit->created_at,
+ 'updated_at' => $unit->updated_at,
+ ],
'price' => (float)$price,
- 'created_at' => now(),
- 'updated_at' => now()
];
}
@@ -150,28 +155,9 @@ public function importFromCsv(Request $request, $invoiceId)
return response()->json(['message' => 'No valid items found in the CSV file'], 400);
}
- // Delete existing items for this invoice
- LineItem::where('invoice_id', $invoiceId)->delete();
-
- // Insert new items
- LineItem::insert($lineItems);
-
- // Return the newly created items
- $items = LineItem::with('unit')
- ->where('invoice_id', $invoiceId)
- ->orderBy('position', 'asc')
- ->get();
-
- return $items->map(function ($item) {
- $itemArray = $item->toArray();
-
- if ($item->unit) {
- $itemArray['unit_name'] = $item->unit->name;
- $itemArray['unit_symbol'] = $item->unit->symbol;
- }
-
- return ApiDataTransformer::snakeToCamel($itemArray);
- });
+ return response()->json(
+ ApiDataTransformer::snakeToCamel($lineItems)
+ );
}
/**
diff --git a/resources/js/components/documents/LineItemTable.vue b/resources/js/components/documents/LineItemTable.vue
index 76be6a7..a9c8e38 100644
--- a/resources/js/components/documents/LineItemTable.vue
+++ b/resources/js/components/documents/LineItemTable.vue
@@ -2,20 +2,28 @@
+
+
+
+
+
+
diff --git a/resources/js/components/ui/command/CommandDialog.vue b/resources/js/components/ui/command/CommandDialog.vue
new file mode 100644
index 0000000..bccd25c
--- /dev/null
+++ b/resources/js/components/ui/command/CommandDialog.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
diff --git a/resources/js/components/ui/command/CommandEmpty.vue b/resources/js/components/ui/command/CommandEmpty.vue
new file mode 100644
index 0000000..d4d156f
--- /dev/null
+++ b/resources/js/components/ui/command/CommandEmpty.vue
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
diff --git a/resources/js/components/ui/command/CommandGroup.vue b/resources/js/components/ui/command/CommandGroup.vue
new file mode 100644
index 0000000..99df3a4
--- /dev/null
+++ b/resources/js/components/ui/command/CommandGroup.vue
@@ -0,0 +1,44 @@
+
+
+
+
+
+ {{ heading }}
+
+
+
+
diff --git a/resources/js/components/ui/command/CommandInput.vue b/resources/js/components/ui/command/CommandInput.vue
new file mode 100644
index 0000000..4f7e84a
--- /dev/null
+++ b/resources/js/components/ui/command/CommandInput.vue
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
diff --git a/resources/js/components/ui/command/CommandItem.vue b/resources/js/components/ui/command/CommandItem.vue
new file mode 100644
index 0000000..c6088e2
--- /dev/null
+++ b/resources/js/components/ui/command/CommandItem.vue
@@ -0,0 +1,75 @@
+
+
+
+ {
+ filterState.search = ''
+ }"
+ >
+
+
+
diff --git a/resources/js/components/ui/command/CommandList.vue b/resources/js/components/ui/command/CommandList.vue
new file mode 100644
index 0000000..d94b969
--- /dev/null
+++ b/resources/js/components/ui/command/CommandList.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
diff --git a/resources/js/components/ui/command/CommandSeparator.vue b/resources/js/components/ui/command/CommandSeparator.vue
new file mode 100644
index 0000000..799319b
--- /dev/null
+++ b/resources/js/components/ui/command/CommandSeparator.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
diff --git a/resources/js/components/ui/command/CommandShortcut.vue b/resources/js/components/ui/command/CommandShortcut.vue
new file mode 100644
index 0000000..6d95d73
--- /dev/null
+++ b/resources/js/components/ui/command/CommandShortcut.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
diff --git a/resources/js/components/ui/command/index.ts b/resources/js/components/ui/command/index.ts
new file mode 100644
index 0000000..af18933
--- /dev/null
+++ b/resources/js/components/ui/command/index.ts
@@ -0,0 +1,25 @@
+import type { Ref } from "vue"
+import { createContext } from "reka-ui"
+
+export { default as Command } from "./Command.vue"
+export { default as CommandDialog } from "./CommandDialog.vue"
+export { default as CommandEmpty } from "./CommandEmpty.vue"
+export { default as CommandGroup } from "./CommandGroup.vue"
+export { default as CommandInput } from "./CommandInput.vue"
+export { default as CommandItem } from "./CommandItem.vue"
+export { default as CommandList } from "./CommandList.vue"
+export { default as CommandSeparator } from "./CommandSeparator.vue"
+export { default as CommandShortcut } from "./CommandShortcut.vue"
+
+export const [useCommand, provideCommandContext] = createContext<{
+ allItems: Ref