Version 4.1.19
This commit is contained in:
1 parent
28bd025b35
commit
2bd5025018
2674 files changed
+233518
-77766
No files matched your search
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief License Key Model
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 30 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -49,6 +49,11 @@ abstract class _LicenseKey extends \IPS\Patterns\ActiveRecord
|
||||
*/
|
||||
protected static $databaseIdFields = array( 'lkey_purchase' );
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Map
|
||||
*/
|
||||
protected static $multitonMap = array();
|
||||
|
||||
/**
|
||||
* Construct ActiveRecord from database row
|
||||
*
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief License Key Model - MD5
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 30 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief License Key Model - Standard
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 30 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -62,21 +62,21 @@ class _Standard extends \IPS\nexus\Purchase\LicenseKey
|
||||
public function generate()
|
||||
{
|
||||
$key = array();
|
||||
foreach ( range( 1, self::$blocks ) as $i )
|
||||
foreach ( range( 1, static::$blocks ) as $i )
|
||||
{
|
||||
$_k = '';
|
||||
foreach ( range( 1, self::$characters ) as $j )
|
||||
foreach ( range( 1, static::$characters ) as $j )
|
||||
{
|
||||
do
|
||||
{
|
||||
$chr = rand( self::$low, self::$high );
|
||||
$chr = rand( static::$low, static::$high );
|
||||
}
|
||||
while ( in_array( $chr, self::$disallowed ) );
|
||||
while ( in_array( $chr, static::$disallowed ) );
|
||||
$_k .= chr( $chr );
|
||||
}
|
||||
$key[] = $_k;
|
||||
}
|
||||
|
||||
return implode( self::$seperator, $key );
|
||||
return implode( static::$seperator, $key );
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Purchase Model
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 10 Feb 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -107,11 +107,34 @@ class _Purchase extends \IPS\Node\Model
|
||||
{
|
||||
$childCount = $this->childrenCount( NULL, NULL, TRUE, array( array( 'ps_show=1' ) ) );
|
||||
$hasCustomFields = count( $this->custom_fields );
|
||||
|
||||
try
|
||||
{
|
||||
$description = call_user_func( array( $this->extension(), 'getPurchaseNameInfo' ), $this );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
$description = array();
|
||||
}
|
||||
if ( $this->grouped_renewals )
|
||||
{
|
||||
$description[] = \IPS\Member::loggedIn()->language()->addToStack('purchase_grouped');
|
||||
}
|
||||
elseif ( $this->renewals )
|
||||
{
|
||||
$renewals = (string) $this->renewals;
|
||||
if ( $this->renewals->tax )
|
||||
{
|
||||
$renewals .= \IPS\Member::loggedIn()->language()->addToStack( 'plus_tax_rate', NULL, array( 'sprintf' => array( $this->renewals->tax->_title ) ) );
|
||||
}
|
||||
$description[] = $renewals;
|
||||
}
|
||||
$description = implode( ' · ', $description );
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'trees', 'core' )->row(
|
||||
$url,
|
||||
$this->id,
|
||||
$hasCustomFields ? \IPS\Theme::i()->getTemplate( 'purchases', 'nexus' )->link( $this ) : $this->name,
|
||||
( $hasCustomFields and !$childCount ) ? \IPS\Theme::i()->getTemplate( 'purchases', 'nexus' )->link( $this, FALSE, FALSE, TRUE ) : $this->_name,
|
||||
$childCount,
|
||||
array_merge( array(
|
||||
'view' => array(
|
||||
@@ -120,13 +143,13 @@ class _Purchase extends \IPS\Node\Model
|
||||
'icon' => 'search',
|
||||
)
|
||||
), $this->buttons( $ref ) ),
|
||||
$this->grouped_renewals ? \IPS\Member::loggedIn()->language()->addToStack('purchase_grouped') : ( (string) ( $this->renewals ?: '' ) ),
|
||||
$description,
|
||||
$this->getIcon(),
|
||||
NULL,
|
||||
$this->id == \IPS\Request::i()->root,
|
||||
NULL,
|
||||
NULL,
|
||||
!$this->active ? ( $this->cancelled ? array( 'style5', 'canceled' ) : array( 'style6', 'expired' ) ) : NULL,
|
||||
!$this->active ? ( $this->cancelled ? array( 'style5', 'purchase_canceled' ) : array( 'style6', 'purchase_expired' ) ) : NULL,
|
||||
$hasCustomFields
|
||||
);
|
||||
}
|
||||
@@ -293,6 +316,10 @@ class _Purchase extends \IPS\Node\Model
|
||||
if ( !$this->expire or $this->expire->getTimestamp() > time() )
|
||||
{
|
||||
$this->active = TRUE;
|
||||
if ( $this->_data['cancelled'] )
|
||||
{
|
||||
$this->onReactivate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,7 +388,7 @@ class _Purchase extends \IPS\Node\Model
|
||||
*/
|
||||
public function get_renewals()
|
||||
{
|
||||
if( $this->_data['renewals'] )
|
||||
if( isset( $this->_data['renewals'] ) and $this->_data['renewals'] )
|
||||
{
|
||||
$tax = NULL;
|
||||
if ( $this->_data['tax'] )
|
||||
@@ -558,6 +585,38 @@ class _Purchase extends \IPS\Node\Model
|
||||
$this->_data['grouped_renewals'] = !is_null( $data ) ? json_encode( $data ) : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get billing agreement
|
||||
*
|
||||
* @return \IPS\nexus\Customer\BillingAgreement|NULL
|
||||
*/
|
||||
public function get_billing_agreement()
|
||||
{
|
||||
if ( $this->_data['billing_agreement'] )
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\nexus\Customer\BillingAgreement::load( $this->_data['billing_agreement'] );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
$this->_data['billing_agreement'] = NULL;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set billing agreement
|
||||
*
|
||||
* @param \IPS\nexus\Customer\BillingAgreement|NULL $billingAgreement The billing agreement
|
||||
* @return void
|
||||
*/
|
||||
public function set_billing_agreement( \IPS\nexus\Customer\BillingAgreement $billingAgreement = NULL )
|
||||
{
|
||||
$this->_data['billing_agreement'] = $billingAgreement === NULL ? NULL : $billingAgreement->id;
|
||||
}
|
||||
|
||||
/* !Properties and syncing */
|
||||
|
||||
/**
|
||||
@@ -569,12 +628,27 @@ class _Purchase extends \IPS\Node\Model
|
||||
* Get extension
|
||||
*
|
||||
* @return \IPS\nexus\Invoice\Item\Purchase
|
||||
* @throws \OutOfRangeException
|
||||
*/
|
||||
protected function extension()
|
||||
{
|
||||
if ( $this->extension === NULL )
|
||||
{
|
||||
foreach ( \IPS\Application::load( $this->app )->extensions( 'nexus', 'Item', FALSE ) as $ext )
|
||||
/* Load the app. \IPS\Application::load() throws UnexpectedValueException
|
||||
if the Application.php does not exist, which we'll standardize to
|
||||
OutOfRangeException so areas calling this method only need to check
|
||||
for that */
|
||||
try
|
||||
{
|
||||
$app = \IPS\Application::load( $this->app );
|
||||
}
|
||||
catch ( \UnexpectedValueException $e )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
|
||||
/* Find the extension */
|
||||
foreach ( $app->extensions( 'nexus', 'Item', FALSE ) as $ext )
|
||||
{
|
||||
if ( $ext::$type == $this->type )
|
||||
{
|
||||
@@ -582,6 +656,12 @@ class _Purchase extends \IPS\Node\Model
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't have it? */
|
||||
if ( !$this->extension )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
}
|
||||
return $this->extension;
|
||||
}
|
||||
@@ -742,6 +822,23 @@ class _Purchase extends \IPS\Node\Model
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ACP Support View HTML
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function acpSupportView()
|
||||
{
|
||||
try
|
||||
{
|
||||
return call_user_func( array( $this->extension(), 'acpSupportView' ), $this );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Support Severity
|
||||
*
|
||||
@@ -758,6 +855,23 @@ class _Purchase extends \IPS\Node\Model
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get renewal payment methods IDs
|
||||
*
|
||||
* @return array|NULL
|
||||
*/
|
||||
public function renewalPaymentMethodIds()
|
||||
{
|
||||
try
|
||||
{
|
||||
return call_user_func( array( $this->extension(), 'renewalPaymentMethodIds' ), $this );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call on*
|
||||
@@ -779,12 +893,67 @@ class _Purchase extends \IPS\Node\Model
|
||||
throw new \BadMethodCallException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get output for API
|
||||
*
|
||||
* @return array
|
||||
* @apiresponse int id ID number
|
||||
* @apiresponse string name Name
|
||||
* @apiresponse string itemApp Key for application. For example, 'nexus' for products and renewals; 'downloads' for Downloads files
|
||||
* @apiresponse string itemType Key for item type. For example, 'package' for products; 'file' for Downloads files.
|
||||
* @apiresponse int itemId The ID for the item. For example, the product ID or the file ID.
|
||||
* @apiresponse \IPS\nexus\Customer customer Customer
|
||||
* @apiresponse datetime purchased Purchased date
|
||||
* @apiresponse datetime expires Expiration date
|
||||
* @apiresponse bool active If purchase is currently active (not expired)
|
||||
* @apiresponse bool canceled If purchase has been canceled
|
||||
* @apiresponse \IPS\nexus\Purchase\RenewalTerm renewalTerm Renewal term
|
||||
* @apiresponse object customFields Values for custom fields
|
||||
* @apiresponse \IPS\nexus\Purchase parent Parent purchase
|
||||
* @apiresponse bool show If this purchase shows in the client area and AdminCP
|
||||
* @apiresponse string licenseKey License key
|
||||
* @apiresponse string image If the item has a relevant image (for exmaple, product image, Downloads file screenshot), the URL to it
|
||||
* @apiresponse string url The URL for the customer to view this purchase in the client area
|
||||
*/
|
||||
public function apiOutput()
|
||||
{
|
||||
$parent = NULL;
|
||||
if ( $this->parent )
|
||||
{
|
||||
try
|
||||
{
|
||||
$parent = static::load( $this->parent )->apiOutput();
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) {}
|
||||
}
|
||||
|
||||
return array(
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'itemApp' => $this->app,
|
||||
'itemType' => $this->type,
|
||||
'itemId' => $this->item_id,
|
||||
'customer' => $this->member->apiOutput(),
|
||||
'purchased' => $this->start->rfc3339(),
|
||||
'expires' => $this->expire ? $this->expire->rfc3339() : null,
|
||||
'active' => (bool) $this->active,
|
||||
'canceled' => (bool) $this->cancelled,
|
||||
'renewalTerm' => $this->renewals ? $this->renewals->apiOutput() : null,
|
||||
'customFields' => $this->custom_fields,
|
||||
'parent' => $parent,
|
||||
'show' => (bool) $this->show,
|
||||
'licenseKey' => $this->licenseKey() ? $this->licenseKey()->key : null,
|
||||
'image' => $this->image() ? ( (string) $this->image()->url ) : null,
|
||||
'url' => (string) $this->url(),
|
||||
);
|
||||
}
|
||||
|
||||
/* !License Keys */
|
||||
|
||||
/**
|
||||
* @brief License key
|
||||
*/
|
||||
protected $licenseKey;
|
||||
public $licenseKey;
|
||||
|
||||
/**
|
||||
* Get license key
|
||||
@@ -897,6 +1066,11 @@ class _Purchase extends \IPS\Node\Model
|
||||
*/
|
||||
public function canChangeExpireDate()
|
||||
{
|
||||
if ( $this->billing_agreement and !$this->billing_agreement->canceled )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return call_user_func( array( $this->extension(), 'canChangeExpireDate' ), $this );
|
||||
@@ -924,14 +1098,20 @@ class _Purchase extends \IPS\Node\Model
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( !$admin and $this->cancelled or !$this->expire or !$this->renewals )
|
||||
if ( $this->cancelled or !$this->renewals or ( $this->billing_agreement and !$this->billing_agreement->canceled ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( !$admin and $pendingInvoice = $this->invoice_pending and $pendingInvoice->status === $pendingInvoice::STATUS_PENDING )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$date = call_user_func( array( $this->extension(), 'canRenewUntil' ), $this, $admin );
|
||||
|
||||
|
||||
if ( $inCycles and $date instanceof \IPS\DateTime )
|
||||
{
|
||||
$now = \IPS\DateTime::create();
|
||||
@@ -967,7 +1147,7 @@ class _Purchase extends \IPS\Node\Model
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return !$this->grouped_renewals and $this->renewals and $this->active;
|
||||
return !$this->grouped_renewals and ( !$this->billing_agreement or $this->billing_agreement->canceled ) and $this->renewals and $this->active;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -984,7 +1164,7 @@ class _Purchase extends \IPS\Node\Model
|
||||
{
|
||||
if( $this->_url === NULL )
|
||||
{
|
||||
$this->_url = \IPS\Http\Url::internal( "app=nexus&module=clients&controller=purchases&do=view&id={$this->id}", 'front', 'clientspurchase', array( \IPS\Http\Url::seoTitle( $this->name ) ), \IPS\Settings::i()->nexus_https );
|
||||
$this->_url = \IPS\Http\Url::internal( "app=nexus&module=clients&controller=purchases&do=view&id={$this->id}", 'front', 'clientspurchase', array( \IPS\Http\Url\Friendly::seoTitle( $this->name ) ), \IPS\Settings::i()->nexus_https );
|
||||
}
|
||||
|
||||
return $this->_url;
|
||||
@@ -1017,12 +1197,19 @@ class _Purchase extends \IPS\Node\Model
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
\IPS\File::unclaimAttachments( 'nexus_Purchases', $this->id, NULL, 'purchase' );
|
||||
|
||||
foreach ( $this->children() as $child )
|
||||
{
|
||||
$child->delete();
|
||||
}
|
||||
|
||||
$this->onDelete();
|
||||
|
||||
try
|
||||
{
|
||||
$this->onDelete();
|
||||
}
|
||||
catch ( \BadMethodCallException $e ) {}
|
||||
|
||||
parent::delete();
|
||||
}
|
||||
|
||||
@@ -1049,33 +1236,27 @@ class _Purchase extends \IPS\Node\Model
|
||||
/* Remember what our term is */
|
||||
$term = $this->renewals->getTerm();
|
||||
$this->grouped_renewals = array( 'term' => $term['term'], 'unit' => $term['unit'], 'price' => $this->renewals->cost->amount, 'currency' => $this->renewals->cost->currency, 'tax' => $this->renewals->tax ? $this->renewals->tax->id : 0 );
|
||||
$this->save();
|
||||
|
||||
/* If the parent also has a renewal term, merge them */
|
||||
if ( $parent->renewals )
|
||||
/* Add our term to the parent... */
|
||||
if ( !$this->cancelled )
|
||||
{
|
||||
$parentCostPerDay = $parent->renewals->costPerDay();
|
||||
$itemCostPerDay = $this->renewals->costPerDay();
|
||||
if ( $parentCostPerDay->currency !== $itemCostPerDay->currency )
|
||||
/* If the parent also has a renewal term, merge them */
|
||||
if ( $parent->renewals )
|
||||
{
|
||||
throw new \DomainException('currencies_dont_match');
|
||||
$parent->renewals = new \IPS\nexus\Purchase\RenewalTerm( $parent->renewals->add( $this->renewals ), $parent->renewals->interval, $parent->renewals->tax );
|
||||
$parent->save();
|
||||
}
|
||||
|
||||
$sum = $parentCostPerDay->amount + $itemCostPerDay->amount;
|
||||
$increase = 1 / ( $parentCostPerDay->amount / $sum );
|
||||
$newRenewalPrice = new \IPS\nexus\Money( $parent->renewals->cost->amount * $increase, $itemCostPerDay->currency );
|
||||
|
||||
$parent->renewals = new \IPS\nexus\Purchase\RenewalTerm( $newRenewalPrice->round(), $parent->renewals->interval, $parent->renewals->tax );
|
||||
$parent->save();
|
||||
}
|
||||
/* Otherwise just set the parent to this */
|
||||
else
|
||||
{
|
||||
$parent->renewals = $this->renewals;
|
||||
if ( !$parent->expire )
|
||||
/* Otherwise just set the parent to this */
|
||||
else
|
||||
{
|
||||
$parent->expire = $this->expire;
|
||||
$parent->renewals = $this->renewals;
|
||||
if ( !$parent->expire )
|
||||
{
|
||||
$parent->expire = $this->expire;
|
||||
}
|
||||
$parent->save();
|
||||
}
|
||||
$parent->save();
|
||||
}
|
||||
|
||||
/* Cancel any pending invoices as they're no longer valid */
|
||||
@@ -1119,49 +1300,45 @@ class _Purchase extends \IPS\Node\Model
|
||||
if ( $this->renewals )
|
||||
{
|
||||
/* Restore parent renewal term */
|
||||
if ( $parent->renewals )
|
||||
if ( $parent->renewals and !$this->cancelled )
|
||||
{
|
||||
$parentCostPerDay = $parent->renewals->costPerDay();
|
||||
$itemCostPerDay = $this->renewals->costPerDay();
|
||||
if ( $parentCostPerDay->currency !== $itemCostPerDay->currency )
|
||||
$newRenewalPrice = $parent->renewals->subtract( $this->renewals );
|
||||
if ( $newRenewalPrice->amount->isZero() )
|
||||
{
|
||||
throw new \DomainException('currencies_dont_match');
|
||||
}
|
||||
$sum = $parentCostPerDay->amount - $itemCostPerDay->amount;
|
||||
|
||||
if ( $sum and ( $parentCostPerDay->amount / $sum ) )
|
||||
{
|
||||
$increase = 1 / ( $parentCostPerDay->amount / $sum );
|
||||
$newRenewalPrice = new \IPS\nexus\Money( $parent->renewals->cost->amount * $increase, $parent->renewals->cost->currency );
|
||||
$parent->renewals = new \IPS\nexus\Purchase\RenewalTerm( $newRenewalPrice->round(), $parent->renewals->interval, $parent->renewals->tax );
|
||||
$parent->renewals = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
$parent->renewals = NULL;
|
||||
$parent->renewals = new \IPS\nexus\Purchase\RenewalTerm( $newRenewalPrice, $parent->renewals->interval, $parent->renewals->tax );
|
||||
}
|
||||
$parent->save();
|
||||
}
|
||||
|
||||
/* Restore this purchase renewal term */
|
||||
$groupedRenewals = $this->grouped_renewals;
|
||||
try
|
||||
if ( $groupedRenewals['term'] and $groupedRenewals['unit'] )
|
||||
{
|
||||
$tax = ( isset( $groupedRenewals['tax'] ) and $groupedRenewals['tax'] ) ? \IPS\nexus\Tax::load( $groupedRenewals['tax'] ) : NULL;
|
||||
try
|
||||
{
|
||||
$tax = ( isset( $groupedRenewals['tax'] ) and $groupedRenewals['tax'] ) ? \IPS\nexus\Tax::load( $groupedRenewals['tax'] ) : NULL;
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
$tax = NULL;
|
||||
}
|
||||
$this->renewals = new \IPS\nexus\Purchase\RenewalTerm(
|
||||
new \IPS\nexus\Money( $groupedRenewals['price'], isset( $groupedRenewals['currency'] ) ? $groupedRenewals['currency'] : $this->member->defaultCurrency() ),
|
||||
new \DateInterval( 'P' . $groupedRenewals['term'] . mb_strtoupper( $groupedRenewals['unit'] ) ),
|
||||
$tax
|
||||
);
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
$tax = NULL;
|
||||
}
|
||||
$this->renewals = new \IPS\nexus\Purchase\RenewalTerm(
|
||||
new \IPS\nexus\Money( $groupedRenewals['price'], isset( $groupedRenewals['currency'] ) ? $groupedRenewals['currency'] : $this->member->defaultCurrency() ),
|
||||
new \DateInterval( 'P' . $groupedRenewals['term'] . mb_strtoupper( $groupedRenewals['unit'] ) ),
|
||||
$tax
|
||||
);
|
||||
$this->expire = $parent->expire;
|
||||
$this->grouped_renewals = NULL;
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/* Ungroup */
|
||||
$this->grouped_renewals = NULL;
|
||||
$this->save();
|
||||
|
||||
/* Cancel any pending invoices as they're no longer valid */
|
||||
if ( $invoice = $parent->invoice_pending )
|
||||
{
|
||||
@@ -1214,8 +1391,10 @@ class _Purchase extends \IPS\Node\Model
|
||||
$return = array_merge( $return, call_user_func( array( $this->extension(), 'acpButtons' ), $this, $url ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
|
||||
$parent = $this->parent();
|
||||
|
||||
if ( !$this->grouped_renewals and $this->renewals and \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'invoices_add' ) )
|
||||
if ( !$this->grouped_renewals and ( !$this->billing_agreement or $this->billing_agreement->canceled ) and $this->renewals and \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'invoices_add' ) )
|
||||
{
|
||||
$return['renew'] = array(
|
||||
'icon' => 'refresh',
|
||||
@@ -1225,7 +1404,7 @@ class _Purchase extends \IPS\Node\Model
|
||||
);
|
||||
}
|
||||
|
||||
if ( $this->parent() and \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'purchases_edit' ) )
|
||||
if ( ( !$this->billing_agreement or $this->billing_agreement->canceled ) and $this->parent() and \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'purchases_edit' ) )
|
||||
{
|
||||
if ( !$this->grouped_renewals )
|
||||
{
|
||||
@@ -1247,7 +1426,7 @@ class _Purchase extends \IPS\Node\Model
|
||||
}
|
||||
}
|
||||
|
||||
if( !$this->grouped_renewals and \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'purchases_transfer' ) )
|
||||
if( ( !$this->billing_agreement or $this->billing_agreement->canceled ) and !$this->grouped_renewals and \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'purchases_transfer' ) )
|
||||
{
|
||||
$return['transfer'] = array(
|
||||
'icon' => 'user',
|
||||
@@ -1257,7 +1436,7 @@ class _Purchase extends \IPS\Node\Model
|
||||
);
|
||||
}
|
||||
|
||||
if ( !$this->grouped_renewals and \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'purchases_cancel' ) )
|
||||
if ( ( !$this->billing_agreement or $this->billing_agreement->canceled ) and ( !$this->grouped_renewals or !$parent or !$parent->billing_agreement or $parent->billing_agreement->canceled ) and \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'purchases_cancel' ) )
|
||||
{
|
||||
if ( $this->cancelled )
|
||||
{
|
||||
@@ -1279,7 +1458,7 @@ class _Purchase extends \IPS\Node\Model
|
||||
}
|
||||
}
|
||||
|
||||
if ( !$this->grouped_renewals and \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'purchases_delete' ) )
|
||||
if ( ( !$this->billing_agreement or $this->billing_agreement->canceled ) and ( !$this->grouped_renewals or !$parent or !$parent->billing_agreement or $parent->billing_agreement->canceled ) and \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'purchases_delete' ) )
|
||||
{
|
||||
$return['delete'] = array(
|
||||
'icon' => 'times-circle',
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Renewal Term Object
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 13 Feb 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -129,7 +129,7 @@ class _RenewalTerm
|
||||
{
|
||||
$days += $this->interval->d;
|
||||
}
|
||||
return $days;
|
||||
return number_format( $days, 2, '.', '' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,18 +146,161 @@ class _RenewalTerm
|
||||
}
|
||||
else
|
||||
{
|
||||
return new \IPS\nexus\Money( $this->cost->amount / $days, $this->cost->currency );
|
||||
return new \IPS\nexus\Money( $this->cost->amount->divide( new \IPS\Math\Number("{$days}") ), $this->cost->currency );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the combined cost of this term and another term (used for grouping)
|
||||
*
|
||||
* @param \IPS\nexus\Purchase\RenewalTerm $term Term to add
|
||||
* @return \IPS\nexus\Money
|
||||
* @throws \DomainException
|
||||
*/
|
||||
public function add( RenewalTerm $term )
|
||||
{
|
||||
/* They need to have the same currency */
|
||||
if ( $this->cost->currency !== $term->cost->currency )
|
||||
{
|
||||
throw new \DomainException('currencies_dont_match');
|
||||
}
|
||||
|
||||
/* Get some details */
|
||||
$thisTerm = $this->getTerm();
|
||||
$otherTerm = $term->getTerm();
|
||||
$adjustedCost = $term->cost->amount;
|
||||
|
||||
/* If they're not based on the same term, try to normalise as best we can */
|
||||
if ( $thisTerm['unit'] != $otherTerm['unit'] )
|
||||
{
|
||||
switch ( $thisTerm['unit'] )
|
||||
{
|
||||
case 'd':
|
||||
switch ( $otherTerm['unit'] )
|
||||
{
|
||||
case 'm':
|
||||
$otherTerm['term'] *= ( 365 / 12 );
|
||||
break;
|
||||
|
||||
case 'y':
|
||||
$otherTerm['term'] *= 365;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'm':
|
||||
switch ( $otherTerm['unit'] )
|
||||
{
|
||||
case 'd':
|
||||
$thisTerm['term'] *= ( 365 / 12 );
|
||||
break;
|
||||
|
||||
case 'y':
|
||||
$otherTerm['term'] *= 12;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'y':
|
||||
switch ( $otherTerm['unit'] )
|
||||
{
|
||||
case 'd':
|
||||
$thisTerm['term'] *= 365;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
$thisTerm['term'] *= 12;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If they're not the same term, adjust */
|
||||
if ( $thisTerm['term'] != $otherTerm['term'] )
|
||||
{
|
||||
$adjustedCost = $adjustedCost->multiply( ( ( new \IPS\Math\Number("{$thisTerm['term']}") )->divide( new \IPS\Math\Number("{$otherTerm['term']}") ) ) );
|
||||
}
|
||||
|
||||
/* And return */
|
||||
return new \IPS\nexus\Money( $this->cost->amount->add( $adjustedCost ), $this->cost->currency );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cost of this term subtract another term (used for grouping)
|
||||
*
|
||||
* @param \IPS\nexus\Purchase\RenewalTerm $term Term to subtract
|
||||
* @return \IPS\nexus\Money
|
||||
* @throws \DomainException
|
||||
*/
|
||||
public function subtract( RenewalTerm $term )
|
||||
{
|
||||
$term->cost->amount = $term->cost->amount->multiply( new \IPS\Math\Number( '-1' ) );
|
||||
return $this->add( $term );
|
||||
}
|
||||
|
||||
/**
|
||||
* Times quantity (used to describe a combined renewal cost)
|
||||
*
|
||||
* @param int $n The number to times by
|
||||
* @return string
|
||||
*/
|
||||
public function times( $n )
|
||||
{
|
||||
$cost = new \IPS\nexus\Money( $this->cost->amount->multiply( new \IPS\Math\Number("{$n}") ), $this->cost->currency );
|
||||
return sprintf( \IPS\Member::loggedIn()->language()->get( 'renew_option'), $cost, $this->getTermUnit() );
|
||||
}
|
||||
|
||||
/**
|
||||
* To String
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
//return \IPS\Member::loggedIn()->language()->addToStack( 'renew_option', FALSE, array( 'sprintf' => array( $this->cost, $this->getTermUnit() ) ) );
|
||||
{
|
||||
return sprintf( \IPS\Member::loggedIn()->language()->get( 'renew_option'), $this->cost, $this->getTermUnit() ) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* To String incl. tax
|
||||
*
|
||||
* @param \IPS\nexus\Customer|NULL $customer The customer (NULL for currently logged in member)
|
||||
* @param int $quantity The quantity to times amount by
|
||||
* @return string
|
||||
*/
|
||||
public function toDisplay( \IPS\nexus\Customer $customer = NULL, $quantity = 1 )
|
||||
{
|
||||
$cost = $this->cost;
|
||||
if ( \IPS\Settings::i()->nexus_show_tax and $this->tax )
|
||||
{
|
||||
$customer = $customer ?: \IPS\nexus\Customer::loggedIn();
|
||||
$taxRate = new \IPS\Math\Number( $this->tax->rate( $customer->estimatedLocation() ) );
|
||||
$cost = new \IPS\nexus\Money( $cost->amount->add( $cost->amount->multiply( $taxRate ) ), $cost->currency );
|
||||
}
|
||||
|
||||
if ( $quantity != 1 )
|
||||
{
|
||||
$cost = new \IPS\nexus\Money( $cost->amount->multiply( $quantity ), $cost->currency );
|
||||
}
|
||||
|
||||
return sprintf( \IPS\Member::loggedIn()->language()->get( 'renew_option'), $cost, $this->getTermUnit() ) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get output for API
|
||||
*
|
||||
* @return array
|
||||
* @apiresponse string term 'd' for days; 'w' for weeks; 'm' for months; 'y' for years
|
||||
* @apiresponse int unit The number for term. For example, if the renewal term is every 6 months, term will be 'm' and unit will be 6
|
||||
* @apiresponse \IPS\nexus\Money price The renewal price
|
||||
* @apiresponse \IPS\nexus\Tax taxClass If the renewal price is taxed, the tax class that applies
|
||||
*/
|
||||
public function apiOutput()
|
||||
{
|
||||
$term = $this->getTerm();
|
||||
return array(
|
||||
'term' => $term['term'],
|
||||
'unit' => $term['unit'],
|
||||
'price' => $this->cost->apiOutput(),
|
||||
'taxClass' => $this->tax ? $this->tax->apiOutput() : null,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user