Page MenuHomePhabricator

D17579.id.diff
No OneTemporary

D17579.id.diff

diff --git a/resources/sql/autopatches/20170328.account.01.mailkey.sql b/resources/sql/autopatches/20170328.account.01.mailkey.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20170328.account.01.mailkey.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_phortune.phortune_account
+ ADD mailKey binary(20) NOT NULL;
diff --git a/resources/sql/autopatches/20170328.account.02.mailkey.php b/resources/sql/autopatches/20170328.account.02.mailkey.php
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20170328.account.02.mailkey.php
@@ -0,0 +1,18 @@
+<?php
+
+$table = new PhortuneAccount();
+$conn_w = $table->establishConnection('w');
+$iterator = new LiskMigrationIterator($table);
+foreach ($iterator as $account) {
+ $id = $account->getID();
+
+ echo pht('Adding mail key for Phortune Account %d...', $id);
+ echo "\n";
+
+ queryfx(
+ $conn_w,
+ 'UPDATE %T SET mailKey = %s WHERE id = %d',
+ $table->getTableName(),
+ Filesystem::readRandomCharacters(20),
+ $id);
+}
diff --git a/resources/sql/autopatches/20170328.merchant.01.mailkey.sql b/resources/sql/autopatches/20170328.merchant.01.mailkey.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20170328.merchant.01.mailkey.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_phortune.phortune_merchant
+ ADD mailKey binary(20) NOT NULL;
diff --git a/resources/sql/autopatches/20170328.merchant.02.mailkey.php b/resources/sql/autopatches/20170328.merchant.02.mailkey.php
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20170328.merchant.02.mailkey.php
@@ -0,0 +1,18 @@
+<?php
+
+$table = new PhortuneMerchant();
+$conn_w = $table->establishConnection('w');
+$iterator = new LiskMigrationIterator($table);
+foreach ($iterator as $merchant) {
+ $id = $merchant->getID();
+
+ echo pht('Adding mail key for Phortune Merchant %d...', $id);
+ echo "\n";
+
+ queryfx(
+ $conn_w,
+ 'UPDATE %T SET mailKey = %s WHERE id = %d',
+ $table->getTableName(),
+ Filesystem::readRandomCharacters(20),
+ $id);
+}
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -4310,15 +4310,23 @@
'PholioTransactionView' => 'applications/pholio/view/PholioTransactionView.php',
'PholioUploadedImageView' => 'applications/pholio/view/PholioUploadedImageView.php',
'PhortuneAccount' => 'applications/phortune/storage/PhortuneAccount.php',
- 'PhortuneAccountEditController' => 'applications/phortune/controller/PhortuneAccountEditController.php',
+ 'PhortuneAccountAddManagerController' => 'applications/phortune/controller/account/PhortuneAccountAddManagerController.php',
+ 'PhortuneAccountBillingController' => 'applications/phortune/controller/account/PhortuneAccountBillingController.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/PhortuneAccountListController.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',
- 'PhortuneAccountViewController' => 'applications/phortune/controller/PhortuneAccountViewController.php',
+ 'PhortuneAccountTransactionType' => 'applications/phortune/xaction/PhortuneAccountTransactionType.php',
+ 'PhortuneAccountViewController' => 'applications/phortune/controller/account/PhortuneAccountViewController.php',
'PhortuneAdHocCart' => 'applications/phortune/cart/PhortuneAdHocCart.php',
'PhortuneAdHocProduct' => 'applications/phortune/product/PhortuneAdHocProduct.php',
'PhortuneCart' => 'applications/phortune/storage/PhortuneCart.php',
@@ -4356,21 +4364,31 @@
'PhortuneMemberHasAccountEdgeType' => 'applications/phortune/edge/PhortuneMemberHasAccountEdgeType.php',
'PhortuneMemberHasMerchantEdgeType' => 'applications/phortune/edge/PhortuneMemberHasMerchantEdgeType.php',
'PhortuneMerchant' => 'applications/phortune/storage/PhortuneMerchant.php',
+ 'PhortuneMerchantAddManagerController' => 'applications/phortune/controller/merchant/PhortuneMerchantAddManagerController.php',
'PhortuneMerchantCapability' => 'applications/phortune/capability/PhortuneMerchantCapability.php',
- 'PhortuneMerchantController' => 'applications/phortune/controller/PhortuneMerchantController.php',
- 'PhortuneMerchantEditController' => 'applications/phortune/controller/PhortuneMerchantEditController.php',
+ 'PhortuneMerchantContactInfoTransaction' => 'applications/phortune/xaction/PhortuneMerchantContactInfoTransaction.php',
+ 'PhortuneMerchantController' => 'applications/phortune/controller/merchant/PhortuneMerchantController.php',
+ 'PhortuneMerchantDescriptionTransaction' => 'applications/phortune/xaction/PhortuneMerchantDescriptionTransaction.php',
+ 'PhortuneMerchantEditController' => 'applications/phortune/controller/merchant/PhortuneMerchantEditController.php',
'PhortuneMerchantEditEngine' => 'applications/phortune/editor/PhortuneMerchantEditEngine.php',
'PhortuneMerchantEditor' => 'applications/phortune/editor/PhortuneMerchantEditor.php',
'PhortuneMerchantHasMemberEdgeType' => 'applications/phortune/edge/PhortuneMerchantHasMemberEdgeType.php',
- 'PhortuneMerchantInvoiceCreateController' => 'applications/phortune/controller/PhortuneMerchantInvoiceCreateController.php',
- 'PhortuneMerchantListController' => 'applications/phortune/controller/PhortuneMerchantListController.php',
+ 'PhortuneMerchantInvoiceCreateController' => 'applications/phortune/controller/merchant/PhortuneMerchantInvoiceCreateController.php',
+ 'PhortuneMerchantInvoiceEmailTransaction' => 'applications/phortune/xaction/PhortuneMerchantInvoiceEmailTransaction.php',
+ 'PhortuneMerchantInvoiceFooterTransaction' => 'applications/phortune/xaction/PhortuneMerchantInvoiceFooterTransaction.php',
+ 'PhortuneMerchantListController' => 'applications/phortune/controller/merchant/PhortuneMerchantListController.php',
+ 'PhortuneMerchantManagerController' => 'applications/phortune/controller/merchant/PhortuneMerchantManagerController.php',
+ 'PhortuneMerchantNameTransaction' => 'applications/phortune/xaction/PhortuneMerchantNameTransaction.php',
'PhortuneMerchantPHIDType' => 'applications/phortune/phid/PhortuneMerchantPHIDType.php',
- 'PhortuneMerchantPictureController' => 'applications/phortune/controller/PhortuneMerchantPictureController.php',
+ 'PhortuneMerchantPictureController' => 'applications/phortune/controller/merchant/PhortuneMerchantPictureController.php',
+ 'PhortuneMerchantPictureTransaction' => 'applications/phortune/xaction/PhortuneMerchantPictureTransaction.php',
+ 'PhortuneMerchantProfileController' => 'applications/phortune/controller/merchant/PhortuneMerchantProfileController.php',
'PhortuneMerchantQuery' => 'applications/phortune/query/PhortuneMerchantQuery.php',
'PhortuneMerchantSearchEngine' => 'applications/phortune/query/PhortuneMerchantSearchEngine.php',
'PhortuneMerchantTransaction' => 'applications/phortune/storage/PhortuneMerchantTransaction.php',
'PhortuneMerchantTransactionQuery' => 'applications/phortune/query/PhortuneMerchantTransactionQuery.php',
- 'PhortuneMerchantViewController' => 'applications/phortune/controller/PhortuneMerchantViewController.php',
+ 'PhortuneMerchantTransactionType' => 'applications/phortune/xaction/PhortuneMerchantTransactionType.php',
+ 'PhortuneMerchantViewController' => 'applications/phortune/controller/merchant/PhortuneMerchantViewController.php',
'PhortuneMonthYearExpiryControl' => 'applications/phortune/control/PhortuneMonthYearExpiryControl.php',
'PhortuneOrderTableView' => 'applications/phortune/view/PhortuneOrderTableView.php',
'PhortunePayPalPaymentProvider' => 'applications/phortune/provider/PhortunePayPalPaymentProvider.php',
@@ -9739,15 +9757,23 @@
'PhabricatorApplicationTransactionInterface',
'PhabricatorPolicyInterface',
),
+ 'PhortuneAccountAddManagerController' => 'PhortuneController',
+ 'PhortuneAccountBillingController' => 'PhortuneAccountProfileController',
'PhortuneAccountEditController' => 'PhortuneController',
+ 'PhortuneAccountEditEngine' => 'PhabricatorEditEngine',
'PhortuneAccountEditor' => 'PhabricatorApplicationTransactionEditor',
'PhortuneAccountHasMemberEdgeType' => 'PhabricatorEdgeType',
'PhortuneAccountListController' => 'PhortuneController',
+ 'PhortuneAccountManagerController' => 'PhortuneAccountProfileController',
+ 'PhortuneAccountNameTransaction' => 'PhortuneAccountTransactionType',
'PhortuneAccountPHIDType' => 'PhabricatorPHIDType',
+ 'PhortuneAccountProfileController' => 'PhortuneController',
'PhortuneAccountQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
- 'PhortuneAccountTransaction' => 'PhabricatorApplicationTransaction',
+ 'PhortuneAccountSubscriptionController' => 'PhortuneAccountProfileController',
+ 'PhortuneAccountTransaction' => 'PhabricatorModularTransaction',
'PhortuneAccountTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
- 'PhortuneAccountViewController' => 'PhortuneController',
+ 'PhortuneAccountTransactionType' => 'PhabricatorModularTransactionType',
+ 'PhortuneAccountViewController' => 'PhortuneAccountProfileController',
'PhortuneAdHocCart' => 'PhortuneCartImplementation',
'PhortuneAdHocProduct' => 'PhortuneProductImplementation',
'PhortuneCart' => array(
@@ -9796,21 +9822,31 @@
'PhabricatorApplicationTransactionInterface',
'PhabricatorPolicyInterface',
),
+ 'PhortuneMerchantAddManagerController' => 'PhortuneController',
'PhortuneMerchantCapability' => 'PhabricatorPolicyCapability',
+ 'PhortuneMerchantContactInfoTransaction' => 'PhortuneMerchantTransactionType',
'PhortuneMerchantController' => 'PhortuneController',
+ 'PhortuneMerchantDescriptionTransaction' => 'PhortuneMerchantTransactionType',
'PhortuneMerchantEditController' => 'PhortuneMerchantController',
'PhortuneMerchantEditEngine' => 'PhabricatorEditEngine',
'PhortuneMerchantEditor' => 'PhabricatorApplicationTransactionEditor',
'PhortuneMerchantHasMemberEdgeType' => 'PhabricatorEdgeType',
- 'PhortuneMerchantInvoiceCreateController' => 'PhortuneMerchantController',
+ 'PhortuneMerchantInvoiceCreateController' => 'PhortuneMerchantProfileController',
+ 'PhortuneMerchantInvoiceEmailTransaction' => 'PhortuneMerchantTransactionType',
+ 'PhortuneMerchantInvoiceFooterTransaction' => 'PhortuneMerchantTransactionType',
'PhortuneMerchantListController' => 'PhortuneMerchantController',
+ 'PhortuneMerchantManagerController' => 'PhortuneMerchantProfileController',
+ 'PhortuneMerchantNameTransaction' => 'PhortuneMerchantTransactionType',
'PhortuneMerchantPHIDType' => 'PhabricatorPHIDType',
- 'PhortuneMerchantPictureController' => 'PhortuneMerchantController',
+ 'PhortuneMerchantPictureController' => 'PhortuneMerchantProfileController',
+ 'PhortuneMerchantPictureTransaction' => 'PhortuneMerchantTransactionType',
+ 'PhortuneMerchantProfileController' => 'PhortuneController',
'PhortuneMerchantQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhortuneMerchantSearchEngine' => 'PhabricatorApplicationSearchEngine',
- 'PhortuneMerchantTransaction' => 'PhabricatorApplicationTransaction',
+ 'PhortuneMerchantTransaction' => 'PhabricatorModularTransaction',
'PhortuneMerchantTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
- 'PhortuneMerchantViewController' => 'PhortuneMerchantController',
+ 'PhortuneMerchantTransactionType' => 'PhabricatorModularTransactionType',
+ 'PhortuneMerchantViewController' => 'PhortuneMerchantProfileController',
'PhortuneMonthYearExpiryControl' => 'AphrontFormControl',
'PhortuneOrderTableView' => 'AphrontView',
'PhortunePayPalPaymentProvider' => 'PhortunePaymentProvider',
@@ -9818,7 +9854,7 @@
'PhortuneDAO',
'PhabricatorPolicyInterface',
),
- 'PhortunePaymentMethodCreateController' => 'PhortuneController',
+ 'PhortunePaymentMethodCreateController' => 'PhortuneAccountProfileController',
'PhortunePaymentMethodDisableController' => 'PhortuneController',
'PhortunePaymentMethodEditController' => 'PhortuneController',
'PhortunePaymentMethodPHIDType' => 'PhabricatorPHIDType',
diff --git a/src/applications/phortune/application/PhabricatorPhortuneApplication.php b/src/applications/phortune/application/PhabricatorPhortuneApplication.php
--- a/src/applications/phortune/application/PhabricatorPhortuneApplication.php
+++ b/src/applications/phortune/application/PhabricatorPhortuneApplication.php
@@ -67,7 +67,17 @@
),
'account/' => array(
'' => 'PhortuneAccountListController',
- 'edit/(?:(?P<id>\d+)/)?' => 'PhortuneAccountEditController',
+ $this->getEditRoutePattern('edit/')
+ => 'PhortuneAccountEditController',
+ 'add/manager/(?:(?P<id>\d+)/)?'
+ => 'PhortuneAccountAddManagerController',
+ 'billing/(?:(?P<id>\d+)/)?' => 'PhortuneAccountBillingController',
+ 'subscription/(?:(?P<id>\d+)/)?'
+ => 'PhortuneAccountSubscriptionController',
+ 'manager/' => array(
+ '(?:(?P<id>\d+)/)?' => 'PhortuneAccountManagerController',
+ 'add/(?:(?P<id>\d+)/)?' => 'PhortuneAccountAddManagerController',
+ ),
),
'product/' => array(
'' => 'PhortuneProductListController',
@@ -87,6 +97,10 @@
=> 'PhortuneMerchantEditController',
'orders/(?P<merchantID>\d+)/(?:query/(?P<queryKey>[^/]+)/)?'
=> 'PhortuneCartListController',
+ 'manager/' => array(
+ '(?:(?P<id>\d+)/)?' => 'PhortuneMerchantManagerController',
+ 'add/(?:(?P<id>\d+)/)?' => 'PhortuneMerchantAddManagerController',
+ ),
'(?P<merchantID>\d+)/' => array(
'cart/(?P<id>\d+)/' => array(
'' => 'PhortuneCartViewController',
diff --git a/src/applications/phortune/controller/PhortuneAccountEditController.php b/src/applications/phortune/controller/PhortuneAccountEditController.php
deleted file mode 100644
--- a/src/applications/phortune/controller/PhortuneAccountEditController.php
+++ /dev/null
@@ -1,137 +0,0 @@
-<?php
-
-final class PhortuneAccountEditController extends PhortuneController {
-
- public function handleRequest(AphrontRequest $request) {
- $viewer = $request->getViewer();
- $id = $request->getURIData('id');
-
- if ($id) {
- $account = id(new PhortuneAccountQuery())
- ->setViewer($viewer)
- ->withIDs(array($id))
- ->requireCapabilities(
- array(
- PhabricatorPolicyCapability::CAN_VIEW,
- PhabricatorPolicyCapability::CAN_EDIT,
- ))
- ->executeOne();
- if (!$account) {
- return new Aphront404Response();
- }
- $is_new = false;
- } else {
- $account = PhortuneAccount::initializeNewAccount($viewer);
- $account->attachMemberPHIDs(array($viewer->getPHID()));
- $is_new = true;
- }
-
- $v_name = $account->getName();
- $e_name = true;
-
- $v_members = $account->getMemberPHIDs();
- $e_members = null;
-
- $validation_exception = null;
-
- if ($request->isFormPost()) {
- $v_name = $request->getStr('name');
- $v_members = $request->getArr('memberPHIDs');
-
- $type_name = PhortuneAccountTransaction::TYPE_NAME;
- $type_edge = PhabricatorTransactions::TYPE_EDGE;
-
- $xactions = array();
- $xactions[] = id(new PhortuneAccountTransaction())
- ->setTransactionType($type_name)
- ->setNewValue($v_name);
-
- $xactions[] = id(new PhortuneAccountTransaction())
- ->setTransactionType($type_edge)
- ->setMetadataValue(
- 'edge:type',
- PhortuneAccountHasMemberEdgeType::EDGECONST)
- ->setNewValue(
- array(
- '=' => array_fuse($v_members),
- ));
-
- $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);
- $e_members = $ex->getShortMessage($type_edge);
- }
- }
-
- $crumbs = $this->buildApplicationCrumbs();
- $crumbs->setBorder(true);
-
- 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))
- ->appendControl(
- id(new AphrontFormTokenizerControl())
- ->setDatasource(new PhabricatorPeopleDatasource())
- ->setLabel(pht('Members'))
- ->setName('memberPHIDs')
- ->setValue($v_members)
- ->setError($e_members))
- ->appendChild(
- id(new AphrontFormSubmitControl())
- ->setValue($submit_button)
- ->addCancelButton($cancel_uri));
-
- $box = id(new PHUIObjectBoxView())
- ->setHeaderText(pht('Account'))
- ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
- ->setValidationException($validation_exception)
- ->setForm($form);
-
- $header = id(new PHUIHeaderView())
- ->setHeader($title)
- ->setHeaderIcon('fa-pencil');
-
- $view = id(new PHUITwoColumnView())
- ->setHeader($header)
- ->setFooter(array(
- $box,
- ));
-
- return $this->newPage()
- ->setTitle($title)
- ->setCrumbs($crumbs)
- ->appendChild($view);
- }
-
-}
diff --git a/src/applications/phortune/controller/PhortunePaymentMethodCreateController.php b/src/applications/phortune/controller/PhortunePaymentMethodCreateController.php
--- a/src/applications/phortune/controller/PhortunePaymentMethodCreateController.php
+++ b/src/applications/phortune/controller/PhortunePaymentMethodCreateController.php
@@ -1,7 +1,7 @@
<?php
final class PhortunePaymentMethodCreateController
- extends PhortuneController {
+ extends PhortuneAccountProfileController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
@@ -14,13 +14,24 @@
if (!$account) {
return new Aphront404Response();
}
- $account_id = $account->getID();
+ $this->setAccount($account);
+ // Try an individual merchant first
$merchant = id(new PhortuneMerchantQuery())
->setViewer($viewer)
->withIDs(array($request->getInt('merchantID')))
->executeOne();
+
+ // If none passed in, see if only 1 exists
if (!$merchant) {
+ $merchants = id(new PhortuneMerchantQuery())
+ ->setViewer($viewer)
+ ->execute();
+ if (count($merchants) == 1) {
+ $merchant = head($merchants);
+ }
+ } else {
+ // Allow user to select a merchant from a dropdown?
return new Aphront404Response();
}
@@ -32,7 +43,7 @@
$cancel_uri = $this->getApplicationURI(
"{$account_id}/subscription/edit/{$subscription_id}/");
} else {
- $cancel_uri = $this->getApplicationURI($account->getID().'/');
+ $cancel_uri = $this->getApplicationURI("account/billing/{$account_id}/");
}
$providers = $this->loadCreatePaymentMethodProvidersForMerchant($merchant);
@@ -125,9 +136,8 @@
} else if ($subscription_id) {
$next_uri = $cancel_uri;
} else {
- $account_uri = $this->getApplicationURI($account->getID().'/');
- $next_uri = new PhutilURI($account_uri);
- $next_uri->setFragment('payment');
+ $next_uri = $this->getApplicationURI(
+ "account/billing/{$account_id}/");
}
return id(new AphrontRedirectResponse())->setURI($next_uri);
@@ -158,17 +168,15 @@
->addCancelButton($cancel_uri));
$box = id(new PHUIObjectBoxView())
- ->setHeaderText(pht('Method'))
+ ->setHeaderText(pht('Add Payment Method'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setForm($form);
$crumbs = $this->buildApplicationCrumbs();
+ $crumbs->addTextCrumb($account->getName());
$crumbs->addTextCrumb(pht('Add Payment Method'));
- $crumbs->setBorder(true);
- $header = id(new PHUIHeaderView())
- ->setHeader(pht('Add Payment Method'))
- ->setHeaderIcon('fa-plus-square');
+ $header = $this->buildHeaderView();
$view = id(new PHUITwoColumnView())
->setHeader($header)
diff --git a/src/applications/phortune/controller/PhortunePaymentMethodDisableController.php b/src/applications/phortune/controller/PhortunePaymentMethodDisableController.php
--- a/src/applications/phortune/controller/PhortunePaymentMethodDisableController.php
+++ b/src/applications/phortune/controller/PhortunePaymentMethodDisableController.php
@@ -25,7 +25,8 @@
}
$account = $method->getAccount();
- $account_uri = $this->getApplicationURI($account->getID().'/');
+ $account_id = $account->getID();
+ $account_uri = $this->getApplicationURI("account/billing/{$account_id}/");
if ($request->isFormPost()) {
diff --git a/src/applications/phortune/controller/PhortuneSubscriptionEditController.php b/src/applications/phortune/controller/PhortuneSubscriptionEditController.php
--- a/src/applications/phortune/controller/PhortuneSubscriptionEditController.php
+++ b/src/applications/phortune/controller/PhortuneSubscriptionEditController.php
@@ -111,7 +111,8 @@
$crumbs->addTextCrumb(
pht('Subscription %d', $subscription->getID()),
$view_uri);
- $crumbs->addTextCrumb(pht('Edit'));
+ $crumbs->addTextCrumb(pht('Manage'));
+ $crumbs->setBorder(true);
$uri = $this->getApplicationURI($account->getID().'/card/new/');
@@ -152,7 +153,7 @@
->appendChild($form);
$header = id(new PHUIHeaderView())
- ->setHeader(pht('Edit %s', $subscription->getSubscriptionName()))
+ ->setHeader(pht('Manage: %s', $subscription->getSubscriptionName()))
->setHeaderIcon('fa-pencil');
$view = id(new PHUITwoColumnView())
diff --git a/src/applications/phortune/controller/PhortuneSubscriptionViewController.php b/src/applications/phortune/controller/PhortuneSubscriptionViewController.php
--- a/src/applications/phortune/controller/PhortuneSubscriptionViewController.php
+++ b/src/applications/phortune/controller/PhortuneSubscriptionViewController.php
@@ -36,7 +36,7 @@
$header = id(new PHUIHeaderView())
->setHeader($title)
- ->setHeaderIcon('fa-calendar-o');
+ ->setHeaderIcon('fa-retweet');
$curtain = $this->newCurtainView($subscription);
$edit_uri = $subscription->getEditURI();
@@ -44,7 +44,7 @@
$curtain->addAction(
id(new PhabricatorActionView())
->setIcon('fa-pencil')
- ->setName(pht('Edit Subscription'))
+ ->setName(pht('Manage Payment'))
->setHref($edit_uri)
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
@@ -55,6 +55,7 @@
} else {
$this->addAccountCrumb($crumbs, $account);
}
+ $crumbs->addTextCrumb(pht('Subscription'));
$crumbs->addTextCrumb($subscription->getSubscriptionCrumbName());
$crumbs->setBorder(true);
diff --git a/src/applications/phortune/controller/account/PhortuneAccountAddManagerController.php b/src/applications/phortune/controller/account/PhortuneAccountAddManagerController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/controller/account/PhortuneAccountAddManagerController.php
@@ -0,0 +1,75 @@
+<?php
+
+final class PhortuneAccountAddManagerController extends PhortuneController {
+
+ public function handleRequest(AphrontRequest $request) {
+ $viewer = $request->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_members = array();
+ $e_members = null;
+ $account_uri = $this->getApplicationURI("/account/manager/{$id}/");
+
+ if ($request->isFormPost()) {
+ $xactions = array();
+ $v_members = $request->getArr('memberPHIDs');
+ $type_edge = PhabricatorTransactions::TYPE_EDGE;
+
+ $xactions[] = id(new PhortuneAccountTransaction())
+ ->setTransactionType($type_edge)
+ ->setMetadataValue(
+ 'edge:type',
+ PhortuneAccountHasMemberEdgeType::EDGECONST)
+ ->setNewValue(
+ array(
+ '+' => array_fuse($v_members),
+ ));
+
+ $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_members = $ex->getShortMessage($type_edge);
+ }
+ }
+
+ $form = id(new AphrontFormView())
+ ->setUser($viewer)
+ ->appendControl(
+ id(new AphrontFormTokenizerControl())
+ ->setDatasource(new PhabricatorPeopleDatasource())
+ ->setLabel(pht('Members'))
+ ->setName('memberPHIDs')
+ ->setValue($v_members)
+ ->setError($e_members));
+
+ 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
--- /dev/null
+++ b/src/applications/phortune/controller/account/PhortuneAccountBillingController.php
@@ -0,0 +1,179 @@
+<?php
+
+final class PhortuneAccountBillingController
+ extends PhortuneAccountProfileController {
+
+ public function handleRequest(AphrontRequest $request) {
+ $viewer = $this->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'))
+ ->addActionLink($add);
+
+ $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('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);
+ }
+
+}
diff --git a/src/applications/phortune/controller/account/PhortuneAccountEditController.php b/src/applications/phortune/controller/account/PhortuneAccountEditController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/controller/account/PhortuneAccountEditController.php
@@ -0,0 +1,10 @@
+<?php
+
+final class PhortuneAccountEditController extends
+ PhortuneController {
+ public function handleRequest(AphrontRequest $request) {
+ return id(new PhortuneAccountEditEngine())
+ ->setController($this)
+ ->buildResponse();
+ }
+}
diff --git a/src/applications/phortune/controller/PhortuneAccountListController.php b/src/applications/phortune/controller/account/PhortuneAccountListController.php
rename from src/applications/phortune/controller/PhortuneAccountListController.php
rename to src/applications/phortune/controller/account/PhortuneAccountListController.php
--- a/src/applications/phortune/controller/PhortuneAccountListController.php
+++ b/src/applications/phortune/controller/account/PhortuneAccountListController.php
@@ -18,6 +18,7 @@
$merchants = id(new PhortuneMerchantQuery())
->setViewer($viewer)
->withMemberPHIDs(array($viewer->getPHID()))
+ ->needProfileImage(true)
->execute();
$title = pht('Accounts');
@@ -39,7 +40,7 @@
->setHeader($account->getName())
->setHref($this->getApplicationURI($account->getID().'/'))
->setObject($account)
- ->setImageIcon('fa-credit-card');
+ ->setImageIcon('fa-user-circle');
$payment_list->addItem($item);
}
@@ -71,7 +72,7 @@
->setHeader($merchant->getName())
->setHref($this->getApplicationURI('/merchant/'.$merchant->getID().'/'))
->setObject($merchant)
- ->setImageIcon('fa-bank');
+ ->setImageURI($merchant->getProfileImageURI());
$merchant_list->addItem($item);
}
diff --git a/src/applications/phortune/controller/account/PhortuneAccountManagerController.php b/src/applications/phortune/controller/account/PhortuneAccountManagerController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/controller/account/PhortuneAccountManagerController.php
@@ -0,0 +1,101 @@
+<?php
+
+final class PhortuneAccountManagerController
+ extends PhortuneAccountProfileController {
+
+ public function handleRequest(AphrontRequest $request) {
+ $viewer = $this->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
--- /dev/null
+++ b/src/applications/phortune/controller/account/PhortuneAccountProfileController.php
@@ -0,0 +1,84 @@
+<?php
+
+abstract class PhortuneAccountProfileController
+ extends PhortuneController {
+
+ private $account;
+
+ public function setAccount(PhortuneAccount $account) {
+ $this->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'),
+ $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
--- /dev/null
+++ b/src/applications/phortune/controller/account/PhortuneAccountSubscriptionController.php
@@ -0,0 +1,79 @@
+<?php
+
+final class PhortuneAccountSubscriptionController
+ extends PhortuneAccountProfileController {
+
+ public function handleRequest(AphrontRequest $request) {
+ $viewer = $this->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/PhortuneAccountViewController.php b/src/applications/phortune/controller/account/PhortuneAccountViewController.php
rename from src/applications/phortune/controller/PhortuneAccountViewController.php
rename to src/applications/phortune/controller/account/PhortuneAccountViewController.php
--- a/src/applications/phortune/controller/PhortuneAccountViewController.php
+++ b/src/applications/phortune/controller/account/PhortuneAccountViewController.php
@@ -1,9 +1,11 @@
<?php
-final class PhortuneAccountViewController extends PhortuneController {
+final class PhortuneAccountViewController
+ extends PhortuneAccountProfileController {
public function handleRequest(AphrontRequest $request) {
$viewer = $this->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 @@
$account = id(new PhortuneAccountQuery())
->setViewer($viewer)
- ->withIDs(array($request->getURIData('accountID')))
+ ->withIDs(array($id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
@@ -25,6 +27,7 @@
return new Aphront404Response();
}
+ $this->setAccount($account);
$title = $account->getName();
$invoices = id(new PhortuneCartQuery())
@@ -35,19 +38,14 @@
->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 @@
->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 @@
->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);
@@ -125,89 +122,12 @@
}
$curtain->newPanel()
- ->setHeaderText(pht('Status'))
- ->appendChild($status_view);
-
- $curtain->newPanel()
- ->setHeaderText(pht('Members'))
+ ->setHeaderText(pht('Managers'))
->appendChild($member_list);
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 @@
->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,24 +224,31 @@
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 {
+ }
+
+ if (!$methods) {
$items[] = array(
- 'icon' => PHUIStatusItemView::ICON_ACCEPT,
- 'color' => 'green',
- 'target' => pht('Invoices'),
- 'note' => pht('This account has no unpaid invoices.'),
+ 'severity' => PHUIInfoView::SEVERITY_NOTICE,
+ 'note' => pht('No payment methods are associated with this account.'),
);
}
diff --git a/src/applications/phortune/controller/merchant/PhortuneMerchantAddManagerController.php b/src/applications/phortune/controller/merchant/PhortuneMerchantAddManagerController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/controller/merchant/PhortuneMerchantAddManagerController.php
@@ -0,0 +1,76 @@
+<?php
+
+final class PhortuneMerchantAddManagerController extends PhortuneController {
+
+ public function handleRequest(AphrontRequest $request) {
+ $viewer = $request->getViewer();
+ $id = $request->getURIData('id');
+
+ $merchant = id(new PhortuneMerchantQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($id))
+ ->needProfileImage(true)
+ ->requireCapabilities(
+ array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
+ ))
+ ->executeOne();
+ if (!$merchant) {
+ return new Aphront404Response();
+ }
+
+ $v_members = array();
+ $e_members = null;
+ $merchant_uri = $this->getApplicationURI("/merchant/manager/{$id}/");
+
+ if ($request->isFormPost()) {
+ $xactions = array();
+ $v_members = $request->getArr('memberPHIDs');
+ $type_edge = PhabricatorTransactions::TYPE_EDGE;
+
+ $xactions[] = id(new PhortuneMerchantTransaction())
+ ->setTransactionType($type_edge)
+ ->setMetadataValue(
+ 'edge:type',
+ PhortuneMerchantHasMemberEdgeType::EDGECONST)
+ ->setNewValue(
+ array(
+ '+' => array_fuse($v_members),
+ ));
+
+ $editor = id(new PhortuneMerchantEditor())
+ ->setActor($viewer)
+ ->setContentSourceFromRequest($request)
+ ->setContinueOnNoEffect(true);
+
+ try {
+ $editor->applyTransactions($merchant, $xactions);
+
+ return id(new AphrontRedirectResponse())->setURI($merchant_uri);
+ } catch (PhabricatorApplicationTransactionValidationException $ex) {
+ $validation_exception = $ex;
+ $e_members = $ex->getShortMessage($type_edge);
+ }
+ }
+
+ $form = id(new AphrontFormView())
+ ->setUser($viewer)
+ ->appendControl(
+ id(new AphrontFormTokenizerControl())
+ ->setDatasource(new PhabricatorPeopleDatasource())
+ ->setLabel(pht('Members'))
+ ->setName('memberPHIDs')
+ ->setValue($v_members)
+ ->setError($e_members));
+
+ return $this->newDialog()
+ ->setTitle(pht('Add New Manager'))
+ ->appendForm($form)
+ ->setWidth(AphrontDialogView::WIDTH_FORM)
+ ->addCancelButton($merchant_uri)
+ ->addSubmitButton(pht('Add Manager'));
+
+ }
+
+}
diff --git a/src/applications/phortune/controller/PhortuneMerchantController.php b/src/applications/phortune/controller/merchant/PhortuneMerchantController.php
rename from src/applications/phortune/controller/PhortuneMerchantController.php
rename to src/applications/phortune/controller/merchant/PhortuneMerchantController.php
diff --git a/src/applications/phortune/controller/PhortuneMerchantEditController.php b/src/applications/phortune/controller/merchant/PhortuneMerchantEditController.php
rename from src/applications/phortune/controller/PhortuneMerchantEditController.php
rename to src/applications/phortune/controller/merchant/PhortuneMerchantEditController.php
diff --git a/src/applications/phortune/controller/PhortuneMerchantInvoiceCreateController.php b/src/applications/phortune/controller/merchant/PhortuneMerchantInvoiceCreateController.php
rename from src/applications/phortune/controller/PhortuneMerchantInvoiceCreateController.php
rename to src/applications/phortune/controller/merchant/PhortuneMerchantInvoiceCreateController.php
--- a/src/applications/phortune/controller/PhortuneMerchantInvoiceCreateController.php
+++ b/src/applications/phortune/controller/merchant/PhortuneMerchantInvoiceCreateController.php
@@ -1,7 +1,7 @@
<?php
final class PhortuneMerchantInvoiceCreateController
- extends PhortuneMerchantController {
+ extends PhortuneMerchantProfileController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getUser();
@@ -11,6 +11,7 @@
return new Aphront404Response();
}
+ $this->setMerchant($merchant);
$merchant_id = $merchant->getID();
$cancel_uri = $this->getApplicationURI("/merchant/{$merchant_id}/");
@@ -88,8 +89,7 @@
$title = pht('New Invoice');
$crumbs = $this->buildApplicationCrumbs();
- $crumbs->addTextCrumb($merchant->getName());
- $crumbs->setBorder(true);
+ $crumbs->addTextCrumb($title);
$v_title = $request->getStr('title');
$e_title = true;
@@ -245,9 +245,12 @@
$box,
));
+ $navigation = $this->buildSideNavView('orders');
+
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
+ ->setNavigation($navigation)
->appendChild($view);
}
diff --git a/src/applications/phortune/controller/PhortuneMerchantListController.php b/src/applications/phortune/controller/merchant/PhortuneMerchantListController.php
rename from src/applications/phortune/controller/PhortuneMerchantListController.php
rename to src/applications/phortune/controller/merchant/PhortuneMerchantListController.php
diff --git a/src/applications/phortune/controller/merchant/PhortuneMerchantManagerController.php b/src/applications/phortune/controller/merchant/PhortuneMerchantManagerController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/controller/merchant/PhortuneMerchantManagerController.php
@@ -0,0 +1,91 @@
+<?php
+
+final class PhortuneMerchantManagerController
+ extends PhortuneMerchantProfileController {
+
+ public function handleRequest(AphrontRequest $request) {
+ $viewer = $request->getViewer();
+ $id = $request->getURIData('id');
+
+ $merchant = id(new PhortuneMerchantQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($id))
+ ->needProfileImage(true)
+ ->executeOne();
+ if (!$merchant) {
+ return new Aphront404Response();
+ }
+
+ $this->setMerchant($merchant);
+ $header = $this->buildHeaderView();
+
+ $crumbs = $this->buildApplicationCrumbs();
+ $crumbs->addTextCrumb(pht('Managers'));
+
+ $header = $this->buildHeaderView();
+ $members = $this->buildMembersSection($merchant);
+
+ $view = id(new PHUITwoColumnView())
+ ->setHeader($header)
+ ->setFooter(array(
+ $members,
+ ));
+
+ $navigation = $this->buildSideNavView('managers');
+
+ return $this->newPage()
+ ->setTitle(pht('Managers'))
+ ->setCrumbs($crumbs)
+ ->setNavigation($navigation)
+ ->appendChild($view);
+
+ }
+
+ private function buildMembersSection(PhortuneMerchant $merchant) {
+ $viewer = $this->getViewer();
+
+ $can_edit = PhabricatorPolicyFilter::hasCapability(
+ $viewer,
+ $merchant,
+ PhabricatorPolicyCapability::CAN_EDIT);
+
+ $id = $merchant->getID();
+
+ $add = id(new PHUIButtonView())
+ ->setTag('a')
+ ->setText(pht('New Manager'))
+ ->setIcon('fa-plus')
+ ->setWorkflow(true)
+ ->setHref("/phortune/merchant/manager/add/{$id}/");
+
+ $header = id(new PHUIHeaderView())
+ ->setHeader(pht('Merchant Account Managers'))
+ ->addActionLink($add);
+
+ $list = id(new PHUIObjectItemListView())
+ ->setUser($viewer);
+
+ $member_phids = $merchant->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('Merchant Manager'));
+
+ $list->addItem($member);
+ }
+
+ return id(new PHUIObjectBoxView())
+ ->setHeader($header)
+ ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
+ ->setObjectList($list);
+ }
+
+}
diff --git a/src/applications/phortune/controller/PhortuneMerchantPictureController.php b/src/applications/phortune/controller/merchant/PhortuneMerchantPictureController.php
rename from src/applications/phortune/controller/PhortuneMerchantPictureController.php
rename to src/applications/phortune/controller/merchant/PhortuneMerchantPictureController.php
--- a/src/applications/phortune/controller/PhortuneMerchantPictureController.php
+++ b/src/applications/phortune/controller/merchant/PhortuneMerchantPictureController.php
@@ -1,7 +1,7 @@
<?php
final class PhortuneMerchantPictureController
- extends PhortuneMerchantController {
+ extends PhortuneMerchantProfileController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
@@ -21,6 +21,7 @@
return new Aphront404Response();
}
+ $this->setMerchant($merchant);
$uri = $merchant->getViewURI();
$supported_formats = PhabricatorFile::getTransformableImageFormats();
@@ -76,7 +77,8 @@
$xactions = array();
$xactions[] = id(new PhortuneMerchantTransaction())
- ->setTransactionType(PhortuneMerchantTransaction::TYPE_PICTURE)
+ ->setTransactionType(
+ PhortuneMerchantPictureTransaction::TRANSACTIONTYPE)
->setNewValue($new_value);
$editor = id(new PhortuneMerchantEditor())
@@ -91,7 +93,7 @@
}
}
- $title = pht('Edit Merchant Picture');
+ $title = pht('Edit Logo');
$form = id(new PHUIFormLayoutView())
->setUser($viewer);
@@ -207,12 +209,10 @@
->setForm($upload_form);
$crumbs = $this->buildApplicationCrumbs();
- $crumbs->addTextCrumb($merchant->getName(), $uri);
- $crumbs->addTextCrumb(pht('Merchant Logo'));
- $crumbs->setBorder(true);
+ $crumbs->addTextCrumb(pht('Edit Logo'));
$header = id(new PHUIHeaderView())
- ->setHeader(pht('Edit Merchant Logo'))
+ ->setHeader(pht('Edit Logo'))
->setHeaderIcon('fa-camera');
$view = id(new PHUITwoColumnView())
@@ -222,9 +222,12 @@
$upload_box,
));
+ $navigation = $this->buildSideNavView();
+
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
+ ->setNavigation($navigation)
->appendChild(
array(
$view,
diff --git a/src/applications/phortune/controller/merchant/PhortuneMerchantProfileController.php b/src/applications/phortune/controller/merchant/PhortuneMerchantProfileController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/controller/merchant/PhortuneMerchantProfileController.php
@@ -0,0 +1,92 @@
+<?php
+
+abstract class PhortuneMerchantProfileController
+ extends PhortuneController {
+
+ private $merchant;
+
+ public function setMerchant(PhortuneMerchant $merchant) {
+ $this->merchant = $merchant;
+ return $this;
+ }
+
+ public function getMerchant() {
+ return $this->merchant;
+ }
+
+ public function buildApplicationMenu() {
+ return $this->buildSideNavView()->getMenu();
+ }
+
+ protected function buildHeaderView() {
+ $viewer = $this->getViewer();
+ $merchant = $this->getMerchant();
+ $title = $merchant->getName();
+
+ $header = id(new PHUIHeaderView())
+ ->setHeader($title)
+ ->setUser($viewer)
+ ->setPolicyObject($merchant)
+ ->setImage($merchant->getProfileImageURI());
+
+ return $header;
+ }
+
+ protected function buildApplicationCrumbs() {
+ $merchant = $this->getMerchant();
+ $id = $merchant->getID();
+ $merchant_uri = $this->getApplicationURI("/merchant/{$id}/");
+
+ $crumbs = parent::buildApplicationCrumbs();
+ $crumbs->addTextCrumb($merchant->getName(), $merchant_uri);
+ $crumbs->setBorder(true);
+ return $crumbs;
+ }
+
+ protected function buildSideNavView($filter = null) {
+ $viewer = $this->getViewer();
+ $merchant = $this->getMerchant();
+ $id = $merchant->getID();
+
+ $can_edit = PhabricatorPolicyFilter::hasCapability(
+ $viewer,
+ $merchant,
+ PhabricatorPolicyCapability::CAN_EDIT);
+
+ $nav = id(new AphrontSideNavFilterView())
+ ->setBaseURI(new PhutilURI($this->getApplicationURI()));
+
+ $nav->addLabel(pht('Merchant'));
+
+ $nav->addFilter(
+ 'overview',
+ pht('Overview'),
+ $this->getApplicationURI("/merchant/{$id}/"),
+ 'fa-building-o');
+
+ if ($can_edit) {
+ $nav->addFilter(
+ 'orders',
+ pht('Orders'),
+ $this->getApplicationURI("merchant/orders/{$id}/"),
+ 'fa-retweet');
+
+ $nav->addFilter(
+ 'subscriptions',
+ pht('Subscriptions'),
+ $this->getApplicationURI("merchant/{$id}/subscription/"),
+ 'fa-shopping-cart');
+
+ $nav->addFilter(
+ 'managers',
+ pht('Managers'),
+ $this->getApplicationURI("/merchant/manager/{$id}/"),
+ 'fa-group');
+ }
+
+ $nav->selectFilter($filter);
+
+ return $nav;
+ }
+
+}
diff --git a/src/applications/phortune/controller/PhortuneMerchantViewController.php b/src/applications/phortune/controller/merchant/PhortuneMerchantViewController.php
rename from src/applications/phortune/controller/PhortuneMerchantViewController.php
rename to src/applications/phortune/controller/merchant/PhortuneMerchantViewController.php
--- a/src/applications/phortune/controller/PhortuneMerchantViewController.php
+++ b/src/applications/phortune/controller/merchant/PhortuneMerchantViewController.php
@@ -1,7 +1,7 @@
<?php
final class PhortuneMerchantViewController
- extends PhortuneMerchantController {
+ extends PhortuneMerchantProfileController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
@@ -16,21 +16,15 @@
return new Aphront404Response();
}
+ $this->setMerchant($merchant);
$crumbs = $this->buildApplicationCrumbs();
- $crumbs->addTextCrumb($merchant->getName());
- $crumbs->setBorder(true);
+ $header = $this->buildHeaderView();
$title = pht(
'Merchant %d %s',
$merchant->getID(),
$merchant->getName());
- $header = id(new PHUIHeaderView())
- ->setHeader($merchant->getName())
- ->setUser($viewer)
- ->setPolicyObject($merchant)
- ->setImage($merchant->getProfileImageURI());
-
$providers = id(new PhortunePaymentProviderConfigQuery())
->setViewer($viewer)
->withMerchantPHIDs(array($merchant->getPHID()))
@@ -48,6 +42,8 @@
new PhortuneMerchantTransactionQuery());
$timeline->setShouldTerminate(true);
+ $navigation = $this->buildSideNavView('overview');
+
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
@@ -60,6 +56,7 @@
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
+ ->setNavigation($navigation)
->appendChild($view);
}
@@ -198,22 +195,6 @@
$curtain->addAction(
id(new PhabricatorActionView())
- ->setName(pht('View Orders'))
- ->setIcon('fa-shopping-cart')
- ->setHref($this->getApplicationURI("merchant/orders/{$id}/"))
- ->setDisabled(!$can_edit)
- ->setWorkflow(!$can_edit));
-
- $curtain->addAction(
- id(new PhabricatorActionView())
- ->setName(pht('View Subscriptions'))
- ->setIcon('fa-moon-o')
- ->setHref($this->getApplicationURI("merchant/{$id}/subscription/"))
- ->setDisabled(!$can_edit)
- ->setWorkflow(!$can_edit));
-
- $curtain->addAction(
- id(new PhabricatorActionView())
->setName(pht('New Invoice'))
->setIcon('fa-fax')
->setHref($this->getApplicationURI("merchant/{$id}/invoice/new/"))
@@ -240,7 +221,7 @@
}
$curtain->newPanel()
- ->setHeaderText(pht('Members'))
+ ->setHeaderText(pht('Managers'))
->appendChild($member_list);
return $curtain;
diff --git a/src/applications/phortune/edge/PhortuneAccountHasMemberEdgeType.php b/src/applications/phortune/edge/PhortuneAccountHasMemberEdgeType.php
--- a/src/applications/phortune/edge/PhortuneAccountHasMemberEdgeType.php
+++ b/src/applications/phortune/edge/PhortuneAccountHasMemberEdgeType.php
@@ -14,7 +14,7 @@
$add_edges) {
return pht(
- '%s added %s account member(s): %s.',
+ '%s added %s account manager(s): %s.',
$actor,
$add_count,
$add_edges);
@@ -26,7 +26,7 @@
$rem_edges) {
return pht(
- '%s removed %s account member(s): %s.',
+ '%s removed %s account manager(s): %s.',
$actor,
$rem_count,
$rem_edges);
@@ -41,7 +41,7 @@
$rem_edges) {
return pht(
- '%s edited %s account member(s), added %s: %s; removed %s: %s.',
+ '%s edited %s account manager(s), added %s: %s; removed %s: %s.',
$actor,
$total_count,
$add_count,
@@ -57,7 +57,7 @@
$add_edges) {
return pht(
- '%s added %s account member(s) to %s: %s.',
+ '%s added %s account manager(s) to %s: %s.',
$actor,
$add_count,
$object,
@@ -71,7 +71,7 @@
$rem_edges) {
return pht(
- '%s removed %s account member(s) from %s: %s.',
+ '%s removed %s account manager(s) from %s: %s.',
$actor,
$rem_count,
$object,
@@ -88,7 +88,7 @@
$rem_edges) {
return pht(
- '%s edited %s account member(s) for %s, added %s: %s; removed %s: %s.',
+ '%s edited %s account manager(s) for %s, added %s: %s; removed %s: %s.',
$actor,
$total_count,
$object,
diff --git a/src/applications/phortune/edge/PhortuneMerchantHasMemberEdgeType.php b/src/applications/phortune/edge/PhortuneMerchantHasMemberEdgeType.php
--- a/src/applications/phortune/edge/PhortuneMerchantHasMemberEdgeType.php
+++ b/src/applications/phortune/edge/PhortuneMerchantHasMemberEdgeType.php
@@ -14,7 +14,7 @@
$add_edges) {
return pht(
- '%s added %s merchant member(s): %s.',
+ '%s added %s merchant manager(s): %s.',
$actor,
$add_count,
$add_edges);
@@ -26,7 +26,7 @@
$rem_edges) {
return pht(
- '%s removed %s merchant member(s): %s.',
+ '%s removed %s merchant manager(s): %s.',
$actor,
$rem_count,
$rem_edges);
@@ -41,7 +41,7 @@
$rem_edges) {
return pht(
- '%s edited %s merchant member(s), added %s: %s; removed %s: %s.',
+ '%s edited %s merchant manager(s), added %s: %s; removed %s: %s.',
$actor,
$total_count,
$add_count,
@@ -57,7 +57,7 @@
$add_edges) {
return pht(
- '%s added %s merchant member(s) to %s: %s.',
+ '%s added %s merchant manager(s) to %s: %s.',
$actor,
$add_count,
$object,
@@ -71,7 +71,7 @@
$rem_edges) {
return pht(
- '%s removed %s merchant member(s) from %s: %s.',
+ '%s removed %s merchant manager(s) from %s: %s.',
$actor,
$rem_count,
$object,
@@ -88,7 +88,7 @@
$rem_edges) {
return pht(
- '%s edited %s merchant member(s) for %s, added %s: %s; removed %s: %s.',
+ '%s edited %s merchant manager(s) for %s, added %s: %s; removed %s: %s.',
$actor,
$total_count,
$object,
diff --git a/src/applications/phortune/editor/PhortuneAccountEditEngine.php b/src/applications/phortune/editor/PhortuneAccountEditEngine.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/editor/PhortuneAccountEditEngine.php
@@ -0,0 +1,108 @@
+<?php
+
+final class PhortuneAccountEditEngine
+ extends PhabricatorEditEngine {
+
+ const ENGINECONST = 'phortune.account';
+
+ public function getEngineName() {
+ return pht('Phortune Accounts');
+ }
+
+ public function getEngineApplicationClass() {
+ return 'PhabricatorPhortuneApplication';
+ }
+
+ public function getSummaryHeader() {
+ return pht('Configure Phortune Account Forms');
+ }
+
+ public function getSummaryText() {
+ return pht('Configure creation and editing forms in Phortune Accounts.');
+ }
+
+ public function isEngineConfigurable() {
+ return false;
+ }
+
+ protected function newEditableObject() {
+ return PhortuneAccount::initializeNewAccount($this->getViewer());
+ }
+
+ protected function newObjectQuery() {
+ return new PhortuneAccountQuery();
+ }
+
+ protected function getObjectCreateTitleText($object) {
+ return pht('Create Payment Account');
+ }
+
+ protected function getObjectEditTitleText($object) {
+ return pht('Edit Account: %s', $object->getName());
+ }
+
+ protected function getObjectEditShortText($object) {
+ return $object->getName();
+ }
+
+ protected function getObjectCreateShortText() {
+ return pht('Create Account');
+ }
+
+ protected function getObjectName() {
+ return pht('Account');
+ }
+
+ protected function getObjectCreateCancelURI($object) {
+ return $this->getApplication()->getApplicationURI('/');
+ }
+
+ protected function getEditorURI() {
+ return $this->getApplication()->getApplicationURI('edit/');
+ }
+
+ protected function getObjectViewURI($object) {
+ return $object->getViewURI();
+ }
+
+ protected function buildCustomEditFields($object) {
+ $viewer = $this->getViewer();
+
+ if ($this->getIsCreate()) {
+ $member_phids = array($viewer->getPHID());
+ } else {
+ $member_phids = $object->getMemberPHIDs();
+ }
+
+ $fields = array(
+ id(new PhabricatorTextEditField())
+ ->setKey('name')
+ ->setLabel(pht('Name'))
+ ->setDescription(pht('Account name.'))
+ ->setConduitTypeDescription(pht('New account name.'))
+ ->setTransactionType(
+ PhortuneAccountNameTransaction::TRANSACTIONTYPE)
+ ->setValue($object->getName())
+ ->setIsRequired(true),
+
+ id(new PhabricatorUsersEditField())
+ ->setKey('members')
+ ->setAliases(array('memberPHIDs'))
+ ->setLabel(pht('Members'))
+ ->setUseEdgeTransactions(true)
+ ->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
+ ->setMetadataValue(
+ 'edge:type',
+ PhortuneAccountHasMemberEdgeType::EDGECONST)
+ ->setDescription(pht('Initial account members.'))
+ ->setConduitDescription(pht('Set account members.'))
+ ->setConduitTypeDescription(pht('New list of members.'))
+ ->setInitialValue($object->getMemberPHIDs())
+ ->setValue($member_phids),
+ );
+
+ return $fields;
+
+ }
+
+}
diff --git a/src/applications/phortune/editor/PhortuneAccountEditor.php b/src/applications/phortune/editor/PhortuneAccountEditor.php
--- a/src/applications/phortune/editor/PhortuneAccountEditor.php
+++ b/src/applications/phortune/editor/PhortuneAccountEditor.php
@@ -1,6 +1,5 @@
<?php
-
final class PhortuneAccountEditor
extends PhabricatorApplicationTransactionEditor {
@@ -12,55 +11,70 @@
return pht('Phortune Accounts');
}
+ public function getCreateObjectTitle($author, $object) {
+ return pht('%s created this payment account.', $author);
+ }
+
public function getTransactionTypes() {
$types = parent::getTransactionTypes();
+ $types[] = PhortuneAccountNameTransaction::TRANSACTIONTYPE;
$types[] = PhabricatorTransactions::TYPE_EDGE;
- $types[] = PhortuneAccountTransaction::TYPE_NAME;
return $types;
}
-
- protected function getCustomTransactionOldValue(
+ protected function shouldPublishFeedStory(
PhabricatorLiskDAO $object,
- PhabricatorApplicationTransaction $xaction) {
- switch ($xaction->getTransactionType()) {
- case PhortuneAccountTransaction::TYPE_NAME:
- return $object->getName();
- }
- return parent::getCustomTransactionOldValue($object, $xaction);
+ array $xactions) {
+ return true;
}
- protected function getCustomTransactionNewValue(
+ protected function shouldSendMail(
PhabricatorLiskDAO $object,
- PhabricatorApplicationTransaction $xaction) {
- switch ($xaction->getTransactionType()) {
- case PhortuneAccountTransaction::TYPE_NAME:
- return $xaction->getNewValue();
- }
- return parent::getCustomTransactionNewValue($object, $xaction);
+ array $xactions) {
+ return true;
}
- protected function applyCustomInternalTransaction(
- PhabricatorLiskDAO $object,
- PhabricatorApplicationTransaction $xaction) {
- switch ($xaction->getTransactionType()) {
- case PhortuneAccountTransaction::TYPE_NAME:
- $object->setName($xaction->getNewValue());
- return;
+ public function getMailTagsMap() {
+ return array(
+ PhortuneAccountTransaction::MAILTAG_DETAILS =>
+ pht('Someone changes the accounts\'s details.'),
+ );
+ }
+
+ protected function getMailTo(PhabricatorLiskDAO $object) {
+ $phids = array();
+
+ $account = id(new PhortuneAccountQuery())
+ ->setViewer($this->requireActor())
+ ->withPHIDs(array($object->getPHID()))
+ ->executeOne();
+
+ foreach ($account->getMemberPHIDs() as $account_member) {
+ $phids[] = $account_member;
}
- return parent::applyCustomInternalTransaction($object, $xaction);
+
+ return $phids;
}
- protected function applyCustomExternalTransaction(
+ protected function buildMailBody(
PhabricatorLiskDAO $object,
- PhabricatorApplicationTransaction $xaction) {
- switch ($xaction->getTransactionType()) {
- case PhortuneAccountTransaction::TYPE_NAME:
- return;
- }
- return parent::applyCustomExternalTransaction($object, $xaction);
+ array $xactions) {
+
+ $body = parent::buildMailBody($object, $xactions);
+ $body->addLinkSection(
+ pht('ACCOUNT DETAIL'),
+ PhabricatorEnv::getProductionURI('/phortune/'.$object->getID().'/'));
+ return $body;
+ }
+
+ protected function getMailSubjectPrefix() {
+ return pht('[Phortune]');
+ }
+
+ protected function getMailCC(PhabricatorLiskDAO $object) {
+ return array();
}
protected function validateTransaction(
@@ -71,47 +85,29 @@
$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;
case PhabricatorTransactions::TYPE_EDGE:
foreach ($xactions as $xaction) {
switch ($xaction->getMetadataValue('edge:type')) {
case PhortuneAccountHasMemberEdgeType::EDGECONST:
- // TODO: This is a bit cumbersome, but validation happens before
- // transaction normalization. Maybe provide a cleaner attack on
- // this eventually? There's no way to generate "+" or "-"
- // transactions right now.
$new = $xaction->getNewValue();
- $set = idx($new, '=', array());
-
- if (empty($set[$this->requireActor()->getPHID()])) {
- $error = new PhabricatorApplicationTransactionValidationError(
- $type,
- pht('Invalid'),
- pht('You can not remove yourself as an account member.'),
- $xaction);
- $errors[] = $error;
+ $set = idx($new, '-', array());
+ $actor_phid = $this->requireActor()->getPHID();
+ foreach ($set as $phid) {
+ if ($actor_phid == $phid) {
+ $error = new PhabricatorApplicationTransactionValidationError(
+ $type,
+ pht('Invalid'),
+ pht('You can not remove yourself as an account manager.'),
+ $xaction);
+ $errors[] = $error;
+ }
}
- break;
+ break;
}
}
break;
}
-
return $errors;
}
+
}
diff --git a/src/applications/phortune/editor/PhortuneMerchantEditEngine.php b/src/applications/phortune/editor/PhortuneMerchantEditEngine.php
--- a/src/applications/phortune/editor/PhortuneMerchantEditEngine.php
+++ b/src/applications/phortune/editor/PhortuneMerchantEditEngine.php
@@ -81,7 +81,8 @@
->setDescription(pht('Merchant name.'))
->setConduitTypeDescription(pht('New Merchant name.'))
->setIsRequired(true)
- ->setTransactionType(PhortuneMerchantTransaction::TYPE_NAME)
+ ->setTransactionType(
+ PhortuneMerchantNameTransaction::TRANSACTIONTYPE)
->setValue($object->getName()),
id(new PhabricatorUsersEditField())
@@ -104,7 +105,8 @@
->setLabel(pht('Description'))
->setDescription(pht('Merchant description.'))
->setConduitTypeDescription(pht('New merchant description.'))
- ->setTransactionType(PhortuneMerchantTransaction::TYPE_DESCRIPTION)
+ ->setTransactionType(
+ PhortuneMerchantDescriptionTransaction::TRANSACTIONTYPE)
->setValue($object->getDescription()),
id(new PhabricatorRemarkupEditField())
@@ -112,7 +114,8 @@
->setLabel(pht('Contact Info'))
->setDescription(pht('Merchant contact information.'))
->setConduitTypeDescription(pht('Merchant contact information.'))
- ->setTransactionType(PhortuneMerchantTransaction::TYPE_CONTACTINFO)
+ ->setTransactionType(
+ PhortuneMerchantContactInfoTransaction::TRANSACTIONTYPE)
->setValue($object->getContactInfo()),
id(new PhabricatorTextEditField())
@@ -121,7 +124,8 @@
->setDescription(pht('Email address invoices are sent from.'))
->setConduitTypeDescription(
pht('Email address invoices are sent from.'))
- ->setTransactionType(PhortuneMerchantTransaction::TYPE_INVOICEEMAIL)
+ ->setTransactionType(
+ PhortuneMerchantInvoiceEmailTransaction::TRANSACTIONTYPE)
->setValue($object->getInvoiceEmail()),
id(new PhabricatorRemarkupEditField())
@@ -129,7 +133,8 @@
->setLabel(pht('Invoice Footer'))
->setDescription(pht('Footer on invoice forms.'))
->setConduitTypeDescription(pht('Footer on invoice forms.'))
- ->setTransactionType(PhortuneMerchantTransaction::TYPE_INVOICEFOOTER)
+ ->setTransactionType(
+ PhortuneMerchantInvoiceFooterTransaction::TRANSACTIONTYPE)
->setValue($object->getInvoiceFooter()),
);
diff --git a/src/applications/phortune/editor/PhortuneMerchantEditor.php b/src/applications/phortune/editor/PhortuneMerchantEditor.php
--- a/src/applications/phortune/editor/PhortuneMerchantEditor.php
+++ b/src/applications/phortune/editor/PhortuneMerchantEditor.php
@@ -11,102 +11,78 @@
return pht('Phortune Merchants');
}
+ public function getCreateObjectTitle($author, $object) {
+ return pht('%s created this merchant.', $author);
+ }
+
public function getTransactionTypes() {
$types = parent::getTransactionTypes();
- $types[] = PhortuneMerchantTransaction::TYPE_NAME;
- $types[] = PhortuneMerchantTransaction::TYPE_DESCRIPTION;
- $types[] = PhortuneMerchantTransaction::TYPE_CONTACTINFO;
- $types[] = PhortuneMerchantTransaction::TYPE_PICTURE;
- $types[] = PhortuneMerchantTransaction::TYPE_INVOICEEMAIL;
- $types[] = PhortuneMerchantTransaction::TYPE_INVOICEFOOTER;
+ $types[] = PhortuneMerchantNameTransaction::TRANSACTIONTYPE;
+ $types[] = PhortuneMerchantDescriptionTransaction::TRANSACTIONTYPE;
+ $types[] = PhortuneMerchantContactInfoTransaction::TRANSACTIONTYPE;
+ $types[] = PhortuneMerchantPictureTransaction::TRANSACTIONTYPE;
+ $types[] = PhortuneMerchantInvoiceEmailTransaction::TRANSACTIONTYPE;
+ $types[] = PhortuneMerchantInvoiceFooterTransaction::TRANSACTIONTYPE;
+
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
$types[] = PhabricatorTransactions::TYPE_EDGE;
return $types;
}
- protected function getCustomTransactionOldValue(
+ protected function shouldPublishFeedStory(
PhabricatorLiskDAO $object,
- PhabricatorApplicationTransaction $xaction) {
- switch ($xaction->getTransactionType()) {
- case PhortuneMerchantTransaction::TYPE_NAME:
- return $object->getName();
- case PhortuneMerchantTransaction::TYPE_DESCRIPTION:
- return $object->getDescription();
- case PhortuneMerchantTransaction::TYPE_CONTACTINFO:
- return $object->getContactInfo();
- case PhortuneMerchantTransaction::TYPE_INVOICEEMAIL:
- return $object->getInvoiceEmail();
- case PhortuneMerchantTransaction::TYPE_INVOICEFOOTER:
- return $object->getInvoiceFooter();
- case PhortuneMerchantTransaction::TYPE_PICTURE:
- return $object->getProfileImagePHID();
- }
-
- return parent::getCustomTransactionOldValue($object, $xaction);
+ array $xactions) {
+ return true;
}
- protected function getCustomTransactionNewValue(
+ protected function shouldSendMail(
PhabricatorLiskDAO $object,
- PhabricatorApplicationTransaction $xaction) {
-
- switch ($xaction->getTransactionType()) {
- case PhortuneMerchantTransaction::TYPE_NAME:
- case PhortuneMerchantTransaction::TYPE_DESCRIPTION:
- case PhortuneMerchantTransaction::TYPE_CONTACTINFO:
- case PhortuneMerchantTransaction::TYPE_INVOICEEMAIL:
- case PhortuneMerchantTransaction::TYPE_INVOICEFOOTER:
- case PhortuneMerchantTransaction::TYPE_PICTURE:
- return $xaction->getNewValue();
- }
+ array $xactions) {
+ return true;
+ }
- return parent::getCustomTransactionNewValue($object, $xaction);
+ public function getMailTagsMap() {
+ return array(
+ PhortuneMerchantTransaction::MAILTAG_DETAILS =>
+ pht('Someone changes the merchants\'s details.'),
+ );
}
- protected function applyCustomInternalTransaction(
- PhabricatorLiskDAO $object,
- PhabricatorApplicationTransaction $xaction) {
-
- switch ($xaction->getTransactionType()) {
- case PhortuneMerchantTransaction::TYPE_NAME:
- $object->setName($xaction->getNewValue());
- return;
- case PhortuneMerchantTransaction::TYPE_DESCRIPTION:
- $object->setDescription($xaction->getNewValue());
- return;
- case PhortuneMerchantTransaction::TYPE_CONTACTINFO:
- $object->setContactInfo($xaction->getNewValue());
- return;
- case PhortuneMerchantTransaction::TYPE_INVOICEEMAIL:
- $object->setInvoiceEmail($xaction->getNewValue());
- return;
- case PhortuneMerchantTransaction::TYPE_INVOICEFOOTER:
- $object->setInvoiceFooter($xaction->getNewValue());
- return;
- case PhortuneMerchantTransaction::TYPE_PICTURE:
- $object->setProfileImagePHID($xaction->getNewValue());
- return;
+ protected function getMailTo(PhabricatorLiskDAO $object) {
+ $phids = array();
+
+ $merchant = id(new PhortuneMerchantQuery())
+ ->setViewer($this->requireActor())
+ ->withPHIDs(array($object->getPHID()))
+ ->executeOne();
+
+ foreach ($merchant->getMemberPHIDs() as $merchant_member) {
+ $phids[] = $merchant_member;
}
- return parent::applyCustomInternalTransaction($object, $xaction);
+ return $phids;
}
- protected function applyCustomExternalTransaction(
+ protected function buildMailBody(
PhabricatorLiskDAO $object,
- PhabricatorApplicationTransaction $xaction) {
-
- switch ($xaction->getTransactionType()) {
- case PhortuneMerchantTransaction::TYPE_NAME:
- case PhortuneMerchantTransaction::TYPE_DESCRIPTION:
- case PhortuneMerchantTransaction::TYPE_CONTACTINFO:
- case PhortuneMerchantTransaction::TYPE_INVOICEEMAIL:
- case PhortuneMerchantTransaction::TYPE_INVOICEFOOTER:
- case PhortuneMerchantTransaction::TYPE_PICTURE:
- return;
- }
+ array $xactions) {
- return parent::applyCustomExternalTransaction($object, $xaction);
+ $body = parent::buildMailBody($object, $xactions);
+ $body->addLinkSection(
+ pht('MERCHANT DETAIL'),
+ PhabricatorEnv::getProductionURI(
+ '/phortune/merchant/'.$object->getID().'/'));
+ return $body;
+ }
+
+ protected function getMailSubjectPrefix() {
+ return pht('[Phortune]');
+ }
+
+ protected function getMailCC(PhabricatorLiskDAO $object) {
+ return array();
}
protected function validateTransaction(
@@ -117,48 +93,28 @@
$errors = parent::validateTransaction($object, $type, $xactions);
switch ($type) {
- case PhortuneMerchantTransaction::TYPE_NAME:
- $missing = $this->validateIsEmptyTextField(
- $object->getName(),
- $xactions);
-
- if ($missing) {
- $error = new PhabricatorApplicationTransactionValidationError(
- $type,
- pht('Required'),
- pht('Merchant name is required.'),
- nonempty(last($xactions), null));
-
- $error->setIsMissingFieldError(true);
- $errors[] = $error;
- }
- break;
- case PhortuneMerchantTransaction::TYPE_INVOICEEMAIL:
- $new_email = null;
+ case PhabricatorTransactions::TYPE_EDGE:
foreach ($xactions as $xaction) {
- switch ($xaction->getTransactionType()) {
- case PhortuneMerchantTransaction::TYPE_INVOICEEMAIL:
- $new_email = $xaction->getNewValue();
- break;
- }
- }
- if (strlen($new_email)) {
- $email = new PhutilEmailAddress($new_email);
- $domain = $email->getDomainName();
-
- if (!$domain) {
- $error = new PhabricatorApplicationTransactionValidationError(
- $type,
- pht('Invalid'),
- pht('%s is not a valid email.', $new_email),
- nonempty(last($xactions), null));
-
- $errors[] = $error;
+ switch ($xaction->getMetadataValue('edge:type')) {
+ case PhortuneMerchantHasMemberEdgeType::EDGECONST:
+ $new = $xaction->getNewValue();
+ $set = idx($new, '-', array());
+ $actor_phid = $this->requireActor()->getPHID();
+ foreach ($set as $phid) {
+ if ($actor_phid == $phid) {
+ $error = new PhabricatorApplicationTransactionValidationError(
+ $type,
+ pht('Invalid'),
+ pht('You can not remove yourself as an merchant manager.'),
+ $xaction);
+ $errors[] = $error;
+ }
+ }
+ break;
}
}
break;
}
-
return $errors;
}
diff --git a/src/applications/phortune/storage/PhortuneAccount.php b/src/applications/phortune/storage/PhortuneAccount.php
--- a/src/applications/phortune/storage/PhortuneAccount.php
+++ b/src/applications/phortune/storage/PhortuneAccount.php
@@ -12,12 +12,12 @@
PhabricatorPolicyInterface {
protected $name;
+ protected $mailKey;
private $memberPHIDs = self::ATTACHABLE;
public static function initializeNewAccount(PhabricatorUser $actor) {
$account = id(new PhortuneAccount());
-
$account->memberPHIDs = array();
return $account;
@@ -31,7 +31,7 @@
$xactions = array();
$xactions[] = id(new PhortuneAccountTransaction())
- ->setTransactionType(PhortuneAccountTransaction::TYPE_NAME)
+ ->setTransactionType(PhortuneAccountNameTransaction::TRANSACTIONTYPE)
->setNewValue(pht('Default Account'));
$xactions[] = id(new PhortuneAccountTransaction())
@@ -78,6 +78,7 @@
self::CONFIG_AUX_PHID => true,
self::CONFIG_COLUMN_SCHEMA => array(
'name' => 'text255',
+ 'mailKey' => 'bytes20',
),
) + parent::getConfiguration();
}
@@ -96,6 +97,17 @@
return $this;
}
+ public function getViewURI() {
+ return '/phortune/'.$this->getID().'/';
+ }
+
+ public function save() {
+ if (!$this->getMailKey()) {
+ $this->setMailKey(Filesystem::readRandomCharacters(20));
+ }
+ return parent::save();
+ }
+
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
diff --git a/src/applications/phortune/storage/PhortuneAccountTransaction.php b/src/applications/phortune/storage/PhortuneAccountTransaction.php
--- a/src/applications/phortune/storage/PhortuneAccountTransaction.php
+++ b/src/applications/phortune/storage/PhortuneAccountTransaction.php
@@ -1,9 +1,9 @@
<?php
final class PhortuneAccountTransaction
- extends PhabricatorApplicationTransaction {
+ extends PhabricatorModularTransaction {
- const TYPE_NAME = 'phortune:name';
+ const MAILTAG_DETAILS = 'account:details';
public function getApplicationName() {
return 'phortune';
@@ -17,29 +17,21 @@
return null;
}
- public function getTitle() {
- $author_phid = $this->getAuthorPHID();
+ public function getBaseTransactionClass() {
+ return 'PhortuneAccountTransactionType';
+ }
- $old = $this->getOldValue();
- $new = $this->getNewValue();
+ public function getMailTags() {
+ $tags = parent::getMailTags();
switch ($this->getTransactionType()) {
- case self::TYPE_NAME:
- if ($old === null) {
- return pht(
- '%s created this account.',
- $this->renderHandleLink($author_phid));
- } else {
- return pht(
- '%s renamed this account from "%s" to "%s".',
- $this->renderHandleLink($author_phid),
- $old,
- $new);
- }
+ case PhortuneAccountNameTransaction::TRANSACTIONTYPE:
+ case PhabricatorTransactions::TYPE_EDGE:
+ default:
+ $tags[] = self::MAILTAG_DETAILS;
break;
}
-
- return parent::getTitle();
+ return $tags;
}
}
diff --git a/src/applications/phortune/storage/PhortuneMerchant.php b/src/applications/phortune/storage/PhortuneMerchant.php
--- a/src/applications/phortune/storage/PhortuneMerchant.php
+++ b/src/applications/phortune/storage/PhortuneMerchant.php
@@ -12,6 +12,7 @@
protected $invoiceEmail;
protected $invoiceFooter;
protected $profileImagePHID;
+ protected $mailKey;
private $memberPHIDs = self::ATTACHABLE;
private $profileImageFile = self::ATTACHABLE;
@@ -35,6 +36,7 @@
'invoiceEmail' => 'text255',
'invoiceFooter' => 'text',
'profileImagePHID' => 'phid?',
+ 'mailKey' => 'bytes20',
),
) + parent::getConfiguration();
}
@@ -70,6 +72,14 @@
return $this->assertAttached($this->profileImageFile);
}
+ public function save() {
+ if (!$this->getMailKey()) {
+ $this->setMailKey(Filesystem::readRandomCharacters(20));
+ }
+ return parent::save();
+ }
+
+
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
diff --git a/src/applications/phortune/storage/PhortuneMerchantTransaction.php b/src/applications/phortune/storage/PhortuneMerchantTransaction.php
--- a/src/applications/phortune/storage/PhortuneMerchantTransaction.php
+++ b/src/applications/phortune/storage/PhortuneMerchantTransaction.php
@@ -1,14 +1,9 @@
<?php
final class PhortuneMerchantTransaction
- extends PhabricatorApplicationTransaction {
+ extends PhabricatorModularTransaction {
- const TYPE_NAME = 'merchant:name';
- const TYPE_DESCRIPTION = 'merchant:description';
- const TYPE_CONTACTINFO = 'merchant:contactinfo';
- const TYPE_INVOICEEMAIL = 'merchant:invoiceemail';
- const TYPE_INVOICEFOOTER = 'merchant:invoicefooter';
- const TYPE_PICTURE = 'merchant:picture';
+ const MAILTAG_DETAILS = 'merchant:details';
public function getApplicationName() {
return 'phortune';
@@ -22,79 +17,25 @@
return null;
}
- public function getTitle() {
- $author_phid = $this->getAuthorPHID();
-
- $old = $this->getOldValue();
- $new = $this->getNewValue();
-
- switch ($this->getTransactionType()) {
- case self::TYPE_NAME:
- if ($old === null) {
- return pht(
- '%s created this merchant.',
- $this->renderHandleLink($author_phid));
- } else {
- return pht(
- '%s renamed this merchant from "%s" to "%s".',
- $this->renderHandleLink($author_phid),
- $old,
- $new);
- }
- break;
- case self::TYPE_DESCRIPTION:
- return pht(
- '%s updated the description for this merchant.',
- $this->renderHandleLink($author_phid));
- case self::TYPE_CONTACTINFO:
- return pht(
- '%s updated the contact information for this merchant.',
- $this->renderHandleLink($author_phid));
- case self::TYPE_INVOICEEMAIL:
- return pht(
- '%s updated the invoice email for this merchant.',
- $this->renderHandleLink($author_phid));
- case self::TYPE_INVOICEFOOTER:
- return pht(
- '%s updated the invoice footer for this merchant.',
- $this->renderHandleLink($author_phid));
- }
-
- return parent::getTitle();
+ public function getBaseTransactionClass() {
+ return 'PhortuneMerchantTransactionType';
}
- public function shouldHide() {
- $old = $this->getOldValue();
- switch ($this->getTransactionType()) {
- case self::TYPE_DESCRIPTION:
- case self::TYPE_CONTACTINFO:
- case self::TYPE_INVOICEEMAIL:
- case self::TYPE_INVOICEFOOTER:
- return ($old === null);
- }
- return parent::shouldHide();
- }
+ public function getMailTags() {
+ $tags = parent::getMailTags();
- public function hasChangeDetails() {
switch ($this->getTransactionType()) {
- case self::TYPE_DESCRIPTION:
- return ($this->getOldValue() !== null);
- case self::TYPE_CONTACTINFO:
- return ($this->getOldValue() !== null);
- case self::TYPE_INVOICEEMAIL:
- return ($this->getOldValue() !== null);
- case self::TYPE_INVOICEFOOTER:
- return ($this->getOldValue() !== null);
+ case PhortuneMerchantNameTransaction::TRANSACTIONTYPE:
+ case PhortuneMerchantDescriptionTransaction::TRANSACTIONTYPE:
+ case PhortuneMerchantContactInfoTransaction::TRANSACTIONTYPE:
+ case PhortuneMerchantInvoiceEmailTransaction::TRANSACTIONTYPE:
+ case PhortuneMerchantInvoiceFooterTransaction::TRANSACTIONTYPE:
+ case PhabricatorTransactions::TYPE_EDGE:
+ default:
+ $tags[] = self::MAILTAG_DETAILS;
+ break;
}
-
- return parent::hasChangeDetails();
- }
-
- public function renderChangeDetails(PhabricatorUser $viewer) {
- return $this->renderTextCorpusChangeDetails(
- $viewer,
- $this->getOldValue(),
- $this->getNewValue());
+ return $tags;
}
}
diff --git a/src/applications/phortune/xaction/PhortuneAccountNameTransaction.php b/src/applications/phortune/xaction/PhortuneAccountNameTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/xaction/PhortuneAccountNameTransaction.php
@@ -0,0 +1,55 @@
+<?php
+
+final class PhortuneAccountNameTransaction
+ extends PhortuneAccountTransactionType {
+
+ const TRANSACTIONTYPE = 'phortune:name';
+
+ public function generateOldValue($object) {
+ return $object->getName();
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setName($value);
+ }
+
+ public function getTitle() {
+ $old = $this->getOldValue();
+ $new = $this->getNewValue();
+
+ if (strlen($old) && strlen($new)) {
+ return pht(
+ '%s renamed this account from %s to %s.',
+ $this->renderAuthor(),
+ $this->renderOldValue(),
+ $this->renderNewValue());
+ } else {
+ return pht(
+ '%s created this account.',
+ $this->renderAuthor());
+ }
+ }
+
+ public function validateTransactions($object, array $xactions) {
+ $errors = array();
+
+ if ($this->isEmptyTextTransaction($object->getName(), $xactions)) {
+ $errors[] = $this->newRequiredError(
+ pht('Accounts must have a name.'));
+ }
+
+ $max_length = $object->getColumnMaximumByteLength('name');
+ foreach ($xactions as $xaction) {
+ $new_value = $xaction->getNewValue();
+ $new_length = strlen($new_value);
+ if ($new_length > $max_length) {
+ $errors[] = $this->newRequiredError(
+ pht('The name can be no longer than %s characters.',
+ new PhutilNumber($max_length)));
+ }
+ }
+
+ return $errors;
+ }
+
+}
diff --git a/src/applications/phortune/xaction/PhortuneAccountTransactionType.php b/src/applications/phortune/xaction/PhortuneAccountTransactionType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/xaction/PhortuneAccountTransactionType.php
@@ -0,0 +1,4 @@
+<?php
+
+abstract class PhortuneAccountTransactionType
+ extends PhabricatorModularTransactionType {}
diff --git a/src/applications/phortune/xaction/PhortuneMerchantContactInfoTransaction.php b/src/applications/phortune/xaction/PhortuneMerchantContactInfoTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/xaction/PhortuneMerchantContactInfoTransaction.php
@@ -0,0 +1,56 @@
+<?php
+
+final class PhortuneMerchantContactInfoTransaction
+ extends PhortuneMerchantTransactionType {
+
+ const TRANSACTIONTYPE = 'merchant:contactinfo';
+
+ public function generateOldValue($object) {
+ return $object->getContactInfo();
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setContactInfo($value);
+ }
+
+ public function getTitle() {
+ return pht(
+ '%s updated the merchant contact info.',
+ $this->renderAuthor());
+ }
+
+ public function getTitleForFeed() {
+ return pht(
+ '%s updated the merchant contact info for %s.',
+ $this->renderAuthor(),
+ $this->renderObject());
+ }
+
+ public function hasChangeDetailView() {
+ return true;
+ }
+
+ public function getMailDiffSectionHeader() {
+ return pht('CHANGES TO MERCHANT CONTACT INFO');
+ }
+
+ public function newChangeDetailView() {
+ $viewer = $this->getViewer();
+
+ return id(new PhabricatorApplicationTransactionTextDiffDetailView())
+ ->setViewer($viewer)
+ ->setOldText($this->getOldValue())
+ ->setNewText($this->getNewValue());
+ }
+
+ public function newRemarkupChanges() {
+ $changes = array();
+
+ $changes[] = $this->newRemarkupChange()
+ ->setOldValue($this->getOldValue())
+ ->setNewValue($this->getNewValue());
+
+ return $changes;
+ }
+
+}
diff --git a/src/applications/phortune/xaction/PhortuneMerchantDescriptionTransaction.php b/src/applications/phortune/xaction/PhortuneMerchantDescriptionTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/xaction/PhortuneMerchantDescriptionTransaction.php
@@ -0,0 +1,56 @@
+<?php
+
+final class PhortuneMerchantDescriptionTransaction
+ extends PhortuneMerchantTransactionType {
+
+ const TRANSACTIONTYPE = 'merchant:description';
+
+ public function generateOldValue($object) {
+ return $object->getDescription();
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setDescription($value);
+ }
+
+ public function getTitle() {
+ return pht(
+ '%s updated the merchant description.',
+ $this->renderAuthor());
+ }
+
+ public function getTitleForFeed() {
+ return pht(
+ '%s updated the merchant description for %s.',
+ $this->renderAuthor(),
+ $this->renderObject());
+ }
+
+ public function hasChangeDetailView() {
+ return true;
+ }
+
+ public function getMailDiffSectionHeader() {
+ return pht('CHANGES TO MERCHANT DESCRIPTION');
+ }
+
+ public function newChangeDetailView() {
+ $viewer = $this->getViewer();
+
+ return id(new PhabricatorApplicationTransactionTextDiffDetailView())
+ ->setViewer($viewer)
+ ->setOldText($this->getOldValue())
+ ->setNewText($this->getNewValue());
+ }
+
+ public function newRemarkupChanges() {
+ $changes = array();
+
+ $changes[] = $this->newRemarkupChange()
+ ->setOldValue($this->getOldValue())
+ ->setNewValue($this->getNewValue());
+
+ return $changes;
+ }
+
+}
diff --git a/src/applications/phortune/xaction/PhortuneMerchantInvoiceEmailTransaction.php b/src/applications/phortune/xaction/PhortuneMerchantInvoiceEmailTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/xaction/PhortuneMerchantInvoiceEmailTransaction.php
@@ -0,0 +1,94 @@
+<?php
+
+final class PhortuneMerchantInvoiceEmailTransaction
+ extends PhortuneMerchantTransactionType {
+
+ const TRANSACTIONTYPE = 'merchant:invoiceemail';
+
+ public function generateOldValue($object) {
+ return $object->getInvoiceEmail();
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setInvoiceEmail($value);
+ }
+
+ public function getTitle() {
+ $old = $this->getOldValue();
+ $new = $this->getNewValue();
+
+ if (strlen($old) && strlen($new)) {
+ return pht(
+ '%s updated the invoice email from %s to %s.',
+ $this->renderAuthor(),
+ $this->renderOldValue(),
+ $this->renderNewValue());
+ } else if (strlen($old)) {
+ return pht(
+ '%s removed the invoice email.',
+ $this->renderAuthor());
+ } else {
+ return pht(
+ '%s set the invoice email to %s.',
+ $this->renderAuthor(),
+ $this->renderNewValue());
+ }
+ }
+
+ public function getTitleForFeed() {
+ $old = $this->getOldValue();
+ $new = $this->getNewValue();
+
+ if (strlen($old) && strlen($new)) {
+ return pht(
+ '%s updated %s invoice email from %s to %s.',
+ $this->renderAuthor(),
+ $this->renderObject(),
+ $this->renderOldValue(),
+ $this->renderNewValue());
+ } else if (strlen($old)) {
+ return pht(
+ '%s removed the invoice email for %s.',
+ $this->renderAuthor(),
+ $this->renderObject());
+ } else {
+ return pht(
+ '%s set the invoice email for %s to %s.',
+ $this->renderAuthor(),
+ $this->renderObject(),
+ $this->renderNewValue());
+ }
+ }
+
+ public function getIcon() {
+ return 'fa-envelope';
+ }
+
+ public function validateTransactions($object, array $xactions) {
+ $errors = array();
+
+ $max_length = $object->getColumnMaximumByteLength('invoiceEmail');
+ foreach ($xactions as $xaction) {
+ if ($xaction->getNewValue()) {
+ $email = new PhutilEmailAddress($xaction->getNewValue());
+ $domain = $email->getDomainName();
+ if (!$domain) {
+ $errors[] = $this->newRequiredError(
+ pht('Invoice email "%s" must be a valid email.',
+ $xaction->getNewValue()));
+ }
+
+ $new_value = $xaction->getNewValue();
+ $new_length = strlen($new_value);
+ if ($new_length > $max_length) {
+ $errors[] = $this->newRequiredError(
+ pht('The email can be no longer than %s characters.',
+ new PhutilNumber($max_length)));
+ }
+ }
+ }
+
+ return $errors;
+ }
+
+}
diff --git a/src/applications/phortune/xaction/PhortuneMerchantInvoiceFooterTransaction.php b/src/applications/phortune/xaction/PhortuneMerchantInvoiceFooterTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/xaction/PhortuneMerchantInvoiceFooterTransaction.php
@@ -0,0 +1,56 @@
+<?php
+
+final class PhortuneMerchantInvoiceFooterTransaction
+ extends PhortuneMerchantTransactionType {
+
+ const TRANSACTIONTYPE = 'merchant:invoicefooter';
+
+ public function generateOldValue($object) {
+ return $object->getInvoiceFooter();
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setInvoiceFooter($value);
+ }
+
+ public function getTitle() {
+ return pht(
+ '%s updated the merchant invoice footer.',
+ $this->renderAuthor());
+ }
+
+ public function getTitleForFeed() {
+ return pht(
+ '%s updated the merchant invoice footer for %s.',
+ $this->renderAuthor(),
+ $this->renderObject());
+ }
+
+ public function hasChangeDetailView() {
+ return true;
+ }
+
+ public function getMailDiffSectionHeader() {
+ return pht('CHANGES TO MERCHANT INVOICE FOOTER');
+ }
+
+ public function newChangeDetailView() {
+ $viewer = $this->getViewer();
+
+ return id(new PhabricatorApplicationTransactionTextDiffDetailView())
+ ->setViewer($viewer)
+ ->setOldText($this->getOldValue())
+ ->setNewText($this->getNewValue());
+ }
+
+ public function newRemarkupChanges() {
+ $changes = array();
+
+ $changes[] = $this->newRemarkupChange()
+ ->setOldValue($this->getOldValue())
+ ->setNewValue($this->getNewValue());
+
+ return $changes;
+ }
+
+}
diff --git a/src/applications/phortune/xaction/PhortuneMerchantNameTransaction.php b/src/applications/phortune/xaction/PhortuneMerchantNameTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/xaction/PhortuneMerchantNameTransaction.php
@@ -0,0 +1,55 @@
+<?php
+
+final class PhortuneMerchantNameTransaction
+ extends PhortuneMerchantTransactionType {
+
+ const TRANSACTIONTYPE = 'merchant:name';
+
+ public function generateOldValue($object) {
+ return $object->getName();
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setName($value);
+ }
+
+ public function getTitle() {
+ return pht(
+ '%s renamed this merchant from %s to %s.',
+ $this->renderAuthor(),
+ $this->renderOldValue(),
+ $this->renderNewValue());
+ }
+
+ public function getTitleForFeed() {
+ return pht(
+ '%s renamed %s merchant name from %s to %s.',
+ $this->renderAuthor(),
+ $this->renderObject(),
+ $this->renderOldValue(),
+ $this->renderNewValue());
+ }
+
+ public function validateTransactions($object, array $xactions) {
+ $errors = array();
+
+ if ($this->isEmptyTextTransaction($object->getName(), $xactions)) {
+ $errors[] = $this->newRequiredError(
+ pht('Merchants must have a name.'));
+ }
+
+ $max_length = $object->getColumnMaximumByteLength('name');
+ foreach ($xactions as $xaction) {
+ $new_value = $xaction->getNewValue();
+ $new_length = strlen($new_value);
+ if ($new_length > $max_length) {
+ $errors[] = $this->newRequiredError(
+ pht('The name can be no longer than %s characters.',
+ new PhutilNumber($max_length)));
+ }
+ }
+
+ return $errors;
+ }
+
+}
diff --git a/src/applications/phortune/xaction/PhortuneMerchantPictureTransaction.php b/src/applications/phortune/xaction/PhortuneMerchantPictureTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/xaction/PhortuneMerchantPictureTransaction.php
@@ -0,0 +1,33 @@
+<?php
+
+final class PhortuneMerchantPictureTransaction
+ extends PhortuneMerchantTransactionType {
+
+ const TRANSACTIONTYPE = 'merchant:picture';
+
+ public function generateOldValue($object) {
+ return $object->getProfileImagePHID();
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setProfileImagePHID($value);
+ }
+
+ public function getTitle() {
+ return pht(
+ '%s updated the picture.',
+ $this->renderAuthor());
+ }
+
+ public function getTitleForFeed() {
+ return pht(
+ '%s updated the picture for merchant %s.',
+ $this->renderAuthor(),
+ $this->renderObject());
+ }
+
+ public function getIcon() {
+ return 'fa-camera-retro';
+ }
+
+}
diff --git a/src/applications/phortune/xaction/PhortuneMerchantTransactionType.php b/src/applications/phortune/xaction/PhortuneMerchantTransactionType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/xaction/PhortuneMerchantTransactionType.php
@@ -0,0 +1,4 @@
+<?php
+
+abstract class PhortuneMerchantTransactionType
+ extends PhabricatorModularTransactionType {}
diff --git a/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php b/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php
--- a/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php
+++ b/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php
@@ -1610,6 +1610,36 @@
'%s accepted this revision as %s reviewer(s): %s.' =>
'%s accepted this revision as: %3$s.',
+
+ '%s added %s account manager(s): %s.' => array(
+ array(
+ '%s added an account manager: %3$s.',
+ '%s added account managers: %3$s.',
+ ),
+ ),
+
+ '%s removed %s account manager(s): %s.' => array(
+ array(
+ '%s removed an account manager: %3$s.',
+ '%s removed account managers: %3$s.',
+ ),
+ ),
+
+ '%s added %s merchant manager(s): %s.' => array(
+ array(
+ '%s added a merchant manager: %3$s.',
+ '%s added merchant managers: %3$s.',
+ ),
+ ),
+
+ '%s removed %s merchant manager(s): %s.' => array(
+ array(
+ '%s removed a merchant manager: %3$s.',
+ '%s removed merchant managers: %3$s.',
+ ),
+ ),
+
+
);
}

File Metadata

Mime Type
text/plain
Expires
May 18 2024, 2:34 AM (5 w, 5 d ago)
Storage Engine
amazon-s3
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
phabricator/secure/ne/4t/fo4yeeodjvkwwt3a
Default Alt Text
D17579.id.diff (113 KB)

Event Timeline