1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-19 05:12:41 +01:00

Show only recent orders and charges on Phortune account profile page

Summary: Ref T2787. Currently, we show all orders/charges, which won't scale well. Show the 10 most recent and link to full order/charge history.

Test Plan: {F216325}

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T2787

Differential Revision: https://secure.phabricator.com/D10685
This commit is contained in:
epriestley 2014-10-13 11:14:50 -07:00
parent 7fc7b89bb4
commit 8ba2a1fd44
12 changed files with 533 additions and 137 deletions

View file

@ -2571,8 +2571,11 @@ phutil_register_library_map(array(
'PhortuneCartUpdateController' => 'applications/phortune/controller/PhortuneCartUpdateController.php',
'PhortuneCartViewController' => 'applications/phortune/controller/PhortuneCartViewController.php',
'PhortuneCharge' => 'applications/phortune/storage/PhortuneCharge.php',
'PhortuneChargeListController' => 'applications/phortune/controller/PhortuneChargeListController.php',
'PhortuneChargePHIDType' => 'applications/phortune/phid/PhortuneChargePHIDType.php',
'PhortuneChargeQuery' => 'applications/phortune/query/PhortuneChargeQuery.php',
'PhortuneChargeSearchEngine' => 'applications/phortune/query/PhortuneChargeSearchEngine.php',
'PhortuneChargeTableView' => 'applications/phortune/view/PhortuneChargeTableView.php',
'PhortuneConstants' => 'applications/phortune/constants/PhortuneConstants.php',
'PhortuneController' => 'applications/phortune/controller/PhortuneController.php',
'PhortuneCreditCardForm' => 'applications/phortune/view/PhortuneCreditCardForm.php',
@ -2601,6 +2604,7 @@ phutil_register_library_map(array(
'PhortuneMultiplePaymentProvidersException' => 'applications/phortune/exception/PhortuneMultiplePaymentProvidersException.php',
'PhortuneNoPaymentProviderException' => 'applications/phortune/exception/PhortuneNoPaymentProviderException.php',
'PhortuneNotImplementedException' => 'applications/phortune/exception/PhortuneNotImplementedException.php',
'PhortuneOrderTableView' => 'applications/phortune/view/PhortuneOrderTableView.php',
'PhortunePayPalPaymentProvider' => 'applications/phortune/provider/PhortunePayPalPaymentProvider.php',
'PhortunePaymentMethod' => 'applications/phortune/storage/PhortunePaymentMethod.php',
'PhortunePaymentMethodCreateController' => 'applications/phortune/controller/PhortunePaymentMethodCreateController.php',
@ -5637,8 +5641,11 @@ phutil_register_library_map(array(
'PhortuneDAO',
'PhabricatorPolicyInterface',
),
'PhortuneChargeListController' => 'PhortuneController',
'PhortuneChargePHIDType' => 'PhabricatorPHIDType',
'PhortuneChargeQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhortuneChargeSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhortuneChargeTableView' => 'AphrontView',
'PhortuneController' => 'PhabricatorController',
'PhortuneCurrency' => 'Phobject',
'PhortuneCurrencySerializer' => 'PhabricatorLiskSerializer',
@ -5668,6 +5675,7 @@ phutil_register_library_map(array(
'PhortuneMultiplePaymentProvidersException' => 'Exception',
'PhortuneNoPaymentProviderException' => 'Exception',
'PhortuneNotImplementedException' => 'Exception',
'PhortuneOrderTableView' => 'AphrontView',
'PhortunePayPalPaymentProvider' => 'PhortunePaymentProvider',
'PhortunePaymentMethod' => array(
'PhortuneDAO',

View file

@ -39,6 +39,10 @@ final class PhabricatorPhortuneApplication extends PhabricatorApplication {
'card/' => array(
'new/' => 'PhortunePaymentMethodCreateController',
),
'order/(?:query/(?P<queryKey>[^/]+)/)?'
=> 'PhortuneCartListController',
'charge/(?:query/(?P<queryKey>[^/]+)/)?'
=> 'PhortuneChargeListController',
),
'card/(?P<id>\d+)/' => array(
'edit/' => 'PhortunePaymentMethodEditController',

View file

@ -83,8 +83,8 @@ final class PhortuneAccountListController extends PhortuneController {
->setHref($this->getApplicationURI('merchant/'))
->setIcon(
id(new PHUIIconView())
->setIconFont('fa-folder-open'))
->setText(pht('Browse Merchants')));
->setIconFont('fa-list'))
->setText(pht('View All Merchants')));
$merchant_box = id(new PHUIObjectBoxView())
->setHeader($merchant_header)

View file

@ -179,6 +179,7 @@ final class PhortuneAccountViewController extends PhortuneController {
PhortuneCart::STATUS_REVIEW,
PhortuneCart::STATUS_PURCHASED,
))
->setLimit(10)
->execute();
$phids = array();
@ -190,73 +191,23 @@ final class PhortuneAccountViewController extends PhortuneController {
}
$handles = $this->loadViewerHandles($phids);
$rows = array();
$rowc = array();
foreach ($carts as $cart) {
$cart_link = $handles[$cart->getPHID()]->renderLink();
$purchases = $cart->getPurchases();
$orders_uri = $this->getApplicationURI($account->getID().'/order/');
if (count($purchases) == 1) {
$purchase_name = $handles[$purchase->getPHID()]->renderLink();
$purchases = array();
} else {
$purchase_name = '';
}
$rowc[] = '';
$rows[] = array(
$cart->getID(),
phutil_tag(
'strong',
array(),
$cart_link),
$purchase_name,
phutil_tag(
'strong',
array(),
$cart->getTotalPriceAsCurrency()->formatForDisplay()),
PhortuneCart::getNameForStatus($cart->getStatus()),
phabricator_datetime($cart->getDateModified(), $viewer),
);
foreach ($purchases as $purchase) {
$id = $purchase->getID();
$price = $purchase->getTotalPriceAsCurrency()->formatForDisplay();
$rowc[] = '';
$rows[] = array(
'',
$handles[$purchase->getPHID()]->renderLink(),
$price,
'',
'',
);
}
}
$table = id(new AphrontTableView($rows))
->setRowClasses($rowc)
->setHeaders(
array(
pht('ID'),
pht('Order'),
pht('Purchase'),
pht('Amount'),
pht('Status'),
pht('Updated'),
))
->setColumnClasses(
array(
'',
'',
'wide',
'right',
'',
'right',
));
$table = id(new PhortuneOrderTableView())
->setUser($viewer)
->setCarts($carts)
->setHandles($handles);
$header = id(new PHUIHeaderView())
->setHeader(pht('Order History'));
->setHeader(pht('Recent Orders'))
->addActionLink(
id(new PHUIButtonView())
->setTag('a')
->setIcon(
id(new PHUIIconView())
->setIconFont('fa-list'))
->setHref($orders_uri)
->setText(pht('View All Orders')));
return id(new PHUIObjectBoxView())
->setHeader($header)
@ -271,9 +222,40 @@ final class PhortuneAccountViewController extends PhortuneController {
->setViewer($viewer)
->withAccountPHIDs(array($account->getPHID()))
->needCarts(true)
->setLimit(10)
->execute();
return $this->buildChargesTable($charges);
$phids = array();
foreach ($charges as $charge) {
$phids[] = $charge->getProviderPHID();
$phids[] = $charge->getCartPHID();
$phids[] = $charge->getMerchantPHID();
$phids[] = $charge->getPaymentMethodPHID();
}
$handles = $this->loadViewerHandles($phids);
$charges_uri = $this->getApplicationURI($account->getID().'/charge/');
$table = id(new PhortuneChargeTableView())
->setUser($viewer)
->setCharges($charges)
->setHandles($handles);
$header = id(new PHUIHeaderView())
->setHeader(pht('Recent Charges'))
->addActionLink(
id(new PHUIButtonView())
->setTag('a')
->setIcon(
id(new PHUIIconView())
->setIconFont('fa-list'))
->setHref($charges_uri)
->setText(pht('View All Charges')));
return id(new PHUIObjectBoxView())
->setHeader($header)
->appendChild($table);
}
private function buildAccountHistorySection(PhortuneAccount $account) {

View file

@ -3,13 +3,16 @@
final class PhortuneCartListController
extends PhortuneController {
private $accountID;
private $merchantID;
private $queryKey;
private $merchant;
private $account;
public function willProcessRequest(array $data) {
$this->merchantID = idx($data, 'merchantID');
$this->accountID = idx($data, 'accountID');
$this->queryKey = idx($data, 'queryKey');
}
@ -34,6 +37,23 @@ final class PhortuneCartListController
}
$this->merchant = $merchant;
$engine->setMerchant($merchant);
} else if ($this->accountID) {
$account = id(new PhortuneAccountQuery())
->setViewer($viewer)
->withIDs(array($this->accountID))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$account) {
return new Aphront404Response();
}
$this->account = $account;
$engine->setAccount($account);
} else {
return new Aphront404Response();
}
$controller = id(new PhabricatorApplicationSearchController($request))
@ -73,6 +93,17 @@ final class PhortuneCartListController
$this->getApplicationURI("merchant/orders/{$id}/"));
}
$account = $this->account;
if ($account) {
$id = $account->getID();
$crumbs->addTextCrumb(
$account->getName(),
$this->getApplicationURI("{$id}/"));
$crumbs->addTextCrumb(
pht('Orders'),
$this->getApplicationURI("{$id}/order/"));
}
return $crumbs;
}

View file

@ -135,7 +135,24 @@ final class PhortuneCartViewController
->needCarts(true)
->execute();
$charges_table = $this->buildChargesTable($charges, false);
$phids = array();
foreach ($charges as $charge) {
$phids[] = $charge->getProviderPHID();
$phids[] = $charge->getCartPHID();
$phids[] = $charge->getMerchantPHID();
$phids[] = $charge->getPaymentMethodPHID();
}
$handles = $this->loadViewerHandles($phids);
$charges_table = id(new PhortuneChargeTableView())
->setUser($viewer)
->setHandles($handles)
->setCharges($charges)
->setShowOrder(false);
$charges = id(new PHUIObjectBoxView())
->setHeaderText(pht('Charges'))
->appendChild($charges_table);
$account = $cart->getAccount();
@ -147,7 +164,7 @@ final class PhortuneCartViewController
array(
$crumbs,
$cart_box,
$charges_table,
$charges,
),
array(
'title' => pht('Cart'),

View file

@ -0,0 +1,81 @@
<?php
final class PhortuneChargeListController
extends PhortuneController {
private $accountID;
private $queryKey;
private $account;
public function willProcessRequest(array $data) {
$this->accountID = idx($data, 'accountID');
$this->queryKey = idx($data, 'queryKey');
}
public function processRequest() {
$request = $this->getRequest();
$viewer = $request->getUser();
$engine = new PhortuneChargeSearchEngine();
if ($this->accountID) {
$account = id(new PhortuneAccountQuery())
->setViewer($viewer)
->withIDs(array($this->accountID))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$account) {
return new Aphront404Response();
}
$this->account = $account;
$engine->setAccount($account);
} else {
return new Aphront404Response();
}
$controller = id(new PhabricatorApplicationSearchController($request))
->setQueryKey($this->queryKey)
->setSearchEngine($engine)
->setNavigation($this->buildSideNavView());
return $this->delegateToController($controller);
}
public function buildSideNavView() {
$viewer = $this->getRequest()->getUser();
$nav = new AphrontSideNavFilterView();
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
id(new PhortuneChargeSearchEngine())
->setViewer($viewer)
->addNavigationItems($nav->getMenu());
$nav->selectFilter(null);
return $nav;
}
public function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
$account = $this->account;
if ($account) {
$id = $account->getID();
$crumbs->addTextCrumb(
$account->getName(),
$this->getApplicationURI("{$id}/"));
$crumbs->addTextCrumb(
pht('Charges'),
$this->getApplicationURI("{$id}/charge/"));
}
return $crumbs;
}
}

View file

@ -2,73 +2,6 @@
abstract class PhortuneController extends PhabricatorController {
protected function buildChargesTable(array $charges, $show_cart = true) {
$request = $this->getRequest();
$viewer = $request->getUser();
$phids = array();
foreach ($charges as $charge) {
$phids[] = $charge->getProviderPHID();
$phids[] = $charge->getCartPHID();
$phids[] = $charge->getMerchantPHID();
$phids[] = $charge->getPaymentMethodPHID();
}
$handles = $this->loadViewerHandles($phids);
$rows = array();
foreach ($charges as $charge) {
$rows[] = array(
$charge->getID(),
$handles[$charge->getCartPHID()]->renderLink(),
$handles[$charge->getProviderPHID()]->renderLink(),
$charge->getPaymentMethodPHID()
? $handles[$charge->getPaymentMethodPHID()]->renderLink()
: null,
$handles[$charge->getMerchantPHID()]->renderLink(),
$charge->getAmountAsCurrency()->formatForDisplay(),
$charge->getStatusForDisplay(),
phabricator_datetime($charge->getDateCreated(), $viewer),
);
}
$charge_table = id(new AphrontTableView($rows))
->setHeaders(
array(
pht('ID'),
pht('Cart'),
pht('Provider'),
pht('Method'),
pht('Merchant'),
pht('Amount'),
pht('Status'),
pht('Created'),
))
->setColumnClasses(
array(
'',
'',
'',
'',
'',
'wide right',
'',
'',
))
->setColumnVisibility(
array(
true,
$show_cart,
));
$header = id(new PHUIHeaderView())
->setHeader(pht('Charge History'));
return id(new PHUIObjectBoxView())
->setHeader($header)
->appendChild($charge_table);
}
protected function addAccountCrumb(
$crumbs,
PhortuneAccount $account,

View file

@ -4,6 +4,16 @@ final class PhortuneCartSearchEngine
extends PhabricatorApplicationSearchEngine {
private $merchant;
private $account;
public function setAccount(PhortuneAccount $account) {
$this->account = $account;
return $this;
}
public function getAccount() {
return $this->account;
}
public function setMerchant(PhortuneMerchant $merchant) {
$this->merchant = $merchant;
@ -39,6 +49,7 @@ final class PhortuneCartSearchEngine
$viewer = $this->requireViewer();
$merchant = $this->getMerchant();
$account = $this->getAccount();
if ($merchant) {
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
@ -49,9 +60,21 @@ final class PhortuneCartSearchEngine
pht('You can not query orders for a merchant you do not control.'));
}
$query->withMerchantPHIDs(array($merchant->getPHID()));
} else if ($account) {
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$account,
PhabricatorPolicyCapability::CAN_EDIT);
if (!$can_edit) {
throw new Exception(
pht(
'You can not query orders for an account you are not '.
'a member of.'));
}
$query->withAccountPHIDs(array($account->getPHID()));
} else {
$accounts = id(new PhortuneAccountQuery())
->withMemberPHIDs($viewer->getPHID())
->withMemberPHIDs(array($viewer->getPHID()))
->execute();
if ($accounts) {
$query->withAccountPHIDs(mpull($accounts, 'getPHID'));
@ -69,8 +92,11 @@ final class PhortuneCartSearchEngine
protected function getURI($path) {
$merchant = $this->getMerchant();
$account = $this->getAccount();
if ($merchant) {
return '/phortune/merchant/'.$merchant->getID().'/order/'.$path;
} else if ($account) {
return '/phortune/'.$account->getID().'/order/';
} else {
return '/phortune/order/'.$path;
}

View file

@ -0,0 +1,125 @@
<?php
final class PhortuneChargeSearchEngine
extends PhabricatorApplicationSearchEngine {
private $account;
public function setAccount(PhortuneAccount $account) {
$this->account = $account;
return $this;
}
public function getAccount() {
return $this->account;
}
public function getResultTypeDescription() {
return pht('Phortune Charges');
}
public function buildSavedQueryFromRequest(AphrontRequest $request) {
$saved = new PhabricatorSavedQuery();
return $saved;
}
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
$query = id(new PhortuneChargeQuery());
$viewer = $this->requireViewer();
$account = $this->getAccount();
if ($account) {
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$account,
PhabricatorPolicyCapability::CAN_EDIT);
if (!$can_edit) {
throw new Exception(
pht(
'You can not query charges for an account you are not '.
'a member of.'));
}
$query->withAccountPHIDs(array($account->getPHID()));
} else {
$accounts = id(new PhortuneAccountQuery())
->withMemberPHIDs(array($viewer->getPHID()))
->execute();
if ($accounts) {
$query->withAccountPHIDs(mpull($accounts, 'getPHID'));
} else {
throw new Exception(pht('You have no accounts!'));
}
}
return $query;
}
public function buildSearchForm(
AphrontFormView $form,
PhabricatorSavedQuery $saved_query) {}
protected function getURI($path) {
$account = $this->getAccount();
if ($account) {
return '/phortune/'.$account->getID().'/charge/';
} else {
return '/phortune/charge/'.$path;
}
}
public function getBuiltinQueryNames() {
$names = array(
'all' => pht('All Charges'),
);
return $names;
}
public function buildSavedQueryFromBuiltin($query_key) {
$query = $this->newSavedQuery();
$query->setQueryKey($query_key);
switch ($query_key) {
case 'all':
return $query;
}
return parent::buildSavedQueryFromBuiltin($query_key);
}
protected function getRequiredHandlePHIDsForResultList(
array $charges,
PhabricatorSavedQuery $query) {
$phids = array();
foreach ($charges as $charge) {
$phids[] = $charge->getProviderPHID();
$phids[] = $charge->getCartPHID();
$phids[] = $charge->getMerchantPHID();
$phids[] = $charge->getPaymentMethodPHID();
}
return $phids;
}
protected function renderResultList(
array $charges,
PhabricatorSavedQuery $query,
array $handles) {
assert_instances_of($charges, 'PhortuneCharge');
$viewer = $this->requireViewer();
$table = id(new PhortuneChargeTableView())
->setUser($viewer)
->setCharges($charges)
->setHandles($handles);
return id(new PHUIObjectBoxView())
->setHeaderText(pht('Charges'))
->appendChild($table);
}
}

View file

@ -0,0 +1,89 @@
<?php
final class PhortuneChargeTableView extends AphrontView {
private $charges;
private $handles;
private $showOrder;
public function setShowOrder($show_order) {
$this->showOrder = $show_order;
return $this;
}
public function getShowOrder() {
return $this->showOrder;
}
public function setHandles(array $handles) {
$this->handles = $handles;
return $this;
}
public function getHandles() {
return $this->handles;
}
public function setCharges(array $charges) {
$this->charges = $charges;
return $this;
}
public function getCharges() {
return $this->charges;
}
public function render() {
$charges = $this->getCharges();
$handles = $this->getHandles();
$viewer = $this->getUser();
$rows = array();
foreach ($charges as $charge) {
$rows[] = array(
$charge->getID(),
$handles[$charge->getCartPHID()]->renderLink(),
$handles[$charge->getProviderPHID()]->renderLink(),
$charge->getPaymentMethodPHID()
? $handles[$charge->getPaymentMethodPHID()]->renderLink()
: null,
$handles[$charge->getMerchantPHID()]->renderLink(),
$charge->getAmountAsCurrency()->formatForDisplay(),
$charge->getStatusForDisplay(),
phabricator_datetime($charge->getDateCreated(), $viewer),
);
}
$table = id(new AphrontTableView($rows))
->setHeaders(
array(
pht('ID'),
pht('Cart'),
pht('Provider'),
pht('Method'),
pht('Merchant'),
pht('Amount'),
pht('Status'),
pht('Created'),
))
->setColumnClasses(
array(
'',
'',
'',
'',
'',
'wide right',
'',
'',
))
->setColumnVisibility(
array(
true,
$this->getShowOrder(),
));
return $table;
}
}

View file

@ -0,0 +1,100 @@
<?php
final class PhortuneOrderTableView extends AphrontView {
private $carts;
private $handles;
public function setHandles(array $handles) {
$this->handles = $handles;
return $this;
}
public function getHandles() {
return $this->handles;
}
public function setCarts(array $carts) {
$this->carts = $carts;
return $this;
}
public function getCarts() {
return $this->carts;
}
public function render() {
$carts = $this->getCarts();
$handles = $this->getHandles();
$viewer = $this->getUser();
$rows = array();
$rowc = array();
foreach ($carts as $cart) {
$cart_link = $handles[$cart->getPHID()]->renderLink();
$purchases = $cart->getPurchases();
if (count($purchases) == 1) {
$purchase = head($purchases);
$purchase_name = $handles[$purchase->getPHID()]->renderLink();
$purchases = array();
} else {
$purchase_name = '';
}
$rowc[] = '';
$rows[] = array(
$cart->getID(),
phutil_tag(
'strong',
array(),
$cart_link),
$purchase_name,
phutil_tag(
'strong',
array(),
$cart->getTotalPriceAsCurrency()->formatForDisplay()),
PhortuneCart::getNameForStatus($cart->getStatus()),
phabricator_datetime($cart->getDateModified(), $viewer),
);
foreach ($purchases as $purchase) {
$id = $purchase->getID();
$price = $purchase->getTotalPriceAsCurrency()->formatForDisplay();
$rowc[] = '';
$rows[] = array(
'',
$handles[$purchase->getPHID()]->renderLink(),
$price,
'',
'',
);
}
}
$table = id(new AphrontTableView($rows))
->setRowClasses($rowc)
->setHeaders(
array(
pht('ID'),
pht('Order'),
pht('Purchase'),
pht('Amount'),
pht('Status'),
pht('Updated'),
))
->setColumnClasses(
array(
'',
'',
'wide',
'right',
'',
'right',
));
return $table;
}
}