@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+293 -4
+4
src/__phutil_library_map__.php
··· 2557 2557 'PhortuneCartCheckoutController' => 'applications/phortune/controller/PhortuneCartCheckoutController.php', 2558 2558 'PhortuneCartController' => 'applications/phortune/controller/PhortuneCartController.php', 2559 2559 'PhortuneCartImplementation' => 'applications/phortune/cart/PhortuneCartImplementation.php', 2560 + 'PhortuneCartListController' => 'applications/phortune/controller/PhortuneCartListController.php', 2560 2561 'PhortuneCartPHIDType' => 'applications/phortune/phid/PhortuneCartPHIDType.php', 2561 2562 'PhortuneCartQuery' => 'applications/phortune/query/PhortuneCartQuery.php', 2563 + 'PhortuneCartSearchEngine' => 'applications/phortune/query/PhortuneCartSearchEngine.php', 2562 2564 'PhortuneCartViewController' => 'applications/phortune/controller/PhortuneCartViewController.php', 2563 2565 'PhortuneCharge' => 'applications/phortune/storage/PhortuneCharge.php', 2564 2566 'PhortuneChargePHIDType' => 'applications/phortune/phid/PhortuneChargePHIDType.php', ··· 5608 5610 ), 5609 5611 'PhortuneCartCheckoutController' => 'PhortuneCartController', 5610 5612 'PhortuneCartController' => 'PhortuneController', 5613 + 'PhortuneCartListController' => 'PhortuneController', 5611 5614 'PhortuneCartPHIDType' => 'PhabricatorPHIDType', 5612 5615 'PhortuneCartQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 5616 + 'PhortuneCartSearchEngine' => 'PhabricatorApplicationSearchEngine', 5613 5617 'PhortuneCartViewController' => 'PhortuneCartController', 5614 5618 'PhortuneCharge' => array( 5615 5619 'PhortuneDAO',
+1 -1
src/applications/fund/phortune/FundBackerCart.php
··· 23 23 return $this->initiative; 24 24 } 25 25 26 - public function getName() { 26 + public function getName(PhortuneCart $cart) { 27 27 return pht('Fund Initiative'); 28 28 } 29 29
+2
src/applications/phortune/application/PhabricatorPhortuneApplication.php
··· 67 67 'merchant/' => array( 68 68 '(?:query/(?P<queryKey>[^/]+)/)?' => 'PhortuneMerchantListController', 69 69 'edit/(?:(?P<id>\d+)/)?' => 'PhortuneMerchantEditController', 70 + 'orders/(?P<merchantID>\d+)/(?:query/(?P<querKey>[^/]+)/)?' 71 + => 'PhortuneCartListController', 70 72 '(?P<id>\d+)/' => 'PhortuneMerchantViewController', 71 73 ), 72 74 ),
+1 -2
src/applications/phortune/cart/PhortuneCartImplementation.php
··· 12 12 PhabricatorUser $viewer, 13 13 array $carts); 14 14 15 - abstract public function getName(); 16 - 15 + abstract public function getName(PhortuneCart $cart); 17 16 abstract public function getCancelURI(PhortuneCart $cart); 18 17 abstract public function getDoneURI(PhortuneCart $cart); 19 18
+79
src/applications/phortune/controller/PhortuneCartListController.php
··· 1 + <?php 2 + 3 + final class PhortuneCartListController 4 + extends PhortuneController { 5 + 6 + private $merchantID; 7 + private $queryKey; 8 + 9 + private $merchant; 10 + 11 + public function willProcessRequest(array $data) { 12 + $this->merchantID = idx($data, 'merchantID'); 13 + $this->queryKey = idx($data, 'queryKey'); 14 + } 15 + 16 + public function processRequest() { 17 + $request = $this->getRequest(); 18 + $viewer = $request->getUser(); 19 + 20 + $engine = new PhortuneCartSearchEngine(); 21 + 22 + if ($this->merchantID) { 23 + $merchant = id(new PhortuneMerchantQuery()) 24 + ->setViewer($viewer) 25 + ->withIDs(array($this->merchantID)) 26 + ->requireCapabilities( 27 + array( 28 + PhabricatorPolicyCapability::CAN_VIEW, 29 + PhabricatorPolicyCapability::CAN_EDIT, 30 + )) 31 + ->executeOne(); 32 + if (!$merchant) { 33 + return new Aphront404Response(); 34 + } 35 + $this->merchant = $merchant; 36 + $engine->setMerchant($merchant); 37 + } 38 + 39 + $controller = id(new PhabricatorApplicationSearchController($request)) 40 + ->setQueryKey($this->queryKey) 41 + ->setSearchEngine($engine) 42 + ->setNavigation($this->buildSideNavView()); 43 + 44 + return $this->delegateToController($controller); 45 + } 46 + 47 + public function buildSideNavView() { 48 + $viewer = $this->getRequest()->getUser(); 49 + 50 + $nav = new AphrontSideNavFilterView(); 51 + $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); 52 + 53 + id(new PhortuneCartSearchEngine()) 54 + ->setViewer($viewer) 55 + ->addNavigationItems($nav->getMenu()); 56 + 57 + $nav->selectFilter(null); 58 + 59 + return $nav; 60 + } 61 + 62 + public function buildApplicationCrumbs() { 63 + $crumbs = parent::buildApplicationCrumbs(); 64 + 65 + $merchant = $this->merchant; 66 + if ($merchant) { 67 + $id = $merchant->getID(); 68 + $crumbs->addTextCrumb( 69 + $merchant->getName(), 70 + $this->getApplicationURI("merchant/{$id}/")); 71 + $crumbs->addTextCrumb( 72 + pht('Orders'), 73 + $this->getApplicationURI("merchant/orders/{$id}/")); 74 + } 75 + 76 + return $crumbs; 77 + } 78 + 79 + }
+8
src/applications/phortune/controller/PhortuneMerchantViewController.php
··· 177 177 ->setWorkflow(!$can_edit) 178 178 ->setHref($this->getApplicationURI("merchant/edit/{$id}/"))); 179 179 180 + $view->addAction( 181 + id(new PhabricatorActionView()) 182 + ->setName(pht('View Orders')) 183 + ->setIcon('fa-shopping-cart') 184 + ->setHref($this->getApplicationURI("merchant/orders/{$id}/")) 185 + ->setDisabled(!$can_edit) 186 + ->setWorkflow(!$can_edit)); 187 + 180 188 return $view; 181 189 } 182 190
+1 -1
src/applications/phortune/phid/PhortuneCartPHIDType.php
··· 29 29 $cart = $objects[$phid]; 30 30 31 31 $id = $cart->getID(); 32 - $name = $cart->getImplementation()->getName(); 32 + $name = $cart->getName(); 33 33 34 34 $handle->setName($name); 35 35 $handle->setURI("/phortune/cart/{$id}/");
+13
src/applications/phortune/query/PhortuneCartQuery.php
··· 6 6 private $ids; 7 7 private $phids; 8 8 private $accountPHIDs; 9 + private $merchantPHIDs; 9 10 private $statuses; 10 11 11 12 private $needPurchases; ··· 22 23 23 24 public function withAccountPHIDs(array $account_phids) { 24 25 $this->accountPHIDs = $account_phids; 26 + return $this; 27 + } 28 + 29 + public function withMerchantPHIDs(array $merchant_phids) { 30 + $this->merchantPHIDs = $merchant_phids; 25 31 return $this; 26 32 } 27 33 ··· 143 149 $conn, 144 150 'cart.accountPHID IN (%Ls)', 145 151 $this->accountPHIDs); 152 + } 153 + 154 + if ($this->merchantPHIDs !== null) { 155 + $where[] = qsprintf( 156 + $conn, 157 + 'cart.merchantPHID IN (%Ls)', 158 + $this->merchantPHIDs); 146 159 } 147 160 148 161 if ($this->statuses !== null) {
+167
src/applications/phortune/query/PhortuneCartSearchEngine.php
··· 1 + <?php 2 + 3 + final class PhortuneCartSearchEngine 4 + extends PhabricatorApplicationSearchEngine { 5 + 6 + private $merchant; 7 + 8 + public function setMerchant(PhortuneMerchant $merchant) { 9 + $this->merchant = $merchant; 10 + return $this; 11 + } 12 + 13 + public function getMerchant() { 14 + return $this->merchant; 15 + } 16 + 17 + public function getResultTypeDescription() { 18 + return pht('Phortune Orders'); 19 + } 20 + 21 + public function buildSavedQueryFromRequest(AphrontRequest $request) { 22 + $saved = new PhabricatorSavedQuery(); 23 + 24 + return $saved; 25 + } 26 + 27 + public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { 28 + $query = id(new PhortuneCartQuery()) 29 + ->needPurchases(true) 30 + ->withStatuses( 31 + array( 32 + PhortuneCart::STATUS_PURCHASING, 33 + PhortuneCart::STATUS_CHARGED, 34 + PhortuneCart::STATUS_PURCHASED, 35 + )); 36 + 37 + $viewer = $this->requireViewer(); 38 + 39 + $merchant = $this->getMerchant(); 40 + if ($merchant) { 41 + $can_edit = PhabricatorPolicyFilter::hasCapability( 42 + $viewer, 43 + $merchant, 44 + PhabricatorPolicyCapability::CAN_EDIT); 45 + if (!$can_edit) { 46 + throw new Exception( 47 + pht('You can not query orders for a merchant you do not control.')); 48 + } 49 + $query->withMerchantPHIDs(array($merchant->getPHID())); 50 + } else { 51 + $accounts = id(new PhortuneAccountQuery()) 52 + ->withMemberPHIDs($viewer->getPHID()) 53 + ->execute(); 54 + if ($accounts) { 55 + $query->withAccountPHIDs(mpull($accounts, 'getPHID')); 56 + } else { 57 + throw new Exception(pht('You have no accounts!')); 58 + } 59 + } 60 + 61 + return $query; 62 + } 63 + 64 + public function buildSearchForm( 65 + AphrontFormView $form, 66 + PhabricatorSavedQuery $saved_query) {} 67 + 68 + protected function getURI($path) { 69 + $merchant = $this->getMerchant(); 70 + if ($merchant) { 71 + return '/phortune/merchant/'.$merchant->getID().'/order/'.$path; 72 + } else { 73 + return '/phortune/order/'.$path; 74 + } 75 + } 76 + 77 + public function getBuiltinQueryNames() { 78 + $names = array( 79 + 'all' => pht('All Orders'), 80 + ); 81 + 82 + return $names; 83 + } 84 + 85 + public function buildSavedQueryFromBuiltin($query_key) { 86 + 87 + $query = $this->newSavedQuery(); 88 + $query->setQueryKey($query_key); 89 + 90 + switch ($query_key) { 91 + case 'all': 92 + return $query; 93 + } 94 + 95 + return parent::buildSavedQueryFromBuiltin($query_key); 96 + } 97 + 98 + protected function getRequiredHandlePHIDsForResultList( 99 + array $carts, 100 + PhabricatorSavedQuery $query) { 101 + $phids = array(); 102 + foreach ($carts as $cart) { 103 + $phids[] = $cart->getPHID(); 104 + $phids[] = $cart->getMerchantPHID(); 105 + $phids[] = $cart->getAuthorPHID(); 106 + } 107 + return $phids; 108 + } 109 + 110 + protected function renderResultList( 111 + array $carts, 112 + PhabricatorSavedQuery $query, 113 + array $handles) { 114 + assert_instances_of($carts, 'PhortuneCart'); 115 + 116 + $viewer = $this->requireViewer(); 117 + 118 + $rows = array(); 119 + foreach ($carts as $cart) { 120 + $merchant = $cart->getMerchant(); 121 + 122 + $rows[] = array( 123 + $cart->getID(), 124 + $handles[$cart->getPHID()]->renderLink(), 125 + $handles[$merchant->getPHID()]->renderLink(), 126 + $handles[$cart->getAuthorPHID()]->renderLink(), 127 + $cart->getTotalPriceAsCurrency()->formatForDisplay(), 128 + PhortuneCart::getNameForStatus($cart->getStatus()), 129 + phabricator_datetime($cart->getDateModified(), $viewer), 130 + ); 131 + } 132 + 133 + $table = id(new AphrontTableView($rows)) 134 + ->setNoDataString(pht('No orders match the query.')) 135 + ->setHeaders( 136 + array( 137 + pht('ID'), 138 + pht('Order'), 139 + pht('Merchant'), 140 + pht('Authorized By'), 141 + pht('Amount'), 142 + pht('Status'), 143 + pht('Updated'), 144 + )) 145 + ->setColumnClasses( 146 + array( 147 + '', 148 + 'pri', 149 + '', 150 + '', 151 + 'wide right', 152 + '', 153 + 'right', 154 + )); 155 + 156 + $merchant = $this->getMerchant(); 157 + if ($merchant) { 158 + $header = pht('Orders for %s', $merchant->getName()); 159 + } else { 160 + $header = pht('Your Orders'); 161 + } 162 + 163 + return id(new PHUIObjectBoxView()) 164 + ->setHeaderText($header) 165 + ->appendChild($table); 166 + } 167 + }
+17
src/applications/phortune/storage/PhortuneCart.php
··· 51 51 return $purchase; 52 52 } 53 53 54 + public static function getStatusNameMap() { 55 + return array( 56 + self::STATUS_BUILDING => pht('Building'), 57 + self::STATUS_READY => pht('Ready'), 58 + self::STATUS_PURCHASING => pht('Purchasing'), 59 + self::STATUS_CHARGED => pht('Charged'), 60 + self::STATUS_PURCHASED => pht('Purchased'), 61 + ); 62 + } 63 + 64 + public static function getNameForStatus($status) { 65 + return idx(self::getStatusNameMap(), $status, $status); 66 + } 67 + 54 68 public function activateCart() { 55 69 $this->setStatus(self::STATUS_READY)->save(); 56 70 return $this; ··· 128 142 return $this; 129 143 } 130 144 145 + public function getName() { 146 + return $this->getImplementation()->getName($this); 147 + } 131 148 132 149 public function getDoneURI() { 133 150 return $this->getImplementation()->getDoneURI($this);