Files
dewemoji/app/app/Http/Controllers/Api/V1/AdminPricingController.php
2026-02-12 00:52:40 +07:00

142 lines
4.3 KiB
PHP

<?php
namespace App\Http\Controllers\Api\V1;
use App\Http\Controllers\Controller;
use App\Models\PricingChange;
use App\Models\PricingPlan;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class AdminPricingController extends Controller
{
private function authorizeAdmin(Request $request): ?JsonResponse
{
$adminToken = (string) config('dewemoji.admin.token', '');
$provided = trim((string) $request->header('X-Admin-Token', ''));
if ($adminToken === '' || $provided === '' || !hash_equals($adminToken, $provided)) {
return response()->json(['ok' => false, 'error' => 'unauthorized'], 401);
}
return null;
}
public function index(Request $request): JsonResponse
{
if ($res = $this->authorizeAdmin($request)) {
return $res;
}
$plans = PricingPlan::orderBy('id')->get();
return response()->json([
'ok' => true,
'plans' => $plans,
]);
}
public function changes(Request $request): JsonResponse
{
if ($res = $this->authorizeAdmin($request)) {
return $res;
}
$limit = max((int) $request->query('limit', 20), 1);
$items = PricingChange::orderByDesc('id')
->limit($limit)
->get();
return response()->json([
'ok' => true,
'items' => $items,
]);
}
public function update(Request $request): JsonResponse
{
if ($res = $this->authorizeAdmin($request)) {
return $res;
}
$data = $request->validate([
'admin_ref' => 'nullable|string|max:120',
'plans' => 'required|array|min:1',
'plans.*.code' => 'required|string|max:30',
'plans.*.name' => 'required|string|max:50',
'plans.*.currency' => 'required|string|max:10',
'plans.*.amount' => 'required|integer|min:0',
'plans.*.period' => 'nullable|string|max:20',
'plans.*.status' => 'nullable|string|max:20',
'plans.*.meta' => 'nullable|array',
]);
$before = PricingPlan::orderBy('id')->get()->toArray();
DB::transaction(function () use ($data): void {
foreach ($data['plans'] as $plan) {
PricingPlan::updateOrCreate(
['code' => $plan['code']],
[
'name' => $plan['name'],
'currency' => $plan['currency'],
'amount' => $plan['amount'],
'period' => $plan['period'] ?? null,
'status' => $plan['status'] ?? 'active',
'meta' => $plan['meta'] ?? null,
]
);
}
});
$after = PricingPlan::orderBy('id')->get()->toArray();
PricingChange::create([
'admin_ref' => $data['admin_ref'] ?? null,
'before' => $before,
'after' => $after,
]);
return response()->json([
'ok' => true,
'plans' => $after,
]);
}
public function reset(Request $request): JsonResponse
{
if ($res = $this->authorizeAdmin($request)) {
return $res;
}
$defaults = config('dewemoji.pricing.defaults', []);
$before = PricingPlan::orderBy('id')->get()->toArray();
DB::transaction(function () use ($defaults): void {
PricingPlan::query()->delete();
foreach ($defaults as $plan) {
PricingPlan::create([
'code' => $plan['code'],
'name' => $plan['name'],
'currency' => $plan['currency'],
'amount' => $plan['amount'],
'period' => $plan['period'],
'status' => $plan['status'],
'meta' => $plan['meta'] ?? null,
]);
}
});
$after = PricingPlan::orderBy('id')->get()->toArray();
PricingChange::create([
'admin_ref' => (string) $request->header('X-Admin-Ref', ''),
'before' => $before,
'after' => $after,
]);
return response()->json([
'ok' => true,
'plans' => $after,
]);
}
}