Add Ladill POS v1 — register, Pay checkout, and commerce links.
Deploy Ladill Mini / deploy (push) Successful in 23s
Deploy Ladill Mini / deploy (push) Successful in 23s
Staff-facing counter register at pos.ladill.com with catalog cart, cash and MoMo/card checkout via Ladill Pay, CRM timeline/import, invoice prefill, and Merchant catalog import. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\Mini;
|
||||
|
||||
use App\Http\Controllers\Api\Concerns\CallsIdentityApi;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\QrSetting;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class AccountController extends Controller
|
||||
{
|
||||
use CallsIdentityApi;
|
||||
|
||||
public function settings(): JsonResponse
|
||||
{
|
||||
$account = ladill_account();
|
||||
$settings = $account->getOrCreateQrSetting();
|
||||
|
||||
// Phone lives on the central account, not the local mirror — fetch it,
|
||||
// but never let a transient identity-API hiccup break settings loading.
|
||||
$phone = '';
|
||||
$phoneCc = '';
|
||||
try {
|
||||
$profile = $this->identitySend('GET', '/api/identity/profile?user='.urlencode((string) $account->public_id), []);
|
||||
if ($profile->successful()) {
|
||||
$phone = (string) $profile->json('data.phone', '');
|
||||
$phoneCc = (string) $profile->json('data.phone_cc', '');
|
||||
}
|
||||
} catch (\Throwable) {
|
||||
// leave phone blank
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'data' => [
|
||||
'profile' => [
|
||||
'name' => $account->name,
|
||||
'email' => $account->email,
|
||||
'phone' => $phone,
|
||||
'phone_cc' => $phoneCc,
|
||||
],
|
||||
'notifications' => [
|
||||
'notify_email' => $settings->notify_email ?: $account->email,
|
||||
'product_updates' => (bool) ($settings->product_updates ?? true),
|
||||
'notify_registrations' => (bool) ($settings->notify_registrations ?? true),
|
||||
'notify_payouts' => (bool) ($settings->notify_payouts ?? true),
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function updateSettings(Request $request): JsonResponse
|
||||
{
|
||||
$account = ladill_account();
|
||||
|
||||
$data = $request->validate([
|
||||
'notify_email' => ['nullable', 'email', 'max:255'],
|
||||
'product_updates' => ['sometimes', 'boolean'],
|
||||
'notify_registrations' => ['sometimes', 'boolean'],
|
||||
'notify_payouts' => ['sometimes', 'boolean'],
|
||||
]);
|
||||
|
||||
$settings = QrSetting::updateOrCreate(
|
||||
['user_id' => $account->id],
|
||||
[
|
||||
'notify_email' => $data['notify_email'] ?? $account->email,
|
||||
'product_updates' => $request->boolean('product_updates'),
|
||||
'notify_registrations' => $request->boolean('notify_registrations'),
|
||||
'notify_payouts' => $request->boolean('notify_payouts'),
|
||||
],
|
||||
);
|
||||
|
||||
return response()->json([
|
||||
'data' => [
|
||||
'notify_email' => $settings->notify_email,
|
||||
'product_updates' => (bool) $settings->product_updates,
|
||||
'notify_registrations' => (bool) $settings->notify_registrations,
|
||||
'notify_payouts' => (bool) $settings->notify_payouts,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function updateProfile(Request $request): JsonResponse
|
||||
{
|
||||
$account = ladill_account();
|
||||
|
||||
$data = $request->validate([
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'phone_cc' => ['nullable', 'string', 'max:8'],
|
||||
'phone' => ['nullable', 'string', 'max:32'],
|
||||
]);
|
||||
|
||||
$response = $this->identitySend('PUT', '/api/identity/profile', array_merge(
|
||||
['user' => $account->public_id],
|
||||
$data,
|
||||
));
|
||||
$this->rethrowValidation($response, 'name');
|
||||
|
||||
if ($response->successful()) {
|
||||
$account->update(['name' => $data['name']]);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'data' => ['name' => $account->fresh()->name, 'email' => $account->email],
|
||||
]);
|
||||
}
|
||||
|
||||
public function uploadAvatar(Request $request): JsonResponse
|
||||
{
|
||||
$account = ladill_account();
|
||||
|
||||
$request->validate([
|
||||
'avatar' => ['required', 'image', 'mimes:jpg,jpeg,png,webp', 'max:4096'],
|
||||
]);
|
||||
|
||||
$file = $request->file('avatar');
|
||||
|
||||
$response = Http::baseUrl(rtrim((string) config('services.ladill_identity.url'), '/'))
|
||||
->withToken((string) config('services.ladill_identity.key'))
|
||||
->acceptJson()
|
||||
->attach('avatar', (string) file_get_contents($file->getRealPath()), $file->getClientOriginalName())
|
||||
->post('/api/identity/avatar', ['user' => $account->public_id]);
|
||||
|
||||
$this->rethrowValidation($response, 'avatar');
|
||||
|
||||
if ($response->successful()) {
|
||||
$picture = (string) $response->json('data.user.picture', '');
|
||||
if ($picture !== '') {
|
||||
$account->update(['avatar_url' => $picture]);
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json(['data' => ['avatar_url' => $account->fresh()->avatarUrl()]]);
|
||||
}
|
||||
|
||||
public function changePassword(Request $request): JsonResponse
|
||||
{
|
||||
$account = ladill_account();
|
||||
|
||||
$request->validate([
|
||||
'current_password' => ['required', 'string'],
|
||||
'password' => ['required', 'string', 'min:8', 'confirmed'],
|
||||
]);
|
||||
|
||||
$response = $this->identitySend('POST', '/api/identity/auth/change-password', [
|
||||
'user' => $account->public_id,
|
||||
'current_password' => $request->string('current_password'),
|
||||
'password' => $request->string('password'),
|
||||
'password_confirmation' => $request->string('password_confirmation'),
|
||||
]);
|
||||
$this->rethrowValidation($response, 'current_password');
|
||||
|
||||
return response()->json(['data' => ['message' => 'Password updated.']]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user