# Employee Salary Payment Accounts Implementation

## Overview
This implementation adds support for multiple salary payment account types (Bank, bKash, Nagad) with automatic type detection, validation, and primary account management.

## Key Features

### 1. Payment Method Types
- **Bank**: Traditional bank accounts with bank name, account number, etc.
- **Mobile Banking**: bKash or Nagad mobile banking accounts

### 2. Auto-Detection
The backend automatically detects the payment method type based on the data provided:
- If `bank_name` + `account_number` are present → `bank` type
- If `mobile_banking_number` is present → `mobile_banking` type
- **If BOTH are present → Returns 422 error** (user must choose one)
- Defaults to `bank` if nothing is present (validated later)

### 3. Automatic Field Cleaning
When a record is saved, the backend automatically:
- Clears bank fields for mobile banking accounts
- Clears mobile fields for bank accounts
- Ensures no mixed data in the database

### 4. Validation
- **Bank accounts**: Requires bank_name, account_name, account_number
- **Mobile banking**: Requires mobile number in Bangladesh format (01XXXXXXXXX)
- **Provider validation**: Only bKash and Nagad are allowed
- **Phone format**: Validates Bangladeshi mobile numbers (+8801XXXXXXXXX or 01XXXXXXXXX)
- **Mixed submissions**: Rejects when both bank and mobile data provided

### 5. Primary Account Management
- First account added for an employee automatically becomes primary
- Setting a new primary automatically demotes the previous primary
- Deleting a primary account automatically promotes another account
- All operations are wrapped in database transactions

## Files Modified

### Backend

1. **Database Migration** (NEW)
   - `backend/Modules/Employee/database/migrations/2026_08_06_120000_add_payment_method_type_to_employee_bank_accounts_table.php`
   - Adds `payment_method_type` column with default 'bank'

2. **Validation Service** (MODIFIED)
   - `backend/Modules/Employee/app/Services/EmployeeBankAccountValidationService.php`
   - Added `validateAndClean()` - main validation entry point
   - Added `detectPaymentMethodType()` - auto-detects type from data, rejects mixed submissions
   - Added `validateBankDetails()` - validates bank account fields
   - Added `validateMobileDetails()` - validates mobile banking fields
   - Added `cleanIrrelevantFields()` - clears fields not relevant to the type
   - Added Bangladesh phone number validation
   - Added provider validation (bKash or Nagad only)

3. **Main Service** (MODIFIED)
   - `backend/Modules/Employee/app/Services/EmployeeBankAccountService.php`
   - Injected `EmployeeBankAccountValidationService`
   - Calls `validateAndClean()` in `create()` and `update()` methods
   - Backend automatically determines and validates payment method type

4. **Model** (MODIFIED)
   - `backend/Modules/Employee/app/Models/EmployeeBankAccount.php`
   - Added `payment_method_type` to `$fillable`
   - Added cast for `payment_method_type`

5. **Form Requests** (MODIFIED)
   - `backend/Modules/Employee/app/Http/Requests/StoreEmployeeBankAccountRequest.php`
   - `backend/Modules/Employee/app/Http/Requests/UpdateEmployeeBankAccountRequest.php`
   - Added conditional validation rules based on payment method type

6. **API Resource** (MODIFIED)
   - `backend/Modules/Employee/app/Http/Resources/EmployeeBankAccountResource.php`
   - Added `payment_method_type` to response

7. **Tests** (NEW)
   - `backend/tests/Feature/EmployeeSalaryPaymentAccountsTest.php`
   - Tests for bank account creation
   - Tests for mobile banking (bKash, Nagad) creation
   - Tests for invalid mobile number format
   - Tests for invalid provider
   - Tests for automatic primary assignment
   - Tests for primary demotion
   - Tests for primary promotion on delete
   - Tests for field cleaning
   - Tests for company isolation
   - Tests for mixed payment method rejection

### Frontend

1. **TypeScript Types** (MODIFIED)
   - `frontend/src/modules/employee/api/bankAccountApi.ts`
   - Added `payment_method_type` to `EmployeeBankAccount` interface
   - Made `payment_method_type` optional in payloads (backend auto-detects)
   - Added `FormState` interface

2. **Component** (UNCHANGED)
   - `frontend/src/modules/employee/components/profile-tabs/BankInfoTab.tsx`
   - **NO CHANGES TO FORM DESIGN**
   - Kept original layout and fields
   - Backend handles all type detection and validation

## How It Works

### Frontend → Backend Flow

```
User fills form (existing design with all fields visible)
    ↓
User can fill:
  - Only bank fields → Creates bank account
  - Only mobile fields → Creates mobile banking account
  - Both bank + mobile → ERROR: "Please provide only one payment method"
    ↓
Frontend sends: {
  bank_name: "ABC",
  account_name: "JOHN CENA",
  account_number: "147101986532",
  mobile_banking_provider: "bKash",  // optional
  mobile_banking_number: "01712345678",  // optional
  is_primary: true
}
    ↓
Backend receives data
    ↓
ValidationService.validateAndClean() automatically:
  1. Detects: bank_name + account_number present → type = 'bank'
  2. Checks: mobile_banking_number also present → ERROR!
  3. Throws exception: "Please provide only one payment method per account..."
    ↓
User sees error, clears mobile fields, submits again
    ↓
Backend detects: bank_name + account_number present → type = 'bank'
Validates: bank_name, account_name, account_number required
Cleans: Sets mobile_banking_provider = null, mobile_banking_number = null
    ↓
Data saved with payment_method_type = 'bank'
```

### Mobile Banking Example

```
User fills form:
{
  bank_name: "",  // empty
  account_name: "",  // empty
  account_number: "",  // empty
  mobile_banking_provider: "bKash",
  mobile_banking_number: "01712345678"
}
    ↓
Backend detects: mobile_banking_number present → type = 'mobile_banking'
    ↓
Validates: mobile number format (01XXXXXXXXX)
Validates: provider is bKash or Nagad
Cleans: Sets bank_name = null, account_number = null, etc.
    ↓
Data saved with payment_method_type = 'mobile_banking'
```

## Business Rules

### Creation
1. Backend auto-detects payment method type from data
2. **Rejects submissions with both bank and mobile banking data** (returns 422 with clear error)
3. Validates required fields based on detected type
4. Clears irrelevant fields automatically
5. First account for employee automatically becomes primary
6. All operations wrapped in database transactions

### Primary Account Management
1. Only one primary account per employee
2. Setting new primary demotes previous primary
3. Deleting primary promotes oldest remaining account
4. Primary changes go through approval workflow

### Validation Rules

**Bank Accounts:**
- `bank_name`: Required, max 150 characters
- `account_name`: Required, max 150 characters
- `account_number`: Required, max 100 characters
- `branch_name`: Optional, max 150 characters
- `routing_number`: Optional, max 50 characters

**Mobile Banking (bKash/Nagad):**
- `mobile_banking_number`: Required, must match Bangladesh format
  - Valid: `01712345678`, `01812345678`, `01912345678`
  - Valid: `+8801712345678`
  - Invalid: `1234567890`, `017-123-45678`
- `mobile_banking_provider`: Required, must be `bKash` or `Nagad`
- All bank fields are automatically cleared

**Mixed Submissions (Both Bank + Mobile):**
- **Returns 422 error** with message:
  ```
  Please provide only one payment method per account. Either fill bank details 
  (bank name + account number) OR mobile banking details (provider + number), 
  not both. To add multiple payment methods, create separate accounts.
  ```
- User must create separate accounts for each payment method

## API Endpoints

All endpoints remain unchanged. The backend now automatically handles payment method type detection and validation.

### Create Account
```http
POST /employee/bank-accounts
{
  "employee_id": 123,
  "bank_name": "Test Bank",
  "account_name": "Test Account",
  "account_number": "1234567890",
  "is_primary": true
}
```

### Response
```json
{
  "success": true,
  "data": {
    "id": 1,
    "payment_method_type": "bank",
    "bank_name": "Test Bank",
    "account_name": "Test Account",
    "account_number": "******7890",
    "mobile_banking_provider": null,
    "mobile_banking_number": null,
    "is_primary": true
  }
}
```

## Testing

Run the tests:
```bash
cd backend
php artisan test --filter=EmployeeSalaryPaymentAccountsTest
```

### Test Coverage
✅ Create bank account
✅ Create bKash account
✅ Create Nagad account
✅ Invalid Bangladesh mobile number rejected
✅ Invalid provider rejected
✅ First account becomes primary automatically
✅ Setting primary demotes previous primary
✅ Deleting primary promotes another account
✅ Bank fields cleared for mobile accounts
✅ Mobile fields cleared for bank accounts
✅ Company isolation works
✅ Mixed payment methods (both bank + mobile) returns 422

## Migration

Run the migration:
```bash
cd backend
php artisan migrate
```

## Backward Compatibility

- Existing bank accounts default to `payment_method_type = 'bank'`
- No breaking changes to API
- Frontend form design unchanged
- All existing functionality preserved

## Security

- Account numbers are encrypted in database
- Account numbers are masked in API responses
- Company isolation enforced
- Approval workflow preserved for all changes
- Audit logging maintained

## Performance

- Index on `(company_id, employee_id, payment_method_type)` for efficient queries
- No N+1 queries introduced
- Validation happens in service layer (single point of entry)

## Future Enhancements

Possible future additions:
1. Support for more mobile banking providers (Rocket, SureCash)
2. Account verification status
3. Default account selection per payment type
4. Bulk import of payment accounts
5. Account usage tracking (which accounts were used for which payments)

## Notes

- The `EmployeeBankAccountValidationService` is now actively used in the create/update flow
- All validation happens server-side regardless of frontend
- The frontend form design remains completely unchanged
- Backend is responsible for data integrity and type detection
- Mixed payment method submissions are rejected with clear error messages
