mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-29 10:12:41 +01:00
Update Phortune subscriptions for modern infrastructure
Summary: Depends on D20720. Ref T13366. - Use modern policies and policy interfaces. - Use new merchant authority cache. - Add (some) transactions. - Move MFA from pre-upgrade-gate to post-one-shot-check. - Simplify the autopay workflow. - Use the "reloading arrows" icon for subscriptions more consistently. Test Plan: As a merchant-authority and account-authority, viewed, edited, and changed autopay for subscriptions. Subscribers: PHID-OPKG-gm6ozazyms6q6i22gyam Maniphest Tasks: T13366 Differential Revision: https://secure.phabricator.com/D20721
This commit is contained in:
parent
26ec924732
commit
a542024b63
19 changed files with 746 additions and 277 deletions
|
@ -0,0 +1,19 @@
|
|||
CREATE TABLE {$NAMESPACE}_phortune.phortune_subscriptiontransaction (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
phid VARBINARY(64) NOT NULL,
|
||||
authorPHID VARBINARY(64) NOT NULL,
|
||||
objectPHID VARBINARY(64) NOT NULL,
|
||||
viewPolicy VARBINARY(64) NOT NULL,
|
||||
editPolicy VARBINARY(64) NOT NULL,
|
||||
commentPHID VARBINARY(64) DEFAULT NULL,
|
||||
commentVersion INT UNSIGNED NOT NULL,
|
||||
transactionType VARCHAR(32) NOT NULL,
|
||||
oldValue LONGTEXT NOT NULL,
|
||||
newValue LONGTEXT NOT NULL,
|
||||
contentSource LONGTEXT NOT NULL,
|
||||
metadata LONGTEXT NOT NULL,
|
||||
dateCreated INT UNSIGNED NOT NULL,
|
||||
dateModified INT UNSIGNED NOT NULL,
|
||||
UNIQUE KEY `key_phid` (`phid`),
|
||||
KEY `key_object` (`objectPHID`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET={$CHARSET} COLLATE {$COLLATE_TEXT};
|
|
@ -5249,11 +5249,13 @@ phutil_register_library_map(array(
|
|||
'PhortuneAccountOrdersController' => 'applications/phortune/controller/account/PhortuneAccountOrdersController.php',
|
||||
'PhortuneAccountOverviewController' => 'applications/phortune/controller/account/PhortuneAccountOverviewController.php',
|
||||
'PhortuneAccountPHIDType' => 'applications/phortune/phid/PhortuneAccountPHIDType.php',
|
||||
'PhortuneAccountPaymentMethodListController' => 'applications/phortune/controller/account/PhortuneAccountPaymentMethodListController.php',
|
||||
'PhortuneAccountPaymentMethodController' => 'applications/phortune/controller/account/PhortuneAccountPaymentMethodController.php',
|
||||
'PhortuneAccountPaymentMethodViewController' => 'applications/phortune/controller/account/PhortuneAccountPaymentMethodViewController.php',
|
||||
'PhortuneAccountProfileController' => 'applications/phortune/controller/account/PhortuneAccountProfileController.php',
|
||||
'PhortuneAccountQuery' => 'applications/phortune/query/PhortuneAccountQuery.php',
|
||||
'PhortuneAccountSubscriptionAutopayController' => 'applications/phortune/controller/account/PhortuneAccountSubscriptionAutopayController.php',
|
||||
'PhortuneAccountSubscriptionController' => 'applications/phortune/controller/account/PhortuneAccountSubscriptionController.php',
|
||||
'PhortuneAccountSubscriptionViewController' => 'applications/phortune/controller/account/PhortuneAccountSubscriptionViewController.php',
|
||||
'PhortuneAccountTransaction' => 'applications/phortune/storage/PhortuneAccountTransaction.php',
|
||||
'PhortuneAccountTransactionQuery' => 'applications/phortune/query/PhortuneAccountTransactionQuery.php',
|
||||
'PhortuneAccountTransactionType' => 'applications/phortune/xaction/PhortuneAccountTransactionType.php',
|
||||
|
@ -5361,16 +5363,21 @@ phutil_register_library_map(array(
|
|||
'PhortuneSchemaSpec' => 'applications/phortune/storage/PhortuneSchemaSpec.php',
|
||||
'PhortuneStripePaymentProvider' => 'applications/phortune/provider/PhortuneStripePaymentProvider.php',
|
||||
'PhortuneSubscription' => 'applications/phortune/storage/PhortuneSubscription.php',
|
||||
'PhortuneSubscriptionAutopayTransaction' => 'applications/phortune/xaction/subscription/PhortuneSubscriptionAutopayTransaction.php',
|
||||
'PhortuneSubscriptionCart' => 'applications/phortune/cart/PhortuneSubscriptionCart.php',
|
||||
'PhortuneSubscriptionEditController' => 'applications/phortune/controller/subscription/PhortuneSubscriptionEditController.php',
|
||||
'PhortuneSubscriptionEditor' => 'applications/phortune/editor/PhortuneSubscriptionEditor.php',
|
||||
'PhortuneSubscriptionImplementation' => 'applications/phortune/subscription/PhortuneSubscriptionImplementation.php',
|
||||
'PhortuneSubscriptionListController' => 'applications/phortune/controller/subscription/PhortuneSubscriptionListController.php',
|
||||
'PhortuneSubscriptionPHIDType' => 'applications/phortune/phid/PhortuneSubscriptionPHIDType.php',
|
||||
'PhortuneSubscriptionPolicyCodex' => 'applications/phortune/codex/PhortuneSubscriptionPolicyCodex.php',
|
||||
'PhortuneSubscriptionProduct' => 'applications/phortune/product/PhortuneSubscriptionProduct.php',
|
||||
'PhortuneSubscriptionQuery' => 'applications/phortune/query/PhortuneSubscriptionQuery.php',
|
||||
'PhortuneSubscriptionSearchEngine' => 'applications/phortune/query/PhortuneSubscriptionSearchEngine.php',
|
||||
'PhortuneSubscriptionTableView' => 'applications/phortune/view/PhortuneSubscriptionTableView.php',
|
||||
'PhortuneSubscriptionViewController' => 'applications/phortune/controller/subscription/PhortuneSubscriptionViewController.php',
|
||||
'PhortuneSubscriptionTransaction' => 'applications/phortune/storage/PhortuneSubscriptionTransaction.php',
|
||||
'PhortuneSubscriptionTransactionQuery' => 'applications/phortune/query/PhortuneSubscriptionTransactionQuery.php',
|
||||
'PhortuneSubscriptionTransactionType' => 'applications/phortune/xaction/subscription/PhortuneSubscriptionTransactionType.php',
|
||||
'PhortuneSubscriptionWorker' => 'applications/phortune/worker/PhortuneSubscriptionWorker.php',
|
||||
'PhortuneTestPaymentProvider' => 'applications/phortune/provider/PhortuneTestPaymentProvider.php',
|
||||
'PhragmentBrowseController' => 'applications/phragment/controller/PhragmentBrowseController.php',
|
||||
|
@ -11812,11 +11819,13 @@ phutil_register_library_map(array(
|
|||
'PhortuneAccountOrdersController' => 'PhortuneAccountProfileController',
|
||||
'PhortuneAccountOverviewController' => 'PhortuneAccountProfileController',
|
||||
'PhortuneAccountPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhortuneAccountPaymentMethodListController' => 'PhortuneAccountProfileController',
|
||||
'PhortuneAccountPaymentMethodController' => 'PhortuneAccountProfileController',
|
||||
'PhortuneAccountPaymentMethodViewController' => 'PhortuneAccountController',
|
||||
'PhortuneAccountProfileController' => 'PhortuneAccountController',
|
||||
'PhortuneAccountQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhortuneAccountSubscriptionAutopayController' => 'PhortuneAccountController',
|
||||
'PhortuneAccountSubscriptionController' => 'PhortuneAccountProfileController',
|
||||
'PhortuneAccountSubscriptionViewController' => 'PhortuneAccountController',
|
||||
'PhortuneAccountTransaction' => 'PhabricatorModularTransaction',
|
||||
'PhortuneAccountTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhortuneAccountTransactionType' => 'PhabricatorModularTransactionType',
|
||||
|
@ -11953,17 +11962,25 @@ phutil_register_library_map(array(
|
|||
'PhortuneSubscription' => array(
|
||||
'PhortuneDAO',
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorExtendedPolicyInterface',
|
||||
'PhabricatorPolicyCodexInterface',
|
||||
'PhabricatorApplicationTransactionInterface',
|
||||
),
|
||||
'PhortuneSubscriptionAutopayTransaction' => 'PhortuneSubscriptionTransactionType',
|
||||
'PhortuneSubscriptionCart' => 'PhortuneCartImplementation',
|
||||
'PhortuneSubscriptionEditController' => 'PhortuneController',
|
||||
'PhortuneSubscriptionEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhortuneSubscriptionImplementation' => 'Phobject',
|
||||
'PhortuneSubscriptionListController' => 'PhortuneController',
|
||||
'PhortuneSubscriptionPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhortuneSubscriptionPolicyCodex' => 'PhabricatorPolicyCodex',
|
||||
'PhortuneSubscriptionProduct' => 'PhortuneProductImplementation',
|
||||
'PhortuneSubscriptionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhortuneSubscriptionSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PhortuneSubscriptionTableView' => 'AphrontView',
|
||||
'PhortuneSubscriptionViewController' => 'PhortuneController',
|
||||
'PhortuneSubscriptionTransaction' => 'PhabricatorModularTransaction',
|
||||
'PhortuneSubscriptionTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhortuneSubscriptionTransactionType' => 'PhabricatorModularTransactionType',
|
||||
'PhortuneSubscriptionWorker' => 'PhabricatorWorker',
|
||||
'PhortuneTestPaymentProvider' => 'PhortunePaymentProvider',
|
||||
'PhragmentBrowseController' => 'PhragmentController',
|
||||
|
|
|
@ -43,9 +43,7 @@ final class PhabricatorPhortuneApplication extends PhabricatorApplication {
|
|||
'(?:query/(?P<queryKey>[^/]+)/)?'
|
||||
=> 'PhortuneSubscriptionListController',
|
||||
'view/(?P<id>\d+)/'
|
||||
=> 'PhortuneSubscriptionViewController',
|
||||
'edit/(?P<id>\d+)/'
|
||||
=> 'PhortuneSubscriptionEditController',
|
||||
=> 'PhortuneAccountSubscriptionViewController',
|
||||
'order/(?P<subscriptionID>\d+)/'
|
||||
=> 'PhortuneCartListController',
|
||||
),
|
||||
|
@ -73,12 +71,18 @@ final class PhabricatorPhortuneApplication extends PhabricatorApplication {
|
|||
'(?P<accountID>\d+)/' => array(
|
||||
'details/' => 'PhortuneAccountDetailsController',
|
||||
'methods/' => array(
|
||||
'' => 'PhortuneAccountPaymentMethodListController',
|
||||
'' => 'PhortuneAccountPaymentMethodController',
|
||||
'(?P<id>\d+)/' => 'PhortuneAccountPaymentMethodViewController',
|
||||
),
|
||||
'orders/' => 'PhortuneAccountOrdersController',
|
||||
'charges/' => 'PhortuneAccountChargesController',
|
||||
'subscriptions/' => 'PhortuneAccountSubscriptionController',
|
||||
'subscriptions/' => array(
|
||||
'' => 'PhortuneAccountSubscriptionController',
|
||||
'(?P<subscriptionID>\d+)/' => array(
|
||||
'autopay/(?P<methodID>\d+)/'
|
||||
=> 'PhortuneAccountSubscriptionAutopayController',
|
||||
),
|
||||
),
|
||||
'managers/' => array(
|
||||
'' => 'PhortuneAccountManagersController',
|
||||
'add/' => 'PhortuneAccountAddManagerController',
|
||||
|
@ -124,7 +128,7 @@ final class PhabricatorPhortuneApplication extends PhabricatorApplication {
|
|||
'(?:query/(?P<queryKey>[^/]+)/)?'
|
||||
=> 'PhortuneSubscriptionListController',
|
||||
'view/(?P<id>\d+)/'
|
||||
=> 'PhortuneSubscriptionViewController',
|
||||
=> 'PhortuneAccountSubscriptionViewController',
|
||||
'order/(?P<subscriptionID>\d+)/'
|
||||
=> 'PhortuneCartListController',
|
||||
),
|
||||
|
|
|
@ -12,6 +12,7 @@ final class PhortunePaymentMethodPolicyCodex
|
|||
->setCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->setIsActive(true)
|
||||
->setDescription(
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneSubscriptionPolicyCodex
|
||||
extends PhabricatorPolicyCodex {
|
||||
|
||||
public function getPolicySpecialRuleDescriptions() {
|
||||
$object = $this->getObject();
|
||||
|
||||
$rules = array();
|
||||
|
||||
$rules[] = $this->newRule()
|
||||
->setCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->setIsActive(true)
|
||||
->setDescription(
|
||||
pht(
|
||||
'Account members may view and edit subscriptions.'));
|
||||
|
||||
$rules[] = $this->newRule()
|
||||
->setCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
))
|
||||
->setIsActive(true)
|
||||
->setDescription(
|
||||
pht(
|
||||
'Merchants you have a relationship with may view associated '.
|
||||
'subscriptions.'));
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneAccountPaymentMethodListController
|
||||
final class PhortuneAccountPaymentMethodController
|
||||
extends PhortuneAccountProfileController {
|
||||
|
||||
protected function shouldRequireAccountEditCapability() {
|
|
@ -0,0 +1,137 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneAccountSubscriptionAutopayController
|
||||
extends PhortuneAccountController {
|
||||
|
||||
protected function shouldRequireAccountEditCapability() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function handleAccountRequest(AphrontRequest $request) {
|
||||
$viewer = $this->getViewer();
|
||||
$account = $this->getAccount();
|
||||
|
||||
$subscription = id(new PhortuneSubscriptionQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($request->getURIData('subscriptionID')))
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$subscription) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$method = id(new PhortunePaymentMethodQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($request->getURIData('methodID')))
|
||||
->withAccountPHIDs(array($subscription->getAccountPHID()))
|
||||
->withMerchantPHIDs(array($subscription->getMerchantPHID()))
|
||||
->withStatuses(
|
||||
array(
|
||||
PhortunePaymentMethod::STATUS_ACTIVE,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$method) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$next_uri = $subscription->getURI();
|
||||
|
||||
$autopay_phid = $subscription->getDefaultPaymentMethodPHID();
|
||||
$is_stop = ($autopay_phid === $method->getPHID());
|
||||
|
||||
if ($request->isFormOrHisecPost()) {
|
||||
if ($is_stop) {
|
||||
$new_phid = null;
|
||||
} else {
|
||||
$new_phid = $method->getPHID();
|
||||
}
|
||||
|
||||
$xactions = array();
|
||||
|
||||
$xactions[] = $subscription->getApplicationTransactionTemplate()
|
||||
->setTransactionType(
|
||||
PhortuneSubscriptionAutopayTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($new_phid);
|
||||
|
||||
$editor = $subscription->getApplicationTransactionEditor()
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContinueOnMissingFields(true)
|
||||
->setCancelURI($next_uri);
|
||||
|
||||
$editor->applyTransactions($subscription, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($next_uri);
|
||||
}
|
||||
|
||||
$method_phid = $method->getPHID();
|
||||
$subscription_phid = $subscription->getPHID();
|
||||
|
||||
$handles = $viewer->loadHandles(
|
||||
array(
|
||||
$method_phid,
|
||||
$subscription_phid,
|
||||
));
|
||||
|
||||
$method_handle = $handles[$method_phid];
|
||||
$subscription_handle = $handles[$subscription_phid];
|
||||
|
||||
$method_display = $method_handle->renderLink();
|
||||
$method_display = phutil_tag(
|
||||
'strong',
|
||||
array(),
|
||||
$method_display);
|
||||
|
||||
$subscription_display = $subscription_handle->renderLink();
|
||||
$subscription_display = phutil_tag(
|
||||
'strong',
|
||||
array(),
|
||||
$subscription_display);
|
||||
|
||||
$body = array();
|
||||
if ($is_stop) {
|
||||
$title = pht('Stop Autopay');
|
||||
|
||||
$body[] = pht(
|
||||
'Remove %s as the automatic payment method for subscription %s?',
|
||||
$method_display,
|
||||
$subscription_display);
|
||||
|
||||
$body[] = pht(
|
||||
'This payment method will no longer be charged automatically.');
|
||||
|
||||
$submit = pht('Stop Autopay');
|
||||
} else {
|
||||
$title = pht('Start Autopay');
|
||||
|
||||
$body[] = pht(
|
||||
'Set %s as the automatic payment method for subscription %s?',
|
||||
$method_display,
|
||||
$subscription_display);
|
||||
|
||||
$body[] = pht(
|
||||
'This payment method will be used to automatically pay future '.
|
||||
'charges.');
|
||||
|
||||
$submit = pht('Start Autopay');
|
||||
}
|
||||
|
||||
$dialog = $this->newDialog()
|
||||
->setTitle($title)
|
||||
->addCancelButton($next_uri)
|
||||
->addSubmitButton($submit);
|
||||
|
||||
foreach ($body as $graph) {
|
||||
$dialog->appendParagraph($graph);
|
||||
}
|
||||
|
||||
return $dialog;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,338 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneAccountSubscriptionViewController
|
||||
extends PhortuneAccountController {
|
||||
|
||||
protected function shouldRequireAccountEditCapability() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function handleAccountRequest(AphrontRequest $request) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$subscription = id(new PhortuneSubscriptionQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($request->getURIData('id')))
|
||||
->needTriggers(true)
|
||||
->executeOne();
|
||||
if (!$subscription) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$subscription,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$merchant = $subscription->getMerchant();
|
||||
$account = $subscription->getAccount();
|
||||
|
||||
$account_id = $account->getID();
|
||||
$subscription_id = $subscription->getID();
|
||||
|
||||
$title = $subscription->getSubscriptionFullName();
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($title)
|
||||
->setHeaderIcon('fa-retweet');
|
||||
|
||||
$edit_uri = $subscription->getEditURI();
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs()
|
||||
->addTextCrumb($subscription->getSubscriptionCrumbName())
|
||||
->setBorder(true);
|
||||
|
||||
$properties = id(new PHUIPropertyListView())
|
||||
->setUser($viewer);
|
||||
|
||||
$next_invoice = $subscription->getTrigger()->getNextEventPrediction();
|
||||
$properties->addProperty(
|
||||
pht('Next Invoice'),
|
||||
phabricator_datetime($next_invoice, $viewer));
|
||||
|
||||
$autopay = $this->newAutopayView($subscription);
|
||||
|
||||
$details = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Subscription Details'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->addPropertyList($properties);
|
||||
|
||||
$due_box = $this->buildDueInvoices($subscription);
|
||||
$invoice_box = $this->buildPastInvoices($subscription);
|
||||
|
||||
$timeline = $this->buildTransactionTimeline(
|
||||
$subscription,
|
||||
new PhortuneSubscriptionTransactionQuery());
|
||||
$timeline->setShouldTerminate(true);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(
|
||||
array(
|
||||
$details,
|
||||
$autopay,
|
||||
$due_box,
|
||||
$invoice_box,
|
||||
$timeline,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function buildDueInvoices(PhortuneSubscription $subscription) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$invoices = id(new PhortuneCartQuery())
|
||||
->setViewer($viewer)
|
||||
->withSubscriptionPHIDs(array($subscription->getPHID()))
|
||||
->needPurchases(true)
|
||||
->withInvoices(true)
|
||||
->execute();
|
||||
|
||||
$phids = array();
|
||||
foreach ($invoices as $invoice) {
|
||||
$phids[] = $invoice->getPHID();
|
||||
$phids[] = $invoice->getMerchantPHID();
|
||||
foreach ($invoice->getPurchases() as $purchase) {
|
||||
$phids[] = $purchase->getPHID();
|
||||
}
|
||||
}
|
||||
$handles = $this->loadViewerHandles($phids);
|
||||
|
||||
$invoice_table = id(new PhortuneOrderTableView())
|
||||
->setUser($viewer)
|
||||
->setCarts($invoices)
|
||||
->setIsInvoices(true)
|
||||
->setHandles($handles);
|
||||
|
||||
$invoice_header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Invoices Due'));
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeader($invoice_header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->appendChild($invoice_table);
|
||||
}
|
||||
|
||||
private function buildPastInvoices(PhortuneSubscription $subscription) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$invoices = id(new PhortuneCartQuery())
|
||||
->setViewer($viewer)
|
||||
->withSubscriptionPHIDs(array($subscription->getPHID()))
|
||||
->needPurchases(true)
|
||||
->withStatuses(
|
||||
array(
|
||||
PhortuneCart::STATUS_PURCHASING,
|
||||
PhortuneCart::STATUS_CHARGED,
|
||||
PhortuneCart::STATUS_HOLD,
|
||||
PhortuneCart::STATUS_REVIEW,
|
||||
PhortuneCart::STATUS_PURCHASED,
|
||||
))
|
||||
->setLimit(50)
|
||||
->execute();
|
||||
|
||||
$phids = array();
|
||||
foreach ($invoices as $invoice) {
|
||||
$phids[] = $invoice->getPHID();
|
||||
foreach ($invoice->getPurchases() as $purchase) {
|
||||
$phids[] = $purchase->getPHID();
|
||||
}
|
||||
}
|
||||
$handles = $this->loadViewerHandles($phids);
|
||||
|
||||
$invoice_table = id(new PhortuneOrderTableView())
|
||||
->setUser($viewer)
|
||||
->setCarts($invoices)
|
||||
->setHandles($handles);
|
||||
|
||||
$account = $subscription->getAccount();
|
||||
$merchant = $subscription->getMerchant();
|
||||
|
||||
$account_id = $account->getID();
|
||||
$merchant_id = $merchant->getID();
|
||||
$subscription_id = $subscription->getID();
|
||||
|
||||
$invoices_uri = $this->getApplicationURI(
|
||||
"{$account_id}/subscription/order/{$subscription_id}/");
|
||||
|
||||
$invoice_header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Past Invoices'))
|
||||
->addActionLink(
|
||||
id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-list')
|
||||
->setHref($invoices_uri)
|
||||
->setText(pht('View All Invoices')));
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeader($invoice_header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->appendChild($invoice_table);
|
||||
}
|
||||
|
||||
private function newAutopayView(PhortuneSubscription $subscription) {
|
||||
$viewer = $this->getViewer();
|
||||
$account = $subscription->getAccount();
|
||||
|
||||
$add_method_uri = urisprintf(
|
||||
'/phortune/account/%d/card/new/?subscriptionID=%s',
|
||||
$account->getID(),
|
||||
$subscription->getID());
|
||||
$add_method_uri = $this->getApplicationURI($add_method_uri);
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$subscription,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$methods = id(new PhortunePaymentMethodQuery())
|
||||
->setViewer($viewer)
|
||||
->withAccountPHIDs(array($subscription->getAccountPHID()))
|
||||
->withMerchantPHIDs(array($subscription->getMerchantPHID()))
|
||||
->withStatuses(
|
||||
array(
|
||||
PhortunePaymentMethod::STATUS_ACTIVE,
|
||||
))
|
||||
->execute();
|
||||
$methods = mpull($methods, null, 'getPHID');
|
||||
|
||||
$autopay_phid = $subscription->getDefaultPaymentMethodPHID();
|
||||
$autopay_method = idx($methods, $autopay_phid);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Autopay'))
|
||||
->addActionLink(
|
||||
id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-plus')
|
||||
->setHref($add_method_uri)
|
||||
->setText(pht('Add Payment Method'))
|
||||
->setWorkflow(!$can_edit)
|
||||
->setDisabled(!$can_edit));
|
||||
|
||||
$methods = array_select_keys($methods, array($autopay_phid)) + $methods;
|
||||
|
||||
$rows = array();
|
||||
$rowc = array();
|
||||
foreach ($methods as $method) {
|
||||
$is_autopay = ($autopay_method === $method);
|
||||
|
||||
$remove_uri = urisprintf(
|
||||
'/card/%d/disable/?subscriptionID=%d',
|
||||
$method->getID(),
|
||||
$subscription->getID());
|
||||
$remove_uri = $this->getApplicationURI($remove_uri);
|
||||
|
||||
$autopay_uri = urisprintf(
|
||||
'/account/%d/subscriptions/%d/autopay/%d/',
|
||||
$account->getID(),
|
||||
$subscription->getID(),
|
||||
$method->getID());
|
||||
$autopay_uri = $this->getApplicationURI($autopay_uri);
|
||||
|
||||
$remove_button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setColor('grey')
|
||||
->setIcon('fa-times')
|
||||
->setText(pht('Delete'))
|
||||
->setHref($remove_uri)
|
||||
->setWorkflow(true)
|
||||
->setDisabled(!$can_edit);
|
||||
|
||||
if ($is_autopay) {
|
||||
$autopay_button = id(new PHUIButtonView())
|
||||
->setColor('red')
|
||||
->setIcon('fa-times')
|
||||
->setText(pht('Stop Autopay'));
|
||||
} else {
|
||||
if ($autopay_method) {
|
||||
$make_color = 'grey';
|
||||
} else {
|
||||
$make_color = 'green';
|
||||
}
|
||||
|
||||
$autopay_button = id(new PHUIButtonView())
|
||||
->setColor($make_color)
|
||||
->setIcon('fa-retweet')
|
||||
->setText(pht('Start Autopay'));
|
||||
}
|
||||
|
||||
$autopay_button
|
||||
->setTag('a')
|
||||
->setHref($autopay_uri)
|
||||
->setWorkflow(true)
|
||||
->setDisabled(!$can_edit);
|
||||
|
||||
$rows[] = array(
|
||||
$method->getID(),
|
||||
phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $method->getURI(),
|
||||
),
|
||||
$method->getFullDisplayName()),
|
||||
$method->getDisplayExpires(),
|
||||
$autopay_button,
|
||||
$remove_button,
|
||||
);
|
||||
|
||||
if ($is_autopay) {
|
||||
$rowc[] = 'highlighted';
|
||||
} else {
|
||||
$rowc[] = null;
|
||||
}
|
||||
}
|
||||
|
||||
$method_table = id(new AphrontTableView($rows))
|
||||
->setHeaders(
|
||||
array(
|
||||
pht('ID'),
|
||||
pht('Payment Method'),
|
||||
pht('Expires'),
|
||||
null,
|
||||
null,
|
||||
))
|
||||
->setRowClasses($rowc)
|
||||
->setColumnClasses(
|
||||
array(
|
||||
null,
|
||||
'pri wide',
|
||||
null,
|
||||
'right',
|
||||
null,
|
||||
));
|
||||
|
||||
if (!$autopay_method) {
|
||||
$method_table->setNotice(
|
||||
array(
|
||||
id(new PHUIIconView())->setIcon('fa-warning yellow'),
|
||||
' ',
|
||||
pht('Autopay is not currently configured for this subscription.'),
|
||||
));
|
||||
} else {
|
||||
$method_table->setNotice(
|
||||
array(
|
||||
id(new PHUIIconView())->setIcon('fa-check green'),
|
||||
' ',
|
||||
pht(
|
||||
'Autopay is configured using %s.',
|
||||
phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $autopay_method->getURI(),
|
||||
),
|
||||
$autopay_method->getFullDisplayName())),
|
||||
));
|
||||
}
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setTable($method_table);
|
||||
}
|
||||
|
||||
}
|
|
@ -24,6 +24,21 @@ final class PhortunePaymentMethodDisableController
|
|||
return new Aphront400Response();
|
||||
}
|
||||
|
||||
$subscription_id = $request->getInt('subscriptionID');
|
||||
if ($subscription_id) {
|
||||
$subscription = id(new PhortuneSubscriptionQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($subscription_id))
|
||||
->withAccountPHIDs(array($method->getAccountPHID()))
|
||||
->withMerchantPHIDs(array($method->getMerchantPHID()))
|
||||
->executeOne();
|
||||
if (!$subscription) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
} else {
|
||||
$subscription = null;
|
||||
}
|
||||
|
||||
$account = $method->getAccount();
|
||||
$account_id = $account->getID();
|
||||
$account_uri = $account->getPaymentMethodsURI();
|
||||
|
@ -44,18 +59,32 @@ final class PhortunePaymentMethodDisableController
|
|||
|
||||
$editor->applyTransactions($method, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($account_uri);
|
||||
if ($subscription) {
|
||||
$next_uri = $subscription->getURI();
|
||||
} else {
|
||||
$next_uri = $account_uri;
|
||||
}
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($next_uri);
|
||||
}
|
||||
|
||||
$method_phid = $method->getPHID();
|
||||
$handles = $viewer->loadHandles(
|
||||
array(
|
||||
$method_phid,
|
||||
));
|
||||
|
||||
$method_handle = $handles[$method_phid];
|
||||
$method_display = $method_handle->renderLink();
|
||||
$method_display = phutil_tag('strong', array(), $method_display);
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Remove Payment Method'))
|
||||
->addHiddenInput('subscriptionID', $subscription_id)
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Remove the payment method "%s" from your account?',
|
||||
phutil_tag(
|
||||
'strong',
|
||||
array(),
|
||||
$method->getFullDisplayName())))
|
||||
'Remove the payment method %s from your account?',
|
||||
$method_display))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'You will no longer be able to make payments using this payment '.
|
||||
|
|
|
@ -1,224 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneSubscriptionViewController extends PhortuneController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$authority = $this->loadMerchantAuthority();
|
||||
|
||||
$subscription_query = id(new PhortuneSubscriptionQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($request->getURIData('id')))
|
||||
->needTriggers(true);
|
||||
|
||||
if ($authority) {
|
||||
$subscription_query->withMerchantPHIDs(array($authority->getPHID()));
|
||||
}
|
||||
|
||||
$subscription = $subscription_query->executeOne();
|
||||
if (!$subscription) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$subscription,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$merchant = $subscription->getMerchant();
|
||||
$account = $subscription->getAccount();
|
||||
|
||||
$account_id = $account->getID();
|
||||
$subscription_id = $subscription->getID();
|
||||
|
||||
$title = $subscription->getSubscriptionFullName();
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($title)
|
||||
->setHeaderIcon('fa-calendar-o');
|
||||
|
||||
$curtain = $this->newCurtainView($subscription);
|
||||
$edit_uri = $subscription->getEditURI();
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-credit-card')
|
||||
->setName(pht('Manage Autopay'))
|
||||
->setHref($edit_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
if ($authority) {
|
||||
$this->addMerchantCrumb($crumbs, $merchant);
|
||||
} else {
|
||||
$this->addAccountCrumb($crumbs, $account);
|
||||
}
|
||||
$crumbs->addTextCrumb($subscription->getSubscriptionCrumbName());
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
$properties = id(new PHUIPropertyListView())
|
||||
->setUser($viewer);
|
||||
|
||||
$next_invoice = $subscription->getTrigger()->getNextEventPrediction();
|
||||
$properties->addProperty(
|
||||
pht('Next Invoice'),
|
||||
phabricator_datetime($next_invoice, $viewer));
|
||||
|
||||
$default_method = $subscription->getDefaultPaymentMethodPHID();
|
||||
if ($default_method) {
|
||||
$method = id(new PhortunePaymentMethodQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($default_method))
|
||||
->withStatuses(
|
||||
array(
|
||||
PhortunePaymentMethod::STATUS_ACTIVE,
|
||||
))
|
||||
->executeOne();
|
||||
if ($method) {
|
||||
$handles = $this->loadViewerHandles(array($default_method));
|
||||
$autopay_method = $handles[$default_method]->renderLink();
|
||||
} else {
|
||||
$autopay_method = phutil_tag(
|
||||
'em',
|
||||
array(),
|
||||
pht('<Deleted Payment Method>'));
|
||||
}
|
||||
} else {
|
||||
$autopay_method = phutil_tag(
|
||||
'em',
|
||||
array(),
|
||||
pht('No Autopay Method Configured'));
|
||||
}
|
||||
|
||||
$properties->addProperty(
|
||||
pht('Autopay With'),
|
||||
$autopay_method);
|
||||
|
||||
$details = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Details'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->addPropertyList($properties);
|
||||
|
||||
$due_box = $this->buildDueInvoices($subscription, $authority);
|
||||
$invoice_box = $this->buildPastInvoices($subscription, $authority);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setCurtain($curtain)
|
||||
->setMainColumn(array(
|
||||
$details,
|
||||
$due_box,
|
||||
$invoice_box,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function buildDueInvoices(
|
||||
PhortuneSubscription $subscription,
|
||||
$authority) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$invoices = id(new PhortuneCartQuery())
|
||||
->setViewer($viewer)
|
||||
->withSubscriptionPHIDs(array($subscription->getPHID()))
|
||||
->needPurchases(true)
|
||||
->withInvoices(true)
|
||||
->execute();
|
||||
|
||||
$phids = array();
|
||||
foreach ($invoices as $invoice) {
|
||||
$phids[] = $invoice->getPHID();
|
||||
$phids[] = $invoice->getMerchantPHID();
|
||||
foreach ($invoice->getPurchases() as $purchase) {
|
||||
$phids[] = $purchase->getPHID();
|
||||
}
|
||||
}
|
||||
$handles = $this->loadViewerHandles($phids);
|
||||
|
||||
$invoice_table = id(new PhortuneOrderTableView())
|
||||
->setUser($viewer)
|
||||
->setCarts($invoices)
|
||||
->setIsInvoices(true)
|
||||
->setIsMerchantView((bool)$authority)
|
||||
->setHandles($handles);
|
||||
|
||||
$invoice_header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Invoices Due'));
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeader($invoice_header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->appendChild($invoice_table);
|
||||
}
|
||||
|
||||
private function buildPastInvoices(
|
||||
PhortuneSubscription $subscription,
|
||||
$authority) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$invoices = id(new PhortuneCartQuery())
|
||||
->setViewer($viewer)
|
||||
->withSubscriptionPHIDs(array($subscription->getPHID()))
|
||||
->needPurchases(true)
|
||||
->withStatuses(
|
||||
array(
|
||||
PhortuneCart::STATUS_PURCHASING,
|
||||
PhortuneCart::STATUS_CHARGED,
|
||||
PhortuneCart::STATUS_HOLD,
|
||||
PhortuneCart::STATUS_REVIEW,
|
||||
PhortuneCart::STATUS_PURCHASED,
|
||||
))
|
||||
->setLimit(50)
|
||||
->execute();
|
||||
|
||||
$phids = array();
|
||||
foreach ($invoices as $invoice) {
|
||||
$phids[] = $invoice->getPHID();
|
||||
foreach ($invoice->getPurchases() as $purchase) {
|
||||
$phids[] = $purchase->getPHID();
|
||||
}
|
||||
}
|
||||
$handles = $this->loadViewerHandles($phids);
|
||||
|
||||
$invoice_table = id(new PhortuneOrderTableView())
|
||||
->setUser($viewer)
|
||||
->setCarts($invoices)
|
||||
->setHandles($handles);
|
||||
|
||||
$account = $subscription->getAccount();
|
||||
$merchant = $subscription->getMerchant();
|
||||
|
||||
$account_id = $account->getID();
|
||||
$merchant_id = $merchant->getID();
|
||||
$subscription_id = $subscription->getID();
|
||||
|
||||
if ($authority) {
|
||||
$invoices_uri = $this->getApplicationURI(
|
||||
"merchant/{$merchant_id}/subscription/order/{$subscription_id}/");
|
||||
} else {
|
||||
$invoices_uri = $this->getApplicationURI(
|
||||
"{$account_id}/subscription/order/{$subscription_id}/");
|
||||
}
|
||||
|
||||
$invoice_header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Past Invoices'))
|
||||
->addActionLink(
|
||||
id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-list')
|
||||
->setHref($invoices_uri)
|
||||
->setText(pht('View All Invoices')));
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeader($invoice_header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->appendChild($invoice_table);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneSubscriptionEditor
|
||||
extends PhabricatorApplicationTransactionEditor {
|
||||
|
||||
public function getEditorApplicationClass() {
|
||||
return 'PhabricatorPhortuneApplication';
|
||||
}
|
||||
|
||||
public function getEditorObjectsDescription() {
|
||||
return pht('Phortune Subscriptions');
|
||||
}
|
||||
|
||||
public function getCreateObjectTitle($author, $object) {
|
||||
return pht('%s created this subscription.', $author);
|
||||
}
|
||||
|
||||
}
|
|
@ -32,9 +32,9 @@ final class PhortunePaymentMethodPHIDType extends PhabricatorPHIDType {
|
|||
foreach ($handles as $phid => $handle) {
|
||||
$method = $objects[$phid];
|
||||
|
||||
$id = $method->getID();
|
||||
|
||||
$handle->setName($method->getFullDisplayName());
|
||||
$handle
|
||||
->setName($method->getFullDisplayName())
|
||||
->setURI($method->getURI());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,11 +32,9 @@ final class PhortuneSubscriptionPHIDType extends PhabricatorPHIDType {
|
|||
foreach ($handles as $phid => $handle) {
|
||||
$subscription = $objects[$phid];
|
||||
|
||||
$id = $subscription->getID();
|
||||
|
||||
$handle->setName($subscription->getSubscriptionName());
|
||||
$handle->setURI($subscription->getURI());
|
||||
|
||||
$handle
|
||||
->setName($subscription->getSubscriptionName())
|
||||
->setURI($subscription->getURI());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneSubscriptionTransactionQuery
|
||||
extends PhabricatorApplicationTransactionQuery {
|
||||
|
||||
public function getTemplateApplicationTransaction() {
|
||||
return new PhortuneSubscriptionTransaction();
|
||||
}
|
||||
|
||||
}
|
|
@ -180,7 +180,6 @@ final class PhortunePaymentMethod
|
|||
}
|
||||
|
||||
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
|
||||
|
||||
// See T13366. If you can edit the merchant associated with this payment
|
||||
// method, you can view the payment method.
|
||||
if ($capability === PhabricatorPolicyCapability::CAN_VIEW) {
|
||||
|
|
|
@ -3,8 +3,13 @@
|
|||
/**
|
||||
* A subscription bills users regularly.
|
||||
*/
|
||||
final class PhortuneSubscription extends PhortuneDAO
|
||||
implements PhabricatorPolicyInterface {
|
||||
final class PhortuneSubscription
|
||||
extends PhortuneDAO
|
||||
implements
|
||||
PhabricatorPolicyInterface,
|
||||
PhabricatorExtendedPolicyInterface,
|
||||
PhabricatorPolicyCodexInterface,
|
||||
PhabricatorApplicationTransactionInterface {
|
||||
|
||||
const STATUS_ACTIVE = 'active';
|
||||
const STATUS_CANCELLED = 'cancelled';
|
||||
|
@ -55,9 +60,8 @@ final class PhortuneSubscription extends PhortuneDAO
|
|||
) + parent::getConfiguration();
|
||||
}
|
||||
|
||||
public function generatePHID() {
|
||||
return PhabricatorPHID::generateNewPHID(
|
||||
PhortuneSubscriptionPHIDType::TYPECONST);
|
||||
public function getPHIDType() {
|
||||
return PhortuneSubscriptionPHIDType::TYPECONST;
|
||||
}
|
||||
|
||||
public static function initializeNewSubscription(
|
||||
|
@ -245,6 +249,16 @@ final class PhortuneSubscription extends PhortuneDAO
|
|||
$purchase);
|
||||
}
|
||||
|
||||
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
|
||||
|
||||
|
||||
public function getApplicationTransactionEditor() {
|
||||
return new PhortuneSubscriptionEditor();
|
||||
}
|
||||
|
||||
public function getApplicationTransactionTemplate() {
|
||||
return new PhortuneSubscriptionTransaction();
|
||||
}
|
||||
|
||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||
|
||||
|
@ -257,26 +271,17 @@ final class PhortuneSubscription extends PhortuneDAO
|
|||
}
|
||||
|
||||
public function getPolicy($capability) {
|
||||
// NOTE: Both view and edit use the account's edit policy. We punch a hole
|
||||
// through this for merchants, below.
|
||||
return $this
|
||||
->getAccount()
|
||||
->getPolicy(PhabricatorPolicyCapability::CAN_EDIT);
|
||||
return PhabricatorPolicies::getMostOpenPolicy();
|
||||
}
|
||||
|
||||
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
|
||||
if ($this->getAccount()->hasAutomaticCapability($capability, $viewer)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the viewer controls the merchant this subscription bills to, they can
|
||||
// view the subscription.
|
||||
if ($capability == PhabricatorPolicyCapability::CAN_VIEW) {
|
||||
$can_admin = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$this->getMerchant(),
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
if ($can_admin) {
|
||||
// See T13366. If you can edit the merchant associated with this
|
||||
// subscription, you can view the subscription.
|
||||
if ($capability === PhabricatorPolicyCapability::CAN_VIEW) {
|
||||
$any_edit = PhortuneMerchantQuery::canViewersEditMerchants(
|
||||
array($viewer->getPHID()),
|
||||
array($this->getMerchantPHID()));
|
||||
if ($any_edit) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -284,12 +289,31 @@ final class PhortuneSubscription extends PhortuneDAO
|
|||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
|
||||
/* -( PhabricatorExtendedPolicyInterface )--------------------------------- */
|
||||
|
||||
|
||||
public function getExtendedPolicy($capability, PhabricatorUser $viewer) {
|
||||
if ($this->hasAutomaticCapability($capability, $viewer)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// See T13366. For blanket view and edit permissions on all subscriptions,
|
||||
// you must be able to edit the associated account.
|
||||
return array(
|
||||
pht('Subscriptions inherit the policies of the associated account.'),
|
||||
pht(
|
||||
'The merchant you are subscribed with can review and manage the '.
|
||||
'subscription.'),
|
||||
array(
|
||||
$this->getAccount(),
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorPolicyCodexInterface )------------------------------------ */
|
||||
|
||||
|
||||
public function newPolicyCodex() {
|
||||
return new PhortuneSubscriptionPolicyCodex();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneSubscriptionTransaction
|
||||
extends PhabricatorModularTransaction {
|
||||
|
||||
public function getApplicationName() {
|
||||
return 'phortune';
|
||||
}
|
||||
|
||||
public function getApplicationTransactionType() {
|
||||
return PhortuneSubscriptionPHIDType::TYPECONST;
|
||||
}
|
||||
|
||||
public function getBaseTransactionClass() {
|
||||
return 'PhortuneSubscriptionTransactionType';
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneSubscriptionAutopayTransaction
|
||||
extends PhortuneSubscriptionTransactionType {
|
||||
|
||||
const TRANSACTIONTYPE = 'autopay';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
return $object->getDefaultPaymentMethodPHID();
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
$object->setDefaultPaymentMethodPHID($value);
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
$old_phid = $this->getOldValue();
|
||||
$new_phid = $this->getNewValue();
|
||||
|
||||
if ($old_phid && $new_phid) {
|
||||
return pht(
|
||||
'%s changed the automatic payment method for this subscription.',
|
||||
$this->renderAuthor());
|
||||
} else if ($new_phid) {
|
||||
return pht(
|
||||
'%s configured an automatic payment method for this subscription.',
|
||||
$this->renderAuthor());
|
||||
} else {
|
||||
return pht(
|
||||
'%s stopped automatic payments for this subscription.',
|
||||
$this->renderAuthor());
|
||||
}
|
||||
}
|
||||
|
||||
public function shouldTryMFA(
|
||||
$object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
|
||||
abstract class PhortuneSubscriptionTransactionType
|
||||
extends PhabricatorModularTransactionType {}
|
Loading…
Reference in a new issue