Files
portal-api/app/Http/Controllers/Api/Admin/Customer/CustomerController.php
T

514 lines
16 KiB
PHP

<?php
namespace App\Http\Controllers\Api\Admin\Customer;
use App\Http\Controllers\Controller;
use App\Http\Requests\CreateCustomerRequest;
use App\Http\Resources\Api\Admin\CustomerResource;
use App\Jobs\Mail\PasswordRecoverJob;
use App\Models\Customer;
use App\Models\Invoice;
use App\Models\Order;
use App\Models\Transaction;
use App\Repositories\Customer\CustomerRepositoryInterface;
use App\Repositories\Invoice\InvoiceRepositoryInterface;
use App\Repositories\InvoiceItem\InvoiceItemRepositoryInterface;
use App\Repositories\Module\Domain\DomainRepositoryInterface;
use App\Repositories\Module\Hosting\HostingRepositoryInterface as ModuleHostingRepositoryInterface;
use App\Repositories\Module\Vmware\VmwareRepositoryInterface;
use App\Repositories\Order\OrderRepositoryInterface;
use App\Repositories\Service\ServiceRepositoryInterface;
use App\Repositories\Transaction\TransactionRepositoryInterface;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
class CustomerController extends Controller
{
public function __construct(
private readonly CustomerRepositoryInterface $customerRepository,
private readonly InvoiceRepositoryInterface $invoiceRepository,
private readonly InvoiceItemRepositoryInterface $invoiceItemRepository,
private readonly ModuleHostingRepositoryInterface $moduleHostingRepository,
private readonly VmwareRepositoryInterface $vmwareRepository,
private readonly OrderRepositoryInterface $orderRepository,
private readonly TransactionRepositoryInterface $transactionRepository,
private readonly DomainRepositoryInterface $moduleDomainRepository,
private readonly ServiceRepositoryInterface $serviceRepository,
) {}
public function index(Request $request): JsonResponse
{
$perPage = min((int) $request->get('per_page', 15), 500);
$query = $this->customerRepository->filter(
$request->all(),
[],
['hosting', 'vps', 'domain'],
['*'],
true
);
$paginator = $query->paginate($perPage);
return response()->json([
'error' => false,
'data' => [
'items' => CustomerResource::collection($paginator),
'total' => $paginator->total(),
'per_page' => $paginator->perPage(),
'current_page' => $paginator->currentPage(),
'last_page' => $paginator->lastPage(),
],
]);
}
public function store(CreateCustomerRequest $request): JsonResponse
{
$request->validated();
$existingCustomer = $this->customerRepository->findBy('email', $request->get('email'));
if ($existingCustomer) {
return response()->json([
'error' => true,
'message' => 'Email already exists on the system!'
], 422);
}
try {
DB::beginTransaction();
$data = $request->all();
$data['password'] = Hash::make($request->password);
$data['email_marketing'] = $request->email_marketing === "on" ? 1 : 0;
$customer = $this->customerRepository->create($data);
DB::commit();
return response()->json([
'error' => false,
'message' => 'Customer created successfully',
'data' => new CustomerResource($customer)
], 201);
} catch (\Exception $e) {
DB::rollBack();
return response()->json([
'error' => true,
'message' => $e->getMessage()
], 500);
}
}
public function show(string $uuid): JsonResponse
{
$customer = $this->customerRepository->findBy('uuid', $uuid);
if (!$customer) {
return response()->json([
'error' => true,
'message' => "Can't find customer by UUID #" . $uuid
], 404);
}
$customer = $this->customerRepository->findWithRelationships(
$customer->id,
['mail', 'file'],
[
'invoice' => [
'invoices_status_count_1' => ['key' => 'status', 'condition' => '=', 'value' => 1],
'invoices_status_count_0' => ['key' => 'status', 'condition' => '=', 'value' => 0]
],
'hosting' => 'hosting_count',
'vps' => 'vps_count',
'domain' => 'domain_count',
'ticket' => 'ticket_count'
],
[
'invoice' => [
'invoices_status_1' => ['key' => 'status', 'condition' => '=', 'value' => 1, 'sum' => 'total'],
'invoices_status_0' => ['key' => 'status', 'condition' => '=', 'value' => 0, 'sum' => 'total']
]
]
);
if (!$customer) {
return response()->json([
'error' => true,
'message' => "Can't find customer by UUID #" . $uuid
], 404);
}
return response()->json([
'error' => false,
'data' => new CustomerResource($customer)
]);
}
public function update(string $uuid, CreateCustomerRequest $request): JsonResponse
{
$customer = $this->customerRepository->findBy('uuid', $uuid);
if (!$customer) {
return response()->json([
'error' => true,
'message' => "Can't find customer by UUID #" . $uuid
], 404);
}
$request->validated();
try {
DB::beginTransaction();
$data = $request->except(['_token', 'password']);
if (!empty($request->password)) {
$data['password'] = Hash::make($request->password);
}
$this->customerRepository->update($customer->id, $data);
DB::commit();
return response()->json([
'error' => false,
'message' => 'Customer updated successfully',
'data' => new CustomerResource($this->customerRepository->find($customer->id))
]);
} catch (\Exception $e) {
DB::rollBack();
return response()->json([
'error' => true,
'message' => $e->getMessage()
], 500);
}
}
public function destroy(string $uuid): JsonResponse
{
$customer = $this->customerRepository->findBy('uuid', $uuid);
if (!$customer) {
return response()->json([
'error' => true,
'message' => "Can't find customer by UUID #" . $uuid
], 404);
}
try {
DB::beginTransaction();
Invoice::where('customer_id', $customer->id)->delete();
Order::where('customer_id', $customer->id)->delete();
Transaction::where('customer_id', $customer->id)->delete();
$customer->delete();
DB::commit();
return response()->json([
'error' => false,
'message' => 'Customer deleted successfully'
]);
} catch (\Exception $e) {
DB::rollBack();
return response()->json([
'error' => true,
'message' => $e->getMessage()
], 500);
}
}
public function trash(Request $request): JsonResponse
{
$query = $this->customerRepository->onlyTrashed([], ['hosting', 'vps', 'domain']);
return response()->json([
'error' => false,
'data' => CustomerResource::collection($query->get())
]);
}
public function restore(string $uuid): JsonResponse
{
$customer = $this->customerRepository->findBy('uuid', $uuid);
if (!$customer) {
$customer = $this->customerRepository->onlyTrashed()->where('uuid', $uuid)->first();
}
if (!$customer) {
return response()->json([
'error' => true,
'message' => "Can't find customer by UUID #" . $uuid
], 404);
}
try {
DB::beginTransaction();
$customer->restore();
Invoice::withTrashed()->where('customer_id', $customer->id)->restore();
Order::withTrashed()->where('customer_id', $customer->id)->restore();
Transaction::withTrashed()->where('customer_id', $customer->id)->restore();
DB::commit();
return response()->json([
'error' => false,
'message' => 'Customer restored successfully'
]);
} catch (\Exception $e) {
DB::rollBack();
return response()->json([
'error' => true,
'message' => $e->getMessage()
], 500);
}
}
public function forceDelete(string $uuid): JsonResponse
{
$customer = $this->customerRepository->onlyTrashed()->where('uuid', $uuid)->first();
if (!$customer) {
return response()->json([
'error' => true,
'message' => "Can't find customer by UUID #" . $uuid
], 404);
}
try {
DB::beginTransaction();
Invoice::withTrashed()->where('customer_id', $customer->id)->forceDelete();
Order::withTrashed()->where('customer_id', $customer->id)->forceDelete();
Transaction::withTrashed()->where('customer_id', $customer->id)->forceDelete();
$customer->forceDelete();
DB::commit();
return response()->json([
'error' => false,
'message' => 'Customer permanently deleted'
]);
} catch (\Exception $e) {
DB::rollBack();
return response()->json([
'error' => true,
'message' => $e->getMessage()
], 500);
}
}
public function resetPassword(Request $request, string $uuid): JsonResponse
{
$customer = $this->customerRepository->findBy('uuid', $uuid);
if (!$customer) {
return response()->json([
'error' => true,
'message' => "Can't find customer by UUID #" . $uuid
], 404);
}
$password = Str::random(10);
try {
DB::beginTransaction();
$this->customerRepository->update($customer->id, ['password' => Hash::make($password)]);
DB::commit();
return response()->json([
'error' => false,
'message' => 'Password reset successfully',
'data' => ['new_password' => $password]
]);
} catch (\Exception $e) {
DB::rollBack();
return response()->json([
'error' => true,
'message' => $e->getMessage()
], 500);
}
}
public function addCredit(Request $request, string $uuid): JsonResponse
{
$request->validate([
'amount' => 'required|numeric|min:1',
'action' => 'required|in:+,-'
]);
$customer = $this->customerRepository->findBy('uuid', $uuid);
if (!$customer) {
return response()->json([
'error' => true,
'message' => "Can't find customer by UUID #" . $uuid
], 404);
}
try {
DB::beginTransaction();
$amount = (int) $request->amount;
if ($request->action === "+") {
$this->customerRepository->update($customer->id, [
'credit' => (int) $customer->credit + $amount,
'total' => (int) $customer->total + $amount,
]);
} else {
$this->customerRepository->update($customer->id, [
'credit' => (int) $customer->credit - $amount,
'total' => (int) $customer->total - $amount,
]);
}
DB::commit();
return response()->json([
'error' => false,
'message' => 'Credit updated successfully'
]);
} catch (\Exception $e) {
DB::rollBack();
return response()->json([
'error' => true,
'message' => $e->getMessage()
], 500);
}
}
public function getProducts(string $uuid): JsonResponse
{
$customer = $this->customerRepository->findBy('uuid', $uuid);
if (!$customer) {
return response()->json([
'error' => true,
'message' => "Can't find customer by UUID #" . $uuid
], 404);
}
$hostingServices = $this->moduleHostingRepository->filter(['customer_id' => $customer->id], ['server']);
$vpsServices = $this->vmwareRepository->filter(
['customer_id' => $customer->id],
['ipaddress.host.datacenter.vCenter', 'os.osGroup']
);
$allService = collect();
foreach ($hostingServices as $hosting) {
$allService->push([
'product_id' => $hosting->id,
'product_type' => 3,
'name' => $hosting->name,
'description' => $hosting->name . ' (Hosting)'
]);
}
foreach ($vpsServices as $vps) {
$allService->push([
'product_id' => $vps->id,
'product_type' => 4,
'name' => $vps->name,
'description' => $vps->name . ' (VPS)'
]);
}
return response()->json([
'error' => false,
'data' => $allService->values()
]);
}
public function getInvoices(string $uuid, Request $request): JsonResponse
{
$customer = $this->customerRepository->findBy('uuid', $uuid);
if (!$customer) {
return response()->json([
'error' => true,
'message' => "Can't find customer by UUID #" . $uuid
], 404);
}
$invoices = $this->invoiceRepository->filter(
['customer_id' => $customer->id],
['payment']
);
return response()->json([
'error' => false,
'data' => $invoices
]);
}
public function getTransactions(string $uuid, Request $request): JsonResponse
{
$customer = $this->customerRepository->findBy('uuid', $uuid);
if (!$customer) {
return response()->json([
'error' => true,
'message' => "Can't find customer by UUID #" . $uuid
], 404);
}
$transactions = $this->transactionRepository->filter(['customer_id' => $customer->id]);
return response()->json([
'error' => false,
'data' => $transactions
]);
}
public function getDomains(string $uuid, Request $request): JsonResponse
{
$customer = $this->customerRepository->findBy('uuid', $uuid);
if (!$customer) {
return response()->json([
'error' => true,
'message' => "Can't find customer by UUID #" . $uuid
], 404);
}
$domains = $this->moduleDomainRepository->filter(
['customer_id' => $customer->id],
['customer']
);
return response()->json([
'error' => false,
'data' => $domains
]);
}
public function getServices(string $uuid, Request $request): JsonResponse
{
$services = $this->serviceRepository->filter(
['customer_uuid' => $uuid],
['product', 'orderItem', 'invoice']
);
return response()->json([
'error' => false,
'data' => $services
]);
}
public function getOrders(string $uuid, Request $request): JsonResponse
{
$customer = $this->customerRepository->findBy('uuid', $uuid);
if (!$customer) {
return response()->json([
'error' => true,
'message' => "Can't find customer by UUID #" . $uuid
], 404);
}
$orders = $this->orderRepository->filter(
['client' => $customer->id],
['customer', 'payment', 'invoice']
);
return response()->json([
'error' => false,
'data' => $orders
]);
}
}