From 28ce4ed264e0c02d9d299878136fa84cdb4225ca Mon Sep 17 00:00:00 2001 From: Darko Gjorgjijoski Date: Thu, 20 Aug 2026 23:48:38 +0200 Subject: [PATCH] feat(accounts): fresh admin companies and profile controllers --- .../Controllers/Admin/CompaniesController.php | 111 ++++++++++++++++++ .../Company/UserProfileController.php | 82 +++++++++++++ 2 files changed, 193 insertions(+) create mode 100644 app/Domains/Accounts/Http/Controllers/Admin/CompaniesController.php create mode 100644 app/Domains/Accounts/Http/Controllers/Company/UserProfileController.php diff --git a/app/Domains/Accounts/Http/Controllers/Admin/CompaniesController.php b/app/Domains/Accounts/Http/Controllers/Admin/CompaniesController.php new file mode 100644 index 00000000..1f9e5d2b --- /dev/null +++ b/app/Domains/Accounts/Http/Controllers/Admin/CompaniesController.php @@ -0,0 +1,111 @@ +with(['owner', 'address']) + ->when($request->has('search'), function ($query) use ($request) { + $query->where('name', 'like', '%'.$request->search.'%'); + }) + ->when($request->has('orderByField') && $request->has('orderBy'), function ($query) use ($request) { + $query->orderBy($request->orderByField, $request->orderBy); + }, function ($query) { + $query->orderBy('name', 'asc'); + }) + ->paginate($request->input('limit', 10)); + + return CompanyResource::collection($companies); + } + + public function show(Company $company) + { + $company->load(['owner', 'address']); + + return new CompanyResource($company); + } + + public function update(AdminCompanyUpdateRequest $request, Company $company) + { + $company->update([ + 'name' => $request->name, + 'vat_id' => $request->vat_id, + 'tax_id' => $request->tax_id, + 'owner_id' => $request->owner_id, + ]); + + if ($request->has('address')) { + $this->companyAddressWriter->upsert($company, $request->validated('address')); + } + + $company->load(['owner', 'address']); + + return new CompanyResource($company); + } + + public function store(CompaniesRequest $request) + { + $this->authorize('create company'); + + $user = $request->user(); + $company = Company::query()->create($request->getCompanyPayload()); + $company->unique_hash = Hashids::connection(HashidConnection::Company->value)->encode($company->id); + $company->save(); + $this->companyService->setupDefaults($company, (int) $request->validated('currency')); + $user->companies()->attach($company->id); + + BouncerFacade::scope()->to($company->id); + $user->assign('owner'); + + if ($request->address) { + $this->companyAddressWriter->upsert($company, $request->validated('address')); + } + + return new CompanyResource($company); + } + + public function destroy(Request $request) + { + $company = Company::query()->find($request->header('company')); + + $this->authorize('delete company', $company); + + if ($company->name !== $request->input('name')) { + return respondJson( + 'company_name_must_match_with_given_name', + 'Company name must match with given name' + ); + } + + $this->companyService->delete($company); + + return response()->json([ + 'success' => true, + ]); + } + + public function userCompanies(Request $request) + { + return CompanyResource::collection($request->user()->companies); + } +} diff --git a/app/Domains/Accounts/Http/Controllers/Company/UserProfileController.php b/app/Domains/Accounts/Http/Controllers/Company/UserProfileController.php new file mode 100644 index 00000000..d8b6d4bf --- /dev/null +++ b/app/Domains/Accounts/Http/Controllers/Company/UserProfileController.php @@ -0,0 +1,82 @@ +user()); + } + + public function update(ProfileRequest $request) + { + $account = $request->user(); + + $account->update($request->validated()); + + return new UserResource($account); + } + + /** + * Attach, swap or drop the caller's profile picture. + * + * Three things can arrive on one call and each is handled in turn, so a + * payload carrying both a removal flag and a picture ends up with the + * picture, and a payload carrying both transports ends up with whatever + * came in as base64. Only the two picture branches check that somebody is + * actually signed in; the removal branch does not. Kept as it stands. + */ + public function uploadAvatar(AvatarRequest $request) + { + $user = $request->user(); + + if ($request->is_admin_avatar_removed ?? false) { + $this->userAvatarManager->clear($user); + } + if ($user && $request->hasFile('admin_avatar')) { + $file = $request->file('admin_avatar'); + $this->userAvatarManager->replaceFile( + $user, + $file->getRealPath(), + $file->getClientOriginalName(), + ); + } + + if ($user !== null && $request->has('avatar')) { + $encoded = $request->avatar; + $data = json_decode($encoded); + $this->userAvatarManager->replaceBase64($user, $data->data, $data->name); + } + + return new UserResource($user); + } + + public function showSettings(GetSettingsRequest $request): JsonResponse + { + $user = $request->user(); + + return response()->json($user->getSettings((array) $request->settings)); + } + + public function updateSettings(UpdateSettingsRequest $request): JsonResponse + { + $request->user()->setSettings($request->settings); + + return response()->json(['success' => true]); + } +}