mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-30 01:10:58 +01:00
Build a very basic subscription detail page in Phortune
Summary: Ref T6881. - Add a subscription detail page. Minor cosmetics: - Fix glyph, from "X" (old "X marks the spot" icon) to "diamond" (new gem icon). - Name the initial account "Default Account" instead of "Personal Account", since this seems more general. Test Plan: {F278623} And I got two full days to test that Jan 30/31 -> Feb 28 billing logic! Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T6881 Differential Revision: https://secure.phabricator.com/D11576
This commit is contained in:
parent
4adc2d8a72
commit
a65244c449
12 changed files with 164 additions and 17 deletions
|
@ -2815,6 +2815,7 @@ phutil_register_library_map(array(
|
||||||
'PhortuneSubscriptionQuery' => 'applications/phortune/query/PhortuneSubscriptionQuery.php',
|
'PhortuneSubscriptionQuery' => 'applications/phortune/query/PhortuneSubscriptionQuery.php',
|
||||||
'PhortuneSubscriptionSearchEngine' => 'applications/phortune/query/PhortuneSubscriptionSearchEngine.php',
|
'PhortuneSubscriptionSearchEngine' => 'applications/phortune/query/PhortuneSubscriptionSearchEngine.php',
|
||||||
'PhortuneSubscriptionTableView' => 'applications/phortune/view/PhortuneSubscriptionTableView.php',
|
'PhortuneSubscriptionTableView' => 'applications/phortune/view/PhortuneSubscriptionTableView.php',
|
||||||
|
'PhortuneSubscriptionViewController' => 'applications/phortune/controller/PhortuneSubscriptionViewController.php',
|
||||||
'PhortuneTestPaymentProvider' => 'applications/phortune/provider/PhortuneTestPaymentProvider.php',
|
'PhortuneTestPaymentProvider' => 'applications/phortune/provider/PhortuneTestPaymentProvider.php',
|
||||||
'PhortuneWePayPaymentProvider' => 'applications/phortune/provider/PhortuneWePayPaymentProvider.php',
|
'PhortuneWePayPaymentProvider' => 'applications/phortune/provider/PhortuneWePayPaymentProvider.php',
|
||||||
'PhragmentBrowseController' => 'applications/phragment/controller/PhragmentBrowseController.php',
|
'PhragmentBrowseController' => 'applications/phragment/controller/PhragmentBrowseController.php',
|
||||||
|
@ -6168,6 +6169,7 @@ phutil_register_library_map(array(
|
||||||
'PhortuneSubscriptionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhortuneSubscriptionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
'PhortuneSubscriptionSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
'PhortuneSubscriptionSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||||
'PhortuneSubscriptionTableView' => 'AphrontView',
|
'PhortuneSubscriptionTableView' => 'AphrontView',
|
||||||
|
'PhortuneSubscriptionViewController' => 'PhortuneController',
|
||||||
'PhortuneTestPaymentProvider' => 'PhortunePaymentProvider',
|
'PhortuneTestPaymentProvider' => 'PhortunePaymentProvider',
|
||||||
'PhortuneWePayPaymentProvider' => 'PhortunePaymentProvider',
|
'PhortuneWePayPaymentProvider' => 'PhortunePaymentProvider',
|
||||||
'PhragmentBrowseController' => 'PhragmentController',
|
'PhragmentBrowseController' => 'PhragmentController',
|
||||||
|
|
|
@ -23,7 +23,7 @@ final class PhabricatorPhortuneApplication extends PhabricatorApplication {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTitleGlyph() {
|
public function getTitleGlyph() {
|
||||||
return "\xE2\x9C\x98";
|
return "\xE2\x97\x87";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getApplicationGroup() {
|
public function getApplicationGroup() {
|
||||||
|
@ -45,8 +45,12 @@ final class PhabricatorPhortuneApplication extends PhabricatorApplication {
|
||||||
),
|
),
|
||||||
'order/(?:query/(?P<queryKey>[^/]+)/)?'
|
'order/(?:query/(?P<queryKey>[^/]+)/)?'
|
||||||
=> 'PhortuneCartListController',
|
=> 'PhortuneCartListController',
|
||||||
'subscription/(?:query/(?P<queryKey>[^/]+)/)?'
|
'subscription/' => array(
|
||||||
|
'(?:query/(?P<queryKey>[^/]+)/)?'
|
||||||
=> 'PhortuneSubscriptionListController',
|
=> 'PhortuneSubscriptionListController',
|
||||||
|
'view/(?P<id>\d+)/'
|
||||||
|
=> 'PhortuneSubscriptionViewController',
|
||||||
|
),
|
||||||
'charge/(?:query/(?P<queryKey>[^/]+)/)?'
|
'charge/(?:query/(?P<queryKey>[^/]+)/)?'
|
||||||
=> 'PhortuneChargeListController',
|
=> 'PhortuneChargeListController',
|
||||||
),
|
),
|
||||||
|
@ -81,8 +85,12 @@ final class PhabricatorPhortuneApplication extends PhabricatorApplication {
|
||||||
'edit/(?:(?P<id>\d+)/)?' => 'PhortuneMerchantEditController',
|
'edit/(?:(?P<id>\d+)/)?' => 'PhortuneMerchantEditController',
|
||||||
'orders/(?P<merchantID>\d+)/(?:query/(?P<queryKey>[^/]+)/)?'
|
'orders/(?P<merchantID>\d+)/(?:query/(?P<queryKey>[^/]+)/)?'
|
||||||
=> 'PhortuneCartListController',
|
=> 'PhortuneCartListController',
|
||||||
'subscription/(?P<merchantID>\d+)/(?:query/(?P<queryKey>[^/]+)/)?'
|
'(?P<merchantID>\d+)/subscription/' => array(
|
||||||
|
'(?:query/(?P<queryKey>[^/]+)/)?'
|
||||||
=> 'PhortuneSubscriptionListController',
|
=> 'PhortuneSubscriptionListController',
|
||||||
|
'view/(?P<id>\d+)/'
|
||||||
|
=> 'PhortuneSubscriptionViewController',
|
||||||
|
),
|
||||||
'(?P<id>\d+)/' => 'PhortuneMerchantViewController',
|
'(?P<id>\d+)/' => 'PhortuneMerchantViewController',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -35,9 +35,7 @@ final class PhortuneAccountViewController extends PhortuneController {
|
||||||
$title = $account->getName();
|
$title = $account->getName();
|
||||||
|
|
||||||
$crumbs = $this->buildApplicationCrumbs();
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
$crumbs->addTextCrumb(
|
$this->addAccountCrumb($crumbs, $account, $link = false);
|
||||||
$account->getName(),
|
|
||||||
$request->getRequestURI());
|
|
||||||
|
|
||||||
$header = id(new PHUIHeaderView())
|
$header = id(new PHUIHeaderView())
|
||||||
->setHeader($title);
|
->setHeader($title);
|
||||||
|
|
|
@ -7,7 +7,7 @@ abstract class PhortuneController extends PhabricatorController {
|
||||||
PhortuneAccount $account,
|
PhortuneAccount $account,
|
||||||
$link = true) {
|
$link = true) {
|
||||||
|
|
||||||
$name = pht('Account');
|
$name = $account->getName();
|
||||||
$href = null;
|
$href = null;
|
||||||
|
|
||||||
if ($link) {
|
if ($link) {
|
||||||
|
@ -18,6 +18,26 @@ abstract class PhortuneController extends PhabricatorController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function addMerchantCrumb(
|
||||||
|
$crumbs,
|
||||||
|
PhortuneMerchant $merchant,
|
||||||
|
$link = true) {
|
||||||
|
|
||||||
|
$name = $merchant->getName();
|
||||||
|
$href = null;
|
||||||
|
|
||||||
|
$crumbs->addTextCrumb(
|
||||||
|
pht('Merchants'),
|
||||||
|
$this->getApplicationURI('merchant/'));
|
||||||
|
|
||||||
|
if ($link) {
|
||||||
|
$href = $this->getApplicationURI('merchant/'.$merchant->getID().'/');
|
||||||
|
$crumbs->addTextCrumb($name, $href);
|
||||||
|
} else {
|
||||||
|
$crumbs->addTextCrumb($name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private function loadEnabledProvidersForMerchant(PhortuneMerchant $merchant) {
|
private function loadEnabledProvidersForMerchant(PhortuneMerchant $merchant) {
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getRequest()->getUser();
|
||||||
|
|
||||||
|
|
|
@ -190,7 +190,7 @@ final class PhortuneMerchantViewController
|
||||||
id(new PhabricatorActionView())
|
id(new PhabricatorActionView())
|
||||||
->setName(pht('View Subscriptions'))
|
->setName(pht('View Subscriptions'))
|
||||||
->setIcon('fa-moon-o')
|
->setIcon('fa-moon-o')
|
||||||
->setHref($this->getApplicationURI("merchant/subscription/{$id}/"))
|
->setHref($this->getApplicationURI("merchant/{$id}/subscription/"))
|
||||||
->setDisabled(!$can_edit)
|
->setDisabled(!$can_edit)
|
||||||
->setWorkflow(!$can_edit));
|
->setWorkflow(!$can_edit));
|
||||||
|
|
||||||
|
|
|
@ -85,9 +85,7 @@ final class PhortuneSubscriptionListController
|
||||||
$merchant = $this->merchant;
|
$merchant = $this->merchant;
|
||||||
if ($merchant) {
|
if ($merchant) {
|
||||||
$id = $merchant->getID();
|
$id = $merchant->getID();
|
||||||
$crumbs->addTextCrumb(
|
$this->addMerchantCrumb($crumbs, $merchant);
|
||||||
$merchant->getName(),
|
|
||||||
$this->getApplicationURI("merchant/{$id}/"));
|
|
||||||
$crumbs->addTextCrumb(
|
$crumbs->addTextCrumb(
|
||||||
pht('Subscriptions'),
|
pht('Subscriptions'),
|
||||||
$this->getApplicationURI("merchant/subscriptions/{$id}/"));
|
$this->getApplicationURI("merchant/subscriptions/{$id}/"));
|
||||||
|
@ -96,9 +94,7 @@ final class PhortuneSubscriptionListController
|
||||||
$account = $this->account;
|
$account = $this->account;
|
||||||
if ($account) {
|
if ($account) {
|
||||||
$id = $account->getID();
|
$id = $account->getID();
|
||||||
$crumbs->addTextCrumb(
|
$this->addAccountCrumb($crumbs, $account);
|
||||||
$account->getName(),
|
|
||||||
$this->getApplicationURI("{$id}/"));
|
|
||||||
$crumbs->addTextCrumb(
|
$crumbs->addTextCrumb(
|
||||||
pht('Subscriptions'),
|
pht('Subscriptions'),
|
||||||
$this->getApplicationURI("{$id}/subscription/"));
|
$this->getApplicationURI("{$id}/subscription/"));
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhortuneSubscriptionViewController extends PhortuneController {
|
||||||
|
|
||||||
|
public function handleRequest(AphrontRequest $request) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
$subscription = id(new PhortuneSubscriptionQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withIDs(array($request->getURIData('id')))
|
||||||
|
->needTriggers(true)
|
||||||
|
->executeOne();
|
||||||
|
if (!$subscription) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
$is_merchant = (bool)$request->getURIData('merchantID');
|
||||||
|
|
||||||
|
$title = pht('Subscription: %s', $subscription->getSubscriptionName());
|
||||||
|
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setHeader($subscription->getSubscriptionName());
|
||||||
|
|
||||||
|
$actions = id(new PhabricatorActionListView())
|
||||||
|
->setUser($viewer)
|
||||||
|
->setObjectURI($request->getRequestURI());
|
||||||
|
|
||||||
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
|
if ($is_merchant) {
|
||||||
|
$this->addMerchantCrumb($crumbs, $subscription->getMerchant());
|
||||||
|
} else {
|
||||||
|
$this->addAccountCrumb($crumbs, $subscription->getAccount());
|
||||||
|
}
|
||||||
|
$crumbs->addTextCrumb(pht('Subscription %d', $subscription->getID()));
|
||||||
|
|
||||||
|
$properties = id(new PHUIPropertyListView())
|
||||||
|
->setUser($viewer)
|
||||||
|
->setActionList($actions);
|
||||||
|
|
||||||
|
$next_invoice = $subscription->getTrigger()->getNextEventPrediction();
|
||||||
|
$properties->addProperty(
|
||||||
|
pht('Next Invoice'),
|
||||||
|
phabricator_datetime($next_invoice, $viewer));
|
||||||
|
|
||||||
|
$object_box = id(new PHUIObjectBoxView())
|
||||||
|
->setHeader($header)
|
||||||
|
->addPropertyList($properties);
|
||||||
|
|
||||||
|
return $this->buildApplicationPage(
|
||||||
|
array(
|
||||||
|
$crumbs,
|
||||||
|
$object_box,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'title' => $title,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -9,6 +9,8 @@ final class PhortuneSubscriptionQuery
|
||||||
private $merchantPHIDs;
|
private $merchantPHIDs;
|
||||||
private $statuses;
|
private $statuses;
|
||||||
|
|
||||||
|
private $needTriggers;
|
||||||
|
|
||||||
public function withIDs(array $ids) {
|
public function withIDs(array $ids) {
|
||||||
$this->ids = $ids;
|
$this->ids = $ids;
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -34,6 +36,11 @@ final class PhortuneSubscriptionQuery
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function needTriggers($need_triggers) {
|
||||||
|
$this->needTriggers = $need_triggers;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
protected function loadPage() {
|
protected function loadPage() {
|
||||||
$table = new PhortuneSubscription();
|
$table = new PhortuneSubscription();
|
||||||
$conn = $table->establishConnection('r');
|
$conn = $table->establishConnection('r');
|
||||||
|
@ -102,6 +109,24 @@ final class PhortuneSubscriptionQuery
|
||||||
$subscription->attachImplementation($implementation);
|
$subscription->attachImplementation($implementation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->needTriggers) {
|
||||||
|
$trigger_phids = mpull($subscriptions, 'getTriggerPHID');
|
||||||
|
$triggers = id(new PhabricatorWorkerTriggerQuery())
|
||||||
|
->setViewer($this->getViewer())
|
||||||
|
->withPHIDs($trigger_phids)
|
||||||
|
->needEvents(true)
|
||||||
|
->execute();
|
||||||
|
$triggers = mpull($triggers, null, 'getPHID');
|
||||||
|
foreach ($subscriptions as $key => $subscription) {
|
||||||
|
$trigger = idx($triggers, $subscription->getTriggerPHID());
|
||||||
|
if (!$trigger) {
|
||||||
|
unset($subscriptions[$key]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$subscription->attachTrigger($trigger);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $subscriptions;
|
return $subscriptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -144,6 +144,7 @@ final class PhortuneSubscriptionSearchEngine
|
||||||
$merchant = $this->getMerchant();
|
$merchant = $this->getMerchant();
|
||||||
if ($merchant) {
|
if ($merchant) {
|
||||||
$header = pht('Subscriptions for %s', $merchant->getName());
|
$header = pht('Subscriptions for %s', $merchant->getName());
|
||||||
|
$table->setIsMerchantView(true);
|
||||||
} else {
|
} else {
|
||||||
$header = pht('Your Subscriptions');
|
$header = pht('Your Subscriptions');
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ final class PhortuneAccount extends PhortuneDAO
|
||||||
$xactions = array();
|
$xactions = array();
|
||||||
$xactions[] = id(new PhortuneAccountTransaction())
|
$xactions[] = id(new PhortuneAccountTransaction())
|
||||||
->setTransactionType(PhortuneAccountTransaction::TYPE_NAME)
|
->setTransactionType(PhortuneAccountTransaction::TYPE_NAME)
|
||||||
->setNewValue(pht('Personal Account'));
|
->setNewValue(pht('Default Account'));
|
||||||
|
|
||||||
$xactions[] = id(new PhortuneAccountTransaction())
|
$xactions[] = id(new PhortuneAccountTransaction())
|
||||||
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
|
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
|
||||||
|
|
|
@ -153,6 +153,7 @@ final class PhortuneSubscription extends PhortuneDAO
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
$trigger->setPHID($trigger_phid);
|
||||||
$trigger->setAction($trigger_action);
|
$trigger->setAction($trigger_action);
|
||||||
$trigger->save();
|
$trigger->save();
|
||||||
}
|
}
|
||||||
|
@ -165,6 +166,19 @@ final class PhortuneSubscription extends PhortuneDAO
|
||||||
return $this->getImplementation()->getName($this);
|
return $this->getImplementation()->getName($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getURI() {
|
||||||
|
$account_id = $this->getAccount()->getID();
|
||||||
|
$id = $this->getID();
|
||||||
|
|
||||||
|
return "/phortune/{$account_id}/subscription/view/{$id}/";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMerchantURI() {
|
||||||
|
$merchant_id = $this->getMerchant()->getID();
|
||||||
|
$id = $this->getID();
|
||||||
|
return "/phortune/merchant/{$merchant_id}/subscription/view/{$id}/";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ final class PhortuneSubscriptionTableView extends AphrontView {
|
||||||
|
|
||||||
private $subscriptions;
|
private $subscriptions;
|
||||||
private $handles;
|
private $handles;
|
||||||
|
private $isMerchantView;
|
||||||
|
|
||||||
public function setHandles(array $handles) {
|
public function setHandles(array $handles) {
|
||||||
$this->handles = $handles;
|
$this->handles = $handles;
|
||||||
|
@ -23,6 +24,15 @@ final class PhortuneSubscriptionTableView extends AphrontView {
|
||||||
return $this->subscriptions;
|
return $this->subscriptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setIsMerchantView($is_merchant_view) {
|
||||||
|
$this->isMerchantView = $is_merchant_view;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIsMerchantView() {
|
||||||
|
return $this->isMerchantView;
|
||||||
|
}
|
||||||
|
|
||||||
public function render() {
|
public function render() {
|
||||||
$subscriptions = $this->getSubscriptions();
|
$subscriptions = $this->getSubscriptions();
|
||||||
$handles = $this->getHandles();
|
$handles = $this->getHandles();
|
||||||
|
@ -31,9 +41,21 @@ final class PhortuneSubscriptionTableView extends AphrontView {
|
||||||
$rows = array();
|
$rows = array();
|
||||||
$rowc = array();
|
$rowc = array();
|
||||||
foreach ($subscriptions as $subscription) {
|
foreach ($subscriptions as $subscription) {
|
||||||
|
if ($this->getIsMerchantView()) {
|
||||||
|
$uri = $subscription->getMerchantURI();
|
||||||
|
} else {
|
||||||
|
$uri = $subscription->getURI();
|
||||||
|
}
|
||||||
|
|
||||||
$subscription_link = $handles[$subscription->getPHID()]->renderLink();
|
$subscription_link = $handles[$subscription->getPHID()]->renderLink();
|
||||||
$rows[] = array(
|
$rows[] = array(
|
||||||
$subscription->getID(),
|
$subscription->getID(),
|
||||||
|
phutil_tag(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => $uri,
|
||||||
|
),
|
||||||
|
$subscription->getSubscriptionName()),
|
||||||
phabricator_datetime($subscription->getDateCreated(), $viewer),
|
phabricator_datetime($subscription->getDateCreated(), $viewer),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -42,11 +64,13 @@ final class PhortuneSubscriptionTableView extends AphrontView {
|
||||||
->setHeaders(
|
->setHeaders(
|
||||||
array(
|
array(
|
||||||
pht('ID'),
|
pht('ID'),
|
||||||
|
pht('Name'),
|
||||||
pht('Created'),
|
pht('Created'),
|
||||||
))
|
))
|
||||||
->setColumnClasses(
|
->setColumnClasses(
|
||||||
array(
|
array(
|
||||||
'',
|
'',
|
||||||
|
'wide',
|
||||||
'right',
|
'right',
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue