Minor job cleanup, import Ezypay payments update
This commit is contained in:
parent
10e6c73b2b
commit
00f215b780
75
app/Classes/External/Payments/Ezypay.php
vendored
75
app/Classes/External/Payments/Ezypay.php
vendored
@ -45,6 +45,56 @@ class Ezypay extends Payments
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of configured customers
|
||||
*
|
||||
* @return Collection
|
||||
* @todo Hard coded at 100 clients - need to make this more dynamic
|
||||
*
|
||||
* {#1079
|
||||
* +"TermsAndConditions": true
|
||||
* +"Account": {#1082
|
||||
* +"PaymentMethodId": 0
|
||||
* }
|
||||
* +"Address1": "1 Road Street "
|
||||
* +"BillingStatus": "Active"
|
||||
* +"BusinessAccountReference": "12345"
|
||||
* +"CountryCode": "AU"
|
||||
* +"Email": "user@example.com"
|
||||
* +"EzypayReferenceNumber": 12345678
|
||||
* +"Firstname": "Bart"
|
||||
* +"Id": "6219c42b-8e56-4e4e-af3a-76ddf4b0e4e1"
|
||||
* +"MobilePhone": ""
|
||||
* +"Postcode": "1234"
|
||||
* +"ReferenceId": "01nnnn"
|
||||
* +"State": "VIC"
|
||||
* +"Suburb": "TOWN"
|
||||
* +"Towncity": ""
|
||||
* +"Surname": "Simpson "
|
||||
* +"PaymentPlanId": "00000000-0000-0000-0000-000000000000"
|
||||
* +"DateOfBirth": "1970-01-01T00:00:00.000"
|
||||
* +"Gender": "M"
|
||||
* +"DebitType": 0
|
||||
* +"RecurringAmount": 0.0
|
||||
* +"Frequency": 0
|
||||
* +"FrequencyType": 0
|
||||
* +"StartDate": "0001-01-01T00:00:00.000"
|
||||
* +"RecurringDebitEndType": 0
|
||||
* +"TotalAmountCollected": 0.0
|
||||
* +"MinimumNumberOfPayment": 0
|
||||
* +"RecurringWithDifferentFirstDebitAmount": 0.0
|
||||
* +"RecurringDebitFirstDebitDate": "0001-01-01T00:00:00.000"
|
||||
* +"RecurringDebitAmount": 0.0
|
||||
* +"RecurringDebitFrequency": 0
|
||||
* +"RecurringDebitFrequencyType": 0
|
||||
* +"RecurringDebitStartDate": "0001-01-01T00:00:00.000"
|
||||
* +"RecurringDebitDifferentFirstAmountEndType": 0
|
||||
* +"RecurringDebitTotalAmountCollected": 0.0
|
||||
* +"RecurringDebitMinimumNumberOfPayment": 0
|
||||
* +"OnceOffAmount": 0.0
|
||||
* +"OnceOffStartDate": "0001-01-01T00:00:00.000"
|
||||
* }
|
||||
*/
|
||||
public function getCustomers(): Collection
|
||||
{
|
||||
return Cache::remember(__METHOD__,86400,function() {
|
||||
@ -52,6 +102,29 @@ class Ezypay extends Payments
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Specific debits for a client.
|
||||
*
|
||||
* @param array $opt
|
||||
* @return Collection
|
||||
*
|
||||
* Illuminate\Support\Collection^ {#1077
|
||||
* #items: array:4 [
|
||||
* 0 => {#1826
|
||||
* +"Amount": 99.99
|
||||
* +"Id": "76666ef1-106c-458c-9162-e77fe746517c"
|
||||
* +"CustomerId": "6219c42b-8e56-4e4e-af3a-76ddf4b0e4e1"
|
||||
* +"Date": "2021-10-01T00:00:00.000"
|
||||
* +"Status": "Pending"
|
||||
* }
|
||||
* 1 => {#2075
|
||||
* +"Amount": 99.99
|
||||
* +"Id": "80ba201d-fb6f-4700-b1b7-2b13fbfa91d5"
|
||||
* +"CustomerId": "6219c42b-8e56-4e4e-af3a-76ddf4b0e4e1"
|
||||
* +"Date": "2021-09-01T00:00:00.000"
|
||||
* +"Status": "Pending"
|
||||
* }
|
||||
*/
|
||||
public function getDebits($opt=[]): Collection
|
||||
{
|
||||
return Cache::remember(__METHOD__.http_build_query($opt),86400,function() use ($opt) {
|
||||
@ -65,4 +138,4 @@ class Ezypay extends Payments
|
||||
return Collect($this->connect('settlements/'.config('services.ezypay.guid').($opt ? '?'.http_build_query($opt) : '')));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,11 +2,10 @@
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
use App\Classes\External\Payments\Ezypay;
|
||||
use App\Models\{Account,Checkout,Payment};
|
||||
use App\Jobs\PaymentsImport as Job;
|
||||
|
||||
class PaymentsEzypayImport extends Command
|
||||
{
|
||||
@ -24,16 +23,6 @@ class PaymentsEzypayImport extends Command
|
||||
*/
|
||||
protected $description = 'Retrieve payments from Ezypay';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
@ -41,67 +30,6 @@ class PaymentsEzypayImport extends Command
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$poo = new Ezypay();
|
||||
|
||||
// Get our checkout IDs for this plugin
|
||||
$cos = Checkout::where('plugin',config('services.ezypay.plugin'))->pluck('id');
|
||||
|
||||
foreach ($poo->getCustomers() as $c)
|
||||
{
|
||||
if ($c->BillingStatus == 'Inactive')
|
||||
{
|
||||
$this->info(sprintf('Ignoring INACTIVE: [%s] %s %s',$c->EzypayReferenceNumber,$c->Firstname,$c->Surname));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Load Account Details from ReferenceId
|
||||
$ao = Account::where('site_id',(int)substr($c->ReferenceId,0,2))
|
||||
->where('id',(int)substr($c->ReferenceId,2,4))
|
||||
->first();
|
||||
|
||||
if (! $ao)
|
||||
{
|
||||
$this->warn(sprintf('Missing: [%s] %s %s (%s)',$c->EzypayReferenceNumber,$c->Firstname,$c->Surname,$c->ReferenceId));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find the last payment logged
|
||||
$last = Carbon::createFromTimestamp(Payment::whereIN('checkout_id',$cos)->where('account_id',$ao->id)->max('payment_date'));
|
||||
|
||||
$o = $poo->getDebits([
|
||||
'customerId'=>$c->Id,
|
||||
'dateFrom'=>$last->format('Y-m-d'),
|
||||
'dateTo'=>$last->addQuarter()->format('Y-m-d'),
|
||||
'pageSize'=>100,
|
||||
]);
|
||||
|
||||
// Load the payments
|
||||
if ($o->count())
|
||||
{
|
||||
foreach ($o->reverse() as $p)
|
||||
{
|
||||
// If not success, ignore it.
|
||||
if ($p->Status != 'Success')
|
||||
continue;
|
||||
|
||||
$pd = Carbon::createFromFormat('Y-m-d?H:i:s.u',$p->Date);
|
||||
$lp = $ao->payments->last();
|
||||
|
||||
if ($lp AND (($pd == $lp->payment_date) OR ($p->Id == $lp->checkout_data)))
|
||||
continue;
|
||||
|
||||
// New Payment
|
||||
$po = new Payment;
|
||||
$po->site_id = 1; // @todo
|
||||
$po->payment_date = $pd;
|
||||
$po->checkout_id = '999'; // @todo
|
||||
$po->checkout_data = $p->Id;
|
||||
$po->total_amt = $p->Amount;
|
||||
$ao->payments()->save($po);
|
||||
|
||||
$this->info(sprintf('Recorded: Payment for [%s] %s %s (%s) on %s',$c->EzypayReferenceNumber,$c->Firstname,$c->Surname,$po->id,$pd));
|
||||
}
|
||||
}
|
||||
}
|
||||
Job::dispatchSync(new Ezypay);
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
use App\Classes\External\Payments\Ezypay;
|
||||
@ -23,16 +24,6 @@ class PaymentsEzypayNext extends Command
|
||||
*/
|
||||
protected $description = 'Load next payments, and ensure they cover the next invoice';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
@ -40,12 +31,10 @@ class PaymentsEzypayNext extends Command
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$poo = new Ezypay();
|
||||
$poo = new Ezypay;
|
||||
|
||||
foreach ($poo->getCustomers() as $c)
|
||||
{
|
||||
if ($c->BillingStatus == 'Inactive')
|
||||
{
|
||||
foreach ($poo->getCustomers() as $c) {
|
||||
if ($c->BillingStatus == 'Inactive') {
|
||||
$this->info(sprintf('Ignoring INACTIVE: [%s] %s %s',$c->EzypayReferenceNumber,$c->Firstname,$c->Surname));
|
||||
continue;
|
||||
}
|
||||
@ -53,10 +42,9 @@ class PaymentsEzypayNext extends Command
|
||||
// Load Account Details from ReferenceId
|
||||
$ao = Account::where('site_id',(int)substr($c->ReferenceId,0,2))
|
||||
->where('id',(int)substr($c->ReferenceId,2,4))
|
||||
->first();
|
||||
->single();
|
||||
|
||||
if (! $ao)
|
||||
{
|
||||
if (! $ao) {
|
||||
$this->warn(sprintf('Missing: [%s] %s %s (%s)',$c->EzypayReferenceNumber,$c->Firstname,$c->Surname,$c->ReferenceId));
|
||||
continue;
|
||||
}
|
||||
@ -70,12 +58,33 @@ class PaymentsEzypayNext extends Command
|
||||
'dateTo'=>now()->addQuarter()->format('Y-m-d'),
|
||||
])->reverse()->first();
|
||||
|
||||
if ($next_pay->Status !== 'Pending') {
|
||||
$this->warn(sprintf('Next payment is not pending for (%s)',$ao->name));
|
||||
continue;
|
||||
}
|
||||
|
||||
$next_paydate = Carbon::createFromTimeString($next_pay->Date);
|
||||
|
||||
if ($next_pay->Amount < $account_due)
|
||||
$this->warn(sprintf('Next payment for (%s) [%s] not sufficient for outstanding balance [%s]',$ao->name,number_format($next_pay->Amount,2),number_format($account_due,2)));
|
||||
$this->warn(sprintf('Next payment on [%s] for (%s) [%s] not sufficient for outstanding balance [%s]',
|
||||
$next_paydate->format('Y-m-d'),
|
||||
$ao->name,
|
||||
number_format($next_pay->Amount,2),
|
||||
number_format($account_due,2)));
|
||||
|
||||
elseif ($next_pay->Amount > $account_due)
|
||||
$this->warn(sprintf('Next payment for (%s) [%s] is too much for outstanding balance [%s]',$ao->name,number_format($next_pay->Amount,2),number_format($account_due,2)));
|
||||
$this->warn(sprintf('Next payment on [%s] for (%s) [%s] is too much for outstanding balance [%s]',
|
||||
$next_paydate->format('Y-m-d'),
|
||||
$ao->name,
|
||||
number_format($next_pay->Amount,2),
|
||||
number_format($account_due,2)));
|
||||
|
||||
else
|
||||
$this->info(sprintf('Next payment for (%s) [%s] will cover outstanding balance [%s]',$ao->name,number_format($next_pay->Amount,2),number_format($account_due,2)));
|
||||
$this->info(sprintf('Next payment on [%s] for (%s) [%s] will cover outstanding balance [%s]',
|
||||
$next_paydate->format('Y-m-d'),
|
||||
$ao->name,
|
||||
number_format($next_pay->Amount,2),
|
||||
number_format($account_due,2)));
|
||||
}
|
||||
}
|
||||
}
|
@ -5,18 +5,18 @@ namespace App\Jobs;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
use App\Mail\TrafficMismatch;
|
||||
use App\Models\Service\Adsl;
|
||||
use App\Models\Service\AdslTraffic;
|
||||
use App\Models\AdslSupplier;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
/**
|
||||
* Class BroadbandTraffic
|
||||
@ -24,18 +24,18 @@ use Illuminate\Support\Facades\Mail;
|
||||
*
|
||||
* @package App\Jobs
|
||||
*/
|
||||
class BroadbandTraffic implements ShouldQueue
|
||||
final class BroadbandTraffic implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
private const LOGKEY = 'JBT';
|
||||
|
||||
protected $aso = NULL; // The supplier we are updating from
|
||||
private $class_prefix = 'App\Classes\External\Supplier\\';
|
||||
protected Model $o; // The supplier we are updating from
|
||||
private const class_prefix = 'App\Classes\External\Supplier\\';
|
||||
|
||||
public function __construct(AdslSupplier $o)
|
||||
{
|
||||
$this->aso = $o;
|
||||
$this->o = $o;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -47,14 +47,14 @@ class BroadbandTraffic implements ShouldQueue
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
Log::info(sprintf('%s:Importing Broadband Traffic from [%s]',self::LOGKEY,$this->aso->name),['m'=>__METHOD__]);
|
||||
Log::info(sprintf('%s:Importing Broadband Traffic from [%s]',self::LOGKEY,$this->o->name));
|
||||
|
||||
$u = 0;
|
||||
|
||||
// Load our class for this supplier
|
||||
$class = $this->class_prefix.$this->aso->name;
|
||||
$class = self::class_prefix.$this->o->name;
|
||||
if (class_exists($class)) {
|
||||
$o = new $class($this->aso);
|
||||
$o = new $class($this->o);
|
||||
|
||||
} else {
|
||||
Log::error(sprintf('%s: Class doesnt exist: %d',get_class($this),$class));
|
||||
@ -62,12 +62,12 @@ class BroadbandTraffic implements ShouldQueue
|
||||
}
|
||||
|
||||
// Repeat pull traffic data until yesterday
|
||||
while ($this->aso->stats_lastupdate < Carbon::now()->subDay()) {
|
||||
Log::notice(sprintf('%s:Next update is [%s]',self::LOGKEY,$this->aso->stats_lastupdate->format('Y-m-d')),['m'=>__METHOD__]);
|
||||
while ($this->o->stats_lastupdate < Carbon::now()->subDay()) {
|
||||
Log::notice(sprintf('%s:Next update is [%s]',self::LOGKEY,$this->o->stats_lastupdate->format('Y-m-d')));
|
||||
|
||||
// Delete traffic, since we'll refresh it.
|
||||
AdslTraffic::where('supplier_id',$this->aso->id)
|
||||
->where('date',$this->aso->stats_lastupdate)
|
||||
AdslTraffic::where('supplier_id',$this->o->id)
|
||||
->where('date',$this->o->stats_lastupdate)
|
||||
->delete();
|
||||
|
||||
$c = 0;
|
||||
@ -100,8 +100,8 @@ class BroadbandTraffic implements ShouldQueue
|
||||
|
||||
$to = new AdslTraffic;
|
||||
$to->site_id = 1; // @todo TO ADDRESS
|
||||
$to->date = $this->aso->stats_lastupdate;
|
||||
$to->supplier_id = $this->aso->id;
|
||||
$to->date = $this->o->stats_lastupdate;
|
||||
$to->supplier_id = $this->o->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')];
|
||||
@ -112,7 +112,7 @@ class BroadbandTraffic implements ShouldQueue
|
||||
|
||||
// If we have no records
|
||||
if ($oo->count() != 1) {
|
||||
Log::error(sprintf('%s:Too many services return for [%s]',self::LOGKEY,$row[$o->getColumnKey('Login')]),['m'=>__METHOD__,'date'=>$date,'count'=>$oo->count()]);
|
||||
Log::error(sprintf('%s:Too many services return for [%s]',self::LOGKEY,$row[$o->getColumnKey('Login')]),['date'=>$date,'count'=>$oo->count()]);
|
||||
|
||||
$to->service = $row[$o->getColumnKey('Login')];
|
||||
$to->save();
|
||||
@ -124,20 +124,20 @@ class BroadbandTraffic implements ShouldQueue
|
||||
$u++;
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error(sprintf('%s:Exception occurred when storing traffic record for [%s].',self::LOGKEY,$row[$o->getColumnKey('Login')]),['m'=>__METHOD__,'row'=>$row,'line'=>$line]);
|
||||
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 date');
|
||||
}
|
||||
}
|
||||
|
||||
Log::info(sprintf('%s: Records Imported [%d] for [%s]',self::LOGKEY,$u,$this->aso->stats_lastupdate->format('Y-m-d')),['m'=>__METHOD__]);
|
||||
Log::info(sprintf('%s: Records Imported [%d] for [%s]',self::LOGKEY,$u,$this->o->stats_lastupdate->format('Y-m-d')));
|
||||
|
||||
if ($u) {
|
||||
$this->aso->stats_lastupdate = $this->aso->stats_lastupdate->addDay();
|
||||
$this->aso->save();
|
||||
$this->o->stats_lastupdate = $this->o->stats_lastupdate->addDay();
|
||||
$this->o->save();
|
||||
|
||||
if ($this->aso->trafficMismatch($date)->count())
|
||||
if ($this->o->trafficMismatch($date)->count())
|
||||
Mail::to('deon@graytech.net.au') // @todo To change
|
||||
->send(new TrafficMismatch($this->aso,$date));
|
||||
->send(new TrafficMismatch($this->o,$date));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,11 +74,12 @@ class Payment extends Model implements IDs
|
||||
|
||||
public function scopeUnapplied($query)
|
||||
{
|
||||
//DB::enableQueryLog();
|
||||
return $query
|
||||
->select([DB::raw('payment_id AS id'),'payment_date','account_id','checkout_id','total_amt',DB::raw("SUM(alloc_amt) as allocated")])
|
||||
->join('payment_items',['payment_items.payment_id'=>'payments.id'])
|
||||
->groupBy(['payment_id','payment_date','total_amt','account_id','checkout_id'])
|
||||
->having(DB::raw("ROUND(total_amt-allocated,2)"),'>',self::threshold);
|
||||
->select(['payments.id','payment_date','account_id','checkout_id','total_amt',DB::raw("SUM(alloc_amt) as allocated")])
|
||||
->leftJoin('payment_items',['payment_items.payment_id'=>'payments.id'])
|
||||
->groupBy(['payments.id','payment_date','total_amt','account_id','checkout_id'])
|
||||
->having(DB::raw('ROUND(total_amt-IFNULL(allocated,0),2)'),'>',self::threshold);
|
||||
}
|
||||
|
||||
/* ATTRIBUTES */
|
||||
|
@ -104,7 +104,7 @@
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fas fa-fw fa-dollar-sign"></i></span>
|
||||
</div>
|
||||
<input type="text" class="text-right form-control @error('fees_amt') is-invalid @enderror" id="fees_amt" name="fees_amt" value="{{ old('fees_amt',$o->exists ? $o->fees_amt : 0) }}" required>
|
||||
<input type="text" class="text-right form-control @error('fees_amt') is-invalid @enderror" id="fees_amt" name="fees_amt" value="{{ old('fees_amt',$o->exists ? $o->fees_amt : 0) }}">
|
||||
<span class="invalid-feedback" role="alert">
|
||||
@error('fees_amt')
|
||||
{{ $message }}
|
||||
|
Loading…
Reference in New Issue
Block a user