Support multiple payment accounts and account switching in Phortune
Summary: Ref T2787. Support multiple payment accounts so you can have personal vs company payment accounts. Test Plan: See screenshots. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T2787 Differential Revision: https://secure.phabricator.com/D10673
This commit is contained in:
		@@ -2547,7 +2547,9 @@ phutil_register_library_map(array(
 | 
			
		||||
    'PholioTransactionView' => 'applications/pholio/view/PholioTransactionView.php',
 | 
			
		||||
    'PholioUploadedImageView' => 'applications/pholio/view/PholioUploadedImageView.php',
 | 
			
		||||
    'PhortuneAccount' => 'applications/phortune/storage/PhortuneAccount.php',
 | 
			
		||||
    'PhortuneAccountEditController' => 'applications/phortune/controller/PhortuneAccountEditController.php',
 | 
			
		||||
    'PhortuneAccountEditor' => 'applications/phortune/editor/PhortuneAccountEditor.php',
 | 
			
		||||
    'PhortuneAccountListController' => 'applications/phortune/controller/PhortuneAccountListController.php',
 | 
			
		||||
    'PhortuneAccountPHIDType' => 'applications/phortune/phid/PhortuneAccountPHIDType.php',
 | 
			
		||||
    'PhortuneAccountQuery' => 'applications/phortune/query/PhortuneAccountQuery.php',
 | 
			
		||||
    'PhortuneAccountTransaction' => 'applications/phortune/storage/PhortuneAccountTransaction.php',
 | 
			
		||||
@@ -5601,7 +5603,9 @@ phutil_register_library_map(array(
 | 
			
		||||
      'PhortuneDAO',
 | 
			
		||||
      'PhabricatorPolicyInterface',
 | 
			
		||||
    ),
 | 
			
		||||
    'PhortuneAccountEditController' => 'PhortuneController',
 | 
			
		||||
    'PhortuneAccountEditor' => 'PhabricatorApplicationTransactionEditor',
 | 
			
		||||
    'PhortuneAccountListController' => 'PhortuneController',
 | 
			
		||||
    'PhortuneAccountPHIDType' => 'PhabricatorPHIDType',
 | 
			
		||||
    'PhortuneAccountQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
 | 
			
		||||
    'PhortuneAccountTransaction' => 'PhabricatorApplicationTransaction',
 | 
			
		||||
 
 | 
			
		||||
@@ -39,11 +39,25 @@ final class FundInitiativeBackController
 | 
			
		||||
        ->addCancelButton($initiative_uri);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $accounts = PhortuneAccountQuery::loadAccountsForUser(
 | 
			
		||||
      $viewer,
 | 
			
		||||
      PhabricatorContentSource::newFromRequest($request));
 | 
			
		||||
 | 
			
		||||
    $v_amount = null;
 | 
			
		||||
    $e_amount = true;
 | 
			
		||||
 | 
			
		||||
    $v_account = head($accounts)->getPHID();
 | 
			
		||||
 | 
			
		||||
    $errors = array();
 | 
			
		||||
    if ($request->isFormPost()) {
 | 
			
		||||
      $v_amount = $request->getStr('amount');
 | 
			
		||||
      $v_account = $request->getStr('accountPHID');
 | 
			
		||||
 | 
			
		||||
      if (empty($accounts[$v_account])) {
 | 
			
		||||
        $errors[] = pht('You must specify an account.');
 | 
			
		||||
      } else {
 | 
			
		||||
        $account = $accounts[$v_account];
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (!strlen($v_amount)) {
 | 
			
		||||
        $errors[] = pht(
 | 
			
		||||
@@ -74,10 +88,6 @@ final class FundInitiativeBackController
 | 
			
		||||
          ->withClassAndRef('FundBackerProduct', $initiative->getPHID())
 | 
			
		||||
          ->executeOne();
 | 
			
		||||
 | 
			
		||||
        $account = PhortuneAccountQuery::loadActiveAccountForUser(
 | 
			
		||||
          $viewer,
 | 
			
		||||
          PhabricatorContentSource::newFromRequest($request));
 | 
			
		||||
 | 
			
		||||
        $cart_implementation = id(new FundBackerCart())
 | 
			
		||||
          ->setInitiative($initiative);
 | 
			
		||||
 | 
			
		||||
@@ -110,6 +120,12 @@ final class FundInitiativeBackController
 | 
			
		||||
 | 
			
		||||
    $form = id(new AphrontFormView())
 | 
			
		||||
      ->setUser($viewer)
 | 
			
		||||
      ->appendChild(
 | 
			
		||||
        id(new AphrontFormSelectControl())
 | 
			
		||||
          ->setName('accountPHID')
 | 
			
		||||
          ->setLabel(pht('Account'))
 | 
			
		||||
          ->setValue($v_account)
 | 
			
		||||
          ->setOptions(mpull($accounts, 'getName', 'getPHID')))
 | 
			
		||||
      ->appendChild(
 | 
			
		||||
        id(new AphrontFormTextControl())
 | 
			
		||||
          ->setName('amount')
 | 
			
		||||
 
 | 
			
		||||
@@ -79,8 +79,6 @@ final class FundBackerProduct extends PhortuneProductImplementation {
 | 
			
		||||
  public function didPurchaseProduct(
 | 
			
		||||
    PhortuneProduct $product,
 | 
			
		||||
    PhortunePurchase $purchase) {
 | 
			
		||||
    // TODO: This viewer may be wrong if the purchase completes after a hold
 | 
			
		||||
    // we should load the backer explicitly.
 | 
			
		||||
    $viewer = $this->getViewer();
 | 
			
		||||
 | 
			
		||||
    $backer = id(new FundBackerQuery())
 | 
			
		||||
@@ -91,25 +89,33 @@ final class FundBackerProduct extends PhortuneProductImplementation {
 | 
			
		||||
      throw new Exception(pht('Unable to load FundBacker!'));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Load the actual backing user --they may not be the curent viewer if this
 | 
			
		||||
    // product purchase is completing from a background worker or a merchant
 | 
			
		||||
    // action.
 | 
			
		||||
 | 
			
		||||
    $actor = id(new PhabricatorPeopleQuery())
 | 
			
		||||
      ->setViewer($viewer)
 | 
			
		||||
      ->withPHIDs(array($backer->getBackerPHID()))
 | 
			
		||||
      ->executeOne();
 | 
			
		||||
 | 
			
		||||
    $xactions = array();
 | 
			
		||||
    $xactions[] = id(new FundBackerTransaction())
 | 
			
		||||
      ->setTransactionType(FundBackerTransaction::TYPE_STATUS)
 | 
			
		||||
      ->setNewValue(FundBacker::STATUS_PURCHASED);
 | 
			
		||||
 | 
			
		||||
    $editor = id(new FundBackerEditor())
 | 
			
		||||
      ->setActor($viewer)
 | 
			
		||||
      ->setActor($actor)
 | 
			
		||||
      ->setContentSource($this->getContentSource());
 | 
			
		||||
 | 
			
		||||
    $editor->applyTransactions($backer, $xactions);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    $xactions = array();
 | 
			
		||||
    $xactions[] = id(new FundInitiativeTransaction())
 | 
			
		||||
      ->setTransactionType(FundInitiativeTransaction::TYPE_BACKER)
 | 
			
		||||
      ->setNewValue($backer->getPHID());
 | 
			
		||||
 | 
			
		||||
    $editor = id(new FundInitiativeEditor())
 | 
			
		||||
      ->setActor($viewer)
 | 
			
		||||
      ->setActor($actor)
 | 
			
		||||
      ->setContentSource($this->getContentSource());
 | 
			
		||||
 | 
			
		||||
    $editor->applyTransactions($this->getInitiative(), $xactions);
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,122 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
final class PhortuneAccountEditController extends PhortuneController {
 | 
			
		||||
 | 
			
		||||
  private $id;
 | 
			
		||||
 | 
			
		||||
  public function willProcessRequest(array $data) {
 | 
			
		||||
    $this->id = idx($data, 'id');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function processRequest() {
 | 
			
		||||
    $request = $this->getRequest();
 | 
			
		||||
    $viewer = $request->getUser();
 | 
			
		||||
 | 
			
		||||
    if ($this->id) {
 | 
			
		||||
      $account = id(new PhortuneAccountQuery())
 | 
			
		||||
        ->setViewer($viewer)
 | 
			
		||||
        ->withIDs(array($this->id))
 | 
			
		||||
        ->requireCapabilities(
 | 
			
		||||
          array(
 | 
			
		||||
            PhabricatorPolicyCapability::CAN_VIEW,
 | 
			
		||||
            PhabricatorPolicyCapability::CAN_EDIT,
 | 
			
		||||
          ))
 | 
			
		||||
        ->executeOne();
 | 
			
		||||
      if (!$account) {
 | 
			
		||||
        return new Aphront404Response();
 | 
			
		||||
      }
 | 
			
		||||
      $is_new = false;
 | 
			
		||||
    } else {
 | 
			
		||||
      $account = PhortuneAccount::initializeNewAccount($viewer);
 | 
			
		||||
      $is_new = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $v_name = $account->getName();
 | 
			
		||||
    $e_name = true;
 | 
			
		||||
    $validation_exception = null;
 | 
			
		||||
 | 
			
		||||
    if ($request->isFormPost()) {
 | 
			
		||||
      $v_name = $request->getStr('name');
 | 
			
		||||
 | 
			
		||||
      $type_name = PhortuneAccountTransaction::TYPE_NAME;
 | 
			
		||||
 | 
			
		||||
      $xactions = array();
 | 
			
		||||
      $xactions[] = id(new PhortuneAccountTransaction())
 | 
			
		||||
        ->setTransactionType($type_name)
 | 
			
		||||
        ->setNewValue($v_name);
 | 
			
		||||
 | 
			
		||||
      if ($is_new) {
 | 
			
		||||
        $xactions[] = id(new PhortuneAccountTransaction())
 | 
			
		||||
          ->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
 | 
			
		||||
          ->setMetadataValue(
 | 
			
		||||
            'edge:type',
 | 
			
		||||
            PhabricatorEdgeConfig::TYPE_ACCOUNT_HAS_MEMBER)
 | 
			
		||||
          ->setNewValue(
 | 
			
		||||
            array(
 | 
			
		||||
              '=' => array($viewer->getPHID() => $viewer->getPHID()),
 | 
			
		||||
            ));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      $editor = id(new PhortuneAccountEditor())
 | 
			
		||||
        ->setActor($viewer)
 | 
			
		||||
        ->setContentSourceFromRequest($request)
 | 
			
		||||
        ->setContinueOnNoEffect(true);
 | 
			
		||||
 | 
			
		||||
      try {
 | 
			
		||||
        $editor->applyTransactions($account, $xactions);
 | 
			
		||||
 | 
			
		||||
        $account_uri = $this->getApplicationURI($account->getID().'/');
 | 
			
		||||
        return id(new AphrontRedirectResponse())->setURI($account_uri);
 | 
			
		||||
      } catch (PhabricatorApplicationTransactionValidationException $ex) {
 | 
			
		||||
        $validation_exception = $ex;
 | 
			
		||||
        $e_name = $ex->getShortMessage($type_name);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $crumbs = $this->buildApplicationCrumbs();
 | 
			
		||||
 | 
			
		||||
    if ($is_new) {
 | 
			
		||||
      $cancel_uri = $this->getApplicationURI('account/');
 | 
			
		||||
      $crumbs->addTextCrumb(pht('Accounts'), $cancel_uri);
 | 
			
		||||
      $crumbs->addTextCrumb(pht('Create Account'));
 | 
			
		||||
 | 
			
		||||
      $title = pht('Create Payment Account');
 | 
			
		||||
      $submit_button = pht('Create Account');
 | 
			
		||||
    } else {
 | 
			
		||||
      $cancel_uri = $this->getApplicationURI($account->getID().'/');
 | 
			
		||||
      $crumbs->addTextCrumb($account->getName(), $cancel_uri);
 | 
			
		||||
      $crumbs->addTextCrumb(pht('Edit'));
 | 
			
		||||
 | 
			
		||||
      $title = pht('Edit %s', $account->getName());
 | 
			
		||||
      $submit_button = pht('Save Changes');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $form = id(new AphrontFormView())
 | 
			
		||||
      ->setUser($viewer)
 | 
			
		||||
      ->appendChild(
 | 
			
		||||
        id(new AphrontFormTextControl())
 | 
			
		||||
          ->setName('name')
 | 
			
		||||
          ->setLabel(pht('Name'))
 | 
			
		||||
          ->setValue($v_name)
 | 
			
		||||
          ->setError($e_name))
 | 
			
		||||
      ->appendChild(
 | 
			
		||||
        id(new AphrontFormSubmitControl())
 | 
			
		||||
          ->setValue($submit_button)
 | 
			
		||||
          ->addCancelButton($cancel_uri));
 | 
			
		||||
 | 
			
		||||
    $box = id(new PHUIObjectBoxView())
 | 
			
		||||
      ->setHeaderText($title)
 | 
			
		||||
      ->setValidationException($validation_exception)
 | 
			
		||||
      ->appendChild($form);
 | 
			
		||||
 | 
			
		||||
    return $this->buildApplicationPage(
 | 
			
		||||
      array(
 | 
			
		||||
        $crumbs,
 | 
			
		||||
        $box,
 | 
			
		||||
      ),
 | 
			
		||||
      array(
 | 
			
		||||
        'title' => $title,
 | 
			
		||||
      ));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,108 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
final class PhortuneAccountListController extends PhortuneController {
 | 
			
		||||
 | 
			
		||||
  public function processRequest() {
 | 
			
		||||
    $request = $this->getRequest();
 | 
			
		||||
    $viewer = $request->getUser();
 | 
			
		||||
 | 
			
		||||
    $accounts = id(new PhortuneAccountQuery())
 | 
			
		||||
      ->setViewer($viewer)
 | 
			
		||||
      ->withMemberPHIDs(array($viewer->getPHID()))
 | 
			
		||||
      ->requireCapabilities(
 | 
			
		||||
        array(
 | 
			
		||||
          PhabricatorPolicyCapability::CAN_VIEW,
 | 
			
		||||
          PhabricatorPolicyCapability::CAN_EDIT,
 | 
			
		||||
        ))
 | 
			
		||||
      ->execute();
 | 
			
		||||
 | 
			
		||||
    $merchants = id(new PhortuneMerchantQuery())
 | 
			
		||||
      ->setViewer($viewer)
 | 
			
		||||
      ->requireCapabilities(
 | 
			
		||||
        array(
 | 
			
		||||
          PhabricatorPolicyCapability::CAN_VIEW,
 | 
			
		||||
          PhabricatorPolicyCapability::CAN_EDIT,
 | 
			
		||||
        ))
 | 
			
		||||
      ->execute();
 | 
			
		||||
 | 
			
		||||
    $title = pht('Accounts');
 | 
			
		||||
 | 
			
		||||
    $crumbs = $this->buildApplicationCrumbs();
 | 
			
		||||
    $crumbs->addTextCrumb(pht('Accounts'));
 | 
			
		||||
 | 
			
		||||
    $payment_list = id(new PHUIObjectItemListView())
 | 
			
		||||
      ->setUser($viewer)
 | 
			
		||||
      ->setNoDataString(
 | 
			
		||||
        pht(
 | 
			
		||||
          'You are not a member of any payment accounts. Payment '.
 | 
			
		||||
          'accounts are used to make purchases.'));
 | 
			
		||||
 | 
			
		||||
    foreach ($accounts as $account) {
 | 
			
		||||
      $item = id(new PHUIObjectItemView())
 | 
			
		||||
        ->setObjectName(pht('Account %d', $account->getID()))
 | 
			
		||||
        ->setHeader($account->getName())
 | 
			
		||||
        ->setHref($this->getApplicationURI($account->getID().'/'))
 | 
			
		||||
        ->setObject($account);
 | 
			
		||||
 | 
			
		||||
      $payment_list->addItem($item);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $payment_header = id(new PHUIHeaderView())
 | 
			
		||||
      ->setHeader(pht('Payment Accounts'))
 | 
			
		||||
      ->addActionLink(
 | 
			
		||||
        id(new PHUIButtonView())
 | 
			
		||||
          ->setTag('a')
 | 
			
		||||
          ->setHref($this->getApplicationURI('account/edit/'))
 | 
			
		||||
          ->setIcon(
 | 
			
		||||
            id(new PHUIIconView())
 | 
			
		||||
              ->setIconFont('fa-plus'))
 | 
			
		||||
          ->setText(pht('Create Account')));
 | 
			
		||||
 | 
			
		||||
    $payment_box = id(new PHUIObjectBoxView())
 | 
			
		||||
      ->setHeader($payment_header)
 | 
			
		||||
      ->appendChild($payment_list);
 | 
			
		||||
 | 
			
		||||
    $merchant_list = id(new PHUIObjectItemListView())
 | 
			
		||||
      ->setUser($viewer)
 | 
			
		||||
      ->setNoDataString(
 | 
			
		||||
        pht(
 | 
			
		||||
          'You do not control any merchant accounts. Merchant accounts are '.
 | 
			
		||||
          'used to receive payments.'));
 | 
			
		||||
 | 
			
		||||
    foreach ($merchants as $merchant) {
 | 
			
		||||
      $item = id(new PHUIObjectItemView())
 | 
			
		||||
        ->setObjectName(pht('Merchant %d', $merchant->getID()))
 | 
			
		||||
        ->setHeader($merchant->getName())
 | 
			
		||||
        ->setHref($this->getApplicationURI('/merchant/'.$merchant->getID().'/'))
 | 
			
		||||
        ->setObject($merchant);
 | 
			
		||||
 | 
			
		||||
      $merchant_list->addItem($item);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $merchant_header = id(new PHUIHeaderView())
 | 
			
		||||
      ->setHeader(pht('Merchant Accounts'))
 | 
			
		||||
      ->addActionLink(
 | 
			
		||||
        id(new PHUIButtonView())
 | 
			
		||||
          ->setTag('a')
 | 
			
		||||
          ->setHref($this->getApplicationURI('merchant/'))
 | 
			
		||||
          ->setIcon(
 | 
			
		||||
            id(new PHUIIconView())
 | 
			
		||||
              ->setIconFont('fa-folder-open'))
 | 
			
		||||
          ->setText(pht('Browse Merchants')));
 | 
			
		||||
 | 
			
		||||
    $merchant_box = id(new PHUIObjectBoxView())
 | 
			
		||||
      ->setHeader($merchant_header)
 | 
			
		||||
      ->appendChild($merchant_list);
 | 
			
		||||
 | 
			
		||||
    return $this->buildApplicationPage(
 | 
			
		||||
      array(
 | 
			
		||||
        $crumbs,
 | 
			
		||||
        $payment_box,
 | 
			
		||||
        $merchant_box,
 | 
			
		||||
      ),
 | 
			
		||||
      array(
 | 
			
		||||
        'title' => $title,
 | 
			
		||||
      ));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -17,6 +17,7 @@ final class PhortuneAccountViewController extends PhortuneController {
 | 
			
		||||
    // 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($user)
 | 
			
		||||
@@ -27,7 +28,6 @@ final class PhortuneAccountViewController extends PhortuneController {
 | 
			
		||||
          PhabricatorPolicyCapability::CAN_EDIT,
 | 
			
		||||
        ))
 | 
			
		||||
      ->executeOne();
 | 
			
		||||
 | 
			
		||||
    if (!$account) {
 | 
			
		||||
      return new Aphront404Response();
 | 
			
		||||
    }
 | 
			
		||||
@@ -35,11 +35,15 @@ final class PhortuneAccountViewController extends PhortuneController {
 | 
			
		||||
    $title = $account->getName();
 | 
			
		||||
 | 
			
		||||
    $crumbs = $this->buildApplicationCrumbs();
 | 
			
		||||
    $crumbs->addTextCrumb(pht('Account'), $request->getRequestURI());
 | 
			
		||||
    $crumbs->addTextCrumb(
 | 
			
		||||
      $account->getName(),
 | 
			
		||||
      $request->getRequestURI());
 | 
			
		||||
 | 
			
		||||
    $header = id(new PHUIHeaderView())
 | 
			
		||||
      ->setHeader($title);
 | 
			
		||||
 | 
			
		||||
    $edit_uri = $this->getApplicationURI('account/edit/'.$account->getID().'/');
 | 
			
		||||
 | 
			
		||||
    $actions = id(new PhabricatorActionListView())
 | 
			
		||||
      ->setUser($user)
 | 
			
		||||
      ->setObjectURI($request->getRequestURI())
 | 
			
		||||
@@ -47,8 +51,9 @@ final class PhortuneAccountViewController extends PhortuneController {
 | 
			
		||||
        id(new PhabricatorActionView())
 | 
			
		||||
          ->setName(pht('Edit Account'))
 | 
			
		||||
          ->setIcon('fa-pencil')
 | 
			
		||||
          ->setHref('#')
 | 
			
		||||
          ->setDisabled(true))
 | 
			
		||||
          ->setHref($edit_uri)
 | 
			
		||||
          ->setDisabled(!$can_edit)
 | 
			
		||||
          ->setWorkflow(!$can_edit))
 | 
			
		||||
      ->addAction(
 | 
			
		||||
        id(new PhabricatorActionView())
 | 
			
		||||
          ->setName(pht('Edit Members'))
 | 
			
		||||
@@ -291,4 +296,17 @@ final class PhortuneAccountViewController extends PhortuneController {
 | 
			
		||||
    return $xaction_view;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected function buildApplicationCrumbs() {
 | 
			
		||||
    $crumbs = parent::buildApplicationCrumbs();
 | 
			
		||||
 | 
			
		||||
    $crumbs->addAction(
 | 
			
		||||
      id(new PHUIListItemView())
 | 
			
		||||
        ->setIcon('fa-exchange')
 | 
			
		||||
        ->setHref($this->getApplicationURI('account/'))
 | 
			
		||||
        ->setName(pht('Switch Accounts')));
 | 
			
		||||
 | 
			
		||||
    return $crumbs;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -114,7 +114,7 @@ final class PhortuneCartCheckoutController
 | 
			
		||||
      ->setHeaderText(pht('Cart Contents'))
 | 
			
		||||
      ->appendChild($cart_table);
 | 
			
		||||
 | 
			
		||||
    $title = pht('Buy Stuff');
 | 
			
		||||
    $title = $cart->getName();
 | 
			
		||||
 | 
			
		||||
    if (!$methods) {
 | 
			
		||||
      $method_control = id(new AphrontFormStaticControl())
 | 
			
		||||
@@ -210,6 +210,7 @@ final class PhortuneCartCheckoutController
 | 
			
		||||
      ->appendChild($provider_form);
 | 
			
		||||
 | 
			
		||||
    $crumbs = $this->buildApplicationCrumbs();
 | 
			
		||||
    $crumbs->addTextCrumb(pht('Checkout'));
 | 
			
		||||
    $crumbs->addTextCrumb($title);
 | 
			
		||||
 | 
			
		||||
    return $this->buildApplicationPage(
 | 
			
		||||
 
 | 
			
		||||
@@ -67,4 +67,32 @@ final class PhortuneAccountEditor
 | 
			
		||||
    return parent::applyCustomExternalTransaction($object, $xaction);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected function validateTransaction(
 | 
			
		||||
    PhabricatorLiskDAO $object,
 | 
			
		||||
    $type,
 | 
			
		||||
    array $xactions) {
 | 
			
		||||
 | 
			
		||||
    $errors = parent::validateTransaction($object, $type, $xactions);
 | 
			
		||||
 | 
			
		||||
    switch ($type) {
 | 
			
		||||
      case PhortuneAccountTransaction::TYPE_NAME:
 | 
			
		||||
        $missing = $this->validateIsEmptyTextField(
 | 
			
		||||
          $object->getName(),
 | 
			
		||||
          $xactions);
 | 
			
		||||
 | 
			
		||||
        if ($missing) {
 | 
			
		||||
          $error = new PhabricatorApplicationTransactionValidationError(
 | 
			
		||||
            $type,
 | 
			
		||||
            pht('Required'),
 | 
			
		||||
            pht('Account name is required.'),
 | 
			
		||||
            nonempty(last($xactions), null));
 | 
			
		||||
 | 
			
		||||
          $error->setIsMissingFieldError(true);
 | 
			
		||||
          $errors[] = $error;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return $errors;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,26 @@ final class PhortuneAccountQuery
 | 
			
		||||
  private $phids;
 | 
			
		||||
  private $memberPHIDs;
 | 
			
		||||
 | 
			
		||||
  public static function loadAccountsForUser(
 | 
			
		||||
    PhabricatorUser $user,
 | 
			
		||||
    PhabricatorContentSource $content_source) {
 | 
			
		||||
 | 
			
		||||
    $accounts = id(new PhortuneAccountQuery())
 | 
			
		||||
      ->setViewer($user)
 | 
			
		||||
      ->withMemberPHIDs(array($user->getPHID()))
 | 
			
		||||
      ->execute();
 | 
			
		||||
 | 
			
		||||
    if (!$accounts) {
 | 
			
		||||
      $accounts = array(
 | 
			
		||||
        PhortuneAccount::createNewAccount($user, $content_source),
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $accounts = mpull($accounts, null, 'getPHID');
 | 
			
		||||
 | 
			
		||||
    return $accounts;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public static function loadActiveAccountForUser(
 | 
			
		||||
    PhabricatorUser $user,
 | 
			
		||||
    PhabricatorContentSource $content_source) {
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ final class PhortuneAccount extends PhortuneDAO
 | 
			
		||||
    $xactions = array();
 | 
			
		||||
    $xactions[] = id(new PhortuneAccountTransaction())
 | 
			
		||||
      ->setTransactionType(PhortuneAccountTransaction::TYPE_NAME)
 | 
			
		||||
      ->setNewValue(pht('Account (%s)', $actor->getUserName()));
 | 
			
		||||
      ->setNewValue(pht('Personal Account'));
 | 
			
		||||
 | 
			
		||||
    $xactions[] = id(new PhortuneAccountTransaction())
 | 
			
		||||
      ->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user