From 214b5b71581054d4b83e8ebcc2edcb9699056629 Mon Sep 17 00:00:00 2001 From: epriestley Date: Mon, 13 Oct 2014 11:16:27 -0700 Subject: [PATCH] Add cart transactions to Phortune Summary: Ref T2787. I mostly just want these in place so I can glue emails to them, but they're also useful on their own. Test Plan: {F216515} Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T2787 Differential Revision: https://secure.phabricator.com/D10688 --- .../20141012.phortunecartxaction.sql | 19 ++++ src/__phutil_library_map__.php | 6 ++ .../PhortuneAccountViewController.php | 6 +- .../controller/PhortuneCartViewController.php | 12 +++ .../phortune/editor/PhortuneCartEditor.php | 95 +++++++++++++++++++ .../query/PhortuneCartTransactionQuery.php | 10 ++ .../phortune/storage/PhortuneCart.php | 51 +++++++++- .../storage/PhortuneCartTransaction.php | 48 ++++++++++ 8 files changed, 240 insertions(+), 7 deletions(-) create mode 100644 resources/sql/autopatches/20141012.phortunecartxaction.sql create mode 100644 src/applications/phortune/editor/PhortuneCartEditor.php create mode 100644 src/applications/phortune/query/PhortuneCartTransactionQuery.php create mode 100644 src/applications/phortune/storage/PhortuneCartTransaction.php diff --git a/resources/sql/autopatches/20141012.phortunecartxaction.sql b/resources/sql/autopatches/20141012.phortunecartxaction.sql new file mode 100644 index 0000000000..9789377b37 --- /dev/null +++ b/resources/sql/autopatches/20141012.phortunecartxaction.sql @@ -0,0 +1,19 @@ +CREATE TABLE {$NAMESPACE}_phortune.phortune_carttransaction ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + phid VARCHAR(64) COLLATE utf8_bin NOT NULL, + authorPHID VARCHAR(64) COLLATE utf8_bin NOT NULL, + objectPHID VARCHAR(64) COLLATE utf8_bin NOT NULL, + viewPolicy VARCHAR(64) COLLATE utf8_bin NOT NULL, + editPolicy VARCHAR(64) COLLATE utf8_bin NOT NULL, + commentPHID VARCHAR(64) COLLATE utf8_bin DEFAULT NULL, + commentVersion INT UNSIGNED NOT NULL, + transactionType VARCHAR(32) COLLATE utf8_bin NOT NULL, + oldValue LONGTEXT COLLATE utf8_bin NOT NULL, + newValue LONGTEXT COLLATE utf8_bin NOT NULL, + contentSource LONGTEXT COLLATE utf8_bin NOT NULL, + metadata LONGTEXT COLLATE utf8_bin NOT NULL, + dateCreated INT UNSIGNED NOT NULL, + dateModified INT UNSIGNED NOT NULL, + UNIQUE KEY `key_phid` (`phid`), + KEY `key_object` (`objectPHID`) +) ENGINE=InnoDB, COLLATE utf8_general_ci; diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index a8e1ac13d2..1b4088d867 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2563,11 +2563,14 @@ phutil_register_library_map(array( 'PhortuneCartCancelController' => 'applications/phortune/controller/PhortuneCartCancelController.php', 'PhortuneCartCheckoutController' => 'applications/phortune/controller/PhortuneCartCheckoutController.php', 'PhortuneCartController' => 'applications/phortune/controller/PhortuneCartController.php', + 'PhortuneCartEditor' => 'applications/phortune/editor/PhortuneCartEditor.php', 'PhortuneCartImplementation' => 'applications/phortune/cart/PhortuneCartImplementation.php', 'PhortuneCartListController' => 'applications/phortune/controller/PhortuneCartListController.php', 'PhortuneCartPHIDType' => 'applications/phortune/phid/PhortuneCartPHIDType.php', 'PhortuneCartQuery' => 'applications/phortune/query/PhortuneCartQuery.php', 'PhortuneCartSearchEngine' => 'applications/phortune/query/PhortuneCartSearchEngine.php', + 'PhortuneCartTransaction' => 'applications/phortune/storage/PhortuneCartTransaction.php', + 'PhortuneCartTransactionQuery' => 'applications/phortune/query/PhortuneCartTransactionQuery.php', 'PhortuneCartUpdateController' => 'applications/phortune/controller/PhortuneCartUpdateController.php', 'PhortuneCartViewController' => 'applications/phortune/controller/PhortuneCartViewController.php', 'PhortuneCharge' => 'applications/phortune/storage/PhortuneCharge.php', @@ -5631,10 +5634,13 @@ phutil_register_library_map(array( 'PhortuneCartCancelController' => 'PhortuneCartController', 'PhortuneCartCheckoutController' => 'PhortuneCartController', 'PhortuneCartController' => 'PhortuneController', + 'PhortuneCartEditor' => 'PhabricatorApplicationTransactionEditor', 'PhortuneCartListController' => 'PhortuneController', 'PhortuneCartPHIDType' => 'PhabricatorPHIDType', 'PhortuneCartQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhortuneCartSearchEngine' => 'PhabricatorApplicationSearchEngine', + 'PhortuneCartTransaction' => 'PhabricatorApplicationTransaction', + 'PhortuneCartTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhortuneCartUpdateController' => 'PhortuneCartController', 'PhortuneCartViewController' => 'PhortuneCartController', 'PhortuneCharge' => array( diff --git a/src/applications/phortune/controller/PhortuneAccountViewController.php b/src/applications/phortune/controller/PhortuneAccountViewController.php index 0fd3652f26..f3b8a4efee 100644 --- a/src/applications/phortune/controller/PhortuneAccountViewController.php +++ b/src/applications/phortune/controller/PhortuneAccountViewController.php @@ -267,14 +267,10 @@ final class PhortuneAccountViewController extends PhortuneController { ->withObjectPHIDs(array($account->getPHID())) ->execute(); - $engine = id(new PhabricatorMarkupEngine()) - ->setViewer($user); - $xaction_view = id(new PhabricatorApplicationTransactionView()) ->setUser($user) ->setObjectPHID($account->getPHID()) - ->setTransactions($xactions) - ->setMarkupEngine($engine); + ->setTransactions($xactions); return $xaction_view; } diff --git a/src/applications/phortune/controller/PhortuneCartViewController.php b/src/applications/phortune/controller/PhortuneCartViewController.php index aeb11ed9c8..2ec49cc6c6 100644 --- a/src/applications/phortune/controller/PhortuneCartViewController.php +++ b/src/applications/phortune/controller/PhortuneCartViewController.php @@ -160,11 +160,23 @@ final class PhortuneCartViewController $this->addAccountCrumb($crumbs, $cart->getAccount()); $crumbs->addTextCrumb(pht('Cart %d', $cart->getID())); + $xactions = id(new PhortuneCartTransactionQuery()) + ->setViewer($viewer) + ->withObjectPHIDs(array($cart->getPHID())) + ->execute(); + + $xaction_view = id(new PhabricatorApplicationTransactionView()) + ->setUser($viewer) + ->setObjectPHID($cart->getPHID()) + ->setTransactions($xactions) + ->setShouldTerminate(true); + return $this->buildApplicationPage( array( $crumbs, $cart_box, $charges, + $xaction_view, ), array( 'title' => pht('Cart'), diff --git a/src/applications/phortune/editor/PhortuneCartEditor.php b/src/applications/phortune/editor/PhortuneCartEditor.php new file mode 100644 index 0000000000..ed65f7a438 --- /dev/null +++ b/src/applications/phortune/editor/PhortuneCartEditor.php @@ -0,0 +1,95 @@ +getTransactionType()) { + case PhortuneCartTransaction::TYPE_CREATED: + case PhortuneCartTransaction::TYPE_PURCHASED: + case PhortuneCartTransaction::TYPE_HOLD: + case PhortuneCartTransaction::TYPE_REVIEW: + case PhortuneCartTransaction::TYPE_CANCEL: + case PhortuneCartTransaction::TYPE_REFUND: + return null; + } + + return parent::getCustomTransactionOldValue($object, $xaction); + } + + protected function getCustomTransactionNewValue( + PhabricatorLiskDAO $object, + PhabricatorApplicationTransaction $xaction) { + + switch ($xaction->getTransactionType()) { + case PhortuneCartTransaction::TYPE_CREATED: + case PhortuneCartTransaction::TYPE_PURCHASED: + case PhortuneCartTransaction::TYPE_HOLD: + case PhortuneCartTransaction::TYPE_REVIEW: + case PhortuneCartTransaction::TYPE_CANCEL: + case PhortuneCartTransaction::TYPE_REFUND: + return $xaction->getNewValue(); + } + + return parent::getCustomTransactionNewValue($object, $xaction); + } + + protected function applyCustomInternalTransaction( + PhabricatorLiskDAO $object, + PhabricatorApplicationTransaction $xaction) { + + switch ($xaction->getTransactionType()) { + case PhortuneCartTransaction::TYPE_CREATED: + case PhortuneCartTransaction::TYPE_PURCHASED: + case PhortuneCartTransaction::TYPE_HOLD: + case PhortuneCartTransaction::TYPE_REVIEW: + case PhortuneCartTransaction::TYPE_CANCEL: + case PhortuneCartTransaction::TYPE_REFUND: + return; + } + + return parent::applyCustomInternalTransaction($object, $xaction); + } + + protected function applyCustomExternalTransaction( + PhabricatorLiskDAO $object, + PhabricatorApplicationTransaction $xaction) { + + switch ($xaction->getTransactionType()) { + case PhortuneCartTransaction::TYPE_CREATED: + case PhortuneCartTransaction::TYPE_PURCHASED: + case PhortuneCartTransaction::TYPE_HOLD: + case PhortuneCartTransaction::TYPE_REVIEW: + case PhortuneCartTransaction::TYPE_CANCEL: + case PhortuneCartTransaction::TYPE_REFUND: + return; + } + + return parent::applyCustomExternalTransaction($object, $xaction); + } + +} diff --git a/src/applications/phortune/query/PhortuneCartTransactionQuery.php b/src/applications/phortune/query/PhortuneCartTransactionQuery.php new file mode 100644 index 0000000000..a72b74814f --- /dev/null +++ b/src/applications/phortune/query/PhortuneCartTransactionQuery.php @@ -0,0 +1,10 @@ +setStatus(self::STATUS_READY)->save(); + $this->openTransaction(); + $this->beginReadLocking(); + + $copy = clone $this; + $copy->reload(); + + if ($copy->getStatus() !== self::STATUS_BUILDING) { + throw new Exception( + pht( + 'Cart has wrong status ("%s") to call willApplyCharge().', + $copy->getStatus())); + } + + $this->setStatus(self::STATUS_READY)->save(); + + $this->endReadLocking(); + $this->saveTransaction(); + + $this->recordCartTransaction(PhortuneCartTransaction::TYPE_CREATED); + return $this; } @@ -140,6 +159,8 @@ final class PhortuneCart extends PhortuneDAO $this->endReadLocking(); $this->saveTransaction(); + + $this->recordCartTransaction(PhortuneCartTransaction::TYPE_HOLD); } public function didApplyCharge(PhortuneCharge $charge) { @@ -199,7 +220,7 @@ final class PhortuneCart extends PhortuneDAO $this->endReadLocking(); $this->saveTransaction(); - // TODO: Notify merchant to review order. + $this->recordCartTransaction(PhortuneCartTransaction::TYPE_REVIEW); return $this; } @@ -228,6 +249,8 @@ final class PhortuneCart extends PhortuneDAO $this->endReadLocking(); $this->saveTransaction(); + $this->recordCartTransaction(PhortuneCartTransaction::TYPE_PURCHASED); + return $this; } @@ -384,6 +407,30 @@ final class PhortuneCart extends PhortuneDAO $this->saveTransaction(); } + private function recordCartTransaction($type) { + $omnipotent_user = PhabricatorUser::getOmnipotentUser(); + $phortune_phid = id(new PhabricatorPhortuneApplication())->getPHID(); + + $xactions = array(); + + $xactions[] = id(new PhortuneCartTransaction()) + ->setTransactionType($type) + ->setNewValue(true); + + $content_source = PhabricatorContentSource::newForSource( + PhabricatorContentSource::SOURCE_PHORTUNE, + array()); + + $editor = id(new PhortuneCartEditor()) + ->setActor($omnipotent_user) + ->setActingAsPHID($phortune_phid) + ->setContentSource($content_source) + ->setContinueOnMissingFields(true) + ->setContinueOnNoEffect(true); + + $editor->applyTransactions($this, $xactions); + } + public function getName() { return $this->getImplementation()->getName($this); } diff --git a/src/applications/phortune/storage/PhortuneCartTransaction.php b/src/applications/phortune/storage/PhortuneCartTransaction.php new file mode 100644 index 0000000000..6908d1fd16 --- /dev/null +++ b/src/applications/phortune/storage/PhortuneCartTransaction.php @@ -0,0 +1,48 @@ +getOldValue(); + $new = $this->getNewValue(); + + switch ($this->getTransactionType()) { + case self::TYPE_CREATED: + return pht('This order was created.'); + case self::TYPE_HOLD: + return pht('This order was put on hold until payment clears.'); + case self::TYPE_REVIEW: + return pht( + 'This order was flagged for manual processing by the merchant.'); + case self::TYPE_CANCEL: + return pht('This order was cancelled.'); + case self::TYPE_REFUND: + return pht('This order was refunded.'); + case self::TYPE_PURCHASED: + return pht('Payment for this order was completed.'); + } + + return parent::getTitle(); + } + +}