Version 4.3.6
This commit is contained in:
1 parent
fe1acf984a
commit
1a0c7fd3c2
609 files changed
+14707
-5726
No files matched your search
@@ -447,4 +447,28 @@ class _Coupon extends \IPS\Node\Model
|
||||
$this->used_by = array();
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Search
|
||||
*
|
||||
* @param string $column Column to search
|
||||
* @param string $query Search query
|
||||
* @param string|null $order Column to order by
|
||||
* @param mixed $where Where clause
|
||||
* @return array
|
||||
*/
|
||||
public static function search( $column, $query, $order, $where=array() )
|
||||
{
|
||||
if( $column === '_title' )
|
||||
{
|
||||
$column = 'c_code';
|
||||
}
|
||||
|
||||
if( $order === '_title' )
|
||||
{
|
||||
$order = 'c_code';
|
||||
}
|
||||
|
||||
return parent::search( $column, $query, $order, $where );
|
||||
}
|
||||
}
|
||||
@@ -873,7 +873,7 @@ class _Rule extends \IPS\Node\Model
|
||||
$amounts = json_decode( $this->customer_spend_unit, TRUE );
|
||||
|
||||
$spent = array();
|
||||
foreach ( \IPS\Db::i()->select( 't_currency, ( SUM(t_amount)-SUM(t_partial_refund) ) AS amount', 'nexus_transactions', array( 't_member=? AND ( t_status=? OR t_status=? )', $transaction->member->member_id, \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED ), NULL, NULL, 't_currency' ) as $amount )
|
||||
foreach ( \IPS\Db::i()->select( 't_currency, ( SUM(t_amount)-SUM(t_partial_refund) ) AS amount', 'nexus_transactions', array( 't_member=? AND ( t_status=? OR t_status=? ) AND t_method>0', $transaction->member->member_id, \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED ), NULL, NULL, 't_currency' ) as $amount )
|
||||
{
|
||||
$spent[ $amount['t_currency'] ] = $amount['amount'];
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ class _BillingAgreement extends \IPS\nexus\Customer\BillingAgreement
|
||||
* @return \IPS\nexus\Transaction
|
||||
* @throws \IPS\nexus\Gateway\PayPal\Exception
|
||||
* @throws \OutOfRangeException
|
||||
* @throws \IPS\Http\Exception
|
||||
* @throws \IPS\Http\Url\Exception
|
||||
*/
|
||||
public function latestUnclaimedTransaction()
|
||||
{
|
||||
@@ -121,7 +121,7 @@ class _BillingAgreement extends \IPS\nexus\Customer\BillingAgreement
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( \IPS\Http\Exception $e )
|
||||
catch ( \IPS\Http\Url\Exception $e )
|
||||
{
|
||||
throw $e;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,8 @@ class _PayPal extends \IPS\nexus\Gateway
|
||||
/* Card payments can only be certain currency amounts and require name and billing address */
|
||||
if ( $settings['type'] === 'card' )
|
||||
{
|
||||
if ( !in_array( $amount->currency, array( 'USD', 'GBP', 'CAD', 'EUR', 'JPY' ) ) or !$customer->cm_first_name or !$customer->cm_last_name or !$billingAddress )
|
||||
/* Supported Currencies via https://developer.paypal.com/docs/integration/direct/rest/currency-codes/ */
|
||||
if ( !\in_array( $amount->currency, array( 'AUD', 'USD', 'CZK', 'DKK', 'HKD', 'ILS', 'CAD', 'EUR', 'MXN', 'NZD', 'NOK', 'PHP', 'PLN', 'JPY', 'GBP', 'RUB', 'SGD', 'SEK', 'CHF', 'THB' ) ) or !$customer->cm_first_name or !$customer->cm_last_name or !$billingAddress )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -465,6 +465,10 @@ class _Stripe extends \IPS\nexus\Gateway
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if ( $billingAddress and !in_array( $billingAddress->country, array( 'AT', 'AU', 'BE', 'BR', 'CA', 'CH', 'DE', 'DK', 'EE', 'ES', 'FI', 'FR', 'GB', 'HK', 'IE', 'IN', 'IT', 'JP', 'LT', 'LU', 'LV', 'MX', 'NL', 'NZ', 'NO', 'PH', 'PL', 'PT', 'RO', 'SE', 'SG', 'SK', 'US' ) ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Still here? Do normal checks */
|
||||
@@ -659,7 +663,7 @@ class _Stripe extends \IPS\nexus\Gateway
|
||||
$maxMind->setTransactionType('creditcard');
|
||||
}
|
||||
}
|
||||
|
||||
$transaction->save();
|
||||
/* Build data */
|
||||
$data = array(
|
||||
'amount' => static::_amountAsCents( $transaction->amount ),
|
||||
@@ -669,7 +673,7 @@ class _Stripe extends \IPS\nexus\Gateway
|
||||
'metadata' => array(
|
||||
"Transaction ID" => $transaction->id,
|
||||
"Invoice ID" => $transaction->invoice->id,
|
||||
"Customer ID" => $transaction->member->id,
|
||||
"Customer ID" => $transaction->member->member_id,
|
||||
"Customer Email" => $transaction->member->email,
|
||||
),
|
||||
);
|
||||
@@ -728,6 +732,8 @@ class _Stripe extends \IPS\nexus\Gateway
|
||||
{
|
||||
$transaction->save();
|
||||
|
||||
/* Create the 3DSecure source */
|
||||
$returnUrl = \IPS\Settings::i()->base_url . 'applications/nexus/interface/gateways/stripe-redirector.php?nexusTransactionId=' . $transaction->id;
|
||||
$response = $this->api( "sources", array(
|
||||
'type' => 'three_d_secure',
|
||||
'amount' => static::_amountAsCents( $transaction->amount ),
|
||||
@@ -736,14 +742,30 @@ class _Stripe extends \IPS\nexus\Gateway
|
||||
'card' => $card->token
|
||||
),
|
||||
'redirect' => array(
|
||||
'return_url' => \IPS\Settings::i()->base_url . 'applications/nexus/interface/gateways/stripe-redirector.php?nexusTransactionId=' . $transaction->id
|
||||
'return_url' => $returnUrl
|
||||
),
|
||||
) );
|
||||
|
||||
/* If it's ready for them, send the customer over to the URL */
|
||||
if ( $response['status'] == 'pending' )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $response['redirect']['url'] );
|
||||
}
|
||||
|
||||
/* It it's already chargeable (from Stripe: "This can happen if the customer's card has not yet
|
||||
been enrolled in 3D Secure") then we don't need to redirect them, but the webhooks will handle
|
||||
it from here, as if the customer had been redirected and authorized. Therefore, we can redirect
|
||||
the customer to the return URL where they would have been redirected had they actually authorized */
|
||||
elseif ( $response['status'] == 'chargeable' )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $returnUrl );
|
||||
}
|
||||
|
||||
// If it failed (the only other possible value for $response['status']) Stripe advises "you can either
|
||||
// continue with a regular card payment, interrupt the payment flow, or attempt to create a 3D Secure
|
||||
// source later". We'll opt for continuing with a regular card payment, which means there's no else
|
||||
// clause here, we're just letting the code fall through below as if 3DSecure had been detected as not
|
||||
// being required.
|
||||
}
|
||||
|
||||
/* Are we saving it? */
|
||||
@@ -853,7 +875,20 @@ class _Stripe extends \IPS\nexus\Gateway
|
||||
return;
|
||||
}
|
||||
|
||||
$this->api( "charges/{$transaction->gw_id}/capture" );
|
||||
try
|
||||
{
|
||||
$this->api( "charges/{$transaction->gw_id}/capture" );
|
||||
}
|
||||
catch( \IPS\nexus\Gateway\Stripe\Exception $e )
|
||||
{
|
||||
/* If we have already captured/refunded the charge we don't need to let an exception bubble up */
|
||||
if( $e->details['code'] == 'charge_already_captured' or $e->details['code'] == 'charge_already_refunded' )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -929,6 +964,10 @@ class _Stripe extends \IPS\nexus\Gateway
|
||||
return \IPS\Theme::i()->getTemplate( 'transactions', 'nexus', 'admin' )->stripeData( $response, 'error' );
|
||||
}
|
||||
}
|
||||
elseif ( $response['source']['object'] === 'card' and isset( $response['card'] ) ) // For cards stored in older versions
|
||||
{
|
||||
$response['source']['card'] = $response['card'];
|
||||
}
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'transactions', 'nexus', 'admin' )->stripeData( $response );
|
||||
}
|
||||
|
||||
@@ -1270,6 +1270,7 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
if ( $transaction->status === \IPS\nexus\Transaction::STATUS_PART_REFUNDED )
|
||||
{
|
||||
$amountToSubtract = $amountToSubtract->subtract( $transaction->partial_refund->amount );
|
||||
$amountToSubtract = $amountToSubtract->subtract( $transaction->credit->amount );
|
||||
}
|
||||
|
||||
$amountToPay->amount = $amountToPay->amount->subtract( $amountToSubtract );
|
||||
|
||||
@@ -343,23 +343,22 @@ class _Ad extends \IPS\nexus\Package
|
||||
$field = new \IPS\Helpers\Form\Url( 'advertisement_url' . $k, NULL, TRUE );
|
||||
$field->label = \IPS\Member::loggedIn()->language()->addToStack('advertisement_url');
|
||||
$form->add( $field );
|
||||
|
||||
$maxDims = TRUE;
|
||||
if ( $this->max_height or $this->max_width )
|
||||
{
|
||||
$maxDims = array();
|
||||
if ( $this->max_width )
|
||||
{
|
||||
$maxDims['maxWidth'] = $this->max_width;
|
||||
}
|
||||
if ( $this->max_height )
|
||||
{
|
||||
$maxDims['maxHeight'] = $this->max_height;
|
||||
}
|
||||
}
|
||||
$field = new \IPS\Helpers\Form\Upload( 'advertisement_image' . $k, NULL, TRUE, array( 'storageExtension' => 'nexus_Ads', 'image' => $maxDims ) );
|
||||
$field->label = \IPS\Member::loggedIn()->language()->addToStack('advertisement_image');
|
||||
|
||||
$field = new \IPS\Helpers\Form\Upload( 'ad_image' . $k, NULL, TRUE, array( 'image' => TRUE, 'storageExtension' => 'nexus_Ads' ) );
|
||||
$field->label = \IPS\Member::loggedIn()->language()->addToStack('ad_image');
|
||||
$form->add( $field );
|
||||
|
||||
$field = new \IPS\Helpers\Form\YesNo( 'ad_image_more' . $k, FALSE, FALSE, array( 'togglesOn' => array( 'ad_image_small' . $k, 'ad_image_medium' . $k ) ) );
|
||||
$field->label = \IPS\Member::loggedIn()->language()->addToStack('ad_image_more');
|
||||
$form->add( $field );
|
||||
|
||||
$field = new \IPS\Helpers\Form\Upload( 'ad_image_small' . $k, NULL, FALSE, array( 'image' => TRUE, 'storageExtension' => 'nexus_Ads' ), NULL, NULL, NULL, 'ad_image_small' . $k );
|
||||
$field->label = \IPS\Member::loggedIn()->language()->addToStack('ad_image_small');
|
||||
$form->add( $field );
|
||||
|
||||
$field = new \IPS\Helpers\Form\Upload( 'ad_image_medium' . $k, NULL, FALSE, array( 'image' => TRUE, 'storageExtension' => 'nexus_Ads' ), NULL, NULL, NULL, 'ad_image_medium' . $k );
|
||||
$field->label = \IPS\Member::loggedIn()->language()->addToStack('ad_image_medium');
|
||||
$form->add( $field );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -373,7 +372,7 @@ class _Ad extends \IPS\nexus\Package
|
||||
*/
|
||||
public function acpAddToInvoice( \IPS\nexus\extensions\nexus\Item\Package $item, array $values, $k, \IPS\nexus\Invoice $invoice )
|
||||
{
|
||||
$item->extra['image'] = (string) $values[ 'advertisement_image' . $k ];
|
||||
$item->extra['image'] = json_encode( array( 'large' => (string) $values[ 'ad_image' . $k ], 'medium' => (string) $values[ 'ad_image_medium' . $k ], 'small' => (string) $values[ 'ad_image_small' . $k ] ) );
|
||||
$item->extra['link'] = (string) $values[ 'advertisement_url' . $k ];
|
||||
}
|
||||
|
||||
|
||||
@@ -106,6 +106,23 @@ class _CustomField extends \IPS\CustomField
|
||||
*/
|
||||
public static $editorOptions = array( 'app' => 'nexus', 'key' => 'Purchases' );
|
||||
|
||||
/**
|
||||
* @brief [CustomField] Additional Field Toggles
|
||||
*/
|
||||
public static $additionalFieldToggles = array(
|
||||
'Address' => array( 'cf_sticky' ),
|
||||
'Checkbox' => array( 'cf_sticky' ),
|
||||
'CheckboxSet' => array( 'cf_sticky' ),
|
||||
'Date' => array( 'cf_sticky' ),
|
||||
'Email' => array( 'cf_sticky' ),
|
||||
'Number' => array( 'cf_sticky' ),
|
||||
'Password' => array( 'cf_sticky' ),
|
||||
'Radio' => array( 'cf_sticky' ),
|
||||
'Text' => array( 'cf_sticky' ),
|
||||
'Url' => array( 'cf_sticky' ),
|
||||
'YesNo' => array( 'cf_sticky' ),
|
||||
);
|
||||
|
||||
/**
|
||||
* [Node] Add/Edit Form
|
||||
*
|
||||
@@ -129,7 +146,7 @@ class _CustomField extends \IPS\CustomField
|
||||
{
|
||||
return !( $node instanceof \IPS\nexus\Package\Group );
|
||||
} ) ), 'pf_desc' );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'cf_sticky', $this->sticky, FALSE ), 'pf_type' );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'cf_sticky', $this->sticky, FALSE, array(), NULL, NULL, NULL, 'cf_sticky' ), 'pf_type' );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'cf_allow_attachments', $this->id ? $this->allow_attachments : 1, FALSE, array( ), NULL, NULL, NULL, 'pf_allow_attachments' ) );
|
||||
|
||||
$form->addHeader( 'display_settings' );
|
||||
|
||||
@@ -699,7 +699,7 @@ class _Package extends \IPS\Node\Model
|
||||
{
|
||||
if ( $v and isset( $customFields[ $k ] ) and $customFields[ $k ]->sticky )
|
||||
{
|
||||
$stickyFields[] = $v;
|
||||
$stickyFields[] = strip_tags( \IPS\nexus\Package\CustomField::load( $k )->displayValue( $v, TRUE ) ); // We need to call displayValue so things like dates and select boxes show the right value, but we *also* need to call strip_tags as Url fields will return full links and we need text only. Note that fields which would show something other than a simple text output are prevented from being used in this context
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1327,90 +1327,100 @@ class _Package extends \IPS\Node\Model
|
||||
unset( $values['p_stock_price_type'] );
|
||||
unset( $values['custom_fields'] );
|
||||
}
|
||||
|
||||
/* Discounts */
|
||||
if( isset( $values['p_usergroup_discounts'] ) OR isset( $values['p_loyalty_discounts'] ) OR isset( $values['p_bulk_discounts'] ) )
|
||||
/* Reset the discounts ? */
|
||||
if ( isset( $values['p_set_discounts'] ) AND !$values['p_set_discounts'] )
|
||||
{
|
||||
$discounts = array();
|
||||
}
|
||||
|
||||
if( isset( $values['p_usergroup_discounts'] ) )
|
||||
{
|
||||
foreach ( $values['p_usergroup_discounts'] as $k => $data )
|
||||
{
|
||||
if ( isset( $data['group'] ) and $data['group'] and isset( $data['price'] ) )
|
||||
{
|
||||
foreach( $data['price'] as $price )
|
||||
{
|
||||
if ( !$price )
|
||||
{
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
$discounts['usergroup'][] = array(
|
||||
'group' => $data['group'],
|
||||
'price' => $data['price'],
|
||||
'secondary' => (int) isset( $data['secondary'] ),
|
||||
);
|
||||
}
|
||||
}
|
||||
unset( $values['p_usergroup_discounts'] );
|
||||
}
|
||||
|
||||
if( isset( $values['p_loyalty_discounts'] ) )
|
||||
{
|
||||
foreach ( $values['p_loyalty_discounts'] as $k => $data )
|
||||
{
|
||||
if ( $data['owns'] )
|
||||
{
|
||||
foreach( $data['price'] as $price )
|
||||
{
|
||||
if ( !$price )
|
||||
{
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
$packageId = $data['package'] ? mb_substr( $data['package'], 0, mb_strpos( $data['package'], '.' ) ) : 0;
|
||||
|
||||
$discounts['loyalty'][] = array(
|
||||
'owns' => $data['owns'],
|
||||
'package' => ( $data['this'] or ( $this->id and $this->id == $packageId ) ) ? '0' : $packageId,
|
||||
'price' => $data['price'],
|
||||
'active' => (int) isset( $data['active'] ),
|
||||
);
|
||||
}
|
||||
}
|
||||
unset( $values['p_loyalty_discounts'] );
|
||||
}
|
||||
|
||||
if( isset( $values['p_bulk_discounts'] ) )
|
||||
{
|
||||
foreach ( $values['p_bulk_discounts'] as $k => $data )
|
||||
{
|
||||
if ( $data['buying'] )
|
||||
{
|
||||
foreach( $data['price'] as $price )
|
||||
{
|
||||
if ( !$price )
|
||||
{
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
$packageId = $data['package'] ? mb_substr( $data['package'], 0, mb_strpos( $data['package'], '.' ) ) : 0;
|
||||
|
||||
$discounts['bulk'][] = array(
|
||||
'buying' => $data['buying'],
|
||||
'package' => ( $data['this'] or ( $this->id and $this->id == $packageId ) ) ? '0' : $packageId,
|
||||
'price' => $data['price'],
|
||||
);
|
||||
}
|
||||
}
|
||||
unset( $values['p_bulk_discounts'] );
|
||||
$values['discounts'] = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Discounts */
|
||||
if (isset($values['p_usergroup_discounts']) OR isset($values['p_loyalty_discounts']) OR isset($values['p_bulk_discounts']))
|
||||
{
|
||||
$discounts = array();
|
||||
}
|
||||
|
||||
if (isset($values['p_usergroup_discounts']))
|
||||
{
|
||||
foreach ($values['p_usergroup_discounts'] as $k => $data)
|
||||
{
|
||||
if (isset($data['group']) and $data['group'] and isset($data['price']))
|
||||
{
|
||||
foreach ($data['price'] as $price)
|
||||
{
|
||||
if (!$price)
|
||||
{
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
$discounts['usergroup'][] = array(
|
||||
'group' => $data['group'],
|
||||
'price' => $data['price'],
|
||||
'secondary' => (int)isset($data['secondary']),
|
||||
);
|
||||
}
|
||||
}
|
||||
unset($values['p_usergroup_discounts']);
|
||||
}
|
||||
|
||||
if (isset($values['p_loyalty_discounts']))
|
||||
{
|
||||
foreach ($values['p_loyalty_discounts'] as $k => $data)
|
||||
{
|
||||
if ($data['owns'])
|
||||
{
|
||||
foreach ($data['price'] as $price)
|
||||
{
|
||||
if (!$price)
|
||||
{
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
$packageId = $data['package'] ? mb_substr($data['package'], 0, mb_strpos($data['package'], '.')) : 0;
|
||||
|
||||
$discounts['loyalty'][] = array(
|
||||
'owns' => $data['owns'],
|
||||
'package' => ($data['this'] or ($this->id and $this->id == $packageId)) ? '0' : $packageId,
|
||||
'price' => $data['price'],
|
||||
'active' => (int)isset($data['active']),
|
||||
);
|
||||
}
|
||||
}
|
||||
unset($values['p_loyalty_discounts']);
|
||||
}
|
||||
|
||||
if (isset($values['p_bulk_discounts']))
|
||||
{
|
||||
foreach ($values['p_bulk_discounts'] as $k => $data)
|
||||
{
|
||||
if ($data['buying'])
|
||||
{
|
||||
foreach ($data['price'] as $price)
|
||||
{
|
||||
if (!$price)
|
||||
{
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
$packageId = $data['package'] ? mb_substr($data['package'], 0, mb_strpos($data['package'], '.')) : 0;
|
||||
|
||||
$discounts['bulk'][] = array(
|
||||
'buying' => $data['buying'],
|
||||
'package' => ($data['this'] or ($this->id and $this->id == $packageId)) ? '0' : $packageId,
|
||||
'price' => $data['price'],
|
||||
);
|
||||
}
|
||||
}
|
||||
unset($values['p_bulk_discounts']);
|
||||
}
|
||||
}
|
||||
|
||||
if( isset( $discounts ) )
|
||||
{
|
||||
$values['discounts'] = json_encode( $discounts );
|
||||
@@ -1821,6 +1831,18 @@ class _Package extends \IPS\Node\Model
|
||||
{
|
||||
$optionValues = $this->optionValues( $details );
|
||||
$return = array();
|
||||
|
||||
/* If we do not have a currency in our session data, set it now so that if the language is changed, it is not confused about
|
||||
what currency the store should be in */
|
||||
if ( ( isset( $_SESSION['currency'] ) and in_array( $_SESSION['currency'], \IPS\nexus\Money::currencies() ) ) )
|
||||
{
|
||||
$memberCurrency = $_SESSION['currency'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$memberCurrency = \IPS\nexus\Customer::loggedIn()->defaultCurrency();
|
||||
$_SESSION['currency'] = $memberCurrency;
|
||||
}
|
||||
|
||||
/* Work out how we're splitting these */
|
||||
$items = array();
|
||||
@@ -1828,8 +1850,11 @@ class _Package extends \IPS\Node\Model
|
||||
$inThisBatch = 0;
|
||||
for ( $i=0; $i<$quantity;$i++ )
|
||||
{
|
||||
$price = $this->price( NULL, TRUE, TRUE, TRUE, $i );
|
||||
$memberCurrency = $price->currency;
|
||||
$price = $this->price( NULL, TRUE, TRUE, TRUE, $i );
|
||||
if ( $price->currency !== $memberCurrency )
|
||||
{
|
||||
throw new \RuntimeException('CURRENCY_MISMATCH');
|
||||
}
|
||||
$price = $price->amount;
|
||||
|
||||
if ( $previousPrice !== NULL and $previousPrice != $price )
|
||||
@@ -1886,7 +1911,7 @@ class _Package extends \IPS\Node\Model
|
||||
$item->parent = $parent;
|
||||
}
|
||||
|
||||
/* Do any package-sepcific modifications */
|
||||
/* Do any package-specific modifications */
|
||||
$extraItems = ( $values === NULL ) ? array() : $this->addToCart( $item, $values, $memberCurrency );
|
||||
|
||||
/* Hang on, is that the same as anything else in the cart? */
|
||||
@@ -1914,7 +1939,7 @@ class _Package extends \IPS\Node\Model
|
||||
}
|
||||
|
||||
/* Associate extras */
|
||||
if ( count( $extraItems ) )
|
||||
if ( is_array( $extraItems ) and count( $extraItems ) )
|
||||
{
|
||||
foreach ( $extraItems as $item )
|
||||
{
|
||||
@@ -1983,7 +2008,7 @@ class _Package extends \IPS\Node\Model
|
||||
|
||||
foreach ( $customFields as $field )
|
||||
{
|
||||
if( array_key_exists( $field->type, \IPS\nexus\Package\CustomField::$additionalFieldTypes ) )
|
||||
if( array_key_exists( $field->type, \IPS\nexus\Package\CustomField::$additionalFieldTypes ) and !class_exists( 'IPS\Helpers\Form\\' . $field->type ) )
|
||||
{
|
||||
$class = 'IPS\nexus\Form\\' . $field->type;
|
||||
}
|
||||
@@ -2113,7 +2138,18 @@ class _Package extends \IPS\Node\Model
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
$term = array_pop( $renewalOptions );
|
||||
$purchase->renewals = new \IPS\nexus\Purchase\RenewalTerm( new \IPS\nexus\Money( $term['cost'][$currency]['amount'], $currency ), new \DateInterval( 'P' . $term['term'] . mb_strtoupper( $term['unit'] ) ) );
|
||||
|
||||
$tax = NULL;
|
||||
if ( $this->_data['tax'] )
|
||||
{
|
||||
try
|
||||
{
|
||||
$tax = \IPS\nexus\Tax::load( $purchase->tax );
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
}
|
||||
|
||||
$purchase->renewals = new \IPS\nexus\Purchase\RenewalTerm( new \IPS\nexus\Money( $term['cost'][$currency]['amount'], $currency ), new \DateInterval( 'P' . $term['term'] . mb_strtoupper( $term['unit'] ) ), $tax );
|
||||
$purchase->cancelled = FALSE;
|
||||
$purchase->save();
|
||||
|
||||
@@ -2611,7 +2647,6 @@ class _Package extends \IPS\Node\Model
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
/* Cannot upgrade/downgrade without permission unless $overrideRestrictions is set */
|
||||
if ( ( !$this->allow_upgrading AND !$this->allow_downgrading ) AND !$overrideRestrictions )
|
||||
{
|
||||
@@ -2624,8 +2659,7 @@ class _Package extends \IPS\Node\Model
|
||||
return array();
|
||||
}
|
||||
|
||||
/* Loop through our siblings */
|
||||
$return = array();
|
||||
/* Work out how much this package costs, including considering if the renewal term adds to the base price */
|
||||
try
|
||||
{
|
||||
$currency = $purchase->original_invoice->currency;
|
||||
@@ -2633,9 +2667,24 @@ class _Package extends \IPS\Node\Model
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
$currency = $purchase->member->defaultCurrency();
|
||||
}
|
||||
}
|
||||
$prices = json_decode( $this->base_price, TRUE );
|
||||
$thisPrice = $prices[ $currency ]['amount'];
|
||||
if ( $this->renew_options )
|
||||
{
|
||||
$renewalOptions = json_decode( $this->renew_options, TRUE );
|
||||
if ( !empty( $renewalOptions ) )
|
||||
{
|
||||
$option = array_shift( $renewalOptions );
|
||||
if ( $option['add'] )
|
||||
{
|
||||
$thisPrice += ( $option['cost'][ $currency ]['amount'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Loop through our siblings */
|
||||
$return = array();
|
||||
foreach ( $this->parent()->children() as $package )
|
||||
{
|
||||
if ( $package->id === $this->id )
|
||||
@@ -2679,6 +2728,7 @@ class _Package extends \IPS\Node\Model
|
||||
}
|
||||
}
|
||||
|
||||
/* Return */
|
||||
return $return;
|
||||
}
|
||||
|
||||
@@ -3247,7 +3297,7 @@ class _Package extends \IPS\Node\Model
|
||||
/* Have we made other purchases that have changed their primary group? */
|
||||
try
|
||||
{
|
||||
$next = \IPS\Db::i()->select( array( 'ps_id', 'ps_name', 'p_primary_group' ), 'nexus_purchases', array( 'ps_member=? AND ps_app=? AND ps_type=? AND ps_active=1 AND p_primary_group<>0 AND ps_id<>?', $purchase->member->member_id, 'nexus', 'package', $purchase->id ) )
|
||||
$next = \IPS\Db::i()->select( array( 'ps_id', 'ps_name', 'p_primary_group' ), 'nexus_purchases', array( "ps_member=? AND ps_app=? AND ps_type IN('package','subscription') AND ps_active=1 AND p_primary_group<>0 AND ps_id<>?", $purchase->member->member_id, 'nexus', $purchase->id ) )
|
||||
->join( 'nexus_packages', 'p_id=ps_item_id' )
|
||||
->first();
|
||||
|
||||
@@ -3299,7 +3349,7 @@ class _Package extends \IPS\Node\Model
|
||||
|
||||
/* Have we made other purchases that have added secondary groups? */
|
||||
$secondaryGroupsAwardedByOtherPurchases = array();
|
||||
foreach ( \IPS\Db::i()->select( 'p_secondary_group', 'nexus_purchases', array( 'ps_member=? AND ps_app=? AND ps_type=? AND ps_active=1 AND p_secondary_group IS NOT NULL AND p_secondary_group<>? AND ps_id<>?', $purchase->member->member_id, 'nexus', 'package', '', $purchase->id ) )->join( 'nexus_packages', 'p_id=ps_item_id' ) as $secondaryGroups )
|
||||
foreach ( \IPS\Db::i()->select( 'p_secondary_group', 'nexus_purchases', array( "ps_member=? AND ps_app=? AND ps_type IN('package','subscription') AND ps_active=1 AND p_secondary_group IS NOT NULL AND p_secondary_group<>? AND ps_id<>?", $purchase->member->member_id, 'nexus', '', $purchase->id ) )->join( 'nexus_packages', 'p_id=ps_item_id' ) as $secondaryGroups )
|
||||
{
|
||||
$secondaryGroupsAwardedByOtherPurchases = array_merge( $secondaryGroupsAwardedByOtherPurchases, array_filter( explode( ',', $secondaryGroups ) ) );
|
||||
}
|
||||
@@ -3338,9 +3388,12 @@ class _Package extends \IPS\Node\Model
|
||||
});
|
||||
|
||||
/* Save */
|
||||
$purchase->member->mgroup_others = implode( ',', $membersSecondaryGroups );
|
||||
$purchase->member->save();
|
||||
$purchase->member->logHistory( 'core', 'group', array( 'type' => 'secondary', 'by' => 'purchase', 'action' => 'remove', 'id' => $purchase->id, 'name' => $purchase->name, 'old' => $currentSecondaryGroups, 'new' => $membersSecondaryGroups ) );
|
||||
if( $currentSecondaryGroups != $membersSecondaryGroups )
|
||||
{
|
||||
$purchase->member->mgroup_others = implode( ',', $membersSecondaryGroups );
|
||||
$purchase->member->save();
|
||||
$purchase->member->logHistory( 'core', 'group', array( 'type' => 'secondary', 'by' => 'purchase', 'action' => 'remove', 'id' => $purchase->id, 'name' => $purchase->name, 'old' => $currentSecondaryGroups, 'new' => $membersSecondaryGroups ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,7 @@ class _Purchase extends \IPS\Node\Model
|
||||
* @param string $ref Referer
|
||||
* @param \IPS\nexus\Purchase|NULL $root Root (NULL for all root purchases)
|
||||
* @param bool $includeRoot Show the root?
|
||||
* @return \IPS\Helpers\Tree
|
||||
* @return \IPS\Helpers\Tree\Tree
|
||||
*/
|
||||
public static function tree( \IPS\Http\Url $url, array $where, $ref = 'c', \IPS\nexus\Purchase $root = NULL, $includeRoot = TRUE )
|
||||
{
|
||||
|
||||
@@ -112,13 +112,17 @@ class _Package extends \IPS\Node\Model
|
||||
parent::__clone();
|
||||
|
||||
/* Copy across images */
|
||||
try
|
||||
{
|
||||
$file = \IPS\File::get( 'nexus_Products', $old->image );
|
||||
$this->image = (string) \IPS\File::create( 'nexus_Products', $file->originalFilename, $file->contents() );
|
||||
$this->save();
|
||||
}
|
||||
catch( \Exception $e ) {}
|
||||
if ( $old->image )
|
||||
{
|
||||
try
|
||||
{
|
||||
$file = \IPS\File::get( 'nexus_Products', $old->image );
|
||||
$this->image = (string) \IPS\File::create( 'nexus_Products', $file->originalFilename, $file->contents() );
|
||||
$this->save();
|
||||
}
|
||||
catch( \Exception $e ) {}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -421,9 +425,31 @@ class _Package extends \IPS\Node\Model
|
||||
{
|
||||
if ( $price = $this->price() )
|
||||
{
|
||||
/* Include tax? */
|
||||
if ( \IPS\Settings::i()->nexus_show_tax and $this->tax )
|
||||
{
|
||||
try
|
||||
{
|
||||
$taxRate = new \IPS\Math\Number( \IPS\nexus\Tax::load( $this->tax )->rate( \IPS\nexus\Customer::loggedIn()->estimatedLocation() ) );
|
||||
|
||||
$price->amount = $price->amount->add( $price->amount->multiply( $taxRate ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$renewalTerm = $this->renewalTerm( $price->currency );
|
||||
|
||||
/* Include tax? */
|
||||
if ( \IPS\Settings::i()->nexus_show_tax and $this->tax and isset( $taxRate ) and $renewalTerm )
|
||||
{
|
||||
try
|
||||
{
|
||||
$renewalTerm->cost->amount = $renewalTerm->cost->amount->add( $renewalTerm->cost->amount->multiply( $taxRate ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
}
|
||||
|
||||
if ( $renewalTerm and $renewalTerm->cost->amount == $price->amount )
|
||||
{
|
||||
@@ -582,14 +608,14 @@ class _Package extends \IPS\Node\Model
|
||||
|
||||
if ( $newPackage->gateways and $newPackage->gateways != '*' )
|
||||
{
|
||||
$item->paymentMethodIds = explode( ',', $newPackage->methods );
|
||||
$item->paymentMethodIds = explode( ',', $newPackage->gateways );
|
||||
}
|
||||
|
||||
$invoice = new \IPS\nexus\Invoice;
|
||||
$invoice->member = $purchase->member;
|
||||
$invoice->currency = $costToUpgrade->currency;
|
||||
$invoice->addItem( $item );
|
||||
$invoice->return_uri = "app=nexus&module=subscriptons&controller=subscriptons";
|
||||
$invoice->return_uri = "app=nexus&module=subscriptions&controller=subscriptions";
|
||||
$invoice->renewal_ids = array( $purchase->id );
|
||||
$invoice->save();
|
||||
return $invoice;
|
||||
@@ -781,7 +807,7 @@ class _Package extends \IPS\Node\Model
|
||||
}
|
||||
|
||||
/* Secondary Groups */
|
||||
$secondary = array_filter( explode( ',', $this->secondary_group ), create_function( '$v', 'return (bool) $v;' ) );
|
||||
$secondary = array_filter( explode( ',', $this->secondary_group ), function( $v ){ return (bool) $v; } );
|
||||
|
||||
$current_secondary = $member->mgroup_others ? explode( ',', $member->mgroup_others ) : array();
|
||||
$newSecondary = $current_secondary;
|
||||
@@ -949,11 +975,12 @@ class _Package extends \IPS\Node\Model
|
||||
}
|
||||
else if ( $secondaryGroupsAwardedByThisPurchase )
|
||||
{
|
||||
$currentSecondaryGroups = $membersSecondaryGroups;
|
||||
foreach( $membersSecondaryGroups as $group )
|
||||
{
|
||||
if ( in_array( $group, $secondaryGroupsAwardedByThisPurchase ) )
|
||||
{
|
||||
unset( $membersSecondaryGroups[ array_search( $groupId, $membersSecondaryGroups ) ] );
|
||||
unset( $membersSecondaryGroups[ array_search( $group, $membersSecondaryGroups ) ] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,21 @@ class _Subscription extends \IPS\Patterns\ActiveRecord
|
||||
{
|
||||
if ( $this->expire )
|
||||
{
|
||||
if ( $this->purchase_id )
|
||||
{
|
||||
/* This has been invoiced, so there is a purchase row - fetch the expiration from that */
|
||||
try
|
||||
{
|
||||
$purchase = \IPS\nexus\Purchase::load( $this->purchase_id );
|
||||
|
||||
if ( $purchase->expire )
|
||||
{
|
||||
return $purchase->expire;
|
||||
}
|
||||
}
|
||||
catch( \OutOfRangeException $e ) { }
|
||||
}
|
||||
|
||||
return \IPS\DateTime::ts( $this->expire );
|
||||
}
|
||||
|
||||
@@ -141,9 +156,9 @@ class _Subscription extends \IPS\Patterns\ActiveRecord
|
||||
*
|
||||
* @param \IPS\Member $member Take a guess
|
||||
* @param \IPS\nexus\Subscription\Package $package I mean it's really writing itself
|
||||
* @param boolean $active Only get active packages
|
||||
* @param boolean $activeOnly Only get active packages
|
||||
* @return \IPS\nexus\Subscription
|
||||
* @throws OutOfRangeException
|
||||
* @throws \OutOfRangeException
|
||||
*/
|
||||
public static function loadByMemberAndPackage( \IPS\Member $member, \IPS\nexus\Subscription\Package $package, $activeOnly = TRUE )
|
||||
{
|
||||
|
||||
@@ -85,7 +85,12 @@ class _Member
|
||||
* @return array
|
||||
*/
|
||||
public function meta()
|
||||
{
|
||||
{
|
||||
if( !\IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customer', 'customers_view_statistics' ) )
|
||||
{
|
||||
return array( $this->customer->email );
|
||||
}
|
||||
|
||||
return array(
|
||||
$this->customer->email,
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'transaction_customer_since', FALSE, array( 'sprintf' => array( $this->customer->joined->localeDate() ) ) ),
|
||||
|
||||
@@ -403,6 +403,27 @@ class _Transaction extends \IPS\Patterns\ActiveRecord
|
||||
$this->_data['partial_refund'] = (string) $amount->amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get credit amount
|
||||
*
|
||||
* @return \IPS\nexus\Money
|
||||
*/
|
||||
public function get_credit()
|
||||
{
|
||||
return new \IPS\nexus\Money( $this->_data['credit'], $this->_data['currency'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set credit amount
|
||||
*
|
||||
* @param \IPS\nexus\Money $amount The total
|
||||
* @return void
|
||||
*/
|
||||
public function set_credit( \IPS\nexus\Money $amount )
|
||||
{
|
||||
$this->_data['credit'] = (string) $amount->amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get date transaction must be captured by (is set after authorisation. once captured, should be NULL)
|
||||
*
|
||||
@@ -648,6 +669,7 @@ class _Transaction extends \IPS\Patterns\ActiveRecord
|
||||
$extra['history'][] = array( 's' => \IPS\nexus\Transaction::STATUS_REFUSED, 'on' => time(), 'by' => \IPS\Member::loggedIn()->member_id );
|
||||
$this->extra = $extra;
|
||||
$this->status = \IPS\nexus\Transaction::STATUS_REFUSED;
|
||||
$this->auth = NULL;
|
||||
$this->save();
|
||||
|
||||
/* Log it */
|
||||
@@ -672,6 +694,8 @@ class _Transaction extends \IPS\Patterns\ActiveRecord
|
||||
*/
|
||||
public function refund( $refundMethod='gateway', $amount=NULL, $reason=NULL )
|
||||
{
|
||||
$extra = $this->extra;
|
||||
|
||||
/* What's the amount? */
|
||||
if ( $amount )
|
||||
{
|
||||
@@ -684,42 +708,18 @@ class _Transaction extends \IPS\Patterns\ActiveRecord
|
||||
{
|
||||
$amount = NULL;
|
||||
}
|
||||
|
||||
/* Refund */
|
||||
$refundReference = NULL;
|
||||
|
||||
/* Actual Refund */
|
||||
if ( $refundMethod === 'gateway' and method_exists( $this->method, 'refund' ) )
|
||||
{
|
||||
/* Refund with gateway */
|
||||
$refundReference = $this->method->refund( $this, $amount, $reason );
|
||||
}
|
||||
elseif ( $refundMethod === 'credit' )
|
||||
{
|
||||
$credits = $this->member->cm_credits;
|
||||
$credits[ $this->amount->currency ]->amount = $credits[ $this->amount->currency ]->amount->add( $amount ?: $this->amount->amount );
|
||||
$this->member->cm_credits = $credits;
|
||||
$this->member->save();
|
||||
}
|
||||
|
||||
/* Update transaction */
|
||||
$extra = $this->extra;
|
||||
if ( $refundMethod === 'none' )
|
||||
{
|
||||
$this->status = static::STATUS_REFUSED;
|
||||
$extra['history'][] = array( 's' => static::STATUS_REFUSED, 'by' => \IPS\Member::loggedIn()->member_id, 'on' => time() );
|
||||
|
||||
if ( $this->member )
|
||||
{
|
||||
$this->member->log( 'transaction', array(
|
||||
'type' => 'status',
|
||||
'status' => static::STATUS_REFUSED,
|
||||
'id' => $this->id
|
||||
) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update transaction and log */
|
||||
if ( $amount === NULL )
|
||||
{
|
||||
$this->status = static::STATUS_REFUNDED;
|
||||
|
||||
$extra['history'][] = array( 's' => static::STATUS_REFUNDED, 'by' => \IPS\Member::loggedIn()->member_id, 'on' => time(), 'to' => $refundMethod, 'ref' => $refundReference );
|
||||
|
||||
if ( $this->member )
|
||||
@@ -733,19 +733,18 @@ class _Transaction extends \IPS\Patterns\ActiveRecord
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
$this->partial_refund = new \IPS\nexus\Money( $this->partial_refund->amount->add( $amount ), $this->currency );
|
||||
|
||||
$extra['history'][] = array( 's' => static::STATUS_PART_REFUNDED, 'by' => \IPS\Member::loggedIn()->member_id, 'on' => time(), 'to' => $refundMethod, 'amount' => $amount, 'ref' => $refundReference );
|
||||
if ( $amount >= $this->amount->amount )
|
||||
{
|
||||
$this->status = static::STATUS_REFUNDED;
|
||||
$extra['history'][] = array( 's' => static::STATUS_REFUNDED );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->status = static::STATUS_PART_REFUNDED;
|
||||
}
|
||||
$extra['history'][] = array( 's' => $this->status, 'by' => \IPS\Member::loggedIn()->member_id, 'on' => time(), 'to' => $refundMethod, 'amount' => $amount, 'ref' => $refundReference );
|
||||
|
||||
if ( $this->member )
|
||||
{
|
||||
@@ -759,8 +758,89 @@ class _Transaction extends \IPS\Patterns\ActiveRecord
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/* Credit */
|
||||
elseif ( $refundMethod === 'credit' )
|
||||
{
|
||||
$amount = $amount ?: $this->amount->amount->subtract( $this->credit->amount );
|
||||
|
||||
/* Add the credit */
|
||||
$credits = $this->member->cm_credits;
|
||||
$credits[ $this->amount->currency ]->amount = $credits[ $this->amount->currency ]->amount->add( $amount );
|
||||
$this->member->cm_credits = $credits;
|
||||
$this->member->save();
|
||||
|
||||
/* Update transaction */
|
||||
$this->status = static::STATUS_PART_REFUNDED;
|
||||
$this->credit = new \IPS\nexus\Money( $this->credit->amount->add( $amount ), $this->currency );
|
||||
|
||||
/* Log */
|
||||
$extra['history'][] = array( 's' => static::STATUS_PART_REFUNDED, 'by' => \IPS\Member::loggedIn()->member_id, 'on' => time(), 'to' => $refundMethod, 'amount' => $amount, 'ref' => NULL );
|
||||
if ( $this->member )
|
||||
{
|
||||
$this->member->log( 'transaction', array(
|
||||
'type' => 'status',
|
||||
'status' => static::STATUS_PART_REFUNDED,
|
||||
'id' => $this->id,
|
||||
'refund' => $refundMethod,
|
||||
'amount' => $amount,
|
||||
'currency' => $this->currency
|
||||
) );
|
||||
}
|
||||
}
|
||||
/* Mark refused, but don't actually do anything */
|
||||
elseif ( $refundMethod === 'none' )
|
||||
{
|
||||
/* Update transaction */
|
||||
$this->status = static::STATUS_REFUSED;
|
||||
$extra['history'][] = array( 's' => static::STATUS_REFUSED, 'by' => \IPS\Member::loggedIn()->member_id, 'on' => time() );
|
||||
|
||||
/* Log */
|
||||
if ( $this->member )
|
||||
{
|
||||
$this->member->log( 'transaction', array(
|
||||
'type' => 'status',
|
||||
'status' => static::STATUS_REFUSED,
|
||||
'id' => $this->id
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
/* Save */
|
||||
$this->extra = $extra;
|
||||
$this->auth = NULL;
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse previously given credit (will log, but does not change status - status must be set separately)
|
||||
*
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function reverseCredit()
|
||||
{
|
||||
$credits = $this->member->cm_credits;
|
||||
$credits[ $this->amount->currency ]->amount = $credits[ $this->amount->currency ]->amount->subtract( $this->credit->amount );
|
||||
$this->member->cm_credits = $credits;
|
||||
$this->member->save();
|
||||
|
||||
$extra = $this->extra;
|
||||
$extra['history'][] = array( 's' => 'undo_credit', 'by' => \IPS\Member::loggedIn()->member_id, 'on' => time(), 'amount' => $this->credit->amount );
|
||||
if ( $this->member )
|
||||
{
|
||||
$this->member->log( 'transaction', array(
|
||||
'type' => 'undo_credit',
|
||||
'id' => $this->id,
|
||||
'amount' => $this->credit->amount,
|
||||
'currency' => $this->currency
|
||||
) );
|
||||
}
|
||||
$this->extra = $extra;
|
||||
|
||||
$this->credit = new \IPS\nexus\Money( 0, $this->currency );
|
||||
|
||||
$this->save();
|
||||
}
|
||||
|
||||
@@ -911,13 +991,13 @@ class _Transaction extends \IPS\Patterns\ActiveRecord
|
||||
elseif ( in_array( $this->status, array( static::STATUS_PAID, static::STATUS_HELD, static::STATUS_REVIEW, static::STATUS_PART_REFUNDED ) ) and \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'transactions_refund' ) )
|
||||
{
|
||||
$return['refund'] = array(
|
||||
'title' => 'transaction_refund',
|
||||
'title' => 'transaction_refund_credit',
|
||||
'icon' => 'reply',
|
||||
'link' => $url->setQueryString( array( 'do' => 'refund' ) ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack( 'transaction_refund_title', FALSE, array( 'sprintf' => array( $this->amount ) ) ) )
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack( 'transaction_refund_credit_title', FALSE, array( 'sprintf' => array( $this->amount ) ) ) )
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/* Delete button */
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'transactions_delete' ) )
|
||||
{
|
||||
@@ -971,6 +1051,7 @@ class _Transaction extends \IPS\Patterns\ActiveRecord
|
||||
* @apiresponse int invoiceId Invoice ID Number
|
||||
* @apiresponse \IPS\nexus\Money amount Amount
|
||||
* @apiresponse \IPS\nexus\Money refundAmount If partially refunded, the amount that has been refunded
|
||||
* @apiresponse \IPS\nexus\Money credit If credited, the amount that has been credited
|
||||
* @apiresponse \IPS\nexus\Gateway gateway The gateway
|
||||
* @clientapiresponse string gatewayId Any ID number provided by the gateway to identify the transaction on their end
|
||||
* @apiresponse datetime date Date
|
||||
@@ -984,6 +1065,7 @@ class _Transaction extends \IPS\Patterns\ActiveRecord
|
||||
'invoiceId' => $this->invoice->id,
|
||||
'amount' => $this->amount->apiOutput( $authorizedMember ),
|
||||
'refundAmount' => $this->partial_refund ? $this->partial_refund->apiOutput( $authorizedMember ) : null,
|
||||
'creditAmount' => $this->credit ? $this->credit->apiOutput( $authorizedMember ) : null,
|
||||
'gateway' => $this->method ? $this->method->apiOutput( $authorizedMember ) : null,
|
||||
'gatewayId' => $this->gw_id,
|
||||
'date' => $this->date->rfc3339(),
|
||||
|
||||
Reference in new issue
Block a user