diff --git a/app/Http/Controllers/PredefinedMutationController.php b/app/Http/Controllers/PredefinedMutationController.php new file mode 100644 index 0000000..83b5929 --- /dev/null +++ b/app/Http/Controllers/PredefinedMutationController.php @@ -0,0 +1,46 @@ +authorize('update', $dynamic); + + return Inertia::render('Dynamics/PredefinedMutations/Index', [ + 'dynamic' => $dynamic, + 'predefined_mutations' => $dynamic->predefinedMutations()->latest()->get(), + ]); + } + + /** + * Store a newly created resource in storage. + */ + public function store(Request $request, Dynamic $dynamic) + { + $this->authorize('update', $dynamic); + + $request->validate([ + 'name' => ['required', 'string', 'max:255'], + 'description' => ['nullable', 'string'], + 'amount' => ['required', 'integer'], + 'type' => ['required', 'string', 'in:reward,penalty'], + ]); + + $dynamic->predefinedMutations()->create($request->all()); + + return redirect()->route('dynamics.predefined-mutations.index', $dynamic); + } +} diff --git a/app/Models/Mutation.php b/app/Models/Mutation.php index f4c1d91..67431c9 100644 --- a/app/Models/Mutation.php +++ b/app/Models/Mutation.php @@ -20,6 +20,7 @@ class Mutation extends Model 'amount', 'description', 'status', + 'predefined_mutation_id', ]; public function ledger(): BelongsTo @@ -32,6 +33,11 @@ class Mutation extends Model return $this->belongsTo(User::class); } + public function predefinedMutation(): BelongsTo + { + return $this->belongsTo(PredefinedMutation::class); + } + public function chat(): MorphOne { return $this->morphOne(Chat::class, 'chatable'); diff --git a/app/Models/PredefinedMutation.php b/app/Models/PredefinedMutation.php new file mode 100644 index 0000000..cdd1a0f --- /dev/null +++ b/app/Models/PredefinedMutation.php @@ -0,0 +1,25 @@ +belongsTo(Dynamic::class); + } +} diff --git a/app/Services/ActivityService.php b/app/Services/ActivityService.php index 42d7282..7b099a3 100644 --- a/app/Services/ActivityService.php +++ b/app/Services/ActivityService.php @@ -45,6 +45,31 @@ class ActivityService return $cursor ? $cursor->read_at : Carbon::parse('1970-01-01'); } + public function createMessage($chat, $user, $content, $subject = null) + { + $message = $chat->messages()->create([ + 'user_id' => $user ? $user->id : null, + 'content' => $content, + 'subject_id' => $subject ? $subject->id : null, + 'subject_type' => $subject ? get_class($subject) : null, + ]); + + return $message; + } + + public function createMutation($ledger, $user, $type, $amount, $description, $status) + { + $mutation = $ledger->mutations()->create([ + 'user_id' => $user->id, + 'type' => $type, + 'amount' => $amount, + 'description' => $description, + 'status' => $status, + ]); + + return $mutation; + } + /** * Retrieve all activities for a given entity. */ diff --git a/database/migrations/2026_06_16_225928_create_predefined_mutations_table.php b/database/migrations/2026_06_16_225928_create_predefined_mutations_table.php new file mode 100644 index 0000000..1f157e0 --- /dev/null +++ b/database/migrations/2026_06_16_225928_create_predefined_mutations_table.php @@ -0,0 +1,32 @@ +id(); + $table->foreignId('dynamic_id')->constrained()->cascadeOnDelete(); + $table->string('name'); + $table->text('description')->nullable(); + $table->integer('amount'); + $table->string('type')->default('reward'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('predefined_mutations'); + } +}; diff --git a/database/migrations/2026_06_16_225946_add_predefined_mutation_id_to_mutations_table.php b/database/migrations/2026_06_16_225946_add_predefined_mutation_id_to_mutations_table.php new file mode 100644 index 0000000..ccc3740 --- /dev/null +++ b/database/migrations/2026_06_16_225946_add_predefined_mutation_id_to_mutations_table.php @@ -0,0 +1,29 @@ +foreignId('predefined_mutation_id')->nullable()->constrained()->onDelete('set null'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('mutations', function (Blueprint $table) { + $table->dropForeign(['predefined_mutation_id']); + $table->dropColumn('predefined_mutation_id'); + }); + } +}; diff --git a/resources/js/pages/Dynamics/PredefinedMutations/Index.vue b/resources/js/pages/Dynamics/PredefinedMutations/Index.vue new file mode 100644 index 0000000..ae83851 --- /dev/null +++ b/resources/js/pages/Dynamics/PredefinedMutations/Index.vue @@ -0,0 +1,247 @@ + + + + + + + + + + + + Predefined Mutations for {{ dynamic.name }} + + + + + + + {{ mutation.name }} + + + {{ mutation.description }} + + + + {{ mutation.amount }} + + + + + + + + + + Create New Predefined Mutation + + + + + Name + + + + + Description + + + + + Amount + + + + + Type + + Reward + Penalty + + + + + + Create + + + + + + + + + + + diff --git a/resources/js/pages/Dynamics/Settings.vue b/resources/js/pages/Dynamics/Settings.vue index c461ce6..5aaeb8b 100644 --- a/resources/js/pages/Dynamics/Settings.vue +++ b/resources/js/pages/Dynamics/Settings.vue @@ -1,5 +1,5 @@
+ {{ mutation.description }} +