From cd7547dc5760bd0fde42f38118dcb9af3ddc17a0 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Tue, 11 Apr 2017 16:51:02 -0700 Subject: [PATCH] Update UI for PhortuneAccount Summary: Primarily, this splits individual sections of the single account page into a more managable and robust sidenav for subscriptions, billing, and managers. The functionality on the subpages is light, but I expect to build on then in coming diffs. This also starts building out a more effective "status" area on the lead page. Test Plan: - Load up default account - Make some edits - Click on each of the new navigation items - Verify links to "see all" work - Test overdue and no payment states for status {F4337317} Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D17589 --- src/__phutil_library_map__.php | 12 +- .../PhabricatorPhortuneApplication.php | 10 + .../PhortuneAccountAddManagerController.php | 75 ++++++ .../PhortuneAccountBillingController.php | 178 ++++++++++++++ .../PhortuneAccountManagerController.php | 101 ++++++++ .../PhortuneAccountProfileController.php | 84 +++++++ .../PhortuneAccountSubscriptionController.php | 79 ++++++ .../account/PhortuneAccountViewController.php | 228 +++--------------- .../phortune/view/PhortuneChargeTableView.php | 1 + 9 files changed, 574 insertions(+), 194 deletions(-) create mode 100644 src/applications/phortune/controller/account/PhortuneAccountAddManagerController.php create mode 100644 src/applications/phortune/controller/account/PhortuneAccountBillingController.php create mode 100644 src/applications/phortune/controller/account/PhortuneAccountManagerController.php create mode 100644 src/applications/phortune/controller/account/PhortuneAccountProfileController.php create mode 100644 src/applications/phortune/controller/account/PhortuneAccountSubscriptionController.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index cd37164ba2..91ceb48819 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -4319,15 +4319,20 @@ phutil_register_library_map(array( 'PholioTransactionView' => 'applications/pholio/view/PholioTransactionView.php', 'PholioUploadedImageView' => 'applications/pholio/view/PholioUploadedImageView.php', 'PhortuneAccount' => 'applications/phortune/storage/PhortuneAccount.php', + 'PhortuneAccountAddManagerController' => 'applications/phortune/controller/account/PhortuneAccountAddManagerController.php', + 'PhortuneAccountBillingController' => 'applications/phortune/controller/account/PhortuneAccountBillingController.php', 'PhortuneAccountChargeListController' => 'applications/phortune/controller/account/PhortuneAccountChargeListController.php', 'PhortuneAccountEditController' => 'applications/phortune/controller/account/PhortuneAccountEditController.php', 'PhortuneAccountEditEngine' => 'applications/phortune/editor/PhortuneAccountEditEngine.php', 'PhortuneAccountEditor' => 'applications/phortune/editor/PhortuneAccountEditor.php', 'PhortuneAccountHasMemberEdgeType' => 'applications/phortune/edge/PhortuneAccountHasMemberEdgeType.php', 'PhortuneAccountListController' => 'applications/phortune/controller/account/PhortuneAccountListController.php', + 'PhortuneAccountManagerController' => 'applications/phortune/controller/account/PhortuneAccountManagerController.php', 'PhortuneAccountNameTransaction' => 'applications/phortune/xaction/PhortuneAccountNameTransaction.php', 'PhortuneAccountPHIDType' => 'applications/phortune/phid/PhortuneAccountPHIDType.php', + 'PhortuneAccountProfileController' => 'applications/phortune/controller/account/PhortuneAccountProfileController.php', 'PhortuneAccountQuery' => 'applications/phortune/query/PhortuneAccountQuery.php', + 'PhortuneAccountSubscriptionController' => 'applications/phortune/controller/account/PhortuneAccountSubscriptionController.php', 'PhortuneAccountTransaction' => 'applications/phortune/storage/PhortuneAccountTransaction.php', 'PhortuneAccountTransactionQuery' => 'applications/phortune/query/PhortuneAccountTransactionQuery.php', 'PhortuneAccountTransactionType' => 'applications/phortune/xaction/PhortuneAccountTransactionType.php', @@ -9774,19 +9779,24 @@ phutil_register_library_map(array( 'PhabricatorApplicationTransactionInterface', 'PhabricatorPolicyInterface', ), + 'PhortuneAccountAddManagerController' => 'PhortuneController', + 'PhortuneAccountBillingController' => 'PhortuneAccountProfileController', 'PhortuneAccountChargeListController' => 'PhortuneController', 'PhortuneAccountEditController' => 'PhortuneController', 'PhortuneAccountEditEngine' => 'PhabricatorEditEngine', 'PhortuneAccountEditor' => 'PhabricatorApplicationTransactionEditor', 'PhortuneAccountHasMemberEdgeType' => 'PhabricatorEdgeType', 'PhortuneAccountListController' => 'PhortuneController', + 'PhortuneAccountManagerController' => 'PhortuneAccountProfileController', 'PhortuneAccountNameTransaction' => 'PhortuneAccountTransactionType', 'PhortuneAccountPHIDType' => 'PhabricatorPHIDType', + 'PhortuneAccountProfileController' => 'PhortuneController', 'PhortuneAccountQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', + 'PhortuneAccountSubscriptionController' => 'PhortuneAccountProfileController', 'PhortuneAccountTransaction' => 'PhabricatorModularTransaction', 'PhortuneAccountTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhortuneAccountTransactionType' => 'PhabricatorModularTransactionType', - 'PhortuneAccountViewController' => 'PhortuneController', + 'PhortuneAccountViewController' => 'PhortuneAccountProfileController', 'PhortuneAdHocCart' => 'PhortuneCartImplementation', 'PhortuneAdHocProduct' => 'PhortuneProductImplementation', 'PhortuneCart' => array( diff --git a/src/applications/phortune/application/PhabricatorPhortuneApplication.php b/src/applications/phortune/application/PhabricatorPhortuneApplication.php index 4d6030d21d..0ffc138f65 100644 --- a/src/applications/phortune/application/PhabricatorPhortuneApplication.php +++ b/src/applications/phortune/application/PhabricatorPhortuneApplication.php @@ -69,6 +69,16 @@ final class PhabricatorPhortuneApplication extends PhabricatorApplication { '' => 'PhortuneAccountListController', $this->getEditRoutePattern('edit/') => 'PhortuneAccountEditController', + 'edit/(?:(?P\d+)/)?' => 'PhortuneAccountEditController', + 'add/manager/(?:(?P\d+)/)?' + => 'PhortuneAccountAddManagerController', + 'billing/(?:(?P\d+)/)?' => 'PhortuneAccountBillingController', + 'subscription/(?:(?P\d+)/)?' + => 'PhortuneAccountSubscriptionController', + 'manager/' => array( + '(?:(?P\d+)/)?' => 'PhortuneAccountManagerController', + 'add/(?:(?P\d+)/)?' => 'PhortuneAccountAddManagerController', + ), ), 'product/' => array( '' => 'PhortuneProductListController', diff --git a/src/applications/phortune/controller/account/PhortuneAccountAddManagerController.php b/src/applications/phortune/controller/account/PhortuneAccountAddManagerController.php new file mode 100644 index 0000000000..34bb0a480b --- /dev/null +++ b/src/applications/phortune/controller/account/PhortuneAccountAddManagerController.php @@ -0,0 +1,75 @@ +getViewer(); + $id = $request->getURIData('id'); + + $account = id(new PhortuneAccountQuery()) + ->setViewer($viewer) + ->withIDs(array($id)) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->executeOne(); + if (!$account) { + return new Aphront404Response(); + } + + $v_managers = array(); + $e_managers = null; + $account_uri = $this->getApplicationURI("/account/manager/{$id}/"); + + if ($request->isFormPost()) { + $xactions = array(); + $v_managers = $request->getArr('managerPHIDs'); + $type_edge = PhabricatorTransactions::TYPE_EDGE; + + $xactions[] = id(new PhortuneAccountTransaction()) + ->setTransactionType($type_edge) + ->setMetadataValue( + 'edge:type', + PhortuneAccountHasMemberEdgeType::EDGECONST) + ->setNewValue( + array( + '+' => array_fuse($v_managers), + )); + + $editor = id(new PhortuneAccountEditor()) + ->setActor($viewer) + ->setContentSourceFromRequest($request) + ->setContinueOnNoEffect(true); + + try { + $editor->applyTransactions($account, $xactions); + + return id(new AphrontRedirectResponse())->setURI($account_uri); + } catch (PhabricatorApplicationTransactionValidationException $ex) { + $validation_exception = $ex; + $e_managers = $ex->getShortMessage($type_edge); + } + } + + $form = id(new AphrontFormView()) + ->setUser($viewer) + ->appendControl( + id(new AphrontFormTokenizerControl()) + ->setDatasource(new PhabricatorPeopleDatasource()) + ->setLabel(pht('Managers')) + ->setName('managerPHIDs') + ->setValue($v_managers) + ->setError($e_managers)); + + return $this->newDialog() + ->setTitle(pht('Add New Manager')) + ->appendForm($form) + ->setWidth(AphrontDialogView::WIDTH_FORM) + ->addCancelButton($account_uri) + ->addSubmitButton(pht('Add Manager')); + + } + +} diff --git a/src/applications/phortune/controller/account/PhortuneAccountBillingController.php b/src/applications/phortune/controller/account/PhortuneAccountBillingController.php new file mode 100644 index 0000000000..2d662668a4 --- /dev/null +++ b/src/applications/phortune/controller/account/PhortuneAccountBillingController.php @@ -0,0 +1,178 @@ +getViewer(); + + // TODO: Currently, you must be able to edit an account to view the detail + // page, because the account must be broadly visible so merchants can + // process orders but merchants should not be able to see all the details + // of an account. Ideally this page should be visible to merchants, too, + // just with less information. + $can_edit = true; + + $account = id(new PhortuneAccountQuery()) + ->setViewer($viewer) + ->withIDs(array($request->getURIData('id'))) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->executeOne(); + if (!$account) { + return new Aphront404Response(); + } + + $this->setAccount($account); + $title = $account->getName(); + + $crumbs = $this->buildApplicationCrumbs(); + $crumbs->addTextCrumb(pht('Billing')); + + $header = $this->buildHeaderView(); + $methods = $this->buildPaymentMethodsSection($account); + $charge_history = $this->buildChargeHistorySection($account); + + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter(array( + $methods, + $charge_history, + )); + + $navigation = $this->buildSideNavView('billing'); + + return $this->newPage() + ->setTitle($title) + ->setCrumbs($crumbs) + ->setNavigation($navigation) + ->appendChild($view); + + } + + private function buildPaymentMethodsSection(PhortuneAccount $account) { + $viewer = $this->getViewer(); + + $can_edit = PhabricatorPolicyFilter::hasCapability( + $viewer, + $account, + PhabricatorPolicyCapability::CAN_EDIT); + + $id = $account->getID(); + + // TODO: Allow adding a card here directly + $add = id(new PHUIButtonView()) + ->setTag('a') + ->setText(pht('New Payment Method')) + ->setIcon('fa-plus') + ->setHref($this->getApplicationURI("{$id}/card/new/")); + + $header = id(new PHUIHeaderView()) + ->setHeader(pht('Payment Methods')); + + $list = id(new PHUIObjectItemListView()) + ->setUser($viewer) + ->setFlush(true) + ->setNoDataString( + pht('No payment methods associated with this account.')); + + $methods = id(new PhortunePaymentMethodQuery()) + ->setViewer($viewer) + ->withAccountPHIDs(array($account->getPHID())) + ->withStatuses( + array( + PhortunePaymentMethod::STATUS_ACTIVE, + )) + ->execute(); + + foreach ($methods as $method) { + $id = $method->getID(); + + $item = new PHUIObjectItemView(); + $item->setHeader($method->getFullDisplayName()); + + switch ($method->getStatus()) { + case PhortunePaymentMethod::STATUS_ACTIVE: + $item->setStatusIcon('fa-check green'); + + $disable_uri = $this->getApplicationURI('card/'.$id.'/disable/'); + $item->addAction( + id(new PHUIListItemView()) + ->setIcon('fa-times') + ->setHref($disable_uri) + ->setDisabled(!$can_edit) + ->setWorkflow(true)); + break; + case PhortunePaymentMethod::STATUS_DISABLED: + $item->setStatusIcon('fa-ban lightbluetext'); + $item->setDisabled(true); + break; + } + + $provider = $method->buildPaymentProvider(); + $item->addAttribute($provider->getPaymentMethodProviderDescription()); + + $edit_uri = $this->getApplicationURI('card/'.$id.'/edit/'); + + $item->addAction( + id(new PHUIListItemView()) + ->setIcon('fa-pencil') + ->setHref($edit_uri) + ->setDisabled(!$can_edit) + ->setWorkflow(!$can_edit)); + + $list->addItem($item); + } + + return id(new PHUIObjectBoxView()) + ->setHeader($header) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + ->setObjectList($list); + } + + private function buildChargeHistorySection(PhortuneAccount $account) { + $viewer = $this->getViewer(); + + $charges = id(new PhortuneChargeQuery()) + ->setViewer($viewer) + ->withAccountPHIDs(array($account->getPHID())) + ->needCarts(true) + ->setLimit(10) + ->execute(); + + $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('Charge History')) + ->addActionLink( + id(new PHUIButtonView()) + ->setTag('a') + ->setIcon('fa-list') + ->setHref($charges_uri) + ->setText(pht('View All Charges'))); + + return id(new PHUIObjectBoxView()) + ->setHeader($header) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + ->setTable($table); + } + +} diff --git a/src/applications/phortune/controller/account/PhortuneAccountManagerController.php b/src/applications/phortune/controller/account/PhortuneAccountManagerController.php new file mode 100644 index 0000000000..b5f8a38f64 --- /dev/null +++ b/src/applications/phortune/controller/account/PhortuneAccountManagerController.php @@ -0,0 +1,101 @@ +getViewer(); + + // TODO: Currently, you must be able to edit an account to view the detail + // page, because the account must be broadly visible so merchants can + // process orders but merchants should not be able to see all the details + // of an account. Ideally this page should be visible to merchants, too, + // just with less information. + $can_edit = true; + + $account = id(new PhortuneAccountQuery()) + ->setViewer($viewer) + ->withIDs(array($request->getURIData('id'))) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->executeOne(); + if (!$account) { + return new Aphront404Response(); + } + + $this->setAccount($account); + $title = $account->getName(); + + $crumbs = $this->buildApplicationCrumbs(); + $crumbs->addTextCrumb(pht('Managers')); + + $header = $this->buildHeaderView(); + $members = $this->buildMembersSection($account); + + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter(array( + $members, + )); + + $navigation = $this->buildSideNavView('managers'); + + return $this->newPage() + ->setTitle($title) + ->setCrumbs($crumbs) + ->setNavigation($navigation) + ->appendChild($view); + + } + + private function buildMembersSection(PhortuneAccount $account) { + $viewer = $this->getViewer(); + + $can_edit = PhabricatorPolicyFilter::hasCapability( + $viewer, + $account, + PhabricatorPolicyCapability::CAN_EDIT); + + $id = $account->getID(); + + $add = id(new PHUIButtonView()) + ->setTag('a') + ->setText(pht('New Manager')) + ->setIcon('fa-plus') + ->setWorkflow(true) + ->setHref("/phortune/account/manager/add/{$id}/"); + + $header = id(new PHUIHeaderView()) + ->setHeader(pht('Account Managers')) + ->addActionLink($add); + + $list = id(new PHUIObjectItemListView()) + ->setUser($viewer); + + $member_phids = $account->getMemberPHIDs(); + $handles = $viewer->loadHandles($member_phids); + + foreach ($member_phids as $member_phid) { + $image_uri = $handles[$member_phid]->getImageURI(); + $image_href = $handles[$member_phid]->getURI(); + $person = $handles[$member_phid]; + + $member = id(new PHUIObjectItemView()) + ->setImageURI($image_uri) + ->setHref($image_href) + ->setHeader($person->getFullName()) + ->addAttribute(pht('Account Manager')); + + $list->addItem($member); + } + + return id(new PHUIObjectBoxView()) + ->setHeader($header) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + ->setObjectList($list); + } + +} diff --git a/src/applications/phortune/controller/account/PhortuneAccountProfileController.php b/src/applications/phortune/controller/account/PhortuneAccountProfileController.php new file mode 100644 index 0000000000..895b76bdc6 --- /dev/null +++ b/src/applications/phortune/controller/account/PhortuneAccountProfileController.php @@ -0,0 +1,84 @@ +account = $account; + return $this; + } + + public function getAccount() { + return $this->account; + } + + public function buildApplicationMenu() { + return $this->buildSideNavView()->getMenu(); + } + + protected function buildHeaderView() { + $viewer = $this->getViewer(); + $account = $this->getAccount(); + $title = $account->getName(); + + $header = id(new PHUIHeaderView()) + ->setUser($viewer) + ->setHeader($title) + ->setHeaderIcon('fa-user-circle'); + + return $header; + } + + protected function buildApplicationCrumbs() { + $account = $this->getAccount(); + $id = $account->getID(); + $account_uri = $this->getApplicationURI("/{$id}/"); + + $crumbs = parent::buildApplicationCrumbs(); + $crumbs->addTextCrumb($account->getName(), $account_uri); + $crumbs->setBorder(true); + return $crumbs; + } + + protected function buildSideNavView($filter = null) { + $viewer = $this->getViewer(); + $account = $this->getAccount(); + $id = $account->getID(); + + $nav = id(new AphrontSideNavFilterView()) + ->setBaseURI(new PhutilURI($this->getApplicationURI())); + + $nav->addLabel(pht('Account')); + + $nav->addFilter( + 'overview', + pht('Overview'), + $this->getApplicationURI("/{$id}/"), + 'fa-user-circle'); + + $nav->addFilter( + 'subscriptions', + pht('Subscriptions'), + $this->getApplicationURI("/account/subscription/{$id}/"), + 'fa-retweet'); + + $nav->addFilter( + 'billing', + pht('Billing / History'), + $this->getApplicationURI("/account/billing/{$id}/"), + 'fa-credit-card'); + + $nav->addFilter( + 'managers', + pht('Managers'), + $this->getApplicationURI("/account/manager/{$id}/"), + 'fa-group'); + + $nav->selectFilter($filter); + + return $nav; + } + +} diff --git a/src/applications/phortune/controller/account/PhortuneAccountSubscriptionController.php b/src/applications/phortune/controller/account/PhortuneAccountSubscriptionController.php new file mode 100644 index 0000000000..145c5eb5db --- /dev/null +++ b/src/applications/phortune/controller/account/PhortuneAccountSubscriptionController.php @@ -0,0 +1,79 @@ +getViewer(); + + // TODO: Currently, you must be able to edit an account to view the detail + // page, because the account must be broadly visible so merchants can + // process orders but merchants should not be able to see all the details + // of an account. Ideally this page should be visible to merchants, too, + // just with less information. + $can_edit = true; + + $account = id(new PhortuneAccountQuery()) + ->setViewer($viewer) + ->withIDs(array($request->getURIData('id'))) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->executeOne(); + if (!$account) { + return new Aphront404Response(); + } + + $this->setAccount($account); + $title = $account->getName(); + + $crumbs = $this->buildApplicationCrumbs(); + $crumbs->addTextCrumb(pht('Subscriptions')); + + $header = $this->buildHeaderView(); + $subscriptions = $this->buildSubscriptionsSection($account); + + $view = id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter(array( + $subscriptions, + )); + + $navigation = $this->buildSideNavView('subscriptions'); + + return $this->newPage() + ->setTitle($title) + ->setCrumbs($crumbs) + ->setNavigation($navigation) + ->appendChild($view); + + } + + private function buildSubscriptionsSection(PhortuneAccount $account) { + $viewer = $this->getViewer(); + + $subscriptions = id(new PhortuneSubscriptionQuery()) + ->setViewer($viewer) + ->withAccountPHIDs(array($account->getPHID())) + ->setLimit(25) + ->execute(); + + $handles = $this->loadViewerHandles(mpull($subscriptions, 'getPHID')); + + $table = id(new PhortuneSubscriptionTableView()) + ->setUser($viewer) + ->setHandles($handles) + ->setSubscriptions($subscriptions); + + $header = id(new PHUIHeaderView()) + ->setHeader(pht('Subscriptions')); + + return id(new PHUIObjectBoxView()) + ->setHeader($header) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + ->setTable($table); + } + +} diff --git a/src/applications/phortune/controller/account/PhortuneAccountViewController.php b/src/applications/phortune/controller/account/PhortuneAccountViewController.php index d0ef03fc9a..efb94551c3 100644 --- a/src/applications/phortune/controller/account/PhortuneAccountViewController.php +++ b/src/applications/phortune/controller/account/PhortuneAccountViewController.php @@ -1,9 +1,11 @@ getViewer(); + $id = $request->getURIData('accountID'); // TODO: Currently, you must be able to edit an account to view the detail // page, because the account must be broadly visible so merchants can @@ -14,7 +16,7 @@ final class PhortuneAccountViewController extends PhortuneController { $account = id(new PhortuneAccountQuery()) ->setViewer($viewer) - ->withIDs(array($request->getURIData('accountID'))) + ->withIDs(array($id)) ->requireCapabilities( array( PhabricatorPolicyCapability::CAN_VIEW, @@ -25,6 +27,7 @@ final class PhortuneAccountViewController extends PhortuneController { return new Aphront404Response(); } + $this->setAccount($account); $title = $account->getName(); $invoices = id(new PhortuneCartQuery()) @@ -35,19 +38,14 @@ final class PhortuneAccountViewController extends PhortuneController { ->execute(); $crumbs = $this->buildApplicationCrumbs(); - $this->addAccountCrumb($crumbs, $account, $link = false); $crumbs->setBorder(true); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon('fa-credit-card'); + $header = $this->buildHeaderView(); - $curtain = $this->buildCurtainView($account, $invoices); + $curtain = $this->buildCurtainView($account); + $status = $this->buildStatusView($account, $invoices); $invoices = $this->buildInvoicesSection($account, $invoices); $purchase_history = $this->buildPurchaseHistorySection($account); - $charge_history = $this->buildChargeHistorySection($account); - $subscriptions = $this->buildSubscriptionsSection($account); - $payment_methods = $this->buildPaymentMethodsSection($account); $timeline = $this->buildTransactionTimeline( $account, @@ -58,22 +56,34 @@ final class PhortuneAccountViewController extends PhortuneController { ->setHeader($header) ->setCurtain($curtain) ->setMainColumn(array( + $status, $invoices, $purchase_history, - $charge_history, - $subscriptions, - $payment_methods, $timeline, )); + $navigation = $this->buildSideNavView('overview'); + return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) + ->setNavigation($navigation) ->appendChild($view); } - private function buildCurtainView(PhortuneAccount $account, $invoices) { + private function buildStatusView(PhortuneAccount $account, $invoices) { + $status_items = $this->getStatusItemsForAccount($account, $invoices); + $view = array(); + foreach ($status_items as $item) { + $view[] = id(new PHUIInfoView()) + ->setSeverity(idx($item, 'severity')) + ->appendChild(idx($item, 'note')); + } + return $view; + } + + private function buildCurtainView(PhortuneAccount $account) { $viewer = $this->getViewer(); $can_edit = PhabricatorPolicyFilter::hasCapability( @@ -92,19 +102,6 @@ final class PhortuneAccountViewController extends PhortuneController { ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); - $status_items = $this->getStatusItemsForAccount($account, $invoices); - $status_view = new PHUIStatusListView(); - foreach ($status_items as $item) { - $status_view->addItem( - id(new PHUIStatusItemView()) - ->setIcon( - idx($item, 'icon'), - idx($item, 'color'), - idx($item, 'label')) - ->setTarget(idx($item, 'target')) - ->setNote(idx($item, 'note'))); - } - $member_phids = $account->getMemberPHIDs(); $handles = $viewer->loadHandles($member_phids); @@ -124,10 +121,6 @@ final class PhortuneAccountViewController extends PhortuneController { $member_list->addItem($member); } - $curtain->newPanel() - ->setHeaderText(pht('Status')) - ->appendChild($status_view); - $curtain->newPanel() ->setHeaderText(pht('Managers')) ->appendChild($member_list); @@ -135,79 +128,6 @@ final class PhortuneAccountViewController extends PhortuneController { return $curtain; } - private function buildPaymentMethodsSection(PhortuneAccount $account) { - $viewer = $this->getViewer(); - - $can_edit = PhabricatorPolicyFilter::hasCapability( - $viewer, - $account, - PhabricatorPolicyCapability::CAN_EDIT); - - $id = $account->getID(); - - $header = id(new PHUIHeaderView()) - ->setHeader(pht('Payment Methods')); - - $list = id(new PHUIObjectItemListView()) - ->setUser($viewer) - ->setFlush(true) - ->setNoDataString( - pht('No payment methods associated with this account.')); - - $methods = id(new PhortunePaymentMethodQuery()) - ->setViewer($viewer) - ->withAccountPHIDs(array($account->getPHID())) - ->withStatuses( - array( - PhortunePaymentMethod::STATUS_ACTIVE, - )) - ->execute(); - - foreach ($methods as $method) { - $id = $method->getID(); - - $item = new PHUIObjectItemView(); - $item->setHeader($method->getFullDisplayName()); - - switch ($method->getStatus()) { - case PhortunePaymentMethod::STATUS_ACTIVE: - $item->setStatusIcon('fa-check green'); - - $disable_uri = $this->getApplicationURI('card/'.$id.'/disable/'); - $item->addAction( - id(new PHUIListItemView()) - ->setIcon('fa-times') - ->setHref($disable_uri) - ->setDisabled(!$can_edit) - ->setWorkflow(true)); - break; - case PhortunePaymentMethod::STATUS_DISABLED: - $item->setStatusIcon('fa-ban lightbluetext'); - $item->setDisabled(true); - break; - } - - $provider = $method->buildPaymentProvider(); - $item->addAttribute($provider->getPaymentMethodProviderDescription()); - - $edit_uri = $this->getApplicationURI('card/'.$id.'/edit/'); - - $item->addAction( - id(new PHUIListItemView()) - ->setIcon('fa-pencil') - ->setHref($edit_uri) - ->setDisabled(!$can_edit) - ->setWorkflow(!$can_edit)); - - $list->addItem($item); - } - - return id(new PHUIObjectBoxView()) - ->setHeader($header) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setObjectList($list); - } - private function buildInvoicesSection( PhortuneAccount $account, array $carts) { @@ -289,84 +209,6 @@ final class PhortuneAccountViewController extends PhortuneController { ->setTable($table); } - private function buildChargeHistorySection(PhortuneAccount $account) { - $viewer = $this->getViewer(); - - $charges = id(new PhortuneChargeQuery()) - ->setViewer($viewer) - ->withAccountPHIDs(array($account->getPHID())) - ->needCarts(true) - ->setLimit(10) - ->execute(); - - $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('fa-list') - ->setHref($charges_uri) - ->setText(pht('View All Charges'))); - - return id(new PHUIObjectBoxView()) - ->setHeader($header) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); - } - - private function buildSubscriptionsSection(PhortuneAccount $account) { - $viewer = $this->getViewer(); - - $subscriptions = id(new PhortuneSubscriptionQuery()) - ->setViewer($viewer) - ->withAccountPHIDs(array($account->getPHID())) - ->setLimit(10) - ->execute(); - - $subscriptions_uri = $this->getApplicationURI( - $account->getID().'/subscription/'); - - $handles = $this->loadViewerHandles(mpull($subscriptions, 'getPHID')); - - $table = id(new PhortuneSubscriptionTableView()) - ->setUser($viewer) - ->setHandles($handles) - ->setSubscriptions($subscriptions); - - $header = id(new PHUIHeaderView()) - ->setHeader(pht('Recent Subscriptions')) - ->addActionLink( - id(new PHUIButtonView()) - ->setTag('a') - ->setIcon( - id(new PHUIIconView()) - ->setIcon('fa-list')) - ->setHref($subscriptions_uri) - ->setText(pht('View All Subscriptions'))); - - return id(new PHUIObjectBoxView()) - ->setHeader($header) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table); - } - protected function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); @@ -382,25 +224,25 @@ final class PhortuneAccountViewController extends PhortuneController { private function getStatusItemsForAccount( PhortuneAccount $account, array $invoices) { + $viewer = $this->getViewer(); assert_instances_of($invoices, 'PhortuneCart'); - $items = array(); + $methods = id(new PhortunePaymentMethodQuery()) + ->setViewer($viewer) + ->withAccountPHIDs(array($account->getPHID())) + ->withStatuses( + array( + PhortunePaymentMethod::STATUS_ACTIVE, + )) + ->execute(); + if ($invoices) { $items[] = array( - 'icon' => PHUIStatusItemView::ICON_WARNING, - 'color' => 'yellow', - 'target' => pht('Invoices'), + 'severity' => PHUIInfoView::SEVERITY_ERROR, 'note' => pht('You have %d unpaid invoice(s).', count($invoices)), ); - } else { - $items[] = array( - 'icon' => PHUIStatusItemView::ICON_ACCEPT, - 'color' => 'green', - 'target' => pht('Invoices'), - 'note' => pht('This account has no unpaid invoices.'), - ); } // TODO: If a payment method has expired or is expiring soon, we should diff --git a/src/applications/phortune/view/PhortuneChargeTableView.php b/src/applications/phortune/view/PhortuneChargeTableView.php index 4e82404cc6..663c470a81 100644 --- a/src/applications/phortune/view/PhortuneChargeTableView.php +++ b/src/applications/phortune/view/PhortuneChargeTableView.php @@ -55,6 +55,7 @@ final class PhortuneChargeTableView extends AphrontView { } $table = id(new AphrontTableView($rows)) + ->setNoDataString(pht('No charges found.')) ->setHeaders( array( pht('ID'),