Version 4.3.0
This commit is contained in:
1 parent
96997ddd8e
commit
fe1acf984a
1349 files changed
+116159
-67711
No files matched your search
@@ -108,7 +108,10 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
try
|
||||
{
|
||||
$customFields[ $k ] = \IPS\nexus\Package\CustomField::load( $k )->displayValue( $v, TRUE );
|
||||
if ( $displayValue = trim( \IPS\nexus\Package\CustomField::load( $k )->displayValue( $v, TRUE ) ) )
|
||||
{
|
||||
$customFields[ $k ] = $displayValue;
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
}
|
||||
@@ -218,7 +221,14 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/* Transfer */
|
||||
$previousOwner = $this->purchase->member;
|
||||
$this->purchase->transfer( $values['ps_member'] );
|
||||
try
|
||||
{
|
||||
$this->purchase->transfer( $values['ps_member'] );
|
||||
}
|
||||
catch ( \DomainException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( $e->getMessage(), '2X195/8', 403 );
|
||||
}
|
||||
|
||||
/* Log */
|
||||
$previousOwner->log( 'purchase', array( 'type' => 'transfer_from', 'id' => $this->purchase->id, 'name' => $this->purchase->name, 'to' => $values['ps_member']->member_id ) );
|
||||
|
||||
@@ -119,7 +119,7 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
'view' => array(
|
||||
'icon' => 'search',
|
||||
'title' => 'view',
|
||||
'link' => \IPS\Http\Url::internal("app=nexus&module=customers&controller=view&id={$row['member_id']}"),
|
||||
'link' => \IPS\Http\Url::internal("app=core&module=members&controller=members&do=view&tab=nexus_Main&id={$row['member_id']}"),
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -40,6 +40,10 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
try
|
||||
{
|
||||
$this->member = \IPS\nexus\Customer::load( \IPS\Request::i()->id );
|
||||
if ( !$this->member->member_id )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
@@ -64,653 +68,59 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
* View Customer
|
||||
*
|
||||
* @return void
|
||||
* @deprecated
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
$member = $this->member;
|
||||
|
||||
/* Notes */
|
||||
$notes = NULL;
|
||||
$noteCount = 0;
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customer_notes_view' ) )
|
||||
{
|
||||
$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( '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';
|
||||
|
||||
$notes->parsers = array(
|
||||
'note_member' => function( $val )
|
||||
{
|
||||
return \IPS\Member::load( $val );
|
||||
},
|
||||
'note_text' => function( $val )
|
||||
{
|
||||
return $val;
|
||||
}
|
||||
);
|
||||
|
||||
$notes->rowButtons = function( $row ) use ( $member )
|
||||
{
|
||||
$return = array();
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customer_notes_edit' ) )
|
||||
{
|
||||
if ( !isset( \IPS\Request::i()->support ) or !\IPS\Request::i()->support )
|
||||
{
|
||||
$return['edit'] = array(
|
||||
'link' => $member->acpUrl()->setQueryString( array( 'do' => 'noteForm', 'note_id' => $row['note_id'], 'support' => isset( \IPS\Request::i()->support ) ? \IPS\Request::i()->support : 0 ) ),
|
||||
'title' => 'edit',
|
||||
'icon' => 'pencil',
|
||||
'data' => array( 'ipsDialog' => true, 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('edit_note') )
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$return['edit'] = array(
|
||||
'link' => $member->acpUrl()->setQueryString( array( 'do' => 'noteForm', 'note_id' => $row['note_id'], 'support' => isset( \IPS\Request::i()->support ) ? \IPS\Request::i()->support : 0 ) ),
|
||||
'title' => 'edit',
|
||||
'icon' => 'pencil',
|
||||
);
|
||||
}
|
||||
}
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customer_notes_delete' ) )
|
||||
{
|
||||
$return['delete'] = array(
|
||||
'link' => $member->acpUrl()->setQueryString( array( 'do' => 'deleteNote', 'note_id' => $row['note_id'], 'support' => isset( \IPS\Request::i()->support ) ? \IPS\Request::i()->support : 0 ) ),
|
||||
'title' => 'delete',
|
||||
'icon' => 'times-circle',
|
||||
'data' => array( 'delete' => '' )
|
||||
);
|
||||
}
|
||||
return $return;
|
||||
};
|
||||
|
||||
if ( ( !isset( \IPS\Request::i()->support ) or !\IPS\Request::i()->support ) and \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customer_notes_add' ) )
|
||||
{
|
||||
$notes->rootButtons = array(
|
||||
'add' => array(
|
||||
'link' => $this->member->acpUrl()->setQueryString( array( 'do' => 'noteForm', 'support' => isset( \IPS\Request::i()->support ) ? \IPS\Request::i()->support : 0 ) ),
|
||||
'title' => 'add',
|
||||
'icon' => 'plus',
|
||||
'data' => array( 'ipsDialog' => true, 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('add_note') )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( \IPS\Request::i()->view === 'notes' )
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('customers')->customerPopup( $notes );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
$notes->limit = 2;
|
||||
$notes->tableTemplate = array( \IPS\Theme::i()->getTemplate('customers'), 'notesOverview' );
|
||||
$notes->rowsTemplate = array( \IPS\Theme::i()->getTemplate('customers'), 'notesOverviewRows' );
|
||||
}
|
||||
}
|
||||
|
||||
/* Purchases */
|
||||
$purchaseCount = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_member=? AND ps_show=1', $this->member->member_id ) )->first();
|
||||
$purchaseRootCount = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_member=? AND ps_show=1 AND ps_parent=0', $this->member->member_id ) )->first();
|
||||
$purchases = \IPS\nexus\Purchase::tree( $this->member->acpUrl()->setQueryString( 'tab', 'purchases' ), array( array( 'ps_member=?', $this->member->member_id ) ) );
|
||||
$purchases->rootsPerPage = 15;
|
||||
$purchases->getTotalRoots = function()
|
||||
{
|
||||
return NULL;
|
||||
};
|
||||
if ( \IPS\Request::i()->isAjax() and \IPS\Request::i()->tab === 'purchases' )
|
||||
{
|
||||
\IPS\Output::i()->output = $purchases;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Invoices */
|
||||
$invoiceCount = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_invoices', array( 'i_member=?', $this->member->member_id ) )->first();
|
||||
$invoices = \IPS\nexus\Invoice::table( array( 'i_member=?', $this->member->member_id ), $this->member->acpUrl()->setQueryString( 'tab', 'invoices' ), 'c' );
|
||||
$invoices->limit = 15;
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'invoices_add' ) )
|
||||
{
|
||||
$invoices->rootButtons = array(
|
||||
'add' => array(
|
||||
'link' => \IPS\Http\Url::internal( "app=nexus&module=payments&controller=invoices&do=generate&member={$this->member->member_id}" ),
|
||||
'title' => 'add',
|
||||
'icon' => 'plus',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$invoices->tableTemplate = array( \IPS\Theme::i()->getTemplate('customers'), 'invoicesTable' );
|
||||
$invoices->rowsTemplate = array( \IPS\Theme::i()->getTemplate('customers'), 'invoicesTableRows' );
|
||||
/*if ( \IPS\Request::i()->isAjax() and \IPS\Request::i()->tab === 'invoices' )
|
||||
{
|
||||
\IPS\Output::i()->output = $invoices;
|
||||
return;
|
||||
}*/
|
||||
|
||||
/* Addresses */
|
||||
if ( \IPS\Request::i()->view === 'addresses' )
|
||||
{
|
||||
$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 )
|
||||
{
|
||||
return \IPS\GeoLocation::buildFromJson( $val )->toString( '<br>' );
|
||||
} );
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_edit_details' ) )
|
||||
{
|
||||
$addresses->rootButtons = array(
|
||||
'add' => array(
|
||||
'link' => $this->member->acpUrl()->setQueryString( 'do', 'addressForm' ),
|
||||
'title' => 'add',
|
||||
'icon' => 'plus',
|
||||
'data' => array( 'ipsDialog' => true, 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('add_address') )
|
||||
)
|
||||
);
|
||||
$addresses->rowButtons = function( $row ) use ( $member )
|
||||
{
|
||||
return array(
|
||||
'edit' => array(
|
||||
'link' => $member->acpUrl()->setQueryString( array( 'do' => 'addressForm', 'address_id' => $row['id'] ) ),
|
||||
'title' => 'edit',
|
||||
'icon' => 'pencil',
|
||||
'data' => array( 'ipsDialog' => true, 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('edit_address') )
|
||||
),
|
||||
'delete' => array(
|
||||
'link' => $member->acpUrl()->setQueryString( array( 'do' => 'deleteAddress', 'address_id' => $row['id'] ) ),
|
||||
'title' => 'delete',
|
||||
'icon' => 'times-circle',
|
||||
'data' => array( 'delete' => '' )
|
||||
)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
$addresses->tableTemplate = array( \IPS\Theme::i()->getTemplate('customers'), 'addressTable' );
|
||||
$addresses->rowsTemplate = array( \IPS\Theme::i()->getTemplate('customers'), 'addressTableRows' );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('customers')->customerPopup( $addresses );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
$primaryBillingAddress = NULL;
|
||||
try
|
||||
{
|
||||
$primaryBillingAddress = \IPS\nexus\Customer\Address::constructFromData( \IPS\Db::i()->select( '*', 'nexus_customer_addresses', array( 'member=? AND primary_billing=1', $this->member->member_id ) )->first() )->address;
|
||||
}
|
||||
catch ( \UnderflowException $e ) { }
|
||||
}
|
||||
$addressCount = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_customer_addresses', array( 'member=?', $this->member->member_id ) )->first();
|
||||
|
||||
/* Credit Cards */
|
||||
$cards = '';
|
||||
$cardCount = 0;
|
||||
if ( count( \IPS\nexus\Gateway::cardStorageGateways() ) and \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_edit_cards' ) )
|
||||
{
|
||||
$cardCount = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_customer_cards', array( 'card_member=?', $this->member->member_id ) )->first();
|
||||
$cards = array();
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_customer_cards', array( 'card_member=?', $this->member->member_id ), NULL, \IPS\Request::i()->view === 'cards' ? NULL : 2 ), 'IPS\nexus\Customer\CreditCard' ) as $card )
|
||||
{
|
||||
try
|
||||
{
|
||||
$cardData = $card->card;
|
||||
$cards[ $card->id ] = array(
|
||||
'id' => $card->id,
|
||||
'card_type' => $cardData->type,
|
||||
'card_member' => $card->member->member_id,
|
||||
'card_number' => $cardData->lastFour,
|
||||
'card_expire' => ( !is_null( $cardData->expMonth ) AND !is_null( $cardData->expYear ) ) ? str_pad( $cardData->expMonth , 2, '0', STR_PAD_LEFT ). '/' . $cardData->expYear : NULL
|
||||
);
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
}
|
||||
$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' ),
|
||||
'title' => 'add',
|
||||
'icon' => 'plus',
|
||||
'data' => array( 'ipsDialog' => true, 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('add_card') )
|
||||
)
|
||||
);
|
||||
$cards->rowButtons = function( $row ) use ( $member )
|
||||
{
|
||||
return array(
|
||||
'delete' => array(
|
||||
'link' => $member->acpUrl()->setQueryString( array( 'do' => 'deleteCard', 'card_id' => $row['id'] ) ),
|
||||
'title' => 'delete',
|
||||
'icon' => 'times-circle',
|
||||
'data' => array( 'delete' => '' )
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
if ( \IPS\Request::i()->view === 'cards' )
|
||||
{
|
||||
$cards->tableTemplate = array( \IPS\Theme::i()->getTemplate('customers'), 'cardsTable' );
|
||||
$cards->rowsTemplate = array( \IPS\Theme::i()->getTemplate('customers'), 'cardsTableRows' );
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('customers')->customerPopup( $cards );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
$cards->tableTemplate = array( \IPS\Theme::i()->getTemplate('customers'), 'cardsOverview' );
|
||||
$cards->rowsTemplate = array( \IPS\Theme::i()->getTemplate('customers'), 'cardsOverviewRows' );
|
||||
}
|
||||
}
|
||||
|
||||
/* 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( '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' ) )
|
||||
{
|
||||
$alternativeContacts->parsers = array(
|
||||
'alt_id' => function( $val )
|
||||
{
|
||||
return "<a href='" . \IPS\nexus\Customer::load( $val )->acpUrl() . "'>" . \IPS\nexus\Customer::load( $val )->name . "</a>";
|
||||
},
|
||||
'email' => function ( $val, $row )
|
||||
{
|
||||
return \IPS\nexus\Customer::load( $row['alt_id'] )->email;
|
||||
},
|
||||
'purchases' => function( $val )
|
||||
{
|
||||
return implode( '<br>', array_map( function( $id )
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate('purchases')->link( \IPS\nexus\Purchase::load( $id ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}, explode( ',', $val ) ) );
|
||||
},
|
||||
'billing' => function( $val )
|
||||
{
|
||||
return $val ? "<i class='fa fa-check'></i>" : "<i class='fa fa-times'></i>";
|
||||
},
|
||||
'support' => function( $val )
|
||||
{
|
||||
return $val ? "<i class='fa fa-check'></i>" : "<i class='fa fa-times'></i>";
|
||||
}
|
||||
);
|
||||
|
||||
$alternativeContacts->rootButtons = array(
|
||||
'add' => array(
|
||||
'link' => $this->member->acpUrl()->setQueryString( 'do', 'alternativeContactForm' ),
|
||||
'title' => 'add',
|
||||
'icon' => 'plus',
|
||||
'data' => array( 'ipsDialog' => true, 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('altcontact_add') )
|
||||
)
|
||||
);
|
||||
$alternativeContacts->rowButtons = function( $row ) use ( $member )
|
||||
{
|
||||
return array(
|
||||
'view' => array(
|
||||
'link' => $member->acpUrl(),
|
||||
'title' => 'view',
|
||||
'icon' => 'search'
|
||||
),
|
||||
'edit' => array(
|
||||
'link' => $member->acpUrl()->setQueryString( array( 'do' => 'alternativeContactForm', 'alt_id' => $row['alt_id'] ) ),
|
||||
'title' => 'edit',
|
||||
'icon' => 'pencil',
|
||||
'data' => array( 'ipsDialog' => true )
|
||||
),
|
||||
'delete' => array(
|
||||
'link' => $member->acpUrl()->setQueryString( array( 'do' => 'deleteAlternativeContact', 'alt_id' => $row['alt_id'] ) ),
|
||||
'title' => 'delete',
|
||||
'icon' => 'times-circle',
|
||||
'data' => array( 'delete' => '' )
|
||||
)
|
||||
);
|
||||
};
|
||||
}
|
||||
if ( \IPS\Request::i()->view === 'alternatives' )
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('customers')->customerPopup( $alternativeContacts );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
$alternativeContacts->include[] = 'email';
|
||||
$alternativeContacts->limit = 2;
|
||||
$alternativeContacts->tableTemplate = array( \IPS\Theme::i()->getTemplate('customers'), 'altContactsOverview' );
|
||||
$alternativeContacts->rowsTemplate = array( \IPS\Theme::i()->getTemplate('customers'), 'altContactsOverviewRows' );
|
||||
}
|
||||
|
||||
/* Parent Alternative Contacts */
|
||||
$parents = array();
|
||||
foreach ( \IPS\Db::i()->select( 'main_id', 'nexus_alternate_contacts', array( 'alt_id=?', $this->member->member_id ) ) as $row )
|
||||
{
|
||||
$parents[] = \IPS\nexus\Customer::load( $row );
|
||||
}
|
||||
|
||||
/* Referrals */
|
||||
try
|
||||
{
|
||||
$referredBy = \IPS\nexus\Customer::load( \IPS\Db::i()->select( 'referred_by', 'nexus_referrals', array( 'member_id=?', $this->member->member_id ) )->first() );
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
$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( 'view', 'referrals' ), array( 'referred_by=?', $this->member->member_id ) );
|
||||
$referrals->langPrefix = 'ref_';
|
||||
$referrals->include = array( 'member_id', 'amount' );
|
||||
$referrals->sortBy = $referrals->sortBy ?: 'member_id';
|
||||
$referrals->parsers = array(
|
||||
'member_id' => function( $v )
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\nexus\Customer::load( $v )->link();
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('deleted_member');
|
||||
}
|
||||
},
|
||||
'email' => function( $v, $row )
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\nexus\Customer::load( $row['member_id'] )->email;
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('deleted_member');
|
||||
}
|
||||
},
|
||||
'amount' => function( $v ) use ( $member )
|
||||
{
|
||||
$return = array();
|
||||
if ( $v )
|
||||
{
|
||||
foreach ( json_decode( $v, TRUE ) as $currency => $amount )
|
||||
{
|
||||
$return[] = new \IPS\nexus\Money( $amount, $currency );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$return[] = new \IPS\nexus\Money( 0, $member->defaultCurrency() );
|
||||
}
|
||||
return implode( '<br>', $return );
|
||||
}
|
||||
);
|
||||
|
||||
if ( \IPS\Request::i()->isAjax() and \IPS\Request::i()->view === 'referrals' )
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('customers')->customerPopup( $referrals );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
$referrals->include[] = 'email';
|
||||
$referrals->limit = 2;
|
||||
$referrals->tableTemplate = array( \IPS\Theme::i()->getTemplate('customers'), 'referralsOverview' );
|
||||
$referrals->rowsTemplate = array( \IPS\Theme::i()->getTemplate('customers'), 'referralsOverviewRows' );
|
||||
}
|
||||
|
||||
/* Sparkline */
|
||||
$rows = array();
|
||||
$oneYearAgo = \IPS\DateTime::create()->sub( new \DateInterval('P1Y') );
|
||||
$date = clone $oneYearAgo;
|
||||
$endOfLastMonth = mktime( 23, 59, 59, date('n') - 1, date('t'), date('Y') );
|
||||
while ( $date->getTimestamp() < $endOfLastMonth )
|
||||
{
|
||||
foreach ( \IPS\nexus\Money::currencies() as $currency )
|
||||
{
|
||||
$rows[ $date->format( 'n Y' ) ][ $currency ] = 0;
|
||||
}
|
||||
$date->add( new \DateInterval( 'P1M' ) );
|
||||
}
|
||||
$sparkline = new \IPS\Helpers\Chart;
|
||||
foreach( \IPS\Db::i()->select( 'DATE_FORMAT( FROM_UNIXTIME(t_date), \'%c %Y\' ) AS time, SUM(t_amount)-SUM(t_partial_refund) AS amount, t_currency', 'nexus_transactions', array( array( "t_member=? AND ( t_status=? OR t_status=? ) AND t_date>? AND t_date<?", $this->member->member_id, \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED, $oneYearAgo->getTimestamp(), time() ) ), NULL, NULL, array( 'time', 't_currency' ) ) as $row )
|
||||
{
|
||||
if ( isset( $rows[ $row['time'] ][ $row['t_currency'] ] ) ) // Currency may no longer exist
|
||||
{
|
||||
$rows[ $row['time'] ][ $row['t_currency'] ] += $row['amount'];
|
||||
}
|
||||
}
|
||||
$sparkline->addHeader( \IPS\Member::loggedIn()->language()->addToStack('date'), 'date' );
|
||||
foreach ( \IPS\nexus\Money::currencies() as $currency )
|
||||
{
|
||||
$sparkline->addHeader( $currency, 'number' );
|
||||
}
|
||||
foreach ( $rows as $time => $row )
|
||||
{
|
||||
$datetime = new \IPS\DateTime;
|
||||
$datetime->setTime( 0, 0, 0 );
|
||||
$exploded = explode( ' ', $time );
|
||||
$datetime->setDate( $exploded[1], $exploded[0], 1 );
|
||||
|
||||
foreach( $row as $currency => $value )
|
||||
{
|
||||
$row[ $currency ] = number_format( $value, 2, '.', '' );
|
||||
}
|
||||
|
||||
$sparkline->addRow( array_merge( array( $datetime ), $row ) );
|
||||
}
|
||||
|
||||
$sparkline = $sparkline->render( 'AreaChart', array(
|
||||
'areaOpacity' => 0.4,
|
||||
'backgroundColor' => '#fff',
|
||||
'colors' => array( '#10967e' ),
|
||||
'chartArea' => array(
|
||||
'left' => 0,
|
||||
'top' => 0,
|
||||
'width' => '100%',
|
||||
'height' => '100%',
|
||||
),
|
||||
'hAxis' => array(
|
||||
'baselineColor' => '#F3F3F3',
|
||||
'gridlines' => array(
|
||||
'count' => 0,
|
||||
)
|
||||
),
|
||||
'height' => 60,
|
||||
'legend' => array(
|
||||
'position' => 'none',
|
||||
),
|
||||
'lineWidth' => 1,
|
||||
'vAxis' => array(
|
||||
'baselineColor' => '#F3F3F3',
|
||||
'gridlines' => array(
|
||||
'count' => 0,
|
||||
)
|
||||
),
|
||||
) );
|
||||
|
||||
/* 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 */
|
||||
$extraHistoryTypes = array( 'email_change', 'password_change', 'display_name', 'mfa', 'merged' ); // define history types from other applications to include in commerce user history, i.e. changing MFA
|
||||
$memberUrl = \IPS\Member::load( $this->member->member_id )->acpUrl();
|
||||
$history = new \IPS\Member\History( $memberUrl->setQueryString( array( 'do' => 'history', 'nexus_return' => 1 ) ), array( array( 'log_member=? AND ( log_app=? OR ' . \IPS\Db::i()->in( 'log_type', $extraHistoryTypes ) . ' )', $this->member->member_id, 'nexus' ) ), TRUE, FALSE, TRUE );
|
||||
$history->tableTemplate = array( \IPS\Theme::i()->getTemplate( 'customers', 'nexus' ), 'historyTable' );
|
||||
$history->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'customers', 'nexus' ), 'historyRows' );
|
||||
$history->limit = 16;
|
||||
|
||||
/* Display */
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_void' ) )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions']['void'] = array(
|
||||
'title' => 'void_account',
|
||||
'icon' => 'times',
|
||||
'link' => $member->acpUrl()->setQueryString( 'do', 'void' ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('void_account') )
|
||||
);
|
||||
}
|
||||
|
||||
\IPS\Output::i()->customHeader = \IPS\Theme::i()->getTemplate( 'customers' )->viewHeader( $member );
|
||||
|
||||
\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 );
|
||||
\IPS\Output::i()->redirect( $this->member->acpUrl() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Standing Data
|
||||
* View Addresses
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function standing()
|
||||
protected function addresses()
|
||||
{
|
||||
$standing = array();
|
||||
$time = time();
|
||||
foreach ( \IPS\nexus\Money::currencies() as $currency )
|
||||
$addresses = new \IPS\Helpers\Table\Db( 'nexus_customer_addresses', \IPS\Http\Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->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 )
|
||||
{
|
||||
/* 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'
|
||||
return \IPS\GeoLocation::buildFromJson( $val )->toString( '<br>' );
|
||||
} );
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_edit_details' ) )
|
||||
{
|
||||
$addresses->rootButtons = array(
|
||||
'add' => array(
|
||||
'link' => \IPS\Http\Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( 'do', 'addressForm' ),
|
||||
'title' => 'add',
|
||||
'icon' => 'plus',
|
||||
'data' => array( 'ipsDialog' => true, 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('add_address') )
|
||||
)
|
||||
);
|
||||
|
||||
/* 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
|
||||
$addresses->rowButtons = function( $row )
|
||||
{
|
||||
$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'
|
||||
);
|
||||
return array(
|
||||
'edit' => array(
|
||||
'link' => \IPS\Http\Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( array( 'do' => 'addressForm', 'address_id' => $row['id'] ) ),
|
||||
'title' => 'edit',
|
||||
'icon' => 'pencil',
|
||||
'data' => array( 'ipsDialog' => true, 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('edit_address') )
|
||||
),
|
||||
'delete' => array(
|
||||
'link' => \IPS\Http\Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( array( 'do' => 'deleteAddress', 'address_id' => $row['id'] ) ),
|
||||
'title' => 'delete',
|
||||
'icon' => 'times-circle',
|
||||
'data' => array( 'delete' => '' )
|
||||
)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
$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 ) );
|
||||
|
||||
$addresses->tableTemplate = array( \IPS\Theme::i()->getTemplate('customers'), 'addressTable' );
|
||||
$addresses->rowsTemplate = array( \IPS\Theme::i()->getTemplate('customers'), 'addressTableRows' );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('customers')->customerPopup( $addresses );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -720,7 +130,7 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
protected function purchaseList()
|
||||
{
|
||||
$purchases = \IPS\nexus\Purchase::tree( $this->member->acpUrl()->setQueryString( 'do', 'purchaseList' ), array( array( 'ps_member=?', $this->member->member_id ) ) );
|
||||
$purchases = \IPS\nexus\Purchase::tree( \IPS\Http\Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( 'do', 'purchaseList' ), array( array( 'ps_member=?', $this->member->member_id ) ) );
|
||||
$purchases->rootsPerPage = 25;
|
||||
$purchases->getTotalRoots = function()
|
||||
{
|
||||
@@ -824,7 +234,7 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
\IPS\Output::i()->redirect( $this->member->acpUrl() );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core', 'front' ) ), 'popupTemplate' ) );
|
||||
\IPS\Output::i()->output = (string) $form;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1138,16 +548,21 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
if ( isset( \IPS\Request::i()->process ) )
|
||||
{
|
||||
$values = array(
|
||||
'void_refund_transactions' => \IPS\Request::i()->trans,
|
||||
'void_cancel_purchases' => \IPS\Request::i()->purch,
|
||||
'void_refund_transactions' => \IPS\Request::i()->trans,
|
||||
'void_cancel_billing_agreements' => \IPS\Request::i()->ba,
|
||||
'void_cancel_purchases' => \IPS\Request::i()->purch,
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$form = new \IPS\Helpers\Form( 'void_account', 'void_account' );
|
||||
$form->ajaxOutput = TRUE;
|
||||
$form->addMessage( 'void_account_warning', 'ipsMessage ipsMessage_warning' );
|
||||
$form->addMessage( 'void_account_warning' );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'void_refund_transactions', TRUE ) );
|
||||
if ( \IPS\nexus\Gateway::billingAgreementGateways() )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'void_cancel_billing_agreements', TRUE ) );
|
||||
}
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'void_cancel_purchases', TRUE ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'void_cancel_invoices', TRUE ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'void_resolve_support', \IPS\Settings::i()->nexus_autoresolve_status, FALSE, array( 'class' => 'IPS\nexus\Support\Status', 'zeroVal' => 'do_not_change' ) ) );
|
||||
@@ -1189,7 +604,7 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
\IPS\File::claimAttachments( "nexus-note-{$this->member->member_id}-new", $this->member->id, $noteId, 'note' );
|
||||
}
|
||||
|
||||
if ( !$values['void_refund_transactions'] and !$values['void_cancel_purchases'] )
|
||||
if ( !$values['void_refund_transactions'] and !$values['void_cancel_purchases'] and !$values['void_cancel_billing_agreements'] )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $this->member->acpUrl() );
|
||||
}
|
||||
@@ -1199,17 +614,18 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
if ( $values )
|
||||
{
|
||||
$member = $this->member;
|
||||
|
||||
\IPS\Output::i()->output = new \IPS\Helpers\MultipleRedirect( $this->member->acpUrl()->setQueryString( array(
|
||||
|
||||
\IPS\Output::i()->output = new \IPS\Helpers\MultipleRedirect( \IPS\Http\Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( array(
|
||||
'do' => 'void',
|
||||
'process' => 1,
|
||||
'trans' => $values['void_refund_transactions'],
|
||||
'ba' => $values['void_cancel_billing_agreements'],
|
||||
'purch' => $values['void_cancel_purchases'],
|
||||
) ), function( $data ) use ( $member )
|
||||
{
|
||||
if ( !is_array( $data ) )
|
||||
{
|
||||
$data = array( 'trans' => 0, 'purch' => 0, 'fail' => array() );
|
||||
$data = array( 'trans' => 0, 'ba' => 0, 'purch' => 0, 'fail' => array() );
|
||||
}
|
||||
|
||||
$done = 0;
|
||||
@@ -1253,6 +669,25 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
}
|
||||
|
||||
if ( \IPS\Request::i()->ba )
|
||||
{
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_billing_agreements', array( 'ba_member=?', $member->member_id ), 'ba_id', array( $data['ba'], 10 ) ), 'IPS\nexus\Customer\BillingAgreement' ) as $billingAgreement )
|
||||
{
|
||||
try
|
||||
{
|
||||
$billingAgreement->cancel();
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
|
||||
$data['ba']++;
|
||||
$done++;
|
||||
if ( $done >= 10 )
|
||||
{
|
||||
return array( $data, \IPS\Member::loggedIn()->language()->addToStack('processing') );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( \IPS\Request::i()->purch )
|
||||
{
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_purchases', array( 'ps_member=?', $member->member_id ), 'ps_id', array( $data['purch'], 10 ) ), 'IPS\nexus\Purchase' ) as $purchase )
|
||||
|
||||
@@ -478,7 +478,7 @@ class _servers extends \IPS\Node\Controller
|
||||
|
||||
if( isset( \IPS\Request::i()->server_type ) and in_array( \IPS\Request::i()->server_type, $availableTypes ) )
|
||||
{
|
||||
$this->nodeClass = "IPS\\nexus\\Hosting\\" . ucfirst( \IPS\Request::i()->server_type ) . "\\Server";
|
||||
$this->nodeClass = "IPS\\nexus\\Hosting\\" . mb_ucfirst( \IPS\Request::i()->server_type ) . "\\Server";
|
||||
}
|
||||
|
||||
parent::form();
|
||||
|
||||
@@ -55,24 +55,15 @@ class _checkoutsettings extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$requireBillingOptions['domain'] = 'nexus_require_billing_domain';
|
||||
}
|
||||
|
||||
if ( \IPS\Settings::i()->nexus_subs_enabled and \IPS\Db::i()->select( 'COUNT(*)', 'nexus_member_subscription_packages' )->first() )
|
||||
{
|
||||
$requireBillingOptions['subscriptions'] = 'nexus_require_billing_subscriptions';
|
||||
}
|
||||
$requireBillingOptions['other'] = 'nexus_require_billing_other';
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->addHeader( 'checkout_settings' );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_https', \IPS\Settings::i()->nexus_https, FALSE, array(), function( $val )
|
||||
{
|
||||
if ( $val )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\Http\Url::internal( '', 'front', NULL, array(), TRUE )->request()->get();
|
||||
}
|
||||
catch ( \IPS\Http\Request\Exception $e )
|
||||
{
|
||||
throw new \DomainException('nexus_https_err');
|
||||
}
|
||||
}
|
||||
} ) );
|
||||
$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' ) );
|
||||
|
||||
@@ -80,7 +80,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', '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' ) ) )
|
||||
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', 'CLF', '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' );
|
||||
}
|
||||
@@ -106,9 +106,7 @@ 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 );
|
||||
\IPS\Settings::i()->changeValues( array( 'nexus_currency' => json_encode( $save ) ) );
|
||||
|
||||
$definition = \IPS\Db::i()->getTableDefinition( 'nexus_package_base_prices' );
|
||||
|
||||
|
||||
@@ -33,6 +33,11 @@ class _fraud extends \IPS\Node\Controller
|
||||
*/
|
||||
public $_descriptionHtml = TRUE;
|
||||
|
||||
/**
|
||||
* Show the "add" button in the page root rather than the table root
|
||||
*/
|
||||
protected $_addButtonInRoot = FALSE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
@@ -51,17 +56,7 @@ class _fraud extends \IPS\Node\Controller
|
||||
*/
|
||||
public function manage()
|
||||
{
|
||||
foreach ( \IPS\nexus\Fraud\Rule::roots() as $rule )
|
||||
{
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_fraud_rules', array( 'f_order>?', $rule->order ) ), 'IPS\nexus\Fraud\Rule' ) as $otherRule )
|
||||
{
|
||||
if ( $rule->isSubsetOf( $otherRule ) )
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->message( \IPS\Member::loggedIn()->language()->addToStack('fraud_rule_conflict', FALSE, array( 'sprintf' => array( $rule->name, $otherRule->name ) ) ), 'warning', NULL, FALSE );
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'forms', 'core' )->blurb( 'fraud_rule_blurb', TRUE, TRUE );
|
||||
|
||||
parent::manage();
|
||||
}
|
||||
|
||||
@@ -584,12 +584,18 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
$method = $transaction->method;
|
||||
$refundMethods = array();
|
||||
$refundMethodToggles = array( 'credit' => array( $transaction->id . '_refund_amount' ) );
|
||||
$refundReasons = array();
|
||||
if ( $method and $method::SUPPORTS_REFUNDS )
|
||||
{
|
||||
$refundMethods['gateway'] = $method->_title;
|
||||
$refundMethodToggles['gateway'] = array();
|
||||
if ( $method::SUPPORTS_PARTIAL_REFUNDS )
|
||||
{
|
||||
$refundMethodToggles['gateway'] = array( $transaction->id . '_refund_amount' );
|
||||
$refundMethodToggles['gateway'][] = $transaction->id . '_refund_amount';
|
||||
}
|
||||
if ( $refundReasons = $method::refundReasons() )
|
||||
{
|
||||
$refundMethodToggles['gateway'][] = $transaction->id . '_refund_reason';
|
||||
}
|
||||
}
|
||||
$refundMethods['credit'] = 'refund_method_credit';
|
||||
@@ -599,6 +605,12 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
$field = new \IPS\Helpers\Form\Radio( $transaction->id . '_refund_method', 'none', TRUE, array( 'options' => $refundMethods, 'toggles' => $refundMethodToggles ) );
|
||||
$field->label = count( $transactions ) === 1 ? \IPS\Member::loggedIn()->language()->addToStack( 'refund_method' ) : \IPS\Member::loggedIn()->language()->addToStack( 'trans_refund_method', FALSE, array( 'sprintf' => array( $transaction->id ) ) );
|
||||
$form->add( $field );
|
||||
if ( $refundReasons )
|
||||
{
|
||||
$field = new \IPS\Helpers\Form\Radio( $transaction->id . '_refund_reason', NULL, FALSE, array( 'options' => $refundReasons ), NULL, NULL, NULL, $transaction->id . '_refund_reason' );
|
||||
$field->label = count( $transactions ) === 1 ? \IPS\Member::loggedIn()->language()->addToStack( 'refund_reason' ) : \IPS\Member::loggedIn()->language()->addToStack( 'trans_refund_reason', FALSE, array( 'sprintf' => array( $transaction->id ) ) );
|
||||
$form->add( $field );
|
||||
}
|
||||
|
||||
/* Partial refund? */
|
||||
$field = new \IPS\Helpers\Form\Number( $transaction->id . '_refund_amount', ( $transaction->status === \IPS\nexus\Transaction::STATUS_PART_REFUNDED ? (string) $transaction->amount->amount->subtract( $transaction->partial_refund->amount ) : 0 ), TRUE, array( 'unlimited' => 0, 'unlimitedLang' => \IPS\Member::loggedIn()->language()->addToStack( 'refund_full', FALSE, array( 'sprintf' => array( $transaction->amount ) ) ), 'max' => (string) $transaction->amount->amount->subtract( $transaction->partial_refund->amount ), 'decimals' => TRUE ), NULL, NULL, $transaction->amount->currency, $transaction->id . '_refund_amount' );
|
||||
@@ -645,7 +657,7 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
try
|
||||
{
|
||||
$transaction->refund( $values[ $transaction->id . '_refund_method' ], $values[ $transaction->id . '_refund_amount' ] );
|
||||
$transaction->refund( $values[ $transaction->id . '_refund_method' ], $values[ $transaction->id . '_refund_amount' ], isset( $values[ $transaction->id . '_refund_reason' ] ) ? $values[ $transaction->id . '_refund_reason' ] : NULL );
|
||||
}
|
||||
catch ( \LogicException $e )
|
||||
{
|
||||
@@ -764,7 +776,7 @@ class _invoices extends \IPS\Dispatcher\Controller
|
||||
$invoice->delete();
|
||||
|
||||
/* Redirect */
|
||||
$this->_redirect( $invoice );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=payments&controller=invoices') );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -276,7 +276,7 @@ class _payouts extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
if ( !$field->htmlId )
|
||||
{
|
||||
$field->htmlId = md5(uniqid());
|
||||
$field->htmlId = md5(mt_rand());
|
||||
}
|
||||
|
||||
$fields[] = $field;
|
||||
|
||||
@@ -45,7 +45,7 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
/* Create Table */
|
||||
$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=? OR t_status=? )', \IPS\nexus\Transaction::STATUS_HELD, \IPS\nexus\Transaction::STATUS_REVIEW ),
|
||||
'trans_attention_required' => array( '( t_status=? OR t_status=? OR t_status=? )', \IPS\nexus\Transaction::STATUS_HELD, \IPS\nexus\Transaction::STATUS_REVIEW, \IPS\nexus\Transaction::STATUS_DISPUTED ),
|
||||
);
|
||||
$table->advancedSearch = array(
|
||||
't_id' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
@@ -58,6 +58,10 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
$table->quickSearch = 't_id';
|
||||
|
||||
/* Display */
|
||||
if ( isset( \IPS\Request::i()->attn ) and \IPS\Db::i()->select( 'COUNT(*)', 'nexus_transactions', array( '( t_status=? OR t_status=? OR t_status=? )', \IPS\nexus\Transaction::STATUS_HELD, \IPS\nexus\Transaction::STATUS_REVIEW, \IPS\nexus\Transaction::STATUS_DISPUTED ) ) )
|
||||
{
|
||||
$table->filter = 'trans_attention_required';
|
||||
}
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__nexus_payments_transactions');
|
||||
\IPS\Output::i()->output = (string) $table;
|
||||
}
|
||||
@@ -105,7 +109,7 @@ 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, \IPS\nexus\Transaction::STATUS_GATEWAY_PENDING ) ) )
|
||||
if ( !in_array( $transaction->status, array( \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, '' );
|
||||
}
|
||||
@@ -163,7 +167,7 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
$method = $transaction->method;
|
||||
|
||||
/* Can we flag it? */
|
||||
if ( !in_array( $transaction->status, array( \IPS\nexus\Transaction::STATUS_PENDING, \IPS\nexus\Transaction::STATUS_WAITING, \IPS\nexus\Transaction::STATUS_HELD ) ) )
|
||||
if ( !in_array( $transaction->status, array( \IPS\nexus\Transaction::STATUS_WAITING, \IPS\nexus\Transaction::STATUS_HELD ) ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'transaction_status_err', '2X186/B', 403, '' );
|
||||
}
|
||||
@@ -176,11 +180,14 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
$transaction->save();
|
||||
|
||||
/* Log it */
|
||||
$transaction->member->log( 'transaction', array(
|
||||
'type' => 'status',
|
||||
'status' => \IPS\nexus\Transaction::STATUS_REVIEW,
|
||||
'id' => $transaction->id
|
||||
) );
|
||||
if( $transaction->member )
|
||||
{
|
||||
$transaction->member->log( 'transaction', array(
|
||||
'type' => 'status',
|
||||
'status' => \IPS\nexus\Transaction::STATUS_REVIEW,
|
||||
'id' => $transaction->id
|
||||
) );
|
||||
}
|
||||
|
||||
/* Create a support request? */
|
||||
if ( \IPS\Settings::i()->nexus_revw_sa != -1 )
|
||||
@@ -248,7 +255,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, \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 ) ) ) )
|
||||
if ( !in_array( $transaction->status, array( \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, '' );
|
||||
}
|
||||
@@ -302,12 +309,18 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
/* What are the refund methods? */
|
||||
$refundMethods = array();
|
||||
$refundMethodToggles = array( 'credit' => array( 'refund_amount' ) );
|
||||
$refundReasons = array();
|
||||
if ( $method and $method::SUPPORTS_REFUNDS )
|
||||
{
|
||||
$refundMethods['gateway'] = $method->_title;
|
||||
$refundMethodToggles['gateway'] = array();
|
||||
if ( $method::SUPPORTS_PARTIAL_REFUNDS )
|
||||
{
|
||||
$refundMethodToggles['gateway'] = array( 'refund_amount' );
|
||||
$refundMethodToggles['gateway'][] = 'refund_amount';
|
||||
}
|
||||
if ( $refundReasons = $method::refundReasons() )
|
||||
{
|
||||
$refundMethodToggles['gateway'][] = 'refund_reason';
|
||||
}
|
||||
}
|
||||
$refundMethods['credit'] = 'refund_method_credit';
|
||||
@@ -316,7 +329,20 @@ 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->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 ( $refundReasons )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'refund_reason', NULL, FALSE, array( 'options' => $refundReasons ), NULL, NULL, NULL, 'refund_reason' ) );
|
||||
}
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'refund_amount', 0, TRUE, array(
|
||||
'unlimited' => 0,
|
||||
'unlimitedLang' => (
|
||||
$transaction->status === \IPS\nexus\Transaction::STATUS_PART_REFUNDED
|
||||
? \IPS\Member::loggedIn()->language()->addToStack( 'refund_full_remaining', FALSE, array( 'sprintf' => array( new \IPS\nexus\Money( $transaction->amount->amount->subtract( $transaction->partial_refund->amount ), $transaction->currency ) ) ) )
|
||||
: \IPS\Member::loggedIn()->language()->addToStack( 'refund_full', FALSE, array( 'sprintf' => array( $transaction->amount ) ) )
|
||||
),
|
||||
'max' => (string) $transaction->amount->amount->subtract( $transaction->partial_refund->amount ),
|
||||
'decimals' => TRUE
|
||||
), NULL, NULL, $transaction->amount->currency, 'refund_amount' ) );
|
||||
if ( $transaction->invoice !== NULL and $transaction->invoice->status === \IPS\nexus\Invoice::STATUS_PAID )
|
||||
{
|
||||
$field = new \IPS\Helpers\Form\Radio( 'refund_invoice_status', \IPS\nexus\Invoice::STATUS_PENDING, TRUE, array(
|
||||
@@ -340,7 +366,7 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
/* Refund */
|
||||
try
|
||||
{
|
||||
$transaction->refund( $values['refund_method'], $values['refund_amount'] );
|
||||
$transaction->refund( $values['refund_method'], $values['refund_amount'], isset( $values['refund_reason'] ) ? $values['refund_reason'] : NULL );
|
||||
}
|
||||
catch ( \LogicException $e )
|
||||
{
|
||||
@@ -358,12 +384,15 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$transaction->invoice->markUnpaid( $values['refund_invoice_status'] );
|
||||
|
||||
$transaction->invoice->member->log( 'invoice', array(
|
||||
'type' => 'status',
|
||||
'new' => $values['refund_invoice_status'],
|
||||
'id' => $transaction->invoice->id,
|
||||
'title' => $transaction->invoice->title
|
||||
) );
|
||||
if( $transaction->invoice->member )
|
||||
{
|
||||
$transaction->invoice->member->log( 'invoice', array(
|
||||
'type' => 'status',
|
||||
'new' => $values['refund_invoice_status'],
|
||||
'id' => $transaction->invoice->id,
|
||||
'title' => $transaction->invoice->title
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
/* Send Email */
|
||||
@@ -406,11 +435,14 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
/* Log it */
|
||||
try
|
||||
{
|
||||
$transaction->member->log( 'transaction', array(
|
||||
'type' => 'delete',
|
||||
'id' => $transaction->id,
|
||||
'method' => $transaction->method->id
|
||||
) );
|
||||
if( $transaction->member )
|
||||
{
|
||||
$transaction->member->log( 'transaction', array(
|
||||
'type' => 'delete',
|
||||
'id' => $transaction->id,
|
||||
'method' => $transaction->method->id
|
||||
) );
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
|
||||
@@ -41,14 +41,29 @@ class _income extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
$tabs['totals'] = 'nexus_report_income_totals';
|
||||
foreach ( \IPS\nexus\Money::currencies() as $currency )
|
||||
$currencies = \IPS\nexus\Money::currencies();
|
||||
|
||||
$tabs = array( 'totals' => 'nexus_report_income_totals' );
|
||||
|
||||
if( count( $currencies ) == 1 )
|
||||
{
|
||||
$tabs['members'] = 'nexus_report_income_members';
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ( $currencies as $currency )
|
||||
{
|
||||
$tabs[ 'members_' . $currency ] = \IPS\Member::loggedIn()->language()->addToStack( 'nexus_report_income_by_member', NULL, array( 'sprintf' => array( $currency ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $currencies as $currency )
|
||||
{
|
||||
$tabs[ $currency ] = \IPS\Member::loggedIn()->language()->addToStack( 'nexus_report_income_by_method', NULL, array( 'sprintf' => array( $currency ) ) );
|
||||
}
|
||||
|
||||
$activeTab = ( isset( \IPS\Request::i()->tab ) and array_key_exists( \IPS\Request::i()->tab, $tabs ) ) ? \IPS\Request::i()->tab : 'totals';
|
||||
|
||||
|
||||
$chart = new \IPS\Helpers\Chart\Database(
|
||||
\IPS\Http\Url::internal( 'app=nexus&module=reports&controller=income&tab=' . $activeTab ),
|
||||
'nexus_transactions',
|
||||
@@ -61,7 +76,7 @@ class _income extends \IPS\Dispatcher\Controller
|
||||
'lineWidth' => 1,
|
||||
'areaOpacity' => 0.4,
|
||||
),
|
||||
'AreaChart',
|
||||
( \IPS\Request::i()->tab == 'members' ) ? 'PieChart' : 'AreaChart',
|
||||
'monthly',
|
||||
array( 'start' => 0, 'end' => 0 ),
|
||||
array(),
|
||||
@@ -73,11 +88,30 @@ class _income extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$chart->groupBy = 't_currency';
|
||||
|
||||
foreach ( \IPS\nexus\Money::currencies() as $currency )
|
||||
foreach ( $currencies as $currency )
|
||||
{
|
||||
$chart->addSeries( $currency, 'number', 'SUM(t_amount)-SUM(t_partial_refund)', TRUE, $currency );
|
||||
}
|
||||
}
|
||||
elseif( mb_strpos( $activeTab, 'members' ) === 0 )
|
||||
{
|
||||
$chart->groupBy = 't_member';
|
||||
|
||||
if( count( $currencies ) === 1 )
|
||||
{
|
||||
$chart->format = array_pop( $currencies );
|
||||
}
|
||||
else
|
||||
{
|
||||
$chart->format = mb_substr( $activeTab, 8 );
|
||||
$chart->where[] = array( 't_currency=?', $chart->format );
|
||||
}
|
||||
|
||||
foreach ( \IPS\Db::i()->select( 't_member, SUM(t_amount)-SUM(t_partial_refund) as _amount', 'nexus_transactions', $chart->where, '_amount DESC', array( 0, 20 ), 't_member' ) as $member )
|
||||
{
|
||||
$chart->addSeries( \IPS\Member::load( $member['t_member'] )->name, 'number', 'SUM(t_amount)-SUM(t_partial_refund)', TRUE, $member['t_member'] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$chart->where[] = array( 't_currency=?', $activeTab );
|
||||
@@ -89,6 +123,48 @@ class _income extends \IPS\Dispatcher\Controller
|
||||
$chart->addSeries( $gateway->_title, 'number', 'SUM(t_amount)-SUM(t_partial_refund)', TRUE, $gateway->id );
|
||||
}
|
||||
}
|
||||
|
||||
$chart->tableInclude = array( 't_id', 't_member', 't_invoice', 't_method', 't_amount', 't_date' );
|
||||
$chart->tableParsers = array(
|
||||
't_member' => function( $val ) {
|
||||
return \IPS\Theme::i()->getTemplate('global', 'nexus')->userLink( \IPS\Member::load( $val ) );
|
||||
},
|
||||
't_method' => function( $val ) {
|
||||
if ( $val )
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\nexus\Gateway::load( $val )->_title;
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('account_credit');
|
||||
}
|
||||
},
|
||||
't_amount' => function( $val, $row )
|
||||
{
|
||||
return (string) new \IPS\nexus\Money( $val, $row['t_currency'] );
|
||||
},
|
||||
't_invoice' => function( $val )
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate('invoices', 'nexus')->link( \IPS\nexus\Invoice::load( $val ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
},
|
||||
't_date' => function( $val ) {
|
||||
return \IPS\DateTime::ts( $val );
|
||||
}
|
||||
);
|
||||
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
|
||||
@@ -56,7 +56,7 @@ class _markets extends \IPS\Dispatcher\Controller
|
||||
'',
|
||||
array(
|
||||
'backgroundColor' => '#ffffff',
|
||||
'colors' => array( '#10967e', '#ea7963', '#de6470', '#6b9dde', '#b09be4', '#eec766', '#9fc973', '#e291bf', '#55c1a6', '#5fb9da' ),
|
||||
'colors' => array( '#c9e2de', '#10967e' ),
|
||||
'hAxis' => array( 'gridlines' => array( 'color' => '#f5f5f5' ) ),
|
||||
'lineWidth' => 1,
|
||||
'areaOpacity' => 0.4,
|
||||
|
||||
@@ -56,6 +56,18 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
);
|
||||
$chart->where[] = array( 'ps_app=? AND ps_type=?', 'nexus', 'package' );
|
||||
$chart->groupBy = 'ps_item_id';
|
||||
$chart->tableInclude = array( 'ps_id', 'ps_member', 'ps_name', 'ps_start', 'ps_expire' );
|
||||
$chart->tableParsers = array(
|
||||
'ps_member' => function( $val ) {
|
||||
return \IPS\Theme::i()->getTemplate('global', 'nexus')->userLink( \IPS\Member::load( $val ) );
|
||||
},
|
||||
'ps_start' => function( $val ) {
|
||||
return \IPS\DateTime::ts( $val );
|
||||
},
|
||||
'ps_expire' => function( $val ) {
|
||||
return $val ? \IPS\DateTime::ts( $val ) : '';
|
||||
}
|
||||
);
|
||||
|
||||
$packages = array();
|
||||
foreach ( \IPS\Db::i()->select( 'p_id', 'nexus_packages' ) as $packageId )
|
||||
|
||||
@@ -38,6 +38,7 @@ class _packages extends \IPS\Node\Controller
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'packages_manage' );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'admin_store.js', 'nexus', 'admin' ) );
|
||||
parent::execute();
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__nexus_store_packages');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,10 +128,10 @@ class _packages extends \IPS\Node\Controller
|
||||
}
|
||||
|
||||
$changes = json_decode( \IPS\Request::i()->changes, TRUE );
|
||||
|
||||
|
||||
if ( !isset( \IPS\Request::i()->processing ) )
|
||||
{
|
||||
if ( isset( $changes['renew_options'] ) and $changes['renew_options'] )
|
||||
if ( isset( $changes['renew_options'] ) )
|
||||
{
|
||||
$matrix = new \IPS\Helpers\Form\Matrix( 'matrix', 'continue' );
|
||||
$matrix->manageable = FALSE;
|
||||
@@ -180,28 +181,31 @@ class _packages extends \IPS\Node\Controller
|
||||
},
|
||||
);
|
||||
|
||||
foreach ( json_decode( $changes['renew_options'], TRUE ) as $k => $oldOption )
|
||||
if ( $changes['renew_options'] )
|
||||
{
|
||||
$costs = array();
|
||||
foreach ( $oldOption['cost'] as $data )
|
||||
foreach ( json_decode( $changes['renew_options'], TRUE ) as $k => $oldOption )
|
||||
{
|
||||
$costs[] = new \IPS\nexus\Money( $data['amount'], $data['currency'] );
|
||||
$costs = array();
|
||||
foreach ( $oldOption['cost'] as $data )
|
||||
{
|
||||
$costs[] = new \IPS\nexus\Money( $data['amount'], $data['currency'] );
|
||||
}
|
||||
|
||||
switch ( $oldOption['unit'] )
|
||||
{
|
||||
case 'd':
|
||||
$term = \IPS\Member::loggedIn()->language()->addToStack('renew_days', FALSE, array( 'pluralize' => array( $oldOption['term'] ) ) );
|
||||
break;
|
||||
case 'm':
|
||||
$term = \IPS\Member::loggedIn()->language()->addToStack('renew_months', FALSE, array( 'pluralize' => array( $oldOption['term'] ) ) );
|
||||
break;
|
||||
case 'y':
|
||||
$term = \IPS\Member::loggedIn()->language()->addToStack('renew_years', FALSE, array( 'pluralize' => array( $oldOption['term'] ) ) );
|
||||
break;
|
||||
}
|
||||
|
||||
$matrix->rows[ $k ] = array( \IPS\Member::loggedIn()->language()->addToStack( 'renew_option', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->formatList( $costs, \IPS\Member::loggedIn()->language()->get('or_list_format') ), $term ) ) ), "o{$k}" );
|
||||
}
|
||||
|
||||
switch ( $oldOption['unit'] )
|
||||
{
|
||||
case 'd':
|
||||
$term = \IPS\Member::loggedIn()->language()->addToStack('renew_days', FALSE, array( 'pluralize' => array( $oldOption['term'] ) ) );
|
||||
break;
|
||||
case 'm':
|
||||
$term = \IPS\Member::loggedIn()->language()->addToStack('renew_months', FALSE, array( 'pluralize' => array( $oldOption['term'] ) ) );
|
||||
break;
|
||||
case 'y':
|
||||
$term = \IPS\Member::loggedIn()->language()->addToStack('renew_years', FALSE, array( 'pluralize' => array( $oldOption['term'] ) ) );
|
||||
break;
|
||||
}
|
||||
|
||||
$matrix->rows[ $k ] = array( \IPS\Member::loggedIn()->language()->addToStack( 'renew_option', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->formatList( $costs, \IPS\Member::loggedIn()->language()->get('or_list_format') ), $term ) ) ), "o{$k}" );
|
||||
}
|
||||
$matrix->rows['x'] = array( 'any_other_amount', '-' );
|
||||
|
||||
@@ -226,7 +230,7 @@ class _packages extends \IPS\Node\Controller
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( isset( $changes['renew_options'] ) and !isset( \IPS\Request::i()->ba ) )
|
||||
{
|
||||
$needBaPrompt = FALSE;
|
||||
@@ -403,7 +407,7 @@ class _packages extends \IPS\Node\Controller
|
||||
'ps_member' => function( $val ) {
|
||||
try
|
||||
{
|
||||
return \IPS\nexus\Customer::load( $val )->link();
|
||||
return \IPS\Theme::i()->getTemplate('global', 'nexus')->userLink( \IPS\Member::load( $val ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
@@ -454,4 +458,34 @@ class _packages extends \IPS\Node\Controller
|
||||
\IPS\Output::i()->title = $package->_title;
|
||||
\IPS\Output::i()->output = $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show Email Preview
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function emailPreview()
|
||||
{
|
||||
$functionName = 'emailPreview_' . mt_rand();
|
||||
\IPS\Theme::makeProcessFunction( \IPS\Request::i()->value, $functionName, '$purchase' );
|
||||
|
||||
$dummyPurchase = new \IPS\nexus\Purchase;
|
||||
$dummyPurchase->name = \IPS\Member::loggedIn()->language()->addToStack('p_email_preview_example');
|
||||
$dummyPurchase->member = \IPS\Member::loggedIn();
|
||||
$dummyPurchase->expires = \IPS\DateTime::create()->add( new \DateInterval('P1M') );
|
||||
$dummyPurchase->renewals = new \IPS\nexus\Purchase\RenewalTerm( new \IPS\nexus\Money( 10, \IPS\nexus\Customer::loggedIn()->defaultCurrency() ), new \DateInterval('P1M') );
|
||||
$dummyPurchase->custom_fields = array_fill( 0, \IPS\Db::i()->select( 'MAX(cf_id)', 'nexus_package_fields' )->first(), \IPS\Member::loggedIn()->language()->addToStack('p_email_preview_example') );
|
||||
$dummyPurchase->licenseKey = new \IPS\nexus\Purchase\LicenseKey\Standard;
|
||||
$dummyPurchase->licenseKey->key = 'XXXX-XXXX-XXXX-XXXX';
|
||||
|
||||
try
|
||||
{
|
||||
$output = \IPS\Email::buildFromContent( 'Test', call_user_func( 'IPS\\Theme\\'.$functionName, $dummyPurchase ) )->compileContent( 'html', \IPS\Member::loggedIn() );
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
$output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->message( $e->getMessage(), 'error', $e->getMessage(), TRUE, TRUE );
|
||||
}
|
||||
\IPS\Output::i()->sendOutput( $output );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Subscribers
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
* @subpackage Commerce
|
||||
* @since 14 Feb 2018
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\modules\admin\subscriptions;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribers
|
||||
*/
|
||||
class _subscribers extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'subscribers_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
/* Create the table */
|
||||
$table = new \IPS\Helpers\Table\Db( 'nexus_member_subscriptions', \IPS\Http\Url::internal( 'app=nexus&module=subscriptions&controller=subscribers' ) );
|
||||
$table->joins = array(
|
||||
array(
|
||||
'select' => 'core_members.*',
|
||||
'from' => 'core_members',
|
||||
'where' => 'core_members.member_id=nexus_member_subscriptions.sub_member_id'
|
||||
),
|
||||
array(
|
||||
'select' => 'nexus_customers.cm_first_name, nexus_customers.cm_last_name',
|
||||
'from' => 'nexus_customers',
|
||||
'where' => 'core_members.member_id=nexus_customers.member_id'
|
||||
)
|
||||
);
|
||||
|
||||
$table->include = array( 'photo', 'sub_member_id', 'cm_last_name', 'cm_first_name', 'email', 'sub_package_id', 'sub_active', 'sub_start', 'sub_expire');
|
||||
$table->noSort = array( 'photo');
|
||||
$table->sortBy = $table->sortBy ?: 'sub_start';
|
||||
$table->sortDirection = $table->sortDirection ?: 'desc';
|
||||
$table->langPrefix = 'nexus_';
|
||||
|
||||
$table->quickSearch = 'email';
|
||||
|
||||
$table->parsers = array(
|
||||
'photo' => function( $val, $row )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate('customers')->rowPhoto( \IPS\Member::constructFromData( $row ) );
|
||||
},
|
||||
'sub_member_id' => function( $val ) {
|
||||
return \IPS\Theme::i()->getTemplate('global', 'nexus')->userLink( \IPS\Member::load( $val ) );
|
||||
},
|
||||
'sub_package_id' => function( $val ) {
|
||||
try
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate('subscription', 'nexus')->packageLink( \IPS\nexus\Subscription\Package::load( $val ) );
|
||||
}
|
||||
catch( \OutOfRangeException $e ) { }
|
||||
},
|
||||
'sub_start' => function( $val ) {
|
||||
return \IPS\DateTime::ts( $val );
|
||||
},
|
||||
'sub_expire' => function( $val ) {
|
||||
return $val ? \IPS\DateTime::ts( $val ) : '';
|
||||
},
|
||||
'sub_active' => function( $val ) {
|
||||
return \IPS\Theme::i()->getTemplate('subscription', 'nexus')->status( $val );
|
||||
}
|
||||
);
|
||||
|
||||
$table->rowButtons = function( $row ) {
|
||||
$return = array();
|
||||
|
||||
if ( $row['sub_purchase_id'] )
|
||||
{
|
||||
$return['purchase'] = array(
|
||||
'title' => 'nexus_subs_view_purchase',
|
||||
'icon' => 'search',
|
||||
'link' => \IPS\Http\Url::internal( "app=nexus&module=subscriptions&controller=subscribers&do=findPurchase&id=" . $row['sub_id'] )
|
||||
);
|
||||
}
|
||||
|
||||
return $return;
|
||||
};
|
||||
|
||||
$table->filters = array(
|
||||
'nexus_subs_filter_active' => array( 'sub_active=1' ),
|
||||
'nexus_subs_filter_inactive' => array( 'sub_active=0' ),
|
||||
'nexus_subs_filter_renews' => array( 'sub_active=1 and sub_renews=1' )
|
||||
);
|
||||
|
||||
$table->advancedSearch = array(
|
||||
'cm_first_name' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
'cm_last_name' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
'email' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
'name' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
'sub_expire' => \IPS\Helpers\Table\SEARCH_DATE_RANGE,
|
||||
'sub_start' => \IPS\Helpers\Table\SEARCH_DATE_RANGE,
|
||||
'sub_package_id' => array( \IPS\Helpers\Table\SEARCH_NODE, array(
|
||||
'class' => '\IPS\nexus\Subscription\Package',
|
||||
'zeroVal' => 'any'
|
||||
) ),
|
||||
);
|
||||
|
||||
/* Breadcrumb? */
|
||||
if ( isset( \IPS\Request::i()->nexus_sub_package_id ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$package = \IPS\nexus\Subscription\Package::load( \IPS\Request::i()->nexus_sub_package_id );
|
||||
\IPS\Output::i()->breadcrumb[] = array( \IPS\Http\Url::internal( "app=nexus&module=subscriptions&controller=subscriptions&id=" . $package->id ), $package->_title );
|
||||
}
|
||||
catch( \OutOfRangeException $e ) { }
|
||||
}
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('r__subscribers');
|
||||
\IPS\Output::i()->output = (string) $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a manually added member
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function remove()
|
||||
{
|
||||
try
|
||||
{
|
||||
$sub = \IPS\nexus\Subscription::load( \IPS\Request::i()->id );
|
||||
$package = \IPS\nexus\Subscription\Package::load( $sub->package_id );
|
||||
$customer = \IPS\nexus\Customer::load( $sub->member_id );
|
||||
$package->removeMember( $customer );
|
||||
|
||||
\IPS\Output::i()->redirect( $customer->acpUrl(), 'nexus_sub_member_removed' );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'nexus_sub_no_invoice', '2X378/1', 404, '' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find an purchase and redirect to it.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function findPurchase()
|
||||
{
|
||||
try
|
||||
{
|
||||
$sub = \IPS\nexus\Subscription::load( \IPS\Request::i()->id );
|
||||
$purchase = \IPS\nexus\Purchase::load( $sub->purchase_id );
|
||||
\IPS\Output::i()->redirect( $purchase->acpUrl() );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'nexus_sub_no_purchase', '2X378/2', 404, '' );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,317 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief subscriptions
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
* @subpackage Commerce
|
||||
* @since 09 Feb 2018
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\modules\admin\subscriptions;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* subscriptions
|
||||
*/
|
||||
class _subscriptions extends \IPS\Node\Controller
|
||||
{
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
protected $nodeClass = 'IPS\nexus\Subscription\Package';
|
||||
|
||||
/**
|
||||
* Fetch any additional HTML for this row
|
||||
*
|
||||
* @param object $node Node returned from $nodeClass::load()
|
||||
* @return NULL|string
|
||||
*/
|
||||
public function _getRowHtml( $node )
|
||||
{
|
||||
$active = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_member_subscriptions', array( 'sub_package_id=? and sub_active=1', $node->id ) )->first();
|
||||
$inactive = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_member_subscriptions', array( 'sub_package_id=? and sub_active=0', $node->id ) )->first();
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'subscription', 'nexus' )->rowHtml( $node, $node->priceBlurb(), $active, $inactive );
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'subscriptions_manage' );
|
||||
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function manage()
|
||||
{
|
||||
if ( \IPS\Settings::i()->nexus_subs_enabled )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions']['settings'] = array(
|
||||
'primary' => false,
|
||||
'title' => 'settings',
|
||||
'icon' => 'cog',
|
||||
'link' => \IPS\Http\Url::internal('app=nexus&module=subscriptions&controller=subscriptions&do=settings')
|
||||
);
|
||||
|
||||
parent::manage();
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'subscription' )->disabled();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a package to a subscription
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function convertToSubscription()
|
||||
{
|
||||
try
|
||||
{
|
||||
$package = \IPS\nexus\Package::load( \IPS\Request::i()->id );
|
||||
}
|
||||
catch( \OutOfRangeException $ex )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
$renewOptions = array();
|
||||
if ( $package->renew_options and $_renewOptions = json_decode( $package->renew_options, TRUE ) and is_array( $_renewOptions ) )
|
||||
{
|
||||
foreach ( $_renewOptions as $option )
|
||||
{
|
||||
$costs = array();
|
||||
foreach ( $option['cost'] as $cost )
|
||||
{
|
||||
$costs[ $cost['currency'] ] = new \IPS\nexus\Money( $cost['amount'], $cost['currency'] );
|
||||
}
|
||||
|
||||
/* Catch any invalid renewal terms, these can occasionally appear from legacy IP.Subscriptions */
|
||||
try
|
||||
{
|
||||
$renewOptions[] = new \IPS\nexus\Purchase\RenewalTerm( $costs, new \DateInterval( "P{$option['term']}" . mb_strtoupper( $option['unit'] ) ), NULL, $option['add'] );
|
||||
}
|
||||
catch( \Exception $ex) {}
|
||||
}
|
||||
}
|
||||
|
||||
$useRenewals = array_pop( $renewOptions );
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->addHeader('nexus_subs_review_pricing');
|
||||
$form->add( new \IPS\nexus\Form\Money( 'sp_price', $package->base_price, TRUE ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'sp_renews', !empty( $useRenewals ), FALSE, array( 'togglesOn' => array( 'sp_renew_options' ) ), NULL, NULL, NULL, 'sp_renews' ) );
|
||||
$form->add( new \IPS\nexus\Form\RenewalTerm( 'sp_renew_options', $useRenewals, NULL, array( 'allCurrencies' => TRUE ), NULL, NULL, NULL, 'sp_renew_options' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'sp_tax', (int) $package->tax, FALSE, array( 'class' => 'IPS\nexus\Tax', 'zeroVal' => 'do_not_tax' ) ) );
|
||||
$form->addHeader('nexus_subs_after_conversion');
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'sp_after_conversion_delete', FALSE, FALSE ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$sub = new \IPS\nexus\Subscription\Package;
|
||||
$sub->enabled = 1;
|
||||
$sub->tax = $values['sp_tax'] ? $values['p_tax']->id : 0;
|
||||
$sub->gateways = ( isset( $values['sp_gateways'] ) and is_array( $values['sp_gateways'] ) ) ? implode( ',', array_keys( $values['sp_gateways'] ) ) : '*';
|
||||
$sub->price = json_encode( $values['sp_price'] );
|
||||
|
||||
foreach( array( 'primary_group', 'secondary_group') as $thingsWotAreTheSame )
|
||||
{
|
||||
$sub->$thingsWotAreTheSame = $package->$thingsWotAreTheSame;
|
||||
}
|
||||
|
||||
/* Renewal options */
|
||||
if ( $values['sp_renews'] )
|
||||
{
|
||||
$renewOptions = array();
|
||||
$option = $values['sp_renew_options'];
|
||||
$term = $option->getTerm();
|
||||
|
||||
$sub->renew_options = json_encode( array(
|
||||
'cost' => $option->cost,
|
||||
'term' => $term['term'],
|
||||
'unit' => $term['unit']
|
||||
) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$sub->renew_options = '';
|
||||
}
|
||||
|
||||
$sub->save();
|
||||
|
||||
/* Language stuffs */
|
||||
\IPS\Lang::copyCustom( 'nexus', "nexus_package_{$package->id}", "nexus_subs_{$sub->id}" );
|
||||
\IPS\Lang::copyCustom( 'nexus', "nexus_package_{$package->id}_desc", "nexus_subs_{$sub->id}_desc" );
|
||||
|
||||
/* Purchases */
|
||||
foreach( \IPS\Db::i()->select( '*', 'nexus_purchases', array( 'ps_app=? and ps_type=? and ps_active=1 and ps_cancelled=0 and ps_item_id=?', 'nexus', 'package', $package->id ) ) as $purchase )
|
||||
{
|
||||
try
|
||||
{
|
||||
$customer = \IPS\nexus\Customer::load( $purchase['ps_member'] );
|
||||
|
||||
\IPS\Db::i()->update( 'nexus_purchases', array( 'ps_type' => 'subscription', 'ps_item_id' => $sub->id ), array( 'ps_id=?', $purchase['ps_id'] ) );
|
||||
|
||||
$subscription = $sub->addMember( $customer );
|
||||
$subscription->purchase_id = $purchase['ps_id'];
|
||||
$subscription->invoice_id = $purchase['ps_original_invoice'];
|
||||
$subscription->expire = $purchase['ps_expire'];
|
||||
$subscription->start = $purchase['ps_start'];
|
||||
$subscription->save();
|
||||
}
|
||||
catch( \Exception $e ) { }
|
||||
}
|
||||
|
||||
/* Delete original product */
|
||||
if ( $values['sp_after_conversion_delete'] )
|
||||
{
|
||||
$package->delete();
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=subscriptions&controller=subscriptions'), 'nexus_package_converted_lovely' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('nexus_subs_convert');
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'subscription', 'nexus' )->convert( $form, $package );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function enable()
|
||||
{
|
||||
\IPS\Settings::i()->changeValues( array( 'nexus_subs_enabled' => true ) );
|
||||
|
||||
\IPS\Session::i()->log( 'acplog__subscription_settings' );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=subscriptions&controller=subscriptions') );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a member for free!
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function addMember()
|
||||
{
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\Member( 'nexus_subs_member_to_add', NULL, TRUE, array(), function( $val )
|
||||
{
|
||||
if ( $val instanceof \IPS\Member )
|
||||
{
|
||||
try
|
||||
{
|
||||
$package = \IPS\nexus\Subscription\Package::load( \IPS\Request::i()->id );
|
||||
$sub = \IPS\nexus\Subscription::loadByMemberAndPackage( $val, $package, TRUE );
|
||||
|
||||
/* We have cannot have duplicate active subscriptions, so error out */
|
||||
throw new \InvalidArgumentException('nexus_subs_add_member_already_subscribed');
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
/* Nothing found, so that's all lovely and good */
|
||||
}
|
||||
}
|
||||
}, NULL, NULL, 'nexus_subs_member_to_add' ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$sub = \IPS\nexus\Subscription\Package::load( \IPS\Request::i()->id )->addMember( $values['nexus_subs_member_to_add'] );
|
||||
$sub->added_manually = 1;
|
||||
$sub->save();
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=subscriptions&controller=subscriptions'), 'nexus_sub_member_added' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('nexus_subs_add_member');
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'subscription', 'nexus' )->addMemberMessage( $form );
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage Settings
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function settings()
|
||||
{
|
||||
$groups = array();
|
||||
foreach ( \IPS\Member\Group::groups( FALSE, FALSE ) as $group )
|
||||
{
|
||||
$groups[ $group->g_id ] = $group->name;
|
||||
}
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
|
||||
$form->addHeader('subscription_basic_settings');
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_subs_enabled', \IPS\Settings::i()->nexus_subs_enabled, FALSE, array(), NULL, NULL, NULL, 'nexus_subs_enabled' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_subs_register', \IPS\Settings::i()->nexus_subs_register, FALSE, array(), NULL, NULL, NULL, 'nexus_subs_register' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_subs_show_public', \IPS\Settings::i()->nexus_subs_show_public, FALSE, array(), NULL, NULL, NULL, 'nexus_subs_show_public' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'nexus_subs_invoice_grace', \IPS\Settings::i()->nexus_subs_invoice_grace, FALSE, array( ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('days'), 'nexus_subs_invoice_grace' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'nexus_subs_exclude_groups', explode( ',', \IPS\Settings::i()->nexus_subs_exclude_groups ), FALSE, array( 'options' => $groups, 'multiple' => TRUE ) ) );
|
||||
|
||||
|
||||
$form->addHeader('package_upgrade_downgrade');
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_subs_upgrade_toggle', \IPS\Settings::i()->nexus_subs_upgrade > -1, FALSE, array( 'togglesOn' => array( 'nexus_subs_upgrade' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'nexus_subs_upgrade', \IPS\Settings::i()->nexus_subs_upgrade, FALSE, array( 'options' => array(
|
||||
0 => 'p_upgrade_charge_none',
|
||||
1 => 'p_upgrade_charge_full',
|
||||
2 => 'p_upgrade_charge_prorate'
|
||||
) ), NULL, NULL, NULL, 'nexus_subs_upgrade' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_subs_downgrade_toggle', \IPS\Settings::i()->nexus_subs_downgrade > -1, FALSE, array( 'togglesOn' => array( 'nexus_subs_downgrade' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'nexus_subs_downgrade', \IPS\Settings::i()->nexus_subs_downgrade, FALSE, array( 'options' => array(
|
||||
0 => 'p_downgrade_refund_none',
|
||||
1 => 'p_downgrade_refund_full',
|
||||
2 => 'p_downgrade_refund_prorate'
|
||||
)), NULL, NULL, NULL, 'nexus_subs_downgrade' ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
if ( ! $values['nexus_subs_upgrade_toggle'] )
|
||||
{
|
||||
$values['nexus_subs_upgrade'] = -1;
|
||||
}
|
||||
|
||||
if ( ! $values['nexus_subs_downgrade_toggle'] )
|
||||
{
|
||||
$values['nexus_subs_downgrade'] = -1;
|
||||
}
|
||||
|
||||
foreach( array( 'nexus_subs_upgrade_toggle', 'nexus_subs_downgrade_toggle' ) as $field )
|
||||
{
|
||||
unset( $values[ $field ] );
|
||||
}
|
||||
|
||||
$values['nexus_subs_exclude_groups'] = implode( ',', $values['nexus_subs_exclude_groups'] );
|
||||
|
||||
$form->saveAsSettings( $values );
|
||||
|
||||
\IPS\Session::i()->log( 'acplog__nexus_subs_settings' );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=subscriptions&controller=subscriptions') );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('settings');
|
||||
\IPS\Output::i()->output = $form;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -130,13 +130,7 @@ 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\Settings::i()->changeValues( array( 'pop3_server' => '', 'pop3_port' => '', 'pop3_user' => '', 'pop3_password' => '' ) );
|
||||
\IPS\Session::i()->log( 'acplogs__pop3_settings' );
|
||||
\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') );
|
||||
|
||||
@@ -896,7 +896,7 @@ class _request extends \IPS\nexus\modules\front\support\view
|
||||
}
|
||||
$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' ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'support_account', $request->author()->member_id, TRUE, array( 'options' => $options, 'toggles' => $toggles, 'parse' => 'normal' ) ) );
|
||||
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 );
|
||||
@@ -1002,7 +1002,7 @@ class _request extends \IPS\nexus\modules\front\support\view
|
||||
$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() ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'r_staff', $request->staff ? $request->staff->member_id : 0, FALSE, array( 'parse' => 'normal', 'options' => array( 0 => \IPS\Member::loggedIn()->language()->addToStack('unassigned') ) + \IPS\nexus\Support\Request::staff() ) ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
|
||||
@@ -138,7 +138,8 @@ class _requests extends \IPS\Dispatcher\Controller
|
||||
$order = array();
|
||||
if ( $groupByDepartment )
|
||||
{
|
||||
$order[] = 'dpt_position';
|
||||
$order[] = 'nexus_support_staff_dpt_order.dpt_position';
|
||||
$order[] = 'nexus_support_departments.dpt_position'; // This is to prevent an issue if two departments have the same position (which may be the case if new departments have been created since the user set their preferred order)
|
||||
}
|
||||
$honorSeverities = ( !isset( \IPS\Request::i()->cookie['support_honor_severities'] ) or \IPS\Request::i()->cookie['support_honor_severities'] );
|
||||
if ( $honorSeverities )
|
||||
@@ -525,19 +526,26 @@ class _requests extends \IPS\Dispatcher\Controller
|
||||
/* Init */
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'requests_create' );
|
||||
$steps = array();
|
||||
$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 );
|
||||
}
|
||||
|
||||
/* Owner */
|
||||
if ( !isset( \IPS\Request::i()->member ) )
|
||||
{
|
||||
$steps['request_owner'] = function( $data )
|
||||
$steps['request_owner'] = function( $data ) use ( $url )
|
||||
{
|
||||
$form = new \IPS\Helpers\Form( 'owner', 'continue' );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'request_owner_type', 'member', TRUE, array(
|
||||
$form = new \IPS\Helpers\Form( 'owner', 'continue', $url->setQueryString( '_step', 'request_owner' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'request_owner_type', isset( $data['email'] ) ? 'email' : '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' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Member( 'request_owner_member', isset( $data['member'] ) ? \IPS\Member::load( $data['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', isset( $data['email'] ) ? $data['email'] : NULL, FALSE, array(), NULL, NULL, NULL, 'request_owner_email' ) );
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
if ( $values['request_owner_type'] === 'member' )
|
||||
@@ -579,7 +587,7 @@ class _requests extends \IPS\Dispatcher\Controller
|
||||
$stockActions = \IPS\nexus\Support\StockAction::roots();
|
||||
if ( count( $stockActions ) )
|
||||
{
|
||||
$steps['stock_action'] = function( $data ) use ( $stockActions )
|
||||
$steps['stock_action'] = function( $data ) use ( $stockActions, $url )
|
||||
{
|
||||
$options = array( 0 => 'none' );
|
||||
foreach ( $stockActions as $action )
|
||||
@@ -587,8 +595,8 @@ class _requests extends \IPS\Dispatcher\Controller
|
||||
$options[ $action->id ] = $action->_title;
|
||||
}
|
||||
|
||||
$form = new \IPS\Helpers\Form( 'stock_action', 'continue' );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'stock_action', 0, FALSE, array(
|
||||
$form = new \IPS\Helpers\Form( 'stock_action', 'continue', $url->setQueryString( '_step', 'stock_action' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'stock_action', isset( $data['stock_action'] ) ? $data['stock_action'] : 0, FALSE, array(
|
||||
'options' => $options
|
||||
) ) );
|
||||
if ( $values = $form->values() )
|
||||
@@ -602,7 +610,7 @@ class _requests extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
/* Request Details */
|
||||
$steps['request_details'] = function( $data ) use ( $stockActions )
|
||||
$steps['request_details'] = function( $data ) use ( $stockActions, $url )
|
||||
{
|
||||
if ( !isset( $data['member'] ) AND isset( \IPS\Request::i()->member ) )
|
||||
{
|
||||
@@ -615,16 +623,16 @@ class _requests extends \IPS\Dispatcher\Controller
|
||||
$stockAction = $stockActions[ $data['stock_action'] ];
|
||||
}
|
||||
|
||||
$form = new \IPS\Helpers\Form( 'request_details', 'continue' );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'support_title', NULL, TRUE ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'support_department', $stockAction ? $stockAction->department : NULL, TRUE, array( 'class' => 'IPS\nexus\Support\Department' ) ) );
|
||||
$form = new \IPS\Helpers\Form( 'request_details', 'continue', $url->setQueryString( '_step', 'request_details' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'support_title', isset( $data['title'] ) ? $data['title'] : NULL, TRUE ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'support_department', isset( $data['department'] ) ? $data['department'] : ( $stockAction ? $stockAction->department : NULL ), TRUE, array( 'class' => 'IPS\nexus\Support\Department' ) ) );
|
||||
if ( isset( $data['member'] ) )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'support_purchase', 0, FALSE, array( 'class' => 'IPS\nexus\Purchase', 'forceOwner' => \IPS\Member::load( $data['member'] ), 'zeroVal' => 'none' ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'support_purchase', isset( $data['purchase'] ) ? $data['purchase'] : 0, FALSE, array( 'class' => 'IPS\nexus\Purchase', 'forceOwner' => \IPS\Member::load( $data['member'] ), 'zeroVal' => 'none' ) ) );
|
||||
}
|
||||
$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( 0 => 'unassigned' ) + \IPS\nexus\Support\Request::staff() ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'r_status', isset( $data['status'] ) ? $data['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', isset( $data['severity'] ) ? $data['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', isset( $data['staff'] ) ? $data['staff'] : 0, FALSE, array( 'parse' => 'normal', 'options' => array( 0 => \IPS\Member::loggedIn()->language()->addToStack('unassigned') ) + \IPS\nexus\Support\Request::staff() ) ) );
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$data['title'] = $values['support_title'];
|
||||
@@ -645,15 +653,15 @@ class _requests extends \IPS\Dispatcher\Controller
|
||||
$customFields = \IPS\nexus\Support\CustomField::roots();
|
||||
if ( count( $customFields ) )
|
||||
{
|
||||
$steps['custom_support_fields'] = function( $data )
|
||||
$steps['custom_support_fields'] = function( $data ) use ( $url )
|
||||
{
|
||||
$customFields = \IPS\nexus\Support\CustomField::roots( NULL, NULL, array( "sf_departments='*' OR " . \IPS\Db::i()->findInSet( 'sf_departments', array( $data['department'] ) ) ) );
|
||||
if ( count( $customFields ) )
|
||||
{
|
||||
$form = new \IPS\Helpers\Form( 'custom_fields', 'continue' );
|
||||
$form = new \IPS\Helpers\Form( 'custom_fields', 'continue', $url->setQueryString( '_step', 'custom_support_fields' ) );
|
||||
foreach ( $customFields as $field )
|
||||
{
|
||||
$form->add( $field->buildHelper() );
|
||||
$form->add( $field->buildHelper( isset( $data['custom_fields']["nexus_cfield_{$field->id}"] ) ? $data['custom_fields']["nexus_cfield_{$field->id}"] : NULL ) );
|
||||
}
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
@@ -670,7 +678,7 @@ class _requests extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
/* Your Message */
|
||||
$steps['your_message'] = function( $data ) use ( $stockActions )
|
||||
$steps['your_message'] = function( $data ) use ( $stockActions, $url )
|
||||
{
|
||||
$stockAction = NULL;
|
||||
if ( isset( $data['stock_action'] ) and isset( $stockActions[ $data['stock_action'] ] ) )
|
||||
@@ -701,7 +709,7 @@ class _requests extends \IPS\Dispatcher\Controller
|
||||
$defaultContent = NULL;
|
||||
}
|
||||
|
||||
$form = new \IPS\Helpers\Form( 'your_message' );
|
||||
$form = new \IPS\Helpers\Form( 'your_message', 'save', $url->setQueryString( '_step', 'your_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' ) );
|
||||
@@ -845,16 +853,7 @@ 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, $url, TRUE, $initialData );
|
||||
|
||||
@@ -50,9 +50,7 @@ class _severities extends \IPS\Node\Controller
|
||||
|
||||
if ( isset( \IPS\Request::i()->nexus_severities ) )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => \IPS\Request::i()->nexus_severities ), array( 'conf_key=?', 'nexus_severities' ) );
|
||||
\IPS\Settings::i()->nexus_severities = \IPS\Request::i()->nexus_severities;
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
\IPS\Settings::i()->changeValues( array( 'nexus_severities' => \IPS\Request::i()->nexus_severities ) );
|
||||
\IPS\Session::i()->log( 'acplogs__severity_settings' );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=support&controller=settings&tab=severities') );
|
||||
}
|
||||
|
||||
@@ -58,6 +58,26 @@ class _volume extends \IPS\Dispatcher\Controller
|
||||
$chart->addSeries( $department->_title, 'number', 'COUNT(*)', TRUE, $department->id );
|
||||
}
|
||||
|
||||
$chart->tableInclude = array( 'r_id', 'r_title', 'r_member', 'r_department', 'r_status', 'r_started', 'r_last_reply', 'r_replies' );
|
||||
$chart->tableParsers = array(
|
||||
'r_member' => function( $val ) {
|
||||
return \IPS\Theme::i()->getTemplate('global', 'nexus')->userLink( \IPS\Member::load( $val ) );
|
||||
},
|
||||
'r_department' => function( $val ) {
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'nexus_department_' . $val );
|
||||
},
|
||||
'r_status' => function( $val, $row )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'nexus_status_' . $val . '_admin' );
|
||||
},
|
||||
'r_started' => function( $val ) {
|
||||
return \IPS\DateTime::ts( $val );
|
||||
},
|
||||
'r_last_reply' => function( $val ) {
|
||||
return \IPS\DateTime::ts( $val );
|
||||
}
|
||||
);
|
||||
|
||||
\IPS\Output::i()->output = (string) $chart;
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__nexus_support_volume');
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user