From 7d41fb857ac01be924259a2d45115ed5d3b6457a Mon Sep 17 00:00:00 2001 From: Deon George Date: Thu, 28 May 2020 15:08:13 +1000 Subject: [PATCH] ADSL Traffic import --- app/Classes/External/Supplier.php | 11 +- app/Classes/External/Supplier/ExetelVisp.php | 31 ++++ app/Jobs/BroadbandTraffic.php | 142 ++++++++++++++++++ app/Mail/TrafficMismatch.php | 45 ++++++ app/Models/AdslSupplier.php | 29 ++++ app/Models/Service/Adsl.php | 12 ++ app/Models/Service/AdslTraffic.php | 16 ++ ...2020_05_27_144223_enhance_adsl_traffic.php | 41 +++++ .../broadband_traffic_mismatch.blade.php | 17 +++ 9 files changed, 341 insertions(+), 3 deletions(-) create mode 100644 app/Classes/External/Supplier/ExetelVisp.php create mode 100644 app/Jobs/BroadbandTraffic.php create mode 100644 app/Mail/TrafficMismatch.php create mode 100644 app/Models/Service/AdslTraffic.php create mode 100644 database/migrations/2020_05_27_144223_enhance_adsl_traffic.php create mode 100644 resources/views/email/system/broadband_traffic_mismatch.blade.php diff --git a/app/Classes/External/Supplier.php b/app/Classes/External/Supplier.php index bceca8b..a6c4123 100644 --- a/app/Classes/External/Supplier.php +++ b/app/Classes/External/Supplier.php @@ -26,7 +26,7 @@ abstract class Supplier * @param array $args * @return mixed */ - protected function connect(array $args=[]) + public function connect(array $args=[]) { if ($x=$this->mustPause()) { Log::error('API Throttle, waiting .',['m'=>__METHOD__]); @@ -80,7 +80,7 @@ abstract class Supplier * @param Collection $expect * @return Collection */ - protected function getColumns(string $line,Collection $expect): Collection + public function getColumns(string $line,Collection $expect): Collection { $fields = collect(explode(',',$line))->filter(); $this->_columns = $expect; @@ -98,11 +98,16 @@ abstract class Supplier * @param string $key * @return mixed */ - protected function getColumnKey(string $key) + public function getColumnKey(string $key) { return $this->_columns->search($key); } + public function header(): array + { + return static::$header; + } + /** * If the supplier has API throttling... * diff --git a/app/Classes/External/Supplier/ExetelVisp.php b/app/Classes/External/Supplier/ExetelVisp.php new file mode 100644 index 0000000..5c5699e --- /dev/null +++ b/app/Classes/External/Supplier/ExetelVisp.php @@ -0,0 +1,31 @@ +aso = $o; + } + + /** + * Execute the job. + * + * @return void + */ + public function handle() + { + $u = 0; + + $class = $this->class_prefix.$this->aso->name; + + if (class_exists($class)) { + $o = new $class($this->aso); + + } else { + Log::error(sprintf('%s: Class doesnt exist: %d',get_class($this),$class)); + exit(1); + } + + AdslTraffic::where('supplier_id',$this->aso->id) + ->where('date',$this->aso->stats_lastupdate) + ->delete(); + + // @todo Need to trap errors from getting data + $c = 0; + foreach (explode("\n",$o->connect()) as $line) { + if (! trim($line)) + continue; + + // 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 exportupda'); + + $row = str_getcsv(trim($line)); + + try { + $date = Carbon::createFromFormat('Y-m-d',$row[$o->getColumnKey('Date')]); + + $oo = Adsl::where('service_username',$row[$o->getColumnKey('Login')]) + ->select(DB::raw('ab_service__adsl.*')) + ->join('ab_service','ab_service.id','=','service_id') + ->where('ab_service.date_start','<=',$date->format('U')) + ->where(function($query) use ($date) { + $query->whereNULL('ab_service.date_end') + ->orWhere('ab_service.date_end','<=',$date->format('U')); + }) + ->get(); + + // If we have no records + if ($oo->count() != 1) { + Log::error(sprintf('! Records Errors for:%s (%s) [%s]',$row[$o->getColumnKey('Login')],$date,$oo->count())); + + $to = new AdslTraffic; + $to->site_id = 1; // @todo TO ADDRESS + $to->service = $row[$o->getColumnKey('Login')]; + $to->date = $this->aso->stats_lastupdate; + $to->supplier_id = $this->aso->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 + $to->save(); + $u++; + + } else { + $to = new AdslTraffic; + $to->site_id = 1; // @todo TO ADDRESS + $to->date = $this->aso->stats_lastupdate; + $to->supplier_id = $this->aso->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 + $oo->first()->traffic()->save($to); + $u++; + } + } catch (\Exception $e) { + dd(['row'=>$row,'line'=>$line]); + } + } + + if ($u) { + $this->aso->stats_lastupdate = $this->aso->stats_lastupdate->addDay(); + $this->aso->save(); + + if ($this->aso->traffic_mismatch($date)->count()) + Mail::to('deon@graytech.net.au') // @todo To change + ->send(new TrafficMismatch($this->aso,$date)); + } + + Log::info(sprintf('%s: Records Imported: %d',get_class($this),$u)); + } +} \ No newline at end of file diff --git a/app/Mail/TrafficMismatch.php b/app/Mail/TrafficMismatch.php new file mode 100644 index 0000000..a19afcc --- /dev/null +++ b/app/Mail/TrafficMismatch.php @@ -0,0 +1,45 @@ +aso = $o; + $this->date = $date; + } + + /** + * Build the message. + * + * @return $this + */ + public function build() + { + return $this + ->markdown('email.system.broadband_traffic_mismatch') + ->subject('Traffic Mismatch for '.$this->date) + ->with([ + 'site'=>Site::find(1), // @todo To auto determine + 'date'=>$this->date, + 'aso'=>$this->aso, + ]); + } +} diff --git a/app/Models/AdslSupplier.php b/app/Models/AdslSupplier.php index f9c56d7..5fca535 100644 --- a/app/Models/AdslSupplier.php +++ b/app/Models/AdslSupplier.php @@ -2,9 +2,38 @@ namespace App\Models; +use App\Models\Service\AdslTraffic; +use Carbon\Carbon; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Model; class AdslSupplier extends Model { protected $table = 'ab_adsl_supplier'; + + protected $dates = [ + 'stats_lastupdate', + ]; + + public $timestamps = FALSE; + + /** SCOPES */ + + /** + * Only query active categories + */ + public function scopeActive($query) + { + return $query->where('active',TRUE); + } + + /** METHODS **/ + + public function traffic_mismatch(Carbon $date): Collection + { + return AdslTraffic::where('date',$date->format('Y-m-d')) + ->where('supplier_id',$this->id) + ->whereNULL('ab_service_adsl_id') + ->get(); + } } \ No newline at end of file diff --git a/app/Models/Service/Adsl.php b/app/Models/Service/Adsl.php index eef377e..bb48012 100644 --- a/app/Models/Service/Adsl.php +++ b/app/Models/Service/Adsl.php @@ -21,6 +21,18 @@ class Adsl extends ServiceType implements ServiceItem ]; protected $table = 'ab_service__adsl'; + /** RELATIONSHIPS **/ + + /** + * The accounts that this user manages + * + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ + public function traffic() + { + return $this->hasMany(AdslTraffic::class,'ab_service_adsl_id'); + } + /** SCOPES */ /** diff --git a/app/Models/Service/AdslTraffic.php b/app/Models/Service/AdslTraffic.php new file mode 100644 index 0000000..e3c9062 --- /dev/null +++ b/app/Models/Service/AdslTraffic.php @@ -0,0 +1,16 @@ +belongsTo(Adsl::class); + } +} \ No newline at end of file diff --git a/database/migrations/2020_05_27_144223_enhance_adsl_traffic.php b/database/migrations/2020_05_27_144223_enhance_adsl_traffic.php new file mode 100644 index 0000000..4d72831 --- /dev/null +++ b/database/migrations/2020_05_27_144223_enhance_adsl_traffic.php @@ -0,0 +1,41 @@ +bigInteger('ab_service_adsl_id')->nullable(); + $table->foreign('ab_service_adsl_id')->references('id')->on('ab_service__adsl'); + + $table->unique(['ab_service_adsl_id','date','time']); + }); + + DB::statement('ALTER TABLE ab_service__adsl_traffic CHANGE COLUMN service service varchar(128) DEFAULT NULL'); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + DB::statement('ALTER TABLE ab_service__adsl_traffic CHANGE COLUMN service service varchar(128) NOT NULL'); + + Schema::table('ab_service__adsl_traffic', function (Blueprint $table) { + $table->dropForeign(['ab_service_adsl_id']); + $table->dropUnique(['ab_service_adsl_id','date','time']); + $table->dropColumn('ab_service_adsl_id'); + }); + } +} diff --git a/resources/views/email/system/broadband_traffic_mismatch.blade.php b/resources/views/email/system/broadband_traffic_mismatch.blade.php new file mode 100644 index 0000000..198d6e5 --- /dev/null +++ b/resources/views/email/system/broadband_traffic_mismatch.blade.php @@ -0,0 +1,17 @@ +@component('mail::message',['site'=>$site,'heading'=>'Traffic Mismatch: '.$date]) +Hi {{ isset($user) ? $user->name.',' : '' }} + +The traffic import today, had mismatching records. A request to have those login removed has been generated. + +@component('mail::table') +| ID | +| - | +@foreach ($aso->traffic_mismatch($date) as $o) +| {{ $o->service }} +@endforeach + +@endcomponent + +Thanks,
+{{ config('mail.from.name') }} +@endcomponent \ No newline at end of file