1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-22 06:42: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:
epriestley 2019-08-23 13:07:45 -07:00
parent 4e13551e85
commit a0a3879712
12 changed files with 216 additions and 13 deletions

View file

@ -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',

View file

@ -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()

View file

@ -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.');

View 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);
}
}

View file

@ -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())

View file

@ -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());
}
}

View file

@ -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;
}

View file

@ -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 )----------------------------------------- */

View file

@ -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 )------------------------- */

View file

@ -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) {

View file

@ -22,6 +22,7 @@ final class PhortuneSubscriptionWorker extends PhabricatorWorker {
return;
}
$account = $subscription->getAccount();
$merchant = $subscription->getMerchant();

View file

@ -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;