update
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks if correct addresses are selected.
|
||||
* There is a case when options list cannot contain cart addresses 'selected' values
|
||||
* because those are outdated in db (e.g. deleted after cart creation or country is disabled)
|
||||
*
|
||||
* @param {Array} addresses
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const ValidateAddresses = (addresses) => {
|
||||
let deliveryValid = false;
|
||||
let invoiceValid = false;
|
||||
|
||||
addresses.forEach((address) => {
|
||||
if (address.delivery) {
|
||||
deliveryValid = true;
|
||||
}
|
||||
|
||||
if (address.invoice) {
|
||||
invoiceValid = true;
|
||||
}
|
||||
});
|
||||
|
||||
return deliveryValid && invoiceValid;
|
||||
};
|
||||
|
||||
export default ValidateAddresses;
|
||||
@@ -0,0 +1,180 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
|
||||
import createOrderMap from './create-order-map';
|
||||
import Router from '../../../components/router';
|
||||
|
||||
const {$} = window;
|
||||
|
||||
/**
|
||||
* Renders Delivery & Invoice addresses select
|
||||
*/
|
||||
export default class AddressesRenderer {
|
||||
constructor() {
|
||||
this.router = new Router();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Array} addresses
|
||||
* @param {int} cartId
|
||||
*/
|
||||
render(addresses, cartId) {
|
||||
this.cleanAddresses();
|
||||
if (addresses.length === 0) {
|
||||
this.hideAddressesContent();
|
||||
this.showEmptyAddressesWarning();
|
||||
this.showAddressesBlock();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.showAddressesContent();
|
||||
this.hideEmptyAddressesWarning();
|
||||
|
||||
Object.values(addresses).forEach((address) => {
|
||||
this.renderDeliveryAddress(address, cartId);
|
||||
this.renderInvoiceAddress(address, cartId);
|
||||
});
|
||||
|
||||
this.showAddressesBlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders delivery address content
|
||||
*
|
||||
* @param address
|
||||
* @param cartId
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
renderDeliveryAddress(address, cartId) {
|
||||
const deliveryAddressOption = {
|
||||
value: address.addressId,
|
||||
text: address.alias,
|
||||
};
|
||||
|
||||
if (address.delivery) {
|
||||
$(createOrderMap.deliveryAddressDetails).html(address.formattedAddress);
|
||||
deliveryAddressOption.selected = 'selected';
|
||||
$(createOrderMap.deliveryAddressEditBtn).prop('href', this.router.generate('admin_cart_addresses_edit', {
|
||||
addressId: address.addressId,
|
||||
cartId,
|
||||
addressType: 'delivery',
|
||||
liteDisplaying: 1,
|
||||
submitFormAjax: 1,
|
||||
}));
|
||||
}
|
||||
|
||||
$(createOrderMap.deliveryAddressSelect).append($('<option>', deliveryAddressOption));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders invoice address content
|
||||
*
|
||||
* @param address
|
||||
* @param cartId
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
renderInvoiceAddress(address, cartId) {
|
||||
const invoiceAddressOption = {
|
||||
value: address.addressId,
|
||||
text: address.alias,
|
||||
};
|
||||
|
||||
if (address.invoice) {
|
||||
$(createOrderMap.invoiceAddressDetails).html(address.formattedAddress);
|
||||
invoiceAddressOption.selected = 'selected';
|
||||
$(createOrderMap.invoiceAddressEditBtn).prop('href', this.router.generate('admin_cart_addresses_edit', {
|
||||
addressId: address.addressId,
|
||||
cartId,
|
||||
addressType: 'invoice',
|
||||
liteDisplaying: 1,
|
||||
submitFormAjax: 1,
|
||||
}));
|
||||
}
|
||||
|
||||
$(createOrderMap.invoiceAddressSelect).append($('<option>', invoiceAddressOption));
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows addresses block
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
showAddressesBlock() {
|
||||
$(createOrderMap.addressesBlock).removeClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Empties addresses content
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
cleanAddresses() {
|
||||
$(createOrderMap.deliveryAddressDetails).empty();
|
||||
$(createOrderMap.deliveryAddressSelect).empty();
|
||||
$(createOrderMap.invoiceAddressDetails).empty();
|
||||
$(createOrderMap.invoiceAddressSelect).empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows addresses content and hides warning
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
showAddressesContent() {
|
||||
$(createOrderMap.addressesContent).removeClass('d-none');
|
||||
$(createOrderMap.addressesWarning).addClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides addresses content and shows warning
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
hideAddressesContent() {
|
||||
$(createOrderMap.addressesContent).addClass('d-none');
|
||||
$(createOrderMap.addressesWarning).removeClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows warning empty addresses warning
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
showEmptyAddressesWarning() {
|
||||
$(createOrderMap.addressesWarning).removeClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides empty addresses warning
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
hideEmptyAddressesWarning() {
|
||||
$(createOrderMap.addressesWarning).addClass('d-none');
|
||||
}
|
||||
}
|
||||
219
iadmin/themes/new-theme/js/pages/order/create/cart-editor.js
Normal file
219
iadmin/themes/new-theme/js/pages/order/create/cart-editor.js
Normal file
@@ -0,0 +1,219 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
|
||||
import Router from '@components/router';
|
||||
import {EventEmitter} from '@components/event-emitter';
|
||||
import eventMap from '@pages/order/create/event-map';
|
||||
import createOrderMap from './create-order-map';
|
||||
|
||||
const {$} = window;
|
||||
|
||||
/**
|
||||
* Provides ajax calls for cart editing actions
|
||||
* Each method emits an event with updated cart information after success.
|
||||
*/
|
||||
export default class CartEditor {
|
||||
constructor() {
|
||||
this.router = new Router();
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes cart addresses
|
||||
*
|
||||
* @param {Number} cartId
|
||||
* @param {Object} addresses
|
||||
*/
|
||||
changeCartAddresses(cartId, addresses) {
|
||||
$.post(this.router.generate('admin_carts_edit_addresses', {cartId}), addresses)
|
||||
.then((cartInfo) => EventEmitter.emit(eventMap.cartAddressesChanged, cartInfo))
|
||||
.catch((response) => window.showErrorMessage(response.responseJSON.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies cart delivery option
|
||||
*
|
||||
* @param {Number} cartId
|
||||
* @param {Number} value
|
||||
*/
|
||||
changeDeliveryOption(cartId, value) {
|
||||
$.post(this.router.generate('admin_carts_edit_carrier', {cartId}), {
|
||||
carrierId: value,
|
||||
}).then((cartInfo) => EventEmitter.emit(eventMap.cartDeliveryOptionChanged, cartInfo))
|
||||
.catch((response) => window.showErrorMessage(response.responseJSON.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes cart free shipping value
|
||||
*
|
||||
* @param {Number} cartId
|
||||
*/
|
||||
updateDeliveryOptions(cartId) {
|
||||
const freeShippingEnabled = $(createOrderMap.freeShippingSwitch)[1].checked;
|
||||
const isAGiftEnabled = $(createOrderMap.isAGiftSwitchValue).val() === '1';
|
||||
const useRecycledPackagingEnabled = $(createOrderMap.recycledPackagingSwitchValue).val() === '1';
|
||||
const giftMessage = $(createOrderMap.giftMessageField).val();
|
||||
|
||||
$.post(this.router.generate('admin_carts_set_delivery_settings', {cartId}), {
|
||||
freeShipping: freeShippingEnabled,
|
||||
isAGift: isAGiftEnabled,
|
||||
useRecycledPackaging: useRecycledPackagingEnabled,
|
||||
giftMessage,
|
||||
}).then((cartInfo) => EventEmitter.emit(eventMap.cartDeliverySettingChanged, cartInfo))
|
||||
.catch((response) => window.showErrorMessage(response.responseJSON.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds cart rule to cart
|
||||
*
|
||||
* @param {Number} cartRuleId
|
||||
* @param {Number} cartId
|
||||
*/
|
||||
addCartRuleToCart(cartRuleId, cartId) {
|
||||
$.post(this.router.generate('admin_carts_add_cart_rule', {cartId}), {
|
||||
cartRuleId,
|
||||
}).then((cartInfo) => EventEmitter.emit(eventMap.cartRuleAdded, cartInfo))
|
||||
.catch((response) => EventEmitter.emit(eventMap.cartRuleFailedToAdd, response.responseJSON.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes cart rule from cart
|
||||
*
|
||||
* @param {Number} cartRuleId
|
||||
* @param {Number} cartId
|
||||
*/
|
||||
removeCartRuleFromCart(cartRuleId, cartId) {
|
||||
$.post(this.router.generate('admin_carts_delete_cart_rule', {
|
||||
cartId,
|
||||
cartRuleId,
|
||||
})).then((cartInfo) => EventEmitter.emit(eventMap.cartRuleRemoved, cartInfo))
|
||||
.catch((response) => window.showErrorMessage(response.responseJSON.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds product to cart
|
||||
*
|
||||
* @param {Number} cartId
|
||||
* @param {Object} data
|
||||
*/
|
||||
addProduct(cartId, data) {
|
||||
let fileSizeHeader = '';
|
||||
|
||||
if (!$.isEmptyObject(data.fileSizes)) {
|
||||
fileSizeHeader = JSON.stringify(data.fileSizes);
|
||||
}
|
||||
|
||||
$.ajax(this.router.generate('admin_carts_add_product', {cartId}), {
|
||||
headers: {
|
||||
// Adds custom headers with submitted file sizes, to track if all files reached server side.
|
||||
'file-sizes': fileSizeHeader,
|
||||
},
|
||||
method: 'POST',
|
||||
data: data.product,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
}).then((cartInfo) => EventEmitter.emit(eventMap.productAddedToCart, cartInfo))
|
||||
.catch((response) => EventEmitter.emit(eventMap.productAddToCartFailed, response.responseJSON.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes product from cart
|
||||
*
|
||||
* @param {Number} cartId
|
||||
* @param {Object} product
|
||||
*/
|
||||
removeProductFromCart(cartId, product) {
|
||||
$.post(this.router.generate('admin_carts_delete_product', {cartId}), {
|
||||
productId: product.productId,
|
||||
attributeId: product.attributeId,
|
||||
customizationId: product.customizationId,
|
||||
}).then((cartInfo) => EventEmitter.emit(eventMap.productRemovedFromCart, {cartInfo, product}))
|
||||
.catch((response) => window.showErrorMessage(response.responseJSON.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes product price in cart
|
||||
*
|
||||
* @param {Number} cartId
|
||||
* @param {Number} customerId
|
||||
* @param {Object} product the updated product
|
||||
*/
|
||||
changeProductPrice(cartId, customerId, product) {
|
||||
$.post(this.router.generate('admin_carts_edit_product_price', {
|
||||
cartId,
|
||||
productId: product.productId,
|
||||
productAttributeId: product.attributeId,
|
||||
}), {
|
||||
newPrice: product.price,
|
||||
customerId,
|
||||
}).then((cartInfo) => EventEmitter.emit(eventMap.productPriceChanged, cartInfo))
|
||||
.catch((response) => window.showErrorMessage(response.responseJSON.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates product quantity in cart
|
||||
*
|
||||
* @param cartId
|
||||
* @param product
|
||||
*/
|
||||
changeProductQty(cartId, product) {
|
||||
$.post(this.router.generate('admin_carts_edit_product_quantity', {
|
||||
cartId,
|
||||
productId: product.productId,
|
||||
}), {
|
||||
newQty: product.newQty,
|
||||
attributeId: product.attributeId,
|
||||
customizationId: product.customizationId,
|
||||
}).then((cartInfo) => EventEmitter.emit(eventMap.productQtyChanged, {cartInfo, product}))
|
||||
.catch((response) => EventEmitter.emit(eventMap.productQtyChangeFailed, response));
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes cart currency
|
||||
*
|
||||
* @param {Number} cartId
|
||||
* @param {Number} currencyId
|
||||
*/
|
||||
changeCartCurrency(cartId, currencyId) {
|
||||
$(createOrderMap.cartCurrencySelect).data('selectedCurrencyId', currencyId);
|
||||
|
||||
$.post(this.router.generate('admin_carts_edit_currency', {cartId}), {
|
||||
currencyId,
|
||||
}).then((cartInfo) => EventEmitter.emit(eventMap.cartCurrencyChanged, cartInfo))
|
||||
.catch((response) => EventEmitter.emit(eventMap.cartCurrencyChangeFailed, response));
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes cart language
|
||||
*
|
||||
* @param {Number} cartId
|
||||
* @param {Number} languageId
|
||||
*/
|
||||
changeCartLanguage(cartId, languageId) {
|
||||
$.post(this.router.generate('admin_carts_edit_language', {cartId}), {
|
||||
languageId,
|
||||
}).then((cartInfo) => EventEmitter.emit(eventMap.cartLanguageChanged, cartInfo))
|
||||
.catch((response) => window.showErrorMessage(response.responseJSON.message));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
|
||||
import createOrderPageMap from '@pages/order/create/create-order-map';
|
||||
import Router from '@components/router';
|
||||
import {EventEmitter} from '@components/event-emitter';
|
||||
import eventMap from '@pages/order/create/event-map';
|
||||
|
||||
const {$} = window;
|
||||
|
||||
/**
|
||||
* Provides ajax calls for getting cart information
|
||||
*/
|
||||
export default class CartProvider {
|
||||
constructor() {
|
||||
this.$container = $(createOrderPageMap.orderCreationContainer);
|
||||
this.router = new Router();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets cart information
|
||||
*
|
||||
* @param cartId
|
||||
*
|
||||
* @returns {jqXHR}. Object with cart information in response.
|
||||
*/
|
||||
getCart(cartId) {
|
||||
$.get(this.router.generate('admin_carts_info', {cartId})).then((cartInfo) => {
|
||||
EventEmitter.emit(eventMap.cartLoaded, cartInfo);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets existing empty cart or creates new empty cart for customer.
|
||||
*
|
||||
* @param customerId
|
||||
*
|
||||
* @returns {jqXHR}. Object with cart information in response
|
||||
*/
|
||||
loadEmptyCart(customerId) {
|
||||
$.post(this.router.generate('admin_carts_create'), {
|
||||
customerId,
|
||||
}).then((cartInfo) => {
|
||||
EventEmitter.emit(eventMap.cartLoaded, cartInfo);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicates cart from provided order
|
||||
*
|
||||
* @param orderId
|
||||
*
|
||||
* @returns {jqXHR}. Object with cart information in response
|
||||
*/
|
||||
duplicateOrderCart(orderId) {
|
||||
$.post(this.router.generate('admin_orders_duplicate_cart', {orderId})).then((cartInfo) => {
|
||||
EventEmitter.emit(eventMap.cartLoaded, cartInfo);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
|
||||
import CartEditor from '@pages/order/create/cart-editor';
|
||||
import CartRulesRenderer from '@pages/order/create/cart-rules-renderer';
|
||||
import {EventEmitter} from '@components/event-emitter';
|
||||
import eventMap from '@pages/order/create/event-map';
|
||||
import Router from '@components/router';
|
||||
import SummaryRenderer from '@pages/order/create/summary-renderer';
|
||||
import ShippingRenderer from '@pages/order/create/shipping-renderer';
|
||||
import ProductRenderer from '@pages/order/create/product-renderer';
|
||||
|
||||
const {$} = window;
|
||||
|
||||
/**
|
||||
* Responsible for searching cart rules and managing cart rules search block
|
||||
*/
|
||||
export default class CartRuleManager {
|
||||
constructor() {
|
||||
this.activeSearchRequest = null;
|
||||
|
||||
this.router = new Router();
|
||||
this.cartRulesRenderer = new CartRulesRenderer();
|
||||
this.cartEditor = new CartEditor();
|
||||
this.summaryRenderer = new SummaryRenderer();
|
||||
this.shippingRenderer = new ShippingRenderer();
|
||||
this.productRenderer = new ProductRenderer();
|
||||
|
||||
this.initListeners();
|
||||
|
||||
return {
|
||||
search: (searchPhrase) => this.search(searchPhrase),
|
||||
stopSearching: () => this.cartRulesRenderer.hideResultsDropdown(),
|
||||
addCartRuleToCart: (cartRuleId, cartId) => this.cartEditor.addCartRuleToCart(cartRuleId, cartId),
|
||||
removeCartRuleFromCart: (cartRuleId, cartId) => this.cartEditor.removeCartRuleFromCart(cartRuleId, cartId),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiates event listeners for cart rule actions
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
initListeners() {
|
||||
this.onCartRuleSearch();
|
||||
this.onAddCartRuleToCart();
|
||||
this.onAddCartRuleToCartFailure();
|
||||
this.onRemoveCartRuleFromCart();
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for cart rule search action
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
onCartRuleSearch() {
|
||||
EventEmitter.on(eventMap.cartRuleSearched, (cartRules) => {
|
||||
this.cartRulesRenderer.renderSearchResults(cartRules);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens event of add cart rule to cart action
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
onAddCartRuleToCart() {
|
||||
EventEmitter.on(eventMap.cartRuleAdded, (cartInfo) => {
|
||||
const cartIsEmpty = cartInfo.products.length === 0;
|
||||
this.cartRulesRenderer.renderCartRulesBlock(cartInfo.cartRules, cartIsEmpty);
|
||||
this.productRenderer.renderList(cartInfo.products);
|
||||
this.shippingRenderer.render(cartInfo.shipping, cartIsEmpty);
|
||||
this.summaryRenderer.render(cartInfo);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens event when add cart rule to cart fails
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
onAddCartRuleToCartFailure() {
|
||||
EventEmitter.on(eventMap.cartRuleFailedToAdd, (message) => {
|
||||
this.cartRulesRenderer.displayErrorMessage(message);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens event for remove cart rule from cart action
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
onRemoveCartRuleFromCart() {
|
||||
EventEmitter.on(eventMap.cartRuleRemoved, (cartInfo) => {
|
||||
const cartIsEmpty = cartInfo.products.length === 0;
|
||||
this.shippingRenderer.render(cartInfo.shipping, cartIsEmpty);
|
||||
this.cartRulesRenderer.renderCartRulesBlock(cartInfo.cartRules, cartIsEmpty);
|
||||
this.summaryRenderer.render(cartInfo);
|
||||
this.productRenderer.renderList(cartInfo.products);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for cart rules by search phrase
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
search(searchPhrase) {
|
||||
if (this.activeSearchRequest !== null) {
|
||||
this.activeSearchRequest.abort();
|
||||
}
|
||||
|
||||
this.activeSearchRequest = $.get(this.router.generate('admin_cart_rules_search'), {
|
||||
search_phrase: searchPhrase,
|
||||
});
|
||||
|
||||
this.activeSearchRequest.then((cartRules) => {
|
||||
EventEmitter.emit(eventMap.cartRuleSearched, cartRules);
|
||||
}).catch((e) => {
|
||||
if (e.statusText === 'abort') {
|
||||
return;
|
||||
}
|
||||
|
||||
window.showErrorMessage(e.responseJSON.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
|
||||
import createOrderMap from './create-order-map';
|
||||
|
||||
const {$} = window;
|
||||
|
||||
/**
|
||||
* Renders cart rules (cartRules) block
|
||||
*/
|
||||
export default class CartRulesRenderer {
|
||||
constructor() {
|
||||
this.$cartRulesBlock = $(createOrderMap.cartRulesBlock);
|
||||
this.$cartRulesTable = $(createOrderMap.cartRulesTable);
|
||||
this.$searchResultBox = $(createOrderMap.cartRulesSearchResultBox);
|
||||
}
|
||||
|
||||
/**
|
||||
* Responsible for rendering cartRules (a.k.a cart rules/discounts) block
|
||||
*
|
||||
* @param {Array} cartRules
|
||||
* @param {Boolean} emptyCart
|
||||
*/
|
||||
renderCartRulesBlock(cartRules, emptyCart) {
|
||||
this.hideErrorBlock();
|
||||
// do not render cart rules block at all if cart has no products
|
||||
if (emptyCart) {
|
||||
this.hideCartRulesBlock();
|
||||
return;
|
||||
}
|
||||
this.showCartRulesBlock();
|
||||
|
||||
// do not render cart rules list when there are no cart rules
|
||||
if (cartRules.length === 0) {
|
||||
this.hideCartRulesList();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.renderList(cartRules);
|
||||
}
|
||||
|
||||
/**
|
||||
* Responsible for rendering search results dropdown
|
||||
*
|
||||
* @param searchResults
|
||||
*/
|
||||
renderSearchResults(searchResults) {
|
||||
this.clearSearchResults();
|
||||
|
||||
if (searchResults.cart_rules.length === 0) {
|
||||
this.renderNotFound();
|
||||
} else {
|
||||
this.renderFoundCartRules(searchResults.cart_rules);
|
||||
}
|
||||
|
||||
this.showResultsDropdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays error message bellow search input
|
||||
*
|
||||
* @param message
|
||||
*/
|
||||
displayErrorMessage(message) {
|
||||
$(createOrderMap.cartRuleErrorText).text(message);
|
||||
this.showErrorBlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides cart rules search result dropdown
|
||||
*/
|
||||
hideResultsDropdown() {
|
||||
this.$searchResultBox.addClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays cart rules search result dropdown
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
showResultsDropdown() {
|
||||
this.$searchResultBox.removeClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders warning that no cart rule was found
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
renderNotFound() {
|
||||
const $template = $($(createOrderMap.cartRulesNotFoundTemplate).html()).clone();
|
||||
this.$searchResultBox.html($template);
|
||||
}
|
||||
|
||||
/**
|
||||
* Empties cart rule search results block
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
clearSearchResults() {
|
||||
this.$searchResultBox.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders found cart rules after search
|
||||
*
|
||||
* @param cartRules
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
renderFoundCartRules(cartRules) {
|
||||
const $cartRuleTemplate = $($(createOrderMap.foundCartRuleTemplate).html());
|
||||
Object.values(cartRules).forEach((cartRule) => {
|
||||
const $template = $cartRuleTemplate.clone();
|
||||
|
||||
let cartRuleName = cartRule.name;
|
||||
|
||||
if (cartRule.code !== '') {
|
||||
cartRuleName = `${cartRule.name} - ${cartRule.code}`;
|
||||
}
|
||||
|
||||
$template.text(cartRuleName);
|
||||
$template.data('cart-rule-id', cartRule.cartRuleId);
|
||||
this.$searchResultBox.append($template);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Responsible for rendering the list of cart rules
|
||||
*
|
||||
* @param {Array} cartRules
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
renderList(cartRules) {
|
||||
this.cleanCartRulesList();
|
||||
const $cartRulesTableRowTemplate = $($(createOrderMap.cartRulesTableRowTemplate).html());
|
||||
|
||||
Object.values(cartRules).forEach((cartRule) => {
|
||||
const $template = $cartRulesTableRowTemplate.clone();
|
||||
|
||||
$template.find(createOrderMap.cartRuleNameField).text(cartRule.name);
|
||||
$template.find(createOrderMap.cartRuleDescriptionField).text(cartRule.description);
|
||||
$template.find(createOrderMap.cartRuleValueField).text(cartRule.value);
|
||||
$template.find(createOrderMap.cartRuleDeleteBtn).data('cart-rule-id', cartRule.cartRuleId);
|
||||
|
||||
this.$cartRulesTable.find('tbody').append($template);
|
||||
});
|
||||
|
||||
this.showCartRulesList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows error block
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
showErrorBlock() {
|
||||
$(createOrderMap.cartRuleErrorBlock).removeClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides error block
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
hideErrorBlock() {
|
||||
$(createOrderMap.cartRuleErrorBlock).addClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows cartRules block
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
showCartRulesBlock() {
|
||||
this.$cartRulesBlock.removeClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* hide cartRules block
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
hideCartRulesBlock() {
|
||||
this.$cartRulesBlock.addClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the list block of cart rules
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
showCartRulesList() {
|
||||
this.$cartRulesTable.removeClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide list block of cart rules
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
hideCartRulesList() {
|
||||
this.$cartRulesTable.addClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* remove items in cart rules list
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
cleanCartRulesList() {
|
||||
this.$cartRulesTable.find('tbody').empty();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Encapsulates selectors for "Create order" page
|
||||
*/
|
||||
export default {
|
||||
productCustomizationFieldTypeFile: 0,
|
||||
productCustomizationFieldTypeText: 1,
|
||||
|
||||
orderCreationContainer: '#order-creation-container',
|
||||
requiredFieldMark: '.js-required-field-mark',
|
||||
cartInfoWrapper: '#js-cart-info-wrapper',
|
||||
|
||||
// selectors related to customer block
|
||||
customerSearchInput: '#customer-search-input',
|
||||
customerSearchResultsBlock: '.js-customer-search-results',
|
||||
customerSearchResultTemplate: '#customer-search-result-template',
|
||||
customerSearchEmptyResultWarning: '#customer-search-empty-result-warn',
|
||||
customerSearchLoadingNotice: '#customer-search-loading-notice',
|
||||
customerAddBtn: '#customer-add-btn',
|
||||
changeCustomerBtn: '.js-change-customer-btn',
|
||||
customerSearchRow: '.js-search-customer-row',
|
||||
chooseCustomerBtn: '.js-choose-customer-btn',
|
||||
notSelectedCustomerSearchResults: '.js-customer-search-result:not(.border-success)',
|
||||
customerSearchResultName: '.js-customer-name',
|
||||
customerSearchResultEmail: '.js-customer-email',
|
||||
customerSearchResultId: '.js-customer-id',
|
||||
customerSearchResultBirthday: '.js-customer-birthday',
|
||||
customerDetailsBtn: '.js-details-customer-btn',
|
||||
customerSearchResultColumn: '.js-customer-search-result-col',
|
||||
customerSearchBlock: '#customer-search-block',
|
||||
customerCartsTab: '.js-customer-carts-tab',
|
||||
customerOrdersTab: '.js-customer-orders-tab',
|
||||
customerCartsTable: '#customer-carts-table',
|
||||
customerCartsTableRowTemplate: '#customer-carts-table-row-template',
|
||||
customerCheckoutHistory: '#customer-checkout-history',
|
||||
customerOrdersTable: '#customer-orders-table',
|
||||
customerOrdersTableRowTemplate: '#customer-orders-table-row-template',
|
||||
cartRulesTable: '#cart-rules-table',
|
||||
cartRulesTableRowTemplate: '#cart-rules-table-row-template',
|
||||
useCartBtn: '.js-use-cart-btn',
|
||||
cartDetailsBtn: '.js-cart-details-btn',
|
||||
cartIdField: '.js-cart-id',
|
||||
cartDateField: '.js-cart-date',
|
||||
cartTotalField: '.js-cart-total',
|
||||
useOrderBtn: '.js-use-order-btn',
|
||||
orderDetailsBtn: '.js-order-details-btn',
|
||||
orderIdField: '.js-order-id',
|
||||
orderDateField: '.js-order-date',
|
||||
orderProductsField: '.js-order-products',
|
||||
orderTotalField: '.js-order-total-paid',
|
||||
orderPaymentMethod: '.js-order-payment-method',
|
||||
orderStatusField: '.js-order-status',
|
||||
emptyListRowTemplate: '#js-empty-list-row',
|
||||
loadingListRowTemplate: '#js-loading-list-row',
|
||||
emptyListRow: '.js-empty-row',
|
||||
|
||||
// selectors related to cartRules block
|
||||
cartRulesBlock: '#cart-rules-block',
|
||||
cartRuleSearchInput: '#search-cart-rules-input',
|
||||
cartRulesSearchResultBox: '#search-cart-rules-result-box',
|
||||
cartRulesNotFoundTemplate: '#cart-rules-not-found-template',
|
||||
foundCartRuleTemplate: '#found-cart-rule-template',
|
||||
foundCartRuleListItem: '.js-found-cart-rule',
|
||||
cartRuleNameField: '.js-cart-rule-name',
|
||||
cartRuleDescriptionField: '.js-cart-rule-description',
|
||||
cartRuleValueField: '.js-cart-rule-value',
|
||||
cartRuleDeleteBtn: '.js-cart-rule-delete-btn',
|
||||
cartRuleErrorBlock: '#js-cart-rule-error-block',
|
||||
cartRuleErrorText: '#js-cart-rule-error-text',
|
||||
|
||||
// selectors related to addresses block
|
||||
addressesBlock: '#addresses-block',
|
||||
deliveryAddressDetails: '#delivery-address-details',
|
||||
invoiceAddressDetails: '#invoice-address-details',
|
||||
deliveryAddressSelect: '#delivery-address-select',
|
||||
invoiceAddressSelect: '#invoice-address-select',
|
||||
addressSelect: '.js-address-select',
|
||||
addressesContent: '#addresses-content',
|
||||
addressesWarning: '#addresses-warning',
|
||||
deliveryAddressEditBtn: '#js-delivery-address-edit-btn',
|
||||
invoiceAddressEditBtn: '#js-invoice-address-edit-btn',
|
||||
addressAddBtn: '#js-add-address-btn',
|
||||
|
||||
// selectors related to summary block
|
||||
summaryBlock: '#summary-block',
|
||||
summaryTotalProducts: '.js-total-products',
|
||||
summaryTotalDiscount: '.js-total-discounts',
|
||||
summaryTotalShipping: '.js-total-shipping',
|
||||
summaryTotalTaxes: '.js-total-taxes',
|
||||
summaryTotalWithoutTax: '.js-total-without-tax',
|
||||
summaryTotalWithTax: '.js-total-with-tax',
|
||||
placeOrderCartIdField: '.js-place-order-cart-id',
|
||||
processOrderLinkTag: '#js-process-order-link',
|
||||
orderMessageField: '#js-order-message-wrap textarea',
|
||||
sendProcessOrderEmailBtn: '#js-send-process-order-email-btn',
|
||||
summarySuccessAlertBlock: '#js-summary-success-block',
|
||||
summaryErrorAlertBlock: '#js-summary-error-block',
|
||||
summarySuccessAlertText: '#js-summary-success-block .alert-text',
|
||||
summaryErrorAlertText: '#js-summary-error-block .alert-text',
|
||||
|
||||
// selectors related to shipping block
|
||||
shippingBlock: '#shipping-block',
|
||||
shippingForm: '.js-shipping-form',
|
||||
noCarrierBlock: '.js-no-carrier-block',
|
||||
deliveryOptionSelect: '#delivery-option-select',
|
||||
totalShippingField: '.js-total-shipping-tax-inc',
|
||||
freeShippingSwitch: '.js-free-shipping-switch',
|
||||
recycledPackagingSwitch: '.js-recycled-packaging-switch',
|
||||
recycledPackagingSwitchValue: '.js-recycled-packaging-switch:checked',
|
||||
isAGiftSwitch: '.js-is-gift-switch',
|
||||
isAGiftSwitchValue: '.js-is-gift-switch:checked',
|
||||
giftMessageField: '#cart_gift_message',
|
||||
|
||||
// selectors related to cart block
|
||||
cartBlock: '#cart-block',
|
||||
cartCurrencySelect: '#js-cart-currency-select',
|
||||
cartLanguageSelect: '#js-cart-language-select',
|
||||
productSearch: '#product-search',
|
||||
combinationsSelect: '#combination-select',
|
||||
productResultBlock: '#product-search-results',
|
||||
productSelect: '#product-select',
|
||||
quantityInput: '#quantity-input',
|
||||
inStockCounter: '.js-in-stock-counter',
|
||||
combinationsTemplate: '#combinations-template',
|
||||
combinationsRow: '.js-combinations-row',
|
||||
productSelectRow: '.js-product-select-row',
|
||||
productCustomFieldsContainer: '#js-custom-fields-container',
|
||||
productCustomizationContainer: '#js-customization-container',
|
||||
productCustomFileTemplate: '#js-product-custom-file-template',
|
||||
productCustomTextTemplate: '#js-product-custom-text-template',
|
||||
productCustomInputLabel: '.js-product-custom-input-label',
|
||||
productCustomInput: '.js-product-custom-input',
|
||||
quantityRow: '.js-quantity-row',
|
||||
addToCartButton: '#add-product-to-cart-btn',
|
||||
productsTable: '#products-table',
|
||||
productsTableRowTemplate: '#products-table-row-template',
|
||||
productsTableGiftRowTemplate: '#products-table-gift-row-template',
|
||||
listedProductImageField: '.js-product-image',
|
||||
listedProductNameField: '.js-product-name',
|
||||
listedProductAttrField: '.js-product-attr',
|
||||
listedProductReferenceField: '.js-product-ref',
|
||||
listedProductUnitPriceInput: '.js-product-unit-input',
|
||||
listedProductQtyInput: '.js-product-qty-input',
|
||||
listedProductQtyStock: '.js-product-qty-stock',
|
||||
listedProductGiftQty: '.js-product-gift-qty',
|
||||
productTotalPriceField: '.js-product-total-price',
|
||||
listedProductCustomizedTextTemplate: '#js-table-product-customized-text-template',
|
||||
listedProductCustomizedFileTemplate: '#js-table-product-customized-file-template',
|
||||
listedProductCustomizationName: '.js-customization-name',
|
||||
listedProductCustomizationValue: '.js-customization-value',
|
||||
listedProductDefinition: '.js-product-definition-td',
|
||||
productRemoveBtn: '.js-product-remove-btn',
|
||||
productTaxWarning: '.js-tax-warning',
|
||||
noProductsFoundWarning: '.js-no-products-found',
|
||||
searchingProductsNotice: '.js-searching-products',
|
||||
productAddForm: '#js-add-product-form',
|
||||
cartErrorAlertBlock: '#js-cart-error-block',
|
||||
cartErrorAlertText: '#js-cart-error-block .alert-text',
|
||||
createOrderButton: '#create-order-button',
|
||||
};
|
||||
@@ -0,0 +1,644 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
|
||||
import Router from '@components/router';
|
||||
import {EventEmitter} from '@components/event-emitter';
|
||||
import _ from 'lodash';
|
||||
import createOrderMap from './create-order-map';
|
||||
import CustomerManager from './customer-manager';
|
||||
import ShippingRenderer from './shipping-renderer';
|
||||
import CartProvider from './cart-provider';
|
||||
import AddressesRenderer from './addresses-renderer';
|
||||
import CartRulesRenderer from './cart-rules-renderer';
|
||||
import CartEditor from './cart-editor';
|
||||
import eventMap from './event-map';
|
||||
import CartRuleManager from './cart-rule-manager';
|
||||
import ProductManager from './product-manager';
|
||||
import ProductRenderer from './product-renderer';
|
||||
import SummaryRenderer from './summary-renderer';
|
||||
import SummaryManager from './summary-manager';
|
||||
import {ValidateAddresses} from './address-validator';
|
||||
|
||||
const {$} = window;
|
||||
|
||||
/**
|
||||
* Page Object for "Create order" page
|
||||
*/
|
||||
export default class CreateOrderPage {
|
||||
constructor() {
|
||||
this.cartId = null;
|
||||
this.customerId = null;
|
||||
this.$container = $(createOrderMap.orderCreationContainer);
|
||||
|
||||
this.cartProvider = new CartProvider();
|
||||
this.customerManager = new CustomerManager();
|
||||
this.shippingRenderer = new ShippingRenderer();
|
||||
this.addressesRenderer = new AddressesRenderer();
|
||||
this.cartRulesRenderer = new CartRulesRenderer();
|
||||
this.router = new Router();
|
||||
this.cartEditor = new CartEditor();
|
||||
this.cartRuleManager = new CartRuleManager();
|
||||
this.productManager = new ProductManager();
|
||||
this.productRenderer = new ProductRenderer();
|
||||
this.summaryRenderer = new SummaryRenderer();
|
||||
this.summaryManager = new SummaryManager();
|
||||
|
||||
this.initListeners();
|
||||
this.loadCartFromUrlParams();
|
||||
|
||||
return {
|
||||
refreshAddressesList: (refreshCartAddresses) => this.refreshAddressesList(refreshCartAddresses),
|
||||
refreshCart: (refreshCart) => this.refreshCart(refreshCart),
|
||||
search: (string) => this.customerManager.search(string),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if correct addresses are selected.
|
||||
* There is a case when options list cannot contain cart addresses 'selected' values
|
||||
* because those are outdated in db (e.g. deleted after cart creation or country is disabled)
|
||||
*
|
||||
* @param {Array} addresses
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
static validateSelectedAddresses(addresses) {
|
||||
let deliveryValid = false;
|
||||
let invoiceValid = false;
|
||||
|
||||
const keys = Object.keys(addresses);
|
||||
|
||||
for (let i = 0; i < keys.length; i += 1) {
|
||||
const address = addresses[keys[i]];
|
||||
|
||||
if (address.delivery) {
|
||||
deliveryValid = true;
|
||||
}
|
||||
|
||||
if (address.invoice) {
|
||||
invoiceValid = true;
|
||||
}
|
||||
|
||||
if (deliveryValid && invoiceValid) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides whole cart information wrapper
|
||||
*/
|
||||
hideCartInfo() {
|
||||
$(createOrderMap.cartInfoWrapper).addClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows whole cart information wrapper
|
||||
*/
|
||||
showCartInfo() {
|
||||
$(createOrderMap.cartInfoWrapper).removeClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads cart if query params contains valid cartId
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
loadCartFromUrlParams() {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const cartId = Number(urlParams.get('cartId'));
|
||||
|
||||
if (!Number.isNaN(cartId) && cartId !== 0) {
|
||||
this.cartProvider.getCart(cartId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes event listeners
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
initListeners() {
|
||||
this.$container.on('input', createOrderMap.customerSearchInput, (e) => this.initCustomerSearch(e));
|
||||
this.$container.on('click', createOrderMap.chooseCustomerBtn, (e) => this.initCustomerSelect(e));
|
||||
this.$container.on('click', createOrderMap.useCartBtn, (e) => this.initCartSelect(e));
|
||||
this.$container.on('click', createOrderMap.useOrderBtn, (e) => this.initDuplicateOrderCart(e));
|
||||
this.$container.on('input', createOrderMap.productSearch, (e) => this.initProductSearch(e));
|
||||
this.$container.on('input', createOrderMap.cartRuleSearchInput, (e) => this.initCartRuleSearch(e));
|
||||
this.$container.on('blur', createOrderMap.cartRuleSearchInput, () => this.cartRuleManager.stopSearching());
|
||||
this.listenForCartEdit();
|
||||
this.onCartLoaded();
|
||||
this.onCustomersNotFound();
|
||||
this.onCustomerSelected();
|
||||
this.initAddressButtonsIframe();
|
||||
this.initCartRuleButtonsIframe();
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
initAddressButtonsIframe() {
|
||||
$(createOrderMap.addressAddBtn).fancybox({
|
||||
type: 'iframe',
|
||||
width: '90%',
|
||||
height: '90%',
|
||||
});
|
||||
|
||||
$(createOrderMap.invoiceAddressEditBtn).fancybox({
|
||||
type: 'iframe',
|
||||
width: '90%',
|
||||
height: '90%',
|
||||
});
|
||||
|
||||
$(createOrderMap.deliveryAddressEditBtn).fancybox({
|
||||
type: 'iframe',
|
||||
width: '90%',
|
||||
height: '90%',
|
||||
});
|
||||
}
|
||||
|
||||
initCartRuleButtonsIframe() {
|
||||
$('#js-add-cart-rule-btn').fancybox({
|
||||
type: 'iframe',
|
||||
width: '90%',
|
||||
height: '90%',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegates actions to events associated with cart update (e.g. change cart address)
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
listenForCartEdit() {
|
||||
this.onCartAddressesChanged();
|
||||
this.onDeliveryOptionChanged();
|
||||
this.onDeliverySettingChanged();
|
||||
this.addCartRuleToCart();
|
||||
this.removeCartRuleFromCart();
|
||||
this.onCartCurrencyChanged();
|
||||
this.onCartLanguageChanged();
|
||||
|
||||
this.$container.on(
|
||||
'change',
|
||||
createOrderMap.deliveryOptionSelect,
|
||||
(e) => this.cartEditor.changeDeliveryOption(this.cartId, e.currentTarget.value),
|
||||
);
|
||||
|
||||
this.$container.on(
|
||||
'change',
|
||||
createOrderMap.freeShippingSwitch,
|
||||
() => this.cartEditor.updateDeliveryOptions(this.cartId),
|
||||
);
|
||||
|
||||
this.$container.on(
|
||||
'change',
|
||||
createOrderMap.recycledPackagingSwitch,
|
||||
() => this.cartEditor.updateDeliveryOptions(this.cartId),
|
||||
);
|
||||
|
||||
this.$container.on(
|
||||
'change',
|
||||
createOrderMap.isAGiftSwitch,
|
||||
() => this.cartEditor.updateDeliveryOptions(this.cartId),
|
||||
);
|
||||
|
||||
this.$container.on(
|
||||
'blur',
|
||||
createOrderMap.giftMessageField,
|
||||
() => this.cartEditor.updateDeliveryOptions(this.cartId),
|
||||
);
|
||||
|
||||
this.$container.on(
|
||||
'click',
|
||||
createOrderMap.addToCartButton,
|
||||
() => this.productManager.addProductToCart(this.cartId),
|
||||
);
|
||||
|
||||
this.$container.on(
|
||||
'change',
|
||||
createOrderMap.cartCurrencySelect,
|
||||
(e) => this.cartEditor.changeCartCurrency(this.cartId, e.currentTarget.value),
|
||||
);
|
||||
|
||||
this.$container.on(
|
||||
'change',
|
||||
createOrderMap.cartLanguageSelect,
|
||||
(e) => this.cartEditor.changeCartLanguage(this.cartId, e.currentTarget.value),
|
||||
);
|
||||
|
||||
this.$container.on(
|
||||
'click',
|
||||
createOrderMap.sendProcessOrderEmailBtn,
|
||||
() => this.summaryManager.sendProcessOrderEmail(this.cartId),
|
||||
);
|
||||
|
||||
this.$container.on('change', createOrderMap.listedProductUnitPriceInput, (e) => this.initProductChangePrice(e));
|
||||
this.$container.on(
|
||||
'change',
|
||||
createOrderMap.listedProductQtyInput,
|
||||
_.debounce((e) => {
|
||||
const inputsQty = document.querySelectorAll(createOrderMap.listedProductQtyInput);
|
||||
|
||||
inputsQty.forEach((inputQty) => {
|
||||
inputQty.setAttribute('disabled', true);
|
||||
});
|
||||
this.initProductChangeQty(e);
|
||||
}, 500),
|
||||
);
|
||||
this.$container.on('change', createOrderMap.addressSelect, () => this.changeCartAddresses());
|
||||
this.$container.on('click', createOrderMap.productRemoveBtn, (e) => this.initProductRemoveFromCart(e));
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for event when cart is loaded
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
onCartLoaded() {
|
||||
EventEmitter.on(eventMap.cartLoaded, (cartInfo) => {
|
||||
this.cartId = cartInfo.cartId;
|
||||
this.renderCartInfo(cartInfo);
|
||||
if (cartInfo.addresses.length !== 0 && !ValidateAddresses(cartInfo.addresses)) {
|
||||
this.changeCartAddresses();
|
||||
}
|
||||
this.customerManager.loadCustomerCarts(this.cartId);
|
||||
this.customerManager.loadCustomerOrders();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for event when no customers were found by search
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
onCustomersNotFound() {
|
||||
EventEmitter.on(eventMap.customersNotFound, () => {
|
||||
this.hideCartInfo();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for event when customer is selected
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
onCustomerSelected() {
|
||||
EventEmitter.on(eventMap.customerSelected, () => {
|
||||
this.showCartInfo();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for cart addresses update event
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
onCartAddressesChanged() {
|
||||
EventEmitter.on(eventMap.cartAddressesChanged, (cartInfo) => {
|
||||
this.addressesRenderer.render(cartInfo.addresses, cartInfo.cartId);
|
||||
this.cartRulesRenderer.renderCartRulesBlock(cartInfo.cartRules, cartInfo.products.length === 0);
|
||||
this.shippingRenderer.render(cartInfo.shipping, cartInfo.products.length === 0);
|
||||
this.productRenderer.renderList(cartInfo.products);
|
||||
this.summaryRenderer.render(cartInfo);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for cart delivery option update event
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
onDeliveryOptionChanged() {
|
||||
EventEmitter.on(eventMap.cartDeliveryOptionChanged, (cartInfo) => {
|
||||
this.cartRulesRenderer.renderCartRulesBlock(cartInfo.cartRules, cartInfo.products.length === 0);
|
||||
this.shippingRenderer.render(cartInfo.shipping, cartInfo.products.length === 0);
|
||||
this.summaryRenderer.render(cartInfo);
|
||||
this.productRenderer.renderList(cartInfo.products);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for cart delivery setting update event
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
onDeliverySettingChanged() {
|
||||
EventEmitter.on(eventMap.cartDeliverySettingChanged, (cartInfo) => {
|
||||
this.cartRulesRenderer.renderCartRulesBlock(cartInfo.cartRules, cartInfo.products.length === 0);
|
||||
this.shippingRenderer.render(cartInfo.shipping, cartInfo.products.length === 0);
|
||||
this.summaryRenderer.render(cartInfo);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for cart language update event
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
onCartLanguageChanged() {
|
||||
EventEmitter.on(eventMap.cartLanguageChanged, (cartInfo) => {
|
||||
this.preselectCartLanguage(cartInfo.langId);
|
||||
this.renderCartInfo(cartInfo);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for cart currency update event
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
onCartCurrencyChanged() {
|
||||
// on success
|
||||
EventEmitter.on(eventMap.cartCurrencyChanged, (cartInfo) => {
|
||||
this.renderCartInfo(cartInfo);
|
||||
this.productRenderer.reset();
|
||||
});
|
||||
|
||||
// on failure
|
||||
EventEmitter.on(eventMap.cartCurrencyChangeFailed, (response) => {
|
||||
this.productRenderer.renderCartBlockErrorAlert(response.responseJSON.message);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Init customer searching
|
||||
*
|
||||
* @param event
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
initCustomerSearch(event) {
|
||||
clearTimeout(this.timeoutId);
|
||||
this.timeoutId = setTimeout(() => this.customerManager.search($(event.currentTarget).val()), 300);
|
||||
}
|
||||
|
||||
/**
|
||||
* Init selecting customer for which order is being created
|
||||
*
|
||||
* @param event
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
initCustomerSelect(event) {
|
||||
const customerId = this.customerManager.selectCustomer(event);
|
||||
this.customerId = customerId;
|
||||
this.cartProvider.loadEmptyCart(customerId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inits selecting cart to load
|
||||
*
|
||||
* @param event
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
initCartSelect(event) {
|
||||
const cartId = $(event.currentTarget).data('cart-id');
|
||||
this.cartProvider.getCart(cartId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inits duplicating order cart
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
initDuplicateOrderCart(event) {
|
||||
const orderId = $(event.currentTarget).data('order-id');
|
||||
this.cartProvider.duplicateOrderCart(orderId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers cart rule searching
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
initCartRuleSearch(event) {
|
||||
const searchPhrase = event.currentTarget.value;
|
||||
|
||||
clearTimeout(this.timeoutId);
|
||||
this.timeoutId = setTimeout(() => this.cartRuleManager.search(searchPhrase), 300);
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers cart rule select
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
addCartRuleToCart() {
|
||||
this.$container.on('mousedown', createOrderMap.foundCartRuleListItem, (event) => {
|
||||
// prevent blur event to allow selecting cart rule
|
||||
event.preventDefault();
|
||||
const cartRuleId = $(event.currentTarget).data('cart-rule-id');
|
||||
this.cartRuleManager.addCartRuleToCart(cartRuleId, this.cartId);
|
||||
|
||||
// manually fire blur event after cart rule is selected.
|
||||
})
|
||||
.on('click', createOrderMap.foundCartRuleListItem, () => {
|
||||
$(createOrderMap.cartRuleSearchInput).blur();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers cart rule removal from cart
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
removeCartRuleFromCart() {
|
||||
this.$container.on('click', createOrderMap.cartRuleDeleteBtn, (event) => {
|
||||
this.cartRuleManager.removeCartRuleFromCart($(event.currentTarget).data('cart-rule-id'), this.cartId);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Inits product searching
|
||||
*
|
||||
* @param event
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
initProductSearch(event) {
|
||||
const $productSearchInput = $(event.currentTarget);
|
||||
const searchPhrase = $productSearchInput.val();
|
||||
clearTimeout(this.timeoutId);
|
||||
|
||||
this.timeoutId = setTimeout(() => this.productManager.search(searchPhrase), 300);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inits product removing from cart
|
||||
*
|
||||
* @param event
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
initProductRemoveFromCart(event) {
|
||||
const productQty = Number($(event.currentTarget).parents().find(createOrderMap.listedProductQtyInput).val());
|
||||
const product = {
|
||||
productId: $(event.currentTarget).data('product-id'),
|
||||
attributeId: $(event.currentTarget).data('attribute-id'),
|
||||
customizationId: $(event.currentTarget).data('customization-id'),
|
||||
qtyToRemove: productQty,
|
||||
};
|
||||
|
||||
this.productManager.removeProductFromCart(this.cartId, product);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inits product in cart price change
|
||||
*
|
||||
* @param event
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
initProductChangePrice(event) {
|
||||
const product = {
|
||||
productId: $(event.currentTarget).data('product-id'),
|
||||
attributeId: $(event.currentTarget).data('attribute-id'),
|
||||
customizationId: $(event.currentTarget).data('customization-id'),
|
||||
price: $(event.currentTarget).val(),
|
||||
};
|
||||
this.productManager.changeProductPrice(this.cartId, this.customerId, product);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inits product in cart quantity update
|
||||
*
|
||||
* @param event
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
initProductChangeQty(event) {
|
||||
const product = {
|
||||
productId: $(event.currentTarget).data('product-id'),
|
||||
attributeId: $(event.currentTarget).data('attribute-id'),
|
||||
customizationId: $(event.currentTarget).data('customization-id'),
|
||||
newQty: $(event.currentTarget).val(),
|
||||
prevQty: $(event.currentTarget).data('prev-qty'),
|
||||
};
|
||||
|
||||
if (
|
||||
typeof product.productId !== 'undefined'
|
||||
&& product.productId !== null
|
||||
&& typeof product.attributeId !== 'undefined'
|
||||
&& product.attributeId !== null
|
||||
) {
|
||||
this.productManager.changeProductQty(this.cartId, product);
|
||||
} else {
|
||||
const inputsQty = document.querySelectorAll(createOrderMap.listedProductQtyInput);
|
||||
|
||||
inputsQty.forEach((inputQty) => {
|
||||
inputQty.disabled = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders cart summary on the page
|
||||
*
|
||||
* @param {Object} cartInfo
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
renderCartInfo(cartInfo) {
|
||||
this.addressesRenderer.render(cartInfo.addresses, cartInfo.cartId);
|
||||
this.cartRulesRenderer.renderCartRulesBlock(cartInfo.cartRules, cartInfo.products.length === 0);
|
||||
this.shippingRenderer.render(cartInfo.shipping, cartInfo.products.length === 0);
|
||||
this.productRenderer.cleanCartBlockAlerts();
|
||||
this.productRenderer.renderList(cartInfo.products);
|
||||
this.summaryRenderer.render(cartInfo);
|
||||
this.preselectCartCurrency(cartInfo.currencyId);
|
||||
this.preselectCartLanguage(cartInfo.langId);
|
||||
|
||||
$(createOrderMap.cartBlock).removeClass('d-none');
|
||||
$(createOrderMap.cartBlock).data('cartId', cartInfo.cartId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets cart currency selection value
|
||||
*
|
||||
* @param currencyId
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
preselectCartCurrency(currencyId) {
|
||||
$(createOrderMap.cartCurrencySelect).val(currencyId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets cart language selection value
|
||||
*
|
||||
* @param langId
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
preselectCartLanguage(langId) {
|
||||
$(createOrderMap.cartLanguageSelect).val(langId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes cart addresses
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
changeCartAddresses() {
|
||||
const addresses = {
|
||||
deliveryAddressId: $(createOrderMap.deliveryAddressSelect).val(),
|
||||
invoiceAddressId: $(createOrderMap.invoiceAddressSelect).val(),
|
||||
};
|
||||
|
||||
this.cartEditor.changeCartAddresses(this.cartId, addresses);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh addresses list
|
||||
*
|
||||
* @param {boolean} refreshCartAddresses optional
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
refreshAddressesList(refreshCartAddresses) {
|
||||
const cartId = $(createOrderMap.cartBlock).data('cartId');
|
||||
$.get(this.router.generate('admin_carts_info', {cartId})).then((cartInfo) => {
|
||||
this.addressesRenderer.render(cartInfo.addresses, cartInfo.cartId);
|
||||
|
||||
if (refreshCartAddresses) {
|
||||
this.changeCartAddresses();
|
||||
}
|
||||
}).catch((e) => {
|
||||
window.showErrorMessage(e.responseJSON.message);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* proxy to allow other scripts within the page to refresh addresses list
|
||||
*/
|
||||
refreshCart() {
|
||||
const cartId = $(createOrderMap.cartBlock).data('cartId');
|
||||
this.cartProvider.getCart(cartId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
|
||||
import createOrderMap from '@pages/order/create/create-order-map';
|
||||
import CustomerRenderer from '@pages/order/create/customer-renderer';
|
||||
import {EventEmitter} from '@components/event-emitter';
|
||||
import eventMap from '@pages/order/create/event-map';
|
||||
import Router from '@components/router';
|
||||
|
||||
const {$} = window;
|
||||
|
||||
/**
|
||||
* Responsible for customers managing. (search, select, get customer info etc.)
|
||||
*/
|
||||
export default class CustomerManager {
|
||||
constructor() {
|
||||
this.customerId = null;
|
||||
this.activeSearchRequest = null;
|
||||
|
||||
this.router = new Router();
|
||||
this.$container = $(createOrderMap.customerSearchBlock);
|
||||
this.$searchInput = $(createOrderMap.customerSearchInput);
|
||||
this.$customerSearchResultBlock = $(createOrderMap.customerSearchResultsBlock);
|
||||
this.customerRenderer = new CustomerRenderer();
|
||||
|
||||
this.initListeners();
|
||||
this.initAddCustomerIframe();
|
||||
|
||||
return {
|
||||
search: (searchPhrase) => this.search(searchPhrase),
|
||||
selectCustomer: (event) => this.selectCustomer(event),
|
||||
loadCustomerCarts: (currentCartId) => this.loadCustomerCarts(currentCartId),
|
||||
loadCustomerOrders: () => this.loadCustomerOrders(),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes event listeners
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
initListeners() {
|
||||
this.$container.on('click', createOrderMap.changeCustomerBtn, () => this.changeCustomer());
|
||||
this.onCustomerSearch();
|
||||
this.onCustomerSelect();
|
||||
this.onCustomersNotFound();
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
initAddCustomerIframe() {
|
||||
$(createOrderMap.customerAddBtn).fancybox({
|
||||
type: 'iframe',
|
||||
width: '90%',
|
||||
height: '90%',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for customer search event
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
onCustomerSearch() {
|
||||
EventEmitter.on(eventMap.customerSearched, (response) => {
|
||||
this.activeSearchRequest = null;
|
||||
this.customerRenderer.hideSearchingCustomers();
|
||||
|
||||
if (response.customers.length === 0) {
|
||||
EventEmitter.emit(eventMap.customersNotFound);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.customerRenderer.renderSearchResults(response.customers);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for event of when no customers were found by search
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
onCustomersNotFound() {
|
||||
EventEmitter.on(eventMap.customersNotFound, () => {
|
||||
this.customerRenderer.showNotFoundCustomers();
|
||||
this.customerRenderer.hideCheckoutHistoryBlock();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for customer select event
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
onCustomerSelect() {
|
||||
EventEmitter.on(eventMap.customerSelected, (event) => {
|
||||
const $chooseBtn = $(event.currentTarget);
|
||||
this.customerId = $chooseBtn.data('customer-id');
|
||||
|
||||
const createAddressUrl = this.router.generate(
|
||||
'admin_addresses_create',
|
||||
{
|
||||
liteDisplaying: 1,
|
||||
submitFormAjax: 1,
|
||||
id_customer: this.customerId,
|
||||
},
|
||||
);
|
||||
$(createOrderMap.addressAddBtn).attr('href', createAddressUrl);
|
||||
|
||||
this.customerRenderer.displaySelectedCustomerBlock($chooseBtn);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles use case when customer is changed
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
changeCustomer() {
|
||||
this.customerRenderer.showCustomerSearch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads customer carts list
|
||||
*
|
||||
* @param currentCartId
|
||||
*/
|
||||
loadCustomerCarts(currentCartId) {
|
||||
const {customerId} = this;
|
||||
|
||||
this.customerRenderer.showLoadingCarts();
|
||||
$.get(this.router.generate('admin_customers_carts', {customerId})).then((response) => {
|
||||
this.customerRenderer.renderCarts(response.carts, currentCartId);
|
||||
}).catch((e) => {
|
||||
window.showErrorMessage(e.responseJSON.message);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads customer orders list
|
||||
*/
|
||||
loadCustomerOrders() {
|
||||
const {customerId} = this;
|
||||
|
||||
this.customerRenderer.showLoadingOrders();
|
||||
$.get(this.router.generate('admin_customers_orders', {customerId})).then((response) => {
|
||||
this.customerRenderer.renderOrders(response.orders);
|
||||
}).catch((e) => {
|
||||
window.showErrorMessage(e.responseJSON.message);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Event} chooseCustomerEvent
|
||||
*
|
||||
* @return {Number}
|
||||
*/
|
||||
selectCustomer(chooseCustomerEvent) {
|
||||
EventEmitter.emit(eventMap.customerSelected, chooseCustomerEvent);
|
||||
|
||||
return this.customerId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for customers
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
search(searchPhrase) {
|
||||
if (searchPhrase.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.activeSearchRequest !== null) {
|
||||
this.activeSearchRequest.abort();
|
||||
}
|
||||
|
||||
this.customerRenderer.clearShownCustomers();
|
||||
this.customerRenderer.hideNotFoundCustomers();
|
||||
this.customerRenderer.showSearchingCustomers();
|
||||
const $searchRequest = $.get(this.router.generate('admin_customers_search'), {
|
||||
customer_search: searchPhrase,
|
||||
});
|
||||
this.activeSearchRequest = $searchRequest;
|
||||
|
||||
$searchRequest.then((response) => {
|
||||
EventEmitter.emit(eventMap.customerSearched, response);
|
||||
}).catch((response) => {
|
||||
if (response.statusText === 'abort') {
|
||||
return;
|
||||
}
|
||||
|
||||
window.showErrorMessage(response.responseJSON.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,341 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
|
||||
import createOrderMap from '@pages/order/create/create-order-map';
|
||||
import Router from '@components/router';
|
||||
import eventMap from '@pages/order/create/event-map';
|
||||
import {EventEmitter} from '@components/event-emitter';
|
||||
|
||||
const {$} = window;
|
||||
|
||||
/**
|
||||
* Responsible for customer information rendering
|
||||
*/
|
||||
export default class CustomerRenderer {
|
||||
constructor() {
|
||||
this.$container = $(createOrderMap.customerSearchBlock);
|
||||
this.$customerSearchResultBlock = $(createOrderMap.customerSearchResultsBlock);
|
||||
this.router = new Router();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders customer search results
|
||||
*
|
||||
* @param foundCustomers
|
||||
*/
|
||||
renderSearchResults(foundCustomers) {
|
||||
if (foundCustomers.length === 0) {
|
||||
EventEmitter.emit(eventMap.customersNotFound);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Object.entries(foundCustomers).forEach(([customerId, customerResult]) => {
|
||||
const customer = {
|
||||
id: customerId,
|
||||
firstName: customerResult.firstname,
|
||||
lastName: customerResult.lastname,
|
||||
email: customerResult.email,
|
||||
birthday: customerResult.birthday !== '0000-00-00' ? customerResult.birthday : ' ',
|
||||
};
|
||||
|
||||
this.renderFoundCustomer(customer);
|
||||
});
|
||||
|
||||
// Show customer details in fancy box
|
||||
$(createOrderMap.customerDetailsBtn).fancybox({
|
||||
type: 'iframe',
|
||||
width: '90%',
|
||||
height: '90%',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Responsible for displaying customer block after customer select
|
||||
*
|
||||
* @param $targetedBtn
|
||||
*/
|
||||
displaySelectedCustomerBlock($targetedBtn) {
|
||||
this.showCheckoutHistoryBlock();
|
||||
|
||||
$targetedBtn.addClass('d-none');
|
||||
|
||||
const $customerCard = $targetedBtn.closest('.card');
|
||||
|
||||
$customerCard.addClass('border-success');
|
||||
$customerCard.find(createOrderMap.changeCustomerBtn).removeClass('d-none');
|
||||
|
||||
this.$container.find(createOrderMap.customerSearchRow).addClass('d-none');
|
||||
this.$container.find(createOrderMap.notSelectedCustomerSearchResults)
|
||||
.closest(createOrderMap.customerSearchResultColumn)
|
||||
.remove();
|
||||
|
||||
// Initial display of the customer, the cart is gonna be created then customer's carts
|
||||
// and orders are going to be fetched, but we can display the loading messages right now
|
||||
this.showLoadingCarts();
|
||||
this.showLoadingOrders();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows customer search block
|
||||
*/
|
||||
showCustomerSearch() {
|
||||
this.$container.find(createOrderMap.customerSearchRow).removeClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty the cart list and display a loading message.
|
||||
*/
|
||||
showLoadingCarts() {
|
||||
const $cartsTable = $(createOrderMap.customerCartsTable);
|
||||
$cartsTable.find('tbody').empty();
|
||||
this.renderLoading($cartsTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders customer carts list
|
||||
*
|
||||
* @param {Array} carts
|
||||
* @param {Int} currentCartId
|
||||
*/
|
||||
renderCarts(carts, currentCartId) {
|
||||
const $cartsTable = $(createOrderMap.customerCartsTable);
|
||||
const $cartsTableRowTemplate = $($(createOrderMap.customerCartsTableRowTemplate).html());
|
||||
|
||||
$cartsTable.find('tbody').empty();
|
||||
this.showCheckoutHistoryBlock();
|
||||
this.removeEmptyListRowFromTable($cartsTable);
|
||||
|
||||
Object.values(carts).forEach((cart) => {
|
||||
// do not render current cart
|
||||
if (cart.cartId === currentCartId) {
|
||||
// render 'No records found' warn if carts only contain current cart
|
||||
if (carts.length === 1) {
|
||||
this.renderEmptyList($cartsTable);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const $cartsTableRow = $cartsTableRowTemplate.clone();
|
||||
|
||||
$cartsTableRow.find(createOrderMap.cartIdField).text(cart.cartId);
|
||||
$cartsTableRow.find(createOrderMap.cartDateField).text(cart.creationDate);
|
||||
$cartsTableRow.find(createOrderMap.cartTotalField).text(cart.totalPrice);
|
||||
$cartsTableRow.find(createOrderMap.cartDetailsBtn).prop(
|
||||
'href',
|
||||
this.router.generate('admin_carts_view', {
|
||||
cartId: cart.cartId,
|
||||
liteDisplaying: 1,
|
||||
}),
|
||||
);
|
||||
|
||||
$cartsTableRow.find(createOrderMap.useCartBtn).data('cart-id', cart.cartId);
|
||||
|
||||
$cartsTable.find('thead').removeClass('d-none');
|
||||
$cartsTable.find('tbody').append($cartsTableRow);
|
||||
});
|
||||
|
||||
// Show cart details in fancy box
|
||||
$(createOrderMap.cartDetailsBtn).fancybox({
|
||||
type: 'iframe',
|
||||
width: '90%',
|
||||
height: '90%',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty the order list and display a loading message.
|
||||
*/
|
||||
showLoadingOrders() {
|
||||
const $ordersTable = $(createOrderMap.customerOrdersTable);
|
||||
$ordersTable.find('tbody').empty();
|
||||
this.renderLoading($ordersTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders customer orders list
|
||||
*
|
||||
* @param {Array} orders
|
||||
*/
|
||||
renderOrders(orders) {
|
||||
const $ordersTable = $(createOrderMap.customerOrdersTable);
|
||||
const $rowTemplate = $($(createOrderMap.customerOrdersTableRowTemplate).html());
|
||||
|
||||
$ordersTable.find('tbody').empty();
|
||||
this.showCheckoutHistoryBlock();
|
||||
this.removeEmptyListRowFromTable($ordersTable);
|
||||
|
||||
// render 'No records found' when list is empty
|
||||
if (orders.length === 0) {
|
||||
this.renderEmptyList($ordersTable);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Object.values(orders).forEach((order) => {
|
||||
const $template = $rowTemplate.clone();
|
||||
|
||||
$template.find(createOrderMap.orderIdField).text(order.orderId);
|
||||
$template.find(createOrderMap.orderDateField).text(order.orderPlacedDate);
|
||||
$template.find(createOrderMap.orderProductsField).text(order.orderProductsCount);
|
||||
$template.find(createOrderMap.orderTotalField).text(order.totalPaid);
|
||||
$template.find(createOrderMap.orderPaymentMethod).text(order.paymentMethodName);
|
||||
$template.find(createOrderMap.orderStatusField).text(order.orderStatus);
|
||||
$template.find(createOrderMap.orderDetailsBtn).prop(
|
||||
'href',
|
||||
this.router.generate('admin_orders_view', {
|
||||
orderId: order.orderId,
|
||||
liteDisplaying: 1,
|
||||
}),
|
||||
);
|
||||
|
||||
$template.find(createOrderMap.useOrderBtn).data('order-id', order.orderId);
|
||||
|
||||
$ordersTable.find('thead').removeClass('d-none');
|
||||
$ordersTable.find('tbody').append($template);
|
||||
});
|
||||
|
||||
// Show order details in fancy box
|
||||
$(createOrderMap.orderDetailsBtn).fancybox({
|
||||
type: 'iframe',
|
||||
width: '90%',
|
||||
height: '90%',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows empty result when customer is not found
|
||||
*/
|
||||
showNotFoundCustomers() {
|
||||
$(createOrderMap.customerSearchEmptyResultWarning).removeClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides not found customers warning
|
||||
*/
|
||||
hideNotFoundCustomers() {
|
||||
$(createOrderMap.customerSearchEmptyResultWarning).addClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides checkout history block where carts and orders are rendered
|
||||
*/
|
||||
hideCheckoutHistoryBlock() {
|
||||
$(createOrderMap.customerCheckoutHistory).addClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows searching customers notice during request
|
||||
*/
|
||||
showSearchingCustomers() {
|
||||
$(createOrderMap.customerSearchLoadingNotice).removeClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide searching notice
|
||||
*/
|
||||
hideSearchingCustomers() {
|
||||
$(createOrderMap.customerSearchLoadingNotice).addClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders 'No records' warning in list
|
||||
*
|
||||
* @param $table
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
renderEmptyList($table) {
|
||||
const $emptyTableRow = $($(createOrderMap.emptyListRowTemplate).html()).clone();
|
||||
$table.find('tbody').append($emptyTableRow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders 'Loading' message in list
|
||||
*
|
||||
* @param $table
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
renderLoading($table) {
|
||||
const $emptyTableRow = $($(createOrderMap.loadingListRowTemplate).html()).clone();
|
||||
$table.find('tbody').append($emptyTableRow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes empty list row in case it was rendered
|
||||
*/
|
||||
removeEmptyListRowFromTable($table) {
|
||||
$table.find(createOrderMap.emptyListRow).remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders customer information after search action
|
||||
*
|
||||
* @param {Object} customer
|
||||
*
|
||||
* @return {jQuery}
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
renderFoundCustomer(customer) {
|
||||
this.hideNotFoundCustomers();
|
||||
|
||||
const $customerSearchResultTemplate = $($(createOrderMap.customerSearchResultTemplate).html());
|
||||
const $template = $customerSearchResultTemplate.clone();
|
||||
|
||||
$template.find(createOrderMap.customerSearchResultName).text(`${customer.firstName} ${customer.lastName}`);
|
||||
$template.find(createOrderMap.customerSearchResultEmail).text(customer.email);
|
||||
$template.find(createOrderMap.customerSearchResultId).text(customer.id);
|
||||
$template.find(createOrderMap.customerSearchResultBirthday).text(customer.birthday);
|
||||
$template.find(createOrderMap.chooseCustomerBtn).data('customer-id', customer.id);
|
||||
$template.find(createOrderMap.customerDetailsBtn).prop(
|
||||
'href',
|
||||
this.router.generate('admin_customers_view', {
|
||||
customerId: customer.id,
|
||||
liteDisplaying: 1,
|
||||
}),
|
||||
);
|
||||
|
||||
return this.$customerSearchResultBlock.append($template);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows checkout history block where carts and orders are rendered
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
showCheckoutHistoryBlock() {
|
||||
$(createOrderMap.customerCheckoutHistory).removeClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears shown customers
|
||||
*/
|
||||
clearShownCustomers() {
|
||||
this.$customerSearchResultBlock.empty();
|
||||
}
|
||||
}
|
||||
77
iadmin/themes/new-theme/js/pages/order/create/event-map.js
Normal file
77
iadmin/themes/new-theme/js/pages/order/create/event-map.js
Normal file
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Encapsulates js events used in create order page
|
||||
*/
|
||||
export default {
|
||||
// when customer search action is done
|
||||
customerSearched: 'OrderCreateCustomerSearched',
|
||||
// when new customer is selected
|
||||
customerSelected: 'OrderCreateCustomerSelected',
|
||||
// when no customers found by search
|
||||
customersNotFound: 'OrderCreateSearchCustomerNotFound',
|
||||
// when new cart is loaded,
|
||||
// no matter if its empty, selected from carts list or duplicated by order.
|
||||
cartLoaded: 'OrderCreateCartLoaded',
|
||||
// when cart currency has been changed
|
||||
cartCurrencyChanged: 'OrderCreateCartCurrencyChanged',
|
||||
// when cart currency changing fails
|
||||
cartCurrencyChangeFailed: 'OrderCreateCartCurrencyChangeFailed',
|
||||
// when cart language has been changed
|
||||
cartLanguageChanged: 'OrderCreateCartLanguageChanged',
|
||||
// when cart addresses information has been changed
|
||||
cartAddressesChanged: 'OrderCreateCartAddressesChanged',
|
||||
// when cart delivery option has been changed
|
||||
cartDeliveryOptionChanged: 'OrderCreateCartDeliveryOptionChanged',
|
||||
// when cart delivery setting has been changed
|
||||
cartDeliverySettingChanged: 'OrderCreateCartDeliverySettingChangedSet',
|
||||
// when cart rules search action is done
|
||||
cartRuleSearched: 'OrderCreateCartRuleSearched',
|
||||
// when cart rule is removed from cart
|
||||
cartRuleRemoved: 'OrderCreateCartRuleRemoved',
|
||||
// when cart rule is added to cart
|
||||
cartRuleAdded: 'OrderCreateCartRuleAdded',
|
||||
// when cart rule cannot be added to cart
|
||||
cartRuleFailedToAdd: 'OrderCreateCartRuleFailedToAdd',
|
||||
// when product search action is done
|
||||
productSearched: 'OrderCreateProductSearched',
|
||||
// when product is added to cart
|
||||
productAddedToCart: 'OrderCreateProductAddedToCart',
|
||||
// when adding product to cart fails
|
||||
productAddToCartFailed: 'OrderCreateProductAddToCartFailed',
|
||||
// when product is removed from cart
|
||||
productRemovedFromCart: 'OrderCreateProductRemovedFromCart',
|
||||
// when product in cart price has been changed
|
||||
productPriceChanged: 'OrderCreateProductPriceChanged',
|
||||
// when product quantity in cart has been changed
|
||||
productQtyChanged: 'OrderCreateProductQtyChanged',
|
||||
// when changing product quantity in cart failed
|
||||
productQtyChangeFailed: 'OrderCreateProductQtyChangeFailed',
|
||||
// when order process email has been sent to customer
|
||||
processOrderEmailSent: 'OrderCreateProcessOrderEmailSent',
|
||||
// when order process email sending failed
|
||||
processOrderEmailFailed: 'OrderCreateProcessOrderEmailFailed',
|
||||
};
|
||||
422
iadmin/themes/new-theme/js/pages/order/create/product-manager.js
Normal file
422
iadmin/themes/new-theme/js/pages/order/create/product-manager.js
Normal file
@@ -0,0 +1,422 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
|
||||
import CartEditor from '@pages/order/create/cart-editor';
|
||||
import createOrderMap from '@pages/order/create/create-order-map';
|
||||
import eventMap from '@pages/order/create/event-map';
|
||||
import {EventEmitter} from '@components/event-emitter';
|
||||
import ProductRenderer from '@pages/order/create/product-renderer';
|
||||
import Router from '@components/router';
|
||||
|
||||
const {$} = window;
|
||||
|
||||
/**
|
||||
* Product component Object for "Create order" page
|
||||
*/
|
||||
export default class ProductManager {
|
||||
constructor() {
|
||||
this.products = [];
|
||||
this.selectedProduct = null;
|
||||
this.selectedCombinationId = null;
|
||||
this.activeSearchRequest = null;
|
||||
|
||||
this.productRenderer = new ProductRenderer();
|
||||
this.router = new Router();
|
||||
this.cartEditor = new CartEditor();
|
||||
|
||||
this.initListeners();
|
||||
|
||||
return {
|
||||
search: (searchPhrase) => this.search(searchPhrase),
|
||||
addProductToCart: (cartId) => this.cartEditor.addProduct(cartId, this.getProductData()),
|
||||
removeProductFromCart: (cartId, product) => this.cartEditor.removeProductFromCart(cartId, product),
|
||||
/* eslint-disable-next-line max-len */
|
||||
changeProductPrice: (cartId, customerId, updatedProduct) => this.cartEditor.changeProductPrice(cartId, customerId, updatedProduct),
|
||||
changeProductQty: (cartId, updatedProduct) => this.cartEditor.changeProductQty(cartId, updatedProduct),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes event listeners
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
initListeners() {
|
||||
$(createOrderMap.productSelect).on('change', (e) => this.initProductSelect(e));
|
||||
$(createOrderMap.combinationsSelect).on('change', (e) => this.initCombinationSelect(e));
|
||||
|
||||
this.onProductSearch();
|
||||
this.onAddProductToCart();
|
||||
this.onRemoveProductFromCart();
|
||||
this.onProductPriceChange();
|
||||
this.onProductQtyChange();
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for product search event
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
onProductSearch() {
|
||||
EventEmitter.on(eventMap.productSearched, (response) => {
|
||||
this.products = response.products;
|
||||
this.productRenderer.renderSearchResults(this.products);
|
||||
this.selectFirstResult();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for add product to cart event
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
onAddProductToCart() {
|
||||
// on success
|
||||
EventEmitter.on(eventMap.productAddedToCart, (cartInfo) => {
|
||||
this.productRenderer.cleanCartBlockAlerts();
|
||||
this.updateStockOnProductAdd();
|
||||
EventEmitter.emit(eventMap.cartLoaded, cartInfo);
|
||||
});
|
||||
|
||||
// on failure
|
||||
EventEmitter.on(eventMap.productAddToCartFailed, (errorMessage) => {
|
||||
this.productRenderer.renderCartBlockErrorAlert(errorMessage);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for remove product from cart event
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
onRemoveProductFromCart() {
|
||||
EventEmitter.on(eventMap.productRemovedFromCart, (data) => {
|
||||
this.updateStockOnProductRemove(data.product);
|
||||
EventEmitter.emit(eventMap.cartLoaded, data.cartInfo);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for product price change in cart event
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
onProductPriceChange() {
|
||||
EventEmitter.on(eventMap.productPriceChanged, (cartInfo) => {
|
||||
this.productRenderer.cleanCartBlockAlerts();
|
||||
EventEmitter.emit(eventMap.cartLoaded, cartInfo);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for product quantity change in cart success/failure event
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
onProductQtyChange() {
|
||||
const enableQtyInputs = () => {
|
||||
const inputsQty = document.querySelectorAll(createOrderMap.listedProductQtyInput);
|
||||
|
||||
inputsQty.forEach((inputQty) => {
|
||||
inputQty.disabled = false;
|
||||
});
|
||||
};
|
||||
|
||||
// on success
|
||||
EventEmitter.on(eventMap.productQtyChanged, (data) => {
|
||||
this.productRenderer.cleanCartBlockAlerts();
|
||||
this.updateStockOnQtyChange(data.product);
|
||||
|
||||
$(createOrderMap.createOrderButton).prop('disabled', false);
|
||||
EventEmitter.emit(eventMap.cartLoaded, data.cartInfo);
|
||||
|
||||
enableQtyInputs();
|
||||
});
|
||||
|
||||
// on failure
|
||||
EventEmitter.on(eventMap.productQtyChangeFailed, (e) => {
|
||||
this.productRenderer.renderCartBlockErrorAlert(e.responseJSON.message);
|
||||
$(createOrderMap.createOrderButton).prop('disabled', true);
|
||||
enableQtyInputs();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes product select
|
||||
*
|
||||
* @param event
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
initProductSelect(event) {
|
||||
const productId = Number(
|
||||
$(event.currentTarget)
|
||||
.find(':selected')
|
||||
.val(),
|
||||
);
|
||||
this.selectProduct(productId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes combination select
|
||||
*
|
||||
* @param event
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
initCombinationSelect(event) {
|
||||
const combinationId = Number(
|
||||
$(event.currentTarget)
|
||||
.find(':selected')
|
||||
.val(),
|
||||
);
|
||||
this.selectCombination(combinationId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for product
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
search(searchPhrase) {
|
||||
// Search only if the search phrase length is greater than 2 characters
|
||||
if (searchPhrase.length < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.productRenderer.renderSearching();
|
||||
if (this.activeSearchRequest !== null) {
|
||||
this.activeSearchRequest.abort();
|
||||
}
|
||||
|
||||
const params = {
|
||||
search_phrase: searchPhrase,
|
||||
};
|
||||
|
||||
if ($(createOrderMap.cartCurrencySelect).data('selectedCurrencyId') !== undefined) {
|
||||
params.currency_id = $(createOrderMap.cartCurrencySelect).data('selectedCurrencyId');
|
||||
}
|
||||
|
||||
const $searchRequest = $.get(this.router.generate('admin_orders_products_search'), params);
|
||||
this.activeSearchRequest = $searchRequest;
|
||||
|
||||
$searchRequest
|
||||
.then((response) => {
|
||||
EventEmitter.emit(eventMap.productSearched, response);
|
||||
})
|
||||
.catch((response) => {
|
||||
if (response.statusText === 'abort') {
|
||||
return;
|
||||
}
|
||||
|
||||
window.showErrorMessage(response.responseJSON.message);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate first result dataset after search
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
selectFirstResult() {
|
||||
this.unsetProduct();
|
||||
|
||||
if (this.products.length !== 0) {
|
||||
this.selectProduct(this.products[0].productId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles use case when product is selected from search results
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {Number} productId
|
||||
*/
|
||||
selectProduct(productId) {
|
||||
this.unsetCombination();
|
||||
|
||||
const selectedProduct = Object.values(this.products).find((product) => product.productId === productId);
|
||||
|
||||
if (selectedProduct) {
|
||||
this.selectedProduct = selectedProduct;
|
||||
}
|
||||
|
||||
this.productRenderer.renderProductMetadata(this.selectedProduct);
|
||||
// if product has combinations select the first else leave it null
|
||||
if (this.selectedProduct.combinations.length !== 0) {
|
||||
this.selectCombination(Object.keys(this.selectedProduct.combinations)[0]);
|
||||
}
|
||||
|
||||
return this.selectedProduct;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles use case when new combination is selected
|
||||
*
|
||||
* @param combinationId
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
selectCombination(combinationId) {
|
||||
const combination = this.selectedProduct.combinations[combinationId];
|
||||
|
||||
this.selectedCombinationId = combinationId;
|
||||
this.productRenderer.renderStock(
|
||||
$(createOrderMap.inStockCounter),
|
||||
$(createOrderMap.quantityInput),
|
||||
combination.stock,
|
||||
this.selectedProduct.availableOutOfStock || combination.stock <= 0,
|
||||
);
|
||||
|
||||
return combination;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the selected combination id to null
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
unsetCombination() {
|
||||
this.selectedCombinationId = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the selected product to null
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
unsetProduct() {
|
||||
this.selectedProduct = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves product data from product search result block fields
|
||||
*
|
||||
* @returns {Object}
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
getProductData() {
|
||||
const $fileInputs = $(createOrderMap.productCustomizationContainer).find('input[type="file"]');
|
||||
const formData = new FormData(document.querySelector(createOrderMap.productAddForm));
|
||||
const fileSizes = {};
|
||||
|
||||
// adds key value pairs {input name: file size} of each file in separate object
|
||||
// in case formData size exceeds server settings.
|
||||
$.each($fileInputs, (key, input) => {
|
||||
if (input.files.length !== 0) {
|
||||
fileSizes[$(input).data('customization-field-id')] = input.files[0].size;
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
product: formData,
|
||||
fileSizes,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the stock when the product is added to cart in "create new order" page
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
updateStockOnProductAdd() {
|
||||
const {productId} = this.selectedProduct;
|
||||
const attributeId = this.selectedCombinationId;
|
||||
const qty = -Number($(createOrderMap.quantityInput).val());
|
||||
|
||||
this.updateStock(productId, attributeId, qty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the stock when the product is removed from cart in Orders/"create new order page"
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
updateStockOnProductRemove(product) {
|
||||
const {productId, attributeId, qtyToRemove} = product;
|
||||
const qty = qtyToRemove;
|
||||
|
||||
this.updateStock(productId, attributeId, qty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the stock when the quantity of product is changed from cart in Orders/"create new order page"
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
updateStockOnQtyChange(product) {
|
||||
const {
|
||||
productId, attributeId, prevQty, newQty,
|
||||
} = product;
|
||||
const qty = prevQty - newQty;
|
||||
|
||||
this.updateStock(productId, attributeId, qty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the stock in products object and renders the new stock
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
updateStock(productId, attributeId, qty) {
|
||||
const productKeys = Object.keys(this.products);
|
||||
const productValues = Object.values(this.products);
|
||||
|
||||
for (let i = 0; i < productKeys.length; i += 1) {
|
||||
if (productValues[i].productId === productId) {
|
||||
const $template = this.productRenderer.cloneProductTemplate(productValues[i]);
|
||||
// Update the stock value in products object
|
||||
productValues[i].stock += qty;
|
||||
|
||||
// Update the stock also for combination */
|
||||
if (attributeId && attributeId > 0) {
|
||||
productValues[i].combinations[attributeId].stock += qty;
|
||||
}
|
||||
|
||||
// Render the new stock value
|
||||
if (this.selectedProduct.productId === productId) {
|
||||
if (this.selectedProduct.combinations.length === 0) {
|
||||
this.productRenderer.renderStock(
|
||||
$template.find(createOrderMap.listedProductQtyStock),
|
||||
$template.find(createOrderMap.listedProductQtyInput),
|
||||
productValues[i].stock,
|
||||
productValues[i].availableOutOfStock || productValues[i].availableStock <= 0,
|
||||
);
|
||||
} else if (attributeId && Number(this.selectedCombinationId) === Number(attributeId)) {
|
||||
this.productRenderer.renderStock(
|
||||
$template.find(createOrderMap.listedProductQtyStock),
|
||||
$template.find(createOrderMap.listedProductQtyInput),
|
||||
productValues[i].combinations[attributeId].stock,
|
||||
productValues[i].availableOutOfStock || productValues[i].availableStock <= 0,
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,500 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
|
||||
import createOrderMap from './create-order-map';
|
||||
|
||||
const {$} = window;
|
||||
|
||||
export default class ProductRenderer {
|
||||
constructor() {
|
||||
this.$productsTable = $(createOrderMap.productsTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders cart products list
|
||||
*
|
||||
* @param products
|
||||
*/
|
||||
renderList(products) {
|
||||
this.cleanProductsList();
|
||||
|
||||
if (products.length === 0) {
|
||||
this.hideProductsList();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Object.values(products).forEach((product) => {
|
||||
const $template = this.cloneProductTemplate(product);
|
||||
|
||||
let customizationId = 0;
|
||||
|
||||
if (product.customization) {
|
||||
({customizationId} = product.customization);
|
||||
this.renderListedProductCustomization(product.customization, $template);
|
||||
}
|
||||
|
||||
$template.find(createOrderMap.listedProductImageField).prop('src', product.imageLink);
|
||||
$template.find(createOrderMap.listedProductNameField).text(product.name);
|
||||
$template.find(createOrderMap.listedProductAttrField).text(product.attribute);
|
||||
$template.find(createOrderMap.listedProductReferenceField).text(product.reference);
|
||||
|
||||
if (product.gift !== true) {
|
||||
$template.find(createOrderMap.listedProductUnitPriceInput).val(product.unitPrice);
|
||||
$template.find(createOrderMap.listedProductUnitPriceInput).data('product-id', product.productId);
|
||||
$template.find(createOrderMap.listedProductUnitPriceInput).data('attribute-id', product.attributeId);
|
||||
$template.find(createOrderMap.listedProductUnitPriceInput).data('customization-id', customizationId);
|
||||
$template.find(createOrderMap.listedProductQtyInput).val(product.quantity);
|
||||
$template.find(createOrderMap.listedProductQtyInput).data('product-id', product.productId);
|
||||
$template.find(createOrderMap.listedProductQtyInput).data('attribute-id', product.attributeId);
|
||||
$template.find(createOrderMap.listedProductQtyInput).data('customization-id', customizationId);
|
||||
$template.find(createOrderMap.listedProductQtyInput).data('prev-qty', product.quantity);
|
||||
this.renderStock(
|
||||
$template.find(createOrderMap.listedProductQtyStock),
|
||||
$template.find(createOrderMap.listedProductQtyInput),
|
||||
product.availableStock,
|
||||
product.availableOutOfStock || (product.availableStock <= 0),
|
||||
);
|
||||
$template.find(createOrderMap.productTotalPriceField).text(product.price);
|
||||
$template.find(createOrderMap.productRemoveBtn).data('product-id', product.productId);
|
||||
$template.find(createOrderMap.productRemoveBtn).data('attribute-id', product.attributeId);
|
||||
$template.find(createOrderMap.productRemoveBtn).data('customization-id', customizationId);
|
||||
} else {
|
||||
$template.find(createOrderMap.listedProductGiftQty).text(product.quantity);
|
||||
}
|
||||
|
||||
this.$productsTable.find('tbody').append($template);
|
||||
});
|
||||
|
||||
this.showTaxWarning();
|
||||
this.showProductsList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders customization data for listed product
|
||||
*
|
||||
* @param customization
|
||||
* @param $productRowTemplate
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
renderListedProductCustomization(customization, $productRowTemplate) {
|
||||
const $customizedTextTemplate = $($(createOrderMap.listedProductCustomizedTextTemplate).html());
|
||||
const $customizedFileTemplate = $($(createOrderMap.listedProductCustomizedFileTemplate).html());
|
||||
|
||||
Object.values(customization.customizationFieldsData).forEach((customizedData) => {
|
||||
let $customizationTemplate = $customizedTextTemplate.clone();
|
||||
|
||||
if (customizedData.type === createOrderMap.productCustomizationFieldTypeFile) {
|
||||
$customizationTemplate = $customizedFileTemplate.clone();
|
||||
$customizationTemplate.find(createOrderMap.listedProductCustomizationName).text(customizedData.name);
|
||||
$customizationTemplate
|
||||
.find(`${createOrderMap.listedProductCustomizationValue} img`)
|
||||
.prop('src', customizedData.value);
|
||||
} else {
|
||||
$customizationTemplate.find(createOrderMap.listedProductCustomizationName).text(customizedData.name);
|
||||
$customizationTemplate.find(createOrderMap.listedProductCustomizationValue).text(customizedData.value);
|
||||
}
|
||||
|
||||
$productRowTemplate.find(createOrderMap.listedProductDefinition).append($customizationTemplate);
|
||||
});
|
||||
}
|
||||
|
||||
renderSearching() {
|
||||
this.reset();
|
||||
this.toggleSearchingNotice(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders cart products search results block
|
||||
*
|
||||
* @param foundProducts
|
||||
*/
|
||||
renderSearchResults(foundProducts) {
|
||||
this.cleanSearchResults();
|
||||
this.toggleSearchingNotice(false);
|
||||
if (foundProducts.length === 0) {
|
||||
this.showNotFound();
|
||||
this.hideTaxWarning();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.renderFoundProducts(foundProducts);
|
||||
|
||||
this.hideNotFound();
|
||||
this.showTaxWarning();
|
||||
this.showResultBlock();
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.cleanSearchResults();
|
||||
this.hideTaxWarning();
|
||||
this.hideResultBlock();
|
||||
this.toggleSearchingNotice(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders available fields related to selected product
|
||||
*
|
||||
* @param {object} product
|
||||
*/
|
||||
renderProductMetadata(product) {
|
||||
this.renderStock(
|
||||
$(createOrderMap.inStockCounter),
|
||||
$(createOrderMap.quantityInput),
|
||||
product.stock,
|
||||
product.availableOutOfStock || (product.stock <= 0),
|
||||
);
|
||||
this.renderCombinations(product.combinations);
|
||||
this.renderCustomizations(product.customizationFields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates stock text helper value
|
||||
*
|
||||
* @param {object} inputStockCounter Text Help with the stock counter
|
||||
* @param {object} inputQuantity Input for the stock
|
||||
* @param {number} stock Available stock for the product
|
||||
* @param {boolean} infiniteMax If the product order has no limits
|
||||
*/
|
||||
renderStock(inputStockCounter, inputQuantity, stock, infiniteMax) {
|
||||
inputStockCounter.text(stock);
|
||||
|
||||
if (!infiniteMax) {
|
||||
inputQuantity.attr('max', stock);
|
||||
} else {
|
||||
inputQuantity.removeAttr('max');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param product
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
cloneProductTemplate(product) {
|
||||
return product.gift === true
|
||||
? $($(createOrderMap.productsTableGiftRowTemplate).html()).clone()
|
||||
: $($(createOrderMap.productsTableRowTemplate).html()).clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders found products select
|
||||
*
|
||||
* @param foundProducts
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
renderFoundProducts(foundProducts) {
|
||||
Object.values(foundProducts).forEach((product) => {
|
||||
let {name} = product;
|
||||
|
||||
if (product.combinations.length === 0) {
|
||||
name += ` - ${product.formattedPrice}`;
|
||||
}
|
||||
|
||||
$(createOrderMap.productSelect).append(`<option value="${product.productId}">${name}</option>`);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans product search result fields
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
cleanSearchResults() {
|
||||
$(createOrderMap.productSelect).empty();
|
||||
$(createOrderMap.combinationsSelect).empty();
|
||||
$(createOrderMap.quantityInput).empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders combinations row with select options
|
||||
*
|
||||
* @param {Array} combinations
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
renderCombinations(combinations) {
|
||||
this.cleanCombinations();
|
||||
|
||||
if (combinations.length === 0) {
|
||||
this.hideCombinations();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Object.values(combinations).forEach((combination) => {
|
||||
$(createOrderMap.combinationsSelect).append(
|
||||
`<option
|
||||
value="${combination.attributeCombinationId}">
|
||||
${combination.attribute} - ${combination.formattedPrice}
|
||||
</option>`,
|
||||
);
|
||||
});
|
||||
|
||||
this.showCombinations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves weather to add customization fields to result block and adds them if needed
|
||||
*
|
||||
* @param customizationFields
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
renderCustomizations(customizationFields) {
|
||||
// represents customization field type "file".
|
||||
const fieldTypeFile = createOrderMap.productCustomizationFieldTypeFile;
|
||||
// represents customization field type "text".
|
||||
const fieldTypeText = createOrderMap.productCustomizationFieldTypeText;
|
||||
|
||||
this.cleanCustomizations();
|
||||
if (customizationFields.length === 0) {
|
||||
this.hideCustomizations();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const $customFieldsContainer = $(createOrderMap.productCustomFieldsContainer);
|
||||
const $fileInputTemplate = $($(createOrderMap.productCustomFileTemplate).html());
|
||||
const $textInputTemplate = $($(createOrderMap.productCustomTextTemplate).html());
|
||||
|
||||
const templateTypeMap = {
|
||||
[fieldTypeFile]: $fileInputTemplate,
|
||||
[fieldTypeText]: $textInputTemplate,
|
||||
};
|
||||
|
||||
Object.values(customizationFields).forEach((customField) => {
|
||||
const $template = templateTypeMap[customField.type].clone();
|
||||
|
||||
if (customField.type === fieldTypeFile) {
|
||||
$template.on('change', (e) => {
|
||||
const fileName = e.target.files[0].name;
|
||||
|
||||
$(e.target).next('.custom-file-label').html(fileName);
|
||||
});
|
||||
}
|
||||
|
||||
$template
|
||||
.find(createOrderMap.productCustomInput)
|
||||
.attr('name', `customizations[${customField.customizationFieldId}]`)
|
||||
.data('customization-field-id', customField.customizationFieldId);
|
||||
$template
|
||||
.find(createOrderMap.productCustomInputLabel)
|
||||
.attr('for', `customizations[${customField.customizationFieldId}]`)
|
||||
.text(customField.name);
|
||||
|
||||
if (customField.required === true) {
|
||||
$template.find(createOrderMap.requiredFieldMark).removeClass('d-none');
|
||||
}
|
||||
|
||||
$customFieldsContainer.append($template);
|
||||
});
|
||||
|
||||
this.showCustomizations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders error alert for cart block
|
||||
*
|
||||
* @param message
|
||||
*/
|
||||
renderCartBlockErrorAlert(message) {
|
||||
$(createOrderMap.cartErrorAlertText).text(message);
|
||||
this.showCartBlockError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans cart block alerts content and hides them
|
||||
*/
|
||||
cleanCartBlockAlerts() {
|
||||
$(createOrderMap.cartErrorAlertText).text('');
|
||||
this.hideCartBlockError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows error alert block of cart block
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
showCartBlockError() {
|
||||
$(createOrderMap.cartErrorAlertBlock).removeClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides error alert block of cart block
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
hideCartBlockError() {
|
||||
$(createOrderMap.cartErrorAlertBlock).addClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows product customization container
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
showCustomizations() {
|
||||
$(createOrderMap.productCustomizationContainer).removeClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides product customization container
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
hideCustomizations() {
|
||||
$(createOrderMap.productCustomizationContainer).addClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Empties customization fields container
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
cleanCustomizations() {
|
||||
$(createOrderMap.productCustomFieldsContainer).empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows result block
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
showResultBlock() {
|
||||
$(createOrderMap.productResultBlock).removeClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides result block
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
hideResultBlock() {
|
||||
$(createOrderMap.productResultBlock).addClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows products list
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
showProductsList() {
|
||||
this.$productsTable.removeClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides products list
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
hideProductsList() {
|
||||
this.$productsTable.addClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Empties products list
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
cleanProductsList() {
|
||||
this.$productsTable.find('tbody').empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Empties combinations select
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
cleanCombinations() {
|
||||
$(createOrderMap.combinationsSelect).empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows combinations row
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
showCombinations() {
|
||||
$(createOrderMap.combinationsRow).removeClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides combinations row
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
hideCombinations() {
|
||||
$(createOrderMap.combinationsRow).addClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows warning of tax included/excluded
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
showTaxWarning() {
|
||||
$(createOrderMap.productTaxWarning).removeClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides warning of tax included/excluded
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
hideTaxWarning() {
|
||||
$(createOrderMap.productTaxWarning).addClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows product not found warning
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
showNotFound() {
|
||||
$(createOrderMap.noProductsFoundWarning).removeClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides product not found warning
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
hideNotFound() {
|
||||
$(createOrderMap.noProductsFoundWarning).addClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles searching product notice
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
toggleSearchingNotice(visible) {
|
||||
$(createOrderMap.searchingProductsNotice).toggleClass('d-none', !visible);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
|
||||
import createOrderMap from './create-order-map';
|
||||
|
||||
const {$} = window;
|
||||
|
||||
/**
|
||||
* Manipulates UI of Shipping block in Order creation page
|
||||
*/
|
||||
export default class ShippingRenderer {
|
||||
constructor() {
|
||||
this.$container = $(createOrderMap.shippingBlock);
|
||||
this.$form = $(createOrderMap.shippingForm);
|
||||
this.$noCarrierBlock = $(createOrderMap.noCarrierBlock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} shipping
|
||||
* @param {Boolean} emptyCart
|
||||
*/
|
||||
render(shipping, emptyCart) {
|
||||
if (emptyCart) {
|
||||
this.hideContainer();
|
||||
} else if (shipping !== null) {
|
||||
this.displayForm(shipping);
|
||||
} else {
|
||||
this.displayNoCarriersWarning();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show form block with rendered delivery options instead of warning message
|
||||
*
|
||||
* @param shipping
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
displayForm(shipping) {
|
||||
this.hideNoCarrierBlock();
|
||||
this.renderDeliveryOptions(shipping.deliveryOptions, shipping.selectedCarrierId);
|
||||
this.renderTotalShipping(shipping.shippingPrice);
|
||||
this.renderFreeShippingSwitch(shipping.freeShipping);
|
||||
this.renderRecycledPackagingSwitch(shipping.recycledPackaging);
|
||||
this.renderGiftMessageField(shipping.giftMessage);
|
||||
this.renderGiftSwitch(shipping.gift);
|
||||
this.showForm();
|
||||
this.showContainer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders free shipping switch depending on free shipping value
|
||||
*
|
||||
* @param isFreeShipping
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
renderFreeShippingSwitch(isFreeShipping) {
|
||||
$(createOrderMap.freeShippingSwitch).each((key, input) => {
|
||||
if (input.value === '1') {
|
||||
input.checked = isFreeShipping;
|
||||
} else {
|
||||
input.checked = !isFreeShipping;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param useRecycledPackaging
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
renderRecycledPackagingSwitch(useRecycledPackaging) {
|
||||
$(createOrderMap.recycledPackagingSwitch).each((key, input) => {
|
||||
if (input.value === '1') {
|
||||
input.checked = useRecycledPackaging;
|
||||
} else {
|
||||
input.checked = !useRecycledPackaging;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isAGift
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
renderGiftSwitch(isAGift) {
|
||||
$(createOrderMap.isAGiftSwitch).each((key, input) => {
|
||||
if (input.value === '1') {
|
||||
input.checked = isAGift;
|
||||
} else {
|
||||
input.checked = !isAGift;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param giftMessage
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
renderGiftMessageField(giftMessage) {
|
||||
$(createOrderMap.giftMessageField).val(giftMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show warning message that no carriers are available and hide form block
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
displayNoCarriersWarning() {
|
||||
this.showContainer();
|
||||
this.hideForm();
|
||||
this.showNoCarrierBlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders delivery options selection block
|
||||
*
|
||||
* @param deliveryOptions
|
||||
* @param selectedVal
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
renderDeliveryOptions(deliveryOptions, selectedVal) {
|
||||
const $deliveryOptionSelect = $(createOrderMap.deliveryOptionSelect);
|
||||
$deliveryOptionSelect.empty();
|
||||
|
||||
Object.values(deliveryOptions).forEach((option) => {
|
||||
const deliveryOption = {
|
||||
value: option.carrierId,
|
||||
text: `${option.carrierName} - ${option.carrierDelay}`,
|
||||
};
|
||||
|
||||
if (selectedVal === deliveryOption.value) {
|
||||
deliveryOption.selected = 'selected';
|
||||
}
|
||||
|
||||
$deliveryOptionSelect.append($('<option>', deliveryOption));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders dynamic value of shipping price
|
||||
*
|
||||
* @param shippingPrice
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
renderTotalShipping(shippingPrice) {
|
||||
const $totalShippingField = $(createOrderMap.totalShippingField);
|
||||
$totalShippingField.empty();
|
||||
|
||||
$totalShippingField.append(shippingPrice);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show whole shipping container
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
showContainer() {
|
||||
this.$container.removeClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide whole shipping container
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
hideContainer() {
|
||||
this.$container.addClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show form block
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
showForm() {
|
||||
this.$form.removeClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide form block
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
hideForm() {
|
||||
this.$form.addClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show warning message block which warns that no carriers are available
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
showNoCarrierBlock() {
|
||||
this.$noCarrierBlock.removeClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide warning message block which warns that no carriers are available
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
hideNoCarrierBlock() {
|
||||
this.$noCarrierBlock.addClass('d-none');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
|
||||
import {EventEmitter} from '@components/event-emitter';
|
||||
import Router from '@components/router';
|
||||
import eventMap from './event-map';
|
||||
import SummaryRenderer from './summary-renderer';
|
||||
|
||||
const {$} = window;
|
||||
|
||||
/**
|
||||
* Manages summary block
|
||||
*/
|
||||
export default class SummaryManager {
|
||||
constructor() {
|
||||
this.router = new Router();
|
||||
this.summaryRenderer = new SummaryRenderer();
|
||||
this.initListeners();
|
||||
|
||||
return {
|
||||
sendProcessOrderEmail: (cartId) => this.sendProcessOrderEmail(cartId),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Inits event listeners
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
initListeners() {
|
||||
this.onProcessOrderEmailError();
|
||||
this.onProcessOrderEmailSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for process order email sending success event
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
onProcessOrderEmailSuccess() {
|
||||
EventEmitter.on(eventMap.processOrderEmailSent, (response) => {
|
||||
this.summaryRenderer.cleanAlerts();
|
||||
this.summaryRenderer.renderSuccessMessage(response.message);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for process order email failed event
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
onProcessOrderEmailError() {
|
||||
EventEmitter.on(eventMap.processOrderEmailFailed, (response) => {
|
||||
this.summaryRenderer.cleanAlerts();
|
||||
this.summaryRenderer.renderErrorMessage(response.responseJSON.message);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends email to customer with link of order processing
|
||||
*
|
||||
* @param {Number} cartId
|
||||
*/
|
||||
sendProcessOrderEmail(cartId) {
|
||||
$.post(this.router.generate('admin_orders_send_process_order_email'), {
|
||||
cartId,
|
||||
}).then((response) => EventEmitter.emit(eventMap.processOrderEmailSent, response)).catch((e) => {
|
||||
EventEmitter.emit(eventMap.processOrderEmailFailed, e);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
|
||||
import createOrderMap from './create-order-map';
|
||||
import {ValidateAddresses} from './address-validator';
|
||||
|
||||
const {$} = window;
|
||||
|
||||
/**
|
||||
* Responsible for summary block rendering
|
||||
*/
|
||||
export default class SummaryRenderer {
|
||||
constructor() {
|
||||
this.$totalProducts = $(createOrderMap.summaryTotalProducts);
|
||||
this.$totalDiscount = $(createOrderMap.summaryTotalDiscount);
|
||||
this.$totalShipping = $(createOrderMap.totalShippingField);
|
||||
this.$summaryTotalShipping = $(createOrderMap.summaryTotalShipping);
|
||||
this.$totalTaxes = $(createOrderMap.summaryTotalTaxes);
|
||||
this.$totalWithoutTax = $(createOrderMap.summaryTotalWithoutTax);
|
||||
this.$totalWithTax = $(createOrderMap.summaryTotalWithTax);
|
||||
this.$placeOrderCartIdField = $(createOrderMap.placeOrderCartIdField);
|
||||
this.$orderMessageField = $(createOrderMap.orderMessageField);
|
||||
this.$processOrderLink = $(createOrderMap.processOrderLinkTag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders summary block
|
||||
*
|
||||
* @param {Object} cartInfo
|
||||
*/
|
||||
render(cartInfo) {
|
||||
this.cleanSummary();
|
||||
const noProducts = cartInfo.products.length === 0;
|
||||
const noShippingOptions = cartInfo.shipping === null;
|
||||
const addressesAreValid = ValidateAddresses(cartInfo.addresses);
|
||||
|
||||
if (noProducts || noShippingOptions || !addressesAreValid) {
|
||||
this.hideSummaryBlock();
|
||||
|
||||
return;
|
||||
}
|
||||
const cartSummary = cartInfo.summary;
|
||||
this.$totalProducts.text(cartSummary.totalProductsPrice);
|
||||
this.$totalDiscount.text(cartSummary.totalDiscount);
|
||||
this.$summaryTotalShipping.text(cartSummary.totalShippingWithoutTaxes);
|
||||
this.$totalShipping.text(cartSummary.totalShippingPrice);
|
||||
this.$totalTaxes.text(cartSummary.totalTaxes);
|
||||
this.$totalWithoutTax.text(cartSummary.totalPriceWithoutTaxes);
|
||||
this.$totalWithTax.text(cartSummary.totalPriceWithTaxes);
|
||||
this.$processOrderLink.prop('href', cartSummary.processOrderLink);
|
||||
this.$orderMessageField.text(cartSummary.orderMessage);
|
||||
this.$placeOrderCartIdField.val(cartInfo.cartId);
|
||||
|
||||
this.showSummaryBlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders summary success message
|
||||
*
|
||||
* @param message
|
||||
*/
|
||||
renderSuccessMessage(message) {
|
||||
$(createOrderMap.summarySuccessAlertText).text(message);
|
||||
this.showSummarySuccessAlertBlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders summary error message
|
||||
*
|
||||
* @param message
|
||||
*/
|
||||
renderErrorMessage(message) {
|
||||
$(createOrderMap.summaryErrorAlertText).text(message);
|
||||
this.showSummaryErrorAlertBlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans content of success/error summary alerts and hides them
|
||||
*/
|
||||
cleanAlerts() {
|
||||
$(createOrderMap.summarySuccessAlertText).text('');
|
||||
$(createOrderMap.summaryErrorAlertText).text('');
|
||||
this.hideSummarySuccessAlertBlock();
|
||||
this.hideSummaryErrorAlertBlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows summary block
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
showSummaryBlock() {
|
||||
$(createOrderMap.summaryBlock).removeClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides summary block
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
hideSummaryBlock() {
|
||||
$(createOrderMap.summaryBlock).addClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows error alert of summary block
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
showSummaryErrorAlertBlock() {
|
||||
$(createOrderMap.summaryErrorAlertBlock).removeClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides error alert of summary block
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
hideSummaryErrorAlertBlock() {
|
||||
$(createOrderMap.summaryErrorAlertBlock).addClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows success alert of summary block
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
showSummarySuccessAlertBlock() {
|
||||
$(createOrderMap.summarySuccessAlertBlock).removeClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides success alert of summary block
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
hideSummarySuccessAlertBlock() {
|
||||
$(createOrderMap.summarySuccessAlertBlock).addClass('d-none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Empties cart summary fields
|
||||
*/
|
||||
cleanSummary() {
|
||||
this.$totalProducts.empty();
|
||||
this.$totalDiscount.empty();
|
||||
this.$totalShipping.empty();
|
||||
this.$totalTaxes.empty();
|
||||
this.$totalWithoutTax.empty();
|
||||
this.$totalWithTax.empty();
|
||||
this.$processOrderLink.prop('href', '');
|
||||
this.$orderMessageField.text('');
|
||||
this.cleanAlerts();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user