<?php namespace App\Jobs; use Carbon\Carbon; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Arr; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Mail; use App\Classes\External\Supplier as ExternalSupplier; use App\Mail\TrafficMismatch; use App\Models\{Rtm,Supplier}; use App\Models\Service\Broadband as ServiceBroadband; use App\Models\Usage\Broadband as UsageBroadband; /** * Class BroadbandTraffic * Read and update the traffic for a Broadband supplier * * @package App\Jobs */ final class BroadbandTraffic implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; private const LOGKEY = 'JBT'; private const class_prefix = 'App\Classes\External\Supplier\\'; private const traffic = 'broadband'; public function __construct(private string $supplier) {} /** * Execute the job. * * @return void * @throws \Exception */ public function handle() { $so = Supplier::active() ->where('name','ilike',$this->supplier) ->sole(); // Wholesaler email $ro = Rtm::where('parent_id',NULL)->sole(); Log::info(sprintf('%s:Importing Broadband Traffic from [%s]',self::LOGKEY,$so->name)); if ((! $connection=$so->detail->connections->get('broadband')) || (count(array_intersect(array_keys($connection),ExternalSupplier::traffic_connection_keys)) !== 3)) throw new \Exception('No or missing connection details for:'.self::traffic); // Count of updated records $u = 0; // Load our class for this supplier $class = self::class_prefix.$so->name; if (class_exists($class)) { $o = new $class($so); } else { Log::error(sprintf('%s: Class doesnt exist: %s',self::LOGKEY,$class)); exit(1); } $last_update = Carbon::create(Arr::get($connection,'last'))->addDay(); Arr::set($connection,'last',$last_update->format('Y-m-d')); // Repeat pull traffic data until yesterday while ($last_update < Carbon::now()->subDay()) { Log::notice(sprintf('%s:Next update is [%s]',self::LOGKEY,$last_update->format('Y-m-d'))); // Delete traffic, since we'll refresh it. UsageBroadband::where('supplier_id',$so->id) ->where('date',$last_update->format('Y-m-d')) ->delete(); $c = 0; foreach ($o->fetch($connection,self::traffic) as $line) { // The first row is our header if (! $c++) { $fields = $o->getColumns(preg_replace('/,\s+/',',',$line),collect($o->header())); continue; } if (! $fields->count()) abort(500,'? No fields in data export'); $row = str_getcsv(trim($line)); try { $date = Carbon::createFromFormat('Y-m-d',$row[$o->getColumnKey('Date')]); // Find the right service dependent on the dates we supplied the service $oo = ServiceBroadband::where('service_username',$row[$o->getColumnKey('Login')]) ->select('service_broadband.*') ->join('services',['service_broadband.service_id'=>'services.id']) ->where('services.start_at','<=',$date) ->where(fn($query)=> $query->whereNULL('services.stop_at') ->orWhere('services.stop_at','>=',$date) ) ->single(); $to = new UsageBroadband; $to->date = $last_update; $to->supplier_id = $so->id; $to->up_peak = $row[$o->getColumnKey('Peak upload')]; $to->up_offpeak = $row[$o->getColumnKey('Off peak upload')]; $to->down_peak = $row[$o->getColumnKey('Peak download')]; $to->down_offpeak = $row[$o->getColumnKey('Off peak download')]; // $to->peer // $to->internal $to->time = '24:00'; // @todo // If we have no records if (! $oo) { Log::error(sprintf('%s:None or too many services return for [%s]',self::LOGKEY,$row[$o->getColumnKey('Login')]),['date'=>$date]); $to->service = $row[$o->getColumnKey('Login')]; $to->site_id = 1; // @todo This needs to be worked out a better way } else { $to->site_id = $oo->site_id; $to->service_item_id = $oo->id; } if ($to->save()) $u++; } catch (\Exception $e) { Log::error(sprintf('%s:Exception occurred when storing traffic record for [%s].',self::LOGKEY,$row[$o->getColumnKey('Login')]),['row'=>$row,'line'=>$line]); throw new \Exception('Error while storing traffic data: '.$e->getMessage()); } } Log::info(sprintf('%s: Records Imported [%d] for [%s]',self::LOGKEY,$u,$last_update->format('Y-m-d'))); // Save our current progress. $so->detail->connections = $so->detail->connections->put(self::traffic,array_merge($connection,['last'=>$last_update->format('Y-m-d')])); $so->detail->save(); // Update our details for the next iteration. $last_update = $last_update->addDay(); Arr::set($connection,'last',$last_update->format('Y-m-d')); if ($u) { if ($so->trafficMismatch($date)->count()) Mail::to($ro->owner->email) ->send(new TrafficMismatch($so,$date)); } } } }