Version 4.3.6
This commit is contained in:
1 parent
fe1acf984a
commit
1a0c7fd3c2
609 files changed
+14707
-5726
No files matched your search
@@ -294,7 +294,12 @@ class _Application extends \IPS\Application
|
||||
*/
|
||||
public function allowGuestAccess( \IPS\Application\Module $module, $controller, $do )
|
||||
{
|
||||
if( \IPS\Settings::i()->nexus_reg_force AND ( $module->key == 'store' OR $module->key == 'checkout' ) )
|
||||
if( ( \IPS\Settings::i()->nexus_reg_force OR \IPS\Db::i()->select( 'COUNT(*)', 'nexus_packages', 'p_reg=1' )->first() ) AND ( $module->key == 'store' OR $module->key == 'checkout' ) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ( \IPS\Settings::i()->nexus_subs_register AND ( $module->key == 'store' OR $module->key == 'checkout' ) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -66,7 +66,9 @@
|
||||
"customers": {
|
||||
"customers_view": "customers_view",
|
||||
"customers_edit_details": "customers_edit_details",
|
||||
"customers_view_credit": "customers_view_credit",
|
||||
"customers_edit_credit": "customers_edit_credit",
|
||||
"customers_view_statistics": "customers_view_statistics",
|
||||
"customers_edit_cards": "customers_edit_cards",
|
||||
"customers_void": "customers_void"
|
||||
},
|
||||
|
||||
@@ -60,7 +60,8 @@
|
||||
<br>
|
||||
{{endif}}
|
||||
|
||||
<a href='{$invoice->url()}' style="color: #ffffff; font-family: 'Helvetica Neue', helvetica, sans-serif; text-decoration: none; font-size: 14px; background: {setting="email_color"}; line-height: 32px; padding: 0 10px; display: inline-block; border-radius: 3px;">{$email->language->get('email_view_order')}</a>
|
||||
<a href='{{if $invoice->guest_data}}{$invoice->url()->setQueryString( array( 'do' => 'printout', 'key' => md5( $invoice->guest_data['member']['email'] . ';' . $invoice->guest_data['member']['joined'] ) ) )}{{else}}{$invoice->url()}{{endif}}' style="color: #ffffff; font-family: 'Helvetica Neue', helvetica, sans-serif; text-decoration: none; font-size: 14px; background: {setting="email_color"}; line-height: 32px; padding: 0 10px; display: inline-block; border-radius: 3px;">{$email->language->get('email_view_order')}</a>
|
||||
|
||||
|
||||
{{if $updateCard}}
|
||||
|
||||
@@ -2351,7 +2352,7 @@
|
||||
|
||||
{$email->language->addToStack("support_reply_email_id", FALSE, array( 'sprintf' => array( '[SR' . $request->id . '.' . $request->email_key . ']' ) ) )}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>nexus</template_app><template_name>autoresolveWarning</template_name><template_content_html><![CDATA[{$email->language->addToStack("autoresolve_header", FALSE, array( 'sprintf' => array( $request->title ) ) )}<br />
|
||||
<br />
|
||||
{$email->language->addToStack("autoresolve_desc", FALSE, array( 'sprintf' => array( $resolveDay ) ) )}<br />
|
||||
{$email->language->addToStack("autoresolve_desc", FALSE, array( 'sprintf' => array( $resolveDay->relative( \IPS\DateTime::RELATIVE_FORMAT_LOWER, $email->language ) ) ) )}<br />
|
||||
<br />
|
||||
<br />
|
||||
{{if $request->member}}
|
||||
@@ -2363,7 +2364,7 @@
|
||||
<br />
|
||||
<div style="font-size: 0px; line-height: 0px; color:#ffffff !important;">{$email->language->addToStack("support_reply_email_id", FALSE, array( 'sprintf' => array( '[SR' . $request->id . '.' . $request->email_key . ']' ) ) )}</div>]]></template_content_html><template_data>$request, $resolveDay, $email</template_data><template_content_plaintext><![CDATA[{$email->language->addToStack("autoresolve_header", FALSE, array( 'sprintf' => array( $request->title ) ) )}
|
||||
|
||||
{$email->language->addToStack("autoresolve_desc", FALSE, array( 'sprintf' => array( $resolveDay ) ) )}
|
||||
{$email->language->addToStack("autoresolve_desc", FALSE, array( 'sprintf' => array( $resolveDay->relative( \IPS\DateTime::RELATIVE_FORMAT_LOWER, $email->language ) ) ) )}
|
||||
|
||||
{{if $request->member}}
|
||||
{$email->language->addToStack("view_support_request", FALSE)}: {$request->url()}
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
{
|
||||
"Database": {
|
||||
"type": "C",
|
||||
"class": "\\IPS\\Data\\Store\\Database"
|
||||
},
|
||||
"register": {
|
||||
"type": "C",
|
||||
"class": "\\IPS\\core\\modules\\front\\system\\register"
|
||||
},
|
||||
"frontDispatcher": {
|
||||
"type": "C",
|
||||
"class": "\\IPS\\Dispatcher\\Front"
|
||||
},
|
||||
"clientAreaLinkLoad": {
|
||||
"type": "C",
|
||||
"class": "\\IPS\\Data\\Store\\Database"
|
||||
@@ -10,13 +18,5 @@
|
||||
"clientAreaLink": {
|
||||
"type": "S",
|
||||
"class": "\\IPS\\Theme\\class_core_front_global"
|
||||
},
|
||||
"Database": {
|
||||
"type": "C",
|
||||
"class": "\\IPS\\Data\\Store\\Database"
|
||||
},
|
||||
"frontDispatcher": {
|
||||
"type": "C",
|
||||
"class": "\\IPS\\Dispatcher\\Front"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<javascript app="nexus">
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/checkout" javascript_name="ips.checkout.billingForm.js" javascript_type="controller" javascript_version="103005" javascript_position="1000150"><![CDATA[/**
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/checkout" javascript_name="ips.checkout.billingForm.js" javascript_type="controller" javascript_version="103038" javascript_position="1000150"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -53,7 +53,7 @@
|
||||
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/checkout" javascript_name="ips.checkout.register.js" javascript_type="controller" javascript_version="103005" javascript_position="1000150">/**
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/checkout" javascript_name="ips.checkout.register.js" javascript_type="controller" javascript_version="103038" javascript_position="1000150">/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -84,7 +84,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/checkout" javascript_name="ips.checkout.review.js" javascript_type="controller" javascript_version="103005" javascript_position="1000150">/**
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/checkout" javascript_name="ips.checkout.review.js" javascript_type="controller" javascript_version="103038" javascript_position="1000150">/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -121,7 +121,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/checkout" javascript_name="ips.checkout.shippingForm.js" javascript_type="controller" javascript_version="103005" javascript_position="1000150">/**
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/checkout" javascript_name="ips.checkout.shippingForm.js" javascript_type="controller" javascript_version="103038" javascript_position="1000150">/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -144,7 +144,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/clients" javascript_name="ips.clients.referrals.js" javascript_type="controller" javascript_version="103005" javascript_position="1000100">/**
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/clients" javascript_name="ips.clients.referrals.js" javascript_type="controller" javascript_version="103038" javascript_position="1000100">/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -173,7 +173,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="nexus" javascript_location="global" javascript_path="controllers/gateways" javascript_name="ips.gateways.authorizenet.js" javascript_type="controller" javascript_version="103005" javascript_position="1000100"><![CDATA[/**
|
||||
<file javascript_app="nexus" javascript_location="global" javascript_path="controllers/gateways" javascript_name="ips.gateways.authorizenet.js" javascript_type="controller" javascript_version="103038" javascript_position="1000100"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -233,7 +233,7 @@
|
||||
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="nexus" javascript_location="global" javascript_path="controllers/gateways" javascript_name="ips.gateways.stripe.js" javascript_type="controller" javascript_version="103005" javascript_position="1000100"><![CDATA[/**
|
||||
<file javascript_app="nexus" javascript_location="global" javascript_path="controllers/gateways" javascript_name="ips.gateways.stripe.js" javascript_type="controller" javascript_version="103038" javascript_position="1000100"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -254,7 +254,9 @@
|
||||
*/
|
||||
initialize: function () {
|
||||
this.on( $(this.scope).closest('form')[0], 'submit', this.submitForm );
|
||||
this.setup();
|
||||
ips.loader.get(['https://js.stripe.com/v3/']).then( function () {
|
||||
this.setup();
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -290,7 +292,7 @@
|
||||
this.scope.find('.cPayment_visa').css( 'opacity', 1 );
|
||||
break;
|
||||
case 'mastercard':
|
||||
this.scope.find('.cPayment_mastercard').parent().css( 'opacity', 1 );
|
||||
this.scope.find('.cPayment_mastercard').css( 'opacity', 1 );
|
||||
break;
|
||||
case 'amex':
|
||||
this.scope.find('.cPayment_american_express').css( 'opacity', 1 );
|
||||
@@ -502,7 +504,7 @@
|
||||
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="nexus" javascript_location="global" javascript_path="controllers/gateways" javascript_name="ips.gateways.stripeamex.js" javascript_type="controller" javascript_version="103005" javascript_position="1000100">/**
|
||||
<file javascript_app="nexus" javascript_location="global" javascript_path="controllers/gateways" javascript_name="ips.gateways.stripeamex.js" javascript_type="controller" javascript_version="103038" javascript_position="1000100">/**
|
||||
* IPS Community Suite 4
|
||||
* (c) 2017 Invision Power Services - http://www.invisionpower.com
|
||||
*
|
||||
@@ -544,7 +546,7 @@ function aecCallbackHandler(response){
|
||||
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="nexus" javascript_location="global" javascript_path="controllers/gateways" javascript_name="ips.gateways.stripepaymentrequest.js" javascript_type="controller" javascript_version="103005" javascript_position="1000100">/**
|
||||
<file javascript_app="nexus" javascript_location="global" javascript_path="controllers/gateways" javascript_name="ips.gateways.stripepaymentrequest.js" javascript_type="controller" javascript_version="103038" javascript_position="1000100">/**
|
||||
* IPS Community Suite 4
|
||||
* (c) 2017 Invision Power Services - http://www.invisionpower.com
|
||||
*
|
||||
@@ -625,7 +627,7 @@ function aecCallbackHandler(response){
|
||||
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/hosting" javascript_name="ips.nexus.hosting.accountform.js" javascript_type="controller" javascript_version="103005" javascript_position="1000150">/**
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/hosting" javascript_name="ips.nexus.hosting.accountform.js" javascript_type="controller" javascript_version="103038" javascript_position="1000150">/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -657,7 +659,7 @@ function aecCallbackHandler(response){
|
||||
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="nexus" javascript_location="global" javascript_path="controllers/misc" javascript_name="ips.misc.print.js" javascript_type="controller" javascript_version="103005" javascript_position="1000050">/**
|
||||
<file javascript_app="nexus" javascript_location="global" javascript_path="controllers/misc" javascript_name="ips.misc.print.js" javascript_type="controller" javascript_version="103038" javascript_position="1000050">/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -679,7 +681,7 @@ function aecCallbackHandler(response){
|
||||
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/store" javascript_name="ips.store.productoptions.js" javascript_type="controller" javascript_version="103005" javascript_position="1000200"><![CDATA[/**
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/store" javascript_name="ips.store.productoptions.js" javascript_type="controller" javascript_version="103038" javascript_position="1000200"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -734,7 +736,7 @@ function aecCallbackHandler(response){
|
||||
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/store" javascript_name="ips.store.productselector.js" javascript_type="controller" javascript_version="103005" javascript_position="1000200"><![CDATA[/**
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/store" javascript_name="ips.store.productselector.js" javascript_type="controller" javascript_version="103038" javascript_position="1000200"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -794,7 +796,7 @@ function aecCallbackHandler(response){
|
||||
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/store" javascript_name="ips.store.cartReview.js" javascript_type="controller" javascript_version="103005" javascript_position="1000300">/**
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/store" javascript_name="ips.store.cartReview.js" javascript_type="controller" javascript_version="103038" javascript_position="1000300">/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -894,7 +896,7 @@ function aecCallbackHandler(response){
|
||||
}
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/store" javascript_name="ips.store.currencySelect.js" javascript_type="controller" javascript_version="103005" javascript_position="1000300">/**
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/store" javascript_name="ips.store.currencySelect.js" javascript_type="controller" javascript_version="103038" javascript_position="1000300">/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -934,7 +936,7 @@ function aecCallbackHandler(response){
|
||||
}
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/store" javascript_name="ips.store.giftCard.js" javascript_type="controller" javascript_version="103005" javascript_position="1000300"><![CDATA[/**
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/store" javascript_name="ips.store.giftCard.js" javascript_type="controller" javascript_version="103038" javascript_position="1000300"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -1022,7 +1024,7 @@ function aecCallbackHandler(response){
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/store" javascript_name="ips.store.packagePage.js" javascript_type="controller" javascript_version="103005" javascript_position="1000300"><![CDATA[/**
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/store" javascript_name="ips.store.packagePage.js" javascript_type="controller" javascript_version="103038" javascript_position="1000300"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -1236,7 +1238,7 @@ function aecCallbackHandler(response){
|
||||
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/store" javascript_name="ips.store.register.js" javascript_type="controller" javascript_version="103005" javascript_position="1000300"><![CDATA[/**
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/store" javascript_name="ips.store.register.js" javascript_type="controller" javascript_version="103038" javascript_position="1000300"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -1385,7 +1387,7 @@ function aecCallbackHandler(response){
|
||||
},
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/subscriptions" javascript_name="ips.subscriptions.main.js" javascript_type="controller" javascript_version="103005" javascript_position="1000200">/**
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/subscriptions" javascript_name="ips.subscriptions.main.js" javascript_type="controller" javascript_version="103038" javascript_position="1000200">/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -1423,7 +1425,7 @@ function aecCallbackHandler(response){
|
||||
}
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.emailsetup.js" javascript_type="controller" javascript_version="103005" javascript_position="1000100">/**
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.emailsetup.js" javascript_type="controller" javascript_version="103038" javascript_position="1000100">/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -1459,7 +1461,7 @@ function aecCallbackHandler(response){
|
||||
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.filterCheckboxSet.js" javascript_type="controller" javascript_version="103005" javascript_position="1000100">/**
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.filterCheckboxSet.js" javascript_type="controller" javascript_version="103038" javascript_position="1000100">/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -1512,7 +1514,7 @@ function aecCallbackHandler(response){
|
||||
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.list.js" javascript_type="controller" javascript_version="103005" javascript_position="1000100"><![CDATA[/**
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.list.js" javascript_type="controller" javascript_version="103038" javascript_position="1000100"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -1721,7 +1723,7 @@ function aecCallbackHandler(response){
|
||||
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.message.js" javascript_type="controller" javascript_version="103005" javascript_position="1000100"><![CDATA[/**
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.message.js" javascript_type="controller" javascript_version="103038" javascript_position="1000100"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -1777,7 +1779,7 @@ function aecCallbackHandler(response){
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.metamenu.js" javascript_type="controller" javascript_version="103005" javascript_position="1000100"><![CDATA[/**
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.metamenu.js" javascript_type="controller" javascript_version="103038" javascript_position="1000100"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -1951,7 +1953,7 @@ function aecCallbackHandler(response){
|
||||
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.multimod.js" javascript_type="controller" javascript_version="103005" javascript_position="1000100"><![CDATA[/**
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.multimod.js" javascript_type="controller" javascript_version="103038" javascript_position="1000100"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -2051,7 +2053,7 @@ function aecCallbackHandler(response){
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.packageInfo.js" javascript_type="controller" javascript_version="103005" javascript_position="1000100">/**
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.packageInfo.js" javascript_type="controller" javascript_version="103038" javascript_position="1000100">/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -2100,7 +2102,7 @@ function aecCallbackHandler(response){
|
||||
}
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.pendingalert.js" javascript_type="controller" javascript_version="103005" javascript_position="1000100">/**
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.pendingalert.js" javascript_type="controller" javascript_version="103038" javascript_position="1000100">/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -2127,7 +2129,7 @@ function aecCallbackHandler(response){
|
||||
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.replyArea.js" javascript_type="controller" javascript_version="103005" javascript_position="1000100"><![CDATA[/**
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.replyArea.js" javascript_type="controller" javascript_version="103038" javascript_position="1000100"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -2211,7 +2213,7 @@ function aecCallbackHandler(response){
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.request.js" javascript_type="controller" javascript_version="103005" javascript_position="1000100"><![CDATA[/**
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.request.js" javascript_type="controller" javascript_version="103038" javascript_position="1000100"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -2355,7 +2357,7 @@ function aecCallbackHandler(response){
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.splitForm.js" javascript_type="controller" javascript_version="103005" javascript_position="1000100">/**
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.splitForm.js" javascript_type="controller" javascript_version="103038" javascript_position="1000100">/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -2390,6 +2392,7 @@ function aecCallbackHandler(response){
|
||||
dialog.setLoading(true);
|
||||
|
||||
var newWindow = window.open( '', '_blank' );
|
||||
newWindow.opener = null;
|
||||
newWindow.blur();
|
||||
window.focus();
|
||||
|
||||
@@ -2424,7 +2427,7 @@ function aecCallbackHandler(response){
|
||||
}
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/support" javascript_name="ips.support.rate.js" javascript_type="controller" javascript_version="103005" javascript_position="1000250">/**
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/support" javascript_name="ips.support.rate.js" javascript_type="controller" javascript_version="103038" javascript_position="1000250">/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -2446,7 +2449,7 @@ function aecCallbackHandler(response){
|
||||
}
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="templates" javascript_name="ips.templates.store.js" javascript_type="template" javascript_version="103005" javascript_position="1000050"><![CDATA[ips.templates.set('nexus.store.images', " \
|
||||
<file javascript_app="nexus" javascript_location="admin" javascript_path="templates" javascript_name="ips.templates.store.js" javascript_type="template" javascript_version="103038" javascript_position="1000050"><![CDATA[ips.templates.set('nexus.store.images', " \
|
||||
<div class='ipsGrid_span3 ipsAttach ipsImageAttach ipsPad_half ipsAreaBackground_light' id='{{id}}' data-role='file' data-fileid='{{id}}' data-fullsizeurl='{{imagesrc}}' data-thumbnailurl='{{thumbnail}}' data-fileType='image'>\
|
||||
<ul class='ipsList_inline ipsImageAttach_controls'>\
|
||||
<li><input type='radio' name='{{field_name}}_primary_image' value='{{id}}' title='{{#lang}}makePrimaryProductImage{{/lang}}' data-ipsTooltip></li>\
|
||||
@@ -2469,7 +2472,7 @@ function aecCallbackHandler(response){
|
||||
</div>\
|
||||
");
|
||||
]]></file>
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="templates" javascript_name="ips.templates.store.js" javascript_type="template" javascript_version="103005" javascript_position="1000050"><![CDATA[ips.templates.set('nexus.store.productImage', " \
|
||||
<file javascript_app="nexus" javascript_location="front" javascript_path="templates" javascript_name="ips.templates.store.js" javascript_type="template" javascript_version="103038" javascript_position="1000050"><![CDATA[ips.templates.set('nexus.store.productImage', " \
|
||||
<a href='{{fullURL}}' data-fullURL='{{fullURL}}' class='cNexusProduct_primaryImage ipsContained' data-ipsLightbox data-ipsLightbox-group='product' data-ipsProductZoom>\
|
||||
<img src='{{thumbURL}}' class='ipsImage ipsImage_thumb'>\
|
||||
</a>\
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<language>
|
||||
<app key="nexus" version="103005">
|
||||
<app key="nexus" version="103038">
|
||||
<word key="__app_nexus" js="0">Commerce</word>
|
||||
<word key="menutab__nexus" js="0">Commerce</word>
|
||||
<word key="menutab__nexus_icon" js="0">usd</word>
|
||||
@@ -72,13 +72,13 @@
|
||||
<word key="contact_nexus_department" js="0">Create Support Request</word>
|
||||
<word key="contact_nexus" js="0">Department</word>
|
||||
<word key="contact_nexus_no_departments" js="0">Send to Commerce department as a Support Request</word>
|
||||
<word key="contact_nexus_no_departments_desc" js="0"><![CDATA[You don't have any departments set up.<br />Set up a <a href='{internal.app=nexus&module=support&controller=settings&tab=departments&do=form}' target='_blank'>new department</a>]]></word>
|
||||
<word key="contact_nexus_no_departments_desc" js="0"><![CDATA[You don't have any departments set up.<br />Set up a <a href='{internal.app=nexus&module=support&controller=settings&tab=departments&do=form}' target='_blank' rel='noopener'>new department</a>]]></word>
|
||||
<word key="contact_nexus_title" js="0">Support Request created via Contact Us Form</word>
|
||||
<word key="nexus_nodeletedept_contactus" js="0"><![CDATA[The department you attempted to delete is currently set as the department contact us submissions are sent to. You must adjust your <a href='{internal.app=core&module=settings&controller=contactus}'>Contact Us</a> configuration before you can delete this department.]]></word>
|
||||
<word key="menu__nexus_stock_gateways" js="0">Payment Methods</word>
|
||||
<word key="payment_methods" js="0">Payment Methods</word>
|
||||
<word key="gateways_gateway" js="0">Payment Method</word>
|
||||
<word key="gateways_gateway_desc" js="0"><![CDATA[<a href='{external.payment_methods}' target='_blank'>Learn more about the different payment methods</a>]]></word>
|
||||
<word key="gateways_gateway_desc" js="0"><![CDATA[<a href='{external.payment_methods}' target='_blank' rel='noopener'>Learn more about the different payment methods</a>]]></word>
|
||||
<word key="gateways_details" js="0">Details</word>
|
||||
<word key="gateway__PayPal" js="0">PayPal</word>
|
||||
<word key="paymethod_name" js="0">Name</word>
|
||||
@@ -86,20 +86,20 @@
|
||||
<word key="paymethod_countries_desc" js="0">This payment method will be available if the customer's billing address is in one of the selected countries.</word>
|
||||
<word key="paypal_type" js="0">Pay By</word>
|
||||
<word key="paypal_type_paypal" js="0">PayPal</word>
|
||||
<word key="paypal_type_paypal_desc" js="0"><![CDATA[Users are taken to PayPal's site where they can pay with their PayPal account or credit/debit card. Your account <a href='{external.paypal_app_status}' target='_blank'>must have access</a> to PayPal payments.]]></word>
|
||||
<word key="paypal_type_paypal_desc" js="0"><![CDATA[Users are taken to PayPal's site where they can pay with their PayPal account or credit/debit card. Your account <a href='{external.paypal_app_status}' target='_blank' rel='noopener'>must have access</a> to PayPal payments.]]></word>
|
||||
<word key="paypal_type_card" js="0">Card</word>
|
||||
<word key="paypal_type_card_desc" js="0"><![CDATA[Users enter their card details directly on the checkout screen. Your account <a href='{external.paypal_app_status}' target='_blank'>must have access</a> to Direct credit cards.]]></word>
|
||||
<word key="paypal_type_card_desc" js="0"><![CDATA[Users enter their card details directly on the checkout screen. Your account <a href='{external.paypal_app_status}' target='_blank' rel='noopener'>must have access</a> to Direct credit cards.]]></word>
|
||||
<word key="paypal_type_desc" js="0">To allow users to choose to use their card or PayPal account, set up two PayPal payment methods.</word>
|
||||
<word key="paypal_billing_agreements" js="0">Billing Agreements</word>
|
||||
<word key="paypal_billing_agreements_req" js="0">Required: Billing Agreements are always used for purchases with renewal terms.</word>
|
||||
<word key="paypal_billing_agreements_req_desc" js="0">Note that Billing Agreements can only be used when purchasing items with a single renewal term. If, for example, a customer purchases a product which renews every month at the same time as a product which renews every year, a Billing Agreement will not be created.</word>
|
||||
<word key="paypal_billing_agreements_opt" js="0">Optional: Allow the customer to choose if they want to use a Billing Agreement or be invoiced.</word>
|
||||
<word key="paypal_billing_agreements_dis" js="0">Disabled: Do not use Billing Agreements.</word>
|
||||
<word key="paypal_billing_agreements_desc" js="0"><![CDATA[Your account <a href='{external.paypal_app_status}' target='_blank'>must have access</a> to Subscriptions. <a href='{external.billing_agreements}' target='_blank'>Important information about Billing Agreements</a>]]></word>
|
||||
<word key="paypal_billing_agreements_desc" js="0"><![CDATA[Your account <a href='{external.paypal_app_status}' target='_blank' rel='noopener'>must have access</a> to Subscriptions. <a href='{external.billing_agreements}' target='_blank' rel='noopener'>Important information about Billing Agreements</a>]]></word>
|
||||
<word key="paypal_vault" js="0">Allow users to store card details?</word>
|
||||
<word key="paypal_vault_desc" js="0">Card details are stored on PayPal's servers, not your own.</word>
|
||||
<word key="paypal_client_id" js="0">Client ID</word>
|
||||
<word key="paypal_client_id_desc" js="0"><![CDATA[To obtain a client ID and secret, <a href='{external.paypal_developer}' target='_blank'>create an application on PayPal's developer site</a>. Make sure you use the <strong>live credentials</strong>, not the test credentials.]]></word>
|
||||
<word key="paypal_client_id_desc" js="0"><![CDATA[To obtain a client ID and secret, <a href='{external.paypal_developer}' target='_blank' rel='noopener'>create an application on PayPal's developer site</a>. Make sure you use the <strong>live credentials</strong>, not the test credentials.]]></word>
|
||||
<word key="paypal_secret" js="0">Secret</word>
|
||||
<word key="paypal_billing_agreement" js="0">Pay renewal costs automatically</word>
|
||||
<word key="paypal_payer_status" js="0">PayPal Account Status: %s</word>
|
||||
@@ -114,28 +114,28 @@
|
||||
<word key="stripe_type_card" js="0">Card</word>
|
||||
<word key="stripe_type_card_desc" js="0">Users enter their card details directly on the checkout screen.</word>
|
||||
<word key="stripe_type_native" js="0">Browser Features (Apple Pay / Google Pay)</word>
|
||||
<word key="stripe_type_native_desc" js="0"><![CDATA[Users with a supported device / browser can use the browser's native features for taking payments (for example, Apple Pay or Google Pay).<br>This option <a href='{external.https}' target='_blank'>requires HTTPS</a>, and for Apple Pay, you also need to <a href='{external.stripe_applepay_register}' target='_blank'>register your domain</a>.]]></word>
|
||||
<word key="stripe_type_native_desc" js="0"><![CDATA[Users with a supported device / browser can use the browser's native features for taking payments (for example, Apple Pay or Google Pay).<br>This option <a href='{external.https}' target='_blank' rel='noopener'>requires HTTPS</a>, and for Apple Pay, you also need to <a href='{external.stripe_applepay_register}' target='_blank' rel='noopener'>register your domain</a>.]]></word>
|
||||
<word key="stripe_type_amex" js="0">Amex Express Checkout</word>
|
||||
<word key="stripe_type_amex_desc" js="0"><![CDATA[Users will be redirected to the Amex Express Checkout website to complete checkout. <a href='{external.stripe_amex_express}' target='_blank'>Learn more about Amex Express Checkout</a>]]></word>
|
||||
<word key="stripe_type_amex_desc" js="0"><![CDATA[Users will be redirected to the Amex Express Checkout website to complete checkout. <a href='{external.stripe_amex_express}' target='_blank' rel='noopener'>Learn more about Amex Express Checkout</a>]]></word>
|
||||
<word key="stripe_amex_client_id" js="0">Amex Express Checkout Client ID</word>
|
||||
<word key="stripe_amex_client_id_gen" js="0"><![CDATA[<a href='{external.amex_client_id}' target='_blank'>Generate</a>]]></word>
|
||||
<word key="stripe_amex_client_id_gen" js="0"><![CDATA[<a href='{external.amex_client_id}' target='_blank' rel='noopener'>Generate</a>]]></word>
|
||||
<word key="stripe_type_alipay" js="0">Alipay</word>
|
||||
<word key="stripe_type_alipay_desc" js="0"><![CDATA[A popular payment method in China. Users will be redirected to the Alipay website to complete checkout. <a href='{external.alipay}' target='_blank'>Learn more about Alipay</a>]]></word>
|
||||
<word key="stripe_type_alipay_desc" js="0"><![CDATA[A popular payment method in China. Users will be redirected to the Alipay website to complete checkout. <a href='{external.alipay}' target='_blank' rel='noopener'>Learn more about Alipay</a>]]></word>
|
||||
<word key="stripe_type_bancontact" js="0">Bancontact</word>
|
||||
<word key="stripe_type_bancontact_desc" js="0"><![CDATA[A popular payment method in Belgium. Users will be redirected to the Bancontact website to complete checkout. <a href='{external.bancontact}' target='_blank'>Learn more about Bancontact</a>]]></word>
|
||||
<word key="stripe_type_bancontact_desc" js="0"><![CDATA[A popular payment method in Belgium. Users will be redirected to the Bancontact website to complete checkout. <a href='{external.bancontact}' target='_blank' rel='noopener'>Learn more about Bancontact</a>]]></word>
|
||||
<word key="stripe_type_giropay" js="0">Giropay</word>
|
||||
<word key="stripe_type_giropay_desc" js="0"><![CDATA[A popular payment method in Germany. Users will be redirected to the Giropay website to complete checkout. <a href='{external.giropay}' target='_blank'>Learn more about Giropay</a>]]></word>
|
||||
<word key="stripe_type_giropay_desc" js="0"><![CDATA[A popular payment method in Germany. Users will be redirected to the Giropay website to complete checkout. <a href='{external.giropay}' target='_blank' rel='noopener'>Learn more about Giropay</a>]]></word>
|
||||
<word key="stripe_type_ideal" js="0">iDEAL</word>
|
||||
<word key="stripe_type_ideal_desc" js="0"><![CDATA[A popular payment method in the Netherlands. Users will be redirected to the iDEAL website to complete checkout. <a href='{external.ideal}' target='_blank'>Learn more about iDEAL</a>]]></word>
|
||||
<word key="stripe_type_ideal_desc" js="0"><![CDATA[A popular payment method in the Netherlands. Users will be redirected to the iDEAL website to complete checkout. <a href='{external.ideal}' target='_blank' rel='noopener'>Learn more about iDEAL</a>]]></word>
|
||||
<word key="stripe_type_sofort" js="0">SOFORT</word>
|
||||
<word key="stripe_type_sofort_desc" js="0"><![CDATA[A popular payment method in Europe. Users will be redirected to the SOFORT website to complete checkout. <a href='{external.sofort}' target='_blank'>Learn more about SOFORT</a>]]></word>
|
||||
<word key="stripe_type_sofort_desc" js="0"><![CDATA[A popular payment method in Europe. Users will be redirected to the SOFORT website to complete checkout. <a href='{external.sofort}' target='_blank' rel='noopener'>Learn more about SOFORT</a>]]></word>
|
||||
<word key="stripe_webhook" js="0">Webhook</word>
|
||||
<word key="stripe_webhook_blurb" js="0"><![CDATA[You must <a href='{external.stripe_webhooks}' target='_blank'>create a webhook</a> on your Stripe account specifying this URL as the endpoint:<br><pre class='ipsCode'>%s</pre>]]></word>
|
||||
<word key="stripe_webhook_blurb" js="0"><![CDATA[You must <a href='{external.stripe_webhooks}' target='_blank' rel='noopener'>create a webhook</a> on your Stripe account specifying this URL as the endpoint:<br><pre class='ipsCode'>%s</pre>]]></word>
|
||||
<word key="stripe_webhook_secret" js="0">Webhook Signing Secret</word>
|
||||
<word key="stripe_webhook_secret_desc" js="0">When viewing the webhook in your Stripe account you will see a button to reveal the signing secret. The value will not be verified, so ensure the correct secret is provided.</word>
|
||||
<word key="stripe_basic_settings" js="0">Basic Settings</word>
|
||||
<word key="stripe_keys" js="0">Keys</word>
|
||||
<word key="stripe_keys_blurb" js="0"><![CDATA[Provide the Standard API keys from the <a href='{external.stripe_keys}' target='_blank'>API section of your Stripe account</a>.]]></word>
|
||||
<word key="stripe_keys_blurb" js="0"><![CDATA[Provide the Standard API keys from the <a href='{external.stripe_keys}' target='_blank' rel='noopener'>API section of your Stripe account</a>.]]></word>
|
||||
<word key="stripe_type_desc" js="0">To allow users to choose, set up multiple Stripe payment methods.</word>
|
||||
<word key="stripe_3d_secure" js="0">3D Secure</word>
|
||||
<word key="stripe_3d_secure_yes" js="0">All cards which support it</word>
|
||||
@@ -196,7 +196,7 @@
|
||||
<word key="trans_attention_required" js="0">Action Required</word>
|
||||
<word key="gateway__AuthorizeNet" js="0">Authorize.Net</word>
|
||||
<word key="authorizenet_login" js="0">API Login ID</word>
|
||||
<word key="authorizenet_login_desc" js="0"><![CDATA[<a href='{external.authorizenet_keys}' target='_blank'>Get your login ID and transaction key</a>]]></word>
|
||||
<word key="authorizenet_login_desc" js="0"><![CDATA[<a href='{external.authorizenet_keys}' target='_blank' rel='noopener'>Get your login ID and transaction key</a>]]></word>
|
||||
<word key="authorizenet_tran_key" js="0">Transaction Key</word>
|
||||
<word key="authorizenet_method" js="0">API</word>
|
||||
<word key="authorizenet_AIM" js="0">Advanced Integration Method (AIM)</word>
|
||||
@@ -206,13 +206,13 @@
|
||||
<word key="authorizenet_cim" js="0">Allow users to store card details?</word>
|
||||
<word key="authorizenet_cim_desc" js="0">Uses Customer Information Manager (CIM). Card details are stored on Authorize.Net's servers, not your own.</word>
|
||||
<word key="authorizenet_hash" js="0">MD5 Hash</word>
|
||||
<word key="authorizenet_desc" js="0"><![CDATA[<a href='{external.authorizenet_hash}' target='_blank'>Get your MD5 Hash</a>]]></word>
|
||||
<word key="authorizenet_desc" js="0"><![CDATA[<a href='{external.authorizenet_hash}' target='_blank' rel='noopener'>Get your MD5 Hash</a>]]></word>
|
||||
<word key="authorizenet_processor" js="0">Payment Processor</word>
|
||||
<word key="authorizenet_processor_desc" js="0">This is used to show users the correct card types that are accepted and to check the payment can be processed by your processor. If you do not know which payment processor you are using, you can select "Don't Know", but if an unsupported payment is submitted, it will be declined. You can contact Authorize.Net to find out or change which processor your account uses.</word>
|
||||
<word key="dont_know" js="0">Don't Know</word>
|
||||
<word key="gateway__TwoCheckout" js="0">2Checkout</word>
|
||||
<word key="twocheckout_api_username" js="0">API Username</word>
|
||||
<word key="twocheckout_api_username_desc" js="0"><![CDATA[<a href='{external.2checkout_api_accounts}' target='_blank'>Create an API user</a>]]></word>
|
||||
<word key="twocheckout_api_username_desc" js="0"><![CDATA[<a href='{external.2checkout_api_accounts}' target='_blank' rel='noopener'>Create an API user</a>]]></word>
|
||||
<word key="twocheckout_api_password" js="0">API Password</word>
|
||||
<word key="twocheckout_openssl_req" js="0">There was an error communicating with 2Checkout. It is possible that this issue is because your OpenSSL version is out of date. 2Checkout only accepts connections over TLS 1.1 or higher, and not over SSL, which requires OpenSSL 1.0.1 or higher to be installed on your server. Contact your hosting provider or system administrator and ask for OpenSSL to be upgraded.</word>
|
||||
<word key="gateway__Manual" js="0">Manual (check, bank wire, etc.)</word>
|
||||
@@ -236,7 +236,7 @@
|
||||
<word key="tstatus_okay_set" js="0">Approved</word>
|
||||
<word key="tstatus_okay_credit" js="0">Paid with account credit</word>
|
||||
<word key="tstatus_pend" js="0">Pending</word>
|
||||
<word key="tstatus_pend_desc" js="0"><![CDATA[Waiting for user to complete checkout. If you have received payment, the payment method may not be set up correctly. <a href='{internal.app=nexus&module=payments&controller=paymentsettings&tab=gateways}' target='_blank'>Check your settings</a>, and then mark the invoice associated with this transaction paid to override.]]></word>
|
||||
<word key="tstatus_pend_desc" js="0"><![CDATA[Waiting for user to complete checkout. If you have received payment, the payment method may not be set up correctly. <a href='{internal.app=nexus&module=payments&controller=paymentsettings&tab=gateways}' target='_blank' rel='noopener'>Check your settings</a>, and then mark the invoice associated with this transaction paid to override.]]></word>
|
||||
<word key="tstatus_wait" js="0">Waiting</word>
|
||||
<word key="tstatus_wait_desc" js="0">Payment has not yet been received.</word>
|
||||
<word key="tstatus_hold" js="0">Held for approval</word>
|
||||
@@ -253,9 +253,11 @@
|
||||
<word key="tstatus_rfnd" js="0">Refunded</word>
|
||||
<word key="tstatus_rfnd_desc" js="0">Payment was received but has been refunded.</word>
|
||||
<word key="tstatus_rfnd_set" js="0">Refunded</word>
|
||||
<word key="tstatus_prfd" js="0">Partially Refunded</word>
|
||||
<word key="tstatus_prfd_desc" js="0">Payment was received but has been partially refunded.</word>
|
||||
<word key="tstatus_prfd" js="0">Credited</word>
|
||||
<word key="tstatus_prfd_desc" js="0">Payment was received but has been partially refunded or credited.</word>
|
||||
<word key="tstatus_prfd_set" js="0">Partially Refunded</word>
|
||||
<word key="tstatus_credited" js="0">Credited</word>
|
||||
<word key="tstatus_credited_undo" js="0">Credit Reversed</word>
|
||||
<word key="tstatus_gwpd" js="0">Processing</word>
|
||||
<word key="tstatus_gwpd_desc" js="0">The payment gateway is currently processing this transaction. The status will automatically updated when the gateway has finished processing.</word>
|
||||
<word key="tstatus_dspd" js="0">Disputed</word>
|
||||
@@ -271,13 +273,23 @@
|
||||
<word key="transaction_void_err" js="0"><![CDATA[The gateway was unable to void the payment. If the gateway has already voided the payment automatically or it is otherwise not necessary to void with the gateway, you can override this error. <a href='%s'>Override</a>]]></word>
|
||||
<word key="transaction_flag_review" js="0">Flag For Review</word>
|
||||
<word key="transaction_refund" js="0">Refund</word>
|
||||
<word key="transaction_refund_desc" js="0">The funds will actually be returned to the customer through the payment method.</word>
|
||||
<word key="transaction_refund_title" js="0">Refund (%s)</word>
|
||||
<word key="refund_method" js="0">Refund to</word>
|
||||
<word key="refund_method_credit" js="0">Account Credit</word>
|
||||
<word key="transaction_refund_credit" js="0">Refund / Credit</word>
|
||||
<word key="transaction_refund_credit_title" js="0">Refund / Credit (%s)</word>
|
||||
<word key="refund_method" js="0">Action</word>
|
||||
<word key="refund_method_credit" js="0">Credit</word>
|
||||
<word key="refund_method_credit_desc" js="0">You will retain the funds, but the customer's account will be credited with the amount which they can then spend on future purchases.</word>
|
||||
<word key="refund_method_none" js="0">Mark transaction as refused, but do not actually refund</word>
|
||||
<word key="refund_amount" js="0">Refund Amount</word>
|
||||
<word key="refund_method_none_desc" js="0">Choose this option if the payment was marked complete in error or if a manual payment was reversed (for example, the customer sent a check which was then cancelled).</word>
|
||||
<word key="refund_amount" js="0">Amount</word>
|
||||
<word key="refund_full" js="0">Full Amount (%s)</word>
|
||||
<word key="refund_full_remaining" js="0">Remaining Balance (%s)</word>
|
||||
<word key="refund_credit_amount" js="0">Amount</word>
|
||||
<word key="refund_amount_descwarn" js="0"><![CDATA[<span class="ipsType_issue"><i class="fa fa-exclamation-triangle"></i> The customer has already received a %s credit. You may want to give refund less than the full amount, or reverse the already given credit, to avoid the refund and credit amount being greater than the transaction amount.</span>]]></word>
|
||||
<word key="refund_credit_amount_descwarn" js="0"><![CDATA[<span class="ipsType_issue"><i class="fa fa-exclamation-triangle"></i> The customer has already received a %s refund. You may want to credit less than the full amount to avoid the refund and credit amount being greater than the transaction amount.</span>]]></word>
|
||||
<word key="refund_reverse_credit" js="0">Reverse %s Credit?</word>
|
||||
<word key="refund_reverse_credit_desc" js="0">If checked, the credit previously given will be removed from the user's account.</word>
|
||||
<word key="refund_reason" js="0">Reason for Refund</word>
|
||||
<word key="trans_refund_reason" js="0">Reason for Refunding Transaction #%d</word>
|
||||
<word key="refund_reason_duplicate" js="0">Duplicate transaction</word>
|
||||
@@ -286,7 +298,7 @@
|
||||
<word key="refund_reason_requested_by_customer" js="0">Requested by Customer</word>
|
||||
<word key="refund_invoice_status" js="0">Set Invoice Status</word>
|
||||
<word key="refund_invoice_paid" js="0">Paid</word>
|
||||
<word key="refund_invoice_paid_desc" js="0">Nothing on the customer's account will change. Select this option if the refund is a sign of good-will or perk to customer.</word>
|
||||
<word key="refund_invoice_paid_desc" js="0">Nothing on the customer's account will change. Select this option if the refund / credit is a sign of good-will or perk to customer.</word>
|
||||
<word key="refund_invoice_pending" js="0">Pending</word>
|
||||
<word key="refund_invoice_pending_desc" js="0">Any purchases or benefits the customer received from this payment will be revoked. The invoice will be set to pending so they can submit alternative payment. Select this option if there was a problem with the payment and you are expecting the customer to pay a different way.</word>
|
||||
<word key="refund_invoice_expired" js="0">Expired</word>
|
||||
@@ -297,6 +309,9 @@
|
||||
<word key="refund_time_limit" js="0">The gateway is unable to process the refund because too much time has passed since the payment was made. You should go back and refund as account credit.</word>
|
||||
<word key="refund_already_processed" js="0">The gateway reports that the transaction has already been refunded. You should go back and mark the transaction as refused.</word>
|
||||
<word key="refund_failed" js="0">The gateway was unable to process the refund. This can happen if it has been too long since the transaction was made or if there are not sufficient funds in your account to refund. You can go back and refund as account credit or contact the gateway to manually refund and then cancel the transaction without refunding.</word>
|
||||
<word key="refund_cancel_billing_agreement" js="0">Cancel Billing Agreement?</word>
|
||||
<word key="refund_cancel_billing_agreement_desc" js="0">This transaction was created by a Billing Agreement. If the Billing Agreement is not also cancelled, recurring payments will continue be taken automatically.</word>
|
||||
<word key="refund_cancel_billing_agreement_warning" js="0">Failing to cancel the Billing Agreement will mean payments continue to be taken even though there will be no associated purchase to renew.</word>
|
||||
<word key="address_invalid" js="0">The gateway has reported the billing or shipping address as invalid. Please review and ensure all addresses are entered correctly.</word>
|
||||
<word key="invoice_addresses" js="0">Invoice Addresses</word>
|
||||
<word key="transaction_total" js="0">Transaction Total</word>
|
||||
@@ -387,6 +402,7 @@
|
||||
<word key="payment_reference" js="0">Payment reference</word>
|
||||
<word key="trans_invoice_deleted" js="0">The invoice for this transaction has been deleted.</word>
|
||||
<word key="amount_refunded" js="0">Refunded</word>
|
||||
<word key="amount_credited" js="0">Credited</word>
|
||||
<word key="menu__nexus_payments_paymentsettings" js="0">Settings</word>
|
||||
<word key="payment_settings" js="0">Payment Settings</word>
|
||||
<word key="currencies" js="0">Currencies</word>
|
||||
@@ -406,7 +422,7 @@
|
||||
<word key="nexus_require_billing_domain" js="0">Purchasing domain names</word>
|
||||
<word key="nexus_require_billing_other" js="0">Paying other charges</word>
|
||||
<word key="nexus_require_billing_other_desc" js="0">Includes account credit top-ups, pay-per-incident support charges, upgrade charges, and any miscellaneous charges on manually-generated invoices.</word>
|
||||
<word key="nexus_require_billing_desc" js="0"><![CDATA[If you disable any of these options beware that without a billing address:<ul><li>Some <a href='{internal.app=nexus&module=payments&controller=paymentsettings&tab=gateways}' target='_blank'>payment methods</a> will not be able to be used, including PayPal for card payments, PayPal Billing Agreements, 2CheckOut and some Authorize.Net processors. Any payment methods which are set to only be available to certain countries will not be available.</li><li>If any <a href='{internal.app=nexus&module=payments&controller=paymentsettings&tab=tax}' target='_blank'>tax rates</a> use a rate that is dependent on the customer's location, the default tax rate will be used.</li><li>Any <a href='{internal.app=nexus&module=payments&controller=paymentsettings&tab=fraud}' target='_blank'>Anti-Fraud Rules</a> which act on the customer's billing address will assume the customer is not in the country specified by them.</li><li>If <a href='{internal.app=core&module=applications&controller=enhancements&do=edit&id=nexus_MaxMind}' target='_blank'>MaxMind</a> integration is enabled, it's ability to accurately detect fraud will be impeded.</li></ul>It is recommended if you use any of these features that you leave all options checked so customers are always asked for a billing address.]]></word>
|
||||
<word key="nexus_require_billing_desc" js="0"><![CDATA[If you disable any of these options beware that without a billing address:<ul><li>Some <a href='{internal.app=nexus&module=payments&controller=paymentsettings&tab=gateways}' target='_blank' rel='noopener'>payment methods</a> will not be able to be used, including PayPal for card payments, PayPal Billing Agreements, 2CheckOut and some Authorize.Net processors. Any payment methods which are set to only be available to certain countries will not be available.</li><li>If any <a href='{internal.app=nexus&module=payments&controller=paymentsettings&tab=tax}' target='_blank' rel='noopener'>tax rates</a> use a rate that is dependent on the customer's location, the default tax rate will be used.</li><li>Any <a href='{internal.app=nexus&module=payments&controller=paymentsettings&tab=fraud}' target='_blank' rel='noopener'>Anti-Fraud Rules</a> which act on the customer's billing address will assume the customer is not in the country specified by them.</li><li>If <a href='{internal.app=core&module=applications&controller=enhancements&do=edit&id=nexus_MaxMind}' target='_blank' rel='noopener'>MaxMind</a> integration is enabled, it's ability to accurately detect fraud will be impeded.</li></ul>It is recommended if you use any of these features that you leave all options checked so customers are always asked for a billing address.]]></word>
|
||||
<word key="nexus_minimum_order" js="0">Minimum Order Amount</word>
|
||||
<word key="nexus_tac" js="0"><![CDATA[Terms & Conditions]]></word>
|
||||
<word key="nexus_tac_none" js="0">Do not display</word>
|
||||
@@ -418,7 +434,7 @@
|
||||
<word key="nexus_checkreg_usernames" js="0">Ask to provide a display name?</word>
|
||||
<word key="nexus_checkreg_usernames_desc" js="0">If no, their full name (first and last) will be used.</word>
|
||||
<word key="nexus_checkreg_captcha" js="0">Use Question and Answer Challenge</word>
|
||||
<word key="nexus_checkreg_captcha_desc" js="0"><![CDATA[Since the account will not be created until after the payment has been authorised, this is not usually necessary unless your Question and Answer Challenge is used to check for particular knowledge specific to your community.<br><a href='{internal.app=core&module=membersettings&controller=spam&tab=qanda}'>Question and Answer Challenge</a>]]></word>
|
||||
<word key="nexus_checkreg_captcha_desc" js="0"><![CDATA[Since the account will not be created until after the payment has been authorised, this is not usually necessary unless your Question and Answer Challenge is used to check for particular knowledge specific to your community.<br><a href='{internal.app=core&module=moderation&controller=spam&tab=qanda}'>Question and Answer Challenge</a>]]></word>
|
||||
<word key="nexus_checkreg_validate" js="0">Created accounts must be validated?</word>
|
||||
<word key="nexus_checkreg_validate_desc" js="0"><![CDATA[Since providing payment is a reliable way of validating a user is a real person, and having to validate an email account when making a purchase is annoying to most users, it is recommended you leave this setting disabled.<br>This setting does not apply if the purchase is free.]]></word>
|
||||
<word key="acplogs__checkout_settings" js="0">Updated Checkout Settings</word>
|
||||
@@ -595,6 +611,7 @@
|
||||
<word key="billing_agreement_canceled" js="0">Canceled</word>
|
||||
<word key="billing_agreement_unknown" js="0">Status Unknown</word>
|
||||
<word key="billing_agreement_error" js="0">There was an error communicating with the gateway to retrieve information about the Billing Agreement.</word>
|
||||
<word key="billing_agreement_cancel_error" js="0">There was an error communicating with the gateway to cancel the Billing Agreement. The payment has not been reversed. You should cancel the Billing Agreement with the gateway, and then try again with the option to cancel the Billing Agreement disabled.</word>
|
||||
<word key="billing_agreement_error_public" js="0">The requested action could not be performed. Please contact us for further information.</word>
|
||||
<word key="billing_agreement_term" js="0">Term</word>
|
||||
<word key="billing_agreement_next_payment" js="0">Next Payment</word>
|
||||
@@ -703,7 +720,7 @@
|
||||
<word key="enhancements__nexus_MaxMind_desc" js="0">MaxMind minFraud analyses transactions to identify potentially fraudulent transactions. This information can be used in combination with Fraud Rules to automatically hold for manual approval or refuse transactions.</word>
|
||||
<word key="maxmind_enable" js="0">Enable MaxMind minFraud integration?</word>
|
||||
<word key="maxmind_key" js="0">License Key</word>
|
||||
<word key="maxmind_key_desc" js="0"><![CDATA[<a href='{external.maxmind_key}' target='_blank'>Get your license key</a>. For best results, ensure your account is <a href='{external.maxmind_version}' target='_blank'>set to use version 1.3 or above</a>.]]></word>
|
||||
<word key="maxmind_key_desc" js="0"><![CDATA[<a href='{external.maxmind_key}' target='_blank' rel='noopener'>Get your license key</a>. For best results, ensure your account is <a href='{external.maxmind_version}' target='_blank' rel='noopener'>set to use version 1.3 or above</a>.]]></word>
|
||||
<word key="maxmind_upgrade_version" js="0">For better results, upgrade your MaxMind account to version 1.3 or above</word>
|
||||
<word key="maxmind_error" js="0">If there is an error communicating with MaxMind</word>
|
||||
<word key="maxmind_error_okay" js="0">Continue with transaction</word>
|
||||
@@ -766,7 +783,7 @@
|
||||
<word key="payment_received" js="0">Payment Received</word>
|
||||
<word key="total_to_pay" js="0">Total to pay</word>
|
||||
<word key="i_agree_to_tac" js="0">I agree to the %s</word>
|
||||
<word key="you_agree_to_tac" js="0"><![CDATA[By clicking the confirm button, you agree to the <a href='%s' target='_blank'>terms and conditions</a>.]]></word>
|
||||
<word key="you_agree_to_tac" js="0"><![CDATA[By clicking the confirm button, you agree to the <a href='%s' target='_blank' rel='noopener'>terms and conditions</a>.]]></word>
|
||||
<word key="you_must_agree_to_tac" js="0">You must agree to the terms and conditions.</word>
|
||||
<word key="terms_and_conditions" js="0"><![CDATA[terms & conditions]]></word>
|
||||
<word key="account_credit_with_amount" js="0">Account Credit (%s)</word>
|
||||
@@ -833,6 +850,7 @@
|
||||
<word key="transaction_declined" js="0">%s payment by %s was declined</word>
|
||||
<word key="transaction_refunded" js="0">%s paid by %s was refunded</word>
|
||||
<word key="transaction_part_refunded" js="0">%s was refunded from this payment</word>
|
||||
<word key="transaction_part_credited" js="0">%s was credited from this payment</word>
|
||||
<word key="transaction_processing" js="0">Processing</word>
|
||||
<word key="try_another_payment" js="0">Try another payment method</word>
|
||||
<word key="split_payment" js="0">Split Payment</word>
|
||||
@@ -1006,7 +1024,6 @@
|
||||
<word key="customer_manage_alts" js="0">Manage Contacts</word>
|
||||
<word key="customer_manage_referrers" js="0">Manage Referrals</word>
|
||||
<word key="recent_account_activity" js="0">Recent Account Activity</word>
|
||||
<word key="see_all_history" js="0">See all activity</word>
|
||||
<word key="view_account" js="0">View Account</word>
|
||||
<word key="no_alternate_contacts" js="0">No alternative contacts.</word>
|
||||
<word key="no_addresses" js="0">No addresses.</word>
|
||||
@@ -1035,7 +1052,6 @@
|
||||
<word key="customer_tab_alts" js="0">Alternate Contacts</word>
|
||||
<word key="customer_tab_referrers" js="0">Referrers</word>
|
||||
<word key="revenue_past_12_months" js="0">Revenue, 12 months to date</word>
|
||||
<word key="customer_no_history" js="0">There is no history to show for this customer.</word>
|
||||
<word key="memberACPProfileTitle_nexus_Main" js="0">Customer View</word>
|
||||
<word key="menu__nexus_customers_fields" js="0">Custom Fields</word>
|
||||
<word key="nexus_customer_fields" js="0">Customer Fields</word>
|
||||
@@ -1064,9 +1080,11 @@
|
||||
<word key="history_transaction_status_revw" js="0">flagged for review</word>
|
||||
<word key="history_transaction_status_fail" js="0">refused</word>
|
||||
<word key="history_transaction_status_dspd" js="0">disputed</word>
|
||||
<word key="history_transaction_refunded" js="0">%s refunded to %s%s.</word>
|
||||
<word key="history_transaction_part_refunded" js="0">%s of %s refunded to %s%s.</word>
|
||||
<word key="history_transaction_refunded_gateway" js="0">gateway</word>
|
||||
<word key="history_transaction_refunded" js="0">%s refunded %s.</word>
|
||||
<word key="history_transaction_credited" js="0">%s credited%s.</word>
|
||||
<word key="history_transaction_part_credited" js="0">%s of %s credited%s.</word>
|
||||
<word key="history_transaction_undo_credit" js="0">%s of credit given for %s reversed%s.</word>
|
||||
<word key="history_transaction_part_refunded" js="0">%s of %s refunded%s.</word>
|
||||
<word key="history_transaction_delete" js="0">%s deleted%s.</word>
|
||||
<word key="history_shipping_ship" js="0">%s shipped%s.</word>
|
||||
<word key="history_shipping_new" js="0">%s created from %s.</word>
|
||||
@@ -1207,12 +1225,12 @@
|
||||
<word key="nexus_payout" js="0">Available Withdrawal Methods</word>
|
||||
<word key="withdrawal_methods" js="0">Withdrawal Methods</word>
|
||||
<word key="payout__admin_PayPal" js="0">PayPal</word>
|
||||
<word key="payout__admin_PayPal_desc" js="0"><![CDATA[The money will be transferred from your PayPal account to the member's PayPal account. Your account <a href='{external.paypal_app_status}' target='_blank'>must have access</a> to Payouts.]]></word>
|
||||
<word key="payout__admin_PayPal_desc" js="0"><![CDATA[The money will be transferred from your PayPal account to the member's PayPal account. Your account <a href='{external.paypal_app_status}' target='_blank' rel='noopener'>must have access</a> to Payouts.]]></word>
|
||||
<word key="paypal_api_email" js="0">PayPal Email</word>
|
||||
<word key="paypal_api_app" js="0">PayPal Application ID</word>
|
||||
<word key="paypal_api_app_desc" js="0"><![CDATA[<a href='{external.paypal_old_apps}' target='_blank'>Create an application</a>]]></word>
|
||||
<word key="paypal_api_app_desc" js="0"><![CDATA[<a href='{external.paypal_old_apps}' target='_blank' rel='noopener'>Create an application</a>]]></word>
|
||||
<word key="paypal_api_username" js="0">PayPal API Username</word>
|
||||
<word key="paypal_api_username_desc" js="0"><![CDATA[<a href='{external.paypal_old_api}' target='_blank'>Request API Credentials</a>]]></word>
|
||||
<word key="paypal_api_username_desc" js="0"><![CDATA[<a href='{external.paypal_old_api}' target='_blank' rel='noopener'>Request API Credentials</a>]]></word>
|
||||
<word key="paypal_api_password" js="0">PayPal API Password</word>
|
||||
<word key="paypal_api_signature" js="0">PayPal API Signature</word>
|
||||
<word key="payout__front_PayPal" js="0">PayPal</word>
|
||||
@@ -1317,6 +1335,8 @@
|
||||
<word key="already_rated" js="0">You have already rated this response</word>
|
||||
<word key="r__customers" js="0">Customers</word>
|
||||
<word key="r__customers_view" js="0">Can view customers?</word>
|
||||
<word key="r__customers_view_statistics" js="0">Can view customer statistics?</word>
|
||||
<word key="r__customers_view_credit" js="0">Can view customer credit?</word>
|
||||
<word key="r__customers_edit_details" js="0">Can edit customer details?</word>
|
||||
<word key="r__customers_edit_credit" js="0">Can edit account credit?</word>
|
||||
<word key="r__customers_edit_cards" js="0">Can view and manage stored cards (the full card number is never displayed)?</word>
|
||||
@@ -1598,10 +1618,10 @@
|
||||
<word key="nexus_support_satisfaction" js="0">Enable Customer Feedback?</word>
|
||||
<word key="nexus_support_satisfaction_desc" js="0">Allows customers to rate staff responses and leave notes.</word>
|
||||
<word key="acplogs__customerfeedback_settings" js="0">Updated customer feedback settings</word>
|
||||
<word key="dpt_subscriptions" js="0">Associable subscriptons</word>
|
||||
<word key="dpt_subscriptions" js="0">Associable subscriptions</word>
|
||||
<word key="incoming_email_setup" js="0">Incoming Email Setup</word>
|
||||
<word key="ie_splash_intro" js="0"><![CDATA[The support system can read emails, allowing you to use all of the power of support requests but in a way which to customers appears to be a normal email conversation. Each <a href='{internal.app=nexus&module=support&controller=settings&tab=departments}'>department</a> has its own email address.]]></word>
|
||||
<word key="ie_splash_methods" js="0">Emails can read in severals ways:</word>
|
||||
<word key="ie_splash_methods" js="0">Emails can read in several ways:</word>
|
||||
<word key="ie_piping" js="0">Piping</word>
|
||||
<word key="ie_piping_desc" js="0">With piping, when the email is received, your server sends the email straight to the support system. The server Invision Community is installed on must be the same server that receives the email, and must support piping (check with your hosting provider if you're not sure).</word>
|
||||
<word key="ie_piping_use" js="0">Use Piping</word>
|
||||
@@ -1623,10 +1643,10 @@
|
||||
<word key="ie_piping_no_cpanel" js="0">If you do not use CPanel:</word>
|
||||
<word key="ie_piping_no_cpanel_1" js="0">Configure your server to pipe emails sent to pipe to the following command, replacing email@example.com with the email address being piped:</word>
|
||||
<word key="ie_piping_no_cpanel_2" js="0">If you do not know how to do this, contact your hosting provider and ask them to do it for you.</word>
|
||||
<word key="ie_pop3_details" js="0"><![CDATA[Fill in the following details which can be obtained from your email provider. Details for: <a href='{external.pop3_gmail}' target='_blank'>Gmail</a> · <a href='{external.pop3_outlook}' target='_blank'>Outlook.com</a> · <a href='{external.pop3_yahoo}' target='_blank'>Yahoo Mail</a>]]></word>
|
||||
<word key="ie_pop3_details" js="0"><![CDATA[Fill in the following details which can be obtained from your email provider. Details for: <a href='{external.pop3_gmail}' target='_blank' rel='noopener'>Gmail</a> · <a href='{external.pop3_outlook}' target='_blank' rel='noopener'>Outlook.com</a> · <a href='{external.pop3_yahoo}' target='_blank' rel='noopener'>Yahoo Mail</a>]]></word>
|
||||
<word key="ie_sendgrid_intro" js="0">Unlike other options, using SendGrid will require you to set the MX records on an entire domain or subdomain to point to SendGrid. This means you must use a dedicated domain or subdomain that you do not need to receive email for other purposes for. This may mean, for example, rather than using support@example.com, you need to use support@support.example.com.</word>
|
||||
<word key="ie_sendgrid_1" js="0"><![CDATA[If you haven't already, <a href='{external.sendgrid_whitelist}' target='_blank'>add a domain whitelabel in your SendGrid account</a> for your main domain and make sure it has been validated. This will require creating CNAME records to point to specific locations SendGrid will provide to prove that you own the domain. Contact SendGrid if you need any assistance with this step.]]></word>
|
||||
<word key="ie_sendgrid_2" js="0"><![CDATA[<a href='{external.sendgrid_incoming}' target='_blank'>Set up the receiving domain in SendGrid</a>. Enter the <strong>Destination URL</strong> to the URL below and make sure that the <strong>POST the raw, full MIME message</strong> setting <strong>is checked</strong>.]]></word>
|
||||
<word key="ie_sendgrid_1" js="0"><![CDATA[If you haven't already, <a href='{external.sendgrid_whitelist}' target='_blank' rel='noopener'>add a domain whitelabel in your SendGrid account</a> for your main domain and make sure it has been validated. This will require creating CNAME records to point to specific locations SendGrid will provide to prove that you own the domain. Contact SendGrid if you need any assistance with this step.]]></word>
|
||||
<word key="ie_sendgrid_2" js="0"><![CDATA[<a href='{external.sendgrid_incoming}' target='_blank' rel='noopener'>Set up the receiving domain in SendGrid</a>. Enter the <strong>Destination URL</strong> to the URL below and make sure that the <strong>POST the raw, full MIME message</strong> setting <strong>is checked</strong>.]]></word>
|
||||
<word key="pop3_server" js="0">Server</word>
|
||||
<word key="pop3_port" js="0">Port</word>
|
||||
<word key="pop3_user" js="0">Username</word>
|
||||
@@ -1640,7 +1660,7 @@
|
||||
<word key="pop3_settings" js="0">POP3 Settings</word>
|
||||
<word key="disable_pop3" js="0">Disable POP3</word>
|
||||
<word key="ie_sendgrid" js="0">SendGrid</word>
|
||||
<word key="ie_sendgrid_desc" js="0"><![CDATA[SendGrid is a third party service for sending and parsing incoming emails. You configure your domain to have SendGrid receive emails, and then SendGrid sends the emails to the support system. <a href='{external.sendgrid}' target='_blank'>Learn more</a>]]></word>
|
||||
<word key="ie_sendgrid_desc" js="0"><![CDATA[SendGrid is a third party service for sending and parsing incoming emails. You configure your domain to have SendGrid receive emails, and then SendGrid sends the emails to the support system. <a href='{external.sendgrid}' target='_blank' rel='noopener'>Learn more</a>]]></word>
|
||||
<word key="ie_sendgrid_use" js="0">Use SendGrid</word>
|
||||
<word key="request" js="0">Request</word>
|
||||
<word key="menu__nexus_support_requests" js="0">Support Requests</word>
|
||||
@@ -1749,7 +1769,7 @@
|
||||
<word key="reply_action_status" js="0"><![CDATA[%s marked this request <strong>%s</strong>]]></word>
|
||||
<word key="reply_action_moved" js="0"><![CDATA[%s moved this request to <strong>%s</strong>]]></word>
|
||||
<word key="reply_action_severity" js="0"><![CDATA[%s changed the severity to <strong>%s</strong>]]></word>
|
||||
<word key="reply_action_associate" js="0"><![CDATA[%s associated this request with <strong>%s</strong>]]></word>
|
||||
<word key="reply_action_associate" js="0"><![CDATA[%s associated this request with <strong><a href='%s'>%s</a></strong>]]></word>
|
||||
<word key="reply_action_unassociate" js="0">%s unassociated this request from a purchase</word>
|
||||
<word key="reply_action_assign" js="0">%s assigned this request to %s</word>
|
||||
<word key="reply_action_unassign" js="0">%s unassigned this request</word>
|
||||
@@ -1785,7 +1805,7 @@
|
||||
<word key="support_history_department_1" js="0">Moved</word>
|
||||
<word key="support_history_department_2" js="0">request #%d to %s</word>
|
||||
<word key="support_history_purchase_1" js="0">Associated</word>
|
||||
<word key="support_history_purchase_2" js="0">request #%d with %s</word>
|
||||
<word key="support_history_purchase_2" js="0"><![CDATA[request #%d with <a href='%s'>%s</a>]]></word>
|
||||
<word key="support_history_no_purchase_1" js="0">Unassociated</word>
|
||||
<word key="support_history_no_purchase_2" js="0">request #%d with a purchase</word>
|
||||
<word key="support_history_severity_1" js="0">Changed severity</word>
|
||||
@@ -1980,7 +2000,7 @@
|
||||
<word key="p_email_purchase_html" js="0">Email content for after purchase</word>
|
||||
<word key="p_email_purchase_wysiwyg" js="0">Email content for after purchase</word>
|
||||
<word key="p_email_expire_soon_type" js="0">Send email when purchase will expire soon?</word>
|
||||
<word key="p_email_expire_soon_type_desc" js="0"><![CDATA[This will be sent <em>instead of</em> the <a href='{internal.app=nexus&module=payments&controller=invoices&do=settings&searchResult=cm_invoice_warning}' target='_blank'>email about automatic payment</a> so it is best to mention that payment will be taken automatically if the customer has account credit, a card on file or a Billing Agreement.]]></word>
|
||||
<word key="p_email_expire_soon_type_desc" js="0"><![CDATA[This will be sent <em>instead of</em> the <a href='{internal.app=nexus&module=payments&controller=invoices&do=settings&searchResult=cm_invoice_warning}' target='_blank' rel='noopener'>email about automatic payment</a> so it is best to mention that payment will be taken automatically if the customer has account credit, a card on file or a Billing Agreement.]]></word>
|
||||
<word key="p_email_expire_soon_subject" js="0">Email subject for when purchase will expire soon</word>
|
||||
<word key="p_email_expire_soon_html" js="0">Email content for when purchase will expire soon</word>
|
||||
<word key="p_email_expire_soon_wysiwyg" js="0">Email content for when purchase will expire soon</word>
|
||||
@@ -2011,7 +2031,7 @@
|
||||
<word key="lkey_Standard" js="0">Standard (XXXX-XXXX-XXXX-XXXX-XXXX)</word>
|
||||
<word key="lkey_Mdfive" js="0">MD5 (xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)</word>
|
||||
<word key="p_lkey_uses" js="0">Number of times license key can be used</word>
|
||||
<word key="p_lkey_uses_desc" js="0"><![CDATA[Affects how the <a href='{external.licenseapi}' target='_blank'>License Key API</a> will handle activate requests.]]></word>
|
||||
<word key="p_lkey_uses_desc" js="0"><![CDATA[Affects how the <a href='{external.licenseapi}' target='_blank' rel='noopener'>License Key API</a> will handle activate requests.]]></word>
|
||||
<word key="p_lkey_identifier" js="0">Identifier</word>
|
||||
<word key="p_lkey_identifier_desc" js="0">If specified, this value will need to be provided in all API calls along with the license key.</word>
|
||||
<word key="lkey_identifier_none" js="0">No identifier</word>
|
||||
@@ -2497,7 +2517,7 @@
|
||||
<word key="enhancements__nexus_EasyPost_desc" js="0">Easy shipping with USPS, UPS, DHL, FedEx and others.</word>
|
||||
<word key="easypost_enable" js="0">Enable EasyPost integration?</word>
|
||||
<word key="easypost_api_key" js="0">EasyPost API Key</word>
|
||||
<word key="easypost_api_key_desc" js="0"><![CDATA[You can obtain your API key from <a href='{external.easypost_api_key}' target='_blank'>your EasyPost account</a>.]]></word>
|
||||
<word key="easypost_api_key_desc" js="0"><![CDATA[You can obtain your API key from <a href='{external.easypost_api_key}' target='_blank' rel='noopener'>your EasyPost account</a>.]]></word>
|
||||
<word key="easypost_address_select" js="0">Shipment 'From' Address</word>
|
||||
<word key="easypost_address_select_desc" js="0">This is the address that is provided to EasyPost as the 'From' address where you will send shipments from.</word>
|
||||
<word key="easypost_address_default" js="0">Site Physical Address (%s)</word>
|
||||
@@ -2568,11 +2588,11 @@
|
||||
<word key="epc_hs_tarrif" js="0">HS Tarrif Number</word>
|
||||
<word key="epc_origin" js="0">Origin Country</word>
|
||||
<word key="epc_origin_unknown" js="0"> - Unknown / Not Specified - </word>
|
||||
<word key="shipment_cost_others" js="0"><![CDATA[The customer paid %s in shipping charges for this and <a href='{internal.app=nexus&module=payments&controller=invoices&do=view&id=%d}' target='_blank'>%d other shipments</a>.]]></word>
|
||||
<word key="shipment_cost_others" js="0"><![CDATA[The customer paid %s in shipping charges for this and <a href='{internal.app=nexus&module=payments&controller=invoices&do=view&id=%d}' target='_blank' rel='noopener'>%d other shipments</a>.]]></word>
|
||||
<word key="shipment_cost_noothers" js="0">The customer paid %s for shipping.</word>
|
||||
<word key="shipment_label" js="0">Shipment Label</word>
|
||||
<word key="easypost_show_rates" js="0">Allow Customer to Choose Rate?</word>
|
||||
<word key="easypost_show_rates_0" js="0"><![CDATA[No - show the customer the <a href='{internal.app=nexus&module=payments&controller=shippingrates}' target='_blank'>shipping rates I have set up</a>. I will choose if I want to use EasyPost and which rate to use when I ship the parcel.]]></word>
|
||||
<word key="easypost_show_rates_0" js="0"><![CDATA[No - show the customer the <a href='{internal.app=nexus&module=payments&controller=shippingrates}' target='_blank' rel='noopener'>shipping rates I have set up</a>. I will choose if I want to use EasyPost and which rate to use when I ship the parcel.]]></word>
|
||||
<word key="easypost_show_rates_1" js="0">Yes - show the customer the available rates from EasyPost and charge them for the rate they choose.</word>
|
||||
<word key="easypost_tax" js="0">Tax Rate for shipping charges</word>
|
||||
<word key="easypost_price_adjustment" js="0">Price Adjustment</word>
|
||||
@@ -2581,7 +2601,7 @@
|
||||
<word key="easypost_delivery_adjustment_desc" js="0">The customer will be able to see the delivery estimates provided by EasyPost, with the specified adjustment. For example, if EasyPost says the estimated delivery is 3 days, and you enter 1 day here, the customer will see a delivery estimate of 4 days.</word>
|
||||
<word key="easypost_delivery_estimate" js="0">{# [1:day][?:days]}</word>
|
||||
<word key="easypost_test" js="0">Test Settings and View Rates</word>
|
||||
<word key="easypost_test_blurb" js="0"><![CDATA[This tool will show you the available rates to ship the selected products to the chosen location. If you are experiencing issues with EasyPost, you can use this tool to see if any errors are occurring with certain products or destinations. Shipments will show the Physical Address from your <a href='{internal.app=core&module=settings&controller=general}' target='_blank'>General Configuration</a> as the origin address.]]></word>
|
||||
<word key="easypost_test_blurb" js="0"><![CDATA[This tool will show you the available rates to ship the selected products to the chosen location. If you are experiencing issues with EasyPost, you can use this tool to see if any errors are occurring with certain products or destinations. Shipments will show the Physical Address from your <a href='{internal.app=core&module=settings&controller=general}' target='_blank' rel='noopener'>General Configuration</a> as the origin address.]]></word>
|
||||
<word key="easypost_test_method" js="0">Test Method</word>
|
||||
<word key="easypost_test_method_1" js="0">Choose products to be shipped</word>
|
||||
<word key="easypost_test_method_0" js="0">Manually specify parcel specifications</word>
|
||||
@@ -2620,7 +2640,7 @@
|
||||
<word key="server_hostname" js="0">Hostname</word>
|
||||
<word key="server_cpanel_username" js="0">Username</word>
|
||||
<word key="server_cpanel_key" js="0">CPanel Remote Access Key / API Token</word>
|
||||
<word key="server_cpanel_key_desc" js="0"><![CDATA[If you are using CPanel Version 62 or lower, you will need to use a <a href='{external.cpanel_key}' target='_blank'>Remote Access Key</a>. If you are using CPanel Version 64 or higher, then you will need to use an <a href='{external.cpanel_api_token}' target='_blank'>API Token</a>. <a href='{external.cpanel_auth_change}' target='_blank'>Learn More</a>]]></word>
|
||||
<word key="server_cpanel_key_desc" js="0"><![CDATA[If you are using CPanel Version 62 or lower, you will need to use a <a href='{external.cpanel_key}' target='_blank' rel='noopener'>Remote Access Key</a>. If you are using CPanel Version 64 or higher, then you will need to use an <a href='{external.cpanel_api_token}' target='_blank' rel='noopener'>API Token</a>. <a href='{external.cpanel_auth_change}' target='_blank' rel='noopener'>Learn More</a>]]></word>
|
||||
<word key="server_cpanel_key_hostname_err" js="0">The server accepted the key but is reporting a different hostname (%s) to the one provided. Check that you have provided the correct server details.</word>
|
||||
<word key="server_cpanel_call" js="0">Send API calls to</word>
|
||||
<word key="server_max_accounts" js="0">Maximum Accounts</word>
|
||||
@@ -2852,9 +2872,9 @@
|
||||
<word key="network_status_potential_issue" js="0">A potential issue has been detected with this server and we are investigating the issue.</word>
|
||||
<word key="network_status_normal" js="0">Running normally.</word>
|
||||
<word key="network_status_no_issues" js="0">All servers are online.</word>
|
||||
<word key="hosting_cancel_warning" js="0"><![CDATA[If you cancel the purchase, the hosting account will be immediately terminated on the server. If you would prefer to suspend the account, edit the purchase so the expiry date is in the past (beware that once a purchase has been expired for more than {# [1:day][?:days]}, it will be terminated as per your <a href='{internal.app=nexus&module=hosting&controller=settings}' target='_blank'>settings</a>)]]></word>
|
||||
<word key="hosting_cancel_warning_nt" js="0"><![CDATA[If you cancel the purchase, the hosting account will be immediately terminated on the server. If you would prefer to suspend the account, edit the purchase so the expiry date is in the past (beware that once a purchase has been expired for more than {# [1:day][?:days]}, it will be terminated as per your <a href='{internal.app=nexus&module=hosting&controller=settings}' target='_blank'>settings</a>)]]></word>
|
||||
<word key="hosting_cancel_warning_at" js="0"><![CDATA[If you cancel the purchase, the hosting account will be immediately terminated on the server. As per your <a href='{internal.app=nexus&module=hosting&controller=settings}' target='_blank'>settings</a> there is no way to suspend the account instead.]]></word>
|
||||
<word key="hosting_cancel_warning" js="0"><![CDATA[If you cancel the purchase, the hosting account will be immediately terminated on the server. If you would prefer to suspend the account, edit the purchase so the expiry date is in the past (beware that once a purchase has been expired for more than {# [1:day][?:days]}, it will be terminated as per your <a href='{internal.app=nexus&module=hosting&controller=settings}' target='_blank' rel='noopener'>settings</a>)]]></word>
|
||||
<word key="hosting_cancel_warning_nt" js="0"><![CDATA[If you cancel the purchase, the hosting account will be immediately terminated on the server. If you would prefer to suspend the account, edit the purchase so the expiry date is in the past (beware that once a purchase has been expired for more than {# [1:day][?:days]}, it will be terminated as per your <a href='{internal.app=nexus&module=hosting&controller=settings}' target='_blank' rel='noopener'>settings</a>)]]></word>
|
||||
<word key="hosting_cancel_warning_at" js="0"><![CDATA[If you cancel the purchase, the hosting account will be immediately terminated on the server. As per your <a href='{internal.app=nexus&module=hosting&controller=settings}' target='_blank' rel='noopener'>settings</a> there is no way to suspend the account instead.]]></word>
|
||||
<word key="p_type_Ad" js="0">Advertisement</word>
|
||||
<word key="p_type_Ad_desc" js="0"><![CDATA[Sell advertising space on your site that show alongside your <a href='{internal.app=core&module=promotion&controller=advertisements}'>own advertisements</a>.]]></word>
|
||||
<word key="p_locations" js="0">Show the advertisement</word>
|
||||
@@ -3183,6 +3203,7 @@ At this stage, no further action is required from you. We will send you an addit
|
||||
<word key="nexus_subs_after_conversion" js="0">After Conversion</word>
|
||||
<word key="sp_after_conversion_delete" js="0">Delete Original Store Package</word>
|
||||
<word key="nexus_package_converted_lovely" js="0">The package has been converted</word>
|
||||
<word key="nexus_subs_already_got_package" js="0">You already have an active subscription, and cannot purchase another.</word>
|
||||
<word key="nexus_subs_widget_title" js="0">Available Subscriptions</word>
|
||||
<word key="nexus_subs_widget_title_and_price" js="0">%s - %s</word>
|
||||
<word key="nexus_sub_member_id" js="0">Display Name</word>
|
||||
@@ -3232,6 +3253,7 @@ At this stage, no further action is required from you. We will send you an addit
|
||||
<word key="nexus_require_billing_subscriptions" js="0">Member Subscriptions</word>
|
||||
<word key="nexus_subs_non_available" js="0">There are not any subscriptions available at this time.</word>
|
||||
<word key="nexus_dont_delete_group" js="0">Some users who have purchased packages or subscriptions are set to return to this group when their subscription ends. If you delete this group, those users will be returned to the group '%s' instead.</word>
|
||||
<word key="upgrade_fix_refund_transactions" js="0">Updating transaction data</word>
|
||||
<word key="payment_error" js="1">There was an error processing the payment. Please try a different payment method or contact us for assistance.</word>
|
||||
<word key="support_ajax_error" js="1">An error occurred. Your session may have expired. Refresh the page and try again.</word>
|
||||
<word key="click_to_show_url" js="1">Click to show real URL</word>
|
||||
|
||||
@@ -540,6 +540,20 @@
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
},
|
||||
"t_credit": {
|
||||
"name": "t_credit",
|
||||
"type": "DECIMAL",
|
||||
"length": 10,
|
||||
"decimals": 3,
|
||||
"values": null,
|
||||
"allow_null": true,
|
||||
"default": null,
|
||||
"comment": "If transaction has been credited (refund to account credit), the amount that was credited",
|
||||
"unsigned": true,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
@@ -6479,18 +6493,18 @@
|
||||
"zerofill": false
|
||||
},
|
||||
"review_ip_address": {
|
||||
"allow_null": true,
|
||||
"auto_increment": false,
|
||||
"binary": false,
|
||||
"comment": "",
|
||||
"decimals": null,
|
||||
"default": null,
|
||||
"length": 16,
|
||||
"name": "review_ip_address",
|
||||
"type": "VARCHAR",
|
||||
"unsigned": false,
|
||||
"length": 46,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"zerofill": false
|
||||
"allow_null": true,
|
||||
"default": null,
|
||||
"comment": "",
|
||||
"unsigned": false,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
},
|
||||
"review_date": {
|
||||
"allow_null": true,
|
||||
|
||||
+267
-188
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<theme name="Default" author_name="Invision Power Services, Inc" author_url="https://www.invisioncommunity.com">
|
||||
<field sc_key="cm_store_view" sc_type="Select" sc_multiple="0" sc_updated="1510679502" sc_app="nexus" sc_default="grid" sc_tab_key="custom" sc_show_in_vse="0" sc_title="themesetting_cm_store_view" sc_order="11" sc_condition="">[{"key":"grid","value":"Grid"},{"key":"list","value":"List"}]</field>
|
||||
<field sc_key="subscription_active_color" sc_type="Color" sc_multiple="0" sc_updated="1519743529" sc_app="nexus" sc_default="#3d6594" sc_tab_key="frontendcolors" sc_show_in_vse="0" sc_title="themesetting_subscription_active" sc_order="42" sc_condition="">[]</field>
|
||||
<field sc_key="cm_store_view" sc_type="Select" sc_multiple="0" sc_updated="1522241852" sc_app="nexus" sc_default="grid" sc_tab_key="custom" sc_show_in_vse="0" sc_title="themesetting_cm_store_view" sc_order="11" sc_condition="">[{"key":"grid","value":"Grid"},{"key":"list","value":"List"}]</field>
|
||||
<field sc_key="subscription_active_color" sc_type="Color" sc_multiple="0" sc_updated="1527640594" sc_app="nexus" sc_default="#3d6594" sc_tab_key="frontendcolors" sc_show_in_vse="0" sc_title="themesetting_subscription_active" sc_order="42" sc_condition="">[]</field>
|
||||
<template template_group="billingagreements" template_name="view" template_data="$billingAgreement, $purchases, $transactions" template_location="admin" template_app="nexus"><![CDATA[{{if $billingAgreement->status() == $billingAgreement::STATUS_ACTIVE and !$billingAgreement->next_cycle}}
|
||||
<p class="ipsMessage ipsMessage_warning">{lang="billing_agreement_run_failed" sprintf="$billingAgreement->acpUrl()->setQueryString( 'do', 'reconcile' )"}</p>
|
||||
{{endif}}
|
||||
@@ -709,7 +709,7 @@
|
||||
<section class='ipsBox ipsSpacer_top'>
|
||||
<h2 class='ipsType_sectionTitle ipsType_reset'>{lang="order_review"}</h2>
|
||||
<div class='ipsPad'>
|
||||
<a href='{$invoice->url()->setQueryString( 'do', 'printout' )}' target="_blank" class='ipsJS_show ipsButton ipsButton_light ipsButton_verySmall ipsPos_right'>{lang="order_invoice_print"}</a>
|
||||
<a href='{$invoice->url()->setQueryString( 'do', 'printout' )}' target="_blank" rel='noopener' class='ipsJS_show ipsButton ipsButton_light ipsButton_verySmall ipsPos_right'>{lang="order_invoice_print"}</a>
|
||||
<h2 class='ipsType_pageTitle'>{lang="order"} #{$invoice->id}</h2>
|
||||
<hr class='ipsHr'>
|
||||
<div class='ipsGrid ipsGrid_collapsePhone ipsSpacer_top'>
|
||||
@@ -1350,11 +1350,11 @@
|
||||
<div class="cDonateProgressBar_progress" style="width:{expression="100/$goal->goal*$goal->current"}%"></div>
|
||||
</div>
|
||||
<p class="ipsType_center ipsType_normal">
|
||||
<strong>{lang="donate_progress" htmlsprintf="new \IPS\nexus\Money( $goal->current, $goal->currency ), new \IPS\nexus\Money( $goal->goal, $goal->currency )"}</strong>
|
||||
<strong>{lang="donate_progress" sprintf="new \IPS\nexus\Money( $goal->current, $goal->currency ), new \IPS\nexus\Money( $goal->goal, $goal->currency )"}</strong>
|
||||
</p>
|
||||
{{else}}
|
||||
<p class="ipsType_center ipsType_normal">
|
||||
<strong>{lang="donate_sofar" htmlsprintf="new \IPS\nexus\Money( $goal->current, $goal->currency )"}</strong>
|
||||
<strong>{lang="donate_sofar" sprintf="new \IPS\nexus\Money( $goal->current, $goal->currency )"}</strong>
|
||||
</p>
|
||||
{{endif}}
|
||||
</div>
|
||||
@@ -1373,7 +1373,7 @@
|
||||
<template template_group="clients" template_name="invoice" template_data="$invoice" template_location="front" template_app="nexus"><![CDATA[
|
||||
<div class='ipsBox_alt'>
|
||||
<div class='ipsPos_right ipsType_right ipsType_normal'>
|
||||
<a href='{$invoice->url()->setQueryString( 'printout', 'true' )}' target="_blank" class='ipsButton ipsButton_verySmall ipsButton_light'>{lang="order_invoice_print"}</a><br>
|
||||
<a href='{$invoice->url()->setQueryString( 'printout', 'true' )}' target="_blank" rel='noopener' class='ipsButton ipsButton_verySmall ipsButton_light'>{lang="order_invoice_print"}</a><br>
|
||||
{{if $invoice->po}}
|
||||
{lang="invoice_po_number"}: {$invoice->po} <a href="{$invoice->url()->setQueryString( array( 'do' => 'poNumber' ) )}" data-ipsDialog data-ipsDialog-title='{lang="order_po_number_dialog"}' class='ipsType_small' title='{lang="order_po_number"}'>{lang="edit"}</a>
|
||||
{{else}}
|
||||
@@ -1567,7 +1567,7 @@
|
||||
</p>
|
||||
</div>
|
||||
{{if $shipment->trackingUrl()}}
|
||||
<a href="{$shipment->trackingUrl()}" class='ipsButton ipsButton_light ipsButton_verySmall ipsButton_fullWidth' target="_blank">{lang="order_track_delivery"}</a>
|
||||
<a href="{$shipment->trackingUrl()}" class='ipsButton ipsButton_light ipsButton_verySmall ipsButton_fullWidth' target="_blank" rel='noopener'>{lang="order_track_delivery"}</a>
|
||||
{{endif}}
|
||||
{{elseif $shipment->status === $shipment::STATUS_PENDING}}
|
||||
<h3 class='ipsType_large ipsType_reset'>{lang="sstatus_{$shipment->status}"}</h3>
|
||||
@@ -1801,9 +1801,16 @@
|
||||
<strong>{lang="transaction_paid" sprintf="$thisTransaction->amount, ( $thisTransaction->method ) ? $thisTransaction->method->_title : \IPS\Member::loggedIn()->language()->get('account_credit')"}</strong>
|
||||
<span class='ipsType_light ipsType_noBreak'>{datetime="$thisTransaction->date"}</span>
|
||||
</p>
|
||||
<p class='ipsType_medium ipsType_reset'>
|
||||
{lang="transaction_part_refunded" sprintf="$thisTransaction->partial_refund"}
|
||||
</p>
|
||||
{{if $thisTransaction->partial_refund->amount->isGreaterThanZero()}}
|
||||
<p class='ipsType_medium ipsType_reset'>
|
||||
{lang="transaction_part_refunded" sprintf="$thisTransaction->partial_refund"}
|
||||
</p>
|
||||
{{endif}}
|
||||
{{if $thisTransaction->credit->amount->isGreaterThanZero()}}
|
||||
<p class='ipsType_medium ipsType_reset'>
|
||||
{lang="transaction_part_credited" sprintf="$thisTransaction->credit"}
|
||||
</p>
|
||||
{{endif}}
|
||||
{{if $thisTransaction->gw_id}}
|
||||
<p class='ipsType_small ipsType_light ipsType_reset'>
|
||||
{lang="payment_ref"}: {$thisTransaction->gw_id}
|
||||
@@ -2066,11 +2073,11 @@
|
||||
<div class='ipsGrid'>
|
||||
<div class='ipsGrid_span6'>
|
||||
<h3 class='ipsType_minorHeading'>{lang="referral_html"}</h3>
|
||||
<input type='text' class='ipsField_fullWidth' value="<a href='{$url}'><img src='{$banner->url}' alt='{setting="board_name"}'></a>">
|
||||
<input type='text' class='ipsField_fullWidth' value="<a href='{$url}'><img src='{file="$banner->url" extension="nexus_ReferralBanners"}' alt='{setting="board_name"}'></a>">
|
||||
</div>
|
||||
<div class='ipsGrid_span6'>
|
||||
<h3 class='ipsType_minorHeading'>{lang="referral_bbcode"}</h3>
|
||||
<input type='text' class='ipsField_fullWidth' value="[url='{$url}'][img]{$banner->url}[/img][/url]">
|
||||
<input type='text' class='ipsField_fullWidth' value="[url='{$url}'][img]{file="$banner->url" extension="nexus_ReferralBanners"}[/img][/url]">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2136,20 +2143,21 @@
|
||||
</div>
|
||||
</div>]]></template>
|
||||
<template template_group="customers" template_name="accountInformationOverview" template_data="$customer, $sparkline, $referredBy, $primaryBillingAddress, $addressCount" template_location="admin" template_app="nexus"><![CDATA[<div class="ipsPad">
|
||||
{{if $sparkline }}
|
||||
<div id='elCustomerIncome'>{$sparkline|raw}</div>
|
||||
<p class='ipsType_reset ipsType_light ipsType_small ipsSpacer_top ipsSpacer_half'>
|
||||
{lang="revenue_past_12_months"}
|
||||
</p>
|
||||
|
||||
{{endif}}
|
||||
{{if $referredBy}}
|
||||
<hr class='ipsHr'>
|
||||
<p class='ipsType_medium ipsType_center ipsType_light ipsType_blendLinks'>
|
||||
{lang="referred_by"} <a href='{$referredBy->acpUrl()}' title='{$referredBy->email}'>{$referredBy->cm_name}</a>
|
||||
</p>
|
||||
{{endif}}
|
||||
|
||||
|
||||
{{if \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_view_credit' )}}
|
||||
<hr class='ipsHr'>
|
||||
|
||||
{{foreach \IPS\nexus\Money::currencies() as $currency}}
|
||||
<div class='ipsAreaBackground{{if isset( $customer->cm_credits[ $currency ] ) && $customer->cm_credits[ $currency ]->amount->isGreaterThanZero()}}_positive{{endif}} ipsPad_half ipsType_center ipsType_large cCustomerCredit'>
|
||||
<h2 class='ipsType_reset ipsType_minorHeading'>{lang="client_credit"}</h2>
|
||||
@@ -2162,8 +2170,9 @@
|
||||
<p class='ipsType_reset'><a href='{url="app=nexus&module=customers&controller=view&id={$customer->member_id}&do=credits"}' data-ipsDialog data-ipsDialog-title='{lang="edit_credit"}' data-ipsDialog-size='narrow' class='ipsType_small'>{lang="edit"}</a></p>
|
||||
{{endif}}
|
||||
</div>
|
||||
{{endforeach}}
|
||||
|
||||
{{endforeach}}
|
||||
{{endif}}
|
||||
|
||||
<hr class='ipsHr'>
|
||||
|
||||
<h2 class='ipsType_sectionHead ipsType_large'>{lang="primary_address"}</h2>
|
||||
@@ -2491,7 +2500,7 @@
|
||||
<div class='ipsSpacer_bottom ipsSpacer_double'>
|
||||
<div class='ipsBox cNotesBox'>
|
||||
<h2 class='ipsBox_titleBar'>
|
||||
<a href='{url="app=core&module=members&controller=members&do=editBlock&block=IPS\\nexus\\extensions\\core\\MemberACPProfileBlocks\\Notes&id={$customer->member_id}"}' data-ipsDialog data-ipsDialog-title='{lang="customer_notes"}' class='ipsPos_right ipsType_medium'>
|
||||
<a href='{url="app=core&module=members&controller=members&do=lazyBlock&block=IPS\\nexus\\extensions\\core\\MemberACPProfileBlocks\\Notes&id={$customer->member_id}"}' data-ipsDialog data-ipsDialog-title='{lang="customer_notes"}' class='ipsPos_right ipsType_medium'>
|
||||
{lang="manage_notes"}
|
||||
</a>
|
||||
{lang="num_customer_notes_uc" pluralize="$noteCount"} ({$noteCount})
|
||||
@@ -2503,7 +2512,7 @@
|
||||
</div>
|
||||
{{else}}
|
||||
<div class='ipsPad ipsType_light cCustomerNotes_none ipsSpacer_bottom'>
|
||||
<a href='{url="app=core&module=members&controller=members&do=editBlock&block=IPS\\nexus\\extensions\\core\\MemberACPProfileBlocks\\Notes&id={$customer->member_id}"}' data-ipsDialog data-ipsDialog-title='{lang="customer_notes"}' class='ipsPos_right ipsType_medium'>
|
||||
<a href='{url="app=core&module=members&controller=members&do=lazyBlock&block=IPS\\nexus\\extensions\\core\\MemberACPProfileBlocks\\Notes&id={$customer->member_id}"}' data-ipsDialog data-ipsDialog-title='{lang="customer_notes"}' class='ipsPos_right ipsType_medium'>
|
||||
{lang="manage_notes"}
|
||||
</a>
|
||||
{lang="num_customer_notes_uc" pluralize="$noteCount"} ({$noteCount})
|
||||
@@ -3600,7 +3609,7 @@
|
||||
{{endif}}
|
||||
</td>
|
||||
<td><a href='{url="app=nexus&module=customers&controller=purchases&do=view&id={$data['ps_id']}"}'>{$data['account_username']}</a></td>
|
||||
<td><a href="{expression="\IPS\Http\Url::external( 'http://' . $data['account_domain'] )->makeSafeForAcp()"}" target="_blank">{$data['account_domain']}</a></td>
|
||||
<td><a href="{expression="\IPS\Http\Url::external( 'http://' . $data['account_domain'] )->makeSafeForAcp()"}" target="_blank" rel='noopener'>{$data['account_domain']}</a></td>
|
||||
<td>{filesize="$data['disklimit']" decimal="true"}</td>
|
||||
<td>{filesize="$data['diskused']" decimal="true"}</td>
|
||||
</tr>
|
||||
@@ -4384,7 +4393,7 @@
|
||||
</div>
|
||||
</div>]]></template>
|
||||
<template template_group="livesearch" template_name="customer" template_data="$member" template_location="admin" template_app="nexus"><![CDATA[<li class='ipsPhotoPanel ipsPhotoPanel_mini ipsPad_half ipsClearfix' data-role='result'>
|
||||
<a href="{$member->acpUrl()}" class="ipsUserPhoto ipsUserPhoto_mini" target="_blank">
|
||||
<a href="{$member->acpUrl()}" class="ipsUserPhoto ipsUserPhoto_mini" target="_blank" rel='noopener'>
|
||||
<img src='{$member->photo}'>
|
||||
</a>
|
||||
<div>
|
||||
@@ -4547,30 +4556,53 @@
|
||||
</div>
|
||||
</div>]]></template>
|
||||
<template template_group="promotion" template_name="referralBanner" template_data="$url" template_location="global" template_app="nexus"><![CDATA[<img src="{file="$url" extension="nexus_ReferralBanners"}" class="ipsImage">]]></template>
|
||||
<template template_group="purchases" template_name="advertisement" template_data="$purchase, $advertisement" template_location="admin" template_app="nexus"><![CDATA[<div class="ipsAdvertisement">
|
||||
<ul class="ipsType_center ipsList_reset">
|
||||
{{foreach json_decode( $advertisement->images, TRUE ) as $image}}
|
||||
<li>
|
||||
<div class="ipsAdvertisement_large ipsAreaBackground_light ipsPad_half">
|
||||
<div class='ipsAreaBackground_reset ipsPad_half'>
|
||||
<a href="{$advertisement->link}"><img src="{$image}" class="ipsImage ipsContained"></a>
|
||||
</div>
|
||||
<div class="ipsGrid ipsPad_half">
|
||||
<div class="ipsGrid_span6">
|
||||
<span class="ipsType_veryLarge">{$advertisement->impressions}{{if $advertisement->maximum_unit == 'i' and $advertisement->maximum_value != -1}} / {$advertisement->maximum_value}{{endif}}</span>
|
||||
<br>
|
||||
{lang="impressions"}
|
||||
</div>
|
||||
<div class="ipsGrid_span6">
|
||||
<span class="ipsType_veryLarge">{$advertisement->clicks}{{if $advertisement->maximum_unit == 'c' and $advertisement->maximum_value != -1}} / {$advertisement->maximum_value}{{endif}}</span>
|
||||
<br>
|
||||
{lang="clicks"}
|
||||
</div>
|
||||
<template template_group="purchases" template_name="advertisement" template_data="$purchase, $advertisement" template_location="admin" template_app="nexus"><![CDATA[<div class="ipsGrid ipsPad_half ipsType_center ipsSpacer_bottom">
|
||||
<div class="ipsGrid_span6">
|
||||
<span class="ipsType_veryLarge">{$advertisement->impressions}{{if $advertisement->maximum_unit == 'i' and $advertisement->maximum_value != -1}} / {$advertisement->maximum_value}{{endif}}</span>
|
||||
<br>
|
||||
{lang="impressions"}
|
||||
</div>
|
||||
<div class="ipsGrid_span6">
|
||||
<span class="ipsType_veryLarge">{$advertisement->clicks}{{if $advertisement->maximum_unit == 'c' and $advertisement->maximum_value != -1}} / {$advertisement->maximum_value}{{endif}}</span>
|
||||
<br>
|
||||
{lang="clicks"}
|
||||
</div>
|
||||
</div>
|
||||
<div class="ipsAdvertisement ipsAreaBackground_reset ipsType_center">
|
||||
{{$images = array_filter( json_decode( $advertisement->images, TRUE ) );}}
|
||||
{{$link = \IPS\Http\Url::external( $advertisement->link )->makeSafeForAcp();}}
|
||||
|
||||
{{if count( $images ) > 1}}
|
||||
<div class='ipsTabs ipsClearfix acpFormTabBar' id='elTabs_adView' data-ipsTabBar data-ipsTabBar-contentArea='#ipsTabs_content_adView' data-ipsTabBar-updateURL='false'>
|
||||
<a href='#elTabs_adView' data-action='expandTabs'><i class='fa fa-caret-down'></i></a>
|
||||
<ul role='tablist'
|
||||
{{foreach $images as $key => $image}}
|
||||
<li>
|
||||
<a href='#ipsTabs_elTabs_adView_adView_tab_{$key}_panel' id='adView_tab_{$key}' class="ipsTabs_item {{if $key == "large"}}ipsTabs_activeItem{{endif}}" title='{$key}' role="tab" aria-selected="{{if $key == "large"}}true{{else}}false{{endif}}">
|
||||
{{if $key === 'large'}}{lang="ad_image"}{{else}}{lang="ad_image_{$key}"}{{endif}}
|
||||
</a>
|
||||
</li>
|
||||
{{endforeach}}
|
||||
</ul>
|
||||
</div>
|
||||
<section id='ipsTabs_content_adView' class='acpFormTabContent'>
|
||||
{{foreach $images as $key => $image}}
|
||||
<div id='ipsTabs_elTabs_adView_adView_tab_{$key}_panel' class="ipsTabs_panel" aria-labelledby="adView_tab_{$key}" aria-hidden="false">
|
||||
<div class="ipsPad">
|
||||
<a href="{$link}" target='_blank' rel='nofollow noopener'><img src="{file="$image" extension="$advertisement->storageExtension()"}" class="ipsImage ipsContained"></a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
{{endforeach}}
|
||||
</ul>
|
||||
{{endforeach}}
|
||||
</section>
|
||||
{{else}}
|
||||
<div class="ipsPad">
|
||||
{{foreach $images as $key => $image}}
|
||||
<a href="{$link}" target='_blank' rel='nofollow noopener'><img src="{file="$image" extension="$advertisement->storageExtension()"}" class="ipsImage ipsContained"></a>
|
||||
{{endforeach}}
|
||||
</div>
|
||||
{{endif}}
|
||||
<div class="ipsType_small"><a href="{$link}">{$advertisement->link}</a></div>
|
||||
|
||||
</div>]]></template>
|
||||
<template template_group="purchases" template_name="advertisement" template_data="$purchase, $advertisement" template_location="front" template_app="nexus"><![CDATA[{{if $advertisement->active == -1}}
|
||||
<p class="ipsMessage ipsMessage_info">{lang="advertisement_pending_approval"}</p>
|
||||
@@ -4932,7 +4964,7 @@
|
||||
<a href="{$account->ftpLink()}" class='ipsButton ipsButton_primary ipsButton_verySmall ipsButton_fullWidth'>{lang="account_ftp"}</a>
|
||||
</li>
|
||||
<li class='ipsGrid_span6'>
|
||||
<a href="{$account->controlPanelLink()}" class='ipsButton ipsButton_primary ipsButton_verySmall ipsButton_fullWidth' target="_blank">{lang="account_{$account->server->type}_control_panel"}</a>
|
||||
<a href="{$account->controlPanelLink()}" class='ipsButton ipsButton_primary ipsButton_verySmall ipsButton_fullWidth' target="_blank" rel='noopener'>{lang="account_{$account->server->type}_control_panel"}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -4988,7 +5020,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<p class='ipsType_center ipsType_normal'>
|
||||
<strong><a href="{expression="\IPS\Http\Url::external( 'http://' . $account->domain )->makeSafeForAcp()"}" target="_blank">{$account->domain}</a> <i class='fa fa-external-link'></i></strong>
|
||||
<strong><a href="{expression="\IPS\Http\Url::external( 'http://' . $account->domain )->makeSafeForAcp()"}" target="_blank" rel='noopener'>{$account->domain}</a> <i class='fa fa-external-link'></i></strong>
|
||||
</p>
|
||||
</div>
|
||||
</div>]]></template>
|
||||
@@ -5024,7 +5056,7 @@
|
||||
<a href="{$account->ftpLink()}" class='ipsButton ipsButton_primary ipsButton_verySmall ipsButton_fullWidth'>{lang="account_ftp"}</a>
|
||||
</li>
|
||||
<li class='ipsGrid_span6'>
|
||||
<a href="{$account->controlPanelLink()}" class='ipsButton ipsButton_primary ipsButton_verySmall ipsButton_fullWidth' target="_blank">{lang="account_{$account->server->type}_control_panel"}</a>
|
||||
<a href="{$account->controlPanelLink()}" class='ipsButton ipsButton_primary ipsButton_verySmall ipsButton_fullWidth' target="_blank" rel='noopener'>{lang="account_{$account->server->type}_control_panel"}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -5075,7 +5107,7 @@
|
||||
</div>
|
||||
|
||||
<p class='ipsType_center ipsType_normal'>
|
||||
<strong><a href="http://{$account->domain}" target="_blank">{$account->domain}</a> <i class='fa fa-external-link'></i></strong>
|
||||
<strong><a href="http://{$account->domain}" target="_blank" rel='noopener'>{$account->domain}</a> <i class='fa fa-external-link'></i></strong>
|
||||
{{if settings.nexus_hosting_allow_change_domain}}
|
||||
<br>
|
||||
<a href="{$purchase->url()->setQueryString( array( 'do' => 'extra', 'act' => 'changedomain' ) )}" class="ipsType_small">({lang="change_domain"})</a>
|
||||
@@ -5123,12 +5155,12 @@
|
||||
<a href="{$account->ftpLink()}" class='ipsButton ipsButton_primary ipsButton_verySmall ipsButton_fullWidth'>{lang="account_ftp"}</a>
|
||||
</li>
|
||||
<li class='ipsGrid_span6'>
|
||||
<a href="{$account->controlPanelLink()}" class='ipsButton ipsButton_primary ipsButton_verySmall ipsButton_fullWidth' target="_blank">{lang="account_{$account->server->type}_control_panel"}</a>
|
||||
<a href="{$account->controlPanelLink()}" class='ipsButton ipsButton_primary ipsButton_verySmall ipsButton_fullWidth' target="_blank" rel='noopener'>{lang="account_{$account->server->type}_control_panel"}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<p class='ipsType_center ipsType_normal'>
|
||||
<strong><a href="{expression="\IPS\Http\Url::external( 'http://' . $account->domain )->makeSafeForAcp()"}" target="_blank">{$account->domain}</a> <i class='fa fa-external-link'></i></strong>
|
||||
<strong><a href="{expression="\IPS\Http\Url::external( 'http://' . $account->domain )->makeSafeForAcp()"}" target="_blank" rel='noopener'>{$account->domain}</a> <i class='fa fa-external-link'></i></strong>
|
||||
</p>
|
||||
</div>
|
||||
{{else}}
|
||||
@@ -5171,14 +5203,14 @@
|
||||
<a href="{$account->ftpLink()}" class='ipsButton ipsButton_primary ipsButton_verySmall ipsButton_fullWidth'>{lang="account_ftp"}</a>
|
||||
</li>
|
||||
<li class='ipsGrid_span6'>
|
||||
<a href="{$account->controlPanelLink()}" class='ipsButton ipsButton_primary ipsButton_verySmall ipsButton_fullWidth' target="_blank">{lang="account_{$account->server->type}_control_panel"}</a>
|
||||
<a href="{$account->controlPanelLink()}" class='ipsButton ipsButton_primary ipsButton_verySmall ipsButton_fullWidth' target="_blank" rel='noopener'>{lang="account_{$account->server->type}_control_panel"}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class='ipsType_center ipsType_normal'>
|
||||
<strong><a href="http://{$account->domain}" target="_blank">{$account->domain}</a> <i class='fa fa-external-link'></i></strong>
|
||||
<strong><a href="http://{$account->domain}" target="_blank" rel='noopener'>{$account->domain}</a> <i class='fa fa-external-link'></i></strong>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -5194,7 +5226,7 @@
|
||||
<td class='cNexusSupportHeader_colInfo'>
|
||||
<ul class='ipsList_inline'>
|
||||
<li>
|
||||
<i class='fa fa-globe'></i> <a href="{expression="\IPS\Http\Url::external( 'http://' . $account->domain )->makeSafeForAcp()"}" target="_blank">{$account->domain}</a>
|
||||
<i class='fa fa-globe'></i> <a href="{expression="\IPS\Http\Url::external( 'http://' . $account->domain )->makeSafeForAcp()"}" target="_blank" rel='noopener'>{$account->domain}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class='fa fa-server'></i> {$account->server->hostname}
|
||||
@@ -5203,7 +5235,7 @@
|
||||
<i class='fa fa-lock'></i> <span class="ipsType_monospace">{$account->username}</span> / <span class="ipsType_monospace">{$account->password}</span>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{$account->ftpLink()}">{lang="account_ftp"}</a> / <a href="{$account->controlPanelLink()}" target="_blank">{lang="account_{$account->server->type}_control_panel"}</a>
|
||||
<a href="{$account->ftpLink()}">{lang="account_ftp"}</a> / <a href="{$account->controlPanelLink()}" target="_blank" rel='noopener'>{lang="account_{$account->server->type}_control_panel"}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
@@ -5273,9 +5305,9 @@
|
||||
{{endif}}
|
||||
<div class='ipsDataItem_meta ipsType_medium ipsType_light'>
|
||||
{{if $use['last_checked']}}
|
||||
{lang="lkey_use_info" htmlsprintf="\IPS\DateTime::ts( $use['activated'] )->html(), $use['ip'], \IPS\DateTime::ts( $use['last_checked'] )->html()"}
|
||||
{lang="lkey_use_info" htmlsprintf="\IPS\DateTime::ts( $use['activated'] )->html(), htmlspecialchars( $use['ip'], ENT_DISALLOWED, 'UTF-8', FALSE ), \IPS\DateTime::ts( $use['last_checked'] )->html()"}
|
||||
{{else}}
|
||||
{lang="lkey_use_info_nocheck" htmlsprintf="\IPS\DateTime::ts( $use['activated'] )->html(), $use['ip']"}
|
||||
{lang="lkey_use_info_nocheck" htmlsprintf="\IPS\DateTime::ts( $use['activated'] )->html(), htmlspecialchars( $use['ip'], ENT_DISALLOWED, 'UTF-8', FALSE )"}
|
||||
{{endif}}
|
||||
</div>
|
||||
</div>
|
||||
@@ -5693,7 +5725,7 @@
|
||||
{{endif}}
|
||||
{{if $shipment->trackingUrl()}}
|
||||
·
|
||||
<a href="{$shipment->trackingUrl()->makeSafeForAcp()}" target="_blank">{lang="track"}</a>
|
||||
<a href="{$shipment->trackingUrl()->makeSafeForAcp()}" target="_blank" rel='noopener'>{lang="track"}</a>
|
||||
{{endif}}
|
||||
{{endif}}
|
||||
</div>
|
||||
@@ -5707,11 +5739,11 @@
|
||||
<h2 class="ipsBox_title">{lang="shipment_label"}</h2>
|
||||
<div class="ipsBox ipsPad">
|
||||
{{if $shipment->label instanceof \IPS\Http\Url}}
|
||||
<a href="{$shipment->label->makeSafeForAcp()}" target="_blank">
|
||||
<a href="{$shipment->label->makeSafeForAcp()}" target="_blank" rel='noopener'>
|
||||
<img src="{$shipment->label->makeSafeForAcp(TRUE)}" class="ipsImage">
|
||||
</a>
|
||||
{{else}}
|
||||
<a class="ipsButton ipsButton_normal ipsButton_fullWidth ipsButton_small" href="{$shipment->acpUrl()->setQueryString( array( 'do' => 'printout', 'print' => 'apilabel' ) )}" target='_blank'>{lang="print_label"}</a>
|
||||
<a class="ipsButton ipsButton_normal ipsButton_fullWidth ipsButton_small" href="{$shipment->acpUrl()->setQueryString( array( 'do' => 'printout', 'print' => 'apilabel' ) )}" target='_blank' rel='noopener'>{lang="print_label"}</a>
|
||||
{{endif}}
|
||||
</div>
|
||||
{{if $easyPost and isset( $easyPost['tracker'] ) and count( $easyPost['tracker']['tracking_details'] )}}
|
||||
@@ -5747,7 +5779,7 @@
|
||||
<tbody>
|
||||
{{foreach $shipment->items as $item}}
|
||||
<tr>
|
||||
<td>{$item['name']}</td>
|
||||
<td class='ipsTable_wrap'>{$item['name']}</td>
|
||||
<td>{$item['quantity']}</td>
|
||||
</tr>
|
||||
{{endforeach}}
|
||||
@@ -5756,7 +5788,7 @@
|
||||
<br>
|
||||
<div class='ipsGrid ipsGrid_collapsePhone'>
|
||||
<div class='ipsGrid_span6'>
|
||||
<a class="ipsButton ipsButton_important ipsButton_fullWidth ipsButton_medium" href="{$shipment->acpUrl()->setQueryString( array( 'do' => 'printout', 'print' => 'packing_sheet' ) )}" target='_blank'>{lang="print_packing_sheet"}</a>
|
||||
<a class="ipsButton ipsButton_important ipsButton_fullWidth ipsButton_medium" href="{$shipment->acpUrl()->setQueryString( array( 'do' => 'printout', 'print' => 'packing_sheet' ) )}" target='_blank' rel='noopener'>{lang="print_packing_sheet"}</a>
|
||||
</div>
|
||||
<div class='ipsGrid_span6'>
|
||||
<a class="ipsButton ipsButton_primary ipsButton_fullWidth ipsButton_medium" href="{$shipment->invoice->acpUrl()}">{lang="invoice_view"}</a>
|
||||
@@ -5782,7 +5814,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<a class="ipsButton ipsButton_primary ipsButton_fullWidth ipsButton_medium" href="{$shipment->acpUrl()->setQueryString( array( 'do' => 'printout', 'print' => 'label' ) )}" target='_blank'>{lang="print_label"}</a>
|
||||
<a class="ipsButton ipsButton_primary ipsButton_fullWidth ipsButton_medium" href="{$shipment->acpUrl()->setQueryString( array( 'do' => 'printout', 'print' => 'label' ) )}" target='_blank' rel='noopener'>{lang="print_label"}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>]]></template>
|
||||
@@ -5866,7 +5898,7 @@
|
||||
{{endforeach}}
|
||||
<hr class='ipsHr'>
|
||||
<div class='cNexusCart_totals ipsType_right'>
|
||||
{lang="subtotal"}: <span class='cNexusPrice'>{money="$subtotal"}</span>
|
||||
{lang="subtotal"}: <span class='cNexusPrice'>{money="$subtotal" currency="$currency"}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -6592,7 +6624,7 @@
|
||||
<h2 class='cNexusProduct_title ipsType_normal ipsType_unbold ipsType_reset ipsType_blendLinks'>
|
||||
<a href="{$package->url()}" data-role='productLink' class='{{if $carousel}}ipsTruncate ipsTruncate_line{{endif}}'>{$package->_title}</a>
|
||||
</h2>
|
||||
<p class='ipsType_reset'>
|
||||
<p class='ipsType_reset ipsTruncate ipsTruncate_line'>
|
||||
<span data-role="price">{$package->priceToDisplay()|raw}</span>
|
||||
</p>
|
||||
{{if $package->physical}}
|
||||
@@ -6722,7 +6754,7 @@
|
||||
<li>
|
||||
<div class="ipsTree_row ipsTree_noRoot">
|
||||
<div class="ipsTree_rowData ipsClearfix">
|
||||
<h4><a href="{url="app=nexus&module=store&controller=packages&subnode=1&do=form&id={$product->_id}"}" target="_blank">{$product->_title}</a></h4>
|
||||
<h4><a href="{url="app=nexus&module=store&controller=packages&subnode=1&do=form&id={$product->_id}"}" target="_blank" rel='noopener'>{$product->_title}</a></h4>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
@@ -6935,7 +6967,7 @@
|
||||
<template template_group="subscription" template_name="disabled" template_data="" template_location="admin" template_app="nexus"><![CDATA[<p class="ipsType_large">{lang="nexus_subs_off_text"}</p>
|
||||
<br>
|
||||
<a href="{url="app=nexus&module=subscriptions&controller=subscriptions&do=enable"}" class="ipsButton ipsButton_positive">{lang="enable"}</a>]]></template>
|
||||
<template template_group="subscription" template_name="packageLink" template_data="$package" template_location="admin" template_app="nexus"><![CDATA[<a href="{$package->url()}" target="_blank">{$package->_title}</a>]]></template>
|
||||
<template template_group="subscription" template_name="packageLink" template_data="$package" template_location="admin" template_app="nexus"><![CDATA[<a href="{$package->url()}" target="_blank" rel='noopener'>{$package->_title}</a>]]></template>
|
||||
<template template_group="subscription" template_name="profileSubscription" template_data="$member" template_location="front" template_app="nexus"><![CDATA[{{if $subscription = \IPS\nexus\Subscription::loadActiveByMember( $member )}}
|
||||
<div class='cProfileSidebarBlock ipsSpacer_bottom'>
|
||||
<a href='{url="app=nexus&module=subscriptions&controller=subscriptions" seoTemplate="nexus_subscriptions"}'>
|
||||
@@ -6959,7 +6991,11 @@
|
||||
<h2 class='ipsType_reset ipsType_large ipsType_blendLinks cSubscriptionsTitle'>
|
||||
{$package->_title}
|
||||
</h2>
|
||||
<div class='cNexusPrice ipsSpacer_both'>{$package->priceBlurb()}</div>
|
||||
<div class='cNexusPrice ipsSpacer_both'>{$package->priceBlurb()}
|
||||
{{if \IPS\Member::loggedIn()->language()->checkKeyExists('nexus_tax_explain_val')}}
|
||||
<span class='cNexusPrice_tax ipsType_light'>{lang="nexus_tax_explain_val"}</span>
|
||||
{{endif}}
|
||||
</div>
|
||||
<div class="cSubscription_desc ipsType_richText ipsType_medium ipsSpacer_both">{$package->description}</div>
|
||||
</div>
|
||||
<div class='cSubscriptionInfo'>
|
||||
@@ -7012,11 +7048,10 @@
|
||||
</div>
|
||||
</div>]]></template>
|
||||
<template template_group="subscription" template_name="rowHtml" template_data="$package, $price, $active, $inactive" template_location="admin" template_app="nexus"><![CDATA[<div class="ipsPos_right ipsTree_row_cells">
|
||||
<span class="ipsTree_row_cell ipsType_light"><a href="{url="app=nexus&module=subscriptions&controller=subscribers&advanced_search_submitted=1&nexus_sub_package_id={$package->id}&nexus_sub_active=1" csrf="true"}">{lang="nexus_sub_package_count_active" sprintf="$active"}</a></span>
|
||||
<span class="ipsTree_row_cell ipsType_light"><a href="{url="app=nexus&module=subscriptions&controller=subscribers&advanced_search_submitted=1&nexus_sub_package_id={$package->id}&nexus_sub_active=1" csrf="true"}">{lang="nexus_sub_package_count_inactive" sprintf="$inactive"}</a></span>
|
||||
<span class="ipsTree_row_cell ipsType_light"><a href="{url="app=nexus&module=subscriptions&controller=subscribers&advanced_search_submitted=1&nexus_sub_package_id={$package->id}&filter=nexus_subs_filter_active" csrf="true"}">{lang="nexus_sub_package_count_active" sprintf="$active"}</a></span>
|
||||
<span class="ipsTree_row_cell ipsType_light"><a href="{url="app=nexus&module=subscriptions&controller=subscribers&advanced_search_submitted=1&nexus_sub_package_id={$package->id}&filter=nexus_subs_filter_inactive" csrf="true"}">{lang="nexus_sub_package_count_inactive" sprintf="$inactive"}</a></span>
|
||||
<span class="ipsTree_row_cell ipsType_light">{$price}</span>
|
||||
</div>
|
||||
]]></template>
|
||||
</div>]]></template>
|
||||
<template template_group="subscription" template_name="rows" template_data="$table, $headers, $rows, $subscription" template_location="front" template_app="nexus"><![CDATA[{{if count( $rows )}}
|
||||
{{foreach $rows as $row}}
|
||||
<div class='cSubscriptionGrid {{if count( $rows ) == 1}}ipsGrid_span12{{elseif count( $rows ) == 2}}ipsGrid_span6{{else}}ipsGrid_span4{{endif}}'>
|
||||
@@ -7109,7 +7144,7 @@
|
||||
</ul>
|
||||
{{endforeach}}
|
||||
{{endif}}
|
||||
<div class="ipsGrid ipsPad ipsSpacer_bottom">
|
||||
<div class="ipsGrid ipsGrid_collapsePhone ipsPad ipsSpacer_bottom">
|
||||
{{foreach $elements as $tabName => $collection}}
|
||||
{{if $tabName != 'streams' and $tabName != 'title'}}
|
||||
<div class="ipsGrid_span4">
|
||||
@@ -7162,7 +7197,7 @@
|
||||
</div>
|
||||
</form>
|
||||
</div>]]></template>
|
||||
<template template_group="support" template_name="filterFormStream" template_data="$input, $options" template_location="admin" template_app="nexus"><![CDATA[<div class="ipsTabs ipsTabs_stretch ipsClearfix ipsJS_show acpFormTabBar cNexusStream_tabs" id='elSupportTabs'>
|
||||
<template template_group="support" template_name="filterFormStream" template_data="$input, $options" template_location="admin" template_app="nexus"><![CDATA[<div class="ipsTabs ipsTabs_stretch ipsClearfix ipsJS_show acpFormTabBar cNexusStream_tabs" id='elSupportTabs' data-ipsTabBar data-ipsTabBar-disableNav data-ipsTabBar-contentArea='#elRequestsTabContent'>
|
||||
<ul role="tablist">
|
||||
<a href="#elSupportTabs" data-action='expandTabs'><i class='fa fa-caret-down'></i></a>
|
||||
{{foreach $options as $stream}}
|
||||
@@ -7465,34 +7500,34 @@
|
||||
<div class='ipsAreaBackground_reset ipsPad'>
|
||||
<p class='cTimelineAction'>
|
||||
{{if $reply instanceof \IPS\nexus\Support\Reply}}
|
||||
{{try { $request = \IPS\nexus\Support\Request::loadAndCheckPerms( $reply->request ); } catch( \OutOfRangeException $e ) { $request = NULL; } }}
|
||||
<strong>{{if $reply->type == $reply::REPLY_HIDDEN}}{lang="request_added_note_u"}{{else}}{lang="request_replied_u"}{{endif}}</strong> {lang="support_history_to_req" sprintf="$reply->request"}
|
||||
{{try { $request = \IPS\nexus\Support\Request::loadAndCheckPerms( $reply->request ); } catch( \OutOfRangeException $e ) { $request = NULL; } }}
|
||||
<strong>{{if $reply->type == $reply::REPLY_HIDDEN}}{lang="request_added_note_u"}{{else}}{lang="request_replied_u"}{{endif}}</strong>
|
||||
{lang="support_history_to_req" sprintf="$reply->request"}
|
||||
{{else}}
|
||||
{{$request = $reply->request;}}
|
||||
{{if $reply->action === 'status'}}
|
||||
<strong>{lang="support_history_status_1"}</strong> {lang="support_history_status_2" sprintf="$reply->request->id"} {template="status" group="support" params="$reply->new"}
|
||||
{{elseif $reply->action === 'department'}}
|
||||
<strong>{lang="support_history_department_1"}</strong> {lang="support_history_department_2" sprintf="$reply->request->id, $reply->new ? $reply->new->_title : '?'"}
|
||||
{{elseif $reply->action === 'severity'}}
|
||||
<strong>{lang="support_history_severity_1"}</strong> {lang="support_history_severity_2" sprintf="$reply->request->id, $reply->new ? $reply->new->_title : '?'"}
|
||||
{{elseif $reply->action === 'purchase'}}
|
||||
{{if $reply->new}}
|
||||
{{$link = "<a href='{$reply->new->acpUrl()}'>{$reply->new->name}</a>";}}
|
||||
<strong>{lang="support_history_purchase_1"}</strong> {lang="support_history_purchase_2" sprintf="$reply->request->id" htmlsprintf="$link"}
|
||||
{{else}}
|
||||
<strong>{lang="support_history_no_purchase_1"}</strong> {lang="support_history_no_purchase_2" sprintf="$reply->request->id"}
|
||||
{{endif}}
|
||||
{{elseif $reply->action === 'staff'}}
|
||||
{{if $reply->new}}
|
||||
<strong>{lang="support_history_assigned_1"}</strong> {lang="support_history_assigned_2" sprintf="$reply->request->id, $reply->new->name"}
|
||||
{{else}}
|
||||
<strong>{lang="support_history_unassigned_1"}</strong> {lang="support_history_unassigned_2" sprintf="$reply->request->id"}
|
||||
{{endif}}
|
||||
{{elseif $reply->action === 'split_away'}}
|
||||
<strong>{lang="support_history_split_away_1"}</strong> {lang="support_history_split_away_2" sprintf="$reply->request->id"}
|
||||
{{elseif $reply->action === 'split_new'}}
|
||||
<strong>{lang="support_history_split_new_1"}</strong> {lang="support_history_split_new_2" sprintf="$reply->request->id"}
|
||||
{{endif}}
|
||||
{{$request = $reply->request;}}
|
||||
{{if $reply->action === 'status'}}
|
||||
<strong>{lang="support_history_status_1"}</strong> {lang="support_history_status_2" sprintf="$reply->request->id"} {template="status" group="support" params="$reply->new"}
|
||||
{{elseif $reply->action === 'department'}}
|
||||
<strong>{lang="support_history_department_1"}</strong> {lang="support_history_department_2" sprintf="$reply->request->id, $reply->new ? $reply->new->_title : '?'"}
|
||||
{{elseif $reply->action === 'severity'}}
|
||||
<strong>{lang="support_history_severity_1"}</strong> {lang="support_history_severity_2" sprintf="$reply->request->id, $reply->new ? $reply->new->_title : '?'"}
|
||||
{{elseif $reply->action === 'purchase'}}
|
||||
{{if $reply->new}}
|
||||
<strong>{lang="support_history_purchase_1"}</strong> {lang="support_history_purchase_2" sprintf="$reply->request->id, $reply->new->acpUrl(), $reply->new->name"}
|
||||
{{else}}
|
||||
<strong>{lang="support_history_no_purchase_1"}</strong> {lang="support_history_no_purchase_2" sprintf="$reply->request->id"}
|
||||
{{endif}}
|
||||
{{elseif $reply->action === 'staff'}}
|
||||
{{if $reply->new}}
|
||||
<strong>{lang="support_history_assigned_1"}</strong> {lang="support_history_assigned_2" sprintf="$reply->request->id, $reply->new->name"}
|
||||
{{else}}
|
||||
<strong>{lang="support_history_unassigned_1"}</strong> {lang="support_history_unassigned_2" sprintf="$reply->request->id"}
|
||||
{{endif}}
|
||||
{{elseif $reply->action === 'split_away'}}
|
||||
<strong>{lang="support_history_split_away_1"}</strong> {lang="support_history_split_away_2" sprintf="$reply->request->id"}
|
||||
{{elseif $reply->action === 'split_new'}}
|
||||
<strong>{lang="support_history_split_new_1"}</strong> {lang="support_history_split_new_2" sprintf="$reply->request->id"}
|
||||
{{endif}}
|
||||
{{endif}}
|
||||
</p>
|
||||
{{if $request}}
|
||||
@@ -8022,8 +8057,7 @@
|
||||
<i class='fa fa-exclamation'></i> {lang="reply_action_severity" sprintf="$comment->member->name, $comment->new ? $comment->new->_title : '?'"}
|
||||
{{elseif $comment->action === 'purchase'}}
|
||||
{{if $comment->new}}
|
||||
{{$link = "<a href='{$comment->new->acpUrl()}'>{$comment->new->name}</a>";}}
|
||||
<i class='fa fa-cube'></i> {lang="reply_action_associate" sprintf="$comment->member->name" htmlsprintf="$link"}
|
||||
<i class='fa fa-cube'></i> {lang="reply_action_associate" sprintf="$comment->member->name, $comment->new->acpUrl(), $comment->new->name"}
|
||||
{{else}}
|
||||
<i class='fa fa-minus-circle'></i> {lang="reply_action_unassociate" sprintf="$comment->member->name"}
|
||||
{{endif}}
|
||||
@@ -8151,7 +8185,7 @@
|
||||
<hr class='ipsHr'>
|
||||
<p class='ipsType_reset ipsType_medium'>
|
||||
{{if $noteCount = $request->supportAuthor()->noteCount()}}
|
||||
<strong><a href='{url="app=core&module=members&controller=members&do=editBlock&block=IPS\\nexus\\extensions\\core\\MemberACPProfileBlocks\\Notes&id={$request->member}&support={$request->id}"}' data-ipsDialog data-ipsDialog-title="{lang="customer_notes"}">{lang="num_customer_notes" pluralize="$noteCount"}</a></strong>
|
||||
<strong><a href='{url="app=core&module=members&controller=members&do=lazyBlock&block=IPS\\nexus\\extensions\\core\\MemberACPProfileBlocks\\Notes&id={$request->member}&support={$request->id}"}' data-ipsDialog data-ipsDialog-title="{lang="customer_notes"}">{lang="num_customer_notes" pluralize="$noteCount"}</a></strong>
|
||||
{{else}}
|
||||
{lang="num_customer_notes" pluralize="0"}
|
||||
{{endif}}
|
||||
@@ -8163,7 +8197,7 @@
|
||||
|
||||
{{if ( $request->member && \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_login' ) AND !\IPS\Member::load( $request->member )->isBanned() )}}
|
||||
<p class='ipsType_reset ipsType_medium'>
|
||||
<a href='{url="app=core&module=members&controller=members&do=login&id={$request->member}"}' target='_blank'>{lang="sign_in_as_customer"}</a>
|
||||
<a href='{url="app=core&module=members&controller=members&do=login&id={$request->member}"}' target='_blank' rel='noopener'>{lang="sign_in_as_customer"}</a>
|
||||
</p>
|
||||
{{endif}}
|
||||
</div>
|
||||
@@ -8600,7 +8634,7 @@
|
||||
<li><i class="fa fa-exclamation"></i> {$request->severity->_title}</li>
|
||||
{{endif}}
|
||||
<li><i class="fa fa-folder"></i> {$request->department->_title}</li>
|
||||
<li><i class="fa fa-user"></i> {{if $staff = $request->staf}}{$staff->name}{{else}}{lang="unassigned"}{{endif}}</li>
|
||||
<li><i class="fa fa-user"></i> {{if $staff = $request->staff}}{$staff->name}{{else}}{lang="unassigned"}{{endif}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<br>
|
||||
@@ -8621,7 +8655,7 @@
|
||||
<div class="ipsJS_show" data-role="filterForm">
|
||||
{$form|raw}
|
||||
</div>
|
||||
<div data-role='mainTable' class='ipsPad'>
|
||||
<div data-role='mainTable' class='ipsPad' id='elRequestsTabContent'>
|
||||
{{if $stream->temporary}}
|
||||
<a class='ipsResponsive_showPhone ipsResponsive_block ipsButton ipsButton_veryVerySmall ipsButton_light ipsSpacer_half ipsButton_fullWidth ipsSpacer_bottom' href="{url="app=nexus&module=support&controller=requests&do=saveStream&id={$stream->id}"}" data-ipsMenu id="elSaveStream">{lang="save_this_stream"}</a>
|
||||
{{elseif is_int( $stream->id )}}
|
||||
@@ -9219,15 +9253,7 @@
|
||||
<div class='cTransaction_info ipsType_normal'>
|
||||
<h3 class="ipsType_sectionHead">
|
||||
<strong>
|
||||
{{if $transaction->method === 0}}
|
||||
{{if $transaction->gw_id}}
|
||||
{lang="tstatus_okay_set"}
|
||||
{{else}}
|
||||
{lang="tstatus_okay_credit"}
|
||||
{{endif}}
|
||||
{{else}}
|
||||
{lang="tstatus_okay_set"}
|
||||
{{endif}}
|
||||
{lang="tstatus_okay_set"}
|
||||
</strong>
|
||||
</h3>
|
||||
|
||||
@@ -9253,25 +9279,35 @@
|
||||
<template template_group="transactions" template_name="prfd" template_data="$transaction, $log" template_location="admin" template_app="nexus"><![CDATA[
|
||||
<li class='ipsClearfix cTransaction_intermediate'>
|
||||
<div class='cTransaction_icon ipsPos_left'>
|
||||
<i class='fa fa-undo'></i>
|
||||
{{if $log['to'] === 'credit'}}
|
||||
<i class='fa fa-reply'></i>
|
||||
{{else}}
|
||||
<i class='fa fa-reply-all'></i>
|
||||
{{endif}}
|
||||
</div>
|
||||
<div class='cTransaction_info ipsType_normal'>
|
||||
<h3 class="ipsType_sectionHead">
|
||||
<strong>
|
||||
{lang="tstatus_prfd_set"}
|
||||
{{if $log['to'] === 'credit'}}
|
||||
{lang="tstatus_credited"}
|
||||
{{else}}
|
||||
{lang="tstatus_prfd_set"}
|
||||
{{endif}}
|
||||
</strong>
|
||||
</h3>
|
||||
<br>
|
||||
<p class='ipsType_reset ipsType_large'>
|
||||
<span class='cNexusPrice'>{money="$log['amount']" currency="$transaction->currency"}</span>
|
||||
</p>
|
||||
|
||||
{{if isset( $log['amount'] )}}
|
||||
{{if $transaction->amount->amount->compare( new \IPS\Math\Number( $log['amount'] ) ) !== 0}}
|
||||
<p class='ipsType_reset ipsType_large'>
|
||||
<span class='cNexusPrice'>{money="$log['amount']" currency="$transaction->currency"}</span>
|
||||
</p>
|
||||
{{endif}}
|
||||
{{endif}}
|
||||
|
||||
{{if isset( $log['to'] )}}
|
||||
{{if isset( $log['ref'] ) and $log['ref']}}
|
||||
<p class='ipsType_reset ipsType_normal'>
|
||||
{lang="transaction_refund_method"} {{if $log['to'] === 'gateway'}}{$transaction->method->_title}{{else}}{lang="refund_method_credit"}{{endif}}
|
||||
{{if isset( $log['ref'] ) and $log['ref']}}
|
||||
<br>{$log['ref']}
|
||||
{{endif}}
|
||||
{$log['ref']}
|
||||
</p>
|
||||
{{endif}}
|
||||
{{if isset( $log['on'] ) and $log['on']}}
|
||||
@@ -9307,22 +9343,23 @@
|
||||
<template template_group="transactions" template_name="rfnd" template_data="$transaction, $log" template_location="admin" template_app="nexus"><![CDATA[
|
||||
<li class='ipsClearfix cTransaction_negative'>
|
||||
<div class='cTransaction_icon ipsPos_left'>
|
||||
<i class='fa fa-undo'></i>
|
||||
<i class='fa fa-reply-all'></i>
|
||||
</div>
|
||||
<div class='cTransaction_info ipsType_normal'>
|
||||
<h3 class="ipsType_sectionHead">
|
||||
<strong>
|
||||
{lang="tstatus_rfnd_set"}
|
||||
{{if $log['to'] === 'credit'}}
|
||||
{lang="tstatus_credited"}
|
||||
{{else}}
|
||||
{lang="tstatus_rfnd_set"}
|
||||
{{endif}}
|
||||
</strong>
|
||||
</h3>
|
||||
<br>
|
||||
|
||||
{{if isset( $log['to'] )}}
|
||||
{{if isset( $log['ref'] ) and $log['ref']}}
|
||||
<p class='ipsType_reset ipsType_medium'>
|
||||
{lang="transaction_refund_method"} {{if $log['to'] === 'gateway'}}{$transaction->method->_title}{{else}}{lang="refund_method_credit"}{{endif}}
|
||||
{{if isset( $log['ref'] ) and $log['ref']}}
|
||||
<br>{$log['ref']}
|
||||
{{endif}}
|
||||
{$log['ref']}
|
||||
</p>
|
||||
{{endif}}
|
||||
{{if isset( $log['on'] ) and $log['on']}}
|
||||
@@ -9336,7 +9373,7 @@
|
||||
{{endif}}
|
||||
</div>
|
||||
</li>]]></template>
|
||||
<template template_group="transactions" template_name="status" template_data="$status" template_location="admin" template_app="nexus"><![CDATA[<span class="ipsBadge ipsBadge_style{{if $status == \IPS\nexus\Transaction::STATUS_PAID or $status == \IPS\nexus\Transaction::STATUS_PART_REFUNDED}}4{{elseif $status == \IPS\nexus\Transaction::STATUS_HELD}}1{{elseif $status == \IPS\nexus\Transaction::STATUS_REVIEW or $status == \IPS\nexus\Transaction::STATUS_DISPUTED}}7{{elseif $status == \IPS\nexus\Transaction::STATUS_REFUSED}}5{{elseif $status == \IPS\nexus\Transaction::STATUS_REFUNDED}}2{{else}}6{{endif}}">
|
||||
<template template_group="transactions" template_name="status" template_data="$status" template_location="admin" template_app="nexus"><![CDATA[<span class="ipsBadge ipsBadge_style{{if $status == \IPS\nexus\Transaction::STATUS_PAID}}4{{elseif $status == \IPS\nexus\Transaction::STATUS_HELD}}1{{elseif $status == \IPS\nexus\Transaction::STATUS_REVIEW or $status == \IPS\nexus\Transaction::STATUS_DISPUTED}}7{{elseif $status == \IPS\nexus\Transaction::STATUS_REFUSED}}5{{elseif $status == \IPS\nexus\Transaction::STATUS_REFUNDED or $status == \IPS\nexus\Transaction::STATUS_PART_REFUNDED}}2{{else}}6{{endif}}">
|
||||
{lang="tstatus_{$status}"}
|
||||
</span>]]></template>
|
||||
<template template_group="transactions" template_name="stripeData" template_data="$response=NULL, $error=NULL" template_location="admin" template_app="nexus"><![CDATA[{{if isset( $response['outcome'] )}}
|
||||
@@ -9360,17 +9397,17 @@
|
||||
|
||||
{{endif}}
|
||||
{{if $response['source']['card']['brand'] == 'Visa'}}
|
||||
<i class="fa fa-cc-visa"></i>
|
||||
<i class="fa fa-cc-visa" data-ipsTooltip title="{lang="card_type_visa"}"></i>
|
||||
{{elseif $response['source']['card']['brand'] == 'MasterCard'}}
|
||||
<i class="fa fa-cc-mastercard"></i>
|
||||
<i class="fa fa-cc-mastercard" data-ipsTooltip title="{lang="card_type_mastercard"}"></i>
|
||||
{{elseif $response['source']['card']['brand'] == 'Discover'}}
|
||||
<i class="fa fa-cc-discover"></i>
|
||||
<i class="fa fa-cc-discover" data-ipsTooltip title="{lang="card_type_discover"}"></i>
|
||||
{{elseif $response['source']['card']['brand'] == 'American Express'}}
|
||||
<i class="fa fa-cc-amex"></i>
|
||||
<i class="fa fa-cc-amex" data-ipsTooltip title="{lang="card_type_american_express"}"></i>
|
||||
{{elseif $response['source']['card']['brand'] == 'Diners Club'}}
|
||||
<i class="fa fa-cc-diners-club"></i>
|
||||
<i class="fa fa-cc-diners-club" data-ipsTooltip title="{lang="card_type_diners_club"}"></i>
|
||||
{{elseif $response['source']['card']['brand'] == 'JCB'}}
|
||||
<i class="fa fa-cc-jcb"></i>
|
||||
<i class="fa fa-cc-jcb" data-ipsTooltip title="{lang="card_type_jcb"}"></i>
|
||||
{{else}}
|
||||
<i class="fa fa-credit-card"></i>
|
||||
{{endif}}
|
||||
@@ -9513,6 +9550,38 @@
|
||||
{{endif}}
|
||||
|
||||
</div>
|
||||
</li>]]></template>
|
||||
<template template_group="transactions" template_name="undo_credit" template_data="$transaction, $log" template_location="admin" template_app="nexus"><![CDATA[
|
||||
<li class='ipsClearfix cTransaction_intermediate'>
|
||||
<div class='cTransaction_icon ipsPos_left'>
|
||||
<i class='fa fa-forward'></i>
|
||||
</div>
|
||||
<div class='cTransaction_info ipsType_normal'>
|
||||
<h3 class="ipsType_sectionHead">
|
||||
<strong>
|
||||
{lang="tstatus_credited_undo"}
|
||||
</strong>
|
||||
</h3>
|
||||
<br>
|
||||
|
||||
{{if isset( $log['amount'] )}}
|
||||
{{if $transaction->amount->amount->compare( new \IPS\Math\Number( $log['amount'] ) ) !== 0}}
|
||||
<p class='ipsType_reset ipsType_large'>
|
||||
<span class='cNexusPrice'>{money="$log['amount']" currency="$transaction->currency"}</span>
|
||||
</p>
|
||||
{{endif}}
|
||||
{{endif}}
|
||||
|
||||
{{if isset( $log['on'] ) and $log['on']}}
|
||||
{expression="\IPS\DateTime::ts( $log['on'] )"}
|
||||
{{if isset( $log['by'] ) and $log['by']}}
|
||||
<br>
|
||||
<span class='ipsType_medium ipsType_light'>
|
||||
{lang="byline_nodate" sprintf="\IPS\Member::load( $log['by'] )->name"}
|
||||
</span>
|
||||
{{endif}}
|
||||
{{endif}}
|
||||
</div>
|
||||
</li>]]></template>
|
||||
<template template_group="transactions" template_name="view" template_data="$transaction" template_location="admin" template_app="nexus"><![CDATA[
|
||||
<div class='ipsColumns ipsColumns_collapsePhone'>
|
||||
@@ -9521,10 +9590,18 @@
|
||||
<h2 class='ipsType_minorHeading'>{lang="transaction_total"}</h2>
|
||||
<span class="ipsType_veryLarge">{$transaction->amount}</span>
|
||||
{{if $transaction->status === $transaction::STATUS_PART_REFUNDED}}
|
||||
<div class="ipsSpacer_top">
|
||||
<h2 class='ipsType_minorHeading'>{lang="amount_refunded"}</h2>
|
||||
<span class="ipsType_large">{$transaction->partial_refund}</span>
|
||||
</div>
|
||||
{{if $transaction->partial_refund->amount->isGreaterThanZero()}}
|
||||
<div class="ipsSpacer_top">
|
||||
<h2 class='ipsType_minorHeading'>{lang="amount_refunded"}</h2>
|
||||
<span class="ipsType_large">{$transaction->partial_refund}</span>
|
||||
</div>
|
||||
{{endif}}
|
||||
{{if $transaction->credit->amount->isGreaterThanZero()}}
|
||||
<div class="ipsSpacer_top">
|
||||
<h2 class='ipsType_minorHeading'>{lang="amount_credited"}</h2>
|
||||
<span class="ipsType_large">{$transaction->credit}</span>
|
||||
</div>
|
||||
{{endif}}
|
||||
{{endif}}
|
||||
<hr class='ipsHr'>
|
||||
|
||||
@@ -9896,7 +9973,7 @@
|
||||
{{if !$transaction->fraud->minfraud_version or version_compare( $transaction->fraud->minfraud_version, '1.3' ) === -1}}
|
||||
<br>
|
||||
<span class="ipsType_warning">
|
||||
<a href='{url="maxmind_version" ips="true"}' class="ipsType_blendLinks" target='_blank'>{lang="maxmind_upgrade_version"}</a>
|
||||
<a href='{url="maxmind_version" ips="true"}' class="ipsType_blendLinks" target='_blank' rel='noopener'>{lang="maxmind_upgrade_version"}</a>
|
||||
</span>
|
||||
{{endif}}
|
||||
</p>
|
||||
@@ -9910,49 +9987,47 @@
|
||||
<div class="ipsBox">
|
||||
<div class='ipsPad'>
|
||||
<ul class='ipsList_reset cTransaction ipsClearfix'>
|
||||
{{if $transaction->method or $transaction->gw_id}}
|
||||
<li class='ipsClearfix'>
|
||||
<div class='cTransaction_icon ipsPos_left'>
|
||||
<i class='fa fa-shopping-cart'></i>
|
||||
</div>
|
||||
<div class='cTransaction_info ipsType_normal'>
|
||||
<h2 class='ipsType_sectionHead'>
|
||||
<strong>
|
||||
{{if $transaction->method}}
|
||||
{{if in_array( $transaction->status, array( \IPS\nexus\Transaction::STATUS_PENDING, \IPS\nexus\Transaction::STATUS_WAITING ) )}}
|
||||
{lang="transaction_method_pending" sprintf="$transaction->method->_title"}
|
||||
{{else}}
|
||||
{lang="transaction_method" sprintf="$transaction->method->_title"}
|
||||
{{endif}}
|
||||
<li class='ipsClearfix'>
|
||||
<div class='cTransaction_icon ipsPos_left'>
|
||||
<i class='fa fa-shopping-cart'></i>
|
||||
</div>
|
||||
<div class='cTransaction_info ipsType_normal'>
|
||||
<h2 class='ipsType_sectionHead'>
|
||||
<strong>
|
||||
{{if $transaction->method}}
|
||||
{{if in_array( $transaction->status, array( \IPS\nexus\Transaction::STATUS_PENDING, \IPS\nexus\Transaction::STATUS_WAITING ) )}}
|
||||
{lang="transaction_method_pending" sprintf="$transaction->method->_title"}
|
||||
{{else}}
|
||||
{lang="payment_received"}
|
||||
{lang="transaction_method" sprintf="$transaction->method->_title"}
|
||||
{{endif}}
|
||||
</strong>
|
||||
</h2>
|
||||
<p class='ipsType_reset'>
|
||||
{$transaction->date}
|
||||
{{else}}
|
||||
{lang="tstatus_okay_credit"}
|
||||
{{endif}}
|
||||
</strong>
|
||||
</h2>
|
||||
<p class='ipsType_reset'>
|
||||
{$transaction->date}
|
||||
</p>
|
||||
{{if $transaction->gw_id}}
|
||||
<p class='ipsType_normal ipsType_reset'>
|
||||
{lang="payment_reference"}: {{if $url = $transaction->method->gatewayUrl( $transaction )}}<a href="{$url->makeSafeForAcp()}" target="_blank" rel='noopener'>{$transaction->gw_id}</a>{{else}}{$transaction->gw_id}{{endif}}<br>
|
||||
</p>
|
||||
{{if $transaction->gw_id}}
|
||||
<p class='ipsType_normal ipsType_reset'>
|
||||
{lang="payment_reference"}: {{if $url = $transaction->method->gatewayUrl( $transaction )}}<a href="{$url->makeSafeForAcp()}" target="_blank">{$transaction->gw_id}</a>{{else}}{$transaction->gw_id}{{endif}}<br>
|
||||
</p>
|
||||
{{endif}}
|
||||
{{if $extraData = $transaction->method->extraData( $transaction )}}
|
||||
{$extraData|raw}
|
||||
{{endif}}
|
||||
{{if $transaction->billing_agreement}}
|
||||
<p class='ipsType_normal ipsType_reset'>
|
||||
<a href="{$transaction->billing_agreement->acpUrl()}" class="ipsType_blendLinks">{lang="billing_agreement" sprintf="$transaction->billing_agreement->gw_id"}</a><br>
|
||||
</p>
|
||||
{{endif}}
|
||||
{{if $transaction->ip}}
|
||||
<span class='ipsType_medium ipsType_light'>
|
||||
<a class="ipsType_blendLinks" href="{url="app=core&module=members&controller=ip&ip={$transaction->ip}"}">{lang="transaction_ip" sprintf="$transaction->ip"}</a>
|
||||
</span>
|
||||
{{endif}}
|
||||
</div>
|
||||
</li>
|
||||
{{endif}}
|
||||
{{endif}}
|
||||
{{if $transaction->method and $extraData = $transaction->method->extraData( $transaction )}}
|
||||
{$extraData|raw}
|
||||
{{endif}}
|
||||
{{if $transaction->billing_agreement}}
|
||||
<p class='ipsType_normal ipsType_reset'>
|
||||
<a href="{$transaction->billing_agreement->acpUrl()}" class="ipsType_blendLinks">{lang="billing_agreement" sprintf="$transaction->billing_agreement->gw_id"}</a><br>
|
||||
</p>
|
||||
{{endif}}
|
||||
{{if $transaction->ip}}
|
||||
<span class='ipsType_medium ipsType_light'>
|
||||
<a class="ipsType_blendLinks" href="{url="app=core&module=members&controller=ip&ip={$transaction->ip}"}">{lang="transaction_ip" sprintf="$transaction->ip"}</a>
|
||||
</span>
|
||||
{{endif}}
|
||||
</div>
|
||||
</li>
|
||||
|
||||
{{if $transaction->fraud_blocked}}
|
||||
<li class='ipsClearfix'>
|
||||
@@ -9991,8 +10066,9 @@
|
||||
{lang="transaction_customer_since" sprintf="$transaction->member->joined->localeDate()"}<br>
|
||||
{lang="transaction_spent" sprintf="$transaction->member->totalSpent()"}
|
||||
</p>
|
||||
|
||||
{{if member.hasAcpRestriction( 'nexus', 'customers', 'customers_void' )}}
|
||||
<a href="{url="{$transaction->member->acpUrl()->setQueryString( array( 'do' => 'void', 'rt' => $transaction->id ) )}"}" class="ipsButton ipsButton_light ipsButton_verySmall ipsSpacer_top" data-ipsDialog data-ipsDialog-title="{lang="void_account"}">{lang="void_account"}</a>
|
||||
<a href="{url="app=nexus&module=customers&controller=view&do=void&id={$transaction->member->member_id}&rt={$transaction->id}"}" class="ipsButton ipsButton_light ipsButton_verySmall ipsSpacer_top" data-ipsDialog data-ipsDialog-title="{lang="void_account"}">{lang="void_account"}</a>
|
||||
{{endif}}
|
||||
</div>
|
||||
</div>
|
||||
@@ -10176,12 +10252,12 @@
|
||||
<div class="cDonateProgressBar_progress" style="width:{expression="number_format( 100/$goal->goal*$goal->current, 2, '.', '')"}%"></div>
|
||||
</div>
|
||||
<span class="ipsType_light ipsType_small">
|
||||
{lang="donate_progress" htmlsprintf="new \IPS\nexus\Money( $goal->current, $goal->currency ), new \IPS\nexus\Money( $goal->goal, $goal->currency )"}
|
||||
{lang="donate_progress" sprintf="new \IPS\nexus\Money( $goal->current, $goal->currency ), new \IPS\nexus\Money( $goal->goal, $goal->currency )"}
|
||||
</span>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="ipsType_light ipsType_small">
|
||||
{lang="donate_sofar" htmlsprintf="new \IPS\nexus\Money( $goal->current, $goal->currency )"}
|
||||
{lang="donate_sofar" sprintf="new \IPS\nexus\Money( $goal->current, $goal->currency )"}
|
||||
</div>
|
||||
{{endif}}
|
||||
</div>
|
||||
@@ -10227,7 +10303,7 @@
|
||||
{lang="pending_widthdrawals"}
|
||||
</div>
|
||||
</a>
|
||||
</dli>
|
||||
</li>
|
||||
{{endif}}
|
||||
{{if $openSupportRequests !== NULL}}
|
||||
<li class="ipsDataItem">
|
||||
@@ -10275,7 +10351,10 @@
|
||||
<div class='ipsDataItem_main'>
|
||||
<div class='cWidgetSubscription ipsPad_half'>
|
||||
<div class="cWidgetSubscription_bg" style='background-image: url( "{expression="str_replace( array( '(', ')' ), array( '\(', '\)' ), $package->_image->url )"}" )'></div>
|
||||
<span class='cWidgetSubscription_text'>{lang="nexus_subs_widget_title_and_price" sprintf="$package->_title, $package->priceBlurb()"}</span>
|
||||
<span class='cWidgetSubscription_text'>
|
||||
{lang="nexus_subs_widget_title_and_price" sprintf="$package->_title, $package->priceBlurb()"}
|
||||
{{if \IPS\Member::loggedIn()->language()->checkKeyExists('nexus_tax_explain_val')}}<span class='cNexusPrice_tax ipsType_light'>{lang="nexus_tax_explain_val"}</span>{{endif}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
@@ -272,9 +272,43 @@
|
||||
"102046": "4.2.7",
|
||||
"102047": "4.2.8",
|
||||
"102048": "4.2.8",
|
||||
"102049": "4.2.9",
|
||||
"103000": "4.3.0 Beta 1",
|
||||
"103002": "4.3.0 Beta 2",
|
||||
"103003": "4.3.0 Beta 3",
|
||||
"103004": "4.3.0 Beta 4",
|
||||
"103005": "4.3.0"
|
||||
"103005": "4.3.0",
|
||||
"103006": "4.3.1",
|
||||
"103007": "4.3.1",
|
||||
"103008": "4.3.1",
|
||||
"103009": "4.3.2",
|
||||
"103010": "4.3.2",
|
||||
"103011": "4.3.3",
|
||||
"103012": "4.3.3",
|
||||
"103013": "4.3.3",
|
||||
"103014": "4.3.3",
|
||||
"103015": "4.3.3",
|
||||
"103016": "4.3.3",
|
||||
"103017": "4.3.3",
|
||||
"103018": "4.3.3",
|
||||
"103019": "4.3.3",
|
||||
"103020": "4.3.3",
|
||||
"103021": "4.3.4",
|
||||
"103022": "4.3.4",
|
||||
"103023": "4.3.4",
|
||||
"103024": "4.3.4",
|
||||
"103025": "4.3.4",
|
||||
"103026": "4.3.5 Beta 1",
|
||||
"103027": "4.3.5 Beta 2",
|
||||
"103028": "4.3.5",
|
||||
"103029": "4.3.5",
|
||||
"103030": "4.3.5",
|
||||
"103031": "4.3.5",
|
||||
"103032": "4.3.5",
|
||||
"103033": "4.3.6 Beta 1",
|
||||
"103034": "4.3.6 Beta 2",
|
||||
"103035": "4.3.6",
|
||||
"103036": "4.3.6",
|
||||
"103037": "4.3.6",
|
||||
"103038": "4.3.6"
|
||||
}
|
||||
@@ -51,7 +51,7 @@ class _Income
|
||||
$thirtyDaysAgo = \IPS\DateTime::create()->sub( new \DateInterval('P30D') );
|
||||
|
||||
$results = array();
|
||||
foreach( \IPS\Db::i()->select( "t_currency, DATE_FORMAT( FROM_UNIXTIME( t_date ), '%e %c %Y' ) AS date, SUM(t_amount)-SUM(t_partial_refund) AS amount", 'nexus_transactions', array( 't_date>? AND (t_status=? OR t_status=?)', $thirtyDaysAgo->getTimestamp(), \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED ), NULL, NULL, array( 't_currency', 'date' ) ) as $result )
|
||||
foreach( \IPS\Db::i()->select( "t_currency, DATE_FORMAT( FROM_UNIXTIME( t_date ), '%e %c %Y' ) AS date, SUM(t_amount)-SUM(t_partial_refund) AS amount", 'nexus_transactions', array( 't_date>? AND (t_status=? OR t_status=?) AND t_method>0', $thirtyDaysAgo->getTimestamp(), \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED ), NULL, NULL, array( 't_currency', 'date' ) ) as $result )
|
||||
{
|
||||
$results[ $result['date'] ][ $result['t_currency'] ] = $result['amount'];
|
||||
}
|
||||
|
||||
@@ -58,9 +58,10 @@ class _Admin
|
||||
* @param int|null $id2 Secondary ID
|
||||
* @param string|null $id3 Arbitrary data
|
||||
* @param array $attachment The attachment data
|
||||
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
|
||||
* @return bool
|
||||
*/
|
||||
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment )
|
||||
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -54,14 +54,15 @@ class _Customer
|
||||
/**
|
||||
* Permission check for attachments
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param int|null $id1 Primary ID
|
||||
* @param int|null $id2 Secondary ID
|
||||
* @param string|null $id3 Arbitrary data
|
||||
* @param \IPS\Member $member The member
|
||||
* @param int|null $id1 Primary ID
|
||||
* @param int|null $id2 Secondary ID
|
||||
* @param string|null $id3 Arbitrary data
|
||||
* @param array $attachment The attachment data
|
||||
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
|
||||
* @return bool
|
||||
*/
|
||||
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment )
|
||||
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
|
||||
{
|
||||
if ( ( $id3 !== 'note' and $member->member_id == $id1 ) or $member->hasAcpRestriction( 'nexus', 'customers', 'customers_view' ) )
|
||||
{
|
||||
|
||||
@@ -49,14 +49,15 @@ class _Purchases
|
||||
/**
|
||||
* Permission check for attachments
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param int|null $id1 Primary ID
|
||||
* @param int|null $id2 Secondary ID
|
||||
* @param string|null $id3 Arbitrary data
|
||||
* @param \IPS\Member $member The member
|
||||
* @param int|null $id1 Primary ID
|
||||
* @param int|null $id2 Secondary ID
|
||||
* @param string|null $id3 Arbitrary data
|
||||
* @param array $attachment The attachment data
|
||||
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
|
||||
* @return bool
|
||||
*/
|
||||
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment )
|
||||
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -49,14 +49,15 @@ class _Store
|
||||
/**
|
||||
* Permission check for attachments
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param int|null $id1 Primary ID
|
||||
* @param int|null $id2 Secondary ID
|
||||
* @param string|null $id3 Arbitrary data
|
||||
* @param \IPS\Member $member The member
|
||||
* @param int|null $id1 Primary ID
|
||||
* @param int|null $id2 Secondary ID
|
||||
* @param string|null $id3 Arbitrary data
|
||||
* @param array $attachment The attachment data
|
||||
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
|
||||
* @return bool
|
||||
*/
|
||||
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment )
|
||||
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -34,6 +34,16 @@ class _Support
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only allow local embeds?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function embedLocalOnly()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can we use attachments in this editor?
|
||||
*
|
||||
@@ -59,14 +69,15 @@ class _Support
|
||||
/**
|
||||
* Permission check for attachments
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param int|null $id1 Primary ID
|
||||
* @param int|null $id2 Secondary ID
|
||||
* @param string|null $id3 Arbitrary data
|
||||
* @param \IPS\Member $member The member
|
||||
* @param int|null $id1 Primary ID
|
||||
* @param int|null $id2 Secondary ID
|
||||
* @param string|null $id3 Arbitrary data
|
||||
* @param array $attachment The attachment data
|
||||
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
|
||||
* @return bool
|
||||
*/
|
||||
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment )
|
||||
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -208,6 +208,16 @@ class _Support
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
}
|
||||
|
||||
foreach ( $email->cc as $to )
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\nexus\Support\Department::load( $to, 'dpt_email' );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -336,6 +346,32 @@ class _Support
|
||||
$request->title = $email->subject;
|
||||
$request->member = (int) $member->member_id;
|
||||
$request->email = $email->from;
|
||||
|
||||
/* Figure out who to notify for replies */
|
||||
$notify = array();
|
||||
foreach( $email->to as $to )
|
||||
{
|
||||
if ( $to !== $department->email )
|
||||
{
|
||||
$notify[] = array( 'type' => 'e', 'value' => $to );
|
||||
}
|
||||
}
|
||||
foreach( $email->cc as $cc )
|
||||
{
|
||||
if ( $cc !== $department->email )
|
||||
{
|
||||
$notify[] = array( 'type' => 'e', 'value' => $cc );
|
||||
}
|
||||
}
|
||||
foreach( ( $email->bcc ?: array() ) as $cc )
|
||||
{
|
||||
if ( $cc !== $department->email )
|
||||
{
|
||||
$notify[] = array( 'type' => 'e', 'value' => $cc, 'bcc' => 1 );
|
||||
}
|
||||
}
|
||||
|
||||
$request->notify = $notify;
|
||||
$request->save();
|
||||
|
||||
/* Create the reply */
|
||||
@@ -356,7 +392,7 @@ class _Support
|
||||
$fromName = \IPS\Settings::i()->nexus_sout_from;
|
||||
break;
|
||||
}
|
||||
$confirmationEmail->send( $member->member_id ? $member : $email->from, array(), array(), $request->department->email, $fromName );
|
||||
$confirmationEmail->send( $member->member_id ? $member : $email->from, array(), array(), $request->department->email, $fromName, array( 'Message-Id' => "<IPS-0-SR{$request->id}.{$request->email_key}-{$request->department->email}>" ) );
|
||||
}
|
||||
|
||||
/* Return */
|
||||
@@ -426,7 +462,7 @@ class _Support
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( preg_match( '/From:.+?(\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b)/i', $email->quote, $_matches ) )
|
||||
if ( preg_match( '/From:.+?(\b[A-Z0-9._%+-\']+@[A-Z0-9.-]+\.[A-Z]{2,9}\b)/i', $email->quote, $_matches ) )
|
||||
{
|
||||
$originallyFrom = $_matches[1];
|
||||
}
|
||||
|
||||
@@ -25,37 +25,13 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
*/
|
||||
class _CustomerHistory
|
||||
{
|
||||
/**
|
||||
* Find Records by IP
|
||||
*
|
||||
* @param string $ip The IP Address
|
||||
* @param \IPS\Http\Url $baseUrl URL table will be displayed on or NULL to return a count
|
||||
* @return \IPS\Helpers\Table|null
|
||||
*/
|
||||
public function findByIp( $ip, \IPS\Http\Url $baseUrl = NULL )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find IPs by Member
|
||||
* @deprecated
|
||||
*
|
||||
* @code
|
||||
return array(
|
||||
'::1' => array(
|
||||
'ip' => '::1'// string (IP Address)
|
||||
'count' => ... // int (number of times this member has used this IP)
|
||||
'first' => ... // int (timestamp of first use)
|
||||
'last' => ... // int (timestamp of most recent use)
|
||||
),
|
||||
...
|
||||
);
|
||||
* @endcode
|
||||
* @param \IPS\Member $member The member
|
||||
* @return array|NULL
|
||||
*@return bool
|
||||
*/
|
||||
public function findByMember( $member )
|
||||
final public function deprecated()
|
||||
{
|
||||
return NULL;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -69,75 +69,80 @@ class _AccountInformation extends \IPS\core\MemberACPProfile\TabbedBlock
|
||||
protected function _overview()
|
||||
{
|
||||
/* Sparkline */
|
||||
$rows = array();
|
||||
$oneYearAgo = \IPS\DateTime::create()->sub( new \DateInterval('P1Y') );
|
||||
$date = clone $oneYearAgo;
|
||||
$endOfLastMonth = mktime( 23, 59, 59, date('n') - 1, date('t'), date('Y') );
|
||||
while ( $date->getTimestamp() < $endOfLastMonth )
|
||||
$sparkline = NULL;
|
||||
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customer', 'customers_view_statistics' ) )
|
||||
{
|
||||
$rows = array();
|
||||
$oneYearAgo = \IPS\DateTime::create()->sub( new \DateInterval( 'P1Y' ) );
|
||||
$date = clone $oneYearAgo;
|
||||
$endOfLastMonth = mktime( 23, 59, 59, date( 'n' ) - 1, date( 't' ), date( 'Y' ) );
|
||||
while ( $date->getTimestamp() < $endOfLastMonth )
|
||||
{
|
||||
foreach ( \IPS\nexus\Money::currencies() as $currency )
|
||||
{
|
||||
$rows[$date->format( 'n Y' )][$currency] = 0;
|
||||
}
|
||||
$date->add( new \DateInterval( 'P1M' ) );
|
||||
}
|
||||
$sparkline = new \IPS\Helpers\Chart;
|
||||
foreach ( \IPS\Db::i()->select( 'DATE_FORMAT( FROM_UNIXTIME(t_date), \'%c %Y\' ) AS time, SUM(t_amount)-SUM(t_partial_refund) AS amount, t_currency', 'nexus_transactions', array(array("t_member=? AND ( t_status=? OR t_status=? ) AND t_method>0 AND t_date>? AND t_date<?", $this->member->member_id, \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED, $oneYearAgo->getTimestamp(), time())), NULL, NULL, array('time', 't_currency') ) as $row )
|
||||
{
|
||||
if ( isset( $rows[$row['time']][$row['t_currency']] ) ) // Currency may no longer exist
|
||||
{
|
||||
$rows[$row['time']][$row['t_currency']] += $row['amount'];
|
||||
}
|
||||
}
|
||||
$sparkline->addHeader( \IPS\Member::loggedIn()->language()->addToStack( 'date' ), 'date' );
|
||||
foreach ( \IPS\nexus\Money::currencies() as $currency )
|
||||
{
|
||||
$rows[ $date->format( 'n Y' ) ][ $currency ] = 0;
|
||||
$sparkline->addHeader( $currency, 'number' );
|
||||
}
|
||||
$date->add( new \DateInterval( 'P1M' ) );
|
||||
}
|
||||
$sparkline = new \IPS\Helpers\Chart;
|
||||
foreach( \IPS\Db::i()->select( 'DATE_FORMAT( FROM_UNIXTIME(t_date), \'%c %Y\' ) AS time, SUM(t_amount)-SUM(t_partial_refund) AS amount, t_currency', 'nexus_transactions', array( array( "t_member=? AND ( t_status=? OR t_status=? ) AND t_date>? AND t_date<?", $this->member->member_id, \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED, $oneYearAgo->getTimestamp(), time() ) ), NULL, NULL, array( 'time', 't_currency' ) ) as $row )
|
||||
{
|
||||
if ( isset( $rows[ $row['time'] ][ $row['t_currency'] ] ) ) // Currency may no longer exist
|
||||
foreach ( $rows as $time => $row )
|
||||
{
|
||||
$rows[ $row['time'] ][ $row['t_currency'] ] += $row['amount'];
|
||||
}
|
||||
}
|
||||
$sparkline->addHeader( \IPS\Member::loggedIn()->language()->addToStack('date'), 'date' );
|
||||
foreach ( \IPS\nexus\Money::currencies() as $currency )
|
||||
{
|
||||
$sparkline->addHeader( $currency, 'number' );
|
||||
}
|
||||
foreach ( $rows as $time => $row )
|
||||
{
|
||||
$datetime = new \IPS\DateTime;
|
||||
$datetime->setTime( 0, 0, 0 );
|
||||
$exploded = explode( ' ', $time );
|
||||
$datetime->setDate( $exploded[1], $exploded[0], 1 );
|
||||
$datetime = new \IPS\DateTime;
|
||||
$datetime->setTime( 0, 0, 0 );
|
||||
$exploded = explode( ' ', $time );
|
||||
$datetime->setDate( $exploded[1], $exploded[0], 1 );
|
||||
|
||||
foreach( $row as $currency => $value )
|
||||
{
|
||||
$row[ $currency ] = number_format( $value, 2, '.', '' );
|
||||
foreach ( $row as $currency => $value )
|
||||
{
|
||||
$row[$currency] = number_format( $value, 2, '.', '' );
|
||||
}
|
||||
|
||||
$sparkline->addRow( array_merge( array($datetime), $row ) );
|
||||
}
|
||||
|
||||
$sparkline->addRow( array_merge( array( $datetime ), $row ) );
|
||||
|
||||
$sparkline = $sparkline->render( 'AreaChart', array(
|
||||
'areaOpacity' => 0.4,
|
||||
'backgroundColor' => '#fff',
|
||||
'colors' => array('#10967e'),
|
||||
'chartArea' => array(
|
||||
'left' => 0,
|
||||
'top' => 0,
|
||||
'width' => '100%',
|
||||
'height' => '100%',
|
||||
),
|
||||
'hAxis' => array(
|
||||
'baselineColor' => '#F3F3F3',
|
||||
'gridlines' => array(
|
||||
'count' => 0,
|
||||
)
|
||||
),
|
||||
'height' => 60,
|
||||
'legend' => array(
|
||||
'position' => 'none',
|
||||
),
|
||||
'lineWidth' => 1,
|
||||
'vAxis' => array(
|
||||
'baselineColor' => '#F3F3F3',
|
||||
'gridlines' => array(
|
||||
'count' => 0,
|
||||
)
|
||||
),
|
||||
) );
|
||||
}
|
||||
|
||||
$sparkline = $sparkline->render( 'AreaChart', array(
|
||||
'areaOpacity' => 0.4,
|
||||
'backgroundColor' => '#fff',
|
||||
'colors' => array( '#10967e' ),
|
||||
'chartArea' => array(
|
||||
'left' => 0,
|
||||
'top' => 0,
|
||||
'width' => '100%',
|
||||
'height' => '100%',
|
||||
),
|
||||
'hAxis' => array(
|
||||
'baselineColor' => '#F3F3F3',
|
||||
'gridlines' => array(
|
||||
'count' => 0,
|
||||
)
|
||||
),
|
||||
'height' => 60,
|
||||
'legend' => array(
|
||||
'position' => 'none',
|
||||
),
|
||||
'lineWidth' => 1,
|
||||
'vAxis' => array(
|
||||
'baselineColor' => '#F3F3F3',
|
||||
'gridlines' => array(
|
||||
'count' => 0,
|
||||
)
|
||||
),
|
||||
) );
|
||||
|
||||
|
||||
/* Referrals */
|
||||
try
|
||||
{
|
||||
@@ -170,7 +175,7 @@ class _AccountInformation extends \IPS\core\MemberACPProfile\TabbedBlock
|
||||
protected function _cards( $edit = FALSE )
|
||||
{
|
||||
$cards = array();
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_customer_cards', array( 'card_member=?', $this->member->member_id ), NULL, \IPS\Request::i()->view === 'cards' ? NULL : 2 ), 'IPS\nexus\Customer\CreditCard' ) as $card )
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_customer_cards', array( 'card_member=?', $this->member->member_id ), NULL, $edit ? NULL : 10 ), 'IPS\nexus\Customer\CreditCard' ) as $card )
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -233,7 +238,7 @@ class _AccountInformation extends \IPS\core\MemberACPProfile\TabbedBlock
|
||||
{
|
||||
$billingAgreementCount = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_billing_agreements', array( 'ba_member=? AND ba_canceled=0', $this->member->member_id ) )->first();
|
||||
$billingAgreements = array();
|
||||
foreach ( \IPS\Db::i()->select( '*', 'nexus_billing_agreements', array( 'ba_member=? AND ba_canceled=0', $this->member->member_id ), NULL, \IPS\Request::i()->view === 'billingagreements' ? NULL : 2 ) as $billingAgreement )
|
||||
foreach ( \IPS\Db::i()->select( '*', 'nexus_billing_agreements', array( 'ba_member=? AND ba_canceled=0', $this->member->member_id ), NULL, $edit ? NULL : 10 ) as $billingAgreement )
|
||||
{
|
||||
$billingAgreements[ $billingAgreement['ba_id'] ] = array(
|
||||
'id' => $billingAgreement['ba_id'],
|
||||
@@ -412,7 +417,7 @@ class _AccountInformation extends \IPS\core\MemberACPProfile\TabbedBlock
|
||||
}
|
||||
else
|
||||
{
|
||||
$return[] = new \IPS\nexus\Money( 0, $this->member->defaultCurrency() );
|
||||
$return[] = new \IPS\nexus\Money( 0, \IPS\nexus\Customer::load( $this->member )->defaultCurrency() );
|
||||
}
|
||||
return implode( '<br>', $return );
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ class _Notes extends \IPS\core\MemberACPProfile\Block
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function edit()
|
||||
public function lazyOutput()
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'customers', 'nexus' )->customerPopup( $this->notes );
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ class _Purchases extends \IPS\core\MemberACPProfile\Block
|
||||
/**
|
||||
* Get purchase table
|
||||
*
|
||||
* @return \IPS\IPS\Helpers\Tree
|
||||
* @return \IPS\Helpers\Tree\Tree
|
||||
*/
|
||||
protected function purchases()
|
||||
{
|
||||
|
||||
@@ -34,8 +34,8 @@ class _Statistics extends \IPS\core\MemberACPProfile\LazyLoadingBlock
|
||||
foreach ( \IPS\nexus\Money::currencies() as $currency )
|
||||
{
|
||||
/* Total spent */
|
||||
$comparisons = \IPS\Db::i()->select( 'AVG(xval) AS avg, MAX(xval) AS max, MIN(xval) AS min', \IPS\Db::i()->select( "(SUM(t_amount)-SUM(t_partial_refund)) as xval", 'nexus_transactions', array( '( t_status=? OR t_status=? ) AND t_currency=? AND t_member<>0', \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED, $currency ), NULL, NULL, 't_member' ), 'xval>0' )->first();
|
||||
$val = \IPS\Db::i()->select( 'SUM(t_amount)-SUM(t_partial_refund)', 'nexus_transactions', array( 't_member=? AND ( t_status=? OR t_status=? ) AND t_currency=?', $this->member->member_id, \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED, $currency ) )->first();
|
||||
$comparisons = \IPS\Db::i()->select( 'AVG(xval) AS avg, MAX(xval) AS max, MIN(xval) AS min', \IPS\Db::i()->select( "(SUM(t_amount)-SUM(t_partial_refund)) as xval", 'nexus_transactions', array( '( t_status=? OR t_status=? ) AND t_method>0 AND t_currency=? AND t_member<>0', \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED, $currency ), NULL, NULL, 't_member' ), 'xval>0' )->first();
|
||||
$val = \IPS\Db::i()->select( 'SUM(t_amount)-SUM(t_partial_refund)', 'nexus_transactions', array( 't_member=? AND ( t_status=? OR t_status=? ) AND t_method>0 AND t_currency=?', $this->member->member_id, \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED, $currency ) )->first();
|
||||
$standing[ \IPS\Member::loggedIn()->language()->addToStack( 'total_spent_currency', FALSE, array( 'sprintf' => array( $currency ) ) ) ] = array(
|
||||
'value' => new \IPS\nexus\Money( $val ?: '0', $currency ),
|
||||
'avg' => new \IPS\nexus\Money( $comparisons['avg'], $currency ),
|
||||
|
||||
@@ -33,6 +33,16 @@ class _Main extends \IPS\core\MemberACPProfile\MainTab
|
||||
$this->member = \IPS\nexus\Customer::load( $member->member_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Can view this Tab
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canView()
|
||||
{
|
||||
return (bool) \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_view' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get left-column blocks
|
||||
*
|
||||
@@ -52,14 +62,36 @@ class _Main extends \IPS\core\MemberACPProfile\MainTab
|
||||
*/
|
||||
public function mainColumnBlocks()
|
||||
{
|
||||
return array(
|
||||
'IPS\nexus\extensions\core\MemberACPProfileBlocks\Statistics',
|
||||
'IPS\nexus\extensions\core\MemberACPProfileBlocks\ParentAccounts',
|
||||
'IPS\nexus\extensions\core\MemberACPProfileBlocks\Notes',
|
||||
'IPS\nexus\extensions\core\MemberACPProfileBlocks\Purchases',
|
||||
'IPS\nexus\extensions\core\MemberACPProfileBlocks\Invoices',
|
||||
'IPS\nexus\extensions\core\MemberACPProfileBlocks\Support',
|
||||
);
|
||||
$return = array();
|
||||
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_view_credit' ) )
|
||||
{
|
||||
$return[] = 'IPS\nexus\extensions\core\MemberACPProfileBlocks\Statistics';
|
||||
}
|
||||
|
||||
$return[] = 'IPS\nexus\extensions\core\MemberACPProfileBlocks\ParentAccounts';
|
||||
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customer_notes_view' ) )
|
||||
{
|
||||
$return[] = 'IPS\nexus\extensions\core\MemberACPProfileBlocks\Notes';
|
||||
}
|
||||
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'purchases_view' ) )
|
||||
{
|
||||
$return[] = 'IPS\nexus\extensions\core\MemberACPProfileBlocks\Purchases';
|
||||
}
|
||||
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'invoices_manage' ) )
|
||||
{
|
||||
$return[] = 'IPS\nexus\extensions\core\MemberACPProfileBlocks\Invoices';
|
||||
}
|
||||
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'support', 'requests_manage' ) )
|
||||
{
|
||||
$return[] = 'IPS\nexus\extensions\core\MemberACPProfileBlocks\Support';
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief ACP Export Personal Information
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
* @since 15 May 2018
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\extensions\core\MemberExportPersonalInformation;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ACP Export Personal Information
|
||||
*/
|
||||
class _Customer
|
||||
{
|
||||
/**
|
||||
* Return data
|
||||
* @param \IPS\Member $member The member
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getData( \IPS\Member $member )
|
||||
{
|
||||
$return = array();
|
||||
|
||||
try
|
||||
{
|
||||
$customer = \IPS\nexus\Customer::load( $member->member_id );
|
||||
|
||||
/* Name and addresses */
|
||||
$return['customer'] = array(
|
||||
'first_name' => $customer->cm_first_name,
|
||||
'last_name' => $customer->cm_last_name
|
||||
);
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'nexus_customer_addresses', array( 'member=?', $member->member_id ) ) as $address )
|
||||
{
|
||||
$return['addresses'][] = \IPS\GeoLocation::buildFromJson( $address['address'] )->toString( "," );
|
||||
}
|
||||
|
||||
/* Customer custom fields */
|
||||
foreach ( \IPS\nexus\Customer\CustomField::roots() as $field )
|
||||
{
|
||||
$column = $field->column;
|
||||
if ( $column )
|
||||
{
|
||||
$return['fields'][ $column ] = $field->displayValue( $customer->$column, TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
/* Credit cards */
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_customer_cards', array( 'card_member=?', $member->member_id ) ), 'IPS\nexus\Customer\CreditCard' ) as $card )
|
||||
{
|
||||
try
|
||||
{
|
||||
$cardData = $card->card;
|
||||
$return['credit_cards'][ $card->id ] = array(
|
||||
'card_type' => $cardData->type,
|
||||
'card_number' => $cardData->lastFour,
|
||||
'card_expire' => ( !is_null( $cardData->expMonth ) AND !is_null( $cardData->expYear ) ) ? str_pad( $cardData->expMonth , 2, '0', STR_PAD_LEFT ). '/' . $cardData->expYear : NULL
|
||||
);
|
||||
}
|
||||
catch ( \Exception $e ) {}
|
||||
}
|
||||
}
|
||||
catch( \OutOfRangeException $ex )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
}
|
||||
Whitespace-only changes.
@@ -114,13 +114,13 @@ class _Purchases
|
||||
* Get where clause to add to the member retrieval database query
|
||||
*
|
||||
* @param mixed $data The array returned from the save() method
|
||||
* @return string|array|NULL Where clause
|
||||
* @return array|NULL Where clause - must be a single array( "clause", ...binds )
|
||||
*/
|
||||
public function getQueryWhereClause( $data )
|
||||
{
|
||||
if ( isset( $data['nexus_bm_filters_packages'] ) and $data['nexus_bm_filters_packages'] )
|
||||
{
|
||||
return 'nexus_purchases.ps_id IS NOT NULL';
|
||||
return array( 'nexus_purchases.ps_id IS NOT NULL' );
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -112,13 +112,13 @@ class _Subscriptions
|
||||
* Get where clause to add to the member retrieval database query
|
||||
*
|
||||
* @param mixed $data The array returned from the save() method
|
||||
* @return string|array|NULL Where clause
|
||||
* @return array|NULL Where clause - must be a single array( "clause", ...binds )
|
||||
*/
|
||||
public function getQueryWhereClause( $data )
|
||||
{
|
||||
if ( isset( $data['nexus_bm_filters_subscription_pkgs'] ) and $data['nexus_bm_filters_subscription_pkgs'] )
|
||||
{
|
||||
return 'nexus_purchases.ps_id IS NOT NULL';
|
||||
return array( 'nexus_purchases.ps_id IS NOT NULL' );
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -24,26 +24,12 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
class _Nexus
|
||||
{
|
||||
/**
|
||||
* Process Form
|
||||
* @deprecated
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @param \IPS\Member $member Existing Member
|
||||
* @return void
|
||||
* @return bool
|
||||
*/
|
||||
public function process( &$form, $member )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Save
|
||||
*
|
||||
* @param array $values Values from form
|
||||
* @param \IPS\Member $member The member
|
||||
* @return void
|
||||
*/
|
||||
public function save( $values, &$member )
|
||||
final public function deprecated()
|
||||
{
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -147,17 +147,31 @@ class _Nexus
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_transaction_paid', FALSE, array( 'htmlsprintf' => array( $transaction, $invoice, $byStaff, \IPS\Member::loggedIn()->language()->addToStack( 'history_transaction_status_' . $val['status'] ) ) ) );
|
||||
}
|
||||
|
||||
|
||||
case 'status':
|
||||
if ( $val['status'] === \IPS\nexus\Transaction::STATUS_REFUNDED or $val['status'] === \IPS\nexus\Transaction::STATUS_PART_REFUNDED )
|
||||
{
|
||||
if ( $val['refund'] === 'gateway' )
|
||||
{
|
||||
$refundedTo = ( is_object( $transaction ) and $transaction->method ) ? $transaction->method->_title : \IPS\Member::loggedIn()->language()->addToStack('history_transaction_refunded_gateway');
|
||||
if ( isset( $val['amount'] ) and $val['amount'] )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_transaction_part_refunded', FALSE, array( 'htmlsprintf' => array( new \IPS\nexus\Money( $val['amount'], $val['currency'] ), $transaction, $byStaff ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_transaction_refunded', FALSE, array( 'htmlsprintf' => array( $transaction, $byStaff ) ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$refundedTo = mb_strtolower( \IPS\Member::loggedIn()->language()->addToStack( 'refund_method_credit' ) );
|
||||
if ( isset( $val['amount'] ) and $val['amount'] )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_transaction_part_credited', FALSE, array( 'htmlsprintf' => array( new \IPS\nexus\Money( $val['amount'], $val['currency'] ), $transaction, $byStaff ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_transaction_credited', FALSE, array( 'htmlsprintf' => array( $transaction, $byStaff ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $val['status'] === \IPS\nexus\Transaction::STATUS_REFUNDED )
|
||||
@@ -174,6 +188,9 @@ class _Nexus
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_transaction_status', FALSE, array( 'htmlsprintf' => array( $transaction, \IPS\Member::loggedIn()->language()->addToStack( 'history_transaction_status_' . $val['status'] ), $byStaff ) ) );
|
||||
}
|
||||
|
||||
case 'undo_credit':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_transaction_undo_credit', FALSE, array( 'htmlsprintf' => array( new \IPS\nexus\Money( $val['amount'], $val['currency'] ), $transaction, $byStaff ) ) );
|
||||
|
||||
case 'delete':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_transaction_delete', FALSE, array( 'htmlsprintf' => array( $transaction, $byStaff ) ) );
|
||||
}
|
||||
@@ -378,8 +395,6 @@ class _Nexus
|
||||
}
|
||||
|
||||
case 'giftvoucher':
|
||||
|
||||
$currency = isset( $val['currency'] ) ? $val['currency'] : \IPS\nexus\Customer::load( $val['by'] )->defaultCurrency();
|
||||
switch ( $val['type'] )
|
||||
{
|
||||
case 'used':
|
||||
@@ -393,6 +408,8 @@ class _Nexus
|
||||
$customer = new \IPS\nexus\Customer;
|
||||
}
|
||||
|
||||
$currency = isset( $val['currency'] ) ? $val['currency'] : $customer->defaultCurrency();
|
||||
|
||||
return
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'history_giftvoucher_used', FALSE, array( 'htmlsprintf' => array(
|
||||
new \IPS\nexus\Money( $val['amount'], $currency ),
|
||||
@@ -412,6 +429,8 @@ class _Nexus
|
||||
$customer = new \IPS\nexus\Customer;
|
||||
}
|
||||
|
||||
$currency = isset( $val['currency'] ) ? $val['currency'] : $customer->defaultCurrency();
|
||||
|
||||
return
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'history_giftvoucher_redeemed', FALSE, array( 'htmlsprintf' => array(
|
||||
new \IPS\nexus\Money( $val['amount'], $currency ),
|
||||
@@ -421,7 +440,6 @@ class _Nexus
|
||||
) ) );
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'info':
|
||||
@@ -521,9 +539,16 @@ class _Nexus
|
||||
break;
|
||||
|
||||
case 'alternative':
|
||||
try
|
||||
{
|
||||
$altContact = \IPS\nexus\Customer::load( $val['alt_id'] );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
$altContact = new \IPS\nexus\Customer;
|
||||
}
|
||||
|
||||
$altContact = \IPS\nexus\Customer::load( $val['alt_id'] );
|
||||
$altContact = $altContact->member_id ? $altContact->link() : $val['alt_name'];
|
||||
$altContact = $altContact->member_id ? $altContact->link() : htmlspecialchars( $val['alt_name'], ENT_DISALLOWED, 'UTF-8', FALSE );
|
||||
|
||||
switch ( $val['type'] )
|
||||
{
|
||||
|
||||
@@ -109,6 +109,8 @@ class _Nexus
|
||||
\IPS\Db::i()->update( 'nexus_support_requests', array( 'r_member' => $member->member_id ), array( 'r_member=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->update( 'nexus_support_requests', array( 'r_last_reply_by' => $member->member_id ), array( 'r_last_reply_by=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->update( 'nexus_support_replies', array( 'reply_member' => $member->member_id ), array( 'reply_member=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->update( 'nexus_support_ratings', array( 'rating_from' => $member->member_id ), array( 'rating_from=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->update( 'nexus_support_ratings', array( 'rating_staff' => $member->member_id ), array( 'rating_staff=?', $member2->member_id ) );
|
||||
|
||||
/* Account Credit */
|
||||
$customerToKeep = \IPS\nexus\Customer::load( $member->member_id );
|
||||
@@ -131,6 +133,15 @@ class _Nexus
|
||||
}
|
||||
$customerToKeep->cm_credits = $creditToKeep;
|
||||
$customerToKeep->save();
|
||||
|
||||
/* Subscription packages */
|
||||
if ( $keepSub = \IPS\nexus\Subscription::loadActiveByMember( $member ) )
|
||||
{
|
||||
if ( $dropSub = \IPS\nexus\Subscription::loadActiveByMember( $member2 ) )
|
||||
{
|
||||
$dropSub->removeMember( \IPS\nexus\Customer::load( $member2->member_id ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,6 +176,9 @@ class _Nexus
|
||||
|
||||
\IPS\Db::i()->update( 'nexus_purchases', array( 'ps_pay_to' => 0 ), array( 'ps_pay_to=?', $member->member_id ) );
|
||||
\IPS\Db::i()->delete( 'nexus_support_streams', array( 'stream_owner=?', $member->member_id ) );
|
||||
|
||||
/* Subscriptions (mop up orphaned members) */
|
||||
\IPS\Db::i()->delete( 'nexus_member_subscriptions', array( "sub_member_id=?", $member->member_id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Background task to fix refunded transactions following the 4.3.5 change to treat refunds and credits separately
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
* @subpackage Commerce
|
||||
* @since 20 June 2018
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\extensions\core\Queue;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Background task to fix refunded transactions following the 4.3.5 change to treat refunds and credits separately
|
||||
*/
|
||||
class _FixRefundTransactions
|
||||
{
|
||||
|
||||
public $perCycle = 500;
|
||||
|
||||
/**
|
||||
* Parse data before queuing
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function preQueueData( $data )
|
||||
{
|
||||
$data['count'] = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_transactions', array( \IPS\Db::i()->in( 't_status', array( \IPS\nexus\Transaction::STATUS_REFUNDED, \IPS\nexus\Transaction::STATUS_PART_REFUNDED ) ) ) )->first();
|
||||
|
||||
if( $data['count'] == 0 )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$data['done'] = 0;
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run Background Task
|
||||
*
|
||||
* @param mixed $data Data as it was passed to \IPS\Task::queue()
|
||||
* @param int $offset Offset
|
||||
* @return int New offset
|
||||
* @throws \IPS\Task\Queue\OutOfRangeException Indicates offset doesn't exist and thus task is complete
|
||||
*/
|
||||
public function run( $data, $offset )
|
||||
{
|
||||
$transactions = \IPS\Db::i()->select( '*', 'nexus_transactions', array( array( 't_id>?', $offset ), array( \IPS\Db::i()->in( 't_status', array( \IPS\nexus\Transaction::STATUS_REFUNDED, \IPS\nexus\Transaction::STATUS_PART_REFUNDED ) ) ) ), 't_id ASC', $this->perCycle );
|
||||
$lastId = 0;
|
||||
|
||||
foreach( $transactions as $transaction )
|
||||
{
|
||||
$extra = json_decode( $transaction['t_extra'], TRUE );
|
||||
if ( $extra and isset( $extra['history'] ) )
|
||||
{
|
||||
$credit = new \IPS\Math\Number('0');
|
||||
$totalRefunded = new \IPS\Math\Number('0');
|
||||
|
||||
$update = array();
|
||||
$updateHistory = FALSE;
|
||||
foreach ( $extra['history'] as $i => $history )
|
||||
{
|
||||
if ( ( $history['s'] === 'rfnd' or $history['s'] === 'prfd' ) )
|
||||
{
|
||||
if ( $history['to'] === 'credit' )
|
||||
{
|
||||
if ( $history['s'] === 'rfnd' )
|
||||
{
|
||||
$updateHistory = TRUE;
|
||||
$extra['history'][ $i ]['s'] = 'prfd';
|
||||
}
|
||||
|
||||
if ( isset( $history['amount'] ) )
|
||||
{
|
||||
$credit = $credit->add( new \IPS\Math\Number( $history['amount'] ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$credit = $credit->add( new \IPS\Math\Number( $transaction['t_amount'] ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isset( $history['amount'] ) )
|
||||
{
|
||||
$totalRefunded = $totalRefunded->add( new \IPS\Math\Number( $history['amount'] ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$totalRefunded = $totalRefunded->add( new \IPS\Math\Number( $transaction['t_amount'] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $updateHistory )
|
||||
{
|
||||
$update['t_extra'] = json_encode( $extra );
|
||||
}
|
||||
if ( $credit->isGreaterThanZero() )
|
||||
{
|
||||
$update['t_credit'] = (string) $credit;
|
||||
}
|
||||
if ( $transaction['t_status'] === \IPS\nexus\Transaction::STATUS_PART_REFUNDED and $totalRefunded->compare( new \IPS\Math\Number( $transaction['t_partial_refund'] ) ) !== 0 )
|
||||
{
|
||||
$update['t_partial_refund'] = (string) $totalRefunded;
|
||||
}
|
||||
if ( $transaction['t_status'] === \IPS\nexus\Transaction::STATUS_REFUNDED and $totalRefunded->compare( new \IPS\Math\Number( $transaction['t_amount'] ) ) !== 0 )
|
||||
{
|
||||
$update['t_status'] = \IPS\nexus\Transaction::STATUS_PART_REFUNDED;
|
||||
}
|
||||
if ( $update )
|
||||
{
|
||||
\IPS\Db::i()->update( 'nexus_transactions', $update, array( 't_id=?', $transaction['t_id'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
$lastId = $transaction['t_id'];
|
||||
}
|
||||
|
||||
if( $lastId == 0 )
|
||||
{
|
||||
throw new \IPS\Task\Queue\OutOfRangeException;
|
||||
}
|
||||
|
||||
$data['done'] += $this->perCycle;
|
||||
|
||||
return $lastId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Progress
|
||||
*
|
||||
* @param mixed $data Data as it was passed to \IPS\Task::queue()
|
||||
* @param int $offset Offset
|
||||
* @return array( 'text' => 'Doing something...', 'complete' => 50 ) Text explaining task and percentage complete
|
||||
* @throws \OutOfRangeException Indicates offset doesn't exist and thus task is complete
|
||||
*/
|
||||
public function getProgress( $data, $offset )
|
||||
{
|
||||
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack('upgrade_fix_refund_transactions'), 'complete' => $data['done'] ? ( round( 100 / $data['done'] * $data['count'], 2 ) ) : 0 );
|
||||
}
|
||||
}
|
||||
@@ -384,7 +384,7 @@ class _Package extends \IPS\nexus\Invoice\Item\Purchase
|
||||
{
|
||||
try
|
||||
{
|
||||
$chosenOption = \IPS\Db::i()->select( '*', 'nexus_product_options', array( 'opt_package=? AND opt_values=?', $package->id, json_encode( $details ) ) )->first();
|
||||
$chosenOption = \IPS\Db::i()->select( '*', 'nexus_product_options', array( 'opt_package=? AND opt_values=?', $package->id, json_encode( $package->optionValues( $details ) ) ) )->first();
|
||||
$basePriceAdjustments = json_decode( $chosenOption['opt_base_price'], TRUE );
|
||||
if ( isset( $basePrice->currency ) )
|
||||
{
|
||||
|
||||
@@ -145,7 +145,14 @@ class _Subscription extends \IPS\nexus\Invoice\Item\Purchase
|
||||
try
|
||||
{
|
||||
$package = \IPS\nexus\Subscription\Package::load( $purchase->item_id );
|
||||
return explode( ',', $package->gateways );
|
||||
if ( $package->gateways and $package->gateways != '*' )
|
||||
{
|
||||
return explode( ',', $package->gateways );
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
catch ( \Exception $e ) {}
|
||||
|
||||
@@ -196,6 +203,30 @@ class _Subscription extends \IPS\nexus\Invoice\Item\Purchase
|
||||
catch ( \Exception $e ) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* On Renew (Renewal invoice paid. Is not called if expiry data is manually changed)
|
||||
*
|
||||
* @param \IPS\nexus\Purchase $purchase The purchase
|
||||
* @param int $cycles Cycles
|
||||
* @return void
|
||||
*/
|
||||
public static function onRenew( \IPS\nexus\Purchase $purchase, $cycles )
|
||||
{
|
||||
try
|
||||
{
|
||||
$subs = \IPS\nexus\Subscription::loadByMemberAndPackage( $purchase->member, \IPS\nexus\Subscription\Package::load( $purchase->item_id ), FALSE );
|
||||
$subs->active = 1;
|
||||
$subs->save();
|
||||
}
|
||||
catch( \OutOfRangeException $e ) { }
|
||||
|
||||
try
|
||||
{
|
||||
\IPS\nexus\Subscription\Package::load( $purchase->item_id )->addMember( $purchase->member );
|
||||
}
|
||||
catch ( \Exception $e ) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* On Purchase Expired
|
||||
*
|
||||
@@ -271,14 +302,13 @@ class _Subscription extends \IPS\nexus\Invoice\Item\Purchase
|
||||
$subs->active = 1;
|
||||
$subs->save();
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
catch( \OutOfRangeException $e ) { }
|
||||
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\nexus\Subscription\Package::load( $purchase->item_id )->addMember( $purchase->member );
|
||||
}
|
||||
catch ( \Exception $e ) {}
|
||||
\IPS\nexus\Subscription\Package::load( $purchase->item_id )->addMember( $purchase->member );
|
||||
}
|
||||
catch ( \Exception $e ) {}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -305,13 +335,13 @@ class _Subscription extends \IPS\nexus\Invoice\Item\Purchase
|
||||
/* Now if the purchase isn't cancelled... */
|
||||
if ( !$purchase->cancelled )
|
||||
{
|
||||
/* We need the Customer object */
|
||||
$newCustomer = \IPS\nexus\Customer::load( $newCustomer->member_id );
|
||||
|
||||
/* Remove any request/invitation for the new member and add the new record */
|
||||
$package->removeMember( $newCustomer, FALSE );
|
||||
$package->addMember( $newCustomer, FALSE );
|
||||
}
|
||||
|
||||
/* Recount */
|
||||
$package->recountMembers();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -331,7 +361,7 @@ class _Subscription extends \IPS\nexus\Invoice\Item\Purchase
|
||||
*
|
||||
* @param array $values Values from form
|
||||
* @param \IPS\nexus\Invoice $invoice The invoice
|
||||
* @return \IPS\nexus\extensions\nexus\Item\MiscellaneousCharge
|
||||
* @return \IPS\nexus\extensions\nexus\Item\Subscription
|
||||
*/
|
||||
public static function createFromForm( array $values, \IPS\nexus\Invoice $invoice )
|
||||
{
|
||||
@@ -343,7 +373,7 @@ class _Subscription extends \IPS\nexus\Invoice\Item\Purchase
|
||||
$item->id = $package->id;
|
||||
try
|
||||
{
|
||||
$item->tax = $package->tax;
|
||||
$item->tax = $package->tax ? \IPS\nexus\Tax::load( $package->tax ) : NULL;
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
|
||||
@@ -365,6 +395,6 @@ class _Subscription extends \IPS\nexus\Invoice\Item\Purchase
|
||||
*/
|
||||
public function requiresBillingAddress()
|
||||
{
|
||||
return in_array( 'subscription', explode( ',', \IPS\Settings::i()->nexus_require_billing ) );
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,7 @@ class _SubscriptionUpgrade extends \IPS\nexus\Invoice\Item\Charge
|
||||
$oldPackage = \IPS\nexus\Subscription\Package::load( $this->extra['oldPackage'] );
|
||||
$newPackage = \IPS\nexus\Subscription\Package::load( $this->extra['newPackage'] );
|
||||
$oldPackage->upgradeDowngrade( $purchase, $newPackage, TRUE );
|
||||
$purchase->member->log( 'subscription', array( 'type' => 'change', 'id' => $purchase->id, 'old' => $oldPackage->_title, 'name' => $newPackage->_title, 'system' => TRUE ) );
|
||||
$purchase->member->log( 'subscription', array( 'type' => 'change', 'id' => $purchase->id, 'old' => $oldPackage->titleForLog(), 'name' => $newPackage->titleForLog(), 'system' => TRUE ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ){ }
|
||||
}
|
||||
|
||||
@@ -43,7 +43,8 @@ $transaction->save();
|
||||
$maxMind = NULL;
|
||||
if ( \IPS\Settings::i()->maxmind_key and ( !\IPS\Settings::i()->maxmind_gateways or \IPS\Settings::i()->maxmind_gateways == '*' or in_array( $transaction->method->id, explode( ',', \IPS\Settings::i()->maxmind_gateways ) ) ) )
|
||||
{
|
||||
$maxMind = new \IPS\nexus\Fraud\MaxMind\Request;
|
||||
$maxMind = new \IPS\nexus\Fraud\MaxMind\Request( FALSE );
|
||||
$maxMind->setIpAddress( $transaction->ip );
|
||||
$maxMind->setTransaction( $transaction );
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ require_once '../../../../init.php';
|
||||
try
|
||||
{
|
||||
$transaction = \IPS\nexus\Transaction::load( \IPS\Request::i()->nexusTransactionId );
|
||||
$source = $transaction->method->api( 'sources/' . preg_replace( '/[^A-Z0-9_]/i', '', \IPS\Request::i()->source ) );
|
||||
$source = $transaction->method->api( 'sources/' . preg_replace( '/[^A-Z0-9_]/i', '', \IPS\Request::i()->source ), NULL, 'get' );
|
||||
if ( $source['client_secret'] != \IPS\Request::i()->client_secret )
|
||||
{
|
||||
throw new \Exception;
|
||||
|
||||
@@ -83,18 +83,50 @@ try
|
||||
exit;
|
||||
}
|
||||
|
||||
/* Don't need to do anything for cards, since this is only for asynchronous payments */
|
||||
if ( isset( $data['data']['object']['type'] ) and in_array( $data['data']['object']['type'], array( 'card' ) ) )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( 'NO_PROCESSING_REQUIRED', 200, 'text/plain' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/* Load the transaction */
|
||||
if ( isset( $data['data']['object']['metadata']['Transaction ID'] ) )
|
||||
{
|
||||
$transaction = \IPS\nexus\Transaction::load( $data['data']['object']['metadata']['Transaction ID'] );
|
||||
}
|
||||
else
|
||||
elseif ( isset( $data['data']['object']['redirect']['return_url'] ) )
|
||||
{
|
||||
$transaction = loadTransaction( $data['data']['object']['redirect']['return_url'] );
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
$where = array( array( 't_gw_id=?', $data['data']['object']['id'] ) );
|
||||
if ( isset( $data['data']['object']['metadata']['Invoice ID'] ) )
|
||||
{
|
||||
$where[] = array( 't_invoice=?', $data['data']['object']['metadata']['Invoice ID'] );
|
||||
}
|
||||
|
||||
$transaction = \IPS\nexus\Transaction::constructFromData( \IPS\Db::i()->select( '*', 'nexus_transactions', $where )->first() );
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( 'COULD_NOT_FIND_TRANSACTION', 403, 'text/plain' );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
if ( $transaction->status !== \IPS\nexus\Transaction::STATUS_PENDING and $transaction->status !== \IPS\nexus\Transaction::STATUS_WAITING )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( 'BAD_STATUS', 403, 'text/plain' );
|
||||
if ( $transaction->status === \IPS\nexus\Transaction::STATUS_GATEWAY_PENDING )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( 'ALREADY_PROCESSED', 200, 'text/plain' );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( 'BAD_STATUS', 403, 'text/plain' );
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -110,7 +142,8 @@ try
|
||||
$maxMind = NULL;
|
||||
if ( \IPS\Settings::i()->maxmind_key and ( !\IPS\Settings::i()->maxmind_gateways or \IPS\Settings::i()->maxmind_gateways == '*' or in_array( $transaction->method->id, explode( ',', \IPS\Settings::i()->maxmind_gateways ) ) ) )
|
||||
{
|
||||
$maxMind = new \IPS\nexus\Fraud\MaxMind\Request;
|
||||
$maxMind = new \IPS\nexus\Fraud\MaxMind\Request( FALSE );
|
||||
$maxMind->setIpAddress( $transaction->ip );
|
||||
$maxMind->setTransaction( $transaction );
|
||||
}
|
||||
$fraudResult = $transaction->runFraudCheck( $maxMind );
|
||||
@@ -140,13 +173,38 @@ try
|
||||
{
|
||||
$transaction = \IPS\nexus\Transaction::load( $data['data']['object']['metadata']['Transaction ID'] );
|
||||
}
|
||||
else
|
||||
elseif ( isset( $data['data']['object']['source']['redirect']['return_url'] ) )
|
||||
{
|
||||
$transaction = loadTransaction( $data['data']['object']['source']['redirect']['return_url'] );
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
$where = array( array( 't_gw_id=?', $data['data']['object']['id'] ) );
|
||||
if ( isset( $data['data']['object']['metadata']['Invoice ID'] ) )
|
||||
{
|
||||
$where[] = array( 't_invoice=?', $data['data']['object']['metadata']['Invoice ID'] );
|
||||
}
|
||||
|
||||
$transaction = \IPS\nexus\Transaction::constructFromData( \IPS\Db::i()->select( '*', 'nexus_transactions', $where )->first() );
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( 'COULD_NOT_FIND_TRANSACTION', 403, 'text/plain' );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
if ( $transaction->status !== \IPS\nexus\Transaction::STATUS_GATEWAY_PENDING )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( 'BAD_STATUS', 403, 'text/plain' );
|
||||
if ( $transaction->status === \IPS\nexus\Transaction::STATUS_PAID )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( 'ALREADY_PROCESSED', 200, 'text/plain' );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( 'BAD_STATUS', 403, 'text/plain' );
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -154,7 +212,8 @@ try
|
||||
$maxMind = NULL;
|
||||
if ( \IPS\Settings::i()->maxmind_key and ( !\IPS\Settings::i()->maxmind_gateways or \IPS\Settings::i()->maxmind_gateways == '*' or in_array( $transaction->method->id, explode( ',', \IPS\Settings::i()->maxmind_gateways ) ) ) )
|
||||
{
|
||||
$maxMind = new \IPS\nexus\Fraud\MaxMind\Request;
|
||||
$maxMind = new \IPS\nexus\Fraud\MaxMind\Request( FALSE );
|
||||
$maxMind->setIpAddress( $transaction->ip );
|
||||
$maxMind->setTransaction( $transaction );
|
||||
}
|
||||
|
||||
@@ -193,13 +252,38 @@ try
|
||||
{
|
||||
$transaction = \IPS\nexus\Transaction::load( $data['data']['object']['metadata']['Transaction ID'] );
|
||||
}
|
||||
else
|
||||
elseif ( isset( $data['data']['object']['source']['redirect']['return_url'] ) )
|
||||
{
|
||||
$transaction = loadTransaction( $data['data']['object']['source']['redirect']['return_url'] );
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
$where = array( array( 't_gw_id=?', $data['data']['object']['id'] ) );
|
||||
if ( isset( $data['data']['object']['metadata']['Invoice ID'] ) )
|
||||
{
|
||||
$where[] = array( 't_invoice=?', $data['data']['object']['metadata']['Invoice ID'] );
|
||||
}
|
||||
|
||||
$transaction = \IPS\nexus\Transaction::constructFromData( \IPS\Db::i()->select( '*', 'nexus_transactions', $where )->first() );
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( 'COULD_NOT_FIND_TRANSACTION', 403, 'text/plain' );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
if ( $transaction->status !== \IPS\nexus\Transaction::STATUS_GATEWAY_PENDING )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( 'BAD_STATUS', 403, 'text/plain' );
|
||||
if ( $transaction->status === \IPS\nexus\Transaction::STATUS_REFUSED )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( 'ALREADY_PROCESSED', 200, 'text/plain' );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( 'BAD_STATUS', 403, 'text/plain' );
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
@@ -291,7 +291,7 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
'note_date' => time(),
|
||||
) );
|
||||
|
||||
\IPS\File::claimAttachments( "nexus-note-{$this->member->member_id}-new", $this->member->id, $noteId, 'note' );
|
||||
\IPS\File::claimAttachments( "nexus-note-{$this->member->member_id}-new", $this->member->member_id, $noteId, 'note' );
|
||||
|
||||
$this->member->log( 'note', 'added' );
|
||||
}
|
||||
@@ -434,6 +434,7 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
public function addCard()
|
||||
{
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'global_gateways.js', 'nexus', 'global' ) );
|
||||
$form = \IPS\nexus\Customer\CreditCard::create( $this->member );
|
||||
if ( $form instanceof \IPS\nexus\Customer\CreditCard )
|
||||
{
|
||||
@@ -619,7 +620,7 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
'do' => 'void',
|
||||
'process' => 1,
|
||||
'trans' => $values['void_refund_transactions'],
|
||||
'ba' => $values['void_cancel_billing_agreements'],
|
||||
'ba' => isset( $values['void_cancel_billing_agreements'] ) ? $values['void_cancel_billing_agreements'] : FALSE ,
|
||||
'purch' => $values['void_cancel_purchases'],
|
||||
) ), function( $data ) use ( $member )
|
||||
{
|
||||
|
||||
@@ -55,11 +55,7 @@ class _checkoutsettings extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$requireBillingOptions['domain'] = 'nexus_require_billing_domain';
|
||||
}
|
||||
|
||||
if ( \IPS\Settings::i()->nexus_subs_enabled and \IPS\Db::i()->select( 'COUNT(*)', 'nexus_member_subscription_packages' )->first() )
|
||||
{
|
||||
$requireBillingOptions['subscriptions'] = 'nexus_require_billing_subscriptions';
|
||||
}
|
||||
|
||||
$requireBillingOptions['other'] = 'nexus_require_billing_other';
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
|
||||
@@ -397,6 +397,7 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
/* Display form */
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'global_gateways.js', 'nexus', 'global' ) );
|
||||
return $form;
|
||||
}
|
||||
|
||||
@@ -583,12 +584,12 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
/* What refund options are available? */
|
||||
$method = $transaction->method;
|
||||
$refundMethods = array();
|
||||
$refundMethodToggles = array( 'credit' => array( $transaction->id . '_refund_amount' ) );
|
||||
$refundMethodToggles = array( 'none' => array( $transaction->id . '_refund_reverse_credit' ) );
|
||||
$refundReasons = array();
|
||||
if ( $method and $method::SUPPORTS_REFUNDS )
|
||||
{
|
||||
$refundMethods['gateway'] = $method->_title;
|
||||
$refundMethodToggles['gateway'] = array();
|
||||
$refundMethods['gateway'] = 'transaction_refund';
|
||||
$refundMethodToggles['gateway'] = array( $transaction->id . '_refund_reverse_credit' );
|
||||
if ( $method::SUPPORTS_PARTIAL_REFUNDS )
|
||||
{
|
||||
$refundMethodToggles['gateway'][] = $transaction->id . '_refund_amount';
|
||||
@@ -598,7 +599,11 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
$refundMethodToggles['gateway'][] = $transaction->id . '_refund_reason';
|
||||
}
|
||||
}
|
||||
$refundMethods['credit'] = 'refund_method_credit';
|
||||
if ( $transaction->credit->amount->compare( $transaction->amount->amount ) === -1 )
|
||||
{
|
||||
$refundMethods['credit'] = 'refund_method_credit';
|
||||
$refundMethodToggles['credit'][] = $transaction->id . '_refund_credit_amount';
|
||||
}
|
||||
$refundMethods['none'] = 'refund_method_none';
|
||||
|
||||
/* How do we want to refund? */
|
||||
@@ -613,9 +618,78 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
/* Partial refund? */
|
||||
$field = new \IPS\Helpers\Form\Number( $transaction->id . '_refund_amount', ( $transaction->status === \IPS\nexus\Transaction::STATUS_PART_REFUNDED ? (string) $transaction->amount->amount->subtract( $transaction->partial_refund->amount ) : 0 ), TRUE, array( 'unlimited' => 0, 'unlimitedLang' => \IPS\Member::loggedIn()->language()->addToStack( 'refund_full', FALSE, array( 'sprintf' => array( $transaction->amount ) ) ), 'max' => (string) $transaction->amount->amount->subtract( $transaction->partial_refund->amount ), 'decimals' => TRUE ), NULL, NULL, $transaction->amount->currency, $transaction->id . '_refund_amount' );
|
||||
$field->label = \IPS\Member::loggedIn()->language()->addToStack( 'refund_amount' );
|
||||
$form->add( $field );
|
||||
if ( $method and $method::SUPPORTS_REFUNDS and $method::SUPPORTS_PARTIAL_REFUNDS )
|
||||
{
|
||||
$field = new \IPS\Helpers\Form\Number( $transaction->id . '_refund_amount', 0, TRUE, array(
|
||||
'unlimited' => 0,
|
||||
'unlimitedLang' => (
|
||||
$transaction->partial_refund->amount->isGreaterThanZero()
|
||||
? \IPS\Member::loggedIn()->language()->addToStack( 'refund_full_remaining', FALSE, array( 'sprintf' => array(
|
||||
new \IPS\nexus\Money( $transaction->amount->amount->subtract( $transaction->partial_refund->amount ), $transaction->currency ) )
|
||||
) )
|
||||
: \IPS\Member::loggedIn()->language()->addToStack( 'refund_full', FALSE, array( 'sprintf' => array( $transaction->amount ) ) )
|
||||
),
|
||||
'max' => (string) $transaction->amount->amount->subtract( $transaction->partial_refund->amount ),
|
||||
'decimals' => TRUE
|
||||
), NULL, NULL, $transaction->amount->currency, $transaction->id . '_refund_amount' );
|
||||
$field->label = \IPS\Member::loggedIn()->language()->addToStack( 'refund_amount' );
|
||||
$form->add( $field );
|
||||
if ( $transaction->credit->amount->isGreaterThanZero() )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words[ $transaction->id . '_refund_amount_desc' ] = sprintf( \IPS\Member::loggedIn()->language()->get('refund_amount_descwarn'), $transaction->credit );
|
||||
}
|
||||
}
|
||||
if ( $transaction->credit->amount->compare( $transaction->amount->amount ) === -1 )
|
||||
{
|
||||
$field = new \IPS\Helpers\Form\Number( $transaction->id . '_refund_credit_amount', 0, TRUE, array(
|
||||
'unlimited' => 0,
|
||||
'unlimitedLang' => (
|
||||
$transaction->credit->amount->isGreaterThanZero()
|
||||
? \IPS\Member::loggedIn()->language()->addToStack( 'refund_full_remaining', FALSE, array( 'sprintf' => array(
|
||||
new \IPS\nexus\Money( $transaction->amount->amount->subtract( $transaction->credit->amount ), $transaction->currency ) )
|
||||
) )
|
||||
: \IPS\Member::loggedIn()->language()->addToStack( 'refund_full', FALSE, array( 'sprintf' => array( $transaction->amount ) ) )
|
||||
),
|
||||
'max' => (string) $transaction->amount->amount->subtract( $transaction->credit->amount ),
|
||||
'decimals' => TRUE
|
||||
), NULL, NULL, $transaction->amount->currency, $transaction->id . '_refund_credit_amount' );
|
||||
$field->label = \IPS\Member::loggedIn()->language()->addToStack( 'refund_credit_amount' );
|
||||
$form->add( $field );
|
||||
|
||||
if ( $transaction->partial_refund->amount->isGreaterThanZero() )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words[ $transaction->id . '_refund_credit_amount_desc' ] = sprintf( \IPS\Member::loggedIn()->language()->get('refund_credit_amount_descwarn'), $transaction->partial_refund );
|
||||
}
|
||||
}
|
||||
|
||||
/* Reverse credit? */
|
||||
if ( $transaction->credit->amount->isGreaterThanZero() )
|
||||
{
|
||||
$field = new \IPS\Helpers\Form\YesNo( $transaction->id . '_refund_reverse_credit', TRUE, TRUE, array( 'togglesOn' => array( "form_{$transaction->id}_refund_reverse_credit_warning" ) ), NULL, NULL, NULL, $transaction->id . '_refund_reverse_credit' );
|
||||
$field->label = \IPS\Member::loggedIn()->language()->addToStack( 'refund_reverse_credit', FALSE, array( 'sprintf' => array( $transaction->credit ) ) );
|
||||
\IPS\Member::loggedIn()->language()->words[ $transaction->id . '_refund_reverse_credit_desc' ] = \IPS\Member::loggedIn()->language()->addToStack( 'refund_reverse_credit_desc' );
|
||||
$form->add( $field );
|
||||
|
||||
$credits = $transaction->member->cm_credits;
|
||||
if ( $credits[ $transaction->amount->currency ]->amount->compare( $transaction->credit->amount ) === -1 )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words[ $transaction->id . '_refund_reverse_credit_warning' ] = \IPS\Member::loggedIn()->language()->addToStack( 'account_credit_remove_neg' );
|
||||
}
|
||||
}
|
||||
|
||||
/* Billing Agreement? */
|
||||
if ( $billingAgreement = $transaction->billing_agreement )
|
||||
{
|
||||
$field = new \IPS\Helpers\Form\YesNo( $transaction->id . '_refund_cancel_billing_agreement', TRUE, NULL, array( 'togglesOff' => array( "form_{$transaction->id}_refund_cancel_billing_agreement_warning" ) ) );
|
||||
$field->label = \IPS\Member::loggedIn()->language()->addToStack( 'refund_cancel_billing_agreement' );
|
||||
\IPS\Member::loggedIn()->language()->words[ $transaction->id . '_refund_cancel_billing_agreement_desc' ] = \IPS\Member::loggedIn()->language()->addToStack( 'refund_cancel_billing_agreement_desc' );
|
||||
if ( !\IPS\Db::i()->select( 'COUNT(*)', 'nexus_transactions', array( 't_billing_agreement=? AND t_id<?', $billingAgreement->id, $transaction->id ) )->first() )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words[ $transaction->id . '_refund_cancel_billing_agreement_warning' ] = \IPS\Member::loggedIn()->language()->addToStack( 'refund_cancel_billing_agreement_warning' );
|
||||
}
|
||||
|
||||
$form->add( $field );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -655,9 +729,41 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
foreach ( $transactions as $transaction )
|
||||
{
|
||||
/* Handle billing agreement */
|
||||
if ( $transaction->billing_agreement )
|
||||
{
|
||||
if ( isset( $values[ $transaction->id . '_refund_cancel_billing_agreement' ] ) and $values[ $transaction->id . '_refund_cancel_billing_agreement' ] )
|
||||
{
|
||||
try
|
||||
{
|
||||
$transaction->billing_agreement->cancel();
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'billing_agreement_cancel_error', '3X190/G', 500, '', array(), $e->getMessage() );
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Reverse credit */
|
||||
if ( $values[ $transaction->id . '_refund_method' ] !== 'credit' and isset( $values[ $transaction->id . '_refund_reverse_credit' ] ) and $values[ $transaction->id . '_refund_reverse_credit' ] )
|
||||
{
|
||||
$transaction->reverseCredit();
|
||||
}
|
||||
|
||||
/* Refund */
|
||||
try
|
||||
{
|
||||
$transaction->refund( $values[ $transaction->id . '_refund_method' ], $values[ $transaction->id . '_refund_amount' ], isset( $values[ $transaction->id . '_refund_reason' ] ) ? $values[ $transaction->id . '_refund_reason' ] : NULL );
|
||||
$amount = NULL;
|
||||
if ( $values[ $transaction->id . '_refund_method' ] === 'gateway' and isset( $values[ $transaction->id . '_refund_amount' ] ) )
|
||||
{
|
||||
$amount = $values[ $transaction->id . '_refund_amount' ];
|
||||
}
|
||||
elseif ( $values[ $transaction->id . '_refund_method' ] === 'credit' and isset( $values[ $transaction->id . '_refund_credit_amount' ] ) )
|
||||
{
|
||||
$amount = $values[ $transaction->id . '_refund_credit_amount' ];
|
||||
}
|
||||
|
||||
$transaction->refund( $values[ $transaction->id . '_refund_method' ], $amount, isset( $values[ $transaction->id . '_refund_reason' ] ) ? $values[ $transaction->id . '_refund_reason' ] : NULL );
|
||||
}
|
||||
catch ( \LogicException $e )
|
||||
{
|
||||
|
||||
@@ -308,12 +308,12 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
|
||||
/* What are the refund methods? */
|
||||
$refundMethods = array();
|
||||
$refundMethodToggles = array( 'credit' => array( 'refund_amount' ) );
|
||||
$refundMethodToggles = array( 'none' => array( 'refund_reverse_credit' ) );
|
||||
$refundReasons = array();
|
||||
if ( $method and $method::SUPPORTS_REFUNDS )
|
||||
{
|
||||
$refundMethods['gateway'] = $method->_title;
|
||||
$refundMethodToggles['gateway'] = array();
|
||||
$refundMethods['gateway'] = 'transaction_refund';
|
||||
$refundMethodToggles['gateway'] = array( 'refund_reverse_credit' );
|
||||
if ( $method::SUPPORTS_PARTIAL_REFUNDS )
|
||||
{
|
||||
$refundMethodToggles['gateway'][] = 'refund_amount';
|
||||
@@ -323,7 +323,11 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
$refundMethodToggles['gateway'][] = 'refund_reason';
|
||||
}
|
||||
}
|
||||
$refundMethods['credit'] = 'refund_method_credit';
|
||||
if ( $transaction->credit->amount->compare( $transaction->amount->amount ) === -1 )
|
||||
{
|
||||
$refundMethods['credit'] = 'refund_method_credit';
|
||||
$refundMethodToggles['credit'][] = 'refund_credit_amount';
|
||||
}
|
||||
$refundMethods['none'] = 'refund_method_none';
|
||||
|
||||
/* Build form */
|
||||
@@ -333,16 +337,57 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'refund_reason', NULL, FALSE, array( 'options' => $refundReasons ), NULL, NULL, NULL, 'refund_reason' ) );
|
||||
}
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'refund_amount', 0, TRUE, array(
|
||||
'unlimited' => 0,
|
||||
'unlimitedLang' => (
|
||||
$transaction->status === \IPS\nexus\Transaction::STATUS_PART_REFUNDED
|
||||
? \IPS\Member::loggedIn()->language()->addToStack( 'refund_full_remaining', FALSE, array( 'sprintf' => array( new \IPS\nexus\Money( $transaction->amount->amount->subtract( $transaction->partial_refund->amount ), $transaction->currency ) ) ) )
|
||||
: \IPS\Member::loggedIn()->language()->addToStack( 'refund_full', FALSE, array( 'sprintf' => array( $transaction->amount ) ) )
|
||||
),
|
||||
'max' => (string) $transaction->amount->amount->subtract( $transaction->partial_refund->amount ),
|
||||
'decimals' => TRUE
|
||||
), NULL, NULL, $transaction->amount->currency, 'refund_amount' ) );
|
||||
if ( $method and $method::SUPPORTS_REFUNDS and $method::SUPPORTS_PARTIAL_REFUNDS )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'refund_amount', 0, TRUE, array(
|
||||
'unlimited' => 0,
|
||||
'unlimitedLang' => (
|
||||
$transaction->partial_refund->amount->isGreaterThanZero()
|
||||
? \IPS\Member::loggedIn()->language()->addToStack( 'refund_full_remaining', FALSE, array( 'sprintf' => array(
|
||||
new \IPS\nexus\Money( $transaction->amount->amount->subtract( $transaction->partial_refund->amount ), $transaction->currency ) )
|
||||
) )
|
||||
: \IPS\Member::loggedIn()->language()->addToStack( 'refund_full', FALSE, array( 'sprintf' => array( $transaction->amount ) ) )
|
||||
),
|
||||
'max' => (string) $transaction->amount->amount->subtract( $transaction->partial_refund->amount ),
|
||||
'decimals' => TRUE
|
||||
), NULL, NULL, $transaction->amount->currency, 'refund_amount' ) );
|
||||
|
||||
if ( $transaction->credit->amount->isGreaterThanZero() )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['refund_amount_desc'] = sprintf( \IPS\Member::loggedIn()->language()->get('refund_amount_descwarn'), $transaction->credit );
|
||||
}
|
||||
}
|
||||
if ( $transaction->credit->amount->compare( $transaction->amount->amount ) === -1 )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'refund_credit_amount', 0, TRUE, array(
|
||||
'unlimited' => 0,
|
||||
'unlimitedLang' => (
|
||||
$transaction->credit->amount->isGreaterThanZero()
|
||||
? \IPS\Member::loggedIn()->language()->addToStack( 'refund_full_remaining', FALSE, array( 'sprintf' => array(
|
||||
new \IPS\nexus\Money( $transaction->amount->amount->subtract( $transaction->credit->amount ), $transaction->currency ) )
|
||||
) )
|
||||
: \IPS\Member::loggedIn()->language()->addToStack( 'refund_full', FALSE, array( 'sprintf' => array( $transaction->amount ) ) )
|
||||
),
|
||||
'max' => (string) $transaction->amount->amount->subtract( $transaction->credit->amount ),
|
||||
'decimals' => TRUE
|
||||
), NULL, NULL, $transaction->amount->currency, 'refund_credit_amount' ) );
|
||||
|
||||
if ( $transaction->partial_refund->amount->isGreaterThanZero() )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['refund_credit_amount_desc'] = sprintf( \IPS\Member::loggedIn()->language()->get('refund_credit_amount_descwarn'), $transaction->partial_refund );
|
||||
}
|
||||
}
|
||||
if ( $transaction->credit->amount->isGreaterThanZero() )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'refund_reverse_credit', TRUE, TRUE, array( 'togglesOn' => array( 'form_refund_reverse_credit_warning' ) ), NULL, NULL, NULL, 'refund_reverse_credit' ) );
|
||||
\IPS\Member::loggedIn()->language()->words['refund_reverse_credit'] = sprintf( \IPS\Member::loggedIn()->language()->get( 'refund_reverse_credit' ), $transaction->credit );
|
||||
|
||||
$credits = $transaction->member->cm_credits;
|
||||
if ( $credits[ $transaction->amount->currency ]->amount->compare( $transaction->credit->amount ) === -1 )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['refund_reverse_credit_warning'] = \IPS\Member::loggedIn()->language()->addToStack( 'account_credit_remove_neg' );
|
||||
}
|
||||
}
|
||||
if ( $transaction->invoice !== NULL and $transaction->invoice->status === \IPS\nexus\Invoice::STATUS_PAID )
|
||||
{
|
||||
$field = new \IPS\Helpers\Form\Radio( 'refund_invoice_status', \IPS\nexus\Invoice::STATUS_PENDING, TRUE, array(
|
||||
@@ -359,14 +404,55 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
$field->warningBox = \IPS\Theme::i()->getTemplate('invoices')->unpaidConsequences( $transaction->invoice );
|
||||
$form->add( $field );
|
||||
}
|
||||
if ( $billingAgreement = $transaction->billing_agreement )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'refund_cancel_billing_agreement', TRUE, NULL, array( 'togglesOff' => array( 'form_refund_cancel_billing_agreement_warning' ) ) ) );
|
||||
|
||||
if ( \IPS\Db::i()->select( 'COUNT(*)', 'nexus_transactions', array( 't_billing_agreement=? AND t_id<?', $billingAgreement->id, $transaction->id ) )->first() )
|
||||
{
|
||||
unset( \IPS\Member::loggedIn()->language()->words['refund_cancel_billing_agreement_warning'] );
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle submissions */
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
/* Handle billing agreement */
|
||||
if ( $transaction->billing_agreement )
|
||||
{
|
||||
if ( isset( $values['refund_cancel_billing_agreement'] ) and $values['refund_cancel_billing_agreement'] )
|
||||
{
|
||||
try
|
||||
{
|
||||
$transaction->billing_agreement->cancel();
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'billing_agreement_cancel_error', '3X186/G', 500, '', array(), $e->getMessage() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Reverse credit */
|
||||
if ( $values['refund_method'] !== 'credit' and isset( $values['refund_reverse_credit'] ) and $values['refund_reverse_credit'] )
|
||||
{
|
||||
$transaction->reverseCredit();
|
||||
}
|
||||
|
||||
/* Refund */
|
||||
try
|
||||
{
|
||||
$transaction->refund( $values['refund_method'], $values['refund_amount'], isset( $values['refund_reason'] ) ? $values['refund_reason'] : NULL );
|
||||
$amount = NULL;
|
||||
if ( $values['refund_method'] === 'gateway' and isset( $values['refund_amount'] ) )
|
||||
{
|
||||
$amount = $values['refund_amount'];
|
||||
}
|
||||
elseif ( $values['refund_method'] === 'credit' and isset( $values['refund_credit_amount'] ) )
|
||||
{
|
||||
$amount = $values['refund_credit_amount'];
|
||||
}
|
||||
|
||||
$transaction->refund( $values['refund_method'], $amount, isset( $values['refund_reason'] ) ? $values['refund_reason'] : NULL );
|
||||
}
|
||||
catch ( \LogicException $e )
|
||||
{
|
||||
|
||||
@@ -82,7 +82,7 @@ class _income extends \IPS\Dispatcher\Controller
|
||||
array(),
|
||||
$activeTab
|
||||
);
|
||||
$chart->where[] = array( '( t_status=? OR t_status=? )', \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED );
|
||||
$chart->where[] = array( '( t_status=? OR t_status=? ) AND t_method>0', \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED );
|
||||
|
||||
if ( $activeTab === 'totals' )
|
||||
{
|
||||
|
||||
@@ -151,6 +151,7 @@ class _checkout extends \IPS\Dispatcher\Controller
|
||||
try
|
||||
{
|
||||
$this->invoice->billaddress = \IPS\nexus\Customer\Address::constructFromData( \IPS\Db::i()->select( '*', 'nexus_customer_addresses', array( 'member=? AND primary_billing=1', \IPS\Member::loggedIn()->member_id ) )->first() )->address;
|
||||
$this->invoice->recalculateTotal();
|
||||
$this->invoice->save();
|
||||
$_SESSION[ 'wizard-' . md5( $checkoutUrl ) . '-step' ] = isset( $steps['checkout_shipping'] ) ? 'checkout_shipping' : 'checkout_pay';
|
||||
}
|
||||
@@ -418,17 +419,7 @@ class _checkout extends \IPS\Dispatcher\Controller
|
||||
|
||||
/* Misc */
|
||||
$form->add( new \IPS\Helpers\Form\Checkbox( 'reg_admin_mails', $guestData ? $guestData['member']['allow_admin_mails'] : \IPS\Settings::i()->updates_consent_default == 'enabled' ? TRUE : FALSE, FALSE ) );
|
||||
\IPS\Member::loggedIn()->language()->words[ "reg_agreed_terms" ] = sprintf( \IPS\Member::loggedIn()->language()->get("reg_agreed_terms"), \IPS\Http\Url::internal( 'app=core&module=system&controller=terms', 'front', 'terms', array(), \IPS\Http\Url::PROTOCOL_RELATIVE ) );
|
||||
|
||||
/* Build the appropriate links for registration terms & privacy policy */
|
||||
if ( \IPS\Settings::i()->privacy_type == "internal" )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words[ "reg_agreed_terms" ] .= sprintf( \IPS\Member::loggedIn()->language()->get("reg_privacy_link"), \IPS\Http\Url::internal( 'app=core&module=system&controller=privacy', 'front', 'privacy', array(), \IPS\Http\Url::PROTOCOL_RELATIVE ), 'data-ipsDialog data-ipsDialog-size="wide" data-ipsDialog-title="' . \IPS\Member::loggedIn()->language()->get("privacy") . '"' );
|
||||
}
|
||||
else if ( \IPS\Settings::i()->privacy_type == "external" )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words[ "reg_agreed_terms" ] .= sprintf( \IPS\Member::loggedIn()->language()->get("reg_privacy_link"), \IPS\Http\Url::external( \IPS\Settings::i()->privacy_link ), 'target="_blank"' );
|
||||
}
|
||||
\IPS\core\modules\front\system\register::buildRegistrationTerm();
|
||||
$form->add( new \IPS\Helpers\Form\Checkbox( 'reg_agreed_terms', (bool) $guestData, TRUE, array(), function( $val )
|
||||
{
|
||||
if ( !$val )
|
||||
@@ -479,7 +470,7 @@ class _checkout extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
if ( isset( $securityQuestionAnswers[ $v ] ) )
|
||||
{
|
||||
$form->error = \IPS\Member::loggedIn()->language()->addToStack('security_questions_unique');
|
||||
$form->error = \IPS\Member::loggedIn()->language()->addToStack( 'security_questions_unique', FALSE, array( 'pluralize' => array( \IPS\Settings::i()->security_questions_number ?: 3 ) ) );
|
||||
break;
|
||||
}
|
||||
else
|
||||
@@ -646,6 +637,7 @@ class _checkout extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
/* Save */
|
||||
$this->invoice->recalculateTotal();
|
||||
$this->invoice->save();
|
||||
return array();
|
||||
}
|
||||
@@ -1243,6 +1235,11 @@ class _checkout extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
foreach ( $paymentMethods as $k => $v )
|
||||
{
|
||||
if ( in_array( '*', $item->paymentMethodIds ) ) // This looks odd but in older versions IPS\nexus\extensions\nexus\Item\Subscription::renewalPaymentMethodIds() was mistakenly returning array('*') and since the value is stored in the invoice we have to keep this for compatibility with invoices created at that time
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !in_array( $k, $item->paymentMethodIds ) )
|
||||
{
|
||||
unset( $paymentMethods[ $k ] );
|
||||
@@ -1312,7 +1309,7 @@ class _checkout extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
if ( \IPS\Settings::i()->nexus_tac === 'checkbox' )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Checkbox( 'i_agree_to_tac', FALSE, TRUE, array( 'labelHtmlSprintf' => array( "<a href='" . htmlspecialchars( \IPS\Settings::i()->nexus_tac_link, ENT_DISALLOWED, 'UTF-8', FALSE ) . "' target='_blank'>" . \IPS\Member::loggedIn()->language()->addToStack( 'terms_and_conditions' ) . '</a>' ) ), function( $val )
|
||||
$form->add( new \IPS\Helpers\Form\Checkbox( 'i_agree_to_tac', FALSE, TRUE, array( 'labelHtmlSprintf' => array( "<a href='" . htmlspecialchars( \IPS\Settings::i()->nexus_tac_link, ENT_DISALLOWED, 'UTF-8', FALSE ) . "' target='_blank' rel='noopener'>" . \IPS\Member::loggedIn()->language()->addToStack( 'terms_and_conditions' ) . '</a>' ) ), function( $val )
|
||||
{
|
||||
if ( !$val )
|
||||
{
|
||||
@@ -1512,7 +1509,7 @@ class _checkout extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$invoice->addItem( $values['coupon_code'] );
|
||||
$invoice->save();
|
||||
\IPS\Output::i()->redirect( $invoice->checkoutUrl() );
|
||||
\IPS\Output::i()->redirect( $invoice->checkoutUrl()->setQueryString( '_step', 'checkout_pay' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ class _cards extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'global_gateways.js', 'nexus', 'global' ) );
|
||||
$form = \IPS\nexus\Customer\CreditCard::create( \IPS\nexus\Customer::loggedIn() );
|
||||
if ( $form instanceof \IPS\nexus\Customer\CreditCard )
|
||||
{
|
||||
@@ -111,8 +112,10 @@ class _cards extends \IPS\Dispatcher\Controller
|
||||
$card = \IPS\nexus\Customer\CreditCard::load( \IPS\Request::i()->id );
|
||||
if ( $card->member->member_id === \IPS\nexus\Customer::loggedIn()->member_id )
|
||||
{
|
||||
$cardData = $card->card;
|
||||
|
||||
$card->delete();
|
||||
\IPS\nexus\Customer::loggedIn()->log( 'card', array( 'type' => 'delete', 'number' => $card->card->lastFour ) );
|
||||
\IPS\nexus\Customer::loggedIn()->log( 'card', array( 'type' => 'delete', 'number' => $cardData->lastFour ) );
|
||||
}
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
|
||||
@@ -59,6 +59,16 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
\IPS\Output::i()->error( 'node_error', '2X215/5', 404, '' );
|
||||
}
|
||||
}
|
||||
else if ( isset( \IPS\Request::i()->do ) and \IPS\Request::i()->do == 'printout' and isset( \IPS\Request::i()->key ) )
|
||||
{
|
||||
$this->invoice = \IPS\nexus\Invoice::load( \IPS\Request::i()->id );
|
||||
$guest = $this->invoice->guest_data;
|
||||
|
||||
if ( md5( $guest['member']['email'] . ';' . $guest['member']['joined'] ) != \IPS\Request::i()->key )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X215/7', 404, '' );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->error( 'no_module_permission_guest', '2X215/6', 404, '' );
|
||||
|
||||
@@ -243,7 +243,7 @@ class _product extends \IPS\Content\Controller
|
||||
\IPS\Output::i()->jsonLd['package']['image'] = (string) $package->image;
|
||||
}
|
||||
|
||||
if( $package->reviewable )
|
||||
if( $package->reviewable AND $item->averageReviewRating() )
|
||||
{
|
||||
\IPS\Output::i()->jsonLd['package']['aggregateRating'] = array(
|
||||
'@type' => 'AggregateRating',
|
||||
@@ -323,9 +323,9 @@ class _product extends \IPS\Content\Controller
|
||||
{
|
||||
$customFields = \IPS\nexus\Package\CustomField::roots();
|
||||
$stickyFields = array();
|
||||
foreach ( $item->details as $k => $v )
|
||||
foreach ( $item->details as $_k => $v )
|
||||
{
|
||||
if ( $v and isset( $customFields[ $k ] ) and $customFields[ $k ]->sticky )
|
||||
if ( $v and isset( $customFields[ $_k ] ) and $customFields[ $_k ]->sticky )
|
||||
{
|
||||
$stickyFields[] = $v;
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ class _store extends \IPS\Dispatcher\Controller
|
||||
\IPS\Output::i()->jsonLd['package' . $package->id ]['image'] = (string) $package->image;
|
||||
}
|
||||
|
||||
if( $package->reviewable )
|
||||
if( $package->reviewable and $item->averageReviewRating() )
|
||||
{
|
||||
\IPS\Output::i()->jsonLd['package' . $package->id ]['aggregateRating'] = array(
|
||||
'@type' => 'AggregateRating',
|
||||
|
||||
@@ -194,6 +194,12 @@ class _subscriptions extends \IPS\Dispatcher\Controller
|
||||
/* CSRF Check */
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
/* Already purchased a subscription? */
|
||||
if ( \IPS\nexus\Subscription::loadActiveByMember( \IPS\nexus\Customer::loggedIn() ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'nexus_subs_already_got_package', '2X379/6', 403, '' );
|
||||
}
|
||||
|
||||
$package = \IPS\nexus\Subscription\Package::load( \IPS\Request::i()->id );
|
||||
$price = $package->price();
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"1": {
|
||||
"method": "delete",
|
||||
"params": [
|
||||
"core_sys_lang_words",
|
||||
"word_app='nexus' AND ( word_key IN ( 'customer_no_history', 'see_all_history' ) )"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"1": {
|
||||
"method": "addColumn",
|
||||
"params": [
|
||||
"nexus_transactions",
|
||||
{
|
||||
"name": "t_credit",
|
||||
"type": "DECIMAL",
|
||||
"length": 10,
|
||||
"decimals": 3,
|
||||
"values": null,
|
||||
"allow_null": true,
|
||||
"default": null,
|
||||
"comment": "If transaction has been partially credited (refund to account credit), the amount that was credited",
|
||||
"unsigned": true,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"2": {
|
||||
"method": "changeColumn",
|
||||
"params": [
|
||||
"nexus_reviews",
|
||||
"review_ip_address",
|
||||
{
|
||||
"name": "review_ip_address",
|
||||
"type": "VARCHAR",
|
||||
"length": 46,
|
||||
"decimals": null,
|
||||
"values": [],
|
||||
"allow_null": true,
|
||||
"default": null,
|
||||
"comment": "",
|
||||
"unsigned": false,
|
||||
"zerofill": false,
|
||||
"auto_increment": false,
|
||||
"binary": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief 4.3.5 Beta 1 Upgrade Code
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
* @subpackage Commerce
|
||||
* @since 21 Jun 2018
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\setup\upg_103026;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* 4.3.5 Beta 1 Upgrade Code
|
||||
*/
|
||||
class _Upgrade
|
||||
{
|
||||
/**
|
||||
* Initate FixRefundTransactions background task
|
||||
*
|
||||
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
|
||||
*/
|
||||
public function step1()
|
||||
{
|
||||
\IPS\Task::queue( 'nexus', 'FixRefundTransactions' );
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -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(),
|
||||
|
||||
@@ -125,7 +125,7 @@ class _billingAgreements extends \IPS\Task
|
||||
}
|
||||
$billingAgreement->save();
|
||||
}
|
||||
catch ( \IPS\Http\Exception $e )
|
||||
catch ( \IPS\Http\Url\Exception $e )
|
||||
{
|
||||
/* Just log the issue, but don't do anything here,.. this was probably a temporary issue so let the next call run this again */
|
||||
\IPS\Log::log( $e, 'ba_sync_fail' );
|
||||
|
||||
@@ -38,31 +38,51 @@ class _capture extends \IPS\Task
|
||||
{
|
||||
$taskFrequency = new \DateInterval( $this->frequency );
|
||||
$time = \IPS\DateTime::create()->add( $taskFrequency )->add( $taskFrequency );
|
||||
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_transactions', array( 't_auth<?', $time->getTimestamp() ) ), 'IPS\nexus\Transaction' ) as $transaction )
|
||||
|
||||
$this->runUntilTimeout( function() use ( $time )
|
||||
{
|
||||
if ( $transaction->method )
|
||||
try
|
||||
{
|
||||
try
|
||||
$transaction = \IPS\nexus\Transaction::constructFromData( \IPS\Db::i()->select( '*', 'nexus_transactions', array( 't_auth<?', $time->getTimestamp() ), 't_auth ASC', 1 )->first() );
|
||||
|
||||
if ( $transaction->method )
|
||||
{
|
||||
$transaction->capture();
|
||||
try
|
||||
{
|
||||
$transaction->capture();
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
if ( in_array( $transaction->status, array( $transaction::STATUS_PENDING, $transaction::STATUS_WAITING, $transaction::STATUS_GATEWAY_PENDING ) ) )
|
||||
{
|
||||
$transaction->status = \IPS\nexus\Transaction::STATUS_REFUSED;
|
||||
$extra = $transaction->extra;
|
||||
$extra['history'][] = array( 's' => \IPS\nexus\Transaction::STATUS_REFUSED, 'noteRaw' => $e->getMessage() );
|
||||
$transaction->extra = $extra;
|
||||
}
|
||||
|
||||
$transaction->auth = NULL;
|
||||
$transaction->save();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* the gateway doesn't exist anymore, so reset the auth time */
|
||||
$transaction->auth = NULL;
|
||||
$extra = $transaction->extra;
|
||||
$extra['history'][] = array( 's' => \IPS\nexus\Transaction::STATUS_REFUSED, 'on' => time(), 'noteRaw' => 'invalid_gateway' );
|
||||
$transaction->extra = $extra;
|
||||
$transaction->status = \IPS\nexus\Transaction::STATUS_REFUSED;
|
||||
$transaction->save();
|
||||
|
||||
throw new \IPS\Task\Exception( $this, array( 'invalid_gateway', $transaction->id ) );
|
||||
}
|
||||
catch ( \Exception $e ) {}
|
||||
}
|
||||
else
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
/* the gateway doesn't exist anymore, so reset the auth time */
|
||||
$transaction->auth = NULL;
|
||||
$extra = $transaction->extra;
|
||||
$extra['history'][] = array( 's' => \IPS\nexus\Transaction::STATUS_REFUSED, 'on' => time(), 'noteRaw' => 'invalid_gateway' );
|
||||
$transaction->extra = $extra;
|
||||
$transaction->status = \IPS\nexus\Transaction::STATUS_REFUSED;
|
||||
$transaction->save();
|
||||
|
||||
throw new \IPS\Task\Exception( $this, \IPS\Member::loggedIn()->language()->addToStack( 'invalid_gateway', FALSE, array( 'sprintf' => array( $transaction->id ) ) ) );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -65,9 +65,10 @@ class _supportAutoresolve extends \IPS\Task
|
||||
array( 'r_ar_notify=0' )
|
||||
) );
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_support_requests', $warningWhere ), 'IPS\nexus\Support\Request' ) as $request )
|
||||
{
|
||||
$email = \IPS\Email::buildFromTemplate( 'nexus', 'autoresolveWarning', array( $request, \IPS\DateTime::ts( $request->last_reply )->add( new \DateInterval( 'P' . \IPS\Settings::i()->nexus_autoresolve_days . 'D' ) )->relative() ), \IPS\Email::TYPE_TRANSACTIONAL );
|
||||
$email->send( $request->email ?: $request->author() );
|
||||
{
|
||||
$fromEmail = $request->department->email ?: \IPS\Settings::i()->email_out;
|
||||
$email = \IPS\Email::buildFromTemplate( 'nexus', 'autoresolveWarning', array( $request, \IPS\DateTime::ts( $request->last_reply )->add( new \DateInterval( 'P' . \IPS\Settings::i()->nexus_autoresolve_days . 'D' ) ) ), \IPS\Email::TYPE_TRANSACTIONAL );
|
||||
$email->send( $request->email ?: $request->author(), array(), array(), $fromEmail, NULL, array( 'Message-Id' => "<IPS-000-SR{$request->id}.{$request->email_key}-{$fromEmail}>" ) );
|
||||
|
||||
$request->ar_notify = TRUE;
|
||||
$request->save();
|
||||
|
||||
Reference in new issue
Block a user