Version 4.6.0

This commit is contained in:
Neo committed 2025-12-19 05:55:31 -08:00
1 parent f79dcf067a
commit 517a5e1f70
2036 files changed
+110041 -26162

No files matched your search

@@ -206,7 +206,28 @@ class _BillingAgreement extends \IPS\Patterns\ActiveRecord
{
$this->_data['started'] = $date->getTimestamp();
}
/**
* Suspend
*
* @return void
* @throws \DomainException
*/
public function refresh()
{
try
{
while( true )
{
$this->checkForLatestTransaction();
}
}
catch( \OutOfRangeException | \UnderflowException $e )
{
return;
}
}
/**
* Suspend
*
@@ -272,4 +293,96 @@ class _BillingAgreement extends \IPS\Patterns\ActiveRecord
{
return \IPS\Http\Url::internal( "app=nexus&module=payments&controller=billingagreements&id={$this->id}", 'admin' );
}
/**
* Check for latest unclaimed transactions
*
* @return void
*/
public function checkForLatestTransaction()
{
/* Fetch the latest unclaimed transaction */
try
{
$transaction = $this->latestUnclaimedTransaction();
}
/* If there isn't one yet, it might just be that PayPal hasn't taken it yet. Let it try for up to 5 days before giving up, which is how long PayPal will try for if there's an issue. */
catch ( \OutOfRangeException $e )
{
if ( $this->next_cycle->getTimestamp() > ( time() - ( 86400 * 5 ) ) )
{
throw new \UnderflowException;
}
else
{
/* We are here because we could not find any unclaimed transactions and it has been at least 5 days since we expected to. Verify the next cycle before proceeding because it may not have been set properly in the past so before we say there's a problem let's check. */
$nextPaymentDate = $this->nextPaymentDate();
if( $nextPaymentDate->getTimestamp() > time() )
{
$this->next_cycle = $nextPaymentDate;
$this->save();
throw new \UnderflowException;
}
throw $e;
}
}
/* Get purchases */
$purchases = new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_purchases', array( 'ps_billing_agreement=?', $this->id ) ), 'IPS\nexus\Purchase' );
/* Generate an invoice */
$invoice = new \IPS\nexus\Invoice;
$invoice->system = TRUE;
$invoice->currency = $transaction->amount->currency;
$invoice->member = $this->member;
$invoice->billaddress = $this->member->primaryBillingAddress();
foreach ( $purchases as $purchase )
{
$invoice->addItem( \IPS\nexus\Invoice\Item\Renewal::create( $purchase ) );
}
$invoice->save();
/* Assign the transaction to it */
$transaction->invoice = $invoice;
$transaction->save();
$transaction->approve();
$invoice->status = $transaction->invoice->status;
/* Log */
$invoice->member->log( 'transaction', array(
'type' => 'paid',
'status' => \IPS\nexus\Transaction::STATUS_PAID,
'id' => $transaction->id,
'invoice_id' => $invoice->id,
'invoice_title' => $invoice->title,
'automatic' => TRUE,
), FALSE );
/* Update the purchase */
if ( $invoice->status !== $invoice::STATUS_PAID )
{
foreach ( $purchases as $purchase )
{
$purchase->invoice_pending = $invoice;
$purchase->save();
}
}
/* Send notification */
$invoice->sendNotification();
/* Update billing agreement */
if ( $invoice->status === $invoice::STATUS_PAID )
{
$this->next_cycle = $this->nextPaymentDate();
}
else
{
$this->next_cycle = NULL;
}
$this->save();
}
}