mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-19 05:12:41 +01:00
Make Fund transactions more informative and complete
Summary: Ref T5835. Show backing amounts in transactions. Account for and show refunds. Test Plan: {F215869} Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T5835 Differential Revision: https://secure.phabricator.com/D10676
This commit is contained in:
parent
38927d5704
commit
44415c5473
10 changed files with 125 additions and 36 deletions
|
@ -63,7 +63,8 @@ final class FundInitiativeViewController
|
|||
$timeline = id(new PhabricatorApplicationTransactionView())
|
||||
->setUser($viewer)
|
||||
->setObjectPHID($initiative->getPHID())
|
||||
->setTransactions($xactions);
|
||||
->setTransactions($xactions)
|
||||
->setShouldTerminate(true);
|
||||
|
||||
return $this->buildApplicationPage(
|
||||
array(
|
||||
|
|
|
@ -13,7 +13,9 @@ final class FundBackerEditor
|
|||
|
||||
public function getTransactionTypes() {
|
||||
$types = parent::getTransactionTypes();
|
||||
|
||||
$types[] = FundBackerTransaction::TYPE_STATUS;
|
||||
$types[] = FundBackerTransaction::TYPE_REFUND;
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
@ -24,6 +26,8 @@ final class FundBackerEditor
|
|||
switch ($xaction->getTransactionType()) {
|
||||
case FundBackerTransaction::TYPE_STATUS:
|
||||
return $object->getStatus();
|
||||
case FundBackerTransaction::TYPE_REFUND:
|
||||
return null;
|
||||
}
|
||||
|
||||
return parent::getCustomTransactionOldValue($object, $xaction);
|
||||
|
@ -35,6 +39,7 @@ final class FundBackerEditor
|
|||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case FundBackerTransaction::TYPE_STATUS:
|
||||
case FundBackerTransaction::TYPE_REFUND:
|
||||
return $xaction->getNewValue();
|
||||
}
|
||||
|
||||
|
@ -49,6 +54,8 @@ final class FundBackerEditor
|
|||
case FundBackerTransaction::TYPE_STATUS:
|
||||
$object->setStatus($xaction->getNewValue());
|
||||
return;
|
||||
case FundBackerTransaction::TYPE_REFUND:
|
||||
return;
|
||||
}
|
||||
|
||||
return parent::applyCustomInternalTransaction($object, $xaction);
|
||||
|
@ -60,6 +67,7 @@ final class FundBackerEditor
|
|||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case FundBackerTransaction::TYPE_STATUS:
|
||||
case FundBackerTransaction::TYPE_REFUND:
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ final class FundInitiativeEditor
|
|||
$types[] = FundInitiativeTransaction::TYPE_RISKS;
|
||||
$types[] = FundInitiativeTransaction::TYPE_STATUS;
|
||||
$types[] = FundInitiativeTransaction::TYPE_BACKER;
|
||||
$types[] = FundInitiativeTransaction::TYPE_REFUND;
|
||||
$types[] = FundInitiativeTransaction::TYPE_MERCHANT;
|
||||
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
|
||||
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
|
||||
|
@ -39,6 +40,7 @@ final class FundInitiativeEditor
|
|||
case FundInitiativeTransaction::TYPE_STATUS:
|
||||
return $object->getStatus();
|
||||
case FundInitiativeTransaction::TYPE_BACKER:
|
||||
case FundInitiativeTransaction::TYPE_REFUND:
|
||||
return null;
|
||||
case FundInitiativeTransaction::TYPE_MERCHANT:
|
||||
return $object->getMerchantPHID();
|
||||
|
@ -57,6 +59,7 @@ final class FundInitiativeEditor
|
|||
case FundInitiativeTransaction::TYPE_RISKS:
|
||||
case FundInitiativeTransaction::TYPE_STATUS:
|
||||
case FundInitiativeTransaction::TYPE_BACKER:
|
||||
case FundInitiativeTransaction::TYPE_REFUND:
|
||||
case FundInitiativeTransaction::TYPE_MERCHANT:
|
||||
return $xaction->getNewValue();
|
||||
}
|
||||
|
@ -68,7 +71,8 @@ final class FundInitiativeEditor
|
|||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
$type = $xaction->getTransactionType();
|
||||
switch ($type) {
|
||||
case FundInitiativeTransaction::TYPE_NAME:
|
||||
$object->setName($xaction->getNewValue());
|
||||
return;
|
||||
|
@ -85,18 +89,18 @@ final class FundInitiativeEditor
|
|||
$object->setStatus($xaction->getNewValue());
|
||||
return;
|
||||
case FundInitiativeTransaction::TYPE_BACKER:
|
||||
$backer = id(new FundBackerQuery())
|
||||
->setViewer($this->requireActor())
|
||||
->withPHIDs(array($xaction->getNewValue()))
|
||||
->executeOne();
|
||||
if (!$backer) {
|
||||
throw new Exception(pht('No such backer!'));
|
||||
case FundInitiativeTransaction::TYPE_REFUND:
|
||||
$amount = $xaction->getMetadataValue(
|
||||
FundInitiativeTransaction::PROPERTY_AMOUNT);
|
||||
$amount = PhortuneCurrency::newFromString($amount);
|
||||
|
||||
if ($type == FundInitiativeTransaction::TYPE_REFUND) {
|
||||
$total = $object->getTotalAsCurrency()->subtract($amount);
|
||||
} else {
|
||||
$total = $object->getTotalAsCurrency()->add($amount);
|
||||
}
|
||||
|
||||
$backer_amount = $backer->getAmountAsCurrency();
|
||||
$total = $object->getTotalAsCurrency()->add($backer_amount);
|
||||
$object->setTotalAsCurrency($total);
|
||||
|
||||
return;
|
||||
case PhabricatorTransactions::TYPE_SUBSCRIBERS:
|
||||
case PhabricatorTransactions::TYPE_EDGE:
|
||||
|
@ -110,14 +114,45 @@ final class FundInitiativeEditor
|
|||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
$type = $xaction->getTransactionType();
|
||||
switch ($type) {
|
||||
case FundInitiativeTransaction::TYPE_NAME:
|
||||
case FundInitiativeTransaction::TYPE_DESCRIPTION:
|
||||
case FundInitiativeTransaction::TYPE_RISKS:
|
||||
case FundInitiativeTransaction::TYPE_STATUS:
|
||||
case FundInitiativeTransaction::TYPE_MERCHANT:
|
||||
return;
|
||||
case FundInitiativeTransaction::TYPE_BACKER:
|
||||
// TODO: Maybe we should apply the backer transaction from here?
|
||||
case FundInitiativeTransaction::TYPE_REFUND:
|
||||
$backer = id(new FundBackerQuery())
|
||||
->setViewer($this->requireActor())
|
||||
->withPHIDs(array($xaction->getNewValue()))
|
||||
->executeOne();
|
||||
if (!$backer) {
|
||||
throw new Exception(pht('Unable to load FundBacker!'));
|
||||
}
|
||||
|
||||
$subx = array();
|
||||
|
||||
if ($type == FundInitiativeTransaction::TYPE_BACKER) {
|
||||
$subx[] = id(new FundBackerTransaction())
|
||||
->setTransactionType(FundBackerTransaction::TYPE_STATUS)
|
||||
->setNewValue(FundBacker::STATUS_PURCHASED);
|
||||
} else {
|
||||
$amount = $xaction->getMetadataValue(
|
||||
FundInitiativeTransaction::PROPERTY_AMOUNT);
|
||||
$subx[] = id(new FundBackerTransaction())
|
||||
->setTransactionType(FundBackerTransaction::TYPE_STATUS)
|
||||
->setNewValue($amount);
|
||||
}
|
||||
|
||||
$editor = id(new FundBackerEditor())
|
||||
->setActor($this->requireActor())
|
||||
->setContentSource($this->getContentSource())
|
||||
->setContinueOnMissingFields(true)
|
||||
->setContinueOnNoEffect(true);
|
||||
|
||||
$editor->applyTransactions($backer, $subx);
|
||||
return;
|
||||
case PhabricatorTransactions::TYPE_SUBSCRIBERS:
|
||||
case PhabricatorTransactions::TYPE_EDGE:
|
||||
|
|
|
@ -89,7 +89,7 @@ final class FundBackerProduct extends PhortuneProductImplementation {
|
|||
throw new Exception(pht('Unable to load FundBacker!'));
|
||||
}
|
||||
|
||||
// Load the actual backing user --they may not be the curent viewer if this
|
||||
// Load the actual backing user -- they may not be the curent viewer if this
|
||||
// product purchase is completing from a background worker or a merchant
|
||||
// action.
|
||||
|
||||
|
@ -98,20 +98,12 @@ final class FundBackerProduct extends PhortuneProductImplementation {
|
|||
->withPHIDs(array($backer->getBackerPHID()))
|
||||
->executeOne();
|
||||
|
||||
$xactions = array();
|
||||
$xactions[] = id(new FundBackerTransaction())
|
||||
->setTransactionType(FundBackerTransaction::TYPE_STATUS)
|
||||
->setNewValue(FundBacker::STATUS_PURCHASED);
|
||||
|
||||
$editor = id(new FundBackerEditor())
|
||||
->setActor($actor)
|
||||
->setContentSource($this->getContentSource());
|
||||
|
||||
$editor->applyTransactions($backer, $xactions);
|
||||
|
||||
$xactions = array();
|
||||
$xactions[] = id(new FundInitiativeTransaction())
|
||||
->setTransactionType(FundInitiativeTransaction::TYPE_BACKER)
|
||||
->setMetadataValue(
|
||||
FundInitiativeTransaction::PROPERTY_AMOUNT,
|
||||
$backer->getAmountAsCurrency()->serializeForStorage())
|
||||
->setNewValue($backer->getPHID());
|
||||
|
||||
$editor = id(new FundInitiativeEditor())
|
||||
|
@ -119,15 +111,38 @@ final class FundBackerProduct extends PhortuneProductImplementation {
|
|||
->setContentSource($this->getContentSource());
|
||||
|
||||
$editor->applyTransactions($this->getInitiative(), $xactions);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public function didRefundProduct(
|
||||
PhortuneProduct $product,
|
||||
PhortunePurchase $purchase) {
|
||||
PhortunePurchase $purchase,
|
||||
PhortuneCurrency $amount) {
|
||||
$viewer = $this->getViewer();
|
||||
// TODO: Undonate.
|
||||
|
||||
$backer = id(new FundBackerQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($purchase->getMetadataValue('backerPHID')))
|
||||
->executeOne();
|
||||
if (!$backer) {
|
||||
throw new Exception(pht('Unable to load FundBacker!'));
|
||||
}
|
||||
|
||||
$xactions = array();
|
||||
$xactions[] = id(new FundInitiativeTransaction())
|
||||
->setTransactionType(FundInitiativeTransaction::TYPE_REFUND)
|
||||
->setMetadataValue(
|
||||
FundInitiativeTransaction::PROPERTY_AMOUNT,
|
||||
$amount->serializeForStorage())
|
||||
->setMetadataValue(
|
||||
FundInitiativeTransaction::PROPERTY_BACKER,
|
||||
$backer->getBackerPHID())
|
||||
->setNewValue($backer->getPHID());
|
||||
|
||||
$editor = id(new FundInitiativeEditor())
|
||||
->setActor($viewer)
|
||||
->setContentSource($this->getContentSource());
|
||||
|
||||
$editor->applyTransactions($this->getInitiative(), $xactions);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ final class FundBackerTransaction
|
|||
extends PhabricatorApplicationTransaction {
|
||||
|
||||
const TYPE_STATUS = 'fund:backer:status';
|
||||
const TYPE_REFUND = 'fund:backer:refund';
|
||||
|
||||
public function getApplicationName() {
|
||||
return 'fund';
|
||||
|
|
|
@ -8,8 +8,12 @@ final class FundInitiativeTransaction
|
|||
const TYPE_RISKS = 'fund:risks';
|
||||
const TYPE_STATUS = 'fund:status';
|
||||
const TYPE_BACKER = 'fund:backer';
|
||||
const TYPE_REFUND = 'fund:refund';
|
||||
const TYPE_MERCHANT = 'fund:merchant';
|
||||
|
||||
const PROPERTY_AMOUNT = 'fund.amount';
|
||||
const PROPERTY_BACKER = 'fund.backer';
|
||||
|
||||
public function getApplicationName() {
|
||||
return 'fund';
|
||||
}
|
||||
|
@ -38,6 +42,9 @@ final class FundInitiativeTransaction
|
|||
$phids[] = $new;
|
||||
}
|
||||
break;
|
||||
case FundInitiativeTransaction::TYPE_REFUND:
|
||||
$phids[] = $this->getMetadataValue(self::PROPERTY_BACKER);
|
||||
break;
|
||||
}
|
||||
|
||||
return $phids;
|
||||
|
@ -86,9 +93,23 @@ final class FundInitiativeTransaction
|
|||
}
|
||||
break;
|
||||
case FundInitiativeTransaction::TYPE_BACKER:
|
||||
$amount = $this->getMetadataValue(self::PROPERTY_AMOUNT);
|
||||
$amount = PhortuneCurrency::newFromString($amount);
|
||||
return pht(
|
||||
'%s backed this initiative.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
'%s backed this initiative with %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$amount->formatForDisplay());
|
||||
case FundInitiativeTransaction::TYPE_REFUND:
|
||||
$amount = $this->getMetadataValue(self::PROPERTY_AMOUNT);
|
||||
$amount = PhortuneCurrency::newFromString($amount);
|
||||
|
||||
$backer_phid = $this->getMetadataValue(self::PROPERTY_BACKER);
|
||||
|
||||
return pht(
|
||||
'%s refunded %s to %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$amount->formatForDisplay(),
|
||||
$this->renderHandleLink($backer_phid));
|
||||
case FundInitiativeTransaction::TYPE_MERCHANT:
|
||||
if ($old === null) {
|
||||
return pht(
|
||||
|
|
|
@ -87,7 +87,7 @@ final class PhortuneCartCancelController
|
|||
$request->getStr('refund'));
|
||||
$refund->assertInRange('0.00 USD', $maximum->formatForDisplay());
|
||||
} catch (Exception $ex) {
|
||||
$errors[] = $ex;
|
||||
$errors[] = $ex->getMessage();
|
||||
$e_refund = pht('Invalid');
|
||||
}
|
||||
} else {
|
||||
|
@ -199,6 +199,7 @@ final class PhortuneCartCancelController
|
|||
|
||||
return $this->newDialog()
|
||||
->setTitle($title)
|
||||
->setErrors($errors)
|
||||
->appendChild($body)
|
||||
->appendChild($form)
|
||||
->addSubmitButton($button)
|
||||
|
|
|
@ -30,7 +30,8 @@ abstract class PhortuneProductImplementation {
|
|||
|
||||
public function didRefundProduct(
|
||||
PhortuneProduct $product,
|
||||
PhortunePurchase $purchase) {
|
||||
PhortunePurchase $purchase,
|
||||
PhortuneCurrency $amount) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -351,8 +351,9 @@ final class PhortuneCart extends PhortuneDAO
|
|||
$this->endReadLocking();
|
||||
$this->saveTransaction();
|
||||
|
||||
$amount = $refund->getAmountAsCurrency()->negate();
|
||||
foreach ($this->purchases as $purchase) {
|
||||
$purchase->getProduct()->didRefundProduct($purchase);
|
||||
$purchase->getProduct()->didRefundProduct($purchase, $amount);
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
|
|
@ -78,8 +78,13 @@ final class PhortuneProduct extends PhortuneDAO
|
|||
return $this->getImplementation()->didPurchaseProduct($this, $purchase);
|
||||
}
|
||||
|
||||
public function didRefundProduct(PhortunePurchase $purchase) {
|
||||
return $this->getImplementation()->didRefundProduct($this, $purchase);
|
||||
public function didRefundProduct(
|
||||
PhortunePurchase $purchase,
|
||||
PhortuneCurrency $amount) {
|
||||
return $this->getImplementation()->didRefundProduct(
|
||||
$this,
|
||||
$purchase,
|
||||
$amount);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue