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 final class PhortuneCartEditor
extends PhabricatorApplicationTransactionEditor { 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() { public function getEditorApplicationClass() {
return 'PhabricatorPhortuneApplication'; return 'PhabricatorPhortuneApplication';
} }
@ -20,6 +35,7 @@ final class PhortuneCartEditor
$types[] = PhortuneCartTransaction::TYPE_REVIEW; $types[] = PhortuneCartTransaction::TYPE_REVIEW;
$types[] = PhortuneCartTransaction::TYPE_CANCEL; $types[] = PhortuneCartTransaction::TYPE_CANCEL;
$types[] = PhortuneCartTransaction::TYPE_REFUND; $types[] = PhortuneCartTransaction::TYPE_REFUND;
$types[] = PhortuneCartTransaction::TYPE_INVOICED;
return $types; return $types;
} }
@ -35,6 +51,7 @@ final class PhortuneCartEditor
case PhortuneCartTransaction::TYPE_REVIEW: case PhortuneCartTransaction::TYPE_REVIEW:
case PhortuneCartTransaction::TYPE_CANCEL: case PhortuneCartTransaction::TYPE_CANCEL:
case PhortuneCartTransaction::TYPE_REFUND: case PhortuneCartTransaction::TYPE_REFUND:
case PhortuneCartTransaction::TYPE_INVOICED:
return null; return null;
} }
@ -52,6 +69,7 @@ final class PhortuneCartEditor
case PhortuneCartTransaction::TYPE_REVIEW: case PhortuneCartTransaction::TYPE_REVIEW:
case PhortuneCartTransaction::TYPE_CANCEL: case PhortuneCartTransaction::TYPE_CANCEL:
case PhortuneCartTransaction::TYPE_REFUND: case PhortuneCartTransaction::TYPE_REFUND:
case PhortuneCartTransaction::TYPE_INVOICED:
return $xaction->getNewValue(); return $xaction->getNewValue();
} }
@ -69,6 +87,7 @@ final class PhortuneCartEditor
case PhortuneCartTransaction::TYPE_REVIEW: case PhortuneCartTransaction::TYPE_REVIEW:
case PhortuneCartTransaction::TYPE_CANCEL: case PhortuneCartTransaction::TYPE_CANCEL:
case PhortuneCartTransaction::TYPE_REFUND: case PhortuneCartTransaction::TYPE_REFUND:
case PhortuneCartTransaction::TYPE_INVOICED:
return; return;
} }
@ -86,6 +105,7 @@ final class PhortuneCartEditor
case PhortuneCartTransaction::TYPE_REVIEW: case PhortuneCartTransaction::TYPE_REVIEW:
case PhortuneCartTransaction::TYPE_CANCEL: case PhortuneCartTransaction::TYPE_CANCEL:
case PhortuneCartTransaction::TYPE_REFUND: case PhortuneCartTransaction::TYPE_REFUND:
case PhortuneCartTransaction::TYPE_INVOICED:
return; return;
} }
@ -113,6 +133,25 @@ final class PhortuneCartEditor
$body = parent::buildMailBody($object, $xactions); $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(); $items = array();
foreach ($object->getPurchases() as $purchase) { foreach ($object->getPurchases() as $purchase) {
$name = $purchase->getFullDisplayName(); $name = $purchase->getFullDisplayName();
@ -123,9 +162,26 @@ final class PhortuneCartEditor
$body->addTextSection(pht('ORDER CONTENTS'), implode("\n", $items)); $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( $body->addLinkSection(
pht('ORDER DETAIL'), 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; return $body;
} }
@ -156,7 +212,7 @@ final class PhortuneCartEditor
} }
protected function getMailSubjectPrefix() { protected function getMailSubjectPrefix() {
return 'Order'; return '[Phortune]';
} }
protected function buildReplyHandler(PhabricatorLiskDAO $object) { protected function buildReplyHandler(PhabricatorLiskDAO $object) {

View file

@ -9,6 +9,7 @@ final class PhortuneCartTransaction
const TYPE_CANCEL = 'cart:cancel'; const TYPE_CANCEL = 'cart:cancel';
const TYPE_REFUND = 'cart:refund'; const TYPE_REFUND = 'cart:refund';
const TYPE_PURCHASED = 'cart:purchased'; const TYPE_PURCHASED = 'cart:purchased';
const TYPE_INVOICED = 'cart:invoiced';
public function getApplicationName() { public function getApplicationName() {
return 'phortune'; return 'phortune';
@ -49,9 +50,42 @@ final class PhortuneCartTransaction
return pht('This order was refunded.'); return pht('This order was refunded.');
case self::TYPE_PURCHASED: case self::TYPE_PURCHASED:
return pht('Payment for this order was completed.'); return pht('Payment for this order was completed.');
case self::TYPE_INVOICED:
return pht('This order was invoiced.');
} }
return parent::getTitle(); 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, $start_epoch,
$end_epoch); $end_epoch);
protected function getContentSource() {
return PhabricatorContentSource::newForSource(
PhabricatorContentSource::SOURCE_PHORTUNE,
array());
}
public function getCartName( public function getCartName(
PhortuneSubscription $subscription, PhortuneSubscription $subscription,
PhortuneCart $cart) { PhortuneCart $cart) {

View file

@ -73,9 +73,27 @@ final class PhortuneSubscriptionWorker extends PhabricatorWorker {
return; return;
} }
// TODO: Send an email telling the user that we weren't able to autopay // We're shoving this through the CartEditor because it has all the logic
// so they need to pay this manually. // for sending mail about carts. This doesn't really affect the state of
throw new Exception(implode("\n", $issues)); // 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);
} }