public function run()
 {
     $users = User::active()->where('status', '=', 'active')->notSpecialCase()->get();
     foreach ($users as $user) {
         /** @var $user \BB\Entities\User */
         echo $user->name;
         $expired = false;
         $cutOffDate = MembershipPayments::getSubGracePeriodDate($user->payment_method);
         if (!$user->subscription_expires || $user->subscription_expires->lt($cutOffDate)) {
             $expired = true;
         }
         //Check for payments first
         if ($expired) {
             $paidUntil = MembershipPayments::lastUserPaymentExpires($user->id);
             //$paidUntil = $this->memberSubscriptionCharges->lastUserChargeExpires($user->id);
             if ($paidUntil) {
                 if ($user->subscription_expires && $user->subscription_expires->lt($paidUntil)) {
                     $user->extendMembership($user->payment_method, $paidUntil);
                     //This may not be true but it simplifies things now and tomorrows process will deal with it
                     $expired = false;
                 }
             }
         }
         if ($expired) {
             $user->setSuspended();
             echo ' - Suspended';
         }
         echo PHP_EOL;
     }
 }
 public function run()
 {
     $today = new Carbon();
     //Fetch and check over active users which have a status of leaving
     $users = User::paymentWarning()->get();
     foreach ($users as $user) {
         /** @var $user \BB\Entities\User */
         if ($user->subscription_expires->lt($today)) {
             //User has passed their expiry date
             echo $user->name . ' has a payment warning and has passed their expiry date' . PHP_EOL;
             //Check the actual expiry date
             //When did their last sub payment expire
             $paidUntil = MembershipPayments::lastUserPaymentExpires($user->id);
             //What grace period do they have - when should we give them to
             $cutOffDate = MembershipPayments::getSubGracePeriodDate($user->payment_method);
             //If the cut of date is greater than (sooner) than the last payment date "expire" them
             if ($paidUntil == false || $cutOffDate->subDays(2)->gt($paidUntil)) {
                 //set the status to left and active to false
                 $this->userRepository->memberLeft($user->id);
                 echo $user->name . ' marked as having left' . PHP_EOL;
             }
             //an email will be sent by the user observer
         } else {
             echo $user->name . ' has a payment warning but is within their expiry date' . PHP_EOL;
         }
     }
 }
 /**
  * A sub charge has been rolled back as a payment failed
  *
  * @param integer $chargeId
  * @param integer $userId
  * @param Carbon  $paymentDate
  * @param double  $amount
  */
 public function onPaymentFailure($chargeId, $userId, Carbon $paymentDate, $amount)
 {
     $paidUntil = MembershipPayments::lastUserPaymentExpires($userId);
     if ($paidUntil) {
         $user = $this->userRepository->getById($userId);
         /** @var $user \BB\Entities\User */
         $user->extendMembership(null, $paidUntil);
     } else {
         \Log::info('Payment cancelled, expiry date rollback failed as there is no previous payment. User ID:' . $userId);
     }
 }
 public function run()
 {
     $today = new Carbon();
     //Fetch and check over active users which have a status of suspended
     $users = User::suspended()->get();
     foreach ($users as $user) {
         if (!$user->subscription_expires || $user->subscription_expires->lt($today)) {
             //User has passed their expiry date
             echo $user->name . ' is suspended and has passed their expiry date' . PHP_EOL;
             //Check the actual expiry date
             //When did their last sub payment expire
             $paidUntil = MembershipPayments::lastUserPaymentExpires($user->id);
             if ($paidUntil) {
                 if (!$user->subscription_expires || $user->subscription_expires->lt($paidUntil)) {
                     $user->extendMembership(null, $paidUntil);
                 }
             }
             //an email will be sent by the user observer
         } else {
             echo $user->name . ' has a payment warning but is within their expiry date' . PHP_EOL;
         }
     }
 }
<?php

use BB\Entities\Payment;
use BB\Entities\User;
$I = new UnitTester($scenario);
$I->wantTo('confirm the payment helper fetches the correct payment date');
//Create a user record
$user = User::create(['given_name' => 'Test', 'family_name' => 'Person', 'email' => '*****@*****.**']);
$date = \BB\Helpers\MembershipPayments::lastUserPaymentDate($user->id);
$I->assertFalse($date, 'Date should be false as no payments exist');
//Create some payment records
\BB\Entities\SubscriptionCharge::create(['user_id' => $user->id, 'charge_date' => '2014-01-01', 'payment_date' => '2014-01-01', 'status' => 'paid']);
Payment::create(['reason' => 'subscription', 'source' => 'other', 'user_id' => $user->id, 'amount' => 20, 'amount_minus_fee' => 20, 'status' => 'paid', 'created_at' => '2014-01-01']);
\BB\Entities\SubscriptionCharge::create(['user_id' => $user->id, 'charge_date' => '2014-06-01', 'status' => 'processing']);
Payment::create(['reason' => 'subscription', 'source' => 'other', 'user_id' => $user->id, 'amount' => 20, 'amount_minus_fee' => 20, 'status' => 'pending', 'created_at' => '2014-06-01']);
\BB\Entities\SubscriptionCharge::create(['user_id' => $user->id, 'charge_date' => '2014-08-01', 'status' => 'cancelled']);
Payment::create(['reason' => 'subscription', 'source' => 'other', 'user_id' => $user->id, 'amount' => 20, 'amount_minus_fee' => 20, 'status' => 'cancelled', 'created_at' => '2014-08-01']);
//Now we have some payments re-fetch the last payment date
$date = \BB\Helpers\MembershipPayments::lastUserPaymentDate($user->id);
//Make sure its a date that's returned
$I->assertEquals(get_parent_class($date), 'DateTime');
//Confirm the datetime matched the first payment record, the only paid one
$I->assertEquals(new \Carbon\Carbon('2014-01-01'), $date);
 /**
  * The bill has been cancelled or failed, update the user records to compensate
  *
  * @param $existingPayment
  */
 private function handleFailedCancelledBill(Payment $existingPayment)
 {
     if ($existingPayment->reason == 'subscription') {
         //If the payment is a subscription payment then we need to take action and warn the user
         $user = $existingPayment->user()->first();
         $user->status = 'suspended';
         //Rollback the users subscription expiry date or set it to today
         $expiryDate = \BB\Helpers\MembershipPayments::lastUserPaymentExpires($user->id);
         if ($expiryDate) {
             $user->subscription_expires = $expiryDate;
         } else {
             $user->subscription_expires = new Carbon();
         }
         $user->save();
         //Update the subscription charge to reflect the payment failure
         $subCharge = $this->subscriptionChargeRepository->getById($existingPayment->reference);
         if ($subCharge) {
             $this->subscriptionChargeRepository->paymentFailed($subCharge->id);
         }
     } elseif ($existingPayment->reason == 'induction') {
         //We still need to collect the payment from the user
     } elseif ($existingPayment->reason == 'box-deposit') {
     } elseif ($existingPayment->reason == 'key-deposit') {
     }
 }
<?php

use Carbon\Carbon;
$I = new UnitTester($scenario);
$I->wantTo('confirm the grace period dates are correct');
$paypalDate = \BB\Helpers\MembershipPayments::getSubGracePeriodDate('paypal');
//Make sure its a date that's returned
$I->assertEquals(get_parent_class($paypalDate), 'DateTime');
//Confirm the date is what we expect
$I->assertEquals(Carbon::now()->subDays(7)->setTime(0, 0, 0), $paypalDate);