1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-01-09 22:31:03 +01:00

Add "Carts" to Phortune

Summary: Although I imagine we aren't really going to have an "add to cart" type storefront, putting this in place makes a lot of other workflows simpler. No storage yet, just allows reasonable construction of a "buy stuff" page.

Test Plan: {F41342}

Reviewers: chad, btrahan

Reviewed By: chad

CC: aran

Maniphest Tasks: T2787

Differential Revision: https://secure.phabricator.com/D5745
This commit is contained in:
epriestley 2013-04-25 09:45:07 -07:00
parent 897274eed6
commit 2b5c0c4b3b
7 changed files with 160 additions and 13 deletions

View file

@ -1580,6 +1580,7 @@ phutil_register_library_map(array(
'PhortuneAccountTransaction' => 'applications/phortune/storage/PhortuneAccountTransaction.php', 'PhortuneAccountTransaction' => 'applications/phortune/storage/PhortuneAccountTransaction.php',
'PhortuneAccountTransactionQuery' => 'applications/phortune/query/PhortuneAccountTransactionQuery.php', 'PhortuneAccountTransactionQuery' => 'applications/phortune/query/PhortuneAccountTransactionQuery.php',
'PhortuneAccountViewController' => 'applications/phortune/controller/PhortuneAccountViewController.php', 'PhortuneAccountViewController' => 'applications/phortune/controller/PhortuneAccountViewController.php',
'PhortuneCart' => 'applications/phortune/storage/PhortuneCart.php',
'PhortuneCharge' => 'applications/phortune/storage/PhortuneCharge.php', 'PhortuneCharge' => 'applications/phortune/storage/PhortuneCharge.php',
'PhortuneController' => 'applications/phortune/controller/PhortuneController.php', 'PhortuneController' => 'applications/phortune/controller/PhortuneController.php',
'PhortuneDAO' => 'applications/phortune/storage/PhortuneDAO.php', 'PhortuneDAO' => 'applications/phortune/storage/PhortuneDAO.php',
@ -3293,6 +3294,7 @@ phutil_register_library_map(array(
'PhortuneAccountTransaction' => 'PhabricatorApplicationTransaction', 'PhortuneAccountTransaction' => 'PhabricatorApplicationTransaction',
'PhortuneAccountTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhortuneAccountTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhortuneAccountViewController' => 'PhortuneController', 'PhortuneAccountViewController' => 'PhortuneController',
'PhortuneCart' => 'PhortuneDAO',
'PhortuneCharge' => 'PhortuneDAO', 'PhortuneCharge' => 'PhortuneDAO',
'PhortuneController' => 'PhabricatorController', 'PhortuneController' => 'PhabricatorController',
'PhortuneDAO' => 'PhabricatorLiskDAO', 'PhortuneDAO' => 'PhabricatorLiskDAO',
@ -3318,7 +3320,7 @@ phutil_register_library_map(array(
'PhortuneProductQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhortuneProductQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhortuneProductTransaction' => 'PhabricatorApplicationTransaction', 'PhortuneProductTransaction' => 'PhabricatorApplicationTransaction',
'PhortuneProductTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhortuneProductTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhortuneProductViewController' => 'PhabricatorController', 'PhortuneProductViewController' => 'PhortuneController',
'PhortunePurchase' => 'PhortuneDAO', 'PhortunePurchase' => 'PhortuneDAO',
'PhortuneStripePaymentFormView' => 'AphrontView', 'PhortuneStripePaymentFormView' => 'AphrontView',
'PhrequentController' => 'PhabricatorController', 'PhrequentController' => 'PhabricatorController',

View file

@ -38,6 +38,7 @@ final class PhabricatorPHIDConstants {
const PHID_TYPE_PRCH = 'PRCH'; const PHID_TYPE_PRCH = 'PRCH';
const PHID_TYPE_PAYM = 'PAYM'; const PHID_TYPE_PAYM = 'PAYM';
const PHID_TYPE_CHRG = 'CHRG'; const PHID_TYPE_CHRG = 'CHRG';
const PHID_TYPE_CART = 'CART';
const PHID_TYPE_XACT = 'XACT'; const PHID_TYPE_XACT = 'XACT';
const PHID_TYPE_XCMT = 'XCMT'; const PHID_TYPE_XCMT = 'XCMT';

View file

@ -33,7 +33,87 @@ final class PhortuneAccountBuyController
return new Aphront404Response(); return new Aphront404Response();
} }
$title = pht('Buy %s', $product->getProductName()); $purchase = new PhortunePurchase();
$purchase->setProductPHID($product->getPHID());
$purchase->setAccountPHID($account->getPHID());
$purchase->setPurchaseName($product->getProductName());
$purchase->setBasePriceInCents($product->getPriceInCents());
$purchase->setQuantity(1);
$purchase->setTotalPriceInCents(
$purchase->getBasePriceInCents() * $purchase->getQuantity());
$purchase->setStatus(PhortunePurchase::STATUS_PENDING);
$cart = new PhortuneCart();
$cart->setAccountPHID($account->getPHID());
$cart->setOwnerPHID($user->getPHID());
$cart->attachPurchases(
array(
$purchase,
));
$rows = array();
$total = 0;
foreach ($cart->getPurchases() as $purchase) {
$rows[] = array(
$purchase->getPurchaseName(),
PhortuneUtil::formatCurrency($purchase->getBasePriceInCents()),
$purchase->getQuantity(),
PhortuneUtil::formatCurrency($purchase->getTotalPriceInCents()),
);
$total += $purchase->getTotalPriceInCents();
}
$rows[] = array(
phutil_tag('strong', array(), pht('Total')),
'',
'',
phutil_tag('strong', array(), PhortuneUtil::formatCurrency($total)),
);
$table = new AphrontTableView($rows);
$table->setHeaders(
array(
pht('Item'),
pht('Price'),
pht('Qty.'),
pht('Total'),
));
$panel = new AphrontPanelView();
$panel->setNoBackground(true);
$panel->appendChild($table);
$title = pht('Buy Stuff');
$methods = id(new PhortunePaymentMethodQuery())
->setViewer($user)
->withAccountPHIDs(array($account->getPHID()))
->withStatus(PhortunePaymentMethodQuery::STATUS_OPEN)
->execute();
$method_control = id(new AphrontFormRadioButtonControl())
->setLabel(pht('Payment Method'));
if (!$methods) {
$method_control = id(new AphrontFormStaticControl())
->setLabel(pht('Payment Method'))
->setValue(
phutil_tag('em', array(), pht('No payment methods configured.')));
} else {
$method_control = id(new AphrontFormRadioButtonControl())
->setLabel(pht('Payment Method'))
->setName('paymentMethodID')
->setValue($request->getInt('paymentMethodID'));
foreach ($methods as $method) {
$method_control->addButton(
$method->getID(),
$method->getName(),
$method->getDescription());
}
}
$payment_method_uri = $this->getApplicationURI( $payment_method_uri = $this->getApplicationURI(
$account->getID().'/paymentmethod/edit/'); $account->getID().'/paymentmethod/edit/');
@ -46,16 +126,9 @@ final class PhortuneAccountBuyController
), ),
pht('Add New Payment Method')); pht('Add New Payment Method'));
$form = id(new AphrontFormView()) $form = id(new AphrontFormView())
->setUser($user) ->setUser($user)
->appendChild( ->appendChild($method_control)
id(new AphrontFormStaticControl())
->setLabel(pht('Stuff'))
->setValue($product->getProductName()))
->appendChild(
id(new AphrontFormRadioButtonControl())
->setLabel(pht('Payment Method')))
->appendChild( ->appendChild(
id(new AphrontFormMarkupControl()) id(new AphrontFormMarkupControl())
->setValue($new_method)) ->setValue($new_method))
@ -64,7 +137,10 @@ final class PhortuneAccountBuyController
->setValue(pht("Dolla Dolla Bill Y'all"))); ->setValue(pht("Dolla Dolla Bill Y'all")));
return $this->buildApplicationPage( return $this->buildApplicationPage(
array(
$panel,
$form, $form,
),
array( array(
'title' => $title, 'title' => $title,
'device' => true, 'device' => true,

View file

@ -2,6 +2,21 @@
abstract class PhortuneController extends PhabricatorController { abstract class PhortuneController extends PhabricatorController {
protected function loadActiveAccount(PhabricatorUser $user) {
$accounts = id(new PhortuneAccountQuery())
->setViewer($user)
->withMemberPHIDs(array($user->getPHID()))
->execute();
if (!$accounts) {
return $this->createUserAccount($user);
} else if (count($accounts) == 1) {
return head($accounts);
} else {
throw new Exception("TODO: No account selection yet.");
}
}
protected function createUserAccount(PhabricatorUser $user) { protected function createUserAccount(PhabricatorUser $user) {
$request = $this->getRequest(); $request = $this->getRequest();

View file

@ -1,6 +1,6 @@
<?php <?php
final class PhortuneProductViewController extends PhabricatorController { final class PhortuneProductViewController extends PhortuneController {
private $productID; private $productID;
@ -26,7 +26,11 @@ final class PhortuneProductViewController extends PhabricatorController {
$header = id(new PhabricatorHeaderView()) $header = id(new PhabricatorHeaderView())
->setHeader($product->getProductName()); ->setHeader($product->getProductName());
$account = $this->loadActiveAccount($user);
$edit_uri = $this->getApplicationURI('product/edit/'.$product->getID().'/'); $edit_uri = $this->getApplicationURI('product/edit/'.$product->getID().'/');
$cart_uri = $this->getApplicationURI(
$account->getID().'/buy/'.$product->getID().'/');
$actions = id(new PhabricatorActionListView()) $actions = id(new PhabricatorActionListView())
->setUser($user) ->setUser($user)
@ -34,7 +38,14 @@ final class PhortuneProductViewController extends PhabricatorController {
id(new PhabricatorActionView()) id(new PhabricatorActionView())
->setName(pht('Edit Product')) ->setName(pht('Edit Product'))
->setHref($edit_uri) ->setHref($edit_uri)
->setIcon('edit')); ->setIcon('edit'))
->addAction(
id(new PhabricatorActionView())
->setUser($user)
->setName(pht('Purchase'))
->setHref($cart_uri)
->setIcon('new')
->setRenderAsForm(true));
$crumbs = $this->buildApplicationCrumbs(); $crumbs = $this->buildApplicationCrumbs();
$crumbs->setActionList($actions); $crumbs->setActionList($actions);

View file

@ -0,0 +1,38 @@
<?php
final class PhortuneCart extends PhortuneDAO {
protected $accountPHID;
protected $ownerPHID;
protected $metadata;
private $purchases;
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_SERIALIZATION => array(
'metadata' => self::SERIALIZATION_JSON,
),
) + parent::getConfiguration();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
PhabricatorPHIDConstants::PHID_TYPE_CART);
}
public function attachPurchases(array $purchases) {
assert_instances_of($purchases, 'PhortunePurchase');
$this->purchases = $purchases;
return $this;
}
public function getPurchases() {
if ($this->purchases === null) {
throw new Exception("Purchases not attached to cart!");
}
return $this->purchases;
}
}

View file

@ -46,6 +46,10 @@ final class PhortunePaymentMethod extends PhortuneDAO
return $this->account; return $this->account;
} }
public function getDescription() {
return pht('Expires %s', date('m/y'), $this->getExpiresEpoch());
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */ /* -( PhabricatorPolicyInterface )----------------------------------------- */