# Daily Batch `.txt` File Transfer (Laravel 8) to Host `ABC`

This guide explains how to generate a daily `.txt` batch file and transfer it to remote host `ABC` using Laravel.

## 1. Install SFTP Filesystem Driver

```bash
composer require league/flysystem-sftp-v3:^3.0
```

## 2. Add Environment Variables

Add these to your `.env`:

```env
# Batch transfer schedule (server timezone)
BATCH_TRANSFER_TIME=01:00

# Host ABC SFTP settings
ABC_SFTP_HOST=abc.example.com
ABC_SFTP_PORT=22
ABC_SFTP_USERNAME=your_username
ABC_SFTP_PASSWORD=your_password
ABC_SFTP_ROOT=/inbound
ABC_SFTP_TIMEOUT=30

# Optional: local temp path for generated files
BATCH_LOCAL_PATH=app/batch_out
```

## 3. Configure SFTP Disk

In `config/filesystems.php`, add a disk:

```php
'abc_sftp' => [
    'driver' => 'sftp',
    'host' => env('ABC_SFTP_HOST'),
    'port' => (int) env('ABC_SFTP_PORT', 22),
    'username' => env('ABC_SFTP_USERNAME'),
    'password' => env('ABC_SFTP_PASSWORD'),
    'root' => env('ABC_SFTP_ROOT', '/'),
    'timeout' => (int) env('ABC_SFTP_TIMEOUT', 30),
],
```

## 4. Create Artisan Command

```bash
php artisan make:command SendDailyBatchToAbc
```

Use this template in `app/Console/Commands/SendDailyBatchToAbc.php`:

```php
<?php

namespace App\Console\Commands;

use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;

class SendDailyBatchToAbc extends Command
{
    protected $signature = 'batch:send-abc';
    protected $description = 'Generate daily .txt batch and transfer to host ABC';

    public function handle(): int
    {
        $date = Carbon::now()->format('Ymd');
        $filename = "BATCH_{$date}.txt";

        // 1) Build your batch lines from DB/data source
        // Example format only; replace with real columns and rules
        $lines = [
            "HDR|{$date}|SYSTEM_A",
            "DTL|1001|50.00|SUCCESS",
            "DTL|1002|25.90|SUCCESS",
            "TRL|2",
        ];

        $content = implode(PHP_EOL, $lines) . PHP_EOL;

        // 2) Store local copy (optional, for audit/retry)
        $localPath = trim(env('BATCH_LOCAL_PATH', 'app/batch_out'), '/');
        Storage::disk('local')->put("{$localPath}/{$filename}", $content);

        // 3) Upload to host ABC via SFTP
        Storage::disk('abc_sftp')->put($filename, $content);

        Log::info('Daily batch transferred to ABC', [
            'filename' => $filename,
            'date' => $date,
        ]);

        $this->info("Uploaded {$filename} to ABC.");
        return self::SUCCESS;
    }
}
```

## 5. Schedule the Command Daily

In `app/Console/Kernel.php`:

```php
protected function schedule(\Illuminate\Console\Scheduling\Schedule $schedule)
{
    $schedule->command('batch:send-abc')
        ->dailyAt(env('BATCH_TRANSFER_TIME', '01:00'))
        ->withoutOverlapping()
        ->onOneServer();
}
```

## 6. Enable Laravel Scheduler on Server

Set system cron (Linux) to run every minute:

```bash
* * * * * cd /path/to/project && php artisan schedule:run >> /dev/null 2>&1
```

## 7. Test End-to-End

Run command manually:

```bash
php artisan batch:send-abc
```

Verify:

1. File exists in local `storage/app/batch_out` (or your configured path).
2. File appears in remote `ABC_SFTP_ROOT`.
3. App log has success message in `storage/logs/laravel.log`.

## 8. Recommended Production Hardening

1. Use SSH key auth instead of password when possible.
2. Add retry logic and alerting on failed transfer.
3. Keep local archive of sent files for reconciliation.
4. Add checksum/record count validation with host `ABC`.
5. Add idempotency key (do not resend same file twice unless retry is intentional).

## 9. Optional: Date-Based Filename Rule

If host `ABC` expects specific naming, update:

```php
$filename = "ABC_".Carbon::now()->format('Ymd').".txt";
```

---

Adjust the sample `lines` format to match the exact layout required by host `ABC` (delimiter, fixed-width, headers, trailer, encoding, etc.).
