Import export templates

This commit is contained in:
Simon Pocrnjič
2025-12-28 14:29:07 +01:00
parent 36b63a180d
commit b9f66cbfbe
3 changed files with 446 additions and 7 deletions
@@ -23,6 +23,16 @@ public function index()
->orderBy('name')
->get();
// Preload options for import mapping
$clients = Client::query()
->join('person', 'person.id', '=', 'clients.person_id')
->orderBy('person.full_name')
->get(['clients.uuid', DB::raw('person.full_name as name')]);
$segments = Segment::query()->orderBy('name')->get(['id', 'name']);
$decisions = Decision::query()->orderBy('name')->get(['id', 'name']);
$actions = Action::query()->orderBy('name')->get(['id', 'name']);
return Inertia::render('Imports/Templates/Index', [
'templates' => $templates->map(fn ($t) => [
'uuid' => $t->uuid,
@@ -35,6 +45,10 @@ public function index()
'name' => $t->client->person?->full_name,
] : null,
]),
'clients' => $clients,
'segments' => $segments,
'decisions' => $decisions,
'actions' => $actions,
]);
}
@@ -664,4 +678,138 @@ public function destroy(ImportTemplate $template)
return redirect()->route('importTemplates.index')->with('success', 'Template deleted');
}
// Export template as JSON file
public function export(ImportTemplate $template)
{
$template->load('mappings');
$data = [
'name' => $template->name,
'description' => $template->description,
'source_type' => $template->source_type,
'default_record_type' => $template->default_record_type,
'sample_headers' => $template->sample_headers,
'is_active' => $template->is_active,
'reactivate' => $template->reactivate,
'meta' => $template->meta,
'mappings' => $template->mappings->map(fn($m) => [
'source_column' => $m->source_column,
'entity' => $m->entity,
'target_field' => $m->target_field,
'transform' => $m->transform,
'apply_mode' => $m->apply_mode,
'options' => $m->options,
'position' => $m->position,
])->values()->toArray(),
];
$filename = Str::slug($template->name) . '-' . now()->format('Y-m-d') . '.json';
return response()->json($data)
->header('Content-Disposition', 'attachment; filename="' . $filename . '"');
}
// Import template from JSON file
public function import(Request $request)
{
$data = $request->validate([
'file' => 'required|file|mimes:json,txt|max:10240',
'client_uuid' => 'nullable|string|exists:clients,uuid',
'segment_id' => 'nullable|integer|exists:segments,id',
'decision_id' => 'nullable|integer|exists:decisions,id',
'action_id' => 'nullable|integer|exists:actions,id',
'activity_action_id' => 'nullable|integer|exists:actions,id',
'activity_decision_id' => 'nullable|integer|exists:decisions,id',
]);
$file = $request->file('file');
$contents = file_get_contents($file->getRealPath());
$json = json_decode($contents, true);
if (json_last_error() !== JSON_ERROR_NONE) {
return back()->withErrors(['file' => 'Invalid JSON file']);
}
// Validate structure
$validator = validator($json, [
'name' => 'required|string|max:100',
'description' => 'nullable|string|max:255',
'source_type' => 'required|string|in:csv,xml,xls,xlsx,json',
'default_record_type' => 'nullable|string|max:50',
'sample_headers' => 'nullable|array',
'is_active' => 'nullable|boolean',
'reactivate' => 'nullable|boolean',
'meta' => 'nullable|array',
'mappings' => 'nullable|array',
'mappings.*.source_column' => 'required|string',
'mappings.*.entity' => 'nullable|string',
'mappings.*.target_field' => 'nullable|string',
'mappings.*.transform' => 'nullable|string',
'mappings.*.apply_mode' => 'nullable|string|in:insert,update,both,keyref',
'mappings.*.options' => 'nullable|array',
'mappings.*.position' => 'nullable|integer',
]);
if ($validator->fails()) {
return back()->withErrors($validator)->withInput();
}
$clientId = null;
if (!empty($data['client_uuid'])) {
$clientId = Client::where('uuid', $data['client_uuid'])->value('id');
}
// Replace IDs in meta if provided
$meta = $json['meta'] ?? [];
if (!empty($data['segment_id'])) {
$meta['segment_id'] = $data['segment_id'];
}
if (!empty($data['decision_id'])) {
$meta['decision_id'] = $data['decision_id'];
}
if (!empty($data['action_id'])) {
$meta['action_id'] = $data['action_id'];
}
if (!empty($data['activity_action_id'])) {
$meta['activity_action_id'] = $data['activity_action_id'];
}
if (!empty($data['activity_decision_id'])) {
$meta['activity_decision_id'] = $data['activity_decision_id'];
}
$template = null;
DB::transaction(function () use (&$template, $request, $json, $clientId, $meta) {
$template = ImportTemplate::create([
'uuid' => (string) Str::uuid(),
'name' => $json['name'],
'description' => $json['description'] ?? null,
'source_type' => $json['source_type'],
'default_record_type' => $json['default_record_type'] ?? null,
'sample_headers' => $json['sample_headers'] ?? null,
'user_id' => $request->user()?->id,
'client_id' => $clientId,
'is_active' => $json['is_active'] ?? true,
'reactivate' => $json['reactivate'] ?? false,
'meta' => $meta,
]);
foreach (($json['mappings'] ?? []) as $m) {
ImportTemplateMapping::create([
'import_template_id' => $template->id,
'entity' => $m['entity'] ?? null,
'source_column' => $m['source_column'],
'target_field' => $m['target_field'] ?? null,
'transform' => $m['transform'] ?? null,
'apply_mode' => $m['apply_mode'] ?? 'both',
'options' => $m['options'] ?? null,
'position' => $m['position'] ?? null,
]);
}
});
return redirect()
->route('importTemplates.edit', ['template' => $template->uuid])
->with('success', 'Template imported successfully');
}
}