1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-09-20 17:28:51 +02:00

Mail account owners when they have an invoice due

Summary: Ref T6881. If we can't automatically bill an invoice, send the account owners a mail explaining why and asking them to pay it.

Test Plan: {F279596}

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T6881

Differential Revision: https://secure.phabricator.com/D11602
This commit is contained in:
epriestley 2015-02-01 12:33:03 -08:00
parent f6015dbb56
commit 58b3c5614b
4 changed files with 114 additions and 12 deletions

View file

@ -3,6 +3,21 @@
final class PhortuneCartEditor
extends PhabricatorApplicationTransactionEditor {
private $invoiceIssues;
public function setInvoiceIssues(array $invoice_issues) {
$this->invoiceIssues = $invoice_issues;
return $this;
}
public function getInvoiceIssues() {
return $this->invoiceIssues;
}
public function isInvoice() {
return (bool)$this->invoiceIssues;
}
public function getEditorApplicationClass() {
return 'PhabricatorPhortuneApplication';
}
@ -20,6 +35,7 @@ final class PhortuneCartEditor
$types[] = PhortuneCartTransaction::TYPE_REVIEW;
$types[] = PhortuneCartTransaction::TYPE_CANCEL;
$types[] = PhortuneCartTransaction::TYPE_REFUND;
$types[] = PhortuneCartTransaction::TYPE_INVOICED;
return $types;
}
@ -35,6 +51,7 @@ final class PhortuneCartEditor
case PhortuneCartTransaction::TYPE_REVIEW:
case PhortuneCartTransaction::TYPE_CANCEL:
case PhortuneCartTransaction::TYPE_REFUND:
case PhortuneCartTransaction::TYPE_INVOICED:
return null;
}
@ -52,6 +69,7 @@ final class PhortuneCartEditor
case PhortuneCartTransaction::TYPE_REVIEW:
case PhortuneCartTransaction::TYPE_CANCEL:
case PhortuneCartTransaction::TYPE_REFUND:
case PhortuneCartTransaction::TYPE_INVOICED:
return $xaction->getNewValue();
}
@ -69,6 +87,7 @@ final class PhortuneCartEditor
case PhortuneCartTransaction::TYPE_REVIEW:
case PhortuneCartTransaction::TYPE_CANCEL:
case PhortuneCartTransaction::TYPE_REFUND:
case PhortuneCartTransaction::TYPE_INVOICED:
return;
}
@ -86,6 +105,7 @@ final class PhortuneCartEditor
case PhortuneCartTransaction::TYPE_REVIEW:
case PhortuneCartTransaction::TYPE_CANCEL:
case PhortuneCartTransaction::TYPE_REFUND:
case PhortuneCartTransaction::TYPE_INVOICED:
return;
}
@ -113,6 +133,25 @@ final class PhortuneCartEditor
$body = parent::buildMailBody($object, $xactions);
if ($this->isInvoice()) {
$issues = $this->getInvoiceIssues();
foreach ($issues as $key => $issue) {
$issues[$key] = ' - '.$issue;
}
$issues = implode("\n", $issues);
$overview = pht(
"Payment for this invoice could not be processed automatically:\n\n".
"%s",
$issues);
$body->addRemarkupSection($overview);
$body->addLinkSection(
pht('PAY NOW'),
PhabricatorEnv::getProductionURI($object->getCheckoutURI()));
}
$items = array();
foreach ($object->getPurchases() as $purchase) {
$name = $purchase->getFullDisplayName();
@ -123,9 +162,26 @@ final class PhortuneCartEditor
$body->addTextSection(pht('ORDER CONTENTS'), implode("\n", $items));
if ($this->isInvoice()) {
$subscription = id(new PhortuneSubscriptionQuery())
->setViewer($this->requireActor())
->withPHIDs(array($object->getSubscriptionPHID()))
->executeOne();
if ($subscription) {
$body->addLinkSection(
pht('SUBSCRIPTION'),
PhabricatorEnv::getProductionURI($subscription->getURI()));
}
} else {
$body->addLinkSection(
pht('ORDER DETAIL'),
PhabricatorEnv::getProductionURI('/phortune/cart/'.$object->getID().'/'));
PhabricatorEnv::getProductionURI($object->getDetailURI()));
}
$account_uri = '/phortune/'.$object->getAccount()->getID().'/';
$body->addLinkSection(
pht('ACCOUNT OVERVIEW'),
PhabricatorEnv::getProductionURI($account_uri));
return $body;
}
@ -156,7 +212,7 @@ final class PhortuneCartEditor
}
protected function getMailSubjectPrefix() {
return 'Order';
return '[Phortune]';
}
protected function buildReplyHandler(PhabricatorLiskDAO $object) {

View file

@ -9,6 +9,7 @@ final class PhortuneCartTransaction
const TYPE_CANCEL = 'cart:cancel';
const TYPE_REFUND = 'cart:refund';
const TYPE_PURCHASED = 'cart:purchased';
const TYPE_INVOICED = 'cart:invoiced';
public function getApplicationName() {
return 'phortune';
@ -49,9 +50,42 @@ final class PhortuneCartTransaction
return pht('This order was refunded.');
case self::TYPE_PURCHASED:
return pht('Payment for this order was completed.');
case self::TYPE_INVOICED:
return pht('This order was invoiced.');
}
return parent::getTitle();
}
public function getTitleForMail() {
switch ($this->getTransactionType()) {
case self::TYPE_INVOICED:
return pht('You have a new invoice due.');
}
return parent::getTitleForMail();
}
public function getActionName() {
switch ($this->getTransactionType()) {
case self::TYPE_CREATED:
return pht('Created');
case self::TYPE_HOLD:
return pht('Hold');
case self::TYPE_REVIEW:
return pht('Review');
case self::TYPE_CANCEL:
return pht('Cancelled');
case self::TYPE_REFUND:
return pht('Refunded');
case self::TYPE_PURCHASED:
return pht('Complete');
case self::TYPE_INVOICED:
return pht('New Invoice');
}
return parent::getActionName();
}
}

View file

@ -22,12 +22,6 @@ abstract class PhortuneSubscriptionImplementation {
$start_epoch,
$end_epoch);
protected function getContentSource() {
return PhabricatorContentSource::newForSource(
PhabricatorContentSource::SOURCE_PHORTUNE,
array());
}
public function getCartName(
PhortuneSubscription $subscription,
PhortuneCart $cart) {

View file

@ -73,9 +73,27 @@ final class PhortuneSubscriptionWorker extends PhabricatorWorker {
return;
}
// TODO: Send an email telling the user that we weren't able to autopay
// so they need to pay this manually.
throw new Exception(implode("\n", $issues));
// We're shoving this through the CartEditor because it has all the logic
// for sending mail about carts. This doesn't really affect the state of
// the cart, but reduces the amount of code duplication.
$xactions = array();
$xactions[] = id(new PhortuneCartTransaction())
->setTransactionType(PhortuneCartTransaction::TYPE_INVOICED)
->setNewValue(true);
$content_source = PhabricatorContentSource::newForSource(
PhabricatorContentSource::SOURCE_PHORTUNE,
array());
$acting_phid = id(new PhabricatorPhortuneApplication())->getPHID();
$editor = id(new PhortuneCartEditor())
->setActor($viewer)
->setActingAsPHID($acting_phid)
->setContentSource($content_source)
->setContinueOnMissingFields(true)
->setInvoiceIssues($issues)
->applyTransactions($cart, $xactions);
}