Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
12c5ced
[TASK] Created basic structure for coupons implementation
mabolek Nov 8, 2019
9fd1550
[TASK] Wish list is now stored in TYPO3 session as an Order object
mabolek Nov 15, 2019
5b96701
[TASK] Find coupons by case insensitive code search
mabolek Nov 15, 2019
80cb5f4
[TASK] Created OrderUtility
mabolek Nov 15, 2019
386c181
[TASK] Created UnknownProductException
mabolek Nov 15, 2019
ff213b8
[TASK] Added new translation labels
mabolek Nov 15, 2019
c5e8404
[TASK] addCoupon and removeCoupon convenience functions in Order class
mabolek Nov 15, 2019
05810a2
[TASK] First full implementation of addCouponCodeToOrderAction in Pro…
mabolek Nov 15, 2019
7e3f9a3
[TASK] DB schema fixes
mabolek Nov 15, 2019
a5c4a49
[TASK] Misc. parsing and execution errors fixed
mabolek Nov 15, 2019
cced529
[TASK] Basic coupon listing implemented
mabolek Nov 15, 2019
ab69732
[TASK] Correct path used for wishlist limit
mabolek Nov 15, 2019
251a5da
[TASK] Correct path used for wishlist limit
mabolek Nov 15, 2019
212571e
[TASK] Move FE price calculation to Backend
Nov 15, 2019
2007443
[TASK] Added Order::getProductQuantity(Product $product)
mabolek Nov 16, 2019
704fbb6
[TASK] Added static PriceService::formatForIso4217
mabolek Nov 16, 2019
e06abe1
[TASK] Improved locale handling in PriceService::formatForIso4217()
mabolek Nov 16, 2019
8228e5d
[TASK] Move FE price calculation to Backend #168
mabolek Nov 16, 2019
de52385
[TASK] Changed function name from plural to singular
mabolek Nov 16, 2019
b827d02
Merge branch '165-add-discount-codes' of github.com:pixelant/pxa_prod…
mabolek Nov 16, 2019
86d9ac0
[TASK] Added getPriceForCheckout() and getTaxForCheckout()
mabolek Nov 16, 2019
77deae4
[TASK] Full PriceService implementation
mabolek Nov 16, 2019
1d9a4cb
[TASK] Refactored PriceService calls
mabolek Nov 16, 2019
a7ccac0
[TASK] Additional functions in PriceService
mabolek Nov 16, 2019
a851639
[TASK] Removed excess ">"
mabolek Nov 16, 2019
da369c9
[TASK] Fixed issue with product counting in list
mabolek Nov 16, 2019
c750163
[TASK] Fixed issue where repository wasn't instanced correctly
mabolek Nov 16, 2019
5fccaac
[BUGFIX] Tax-related calculation errors are now gone
mabolek Nov 16, 2019
61130e6
[TASK] Get correct cart count
mabolek Nov 16, 2019
3f51a5e
[BUGFIX] Corrected bug in formatForIso4217
mabolek Nov 17, 2019
1958c6a
[BUGFIX] Corrected bug in product price calculation where tax was inc…
mabolek Nov 17, 2019
bfeef47
[BUGFIX] Corrected bug in formatForIso4217 where value was cast to in…
mabolek Nov 17, 2019
3d10b05
[TASK] Changed task to being inclusive tax
mabolek Nov 17, 2019
b22a0d3
[BUGFIX] Misc. fixes in price calculations
mabolek Nov 17, 2019
8876dc2
[BUGFIX] Corrected language label for 'usage_count' field
mabolek Nov 17, 2019
5ad3379
[TASK] Made it possible to remove items from order
mabolek Nov 17, 2019
0a58324
[TASK] Corrected coupon label
mabolek Nov 17, 2019
6901ae6
[TASK] Improved product removal.
mabolek Nov 17, 2019
c5c81d0
[BUGFIX] Changed target to source tags in locallang.xlf
mabolek Nov 17, 2019
9fa9f54
[BUGFIX] Corrected language key in locallang.xlf
mabolek Nov 17, 2019
9982841
[TASK] Session order as static property to avoid unnecessary DB queries
mabolek Nov 17, 2019
9e5ac1e
[BUGFIX] Removing products from order now works as expected.
mabolek Nov 17, 2019
748e194
[TASK] Updated code field placeholder
mabolek Nov 17, 2019
0af0321
[BUGFIX] Correct message is given when product is removed from list
mabolek Nov 17, 2019
b9bb0c4
[TASK] WIP fix wishlist counters
Nov 20, 2019
593be2f
[WIP] Add recurring payments renewals
Nov 22, 2019
6e439d0
[TASK] Add payment is and status fields; Add today date faker setting
Nov 25, 2019
4807628
[TASK] Small refactoring
Nov 25, 2019
fc64ac3
[TASK] Add subscriptions
Nov 26, 2019
606bc97
[TASK] Add first order getter, today date debug setting
Nov 27, 2019
223fe62
[TASK] Add subscription order getter
Nov 27, 2019
22e9d8e
[TASK] Add external id to searchables
Nov 27, 2019
6e26933
[TASK] Change subscription TCA
Nov 28, 2019
7a073f7
[TASK] Cleanup
Nov 28, 2019
3c305ab
Merge pull request #171 from pixelant/fixSubscriptions
Nov 28, 2019
7454312
[TASK] Fix totatl price formatting
Nov 29, 2019
adba089
Merge pull request #172 from pixelant/fixTotalPriceFormatting
Nov 29, 2019
c0d56aa
[TASK] Add get wishlist items request functions
Nov 29, 2019
1967c26
Merge branch '165-add-discount-codes' into fixWishlistCounters
Nov 29, 2019
a3b8774
Merge pull request #173 from pixelant/fixWishlistCounters
Nov 29, 2019
c802741
[TASK] Fix total price calculation
Dec 2, 2019
0ef73d9
[TASK] Fix total price recalculation on product quantity change
Dec 2, 2019
9bc19c5
Merge pull request #174 from pixelant/fixTotalPriceRecalculation
Dec 2, 2019
47e0e70
[TASK] Make subscription getter return subscription record
Dec 3, 2019
9f6e3b3
Merge pull request #175 from pixelant/changeSubscriptionGetter
Dec 3, 2019
91c34a2
[TASK] Fix order duplication
Dec 3, 2019
b72beb3
Merge pull request #176 from pixelant/fixOrderDuplication
Dec 3, 2019
20f1abd
[FEATURE] Persistable order state hash (#180)
mabolek Apr 7, 2020
28123eb
[BUGFIX] Ensure $order is set before checking if it's complete
mabolek Jun 3, 2020
3f2f610
[FEATURE] Configurable maximum coupons per order (#190)
mabolek Jun 5, 2020
c0f4d27
[FEATURE] Return total price also without coupon
mabolek Jun 26, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 120 additions & 12 deletions Classes/Controller/AjaxJsonController.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,13 @@
***************************************************************/

use Pixelant\PxaProductManager\Domain\Model\Product;
use Pixelant\PxaProductManager\Exception\InvalidPriceCalculationException;
use Pixelant\PxaProductManager\Factory\PriceServiceFactory;
use Pixelant\PxaProductManager\Service\WishlistService;
use Pixelant\PxaProductManager\Utility\MainUtility;
use Pixelant\PxaProductManager\Utility\OrderUtility;
use Pixelant\PxaProductManager\Utility\ProductUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Mvc\View\JsonView;

/**
Expand All @@ -51,33 +56,47 @@ class AjaxJsonController extends AbstractController
*/
public function toggleWishListAction(Product $wishProduct = null)
{
$order = OrderUtility::getSessionOrder();
$response = [
'success' => false
'success' => false,
];

$limit = (int)$this->settings['wishList']['limit'];

if ($wishProduct !== null) {
$inWishList = ProductUtility::isProductInWishList($wishProduct);
$response['inList'] = !$inWishList;

if (!$inWishList && count(ProductUtility::getWishList()) >= $limit) {
$message = $this->translate('fe.error_limit');
} else {
MainUtility::{$inWishList ? 'removeValueFromListCookie' : 'addValueToListCookie'}(
ProductUtility::WISH_LIST_COOKIE_NAME,
$wishProduct->getUid(),
$limit
);
if ($inWishList) {
$order->removeProduct($wishProduct);

$this->orderRepository->update($order);

$response['success'] = true;
$message = $this->translate(
$inWishList ? 'fe.remove_from_list' : 'fe.added_to_list',
'fe.remove_from_list',
[
$this->translate('fe.wish_list')
]
);
} else {
if ($order->getProductsQuantityTotal() + 1 > $limit) {
$message = $this->translate('fe.error_limit');
unset($response['inList']);
} else {
$order->addProduct($wishProduct);

$response['success'] = true;
$response['inList'] = !$inWishList;
$this->orderRepository->update($order);

$response['success'] = true;

$message = $this->translate(
'fe.added_to_list',
[
$this->translate('fe.wish_list')
]
);
}
}
}

Expand Down Expand Up @@ -178,4 +197,93 @@ public function addLatestVisitedProductAction(Product $product)

$this->view->assign('value', ['success' => true]);
}

/**
* @return mixed
*/
public function totalOrderPricesAction()
{
try {
$priceService = (new PriceServiceFactory())->createFromSession();

$totalPrice = $priceService->calculatePrice();
$totalTaxPrice = $priceService->calculateTax();

$orderWithoutCoupon = clone $priceService->getOrder();
foreach ($orderWithoutCoupon->getCoupons() as $coupon) {
$orderWithoutCoupon->removeCoupon($coupon);
}

$totalPriceThereafter = $priceService->calculatePrice();
$totalTaxPriceThereafter = $priceService->calculateTax();
} catch (\Exception $e) {
$this->response->setStatus(500, 'Price calculation error');
return null;
}

if ($totalPrice < 0 || $totalTaxPrice < 0) {
$this->response->setStatus(500, 'Price calculation error');
return null;
}

$response = [
'totalPrice' => $totalPrice,
'totalTaxPrice' => $totalTaxPrice,
'totalPriceThereafter' => $totalPriceThereafter,
'totalTaxPriceThereafter' => $totalTaxPriceThereafter
];

$this->response->setStatus(200, 'OK');
$this->view->assign('value', $response);
}

/**
* @return int
*/
public function wishlistProductsCountAction()
{
/** @var WishlistService $wishlistService */
$wishlistService = GeneralUtility::makeInstance(WishlistService::class);
$this->response->setStatus(200, 'OK');
$this->view->assign('value', $wishlistService->productsCount() ?? 0);
}

/**
* @return bool
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException
*/
public function updateOrderQuantitiesAction()
{
if (!GeneralUtility::_GP('quantities')) {
$this->response->setStatus(400, 'Quantities are required');
return false;
}

$quantities = GeneralUtility::_GP('quantities');

// REST violation yay!!! :D
$order = OrderUtility::getSessionOrder();

if (!$order) {
$this->response->setStatus(400, 'Order not found');
return false;
}

// Dont want to just set the whole quantities field in case it will contain incorrect data
/** @var Product $product */
foreach ($order->getProducts() as $product) {
$uid = $product->getUid();
if (array_key_exists($uid, $quantities)) {
$order->setProductQuantity($product, $quantities[$uid]);
}
}

$this->orderRepository->update($order);

$response = null;
$this->response->setStatus(200, 'OK');
$this->view->assign('value', $response);
return true;
}
}
106 changes: 93 additions & 13 deletions Classes/Controller/ProductController.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@
use Pixelant\PxaProductManager\Domain\Model\OrderConfiguration;
use Pixelant\PxaProductManager\Domain\Model\OrderFormField;
use Pixelant\PxaProductManager\Domain\Model\Product;
use Pixelant\PxaProductManager\Domain\Repository\CouponRepository;
use Pixelant\PxaProductManager\Service\OrderMailService;
use Pixelant\PxaProductManager\Utility\ConfigurationUtility;
use Pixelant\PxaProductManager\Utility\MainUtility;
use Pixelant\PxaProductManager\Utility\OrderUtility;
use Pixelant\PxaProductManager\Utility\ProductUtility;
use Pixelant\PxaProductManager\Validation\ValidatorResolver;
use TYPO3\CMS\Core\Context\Context;
use TYPO3\CMS\Core\Context\VisibilityAspect;
use TYPO3\CMS\Core\Messaging\FlashMessage;
use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\StringUtility;
Expand Down Expand Up @@ -229,6 +232,8 @@ public function wishListCartAction()
*/
public function wishListAction(bool $sendOrder = false)
{
$order = OrderUtility::getSessionOrder();

// Select the checkout system to use
$checkoutToUse = $this->settings['wishList']['checkoutSystem']
?: ConfigurationUtility::getExtManagerConfigurationByPath('checkoutSystem') ?: 'default';
Expand Down Expand Up @@ -267,20 +272,91 @@ public function wishListAction(bool $sendOrder = false)
}
}

if ($this->request->hasArgument('orderProducts')) {
$orderState = $this->request->getArgument('orderProducts');
} else {
$orderState = ProductUtility::getOrderState();
}

$this->view->assignMultiple([
'checkout' => $checkout,
'products' => $this->getProductsFromCookieList(ProductUtility::WISH_LIST_COOKIE_NAME),
'orderProducts' => $orderState ?? [],
'sendOrder' => $sendOrder
'products' => $order->getProducts(),
'orderProducts' => $order->getProductsQuantity(),
'sendOrder' => $sendOrder,
'coupons' => $order->getCoupons()
]);
}

/**
* @param string $couponCode submitted by the user
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException
*/
public function addCouponCodeToOrderAction($couponCode = '') {
if (!$this->settings['coupons']['enable']) {
$this->addFlashMessage(
$this->translate('fe.couponCode.notEnabled'),
'',
FlashMessage::ERROR
);

$this->redirect('wishList');
}

if($couponCode === '') {
$this->addFlashMessage(
$this->translate('fe.couponCode.noCodeSuppliedWarning'),
'',
FlashMessage::WARNING
);

$this->redirect('wishList');
}

/** @var CouponRepository $couponRepository */
$couponRepository = $this->objectManager->get(CouponRepository::class);

$coupon = $couponRepository->findByCaseInsensitiveCode($couponCode);

if ($coupon === null) {
$this->addFlashMessage(
$this->translate('fe.couponCode.codeNotFoundError'),
'',
FlashMessage::ERROR
);

$this->redirect('wishList');
}

$order = OrderUtility::getSessionOrder();

if ($order->getCoupons()->contains($coupon)) {
$this->addFlashMessage(
$this->translate('fe.couponCode.codeAlreadyAddedWarning'),
'',
FlashMessage::WARNING
);

$this->redirect('wishList');
}

if ($this->settings['coupons']['orderMax'] && $order->getCoupons()->count() > $this->settings['coupons']['orderMax']) {
$this->addFlashMessage(
$this->translate('fe.couponCode.orderMaxReached', [$this->settings['coupons']['orderMax']]),
'',
FlashMessage::ERROR
);

$this->redirect('wishList');
}

$order->addCoupon($coupon);

$this->orderRepository->update($order);

$this->addFlashMessage(
$this->translate('fe.couponCode.newCodeAdded'),
'',
FlashMessage::OK
);

$this->redirect('wishList');
}

/**
* Finish order text
* Show some successful texts
Expand Down Expand Up @@ -919,11 +995,15 @@ protected function buildProductCanonicalUrl(Product $product)
*/
protected function getProductsFromCookieList($cookieName, int $excludeProduct = 0, int $limit = 0)
{
$productUids = array_key_exists($cookieName, $_COOKIE)
? GeneralUtility::intExplode(',', $_COOKIE[$cookieName], true)
: [];
if($cookieName === ProductUtility::WISH_LIST_COOKIE_NAME) {
$products = OrderUtility::getSessionOrder()->getProducts()->getArray();
} else {
$productUids = array_key_exists($cookieName, $_COOKIE)
? GeneralUtility::intExplode(',', $_COOKIE[$cookieName], true)
: [];

$products = $this->getProductByUidsList($productUids, $excludeProduct);
$products = $this->getProductByUidsList($productUids, $excludeProduct);
}

if ($limit && count($products) > $limit) {
$products = array_slice($products, 0, $limit);
Expand Down
Loading