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:
parent
897274eed6
commit
2b5c0c4b3b
7 changed files with 160 additions and 13 deletions
|
@ -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',
|
||||||
|
|
|
@ -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';
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
38
src/applications/phortune/storage/PhortuneCart.php
Normal file
38
src/applications/phortune/storage/PhortuneCart.php
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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 )----------------------------------------- */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue