Version 4.1.19
This commit is contained in:
1 parent
28bd025b35
commit
2bd5025018
2674 files changed
+233518
-77766
No files matched your search
@@ -2,10 +2,10 @@
|
||||
/**
|
||||
* @brief Comission Rules
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 15 Aug 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
/**
|
||||
* @brief fields
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 12 May 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Purchases
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 11 Feb 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -52,6 +52,16 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
$this->view();
|
||||
}
|
||||
|
||||
/**
|
||||
* View
|
||||
*
|
||||
@@ -131,20 +141,23 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
/* Work stuff out */
|
||||
$renewals = $this->purchase->renewals ?: NULL;
|
||||
$groupedChildren = array();
|
||||
if ( $renewals and \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_parent=? AND ps_grouped_renewals<>?', $this->purchase->id, '' ) )->first() )
|
||||
if ( $renewals and \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_parent=? AND ps_grouped_renewals<>? AND ps_cancelled=0', $this->purchase->id, '' ) )->first() )
|
||||
{
|
||||
$costPerDay = $this->purchase->renewals->costPerDay()->amount;
|
||||
$renewals = $this->purchase->renewals;
|
||||
foreach ( $this->purchase->children() as $child )
|
||||
{
|
||||
if ( $child->grouped_renewals )
|
||||
if ( $child->grouped_renewals and !$child->cancelled )
|
||||
{
|
||||
$groupedChildren[] = $child;
|
||||
$childGroupedRenewals = $child->grouped_renewals;
|
||||
$childGroupedRenewalTerm = new \IPS\nexus\Purchase\RenewalTerm( new \IPS\nexus\Money( $childGroupedRenewals['price'], $this->purchase->renewals->cost->currency ), new \DateInterval( 'P' . $childGroupedRenewals['term'] . mb_strtoupper( $childGroupedRenewals['unit'] ) ) );
|
||||
$costPerDay -= $childGroupedRenewalTerm->costPerDay()->amount;
|
||||
try
|
||||
{
|
||||
$childGroupedRenewalTerm = new \IPS\nexus\Purchase\RenewalTerm( new \IPS\nexus\Money( $childGroupedRenewals['price'], $this->purchase->renewals->cost->currency ), new \DateInterval( 'P' . $childGroupedRenewals['term'] . mb_strtoupper( $childGroupedRenewals['unit'] ) ) );
|
||||
$renewals = new \IPS\nexus\Purchase\RenewalTerm( $renewals->subtract( $childGroupedRenewalTerm ), $renewals->interval );
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
}
|
||||
}
|
||||
$renewals = new \IPS\nexus\Purchase\RenewalTerm( new \IPS\nexus\Money( $costPerDay * $renewals->days(), $this->purchase->renewals->cost->currency ), $renewals->interval );
|
||||
}
|
||||
|
||||
/* Build form */
|
||||
@@ -192,6 +205,10 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
\IPS\Output::i()->error( 'not_with_grouped', '2X195/6', 403, '' );
|
||||
}
|
||||
if ( $this->purchase->billing_agreement and !$this->purchase->billing_agreement->canceled )
|
||||
{
|
||||
\IPS\Output::i()->error( 'not_with_billing_agreement', '2X195/G', 403, '' );
|
||||
}
|
||||
|
||||
/* Build form */
|
||||
$form = new \IPS\Helpers\Form;
|
||||
@@ -223,21 +240,22 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
public function renew()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'purchases_edit', 'nexus', 'payments' );
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'invoices_add', 'nexus', 'payments' );
|
||||
|
||||
if ( $this->purchase->grouped_renewals )
|
||||
{
|
||||
\IPS\Output::i()->error( 'not_with_grouped', '2X195/7', 403, '' );
|
||||
}
|
||||
if ( $this->purchase->billing_agreement and !$this->purchase->billing_agreement->canceled )
|
||||
{
|
||||
\IPS\Output::i()->error( 'not_with_billing_agreement', '2X195/D', 403, '' );
|
||||
}
|
||||
|
||||
/* If this purchase has renewal term, we cannot generate a renewal invoice */
|
||||
if ( !$this->purchase->renewals )
|
||||
{
|
||||
\IPS\Output::i()->error( 'purchase_no_renew', '2X195/3', 403, '' );
|
||||
}
|
||||
if ( !$this->purchase->expire )
|
||||
{
|
||||
\IPS\Output::i()->error( 'purchase_no_expire', '1X195/C', 403, '' );
|
||||
}
|
||||
|
||||
/* Build form */
|
||||
$form = new \IPS\Helpers\Form;
|
||||
@@ -290,9 +308,12 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
protected function cancel()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'purchases_cancel' );
|
||||
if ( $this->purchase->grouped_renewals )
|
||||
|
||||
$parent = $this->purchase->parent();
|
||||
|
||||
if ( ( $this->purchase->billing_agreement and !$this->purchase->billing_agreement->canceled ) or ( $this->purchase->grouped_renewals and $parent->billing_agreement and !$parent->billing_agreement->canceled ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'not_with_grouped', '2X195/8', 403, '' );
|
||||
\IPS\Output::i()->error( 'not_with_billing_agreement', '2X195/H', 403, '' );
|
||||
}
|
||||
|
||||
/* What options are available for cancelling? */
|
||||
@@ -307,12 +328,25 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'cancel_type', 'no_renew', FALSE, array(
|
||||
'options' => $options,
|
||||
'toggles' => array( 'cancel' => array( 'form_cancel_type_warning' ) )
|
||||
) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'ps_can_reactivate', FALSE ) );
|
||||
if ( $onCancelWarning = $this->purchase->onCancelWarning() )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['cancel_type_warning'] = $onCancelWarning;
|
||||
}
|
||||
|
||||
/* Handle submissions */
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
/* If grouped, ungroup */
|
||||
$grouped = $this->purchase->grouped_renewals;
|
||||
if ( $grouped )
|
||||
{
|
||||
$this->purchase->ungroupFromParent();
|
||||
$this->purchase->save();
|
||||
}
|
||||
|
||||
/* Update purchase and log */
|
||||
if ( $values['cancel_type'] === 'no_renew' )
|
||||
{
|
||||
@@ -327,6 +361,13 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
$this->purchase->can_reactivate = $values['ps_can_reactivate'];
|
||||
$this->purchase->save();
|
||||
|
||||
/* If grouped, regroup */
|
||||
if ( $grouped )
|
||||
{
|
||||
$this->purchase->groupWithParent();
|
||||
$this->purchase->save();
|
||||
}
|
||||
|
||||
/* Redirect */
|
||||
$this->_redirect();
|
||||
}
|
||||
@@ -343,15 +384,35 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
protected function reactivate()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'purchases_cancel' );
|
||||
if ( $this->purchase->grouped_renewals )
|
||||
|
||||
$parent = $this->purchase->parent();
|
||||
|
||||
if ( ( $this->purchase->billing_agreement and !$this->purchase->billing_agreement->canceled ) or ( $this->purchase->grouped_renewals and $parent->billing_agreement and !$parent->billing_agreement->canceled ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'not_with_grouped', '2X195/9', 403, '' );
|
||||
\IPS\Output::i()->error( 'not_with_billing_agreement', '2X195/I', 403, '' );
|
||||
}
|
||||
|
||||
/* If grouped, ungroup */
|
||||
$grouped = $this->purchase->grouped_renewals;
|
||||
if ( $grouped )
|
||||
{
|
||||
$this->purchase->ungroupFromParent();
|
||||
$this->purchase->save();
|
||||
}
|
||||
|
||||
/* Do it */
|
||||
$this->purchase->cancelled = FALSE;
|
||||
$this->purchase->save();
|
||||
$this->purchase->member->log( 'purchase', array( 'type' => 'uncancel', 'id' => $this->purchase->id, 'name' => $this->purchase->name ) );
|
||||
|
||||
/* If grouped, regroup */
|
||||
if ( $grouped )
|
||||
{
|
||||
$this->purchase->groupWithParent();
|
||||
$this->purchase->save();
|
||||
}
|
||||
|
||||
/* Redirect */
|
||||
$this->_redirect();
|
||||
}
|
||||
|
||||
@@ -363,16 +424,32 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
protected function delete()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'purchases_delete' );
|
||||
\IPS\Request::i()->confirmedDelete();
|
||||
|
||||
$parent = $this->purchase->parent();
|
||||
|
||||
if ( ( $this->purchase->billing_agreement and !$this->purchase->billing_agreement->canceled ) or ( $this->purchase->grouped_renewals and $parent->billing_agreement and !$parent->billing_agreement->canceled ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'not_with_billing_agreement', '2X195/J', 403, '' );
|
||||
}
|
||||
|
||||
if ( $this->purchase->grouped_renewals )
|
||||
{
|
||||
\IPS\Output::i()->error( 'not_with_grouped', '2X195/A', 403, '' );
|
||||
$this->purchase->ungroupFromParent();
|
||||
$this->purchase->save();
|
||||
}
|
||||
|
||||
$this->purchase->member->log( 'purchase', array( 'type' => 'delete', 'id' => $this->purchase->id, 'name' => $this->purchase->name ) );
|
||||
$this->purchase->delete();
|
||||
|
||||
\IPS\Output::i()->redirect( $this->purchase->member->acpUrl() );
|
||||
if ( $parent )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $parent->acpUrl() );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->redirect( $this->purchase->member->acpUrl() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -400,6 +477,11 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
protected function group()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'purchases_edit' );
|
||||
if ( $this->purchase->billing_agreement and !$this->purchase->billing_agreement->canceled )
|
||||
{
|
||||
\IPS\Output::i()->error( 'not_with_billing_agreement', '2X195/E', 403, '' );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$this->purchase->groupWithParent();
|
||||
@@ -420,6 +502,11 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
protected function ungroup()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'purchases_edit' );
|
||||
if ( $this->purchase->billing_agreement and !$this->purchase->billing_agreement->canceled )
|
||||
{
|
||||
\IPS\Output::i()->error( 'not_with_billing_agreement', '2X195/F', 403, '' );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$this->purchase->ungroupFromParent();
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
/**
|
||||
* @brief referralbanners
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 18 Aug 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Referrals
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 15 Aug 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Referral Settings
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 15 Aug 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Customer Search
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 12 May 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief View Customer
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 11 Feb 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -49,6 +49,7 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'customer.css', 'nexus', 'admin' ) );
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'support.css', 'nexus', 'admin' ) );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'admin_customer.js', 'nexus', 'admin' ) );
|
||||
\IPS\Output::i()->title = "{$this->member->cm_name}";
|
||||
|
||||
parent::execute();
|
||||
@@ -70,7 +71,7 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$noteCount = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_notes', array( 'note_member=?', $this->member->member_id ) )->first();
|
||||
|
||||
$notes = new \IPS\Helpers\Table\Db( 'nexus_notes', $this->member->acpUrl()->setQueryString( array( 'tab' => 'notes', 'support' => isset( \IPS\Request::i()->support ) ? \IPS\Request::i()->support : 0 ) ), array( 'note_member=?', $this->member->member_id ) );
|
||||
$notes = new \IPS\Helpers\Table\Db( 'nexus_notes', $this->member->acpUrl()->setQueryString( array( 'view' => 'notes', 'support' => isset( \IPS\Request::i()->support ) ? \IPS\Request::i()->support : 0 ) ), array( 'note_member=?', $this->member->member_id ) );
|
||||
$notes->tableTemplate = array( \IPS\Theme::i()->getTemplate('customers'), 'notes' );
|
||||
$notes->sortBy = 'note_date';
|
||||
|
||||
@@ -186,7 +187,7 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
/* Addresses */
|
||||
if ( \IPS\Request::i()->view === 'addresses' )
|
||||
{
|
||||
$addresses = new \IPS\Helpers\Table\Db( 'nexus_customer_addresses', $this->member->acpUrl()->setQueryString( 'tab', 'addresses' ), array( 'member=?', $this->member->member_id ) );
|
||||
$addresses = new \IPS\Helpers\Table\Db( 'nexus_customer_addresses', $this->member->acpUrl()->setQueryString( 'view', 'addresses' ), array( 'member=?', $this->member->member_id ) );
|
||||
$addresses->sortBy = 'primary_billing, primary_shipping, added';
|
||||
$addresses->include = array( 'address', 'primary_billing', 'primary_shipping' );
|
||||
$addresses->parsers = array( 'address' => function( $val )
|
||||
@@ -236,6 +237,7 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
catch ( \UnderflowException $e ) { }
|
||||
}
|
||||
$addressCount = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_customer_addresses', array( 'member=?', $this->member->member_id ) )->first();
|
||||
|
||||
/* Credit Cards */
|
||||
$cards = '';
|
||||
@@ -253,12 +255,12 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
'id' => $card->id,
|
||||
'card_type' => $cardData->type,
|
||||
'card_number' => $cardData->lastFour,
|
||||
'card_expire' => str_pad( $cardData->expMonth , 2, '0', STR_PAD_LEFT ). '/' . $cardData->expYear
|
||||
'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 ) { }
|
||||
}
|
||||
$cards = new \IPS\Helpers\Table\Custom( $cards, $this->member->acpUrl()->setQueryString( 'tab', 'cards' ) );
|
||||
$cards = new \IPS\Helpers\Table\Custom( $cards, $this->member->acpUrl()->setQueryString( 'view', 'cards' ) );
|
||||
$cards->rootButtons = array(
|
||||
'add' => array(
|
||||
'link' => $this->member->acpUrl()->setQueryString( 'do', 'addCard' ),
|
||||
@@ -294,9 +296,58 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
}
|
||||
|
||||
/* Billing Agreements */
|
||||
$billingAgreements = '';
|
||||
$billingAgreementCount = 0;
|
||||
if ( count( \IPS\nexus\Gateway::billingAgreementGateways() ) and \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'billingagreements_view' ) )
|
||||
{
|
||||
$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 )
|
||||
{
|
||||
$billingAgreements[ $billingAgreement['ba_id'] ] = array(
|
||||
'id' => $billingAgreement['ba_id'],
|
||||
'gw_id' => $billingAgreement['ba_gw_id'],
|
||||
'started' => $billingAgreement['ba_started'],
|
||||
'next_cycle' => $billingAgreement['ba_next_cycle'],
|
||||
);
|
||||
}
|
||||
$billingAgreements = new \IPS\Helpers\Table\Custom( $billingAgreements, $this->member->acpUrl()->setQueryString( 'view', 'billingagreements' ) );
|
||||
$billingAgreements->parsers = array(
|
||||
'started' => function( $val ) {
|
||||
return $val ? \IPS\DateTime::ts( $val )->relative() : null;
|
||||
},
|
||||
'next_cycle' => function( $val ) {
|
||||
return $val ? \IPS\DateTime::ts( $val )->relative() : null;
|
||||
},
|
||||
);
|
||||
$billingAgreements->rowButtons = function( $row, $id )
|
||||
{
|
||||
return array(
|
||||
'view' => array(
|
||||
'link' => \IPS\Http\Url::internal("app=nexus&module=payments&controller=billingagreements&id={$id}"),
|
||||
'title' => 'view',
|
||||
'icon' => 'search',
|
||||
)
|
||||
);
|
||||
};
|
||||
if ( \IPS\Request::i()->view === 'billingagreements' )
|
||||
{
|
||||
$billingAgreements->exclude = array( 'id', 'last_transaction_currency' );
|
||||
$billingAgreements->langPrefix = 'ba_';
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('customers')->customerPopup( $billingAgreements );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
$billingAgreements->tableTemplate = array( \IPS\Theme::i()->getTemplate('customers'), 'billingAgreementsOverview' );
|
||||
$billingAgreements->rowsTemplate = array( \IPS\Theme::i()->getTemplate('customers'), 'billingAgreementsOverviewRows' );
|
||||
}
|
||||
}
|
||||
|
||||
/* Alternative Contacts */
|
||||
$altContactCount = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_alternate_contacts', array( 'main_id=?', $this->member->member_id ) )->first();
|
||||
$alternativeContacts = new \IPS\Helpers\Table\Db( 'nexus_alternate_contacts', $this->member->acpUrl()->setQueryString( 'tab', 'alternatives' ), array( 'main_id=?', $this->member->member_id ) );
|
||||
$alternativeContacts = new \IPS\Helpers\Table\Db( 'nexus_alternate_contacts', $this->member->acpUrl()->setQueryString( 'view', 'alternatives' ), array( 'main_id=?', $this->member->member_id ) );
|
||||
$alternativeContacts->langPrefix = 'altcontactTable_';
|
||||
$alternativeContacts->include = array( 'alt_id', 'purchases', 'billing', 'support' );
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_edit_details' ) )
|
||||
@@ -339,7 +390,7 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
'link' => $this->member->acpUrl()->setQueryString( 'do', 'alternativeContactForm' ),
|
||||
'title' => 'add',
|
||||
'icon' => 'plus',
|
||||
'data' => array( 'ipsDialog' => true, 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('add_address') )
|
||||
'data' => array( 'ipsDialog' => true, 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('altcontact_add') )
|
||||
)
|
||||
);
|
||||
$alternativeContacts->rowButtons = function( $row ) use ( $member )
|
||||
@@ -390,7 +441,7 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
$referredBy = NULL;
|
||||
}
|
||||
$referCount = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_referrals', array( 'referred_by=?', $this->member->member_id ) )->first();
|
||||
$referrals = new \IPS\Helpers\Table\Db( 'nexus_referrals', $this->member->acpUrl()->setQueryString( 'tab', 'referrals' ), array( 'referred_by=?', $this->member->member_id ) );
|
||||
$referrals = new \IPS\Helpers\Table\Db( 'nexus_referrals', $this->member->acpUrl()->setQueryString( 'view', 'referrals' ), array( 'referred_by=?', $this->member->member_id ) );
|
||||
$referrals->langPrefix = 'ref_';
|
||||
$referrals->include = array( 'member_id', 'amount' );
|
||||
$referrals->sortBy = $referrals->sortBy ?: 'member_id';
|
||||
@@ -448,115 +499,12 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
$referrals->rowsTemplate = array( \IPS\Theme::i()->getTemplate('customers'), 'referralsOverviewRows' );
|
||||
}
|
||||
|
||||
/* Support Requests */
|
||||
$supportCount = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_requests', array( 'r_member=?', $this->member->member_id ) )->first();
|
||||
$support = \IPS\nexus\Support\Request::table( $this->member->acpUrl()->setQueryString( 'tab', 'support' ), array( 'r_member=?', $this->member->member_id ) );
|
||||
$support->limit = 15;
|
||||
$support->exclude = array( 'r_member' );
|
||||
$support->tableTemplate = array( \IPS\Theme::i()->getTemplate('customers'), 'supportTable' );
|
||||
$support->rowsTemplate = array( \IPS\Theme::i()->getTemplate('customers'), 'supportTableRows' );
|
||||
|
||||
/* History */
|
||||
$history = new \IPS\nexus\Customer\History( $this->member->acpUrl()->setQueryString( 'do', 'history' ), array( 'log_member=?', $this->member->member_id ) );
|
||||
$history->limit = 16;
|
||||
|
||||
/* Standing */
|
||||
$standing = array();
|
||||
$time = time();
|
||||
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' ) )->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();
|
||||
$standing[ \IPS\Member::loggedIn()->language()->addToStack( 'total_spent_currency', FALSE, array( 'sprintf' => array( $currency ) ) ) ] = array(
|
||||
'value' => new \IPS\nexus\Money( $val, $currency ),
|
||||
'avg' => new \IPS\nexus\Money( $comparisons['avg'], $currency ),
|
||||
'highest' => new \IPS\nexus\Money( $comparisons['max'], $currency ),
|
||||
'lowest' => new \IPS\nexus\Money( $comparisons['min'], $currency ),
|
||||
'lowval' => $comparisons['min'],
|
||||
'highval' => $comparisons['max'],
|
||||
'avgval' => $comparisons['avg'],
|
||||
'thisval' => $val,
|
||||
'avgpct' => $comparisons['max'] ? round( ( ( $comparisons['avg'] - $comparisons['min'] ) / $comparisons['max'] ) * 100, 1 ) : 0,
|
||||
'thispct' => $comparisons['max'] ? round( ( ( $val - $comparisons['min'] ) / $comparisons['max'] ) * 100, 1 ) : 0,
|
||||
'type' => 'totalspent'
|
||||
);
|
||||
|
||||
/* Average monthly spend */
|
||||
$sum = "( SUM(t_amount) / ( ( {$time} - core_members.joined ) / 2592000 ) )";
|
||||
$where = array( array( "( t_status=? OR t_status=? ) AND ({$time} - core_members.joined > 2592000) AND t_currency=?", \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED, $currency ) );
|
||||
try
|
||||
{
|
||||
$val = \IPS\Db::i()->select( "{$sum} as sum", 'nexus_transactions', array_merge( $where, array( array( 't_member=?', $this->member->member_id ) ) ), 'joined', NULL, 'joined' )->join( 'core_members', 'member_id=t_member' )->first();
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
{
|
||||
$val = 0;
|
||||
}
|
||||
$comparisons = \IPS\Db::i()->select( 'AVG(xval) AS avg, MAX(xval) AS max, MIN(xval) AS min', \IPS\Db::i()->select( "{$sum} as xval", 'nexus_transactions', array_merge( $where, array( array( 't_member<>0' ) ) ), NULL, NULL, 't_member' ) )->join( 'core_members', 'member_id=t_member' )->first();
|
||||
$standing[ \IPS\Member::loggedIn()->language()->addToStack( 'average_spend_currency', FALSE, array( 'sprintf' => array( $currency ) ) ) ] = array(
|
||||
'value' => new \IPS\nexus\Money( $val, $currency ),
|
||||
'avg' => new \IPS\nexus\Money( $comparisons['avg'], $currency ),
|
||||
'highest' => new \IPS\nexus\Money( $comparisons['max'], $currency ),
|
||||
'lowest' => new \IPS\nexus\Money( $comparisons['min'], $currency ),
|
||||
'lowval' => $comparisons['min'],
|
||||
'highval' => $comparisons['max'],
|
||||
'avgval' => $comparisons['avg'],
|
||||
'thisval' => $val,
|
||||
'avgpct' => $comparisons['max'] ? round( ( ( $comparisons['avg'] - $comparisons['min'] ) / $comparisons['max'] ) * 100, 1 ) : 0,
|
||||
'thispct' => $comparisons['max'] ? round( ( ( $val - $comparisons['min'] ) / $comparisons['max'] ) * 100, 1 ) : 0,
|
||||
'type' => 'avgspent'
|
||||
);
|
||||
}
|
||||
|
||||
$sum = "ROUND( ( AVG( i_paid - i_date ) / 86400 ), 2 )";
|
||||
$where = array( array( "i_status=? AND i_date>0 AND i_paid>0", \IPS\nexus\Invoice::STATUS_PAID ) );
|
||||
$val = \IPS\Db::i()->select( "{$sum} as sum", 'nexus_invoices', array_merge( $where, array( array( 'i_member=?', $this->member->member_id ) ) ) )->join( 'core_members', 'member_id=i_member' )->first();
|
||||
$comparisons = \IPS\Db::i()->select( 'AVG(xval) AS avg, MAX(xval) AS max, MIN(xval) AS min', \IPS\Db::i()->select( "{$sum} as xval", 'nexus_invoices', array_merge( $where, array( array( 'i_member<>0' ) ) ), NULL, NULL, array( 'i_member', 'joined' ) ) )->join( 'core_members', 'member_id=i_member' )->first();
|
||||
$standing[ \IPS\Member::loggedIn()->language()->addToStack( 'average_time_to_pay' ) ] = array(
|
||||
'value' => \IPS\Member::loggedIn()->language()->formatNumber( $val, 2 ) . ' ' . \IPS\Member::loggedIn()->language()->addToStack('days'),
|
||||
'avg' => \IPS\Member::loggedIn()->language()->formatNumber( $comparisons['avg'], 2 ) . ' ' . \IPS\Member::loggedIn()->language()->addToStack('days'),
|
||||
'highest' => \IPS\Member::loggedIn()->language()->formatNumber( $comparisons['max'], 2 ) . ' ' . \IPS\Member::loggedIn()->language()->addToStack('days'),
|
||||
'lowest' => \IPS\Member::loggedIn()->language()->formatNumber( $comparisons['min'], 2 ) . ' ' . \IPS\Member::loggedIn()->language()->addToStack('days'),
|
||||
'lowval' => $comparisons['min'],
|
||||
'highval' => $comparisons['max'],
|
||||
'avgval' => $comparisons['avg'],
|
||||
'thisval' => $val,
|
||||
'avgpct' => floatval( $comparisons['max'] ) ? round( ( ( $comparisons['avg'] - $comparisons['min'] ) / $comparisons['max'] ) * 100, 1 ) : 0,
|
||||
'thispct' => floatval( $comparisons['max'] ) ? round( ( ( $val - $comparisons['min'] ) / $comparisons['max'] ) * 100, 1 ) : 0,
|
||||
'type' => 'timetopay'
|
||||
);
|
||||
|
||||
$sum = "( COUNT(*) / ( ( {$time} - core_members.joined ) / 2592000 ) )";
|
||||
try
|
||||
{
|
||||
$val = \IPS\Db::i()->select( "{$sum} as sum", 'nexus_support_requests', array( 'r_member=?', $this->member->member_id ), 'joined', NULL, 'joined' )->join( 'core_members', 'member_id=r_member' )->first();
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
{
|
||||
$val = 0;
|
||||
}
|
||||
$comparisons = \IPS\Db::i()->select( 'AVG(xval) AS avg, MAX(xval) AS max, MIN(xval) AS min', \IPS\Db::i()->select( "{$sum} as xval", 'nexus_support_requests', 'r_member<>0', NULL, NULL, 'joined' ) )->join( 'core_members', 'member_id=r_member' )->first();
|
||||
$standing[ \IPS\Member::loggedIn()->language()->addToStack( 'average_monthly_support_requests' ) ] = array(
|
||||
'value' => \IPS\Member::loggedIn()->language()->formatNumber( $val, 2 ),
|
||||
'avg' => \IPS\Member::loggedIn()->language()->formatNumber( $comparisons['avg'], 2 ),
|
||||
'highest' => \IPS\Member::loggedIn()->language()->formatNumber( $comparisons['max'], 2 ),
|
||||
'lowest' => \IPS\Member::loggedIn()->language()->formatNumber( $comparisons['min'], 2 ),
|
||||
'lowval' => $comparisons['min'],
|
||||
'highval' => $comparisons['max'],
|
||||
'avgval' => $comparisons['avg'],
|
||||
'thisval' => $val,
|
||||
'avgpct' => $comparisons['max'] ? round( ( ( $comparisons['avg'] - $comparisons['min'] ) / $comparisons['max'] ) * 100, 1 ) : 0,
|
||||
'thispct' => $comparisons['max'] ? round( ( ( $val - $comparisons['min'] ) / $comparisons['max'] ) * 100, 1 ) : 0,
|
||||
'type' => 'support'
|
||||
);
|
||||
|
||||
/* Sparkline */
|
||||
$rows = array();
|
||||
$oneYearAgo = \IPS\DateTime::create()->sub( new \DateInterval('P1Y') );
|
||||
$date = clone $oneYearAgo;
|
||||
$endOfThisMonth = mktime( 23, 59, 59, date('n'), date('t'), date('Y') );
|
||||
while ( $date->getTimestamp() < $endOfThisMonth )
|
||||
$endOfLastMonth = mktime( 23, 59, 59, date('n') - 1, date('t'), date('Y') );
|
||||
while ( $date->getTimestamp() < $endOfLastMonth )
|
||||
{
|
||||
foreach ( \IPS\nexus\Money::currencies() as $currency )
|
||||
{
|
||||
@@ -565,7 +513,7 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
$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>?", $this->member->member_id, \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED, $oneYearAgo->getTimestamp() ) ), NULL, NULL, array( 'time', 't_currency' ) ) as $row )
|
||||
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
|
||||
{
|
||||
@@ -584,6 +532,11 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
$exploded = explode( ' ', $time );
|
||||
$datetime->setDate( $exploded[1], $exploded[0], 1 );
|
||||
|
||||
foreach( $row as $currency => $value )
|
||||
{
|
||||
$row[ $currency ] = number_format( $value, 2, '.', '' );
|
||||
}
|
||||
|
||||
$sparkline->addRow( array_merge( array( $datetime ), $row ) );
|
||||
}
|
||||
|
||||
@@ -612,7 +565,20 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
)
|
||||
),
|
||||
) );
|
||||
|
||||
/* Support Requests */
|
||||
$customerStream = \IPS\nexus\Support\Stream::customer( $this->member );
|
||||
$supportCount = $customerStream->count( \IPS\Member::loggedIn() );
|
||||
$results = $customerStream->results( \IPS\Member::loggedIn(), 'r_started DESC', 1, 15 );
|
||||
$supportRequestsInView = array_keys( iterator_to_array( $results ) );
|
||||
$tracked = iterator_to_array( \IPS\Db::i()->select( array( 'request_id', 'notify' ), 'nexus_support_tracker', array( array( 'member_id=?', \IPS\Member::loggedIn()->member_id ), array( \IPS\Db::i()->in( 'request_id', $supportRequestsInView ) ) ) )->setKeyField( 'request_id' )->setValueField( 'notify' ) );
|
||||
$participatedIn = iterator_to_array( \IPS\Db::i()->select( 'DISTINCT reply_request', 'nexus_support_replies', array( array( 'reply_member=?', \IPS\Member::loggedIn()->member_id ), array( \IPS\Db::i()->in( 'reply_request', $supportRequestsInView ) ) ) ) );
|
||||
$support = \IPS\Theme::i()->getTemplate('support')->requestsTableResults( $results, NULL, FALSE, $tracked, $participatedIn, FALSE );
|
||||
|
||||
/* History */
|
||||
$history = new \IPS\nexus\Customer\History( $this->member->acpUrl()->setQueryString( 'do', 'history' ), array( 'log_member=?', $this->member->member_id ) );
|
||||
$history->limit = 16;
|
||||
|
||||
/* Display */
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_void' ) )
|
||||
{
|
||||
@@ -630,7 +596,107 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
'link' => \IPS\Http\Url::internal( 'app=core&module=members&controller=members&do=edit&id=' . $this->member->member_id )
|
||||
);
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('customers')->view( $member, (string) $notes, $noteCount, $primaryBillingAddress, (string) $cards, $cardCount, $parents, (string) $alternativeContacts, $altContactCount, $purchases, $purchaseCount, $invoices, $invoiceCount, $history, $referredBy, $referrals, $referCount, $standing, $support, $supportCount, $sparkline, $purchaseRootCount );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('customers')->view( $member, (string) $notes, $noteCount, $primaryBillingAddress, (string) $cards, $cardCount, $parents, (string) $alternativeContacts, $altContactCount, $purchases, $purchaseCount, $invoices, $invoiceCount, $history, $referredBy, $referrals, $referCount, $support, $supportCount, $sparkline, $purchaseRootCount, $billingAgreements, $billingAgreementCount, $addressCount );
|
||||
}
|
||||
|
||||
/**
|
||||
* Standing Data
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function standing()
|
||||
{
|
||||
$standing = array();
|
||||
$time = time();
|
||||
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();
|
||||
$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 ),
|
||||
'highest' => new \IPS\nexus\Money( $comparisons['max'], $currency ),
|
||||
'lowest' => new \IPS\nexus\Money( $comparisons['min'], $currency ),
|
||||
'lowval' => $comparisons['min'],
|
||||
'highval' => $comparisons['max'],
|
||||
'avgval' => $comparisons['avg'],
|
||||
'thisval' => $val,
|
||||
'avgpct' => $comparisons['max'] ? round( ( ( $comparisons['avg'] - $comparisons['min'] ) / $comparisons['max'] ) * 100, 1 ) : 0,
|
||||
'thispct' => $comparisons['max'] ? round( ( ( $val - $comparisons['min'] ) / $comparisons['max'] ) * 100, 1 ) : 0,
|
||||
'type' => 'totalspent'
|
||||
);
|
||||
|
||||
/* Average monthly spend */
|
||||
$sum = "( SUM(t_amount) / ( ( {$time} - core_members.joined ) / 2592000 ) )";
|
||||
$where = array( array( "( t_status=? OR t_status=? ) AND ({$time} - core_members.joined > 2592000) AND t_currency=?", \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED, $currency ) );
|
||||
try
|
||||
{
|
||||
$val = \IPS\Db::i()->select( "{$sum} as sum", 'nexus_transactions', array_merge( $where, array( array( 't_member=?', $this->member->member_id ) ) ), 'joined', NULL, 'joined' )->join( 'core_members', 'member_id=t_member' )->first();
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
{
|
||||
$val = 0;
|
||||
}
|
||||
$comparisons = \IPS\Db::i()->select( 'AVG(xval) AS avg, MAX(xval) AS max, MIN(xval) AS min', \IPS\Db::i()->select( "{$sum} as xval", 'nexus_transactions', array_merge( $where, array( array( 't_member<>0' ) ) ), NULL, NULL, array( 't_member', 'joined' ) ), 'xval>0' )->join( 'core_members', 'member_id=t_member' )->first();
|
||||
$standing[ \IPS\Member::loggedIn()->language()->addToStack( 'average_spend_currency', FALSE, array( 'sprintf' => array( $currency ) ) ) ] = array(
|
||||
'value' => new \IPS\nexus\Money( $val, $currency ),
|
||||
'avg' => new \IPS\nexus\Money( $comparisons['avg'], $currency ),
|
||||
'highest' => new \IPS\nexus\Money( $comparisons['max'], $currency ),
|
||||
'lowest' => new \IPS\nexus\Money( $comparisons['min'], $currency ),
|
||||
'lowval' => $comparisons['min'],
|
||||
'highval' => $comparisons['max'],
|
||||
'avgval' => $comparisons['avg'],
|
||||
'thisval' => $val,
|
||||
'avgpct' => $comparisons['max'] ? round( ( ( $comparisons['avg'] - $comparisons['min'] ) / $comparisons['max'] ) * 100, 1 ) : 0,
|
||||
'thispct' => $comparisons['max'] ? round( ( ( $val - $comparisons['min'] ) / $comparisons['max'] ) * 100, 1 ) : 0,
|
||||
'type' => 'avgspent'
|
||||
);
|
||||
}
|
||||
|
||||
$sum = "ROUND( ( AVG( i_paid - i_date ) / 86400 ), 2 )";
|
||||
$where = array( array( "i_status=? AND i_date>0 AND i_paid>0", \IPS\nexus\Invoice::STATUS_PAID ) );
|
||||
$val = \IPS\Db::i()->select( "{$sum} as sum", 'nexus_invoices', array_merge( $where, array( array( 'i_member=?', $this->member->member_id ) ) ) )->join( 'core_members', 'member_id=i_member' )->first();
|
||||
$comparisons = \IPS\Db::i()->select( 'AVG(xval) AS avg, MAX(xval) AS max, MIN(xval) AS min', \IPS\Db::i()->select( "{$sum} as xval", 'nexus_invoices', array_merge( $where, array( array( 'i_member<>0' ) ) ), NULL, NULL, array( 'i_member', 'joined' ) ), 'xval>0' )->join( 'core_members', 'member_id=i_member' )->first();
|
||||
$standing[ \IPS\Member::loggedIn()->language()->addToStack( 'average_time_to_pay' ) ] = array(
|
||||
'value' => \IPS\Member::loggedIn()->language()->formatNumber( $val, 2 ) . ' ' . \IPS\Member::loggedIn()->language()->addToStack('days'),
|
||||
'avg' => \IPS\Member::loggedIn()->language()->formatNumber( $comparisons['avg'], 2 ) . ' ' . \IPS\Member::loggedIn()->language()->addToStack('days'),
|
||||
'highest' => \IPS\Member::loggedIn()->language()->formatNumber( $comparisons['max'], 2 ) . ' ' . \IPS\Member::loggedIn()->language()->addToStack('days'),
|
||||
'lowest' => \IPS\Member::loggedIn()->language()->formatNumber( $comparisons['min'], 2 ) . ' ' . \IPS\Member::loggedIn()->language()->addToStack('days'),
|
||||
'lowval' => $comparisons['min'],
|
||||
'highval' => $comparisons['max'],
|
||||
'avgval' => $comparisons['avg'],
|
||||
'thisval' => $val,
|
||||
'avgpct' => floatval( $comparisons['max'] ) ? round( ( ( $comparisons['avg'] - $comparisons['min'] ) / $comparisons['max'] ) * 100, 1 ) : 0,
|
||||
'thispct' => floatval( $comparisons['max'] ) ? round( ( ( $val - $comparisons['min'] ) / $comparisons['max'] ) * 100, 1 ) : 0,
|
||||
'type' => 'timetopay'
|
||||
);
|
||||
|
||||
$sum = "LEAST( ( COUNT(*) / ( ( {$time} - core_members.joined ) / 2592000 ) ), COUNT(*) )";
|
||||
try
|
||||
{
|
||||
$val = \IPS\Db::i()->select( "{$sum} as sum", 'nexus_support_requests', array( 'r_member=?', $this->member->member_id ), 'joined', NULL, 'joined' )->join( 'core_members', 'member_id=r_member' )->first();
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
{
|
||||
$val = 0;
|
||||
}
|
||||
$comparisons = \IPS\Db::i()->select( 'AVG(xval) AS avg, MAX(xval) AS max, MIN(xval) AS min', \IPS\Db::i()->select( "{$sum} as xval", 'nexus_support_requests', 'r_member<>0', NULL, NULL, 'joined' ) )->join( 'core_members', 'member_id=r_member' )->first();
|
||||
$standing[ \IPS\Member::loggedIn()->language()->addToStack( 'average_monthly_support_requests' ) ] = array(
|
||||
'value' => \IPS\Member::loggedIn()->language()->formatNumber( $val, 2 ),
|
||||
'avg' => \IPS\Member::loggedIn()->language()->formatNumber( $comparisons['avg'], 2 ),
|
||||
'highest' => \IPS\Member::loggedIn()->language()->formatNumber( $comparisons['max'], 2 ),
|
||||
'lowest' => \IPS\Member::loggedIn()->language()->formatNumber( $comparisons['min'], 2 ),
|
||||
'lowval' => $comparisons['min'],
|
||||
'highval' => $comparisons['max'],
|
||||
'avgval' => $comparisons['avg'],
|
||||
'thisval' => $val,
|
||||
'avgpct' => $comparisons['max'] ? round( ( ( $comparisons['avg'] - $comparisons['min'] ) / $comparisons['max'] ) * 100, 1 ) : 0,
|
||||
'thispct' => $comparisons['max'] ? round( ( ( $val - $comparisons['min'] ) / $comparisons['max'] ) * 100, 1 ) : 0,
|
||||
'type' => 'support'
|
||||
);
|
||||
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate('customers')->standing( $standing ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -682,8 +748,8 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'cm_first_name', $this->member->cm_first_name, TRUE ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'cm_last_name', $this->member->cm_last_name, TRUE ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'cm_first_name', $this->member->cm_first_name, FALSE ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'cm_last_name', $this->member->cm_last_name, FALSE ) );
|
||||
|
||||
foreach ( \IPS\nexus\Customer\CustomField::roots() as $field )
|
||||
{
|
||||
@@ -698,7 +764,12 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
if ( $values[ $k ] != $this->member->$k )
|
||||
{
|
||||
$changes['name'] = $this->member->cm_name;
|
||||
/* We only need to log this once, so do it if it isn't set */
|
||||
if ( !isset( $changes['name'] ) )
|
||||
{
|
||||
$changes['name'] = $this->member->cm_name;
|
||||
}
|
||||
|
||||
$this->member->$k = $values[ $k ];
|
||||
}
|
||||
}
|
||||
@@ -707,7 +778,7 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
$column = $field->column;
|
||||
if ( $this->member->$column != $values["nexus_ccfield_{$field->id}"] )
|
||||
{
|
||||
$changes['other'][] = array( 'name' => 'nexus_ccfield_' . $field->id, 'value' => $values["nexus_ccfield_{$field->id}"], 'old' => $this->member->$column );
|
||||
$changes['other'][] = array( 'name' => 'nexus_ccfield_' . $field->id, 'value' => $field->displayValue( $values["nexus_ccfield_{$field->id}"] ), 'old' => $this->member->$column );
|
||||
$this->member->$column = $values["nexus_ccfield_{$field->id}"];
|
||||
}
|
||||
|
||||
@@ -740,7 +811,7 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
$form->class = 'ipsForm_vertical';
|
||||
foreach ( \IPS\nexus\Money::currencies() as $currency )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Number( $currency, isset( $this->member->cm_credits[ $currency ] ) ? $this->member->cm_credits[ $currency ]->amount : 0, FALSE, array( 'min' => 0, 'decimals' => TRUE ), NULL, NULL, $currency ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( $currency, isset( $this->member->cm_credits[ $currency ] ) ? $this->member->cm_credits[ $currency ]->amount : 0, FALSE, array( 'min' => 0, 'decimals' => \IPS\nexus\Money::numberOfDecimalsForCurrency( $currency ) ), NULL, NULL, $currency ) );
|
||||
}
|
||||
|
||||
if ( $values = $form->values() )
|
||||
@@ -748,9 +819,10 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
$credits = $this->member->cm_credits;
|
||||
foreach ( $values as $currency => $amount )
|
||||
{
|
||||
if ( ( isset( $this->member->cm_credits[ $currency ] ) and $this->member->cm_credits[ $currency ]->amount != $amount ) or $amount )
|
||||
$amount = new \IPS\Math\Number( number_format( $amount, \IPS\nexus\Money::numberOfDecimalsForCurrency( $currency ), '.', '' ) );
|
||||
if ( ( isset( $this->member->cm_credits[ $currency ] ) and $this->member->cm_credits[ $currency ]->amount->compare( $amount ) !== 0 ) or $amount )
|
||||
{
|
||||
$this->member->log( 'comission', array( 'type' => 'manual', 'old' => isset( $this->member->cm_credits[ $currency ] ) ? $this->member->cm_credits[ $currency ]->amount : 0, 'new' => $amount, 'currency' => $currency ) );
|
||||
$this->member->log( 'comission', array( 'type' => 'manual', 'old' => isset( $this->member->cm_credits[ $currency ] ) ? $this->member->cm_credits[ $currency ]->amountAsString() : 0, 'new' => (string) $amount, 'currency' => $currency ) );
|
||||
}
|
||||
$credits[ $currency ] = new \IPS\nexus\Money( $amount, $currency );
|
||||
}
|
||||
@@ -803,7 +875,7 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
\IPS\Db::i()->update( 'nexus_notes', array(
|
||||
'note_text' => $values['customer_note']
|
||||
) );
|
||||
), array( 'note_id=?', \IPS\Request::i()->note_id ) );
|
||||
|
||||
$this->member->log( 'note', 'edited' );
|
||||
}
|
||||
@@ -843,6 +915,9 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'customer_notes_delete' );
|
||||
|
||||
/* Make sure the user confirmed the deletion */
|
||||
\IPS\Request::i()->confirmedDelete();
|
||||
|
||||
\IPS\Db::i()->delete( 'nexus_notes', array( 'note_id=?', \IPS\Request::i()->note_id ) );
|
||||
$this->member->log( 'note', 'deleted' );
|
||||
|
||||
@@ -936,6 +1011,9 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'customers_edit_details' );
|
||||
|
||||
/* Make sure the user confirmed the deletion */
|
||||
\IPS\Request::i()->confirmedDelete();
|
||||
|
||||
try
|
||||
{
|
||||
$address = \IPS\nexus\Customer\Address::load( \IPS\Request::i()->address_id );
|
||||
@@ -973,6 +1051,9 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
public function deleteCard()
|
||||
{
|
||||
/* Make sure the user confirmed the deletion */
|
||||
\IPS\Request::i()->confirmedDelete();
|
||||
|
||||
try
|
||||
{
|
||||
$card = \IPS\nexus\Customer\CreditCard::load( \IPS\Request::i()->card_id );
|
||||
@@ -1039,6 +1120,9 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
public function deleteAlternativeContact()
|
||||
{
|
||||
/* Make sure the user confirmed the deletion */
|
||||
\IPS\Request::i()->confirmedDelete();
|
||||
|
||||
try
|
||||
{
|
||||
$contact = \IPS\nexus\Customer\AlternativeContact::constructFromData( \IPS\Db::i()->select( '*', 'nexus_alternate_contacts', array( 'main_id=? AND alt_id=?', $this->member->member_id, \IPS\Request::i()->alt_id ) )->first() );
|
||||
@@ -1089,7 +1173,7 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
if ( $values['void_cancel_invoices'] )
|
||||
{
|
||||
\IPS\Db::i()->update( 'nexus_invoices', array( 'i_status' => \IPS\nexus\Invoice::STATUS_CANCELED ), array( 'i_member=?', $this->member->member_id ) );
|
||||
\IPS\Db::i()->update( 'nexus_invoices', array( 'i_status' => \IPS\nexus\Invoice::STATUS_CANCELED ), array( 'i_member=? AND i_status<>?', $this->member->member_id, \IPS\nexus\Invoice::STATUS_PAID ) );
|
||||
}
|
||||
if ( $values['void_resolve_support'] )
|
||||
{
|
||||
@@ -1130,7 +1214,7 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
'purch' => $values['void_cancel_purchases'],
|
||||
) ), function( $data ) use ( $member )
|
||||
{
|
||||
if ( $data == 0 )
|
||||
if ( !is_array( $data ) )
|
||||
{
|
||||
$data = array( 'trans' => 0, 'purch' => 0, 'fail' => array() );
|
||||
}
|
||||
@@ -1141,7 +1225,7 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_transactions', array( 't_member=?', $member->member_id ), 't_id', array( $data['trans'], 10 ) ), 'IPS\nexus\Transaction' ) as $transaction )
|
||||
{
|
||||
if ( in_array( $transaction->status, array( $transaction::STATUS_PENDING, $transaction::STATUS_WAITING ) ) )
|
||||
if ( in_array( $transaction->status, array( $transaction::STATUS_PENDING, $transaction::STATUS_WAITING, $transaction::STATUS_GATEWAY_PENDING ) ) )
|
||||
{
|
||||
$transaction->status = $transaction::STATUS_REVIEW;
|
||||
$transaction->save();
|
||||
@@ -1150,7 +1234,16 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
try
|
||||
{
|
||||
$transaction->refund();
|
||||
if ( $this->auth and in_array( $this->status, array( static::STATUS_HELD, static::STATUS_REVIEW ) ) )
|
||||
{
|
||||
$transaction->void();
|
||||
}
|
||||
else
|
||||
{
|
||||
$transaction->refund();
|
||||
}
|
||||
|
||||
$transaction->invoice->markUnpaid( \IPS\nexus\Invoice::STATUS_CANCELED, \IPS\Member::loggedIn() );
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Hosting Server Errors
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 12 Aug 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -209,6 +209,9 @@ class _errors extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
/* Make sure the user confirmed the deletion */
|
||||
\IPS\Request::i()->confirmedDelete();
|
||||
|
||||
\IPS\Db::i()->delete( 'nexus_hosting_errors', array( 'e_id=?', \IPS\Request::i()->id ) );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=hosting&controller=errors'), 'deleted' );
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Monitoring Settings
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 07 Aug 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -77,11 +77,11 @@ class _monitoring extends \IPS\Node\Controller
|
||||
if ( !$values['monitoring_on'] )
|
||||
{
|
||||
$values['monitoring_script'] = '';
|
||||
\IPS\DB::i()->update( 'core_tasks', array( 'enabled' => 0 ), "`key`='monitor'" );
|
||||
\IPS\Db::i()->update( 'core_tasks', array( 'enabled' => 0 ), "`key`='monitor'" );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\DB::i()->update( 'core_tasks', array( 'enabled' => 1 ), "`key`='monitor'" );
|
||||
\IPS\Db::i()->update( 'core_tasks', array( 'enabled' => 1 ), "`key`='monitor'" );
|
||||
}
|
||||
unset( $values['monitoring_on'] );
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Hosting Queues
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 06 Aug 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Hosting Servers
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 06 Aug 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -190,7 +190,7 @@ class _servers extends \IPS\Node\Controller
|
||||
$months += ( $purchase->renewals->interval->m );
|
||||
$months += ( $purchase->renewals->interval->d * ( 365 / 12 ) );
|
||||
|
||||
return new \IPS\nexus\Money( $purchase->renewals->cost->amount * $months, $purchase->renewals->cost->currency );
|
||||
return new \IPS\nexus\Money( $purchase->renewals->cost->amount->multiply( new \IPS\Math\Number("{$months}" ) ), $purchase->renewals->cost->currency );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
@@ -295,7 +295,7 @@ class _servers extends \IPS\Node\Controller
|
||||
\IPS\Http\Url::internal('app=nexus&module=hosting&controller=servers&do=audit'),
|
||||
function( $data ) use ( $self )
|
||||
{
|
||||
if ( $data === 0 )
|
||||
if ( !is_array( $data ) )
|
||||
{
|
||||
$_SESSION['serverAudit'] = array();
|
||||
$data = array( 'offset' => 0, 'bad' => array() );
|
||||
@@ -303,7 +303,7 @@ class _servers extends \IPS\Node\Controller
|
||||
|
||||
try
|
||||
{
|
||||
$select = \IPS\Db::i()->select( '*', 'nexus_hosting_servers', array(), 'server_hostname', array( $data['offset'], 1 ) );
|
||||
$select = \IPS\Db::i()->select( '*', 'nexus_hosting_servers', array(), 'server_hostname', array( $data['offset'], 1 ), NULL, NULL, \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS );
|
||||
$server = \IPS\nexus\Hosting\Server::constructFromData( $select->first() );
|
||||
|
||||
$results = $self->_audit( $server );
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Hosting Settings
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 08 Aug 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -54,6 +54,7 @@ class _settings extends \IPS\Dispatcher\Controller
|
||||
$form->addHeader('domain_options');
|
||||
$optionsVal = array();
|
||||
$domainPrices = array();
|
||||
|
||||
if ( \IPS\Settings::i()->nexus_enom_un and $domainPrices = json_decode( \IPS\Settings::i()->nexus_domain_prices, TRUE ) and count( $domainPrices ) )
|
||||
{
|
||||
$optionsVal[] = 'enom';
|
||||
@@ -75,14 +76,37 @@ class _settings extends \IPS\Dispatcher\Controller
|
||||
'toggles' => array(
|
||||
'enom' => array( 'form_header_nexus_domain_prices', 'nexus_domain_prices', 'nexus_domain_tax' ),
|
||||
'sub' => array( 'form_header_nexus_hosting_sub', 'nexus_hosting_subdomains' ),
|
||||
'own' => array()
|
||||
'own' => array( 'nexus_hosting_own_domains' )
|
||||
),
|
||||
'disabled' => \IPS\Settings::i()->nexus_enom_un ? array() : array( 'enom' )
|
||||
) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Stack( 'nexus_hosting_nameservers', explode( ',', \IPS\Settings::i()->nexus_hosting_nameservers ), FALSE, array(), NULL, NULL, NULL, 'nexus_hosting_nameservers' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Stack( 'nexus_hosting_nameservers', explode( ',', \IPS\Settings::i()->nexus_hosting_nameservers ), FALSE, array(), function( $val ) {
|
||||
if ( empty( $val ) and ( array_key_exists( 'enom', \IPS\Request::i()->domain_options ) or ( array_key_exists( 'own', \IPS\Request::i()->domain_options ) and array_key_exists( 'nameservers', \IPS\Request::i()->nexus_hosting_own_domains ) ) ) )
|
||||
{
|
||||
throw new \DomainException('nexus_hosting_nameservers_err');
|
||||
}
|
||||
}, NULL, NULL, 'nexus_hosting_nameservers' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Stack( 'nexus_hosting_subdomains', explode( ',', \IPS\Settings::i()->nexus_hosting_subdomains ), FALSE, array(), NULL, NULL, NULL, 'nexus_hosting_subdomains' ) );
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'nexus_hosting_own_domains', explode( ',', \IPS\Settings::i()->nexus_hosting_own_domains ), FALSE, array(
|
||||
'options' => array(
|
||||
'nameservers' => 'nexus_hosting_own_domains_nameservers',
|
||||
'aname' => 'nexus_hosting_own_domains_aname',
|
||||
'cname' => 'nexus_hosting_own_domains_cname',
|
||||
),
|
||||
'toggles' => array(
|
||||
'cname' => array( 'nexus_hosting_own_domain_sub' )
|
||||
)
|
||||
), NULL, NULL, NULL, 'nexus_hosting_own_domains' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'nexus_hosting_own_domain_sub', \IPS\Settings::i()->nexus_hosting_own_domain_sub, FALSE, array(), function( $val ) {
|
||||
if ( !$val and array_key_exists( 'own', \IPS\Request::i()->domain_options ) and array_key_exists( 'cname', \IPS\Request::i()->nexus_hosting_own_domains ) )
|
||||
{
|
||||
throw new \DomainException('nexus_hosting_own_domain_sub_err');
|
||||
}
|
||||
}, NULL, NULL, 'nexus_hosting_own_domain_sub' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_hosting_allow_change_domain', \IPS\Settings::i()->nexus_hosting_allow_change_domain, FALSE, array(), NULL, NULL, NULL ) );
|
||||
$form->addHeader('nexus_domain_prices');
|
||||
$matrix = new \IPS\Helpers\Form\Matrix;
|
||||
$matrix = new \IPS\Helpers\Form\Matrix( 'prices' );
|
||||
$matrix->squashFields = FALSE;
|
||||
$matrix->columns = array(
|
||||
'domain_tld' => array( 'Text' ),
|
||||
'domain_price' => function( $key, $value, $data )
|
||||
@@ -104,10 +128,11 @@ class _settings extends \IPS\Dispatcher\Controller
|
||||
$form->addMatrix( 'nexus_domain_prices', $matrix );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'nexus_domain_tax', \IPS\Settings::i()->nexus_domain_tax, FALSE, array( 'class' => 'IPS\nexus\Tax', 'zeroVal' => 'do_not_tax' ), NULL, NULL, NULL, 'nexus_domain_tax' ) );
|
||||
|
||||
/* Badwidth */
|
||||
/* Bandwidth */
|
||||
$form->addTab('nexus_hosting_bandwidth');
|
||||
$form->addMessage( 'nexus_hosting_bandwidth_blurb' );
|
||||
$bandwidthMatrix = new \IPS\Helpers\Form\Matrix;
|
||||
$bandwidthMatrix = new \IPS\Helpers\Form\Matrix( 'bandwidth' );
|
||||
$bandwidthMatrix->squashFields = FALSE;
|
||||
$bandwidthMatrix->columns = array(
|
||||
'bandwidth_amount' => array( 'Number' ),
|
||||
'bandwidth_price' => function( $key, $value, $data )
|
||||
@@ -148,11 +173,13 @@ class _settings extends \IPS\Dispatcher\Controller
|
||||
|
||||
$values['nexus_hosting_nameservers'] = implode( ',', $values['nexus_hosting_nameservers'] );
|
||||
$values['nexus_hosting_subdomains'] = in_array( 'sub', $values['domain_options'] ) ? implode( ',', $values['nexus_hosting_subdomains'] ) : '';
|
||||
$values['nexus_hosting_own_domains'] = in_array( 'own', $values['domain_options'] ) ? implode( ',', $values['nexus_hosting_own_domains'] ) : '';
|
||||
|
||||
\IPS\DB::i()->update( 'core_tasks', array( 'enabled' => (bool) $values['nexus_hosting_terminate'] ), "`key`='terminateHosting'" );
|
||||
\IPS\Db::i()->update( 'core_tasks', array( 'enabled' => (bool) $values['nexus_hosting_terminate'] ), "`key`='terminateHosting'" );
|
||||
|
||||
$bandwidthPrices = array();
|
||||
foreach ( $values['nexus_hosting_bandwidth'] as $option )
|
||||
|
||||
foreach ( $values['nexus_hosting_bandwidth'] as $key => $option )
|
||||
{
|
||||
if ( $option['bandwidth_amount'] )
|
||||
{
|
||||
@@ -165,6 +192,7 @@ class _settings extends \IPS\Dispatcher\Controller
|
||||
$form->saveAsSettings( $values );
|
||||
|
||||
\IPS\Session::i()->log( 'acplogs__hosting_settings' );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=nexus&module=hosting&controller=settings" ) );
|
||||
}
|
||||
|
||||
/* Display */
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Billing Agreememts
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 16 Dec 2015
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\modules\admin\payments;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Billing Agreements
|
||||
*/
|
||||
class _billingagreements extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'billingagreements_view' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* View
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function manage()
|
||||
{
|
||||
/* Load */
|
||||
try
|
||||
{
|
||||
$billingAgreement = \IPS\nexus\Customer\BillingAgreement::load( \IPS\Request::i()->id );
|
||||
|
||||
if ( !$billingAgreement->canceled and $billingAgreement->status() == $billingAgreement::STATUS_CANCELED )
|
||||
{
|
||||
$billingAgreement->canceled = TRUE;
|
||||
$billingAgreement->save();
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X320/1', 404, '' );
|
||||
}
|
||||
catch ( \IPS\nexus\Gateway\PayPal\Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'billing_agreement_error_public', '4X320/9', 500, 'billing_agreement_error', array(), $e->getName() );
|
||||
}
|
||||
|
||||
/* Show */
|
||||
try
|
||||
{
|
||||
/* Purchases */
|
||||
$purchases = NULL;
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'purchases_view' ) and ( !isset( \IPS\Request::i()->table ) ) )
|
||||
{
|
||||
$purchases = \IPS\nexus\Purchase::tree( $billingAgreement->acpUrl(), array( array( 'ps_billing_agreement=?', $billingAgreement->id ) ), 'ba' );
|
||||
}
|
||||
|
||||
/* Transactions */
|
||||
$transactions = NULL;
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'transactions_manage' ) and ( !isset( \IPS\Request::i()->table ) ) )
|
||||
{
|
||||
$transactions = \IPS\nexus\Transaction::table( array( array( 't_billing_agreement=? AND t_status<>?', $billingAgreement->id, \IPS\nexus\Transaction::STATUS_PENDING ) ), $billingAgreement->acpUrl(), 'ba' );
|
||||
$transactions->limit = 50;
|
||||
foreach ( $transactions->include as $k => $v )
|
||||
{
|
||||
if ( in_array( $v, array( 't_method', 't_member' ) ) )
|
||||
{
|
||||
unset( $transactions->include[ $k ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Action Buttons */
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'billingagreements_manage' ) )
|
||||
{
|
||||
if ( $billingAgreement->status() == $billingAgreement::STATUS_ACTIVE )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions']['suspend'] = array(
|
||||
'icon' => 'times',
|
||||
'title' => 'billing_agreement_suspend',
|
||||
'link' => $billingAgreement->acpUrl()->setQueryString( array( 'do' => 'act', 'act' => 'suspend' ) ),
|
||||
'data' => array( 'confirm' => '', 'confirmSubMessage' => \IPS\Member::loggedIn()->language()->addToStack('billing_agreement_suspend_confirm') )
|
||||
);
|
||||
}
|
||||
elseif ( $billingAgreement->status() == $billingAgreement::STATUS_SUSPENDED )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions']['reactivate'] = array(
|
||||
'icon' => 'check',
|
||||
'title' => 'billing_agreement_reactivate',
|
||||
'link' => $billingAgreement->acpUrl()->setQueryString( array( 'do' => 'act', 'act' => 'reactivate' ) ),
|
||||
'data' => array( 'confirm' => '' )
|
||||
);
|
||||
}
|
||||
if ( $billingAgreement->status() != $billingAgreement::STATUS_CANCELED )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions']['cancel'] = array(
|
||||
'icon' => 'times-circle',
|
||||
'title' => 'billing_agreement_cancel',
|
||||
'link' => $billingAgreement->acpUrl()->setQueryString( array( 'do' => 'act', 'act' => 'cancel' ) ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'billing_agreement_id', FALSE, array( 'sprintf' => array( $billingAgreement->id ) ) );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'billingagreements' )->view( $billingAgreement, $purchases, $transactions );
|
||||
}
|
||||
catch ( \IPS\nexus\Gateway\PayPal\Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'billing_agreement_error', '1X320/2', 500, '', array(), $e->getName() );
|
||||
}
|
||||
catch ( \DomainException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'billing_agreement_error', '1X320/3', 500 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconcile - resets next_cycle date
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function reconcile()
|
||||
{
|
||||
/* Load */
|
||||
try
|
||||
{
|
||||
$billingAgreement = \IPS\nexus\Customer\BillingAgreement::load( \IPS\Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X320/5', 404, '' );
|
||||
}
|
||||
|
||||
/* Reconcile */
|
||||
try
|
||||
{
|
||||
$billingAgreement->next_cycle = $billingAgreement->nextPaymentDate();
|
||||
$billingAgreement->save();
|
||||
|
||||
\IPS\Output::i()->redirect( $billingAgreement->acpUrl() );
|
||||
}
|
||||
catch ( \IPS\nexus\Gateway\PayPal\Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'billing_agreement_error', '1X320/6', 500, '', array(), $e->getName() );
|
||||
}
|
||||
catch ( \DomainException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'billing_agreement_error', '1X320/7', 500 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Suspend/Reactivate/Cancel
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function act()
|
||||
{
|
||||
/* Check act */
|
||||
$act = \IPS\Request::i()->act;
|
||||
if ( !in_array( $act, array( 'suspend', 'reactivate', 'cancel' ) ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '3X320/8', 403, '' );
|
||||
}
|
||||
|
||||
/* Load */
|
||||
try
|
||||
{
|
||||
$billingAgreement = \IPS\nexus\Customer\BillingAgreement::load( \IPS\Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X320/8', 404, '' );
|
||||
}
|
||||
|
||||
/* Perform Action */
|
||||
try
|
||||
{
|
||||
$billingAgreement->$act();
|
||||
|
||||
\IPS\Output::i()->redirect( $billingAgreement->acpUrl() );
|
||||
}
|
||||
catch ( \IPS\nexus\Gateway\PayPal\Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'billing_agreement_error', '1X320/9', 500, '', array(), $e->getName() );
|
||||
}
|
||||
catch ( \DomainException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'billing_agreement_error', '1X320/A', 500 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Checkout Settings
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 28 Mar 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -41,7 +41,23 @@ class _checkoutsettings extends \IPS\Dispatcher\Controller
|
||||
* @return void
|
||||
*/
|
||||
public function manage()
|
||||
{
|
||||
{
|
||||
$requireBillingOptions = array();
|
||||
$requireBillingOptions['product'] = 'nexus_require_billing_package';
|
||||
if ( ( $giftVouchers = json_decode( \IPS\Settings::i()->nexus_gift_vouchers, TRUE ) and count( $giftVouchers ) ) or \IPS\Settings::i()->nexus_gift_vouchers_free )
|
||||
{
|
||||
$requireBillingOptions['giftvoucher'] = 'nexus_require_billing_gift';
|
||||
}
|
||||
if ( \IPS\Db::i()->select( 'COUNT(*)', 'nexus_donate_goals' )->first() )
|
||||
{
|
||||
$requireBillingOptions['donation'] = 'nexus_require_billing_donation';
|
||||
}
|
||||
if ( \IPS\Settings::i()->nexus_enom_un and $domainPrices = json_decode( \IPS\Settings::i()->nexus_domain_prices, TRUE ) and count( $domainPrices ) )
|
||||
{
|
||||
$requireBillingOptions['domain'] = 'nexus_require_billing_domain';
|
||||
}
|
||||
$requireBillingOptions['other'] = 'nexus_require_billing_other';
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->addHeader( 'checkout_settings' );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_https', \IPS\Settings::i()->nexus_https, FALSE, array(), function( $val )
|
||||
@@ -58,6 +74,7 @@ class _checkoutsettings extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
}
|
||||
} ) );
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'nexus_require_billing', explode( ',', \IPS\Settings::i()->nexus_require_billing ), FALSE, array( 'options' => $requireBillingOptions ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_split_payments_on', \IPS\Settings::i()->nexus_split_payments != -1, FALSE, array( 'togglesOn' => array( 'nexus_split_payments' ) ) ) );
|
||||
$form->add( new \IPS\nexus\Form\Money( 'nexus_split_payments', \IPS\Settings::i()->nexus_split_payments ?: '*', FALSE, array( 'unlimitedLang' => 'no_restriction' ), NULL, NULL, NULL, 'nexus_split_payments' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'nexus_tac', \IPS\Settings::i()->nexus_tac, FALSE, array(
|
||||
@@ -76,9 +93,14 @@ class _checkoutsettings extends \IPS\Dispatcher\Controller
|
||||
$form->addMessage( 'nexus_checkreg_desc' );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_checkreg_usernames', \IPS\Settings::i()->nexus_checkreg_usernames ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_checkreg_captcha', \IPS\Settings::i()->nexus_checkreg_captcha ) );
|
||||
if ( \IPS\Settings::i()->reg_auth_type != 'none' )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_checkreg_validate', \IPS\Settings::i()->nexus_checkreg_validate ) );
|
||||
}
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$values['nexus_split_payments'] = $values['nexus_split_payments_on'] ? ( $values['nexus_split_payments'] == '*' ? 0 : json_encode( $values['nexus_split_payments'] ) ) : -1;
|
||||
$values['nexus_require_billing'] = count( $values['nexus_require_billing'] ) ? implode( ',', $values['nexus_require_billing'] ) : 'none';
|
||||
$form->saveAsSettings( $values );
|
||||
|
||||
\IPS\Session::i()->log( 'acplogs__checkout_settings' );
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Currencies
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 26 Mar 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -45,6 +45,7 @@ class _currencies extends \IPS\Dispatcher\Controller
|
||||
$languages = \IPS\Lang::languages();
|
||||
|
||||
$matrix = new \IPS\Helpers\Form\Matrix;
|
||||
$matrix->squashFields = FALSE; // This has issues with select fields
|
||||
$matrix->langPrefix = 'currency_';
|
||||
$matrix->columns = array(
|
||||
'code' => function( $key, $value, $data )
|
||||
@@ -80,7 +81,7 @@ class _currencies extends \IPS\Dispatcher\Controller
|
||||
'default' => $defaults
|
||||
);
|
||||
|
||||
if ( !in_array( $code, array( 'AED', 'AFN', 'ALL', 'AMD', 'ANG', 'AOA', 'ARS', 'AUD', 'AWG', 'AZN', 'BAM', 'BBD', 'BDT', 'BGN', 'BHD', 'BIF', 'BMD', 'BND', 'BOB', 'BRL', 'BSD', 'BTN', 'BWP', 'BYR', 'BZD', 'CAD', 'CDF', 'CHF', 'CLP', 'CNY', 'COP', 'CRC', 'CUC', 'CUP', 'CVE', 'CZK', 'DJF', 'DKK', 'DOP', 'DZD', 'EGP', 'ERN', 'ETB', 'EUR', 'FJD', 'FKP', 'GBP', 'GEL', 'GGP', 'GHS', 'GIP', 'GMD', 'GNF', 'GTQ', 'GYD', 'HKD', 'HNL', 'HRK', 'HTG', 'HUF', 'IDR', 'ILS', 'IMP', 'INR', 'IQD', 'IRR', 'ISK', 'JEP', 'JMD', 'JOD', 'JPY', 'KES', 'KGS', 'KHR', 'KMF', 'KPW', 'KRW', 'KWD', 'KYD', 'KZT', 'LAK', 'LBP', 'LKR', 'LRD', 'LSL', 'LYD', 'MAD', 'MDL', 'MGA', 'MKD', 'MMK', 'MNT', 'MOP', 'MRO', 'MUR', 'MVR', 'MWK', 'MXN', 'MYR', 'MZN', 'NAD', 'NGN', 'NIO', 'NOK', 'NPR', 'NZD', 'OMR', 'PAB', 'PEN', 'PGK', 'PHP', 'PKR', 'PLN', 'PYG', 'QAR', 'RON', 'RSD', 'RUB', 'RWF', 'SAR', 'SBD', 'SCR', 'SDG', 'SEK', 'SGD', 'SHP', 'SLL', 'SOS', 'SPL*', 'SRD', 'STD', 'SVC', 'SYP', 'SZL', 'THB', 'TJS', 'TMT', 'TND', 'TOP', 'TRY', 'TTD', 'TVD', 'TWD', 'TZS', 'UAH', 'UGX', 'USD', 'UYU', 'UZS', 'VEF', 'VND', 'VUV', 'WST', 'XAF', 'XCD', 'XDR', 'XOF', 'XPF', 'YER', 'ZAR', 'ZMW', 'ZWD' ) ) )
|
||||
if ( !in_array( $code, array( 'AED', 'AFN', 'ALL', 'AMD', 'ANG', 'AOA', 'ARS', 'AUD', 'AWG', 'AZN', 'BAM', 'BBD', 'BDT', 'BGN', 'BHD', 'BIF', 'BMD', 'BND', 'BOB', 'BRL', 'BSD', 'BTN', 'BWP', 'BYN', 'BYR', 'BZD', 'CAD', 'CDF', 'CHF', 'CLP', 'CNY', 'COP', 'CRC', 'CUC', 'CUP', 'CVE', 'CZK', 'DJF', 'DKK', 'DOP', 'DZD', 'EGP', 'ERN', 'ETB', 'EUR', 'FJD', 'FKP', 'GBP', 'GEL', 'GGP', 'GHS', 'GIP', 'GMD', 'GNF', 'GTQ', 'GYD', 'HKD', 'HNL', 'HRK', 'HTG', 'HUF', 'IDR', 'ILS', 'IMP', 'INR', 'IQD', 'IRR', 'ISK', 'JEP', 'JMD', 'JOD', 'JPY', 'KES', 'KGS', 'KHR', 'KMF', 'KPW', 'KRW', 'KWD', 'KYD', 'KZT', 'LAK', 'LBP', 'LKR', 'LRD', 'LSL', 'LYD', 'MAD', 'MDL', 'MGA', 'MKD', 'MMK', 'MNT', 'MOP', 'MRO', 'MUR', 'MVR', 'MWK', 'MXN', 'MYR', 'MZN', 'NAD', 'NGN', 'NIO', 'NOK', 'NPR', 'NZD', 'OMR', 'PAB', 'PEN', 'PGK', 'PHP', 'PKR', 'PLN', 'PYG', 'QAR', 'RON', 'RSD', 'RUB', 'RWF', 'SAR', 'SBD', 'SCR', 'SDG', 'SEK', 'SGD', 'SHP', 'SLL', 'SOS', 'SPL*', 'SRD', 'STD', 'SVC', 'SYP', 'SZL', 'THB', 'TJS', 'TMT', 'TND', 'TOP', 'TRY', 'TTD', 'TVD', 'TWD', 'TZS', 'UAH', 'UGX', 'USD', 'UYU', 'UZS', 'VEF', 'VND', 'VUV', 'WST', 'XAF', 'XCD', 'XDR', 'XOF', 'XPF', 'YER', 'ZAR', 'ZMW', 'ZWD' ) ) )
|
||||
{
|
||||
$warnings .= \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->message( \IPS\Member::loggedIn()->language()->addToStack( 'currency_code_invalid', FALSE, array( 'sprintf' => array( $code ) ) ), 'warning' );
|
||||
}
|
||||
@@ -109,6 +110,22 @@ class _currencies extends \IPS\Dispatcher\Controller
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => json_encode( $save ) ), array( 'conf_key=?', 'nexus_currency' ) );
|
||||
\IPS\Settings::i()->nexus_currency = json_encode( $save );
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
|
||||
$definition = \IPS\Db::i()->getTableDefinition( 'nexus_package_base_prices' );
|
||||
|
||||
foreach ( $definition['columns'] AS $key => $value )
|
||||
{
|
||||
if ( $key === 'id' )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !isset( $save[$key] ) )
|
||||
{
|
||||
\IPS\Db::i()->dropColumn( 'nexus_package_base_prices', $key );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
\IPS\Session::i()->log( 'acplogs__currencies' );
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
/**
|
||||
* @brief donations
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 05 May 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
/**
|
||||
* @brief donations
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 17 Jun 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Notification Copy Settings
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 19 Aug 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Anti-Fraud Rules
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 11 Mar 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Payment Gateways
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 10 Feb 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Invoice Timeline
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 19 Jun 2015
|
||||
* @version SVN_VERSION_NUMBER
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Invoices
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 11 Feb 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -98,8 +98,8 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->title = $customer ? \IPS\Member::loggedIn()->language()->addToStack( 'members_invoices', FALSE, array( 'sprintf' => array( $customer->cm_name ) ) ) : \IPS\Member::loggedIn()->language()->addToStack('menu__nexus_payments_invoices');
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->block( 'title', (string) $table );
|
||||
\IPS\Output::i()->title = $customer ? \IPS\Member::loggedIn()->language()->addToStack( 'members_invoices', FALSE, array( 'sprintf' => array( $customer->cm_name ) ) ) : \IPS\Member::loggedIn()->language()->addToStack('menu__nexus_payments_invoices');
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->block( 'title', (string) $table );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,7 +123,7 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
$transactions = NULL;
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'transactions_manage' ) and ( !isset( \IPS\Request::i()->table ) ) )
|
||||
{
|
||||
$transactions = \IPS\nexus\Transaction::table( array( array( 't_invoice=?', $invoice->id ) ), $invoice->acpUrl(), 'i' );
|
||||
$transactions = \IPS\nexus\Transaction::table( array( array( 't_invoice=? and t_status<>?', $invoice->id, \IPS\nexus\Transaction::STATUS_PENDING ) ), $invoice->acpUrl(), 'i' );
|
||||
$transactions->limit = 50;
|
||||
$transactions->tableTemplate = array( \IPS\Theme::i()->getTemplate('invoices'), 'transactionsTable' );
|
||||
$transactions->rowsTemplate = array( \IPS\Theme::i()->getTemplate('invoices'), 'transactionsTableRows' );
|
||||
@@ -219,7 +219,7 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
/* Any pending transactions? */
|
||||
if ( !isset( \IPS\Request::i()->override ) and \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'transactions_manage' ) )
|
||||
{
|
||||
$pendingTransactions = $invoice->transactions( array( \IPS\nexus\Transaction::STATUS_WAITING, \IPS\nexus\Transaction::STATUS_HELD, \IPS\nexus\Transaction::STATUS_REVIEW ) );
|
||||
$pendingTransactions = $invoice->transactions( array( \IPS\nexus\Transaction::STATUS_WAITING, \IPS\nexus\Transaction::STATUS_HELD, \IPS\nexus\Transaction::STATUS_REVIEW, \IPS\nexus\Transaction::STATUS_GATEWAY_PENDING ) );
|
||||
if ( count( $pendingTransactions ) )
|
||||
{
|
||||
$transUrl = $invoice->acpUrl();
|
||||
@@ -248,7 +248,7 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
) );
|
||||
|
||||
/* Send Email */
|
||||
\IPS\Email::buildFromTemplate( 'nexus', 'invoiceMarkedPaid', array( $invoice, $invoice->summary() ) )
|
||||
\IPS\Email::buildFromTemplate( 'nexus', 'invoiceMarkedPaid', array( $invoice, $invoice->summary() ), \IPS\Email::TYPE_TRANSACTIONAL )
|
||||
->send(
|
||||
$invoice->member,
|
||||
array_map(
|
||||
@@ -276,7 +276,8 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
public function card()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'chargetocard' );
|
||||
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'customer.css', 'nexus', 'admin' ) );
|
||||
|
||||
/* Load Invoice */
|
||||
try
|
||||
{
|
||||
@@ -305,7 +306,7 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$amountToPay = $invoice->amountToPay()->amount;
|
||||
$form = new \IPS\Helpers\Form( 'amount', 'continue' );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 't_amount', $amountToPay, TRUE, array( 'min' => 0.01, 'max' => $amountToPay, 'decimals' => TRUE ), NULL, NULL, $invoice->currency ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 't_amount', $amountToPay, TRUE, array( 'min' => 0.01, 'max' => (string) $amountToPay, 'decimals' => TRUE ), NULL, NULL, $invoice->currency ) );
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
return $values;
|
||||
@@ -321,7 +322,7 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
$paymentMethodsToggles = array();
|
||||
foreach ( $gateways as $gateway )
|
||||
{
|
||||
foreach ( $gateway->paymentScreen( $invoice, $amountToPay ) as $element )
|
||||
foreach ( $gateway->paymentScreen( $invoice, $amountToPay, $invoice->member ) as $element )
|
||||
{
|
||||
if ( !$element->htmlId )
|
||||
{
|
||||
@@ -433,11 +434,11 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
$amountToPay = $invoice->amountToPay()->amount;
|
||||
$credits = $invoice->member->cm_credits;
|
||||
$credit = $credits[ $invoice->currency ]->amount;
|
||||
$maxCanCharge = ( $credit < $amountToPay ) ? $credit : $amountToPay;
|
||||
|
||||
$maxCanCharge = ( $credit->compare( $amountToPay ) === -1 ) ? $credit : $amountToPay;
|
||||
|
||||
/* Build Form */
|
||||
$form = new \IPS\Helpers\Form( 'amount', 'invoice_charge_to_credit' );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 't_amount', $maxCanCharge, TRUE, array( 'min' => 0.01, 'max' => $maxCanCharge, 'decimals' => TRUE ), NULL, NULL, $invoice->currency ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 't_amount', $maxCanCharge, TRUE, array( 'min' => 0.01, 'max' => (string) $maxCanCharge, 'decimals' => TRUE ), NULL, NULL, $invoice->currency ) );
|
||||
|
||||
/* Handle submissions */
|
||||
if ( $values = $form->values() )
|
||||
@@ -452,7 +453,7 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
$transaction->approve( NULL );
|
||||
$transaction->sendNotification();
|
||||
|
||||
$credits[ $invoice->currency ]->amount -= $values['t_amount'];
|
||||
$credits[ $invoice->currency ]->amount = $credits[ $invoice->currency ]->amount->subtract( $transaction->amount->amount );
|
||||
$invoice->member->cm_credits = $credits;
|
||||
$invoice->member->save();
|
||||
|
||||
@@ -527,9 +528,24 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X190/D', 404, '' );
|
||||
}
|
||||
|
||||
/* Get the address */
|
||||
$address = NULL;
|
||||
if ( $invoice->billaddress )
|
||||
{
|
||||
$address = $invoice->billaddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
$address = \IPS\nexus\Customer\Address::constructFromData( \IPS\Db::i()->select( '*', 'nexus_customer_addresses', array( "member=? AND primary_billing=?", $invoice->member->member_id, 1 ) )->first() )->address;
|
||||
}
|
||||
catch( \UnderflowException $e ) {}
|
||||
}
|
||||
|
||||
/* Get output */
|
||||
$output = \IPS\Theme::i()->getTemplate( 'invoices', 'nexus', 'global' )->printInvoice( $invoice, $invoice->summary() );
|
||||
$output = \IPS\Theme::i()->getTemplate( 'invoices', 'nexus', 'global' )->printInvoice( $invoice, $invoice->summary(), $address );
|
||||
\IPS\Output::i()->title = 'I' . $invoice->id;
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core', 'front' )->blankTemplate( $output ) );
|
||||
}
|
||||
@@ -585,7 +601,7 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
$form->add( $field );
|
||||
|
||||
/* Partial refund? */
|
||||
$field = new \IPS\Helpers\Form\Number( $transaction->id . '_refund_amount', ( $transaction->status === \IPS\nexus\Transaction::STATUS_PART_REFUNDED ? $transaction->amount->amount - $transaction->partial_refund->amount : 0 ), TRUE, array( 'unlimited' => 0, 'unlimitedLang' => \IPS\Member::loggedIn()->language()->addToStack( 'refund_full', FALSE, array( 'sprintf' => array( $transaction->amount ) ) ), 'max' => ( $transaction->amount->amount - $transaction->partial_refund->amount ), 'decimals' => TRUE ), NULL, NULL, $transaction->amount->currency, $transaction->id . '_refund_amount' );
|
||||
$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 );
|
||||
}
|
||||
@@ -595,7 +611,7 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
if ( $invoice->status === \IPS\nexus\Invoice::STATUS_PAID )
|
||||
{
|
||||
$statusOptions = array();
|
||||
if ( $invoice->total->amount !== (float) 0 )
|
||||
if ( !$invoice->total->amount->isZero() )
|
||||
{
|
||||
$statusOptions[ \IPS\nexus\Invoice::STATUS_PENDING ] = 'refund_invoice_pending';
|
||||
}
|
||||
@@ -724,6 +740,9 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'invoices_delete' );
|
||||
|
||||
/* Make sure the user confirmed the deletion */
|
||||
\IPS\Request::i()->confirmedDelete();
|
||||
|
||||
/* Load Transaction */
|
||||
try
|
||||
{
|
||||
@@ -758,21 +777,39 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
/* Init */
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'invoices_add' );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'admin_store.js', 'nexus', 'admin' ) );
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('generate_invoice');
|
||||
$url = \IPS\Http\Url::internal("app=nexus&module=payments&controller=invoices&do=generate");
|
||||
if ( isset( \IPS\Request::i()->member ) )
|
||||
{
|
||||
$url = $url->setQueryString( 'member', \IPS\Request::i()->member );
|
||||
}
|
||||
|
||||
/* Are we editing an invoice? */
|
||||
$invoice = NULL;
|
||||
if ( isset( \IPS\Request::i()->id ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$invoice = \IPS\nexus\Invoice::load( \IPS\Request::i()->id );
|
||||
|
||||
if ( $invoice->status === \IPS\nexus\Invoice::STATUS_PAID )
|
||||
{
|
||||
\IPS\Output::i()->error( 'cannot_edit_paid_invoice', '2X190/F', 403, '' );
|
||||
}
|
||||
|
||||
$url = $url->setQueryString( 'id', \IPS\Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
}
|
||||
\IPS\Output::i()->title = $invoice ? \IPS\Member::loggedIn()->language()->addToStack( 'invoice_number', FALSE, array( 'sprintf' => array( $invoice->id ) ) ) : \IPS\Member::loggedIn()->language()->addToStack('generate_invoice');
|
||||
|
||||
/* Select Customer */
|
||||
$steps = array();
|
||||
if ( !isset( \IPS\Request::i()->member ) )
|
||||
if ( !isset( \IPS\Request::i()->member ) and !$invoice )
|
||||
{
|
||||
$steps['invoice_generate_member'] = function( $data )
|
||||
{
|
||||
$form = new \IPS\Helpers\Form('customer', 'continue');
|
||||
$form->add( new \IPS\Helpers\Form\Member( 'invoice_generate_member' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Member( 'invoice_generate_member', NULL, TRUE ) );
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
return array( 'member' => $values['invoice_generate_member']->member_id );
|
||||
@@ -782,9 +819,9 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
/* Select Addresses */
|
||||
$steps['invoice_generate_settings'] = function( $data )
|
||||
$steps['invoice_generate_settings'] = function( $data ) use ( $invoice )
|
||||
{
|
||||
$customer = \IPS\nexus\Customer::load( isset( \IPS\Request::i()->member ) ? \IPS\Request::i()->member : $data['member'] );
|
||||
$customer = $invoice ? $invoice->member : ( \IPS\nexus\Customer::load( isset( \IPS\Request::i()->member ) ? \IPS\Request::i()->member : $data['member'] ) );
|
||||
|
||||
$form = new \IPS\Helpers\Form('settings', 'continue');
|
||||
|
||||
@@ -792,7 +829,7 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
$currencies = \IPS\nexus\Money::currencies();
|
||||
if ( count( $currencies ) > 1 )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'currency', $customer->defaultCurrency(), TRUE, array( 'options' => array_combine( $currencies, $currencies ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'currency', $invoice ? $invoice->currency : $customer->defaultCurrency(), TRUE, array( 'options' => array_combine( $currencies, $currencies ) ) ) );
|
||||
}
|
||||
$statusOptions = array();
|
||||
$statusOptions[ \IPS\nexus\Invoice::STATUS_PAID ] = 'invoice_status_paid';
|
||||
@@ -802,47 +839,58 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
$statusOptions[ \IPS\nexus\Invoice::STATUS_EXPIRED ] = 'invoice_status_expd';
|
||||
}
|
||||
$statusOptions[ \IPS\nexus\Invoice::STATUS_CANCELED ] = 'invoice_status_canc';
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'invoice_status', \IPS\nexus\Invoice::STATUS_PENDING, TRUE, array( 'options' => $statusOptions ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'invoice_title', NULL, FALSE ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'invoice_po_number', NULL, FALSE, array( 'maxLength' => 255 ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\TextArea( 'invoice_notes', NULL ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'invoice_status', $invoice ? $invoice->status : \IPS\nexus\Invoice::STATUS_PENDING, TRUE, array( 'options' => $statusOptions ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'invoice_title', $invoice ? $invoice->title : NULL, FALSE ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'invoice_po_number', $invoice ? $invoice->po_number : NULL, FALSE, array( 'maxLength' => 255 ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\TextArea( 'invoice_notes', $invoice ? $invoice->notes : NULL ) );
|
||||
|
||||
$form->addHeader( 'invoice_generate_addresses' );
|
||||
$addresses = \IPS\Db::i()->select( '*', 'nexus_customer_addresses', array( 'member=?', isset( \IPS\Request::i()->member ) ? \IPS\Request::i()->member : $data['member'] ) );
|
||||
$addresses = \IPS\Db::i()->select( '*', 'nexus_customer_addresses', array( 'member=?', $customer->member_id ) );
|
||||
if ( count( $addresses ) )
|
||||
{
|
||||
$billing = NULL;
|
||||
$shipping = 'x';
|
||||
$primaryBillingAddressId = NULL;
|
||||
$chosenBillingAddressId = 0;
|
||||
$primaryShippingAddressId = 'x';
|
||||
$chosenShippingAddressid = 0;
|
||||
$options = array();
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( $addresses, 'IPS\nexus\Customer\Address' ) as $address )
|
||||
{
|
||||
$options[ $address->id ] = (string) $address->address;
|
||||
if ( $address->primary_billing )
|
||||
{
|
||||
$billing = $address->id;
|
||||
$primaryBillingAddressId = $address->id;
|
||||
}
|
||||
if ( $address->primary_shipping )
|
||||
{
|
||||
$shipping = $address->id;
|
||||
$primaryShippingAddressId = $address->id;
|
||||
}
|
||||
|
||||
if ( $invoice and $invoice->billaddress and $invoice->billaddress == $address->address )
|
||||
{
|
||||
$chosenBillingAddressId = $address->id;
|
||||
}
|
||||
if ( $invoice and $invoice->shipaddress and $invoice->shipaddress == $address->address )
|
||||
{
|
||||
$chosenShippingAddressid = $address->id;
|
||||
}
|
||||
}
|
||||
$options[0] = 'other';
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'billing_address', $billing, TRUE, array( 'options' => $options, 'toggles' => array( 0 => array( 'new_billing_address' ) ) ) ) );
|
||||
$newAddress = new \IPS\Helpers\Form\Address( 'new_billing_address', NULL, FALSE, array(), NULL, NULL, NULL, 'new_billing_address' );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'billing_address', ( $invoice and $invoice->billaddress ) ? $chosenBillingAddressId : $primaryBillingAddressId, TRUE, array( 'options' => $options, 'toggles' => array( 0 => array( 'new_billing_address' ) ) ) ) );
|
||||
$newAddress = new \IPS\Helpers\Form\Address( 'new_billing_address', $invoice ? $invoice->billaddress : NULL, FALSE, array(), NULL, NULL, NULL, 'new_billing_address' );
|
||||
$newAddress->label = ' ';
|
||||
$form->add( $newAddress );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'shipping_address', ( $shipping == $billing ) ? 'x' : $shipping, TRUE, array( 'unlimited' => 'x', 'unlimitedLang' => 'same_as_billing_address', 'options' => $options, 'toggles' => array( 0 => array( 'new_shipping_address' ) ) ) ) );
|
||||
$newAddress = new \IPS\Helpers\Form\Address( 'new_shipping_address', NULL, FALSE, array(), NULL, NULL, NULL, 'new_shipping_address' );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'shipping_address', ( $invoice and $invoice->shipaddress ) ? $chosenShippingAddressid : ( ( $primaryShippingAddressId == $primaryBillingAddressId ) ? 'x' : $primaryShippingAddressId ), TRUE, array( 'options' => array( 'x' => 'same_as_billing_address' ) + $options, 'toggles' => array( 0 => array( 'new_shipping_address' ) ) ) ) );
|
||||
$newAddress = new \IPS\Helpers\Form\Address( 'new_shipping_address', $invoice ? $invoice->shipaddress : NULL, FALSE, array(), NULL, NULL, NULL, 'new_shipping_address' );
|
||||
$newAddress->label = ' ';
|
||||
$form->add( $newAddress );
|
||||
}
|
||||
else
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Address( 'new_billing_address', NULL, TRUE ) );
|
||||
$form->add( new \IPS\Helpers\Form\Checkbox( 'same_shipping_address', TRUE, FALSE, array( 'togglesOff' => array( 'new_shipping_address' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Address( 'new_shipping_address', NULL, FALSE, array(), NULL, NULL, NULL, 'new_shipping_address' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Address( 'new_billing_address', $invoice ? $invoice->billaddress : NULL, FALSE ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'shipping_address', ( $invoice and $invoice->shipaddress and $invoice->shipaddress != $invoice->billaddress ) ? '1' : 'x', FALSE, array( 'options' => array( 'x' => 'same_as_billing_address', '1' => 'other' ), 'toggles' => array( '1' => array( 'new_shipping_address' ) ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Address( 'new_shipping_address', $invoice ? $invoice->billaddress : NULL, FALSE, array(), NULL, NULL, NULL, 'new_shipping_address' ) );
|
||||
}
|
||||
|
||||
if ( $values = $form->values() )
|
||||
@@ -855,18 +903,19 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
if( $values['new_billing_address'] === NULL OR empty( $values['new_billing_address']->addressLines ) or !$values['new_billing_address']->city or !$values['new_billing_address']->country or ( !$values['new_billing_address']->region and array_key_exists( $values['new_billing_address']->country, \IPS\GeoLocation::$states ) ) or !$values['new_billing_address']->postalCode )
|
||||
{
|
||||
$form->error = \IPS\Member::loggedIn()->language()->addToStack('billing_address_required');
|
||||
return $form;
|
||||
$data['billaddress'] = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['billaddress'] = $values['new_billing_address'];
|
||||
}
|
||||
|
||||
$data['billaddress'] = $values['new_billing_address'];
|
||||
}
|
||||
|
||||
|
||||
if ( count( $addresses ) and $values['shipping_address'] and $values['shipping_address'] !== 'x' )
|
||||
{
|
||||
$data['shipaddress'] = \IPS\nexus\Customer\Address::load( $values['shipping_address'] )->address;
|
||||
}
|
||||
elseif ( ( isset( $values['same_shipping_address'] ) and $values['same_shipping_address'] ) or $values['shipping_address'] === 'x' )
|
||||
elseif ( $values['shipping_address'] === 'x' )
|
||||
{
|
||||
$data['shipaddress'] = $data['billaddress'];
|
||||
}
|
||||
@@ -874,19 +923,25 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
if( $values['new_shipping_address'] === NULL OR empty( $values['new_shipping_address']->addressLines ) or !$values['new_shipping_address']->city or !$values['new_shipping_address']->country or ( !$values['new_shipping_address']->region and array_key_exists( $values['new_shipping_address']->country, \IPS\GeoLocation::$states ) ) or !$values['new_shipping_address']->postalCode )
|
||||
{
|
||||
$form->error = \IPS\Member::loggedIn()->language()->addToStack('shipping_address_required');
|
||||
return $form;
|
||||
$data['shipaddress'] = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['shipaddress'] = $values['new_shipping_address'];
|
||||
}
|
||||
|
||||
$data['shipaddress'] = $values['new_shipping_address'];
|
||||
}
|
||||
|
||||
|
||||
$data['currency'] = isset( $values['currency'] ) ? $values['currency'] : $customer->defaultCurrency();
|
||||
$data['status'] = $values['invoice_status'];
|
||||
$data['title'] = $values['invoice_title'];
|
||||
$data['po_number'] = $values['invoice_po_number'];
|
||||
$data['notes'] = $values['invoice_notes'];
|
||||
|
||||
if ( $invoice )
|
||||
{
|
||||
$data['items'] = $invoice->items;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
@@ -894,13 +949,22 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
};
|
||||
|
||||
/* Add Items */
|
||||
$steps['invoice_generate_items'] = function( $data ) use ( $url )
|
||||
$steps['invoice_generate_items'] = function( $data ) use ( $url, $invoice )
|
||||
{
|
||||
$invoice = new \IPS\nexus\Invoice;
|
||||
$invoice->member = \IPS\Member::load( isset( \IPS\Request::i()->member ) ? \IPS\Request::i()->member : $data['member'] );
|
||||
if ( !$invoice )
|
||||
{
|
||||
$invoice = new \IPS\nexus\Invoice;
|
||||
$invoice->member = \IPS\Member::load( isset( \IPS\Request::i()->member ) ? \IPS\Request::i()->member : $data['member'] );
|
||||
}
|
||||
$invoice->currency = $data['currency'];
|
||||
$invoice->billaddress = $data['billaddress'];
|
||||
$invoice->shipaddress = $data['shipaddress'];
|
||||
if ( $data['billaddress'] )
|
||||
{
|
||||
$invoice->billaddress = $data['billaddress'];
|
||||
}
|
||||
if ( $data['shipaddress'] )
|
||||
{
|
||||
$invoice->shipaddress = $data['shipaddress'];
|
||||
}
|
||||
$invoice->items = isset( $data['items'] ) ? json_encode( $data['items'] ) : json_encode( array() );
|
||||
|
||||
if ( isset( \IPS\Request::i()->continue ) )
|
||||
@@ -1102,7 +1166,7 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
\IPS\DB::i()->update( 'core_tasks', array( 'enabled' => (int) (bool) $values['cm_invoice_expireafter'] ), "`key`='expireInvoices'" );
|
||||
\IPS\Db::i()->update( 'core_tasks', array( 'enabled' => (int) (bool) $values['cm_invoice_expireafter'] ), "`key`='expireInvoices'" );
|
||||
|
||||
$form->saveAsSettings();
|
||||
\IPS\Session::i()->log( 'acplogs__invoice_settings' );
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Payment Settings
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 26 Mar 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Payouts
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 07 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -138,7 +138,7 @@ class _payouts extends \IPS\Dispatcher\Controller
|
||||
\IPS\Session::i()->log( 'acplogs__payout_processed', array( $payout->id => FALSE ) );
|
||||
$payout->member->log( 'payout', array( 'type' => 'processed', 'amount' => $payout->amount->amount, 'currency' => $payout->amount->currency, 'payout_id' => $payout->id ) );
|
||||
|
||||
\IPS\Email::buildFromTemplate( 'nexus', 'payoutComplete', array( $payout ) )->send( $payout->member );
|
||||
\IPS\Email::buildFromTemplate( 'nexus', 'payoutComplete', array( $payout ), \IPS\Email::TYPE_TRANSACTIONAL )->send( $payout->member );
|
||||
|
||||
$this->_redirect( $payout );
|
||||
}
|
||||
@@ -178,7 +178,7 @@ class _payouts extends \IPS\Dispatcher\Controller
|
||||
\IPS\Session::i()->log( 'acplogs__payout_processed', array( $payout->id => FALSE ) );
|
||||
$payout->member->log( 'payout', array( 'type' => 'processed', 'amount' => $payout->amount->amount, 'currency' => $payout->amount->currency, 'payout_id' => $payout->id ) );
|
||||
|
||||
\IPS\Email::buildFromTemplate( 'nexus', 'payoutComplete', array( $payout ) )->send( $payout->member );
|
||||
\IPS\Email::buildFromTemplate( 'nexus', 'payoutComplete', array( $payout ), \IPS\Email::TYPE_TRANSACTIONAL )->send( $payout->member );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=payments&controller=payouts') );
|
||||
@@ -217,7 +217,7 @@ class _payouts extends \IPS\Dispatcher\Controller
|
||||
if ( \IPS\Request::i()->prompt )
|
||||
{
|
||||
$credits = $payout->member->cm_credits;
|
||||
$credits[ $payout->currency ]->amount += $payout->amount->amount;
|
||||
$credits[ $payout->amount->currency ]->amount = $credits[ $payout->amount->currency ]->amount->add( $payout->amount->amount );
|
||||
$payout->member->cm_credits = $credits;
|
||||
$payout->member->save();
|
||||
}
|
||||
@@ -234,6 +234,9 @@ class _payouts extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'payouts_delete' );
|
||||
|
||||
/* Make sure the user confirmed the deletion */
|
||||
\IPS\Request::i()->confirmedDelete();
|
||||
|
||||
try
|
||||
{
|
||||
$payout = \IPS\nexus\Payout::load( \IPS\Request::i()->id );
|
||||
@@ -264,7 +267,7 @@ class _payouts extends \IPS\Dispatcher\Controller
|
||||
$fields = array();
|
||||
foreach ( new \DirectoryIterator( \IPS\ROOT_PATH . '/applications/nexus/sources/Gateway' ) as $file )
|
||||
{
|
||||
if ( $file->isDir() and !$file->isDot() and file_exists( \IPS\ROOT_PATH . '/applications/nexus/sources/Gateway/' . $file . '/Payout.php' ) )
|
||||
if ( $file->isDir() and !$file->isDot() and $file != 'Stripe' and file_exists( \IPS\ROOT_PATH . '/applications/nexus/sources/Gateway/' . $file . '/Payout.php' ) )
|
||||
{
|
||||
$options[ (string) $file ] = 'payout__admin_' . $file;
|
||||
$toggles[ (string) $file ] = array( 'form_header_payout_settings' );
|
||||
@@ -304,6 +307,14 @@ class _payouts extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
$form->addHeader('payout_settings');
|
||||
$form->add( new \IPS\nexus\Form\Money( 'nexus_payout_min', \IPS\Settings::i()->nexus_payout_min ? json_decode( \IPS\Settings::i()->nexus_payout_min, TRUE ) : '*', FALSE, array( 'unlimitedLang' => 'no_restriction' ), NULL, NULL, NULL, 'nexus_payout_min' ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Custom( 'nexus_payout_maximum', NULL, FALSE, array( 'getHtml' => function( $element ) {
|
||||
$amount = new \IPS\nexus\Form\Money( 'nexus_payout_maximum[2]', \IPS\Settings::i()->nexus_payout_max ? json_decode( \IPS\Settings::i()->nexus_payout_max, TRUE ) : '*', FALSE, array( 'unlimitedLang' => 'no_restriction', 'unlimitedTogglesOff' => array( 'payout_max_limited' ) ), NULL, NULL, NULL, 'nexus_payout_max' );
|
||||
$period = \IPS\Settings::i()->nexus_payout_max_period ? json_decode( \IPS\Settings::i()->nexus_payout_max_period, TRUE ) : array( 1, 'day' );
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'payouts' )->maximumLimits( $amount->html(), (int) $period[0], $period[1] );
|
||||
} ), NULL, NULL, NULL, 'nexus_payout_maximum' ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_payout_approve', \IPS\Settings::i()->nexus_payout_approve, FALSE, array(), NULL, NULL, NULL, 'nexus_payout_approve' ) );
|
||||
$form->addHeader('topup_settings');
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'allow_topups', \IPS\Settings::i()->nexus_min_topup, FALSE, array( 'togglesOn' => array( 'nexus_min_topup', 'nexus_max_credit' ) ) ) );
|
||||
@@ -326,7 +337,9 @@ class _payouts extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
$values['nexus_payout'] = json_encode( $payoutSettings );
|
||||
$values['nexus_payout_min'] = is_array( $values['nexus_payout_min'] ) ? json_encode( $values['nexus_payout_min'] ) : '*';
|
||||
$values['nexus_payout_min'] = is_array( $values['nexus_payout_min'] ) ? json_encode( $values['nexus_payout_min'] ) : '*';
|
||||
$values['nexus_payout_max'] = is_array( $values['nexus_payout_maximum'][2] ) ? json_encode( $values['nexus_payout_maximum'][2] ) : '*';
|
||||
$values['nexus_payout_max_period'] = json_encode( array( $values['nexus_payout_maximum'][0], $values['nexus_payout_maximum'][1] ) );
|
||||
|
||||
if ( $values['allow_topups'] )
|
||||
{
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Transaction Review
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 26 Mar 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Shipments
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 20 Mar 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -550,7 +550,7 @@ class _shipping extends \IPS\Dispatcher\Controller
|
||||
|
||||
if ( isset( $response['error'] ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'err_err_easypost', '3X193/9', 500, '', array(), $response['error'] );
|
||||
\IPS\Output::i()->error( 'err_err_easypost', '3X193/9', 500, '', array(), $response['error']['message'] );
|
||||
}
|
||||
|
||||
$shipment->label = $response['postage_label']['label_url'];
|
||||
@@ -619,6 +619,9 @@ class _shipping extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'shiporders_delete' );
|
||||
|
||||
/* Make sure the user confirmed the deletion */
|
||||
\IPS\Request::i()->confirmedDelete();
|
||||
|
||||
/* Load */
|
||||
try
|
||||
{
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Shipping Rates
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 13 Feb 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -36,7 +36,108 @@ class _shippingrates extends \IPS\Node\Controller
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'shipping_manage' );
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'shipmethods_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Warning about unconsecutive rules
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function warning()
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->decision( 'ship_rates_' . \IPS\Request::i()->type, array(
|
||||
'ship_rates_go_back' => \IPS\Http\Url::internal( 'app=nexus&module=payments&controller=shippingrates&do=form&id=' . \IPS\Request::i()->id ),
|
||||
'ship_rates_save_anyway' => \IPS\Http\Url::internal( $this->url ),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect after save
|
||||
*
|
||||
* @param \IPS\Node\Model $old A clone of the node as it was before or NULL if this is a creation
|
||||
* @param \IPS\Node\Model $new The node now
|
||||
* @param string $lastUsedTab The tab last used in the form
|
||||
* @return void
|
||||
*/
|
||||
protected function _afterSave( \IPS\Node\Model $old = NULL, \IPS\Node\Model $new, $lastUsedTab = FALSE )
|
||||
{
|
||||
$haveNoLowerLimit = FALSE;
|
||||
$haveNoUpperLimit = FALSE;
|
||||
$lastUpper = NULL;
|
||||
$consecutive = TRUE;
|
||||
|
||||
foreach ( json_decode( $new->rates, TRUE ) as $rate )
|
||||
{
|
||||
if ( !$haveNoLowerLimit )
|
||||
{
|
||||
if ( $rate['min'] === '*' )
|
||||
{
|
||||
$haveNoLowerLimit = TRUE;
|
||||
}
|
||||
elseif ( is_array( $rate['min'] ) )
|
||||
{
|
||||
$allAreZero = TRUE;
|
||||
foreach ( $rate['min'] as $val )
|
||||
{
|
||||
if ( $val !== 0 )
|
||||
{
|
||||
$allAreZero = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $allAreZero )
|
||||
{
|
||||
$haveNoLowerLimit = TRUE;
|
||||
}
|
||||
}
|
||||
elseif ( $rate['min'] === 0 )
|
||||
{
|
||||
$haveNoLowerLimit = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !$haveNoUpperLimit and $rate['max'] === '*' )
|
||||
{
|
||||
$haveNoUpperLimit = TRUE;
|
||||
}
|
||||
|
||||
if ( $lastUpper !== NULL )
|
||||
{
|
||||
if ( is_array( $lastUpper ) )
|
||||
{
|
||||
foreach ( $lastUpper as $k => $v )
|
||||
{
|
||||
if ( strval( $rate['min'][ $k ] - $v ) > 0.01 ) # @note: We use strval() here to prevent PHP from applying a precision to the float, inadvertently causing this to return TRUE
|
||||
{
|
||||
$consecutive = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ( strval( $rate['min'] - $lastUpper ) > 0.01 ) # @note: We use strval() here to prevent PHP from applying a precision to the float, inadvertently causing this to return TRUE
|
||||
{
|
||||
$consecutive = FALSE;
|
||||
}
|
||||
}
|
||||
$lastUpper = $rate['max'];
|
||||
}
|
||||
|
||||
if( !$haveNoLowerLimit )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $this->url->setQueryString( array( 'do' => 'warning', 'type' => 'missing_lower', 'id' => $new->_id ) ) );
|
||||
}
|
||||
elseif( !$haveNoUpperLimit )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $this->url->setQueryString( array( 'do' => 'warning', 'type' => 'missing_upper', 'id' => $new->_id ) ) );
|
||||
}
|
||||
elseif ( !$consecutive )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $this->url->setQueryString( array( 'do' => 'warning', 'type' => 'unconsecutive', 'id' => $new->_id ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
parent::_afterSave( $old, $new, $lastUsedTab );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Tax Classes
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 12 Feb 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Transactions
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 11 Feb 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -44,9 +44,9 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
protected function manage()
|
||||
{
|
||||
/* Create Table */
|
||||
$table = \IPS\nexus\Transaction::table( array(), \IPS\Http\Url::internal( 'app=nexus&module=payments&controller=transactions' ), 't' );
|
||||
$table = \IPS\nexus\Transaction::table( array( array( 't_status<>?', \IPS\nexus\Transaction::STATUS_PENDING ) ), \IPS\Http\Url::internal( 'app=nexus&module=payments&controller=transactions' ), 't' );
|
||||
$table->filters = array(
|
||||
'tstatus_hold' => array( 't_status=?', 'hold' ),
|
||||
'tstatus_hold' => array( '( t_status=? OR t_status=? )', \IPS\nexus\Transaction::STATUS_HELD, \IPS\nexus\Transaction::STATUS_REVIEW ),
|
||||
);
|
||||
$table->advancedSearch = array(
|
||||
't_id' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
@@ -106,18 +106,21 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
$method = $transaction->method;
|
||||
|
||||
/* Can we approve it? */
|
||||
if ( !in_array( $transaction->status, array( \IPS\nexus\Transaction::STATUS_PENDING, \IPS\nexus\Transaction::STATUS_WAITING, \IPS\nexus\Transaction::STATUS_HELD, \IPS\nexus\Transaction::STATUS_REVIEW ) ) )
|
||||
if ( !in_array( $transaction->status, array( \IPS\nexus\Transaction::STATUS_PENDING, \IPS\nexus\Transaction::STATUS_WAITING, \IPS\nexus\Transaction::STATUS_HELD, \IPS\nexus\Transaction::STATUS_REVIEW, \IPS\nexus\Transaction::STATUS_GATEWAY_PENDING ) ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'transaction_status_err', '2X186/A', 403, '' );
|
||||
}
|
||||
|
||||
/* Log it */
|
||||
$transaction->member->log( 'transaction', array(
|
||||
'type' => 'status',
|
||||
'status' => \IPS\nexus\Transaction::STATUS_PAID,
|
||||
'id' => $transaction->id
|
||||
) );
|
||||
|
||||
if( $transaction->member )
|
||||
{
|
||||
$transaction->member->log( 'transaction', array(
|
||||
'type' => 'status',
|
||||
'status' => \IPS\nexus\Transaction::STATUS_PAID,
|
||||
'id' => $transaction->id
|
||||
) );
|
||||
}
|
||||
|
||||
/* Do it */
|
||||
try
|
||||
{
|
||||
@@ -183,22 +186,28 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
/* Create a support request? */
|
||||
if ( \IPS\Settings::i()->nexus_revw_sa != -1 )
|
||||
{
|
||||
$extraData = array();
|
||||
if ( $transaction->member->member_id )
|
||||
{
|
||||
$extraData['member'] = $transaction->member->member_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
$extraData['email'] = $transaction->invoice->guest_data['member']['email'];
|
||||
}
|
||||
|
||||
$createUrl = \IPS\Http\Url::internal('app=nexus&module=support&controller=requests&do=create');
|
||||
$key = md5( $createUrl );
|
||||
|
||||
if ( \IPS\Settings::i()->nexus_revw_sa )
|
||||
{
|
||||
$_SESSION["wizard-{$key}-data"] = array(
|
||||
'member' => $transaction->member->member_id,
|
||||
'stock_action' => \IPS\Settings::i()->nexus_revw_sa
|
||||
);
|
||||
$extraData['stock_action'] = \IPS\Settings::i()->nexus_revw_sa;
|
||||
$_SESSION["wizard-{$key}-data"] = $extraData;
|
||||
$_SESSION["wizard-{$key}-step"] = 'request_details';
|
||||
}
|
||||
else
|
||||
{
|
||||
$_SESSION["wizard-{$key}-data"] = array(
|
||||
'member' => $transaction->member->member_id,
|
||||
);
|
||||
$_SESSION["wizard-{$key}-data"] = $extraData;
|
||||
if ( count( \IPS\nexus\Support\StockAction::roots() ) )
|
||||
{
|
||||
$_SESSION["wizard-{$key}-step"] = 'stock_action';
|
||||
@@ -240,7 +249,7 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
$method = $transaction->method;
|
||||
|
||||
/* Can we void it? */
|
||||
if ( !in_array( $transaction->status, array( \IPS\nexus\Transaction::STATUS_PENDING, \IPS\nexus\Transaction::STATUS_WAITING ) ) and ( !$transaction->auth or !in_array( $transaction->status, array( \IPS\nexus\Transaction::STATUS_HELD, \IPS\nexus\Transaction::STATUS_REVIEW ) ) ) )
|
||||
if ( !in_array( $transaction->status, array( \IPS\nexus\Transaction::STATUS_PENDING, \IPS\nexus\Transaction::STATUS_WAITING, \IPS\nexus\Transaction::STATUS_GATEWAY_PENDING ) ) and ( !$transaction->auth or !in_array( $transaction->status, array( \IPS\nexus\Transaction::STATUS_HELD, \IPS\nexus\Transaction::STATUS_REVIEW ) ) ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'transaction_status_err', '2X186/5', 403, '' );
|
||||
}
|
||||
@@ -248,7 +257,7 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
/* Void it */
|
||||
try
|
||||
{
|
||||
$transaction->method->void( $transaction );
|
||||
$transaction->void( $transaction );
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
@@ -257,18 +266,6 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
\IPS\Output::i()->error( \IPS\Member::loggedIn()->language()->addToStack( 'transaction_void_err', FALSE, array( 'sprintf' => array( $transaction->acpUrl()->setQueryString( array( 'do' => 'void', 'override' => 1 ) ) ) ) ), '3X186/6', 500, '', array(), $e->getMessage() );
|
||||
}
|
||||
}
|
||||
$extra = $transaction->extra;
|
||||
$extra['history'][] = array( 's' => \IPS\nexus\Transaction::STATUS_REFUSED, 'on' => time(), 'by' => \IPS\Member::loggedIn()->member_id );
|
||||
$transaction->extra = $extra;
|
||||
$transaction->status = \IPS\nexus\Transaction::STATUS_REFUSED;
|
||||
$transaction->save();
|
||||
|
||||
/* Log it */
|
||||
$transaction->member->log( 'transaction', array(
|
||||
'type' => 'status',
|
||||
'status' => \IPS\nexus\Transaction::STATUS_REFUSED,
|
||||
'id' => $transaction->id
|
||||
) );
|
||||
|
||||
/* Send Email */
|
||||
$transaction->sendNotification();
|
||||
@@ -320,7 +317,7 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
/* Build form */
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'refund_method', ( $method and $method::SUPPORTS_REFUNDS ) ? 'gateway' : 'credit', TRUE, array( 'options' => $refundMethods, 'toggles' => $refundMethodToggles ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'refund_amount', ( $transaction->status === \IPS\nexus\Transaction::STATUS_PART_REFUNDED ? $transaction->amount->amount - $transaction->partial_refund->amount : 0 ), TRUE, array( 'unlimited' => 0, 'unlimitedLang' => \IPS\Member::loggedIn()->language()->addToStack( 'refund_full', FALSE, array( 'sprintf' => array( $transaction->amount ) ) ), 'max' => ( $transaction->amount->amount - $transaction->partial_refund->amount ), 'decimals' => TRUE ), NULL, NULL, $transaction->amount->currency, 'refund_amount' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'refund_amount', ( $transaction->status === \IPS\nexus\Transaction::STATUS_PART_REFUNDED ? $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, 'refund_amount' ) );
|
||||
if ( $transaction->invoice->status === \IPS\nexus\Invoice::STATUS_PAID )
|
||||
{
|
||||
$field = new \IPS\Helpers\Form\Radio( 'refund_invoice_status', \IPS\nexus\Invoice::STATUS_PENDING, TRUE, array(
|
||||
@@ -388,6 +385,9 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'transactions_delete' );
|
||||
|
||||
/* Make sure the user confirmed the deletion */
|
||||
\IPS\Request::i()->confirmedDelete();
|
||||
|
||||
/* Load Transaction */
|
||||
try
|
||||
{
|
||||
@@ -402,11 +402,18 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
$transaction->delete();
|
||||
|
||||
/* Log it */
|
||||
$transaction->member->log( 'transaction', array(
|
||||
'type' => 'delete',
|
||||
'id' => $transaction->id,
|
||||
'method' => $transaction->method->id
|
||||
) );
|
||||
try
|
||||
{
|
||||
$transaction->member->log( 'transaction', array(
|
||||
'type' => 'delete',
|
||||
'id' => $transaction->id,
|
||||
'method' => $transaction->method->id
|
||||
) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
// If the member no longer exists, we just won't log it
|
||||
}
|
||||
|
||||
/* Redirect */
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=payments&controller=transactions') );
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Income Report
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 14 Aug 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Markets Report
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 14 Aug 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Purchases Reports
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 14 Aug 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Coupons
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 05 May 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
/**
|
||||
* @brief fields
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 01 May 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
@@ -50,4 +50,40 @@ class _fields extends \IPS\Node\Controller
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'forms', 'core' )->blurb( 'custom_package_fields_blurb' );
|
||||
return parent::manage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Warning about unconsecutive rules
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function warning()
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'store' )->productOptionsChanged(
|
||||
new \IPS\Patterns\ActiveRecordIterator(
|
||||
\IPS\Db::i()->select( '*', 'nexus_packages', \IPS\Db::i()->in( 'p_id', explode( ',', \IPS\Request::i()->ids ) ) ),
|
||||
'IPS\nexus\Package'
|
||||
)
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Redirect after save
|
||||
*
|
||||
* @param \IPS\Node\Model $old A clone of the node as it was before or NULL if this is a creation
|
||||
* @param \IPS\Node\Model $new The node now
|
||||
* @param string $lastUsedTab The tab last used in the form
|
||||
* @return void
|
||||
*/
|
||||
protected function _afterSave( \IPS\Node\Model $old = NULL, \IPS\Node\Model $new, $lastUsedTab = FALSE )
|
||||
{
|
||||
if ( $old AND $old->extra != $new->extra )
|
||||
{
|
||||
$products = \IPS\Db::i()->select( 'DISTINCT(opt_package)', 'nexus_product_options', "opt_values LIKE '%\"{$new->_id}\":%'" );
|
||||
if ( count( $products ) )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $this->url->setQueryString( array( 'do' => 'warning', 'ids' => implode( ',', iterator_to_array( $products ) ) ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
parent::_afterSave( $old, $new, $lastUsedTab );
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Packages
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 29 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -61,15 +61,16 @@ class _packages extends \IPS\Node\Controller
|
||||
/**
|
||||
* Redirect after save
|
||||
*
|
||||
* @param \IPS\Node\Model $old A clone of the node as it was before or NULL if this is a creation
|
||||
* @param \IPS\Node\Model $node The node now
|
||||
* @param \IPS\Node\Model $old A clone of the node as it was before or NULL if this is a creation
|
||||
* @param \IPS\Node\Model $new The node now
|
||||
* @param string $lastUsedTab The tab last used in the form
|
||||
* @return void
|
||||
*/
|
||||
protected function _afterSave( \IPS\Node\Model $old = NULL, \IPS\Node\Model $new )
|
||||
protected function _afterSave( \IPS\Node\Model $old = NULL, \IPS\Node\Model $new, $lastUsedTab = FALSE )
|
||||
{
|
||||
if ( !( $new instanceof \IPS\nexus\Package ) )
|
||||
{
|
||||
return parent::_afterSave( $old, $new );
|
||||
return parent::_afterSave( $old, $new, $lastUsedTab );
|
||||
}
|
||||
|
||||
$changes = array();
|
||||
@@ -84,18 +85,21 @@ class _packages extends \IPS\Node\Controller
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear cache */
|
||||
unset( \IPS\Data\Store::i()->nexusPackagesWithReviews );
|
||||
|
||||
/* If something has changed, see if anyone has purchased */
|
||||
$purchases = 0;
|
||||
|
||||
if( count( $changes ) )
|
||||
{
|
||||
$purchases = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=?', 'nexus', 'package', $new->id ) )->first();
|
||||
}
|
||||
}
|
||||
|
||||
/* Only show this screen if the package has been purchased. Otherwise even just copying a package and saving asks if you want to update
|
||||
existing purchases unnecessarily */
|
||||
if ( !empty( $changes ) AND $purchases )
|
||||
{
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->decision( 'product_change_blurb', array(
|
||||
'product_change_blurb_existing' => \IPS\Http\Url::internal( "app=nexus&module=store&controller=packages&do=updateExisting&id={$new->_id}" )->setQueryString( 'changes', json_encode( $changes ) ),
|
||||
'product_change_blurb_new' => $this->url->setQueryString( array( 'root' => ( $new->parent() ? $new->parent()->_id : '' ) ) ),
|
||||
@@ -103,7 +107,7 @@ class _packages extends \IPS\Node\Controller
|
||||
}
|
||||
else
|
||||
{
|
||||
return parent::_afterSave( $old, $new );
|
||||
return parent::_afterSave( $old, $new, $lastUsedTab );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +131,7 @@ class _packages extends \IPS\Node\Controller
|
||||
|
||||
if ( !isset( \IPS\Request::i()->processing ) )
|
||||
{
|
||||
if ( isset( $changes['renew_options'] ) )
|
||||
if ( isset( $changes['renew_options'] ) and $changes['renew_options'] )
|
||||
{
|
||||
$matrix = new \IPS\Helpers\Form\Matrix( 'matrix', 'continue' );
|
||||
$matrix->manageable = FALSE;
|
||||
@@ -206,36 +210,78 @@ class _packages extends \IPS\Node\Controller
|
||||
{
|
||||
$renewOptions = json_decode( $changes['renew_options'], TRUE );
|
||||
$changes['renew_options'] = array();
|
||||
foreach ( $renewOptions as $k => $data )
|
||||
if( !empty( $renewOptions ) )
|
||||
{
|
||||
$changes['renew_options'][ $k ] = array( 'old' => $data, 'new' => $values[ $k ]['now_pay'] );
|
||||
foreach ( $renewOptions as $k => $data )
|
||||
{
|
||||
$changes['renew_options'][ $k ] = array( 'old' => $data, 'new' => $values[ $k ]['now_pay'] );
|
||||
}
|
||||
}
|
||||
|
||||
$changes['renew_options']['x'] = array( 'old' => 'x', 'new' => $values['x']['now_pay'] );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->output = $matrix;
|
||||
{
|
||||
\IPS\Output::i()->output .= $matrix;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $changes['renew_options'] ) and !isset( \IPS\Request::i()->ba ) )
|
||||
{
|
||||
$needBaPrompt = FALSE;
|
||||
foreach ( $changes['renew_options'] as $ro )
|
||||
{
|
||||
if ( !in_array( $ro['new'], array( '-', 'x', 'y', 'z' ) ) )
|
||||
{
|
||||
$needBaPrompt = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $needBaPrompt and $withBillingAgreement = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=? AND ps_billing_agreement>0 AND ba_canceled=0', 'nexus', 'package', $package->id ) )->join( 'nexus_billing_agreements', 'ba_id=ps_billing_agreement' )->first() )
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->decision( 'change_renew_ba_blurb', array(
|
||||
'change_renew_ba_skip' => \IPS\Http\Url::internal( "app=nexus&module=store&controller=packages&do=updateExisting" )->setQueryString( array(
|
||||
'id' => \IPS\Request::i()->id,
|
||||
'changes' => json_encode( $changes ),
|
||||
'processing'=> 1,
|
||||
'ba' => 0
|
||||
) ),
|
||||
'change_renew_ba_cancel' => \IPS\Http\Url::internal( "app=nexus&module=store&controller=packages&do=updateExisting" )->setQueryString( array(
|
||||
'id' => \IPS\Request::i()->id,
|
||||
'changes' => json_encode( $changes ),
|
||||
'processing'=> 1,
|
||||
'ba' => 1
|
||||
) ),
|
||||
'change_renew_ba_go_back' => \IPS\Http\Url::internal( "app=nexus&module=store&controller=packages&do=updateExisting" )->setQueryString( array(
|
||||
'id' => \IPS\Request::i()->id,
|
||||
'changes' => \IPS\Request::i()->changes,
|
||||
) ),
|
||||
) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = new \IPS\Helpers\MultipleRedirect(
|
||||
\IPS\Http\Url::internal( "app=nexus&module=store&controller=packages&do=updateExisting&id=1&changes=secondary_group" )->setQueryString( array(
|
||||
'id' => \IPS\Request::i()->id,
|
||||
'changes' => json_encode( $changes ),
|
||||
'processing'=> 1
|
||||
'processing'=> 1,
|
||||
'ba' => isset( \IPS\Request::i()->ba ) ? \IPS\Request::i()->ba : 0
|
||||
) ),
|
||||
function( $offset ) use ( $package, $changes )
|
||||
{
|
||||
$select = \IPS\Db::i()->select( '*', 'nexus_purchases', array( "ps_app=? and ps_type=? and ps_item_id=?", 'nexus', 'package', $package->id ), 'ps_id', array( $offset, 1 ), NULL, NULL, \IPS\DB::SELECT_SQL_CALC_FOUND_ROWS );
|
||||
$offset = intval( $offset );
|
||||
$select = \IPS\Db::i()->select( '*', 'nexus_purchases', array( "ps_app=? and ps_type=? and ps_item_id=?", 'nexus', 'package', $package->id ), 'ps_id', array( $offset, 1 ), NULL, NULL, \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS );
|
||||
|
||||
try
|
||||
{
|
||||
$purchase = \IPS\nexus\Purchase::constructFromData( $select->first() );
|
||||
$total = $select->count( TRUE );
|
||||
|
||||
$package->updatePurchase( $purchase, $changes );
|
||||
$package->updatePurchase( $purchase, $changes, \IPS\Request::i()->ba );
|
||||
|
||||
return array( ++$offset, \IPS\Member::loggedIn()->language()->get('processing'), 100 / $total * $offset );
|
||||
}
|
||||
@@ -331,7 +377,7 @@ class _packages extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function view_purchases()
|
||||
protected function viewPurchases()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'purchases_view', 'nexus', 'customers' );
|
||||
|
||||
@@ -344,7 +390,7 @@ class _packages extends \IPS\Node\Controller
|
||||
\IPS\Output::i()->error( 'node_error', '2X249/2', 404, '' );
|
||||
}
|
||||
|
||||
$table = new \IPS\Helpers\Table\Db( 'nexus_purchases', \IPS\Http\Url::internal( "app=nexus&module=store&controller=packages&do=view_purchases&id={$package->id}" ), array( array( 'ps_app=? AND ps_type=? AND ps_item_id=?', 'nexus', 'package', $package->id ) ) );
|
||||
$table = new \IPS\Helpers\Table\Db( 'nexus_purchases', \IPS\Http\Url::internal( "app=nexus&module=store&controller=packages&do=viewPurchases&id={$package->id}" ), array( array( 'ps_app=? AND ps_type=? AND ps_item_id=?', 'nexus', 'package', $package->id ) ) );
|
||||
$table->include = array( 'ps_id', 'ps_member', 'purchase_status', 'ps_start', 'ps_expire', 'ps_renewals' );
|
||||
$table->quickSearch = 'ps_id';
|
||||
$table->advancedSearch = array(
|
||||
@@ -356,7 +402,14 @@ class _packages extends \IPS\Node\Controller
|
||||
$table->filters = array( 'active' => 'ps_active=1' );
|
||||
$table->parsers = array(
|
||||
'ps_member' => function( $val ) {
|
||||
return \IPS\nexus\Customer::load( $val )->link();
|
||||
try
|
||||
{
|
||||
return \IPS\nexus\Customer::load( $val )->link();
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('deleted_member');
|
||||
}
|
||||
},
|
||||
'purchase_status' => function( $val, $row ) {
|
||||
$purchase = \IPS\nexus\Purchase::constructFromData( $row );
|
||||
@@ -368,7 +421,7 @@ class _packages extends \IPS\Node\Controller
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('purchase_expired');
|
||||
}
|
||||
elseif ( $purchase->grace_period and $purchase->expire->getTimestamp() < time() )
|
||||
elseif ( $purchase->grace_period and ( $purchase->expire and $purchase->expire->getTimestamp() < time() ) )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('purchase_in_grace_period');
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Store Settings
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 05 May 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -58,7 +58,7 @@ class _settings extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$groups[ $group->g_id ] = $group->name;
|
||||
}
|
||||
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->addTab('nexus_store_display');
|
||||
$form->addHeader('nexus_store_tax');
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Autoresolve Settings
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 25 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -34,7 +34,18 @@ class _autoresolve extends \IPS\Dispatcher\Controller
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'autoresolve_manage' );
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_autoresolve_on', \IPS\Settings::i()->nexus_autoresolve_days, FALSE, array( 'togglesOn' => array( 'nexus_autoresolve_departments', 'nexus_autoresolve_applicable', 'nexus_autoresolve_days', 'nexus_autoresolve_notify', 'nexus_autoresolve_status' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_autoresolve_on', \IPS\Settings::i()->nexus_autoresolve_days, FALSE, array( 'togglesOn' => array( 'reply_request_resolved', 'nexus_autoresolve_departments', 'nexus_autoresolve_applicable', 'nexus_autoresolve_days', 'nexus_autoresolve_notify', 'nexus_autoresolve_status' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'reply_request_resolved', \IPS\Settings::i()->reply_request_resolved, FALSE, array(
|
||||
'options' => array(
|
||||
'reopen' => 'reopen_request_autoresolve',
|
||||
'create' => 'create_new_request_autoresolve',
|
||||
'reject' => 'reject_notify_user_autoresolve'
|
||||
),
|
||||
'descriptions' => array(
|
||||
'create' => \IPS\Member::loggedIn()->language()->addToStack( 'create_new_request_autoresolve_desc' ),
|
||||
'reject' => \IPS\Member::loggedIn()->language()->addToStack( 'reject_notify_user_autoresolve_desc' )
|
||||
)
|
||||
) ) );
|
||||
$form->addSeparator();
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'nexus_autoresolve_departments', \IPS\Settings::i()->nexus_autoresolve_departments === '*' ? 0 : explode( ',', \IPS\Settings::i()->nexus_autoresolve_departments ), FALSE, array( 'class' => 'IPS\nexus\Support\Department', 'multiple' => TRUE, 'zeroVal' => 'any' ), NULL, NULL, NULL, 'nexus_autoresolve_departments' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'nexus_autoresolve_applicable', \IPS\Settings::i()->nexus_autoresolve_applicable, FALSE, array( 'class' => 'IPS\nexus\Support\Status', 'multiple' => TRUE ), NULL, NULL, NULL, 'nexus_autoresolve_applicable' ) );
|
||||
@@ -44,16 +55,16 @@ class _autoresolve extends \IPS\Dispatcher\Controller
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
\IPS\DB::i()->update( 'core_tasks', array( 'enabled' => (int) $values['nexus_autoresolve_on'] ), "`key`='supportAutoresolve'" );
|
||||
\IPS\Db::i()->update( 'core_tasks', array( 'enabled' => (int) $values['nexus_autoresolve_on'] ), "`key`='supportAutoresolve'" );
|
||||
|
||||
if ( !$values['nexus_autoresolve_on'] )
|
||||
{
|
||||
$values['nexus_autoresolve_days'] = 0;
|
||||
}
|
||||
unset( $values['nexus_autoresolve_on'] );
|
||||
|
||||
|
||||
$values['nexus_autoresolve_departments'] = $values['nexus_autoresolve_departments'] ? implode( ',' , array_keys( $values['nexus_autoresolve_departments'] ) ) : '*';
|
||||
$values['nexus_autoresolve_applicable'] = implode( ',', array_keys( $values['nexus_autoresolve_applicable'] ) );
|
||||
$values['nexus_autoresolve_applicable'] = is_array( $values['nexus_autoresolve_applicable'] ) ? implode( ',', array_keys( $values['nexus_autoresolve_applicable'] ) ) : $values['nexus_autoresolve_applicable'];
|
||||
$values['nexus_autoresolve_status'] = $values['nexus_autoresolve_status']->id;
|
||||
|
||||
$form->saveAsSettings( $values );
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Customer Feedback Settings
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 23 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Support Departments
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 08 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -50,7 +50,12 @@ class _departments extends \IPS\Node\Controller
|
||||
try
|
||||
{
|
||||
$node = \IPS\nexus\Support\Department::load( \IPS\Request::i()->id );
|
||||
|
||||
|
||||
if( \IPS\Settings::i()->contact_type == 'contact_nexus_department' AND \IPS\Settings::i()->contact_nexus_department == $node->id )
|
||||
{
|
||||
\IPS\Output::i()->error( 'nexus_nodeletedept_contactus', '1X344/1', 403, '' );
|
||||
}
|
||||
|
||||
if ( $node->canDelete() and \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_requests', array( 'r_department=?', $node->id ) ) )
|
||||
{
|
||||
$form = new \IPS\Helpers\Form( 'delete', 'delete' );
|
||||
@@ -62,15 +67,16 @@ class _departments extends \IPS\Node\Controller
|
||||
{
|
||||
\IPS\Db::i()->update( 'nexus_support_requests', array( 'r_department' => $values['move_existing_requests_to']->id ), array( 'r_department=?', $node->id ) );
|
||||
\IPS\Request::i()->form_submitted = TRUE;
|
||||
\IPS\Request::i()->wasConfirmed = TRUE;
|
||||
return parent::delete();
|
||||
}
|
||||
|
||||
|
||||
\IPS\Output::i()->output = $form;
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e ){}
|
||||
|
||||
|
||||
return parent::delete();
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Support Custom Fields
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 16 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Incoming Email Setup
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 16 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -93,6 +93,10 @@ class _incomingemail extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$content = \IPS\Theme::i()->getTemplate('incomingemailsetup')->pop3( $this->_pop3() );
|
||||
}
|
||||
elseif ( \IPS\Request::i()->type === 'sendgrid' )
|
||||
{
|
||||
$content = \IPS\Theme::i()->getTemplate('incomingemailsetup')->sendgrid();
|
||||
}
|
||||
else
|
||||
{
|
||||
$content = \IPS\Theme::i()->getTemplate('incomingemailsetup')->splash( (string) $table );
|
||||
@@ -127,8 +131,15 @@ class _incomingemail extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
protected function disablePop3()
|
||||
{
|
||||
foreach ( array( 'pop3_server', 'pop3_port', 'pop3_user', 'pop3_password' ) as $k )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => '' ), array( 'conf_key=?', $k ) );
|
||||
\IPS\Settings::i()->$k = '';
|
||||
}
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
|
||||
\IPS\Session::i()->log( 'acplogs__pop3_settings' );
|
||||
\IPS\DB::i()->update( 'core_tasks', array( 'enabled' => 0 ), array( 'app=? AND `key`=?', 'core', 'pop' ) );
|
||||
\IPS\Db::i()->update( 'core_tasks', array( 'enabled' => 0 ), array( 'app=? AND `key`=?', 'core', 'pop' ) );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=support&controller=settings&tab=incomingemail') );
|
||||
}
|
||||
|
||||
@@ -148,28 +159,20 @@ class _incomingemail extends \IPS\Dispatcher\Controller
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
require_once \IPS\ROOT_PATH . '/system/3rd_party/pop3/pop3.class.inc';
|
||||
$pop3 = new \POP3;
|
||||
try
|
||||
{
|
||||
if ( !$pop3->connect( ( $values['pop3_tls'] ? 'ssl://' : '' ) . $values['pop3_server'], $values['pop3_port'] ) )
|
||||
{
|
||||
throw new \DomainException( \IPS\Member::loggedIn()->language()->addToStack('pop3_connect_err') );
|
||||
}
|
||||
|
||||
if ( !$pop3->login( $values['pop3_user'], $values['pop3_password'] ) )
|
||||
{
|
||||
throw new \DomainException( \IPS\Member::loggedIn()->language()->addToStack('pop3_login_err') );
|
||||
}
|
||||
$pop3 = new \IPS\Email\Incoming\PopImap( $values['pop3_server'], $values['pop3_tls'], $values['pop3_port'], $values['pop3_user'], $values['pop3_password'] );
|
||||
|
||||
$form->saveAsSettings();
|
||||
|
||||
\IPS\Session::i()->log( 'acplogs__pop3_settings' );
|
||||
\IPS\DB::i()->update( 'core_tasks', array( 'enabled' => 1 ), array( 'app=? AND `key`=?', 'core', 'pop' ) );
|
||||
\IPS\Db::i()->update( 'core_tasks', array( 'enabled' => 1 ), array( 'app=? AND `key`=?', 'core', 'pop' ) );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=support&controller=settings&tab=incomingemail') );
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
catch ( \IPS\Email\Incoming\PopImapException $e )
|
||||
{
|
||||
$form->error = $e->getMessage();
|
||||
$form->error = \IPS\Member::loggedIn()->language()->addToStack( $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,7 +245,10 @@ class _incomingemail extends \IPS\Dispatcher\Controller
|
||||
* @return void
|
||||
*/
|
||||
protected function incomingEmailDelete()
|
||||
{
|
||||
{
|
||||
/* Make sure the user confirmed the deletion */
|
||||
\IPS\Request::i()->confirmedDelete();
|
||||
|
||||
\IPS\Db::i()->delete( 'core_incoming_emails', array( 'rule_id=?', \IPS\Request::i()->id ) );
|
||||
\IPS\Session::i()->log( 'acplogs__incomingemail_deleted' );
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Outgoing Email Settings
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 18 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Support Reports
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 23 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -45,7 +45,7 @@ class _reports extends \IPS\Dispatcher\Controller
|
||||
/* Tabs */
|
||||
$tabs = array(
|
||||
'overview' => 'overview',
|
||||
'replies' => 'replies',
|
||||
'replies' => 'latest_replies',
|
||||
'feedback_ratings' => 'feedback_ratings',
|
||||
'latest_feedback' => 'latest_feedback',
|
||||
);
|
||||
@@ -55,64 +55,81 @@ class _reports extends \IPS\Dispatcher\Controller
|
||||
/* Staff Productivity */
|
||||
if ( $activeTab === 'overview' )
|
||||
{
|
||||
/* Build table */
|
||||
$staffProductivityTable = new \IPS\Helpers\Table\Db(
|
||||
'nexus_support_replies',
|
||||
\IPS\Http\Url::internal( 'app=nexus&module=support&controller=reports&act=productivity_table' ),
|
||||
array(
|
||||
array( 'reply_type=?', \IPS\nexus\Support\Reply::REPLY_STAFF ),
|
||||
\IPS\Db::i()->in( 'reply_member', array_keys( \IPS\nexus\Support\Request::staff() ) )
|
||||
),
|
||||
'reply_member'
|
||||
/* Filters */
|
||||
$filters = array(
|
||||
'last_24_hours' => \IPS\DateTime::create()->sub( new \DateInterval( 'P1D' ) )->getTimestamp(),
|
||||
'last_7_days' => \IPS\DateTime::create()->sub( new \DateInterval( 'P7D' ) )->getTimestamp(),
|
||||
'last_30_days' => \IPS\DateTime::create()->sub( new \DateInterval( 'P30D' ) )->getTimestamp(),
|
||||
);
|
||||
|
||||
/* Set default values */
|
||||
$data = array();
|
||||
foreach ( \IPS\nexus\Support\Request::staff() as $staffId => $name )
|
||||
{
|
||||
$data[ $staffId ] = array( 'name' => $name, 'reply_count' => 0 );
|
||||
if ( \IPS\Settings::i()->nexus_support_satisfaction )
|
||||
{
|
||||
$data[ $staffId ]['rating_count'] = 0;
|
||||
$data[ $staffId ]['rating_average'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get their replies */
|
||||
$where = array( array( \IPS\Db::i()->in( 'reply_member', array_keys( $data ) ) ) );
|
||||
if ( isset( \IPS\Request::i()->filter ) and array_key_exists( \IPS\Request::i()->filter, $filters ) )
|
||||
{
|
||||
$where[] = array( 'reply_date>?', $filters[ \IPS\Request::i()->filter ] );
|
||||
}
|
||||
foreach ( \IPS\Db::i()->select( 'COUNT(*) AS count, reply_member', 'nexus_support_replies', $where, NULL, NULL, 'reply_member' ) as $row )
|
||||
{
|
||||
$data[ $row['reply_member'] ]['reply_count'] = $row['count'];
|
||||
}
|
||||
|
||||
/* And their ratings */
|
||||
if ( \IPS\Settings::i()->nexus_support_satisfaction )
|
||||
{
|
||||
$where = array( \IPS\Db::i()->in( 'rating_staff', array_keys( $data ) ) );
|
||||
if ( isset( \IPS\Request::i()->filter ) and array_key_exists( \IPS\Request::i()->filter, $filters ) )
|
||||
{
|
||||
$where[] = array( 'rating_date>?', $filters[ \IPS\Request::i()->filter ] );
|
||||
}
|
||||
foreach ( \IPS\Db::i()->select( 'COUNT(*) AS count, AVG(rating_rating) AS rating, rating_staff', 'nexus_support_ratings', $where, NULL, NULL, 'rating_staff' ) as $row )
|
||||
{
|
||||
$data[ $row['rating_staff'] ]['rating_count'] = $row['count'];
|
||||
$data[ $row['rating_staff'] ]['rating_average'] = $row['rating'];
|
||||
}
|
||||
}
|
||||
|
||||
/* Build the table */
|
||||
$staffProductivityTable = new \IPS\Helpers\Table\Custom( $data, \IPS\Http\Url::internal( 'app=nexus&module=support&controller=reports&tab=overview' ) );
|
||||
$staffProductivityTable->langPrefix = 'staff_';
|
||||
$staffProductivityTable->selects = array( 'COUNT(*) AS reply_count' );
|
||||
$staffProductivityTable->include = array( 'name', 'reply_count' );
|
||||
$staffProductivityTable->widths = array( 'name' => 75, 'reply_count' => 25 );
|
||||
$staffProductivityTable->parsers['reply_count'] = function( $val ) { return intval( $val ); };
|
||||
$staffProductivityTable->widths = \IPS\Settings::i()->nexus_support_satisfaction ? array( 'name' => 50, 'reply_count' => 25, 'rating_average' => 25 ) : array( 'name' => 75, 'reply_count' => 25 );
|
||||
if ( \IPS\Settings::i()->nexus_support_satisfaction )
|
||||
{
|
||||
$staffProductivityTable->joins[] = array(
|
||||
'select' => 'rating_count, rating_average',
|
||||
'from' => \IPS\Db::i()->select( 'rating_reply, COUNT(*) AS rating_count, AVG(rating_rating) AS rating_average', 'nexus_support_ratings' ),
|
||||
'where' => 'rating_reply=reply_id'
|
||||
);
|
||||
|
||||
$staffProductivityTable->include[] = 'rating_average';
|
||||
$staffProductivityTable->widths = array( 'name' => 50, 'reply_count' => 25, 'rating_average' => 25 );
|
||||
$staffProductivityTable->parsers['rating_average'] = function( $val, $row ) {
|
||||
return \IPS\Theme::i()->getTemplate('supportreports')->averageRatingCell( $val, $row['rating_count'] );
|
||||
};
|
||||
$staffProductivityTable->include = array( 'name', 'reply_count', 'rating_average' );
|
||||
}
|
||||
$staffProductivityTable->sortBy = $staffProductivityTable->sortBy ?: 'reply_count';
|
||||
|
||||
/* We need to join the members table for the name */
|
||||
$staffProductivityTable->joins[] = array(
|
||||
'select' => 'name',
|
||||
'from' => 'core_members',
|
||||
'where' => 'member_id=reply_member'
|
||||
);
|
||||
$staffProductivityTable->quickSearch = 'name';
|
||||
|
||||
|
||||
/* Specify the filters and search options */
|
||||
$staffProductivityTable->filters = array(
|
||||
'last_24_hours' => array( 'reply_date>?', \IPS\DateTime::create()->sub( new \DateInterval( 'P1D' ) )->getTimestamp() ),
|
||||
'last_7_days' => array( 'reply_date>?', \IPS\DateTime::create()->sub( new \DateInterval( 'P7D' ) )->getTimestamp() ),
|
||||
'last_30_days' => array( 'reply_date>?', \IPS\DateTime::create()->sub( new \DateInterval( 'P30D' ) )->getTimestamp() ),
|
||||
);
|
||||
$staffProductivityTable->filters = $filters;
|
||||
|
||||
/* Buttons for each member */
|
||||
$staffProductivityTable->rowButtons = function( $row )
|
||||
$staffProductivityTable->rowButtons = function( $row, $id )
|
||||
{
|
||||
return array(
|
||||
'report' => array(
|
||||
'icon' => 'search',
|
||||
'title' => 'view_report',
|
||||
'link' => \IPS\Http\Url::internal('app=nexus&module=support&controller=reports&do=staff')->setQueryString( 'id', $row['reply_member'] ),
|
||||
'link' => \IPS\Http\Url::internal('app=nexus&module=support&controller=reports&do=staff')->setQueryString( 'id', $id ),
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
/* Output */
|
||||
$activeTabContents = (string) $staffProductivityTable;
|
||||
}
|
||||
|
||||
@@ -122,6 +139,7 @@ class _reports extends \IPS\Dispatcher\Controller
|
||||
$staffRepliesChart = new \IPS\Helpers\Chart\Dynamic( \IPS\Http\Url::internal( 'app=nexus&module=support&controller=reports&tab=replies' ), 'nexus_support_replies', 'reply_date', '',
|
||||
array(
|
||||
'vAxis' => array( 'title' => \IPS\Member::loggedIn()->language()->addToStack('replies_made') ),
|
||||
'height' => 700
|
||||
),
|
||||
'LineChart', 'daily', array( 'start' => \IPS\DateTime::create()->sub( new \DateInterval( 'P1M' ) ), 'end' => 0 )
|
||||
);
|
||||
@@ -141,8 +159,9 @@ class _reports extends \IPS\Dispatcher\Controller
|
||||
$staffRatingsChart = new \IPS\Helpers\Chart\Dynamic( \IPS\Http\Url::internal( 'app=nexus&module=support&controller=reports&tab=feedback_ratings' ), 'nexus_support_ratings', 'rating_date', '',
|
||||
array(
|
||||
'vAxis' => array( 'title' => \IPS\Member::loggedIn()->language()->addToStack('average_rating'), 'viewWindow' => array( 'min' => 0, 'max' => 5 ) ),
|
||||
'height' => 700
|
||||
),
|
||||
'ColumnChart', 'monthly'
|
||||
'ColumnChart', 'monthly', array( 'start' => \IPS\DateTime::create()->sub( new \DateInterval( 'P1M' ) ), 'end' => \IPS\DateTime::create() )
|
||||
);
|
||||
$staffRatingsChart->plotZeros = FALSE;
|
||||
$staffRatingsChart->groupBy = 'rating_staff';
|
||||
@@ -253,19 +272,44 @@ class _reports extends \IPS\Dispatcher\Controller
|
||||
|
||||
/* Get average replies by hour for this staff member */
|
||||
$thisStaffMember = array();
|
||||
foreach( \IPS\Db::i()->select( "COUNT(*) AS count, reply_date AS unixtime, DATE_FORMAT( FROM_UNIXTIME( reply_date ), '{$group}' ) AS hour", 'nexus_support_replies', array_merge( $where, array( array( 'reply_member=?', $staff->member_id ) ) ), NULL, NULL, 'hour' ) as $row )
|
||||
{
|
||||
$thisStaffMemberCount = array();
|
||||
foreach( \IPS\Db::i()->select( "COUNT(*) AS count, reply_date AS unixtime, DATE_FORMAT( FROM_UNIXTIME( reply_date ), '{$group}' ) AS hour", 'nexus_support_replies', array_merge( $where, array( array( 'reply_member=?', $staff->member_id ) ) ), NULL, NULL, array( 'hour', 'reply_date' ) ) as $row )
|
||||
{
|
||||
$_group = $span === 'day' ? \IPS\DateTime::ts( $row['unixtime'] )->format('G') : \IPS\DateTime::ts( $row['unixtime'] )->format('w');
|
||||
$thisStaffMember[ $_group ] = round( ( $type === 'average' ) ? ( $row['count'] / $daysInTimeframe ) : $row['count'], 1 );
|
||||
|
||||
if ( !isset( $thisStaffMemberCount[ $_group ] ) )
|
||||
{
|
||||
$thisStaffMemberCount[ $_group ] = 0;
|
||||
}
|
||||
|
||||
$thisStaffMemberCount[ $_group ] = $thisStaffMemberCount[ $_group ] + $row['count'];
|
||||
}
|
||||
|
||||
foreach( $thisStaffMemberCount AS $_group => $count )
|
||||
{
|
||||
$thisStaffMember[ $_group ] = round( ( $type === 'average' ) ? ( $count / $daysInTimeframe ) : $count, 1 );
|
||||
}
|
||||
|
||||
/* Get average replies by hour for all staff members */
|
||||
if ( $numberOfStaffMembers > 1 )
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( "COUNT(*) AS count, reply_date AS unixtime, DATE_FORMAT( FROM_UNIXTIME( reply_date ), '{$group}' ) AS hour", 'nexus_support_replies', $where, NULL, NULL, 'hour' ) as $row )
|
||||
$allStaffMembers = array();
|
||||
$allStaffMembersCount = array();
|
||||
foreach( \IPS\Db::i()->select( "COUNT(*) AS count, reply_date AS unixtime, DATE_FORMAT( FROM_UNIXTIME( reply_date ), '{$group}' ) AS hour", 'nexus_support_replies', $where, NULL, NULL, array( 'hour', 'reply_date' ) ) as $row )
|
||||
{
|
||||
$_group = $span === 'day' ? \IPS\DateTime::ts( $row['unixtime'] )->format('G') : \IPS\DateTime::ts( $row['unixtime'] )->format('w');
|
||||
$allStaffMembers[ $_group ] = round( ( ( $type === 'average' ) ? ( $row['count'] / $daysInTimeframe ) : $row['count'] ) / $numberOfStaffMembers, 1 );
|
||||
|
||||
if ( !isset( $allStaffMembersCount[ $_group ] ) )
|
||||
{
|
||||
$allStaffMembersCount[ $_group ] = 0;
|
||||
}
|
||||
|
||||
$allStaffMembersCount[ $_group ] = $allStaffMembersCount[ $_group ] + $row['count'];
|
||||
}
|
||||
|
||||
foreach( $allStaffMembersCount AS $_group => $count )
|
||||
{
|
||||
$allStaffMembers[ $_group ] = round( ( ( $type === 'average' ) ? ( $count / $daysInTimeframe ) : $count ) / $numberOfStaffMembers, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Support Request View
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 09 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -123,7 +123,7 @@ class _request extends \IPS\nexus\modules\front\support\view
|
||||
/* Setting Order? */
|
||||
if ( isset( \IPS\Request::i()->order ) )
|
||||
{
|
||||
\IPS\Request::i()->setCookie( 'support_order', \IPS\Request::i()->order, \IPS\DateTime::create()->add( new \DateInterval('P1Y') ) );
|
||||
\IPS\Request::i()->setCookie( 'support_replies_order', \IPS\Request::i()->order, \IPS\DateTime::create()->add( new \DateInterval('P1Y') ) );
|
||||
}
|
||||
|
||||
/* Views */
|
||||
@@ -146,21 +146,24 @@ class _request extends \IPS\nexus\modules\front\support\view
|
||||
'title' => $this->request->status->_title,
|
||||
'menu' => array(),
|
||||
'menuClass' => 'ipsMenu_selectable ipsMenu_narrow',
|
||||
'data' => array( 'controller' => 'nexus.admin.support.metamenu' )
|
||||
'data' => array( 'role' => 'statusMenu', 'controller' => 'nexus.admin.support.metamenu' ),
|
||||
'tooltip' => \IPS\Member::loggedIn()->language()->addToStack('keyboard_shortcut_status')
|
||||
),
|
||||
'severity' => array(
|
||||
'icon' => 'exclamation',
|
||||
'title' => $this->request->severity->_title,
|
||||
'menu' => array(),
|
||||
'menuClass' => 'ipsMenu_selectable',
|
||||
'data' => array( 'controller' => 'nexus.admin.support.metamenu' )
|
||||
'data' => array( 'role' => 'severityMenu', 'controller' => 'nexus.admin.support.metamenu' ),
|
||||
'tooltip' => \IPS\Member::loggedIn()->language()->addToStack('keyboard_shortcut_severity')
|
||||
),
|
||||
'department' => array(
|
||||
'icon' => 'folder',
|
||||
'title' => $this->request->department->_title,
|
||||
'menu' => array(),
|
||||
'menuClass' => 'ipsMenu_selectable ipsMenu_narrow',
|
||||
'data' => array( 'controller' => 'nexus.admin.support.metamenu' )
|
||||
'data' => array( 'role' => 'departmentMenu', 'controller' => 'nexus.admin.support.metamenu' ),
|
||||
'tooltip' => \IPS\Member::loggedIn()->language()->addToStack('keyboard_shortcut_department')
|
||||
),
|
||||
'staff' => array(
|
||||
'icon' => 'user',
|
||||
@@ -168,9 +171,17 @@ class _request extends \IPS\nexus\modules\front\support\view
|
||||
'menu' => array(),
|
||||
'menuClass' => 'ipsMenu_selectable',
|
||||
'data' => array( 'controller' => 'nexus.admin.support.metamenu', 'role' => 'staffMenu' ),
|
||||
'tooltip' => \IPS\Member::loggedIn()->language()->addToStack('keyboard_shortcut_staff')
|
||||
),
|
||||
'purchase' => array(
|
||||
'icon' => 'cube',
|
||||
'title' => 'associate_purchase',
|
||||
'link' => $this->request->acpUrl()->setQueryString( 'do', 'associate' ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('associate'), 'ipsDialog-size' => 'narrow', 'role' => 'associatePurchaseMenu' ),
|
||||
'tooltip' => \IPS\Member::loggedIn()->language()->addToStack('keyboard_shortcut_purchase')
|
||||
),
|
||||
'track' => array(
|
||||
'icon' => 'star',
|
||||
'icon' => 'bookmark',
|
||||
'title' => $trackLang,
|
||||
'menu' => array(
|
||||
array(
|
||||
@@ -190,7 +201,8 @@ class _request extends \IPS\nexus\modules\front\support\view
|
||||
)
|
||||
),
|
||||
'menuClass' => 'ipsMenu_selectable',
|
||||
'data' => array( 'controller' => 'nexus.admin.support.metamenu' )
|
||||
'data' => array( 'role' => 'trackMenu', 'controller' => 'nexus.admin.support.metamenu' ),
|
||||
'tooltip' => \IPS\Member::loggedIn()->language()->addToStack('keyboard_shortcut_tracking')
|
||||
)
|
||||
);
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'support', 'requests_delete' ) )
|
||||
@@ -289,8 +301,10 @@ class _request extends \IPS\nexus\modules\front\support\view
|
||||
);
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'request_x', FALSE, array( 'sprintf' => "#{$this->request->id}" ) );
|
||||
\IPS\Output::i()->title = "#{$this->request->id} " . $this->request->mapped('title');
|
||||
\IPS\Output::i()->showTitle = FALSE;
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'admin_support.js', 'nexus', 'admin' ) );
|
||||
\IPS\Output::i()->globalControllers[] = 'nexus.admin.support.request';
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'support.css', 'nexus', 'admin' ) );
|
||||
if ( \IPS\Theme::i()->settings['responsive'] )
|
||||
{
|
||||
@@ -298,6 +312,175 @@ class _request extends \IPS\nexus\modules\front\support\view
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hovercard
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function hovercard()
|
||||
{
|
||||
/* Load request */
|
||||
try
|
||||
{
|
||||
$request = \IPS\nexus\Support\Request::loadAndCheckPerms( \IPS\Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X208/K', 404, '' );
|
||||
}
|
||||
|
||||
/* Start with the first message */
|
||||
$overview = array( 'firstMessage' => array( 'support_first_message', $request->comments( 1, 0, 'date', 'asc', NULL, FALSE ) ) );
|
||||
|
||||
/* Add the last customer reply */
|
||||
if ( $request->last_reply != $request->started )
|
||||
{
|
||||
if ( $latestPost = $request->comments( 1, 0, 'date', 'desc', NULL, FALSE, NULL, array( '( reply_type=? OR reply_type=? OR reply_type=? )', \IPS\nexus\Support\Reply::REPLY_MEMBER, \IPS\nexus\Support\Reply::REPLY_ALTCONTACT, \IPS\nexus\Support\Reply::REPLY_EMAIL ) ) )
|
||||
{
|
||||
$overview['lastCustomerReply'] = array( 'support_last_customer_reply', $latestPost );
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the last staff reply */
|
||||
if ( $request->last_staff_reply )
|
||||
{
|
||||
if ( $latestStaffReply = $request->comments( 1, 0, 'date', 'desc', NULL, FALSE, NULL, array( 'reply_type=?', \IPS\nexus\Support\Reply::REPLY_STAFF ) ) )
|
||||
{
|
||||
$overview['lastStaffReply'] = array( 'support_last_staff_reply', $latestStaffReply );
|
||||
}
|
||||
}
|
||||
|
||||
/* And the latest note */
|
||||
if ( $latestNote = $request->comments( 1, 0, 'date', 'desc', NULL, NULL, NULL, array( 'reply_type=?', \IPS\nexus\Support\Reply::REPLY_HIDDEN ) ) )
|
||||
{
|
||||
$overview['lastNote'] = array( 'support_last_note', $latestNote );
|
||||
}
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'support' )->requestHover( $request, $overview ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Go to first unread
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getNewComment()
|
||||
{
|
||||
/* Load request */
|
||||
try
|
||||
{
|
||||
$request = \IPS\nexus\Support\Request::loadAndCheckPerms( \IPS\Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X208/L', 404, '' );
|
||||
}
|
||||
|
||||
/* What order are we viewing? */
|
||||
$order = isset( \IPS\Request::i()->cookie['support_replies_order'] ) ? mb_strtolower( \IPS\Request::i()->cookie['support_replies_order'] ) : 'desc';
|
||||
|
||||
/* Have we read it before? */
|
||||
$timeLastRead = $request->timeLastRead();
|
||||
if ( $timeLastRead instanceof \IPS\DateTime )
|
||||
{
|
||||
if( $unreadComment = $request->comments( 1, NULL, 'date', 'asc', NULL, NULL, $timeLastRead ) )
|
||||
{
|
||||
$where = array( array( 'reply_request=?', $request->id ) );
|
||||
|
||||
if ( $order === 'desc' )
|
||||
{
|
||||
$where[] = array( 'reply_id>?', $unreadComment->id );
|
||||
}
|
||||
else
|
||||
{
|
||||
$where[] = array( 'reply_id<?', $unreadComment->id );
|
||||
}
|
||||
|
||||
$commentPosition = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_replies', $where )->first();
|
||||
|
||||
$url = $request->acpUrl();
|
||||
$page = ceil( $commentPosition / \IPS\nexus\Support\Request::getCommentsPerPage() );
|
||||
if ( $page != 1 )
|
||||
{
|
||||
$url = $url->setQueryString( 'page', $page );
|
||||
}
|
||||
$url = $url->setFragment( "reply-{$unreadComment->id}" );
|
||||
|
||||
\IPS\Output::i()->redirect( $url );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->redirect( $request->acpUrl() );
|
||||
}
|
||||
}
|
||||
/* Nope? Just go to the first message */
|
||||
else
|
||||
{
|
||||
$url = $request->acpUrl();
|
||||
|
||||
if ( $order === 'desc' )
|
||||
{
|
||||
$lastPage = $request->commentPageCount();
|
||||
if ( $lastPage != 1 )
|
||||
{
|
||||
$url = $url->setQueryString( 'page', $lastPage );
|
||||
}
|
||||
}
|
||||
|
||||
$firstMessage = $request->comments( 1, 0, 'date', 'asc', NULL, FALSE );
|
||||
$url = $url->setFragment( "reply-{$firstMessage->id}" );
|
||||
|
||||
\IPS\Output::i()->redirect( $url );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a Comment
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function findComment()
|
||||
{
|
||||
/* Load request and comment */
|
||||
try
|
||||
{
|
||||
$request = \IPS\nexus\Support\Request::loadAndCheckPerms( \IPS\Request::i()->id );
|
||||
$comment = \IPS\nexus\Support\Reply::load( \IPS\Request::i()->comment );
|
||||
if ( $comment->request != $request->id )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X208/M', 404, '' );
|
||||
}
|
||||
|
||||
/* Find its position */
|
||||
$order = isset( \IPS\Request::i()->cookie['support_replies_order'] ) ? mb_strtolower( \IPS\Request::i()->cookie['support_replies_order'] ) : 'desc';
|
||||
$where = array( array( 'reply_request=?', $request->id ) );
|
||||
if ( $order === 'desc' )
|
||||
{
|
||||
$where[] = array( 'reply_id>?', $comment->id );
|
||||
}
|
||||
else
|
||||
{
|
||||
$where[] = array( 'reply_id<?', $comment->id );
|
||||
}
|
||||
$commentPosition = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_replies', $where )->first();
|
||||
|
||||
/* Redirect */
|
||||
$url = $request->acpUrl();
|
||||
$page = ceil( $commentPosition / \IPS\nexus\Support\Request::getCommentsPerPage() );
|
||||
if ( $page != 1 )
|
||||
{
|
||||
$url = $url->setQueryString( 'page', $page );
|
||||
}
|
||||
$url = $url->setFragment( "reply-{$comment->id}" );
|
||||
\IPS\Output::i()->redirect( $url );
|
||||
}
|
||||
|
||||
/**
|
||||
* Pending Response Send/Discard
|
||||
*
|
||||
@@ -318,7 +501,34 @@ class _request extends \IPS\nexus\modules\front\support\view
|
||||
$message->delete();
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( $message->item()->acpUrl()->setQueryString( array( 'filter' => \IPS\Request::i()->filter, 'sort' => \IPS\Request::i()->sort ) ) );
|
||||
if ( isset( \IPS\Request::i()->department ) and \IPS\Request::i()->department != -1 )
|
||||
{
|
||||
$newDepartment = Support\Department::load( \IPS\Request::i()->department );
|
||||
if ( $message->item()->department != $newDepartment )
|
||||
{
|
||||
$message->item()->log( 'department', $message->item()->department, $newDepartment );
|
||||
$message->item()->department = $newDepartment;
|
||||
}
|
||||
}
|
||||
if ( isset( \IPS\Request::i()->status ) and \IPS\Request::i()->status != -1 )
|
||||
{
|
||||
$message->item()->status = Support\Status::load( \IPS\Request::i()->status );
|
||||
}
|
||||
if ( isset( \IPS\Request::i()->staff ) and \IPS\Request::i()->staff != -1 )
|
||||
{
|
||||
$newStaff = \IPS\Request::i()->staff ? \IPS\Member::load( \IPS\Request::i()->staff ) : NULL;
|
||||
if ( $message->item()->staff != $newStaff )
|
||||
{
|
||||
if ( $newStaff )
|
||||
{
|
||||
$message->item()->log( 'staff', $message->item()->staff, $newStaff );
|
||||
}
|
||||
$message->item()->staff = $newStaff;
|
||||
}
|
||||
}
|
||||
$message->item()->save();
|
||||
|
||||
\IPS\Output::i()->redirect( $message->item()->acpUrl() );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
@@ -403,7 +613,7 @@ class _request extends \IPS\nexus\modules\front\support\view
|
||||
try
|
||||
{
|
||||
/* Init */
|
||||
$return = array();
|
||||
$return = array( 'note_status' => \IPS\Request::i()->status );
|
||||
$request = Support\Request::loadAndCheckPerms( \IPS\Request::i()->id );
|
||||
$status = Support\Status::load( \IPS\Request::i()->status );
|
||||
$oldStatus = $request->status;
|
||||
@@ -418,12 +628,16 @@ class _request extends \IPS\nexus\modules\front\support\view
|
||||
}
|
||||
$request->staff = \IPS\Member::loggedIn();
|
||||
$return['staff'] = array( 'id' => \IPS\Member::loggedIn()->member_id, 'name' => \IPS\Member::loggedIn()->name );
|
||||
$return['note_assign_to'] = \IPS\Member::loggedIn()->member_id;
|
||||
$return['staffBadge'] = \IPS\Member::loggedIn()->language()->addToStack( 'assigned_to_x', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack('you') ) ) );
|
||||
}
|
||||
/* Or set the previous status was "Working", release our assigning */
|
||||
elseif ( $oldStatus->assign and $request->staff )
|
||||
{
|
||||
$request->staff = NULL;
|
||||
$return['staff'] = array( 'id' => 0, 'name' => \IPS\Member::loggedIn()->language()->addToStack('unassigned') );
|
||||
$return['note_assign_to'] = 0;
|
||||
$return['staffBadge'] = '';
|
||||
}
|
||||
$request->save();
|
||||
|
||||
@@ -434,6 +648,7 @@ class _request extends \IPS\nexus\modules\front\support\view
|
||||
}
|
||||
|
||||
/* Return */
|
||||
$return['statusBadge'] = \IPS\Theme::i()->getTemplate('support')->status( $request->status );
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->json( $return );
|
||||
@@ -465,7 +680,9 @@ class _request extends \IPS\nexus\modules\front\support\view
|
||||
$request->save();
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->json( array() );
|
||||
$return = array();
|
||||
$return['severityBadge'] = $request->severity->color != '000' ? \IPS\Theme::i()->getTemplate('support')->severity( $request->severity ) : '';
|
||||
\IPS\Output::i()->json( $return );
|
||||
}
|
||||
\IPS\Output::i()->redirect( $request->acpUrl() );
|
||||
}
|
||||
@@ -548,7 +765,25 @@ class _request extends \IPS\nexus\modules\front\support\view
|
||||
$stockActions[ $action->id ] = $action->_title;
|
||||
}
|
||||
|
||||
\IPS\Output::i()->json( array( 'department' => \IPS\Request::i()->department, 'stockActions' => $stockActions, 'requiresPurchase' => (bool) $request->department->require_package ) );
|
||||
$purchaseWarning = NULL;
|
||||
if ( $request->department->packages )
|
||||
{
|
||||
if ( !$request->purchase )
|
||||
{
|
||||
$purchaseWarning = 'purchaseWarningNone';
|
||||
}
|
||||
elseif ( !$request->purchase->active )
|
||||
{
|
||||
$purchaseWarning = 'purchaseWarningInactive';
|
||||
}
|
||||
|
||||
if ( $purchaseWarning )
|
||||
{
|
||||
$purchaseWarning .= ( $request->department->require_package ? 'Required' : 'Optional' );
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->json( array( 'department' => \IPS\Request::i()->department, 'note_department' => \IPS\Request::i()->department, 'stockActions' => $stockActions, 'purchaseWarning' => $purchaseWarning ) );
|
||||
}
|
||||
\IPS\Output::i()->redirect( $request->acpUrl() );
|
||||
}
|
||||
@@ -574,7 +809,11 @@ class _request extends \IPS\nexus\modules\front\support\view
|
||||
$request->save();
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->json( array( 'assign_to' => ( $request->staff_lock ? ( $request->staff ? $request->staff->member_id : 0 ) : 0 ) ) );
|
||||
\IPS\Output::i()->json( array(
|
||||
'assign_to' => ( $request->staff_lock ? ( $request->staff ? $request->staff->member_id : 0 ) : 0 ),
|
||||
'note_assign_to' => $request->staff ? $request->staff->member_id : 0,
|
||||
'staffBadge' => $request->staff ? \IPS\Member::loggedIn()->language()->addToStack( 'assigned_to_x', FALSE, array( 'sprintf' => array( $request->staff->name ) ) ) : ''
|
||||
) );
|
||||
}
|
||||
\IPS\Output::i()->redirect( $request->acpUrl() );
|
||||
}
|
||||
@@ -634,12 +873,52 @@ class _request extends \IPS\nexus\modules\front\support\view
|
||||
$request = Support\Request::loadAndCheckPerms( \IPS\Request::i()->id );
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->class = 'ipsForm_vertical ipsForm_noLabels';
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'associated_purchase', $request->purchase, TRUE, array( 'class' => 'IPS\nexus\Purchase', 'forceOwner' => $request->author(), 'zeroVal' => 'none' ) ) );
|
||||
|
||||
$parentContacts = \IPS\nexus\Customer::load( $request->author()->member_id )->parentContacts();
|
||||
if ( count( $parentContacts ) )
|
||||
{
|
||||
$form->class = 'ipsForm_vertical';
|
||||
$options = array();
|
||||
$toggles = array();
|
||||
foreach ( $parentContacts as $contact )
|
||||
{
|
||||
$options[ $contact->main_id->member_id ] = $contact->main_id->cm_name;
|
||||
$toggles[ $contact->main_id->member_id ] = array( 'associated_purchase_' . $contact->main_id->member_id );
|
||||
}
|
||||
$options[ $request->author()->member_id ] = $request->author()->name;
|
||||
$toggles[ $request->author()->member_id ] = array( 'associated_purchase_' . $request->author()->member_id );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'support_account', $request->author()->member_id, TRUE, array( 'options' => $options, 'toggles' => $toggles, 'parse' => 'none' ) ) );
|
||||
foreach ( $options as $memberId => $memberName )
|
||||
{
|
||||
$field = new \IPS\Helpers\Form\Node( 'associated_purchase_' . $memberId, $memberId == $request->author()->member_id ? $request->purchase : NULL, TRUE, array( 'class' => 'IPS\nexus\Purchase', 'forceOwner' => \IPS\Member::load( $memberId ), 'zeroVal' => 'none' ), NULL, NULL, NULL, 'associated_purchase_' . $memberId );
|
||||
$field->label = \IPS\Member::loggedIn()->language()->addToStack('associated_purchase');
|
||||
$form->add( $field );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$form->class = 'ipsForm_vertical ipsForm_noLabels';
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'associated_purchase', $request->purchase, TRUE, array( 'class' => 'IPS\nexus\Purchase', 'forceOwner' => $request->author(), 'zeroVal' => 'none' ) ) );
|
||||
}
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$request->log( 'purchase', $request->purchase, $values['associated_purchase'] ?: NULL );
|
||||
$request->purchase = $values['associated_purchase'] ?: NULL;
|
||||
if ( isset( $values['support_account'] ) )
|
||||
{
|
||||
if ( $values['support_account'] != $request->member )
|
||||
{
|
||||
\IPS\Db::i()->update( 'nexus_support_replies', array( 'reply_type' => \IPS\nexus\Support\Reply::REPLY_MEMBER ), array( 'reply_request=? AND reply_member=?', $request->id, $values['support_account'] ) );
|
||||
\IPS\Db::i()->update( 'nexus_support_replies', array( 'reply_type' => \IPS\nexus\Support\Reply::REPLY_ALTCONTACT ), array( 'reply_request=? AND reply_member=?', $request->id, $request->member ) );
|
||||
$request->member = $values['support_account'];
|
||||
}
|
||||
$request->log( 'purchase', $request->purchase, $values[ 'associated_purchase_' . $values['support_account'] ] ?: NULL );
|
||||
$request->purchase = $values[ 'associated_purchase_' . $values['support_account'] ] ?: NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
$request->log( 'purchase', $request->purchase, $values['associated_purchase'] ?: NULL );
|
||||
$request->purchase = $values['associated_purchase'] ?: NULL;
|
||||
}
|
||||
$request->save();
|
||||
\IPS\Output::i()->redirect( $request->acpUrl() );
|
||||
}
|
||||
@@ -673,6 +952,114 @@ class _request extends \IPS\nexus\modules\front\support\view
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Multimod
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function multimod()
|
||||
{
|
||||
/* CSRF check */
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
/* Load request */
|
||||
$request = Support\Request::loadAndCheckPerms( \IPS\Request::i()->id );
|
||||
|
||||
/* Are we going to leave any messages in the request? */
|
||||
$count = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_replies', array( array( 'reply_request=? AND reply_hidden=0', $request->id ), \IPS\Db::i()->in( 'reply_id', array_keys( \IPS\Request::i()->multimod ), TRUE ) ) )->first();
|
||||
if ( !$count )
|
||||
{
|
||||
\IPS\Output::i()->error( 'can_not_multimod_all', '1X208/H', 403, '' );
|
||||
}
|
||||
|
||||
/* Splitting? */
|
||||
if ( \IPS\Request::i()->modaction === 'split' )
|
||||
{
|
||||
/* Permission check */
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'requests_split' );
|
||||
|
||||
/* Check we're not trying to split notes only */
|
||||
$count = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_replies', array( array( 'reply_hidden=0', $request->id ), \IPS\Db::i()->in( 'reply_id', array_keys( \IPS\Request::i()->multimod ) ) ) )->first();
|
||||
if ( !$count )
|
||||
{
|
||||
\IPS\Output::i()->error( 'can_not_split_notes_only', '1S208/J', 403, '' );
|
||||
}
|
||||
|
||||
/* Create form */
|
||||
$url = $request->acpUrl()->setQueryString( array( 'do' => 'multimod', 'modaction' => 'split', 'multimod' => \IPS\Request::i()->multimod ) )->csrf();
|
||||
$form = new \IPS\Helpers\Form( 'split_form', 'split', $url, array( 'data-controller' => 'nexus.admin.support.splitForm' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'support_title', sprintf( \IPS\Member::loggedIn()->language()->get( 'split_request_title' ), $request->title, $request->id ), TRUE ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'support_department', $request->department, TRUE, array( 'class' => 'IPS\nexus\Support\Department', 'url' => $url ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'r_status', $request->status, TRUE, array( 'class' => 'IPS\nexus\Support\Status', 'url' => $url ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'support_severity', $request->severity, TRUE, array( 'class' => 'IPS\nexus\Support\Severity', 'url' => $url ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'r_staff', $request->staff ? $request->staff->member_id : 0, FALSE, array( 'options' => array( 0 => 'unassigned' ) + \IPS\nexus\Support\Request::staff() ) ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$newRequest = new \IPS\nexus\Support\Request;
|
||||
$newRequest->title = $values['support_title'];
|
||||
$newRequest->member = $request->member;
|
||||
$newRequest->email = $request->email;
|
||||
$newRequest->department = $values['support_department'];
|
||||
if ( $request->purchase )
|
||||
{
|
||||
$newRequest->purchase = $request->purchase;
|
||||
}
|
||||
$newRequest->status = $values['r_status'];
|
||||
$newRequest->severity = $values['support_severity'];
|
||||
if ( $values['r_staff'] )
|
||||
{
|
||||
$newRequest->staff = \IPS\Member::load( $values['r_staff']);
|
||||
}
|
||||
$newRequest->cfields = $request->cfields;
|
||||
$newRequest->notify = $request->notify;
|
||||
$newRequest->save();
|
||||
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_support_replies', array( array( 'reply_request=?', $request->id ), \IPS\Db::i()->in( 'reply_id', array_keys( \IPS\Request::i()->multimod ) ) ) ), 'IPS\nexus\Support\Reply' ) as $comment )
|
||||
{
|
||||
$comment->move( $newRequest );
|
||||
}
|
||||
|
||||
$request->rebuildFirstAndLastCommentData();
|
||||
$newRequest->rebuildFirstAndLastCommentData();
|
||||
|
||||
|
||||
|
||||
$request->log( 'split_away', $request, $newRequest );
|
||||
$newRequest->log( 'split_new', $request, $newRequest );
|
||||
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->json( array( 'oldUrl' => (string) $request->acpUrl(), 'newUrl' => (string) $newRequest->acpUrl() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->redirect( $newRequest->acpUrl() );
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = $form;
|
||||
}
|
||||
/* Or deleting? */
|
||||
elseif ( \IPS\Request::i()->modaction === 'delete' )
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'requests_reply_delete' );
|
||||
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_support_replies', array( array( 'reply_request=?', $request->id ), \IPS\Db::i()->in( 'reply_id', array_keys( \IPS\Request::i()->multimod ) ) ) ), 'IPS\nexus\Support\Reply' ) as $comment )
|
||||
{
|
||||
$comment->delete();
|
||||
}
|
||||
|
||||
$request->rebuildFirstAndLastCommentData();
|
||||
|
||||
\IPS\Output::i()->redirect( $request->acpUrl() );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->error( 'generic_error', '3X208/I', 403, '' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete
|
||||
*
|
||||
@@ -682,9 +1069,13 @@ class _request extends \IPS\nexus\modules\front\support\view
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'requests_delete' );
|
||||
|
||||
/* Make sure the user confirmed the deletion */
|
||||
\IPS\Request::i()->confirmedDelete();
|
||||
|
||||
try
|
||||
{
|
||||
$request = Support\Request::loadAndCheckPerms( \IPS\Request::i()->id );
|
||||
\IPS\Session::i()->log( 'acplogs__deleted_request', array( $request->id => FALSE ) );
|
||||
$request->delete();
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=nexus&module=support&controller=requests" ) );
|
||||
}
|
||||
@@ -703,9 +1094,13 @@ class _request extends \IPS\nexus\modules\front\support\view
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'requests_reply_delete' );
|
||||
|
||||
/* Make sure the user confirmed the deletion */
|
||||
\IPS\Request::i()->confirmedDelete();
|
||||
|
||||
try
|
||||
{
|
||||
$reply = Support\Reply::loadAndCheckPerms( \IPS\Request::i()->id );
|
||||
\IPS\Session::i()->log( 'acplogs__deleted_reply', array( $reply->id => FALSE ) );
|
||||
$reply->delete();
|
||||
\IPS\Output::i()->redirect( $reply->item()->acpUrl() );
|
||||
}
|
||||
@@ -745,4 +1140,25 @@ class _request extends \IPS\nexus\modules\front\support\view
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'support' )->feedback( $rating );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default action
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function defaultReplyAction()
|
||||
{
|
||||
$defaultAction = NULL;
|
||||
try
|
||||
{
|
||||
$defaultAction = \IPS\Db::i()->select( 'action', 'nexus_support_staff_preferences', array( 'staff_id=?', \IPS\Member::loggedIn()->member_id ) )->first();
|
||||
}
|
||||
catch ( \UnderflowException $e ) {}
|
||||
|
||||
if ( !$defaultAction )
|
||||
{
|
||||
$defaultAction = isset( \IPS\Request::i()->cookie['support_primary_action'] ) ? \IPS\Request::i()->cookie['support_primary_action'] : 'first';
|
||||
}
|
||||
return $defaultAction;
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Support Requests
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 09 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -38,6 +38,8 @@ class _requests extends \IPS\Dispatcher\Controller
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'support_responsive.css', 'nexus', 'admin' ) );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'admin_support.js', 'nexus', 'admin' ) );
|
||||
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'requests_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
@@ -61,93 +63,143 @@ class _requests extends \IPS\Dispatcher\Controller
|
||||
\IPS\Output::i()->error( 'err_no_departments_with_perm2', '1X261/2', 403, '' );
|
||||
}
|
||||
}
|
||||
|
||||
/* URL */
|
||||
$url = \IPS\Http\Url::internal( 'app=nexus&module=support&controller=requests' );
|
||||
$customer = NULL;
|
||||
$where = array();
|
||||
if ( isset( \IPS\Request::i()->member ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$customer = \IPS\nexus\Customer::load( \IPS\Request::i()->member );
|
||||
$url = $url->setQueryString( 'member', $customer->member_id );
|
||||
$where[] = array( 'r_member=?', $customer->member_id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
}
|
||||
|
||||
/* Permissions */
|
||||
$where[] = array( "( dpt_staff='*' OR " . \IPS\Db::i()->findInSet( 'dpt_staff', \IPS\nexus\Support\Department::staffDepartmentPerms() ) . ')' );
|
||||
|
||||
/* Filters */
|
||||
if ( isset( \IPS\Request::i()->assigned ) )
|
||||
{
|
||||
$where[] = array( 'r_staff=?', \IPS\Member::loggedIn()->member_id );
|
||||
}
|
||||
if ( isset( \IPS\Request::i()->tracked ) )
|
||||
{
|
||||
$where[] = array( 'request_id IS NOT NULL' );
|
||||
}
|
||||
if ( isset( \IPS\Request::i()->replied ) )
|
||||
{
|
||||
$where[] = array( 'r_id IN(?)', \IPS\Db::i()->select( 'DISTINCT(reply_request)', 'nexus_support_replies', array( 'reply_member=?', \IPS\Member::loggedIn()->member_id ) ) );
|
||||
}
|
||||
|
||||
/* Departments / Statuses */
|
||||
$myFilters = \IPS\nexus\Support\Request::myFilters();
|
||||
if ( isset( \IPS\Request::i()->departments ) or isset( \IPS\Request::i()->statuses ) )
|
||||
{
|
||||
$newFilters = array( 'departments' => isset( \IPS\Request::i()->departments ) ? explode( ',', \IPS\Request::i()->departments ) : $myFilters['departments'], 'statuses' => isset( \IPS\Request::i()->statuses ) ? explode( ',', \IPS\Request::i()->statuses ) : $myFilters['statuses'] );
|
||||
\IPS\Request::i()->setCookie( 'support_filters', json_encode( $newFilters ), \IPS\DateTime::create()->add( new \DateInterval( 'P1Y' ) ) );
|
||||
$myFilters = \IPS\nexus\Support\Request::myFilters( $newFilters );
|
||||
}
|
||||
$where[] = $myFilters['whereClause'];
|
||||
|
||||
/* Create the table */
|
||||
$table = \IPS\nexus\Support\Request::table( $url, $where );
|
||||
$table->classes[] = 'cNexusSupportTable';
|
||||
$table->tableTemplate = array( \IPS\Theme::i()->getTemplate( 'support', 'nexus', 'admin' ), 'requestTable' );
|
||||
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'support', 'nexus', 'admin' ), 'requestRows' );
|
||||
|
||||
/* Search */
|
||||
$table->quickSearch = 'r_title';
|
||||
$table->advancedSearch = array(
|
||||
'r_title_or_message'=> array( \IPS\Helpers\Table\SEARCH_CUSTOM, array(
|
||||
'getHtml' => function( $field )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'forms', 'core', 'global' )->text( $field->name, 'text', $field->value, $field->required );
|
||||
}
|
||||
), function( $v )
|
||||
{
|
||||
return array( 'r_title LIKE ? OR ' . \IPS\Db::i()->in( 'r_id', \IPS\Db::i()->select( 'reply_request', 'nexus_support_replies', array( "MATCH(reply_post) AGAINST (? IN BOOLEAN MODE)", $v ) ) ), '%' . $v . '%' );
|
||||
} ),
|
||||
'r_severity' => array( \IPS\Helpers\Table\SEARCH_NODE, array( 'class' => 'IPS\nexus\Support\Severity', 'multiple' => TRUE ) ),
|
||||
'r_department' => array( \IPS\Helpers\Table\SEARCH_NODE, array( 'class' => 'IPS\nexus\Support\Department', 'multiple' => TRUE ) ),
|
||||
'r_member' => \IPS\Helpers\Table\SEARCH_MEMBER,
|
||||
'r_email' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
'r_replies' => \IPS\Helpers\Table\SEARCH_NUMERIC,
|
||||
'r_started' => \IPS\Helpers\Table\SEARCH_DATE_RANGE,
|
||||
'r_last_new_reply' => \IPS\Helpers\Table\SEARCH_DATE_RANGE,
|
||||
'r_last_reply' => \IPS\Helpers\Table\SEARCH_DATE_RANGE,
|
||||
'r_last_reply_by' => \IPS\Helpers\Table\SEARCH_MEMBER,
|
||||
'r_last_staff_reply'=> \IPS\Helpers\Table\SEARCH_DATE_RANGE,
|
||||
'r_status' => array( \IPS\Helpers\Table\SEARCH_NODE, array( 'class' => 'IPS\nexus\Support\Status', 'multiple' => TRUE ) ),
|
||||
'r_staff' => array( \IPS\Helpers\Table\SEARCH_SELECT, array( 'options' => \IPS\nexus\Support\Request::staff(), 'multiple' => TRUE, 'noDefault' => TRUE ) ),
|
||||
);
|
||||
|
||||
/* Permissions */
|
||||
$where = array();
|
||||
$where[] = array( "( dpt_staff='*' OR " . \IPS\Db::i()->findInSet( 'dpt_staff', \IPS\nexus\Support\Department::staffDepartmentPerms() ) . ')' );
|
||||
|
||||
/* Get my stream */
|
||||
$stream = NULL;
|
||||
if ( isset( \IPS\Request::i()->cookie['support_stream'] ) or isset( \IPS\Request::i()->stream ) or isset( \IPS\Request::i()->member ) )
|
||||
{
|
||||
if ( isset( \IPS\Request::i()->member ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$customer = \IPS\nexus\Customer::load( \IPS\Request::i()->member );
|
||||
|
||||
$stream = \IPS\nexus\Support\Stream::customer( $customer );
|
||||
$stream->temporary = TRUE;
|
||||
$stream->owner = \IPS\Member::loggedIn()->member_id;
|
||||
$stream->save();
|
||||
|
||||
\IPS\Request::i()->setCookie( 'support_stream', $stream->id, \IPS\DateTime::create()->add( new \DateInterval( 'P1Y') ), FALSE );
|
||||
\IPS\Db::i()->delete( 'nexus_support_streams', array( 'stream_owner=? AND stream_temporary=1 AND stream_id<>?', \IPS\Member::loggedIn()->member_id, $stream->id ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X261/4', 404, '' );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$streamId = isset( \IPS\Request::i()->stream ) ? \IPS\Request::i()->stream : \IPS\Request::i()->cookie['support_stream'];
|
||||
try
|
||||
{
|
||||
$stream = \IPS\nexus\Support\Stream::load( $streamId );
|
||||
|
||||
if ( isset( \IPS\Request::i()->stream ) )
|
||||
{
|
||||
\IPS\Request::i()->setCookie( 'support_stream', $streamId, \IPS\DateTime::create()->add( new \DateInterval( 'P1Y') ), FALSE );
|
||||
\IPS\Db::i()->delete( 'nexus_support_streams', array( 'stream_owner=? AND stream_temporary=1 AND stream_id<>?', \IPS\Member::loggedIn()->member_id, $streamId ) );
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
}
|
||||
}
|
||||
$stream = $stream ?: \IPS\nexus\Support\Stream::load('open');
|
||||
|
||||
/* Are we grouping by department? */
|
||||
if ( isset( \IPS\Request::i()->groupByDepartment ) )
|
||||
{
|
||||
if ( \IPS\Request::i()->groupByDepartment )
|
||||
{
|
||||
\IPS\Request::i()->setCookie( 'support_dpt_group', 1, \IPS\DateTime::create()->add( new \DateInterval( 'P1Y') ), FALSE );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Request::i()->setCookie( 'support_dpt_group', 0, \IPS\DateTime::create()->add( new \DateInterval( 'P1Y') ), FALSE );
|
||||
}
|
||||
}
|
||||
$groupByDepartment = ( isset( \IPS\Request::i()->cookie['support_dpt_group'] ) and \IPS\Request::i()->cookie['support_dpt_group'] );
|
||||
|
||||
/* What's our order? */
|
||||
if ( \IPS\Request::i()->sortBy )
|
||||
{
|
||||
\IPS\Request::i()->setCookie( 'support_sort', \IPS\Request::i()->sortBy, \IPS\DateTime::create()->add( new \DateInterval( 'P1Y') ), FALSE );
|
||||
}
|
||||
if ( \IPS\Request::i()->sortDir )
|
||||
{
|
||||
\IPS\Request::i()->setCookie( 'support_order', \IPS\Request::i()->sortDir, \IPS\DateTime::create()->add( new \DateInterval( 'P1Y') ), FALSE );
|
||||
}
|
||||
if ( isset( \IPS\Request::i()->honorSeverities ) )
|
||||
{
|
||||
\IPS\Request::i()->setCookie( 'support_honor_severities', \IPS\Request::i()->honorSeverities, \IPS\DateTime::create()->add( new \DateInterval( 'P1Y') ), FALSE );
|
||||
}
|
||||
$order = array();
|
||||
if ( $groupByDepartment )
|
||||
{
|
||||
$order[] = 'dpt_position';
|
||||
}
|
||||
$honorSeverities = ( !isset( \IPS\Request::i()->cookie['support_honor_severities'] ) or \IPS\Request::i()->cookie['support_honor_severities'] );
|
||||
if ( $honorSeverities )
|
||||
{
|
||||
$order[] = 'sev_position ASC';
|
||||
}
|
||||
$sortBy = ( isset( \IPS\Request::i()->cookie['support_sort'] ) and in_array( \IPS\Request::i()->cookie['support_sort'], array( 'r_started', 'r_last_new_reply', 'r_last_reply', 'r_last_staff_reply' ) ) ) ? \IPS\Request::i()->cookie['support_sort'] : 'r_last_new_reply';
|
||||
$sortDir = ( isset( \IPS\Request::i()->cookie['support_order'] ) and in_array( \IPS\Request::i()->cookie['support_order'], array( 'ASC', 'DESC' ) ) ) ? \IPS\Request::i()->cookie['support_order'] : 'ASC';
|
||||
$order[] = $sortBy . ' ' . $sortDir;
|
||||
$order = implode( ', ', $order );
|
||||
|
||||
/* Get the results and pagination */
|
||||
$perPage = 25;
|
||||
$count = $stream->count( \IPS\Member::loggedIn() );
|
||||
$numberOfPages = ceil( $count / $perPage );
|
||||
$page = ( isset( \IPS\Request::i()->page ) and \IPS\Request::i()->page <= $numberOfPages ) ? intval( \IPS\Request::i()->page ) : 1;
|
||||
$results = $stream->results( \IPS\Member::loggedIn(), $order, $page, $perPage );
|
||||
$pagination = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination( \IPS\Http\Url::internal('app=nexus&module=support&controller=requests'), $numberOfPages, $page, $perPage );
|
||||
|
||||
/* Are any of those tracked/participated in? */
|
||||
$supportRequestsInView = array_keys( iterator_to_array( $results ) );
|
||||
$tracked = iterator_to_array( \IPS\Db::i()->select( array( 'request_id', 'notify' ), 'nexus_support_tracker', array( array( 'member_id=?', \IPS\Member::loggedIn()->member_id ), array( \IPS\Db::i()->in( 'request_id', $supportRequestsInView ) ) ) )->setKeyField( 'request_id' )->setValueField( 'notify' ) );
|
||||
$participatedIn = iterator_to_array( \IPS\Db::i()->select( 'DISTINCT reply_request', 'nexus_support_replies', array( array( 'reply_member=?', \IPS\Member::loggedIn()->member_id ), array( \IPS\Db::i()->in( 'reply_request', $supportRequestsInView ) ) ) ) );
|
||||
|
||||
/* Filter form */
|
||||
$form = \IPS\nexus\Support\Stream::load('open')->form( $stream, \IPS\Http\Url::internal('app=nexus&module=support&controller=requests') );
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
if ( $values['stream'] == 'custom' )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'nexus_support_streams', array( 'stream_owner=? AND stream_temporary=1', \IPS\Member::loggedIn()->member_id ) );
|
||||
$stream = \IPS\nexus\Support\Stream::createFromForm( $values );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=support&controller=requests&stream=') . $stream->id );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Request::i()->setCookie( 'support_stream', $values['stream'], \IPS\DateTime::create()->add( new \DateInterval( 'P1Y') ), FALSE );
|
||||
}
|
||||
}
|
||||
$form = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'support' ) ), 'filterForm' ) );
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->title = $customer ? \IPS\Member::loggedIn()->language()->addToStack( 'members_support_requests', FALSE, array( 'sprintf' => array( $customer->cm_name ) ) ) : \IPS\Member::loggedIn()->language()->addToStack('menu__nexus_support_requests');
|
||||
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'global', 'core' )->block( 'title', (string) $table );
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->json( array(
|
||||
'form' => $form,
|
||||
'results' => \IPS\Theme::i()->getTemplate( 'support' )->requestsTable( $results, $pagination, $groupByDepartment, $sortBy, $sortDir, $tracked, $participatedIn, $honorSeverities )
|
||||
) );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__nexus_support_requests');
|
||||
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'support' )->requests( $form, $stream, $results, $pagination, $groupByDepartment, $sortBy, $sortDir, $tracked, $participatedIn, $honorSeverities );
|
||||
}
|
||||
|
||||
/* Create Button */
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'support', 'requests_create' ) )
|
||||
{
|
||||
$createUrl = \IPS\Http\Url::internal('app=nexus&module=support&controller=requests&do=create&_new=1');
|
||||
if ( $customer )
|
||||
{
|
||||
$createUrl = $createUrl->setQueryString( 'member', $customer->member_id );
|
||||
}
|
||||
\IPS\Output::i()->sidebar['actions']['create'] = array(
|
||||
'icon' => 'plus',
|
||||
'title' => 'add',
|
||||
@@ -156,40 +208,211 @@ class _requests extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
/* Settings */
|
||||
\IPS\Output::i()->sidebar['actions']['notifications'] = array(
|
||||
'icon' => 'envelope',
|
||||
'title' => 'my_notifications',
|
||||
'link' => \IPS\Http\Url::internal('app=nexus&module=support&controller=requests&do=notifications'),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('my_notifications') )
|
||||
\IPS\Output::i()->sidebar['actions']['my_preferences'] = array(
|
||||
'icon' => 'cog',
|
||||
'title' => 'my_preferences',
|
||||
'link' => \IPS\Http\Url::internal('app=nexus&module=support&controller=requests&do=preferences'),
|
||||
);
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'support', 'support_display_settings' ) )
|
||||
|
||||
/* History Button */
|
||||
\IPS\Output::i()->sidebar['actions']['history'] = array(
|
||||
'icon' => 'clock-o',
|
||||
'title' => 'my_history',
|
||||
'link' => \IPS\Http\Url::internal('app=nexus&module=support&controller=requests&do=history'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter form
|
||||
*
|
||||
* @return \IPS\Helpers\Form
|
||||
*/
|
||||
protected function filters()
|
||||
{
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__nexus_support_requests');
|
||||
\IPS\Output::i()->output = \IPS\nexus\Support\Stream::load('open')->form( NULL, \IPS\Http\Url::internal('app=nexus&module=support&controller=requests') )->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'support' ) ), 'filterForm' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a temporary stream
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function saveStream()
|
||||
{
|
||||
if ( isset( \IPS\Request::i()->stream_title ) )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions']['settings'] = array(
|
||||
'icon' => 'cog',
|
||||
'title' => 'display_settings',
|
||||
'link' => \IPS\Http\Url::internal('app=nexus&module=support&controller=requests&do=settings'),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('display_settings') )
|
||||
);
|
||||
\IPS\Db::i()->update( 'nexus_support_streams', array(
|
||||
'stream_title' => \IPS\Request::i()->stream_title,
|
||||
'stream_temporary' => 0
|
||||
), array( 'stream_owner=? AND stream_temporary=1', \IPS\Member::loggedIn()->member_id ) );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=support&controller=requests' ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'stream_title', '', TRUE ) );
|
||||
\IPS\Output::i()->output = $form;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset my departments
|
||||
* Edit a saved stream
|
||||
*
|
||||
* @return void
|
||||
* @return void
|
||||
*/
|
||||
protected function resetMyDepartments()
|
||||
protected function editStream()
|
||||
{
|
||||
\IPS\Request::i()->setCookie( 'support_filters', '', \IPS\DateTime::create()->sub( new \DateInterval( 'P1D' ) ) );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=support&controller=requests') );
|
||||
try
|
||||
{
|
||||
$stream = \IPS\nexus\Support\Stream::load( \IPS\Request::i()->id );
|
||||
if ( $stream->temporary or $stream->owner != \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X261/3', 404, '' );
|
||||
}
|
||||
|
||||
$form = $stream->form( $stream, \IPS\Http\Url::internal( 'app=nexus&module=support&controller=requests&do=editStream&id=' . $stream->id ) );
|
||||
$form->addTab('title');
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'stream_title', $stream->title, TRUE ) );
|
||||
$form->addButton( 'delete', 'submit', NULL, 'ipsButton ipsButton_light', array( 'name' => 'deleteButton', 'value' => 1 ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
if ( isset( \IPS\Request::i()->deleteButton ) and \IPS\Request::i()->deleteButton )
|
||||
{
|
||||
$stream->delete();
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=nexus&module=support&controller=requests' ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$stream->title = $values['stream_title'];
|
||||
$stream->updateFromForm( $values );
|
||||
$stream->save();
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=nexus&module=support&controller=requests&stream=' . $stream->id ) );
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'support' ) ), 'filterForm' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* My Notifications
|
||||
* Multimod
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function notifications()
|
||||
protected function multimod()
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
$notices = array();
|
||||
|
||||
/* Tracking? */
|
||||
if ( \IPS\Request::i()->modaction === 'track_off' )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'nexus_support_tracker', array( array( 'member_id=?', \IPS\Member::loggedIn()->member_id ), array( \IPS\Db::i()->in( 'request_id', array_keys( \IPS\Request::i()->multimod ) ) ) ) );
|
||||
}
|
||||
elseif ( \IPS\Request::i()->modaction === 'track_on' or \IPS\Request::i()->modaction === 'track_notify' )
|
||||
{
|
||||
foreach ( array_keys( \IPS\Request::i()->multimod ) as $requestId )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'nexus_support_tracker', array(
|
||||
'member_id' => \IPS\Member::loggedIn()->member_id,
|
||||
'request_id' => $requestId,
|
||||
'notify' => \IPS\Request::i()->modaction === 'track_notify'
|
||||
), TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
/* Everything else requires a loop... */
|
||||
else
|
||||
{
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_support_requests', \IPS\Db::i()->in( 'r_id', array_keys( \IPS\Request::i()->multimod ) ) ), 'IPS\nexus\Support\Request' ) as $request )
|
||||
{
|
||||
if ( $request->canView() )
|
||||
{
|
||||
/* Set status */
|
||||
if ( mb_substr( \IPS\Request::i()->modaction, 0, 7 ) === 'status_' )
|
||||
{
|
||||
/* Set it */
|
||||
$status = \IPS\nexus\Support\Status::load( mb_substr( \IPS\Request::i()->modaction, 7 ) );
|
||||
$oldStatus = $request->status;
|
||||
$request->status = $status;
|
||||
|
||||
/* Assign it if we have to */
|
||||
if ( $status->assign )
|
||||
{
|
||||
if ( $request->staff and $request->staff->member_id != \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
$notices[] = \IPS\Member::loggedIn()->language()->addToStack( 'you_have_stolen_request_multimod', FALSE, array( 'sprintf' => array( $request->id, $request->staff->name ) ) );
|
||||
}
|
||||
|
||||
$request->staff = \IPS\Member::loggedIn();
|
||||
}
|
||||
/* Or set the previous status was "Working", release our assigning */
|
||||
elseif ( $oldStatus->assign and $request->staff )
|
||||
{
|
||||
$request->staff = NULL;
|
||||
}
|
||||
|
||||
/* Save and Log */
|
||||
$request->save();
|
||||
if ( $status->log )
|
||||
{
|
||||
$request->log( 'status', $oldStatus, $status );
|
||||
}
|
||||
}
|
||||
|
||||
/* Set severity */
|
||||
elseif ( mb_substr( \IPS\Request::i()->modaction, 0, 9 ) === 'severity_' )
|
||||
{
|
||||
$new = \IPS\nexus\Support\Severity::load( mb_substr( \IPS\Request::i()->modaction, 9 ) );
|
||||
$request->log( 'severity', $request->severity, $new );
|
||||
$request->severity = $new;
|
||||
$request->save();
|
||||
}
|
||||
|
||||
/* Set department */
|
||||
elseif ( mb_substr( \IPS\Request::i()->modaction, 0, 11 ) === 'department_' )
|
||||
{
|
||||
$new = \IPS\nexus\Support\Department::load( mb_substr( \IPS\Request::i()->modaction, 11 ) );
|
||||
$request->log( 'department', $request->department, $new );
|
||||
$request->department = $new;
|
||||
$request->save();
|
||||
}
|
||||
|
||||
/* Assign */
|
||||
elseif ( mb_substr( \IPS\Request::i()->modaction, 0, 6 ) === 'staff_' )
|
||||
{
|
||||
$staff = mb_substr( \IPS\Request::i()->modaction, 6 );
|
||||
$new = $staff ? \IPS\Member::load( $staff ) : NULL;
|
||||
$request->log( 'staff', $request->staff, $new );
|
||||
$request->staff = $new;
|
||||
$request->save();
|
||||
}
|
||||
|
||||
/* Delete? */
|
||||
elseif ( \IPS\Request::i()->modaction === 'delete' and \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'support', 'requests_delete' ) )
|
||||
{
|
||||
$request->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=support&controller=requests' ), implode( ', ', $notices ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* My Preferences
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function preferences()
|
||||
{
|
||||
$types = array( 'support_notify_new' => 'n', 'support_notify_replies' => 'r', 'support_notify_assign' => 'a' );
|
||||
|
||||
@@ -202,15 +425,76 @@ class _requests extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->addMessage( 'support_notify_blurb' );
|
||||
|
||||
$form->addHeader('my_preferences');
|
||||
try
|
||||
{
|
||||
$preferences = \IPS\Db::i()->select( '*', 'nexus_support_staff_preferences', array( 'staff_id=?', \IPS\Member::loggedIn()->member_id ) )->first();
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
$preferences = NULL;
|
||||
}
|
||||
$form->add( new \IPS\Helpers\Form\Editor( 'nexus_default_support_content', $preferences ? $preferences['content'] : NULL, FALSE, array( 'app' => 'nexus', 'key' => 'Support', 'autoSaveKey' => 'default_content', 'tags' => array(
|
||||
'{customer_first_name}' => \IPS\Member::loggedIn()->language()->addToStack('customer_first_name'),
|
||||
'{customer_last_name}' => \IPS\Member::loggedIn()->language()->addToStack('customer_first_name'),
|
||||
'{customer_full_name}' => \IPS\Member::loggedIn()->language()->addToStack('customer_full_name'),
|
||||
'{department_name}' => \IPS\Member::loggedIn()->language()->addToStack('department_name'),
|
||||
'{department_email}' => \IPS\Member::loggedIn()->language()->addToStack('department_email'),
|
||||
) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'nexus_default_support_action', $preferences ? $preferences['action'] : '', FALSE, array( 'options' => array(
|
||||
'' => 'reply_remember_last',
|
||||
'first' => 'reply_and_go_to_first',
|
||||
'stay' => 'reply_and_stay',
|
||||
'next' => 'reply_and_go_to_next',
|
||||
'list' => 'reply_and_go_to_list',
|
||||
) ) ) );
|
||||
|
||||
$_myDepartments = iterator_to_array( \IPS\nexus\Support\Department::departmentsWithPermission() );
|
||||
$myOrder = array();
|
||||
foreach ( \IPS\Db::i()->select( array( 'department_id' ), 'nexus_support_staff_dpt_order', array( 'staff_id=?', \IPS\Member::loggedIn()->member_id ), 'dpt_position ASC' ) as $departmentId )
|
||||
{
|
||||
if ( array_key_exists( $departmentId, $_myDepartments ) )
|
||||
{
|
||||
$myOrder[ $departmentId ] = $_myDepartments[ $departmentId ]->_title;
|
||||
}
|
||||
}
|
||||
foreach( $_myDepartments as $department )
|
||||
{
|
||||
if ( !array_key_exists( $department->id, $myOrder ) )
|
||||
{
|
||||
$myOrder[ $department->id ] = $department->_title;
|
||||
}
|
||||
}
|
||||
$form->add( new \IPS\Helpers\Form\Sort( 'nexus_group_departments_order', $myOrder, FALSE ) );
|
||||
|
||||
$form->addHeader('notify_me_when');
|
||||
$form->addMessage( 'support_notify_blurb' );
|
||||
foreach ( $types as $k => $t )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Select( $k, isset( $existing[ $t ] ) ? ( $existing[ $t ] === '*' ? 0 : explode( ',', $existing[ $t ] ) ) : NULL, FALSE, array( 'options' => $myDepartments, 'multiple' => TRUE, 'unlimited' => 0, 'unlimitedLang' => 'all' ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Select( $k, isset( $existing[ $t ] ) ? ( $existing[ $t ] === '*' ? 0 : explode( ',', $existing[ $t ] ) ) : NULL, FALSE, array( 'options' => $myDepartments, 'multiple' => TRUE, 'unlimited' => 0, 'unlimitedLang' => 'all', 'noDefault' => TRUE ) ) );
|
||||
}
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'nexus_support_staff_preferences', array(
|
||||
'staff_id' => \IPS\Member::loggedIn()->member_id,
|
||||
'content' => $values['nexus_default_support_content'],
|
||||
'action' => $values['nexus_default_support_action'],
|
||||
), TRUE );
|
||||
|
||||
\IPS\Db::i()->delete( 'nexus_support_staff_dpt_order', array( 'staff_id=?', \IPS\Member::loggedIn()->member_id ) );
|
||||
|
||||
$i = 1;
|
||||
foreach ( $values['nexus_group_departments_order'] as $k => $v )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'nexus_support_staff_dpt_order', array(
|
||||
'staff_id' => \IPS\Member::loggedIn()->member_id,
|
||||
'department_id' => $k,
|
||||
'dpt_position' => $i++,
|
||||
) );
|
||||
}
|
||||
|
||||
\IPS\Db::i()->delete( 'nexus_support_notify', array( 'staff_id=?', \IPS\Member::loggedIn()->member_id ) );
|
||||
|
||||
foreach ( $types as $k => $t )
|
||||
@@ -228,72 +512,10 @@ class _requests extends \IPS\Dispatcher\Controller
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal("app=nexus&module=support&controller=requests") );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('my_notifications');
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('my_preferences');
|
||||
\IPS\Output::i()->output = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display Settings
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function settings()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'support_display_settings' );
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\Custom( 'support_old_highlight', array( \IPS\Settings::i()->support_old_stat, \IPS\Settings::i()->support_old_number ), FALSE, array(
|
||||
'getHtml' => function( $obj )
|
||||
{
|
||||
$number = \IPS\Settings::i()->support_old_number;
|
||||
$numberType = $number ? 'minutes' : 'hours';
|
||||
if ( $number % 1440 === 0 )
|
||||
{
|
||||
$number /= 1440; # Fun fact: that's the first time I've used that operator
|
||||
$numberType = 'days';
|
||||
}
|
||||
elseif ( $number % 60 === 0 )
|
||||
{
|
||||
$number /= 60; # Fun fact: that's the second time I've used that operator
|
||||
$numberType = 'hours';
|
||||
}
|
||||
|
||||
return \IPS\Theme::i()->getTemplate('support')->highlightSetting( $obj->name, $obj->value[0], $number, $numberType );
|
||||
}
|
||||
) ) );
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$save = array();
|
||||
if ( isset( $values['support_old_highlight'][3] ) )
|
||||
{
|
||||
$save['support_old_number'] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$save['support_old_stat'] = $values['support_old_highlight'][0];
|
||||
switch ( $values['support_old_highlight'][2] )
|
||||
{
|
||||
case 'minutes':
|
||||
$save['support_old_number'] = $values['support_old_highlight'][1];
|
||||
break;
|
||||
case 'hours':
|
||||
$save['support_old_number'] = $values['support_old_highlight'][1] * 60;
|
||||
break;
|
||||
case 'days':
|
||||
$save['support_old_number'] = $values['support_old_highlight'][1] * 1440;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$form->saveAsSettings( $save );
|
||||
\IPS\Session::i()->log( 'acplogs__support_display_settings' );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=nexus&module=support&controller=requests' ), 'saved' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create
|
||||
*
|
||||
@@ -306,50 +528,53 @@ class _requests extends \IPS\Dispatcher\Controller
|
||||
$steps = array();
|
||||
|
||||
/* Owner */
|
||||
$steps['request_owner'] = function( $data )
|
||||
if ( !isset( \IPS\Request::i()->member ) )
|
||||
{
|
||||
$form = new \IPS\Helpers\Form( 'owner', 'continue' );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'request_owner_type', 'member', TRUE, array(
|
||||
'options' => array( 'member' => 'request_owner_member', 'email' => 'request_owner_email' ),
|
||||
'toggles' => array( 'member' => array( 'request_owner_member' ), 'email' => array( 'request_owner_email' ) )
|
||||
) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Member( 'request_owner_member', isset( \IPS\Request::i()->member ) ? \IPS\Member::load( \IPS\Request::i()->member ) : NULL, FALSE, array(), NULL, NULL, NULL, 'request_owner_member' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Email( 'request_owner_email', NULL, FALSE, array(), NULL, NULL, NULL, 'request_owner_email' ) );
|
||||
if ( $values = $form->values() )
|
||||
$steps['request_owner'] = function( $data )
|
||||
{
|
||||
if ( $values['request_owner_type'] === 'member' )
|
||||
$form = new \IPS\Helpers\Form( 'owner', 'continue' );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'request_owner_type', 'member', TRUE, array(
|
||||
'options' => array( 'member' => 'request_owner_member', 'email' => 'request_owner_email' ),
|
||||
'toggles' => array( 'member' => array( 'request_owner_member' ), 'email' => array( 'request_owner_email' ) )
|
||||
) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Member( 'request_owner_member', isset( \IPS\Request::i()->member ) ? \IPS\Member::load( \IPS\Request::i()->member ) : NULL, FALSE, array(), NULL, NULL, NULL, 'request_owner_member' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Email( 'request_owner_email', NULL, FALSE, array(), NULL, NULL, NULL, 'request_owner_email' ) );
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
if ( !$values['request_owner_member'] )
|
||||
if ( $values['request_owner_type'] === 'member' )
|
||||
{
|
||||
$form->error = \IPS\Member::loggedIn()->language()->addToStack('request_owner_req');
|
||||
return (string) $form;
|
||||
}
|
||||
$data['member'] = $values['request_owner_member']->member_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !$values['request_owner_email'] )
|
||||
{
|
||||
$form->error = \IPS\Member::loggedIn()->language()->addToStack('request_owner_req');
|
||||
return (string) $form;
|
||||
}
|
||||
|
||||
$member = \IPS\Member::load( $values['request_owner_email'], 'email' );
|
||||
if ( $member->member_id )
|
||||
{
|
||||
$data['member'] = $member->member_id;
|
||||
if ( !$values['request_owner_member'] )
|
||||
{
|
||||
$form->error = \IPS\Member::loggedIn()->language()->addToStack('request_owner_req');
|
||||
return (string) $form;
|
||||
}
|
||||
$data['member'] = $values['request_owner_member']->member_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['email'] = $values['request_owner_email'];
|
||||
if ( !$values['request_owner_email'] )
|
||||
{
|
||||
$form->error = \IPS\Member::loggedIn()->language()->addToStack('request_owner_req');
|
||||
return (string) $form;
|
||||
}
|
||||
|
||||
$member = \IPS\Member::load( $values['request_owner_email'], 'email' );
|
||||
if ( $member->member_id )
|
||||
{
|
||||
$data['member'] = $member->member_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['email'] = $values['request_owner_email'];
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
return (string) $form;
|
||||
};
|
||||
return (string) $form;
|
||||
};
|
||||
}
|
||||
|
||||
/* Stock Actions */
|
||||
$stockActions = \IPS\nexus\Support\StockAction::roots();
|
||||
@@ -380,6 +605,11 @@ class _requests extends \IPS\Dispatcher\Controller
|
||||
/* Request Details */
|
||||
$steps['request_details'] = function( $data ) use ( $stockActions )
|
||||
{
|
||||
if ( !isset( $data['member'] ) AND isset( \IPS\Request::i()->member ) )
|
||||
{
|
||||
$data['member'] = \IPS\Request::i()->member;
|
||||
}
|
||||
|
||||
$stockAction = NULL;
|
||||
if ( isset( $data['stock_action'] ) and isset( $stockActions[ $data['stock_action'] ] ) )
|
||||
{
|
||||
@@ -395,7 +625,7 @@ class _requests extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'r_status', $stockAction ? $stockAction->status : \IPS\nexus\Support\Status::load( TRUE, 'status_default_staff' ), TRUE, array( 'class' => 'IPS\nexus\Support\Status' ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'support_severity', \IPS\nexus\Support\Severity::load( TRUE, 'sev_default' ), TRUE, array( 'class' => 'IPS\nexus\Support\Severity' ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'r_staff', 0, FALSE, array( 'options' => array_merge( array( 0 => '' ), \IPS\nexus\Support\Request::staff() ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'r_staff', 0, FALSE, array( 'options' => array( 0 => 'unassigned' ) + \IPS\nexus\Support\Request::staff() ) ) );
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$data['title'] = $values['support_title'];
|
||||
@@ -449,11 +679,35 @@ class _requests extends \IPS\Dispatcher\Controller
|
||||
$stockAction = $stockActions[ $data['stock_action'] ];
|
||||
}
|
||||
|
||||
$department = \IPS\nexus\Support\Department::load( $data['department'] );
|
||||
try
|
||||
{
|
||||
$owner = isset( $data['member'] ) ? \IPS\nexus\Customer::load( $data['member'] ) : NULL;
|
||||
|
||||
$defaultContent = \IPS\Db::i()->select( 'content', 'nexus_support_staff_preferences', array( 'staff_id=?', \IPS\Member::loggedIn()->member_id ) )->first();
|
||||
$defaultContent = str_replace(
|
||||
array( '{customer_first_name}', '{customer_last_name}', '{customer_full_name}', '{department_name}', '{department_email}' ),
|
||||
array(
|
||||
$owner ? $owner->cm_first_name : '',
|
||||
$owner ? $owner->cm_last_name : '',
|
||||
$owner ? $owner->cm_name : $data['email'],
|
||||
$department->_title,
|
||||
$department->email
|
||||
),
|
||||
$defaultContent
|
||||
);
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
$defaultContent = NULL;
|
||||
}
|
||||
|
||||
$form = new \IPS\Helpers\Form( 'your_message' );
|
||||
$form->add( new \IPS\Helpers\Form\Email( 'to', isset( $data['member'] ) ? \IPS\Member::load( $data['member'] )->email : $data['email'] ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'cc', array(), FALSE, array( 'autocomplete' => array( 'unique' => TRUE, 'forceLower' => TRUE ) ), array( 'IPS\nexus\Support\Request', '_validateEmail' ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'bcc', array(), FALSE, array( 'autocomplete' => array( 'unique' => TRUE, 'forceLower' => TRUE ) ), array( 'IPS\nexus\Support\Request', '_validateEmail' ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Editor( 'message', $stockAction ? $stockAction->message : NULL, TRUE, array( 'app' => 'nexus', 'key' => 'Support', 'autoSaveKey' => md5( "new-req-message" ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'support_email_customer', TRUE, TRUE, array( 'togglesOn' => array( 'support_create_to', 'support_create_cc', 'support_create_bcc' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Email( 'to', isset( $data['member'] ) ? \IPS\Member::load( $data['member'] )->email : $data['email'], NULL, array(), NULL, NULL, NULL, 'support_create_to' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'cc', array(), FALSE, array( 'autocomplete' => array( 'unique' => TRUE, 'forceLower' => TRUE ) ), array( 'IPS\nexus\Support\Request', '_validateEmail' ), NULL, NULL, 'support_create_cc' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'bcc', array(), FALSE, array( 'autocomplete' => array( 'unique' => TRUE, 'forceLower' => TRUE ) ), array( 'IPS\nexus\Support\Request', '_validateEmail' ), NULL, NULL, 'support_create_bcc' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Editor( 'message', $stockAction ? $stockAction->message : $defaultContent, TRUE, array( 'app' => 'nexus', 'key' => 'Support', 'autoSaveKey' => "new-req-message", 'defaultIfNoAutoSave' => TRUE ) ) );
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$request = new \IPS\nexus\Support\Request;
|
||||
@@ -467,7 +721,7 @@ class _requests extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$request->email = $data['email'];
|
||||
}
|
||||
$request->department = \IPS\nexus\Support\Department::load( $data['department'] );
|
||||
$request->department = $department;
|
||||
if ( isset( $data['purchase'] ) and $data['purchase'] )
|
||||
{
|
||||
$request->purchase = \IPS\nexus\Purchase::load( $data['purchase'] );
|
||||
@@ -481,10 +735,17 @@ class _requests extends \IPS\Dispatcher\Controller
|
||||
if ( isset( $data['custom_fields'] ) )
|
||||
{
|
||||
$cfields = array();
|
||||
$customFieldObjects = \IPS\nexus\Support\CustomField::roots();
|
||||
foreach ( $data['custom_fields'] as $k => $v )
|
||||
{
|
||||
$cfields[ mb_substr( $k, 13 ) ] = $v;
|
||||
if ( mb_substr( $k, 0, 13 ) === 'nexus_cfield_' )
|
||||
{
|
||||
$k = mb_substr( $k, 13 );
|
||||
$class = $customFieldObjects[ $k ]->buildHelper();
|
||||
$cfields[ $k ] = $class::stringValue( $v );
|
||||
}
|
||||
}
|
||||
|
||||
$request->cfields = $cfields;
|
||||
}
|
||||
|
||||
@@ -534,9 +795,14 @@ class _requests extends \IPS\Dispatcher\Controller
|
||||
$reply->ip_address = \IPS\Request::i()->ipAddress();
|
||||
$reply->bcc = implode( ',', $values['bcc'] );
|
||||
$reply->save();
|
||||
|
||||
|
||||
\IPS\File::claimAttachments( 'new-req-message', $request->id, $reply->id );
|
||||
|
||||
$request->processAfterCreate( $reply, $data );
|
||||
$reply->sendCustomerNotifications( $values['to'], $values['cc'], $values['bcc'] );
|
||||
if ( $values['support_email_customer'] )
|
||||
{
|
||||
$reply->sendCustomerNotifications( $values['to'], $values['cc'], $values['bcc'] );
|
||||
}
|
||||
$reply->sendNotifications();
|
||||
|
||||
$url = NULL;
|
||||
@@ -581,8 +847,169 @@ class _requests extends \IPS\Dispatcher\Controller
|
||||
return $form;
|
||||
};
|
||||
|
||||
/* Set member */
|
||||
$url = \IPS\Http\Url::internal('app=nexus&module=support&controller=requests&do=create');
|
||||
$initialData = NULL;
|
||||
if ( isset( \IPS\Request::i()->member ) )
|
||||
{
|
||||
$initialData = array( 'member' => \IPS\Request::i()->member );
|
||||
$url = $url->setQueryString( 'member', \IPS\Request::i()->member );
|
||||
}
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('create_support_request');
|
||||
\IPS\Output::i()->output = new \IPS\Helpers\Wizard( $steps, \IPS\Http\Url::internal('app=nexus&module=support&controller=requests&do=create') );
|
||||
\IPS\Output::i()->output = new \IPS\Helpers\Wizard( $steps, $url, TRUE, $initialData );
|
||||
}
|
||||
|
||||
/**
|
||||
* View History
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function history()
|
||||
{
|
||||
/* Jump to the right date */
|
||||
if ( isset( \IPS\Request::i()->date_jump ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$timezone = \IPS\Member::loggedIn()->timezone ? new \DateTimeZone( \IPS\Member::loggedIn()->timezone ) : NULL;
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
$timezone = NULL;
|
||||
}
|
||||
|
||||
$date = new \IPS\DateTime( \IPS\Helpers\Form\Date::_convertDateFormat( \IPS\Request::i()->date_jump ), $timezone );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=nexus&module=support&controller=requests&do=history&date=' . $date->getTimestamp() ) );
|
||||
}
|
||||
|
||||
/* Get our dates */
|
||||
$date = isset( \IPS\Request::i()->date ) ? \IPS\DateTime::ts( \IPS\Request::i()->date ) : \IPS\DateTime::ts( time() )->setTime( 0, 0, 0 );
|
||||
$tomorrow = clone $date;
|
||||
$tomorrow = $tomorrow->add( new \DateInterval('P1D') );
|
||||
$yesterday = clone $date;
|
||||
$yesterday = $yesterday->sub( new \DateInterval('P1D') );
|
||||
|
||||
/* What page are we on? */
|
||||
$page = isset( \IPS\Request::i()->page ) ? intval( \IPS\Request::i()->page ) : 1;
|
||||
$perPage = 25;
|
||||
|
||||
/* Get our replies */
|
||||
$replyWhere = array(
|
||||
array( 'reply_member=? AND reply_date>? AND reply_date<?', \IPS\Member::loggedIn()->member_id, $date->getTimestamp(), $tomorrow->getTimestamp() ),
|
||||
array( \IPS\Db::i()->in( 'r_department', array_keys( iterator_to_array( \IPS\nexus\Support\Department::departmentsWithPermission( \IPS\Member::loggedIn() ) ) ) ) )
|
||||
);
|
||||
$replies = new \IPS\Patterns\ActiveRecordIterator(
|
||||
\IPS\Db::i()->select( 'nexus_support_replies.*, nexus_support_ratings.*', 'nexus_support_replies',
|
||||
$replyWhere,
|
||||
'reply_id DESC',
|
||||
array( ( $page - 1 ) * $perPage, $perPage ),
|
||||
NULL,
|
||||
NULL,
|
||||
\IPS\Db::SELECT_SQL_CALC_FOUND_ROWS + \IPS\Db::SELECT_MULTIDIMENSIONAL_JOINS
|
||||
)
|
||||
->join( 'nexus_support_requests', 'r_id=reply_request' )
|
||||
->join( 'nexus_support_departments', 'dpt_id=r_department' )
|
||||
->join( 'nexus_support_ratings', 'reply_id=rating_reply' )
|
||||
, 'IPS\nexus\Support\Reply'
|
||||
);
|
||||
|
||||
/* Work out pagination */
|
||||
$count = $replies->count( TRUE );
|
||||
$numberOfPages = ceil( $count / $perPage );
|
||||
$pagination = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination( \IPS\Http\Url::internal( 'app=nexus&module=support&controller=requests&do=history&date=' . $date->getTimestamp() ), $numberOfPages, $page, $perPage );
|
||||
|
||||
/* Any tracked? */
|
||||
$supportRequestsInView = array();
|
||||
$first = NULL;
|
||||
$last = NULL;
|
||||
foreach ( $replies as $reply )
|
||||
{
|
||||
if ( $first === NULL )
|
||||
{
|
||||
$first = $reply;
|
||||
}
|
||||
$supportRequestsInView[] = $reply->request;
|
||||
$last = $reply;
|
||||
}
|
||||
$tracked = iterator_to_array( \IPS\Db::i()->select( array( 'request_id', 'notify' ), 'nexus_support_tracker', array( array( 'member_id=?', \IPS\Member::loggedIn()->member_id ), array( \IPS\Db::i()->in( 'request_id', $supportRequestsInView ) ) ) )->setKeyField( 'request_id' )->setValueField( 'notify' ) );
|
||||
|
||||
/* Add in actions */
|
||||
if ( $last )
|
||||
{
|
||||
$logWhere = array( array( 'rlog_member=? AND rlog_date>=?', \IPS\Member::loggedIn()->member_id, $last->date ) );
|
||||
try
|
||||
{
|
||||
$firstOnNextPage = \IPS\Db::i()->select( 'reply_date', 'nexus_support_replies', array_merge( $replyWhere, array( array( 'reply_date>?', $first->date ) ) ), 'reply_date ASC', 1 )->join( 'nexus_support_requests', 'r_id=reply_request' )->join( 'nexus_support_departments', 'dpt_id=r_department' )->first();
|
||||
$logWhere[] = array( 'rlog_date<?', $firstOnNextPage );
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
$logWhere[] = array( 'rlog_date<?', $tomorrow->getTimestamp() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$logWhere = array( array( 'rlog_member=? AND rlog_date>? AND rlog_date<?', \IPS\Member::loggedIn()->member_id, $date->getTimestamp(), $tomorrow->getTimestamp() ) );
|
||||
}
|
||||
$iterator = new \IPS\Patterns\UnionIterator( 'desc' );
|
||||
$iterator->attachIterator( $replies, 'date' );
|
||||
$iterator->attachIterator( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_support_request_log', $logWhere, 'rlog_date DESC' ), 'IPS\nexus\Support\Log' ), 'date' );
|
||||
|
||||
/* Make a 30 day chart */
|
||||
$data = array();
|
||||
$workingDate = \IPS\DateTime::ts( time() - ( 86400 * 29 ) )->setTime( 0, 0, 0 );
|
||||
$thirtyDaysAgo = $workingDate->getTimestamp();
|
||||
for ( $i = 0; $i < 30; $i++ )
|
||||
{
|
||||
$data[ $workingDate->format( 'Y-n-j' ) ] = 0;
|
||||
$workingDate->add( new \DateInterval('P1D') );
|
||||
}
|
||||
$chart = new \IPS\Helpers\Chart;
|
||||
$chart->addHeader( \IPS\Member::loggedIn()->language()->addToStack('date'), 'date' );
|
||||
$chart->addHeader( \IPS\Member::loggedIn()->language()->addToStack('staff_reply_count'), 'number' );
|
||||
foreach ( \IPS\Db::i()->select( "COUNT(*) AS count, DATE_FORMAT( FROM_UNIXTIME( reply_date ), '%Y-%c-%e' ) AS time", 'nexus_support_replies', array( 'reply_member=? AND reply_type=? AND reply_date>?', \IPS\Member::loggedIn()->member_id, \IPS\nexus\Support\Reply::REPLY_STAFF, $thirtyDaysAgo ), NULL, NULL, 'time' ) as $row )
|
||||
{
|
||||
$data[ $row['time'] ] = $row['count'];
|
||||
}
|
||||
foreach ( $data as $dateString => $count )
|
||||
{
|
||||
$datetime = new \IPS\DateTime;
|
||||
$exploded = explode( '-', $dateString );
|
||||
$datetime->setDate( (float) $exploded[0], $exploded[1], $exploded[2] );
|
||||
$datetime->setTime( 0, 0, 0 );
|
||||
$chart->addRow( array( $datetime, $count ) );
|
||||
}
|
||||
$chart = $chart->render( 'ColumnChart', array(
|
||||
'backgroundColor' => '#f5f5f5',
|
||||
'chartArea' => array( 'width' => '97%', 'height' => '81%' ),
|
||||
'colors' => array( '#394248' ),
|
||||
'fontSize' => 10,
|
||||
'height' => 150,
|
||||
'vAxis' => array( 'gridlines' => array( 'count' => 4 ), 'maxValue' => max( $data ), 'textPosition' => 'none' ),
|
||||
'hAxis' => array( 'gridlines' => array( 'color' => '#f5f5f5' ) ),
|
||||
'legend' => array( 'position' => 'none' )
|
||||
) );
|
||||
|
||||
/* Stats */
|
||||
$sixtyDaysAgo = ( $thirtyDaysAgo - ( 86400 * 30 ) );
|
||||
$resolvedStatuses = iterator_to_array( \IPS\Db::i()->select( 'status_id', 'nexus_support_statuses', 'status_is_locked=1' ) );
|
||||
$stats = array();
|
||||
|
||||
$stats['totalRepliesThis'] = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_replies', array( 'reply_member=? AND reply_type=? AND reply_date>?', \IPS\Member::loggedIn()->member_id, \IPS\nexus\Support\Reply::REPLY_STAFF, $thirtyDaysAgo ) )->first();
|
||||
$stats['totalRepliesPrev'] = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_replies', array( 'reply_member=? AND reply_type=? AND reply_date>? AND reply_date<?', \IPS\Member::loggedIn()->member_id, \IPS\nexus\Support\Reply::REPLY_STAFF, $sixtyDaysAgo, $thirtyDaysAgo ) )->first();
|
||||
$stats['customersHelpedThis'] = \IPS\Db::i()->select( 'COUNT( DISTINCT IF( nexus_support_requests.r_member, nexus_support_requests.r_member, nexus_support_requests.r_email ) )', 'nexus_support_replies', array( 'reply_member=? AND reply_type=? AND reply_date>?', \IPS\Member::loggedIn()->member_id, \IPS\nexus\Support\Reply::REPLY_STAFF, $thirtyDaysAgo ) )->join( 'nexus_support_requests', 'reply_request=r_id' )->first();
|
||||
$stats['customersHelpedPrev'] = \IPS\Db::i()->select( 'COUNT( DISTINCT IF( nexus_support_requests.r_member, nexus_support_requests.r_member, nexus_support_requests.r_email ) )', 'nexus_support_replies', array( 'reply_member=? AND reply_type=? AND reply_date>? AND reply_date<?', \IPS\Member::loggedIn()->member_id, \IPS\nexus\Support\Reply::REPLY_STAFF, $sixtyDaysAgo, $thirtyDaysAgo ) )->join( 'nexus_support_requests', 'reply_request=r_id' )->first();
|
||||
$stats['issuesResolvedThis'] = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_requests', array( 'reply_member=? AND r_last_staff_reply>?', \IPS\Member::loggedIn()->member_id, $thirtyDaysAgo ) )->join( 'nexus_support_replies', 'reply_date=r_last_staff_reply' )->first();
|
||||
$stats['issuesResolvedPrev'] = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_requests', array( 'reply_member=? AND r_last_staff_reply>? AND r_last_staff_reply<?', \IPS\Member::loggedIn()->member_id, $sixtyDaysAgo, $thirtyDaysAgo ) )->join( 'nexus_support_replies', 'reply_date=r_last_staff_reply' )->first();
|
||||
$stats['averageRatingThis'] = round( \IPS\Db::i()->select( 'AVG(rating_rating)', 'nexus_support_ratings', array( 'rating_staff=? AND rating_date>?', \IPS\Member::loggedIn()->member_id, $thirtyDaysAgo ) )->first(), 1 );
|
||||
$stats['averageRatingPrev'] = round( \IPS\Db::i()->select( 'AVG(rating_rating)', 'nexus_support_ratings', array( 'rating_staff=? AND rating_date>? AND rating_date<?', \IPS\Member::loggedIn()->member_id, $sixtyDaysAgo, $thirtyDaysAgo ) )->first(), 1 );
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('my_history');
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('support')->myHistory( $date, $tomorrow, $yesterday, $iterator, $pagination, $tracked, $chart, $stats );
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Support Settings
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 15 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
/**
|
||||
* @brief severities
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 09 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
@@ -91,7 +91,7 @@ class _severities extends \IPS\Node\Controller
|
||||
\IPS\Db::i()->update( 'nexus_support_requests', array( 'r_severity' => $values['set_existing_requests_to']->id ), array( 'r_severity=?', $node->id ) );
|
||||
|
||||
/* Delete it */
|
||||
\IPS\Session::i()->log( 'acplog__node_deleted', array( $this->title => TRUE, $node->_logKey => TRUE ) );
|
||||
\IPS\Session::i()->log( 'acplog__node_deleted', array( $this->title => TRUE, $node->titleForLog() => FALSE ) );
|
||||
$node->delete();
|
||||
|
||||
/* Clear out member's cached "Create Menu" contents */
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Support Statuses
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 09 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
/**
|
||||
* @brief stockactions
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 15 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief New Support Request Volumme
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 25 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
|
||||
Reference in new issue
Block a user