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',
|
'PhortuneCartCheckoutController' => 'applications/phortune/controller/PhortuneCartCheckoutController.php',
|
||||||
'PhortuneCartController' => 'applications/phortune/controller/PhortuneCartController.php',
|
'PhortuneCartController' => 'applications/phortune/controller/PhortuneCartController.php',
|
||||||
'PhortuneCartImplementation' => 'applications/phortune/cart/PhortuneCartImplementation.php',
|
'PhortuneCartImplementation' => 'applications/phortune/cart/PhortuneCartImplementation.php',
|
||||||
|
'PhortuneCartListController' => 'applications/phortune/controller/PhortuneCartListController.php',
|
||||||
'PhortuneCartPHIDType' => 'applications/phortune/phid/PhortuneCartPHIDType.php',
|
'PhortuneCartPHIDType' => 'applications/phortune/phid/PhortuneCartPHIDType.php',
|
||||||
'PhortuneCartQuery' => 'applications/phortune/query/PhortuneCartQuery.php',
|
'PhortuneCartQuery' => 'applications/phortune/query/PhortuneCartQuery.php',
|
||||||
|
'PhortuneCartSearchEngine' => 'applications/phortune/query/PhortuneCartSearchEngine.php',
|
||||||
'PhortuneCartViewController' => 'applications/phortune/controller/PhortuneCartViewController.php',
|
'PhortuneCartViewController' => 'applications/phortune/controller/PhortuneCartViewController.php',
|
||||||
'PhortuneCharge' => 'applications/phortune/storage/PhortuneCharge.php',
|
'PhortuneCharge' => 'applications/phortune/storage/PhortuneCharge.php',
|
||||||
'PhortuneChargePHIDType' => 'applications/phortune/phid/PhortuneChargePHIDType.php',
|
'PhortuneChargePHIDType' => 'applications/phortune/phid/PhortuneChargePHIDType.php',
|
||||||
|
@ -5608,8 +5610,10 @@ phutil_register_library_map(array(
|
||||||
),
|
),
|
||||||
'PhortuneCartCheckoutController' => 'PhortuneCartController',
|
'PhortuneCartCheckoutController' => 'PhortuneCartController',
|
||||||
'PhortuneCartController' => 'PhortuneController',
|
'PhortuneCartController' => 'PhortuneController',
|
||||||
|
'PhortuneCartListController' => 'PhortuneController',
|
||||||
'PhortuneCartPHIDType' => 'PhabricatorPHIDType',
|
'PhortuneCartPHIDType' => 'PhabricatorPHIDType',
|
||||||
'PhortuneCartQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhortuneCartQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
|
'PhortuneCartSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||||
'PhortuneCartViewController' => 'PhortuneCartController',
|
'PhortuneCartViewController' => 'PhortuneCartController',
|
||||||
'PhortuneCharge' => array(
|
'PhortuneCharge' => array(
|
||||||
'PhortuneDAO',
|
'PhortuneDAO',
|
||||||
|
|
|
@ -23,7 +23,7 @@ final class FundBackerCart extends PhortuneCartImplementation {
|
||||||
return $this->initiative;
|
return $this->initiative;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getName() {
|
public function getName(PhortuneCart $cart) {
|
||||||
return pht('Fund Initiative');
|
return pht('Fund Initiative');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,8 @@ final class PhabricatorPhortuneApplication extends PhabricatorApplication {
|
||||||
'merchant/' => array(
|
'merchant/' => array(
|
||||||
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PhortuneMerchantListController',
|
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PhortuneMerchantListController',
|
||||||
'edit/(?:(?P<id>\d+)/)?' => 'PhortuneMerchantEditController',
|
'edit/(?:(?P<id>\d+)/)?' => 'PhortuneMerchantEditController',
|
||||||
|
'orders/(?P<merchantID>\d+)/(?:query/(?P<querKey>[^/]+)/)?'
|
||||||
|
=> 'PhortuneCartListController',
|
||||||
'(?P<id>\d+)/' => 'PhortuneMerchantViewController',
|
'(?P<id>\d+)/' => 'PhortuneMerchantViewController',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -12,8 +12,7 @@ abstract class PhortuneCartImplementation {
|
||||||
PhabricatorUser $viewer,
|
PhabricatorUser $viewer,
|
||||||
array $carts);
|
array $carts);
|
||||||
|
|
||||||
abstract public function getName();
|
abstract public function getName(PhortuneCart $cart);
|
||||||
|
|
||||||
abstract public function getCancelURI(PhortuneCart $cart);
|
abstract public function getCancelURI(PhortuneCart $cart);
|
||||||
abstract public function getDoneURI(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)
|
->setWorkflow(!$can_edit)
|
||||||
->setHref($this->getApplicationURI("merchant/edit/{$id}/")));
|
->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;
|
return $view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ final class PhortuneCartPHIDType extends PhabricatorPHIDType {
|
||||||
$cart = $objects[$phid];
|
$cart = $objects[$phid];
|
||||||
|
|
||||||
$id = $cart->getID();
|
$id = $cart->getID();
|
||||||
$name = $cart->getImplementation()->getName();
|
$name = $cart->getName();
|
||||||
|
|
||||||
$handle->setName($name);
|
$handle->setName($name);
|
||||||
$handle->setURI("/phortune/cart/{$id}/");
|
$handle->setURI("/phortune/cart/{$id}/");
|
||||||
|
|
|
@ -6,6 +6,7 @@ final class PhortuneCartQuery
|
||||||
private $ids;
|
private $ids;
|
||||||
private $phids;
|
private $phids;
|
||||||
private $accountPHIDs;
|
private $accountPHIDs;
|
||||||
|
private $merchantPHIDs;
|
||||||
private $statuses;
|
private $statuses;
|
||||||
|
|
||||||
private $needPurchases;
|
private $needPurchases;
|
||||||
|
@ -25,6 +26,11 @@ final class PhortuneCartQuery
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function withMerchantPHIDs(array $merchant_phids) {
|
||||||
|
$this->merchantPHIDs = $merchant_phids;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function withStatuses(array $statuses) {
|
public function withStatuses(array $statuses) {
|
||||||
$this->statuses = $statuses;
|
$this->statuses = $statuses;
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -145,6 +151,13 @@ final class PhortuneCartQuery
|
||||||
$this->accountPHIDs);
|
$this->accountPHIDs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->merchantPHIDs !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'cart.merchantPHID IN (%Ls)',
|
||||||
|
$this->merchantPHIDs);
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->statuses !== null) {
|
if ($this->statuses !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn,
|
$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;
|
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() {
|
public function activateCart() {
|
||||||
$this->setStatus(self::STATUS_READY)->save();
|
$this->setStatus(self::STATUS_READY)->save();
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -128,6 +142,9 @@ final class PhortuneCart extends PhortuneDAO
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getName() {
|
||||||
|
return $this->getImplementation()->getName($this);
|
||||||
|
}
|
||||||
|
|
||||||
public function getDoneURI() {
|
public function getDoneURI() {
|
||||||
return $this->getImplementation()->getDoneURI($this);
|
return $this->getImplementation()->getDoneURI($this);
|
||||||
|
|
Loading…
Reference in a new issue