# Loyal Aid System - Implementation Guide

This guide provides detailed instructions for implementing the remaining features of the Loyal Aid system.

## 1. Member Registration Controller

### Implementation Steps

1. **Create Registration Form View** (`resources/views/member/register.blade.php`)
   - Multi-step form matching the original JotForm structure
   - Include all fields: personal info, dependents, employment, banking
   - Validation on each step

2. **Implement Registration Logic** (`app/Http/Controllers/MemberRegistrationController.php`)
   - Validate all form data
   - Create member record
   - Create dependents (if any)
   - Generate reference number (Loyalaid/XXXX format)
   - Optionally create user account for member login

3. **Routes:**
   ```php
   Route::get('/register', [MemberRegistrationController::class, 'show'])->name('member.register');
   Route::post('/register', [MemberRegistrationController::class, 'store'])->name('member.register.store');
   ```

## 2. CSV Bank Payment Import

### Implementation Steps

1. **Create Import View** (`resources/views/admin/bank-payments/import.blade.php`)
   - File upload form
   - Preview of imported data
   - Confirmation before processing

2. **Implement Import Logic** (`app/Http/Controllers/Admin/BankPaymentController.php`)

   ```php
   public function import(Request $request)
   {
       $request->validate([
           'csv_file' => 'required|mimes:csv,txt,xlsx'
       ]);

       $file = $request->file('csv_file');
       $data = $this->parseCsvFile($file);
       
       foreach ($data as $row) {
           // Find member by account number or reference
           $member = Member::where('reference_number', $row['reference_number'])
               ->orWhere('standard_bank_account', $row['account_number'])
               ->first();
           
           BankPayment::create([
               'member_id' => $member?->id,
               'bank_name' => $row['bank_name'],
               'member_name' => $row['member_name'],
               'account_number' => $row['account_number'],
               'amount' => $row['amount'],
               'reference_number' => $row['reference_number'],
               'payment_day_of_month' => $this->extractDayFromDate($row['payment_date']),
               'status' => 'not_processed',
           ]);
       }
       
       return redirect()->back()->with('success', 'CSV imported successfully');
   }
   
   private function parseCsvFile($file)
   {
       // Use PhpSpreadsheet or Laravel Excel to parse
       // Handle both CSV and Excel formats
   }
   ```

3. **Payment Processing:**
   ```php
   public function processPayment(BankPayment $payment)
   {
       if ($payment->status !== 'not_processed') {
           return back()->with('error', 'Payment already processed');
       }
       
       $member = $payment->member;
       if (!$member) {
           return back()->with('error', 'Member not found');
       }
       
       // Award points based on subscription plan
       $plan = $member->subscriptionPlan;
       if ($plan) {
           $member->addPoints(
               $plan->points_per_month,
               'bank_payment',
               $payment->id,
               "Monthly subscription payment - {$payment->reference_number}",
               auth()->id()
           );
       }
       
       $payment->update([
           'status' => 'processed',
           'processed_by' => auth()->id(),
           'processed_at' => now(),
       ]);
       
       return back()->with('success', 'Payment processed and points awarded');
   }
   ```

## 3. Points Management

### Implementation Steps

1. **Points Dashboard** (`resources/views/admin/points/index.blade.php`)
   - List all transactions
   - Filter by member, date, type
   - Summary statistics

2. **Add Points Form** (`app/Http/Controllers/Admin/PointsController.php`)
   ```php
   public function addPoints(Request $request, Member $member)
   {
       $validated = $request->validate([
           'points' => 'required|numeric|min:0.01',
           'description' => 'nullable|string|max:500',
       ]);
       
       $transaction = $member->addPoints(
           $validated['points'],
           'manual',
           null,
           $validated['description'],
           auth()->id()
       );
       
       return back()->with('success', 'Points added successfully');
   }
   ```

3. **Deduct Points:**
   ```php
   public function deductPoints(Request $request, Member $member)
   {
       $validated = $request->validate([
           'points' => 'required|numeric|min:0.01',
           'description' => 'nullable|string|max:500',
       ]);
       
       $transaction = $member->deductPoints(
           $validated['points'],
           'manual',
           null,
           $validated['description'],
           auth()->id()
       );
       
       if (!$transaction) {
           return back()->with('error', 'Insufficient points');
       }
       
       return back()->with('success', 'Points deducted successfully');
   }
   ```

## 4. Admin Member Management

### Implementation Steps

1. **Member List** (`resources/views/admin/members/index.blade.php`)
   - Searchable/filterable table
   - Columns: Name, ID, Email, Plan, Points, Status
   - Actions: View, Edit, Manage Points

2. **Member Edit Form** (`app/Http/Controllers/Admin/MemberController.php`)
   ```php
   public function update(Request $request, Member $member)
   {
       $validated = $request->validate([
           'first_name' => 'required|string|max:255',
           'last_name' => 'required|string|max:255',
           'email' => 'required|email|unique:members,email,' . $member->id,
           'subscription_plan_id' => 'nullable|exists:subscription_plans,id',
           // ... other fields
       ]);
       
       $member->update($validated);
       
       return redirect()->route('admin.members.show', $member)
           ->with('success', 'Member updated successfully');
   }
   ```

## 5. Role and Permission Management

### Implementation Steps

1. **Role Management** (`app/Http/Controllers/Admin/RoleController.php`)
   ```php
   public function assignPermissions(Request $request, Role $role)
   {
       $validated = $request->validate([
           'permissions' => 'required|array',
           'permissions.*' => 'exists:permissions,id',
       ]);
       
       $role->permissions()->sync($validated['permissions']);
       
       return back()->with('success', 'Permissions updated');
   }
   ```

2. **Middleware for Permission Checking:**
   ```php
   // app/Http/Middleware/CheckPermission.php
   public function handle(Request $request, Closure $next, string $permission)
   {
       if (!auth()->user()->hasPermission($permission)) {
           abort(403, 'Unauthorized');
       }
       
       return $next($request);
   }
   ```

## 6. Loyverse POS Integration

### Implementation Steps

1. **Install HTTP Client:**
   ```bash
   composer require guzzlehttp/guzzle
   ```

2. **Create Loyverse Service** (`app/Services/LoyverseService.php`)
   ```php
   class LoyverseService
   {
       private $baseUrl = 'https://api.loyverse.com';
       private $accessToken;
       
       public function __construct()
       {
           $this->accessToken = config('services.loyverse.access_token');
       }
       
       public function createCustomer(Member $member)
       {
           $response = Http::withHeaders([
               'Authorization' => 'Bearer ' . $this->accessToken,
           ])->post("{$this->baseUrl}/customers", [
               'name' => $member->full_name,
               'email' => $member->email,
               'phone' => $member->phone_number,
               'note' => "Loyal Aid Member - {$member->reference_number}",
           ]);
           
           if ($response->successful()) {
               $data = $response->json();
               $member->update(['loyverse_customer_id' => $data['id']]);
               
               LoyverseSync::create([
                   'member_id' => $member->id,
                   'loyverse_customer_id' => $data['id'],
                   'sync_type' => 'customer_create',
                   'status' => 'success',
                   'response_data' => $data,
                   'synced_at' => now(),
               ]);
               
               return $data;
           }
           
           return null;
       }
       
       public function syncPoints(Member $member, float $points, string $type = 'earned')
       {
           // Update customer note or use custom fields
           // Loyverse doesn't have native points, so you may need to:
           // 1. Store in customer notes
           // 2. Use custom fields if available
           // 3. Create a separate tracking system
           
           $response = Http::withHeaders([
               'Authorization' => 'Bearer ' . $this->accessToken,
           ])->patch("{$this->baseUrl}/customers/{$member->loyverse_customer_id}", [
               'note' => "Loyal Aid Points: {$member->loyal_aid_points}",
           ]);
           
           return $response->successful();
       }
   }
   ```

3. **Add to config/services.php:**
   ```php
   'loyverse' => [
       'access_token' => env('LOYVERSE_ACCESS_TOKEN'),
       'store_id' => env('LOYVERSE_STORE_ID'),
   ],
   ```

## 7. Member Dashboard

### Implementation Steps

1. **Dashboard View** (`resources/views/member/dashboard.blade.php`)
   - Display current points balance
   - Recent transactions
   - Profile information
   - Subscription plan details

2. **Controller** (`app/Http/Controllers/MemberDashboardController.php`)
   ```php
   public function index()
   {
       $member = auth()->user()->member ?? Member::where('email', auth()->user()->email)->first();
       
       if (!$member) {
           return redirect()->route('member.register');
       }
       
       $transactions = $member->pointsTransactions()
           ->latest()
           ->limit(20)
           ->get();
       
       return view('member.dashboard', compact('member', 'transactions'));
   }
   ```

## 8. Routes Setup

Add to `routes/web.php`:

```php
// Public routes
Route::get('/', function () {
    return view('welcome');
});

Route::get('/register', [MemberRegistrationController::class, 'show'])->name('member.register');
Route::post('/register', [MemberRegistrationController::class, 'store'])->name('member.register.store');

// Member routes (authenticated)
Route::middleware(['auth'])->group(function () {
    Route::get('/dashboard', [MemberDashboardController::class, 'index'])->name('member.dashboard');
    Route::get('/profile', [MemberDashboardController::class, 'profile'])->name('member.profile');
});

// Admin routes
Route::middleware(['auth', 'role:admin,staff'])->prefix('admin')->name('admin.')->group(function () {
    Route::get('/dashboard', function () {
        return view('admin.dashboard');
    })->name('dashboard');
    
    // Members
    Route::resource('members', Admin\MemberController::class);
    
    // Points
    Route::get('/points', [Admin\PointsController::class, 'index'])->name('points.index');
    Route::post('/points/{member}/add', [Admin\PointsController::class, 'addPoints'])->name('points.add');
    Route::post('/points/{member}/deduct', [Admin\PointsController::class, 'deductPoints'])->name('points.deduct');
    
    // Bank Payments
    Route::get('/bank-payments', [Admin\BankPaymentController::class, 'index'])->name('bank-payments.index');
    Route::post('/bank-payments/import', [Admin\BankPaymentController::class, 'import'])->name('bank-payments.import');
    Route::post('/bank-payments/{payment}/process', [Admin\BankPaymentController::class, 'process'])->name('bank-payments.process');
    
    // Users, Roles, Permissions (admin only)
    Route::middleware(['permission:manage_users'])->group(function () {
        Route::resource('users', Admin\UserController::class);
        Route::resource('roles', Admin\RoleController::class);
    });
});

// Loyverse webhooks (if needed)
Route::post('/webhooks/loyverse', [LoyverseController::class, 'webhook'])->name('loyverse.webhook');
```

## 9. Additional Packages

Consider installing:

```bash
# For Excel/CSV handling
composer require maatwebsite/excel

# For better date handling
composer require nesbot/carbon

# For API documentation (optional)
composer require darkaonline/l5-swagger
```

## 10. Testing

Create feature tests:

```php
// tests/Feature/MemberRegistrationTest.php
public function test_member_can_register()
{
    $response = $this->post('/register', [
        'first_name' => 'John',
        'last_name' => 'Doe',
        // ... other fields
    ]);
    
    $this->assertDatabaseHas('members', [
        'first_name' => 'John',
        'last_name' => 'Doe',
    ]);
}
```

## Next Steps

1. Implement all controllers with full CRUD operations
2. Create all Blade views with proper styling
3. Add form validation and error handling
4. Implement search and filtering
5. Add export functionality (PDF reports, Excel exports)
6. Set up email notifications
7. Add audit logging
8. Implement backup and restore functionality
9. Performance optimization (caching, eager loading)
10. Security hardening (rate limiting, CSRF protection)

## Support

For implementation questions, refer to:
- Laravel Documentation: https://laravel.com/docs
- Loyverse API Docs: https://developer.loyverse.com/docs/

