mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 14:52:41 +01:00
Give the Phortune external portal an order view
Summary: Depends on D20739. Ref T13366. Slightly modularize/update components of order views, and make orders viewable from either an account context (existing view) or an external context (new view). The new view is generally simpler so this mostly just reorganizes existing code. Test Plan: Viewed orders as an account owner and an external user. Maniphest Tasks: T13366 Differential Revision: https://secure.phabricator.com/D20740
This commit is contained in:
parent
a0a3879712
commit
97a4a59cf2
13 changed files with 663 additions and 463 deletions
|
@ -5302,7 +5302,6 @@ phutil_register_library_map(array(
|
|||
'PhortuneExternalOrderController' => 'applications/phortune/controller/external/PhortuneExternalOrderController.php',
|
||||
'PhortuneExternalOverviewController' => 'applications/phortune/controller/external/PhortuneExternalOverviewController.php',
|
||||
'PhortuneExternalUnsubscribeController' => 'applications/phortune/controller/external/PhortuneExternalUnsubscribeController.php',
|
||||
'PhortuneInvoiceView' => 'applications/phortune/view/PhortuneInvoiceView.php',
|
||||
'PhortuneLandingController' => 'applications/phortune/controller/PhortuneLandingController.php',
|
||||
'PhortuneMemberHasAccountEdgeType' => 'applications/phortune/edge/PhortuneMemberHasAccountEdgeType.php',
|
||||
'PhortuneMemberHasMerchantEdgeType' => 'applications/phortune/edge/PhortuneMemberHasMerchantEdgeType.php',
|
||||
|
@ -5343,7 +5342,11 @@ phutil_register_library_map(array(
|
|||
'PhortuneMerchantTransactionQuery' => 'applications/phortune/query/PhortuneMerchantTransactionQuery.php',
|
||||
'PhortuneMerchantTransactionType' => 'applications/phortune/xaction/PhortuneMerchantTransactionType.php',
|
||||
'PhortuneMonthYearExpiryControl' => 'applications/phortune/control/PhortuneMonthYearExpiryControl.php',
|
||||
'PhortuneOrderDescriptionView' => 'applications/phortune/view/PhortuneOrderDescriptionView.php',
|
||||
'PhortuneOrderItemsView' => 'applications/phortune/view/PhortuneOrderItemsView.php',
|
||||
'PhortuneOrderSummaryView' => 'applications/phortune/view/PhortuneOrderSummaryView.php',
|
||||
'PhortuneOrderTableView' => 'applications/phortune/view/PhortuneOrderTableView.php',
|
||||
'PhortuneOrderView' => 'applications/phortune/view/PhortuneOrderView.php',
|
||||
'PhortunePayPalPaymentProvider' => 'applications/phortune/provider/PhortunePayPalPaymentProvider.php',
|
||||
'PhortunePaymentMethod' => 'applications/phortune/storage/PhortunePaymentMethod.php',
|
||||
'PhortunePaymentMethodCreateController' => 'applications/phortune/controller/paymentmethod/PhortunePaymentMethodCreateController.php',
|
||||
|
@ -11895,7 +11898,6 @@ phutil_register_library_map(array(
|
|||
'PhortuneExternalOrderController' => 'PhortuneExternalController',
|
||||
'PhortuneExternalOverviewController' => 'PhortuneExternalController',
|
||||
'PhortuneExternalUnsubscribeController' => 'PhortuneExternalController',
|
||||
'PhortuneInvoiceView' => 'AphrontTagView',
|
||||
'PhortuneLandingController' => 'PhortuneController',
|
||||
'PhortuneMemberHasAccountEdgeType' => 'PhabricatorEdgeType',
|
||||
'PhortuneMemberHasMerchantEdgeType' => 'PhabricatorEdgeType',
|
||||
|
@ -11940,7 +11942,11 @@ phutil_register_library_map(array(
|
|||
'PhortuneMerchantTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhortuneMerchantTransactionType' => 'PhabricatorModularTransactionType',
|
||||
'PhortuneMonthYearExpiryControl' => 'AphrontFormControl',
|
||||
'PhortuneOrderDescriptionView' => 'AphrontView',
|
||||
'PhortuneOrderItemsView' => 'PhortuneOrderView',
|
||||
'PhortuneOrderSummaryView' => 'PhortuneOrderView',
|
||||
'PhortuneOrderTableView' => 'AphrontView',
|
||||
'PhortuneOrderView' => 'AphrontView',
|
||||
'PhortunePayPalPaymentProvider' => 'PhortunePaymentProvider',
|
||||
'PhortunePaymentMethod' => array(
|
||||
'PhortuneDAO',
|
||||
|
|
|
@ -481,7 +481,7 @@ abstract class PhabricatorController extends AphrontController {
|
|||
|
||||
protected function buildTransactionTimeline(
|
||||
PhabricatorApplicationTransactionInterface $object,
|
||||
PhabricatorApplicationTransactionQuery $query,
|
||||
PhabricatorApplicationTransactionQuery $query = null,
|
||||
PhabricatorMarkupEngine $engine = null,
|
||||
$view_data = array()) {
|
||||
|
||||
|
@ -489,6 +489,17 @@ abstract class PhabricatorController extends AphrontController {
|
|||
$viewer = $this->getViewer();
|
||||
$xaction = $object->getApplicationTransactionTemplate();
|
||||
|
||||
if (!$query) {
|
||||
$query = PhabricatorApplicationTransactionQuery::newQueryForObject(
|
||||
$object);
|
||||
if (!$query) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Unable to find transaction query for object of class "%s".',
|
||||
get_class($object)));
|
||||
}
|
||||
}
|
||||
|
||||
$pager = id(new AphrontCursorPagerView())
|
||||
->readFromRequest($request)
|
||||
->setURI(new PhutilURI(
|
||||
|
|
|
@ -113,7 +113,10 @@ final class PhabricatorPhortuneApplication extends PhabricatorApplication {
|
|||
'' => 'PhortuneExternalOverviewController',
|
||||
'unsubscribe/' => 'PhortuneExternalUnsubscribeController',
|
||||
'order/' => array(
|
||||
'(?P<orderID>[^/]+)/' => 'PhortuneExternalOrderController',
|
||||
'(?P<orderID>[^/]+)/' => array(
|
||||
'' => 'PhortuneExternalOrderController',
|
||||
'(?P<action>print)/' => 'PhortuneExternalOrderController',
|
||||
),
|
||||
),
|
||||
),
|
||||
'merchant/' => array(
|
||||
|
|
|
@ -207,7 +207,9 @@ final class PhortuneCartCheckoutController
|
|||
->appendChild($form)
|
||||
->appendChild($provider_form);
|
||||
|
||||
$description_box = $this->renderCartDescription($cart);
|
||||
$description_view = id(new PhortuneOrderDescriptionView())
|
||||
->setViewer($viewer)
|
||||
->setOrder($cart);
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(pht('Checkout'));
|
||||
|
@ -220,9 +222,10 @@ final class PhortuneCartCheckoutController
|
|||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(array(
|
||||
->setFooter(
|
||||
array(
|
||||
$description_view,
|
||||
$cart_box,
|
||||
$description_box,
|
||||
$payment_box,
|
||||
));
|
||||
|
||||
|
|
|
@ -74,61 +74,4 @@ abstract class PhortuneCartController
|
|||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
}
|
||||
|
||||
protected function buildCartContentTable(PhortuneCart $cart) {
|
||||
|
||||
$rows = array();
|
||||
foreach ($cart->getPurchases() as $purchase) {
|
||||
$rows[] = array(
|
||||
$purchase->getFullDisplayName(),
|
||||
$purchase->getBasePriceAsCurrency()->formatForDisplay(),
|
||||
$purchase->getQuantity(),
|
||||
$purchase->getTotalPriceAsCurrency()->formatForDisplay(),
|
||||
);
|
||||
}
|
||||
|
||||
$rows[] = array(
|
||||
phutil_tag('strong', array(), pht('Total')),
|
||||
'',
|
||||
'',
|
||||
phutil_tag('strong', array(),
|
||||
$cart->getTotalPriceAsCurrency()->formatForDisplay()),
|
||||
);
|
||||
|
||||
$table = new AphrontTableView($rows);
|
||||
$table->setHeaders(
|
||||
array(
|
||||
pht('Item'),
|
||||
pht('Price'),
|
||||
pht('Qty.'),
|
||||
pht('Total'),
|
||||
));
|
||||
$table->setColumnClasses(
|
||||
array(
|
||||
'wide',
|
||||
'right',
|
||||
'right',
|
||||
'right',
|
||||
));
|
||||
|
||||
return $table;
|
||||
}
|
||||
|
||||
protected function renderCartDescription(PhortuneCart $cart) {
|
||||
$description = $cart->getDescription();
|
||||
if (!strlen($description)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$output = new PHUIRemarkupView($this->getViewer(), $description);
|
||||
|
||||
$box = id(new PHUIBoxView())
|
||||
->addMargin(PHUI::MARGIN_LARGE)
|
||||
->appendChild($output);
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Description'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->appendChild($box);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
final class PhortuneCartViewController
|
||||
extends PhortuneCartController {
|
||||
|
||||
private $action = null;
|
||||
|
||||
protected function shouldRequireAccountAuthority() {
|
||||
return false;
|
||||
}
|
||||
|
@ -15,214 +13,93 @@ final class PhortuneCartViewController
|
|||
|
||||
protected function handleCartRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$cart = $this->getCart();
|
||||
$order = $this->getCart();
|
||||
$authority = $this->getMerchantAuthority();
|
||||
$can_edit = $this->hasAccountAuthority();
|
||||
|
||||
$this->action = $request->getURIData('action');
|
||||
$is_printable = ($request->getURIData('action') === 'print');
|
||||
|
||||
$cart_table = $this->buildCartContentTable($cart);
|
||||
|
||||
$errors = array();
|
||||
$error_view = null;
|
||||
$resume_uri = null;
|
||||
switch ($cart->getStatus()) {
|
||||
case PhortuneCart::STATUS_READY:
|
||||
if ($cart->getIsInvoice()) {
|
||||
$error_view = id(new PHUIInfoView())
|
||||
->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
|
||||
->appendChild(pht('This invoice is ready for payment.'));
|
||||
}
|
||||
break;
|
||||
case PhortuneCart::STATUS_PURCHASING:
|
||||
if ($order->getStatus() === PhortuneCart::STATUS_PURCHASING) {
|
||||
if ($can_edit) {
|
||||
$resume_uri = $cart->getMetadataValue('provider.checkoutURI');
|
||||
if ($resume_uri) {
|
||||
$errors[] = pht(
|
||||
'The checkout process has been started, but not yet completed. '.
|
||||
'You can continue checking out by clicking %s, or cancel the '.
|
||||
'order, or contact the merchant for assistance.',
|
||||
phutil_tag('strong', array(), pht('Continue Checkout')));
|
||||
} else {
|
||||
$errors[] = pht(
|
||||
'The checkout process has been started, but an error occurred. '.
|
||||
'You can cancel the order or contact the merchant for '.
|
||||
'assistance.');
|
||||
$resume_uri = $order->getMetadataValue('provider.checkoutURI');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PhortuneCart::STATUS_CHARGED:
|
||||
if ($can_edit) {
|
||||
$errors[] = pht(
|
||||
'You have been charged, but processing could not be completed. '.
|
||||
'You can cancel your order, or contact the merchant for '.
|
||||
'assistance.');
|
||||
}
|
||||
break;
|
||||
case PhortuneCart::STATUS_HOLD:
|
||||
if ($can_edit) {
|
||||
$errors[] = pht(
|
||||
'Payment for this order is on hold. You can click %s to check '.
|
||||
'for updates, cancel the order, or contact the merchant for '.
|
||||
'assistance.',
|
||||
phutil_tag('strong', array(), pht('Update Status')));
|
||||
}
|
||||
break;
|
||||
case PhortuneCart::STATUS_REVIEW:
|
||||
if ($authority) {
|
||||
$errors[] = pht(
|
||||
'This order has been flagged for manual review. Review the order '.
|
||||
'and choose %s to accept it or %s to reject it.',
|
||||
phutil_tag('strong', array(), pht('Accept Order')),
|
||||
phutil_tag('strong', array(), pht('Refund Order')));
|
||||
} else if ($can_edit) {
|
||||
$errors[] = pht(
|
||||
'This order requires manual processing and will complete once '.
|
||||
'the merchant accepts it.');
|
||||
}
|
||||
break;
|
||||
case PhortuneCart::STATUS_PURCHASED:
|
||||
$error_view = id(new PHUIInfoView())
|
||||
->setSeverity(PHUIInfoView::SEVERITY_SUCCESS)
|
||||
->appendChild(pht('This purchase has been completed.'));
|
||||
break;
|
||||
}
|
||||
|
||||
if ($errors) {
|
||||
$error_view = id(new PHUIInfoView())
|
||||
->setSeverity(PHUIInfoView::SEVERITY_WARNING)
|
||||
->appendChild($errors);
|
||||
}
|
||||
|
||||
$details = $this->buildDetailsView($cart);
|
||||
$curtain = $this->buildCurtainView(
|
||||
$cart,
|
||||
$can_edit,
|
||||
$authority,
|
||||
$resume_uri);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setUser($viewer)
|
||||
->setHeader($cart->getName())
|
||||
->setHeader($order->getName())
|
||||
->setHeaderIcon('fa-shopping-bag');
|
||||
|
||||
if ($cart->getStatus() == PhortuneCart::STATUS_PURCHASED) {
|
||||
$done_uri = $cart->getDoneURI();
|
||||
if ($order->getStatus() == PhortuneCart::STATUS_PURCHASED) {
|
||||
$done_uri = $order->getDoneURI();
|
||||
if ($done_uri) {
|
||||
$header->addActionLink(
|
||||
id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setHref($done_uri)
|
||||
->setIcon('fa-check-square green')
|
||||
->setText($cart->getDoneActionName()));
|
||||
->setText($order->getDoneActionName()));
|
||||
}
|
||||
}
|
||||
|
||||
$cart_box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Cart Items'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setTable($cart_table);
|
||||
|
||||
$description = $this->renderCartDescription($cart);
|
||||
|
||||
$charges = id(new PhortuneChargeQuery())
|
||||
$order_view = id(new PhortuneOrderSummaryView())
|
||||
->setViewer($viewer)
|
||||
->withCartPHIDs(array($cart->getPHID()))
|
||||
->needCarts(true)
|
||||
->execute();
|
||||
->setOrder($order)
|
||||
->setResumeURI($resume_uri)
|
||||
->setPrintable($is_printable);
|
||||
|
||||
$charges_table = id(new PhortuneChargeTableView())
|
||||
->setUser($viewer)
|
||||
->setCharges($charges)
|
||||
->setShowOrder(false);
|
||||
$crumbs = null;
|
||||
$curtain = null;
|
||||
|
||||
$charges = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Charges'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setTable($charges_table);
|
||||
$main = array();
|
||||
$tail = array();
|
||||
|
||||
$account = $cart->getAccount();
|
||||
require_celerity_resource('phortune-invoice-css');
|
||||
|
||||
if ($is_printable) {
|
||||
$body_class = 'phortune-invoice-view';
|
||||
|
||||
$tail[] = $order_view;
|
||||
} else {
|
||||
$body_class = 'phortune-cart-page';
|
||||
|
||||
$curtain = $this->buildCurtainView(
|
||||
$order,
|
||||
$can_edit,
|
||||
$authority,
|
||||
$resume_uri);
|
||||
|
||||
$account = $order->getAccount();
|
||||
$crumbs = $this->buildApplicationCrumbs()
|
||||
->addTextCrumb($account->getName(), $account->getURI())
|
||||
->addTextCrumb(pht('Orders'), $account->getOrdersURI())
|
||||
->addTextCrumb(pht('Cart %d', $cart->getID()))
|
||||
->addTextCrumb($order->getObjectName())
|
||||
->setBorder(true);
|
||||
|
||||
require_celerity_resource('phortune-css');
|
||||
|
||||
if (!$this->action) {
|
||||
$class = 'phortune-cart-page';
|
||||
$timeline = $this->buildTransactionTimeline(
|
||||
$cart,
|
||||
new PhortuneCartTransactionQuery());
|
||||
$timeline
|
||||
$timeline = $this->buildTransactionTimeline($order)
|
||||
->setShouldTerminate(true);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setCurtain($curtain)
|
||||
->setMainColumn(array(
|
||||
$error_view,
|
||||
$details,
|
||||
$cart_box,
|
||||
$description,
|
||||
$charges,
|
||||
$timeline,
|
||||
));
|
||||
|
||||
} else {
|
||||
$class = 'phortune-invoice-view';
|
||||
$crumbs = null;
|
||||
$merchant_phid = $cart->getMerchantPHID();
|
||||
$buyer_phid = $cart->getAuthorPHID();
|
||||
$merchant = id(new PhortuneMerchantQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($merchant_phid))
|
||||
->needProfileImage(true)
|
||||
->executeOne();
|
||||
$buyer = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($buyer_phid))
|
||||
->needProfileImage(true)
|
||||
->executeOne();
|
||||
|
||||
$merchant_contact = new PHUIRemarkupView(
|
||||
$viewer,
|
||||
$merchant->getContactInfo());
|
||||
|
||||
$account_name = $account->getBillingName();
|
||||
if (!strlen($account_name)) {
|
||||
$account_name = $buyer->getRealName();
|
||||
$main[] = $order_view;
|
||||
$main[] = $timeline;
|
||||
}
|
||||
|
||||
$account_contact = $account->getBillingAddress();
|
||||
if (strlen($account_contact)) {
|
||||
$account_contact = new PHUIRemarkupView(
|
||||
$viewer,
|
||||
$account_contact);
|
||||
}
|
||||
$column_view = id(new PHUITwoColumnView())
|
||||
->setMainColumn($main)
|
||||
->setFooter($tail);
|
||||
|
||||
$view = id(new PhortuneInvoiceView())
|
||||
->setMerchantName($merchant->getName())
|
||||
->setMerchantLogo($merchant->getProfileImageURI())
|
||||
->setMerchantContact($merchant_contact)
|
||||
->setMerchantFooter($merchant->getInvoiceFooter())
|
||||
->setAccountName($account_name)
|
||||
->setAccountContact($account_contact)
|
||||
->setStatus($error_view)
|
||||
->setContent(
|
||||
array(
|
||||
$details,
|
||||
$cart_box,
|
||||
$charges,
|
||||
));
|
||||
if ($curtain) {
|
||||
$column_view->setCurtain($curtain);
|
||||
}
|
||||
|
||||
$page = $this->newPage()
|
||||
->setTitle(pht('Cart %d', $cart->getID()))
|
||||
->addClass($class)
|
||||
->appendChild($view);
|
||||
->addClass($body_class)
|
||||
->setTitle(
|
||||
array(
|
||||
$order->getObjectName(),
|
||||
$order->getName(),
|
||||
))
|
||||
->appendChild($column_view);
|
||||
|
||||
if ($crumbs) {
|
||||
$page->setCrumbs($crumbs);
|
||||
|
@ -231,45 +108,6 @@ final class PhortuneCartViewController
|
|||
return $page;
|
||||
}
|
||||
|
||||
private function buildDetailsView(PhortuneCart $cart) {
|
||||
$viewer = $this->getViewer();
|
||||
$view = id(new PHUIPropertyListView())
|
||||
->setUser($viewer)
|
||||
->setObject($cart);
|
||||
|
||||
$handles = $this->loadViewerHandles(
|
||||
array(
|
||||
$cart->getAccountPHID(),
|
||||
$cart->getAuthorPHID(),
|
||||
$cart->getMerchantPHID(),
|
||||
));
|
||||
|
||||
if ($this->action == 'print') {
|
||||
$view->addProperty(pht('Order Name'), $cart->getName());
|
||||
}
|
||||
|
||||
$view->addProperty(
|
||||
pht('Account'),
|
||||
$handles[$cart->getAccountPHID()]->renderLink());
|
||||
$view->addProperty(
|
||||
pht('Authorized By'),
|
||||
$handles[$cart->getAuthorPHID()]->renderLink());
|
||||
$view->addProperty(
|
||||
pht('Merchant'),
|
||||
$handles[$cart->getMerchantPHID()]->renderLink());
|
||||
$view->addProperty(
|
||||
pht('Status'),
|
||||
PhortuneCart::getNameForStatus($cart->getStatus()));
|
||||
$view->addProperty(
|
||||
pht('Updated'),
|
||||
phabricator_datetime($cart->getDateModified(), $viewer));
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Details'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function buildCurtainView(
|
||||
PhortuneCart $cart,
|
||||
$can_edit,
|
||||
|
@ -297,6 +135,18 @@ final class PhortuneCartViewController
|
|||
$checkout_uri = $cart->getCheckoutURI();
|
||||
$void_uri = $this->getApplicationURI("cart/{$id}/void/");
|
||||
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Printable Version'))
|
||||
->setHref($print_uri)
|
||||
->setOpenInNewWindow(true)
|
||||
->setIcon('fa-print'));
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setType(PhabricatorActionView::TYPE_DIVIDER));
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Pay Now'))
|
||||
|
@ -327,13 +177,6 @@ final class PhortuneCartViewController
|
|||
->setHref($resume_uri));
|
||||
}
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Printable Version'))
|
||||
->setHref($print_uri)
|
||||
->setOpenInNewWindow(true)
|
||||
->setIcon('fa-print'));
|
||||
|
||||
if ($authority) {
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
|
|
|
@ -17,24 +17,82 @@ final class PhortuneExternalOrderController
|
|||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$timeline = $this->buildTransactionTimeline(
|
||||
$order,
|
||||
new PhortuneCartTransactionQuery());
|
||||
$timeline->setShouldTerminate(true);
|
||||
$is_printable = ($request->getURIData('action') === 'print');
|
||||
|
||||
$order_view = id(new PhortuneOrderSummaryView())
|
||||
->setViewer($xviewer)
|
||||
->setOrder($order)
|
||||
->setPrintable($is_printable);
|
||||
|
||||
$crumbs = null;
|
||||
$curtain = null;
|
||||
|
||||
$main = array();
|
||||
$tail = array();
|
||||
|
||||
require_celerity_resource('phortune-invoice-css');
|
||||
|
||||
if ($is_printable) {
|
||||
$body_class = 'phortune-invoice-view';
|
||||
|
||||
$tail[] = $order_view;
|
||||
} else {
|
||||
$body_class = 'phortune-cart-page';
|
||||
|
||||
$curtain = $this->newCurtain($order);
|
||||
|
||||
$crumbs = $this->newExternalCrumbs()
|
||||
->addTextCrumb($order->getObjectName());
|
||||
->addTextCrumb($order->getObjectName())
|
||||
->setBorder(true);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setMainColumn(
|
||||
$timeline = $this->buildTransactionTimeline($order)
|
||||
->setShouldTerminate(true);
|
||||
|
||||
$main[] = $order_view;
|
||||
$main[] = $timeline;
|
||||
}
|
||||
|
||||
$column_view = id(new PHUITwoColumnView())
|
||||
->setMainColumn($main)
|
||||
->setFooter($tail);
|
||||
|
||||
if ($curtain) {
|
||||
$column_view->setCurtain($curtain);
|
||||
}
|
||||
|
||||
$page = $this->newPage()
|
||||
->addClass($body_class)
|
||||
->setTitle(
|
||||
array(
|
||||
$timeline,
|
||||
));
|
||||
$order->getObjectName(),
|
||||
$order->getName(),
|
||||
))
|
||||
->appendChild($column_view);
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle(pht('Order %d', $order->getID()))
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($view);
|
||||
if ($crumbs) {
|
||||
$page->setCrumbs($crumbs);
|
||||
}
|
||||
|
||||
return $page;
|
||||
}
|
||||
|
||||
|
||||
private function newCurtain(PhortuneCart $order) {
|
||||
$xviewer = $this->getExternalViewer();
|
||||
$email = $this->getAccountEmail();
|
||||
|
||||
$curtain = $this->newCurtainView($order);
|
||||
|
||||
$print_uri = $email->getExternalOrderPrintURI($order);
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Printable Version'))
|
||||
->setHref($print_uri)
|
||||
->setOpenInNewWindow(true)
|
||||
->setIcon('fa-print'));
|
||||
|
||||
return $curtain;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -100,6 +100,14 @@ final class PhortuneAccountEmail
|
|||
$cart->getID());
|
||||
}
|
||||
|
||||
public function getExternalOrderPrintURI(PhortuneCart $cart) {
|
||||
return urisprintf(
|
||||
'/phortune/external/%s/%s/order/%d/print/',
|
||||
$this->getAddressKey(),
|
||||
$this->getAccessKey(),
|
||||
$cart->getID());
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||
|
||||
|
|
|
@ -1,159 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneInvoiceView extends AphrontTagView {
|
||||
|
||||
private $merchantName;
|
||||
private $merchantLogo;
|
||||
private $merchantContact;
|
||||
private $merchantFooter;
|
||||
private $accountName;
|
||||
private $accountContact;
|
||||
private $status;
|
||||
private $content;
|
||||
|
||||
public function setMerchantName($name) {
|
||||
$this->merchantName = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setMerchantLogo($logo) {
|
||||
$this->merchantLogo = $logo;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setMerchantContact($contact) {
|
||||
$this->merchantContact = $contact;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setMerchantFooter($footer) {
|
||||
$this->merchantFooter = $footer;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setAccountName($name) {
|
||||
$this->accountName = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setAccountContact($contact) {
|
||||
$this->accountContact = $contact;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setStatus($status) {
|
||||
$this->status = $status;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setContent($content) {
|
||||
$this->content = $content;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function getTagAttributes() {
|
||||
$classes = array();
|
||||
$classes[] = 'phortune-invoice-view';
|
||||
|
||||
return array(
|
||||
'class' => implode(' ', $classes),
|
||||
);
|
||||
}
|
||||
|
||||
protected function getTagContent() {
|
||||
require_celerity_resource('phortune-invoice-css');
|
||||
|
||||
$logo = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phortune-invoice-logo',
|
||||
),
|
||||
phutil_tag(
|
||||
'img',
|
||||
array(
|
||||
'height' => '50',
|
||||
'width' => '50',
|
||||
'alt' => $this->merchantName,
|
||||
'src' => $this->merchantLogo,
|
||||
)));
|
||||
|
||||
$to_title = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phortune-mini-header',
|
||||
),
|
||||
pht('Bill To:'));
|
||||
|
||||
$bill_to = phutil_tag(
|
||||
'td',
|
||||
array(
|
||||
'class' => 'phortune-invoice-to',
|
||||
'width' => '50%',
|
||||
),
|
||||
array(
|
||||
$to_title,
|
||||
phutil_tag('strong', array(), $this->accountName),
|
||||
phutil_tag('br', array()),
|
||||
$this->accountContact,
|
||||
));
|
||||
|
||||
$from_title = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phortune-mini-header',
|
||||
),
|
||||
pht('From:'));
|
||||
|
||||
$bill_from = phutil_tag(
|
||||
'td',
|
||||
array(
|
||||
'class' => 'phortune-invoice-from',
|
||||
'width' => '50%',
|
||||
),
|
||||
array(
|
||||
$from_title,
|
||||
phutil_tag('strong', array(), $this->merchantName),
|
||||
phutil_tag('br', array()),
|
||||
$this->merchantContact,
|
||||
));
|
||||
|
||||
$contact = phutil_tag(
|
||||
'table',
|
||||
array(
|
||||
'class' => 'phortune-invoice-contact',
|
||||
'width' => '100%',
|
||||
),
|
||||
phutil_tag(
|
||||
'tr',
|
||||
array(),
|
||||
array(
|
||||
$bill_to,
|
||||
$bill_from,
|
||||
)));
|
||||
|
||||
$status = null;
|
||||
if ($this->status) {
|
||||
$status = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phortune-invoice-status',
|
||||
),
|
||||
$this->status);
|
||||
}
|
||||
|
||||
$footer = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phortune-invoice-footer',
|
||||
),
|
||||
$this->merchantFooter);
|
||||
|
||||
return array(
|
||||
$logo,
|
||||
$contact,
|
||||
$status,
|
||||
$this->content,
|
||||
$footer,
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneOrderDescriptionView
|
||||
extends AphrontView {
|
||||
|
||||
private $order;
|
||||
|
||||
public function setOrder(PhortuneCart $order) {
|
||||
$this->order = $order;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getOrder() {
|
||||
return $this->order;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$viewer = $this->getViewer();
|
||||
$order = $this->getOrder();
|
||||
|
||||
$description = $order->getDescription();
|
||||
if (!strlen($description)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$output = new PHUIRemarkupView($viewer, $description);
|
||||
|
||||
$description_box = id(new PHUIBoxView())
|
||||
->addMargin(PHUI::MARGIN_LARGE)
|
||||
->appendChild($output);
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Description'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->appendChild($description_box);
|
||||
}
|
||||
|
||||
|
||||
}
|
58
src/applications/phortune/view/PhortuneOrderItemsView.php
Normal file
58
src/applications/phortune/view/PhortuneOrderItemsView.php
Normal file
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneOrderItemsView
|
||||
extends PhortuneOrderView {
|
||||
|
||||
public function render() {
|
||||
$viewer = $this->getViewer();
|
||||
$order = $this->getOrder();
|
||||
|
||||
$purchases = id(new PhortunePurchaseQuery())
|
||||
->setViewer($viewer)
|
||||
->withCartPHIDs(array($order->getPHID()))
|
||||
->execute();
|
||||
|
||||
$order->attachPurchases($purchases);
|
||||
|
||||
$rows = array();
|
||||
foreach ($purchases as $purchase) {
|
||||
$rows[] = array(
|
||||
$purchase->getFullDisplayName(),
|
||||
$purchase->getBasePriceAsCurrency()->formatForDisplay(),
|
||||
$purchase->getQuantity(),
|
||||
$purchase->getTotalPriceAsCurrency()->formatForDisplay(),
|
||||
);
|
||||
}
|
||||
|
||||
$rows[] = array(
|
||||
phutil_tag('strong', array(), pht('Total')),
|
||||
'',
|
||||
'',
|
||||
phutil_tag('strong', array(),
|
||||
$order->getTotalPriceAsCurrency()->formatForDisplay()),
|
||||
);
|
||||
|
||||
$table = new AphrontTableView($rows);
|
||||
$table->setHeaders(
|
||||
array(
|
||||
pht('Item'),
|
||||
pht('Price'),
|
||||
pht('Qty.'),
|
||||
pht('Total'),
|
||||
));
|
||||
$table->setColumnClasses(
|
||||
array(
|
||||
'wide',
|
||||
'right',
|
||||
'right',
|
||||
'right',
|
||||
));
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Items'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setTable($table);
|
||||
}
|
||||
|
||||
|
||||
}
|
370
src/applications/phortune/view/PhortuneOrderSummaryView.php
Normal file
370
src/applications/phortune/view/PhortuneOrderSummaryView.php
Normal file
|
@ -0,0 +1,370 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneOrderSummaryView
|
||||
extends PhortuneOrderView {
|
||||
|
||||
private $resumeURI;
|
||||
private $printable;
|
||||
|
||||
public function setResumeURI($resume_uri) {
|
||||
$this->resumeURI = $resume_uri;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getResumeURI() {
|
||||
return $this->resumeURI;
|
||||
}
|
||||
|
||||
public function setPrintable($printable) {
|
||||
$this->printable = $printable;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPrintable() {
|
||||
return $this->printable;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$is_printable = $this->getPrintable();
|
||||
|
||||
$content = array();
|
||||
|
||||
if ($is_printable) {
|
||||
$content[] = $this->newContactHeader();
|
||||
}
|
||||
|
||||
$content[] = $this->newMessagesView();
|
||||
$content[] = $this->newDetailsView();
|
||||
$content[] = $this->newDescriptionView();
|
||||
$content[] = $this->newItemsView();
|
||||
$content[] = $this->newChargesView();
|
||||
|
||||
if ($is_printable) {
|
||||
$content[] = $this->newContactFooter();
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
private function newMessagesView() {
|
||||
$viewer = $this->getViewer();
|
||||
$order = $this->getOrder();
|
||||
|
||||
$messages = array();
|
||||
$severity = null;
|
||||
|
||||
$resume_uri = $this->getResumeURI();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$order,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$can_merchant = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$order->getMerchant(),
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
switch ($order->getStatus()) {
|
||||
case PhortuneCart::STATUS_READY:
|
||||
if ($order->getIsInvoice()) {
|
||||
$severity = PHUIInfoView::SEVERITY_NOTICE;
|
||||
$messages[] = pht('This invoice is ready for payment.');
|
||||
}
|
||||
break;
|
||||
case PhortuneCart::STATUS_PURCHASING:
|
||||
if ($can_edit) {
|
||||
if ($resume_uri) {
|
||||
$messages[] = pht(
|
||||
'The checkout process has been started, but not yet completed. '.
|
||||
'You can continue checking out by clicking %s, or cancel the '.
|
||||
'order, or contact the merchant for assistance.',
|
||||
phutil_tag('strong', array(), pht('Continue Checkout')));
|
||||
} else {
|
||||
$messages[] = pht(
|
||||
'The checkout process has been started, but an error occurred. '.
|
||||
'You can cancel the order or contact the merchant for '.
|
||||
'assistance.');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PhortuneCart::STATUS_CHARGED:
|
||||
if ($can_edit) {
|
||||
$messages[] = pht(
|
||||
'You have been charged, but processing could not be completed. '.
|
||||
'You can cancel your order, or contact the merchant for '.
|
||||
'assistance.');
|
||||
}
|
||||
break;
|
||||
case PhortuneCart::STATUS_HOLD:
|
||||
if ($can_edit) {
|
||||
$messages[] = pht(
|
||||
'Payment for this order is on hold. You can click %s to check '.
|
||||
'for updates, cancel the order, or contact the merchant for '.
|
||||
'assistance.',
|
||||
phutil_tag('strong', array(), pht('Update Status')));
|
||||
}
|
||||
break;
|
||||
case PhortuneCart::STATUS_REVIEW:
|
||||
if ($can_merchant) {
|
||||
$messages[] = pht(
|
||||
'This order has been flagged for manual review. Review the order '.
|
||||
'and choose %s to accept it or %s to reject it.',
|
||||
phutil_tag('strong', array(), pht('Accept Order')),
|
||||
phutil_tag('strong', array(), pht('Refund Order')));
|
||||
} else if ($can_edit) {
|
||||
$messages[] = pht(
|
||||
'This order requires manual processing and will complete once '.
|
||||
'the merchant accepts it.');
|
||||
}
|
||||
break;
|
||||
case PhortuneCart::STATUS_PURCHASED:
|
||||
$severity = PHUIInfoView::SEVERITY_SUCCESS;
|
||||
$messages[] = pht('This purchase has been completed.');
|
||||
break;
|
||||
}
|
||||
|
||||
if (!$messages) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($severity === null) {
|
||||
$severity = PHUIInfoView::SEVERITY_WARNING;
|
||||
}
|
||||
|
||||
$messages_view = id(new PHUIInfoView())
|
||||
->setSeverity($severity)
|
||||
->appendChild($messages);
|
||||
|
||||
$is_printable = $this->getPrintable();
|
||||
if ($is_printable) {
|
||||
$messages_view = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phortune-invoice-status',
|
||||
),
|
||||
$messages_view);
|
||||
}
|
||||
|
||||
return $messages_view;
|
||||
}
|
||||
|
||||
private function newDetailsView() {
|
||||
$viewer = $this->getViewer();
|
||||
$order = $this->getOrder();
|
||||
$is_printable = $this->getPrintable();
|
||||
|
||||
$view = id(new PHUIPropertyListView())
|
||||
->setViewer($viewer)
|
||||
->setObject($order);
|
||||
|
||||
$account_phid = $order->getAccountPHID();
|
||||
$author_phid = $order->getAuthorPHID();
|
||||
$merchant_phid = $order->getMerchantPHID();
|
||||
|
||||
$handles = $viewer->loadHandles(
|
||||
array(
|
||||
$account_phid,
|
||||
$author_phid,
|
||||
$merchant_phid,
|
||||
));
|
||||
|
||||
if ($is_printable) {
|
||||
$account_link = $handles[$account_phid]->getFullName();
|
||||
$author_link = $handles[$author_phid]->getFullName();
|
||||
$merchant_link = $handles[$merchant_phid]->getFullName();
|
||||
} else {
|
||||
$account_link = $handles[$account_phid]->renderLink();
|
||||
$author_link = $handles[$author_phid]->renderLink();
|
||||
$merchant_link = $handles[$merchant_phid]->renderLink();
|
||||
}
|
||||
|
||||
if ($is_printable) {
|
||||
$view->addProperty(pht('Order Name'), $order->getName());
|
||||
}
|
||||
|
||||
$view->addProperty(pht('Account'), $account_link);
|
||||
$view->addProperty(pht('Authorized By'), $author_link);
|
||||
$view->addProperty(pht('Merchant'), $merchant_link);
|
||||
|
||||
$view->addProperty(
|
||||
pht('Order Status'),
|
||||
PhortuneCart::getNameForStatus($order->getStatus()));
|
||||
$view->addProperty(
|
||||
pht('Created'),
|
||||
phabricator_datetime($order->getDateCreated(), $viewer));
|
||||
$view->addProperty(
|
||||
pht('Updated'),
|
||||
phabricator_datetime($order->getDateModified(), $viewer));
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Details'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function newChargesView() {
|
||||
$viewer = $this->getViewer();
|
||||
$order = $this->getOrder();
|
||||
|
||||
$charges = id(new PhortuneChargeQuery())
|
||||
->setViewer($viewer)
|
||||
->withCartPHIDs(array($order->getPHID()))
|
||||
->needCarts(true)
|
||||
->execute();
|
||||
|
||||
$charges_table = id(new PhortuneChargeTableView())
|
||||
->setUser($viewer)
|
||||
->setCharges($charges)
|
||||
->setShowOrder(false);
|
||||
|
||||
$charges_view = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Charges'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setTable($charges_table);
|
||||
|
||||
return $charges_view;
|
||||
}
|
||||
|
||||
private function newDescriptionView() {
|
||||
$viewer = $this->getViewer();
|
||||
$order = $this->getOrder();
|
||||
|
||||
return id(new PhortuneOrderDescriptionView())
|
||||
->setViewer($viewer)
|
||||
->setOrder($order);
|
||||
}
|
||||
|
||||
private function newItemsView() {
|
||||
$viewer = $this->getViewer();
|
||||
$order = $this->getOrder();
|
||||
|
||||
return id(new PhortuneOrderItemsView())
|
||||
->setViewer($viewer)
|
||||
->setOrder($order);
|
||||
}
|
||||
|
||||
private function newContactHeader() {
|
||||
$viewer = $this->getViewer();
|
||||
$order = $this->getOrder();
|
||||
|
||||
$merchant = id(new PhortuneMerchantQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($order->getMerchant()->getPHID()))
|
||||
->needProfileImage(true)
|
||||
->executeOne();
|
||||
|
||||
$merchant_name = $merchant->getName();
|
||||
$merchant_image = $merchant->getProfileImageURI();
|
||||
|
||||
$account = $order->getAccount();
|
||||
$account_name = $account->getBillingName();
|
||||
|
||||
$account_contact = $account->getBillingAddress();
|
||||
if (strlen($account_contact)) {
|
||||
$account_contact = new PHUIRemarkupView(
|
||||
$viewer,
|
||||
$account_contact);
|
||||
}
|
||||
|
||||
$merchant_contact = $merchant->getContactInfo();
|
||||
if (strlen($merchant_contact)) {
|
||||
$merchant_contact = new PHUIRemarkupView(
|
||||
$viewer,
|
||||
$merchant->getContactInfo());
|
||||
}
|
||||
|
||||
$logo = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phortune-invoice-logo',
|
||||
),
|
||||
phutil_tag(
|
||||
'img',
|
||||
array(
|
||||
'height' => '50',
|
||||
'width' => '50',
|
||||
'alt' => $merchant_name,
|
||||
'src' => $merchant_image,
|
||||
)));
|
||||
|
||||
$to_title = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phortune-mini-header',
|
||||
),
|
||||
pht('Bill To:'));
|
||||
|
||||
$bill_to = phutil_tag(
|
||||
'td',
|
||||
array(
|
||||
'class' => 'phortune-invoice-to',
|
||||
'width' => '50%',
|
||||
),
|
||||
array(
|
||||
$to_title,
|
||||
phutil_tag('strong', array(), $account_name),
|
||||
phutil_tag('br', array()),
|
||||
$account_contact,
|
||||
));
|
||||
|
||||
$from_title = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phortune-mini-header',
|
||||
),
|
||||
pht('From:'));
|
||||
|
||||
$bill_from = phutil_tag(
|
||||
'td',
|
||||
array(
|
||||
'class' => 'phortune-invoice-from',
|
||||
'width' => '50%',
|
||||
),
|
||||
array(
|
||||
$from_title,
|
||||
phutil_tag('strong', array(), $merchant_name),
|
||||
phutil_tag('br', array()),
|
||||
$merchant_contact,
|
||||
));
|
||||
|
||||
$contact = phutil_tag(
|
||||
'table',
|
||||
array(
|
||||
'class' => 'phortune-invoice-contact',
|
||||
'width' => '100%',
|
||||
),
|
||||
phutil_tag(
|
||||
'tr',
|
||||
array(),
|
||||
array(
|
||||
$bill_to,
|
||||
$bill_from,
|
||||
)));
|
||||
|
||||
return array(
|
||||
$logo,
|
||||
$contact,
|
||||
);
|
||||
}
|
||||
|
||||
private function newContactFooter() {
|
||||
$viewer = $this->getViewer();
|
||||
$order = $this->getOrder();
|
||||
|
||||
$merchant = $order->getMerchant();
|
||||
$footer = $merchant->getInvoiceFooter();
|
||||
|
||||
if (!strlen($footer)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phortune-invoice-footer',
|
||||
),
|
||||
$footer);
|
||||
}
|
||||
|
||||
}
|
17
src/applications/phortune/view/PhortuneOrderView.php
Normal file
17
src/applications/phortune/view/PhortuneOrderView.php
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
abstract class PhortuneOrderView
|
||||
extends AphrontView {
|
||||
|
||||
private $order;
|
||||
|
||||
final public function setOrder(PhortuneCart $order) {
|
||||
$this->order = $order;
|
||||
return $this;
|
||||
}
|
||||
|
||||
final public function getOrder() {
|
||||
return $this->order;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue