diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -5302,7 +5302,6 @@ '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 @@ '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 @@ 'PhortuneExternalOrderController' => 'PhortuneExternalController', 'PhortuneExternalOverviewController' => 'PhortuneExternalController', 'PhortuneExternalUnsubscribeController' => 'PhortuneExternalController', - 'PhortuneInvoiceView' => 'AphrontTagView', 'PhortuneLandingController' => 'PhortuneController', 'PhortuneMemberHasAccountEdgeType' => 'PhabricatorEdgeType', 'PhortuneMemberHasMerchantEdgeType' => 'PhabricatorEdgeType', @@ -11940,7 +11942,11 @@ 'PhortuneMerchantTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhortuneMerchantTransactionType' => 'PhabricatorModularTransactionType', 'PhortuneMonthYearExpiryControl' => 'AphrontFormControl', + 'PhortuneOrderDescriptionView' => 'AphrontView', + 'PhortuneOrderItemsView' => 'PhortuneOrderView', + 'PhortuneOrderSummaryView' => 'PhortuneOrderView', 'PhortuneOrderTableView' => 'AphrontView', + 'PhortuneOrderView' => 'AphrontView', 'PhortunePayPalPaymentProvider' => 'PhortunePaymentProvider', 'PhortunePaymentMethod' => array( 'PhortuneDAO', diff --git a/src/applications/base/controller/PhabricatorController.php b/src/applications/base/controller/PhabricatorController.php --- a/src/applications/base/controller/PhabricatorController.php +++ b/src/applications/base/controller/PhabricatorController.php @@ -481,7 +481,7 @@ protected function buildTransactionTimeline( PhabricatorApplicationTransactionInterface $object, - PhabricatorApplicationTransactionQuery $query, + PhabricatorApplicationTransactionQuery $query = null, PhabricatorMarkupEngine $engine = null, $view_data = array()) { @@ -489,6 +489,17 @@ $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( diff --git a/src/applications/phortune/application/PhabricatorPhortuneApplication.php b/src/applications/phortune/application/PhabricatorPhortuneApplication.php --- a/src/applications/phortune/application/PhabricatorPhortuneApplication.php +++ b/src/applications/phortune/application/PhabricatorPhortuneApplication.php @@ -113,7 +113,10 @@ '' => 'PhortuneExternalOverviewController', 'unsubscribe/' => 'PhortuneExternalUnsubscribeController', 'order/' => array( - '(?P[^/]+)/' => 'PhortuneExternalOrderController', + '(?P[^/]+)/' => array( + '' => 'PhortuneExternalOrderController', + '(?Pprint)/' => 'PhortuneExternalOrderController', + ), ), ), 'merchant/' => array( diff --git a/src/applications/phortune/controller/cart/PhortuneCartCheckoutController.php b/src/applications/phortune/controller/cart/PhortuneCartCheckoutController.php --- a/src/applications/phortune/controller/cart/PhortuneCartCheckoutController.php +++ b/src/applications/phortune/controller/cart/PhortuneCartCheckoutController.php @@ -207,7 +207,9 @@ ->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,11 +222,12 @@ $view = id(new PHUITwoColumnView()) ->setHeader($header) - ->setFooter(array( - $cart_box, - $description_box, - $payment_box, - )); + ->setFooter( + array( + $description_view, + $cart_box, + $payment_box, + )); return $this->newPage() ->setTitle($title) diff --git a/src/applications/phortune/controller/cart/PhortuneCartController.php b/src/applications/phortune/controller/cart/PhortuneCartController.php --- a/src/applications/phortune/controller/cart/PhortuneCartController.php +++ b/src/applications/phortune/controller/cart/PhortuneCartController.php @@ -74,61 +74,4 @@ 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); - } - } diff --git a/src/applications/phortune/controller/cart/PhortuneCartViewController.php b/src/applications/phortune/controller/cart/PhortuneCartViewController.php --- a/src/applications/phortune/controller/cart/PhortuneCartViewController.php +++ b/src/applications/phortune/controller/cart/PhortuneCartViewController.php @@ -3,8 +3,6 @@ final class PhortuneCartViewController extends PhortuneCartController { - private $action = null; - protected function shouldRequireAccountAuthority() { return false; } @@ -15,214 +13,93 @@ 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'); - - $cart_table = $this->buildCartContentTable($cart); + $is_printable = ($request->getURIData('action') === 'print'); - $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 ($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.'); - } - } - 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); + if ($order->getStatus() === PhortuneCart::STATUS_PURCHASING) { + if ($can_edit) { + $resume_uri = $order->getMetadataValue('provider.checkoutURI'); + } } - $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); + $order_view = id(new PhortuneOrderSummaryView()) + ->setViewer($viewer) + ->setOrder($order) + ->setResumeURI($resume_uri) + ->setPrintable($is_printable); - $description = $this->renderCartDescription($cart); + $crumbs = null; + $curtain = null; - $charges = id(new PhortuneChargeQuery()) - ->setViewer($viewer) - ->withCartPHIDs(array($cart->getPHID())) - ->needCarts(true) - ->execute(); + $main = array(); + $tail = array(); - $charges_table = id(new PhortuneChargeTableView()) - ->setUser($viewer) - ->setCharges($charges) - ->setShowOrder(false); - - $charges = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Charges')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($charges_table); - - $account = $cart->getAccount(); - - $crumbs = $this->buildApplicationCrumbs() - ->addTextCrumb($account->getName(), $account->getURI()) - ->addTextCrumb(pht('Orders'), $account->getOrdersURI()) - ->addTextCrumb(pht('Cart %d', $cart->getID())) - ->setBorder(true); - - require_celerity_resource('phortune-css'); - - if (!$this->action) { - $class = 'phortune-cart-page'; - $timeline = $this->buildTransactionTimeline( - $cart, - new PhortuneCartTransactionQuery()); - $timeline - ->setShouldTerminate(true); - - $view = id(new PHUITwoColumnView()) - ->setHeader($header) - ->setCurtain($curtain) - ->setMainColumn(array( - $error_view, - $details, - $cart_box, - $description, - $charges, - $timeline, - )); + require_celerity_resource('phortune-invoice-css'); + + if ($is_printable) { + $body_class = 'phortune-invoice-view'; + $tail[] = $order_view; } 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(); - } + $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($order->getObjectName()) + ->setBorder(true); + + $timeline = $this->buildTransactionTimeline($order) + ->setShouldTerminate(true); + + $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 @@ 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 @@ $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 @@ ->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()) diff --git a/src/applications/phortune/controller/external/PhortuneExternalOrderController.php b/src/applications/phortune/controller/external/PhortuneExternalOrderController.php --- a/src/applications/phortune/controller/external/PhortuneExternalOrderController.php +++ b/src/applications/phortune/controller/external/PhortuneExternalOrderController.php @@ -17,24 +17,82 @@ return new Aphront404Response(); } - $timeline = $this->buildTransactionTimeline( - $order, - new PhortuneCartTransactionQuery()); - $timeline->setShouldTerminate(true); + $is_printable = ($request->getURIData('action') === 'print'); - $crumbs = $this->newExternalCrumbs() - ->addTextCrumb($order->getObjectName()); + $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); - $view = id(new PHUITwoColumnView()) - ->setMainColumn( + $crumbs = $this->newExternalCrumbs() + ->addTextCrumb($order->getObjectName()) + ->setBorder(true); + + $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, - )); - - return $this->newPage() - ->setTitle(pht('Order %d', $order->getID())) - ->setCrumbs($crumbs) - ->appendChild($view); - } + $order->getObjectName(), + $order->getName(), + )) + ->appendChild($column_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; + } } diff --git a/src/applications/phortune/storage/PhortuneAccountEmail.php b/src/applications/phortune/storage/PhortuneAccountEmail.php --- a/src/applications/phortune/storage/PhortuneAccountEmail.php +++ b/src/applications/phortune/storage/PhortuneAccountEmail.php @@ -100,6 +100,14 @@ $cart->getID()); } + public function getExternalOrderPrintURI(PhortuneCart $cart) { + return urisprintf( + '/phortune/external/%s/%s/order/%d/print/', + $this->getAddressKey(), + $this->getAccessKey(), + $cart->getID()); + } + /* -( PhabricatorPolicyInterface )----------------------------------------- */ diff --git a/src/applications/phortune/view/PhortuneInvoiceView.php b/src/applications/phortune/view/PhortuneInvoiceView.php deleted file mode 100644 --- a/src/applications/phortune/view/PhortuneInvoiceView.php +++ /dev/null @@ -1,159 +0,0 @@ -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, - ); - } -} diff --git a/src/applications/phortune/view/PhortuneOrderDescriptionView.php b/src/applications/phortune/view/PhortuneOrderDescriptionView.php new file mode 100644 --- /dev/null +++ b/src/applications/phortune/view/PhortuneOrderDescriptionView.php @@ -0,0 +1,39 @@ +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); + } + + +} diff --git a/src/applications/phortune/view/PhortuneOrderItemsView.php b/src/applications/phortune/view/PhortuneOrderItemsView.php new file mode 100644 --- /dev/null +++ b/src/applications/phortune/view/PhortuneOrderItemsView.php @@ -0,0 +1,58 @@ +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); + } + + +} diff --git a/src/applications/phortune/view/PhortuneOrderSummaryView.php b/src/applications/phortune/view/PhortuneOrderSummaryView.php new file mode 100644 --- /dev/null +++ b/src/applications/phortune/view/PhortuneOrderSummaryView.php @@ -0,0 +1,370 @@ +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); + } + +} diff --git a/src/applications/phortune/view/PhortuneOrderView.php b/src/applications/phortune/view/PhortuneOrderView.php new file mode 100644 --- /dev/null +++ b/src/applications/phortune/view/PhortuneOrderView.php @@ -0,0 +1,17 @@ +order = $order; + return $this; + } + + final public function getOrder() { + return $this->order; + } + +}