mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-19 12:00:55 +01:00
Allow merchant controllers to review orders in Phortune
Summary: Ref T2787. Sets the stage for administrating / cancelling / refunding orders and hold orders. Test Plan: {F215140} {F215141} Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T2787 Differential Revision: https://secure.phabricator.com/D10663
This commit is contained in:
parent
19db3fbb60
commit
b6c65719e4
10 changed files with 293 additions and 4 deletions
|
@ -2557,8 +2557,10 @@ phutil_register_library_map(array(
|
|||
'PhortuneCartCheckoutController' => 'applications/phortune/controller/PhortuneCartCheckoutController.php',
|
||||
'PhortuneCartController' => 'applications/phortune/controller/PhortuneCartController.php',
|
||||
'PhortuneCartImplementation' => 'applications/phortune/cart/PhortuneCartImplementation.php',
|
||||
'PhortuneCartListController' => 'applications/phortune/controller/PhortuneCartListController.php',
|
||||
'PhortuneCartPHIDType' => 'applications/phortune/phid/PhortuneCartPHIDType.php',
|
||||
'PhortuneCartQuery' => 'applications/phortune/query/PhortuneCartQuery.php',
|
||||
'PhortuneCartSearchEngine' => 'applications/phortune/query/PhortuneCartSearchEngine.php',
|
||||
'PhortuneCartViewController' => 'applications/phortune/controller/PhortuneCartViewController.php',
|
||||
'PhortuneCharge' => 'applications/phortune/storage/PhortuneCharge.php',
|
||||
'PhortuneChargePHIDType' => 'applications/phortune/phid/PhortuneChargePHIDType.php',
|
||||
|
@ -5608,8 +5610,10 @@ phutil_register_library_map(array(
|
|||
),
|
||||
'PhortuneCartCheckoutController' => 'PhortuneCartController',
|
||||
'PhortuneCartController' => 'PhortuneController',
|
||||
'PhortuneCartListController' => 'PhortuneController',
|
||||
'PhortuneCartPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhortuneCartQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhortuneCartSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PhortuneCartViewController' => 'PhortuneCartController',
|
||||
'PhortuneCharge' => array(
|
||||
'PhortuneDAO',
|
||||
|
|
|
@ -23,7 +23,7 @@ final class FundBackerCart extends PhortuneCartImplementation {
|
|||
return $this->initiative;
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
public function getName(PhortuneCart $cart) {
|
||||
return pht('Fund Initiative');
|
||||
}
|
||||
|
||||
|
|
|
@ -67,6 +67,8 @@ final class PhabricatorPhortuneApplication extends PhabricatorApplication {
|
|||
'merchant/' => array(
|
||||
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PhortuneMerchantListController',
|
||||
'edit/(?:(?P<id>\d+)/)?' => 'PhortuneMerchantEditController',
|
||||
'orders/(?P<merchantID>\d+)/(?:query/(?P<querKey>[^/]+)/)?'
|
||||
=> 'PhortuneCartListController',
|
||||
'(?P<id>\d+)/' => 'PhortuneMerchantViewController',
|
||||
),
|
||||
),
|
||||
|
|
|
@ -12,8 +12,7 @@ abstract class PhortuneCartImplementation {
|
|||
PhabricatorUser $viewer,
|
||||
array $carts);
|
||||
|
||||
abstract public function getName();
|
||||
|
||||
abstract public function getName(PhortuneCart $cart);
|
||||
abstract public function getCancelURI(PhortuneCart $cart);
|
||||
abstract public function getDoneURI(PhortuneCart $cart);
|
||||
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneCartListController
|
||||
extends PhortuneController {
|
||||
|
||||
private $merchantID;
|
||||
private $queryKey;
|
||||
|
||||
private $merchant;
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->merchantID = idx($data, 'merchantID');
|
||||
$this->queryKey = idx($data, 'queryKey');
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
$viewer = $request->getUser();
|
||||
|
||||
$engine = new PhortuneCartSearchEngine();
|
||||
|
||||
if ($this->merchantID) {
|
||||
$merchant = id(new PhortuneMerchantQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($this->merchantID))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$merchant) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$this->merchant = $merchant;
|
||||
$engine->setMerchant($merchant);
|
||||
}
|
||||
|
||||
$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 PhortuneCartSearchEngine())
|
||||
->setViewer($viewer)
|
||||
->addNavigationItems($nav->getMenu());
|
||||
|
||||
$nav->selectFilter(null);
|
||||
|
||||
return $nav;
|
||||
}
|
||||
|
||||
public function buildApplicationCrumbs() {
|
||||
$crumbs = parent::buildApplicationCrumbs();
|
||||
|
||||
$merchant = $this->merchant;
|
||||
if ($merchant) {
|
||||
$id = $merchant->getID();
|
||||
$crumbs->addTextCrumb(
|
||||
$merchant->getName(),
|
||||
$this->getApplicationURI("merchant/{$id}/"));
|
||||
$crumbs->addTextCrumb(
|
||||
pht('Orders'),
|
||||
$this->getApplicationURI("merchant/orders/{$id}/"));
|
||||
}
|
||||
|
||||
return $crumbs;
|
||||
}
|
||||
|
||||
}
|
|
@ -177,6 +177,14 @@ final class PhortuneMerchantViewController
|
|||
->setWorkflow(!$can_edit)
|
||||
->setHref($this->getApplicationURI("merchant/edit/{$id}/")));
|
||||
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('View Orders'))
|
||||
->setIcon('fa-shopping-cart')
|
||||
->setHref($this->getApplicationURI("merchant/orders/{$id}/"))
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ final class PhortuneCartPHIDType extends PhabricatorPHIDType {
|
|||
$cart = $objects[$phid];
|
||||
|
||||
$id = $cart->getID();
|
||||
$name = $cart->getImplementation()->getName();
|
||||
$name = $cart->getName();
|
||||
|
||||
$handle->setName($name);
|
||||
$handle->setURI("/phortune/cart/{$id}/");
|
||||
|
|
|
@ -6,6 +6,7 @@ final class PhortuneCartQuery
|
|||
private $ids;
|
||||
private $phids;
|
||||
private $accountPHIDs;
|
||||
private $merchantPHIDs;
|
||||
private $statuses;
|
||||
|
||||
private $needPurchases;
|
||||
|
@ -25,6 +26,11 @@ final class PhortuneCartQuery
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function withMerchantPHIDs(array $merchant_phids) {
|
||||
$this->merchantPHIDs = $merchant_phids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withStatuses(array $statuses) {
|
||||
$this->statuses = $statuses;
|
||||
return $this;
|
||||
|
@ -145,6 +151,13 @@ final class PhortuneCartQuery
|
|||
$this->accountPHIDs);
|
||||
}
|
||||
|
||||
if ($this->merchantPHIDs !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'cart.merchantPHID IN (%Ls)',
|
||||
$this->merchantPHIDs);
|
||||
}
|
||||
|
||||
if ($this->statuses !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
|
|
167
src/applications/phortune/query/PhortuneCartSearchEngine.php
Normal file
167
src/applications/phortune/query/PhortuneCartSearchEngine.php
Normal file
|
@ -0,0 +1,167 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneCartSearchEngine
|
||||
extends PhabricatorApplicationSearchEngine {
|
||||
|
||||
private $merchant;
|
||||
|
||||
public function setMerchant(PhortuneMerchant $merchant) {
|
||||
$this->merchant = $merchant;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMerchant() {
|
||||
return $this->merchant;
|
||||
}
|
||||
|
||||
public function getResultTypeDescription() {
|
||||
return pht('Phortune Orders');
|
||||
}
|
||||
|
||||
public function buildSavedQueryFromRequest(AphrontRequest $request) {
|
||||
$saved = new PhabricatorSavedQuery();
|
||||
|
||||
return $saved;
|
||||
}
|
||||
|
||||
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
|
||||
$query = id(new PhortuneCartQuery())
|
||||
->needPurchases(true)
|
||||
->withStatuses(
|
||||
array(
|
||||
PhortuneCart::STATUS_PURCHASING,
|
||||
PhortuneCart::STATUS_CHARGED,
|
||||
PhortuneCart::STATUS_PURCHASED,
|
||||
));
|
||||
|
||||
$viewer = $this->requireViewer();
|
||||
|
||||
$merchant = $this->getMerchant();
|
||||
if ($merchant) {
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$merchant,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
if (!$can_edit) {
|
||||
throw new Exception(
|
||||
pht('You can not query orders for a merchant you do not control.'));
|
||||
}
|
||||
$query->withMerchantPHIDs(array($merchant->getPHID()));
|
||||
} else {
|
||||
$accounts = id(new PhortuneAccountQuery())
|
||||
->withMemberPHIDs($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) {
|
||||
$merchant = $this->getMerchant();
|
||||
if ($merchant) {
|
||||
return '/phortune/merchant/'.$merchant->getID().'/order/'.$path;
|
||||
} else {
|
||||
return '/phortune/order/'.$path;
|
||||
}
|
||||
}
|
||||
|
||||
public function getBuiltinQueryNames() {
|
||||
$names = array(
|
||||
'all' => pht('All Orders'),
|
||||
);
|
||||
|
||||
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 $carts,
|
||||
PhabricatorSavedQuery $query) {
|
||||
$phids = array();
|
||||
foreach ($carts as $cart) {
|
||||
$phids[] = $cart->getPHID();
|
||||
$phids[] = $cart->getMerchantPHID();
|
||||
$phids[] = $cart->getAuthorPHID();
|
||||
}
|
||||
return $phids;
|
||||
}
|
||||
|
||||
protected function renderResultList(
|
||||
array $carts,
|
||||
PhabricatorSavedQuery $query,
|
||||
array $handles) {
|
||||
assert_instances_of($carts, 'PhortuneCart');
|
||||
|
||||
$viewer = $this->requireViewer();
|
||||
|
||||
$rows = array();
|
||||
foreach ($carts as $cart) {
|
||||
$merchant = $cart->getMerchant();
|
||||
|
||||
$rows[] = array(
|
||||
$cart->getID(),
|
||||
$handles[$cart->getPHID()]->renderLink(),
|
||||
$handles[$merchant->getPHID()]->renderLink(),
|
||||
$handles[$cart->getAuthorPHID()]->renderLink(),
|
||||
$cart->getTotalPriceAsCurrency()->formatForDisplay(),
|
||||
PhortuneCart::getNameForStatus($cart->getStatus()),
|
||||
phabricator_datetime($cart->getDateModified(), $viewer),
|
||||
);
|
||||
}
|
||||
|
||||
$table = id(new AphrontTableView($rows))
|
||||
->setNoDataString(pht('No orders match the query.'))
|
||||
->setHeaders(
|
||||
array(
|
||||
pht('ID'),
|
||||
pht('Order'),
|
||||
pht('Merchant'),
|
||||
pht('Authorized By'),
|
||||
pht('Amount'),
|
||||
pht('Status'),
|
||||
pht('Updated'),
|
||||
))
|
||||
->setColumnClasses(
|
||||
array(
|
||||
'',
|
||||
'pri',
|
||||
'',
|
||||
'',
|
||||
'wide right',
|
||||
'',
|
||||
'right',
|
||||
));
|
||||
|
||||
$merchant = $this->getMerchant();
|
||||
if ($merchant) {
|
||||
$header = pht('Orders for %s', $merchant->getName());
|
||||
} else {
|
||||
$header = pht('Your Orders');
|
||||
}
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeaderText($header)
|
||||
->appendChild($table);
|
||||
}
|
||||
}
|
|
@ -51,6 +51,20 @@ final class PhortuneCart extends PhortuneDAO
|
|||
return $purchase;
|
||||
}
|
||||
|
||||
public static function getStatusNameMap() {
|
||||
return array(
|
||||
self::STATUS_BUILDING => pht('Building'),
|
||||
self::STATUS_READY => pht('Ready'),
|
||||
self::STATUS_PURCHASING => pht('Purchasing'),
|
||||
self::STATUS_CHARGED => pht('Charged'),
|
||||
self::STATUS_PURCHASED => pht('Purchased'),
|
||||
);
|
||||
}
|
||||
|
||||
public static function getNameForStatus($status) {
|
||||
return idx(self::getStatusNameMap(), $status, $status);
|
||||
}
|
||||
|
||||
public function activateCart() {
|
||||
$this->setStatus(self::STATUS_READY)->save();
|
||||
return $this;
|
||||
|
@ -128,6 +142,9 @@ final class PhortuneCart extends PhortuneDAO
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return $this->getImplementation()->getName($this);
|
||||
}
|
||||
|
||||
public function getDoneURI() {
|
||||
return $this->getImplementation()->getDoneURI($this);
|
||||
|
|
Loading…
Reference in a new issue