# Subcontract

- Module key: `Subcontract`
- Category: `General`
- Path: `app/Modules/Subcontract`

## Ringkasan

Subcontract berada di kategori General. Modul ini memiliki 19 definisi route, 1 controller, 3 model, dan 1 view. Database module terdeteksi pada tabel: `subcontract_contracts`, `subcontract_claims`, `subcontract_payments`.

## Flowchart

```mermaid
flowchart TD
    A[User / Operator] --> B[Menu Subcontract]
    B --> C[Routes: 19]
    C --> D[Controllers: 1]
    D --> E[Views: 1]
    D --> F[(Tables: 3<br/>subcontract_contracts<br/>subcontract_claims<br/>subcontract_payments)]
    D --> G[Validation / Business Rules]
    G --> F
    F --> H[Report / Export / Audit]
```


## Routes

- `Route::middleware(['auth', 'ip.block', 'menu.access'])`  
  File: `app/Modules/Subcontract/routes/web.php`
- `Route::get('/', [SubcontractController::class, 'index'])->name('page');`  
  File: `app/Modules/Subcontract/routes/web.php`
- `Route::get('/data', [SubcontractController::class, 'contractsData'])->name('data');`  
  File: `app/Modules/Subcontract/routes/web.php`
- `Route::post('/', [SubcontractController::class, 'storeContract'])->name('store');`  
  File: `app/Modules/Subcontract/routes/web.php`
- `Route::put('/{id}', [SubcontractController::class, 'updateContract'])->name('update');`  
  File: `app/Modules/Subcontract/routes/web.php`
- `Route::post('/{id}/approve', [SubcontractController::class, 'approveContract'])->name('approve');`  
  File: `app/Modules/Subcontract/routes/web.php`
- `Route::post('/{id}/close', [SubcontractController::class, 'closeContract'])->name('close');`  
  File: `app/Modules/Subcontract/routes/web.php`
- `Route::get('/{id}/claims/data', [SubcontractController::class, 'claimsData'])->name('claims.data');`  
  File: `app/Modules/Subcontract/routes/web.php`
- `Route::post('/{id}/claims', [SubcontractController::class, 'storeClaim'])->name('claims.store');`  
  File: `app/Modules/Subcontract/routes/web.php`
- `Route::post('/claims/{claimId}/submit', [SubcontractController::class, 'submitClaim'])->name('claims.submit');`  
  File: `app/Modules/Subcontract/routes/web.php`
- `Route::post('/claims/{claimId}/approve', [SubcontractController::class, 'approveClaim'])->name('claims.approve');`  
  File: `app/Modules/Subcontract/routes/web.php`
- `Route::post('/claims/{claimId}/reject', [SubcontractController::class, 'rejectClaim'])->name('claims.reject');`  
  File: `app/Modules/Subcontract/routes/web.php`
- `Route::get('/{id}/payments/data', [SubcontractController::class, 'paymentsData'])->name('payments.data');`  
  File: `app/Modules/Subcontract/routes/web.php`
- `Route::post('/{id}/payments', [SubcontractController::class, 'storePayment'])->name('payments.store');`  
  File: `app/Modules/Subcontract/routes/web.php`
- `Route::post('/payments/{paymentId}/post', [SubcontractController::class, 'postPayment'])->name('payments.post');`  
  File: `app/Modules/Subcontract/routes/web.php`
- `Route::post('/payments/{paymentId}/void', [SubcontractController::class, 'voidPayment'])->name('payments.void');`  
  File: `app/Modules/Subcontract/routes/web.php`
- `Route::get('/projects/search', [SubcontractController::class, 'projectsSearch'])->name('projects.search');`  
  File: `app/Modules/Subcontract/routes/web.php`
- `Route::get('/vendors/search', [SubcontractController::class, 'vendorsSearch'])->name('vendors.search');`  
  File: `app/Modules/Subcontract/routes/web.php`
- `Route::get('/accounts/search', [SubcontractController::class, 'accountsSearch'])->name('accounts.search');`  
  File: `app/Modules/Subcontract/routes/web.php`

## Controllers

- `app/Modules/Subcontract/Http/Controllers/SubcontractController.php`

## Models

- `app/Modules/Subcontract/Models/SubcontractClaimModel.php`
- `app/Modules/Subcontract/Models/SubcontractContractModel.php`
- `app/Modules/Subcontract/Models/SubcontractPaymentModel.php`

## Views

- `app/Modules/Subcontract/Resources/views/index.blade.php`

## Database / Migration

### `subcontract_contracts`
- Actions: `create`
- Columns: 16
  - `project_id:foreignId`
  - `vendor_id:foreignId`
  - `contract_no:string`
  - `contract_date:date`
  - `title:string`
  - `contract_amount:decimal`
  - `retention_percent:decimal`
  - `ap_account_id:foreignId`
  - `expense_account_id:foreignId`
  - `status:string`
  - `notes:text`
  - `is_active:boolean`
  - `created_by:unsignedBigInteger`
  - `updated_by:unsignedBigInteger`
  - `project_id:index`
  - `status:index`
- Migrations:
  - `app/Modules/Subcontract/Database/migrations/2026_03_26_131000_create_subcontract_tables.php`
### `subcontract_claims`
- Actions: `create`
- Columns: 21
  - `contract_id:foreignId`
  - `claim_no:string`
  - `claim_date:date`
  - `description:text`
  - `progress_percent:decimal`
  - `gross_amount:decimal`
  - `retention_amount:decimal`
  - `net_amount:decimal`
  - `status:string`
  - `journal_id:unsignedBigInteger`
  - `created_by:unsignedBigInteger`
  - `updated_by:unsignedBigInteger`
  - `submitted_at:timestamp`
  - `submitted_by:unsignedBigInteger`
  - `approved_at:timestamp`
  - `approved_by:unsignedBigInteger`
  - `rejected_at:timestamp`
  - `rejected_by:unsignedBigInteger`
  - `reject_reason:string`
  - `contract_id:index`
  - `status:index`
- Migrations:
  - `app/Modules/Subcontract/Database/migrations/2026_03_26_131000_create_subcontract_tables.php`
### `subcontract_payments`
- Actions: `create`
- Columns: 20
  - `contract_id:foreignId`
  - `claim_id:foreignId`
  - `payment_no:string`
  - `pay_date:date`
  - `amount_idr:decimal`
  - `method:string`
  - `reference_number:string`
  - `notes:text`
  - `bank_account_id:foreignId`
  - `ap_account_id:foreignId`
  - `status:string`
  - `journal_id:unsignedBigInteger`
  - `created_by:unsignedBigInteger`
  - `updated_by:unsignedBigInteger`
  - `posted_at:timestamp`
  - `posted_by:unsignedBigInteger`
  - `void_at:timestamp`
  - `void_by:unsignedBigInteger`
  - `contract_id:index`
  - `status:index`
- Migrations:
  - `app/Modules/Subcontract/Database/migrations/2026_03_26_131000_create_subcontract_tables.php`
