mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 08:52:39 +01: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:
parent
f6015dbb56
commit
58b3c5614b
4 changed files with 114 additions and 12 deletions
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue