mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-26 00:32:42 +01:00
In Phortune, send order email to account external addresses
Summary: Depends on D20738. Ref T13366. Fixes T8389. Now that the infrastructure is in place, actually send email to external addresses. Test Plan: Used `bin/phortune invoice` to generate invoices and saw associated external accounts receive mail in `bin/mail list-outbound`. Maniphest Tasks: T13366, T8389 Differential Revision: https://secure.phabricator.com/D20739
This commit is contained in:
parent
4e13551e85
commit
a0a3879712
12 changed files with 216 additions and 13 deletions
|
@ -5299,6 +5299,7 @@ phutil_register_library_map(array(
|
|||
'PhortuneDisplayException' => 'applications/phortune/exception/PhortuneDisplayException.php',
|
||||
'PhortuneErrCode' => 'applications/phortune/constants/PhortuneErrCode.php',
|
||||
'PhortuneExternalController' => 'applications/phortune/controller/external/PhortuneExternalController.php',
|
||||
'PhortuneExternalOrderController' => 'applications/phortune/controller/external/PhortuneExternalOrderController.php',
|
||||
'PhortuneExternalOverviewController' => 'applications/phortune/controller/external/PhortuneExternalOverviewController.php',
|
||||
'PhortuneExternalUnsubscribeController' => 'applications/phortune/controller/external/PhortuneExternalUnsubscribeController.php',
|
||||
'PhortuneInvoiceView' => 'applications/phortune/view/PhortuneInvoiceView.php',
|
||||
|
@ -11891,6 +11892,7 @@ phutil_register_library_map(array(
|
|||
'PhortuneDisplayException' => 'Exception',
|
||||
'PhortuneErrCode' => 'PhortuneConstants',
|
||||
'PhortuneExternalController' => 'PhortuneController',
|
||||
'PhortuneExternalOrderController' => 'PhortuneExternalController',
|
||||
'PhortuneExternalOverviewController' => 'PhortuneExternalController',
|
||||
'PhortuneExternalUnsubscribeController' => 'PhortuneExternalController',
|
||||
'PhortuneInvoiceView' => 'AphrontTagView',
|
||||
|
|
|
@ -112,6 +112,9 @@ final class PhabricatorPhortuneApplication extends PhabricatorApplication {
|
|||
'external/(?P<addressKey>[^/]+)/(?P<accessKey>[^/]+)/' => array(
|
||||
'' => 'PhortuneExternalOverviewController',
|
||||
'unsubscribe/' => 'PhortuneExternalUnsubscribeController',
|
||||
'order/' => array(
|
||||
'(?P<orderID>[^/]+)/' => 'PhortuneExternalOrderController',
|
||||
),
|
||||
),
|
||||
'merchant/' => array(
|
||||
$this->getQueryRoutePattern()
|
||||
|
|
|
@ -127,19 +127,11 @@ abstract class PhortuneExternalController
|
|||
|
||||
$crumb = id(new PHUICrumbView())
|
||||
->setIcon('fa-diamond')
|
||||
->setName($crumb_name);
|
||||
|
||||
$can_see = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$account,
|
||||
PhabricatorPolicyCapability::CAN_VIEW);
|
||||
if ($can_see) {
|
||||
$crumb->setHref($account->getURI());
|
||||
}
|
||||
->setName($crumb_name)
|
||||
->setHref($email->getExternalURI());
|
||||
|
||||
$crumbs
|
||||
->addCrumb($crumb)
|
||||
->addTextCrumb(pht('Viewing As "%s"', $email->getAddress()));
|
||||
->addCrumb($crumb);
|
||||
} else {
|
||||
$crumb = id(new PHUICrumbView())
|
||||
->setIcon('fa-diamond')
|
||||
|
@ -153,11 +145,22 @@ abstract class PhortuneExternalController
|
|||
|
||||
final protected function newExternalView() {
|
||||
$email = $this->getAccountEmail();
|
||||
$xviewer = $this->getExternalViewer();
|
||||
|
||||
$origin_phid = $email->getAuthorPHID();
|
||||
|
||||
$handles = $xviewer->loadHandles(array($origin_phid));
|
||||
|
||||
|
||||
$messages = array();
|
||||
$messages[] = pht(
|
||||
'You are viewing this payment account as: %s',
|
||||
phutil_tag('strong', array(), $email->getAddress()));
|
||||
|
||||
$messages[] = pht(
|
||||
'This email address was added to this payment account by: %s',
|
||||
phutil_tag('strong', array(), $handles[$origin_phid]->getFullName()));
|
||||
|
||||
$messages[] = pht(
|
||||
'Anyone who has a link to this page can view order history for '.
|
||||
'this payment account.');
|
||||
|
|
40
src/applications/phortune/controller/external/PhortuneExternalOrderController.php
vendored
Normal file
40
src/applications/phortune/controller/external/PhortuneExternalOrderController.php
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneExternalOrderController
|
||||
extends PhortuneExternalController {
|
||||
|
||||
protected function handleExternalRequest(AphrontRequest $request) {
|
||||
$xviewer = $this->getExternalViewer();
|
||||
$email = $this->getAccountEmail();
|
||||
$account = $email->getAccount();
|
||||
|
||||
$order = id(new PhortuneCartQuery())
|
||||
->setViewer($xviewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->withIDs(array($request->getURIData('orderID')))
|
||||
->executeOne();
|
||||
if (!$order) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$timeline = $this->buildTransactionTimeline(
|
||||
$order,
|
||||
new PhortuneCartTransactionQuery());
|
||||
$timeline->setShouldTerminate(true);
|
||||
|
||||
$crumbs = $this->newExternalCrumbs()
|
||||
->addTextCrumb($order->getObjectName());
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setMainColumn(
|
||||
array(
|
||||
$timeline,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle(pht('Order %d', $order->getID()))
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
}
|
|
@ -9,6 +9,7 @@ final class PhortuneExternalOverviewController
|
|||
$account = $email->getAccount();
|
||||
|
||||
$crumbs = $this->newExternalCrumbs()
|
||||
->addTextCrumb(pht('Viewing As "%s"', $email->getAddress()))
|
||||
->setBorder(true);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
|
@ -61,6 +62,7 @@ final class PhortuneExternalOverviewController
|
|||
|
||||
$invoices_table = id(new PhortuneOrderTableView())
|
||||
->setViewer($xviewer)
|
||||
->setAccountEmail($email)
|
||||
->setCarts($invoices)
|
||||
->setIsInvoices(true);
|
||||
|
||||
|
@ -87,6 +89,7 @@ final class PhortuneExternalOverviewController
|
|||
|
||||
$receipts_table = id(new PhortuneOrderTableView())
|
||||
->setViewer($xviewer)
|
||||
->setAccountEmail($email)
|
||||
->setCarts($receipts);
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
|
|
|
@ -246,5 +246,102 @@ final class PhortuneCartEditor
|
|||
return $xactions;
|
||||
}
|
||||
|
||||
protected function newAuxiliaryMail($object, array $xactions) {
|
||||
$xviewer = PhabricatorUser::getOmnipotentUser();
|
||||
$account = $object->getAccount();
|
||||
|
||||
$addresses = id(new PhortuneAccountEmailQuery())
|
||||
->setViewer($xviewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->withStatuses(
|
||||
array(
|
||||
PhortuneAccountEmailStatus::STATUS_ACTIVE,
|
||||
))
|
||||
->execute();
|
||||
|
||||
$messages = array();
|
||||
foreach ($addresses as $address) {
|
||||
$message = $this->newExternalMail($address, $object, $xactions);
|
||||
if ($message) {
|
||||
$messages[] = $message;
|
||||
}
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
private function newExternalMail(
|
||||
PhortuneAccountEmail $email,
|
||||
PhortuneCart $cart,
|
||||
array $xactions) {
|
||||
$xviewer = PhabricatorUser::getOmnipotentUser();
|
||||
$account = $cart->getAccount();
|
||||
|
||||
$id = $cart->getID();
|
||||
$name = $cart->getName();
|
||||
|
||||
$origin_user = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($xviewer)
|
||||
->withPHIDs(array($email->getAuthorPHID()))
|
||||
->executeOne();
|
||||
if (!$origin_user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->isInvoice()) {
|
||||
$subject = pht('[Invoice #%d] %s', $id, $name);
|
||||
$order_header = pht('INVOICE DETAIL');
|
||||
} else {
|
||||
$subject = pht('[Order #%d] %s', $id, $name);
|
||||
$order_header = pht('ORDER DETAIL');
|
||||
}
|
||||
|
||||
$body = id(new PhabricatorMetaMTAMailBody())
|
||||
->setViewer($xviewer)
|
||||
->setContextObject($cart);
|
||||
|
||||
$origin_username = $origin_user->getUsername();
|
||||
$origin_realname = $origin_user->getRealName();
|
||||
if (strlen($origin_realname)) {
|
||||
$origin_display = pht('%s (%s)', $origin_username, $origin_realname);
|
||||
} else {
|
||||
$origin_display = pht('%s', $origin_username);
|
||||
}
|
||||
|
||||
$body->addRawSection(
|
||||
pht(
|
||||
'This email address (%s) was added to a payment account (%s) '.
|
||||
'by %s.',
|
||||
$email->getAddress(),
|
||||
$account->getName(),
|
||||
$origin_display));
|
||||
|
||||
$body->addLinkSection(
|
||||
$order_header,
|
||||
PhabricatorEnv::getProductionURI($email->getExternalOrderURI($cart)));
|
||||
|
||||
$body->addLinkSection(
|
||||
pht('FULL ORDER HISTORY'),
|
||||
PhabricatorEnv::getProductionURI($email->getExternalURI()));
|
||||
|
||||
$body->addLinkSection(
|
||||
pht('UNSUBSCRIBE'),
|
||||
PhabricatorEnv::getProductionURI($email->getUnsubscribeURI()));
|
||||
|
||||
return id(new PhabricatorMetaMTAMail())
|
||||
->setFrom($this->getActingAsPHID())
|
||||
->setSubject($subject)
|
||||
->addRawTos(
|
||||
array(
|
||||
$email->getAddress(),
|
||||
))
|
||||
->setForceDelivery(true)
|
||||
->setIsBulk(true)
|
||||
->setSensitiveContent(true)
|
||||
->setBody($body->render())
|
||||
->setHTMLBody($body->renderHTML());
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ final class PhortuneAccountEmailQuery
|
|||
private $phids;
|
||||
private $accountPHIDs;
|
||||
private $addressKeys;
|
||||
private $statuses;
|
||||
|
||||
public function withIDs(array $ids) {
|
||||
$this->ids = $ids;
|
||||
|
@ -28,6 +29,11 @@ final class PhortuneAccountEmailQuery
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function withStatuses(array $statuses) {
|
||||
$this->statuses = $statuses;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function newResultObject() {
|
||||
return new PhortuneAccountEmail();
|
||||
}
|
||||
|
@ -90,6 +96,13 @@ final class PhortuneAccountEmailQuery
|
|||
$this->addressKeys);
|
||||
}
|
||||
|
||||
if ($this->statuses !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'address.status IN (%Ls)',
|
||||
$this->statuses);
|
||||
}
|
||||
|
||||
return $where;
|
||||
}
|
||||
|
||||
|
|
|
@ -92,6 +92,14 @@ final class PhortuneAccountEmail
|
|||
$this->getAccessKey());
|
||||
}
|
||||
|
||||
public function getExternalOrderURI(PhortuneCart $cart) {
|
||||
return urisprintf(
|
||||
'/phortune/external/%s/%s/order/%d/',
|
||||
$this->getAddressKey(),
|
||||
$this->getAccessKey(),
|
||||
$cart->getID());
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||
|
||||
|
|
|
@ -656,6 +656,10 @@ final class PhortuneCart extends PhortuneDAO
|
|||
return idx($this->metadata, $key, $default);
|
||||
}
|
||||
|
||||
public function getObjectName() {
|
||||
return pht('Order %d', $this->getID());
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ final class PhortuneOrderTableView extends AphrontView {
|
|||
private $noDataString;
|
||||
private $isInvoices;
|
||||
private $isMerchantView;
|
||||
private $accountEmail;
|
||||
|
||||
public function setCarts(array $carts) {
|
||||
$this->carts = $carts;
|
||||
|
@ -43,13 +44,24 @@ final class PhortuneOrderTableView extends AphrontView {
|
|||
return $this->isMerchantView;
|
||||
}
|
||||
|
||||
public function setAccountEmail(PhortuneAccountEmail $account_email) {
|
||||
$this->accountEmail = $account_email;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAccountEmail() {
|
||||
return $this->accountEmail;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$carts = $this->getCarts();
|
||||
$viewer = $this->getUser();
|
||||
|
||||
$is_invoices = $this->getIsInvoices();
|
||||
$is_merchant = $this->getIsMerchantView();
|
||||
$is_external = (!$viewer->getPHID());
|
||||
$is_external = (bool)$this->getAccountEmail();
|
||||
|
||||
$email = $this->getAccountEmail();
|
||||
|
||||
$phids = array();
|
||||
foreach ($carts as $cart) {
|
||||
|
@ -65,7 +77,16 @@ final class PhortuneOrderTableView extends AphrontView {
|
|||
$rows = array();
|
||||
$rowc = array();
|
||||
foreach ($carts as $cart) {
|
||||
$cart_link = $handles[$cart->getPHID()]->renderLink();
|
||||
if ($is_external) {
|
||||
$cart_link = phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $email->getExternalOrderURI($cart),
|
||||
),
|
||||
$handles[$cart->getPHID()]->getName());
|
||||
} else {
|
||||
$cart_link = $handles[$cart->getPHID()]->renderLink();
|
||||
}
|
||||
$purchases = $cart->getPurchases();
|
||||
|
||||
if (count($purchases) == 1) {
|
||||
|
|
|
@ -22,6 +22,7 @@ final class PhortuneSubscriptionWorker extends PhabricatorWorker {
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
$account = $subscription->getAccount();
|
||||
$merchant = $subscription->getMerchant();
|
||||
|
||||
|
|
|
@ -1520,6 +1520,10 @@ abstract class PhabricatorApplicationTransactionEditor
|
|||
}
|
||||
}
|
||||
|
||||
foreach ($this->newAuxiliaryMail($object, $xactions) as $message) {
|
||||
$messages[] = $message;
|
||||
}
|
||||
|
||||
// NOTE: This actually sends the mail. We do this last to reduce the chance
|
||||
// that we send some mail, hit an exception, then send the mail again when
|
||||
// retrying.
|
||||
|
@ -4799,6 +4803,10 @@ abstract class PhabricatorApplicationTransactionEditor
|
|||
return $extensions;
|
||||
}
|
||||
|
||||
protected function newAuxiliaryMail($object, array $xactions) {
|
||||
return array();
|
||||
}
|
||||
|
||||
private function generateMailStamps($object, $data) {
|
||||
if (!$data || !is_array($data)) {
|
||||
return null;
|
||||
|
|
Loading…
Reference in a new issue