first commit

This commit is contained in:
2024-11-05 12:22:50 +01:00
commit e5682a3912
19641 changed files with 2948548 additions and 0 deletions

View File

@@ -0,0 +1,41 @@
/**
* 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)
*/
/**
* Defines all selectors that are used in customers address add/edit form.
*/
export default {
addressEmailInput: '#customer_address_customer_email',
addressFirstnameInput: '#customer_address_first_name',
addressLastnameInput: '#customer_address_last_name',
addressCompanyInput: '#customer_address_company',
addressCountrySelect: '#customer_address_id_country',
addressStateSelect: '#customer_address_id_state',
addressStateBlock: '.js-address-state-select',
addressDniInput: '#customer_address_dni',
addressDniInputLabel: 'label[for="customer_address_dni"]',
addressPostcodeInput: '#customer_address_postcode',
addressPostcodeInputLabel: 'label[for="customer_address_postcode"]',
};

View File

@@ -0,0 +1,58 @@
/**
* 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 AutocompleteWithEmail from '@components/form/autocomplete-with-email';
import CountryStateSelectionToggler from '@components/country-state-selection-toggler';
import CountryDniRequiredToggler from '@components/country-dni-required-toggler';
import CountryPostcodeRequiredToggler from '@components/country-postcode-required-toggler';
import addressFormMap from './address-form-map';
const {$} = window;
$(document).ready(() => {
new AutocompleteWithEmail(
addressFormMap.addressEmailInput,
{
firstName: addressFormMap.addressFirstnameInput,
lastName: addressFormMap.addressLastnameInput,
company: addressFormMap.addressCompanyInput,
},
);
new CountryStateSelectionToggler(
addressFormMap.addressCountrySelect,
addressFormMap.addressStateSelect,
addressFormMap.addressStateBlock,
);
new CountryDniRequiredToggler(
addressFormMap.addressCountrySelect,
addressFormMap.addressDniInput,
addressFormMap.addressDniInputLabel,
);
new CountryPostcodeRequiredToggler(
addressFormMap.addressCountrySelect,
addressFormMap.addressPostcodeInput,
addressFormMap.addressPostcodeInputLabel,
);
});

View File

@@ -0,0 +1,53 @@
/**
* 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 Grid from '@components/grid/grid';
import FiltersResetExtension from '@components/grid/extension/filters-reset-extension';
import SortingExtension from '@components/grid/extension/sorting-extension';
import ExportToSqlManagerExtension from '@components/grid/extension/export-to-sql-manager-extension';
import ReloadListExtension from '@components/grid/extension/reload-list-extension';
import BulkActionCheckboxExtension from '@components/grid/extension/bulk-action-checkbox-extension';
import SubmitBulkExtension from '@components/grid/extension/submit-bulk-action-extension';
import SubmitRowActionExtension from '@components/grid/extension/action/row/submit-row-action-extension';
import LinkRowActionExtension from '@components/grid/extension/link-row-action-extension';
import ChoiceTable from '@components/choice-table';
const {$} = window;
$(() => {
const addressGrid = new Grid('address');
addressGrid.addExtension(new FiltersResetExtension());
addressGrid.addExtension(new SortingExtension());
addressGrid.addExtension(new ExportToSqlManagerExtension());
addressGrid.addExtension(new ReloadListExtension());
addressGrid.addExtension(new BulkActionCheckboxExtension());
addressGrid.addExtension(new SubmitBulkExtension());
addressGrid.addExtension(new SubmitRowActionExtension());
addressGrid.addExtension(new LinkRowActionExtension());
// needed for address required fields form
new ChoiceTable();
});

View File

@@ -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)
*/
import Grid from '@components/grid/grid';
import FiltersResetExtension from '@components/grid/extension/filters-reset-extension';
import SortingExtension from '@components/grid/extension/sorting-extension';
import ExportToSqlManagerExtension from '@components/grid/extension/export-to-sql-manager-extension';
import ReloadListExtension from '@components/grid/extension/reload-list-extension';
import BulkActionCheckboxExtension from '@components/grid/extension/bulk-action-checkbox-extension';
import SubmitBulkExtension from '@components/grid/extension/submit-bulk-action-extension';
import SubmitRowActionExtension from '@components/grid/extension/action/row/submit-row-action-extension';
import LinkRowActionExtension from '@components/grid/extension/link-row-action-extension';
import TranslatableInput from '@components/translatable-input';
const {$} = window;
$(() => {
const attachmentGrid = new Grid('attachment');
attachmentGrid.addExtension(new FiltersResetExtension());
attachmentGrid.addExtension(new SortingExtension());
attachmentGrid.addExtension(new ExportToSqlManagerExtension());
attachmentGrid.addExtension(new ReloadListExtension());
attachmentGrid.addExtension(new BulkActionCheckboxExtension());
attachmentGrid.addExtension(new SubmitBulkExtension());
attachmentGrid.addExtension(new SubmitRowActionExtension());
attachmentGrid.addExtension(new LinkRowActionExtension());
new TranslatableInput();
});

View File

@@ -0,0 +1,57 @@
/**
* 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 Grid from '@components/grid/grid';
import SortingExtension from '@components/grid/extension/sorting-extension';
import FiltersResetExtension from '@components/grid/extension/filters-reset-extension';
import ReloadListActionExtension from '@components/grid/extension/reload-list-extension';
import SubmitRowActionExtension from '@components/grid/extension/action/row/submit-row-action-extension';
import SubmitBulkExtension from '@components/grid/extension/submit-bulk-action-extension';
import BulkActionCheckboxExtension from '@components/grid/extension/bulk-action-checkbox-extension';
import ExportToSqlManagerExtension from '@components/grid/extension/export-to-sql-manager-extension';
import FiltersSubmitButtonEnablerExtension
from '@components/grid/extension/filters-submit-button-enabler-extension';
import ShowcaseCard from '@components/showcase-card/showcase-card';
import ShowcaseCardCloseExtension from '@components/showcase-card/extension/showcase-card-close-extension';
import PositionExtension from '@components/grid/extension/position-extension';
const {$} = window;
$(() => {
const grid = new Grid('attribute_group');
grid.addExtension(new ExportToSqlManagerExtension());
grid.addExtension(new ReloadListActionExtension());
grid.addExtension(new SortingExtension());
grid.addExtension(new FiltersResetExtension());
grid.addExtension(new SubmitRowActionExtension());
grid.addExtension(new SubmitBulkExtension());
grid.addExtension(new BulkActionCheckboxExtension());
grid.addExtension(new FiltersSubmitButtonEnablerExtension());
grid.addExtension(new PositionExtension());
const showcaseCard = new ShowcaseCard('attributesShowcaseCard');
showcaseCard.addExtension(new ShowcaseCardCloseExtension());
});

View File

@@ -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)
*/
import Grid from '@components/grid/grid';
import SortingExtension from '@components/grid/extension/sorting-extension';
import FiltersResetExtension from '@components/grid/extension/filters-reset-extension';
import ReloadListActionExtension from '@components/grid/extension/reload-list-extension';
import SubmitRowActionExtension from '@components/grid/extension/action/row/submit-row-action-extension';
import SubmitBulkExtension from '@components/grid/extension/submit-bulk-action-extension';
import BulkActionCheckboxExtension from '@components/grid/extension/bulk-action-checkbox-extension';
import ExportToSqlManagerExtension from '@components/grid/extension/export-to-sql-manager-extension';
import FiltersSubmitButtonEnablerExtension
from '@components/grid/extension/filters-submit-button-enabler-extension';
import PositionExtension from '@components/grid/extension/position-extension';
const {$} = window;
$(() => {
const grid = new Grid('attribute');
grid.addExtension(new ExportToSqlManagerExtension());
grid.addExtension(new ReloadListActionExtension());
grid.addExtension(new SortingExtension());
grid.addExtension(new FiltersResetExtension());
grid.addExtension(new SubmitRowActionExtension());
grid.addExtension(new SubmitBulkExtension());
grid.addExtension(new BulkActionCheckboxExtension());
grid.addExtension(new FiltersSubmitButtonEnablerExtension());
grid.addExtension(new PositionExtension());
});

View File

@@ -0,0 +1,44 @@
/**
* 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 Grid from '@components/grid/grid';
import BulkActionCheckboxExtension from '@components/grid/extension/bulk-action-checkbox-extension';
import SubmitBulkExtension from '@components/grid/extension/submit-bulk-action-extension';
import LinkRowActionExtension from '@components/grid/extension/link-row-action-extension';
import SubmitRowActionExtension from '@components/grid/extension/action/row/submit-row-action-extension';
import FiltersSubmitButtonEnablerExtension
from '@components/grid/extension/filters-submit-button-enabler-extension';
const {$} = window;
$(() => {
const backupGrid = new Grid('backup');
backupGrid.addExtension(new BulkActionCheckboxExtension());
backupGrid.addExtension(new SubmitBulkExtension());
backupGrid.addExtension(new LinkRowActionExtension());
backupGrid.addExtension(new SubmitRowActionExtension());
backupGrid.addExtension(new FiltersSubmitButtonEnablerExtension());
});

View File

@@ -0,0 +1,61 @@
/**
* 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 ShowcaseCard from '@components/showcase-card/showcase-card';
import ShowcaseCardCloseExtension from '@components/showcase-card/extension/showcase-card-close-extension';
import Grid from '@components/grid/grid';
import SortingExtension from '@components/grid/extension/sorting-extension';
import FiltersResetExtension from '@components/grid/extension/filters-reset-extension';
import ReloadListActionExtension from '@components/grid/extension/reload-list-extension';
import ColumnTogglingExtension from '@components/grid/extension/column-toggling-extension';
import SubmitRowActionExtension from '@components/grid/extension/action/row/submit-row-action-extension';
import SubmitBulkExtension from '@components/grid/extension/submit-bulk-action-extension';
import BulkActionCheckboxExtension from '@components/grid/extension/bulk-action-checkbox-extension';
import ExportToSqlManagerExtension from '@components/grid/extension/export-to-sql-manager-extension';
import FiltersSubmitButtonEnablerExtension
from '@components/grid/extension/filters-submit-button-enabler-extension';
import LinkRowActionExtension from '@components/grid/extension/link-row-action-extension';
import PositionExtension from '@components/grid/extension/position-extension';
const {$} = window;
$(() => {
const carrierGrid = new Grid('carrier');
carrierGrid.addExtension(new SortingExtension());
carrierGrid.addExtension(new ReloadListActionExtension());
carrierGrid.addExtension(new PositionExtension());
carrierGrid.addExtension(new FiltersSubmitButtonEnablerExtension());
carrierGrid.addExtension(new FiltersResetExtension());
carrierGrid.addExtension(new ExportToSqlManagerExtension());
carrierGrid.addExtension(new ColumnTogglingExtension());
carrierGrid.addExtension(new LinkRowActionExtension());
carrierGrid.addExtension(new SubmitRowActionExtension());
carrierGrid.addExtension(new SubmitBulkExtension());
carrierGrid.addExtension(new BulkActionCheckboxExtension());
const showcaseCard = new ShowcaseCard('carriersShowcaseCard');
showcaseCard.addExtension(new ShowcaseCardCloseExtension());
});

View File

@@ -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)
*/
import Grid from '@components/grid/grid';
import SortingExtension from '@components/grid/extension/sorting-extension';
import ColumnTogglingExtension from '@components/grid/extension/column-toggling-extension';
import FiltersResetExtension from '@components/grid/extension/filters-reset-extension';
import ReloadListActionExtension from '@components/grid/extension/reload-list-extension';
import SubmitRowActionExtension from '@components/grid/extension/action/row/submit-row-action-extension';
import SubmitBulkExtension from '@components/grid/extension/submit-bulk-action-extension';
import BulkActionCheckboxExtension from '@components/grid/extension/bulk-action-checkbox-extension';
import ExportToSqlManagerExtension from '@components/grid/extension/export-to-sql-manager-extension';
import FiltersSubmitButtonEnablerExtension
from '@components/grid/extension/filters-submit-button-enabler-extension';
const {$} = window;
$(() => {
const cartRuleGrid = new Grid('cart_rule');
cartRuleGrid.addExtension(new ExportToSqlManagerExtension());
cartRuleGrid.addExtension(new ReloadListActionExtension());
cartRuleGrid.addExtension(new SortingExtension());
cartRuleGrid.addExtension(new FiltersResetExtension());
cartRuleGrid.addExtension(new ColumnTogglingExtension());
cartRuleGrid.addExtension(new SubmitRowActionExtension());
cartRuleGrid.addExtension(new SubmitBulkExtension());
cartRuleGrid.addExtension(new BulkActionCheckboxExtension());
cartRuleGrid.addExtension(new FiltersSubmitButtonEnablerExtension());
});

View File

@@ -0,0 +1,37 @@
/**
* 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)
*/
/**
* Defines all selectors that are used in catalog price rule add/edit form.
*/
export default {
// mapping for price-field-availability-handler
initialPrice: '#catalog_price_rule_leave_initial_price',
price: '#catalog_price_rule_price',
// mapping for include-tax-field-visibility-handler
reductionType: '.js-reduction-type-source',
includeTax: '.js-include-tax-target',
};

View File

@@ -0,0 +1,53 @@
/**
* 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)
*/
const {$} = window;
/**
* Shows/hides 'include_tax' field depending from 'reduction_type' field value
*/
export default class IncludeTaxFieldVisibilityHandler {
constructor(sourceSelector, targetSelector) {
this.$sourceSelector = $(sourceSelector);
this.$targetSelector = $(targetSelector);
this.handle();
this.$sourceSelector.on('change', () => this.handle());
return {};
}
/**
* When source value is 'percentage', target field is shown, else hidden
*
* @private
*/
handle() {
if (this.$sourceSelector.val() === 'percentage') {
this.$targetSelector.fadeOut();
} else {
this.$targetSelector.fadeIn();
}
}
}

View File

@@ -0,0 +1,44 @@
/**
* 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 PriceFieldAvailabilityHandler
from './price-field-availability-handler';
import IncludeTaxFieldVisibilityHandler
from './include-tax-field-visibility-handler';
import CatalogPriceRuleFormMap from './catalog-price-rule-form-map';
const {$} = window;
$(() => {
new PriceFieldAvailabilityHandler(
CatalogPriceRuleFormMap.initialPrice,
CatalogPriceRuleFormMap.price,
);
new IncludeTaxFieldVisibilityHandler(
CatalogPriceRuleFormMap.reductionType,
CatalogPriceRuleFormMap.includeTax,
);
});

View File

@@ -0,0 +1,51 @@
/**
* 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)
*/
const {$} = window;
/**
* Enables/disables 'price' field depending from 'leave_initial_price' field checkbox value
*/
export default class PriceFieldAvailabilityHandler {
constructor(checkboxSelector, targetSelector) {
this.$sourceSelector = $(checkboxSelector);
this.$targetSelector = $(targetSelector);
this.handle();
this.$sourceSelector.on('change', () => this.handle());
return {};
}
/**
* When checkbox value is 1, target field is disabled, else enabled
*
* @private
*/
handle() {
const checkboxVal = this.$sourceSelector.is(':checked');
this.$targetSelector.prop('disabled', checkboxVal);
}
}

View File

@@ -0,0 +1,50 @@
/**
* 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 Grid from '@components/grid/grid';
import SortingExtension from '@components/grid/extension/sorting-extension';
import FiltersResetExtension from '@components/grid/extension/filters-reset-extension';
import ReloadListActionExtension from '@components/grid/extension/reload-list-extension';
import SubmitRowActionExtension from '@components/grid/extension/action/row/submit-row-action-extension';
import SubmitBulkExtension from '@components/grid/extension/submit-bulk-action-extension';
import BulkActionCheckboxExtension from '@components/grid/extension/bulk-action-checkbox-extension';
import ExportToSqlManagerExtension from '@components/grid/extension/export-to-sql-manager-extension';
import FiltersSubmitButtonEnablerExtension
from '@components/grid/extension/filters-submit-button-enabler-extension';
const {$} = window;
$(() => {
const priceRuleGrid = new Grid('catalog_price_rule');
priceRuleGrid.addExtension(new ExportToSqlManagerExtension());
priceRuleGrid.addExtension(new ReloadListActionExtension());
priceRuleGrid.addExtension(new SortingExtension());
priceRuleGrid.addExtension(new FiltersResetExtension());
priceRuleGrid.addExtension(new SubmitRowActionExtension());
priceRuleGrid.addExtension(new SubmitBulkExtension());
priceRuleGrid.addExtension(new BulkActionCheckboxExtension());
priceRuleGrid.addExtension(new FiltersSubmitButtonEnablerExtension());
});

View File

@@ -0,0 +1,32 @@
/**
* 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 SpecificPriceFormHandler from './specific-price-form-handler';
const {$} = window;
$(() => {
new SpecificPriceFormHandler();
});

View File

@@ -0,0 +1,512 @@
/**
* 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)
*/
const {$} = window;
class SpecificPriceFormHandler {
constructor() {
this.prefixCreateForm = 'form_step2_specific_price_';
this.prefixEditForm = 'form_modal_';
this.editModalIsOpen = false;
this.$createPriceFormDefaultValues = {};
this.storePriceFormDefaultValues();
this.loadAndDisplayExistingSpecificPricesList();
this.configureAddPriceFormBehavior();
this.configureEditPriceModalBehavior();
this.configureDeletePriceButtonsBehavior();
this.configureMultipleModalsBehavior();
}
/**
* @private
*/
loadAndDisplayExistingSpecificPricesList() {
const listContainer = $('#js-specific-price-list');
const url = listContainer.data('listingUrl').replace(/list\/\d+/, `list/${this.getProductId()}`);
$.ajax({
type: 'GET',
url,
})
.done((specificPrices) => {
const tbody = listContainer.find('tbody');
tbody.find('tr').remove();
if (specificPrices.length > 0) {
listContainer.removeClass('hide');
} else {
listContainer.addClass('hide');
}
const specificPricesList = this.renderSpecificPricesListingAsHtml(specificPrices);
tbody.append(specificPricesList);
});
}
/**
* @param array specificPrices
*
* @returns string
*
* @private
*/
renderSpecificPricesListingAsHtml(specificPrices) {
let specificPricesList = '';
const self = this;
$.each(specificPrices, (index, specificPrice) => {
const deleteUrl = $('#js-specific-price-list')
.attr('data-action-delete')
.replace(/delete\/\d+/, `delete/${specificPrice.id_specific_price}`);
const row = self.renderSpecificPriceRow(specificPrice, deleteUrl);
specificPricesList += row;
});
return specificPricesList;
}
/**
* @param Object specificPrice
* @param string deleteUrl
*
* @returns string
*
* @private
*/
renderSpecificPriceRow(specificPrice, deleteUrl) {
const specificPriceId = specificPrice.id_specific_price;
/* eslint-disable max-len */
const canDelete = specificPrice.can_delete
? `<a href="${deleteUrl}" class="js-delete delete btn tooltip-link delete pl-0 pr-0"><i class="material-icons">delete</i></a>`
: '';
const canEdit = specificPrice.can_edit
? `<a href="#" data-specific-price-id="${specificPriceId}" class="js-edit edit btn tooltip-link delete pl-0 pr-0"><i class="material-icons">edit</i></a>`
: '';
const row = `<tr> \
<td>${specificPrice.id_specific_price}</td> \
<td>${specificPrice.rule_name}</td> \
<td>${specificPrice.attributes_name}</td> \
<td>${specificPrice.currency}</td> \
<td>${specificPrice.country}</td> \
<td>${specificPrice.group}</td> \
<td>${specificPrice.customer}</td> \
<td>${specificPrice.fixed_price}</td> \
<td>${specificPrice.impact}</td> \
<td>${specificPrice.period}</td> \
<td>${specificPrice.from_quantity}</td> \
<td>${canDelete}</td> \
<td>${canEdit}</td></tr>`;
/* eslint-enable max-len */
return row;
}
/**
* @private
*/
configureAddPriceFormBehavior() {
const usePrefixForCreate = true;
const selectorPrefix = this.getPrefixSelector(usePrefixForCreate);
$('#specific_price_form .js-cancel').click(() => {
this.resetCreatePriceFormDefaultValues();
$('#specific_price_form').collapse('hide');
});
$('#specific_price_form .js-save').on(
'click',
() => this.submitCreatePriceForm(),
);
$('#js-open-create-specific-price-form').on(
'click',
() => this.loadAndFillOptionsForSelectCombinationInput(usePrefixForCreate),
);
$(`${selectorPrefix}leave_bprice`).on(
'click',
() => this.enableSpecificPriceFieldIfEligible(usePrefixForCreate),
);
$(`${selectorPrefix}sp_reduction_type`).on(
'change',
() => this.enableSpecificPriceTaxFieldIfEligible(usePrefixForCreate),
);
}
/**
* @private
*/
configureEditPriceFormInsideModalBehavior() {
const usePrefixForCreate = false;
const selectorPrefix = this.getPrefixSelector(usePrefixForCreate);
$('#form_modal_cancel').click(() => this.closeEditPriceModalAndRemoveForm());
$('#form_modal_close').click(() => this.closeEditPriceModalAndRemoveForm());
$('#form_modal_save').click(() => this.submitEditPriceForm());
this.loadAndFillOptionsForSelectCombinationInput(usePrefixForCreate);
$(`${selectorPrefix}leave_bprice`).on('click', () => this.enableSpecificPriceFieldIfEligible(usePrefixForCreate));
$(`${selectorPrefix}sp_reduction_type`).on(
'change',
() => this.enableSpecificPriceTaxFieldIfEligible(usePrefixForCreate),
);
this.reinitializeDatePickers();
this.initializeLeaveBPriceField(usePrefixForCreate);
this.enableSpecificPriceTaxFieldIfEligible(usePrefixForCreate);
}
/**
* @private
*/
reinitializeDatePickers() {
$('.datepicker input').datetimepicker({format: 'YYYY-MM-DD'});
}
/**
* @param boolean usePrefixForCreate
*
* @private
*/
initializeLeaveBPriceField(usePrefixForCreate) {
const selectorPrefix = this.getPrefixSelector(usePrefixForCreate);
if ($(`${selectorPrefix}sp_price`).val() !== '') {
$(`${selectorPrefix}sp_price`).prop('disabled', false);
$(`${selectorPrefix}leave_bprice`).prop('checked', false);
}
}
/**
* @private
*/
configureEditPriceModalBehavior() {
$(document).on('click', '#js-specific-price-list .js-edit', (event) => {
event.preventDefault();
const specificPriceId = $(event.currentTarget).data('specificPriceId');
this.openEditPriceModalAndLoadForm(specificPriceId);
});
}
/**
* @private
*/
configureDeletePriceButtonsBehavior() {
$(document).on('click', '#js-specific-price-list .js-delete', (event) => {
event.preventDefault();
this.deleteSpecificPrice(event.currentTarget);
});
}
configureMultipleModalsBehavior() {
$('.modal').on('hidden.bs.modal', () => {
if (this.editModalIsOpen) {
$('body').addClass('modal-open');
}
});
}
/**
* @private
*/
submitCreatePriceForm() {
const url = $('#specific_price_form').attr('data-action');
const data = $('#specific_price_form input, #specific_price_form select, #form_id_product').serialize();
$('#specific_price_form .js-save').attr('disabled', 'disabled');
$.ajax({
type: 'POST',
url,
data,
}).done(() => {
window.showSuccessMessage(window.translate_javascripts['Form update success']);
this.resetCreatePriceFormDefaultValues();
$('#specific_price_form').collapse('hide');
this.loadAndDisplayExistingSpecificPricesList();
$('#specific_price_form .js-save').removeAttr('disabled');
}).fail((errors) => {
window.showErrorMessage(errors.responseJSON);
$('#specific_price_form .js-save').removeAttr('disabled');
});
}
/**
* @private
*/
submitEditPriceForm() {
const baseUrl = $('#edit-specific-price-modal-form').attr('data-action');
const specificPriceId = $('#edit-specific-price-modal-form').data('specificPriceId');
const url = baseUrl.replace(/update\/\d+/, `update/${specificPriceId}`);
/* eslint-disable-next-line max-len */
const data = $('#edit-specific-price-modal-form input, #edit-specific-price-modal-form select, #form_id_product').serialize();
$('#edit-specific-price-modal-form .js-save').attr('disabled', 'disabled');
$.ajax({
type: 'POST',
url,
data,
})
.done(() => {
window.showSuccessMessage(window.translate_javascripts['Form update success']);
this.closeEditPriceModalAndRemoveForm();
this.loadAndDisplayExistingSpecificPricesList();
$('#edit-specific-price-modal-form .js-save').removeAttr('disabled');
})
.fail((errors) => {
window.showErrorMessage(errors.responseJSON);
$('#edit-specific-price-modal-form .js-save').removeAttr('disabled');
});
}
/**
* @param string clickedLink selector
*
* @private
*/
deleteSpecificPrice(clickedLink) {
window.modalConfirmation.create(
window.translate_javascripts['Are you sure you want to delete this item?'],
null,
{
onContinue: () => {
const url = $(clickedLink).attr('href');
$(clickedLink).attr('disabled', 'disabled');
$.ajax({
type: 'GET',
url,
}).done((response) => {
this.loadAndDisplayExistingSpecificPricesList();
window.showSuccessMessage(response);
$(clickedLink).removeAttr('disabled');
}).fail((errors) => {
window.showErrorMessage(errors.responseJSON);
$(clickedLink).removeAttr('disabled');
});
},
},
).show();
}
/**
* Store 'add specific price' form values
* for future usage
*
* @private
*/
storePriceFormDefaultValues() {
const storage = this.$createPriceFormDefaultValues;
$('#specific_price_form').find('select,input').each((index, value) => {
storage[$(value).attr('id')] = $(value).val();
});
$('#specific_price_form').find('input:checkbox').each((index, value) => {
storage[$(value).attr('id')] = $(value).prop('checked');
});
this.$createPriceFormDefaultValues = storage;
}
/**
* @param boolean usePrefixForCreate
*
* @private
*/
loadAndFillOptionsForSelectCombinationInput(usePrefixForCreate) {
const selectorPrefix = this.getPrefixSelector(usePrefixForCreate);
const inputField = $(`${selectorPrefix}sp_id_product_attribute`);
const url = inputField
.attr('data-action')
.replace(/product-combinations\/\d+/, `product-combinations/${this.getProductId()}`);
$.ajax({
type: 'GET',
url,
}).done((combinations) => {
/** remove all options except first one */
inputField.find('option:gt(0)').remove();
$.each(combinations, (index, combination) => {
inputField.append(`<option value="${combination.id}">${combination.name}</option>`);
});
if (inputField.data('selectedAttribute') !== '0') {
inputField.val(inputField.data('selectedAttribute')).trigger('change');
}
});
}
/**
* @param boolean usePrefixForCreate
*
* @private
*/
enableSpecificPriceTaxFieldIfEligible(usePrefixForCreate) {
const selectorPrefix = this.getPrefixSelector(usePrefixForCreate);
if ($(`${selectorPrefix}sp_reduction_type`).val() === 'percentage') {
$(`${selectorPrefix}sp_reduction_tax`).hide();
} else {
$(`${selectorPrefix}sp_reduction_tax`).show();
}
}
/**
* Reset 'add specific price' form values
* using previously stored default values
*
* @private
*/
resetCreatePriceFormDefaultValues() {
const previouslyStoredValues = this.$createPriceFormDefaultValues;
$('#specific_price_form').find('input').each((index, value) => {
$(value).val(previouslyStoredValues[$(value).attr('id')]);
});
$('#specific_price_form').find('select').each((index, value) => {
$(value).val(previouslyStoredValues[$(value).attr('id')]).change();
});
$('#specific_price_form').find('input:checkbox').each((index, value) => {
$(value).prop('checked', true);
});
}
/**
* @param boolean usePrefixForCreate
*
* @private
*/
enableSpecificPriceFieldIfEligible(usePrefixForCreate) {
const selectorPrefix = this.getPrefixSelector(usePrefixForCreate);
$(`${selectorPrefix}sp_price`).prop('disabled', $(`${selectorPrefix}leave_bprice`).is(':checked')).val('');
}
/**
* Open 'edit specific price' form into a modal
*
* @param integer specificPriceId
*
* @private
*/
openEditPriceModalAndLoadForm(specificPriceId) {
const url = $('#js-specific-price-list').data('actionEdit').replace(/form\/\d+/, `form/${specificPriceId}`);
$('#edit-specific-price-modal').modal('show');
this.editModalIsOpen = true;
$.ajax({
type: 'GET',
url,
})
.done((response) => {
this.insertEditSpecificPriceFormIntoModal(response);
$('#edit-specific-price-modal-form').data('specificPriceId', specificPriceId);
this.configureEditPriceFormInsideModalBehavior();
})
.fail((errors) => {
window.showErrorMessage(errors.responseJSON);
});
}
/**
* @private
*/
closeEditPriceModalAndRemoveForm() {
$('#edit-specific-price-modal').modal('hide');
this.editModalIsOpen = false;
const formLocationHolder = $('#edit-specific-price-modal-form');
formLocationHolder.empty();
}
/**
* @param string form: HTML 'edit specific price' form
*
* @private
*/
insertEditSpecificPriceFormIntoModal(form) {
const formLocationHolder = $('#edit-specific-price-modal-form');
formLocationHolder.empty();
formLocationHolder.append(form);
}
/**
* Get product ID for current Catalog Product page
*
* @returns integer
*
* @private
*/
getProductId() {
return $('#form_id_product').val();
}
/**
* @param boolean usePrefixForCreate
*
* @returns string
*
* @private
*/
getPrefixSelector(usePrefixForCreate) {
if (usePrefixForCreate) {
return `#${this.prefixCreateForm}`;
}
return `#${this.prefixEditForm}`;
}
}
export default SpecificPriceFormHandler;

View File

@@ -0,0 +1,126 @@
/**
* 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 Grid from '@components/grid/grid';
import FiltersResetExtension from '@components/grid/extension/filters-reset-extension';
import SortingExtension from '@components/grid/extension/sorting-extension';
import ExportToSqlManagerExtension from '@components/grid/extension/export-to-sql-manager-extension';
import ReloadListExtension from '@components/grid/extension/reload-list-extension';
import BulkActionCheckboxExtension from '@components/grid/extension/bulk-action-checkbox-extension';
import SubmitBulkExtension from '@components/grid/extension/submit-bulk-action-extension';
import SubmitRowActionExtension from '@components/grid/extension/action/row/submit-row-action-extension';
import LinkRowActionExtension from '@components/grid/extension/link-row-action-extension';
import CategoryPositionExtension from '@components/grid/extension/column/catalog/category-position-extension';
import AsyncToggleColumnExtension from '@components/grid/extension/column/common/async-toggle-column-extension';
import DeleteCategoryRowActionExtension
from '@components/grid/extension/action/row/category/delete-category-row-action-extension';
import DeleteCategoriesBulkActionExtension
from '@components/grid/extension/action/bulk/category/delete-categories-bulk-action-extension';
import ChoiceTable from '@components/choice-table';
import textToLinkRewriteCopier from '@components/text-to-link-rewrite-copier';
import ChoiceTree from '@components/form/choice-tree';
import FormSubmitButton from '@components/form-submit-button';
import FiltersSubmitButtonEnablerExtension
from '@components/grid/extension/filters-submit-button-enabler-extension';
import ShowcaseCard from '@components/showcase-card/showcase-card';
import ShowcaseCardCloseExtension from '@components/showcase-card/extension/showcase-card-close-extension';
import TextWithRecommendedLengthCounter from '@components/form/text-with-recommended-length-counter';
import Serp from '@app/utils/serp/index';
const {$} = window;
$(() => {
const categoriesGrid = new Grid('category');
categoriesGrid.addExtension(new FiltersResetExtension());
categoriesGrid.addExtension(new SortingExtension());
categoriesGrid.addExtension(new CategoryPositionExtension());
categoriesGrid.addExtension(new ExportToSqlManagerExtension());
categoriesGrid.addExtension(new ReloadListExtension());
categoriesGrid.addExtension(new BulkActionCheckboxExtension());
categoriesGrid.addExtension(new SubmitBulkExtension());
categoriesGrid.addExtension(new SubmitRowActionExtension());
categoriesGrid.addExtension(new LinkRowActionExtension());
categoriesGrid.addExtension(new AsyncToggleColumnExtension());
categoriesGrid.addExtension(new DeleteCategoryRowActionExtension());
categoriesGrid.addExtension(new DeleteCategoriesBulkActionExtension());
categoriesGrid.addExtension(new FiltersSubmitButtonEnablerExtension());
const showcaseCard = new ShowcaseCard('categoriesShowcaseCard');
showcaseCard.addExtension(new ShowcaseCardCloseExtension());
window.prestashop.component.initComponents(
[
'TranslatableField',
'TinyMCEEditor',
'TranslatableInput',
],
);
const translatorInput = window.prestashop.instance.translatableInput;
new ChoiceTable();
new TextWithRecommendedLengthCounter();
textToLinkRewriteCopier({
sourceElementSelector: 'input[name^="category[name]"]',
/* eslint-disable-next-line max-len */
destinationElementSelector: `${translatorInput.localeInputSelector}:not(.d-none) input[name^="category[link_rewrite]"]`,
});
textToLinkRewriteCopier({
sourceElementSelector: 'input[name^="root_category[name]"]',
/* eslint-disable-next-line max-len */
destinationElementSelector: `${translatorInput.localeInputSelector}:not(.d-none) input[name^="root_category[link_rewrite]"]`,
});
new Serp(
{
container: '#serp-app',
defaultTitle: 'input[name^="category[name]"]',
watchedTitle: 'input[name^="category[meta_title]"]',
defaultDescription: 'textarea[name^="category[description]"]',
watchedDescription: 'textarea[name^="category[meta_description]"]',
watchedMetaUrl: 'input[name^="category[link_rewrite]"]',
multiLanguageInput: `${translatorInput.localeInputSelector}:not(.d-none)`,
multiLanguageItem: translatorInput.localeItemSelector,
},
$('#serp-app').data('category-url'),
);
new FormSubmitButton();
new window.prestashop.component.TaggableField({
tokenFieldSelector: 'input.js-taggable-field',
options: {
createTokensOnBlur: true,
},
});
new ChoiceTree('#category_id_parent');
new ChoiceTree('#category_shop_association').enableAutoCheckChildren();
new ChoiceTree('#root_category_id_parent');
new ChoiceTree('#root_category_shop_association').enableAutoCheckChildren();
});

View File

@@ -0,0 +1,75 @@
/**
* 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 ChoiceTree from '@components/form/choice-tree';
import textToLinkRewriteCopier from '@components/text-to-link-rewrite-copier';
import Serp from '@app/utils/serp/index';
const {$} = window;
$(() => {
new ChoiceTree('#cms_page_page_category_id');
window.prestashop.component.initComponents(
[
'TranslatableInput',
'TranslatableField',
'TinyMCEEditor',
],
);
const translatorInput = window.prestashop.instance.translatableInput;
new Serp(
{
container: '#serp-app',
defaultTitle: 'input[name^="cms_page[title]"]',
watchedTitle: 'input[name^="cms_page[meta_title]"]',
defaultDescription: 'input[name^="cms_page[description]"]',
watchedDescription: 'input[name^="cms_page[meta_description]"]',
watchedMetaUrl: 'input[name^="cms_page[friendly_url]"]',
multiLanguageInput: `${translatorInput.localeInputSelector}:not(.d-none)`,
multiLanguageItem: translatorInput.localeItemSelector,
},
$('#serp-app').data('cms-url'),
);
new window.prestashop.component.TaggableField({
tokenFieldSelector: 'input.js-taggable-field',
options: {
createTokensOnBlur: true,
},
});
new window.prestashop.component.PreviewOpener('.js-preview-url');
textToLinkRewriteCopier({
sourceElementSelector: 'input.js-copier-source-title',
/* eslint-disable-next-line max-len */
destinationElementSelector: `${translatorInput.localeInputSelector}:not(.d-none) input.js-copier-destination-friendly-url`,
});
new ChoiceTree('#cms_page_shop_association').enableAutoCheckChildren();
});

View File

@@ -0,0 +1,98 @@
/**
* 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 Grid from '@components/grid/grid';
import SortingExtension from '@components/grid/extension/sorting-extension';
import SubmitRowActionExtension from '@components/grid/extension/action/row/submit-row-action-extension';
import FiltersResetExtension from '@components/grid/extension/filters-reset-extension';
import ReloadListActionExtension from '@components/grid/extension/reload-list-extension';
import ExportToSqlManagerExtension from '@components/grid/extension/export-to-sql-manager-extension';
import LinkRowActionExtension from '@components/grid/extension/link-row-action-extension';
import SubmitBulkExtension from '@components/grid/extension/submit-bulk-action-extension';
import BulkActionCheckboxExtension from '@components/grid/extension/bulk-action-checkbox-extension';
import ColumnTogglingExtension from '@components/grid/extension/column-toggling-extension';
import PositionExtension from '@components/grid/extension/position-extension';
import ChoiceTree from '@components/form/choice-tree';
import TranslatableInput from '@components/translatable-input';
import textToLinkRewriteCopier from '@components/text-to-link-rewrite-copier';
import FiltersSubmitButtonEnablerExtension
from '@components/grid/extension/filters-submit-button-enabler-extension';
import TaggableField from '@components/taggable-field';
import ShowcaseCard from '@components/showcase-card/showcase-card';
import ShowcaseCardCloseExtension from '@components/showcase-card/extension/showcase-card-close-extension';
const {$} = window;
$(() => {
const cmsCategory = new Grid('cms_page_category');
cmsCategory.addExtension(new ReloadListActionExtension());
cmsCategory.addExtension(new ExportToSqlManagerExtension());
cmsCategory.addExtension(new FiltersResetExtension());
cmsCategory.addExtension(new SortingExtension());
cmsCategory.addExtension(new LinkRowActionExtension());
cmsCategory.addExtension(new SubmitBulkExtension());
cmsCategory.addExtension(new BulkActionCheckboxExtension());
cmsCategory.addExtension(new SubmitRowActionExtension());
cmsCategory.addExtension(new ColumnTogglingExtension());
cmsCategory.addExtension(new PositionExtension());
cmsCategory.addExtension(new FiltersSubmitButtonEnablerExtension());
const translatorInput = new TranslatableInput();
textToLinkRewriteCopier({
sourceElementSelector: 'input[name^="cms_page_category[name]"]',
/* eslint-disable-next-line max-len */
destinationElementSelector: `${translatorInput.localeInputSelector}:not(.d-none) input[name^="cms_page_category[friendly_url]"]`,
});
new ChoiceTree('#cms_page_category_parent_category');
const shopChoiceTree = new ChoiceTree('#cms_page_category_shop_association');
shopChoiceTree.enableAutoCheckChildren();
new TaggableField({
tokenFieldSelector: 'input[name^="cms_page_category[meta_keywords]"]',
options: {
createTokensOnBlur: true,
},
});
const cmsGrid = new Grid('cms_page');
cmsGrid.addExtension(new ReloadListActionExtension());
cmsGrid.addExtension(new ExportToSqlManagerExtension());
cmsGrid.addExtension(new FiltersResetExtension());
cmsGrid.addExtension(new SortingExtension());
cmsGrid.addExtension(new ColumnTogglingExtension());
cmsGrid.addExtension(new BulkActionCheckboxExtension());
cmsGrid.addExtension(new SubmitBulkExtension());
cmsGrid.addExtension(new SubmitRowActionExtension());
cmsGrid.addExtension(new PositionExtension());
cmsGrid.addExtension(new FiltersSubmitButtonEnablerExtension());
cmsGrid.addExtension(new LinkRowActionExtension());
const helperBlock = new ShowcaseCard('cms-pages-showcase-card');
helperBlock.addExtension(new ShowcaseCardCloseExtension());
});

View File

@@ -0,0 +1,60 @@
/**
* 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 Grid from '@components/grid/grid';
import ReloadListActionExtension from '@components/grid/extension/reload-list-extension';
import ExportToSqlManagerExtension from '@components/grid/extension/export-to-sql-manager-extension';
import FiltersResetExtension from '@components/grid/extension/filters-reset-extension';
import SortingExtension from '@components/grid/extension/sorting-extension';
import LinkRowActionExtension from '@components/grid/extension/link-row-action-extension';
import SubmitGridExtension from '@components/grid/extension/submit-grid-action-extension';
import SubmitBulkExtension from '@components/grid/extension/submit-bulk-action-extension';
import BulkActionCheckboxExtension from '@components/grid/extension/bulk-action-checkbox-extension';
import SubmitRowActionExtension from '@components/grid/extension/action/row/submit-row-action-extension';
import TranslatableInput from '@components/translatable-input';
import ChoiceTree from '@components/form/choice-tree';
/**
* Responsible for actions in Contacts listing page.
*/
export default class ContactsPage {
constructor() {
const contactGrid = new Grid('contact');
contactGrid.addExtension(new ReloadListActionExtension());
contactGrid.addExtension(new ExportToSqlManagerExtension());
contactGrid.addExtension(new FiltersResetExtension());
contactGrid.addExtension(new SortingExtension());
contactGrid.addExtension(new LinkRowActionExtension());
contactGrid.addExtension(new SubmitGridExtension());
contactGrid.addExtension(new SubmitBulkExtension());
contactGrid.addExtension(new BulkActionCheckboxExtension());
contactGrid.addExtension(new SubmitRowActionExtension());
new TranslatableInput();
new ChoiceTree('#contact_shop_association').enableAutoCheckChildren();
}
}

View File

@@ -0,0 +1,32 @@
/**
* 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 ContactsPage from './ContactsPage';
const {$} = window;
$(() => {
new ContactsPage();
});

View File

@@ -0,0 +1,47 @@
/**
* 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 Grid from '../../components/grid/grid';
import SortingExtension from '../../components/grid/extension/sorting-extension';
import FiltersResetExtension from '../../components/grid/extension/filters-reset-extension';
import ReloadListActionExtension from '../../components/grid/extension/reload-list-extension';
import ExportToSqlManagerExtension from '../../components/grid/extension/export-to-sql-manager-extension';
import TranslatableInput from '../../components/translatable-input';
import FiltersSubmitButtonEnablerExtension
from '../../components/grid/extension/filters-submit-button-enabler-extension';
const {$} = window;
$(() => {
const creditSlipGrid = new Grid('credit_slip');
creditSlipGrid.addExtension(new ExportToSqlManagerExtension());
creditSlipGrid.addExtension(new ReloadListActionExtension());
creditSlipGrid.addExtension(new SortingExtension());
creditSlipGrid.addExtension(new FiltersResetExtension());
creditSlipGrid.addExtension(new FiltersSubmitButtonEnablerExtension());
new TranslatableInput();
});

View File

@@ -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)
*/
const {$} = window;
/**
* This class triggers events required for turning on or off exchange rates scheduler an displaying the right text
* below the switch.
*/
export default class ExchangeRatesUpdateScheduler {
constructor() {
this.initEvents();
return {};
}
initEvents() {
$(document).on('change', '.js-live-exchange-rate', (event) => this.initLiveExchangeRate(event));
}
/**
* @param {Object} event
*
* @private
*/
initLiveExchangeRate(event) {
const $liveExchangeRatesSwitch = $(event.currentTarget);
const $form = $liveExchangeRatesSwitch.closest('form');
const formItems = $form.serialize();
$.ajax({
type: 'POST',
url: $liveExchangeRatesSwitch.attr('data-url'),
data: formItems,
})
.then((response) => {
if (!response.status) {
window.showErrorMessage(response.message);
this.changeTextByCurrentSwitchValue($liveExchangeRatesSwitch.val());
return;
}
window.showSuccessMessage(response.message);
this.changeTextByCurrentSwitchValue($liveExchangeRatesSwitch.val());
},
).fail((response) => {
if (typeof response.responseJSON !== 'undefined') {
window.showErrorMessage(response.responseJSON.message);
this.changeTextByCurrentSwitchValue($liveExchangeRatesSwitch.val());
}
});
}
changeTextByCurrentSwitchValue(switchValue) {
const valueParsed = parseInt(switchValue, 10);
$('.js-exchange-rate-text-when-disabled').toggleClass('d-none', valueParsed !== 0);
$('.js-exchange-rate-text-when-enabled').toggleClass('d-none', valueParsed !== 1);
}
}

View File

@@ -0,0 +1,127 @@
<!--**
* 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)
*-->
<template>
<div class="row">
<div class="col-4">
<h4>{{ $t('step.symbol') }}</h4>
<input
type="text"
v-model="customSymbol"
>
</div>
<div class="col-8 border-left">
<h4>{{ $t('step.format') }}</h4>
<div class="row">
<div
class="ps-radio col-6"
v-for="(pattern, transformation) in availableFormats"
:key="transformation"
:id="transformation"
>
<input
type="radio"
:checked="transformation === customTransformation"
:value="transformation"
>
<label @click.prevent.stop="customTransformation = transformation">
{{ displayPattern(pattern) }}
</label>
</div>
</div>
</div>
</div>
</template>
<script>
import {NumberFormatter} from '@app/cldr';
export default {
name: 'CurrencyFormatForm',
data: () => ({
value: {
symbol: '',
transformation: '',
},
}),
props: {
language: {
type: Object,
required: true,
default: () => {},
},
},
computed: {
availableFormats() {
return this.language.transformations;
},
customSymbol: {
get() {
return this.value.symbol;
},
set(symbol) {
this.value.symbol = symbol;
this.$emit('input', this.value);
},
},
customTransformation: {
get() {
return this.value.transformation;
},
set(transformation) {
this.value.transformation = transformation;
this.$emit('input', this.value);
},
},
},
methods: {
displayPattern(pattern) {
const patterns = pattern.split(';');
const priceSpecification = {...this.language.priceSpecification};
priceSpecification.positivePattern = patterns[0];
priceSpecification.negativePattern = patterns.length > 1 ? patterns[1] : `-${pattern}`;
priceSpecification.currencySymbol = this.customSymbol;
const currencyFormatter = NumberFormatter.build(priceSpecification);
return currencyFormatter.format(14251999.42);
},
},
mounted() {
this.customSymbol = this.language.priceSpecification.currencySymbol;
const currencyPattern = this.language.priceSpecification.positivePattern;
// Detect which transformation matches the language pattern
/* eslint-disable-next-line no-restricted-syntax,guard-for-in */
for (const transformation in this.language.transformations) {
const transformationPatterns = this.language.transformations[transformation].split(';');
if (transformationPatterns[0] === currencyPattern) {
this.customTransformation = transformation;
break;
}
}
},
};
</script>

View File

@@ -0,0 +1,112 @@
<!--**
* 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)
*-->
<template>
<div
:id="id"
class="card-block row"
>
<div class="col-sm">
<language-list
v-if="languagesCount"
:languages="languages"
@selectLanguage="selectLanguage"
@resetLanguage="resetLanguage"
/>
<currency-modal
:language="selectedLanguage"
@close="closeModal"
@applyCustomization="applyCustomization"
/>
</div>
</div>
</template>
<script>
import {showGrowl} from '@app/utils/growl';
import LanguageList from './LanguageList';
import CurrencyModal from './CurrencyModal';
export default {
name: 'CurrencyFormatter',
data: () => ({selectedLanguage: null}),
props: {
id: {
type: String,
required: true,
},
languages: {
type: Array,
required: true,
},
currencyData: {
type: Object,
required: true,
},
},
components: {LanguageList, CurrencyModal},
computed: {
languagesCount() {
return this.languages.length;
},
},
methods: {
closeModal() {
this.selectedLanguage = null;
},
selectLanguage(language) {
this.selectedLanguage = language;
},
resetLanguage(language) {
const patterns = language.currencyPattern.split(';');
language.priceSpecification.positivePattern = patterns[0];
language.priceSpecification.negativePattern = patterns.length > 1 ? patterns[1] : `-${patterns[0]}`;
language.priceSpecification.currencySymbol = language.currencySymbol;
this.currencyData.transformations[language.id] = '';
this.currencyData.symbols[language.id] = language.currencySymbol;
showGrowl('success', this.$t('list.reset.success'));
},
applyCustomization(customData) {
const selectedPattern = this.selectedLanguage.transformations[
customData.transformation
];
const patterns = selectedPattern.split(';');
this.selectedLanguage.priceSpecification.currencySymbol = customData.symbol;
this.selectedLanguage.priceSpecification.positivePattern = patterns[0];
// eslint-disable-next-line
this.selectedLanguage.priceSpecification.negativePattern =
patterns.length > 1 ? patterns[1] : `-${patterns[0]}`;
this.currencyData.transformations[this.selectedLanguage.id] = customData.transformation;
this.currencyData.symbols[this.selectedLanguage.id] = customData.symbol;
this.closeModal();
},
},
};
</script>

View File

@@ -0,0 +1,81 @@
<!--**
* 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)
*-->
<template>
<modal
confirmation
:modal-title="modalTitle"
@close="$emit('close')"
@confirm="$emit('applyCustomization', customData)"
v-if="language !== null"
>
<template slot="body">
<currency-format-form
:language="language"
@input="customData = $event"
/>
</template>
</modal>
</template>
<script>
import Modal from '@vue/components/Modal';
import CurrencyFormatForm from './CurrencyFormatForm';
export default {
name: 'CurrencyModal',
data: () => ({
customData: null,
}),
components: {
CurrencyFormatForm,
Modal,
},
props: {
language: {
type: Object,
required: false,
default: null,
},
},
computed: {
modalTitle() {
return this.$t('modal.title') + (this.language !== null ? ` + ${this.language.name}` : '');
},
},
};
</script>
<style lang="scss" scoped>
@import '~@scss/config/_settings.scss';
.modal-header .close {
font-size: 1.2rem;
color: $gray-medium;
opacity: 1;
}
.modal-content {
border-radius: 0
}
</style>

View File

@@ -0,0 +1,111 @@
<!--**
* 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)
*-->
<template>
<table class="grid-table js-grid-table table">
<thead class="thead-default">
<tr class="column-headers">
<th scope="col">
{{ $t('list.language') }}
</th>
<th scope="col">
{{ $t('list.example') }}
</th>
<th scope="col">
<div class="text-right">
{{ $t('list.edit') }}
</div>
</th>
<th scope="col">
<div class="grid-actions-header-text">
{{ $t('list.reset') }}
</div>
</th>
</tr>
</thead>
<tbody>
<tr
v-for="language in languages"
:key="language.id"
>
<td>
{{ language.name }}
</td>
<td>
{{ displayFormat(language) }}
</td>
<td>
<div class="btn-group-action text-right">
<div class="btn-group">
<button
type="button"
class="btn"
@click.prevent.stop="$emit('selectLanguage', language)"
>
<i class="material-icons">edit</i>
</button>
</div>
</div>
</td>
<td>
<div class="btn-group-action text-right">
<div class="btn-group">
<button
type="button"
class="btn"
@click.prevent.stop="$emit('resetLanguage', language)"
>
<i class="material-icons">refresh</i>
</button>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</template>
<script>
import {NumberFormatter} from '@app/cldr';
export default {
name: 'LanguageList',
props: {
languages: {
type: Array,
required: true,
},
},
methods: {
displayFormat(language) {
const currencyFormatter = NumberFormatter.build(language.priceSpecification);
return this.$t('list.example.format', {
'%price%': currencyFormatter.format(14251999.42),
'%discount%': currencyFormatter.format(-566.268),
});
},
},
};
</script>

View File

@@ -0,0 +1,44 @@
/**
* 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)
*/
/**
* Defines all selectors that are used in currency add/edit form.
*/
export default {
currencyForm: '#currency_form',
currencyFormFooter: '#currency_form .card .card-footer',
currencySelector: '#currency_selected_iso_code',
isUnofficialCheckbox: '#currency_unofficial',
namesInput: (langId) => `#currency_names_${langId}`,
symbolsInput: (langId) => `#currency_symbols_${langId}`,
transformationsInput: (langId) => `#currency_transformations_${langId}`,
isoCodeInput: '#currency_iso_code',
exchangeRateInput: '#currency_exchange_rate',
resetDefaultSettingsInput: '#currency_reset_default_settings',
loadingDataModal: '#currency_loading_data_modal',
precisionInput: '#currency_precision',
shopAssociationTree: '#currency_shop_association',
currencyFormatter: '#currency_formatter',
};

View File

@@ -0,0 +1,270 @@
/**
* 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 Vue from 'vue';
import VueI18n from 'vue-i18n';
import VueResource from 'vue-resource';
import {showGrowl} from '@app/utils/growl';
import ConfirmModal from '@components/modal';
import ReplaceFormatter from '@vue/plugins/vue-i18n/replace-formatter';
import CurrencyFormatter from './components/CurrencyFormatter.vue';
Vue.use(VueResource);
Vue.use(VueI18n);
export default class CurrencyForm {
/**
* @param {object} currencyFormMap - Page map
*/
constructor(currencyFormMap) {
this.map = currencyFormMap;
this.$currencyForm = $(this.map.currencyForm);
this.$currencyFormFooter = $(this.map.currencyFormFooter);
this.apiReferenceUrl = this.$currencyForm.data('reference-url');
this.referenceCurrencyResource = Vue.resource(this.apiReferenceUrl);
this.originalLanguages = this.$currencyForm.data('languages');
this.translations = this.$currencyForm.data('translations');
this.$currencySelector = $(this.map.currencySelector);
this.$isUnofficialCheckbox = $(this.map.isUnofficialCheckbox);
this.$isoCodeInput = $(this.map.isoCodeInput);
this.$exchangeRateInput = $(this.map.exchangeRateInput);
this.$precisionInput = $(this.map.precisionInput);
this.$resetDefaultSettingsButton = $(this.map.resetDefaultSettingsInput);
this.$loadingDataModal = $(this.map.loadingDataModal);
this.currencyFormatterId = this.map.currencyFormatter.replace('#', '');
this.hideModal = true;
this.$loadingDataModal.on('shown.bs.modal', () => {
if (this.hideModal) {
this.$loadingDataModal.modal('hide');
}
});
}
init() {
this.initListeners();
this.initFields();
this.initState();
this.initCurrencyFormatter();
}
initState() {
this.state = {
currencyData: this.getCurrencyDataFromForm(),
languages: [...this.originalLanguages],
};
}
initCurrencyFormatter() {
// Customizer only present when languages data are present (for installed currencies only)
if (!this.originalLanguages.length) {
return;
}
const i18n = new VueI18n({
locale: 'en',
formatter: new ReplaceFormatter(),
messages: {en: this.translations},
});
$(`<div id="${this.currencyFormatterId}"></div>`).insertBefore(this.$currencyFormFooter);
this.currencyFormatter = new Vue({
el: this.map.currencyFormatter,
i18n,
components: {CurrencyFormatter},
data: this.state,
template: `<currency-formatter
id="${this.currencyFormatterId}"
:languages="languages"
:currencyData="currencyData">
</currency-formatter>`,
});
this.currencyFormatter.$watch('currencyData', () => {
// We use the state value directly since the object is shared with the Vue component and already updated
this.fillCurrencyCustomData(this.state.currencyData);
}, {deep: true, immediate: true});
}
initListeners() {
this.$currencySelector.change(this.onCurrencySelectorChange.bind(this));
this.$isUnofficialCheckbox.change(this.onIsUnofficialCheckboxChange.bind(this));
this.$resetDefaultSettingsButton.click(this.onResetDefaultSettingsClick.bind(this));
}
initFields() {
if (!this.isUnofficialCurrency()) {
this.$isUnofficialCheckbox.prop('checked', false);
this.$isoCodeInput.prop('readonly', true);
} else {
this.$currencySelector.val('');
this.$isoCodeInput.prop('readonly', false);
}
}
onCurrencySelectorChange() {
const selectedISOCode = this.$currencySelector.val();
if (selectedISOCode !== '') {
this.$isUnofficialCheckbox.prop('checked', false);
this.$isoCodeInput.prop('readonly', true);
this.resetCurrencyData(selectedISOCode);
} else {
this.$isUnofficialCheckbox.prop('checked', true);
this.$isoCodeInput.prop('readonly', false);
}
}
isUnofficialCurrency() {
if (this.$isUnofficialCheckbox.prop('type') === 'hidden') {
return this.$isUnofficialCheckbox.attr('value') === '1';
}
return this.$isUnofficialCheckbox.prop('checked');
}
onIsUnofficialCheckboxChange() {
if (this.isUnofficialCurrency()) {
this.$currencySelector.val('');
this.$isoCodeInput.prop('readonly', false);
} else {
this.$isoCodeInput.prop('readonly', true);
}
}
async onResetDefaultSettingsClick() {
await this.resetCurrencyData(this.$isoCodeInput.val());
}
showResetDefaultSettingsConfirmModal() {
const confirmTitle = this.translations['modal.restore.title'];
const confirmMessage = this.translations['modal.restore.body'];
const confirmButtonLabel = this.translations['modal.restore.apply'];
const closeButtonLabel = this.translations['modal.restore.cancel'];
const modal = new ConfirmModal({
id: 'currency_restore_default_settings',
confirmTitle,
confirmMessage,
confirmButtonLabel,
closeButtonLabel,
}, () => this.onResetDefaultSettingsClick());
modal.show();
}
async resetCurrencyData(selectedISOCode) {
this.$loadingDataModal.modal('show');
this.$resetDefaultSettingsButton.addClass('spinner');
this.state.currencyData = await this.fetchCurrency(selectedISOCode);
this.fillCurrencyData(this.state.currencyData);
// Reset languages
this.originalLanguages.forEach((language) => {
// Use language data (which contain the reference) to reset
// price specification data (which contain the custom values)
const patterns = language.currencyPattern.split(';');
language.priceSpecification.positivePattern = patterns[0];
language.priceSpecification.negativePattern = patterns.length > 1 ? patterns[1] : `-${patterns[0]}`;
language.priceSpecification.currencySymbol = language.currencySymbol;
});
this.state.languages = [...this.originalLanguages];
this.hideModal = true;
this.$loadingDataModal.modal('hide');
this.$resetDefaultSettingsButton.removeClass('spinner');
}
async fetchCurrency(currencyIsoCode) {
let currencyData = null;
if (currencyIsoCode) {
await this.referenceCurrencyResource.get({id: currencyIsoCode}).then((response) => {
currencyData = response.body;
}, (errorResponse) => {
if (errorResponse.body && errorResponse.body.error) {
showGrowl('error', errorResponse.body.error, 3000);
} else {
showGrowl('error', `Can not find CLDR data for currency ${currencyIsoCode}`, 3000);
}
});
}
if (currencyData && currencyData.transformations === undefined) {
currencyData.transformations = {};
Object.keys(currencyData.symbols).forEach((langId) => {
currencyData.transformations[langId] = '';
});
}
return currencyData;
}
fillCurrencyData(currencyData) {
if (!currencyData) {
return;
}
Object.keys(currencyData.symbols).forEach((langId) => {
const langNameSelector = this.map.namesInput(langId);
$(langNameSelector).val(currencyData.names[langId]);
});
this.fillCurrencyCustomData(currencyData);
this.$isoCodeInput.val(currencyData.isoCode);
this.$exchangeRateInput.val(currencyData.exchangeRate);
this.$precisionInput.val(currencyData.precision);
}
fillCurrencyCustomData(currencyData) {
Object.keys(currencyData.symbols).forEach((langId) => {
const langSymbolSelector = this.map.symbolsInput(langId);
$(langSymbolSelector).val(currencyData.symbols[langId]);
});
Object.keys(currencyData.transformations).forEach((langId) => {
const langTransformationSelector = this.map.transformationsInput(langId);
$(langTransformationSelector).val(currencyData.transformations[langId]);
});
}
getCurrencyDataFromForm() {
const currencyData = {
names: {},
symbols: {},
transformations: {},
isoCode: this.$isoCodeInput.val(),
exchangeRate: this.$exchangeRateInput.val(),
precision: this.$precisionInput.val(),
};
this.originalLanguages.forEach((lang) => {
currencyData.names[lang.id] = $(this.map.namesInput(lang.id)).val();
currencyData.symbols[lang.id] = $(this.map.symbolsInput(lang.id)).val();
currencyData.transformations[lang.id] = $(this.map.transformationsInput(lang.id)).val();
});
return currencyData;
}
}

View File

@@ -0,0 +1,41 @@
/**
* 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 currencyFormMap from './currency-form-map';
import CurrencyForm from './currency-form';
const {$} = window;
$(() => {
window.prestashop.component.initComponents(
[
'TranslatableInput',
],
);
const choiceTree = new window.prestashop.component.ChoiceTree(currencyFormMap.shopAssociationTree);
choiceTree.enableAutoCheckChildren();
const currencyForm = new CurrencyForm(currencyFormMap);
currencyForm.init();
});

View File

@@ -0,0 +1,56 @@
/**
* 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 Grid from '@components/grid/grid';
import BulkActionCheckboxExtension from '@components/grid/extension/bulk-action-checkbox-extension';
import SubmitBulkExtension from '@components/grid/extension/submit-bulk-action-extension';
import ExportToSqlManagerExtension from '@components/grid/extension/export-to-sql-manager-extension';
import SortingExtension from '@components/grid/extension/sorting-extension';
import FiltersResetExtension from '@components/grid/extension/filters-reset-extension';
import ReloadListActionExtension from '@components/grid/extension/reload-list-extension';
import ColumnTogglingExtension from '@components/grid/extension/column-toggling-extension';
import SubmitRowActionExtension from '@components/grid/extension/action/row/submit-row-action-extension';
import ExchangeRatesUpdateScheduler from '@pages/currency/ExchangeRatesUpdateScheduler';
import FiltersSubmitButtonEnablerExtension from '@components/grid/extension/filters-submit-button-enabler-extension';
import LinkRowActionExtension from '@components/grid/extension/link-row-action-extension';
const {$} = window;
$(() => {
const currency = new Grid('currency');
currency.addExtension(new BulkActionCheckboxExtension());
currency.addExtension(new SubmitBulkExtension());
currency.addExtension(new ExportToSqlManagerExtension());
currency.addExtension(new SortingExtension());
currency.addExtension(new FiltersResetExtension());
currency.addExtension(new ReloadListActionExtension());
currency.addExtension(new ColumnTogglingExtension());
currency.addExtension(new SubmitRowActionExtension());
currency.addExtension(new FiltersSubmitButtonEnablerExtension());
currency.addExtension(new LinkRowActionExtension());
new ExchangeRatesUpdateScheduler();
});

View File

@@ -0,0 +1,30 @@
/**
* 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)
*/
export default {
forwardCustomerThreadModal: '#forwardThreadModal',
forwardSomeoneElseEmailInput: '#forward_customer_thread_someone_else_email',
forwardEmployeeInput: '#forward_customer_thread_employee_id',
};

View File

@@ -0,0 +1,43 @@
/**
* 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 CustomerThreadViewPageMap from './customer-thread-view-page-map';
const {$} = window;
$(() => {
$(CustomerThreadViewPageMap.forwardEmployeeInput).on('change', (event) => {
const $someoneElseEmailInput = $(CustomerThreadViewPageMap.forwardSomeoneElseEmailInput);
const $someElseEmailFormGroup = $someoneElseEmailInput.closest('.form-group');
const employeeId = $(event.currentTarget).val();
if (parseInt(employeeId, 10) === 0) {
$someElseEmailFormGroup.removeClass('d-none');
} else {
$someElseEmailFormGroup.addClass('d-none');
}
});
});

View File

@@ -0,0 +1,88 @@
/**
* 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 Grid from '@components/grid/grid';
import ReloadListActionExtension from '@components/grid/extension/reload-list-extension';
import ExportToSqlManagerExtension from '@components/grid/extension/export-to-sql-manager-extension';
import FiltersResetExtension from '@components/grid/extension/filters-reset-extension';
import FormSubmitButton from '@components/form-submit-button';
import SortingExtension from '@components/grid/extension/sorting-extension';
import BulkActionCheckboxExtension from '@components/grid/extension/bulk-action-checkbox-extension';
import SubmitBulkExtension from '@components/grid/extension/submit-bulk-action-extension';
import SubmitGridExtension from '@components/grid/extension/submit-grid-action-extension';
import SubmitRowActionExtension from '@components/grid/extension/action/row/submit-row-action-extension';
import LinkRowActionExtension from '@components/grid/extension/link-row-action-extension';
import LinkableItem from '@components/linkable-item';
import ChoiceTable from '@components/choice-table';
import ColumnTogglingExtension from '@components/grid/extension/column-toggling-extension';
import DeleteCustomersBulkActionExtension
from '@components/grid/extension/action/bulk/customer/delete-customers-bulk-action-extension';
import DeleteCustomerRowActionExtension
from '@components/grid/extension/action/row/customer/delete-customer-row-action-extension';
import FiltersSubmitButtonEnablerExtension
from '@components/grid/extension/filters-submit-button-enabler-extension';
import ShowcaseCard from '@components/showcase-card/showcase-card';
import ShowcaseCardCloseExtension from '@components/showcase-card/extension/showcase-card-close-extension';
const {$} = window;
$(() => {
const customerGrid = new Grid('customer');
customerGrid.addExtension(new ReloadListActionExtension());
customerGrid.addExtension(new ExportToSqlManagerExtension());
customerGrid.addExtension(new FiltersResetExtension());
customerGrid.addExtension(new SortingExtension());
customerGrid.addExtension(new BulkActionCheckboxExtension());
customerGrid.addExtension(new SubmitBulkExtension());
customerGrid.addExtension(new SubmitGridExtension());
customerGrid.addExtension(new LinkRowActionExtension());
customerGrid.addExtension(new ColumnTogglingExtension());
customerGrid.addExtension(new DeleteCustomersBulkActionExtension());
customerGrid.addExtension(new DeleteCustomerRowActionExtension());
customerGrid.addExtension(new FiltersSubmitButtonEnablerExtension());
const customerDiscountsGrid = new Grid('customer_discount');
customerDiscountsGrid.addExtension(new SubmitRowActionExtension());
customerDiscountsGrid.addExtension(new LinkRowActionExtension());
const customerAddressesGrid = new Grid('customer_address');
customerAddressesGrid.addExtension(new SubmitRowActionExtension());
customerAddressesGrid.addExtension(new LinkRowActionExtension());
const showcaseCard = new ShowcaseCard('customersShowcaseCard');
showcaseCard.addExtension(new ShowcaseCardCloseExtension());
// needed for "Group access" input in Add/Edit customer forms
new ChoiceTable();
// in customer view page
// there are a lot of tables
// where you click any row
// and it redirects user to related page
new LinkableItem();
new FormSubmitButton();
});

View File

@@ -0,0 +1,171 @@
/**
* 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)
*/
const {$} = window;
/**
* Class is responsible for managing test email sending
*/
class EmailSendingTest {
constructor() {
this.$successAlert = $('.js-test-email-success');
this.$errorAlert = $('.js-test-email-errors');
this.$loader = $('.js-test-email-loader');
this.$sendEmailBtn = $('.js-send-test-email-btn');
this.$sendEmailBtn.on('click', (event) => {
this.handle(event);
});
}
/**
* Handle test email sending
*
* @param {Event} event
*
* @private
*/
handle(event) {
// fill test email sending form with configured values
$('#test_email_sending_mail_method').val($('input[name="form[mail_method]"]:checked').val());
$('#test_email_sending_smtp_server').val($('#form_smtp_config_server').val());
$('#test_email_sending_smtp_username').val($('#form_smtp_config_username').val());
$('#test_email_sending_smtp_password').val($('#form_smtp_config_password').val());
$('#test_email_sending_smtp_port').val($('#form_smtp_config_port').val());
$('#test_email_sending_smtp_encryption').val($('#form_smtp_config_encryption').val());
const $testEmailSendingForm = $(event.currentTarget).closest('form');
this.resetMessages();
this.hideSendEmailButton();
this.showLoader();
$.post({
url: $testEmailSendingForm.attr('action'),
data: $testEmailSendingForm.serialize(),
}).then((response) => {
this.hideLoader();
this.showSendEmailButton();
if (response.errors.length !== 0) {
this.showErrors(response.errors);
return;
}
this.showSuccess();
});
}
/**
* Make sure that additional content (alerts, loader) is not visible
*
* @private
*/
resetMessages() {
this.hideSuccess();
this.hideErrors();
}
/**
* Show success message
*
* @private
*/
showSuccess() {
this.$successAlert.removeClass('d-none');
}
/**
* Hide success message
*
* @private
*/
hideSuccess() {
this.$successAlert.addClass('d-none');
}
/**
* Show loader during AJAX call
*
* @private
*/
showLoader() {
this.$loader.removeClass('d-none');
}
/**
* Hide loader
*
* @private
*/
hideLoader() {
this.$loader.addClass('d-none');
}
/**
* Show errors
*
* @param {Array} errors
*
* @private
*/
showErrors(errors) {
errors.forEach((error) => {
this.$errorAlert.append(`<p>${error}</p>`);
});
this.$errorAlert.removeClass('d-none');
}
/**
* Hide errors
*
* @private
*/
hideErrors() {
this.$errorAlert.addClass('d-none').empty();
}
/**
* Show send email button
*
* @private
*/
showSendEmailButton() {
this.$sendEmailBtn.removeClass('d-none');
}
/**
* Hide send email button
*
* @private
*/
hideSendEmailButton() {
this.$sendEmailBtn.addClass('d-none');
}
}
export default EmailSendingTest;

View File

@@ -0,0 +1,59 @@
/**
* 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 EmailSendingTest from '@pages/email/email-sending-test';
import SmtpConfigurationToggler from '@pages/email/smtp-configuration-toggler';
import Grid from '@components/grid/grid';
import ReloadListActionExtension from '@components/grid/extension/reload-list-extension';
import ExportToSqlManagerExtension from '@components/grid/extension/export-to-sql-manager-extension';
import FiltersResetExtension from '@components/grid/extension/filters-reset-extension';
import SortingExtension from '@components/grid/extension/sorting-extension';
import BulkActionCheckboxExtension from '@components/grid/extension/bulk-action-checkbox-extension';
import SubmitBulkExtension from '@components/grid/extension/submit-bulk-action-extension';
import SubmitRowActionExtension from '@components/grid/extension/action/row/submit-row-action-extension';
import SubmitGridExtension from '@components/grid/extension/submit-grid-action-extension';
import LinkRowActionExtension from '@components/grid/extension/link-row-action-extension';
import FiltersSubmitButtonEnablerExtension
from '@components/grid/extension/filters-submit-button-enabler-extension';
const {$} = window;
$(() => {
const emailLogsGrid = new Grid('email_logs');
emailLogsGrid.addExtension(new ReloadListActionExtension());
emailLogsGrid.addExtension(new ExportToSqlManagerExtension());
emailLogsGrid.addExtension(new FiltersResetExtension());
emailLogsGrid.addExtension(new SortingExtension());
emailLogsGrid.addExtension(new BulkActionCheckboxExtension());
emailLogsGrid.addExtension(new SubmitBulkExtension());
emailLogsGrid.addExtension(new SubmitRowActionExtension());
emailLogsGrid.addExtension(new SubmitGridExtension());
emailLogsGrid.addExtension(new LinkRowActionExtension());
emailLogsGrid.addExtension(new FiltersSubmitButtonEnablerExtension());
new EmailSendingTest();
new SmtpConfigurationToggler();
});

View File

@@ -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)
*/
const {$} = window;
/**
* Class SmtpConfigurationToggler is responsible for showing/hiding SMTP configuration form
*/
class SmtpConfigurationToggler {
constructor() {
$('.js-email-method').on('change', 'input[type="radio"]', (event) => {
const mailMethod = Number($(event.currentTarget).val());
$('.js-smtp-configuration').toggleClass('d-none', this.getSmtpMailMethodOption() !== mailMethod);
});
}
/**
* Get SMTP mail option value
*
* @private
*
* @returns {Number}
*/
getSmtpMailMethodOption() {
return $('.js-email-method').data('smtp-mail-method');
}
}
export default SmtpConfigurationToggler;

View File

@@ -0,0 +1,171 @@
/**
* 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 ChoiceTree from '../../components/form/choice-tree';
import AddonsConnector from '../../components/addons-connector';
import ChangePasswordControl from '../../components/form/change-password-control';
import employeeFormMap from './employee-form-map';
/**
* Class responsible for javascript actions in employee add/edit page.
*/
export default class EmployeeForm {
constructor() {
this.shopChoiceTreeSelector = employeeFormMap.shopChoiceTree;
this.shopChoiceTree = new ChoiceTree(this.shopChoiceTreeSelector);
this.employeeProfileSelector = employeeFormMap.profileSelect;
this.tabsDropdownSelector = employeeFormMap.defaultPageSelect;
this.shopChoiceTree.enableAutoCheckChildren();
new AddonsConnector(
employeeFormMap.addonsConnectForm,
employeeFormMap.addonsLoginButton,
);
new ChangePasswordControl(
employeeFormMap.changePasswordInputsBlock,
employeeFormMap.showChangePasswordBlockButton,
employeeFormMap.hideChangePasswordBlockButton,
employeeFormMap.generatePasswordButton,
employeeFormMap.oldPasswordInput,
employeeFormMap.newPasswordInput,
employeeFormMap.confirmNewPasswordInput,
employeeFormMap.generatedPasswordDisplayInput,
employeeFormMap.passwordStrengthFeedbackContainer,
);
this.initEvents();
this.toggleShopTree();
return {};
}
/**
* Initialize page's events.
*
* @private
*/
initEvents() {
const $employeeProfilesDropdown = $(this.employeeProfileSelector);
const getTabsUrl = $employeeProfilesDropdown.data('get-tabs-url');
$(document).on('change', this.employeeProfileSelector, () => this.toggleShopTree());
// Reload tabs dropdown when employee profile is changed.
$(document).on('change', this.employeeProfileSelector, (event) => {
$.get(
getTabsUrl,
{
profileId: $(event.currentTarget).val(),
},
(tabs) => {
this.reloadTabsDropdown(tabs);
},
'json',
);
});
}
/**
* Reload tabs dropdown with new content.
*
* @param {Object} accessibleTabs
*
* @private
*/
reloadTabsDropdown(accessibleTabs) {
const $tabsDropdown = $(this.tabsDropdownSelector);
$tabsDropdown.empty();
Object.values(accessibleTabs).forEach((accessibleTab) => {
if (accessibleTab.children.length > 0 && accessibleTab.name) {
// If tab has children - create an option group and put children inside.
const $optgroup = this.createOptionGroup(accessibleTab.name);
Object.keys(accessibleTab.children).forEach((childKey) => {
if (accessibleTab.children[childKey].name) {
$optgroup.append(
this.createOption(
accessibleTab.children[childKey].name,
accessibleTab.children[childKey].id_tab),
);
}
});
$tabsDropdown.append($optgroup);
} else if (accessibleTab.name) {
// If tab doesn't have children - create an option.
$tabsDropdown.append(
this.createOption(
accessibleTab.name,
accessibleTab.id_tab,
),
);
}
});
}
/**
* Hide shop choice tree if superadmin profile is selected, show it otherwise.
*
* @private
*/
toggleShopTree() {
const $employeeProfileDropdown = $(this.employeeProfileSelector);
const superAdminProfileId = $employeeProfileDropdown.data('admin-profile');
$(this.shopChoiceTreeSelector)
.closest('.form-group')
.toggleClass('d-none', $employeeProfileDropdown.val() === superAdminProfileId);
}
/**
* Creates an <optgroup> element
*
* @param {String} name
*
* @returns {jQuery}
*
* @private
*/
createOptionGroup(name) {
return $(`<optgroup label="${name}">`);
}
/**
* Creates an <option> element.
*
* @param {String} name
* @param {String} value
*
* @returns {jQuery}
*
* @private
*/
createOption(name, value) {
return $(`<option value="${value}">${name}</option>`);
}
}

View File

@@ -0,0 +1,46 @@
/**
* 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)
*/
/**
* Defines all selectors that are used in employee add/edit form.
*/
export default {
shopChoiceTree: '#employee_shop_association',
profileSelect: '#employee_profile',
defaultPageSelect: '#employee_default_page',
addonsConnectForm: '#addons-connect-form',
addonsLoginButton: '#addons_login_btn',
// selectors related to "change password" form control
changePasswordInputsBlock: '.js-change-password-block',
showChangePasswordBlockButton: '.js-change-password',
hideChangePasswordBlockButton: '.js-change-password-cancel',
generatePasswordButton: '#employee_change_password_generate_password_button',
oldPasswordInput: '#employee_change_password_old_password',
newPasswordInput: '#employee_change_password_new_password_first',
confirmNewPasswordInput: '#employee_change_password_new_password_second',
generatedPasswordDisplayInput: '#employee_change_password_generated_password',
passwordStrengthFeedbackContainer: '.js-password-strength-feedback',
};

View File

@@ -0,0 +1,30 @@
/**
* 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 EmployeeForm from './EmployeeForm';
$(() => {
new EmployeeForm();
});

View File

@@ -0,0 +1,59 @@
/**
* 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 FiltersSubmitButtonEnablerExtension
from '@components/grid/extension/filters-submit-button-enabler-extension';
import Grid from '@components/grid/grid';
import ReloadListActionExtension from '@components/grid/extension/reload-list-extension';
import ExportToSqlManagerExtension from '@components/grid/extension/export-to-sql-manager-extension';
import FiltersResetExtension from '@components/grid/extension/filters-reset-extension';
import SortingExtension from '@components/grid/extension/sorting-extension';
import BulkActionCheckboxExtension from '@components/grid/extension/bulk-action-checkbox-extension';
import SubmitBulkActionExtension from '@components/grid/extension/submit-bulk-action-extension';
import SubmitRowActionExtension from '@components/grid/extension/action/row/submit-row-action-extension';
import ColumnTogglingExtension from '@components/grid/extension/column-toggling-extension';
import ShowcaseCard from '@components/showcase-card/showcase-card';
import ShowcaseCardCloseExtension from '@components/showcase-card/extension/showcase-card-close-extension';
import LinkRowActionExtension from '@components/grid/extension/link-row-action-extension';
const {$} = window;
$(() => {
const employeeGrid = new Grid('employee');
employeeGrid.addExtension(new ReloadListActionExtension());
employeeGrid.addExtension(new ExportToSqlManagerExtension());
employeeGrid.addExtension(new FiltersResetExtension());
employeeGrid.addExtension(new SortingExtension());
employeeGrid.addExtension(new BulkActionCheckboxExtension());
employeeGrid.addExtension(new SubmitBulkActionExtension());
employeeGrid.addExtension(new SubmitRowActionExtension());
employeeGrid.addExtension(new ColumnTogglingExtension());
employeeGrid.addExtension(new FiltersSubmitButtonEnablerExtension());
employeeGrid.addExtension(new LinkRowActionExtension());
const showcaseCard = new ShowcaseCard('employeesShowcaseCard');
showcaseCard.addExtension(new ShowcaseCardCloseExtension());
});

View File

@@ -0,0 +1,29 @@
/**
* 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)
*/
// jQuery is not available in this page
// so we use plain JS to to listen on button click
// which then goes back in browser history
(() => document.querySelector('.js-go-back-btn').addEventListener('click', () => window.history.back()))();

View File

@@ -0,0 +1,79 @@
/**
* 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 ConfirmModal from '@components/modal';
const {$} = window;
$(() => {
const $submitButton = $('#submit-btn-feature-flag');
$submitButton.prop('disabled', true);
const $form = $('#feature-flag-form');
const $formInputs = $('#feature-flag-form input');
const initialState = $form.serialize();
const initialFormData = $form.serializeArray();
$formInputs.change(() => {
$submitButton.prop('disabled', initialState === $form.serialize());
});
$submitButton.on('click', (event) => {
event.preventDefault();
const formData = $form.serializeArray();
if (initialState === $form.serialize()) {
return;
}
let oneFlagIsEnabled = false;
for (let i = 0; i < formData.length; i += 1) {
if ((formData[i].name !== 'form[_token]') && (formData[i].value !== '0') && (initialFormData[i].value === '0')) {
oneFlagIsEnabled = true;
break;
}
}
const modal = new ConfirmModal(
{
id: 'modal-confirm-submit-feature-flag',
confirmTitle: $submitButton.data('modal-title'),
confirmMessage: $submitButton.data('modal-message'),
confirmButtonLabel: $submitButton.data('modal-apply'),
closeButtonLabel: $submitButton.data('modal-cancel'),
},
() => {
$form.submit();
},
);
if (oneFlagIsEnabled) {
modal.show();
} else {
$form.submit();
}
});
});

View File

@@ -0,0 +1,32 @@
/**
* 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 TranslatableInput from '../../components/translatable-input';
import ChoiceTree from '../../components/form/choice-tree';
$(() => {
new TranslatableInput();
new ChoiceTree('#feature_shop_association').enableAutoCheckChildren();
});

View File

@@ -0,0 +1,34 @@
/**
* 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)
*/
const {$} = window;
$(() => {
window.prestashop.component.initComponents(
[
'ChoiceTable',
],
);
});

View File

@@ -0,0 +1,90 @@
/**
* 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)
*/
const {$} = window;
export default class EntityFieldsValidator {
/**
* Validates entity fields
*
* @returns {boolean}
*/
static validate() {
$('.js-validation-error').addClass('d-none');
return this.checkDuplicateSelectedValues() && this.checkRequiredFields();
}
/**
* Checks if there are no duplicate selected values.
*
* @returns {boolean}
* @private
*/
static checkDuplicateSelectedValues() {
const uniqueFields = [];
let valid = true;
$('.js-entity-field select').each(function () {
const value = $(this).val();
if (value === 'no') {
return;
}
if ($.inArray(value, uniqueFields) !== -1) {
valid = false;
$('.js-duplicate-columns-warning').removeClass('d-none');
return;
}
uniqueFields.push(value);
});
return valid;
}
/**
* Checks if all required fields are selected.
*
* @returns {boolean}
* @private
*/
static checkRequiredFields() {
const requiredImportFields = $('.js-import-data-table').data('required-fields');
/* eslint-disable-next-line */
for (const key in requiredImportFields) {
if ($(`option[value="${requiredImportFields[key]}"]:selected`).length === 0) {
$('.js-missing-column-warning').removeClass('d-none');
$('.js-missing-column').text($(`option[value="${requiredImportFields[key]}"]:first`).text());
return false;
}
}
return true;
}
}

View File

@@ -0,0 +1,100 @@
/**
* 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)
*/
/**
* Class ImportBatchSizeCalculator calculates the import batch size.
* Import batch size is the maximum number of records that
* the import should handle in one batch.
*/
export default class ImportBatchSizeCalculator {
constructor() {
// Target execution time in milliseconds.
this.targetExecutionTime = 5000;
// Maximum batch size increase multiplier.
this.maxAcceleration = 4;
// Minimum and maximum import batch sizes.
this.minBatchSize = 5;
this.maxBatchSize = 100;
}
/**
* Marks the start of the import operation.
* Must be executed before starting the import,
* to be able to calculate the import batch size later on.
*/
markImportStart() {
this.importStartTime = new Date().getTime();
}
/**
* Marks the end of the import operation.
* Must be executed after the import operation finishes,
* to be able to calculate the import batch size later on.
*/
markImportEnd() {
this.actualExecutionTime = new Date().getTime() - this.importStartTime;
}
/**
* Calculates how much the import execution time can be increased to still be acceptable.
*
* @returns {number}
* @private
*/
calculateAcceleration() {
return Math.min(this.maxAcceleration, this.targetExecutionTime / this.actualExecutionTime);
}
/**
* Calculates the recommended import batch size.
*
* @param {number} currentBatchSize current import batch size
* @param {number} maxBatchSize greater than zero, the batch size that shouldn't be exceeded
*
* @returns {number} recommended import batch size
*/
calculateBatchSize(currentBatchSize, maxBatchSize = 0) {
if (!this.importStartTime) {
throw new Error('Import start is not marked.');
}
if (!this.actualExecutionTime) {
throw new Error('Import end is not marked.');
}
const candidates = [
this.maxBatchSize,
Math.max(this.minBatchSize, Math.floor(currentBatchSize * this.calculateAcceleration())),
];
if (maxBatchSize > 0) {
candidates.push(maxBatchSize);
}
return Math.min(...candidates);
}
}

View File

@@ -0,0 +1,69 @@
/**
* 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 ImportMatchConfiguration from './ImportMatchConfiguration';
import ImportDataTable from './ImportDataTable';
import EntityFieldsValidator from './EntityFieldsValidator';
import Importer from './Importer';
export default class ImportDataPage {
constructor() {
new ImportMatchConfiguration();
new ImportDataTable();
this.importer = new Importer();
$(document).on('click', '.js-process-import', (e) => this.importHandler(e));
$(document).on('click', '.js-abort-import', () => this.importer.requestCancelImport());
$(document).on('click', '.js-close-modal', () => this.importer.progressModal.hide());
$(document).on('click', '.js-continue-import', () => this.importer.continueImport());
}
/**
* Import process event handler
*/
importHandler(e) {
e.preventDefault();
if (!EntityFieldsValidator.validate()) {
return;
}
const configuration = {};
// Collect the configuration from the form into an array.
$('.import-data-configuration-form').find(
'#skip, select[name^=type_value], #csv, #iso_lang, #entity,'
+ '#truncate, #match_ref, #regenerate, #forceIDs, #sendemail,'
+ '#separator, #multiple_value_separator',
).each((index, $input) => {
configuration[$($input).attr('name')] = $($input).val();
});
this.importer.import(
$('.js-import-process-button').data('import_url'),
configuration,
);
}
}

View File

@@ -0,0 +1,174 @@
/**
* 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)
*/
const {$} = window;
const $importDataTable = $('.js-import-data-table');
/**
* Pagination directions - forward and backward.
*/
const FORWARD = 'forward';
const BACKWARD = 'backward';
export default class ImportDataTable {
constructor() {
this.numberOfColumnsPerPage = this.getNumberOfVisibleColumns();
this.totalNumberOfColumns = this.getTotalNumberOfColumns();
$('.js-import-next-page').on('click', () => this.importNextPageHandler());
$('.js-import-previous-page').on('click', () => this.importPreviousPageHandler());
}
/**
* Handle the next page action in import data table.
*/
importNextPageHandler() {
this.importPaginationHandler(FORWARD);
}
/**
* Handle the previous page action in import data table.
*/
importPreviousPageHandler() {
this.importPaginationHandler(BACKWARD);
}
/**
* Handle the forward and back buttons actions in the import table.
*
* @param {string} direction
* @private
*/
importPaginationHandler(direction) {
const $currentPageElements = $importDataTable.find('th:visible,td:visible');
const $oppositePaginationButton = direction === FORWARD ? $('.js-import-next-page') : $('.js-import-previous-page');
let lastVisibleColumnFound = false;
let numberOfVisibleColumns = 0;
let $tableColumns = $importDataTable.find('th');
if (direction === BACKWARD) {
// If going backward - reverse the table columns array and use the same logic as forward
$tableColumns = $($tableColumns.toArray().reverse());
}
/* eslint-disable-next-line */
for (const index in $tableColumns) {
if (Number.isNaN(index)) {
// Reached the last column - hide the opposite pagination button
this.hide($oppositePaginationButton);
break;
}
// Searching for last visible column
if ($($tableColumns[index]).is(':visible')) {
lastVisibleColumnFound = true;
/* eslint-disable-next-line no-continue */
continue;
}
// If last visible column was found - show the column after it
if (lastVisibleColumnFound) {
// If going backward, the column index must be counted from the last element
const showColumnIndex = direction === BACKWARD ? this.totalNumberOfColumns - 1 - index : index;
this.showTableColumnByIndex(showColumnIndex);
numberOfVisibleColumns += 1;
// If number of visible columns per page is already reached - break the loop
if (numberOfVisibleColumns >= this.numberOfColumnsPerPage) {
this.hide($oppositePaginationButton);
break;
}
}
}
// Hide all the columns from previous page
this.hide($currentPageElements);
// If the first column in the table is not visible - show the "previous" pagination arrow
if (!$importDataTable.find('th:first').is(':visible')) {
this.show($('.js-import-previous-page'));
}
// If the last column in the table is not visible - show the "next" pagination arrow
if (!$importDataTable.find('th:last').is(':visible')) {
this.show($('.js-import-next-page'));
}
}
/**
* Gets the number of currently visible columns in the import data table.
*
* @returns {number}
* @private
*/
getNumberOfVisibleColumns() {
return $importDataTable.find('th:visible').length;
}
/**
* Gets the total number of columns in the import data table.
*
* @returns {number}
* @private
*/
getTotalNumberOfColumns() {
return $importDataTable.find('th').length;
}
/**
* Hide the elements.
*
* @param $elements
* @private
*/
hide($elements) {
$elements.addClass('d-none');
}
/**
* Show the elements.
*
* @param $elements
* @private
*/
show($elements) {
$elements.removeClass('d-none');
}
/**
* Shows a column from import data table by given index
*
* @param columnIndex
* @private
*/
showTableColumnByIndex(columnIndex) {
// Increasing the index because nth-child calculates from 1 and index starts from 0
const colIndex = columnIndex + 1;
this.show($importDataTable.find(`th:nth-child(${colIndex})`));
this.show($importDataTable.find('tbody > tr').find(`td:nth-child(${colIndex})`));
}
}

View File

@@ -0,0 +1,176 @@
/**
* 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)
*/
const {$} = window;
/**
* Class is responsible for import match configuration
* in Advanced parameters -> Import -> step 2 form.
*/
export default class ImportMatchConfiguration {
/**
* Initializes all the processes related with import matches.
*/
constructor() {
this.loadEvents();
}
/**
* Loads all events for data match configuration.
*/
loadEvents() {
$(document).on('click', '.js-save-import-match', (event) => this.save(event));
$(document).on('click', '.js-load-import-match', (event) => this.load(event));
$(document).on('click', '.js-delete-import-match', (event) => this.delete(event));
}
/**
* Save the import match configuration.
*/
save(event) {
event.preventDefault();
const ajaxUrl = $('.js-save-import-match').attr('data-url');
const formData = $('.import-data-configuration-form').serialize();
$.ajax({
type: 'POST',
url: ajaxUrl,
data: formData,
}).then((response) => {
if (typeof response.errors !== 'undefined' && response.errors.length) {
this.showErrorPopUp(response.errors);
} else if (response.matches.length > 0) {
const $dataMatchesDropdown = this.matchesDropdown;
Object.values(response.matches).forEach((resp) => {
const $existingMatch = $dataMatchesDropdown.find(`option[value=${resp.id_import_match}]`);
// If match already exists with same id - do nothing
if ($existingMatch.length > 0) {
return;
}
// Append the new option to the matches dropdown
this.appendOptionToDropdown(
$dataMatchesDropdown,
resp.name,
resp.id_import_match,
);
});
}
});
}
/**
* Load the import match.
*/
load(event) {
event.preventDefault();
const ajaxUrl = $('.js-load-import-match').attr('data-url');
$.ajax({
type: 'GET',
url: ajaxUrl,
data: {
import_match_id: this.matchesDropdown.val(),
},
}).then((response) => {
if (response) {
this.rowsSkipInput.val(response.skip);
const entityFields = response.match.split('|');
Object.keys(entityFields).forEach((i) => {
$(`#type_value_${i}`).val(entityFields[i]);
});
}
});
}
/**
* Delete the import match.
*/
delete(event) {
event.preventDefault();
const ajaxUrl = $('.js-delete-import-match').attr('data-url');
const $dataMatchesDropdown = this.matchesDropdown;
const selectedMatchId = $dataMatchesDropdown.val();
$.ajax({
type: 'DELETE',
url: ajaxUrl,
data: {
import_match_id: selectedMatchId,
},
}).then(() => {
// Delete the match option from matches dropdown
$dataMatchesDropdown.find(`option[value=${selectedMatchId}]`).remove();
});
}
/**
* Appends a new option to given dropdown.
*
* @param {jQuery} $dropdown
* @param {String} optionText
* @param {String} optionValue
* @private
*/
appendOptionToDropdown($dropdown, optionText, optionValue) {
const $newOption = $('<option>');
$newOption.attr('value', optionValue);
$newOption.text(optionText);
$dropdown.append($newOption);
}
/**
* Shows error messages in the native error pop-up.
*
* @param {Array} errors
* @private
*/
showErrorPopUp(errors) {
alert(errors);
}
/**
* Get the matches dropdown.
*
* @returns {*|HTMLElement}
*/
get matchesDropdown() {
return $('#matches');
}
/**
* Get the "rows to skip" input.
*
* @returns {*|HTMLElement}
*/
get rowsSkipInput() {
return $('#skip');
}
}

View File

@@ -0,0 +1,318 @@
/**
* 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)
*/
export default class ImportProgressModal {
/**
* Show the import progress modal window.
*/
show() {
this.progressModal.modal('show');
}
/**
* Hide the import progress modal window.
*/
hide() {
this.progressModal.modal('hide');
}
/**
* Updates the import progressbar.
*
* @param {number} completed number of completed items.
* @param {number} total number of items in total.
*/
updateProgress(completed, total) {
const progressCompleted = parseInt(completed, 10);
const progressTotal = parseInt(total, 10);
const $progressBar = this.progressBar;
const percentage = (progressCompleted / progressTotal) * 100;
$progressBar.css('width', `${percentage}%`);
$progressBar.find('> span').text(`${progressCompleted}/${progressTotal}`);
}
/**
* Updates the progress bar label.
*
* @param {String} label if not provided - will use the default label
*/
updateProgressLabel(label) {
this.progressLabel.text(label);
}
/**
* Sets the progress label to "importing"
*/
setImportingProgressLabel() {
this.updateProgressLabel(this.progressModal.find('.modal-body').data('importing-label'));
}
/**
* Sets the progress label to "imported"
*/
setImportedProgressLabel() {
this.updateProgressLabel(this.progressModal.find('.modal-body').data('imported-label'));
}
/**
* Shows information messages in the import modal.
*
* @param {Array} messages
*/
showInfoMessages(messages) {
this.showMessages(this.infoMessageBlock, messages);
}
/**
* Shows warning messages in the import modal.
*
* @param {Array} messages
*/
showWarningMessages(messages) {
this.showMessages(this.warningMessageBlock, messages);
}
/**
* Shows error messages in the import modal.
*
* @param {Array} messages
*/
showErrorMessages(messages) {
this.showMessages(this.errorMessageBlock, messages);
}
/**
* Shows the import success message.
*/
showSuccessMessage() {
this.successMessageBlock.removeClass('d-none');
}
/**
* Shows the post size limit warning message.
*
* @param {number} postSizeValue to be shown in the warning
*/
showPostLimitMessage(postSizeValue) {
this.postLimitMessage.find('#post_limit_value').text(postSizeValue);
this.postLimitMessage.removeClass('d-none');
}
/**
* Show messages in given message block.
*
* @param {jQuery} $messageBlock
* @param {Array} messages
* @private
*/
showMessages($messageBlock, messages) {
let showMessagesBlock = false;
Object.values(messages).forEach((msg) => {
// Indicate that the messages block should be displayed
showMessagesBlock = true;
const message = $('<div>');
message.text(msg);
message.addClass('message');
$messageBlock.append(message);
});
if (showMessagesBlock) {
$messageBlock.removeClass('d-none');
}
}
/**
* Show the "Ignore warnings and continue" button.
*/
showContinueImportButton() {
this.continueImportButton.removeClass('d-none');
}
/**
* Hide the "Ignore warnings and continue" button.
*/
hideContinueImportButton() {
this.continueImportButton.addClass('d-none');
}
/**
* Show the "Abort import" button.
*/
showAbortImportButton() {
this.abortImportButton.removeClass('d-none');
}
/**
* Hide the "Abort import" button.
*/
hideAbortImportButton() {
this.abortImportButton.addClass('d-none');
}
/**
* Show the "Close" button of the modal.
*/
showCloseModalButton() {
this.closeModalButton.removeClass('d-none');
}
/**
* Hide the "Close" button.
*/
hideCloseModalButton() {
this.closeModalButton.addClass('d-none');
}
/**
* Clears all warning messages from the modal.
*/
clearWarningMessages() {
this.warningMessageBlock.addClass('d-none').find('.message').remove();
}
/**
* Reset the modal - resets progress bar and removes messages.
*/
reset() {
// Reset the progress bar
this.updateProgress(0, 0);
this.updateProgressLabel(this.progressLabel.attr('default-value'));
// Hide action buttons
this.continueImportButton.addClass('d-none');
this.abortImportButton.addClass('d-none');
this.closeModalButton.addClass('d-none');
// Remove messages
this.successMessageBlock.addClass('d-none');
this.infoMessageBlock.addClass('d-none').find('.message').remove();
this.errorMessageBlock.addClass('d-none').find('.message').remove();
this.postLimitMessage.addClass('d-none');
this.clearWarningMessages();
}
/**
* Gets import progress modal.
*
* @returns {jQuery}
*/
get progressModal() {
return $('#import_progress_modal');
}
/**
* Gets import progress bar.
*
* @returns {jQuery}
*/
get progressBar() {
return this.progressModal.find('.progress-bar');
}
/**
* Gets information messages block.
*
* @returns {jQuery|HTMLElement}
*/
get infoMessageBlock() {
return $('.js-import-info');
}
/**
* Gets error messages block.
*
* @returns {jQuery|HTMLElement}
*/
get errorMessageBlock() {
return $('.js-import-errors');
}
/**
* Gets warning messages block.
*
* @returns {jQuery|HTMLElement}
*/
get warningMessageBlock() {
return $('.js-import-warnings');
}
/**
* Gets success messages block.
*
* @returns {jQuery|HTMLElement}
*/
get successMessageBlock() {
return $('.js-import-success');
}
/**
* Gets post limit message.
*
* @returns {jQuery|HTMLElement}
*/
get postLimitMessage() {
return $('.js-post-limit-warning');
}
/**
* Gets "Ignore warnings and continue" button.
*
* @returns {jQuery|HTMLElement}
*/
get continueImportButton() {
return $('.js-continue-import');
}
/**
* Gets "Abort import" button.
*
* @returns {jQuery|HTMLElement}
*/
get abortImportButton() {
return $('.js-abort-import');
}
/**
* Gets "Close" button of the modal.
*
* @returns {jQuery|HTMLElement}
*/
get closeModalButton() {
return $('.js-close-modal');
}
/**
* Gets progress bar label.
*
* @returns {jQuery|HTMLElement}
*/
get progressLabel() {
return $('#import_progress_bar').find('.progress-details-text');
}
}

View File

@@ -0,0 +1,302 @@
/**
* 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 ImportProgressModal from './ImportProgressModal';
import ImportBatchSizeCalculator from './ImportBatchSizeCalculator';
import PostSizeChecker from './PostSizeChecker';
export default class Importer {
constructor() {
this.configuration = {};
this.progressModal = new ImportProgressModal();
this.batchSizeCalculator = new ImportBatchSizeCalculator();
this.postSizeChecker = new PostSizeChecker();
// Default number of rows in one batch of the import.
this.defaultBatchSize = 5;
}
/**
* Process the import.
*
* @param {String} importUrl url of the controller, processing the import.
* @param {Object} configuration import configuration.
*/
import(importUrl, configuration) {
this.mergeConfiguration(configuration);
this.importUrl = importUrl;
// Total number of rows to be imported.
this.totalRowsCount = 0;
// Flags that mark that there were warnings or errors during import.
this.hasWarnings = false;
this.hasErrors = false;
// Resetting the import progress modal and showing it.
this.progressModal.reset();
this.progressModal.show();
// Starting the import with default batch size, which is adjusted for next iterations.
this.ajaxImport(0, this.defaultBatchSize);
}
/**
* Process the ajax import request.
*
* @param {number} offset row number, from which the import job will start processing data.
* @param {number} batchSize batch size of this import job.
* @param {boolean} validateOnly whether the data should be only validated, if false - the data will be imported.
* @param {Object} recurringVariables variables which are recurring between import batch jobs.
* @private
*/
ajaxImport(offset, batchSize, validateOnly = true, recurringVariables = {}) {
this.mergeConfiguration({
offset,
limit: batchSize,
validateOnly: validateOnly ? 1 : 0,
crossStepsVars: JSON.stringify(recurringVariables),
});
this.onImportStart();
$.post({
url: this.importUrl,
dataType: 'json',
data: this.configuration,
success: (response) => {
if (this.importCancelRequested) {
this.cancelImport();
return false;
}
const hasErrors = response.errors && response.errors.length;
const hasWarnings = response.warnings && response.warnings.length;
const hasNotices = response.notices && response.notices.length;
if (response.totalCount !== undefined && response.totalCount) {
// The total rows count is retrieved only in the first batch response.
this.totalRowsCount = response.totalCount;
}
// Update import progress.
this.progressModal.updateProgress(response.doneCount, this.totalRowsCount);
if (!validateOnly) {
// Set the progress label to "Importing".
this.progressModal.setImportingProgressLabel();
}
// Information messages are not shown during validation.
if (!validateOnly && hasNotices) {
this.progressModal.showInfoMessages(response.notices);
}
if (hasErrors) {
this.hasErrors = true;
this.progressModal.showErrorMessages(response.errors);
// If there are errors and it's not validation step - stop the import.
// If it's validation step - we will show all errors once it finishes.
if (!validateOnly) {
this.onImportStop();
return false;
}
} else if (hasWarnings) {
this.hasWarnings = true;
this.progressModal.showWarningMessages(response.warnings);
}
if (!response.isFinished) {
// Marking the end of import operation.
this.batchSizeCalculator.markImportEnd();
// Calculate next import batch size and offset.
const nextOffset = offset + batchSize;
const nextBatchSize = this.batchSizeCalculator.calculateBatchSize(batchSize, this.totalRowsCount);
// Showing a warning if post size limit is about to be reached.
if (this.postSizeChecker.isReachingPostSizeLimit(response.postSizeLimit, response.nextPostSize)) {
this.progressModal.showPostLimitMessage(
this.postSizeChecker.getRequiredPostSizeInMegabytes(response.nextPostSize),
);
}
// Run the import again for the next batch.
return this.ajaxImport(
nextOffset,
nextBatchSize,
validateOnly,
response.crossStepsVariables,
);
}
// All import batches are finished successfully.
// If it was only validating the import data until this point,
// we have to run the data import now.
if (validateOnly) {
// If errors occurred during validation - stop the import.
if (this.hasErrors) {
this.onImportStop();
return false;
}
if (this.hasWarnings) {
// Show the button to ignore warnings.
this.progressModal.showContinueImportButton();
this.onImportStop();
return false;
}
// Update the progress bar to 100%.
this.progressModal.updateProgress(this.totalRowsCount, this.totalRowsCount);
// Continue with the data import.
return this.ajaxImport(0, this.defaultBatchSize, false);
}
// Import is completely finished.
return this.onImportFinish();
},
error: (XMLHttpRequest, textStatus) => {
let txt = textStatus;
if (txt === 'parsererror') {
txt = 'Technical error: Unexpected response returned by server. Import stopped.';
}
this.onImportStop();
this.progressModal.showErrorMessages([txt]);
},
});
}
/**
* Continue the import when it was stopped.
*/
continueImport() {
if (!this.configuration) {
throw new Error('Missing import configuration. Make sure the import had started before continuing.');
}
this.progressModal.hideContinueImportButton();
this.progressModal.hideCloseModalButton();
this.progressModal.clearWarningMessages();
this.ajaxImport(0, this.defaultBatchSize, false);
}
/**
* Set the import configuration.
*
* @param importConfiguration
*/
set configuration(importConfiguration) {
this.importConfiguration = importConfiguration;
}
/**
* Get the import configuration.
*
* @returns {*}
*/
get configuration() {
return this.importConfiguration;
}
/**
* Set progress modal.
*
* @param {ImportProgressModal} modal
*/
set progressModal(modal) {
this.modal = modal;
}
/**
* Get progress modal.
*
* @returns {ImportProgressModal}
*/
get progressModal() {
return this.modal;
}
/**
* Request import cancellation.
* Import operation will be cancelled at next iteration when requested.
*/
requestCancelImport() {
this.importCancelRequested = true;
}
/**
* Merge given configuration into current import configuration.
*
* @param {Object} configuration
* @private
*/
mergeConfiguration(configuration) {
this.importConfiguration = {...this.importConfiguration, ...configuration};
}
/**
* Cancel the import process.
* @private
*/
cancelImport() {
this.progressModal.hide();
this.importCancelRequested = false;
}
/**
* Additional actions when import is stopped.
* @private
*/
onImportStop() {
this.progressModal.showCloseModalButton();
this.progressModal.hideAbortImportButton();
}
/**
* Additional actions when import is finished.
* @private
*/
onImportFinish() {
this.onImportStop();
this.progressModal.showSuccessMessage();
this.progressModal.setImportedProgressLabel();
this.progressModal.updateProgress(this.totalRowsCount, this.totalRowsCount);
}
/**
* Additional actions when import is starting.
* @private
*/
onImportStart() {
// Marking the start of import operation.
this.batchSizeCalculator.markImportStart();
this.progressModal.showAbortImportButton();
}
}

View File

@@ -0,0 +1,54 @@
/**
* 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)
*/
export default class PostSizeChecker {
constructor() {
// How close can we get to the post size limit. 0.9 means 90%.
this.postSizeLimitThreshold = 0.9;
}
/**
* Check if given postSizeLimit is reaching the required post size
*
* @param {number} postSizeLimit
* @param {number} requiredPostSize
*
* @returns {boolean}
*/
isReachingPostSizeLimit(postSizeLimit, requiredPostSize) {
return requiredPostSize >= postSizeLimit * this.postSizeLimitThreshold;
}
/**
* Get required post size in megabytes.
*
* @param {number} requiredPostSize
*
* @returns {number}
*/
getRequiredPostSizeInMegabytes(requiredPostSize) {
return parseInt(requiredPostSize / (1024 * 1024), 10);
}
}

View File

@@ -0,0 +1,32 @@
/**
* 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 ImportDataPage from './ImportDataPage';
const {$} = window;
$(() => {
new ImportDataPage();
});

View File

@@ -0,0 +1,203 @@
/**
* 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)
*/
const {$} = window;
const entityCategories = 0;
const entityProducts = 1;
const entityCombinations = 2;
const entityCustomers = 3;
const entityAddresses = 4;
const entityBrands = 5;
const entitySuppliers = 6;
const entityAlias = 7;
const entityStoreContacts = 8;
export default class FormFieldToggle {
constructor() {
$('.js-entity-select').on('change', () => this.toggleForm());
this.toggleForm();
}
toggleForm() {
const selectedOption = $('#entity').find('option:selected');
const selectedEntity = parseInt(selectedOption.val(), 10);
const entityName = selectedOption.text().toLowerCase();
this.toggleEntityAlert(selectedEntity);
this.toggleFields(selectedEntity, entityName);
this.loadAvailableFields(selectedEntity);
}
/**
* Toggle alert warning for selected import entity
*
* @param {int} selectedEntity
*/
toggleEntityAlert(selectedEntity) {
const $alert = $('.js-entity-alert');
if ([entityCategories, entityProducts].includes(selectedEntity)) {
$alert.show();
} else {
$alert.hide();
}
}
/**
* Toggle available options for selected entity
*
* @param {int} selectedEntity
* @param {string} entityName
*/
toggleFields(selectedEntity, entityName) {
const $truncateFormGroup = $('.js-truncate-form-group');
const $matchRefFormGroup = $('.js-match-ref-form-group');
const $regenerateFormGroup = $('.js-regenerate-form-group');
const $forceIdsFormGroup = $('.js-force-ids-form-group');
const $entityNamePlaceholder = $('.js-entity-name');
if (entityStoreContacts === selectedEntity) {
$truncateFormGroup.hide();
} else {
$truncateFormGroup.show();
}
if ([entityProducts, entityCombinations].includes(selectedEntity)) {
$matchRefFormGroup.show();
} else {
$matchRefFormGroup.hide();
}
if ([
entityCategories,
entityProducts,
entityBrands,
entitySuppliers,
entityStoreContacts,
].includes(selectedEntity)
) {
$regenerateFormGroup.show();
} else {
$regenerateFormGroup.hide();
}
if ([
entityCategories,
entityProducts,
entityCustomers,
entityAddresses,
entityBrands,
entitySuppliers,
entityStoreContacts,
entityAlias,
].includes(selectedEntity)
) {
$forceIdsFormGroup.show();
} else {
$forceIdsFormGroup.hide();
}
$entityNamePlaceholder.html(entityName);
}
/**
* Load available fields for given entity
*
* @param {int} entity
*/
loadAvailableFields(entity) {
const $availableFields = $('.js-available-fields');
$.ajax({
url: $availableFields.data('url'),
data: {
entity,
},
dataType: 'json',
}).then((response) => {
this.removeAvailableFields($availableFields);
for (let i = 0; i < response.length; i += 1) {
this.appendAvailableField(
$availableFields,
response[i].label + (response[i].required ? '*' : ''),
response[i].description,
);
}
$availableFields.find('[data-toggle="popover"]').popover();
});
}
/**
* Remove available fields content from given container.
*
* @param {jQuery} $container
* @private
*/
removeAvailableFields($container) {
$container.find('[data-toggle="popover"]').popover('hide');
$container.empty();
}
/**
* Append a help box to given field.
*
* @param {jQuery} $field
* @param {String} helpBoxContent
* @private
*/
appendHelpBox($field, helpBoxContent) {
const $helpBox = $('.js-available-field-popover-template').clone();
$helpBox.attr('data-content', helpBoxContent);
$helpBox.removeClass('js-available-field-popover-template d-none');
$field.append($helpBox);
}
/**
* Append available field to given container.
*
* @param {jQuery} $appendTo field will be appended to this container.
* @param {String} fieldText
* @param {String} helpBoxContent
* @private
*/
appendAvailableField($appendTo, fieldText, helpBoxContent) {
const $field = $('.js-available-field-template').clone();
$field.text(fieldText);
if (helpBoxContent) {
// Append help box next to the field
this.appendHelpBox($field, helpBoxContent);
}
$field.removeClass('js-available-field-template d-none');
$field.appendTo($appendTo);
}
}

View File

@@ -0,0 +1,274 @@
/**
* 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 FormFieldToggle from './FormFieldToggle';
const {$} = window;
export default class ImportPage {
constructor() {
new FormFieldToggle();
$('.js-from-files-history-btn').on('click', () => this.showFilesHistoryHandler());
$('.js-close-files-history-block-btn').on('click', () => this.closeFilesHistoryHandler());
$('#fileHistoryTable').on('click', '.js-use-file-btn', (event) => this.useFileFromFilesHistory(event));
$('.js-change-import-file-btn').on('click', () => this.changeImportFileHandler());
$('.js-import-file').on('change', () => this.uploadFile());
this.toggleSelectedFile();
this.handleSubmit();
}
/**
* Handle submit and add confirm box in case the toggle button about
* deleting all entities before import is checked
*/
handleSubmit() {
$('.js-import-form').on('submit', function () {
const $this = $(this);
if ($this.find('input[name="truncate"]:checked').val() === '1') {
/* eslint-disable-next-line max-len */
return window.confirm(`${$this.data('delete-confirm-message')} ${$.trim($('#entity > option:selected').text().toLowerCase())}?`);
}
return true;
});
}
/**
* Check if selected file names exists and if so, then display it
*/
toggleSelectedFile() {
const selectFilename = $('#csv').val();
if (selectFilename.length > 0) {
this.showImportFileAlert(selectFilename);
this.hideFileUploadBlock();
}
}
changeImportFileHandler() {
this.hideImportFileAlert();
this.showFileUploadBlock();
}
/**
* Show files history event handler
*/
showFilesHistoryHandler() {
this.showFilesHistory();
this.hideFileUploadBlock();
}
/**
* Close files history event handler
*/
closeFilesHistoryHandler() {
this.closeFilesHistory();
this.showFileUploadBlock();
}
/**
* Show files history block
*/
showFilesHistory() {
$('.js-files-history-block').removeClass('d-none');
}
/**
* Hide files history block
*/
closeFilesHistory() {
$('.js-files-history-block').addClass('d-none');
}
/**
* Prefill hidden file input with selected file name from history
*/
useFileFromFilesHistory(event) {
const filename = $(event.target).closest('.btn-group').data('file');
$('.js-import-file-input').val(filename);
this.showImportFileAlert(filename);
this.closeFilesHistory();
}
/**
* Show alert with imported file name
*/
showImportFileAlert(filename) {
$('.js-import-file-alert').removeClass('d-none');
$('.js-import-file').text(filename);
}
/**
* Hides selected import file alert
*/
hideImportFileAlert() {
$('.js-import-file-alert').addClass('d-none');
}
/**
* Hides import file upload block
*/
hideFileUploadBlock() {
$('.js-file-upload-form-group').addClass('d-none');
}
/**
* Hides import file upload block
*/
showFileUploadBlock() {
$('.js-file-upload-form-group').removeClass('d-none');
}
/**
* Make file history button clickable
*/
enableFilesHistoryBtn() {
$('.js-from-files-history-btn').removeAttr('disabled');
}
/**
* Show error message if file uploading failed
*
* @param {string} fileName
* @param {integer} fileSize
* @param {string} message
*/
showImportFileError(fileName, fileSize, message) {
const $alert = $('.js-import-file-error');
const fileData = `${fileName} (${this.humanizeSize(fileSize)})`;
$alert.find('.js-file-data').text(fileData);
$alert.find('.js-error-message').text(message);
$alert.removeClass('d-none');
}
/**
* Hide file uploading error
*/
hideImportFileError() {
const $alert = $('.js-import-file-error');
$alert.addClass('d-none');
}
/**
* Show file size in human readable format
*
* @param {int} bytes
*
* @returns {string}
*/
humanizeSize(bytes) {
if (typeof bytes !== 'number') {
return '';
}
if (bytes >= 1000000000) {
return `${(bytes / 1000000000).toFixed(2)} GB`;
}
if (bytes >= 1000000) {
return `${(bytes / 1000000).toFixed(2)} MB`;
}
return `${(bytes / 1000).toFixed(2)} KB`;
}
/**
* Upload selected import file
*/
uploadFile() {
this.hideImportFileError();
const $input = $('#file');
const uploadedFile = $input.prop('files')[0];
const maxUploadSize = $input.data('max-file-upload-size');
if (maxUploadSize < uploadedFile.size) {
this.showImportFileError(uploadedFile.name, uploadedFile.size, 'File is too large');
return;
}
const data = new FormData();
data.append('file', uploadedFile);
$.ajax({
type: 'POST',
url: $('.js-import-form').data('file-upload-url'),
data,
cache: false,
contentType: false,
processData: false,
}).then((response) => {
if (response.error) {
this.showImportFileError(uploadedFile.name, uploadedFile.size, response.error);
return;
}
const filename = response.file.name;
$('.js-import-file-input').val(filename);
this.showImportFileAlert(filename);
this.hideFileUploadBlock();
this.addFileToHistoryTable(filename);
this.enableFilesHistoryBtn();
});
}
/**
* Renders new row in files history table
*
* @param {string} filename
*/
addFileToHistoryTable(filename) {
const $table = $('#fileHistoryTable');
const baseDeleteUrl = $table.data('delete-file-url');
const deleteUrl = `${baseDeleteUrl}&filename=${encodeURIComponent(filename)}`;
const baseDownloadUrl = $table.data('download-file-url');
const downloadUrl = `${baseDownloadUrl}&filename=${encodeURIComponent(filename)}`;
const $template = $table.find('tr:first').clone();
$template.removeClass('d-none');
$template.find('td:first').text(filename);
$template.find('.btn-group').attr('data-file', filename);
$template.find('.js-delete-file-btn').attr('href', deleteUrl);
$template.find('.js-download-file-btn').attr('href', downloadUrl);
$table.find('tbody').append($template);
const filesNumber = $table.find('tr').length - 1;
$('.js-files-history-number').text(filesNumber);
}
}

View File

@@ -0,0 +1,32 @@
/**
* 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 ImportPage from './ImportPage';
const {$} = window;
$(() => {
new ImportPage();
});

View File

@@ -0,0 +1,62 @@
/**
* 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)
*/
const {$} = window;
class HookStatusHandler {
constructor() {
const self = this;
self.$hookStatus = $('.hook-switch-action');
self.$modulePositionsForm = $('#module-positions-form');
self.$hookStatus.on('change', function (e) {
e.stopImmediatePropagation();
self.toogleHookStatus($(this));
});
}
/**
* Toogle hooks status
*/
toogleHookStatus($hookElement) {
$.ajax({
type: 'POST',
headers: {'cache-control': 'no-cache'},
url: this.$modulePositionsForm.data('togglestatus-url'),
data: {hookId: $hookElement.data('hook-id')},
success(data) {
if (data.status) {
window.showSuccessMessage(data.message);
const $hookModulesList = $hookElement.closest('.hook-panel').find('.module-list, .module-list-disabled');
$hookModulesList.fadeTo(500, data.hook_status ? 1 : 0.5);
} else {
window.showErrorMessage(data.message);
}
},
});
}
}
export default HookStatusHandler;

View File

@@ -0,0 +1,34 @@
/**
* 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 PositionsListHandler from './positions-list-handler';
import HookStatusHandler from './hook-status-handler';
const {$} = window;
$(() => {
new PositionsListHandler();
new HookStatusHandler();
});

View File

@@ -0,0 +1,290 @@
/**
* 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)
*/
const {$} = window;
class PositionsListHandler {
constructor() {
if ($('#position-filters').length === 0) {
return;
}
const self = this;
self.$panelSelection = $('#modules-position-selection-panel');
self.$panelSelectionSingleSelection = $('#modules-position-single-selection');
self.$panelSelectionMultipleSelection = $('#modules-position-multiple-selection');
self.$panelSelectionOriginalY = self.$panelSelection.offset().top;
self.$showModules = $('#show-modules');
self.$modulesList = $('.modules-position-checkbox');
self.$hookPosition = $('#hook-position');
self.$hookSearch = $('#hook-search');
self.$modulePositionsForm = $('#module-positions-form');
self.$moduleUnhookButton = $('#unhook-button-position-bottom');
self.$moduleButtonsUpdate = $('.module-buttons-update .btn');
self.handleList();
self.handleSortable();
$('input[name="general[enable_tos]"]').on('change', () => self.handle());
}
/**
* Handle all events for Design -> Positions List
*/
handleList() {
const self = this;
$(window).on('scroll', () => {
const $scrollTop = $(window).scrollTop();
self.$panelSelection.css(
'top',
$scrollTop < 20 ? 0 : $scrollTop - self.$panelSelectionOriginalY,
);
});
self.$modulesList.on('change', () => {
const $checkedCount = self.$modulesList.filter(':checked').length;
if ($checkedCount === 0) {
self.$moduleUnhookButton.hide();
self.$panelSelection.hide();
self.$panelSelectionSingleSelection.hide();
self.$panelSelectionMultipleSelection.hide();
} else if ($checkedCount === 1) {
self.$moduleUnhookButton.show();
self.$panelSelection.show();
self.$panelSelectionSingleSelection.show();
self.$panelSelectionMultipleSelection.hide();
} else {
self.$moduleUnhookButton.show();
self.$panelSelection.show();
self.$panelSelectionSingleSelection.hide();
self.$panelSelectionMultipleSelection.show();
$('#modules-position-selection-count').html($checkedCount);
}
});
self.$panelSelection.find('button').click(() => {
$('button[name="unhookform"]').trigger('click');
});
self.$hooksList = [];
$('section.hook-panel .hook-name').each(function () {
const $this = $(this);
self.$hooksList.push({
title: $this.html(),
element: $this,
container: $this.parents('.hook-panel'),
});
});
self.$showModules.select2();
self.$showModules.on('change', () => {
self.modulesPositionFilterHooks();
});
self.$hookPosition.on('change', () => {
self.modulesPositionFilterHooks();
});
self.$hookSearch.on('input', () => {
self.modulesPositionFilterHooks();
});
self.$hookSearch.on('keypress', (e) => {
const keyCode = e.keyCode || e.which;
return keyCode !== 13;
});
$('.hook-checker').on('click', function () {
$(`.hook${$(this).data('hook-id')}`).prop('checked', $(this).prop('checked'));
});
self.$modulesList.on('click', function () {
$(`#Ghook${$(this).data('hook-id')}`).prop(
'checked',
$(`.hook${$(this).data('hook-id')}:not(:checked)`).length === 0,
);
});
self.$moduleButtonsUpdate.on('click', function () {
const $btn = $(this);
const $current = $btn.closest('.module-item');
let $destination;
if ($btn.data('way')) {
$destination = $current.next('.module-item');
} else {
$destination = $current.prev('.module-item');
}
if ($destination.length === 0) {
return false;
}
if ($btn.data('way')) {
$current.insertAfter($destination);
} else {
$current.insertBefore($destination);
}
self.updatePositions(
{
hookId: $btn.data('hook-id'),
moduleId: $btn.data('module-id'),
way: $btn.data('way'),
positions: [],
},
$btn.closest('ul'),
);
return false;
});
}
/**
* Handle sortable events
*/
handleSortable() {
const self = this;
$('.sortable').sortable({
forcePlaceholderSize: true,
start(e, ui) {
$(this).data('previous-index', ui.item.index());
},
update($event, ui) {
const [hookId, moduleId] = ui.item.attr('id').split('_');
const $data = {
hookId,
moduleId,
way: ($(this).data('previous-index') < ui.item.index()) ? 1 : 0,
positions: [],
};
self.updatePositions(
$data,
$($event.target),
);
},
});
}
updatePositions($data, $list) {
const self = this;
$.each($list.children(), (index, element) => {
$data.positions.push($(element).attr('id'));
});
$.ajax({
type: 'POST',
headers: {'cache-control': 'no-cache'},
url: self.$modulePositionsForm.data('update-url'),
data: $data,
success: () => {
let start = 0;
$.each($list.children(), (index, element) => {
start += 1;
$(element).find('.index-position').html(start);
});
window.showSuccessMessage(window.update_success_msg);
},
});
}
/**
* Filter hooks / modules search and everything
* about hooks positions.
*/
modulesPositionFilterHooks() {
const self = this;
const $hookName = self.$hookSearch.val();
const $moduleId = self.$showModules.val();
const $regex = new RegExp(`(${$hookName})`, 'gi');
for (let $id = 0; $id < self.$hooksList.length; $id += 1) {
self.$hooksList[$id].container.toggle($hookName === '' && $moduleId === 'all');
self.$hooksList[$id].element.html(self.$hooksList[$id].title);
self.$hooksList[$id].container.find('.module-item').removeClass('highlight');
}
// Have select a hook name or a module id
if ($hookName !== '' || $moduleId !== 'all') {
// Prepare set of matched elements
let $hooksToShowFromModule = $();
let $hooksToShowFromHookName = $();
let $currentHooks;
let $start;
for (let $id = 0; $id < self.$hooksList.length; $id += 1) {
// Prepare highlight when one module is selected
if ($moduleId !== 'all') {
$currentHooks = self.$hooksList[$id].container.find(`.module-position-${$moduleId}`);
if ($currentHooks.length > 0) {
$hooksToShowFromModule = $hooksToShowFromModule.add(self.$hooksList[$id].container);
$currentHooks.addClass('highlight');
}
}
// Prepare highlight when there is a hook name
if ($hookName !== '') {
$start = self.$hooksList[$id].title.toLowerCase().search($hookName.toLowerCase());
if ($start !== -1) {
$hooksToShowFromHookName = $hooksToShowFromHookName.add(self.$hooksList[$id].container);
self.$hooksList[$id].element.html(
self.$hooksList[$id].title.replace(
$regex,
'<span class="highlight">$1</span>',
),
);
}
}
}
// Nothing selected
if ($moduleId === 'all' && $hookName !== '') {
$hooksToShowFromHookName.show();
} else if ($hookName === '' && $moduleId !== 'all') { // Have no hook bug have a module
$hooksToShowFromModule.show();
} else { // Both selected
$hooksToShowFromHookName.filter($hooksToShowFromModule).show();
}
}
if (!self.$hookPosition.prop('checked')) {
for (let $id = 0; $id < self.$hooksList.length; $id += 1) {
if (self.$hooksList[$id].container.is('.hook-position')) {
self.$hooksList[$id].container.hide();
}
}
}
}
}
export default PositionsListHandler;

View File

@@ -0,0 +1,34 @@
/**
* 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 initDatePickers from '@app/utils/datepicker';
import TranslatableInput from '@components/translatable-input';
const {$} = window;
$(() => {
initDatePickers();
new TranslatableInput();
});

View File

@@ -0,0 +1,58 @@
/**
* 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 Grid from '@components/grid/grid';
import ReloadListActionExtension from '@components/grid/extension/reload-list-extension';
import ExportToSqlManagerExtension from '@components/grid/extension/export-to-sql-manager-extension';
import FiltersResetExtension from '@components/grid/extension/filters-reset-extension';
import SortingExtension from '@components/grid/extension/sorting-extension';
import LinkRowActionExtension from '@components/grid/extension/link-row-action-extension';
import SubmitBulkExtension from '@components/grid/extension/submit-bulk-action-extension';
import SubmitRowActionExtension from '@components/grid/extension/action/row/submit-row-action-extension';
import BulkActionCheckboxExtension from '@components/grid/extension/bulk-action-checkbox-extension';
import ChoiceTree from '@components/form/choice-tree';
import ColumnTogglingExtension from '@components/grid/extension/column-toggling-extension';
import FiltersSubmitButtonEnablerExtension
from '@components/grid/extension/filters-submit-button-enabler-extension';
const {$} = window;
$(document).ready(() => {
const grid = new Grid('language');
grid.addExtension(new ReloadListActionExtension());
grid.addExtension(new ExportToSqlManagerExtension());
grid.addExtension(new FiltersResetExtension());
grid.addExtension(new SortingExtension());
grid.addExtension(new LinkRowActionExtension());
grid.addExtension(new SubmitBulkExtension());
grid.addExtension(new SubmitRowActionExtension());
grid.addExtension(new BulkActionCheckboxExtension());
grid.addExtension(new ColumnTogglingExtension());
grid.addExtension(new FiltersSubmitButtonEnablerExtension());
// needed for shop association input in form
new ChoiceTree('#language_shop_association').enableAutoCheckChildren();
});

View File

@@ -0,0 +1,30 @@
/**
* 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)
*/
/* eslint-disable max-len */
export default {
formDefaultCurrency: '#form_default_currency',
};

View File

@@ -0,0 +1,34 @@
/**
* 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 LocalizationPageMap from '@pages/localization/LocalizationPageMap';
const {$} = window;
$(() => {
// Show warning message when currency is changed
$(LocalizationPageMap.formDefaultCurrency).on('change', function () {
alert($(this).data('warning-message'));
});
});

View File

@@ -0,0 +1,46 @@
/**
* 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 Grid from '@components/grid/grid';
import ReloadListActionExtension from '@components/grid/extension/reload-list-extension';
import ExportToSqlManagerExtension from '@components/grid/extension/export-to-sql-manager-extension';
import FiltersResetExtension from '@components/grid/extension/filters-reset-extension';
import SortingExtension from '@components/grid/extension/sorting-extension';
import SubmitGridActionExtension from '@components/grid/extension/submit-grid-action-extension';
import FiltersSubmitButtonEnablerExtension
from '@components/grid/extension/filters-submit-button-enabler-extension';
const {$} = window;
$(() => {
const grid = new Grid('logs');
grid.addExtension(new ReloadListActionExtension());
grid.addExtension(new ExportToSqlManagerExtension());
grid.addExtension(new FiltersResetExtension());
grid.addExtension(new SortingExtension());
grid.addExtension(new SubmitGridActionExtension());
grid.addExtension(new FiltersSubmitButtonEnablerExtension());
});

View File

@@ -0,0 +1,35 @@
/**
* 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)
*/
const {$} = window;
$(() => {
window.prestashop.component.initComponents(
[
'MultistoreConfigField',
'TinyMCEEditor',
],
);
});

View File

@@ -0,0 +1,75 @@
/**
* 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 FormSubmitButton from '@components/form-submit-button';
import Grid from '@components/grid/grid';
import SortingExtension from '@components/grid/extension/sorting-extension';
import FiltersResetExtension from '@components/grid/extension/filters-reset-extension';
import ReloadListActionExtension from '@components/grid/extension/reload-list-extension';
import ColumnTogglingExtension from '@components/grid/extension/column-toggling-extension';
import SubmitRowActionExtension from '@components/grid/extension/action/row/submit-row-action-extension';
import SubmitBulkExtension from '@components/grid/extension/submit-bulk-action-extension';
import BulkActionCheckboxExtension from '@components/grid/extension/bulk-action-checkbox-extension';
import ExportToSqlManagerExtension from '@components/grid/extension/export-to-sql-manager-extension';
import FiltersSubmitButtonEnablerExtension
from '@components/grid/extension/filters-submit-button-enabler-extension';
import LinkRowActionExtension from '@components/grid/extension/link-row-action-extension';
const {$} = window;
$(() => {
['manufacturer', 'manufacturer_address'].forEach((gridName) => {
const grid = new Grid(gridName);
grid.addExtension(new ExportToSqlManagerExtension());
grid.addExtension(new ReloadListActionExtension());
grid.addExtension(new SortingExtension());
grid.addExtension(new FiltersResetExtension());
grid.addExtension(new ColumnTogglingExtension());
grid.addExtension(new SubmitRowActionExtension());
grid.addExtension(new SubmitBulkExtension());
grid.addExtension(new BulkActionCheckboxExtension());
grid.addExtension(new FiltersSubmitButtonEnablerExtension());
grid.addExtension(new LinkRowActionExtension());
});
window.prestashop.component.initComponents(
[
'TranslatableInput',
'TranslatableField',
'TinyMCEEditor',
],
);
new window.prestashop.component.TaggableField({
tokenFieldSelector: 'input.js-taggable-field',
options: {
createTokensOnBlur: true,
},
});
new window.prestashop.component.ChoiceTree('#manufacturer_shop_association').enableAutoCheckChildren();
new FormSubmitButton();
});

View File

@@ -0,0 +1,32 @@
/**
* 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)
*/
export default {
manufacturerAddressCountrySelect: '#manufacturer_address_id_country',
manufacturerAddressStateSelect: '#manufacturer_address_id_state',
manufacturerAddressStateBlock: '.js-manufacturer-address-state',
manufacturerAddressDniInput: '#manufacturer_address_dni',
manufacturerAddressDniInputLabel: 'label[for="manufacturer_address_dni"]',
};

View File

@@ -0,0 +1,43 @@
/**
* 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 CountryStateSelectionToggler from '@components/country-state-selection-toggler';
import ManufacturerAddressMap from '@pages/manufacturer/manufacturer-address-map';
import CountryDniRequiredToggler from '@components/country-dni-required-toggler';
const {$} = window;
$(document).ready(() => {
new CountryStateSelectionToggler(
ManufacturerAddressMap.manufacturerAddressCountrySelect,
ManufacturerAddressMap.manufacturerAddressStateSelect,
ManufacturerAddressMap.manufacturerAddressStateBlock,
);
new CountryDniRequiredToggler(
ManufacturerAddressMap.manufacturerAddressCountrySelect,
ManufacturerAddressMap.manufacturerAddressDniInput,
ManufacturerAddressMap.manufacturerAddressDniInputLabel,
);
});

View File

@@ -0,0 +1,42 @@
/**
* 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 Grid from '../../components/grid/grid';
import SortingExtension from '../../components/grid/extension/sorting-extension';
import FiltersResetExtension from '../../components/grid/extension/filters-reset-extension';
import FiltersSubmitButtonEnablerExtension
from '../../components/grid/extension/filters-submit-button-enabler-extension';
import TranslatableInput from '../../components/translatable-input';
const {$} = window;
$(() => {
const grid = new Grid('merchandise_return');
grid.addExtension(new SortingExtension());
grid.addExtension(new FiltersResetExtension());
grid.addExtension(new FiltersSubmitButtonEnablerExtension());
new TranslatableInput();
});

View File

@@ -0,0 +1,71 @@
/**
* 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 Grid from '@components/grid/grid';
import ReloadListActionExtension from '@components/grid/extension/reload-list-extension';
import ExportToSqlManagerExtension from '@components/grid/extension/export-to-sql-manager-extension';
import FiltersResetExtension from '@components/grid/extension/filters-reset-extension';
import SortingExtension from '@components/grid/extension/sorting-extension';
import LinkRowActionExtension from '@components/grid/extension/link-row-action-extension';
import SubmitGridExtension from '@components/grid/extension/submit-grid-action-extension';
import SubmitBulkExtension from '@components/grid/extension/submit-bulk-action-extension';
import BulkActionCheckboxExtension from '@components/grid/extension/bulk-action-checkbox-extension';
import SubmitRowActionExtension from '@components/grid/extension/action/row/submit-row-action-extension';
import ShowcaseCard from '@components/showcase-card/showcase-card';
import ShowcaseCardCloseExtension from '@components/showcase-card/extension/showcase-card-close-extension';
import TaggableField from '@components/taggable-field';
import TranslatableInput from '@components/translatable-input';
import FiltersSubmitButtonEnablerExtension
from '@components/grid/extension/filters-submit-button-enabler-extension';
import MetaPageNameOptionHandler from '@pages/meta/meta-page-name-option-handler';
const {$} = window;
$(() => {
const meta = new Grid('meta');
meta.addExtension(new ReloadListActionExtension());
meta.addExtension(new ExportToSqlManagerExtension());
meta.addExtension(new FiltersResetExtension());
meta.addExtension(new SortingExtension());
meta.addExtension(new LinkRowActionExtension());
meta.addExtension(new SubmitGridExtension());
meta.addExtension(new SubmitBulkExtension());
meta.addExtension(new SubmitRowActionExtension());
meta.addExtension(new BulkActionCheckboxExtension());
meta.addExtension(new FiltersSubmitButtonEnablerExtension());
const helperBlock = new ShowcaseCard('seo-urls-showcase-card');
helperBlock.addExtension(new ShowcaseCardCloseExtension());
new TaggableField({
tokenFieldSelector: 'input.js-taggable-field',
options: {
createTokensOnBlur: true,
},
});
new TranslatableInput();
new MetaPageNameOptionHandler();
});

View File

@@ -0,0 +1,62 @@
/**
* 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)
*/
const {$} = window;
/**
* Class MetaPageNameOptionHandler is responsible for checking the index page condition - if index page is selected it
* does not allow to enter url rewrite field by disabling that input. In another cases url rewrite field is mandatory to
* enter.
*/
export default class MetaPageNameOptionHandler {
constructor() {
const pageNameSelector = '.js-meta-page-name';
const currentPage = $(pageNameSelector).val();
this.setUrlRewriteDisabledStatusByCurrentPage(currentPage);
$(document).on('change', pageNameSelector, (event) => this.changePageNameEvent(event));
}
/**
* An event which is being called after the selector is being updated.
* @param {object} event
* @private
*/
changePageNameEvent(event) {
const $this = $(event.currentTarget);
const currentPage = $this.val();
this.setUrlRewriteDisabledStatusByCurrentPage(currentPage);
}
/**
* Sets url rewrite form field to disabled or enabled according to current page value.
* @param {string} currentPage
* @private
*/
setUrlRewriteDisabledStatusByCurrentPage(currentPage) {
$('.js-url-rewrite input').prop('disabled', currentPage === 'index');
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,36 @@
/**
* 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 ModuleCard from '@components/module-card';
import AdminModuleController from '@pages/module/controller';
import ModuleLoader from '@pages/module/loader';
const {$} = window;
$(() => {
const moduleCardController = new ModuleCard();
new ModuleLoader();
new AdminModuleController(moduleCardController);
});

View File

@@ -0,0 +1,80 @@
/**
* 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)
*/
const {$} = window;
/**
* Module Admin Page Loader.
* @constructor
*/
class ModuleLoader {
constructor() {
ModuleLoader.handleImport();
ModuleLoader.handleEvents();
}
static handleImport() {
const moduleImport = $('#module-import');
moduleImport.click(() => {
moduleImport.addClass('onclick', 250, validate);
});
function validate() {
setTimeout(
() => {
moduleImport.removeClass('onclick');
moduleImport.addClass('validate', 450, callback);
},
2250,
);
}
function callback() {
setTimeout(
() => {
moduleImport.removeClass('validate');
},
1250,
);
}
}
static handleEvents() {
$('body').on(
'click',
'a.module-read-more-grid-btn, a.module-read-more-list-btn',
(event) => {
event.preventDefault();
const modulePoppin = $(event.target).data('target');
$.get(event.target.href, (data) => {
$(modulePoppin).html(data);
$(modulePoppin).modal();
});
},
);
}
}
export default ModuleLoader;

View File

@@ -0,0 +1,84 @@
/**
* 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 Grid from '@components/grid/grid';
import FiltersResetExtension from '@components/grid/extension/filters-reset-extension';
import SortingExtension from '@components/grid/extension/sorting-extension';
import SubmitBulkExtension from '@components/grid/extension/submit-bulk-action-extension';
import SubmitRowActionExtension
from '@components/grid/extension/action/row/submit-row-action-extension';
import LinkRowActionExtension from '@components/grid/extension/link-row-action-extension';
import DeleteCategoryRowActionExtension
from '@components/grid/extension/action/row/category/delete-category-row-action-extension';
import AsyncToggleColumnExtension
from '@components/grid/extension/column/common/async-toggle-column-extension';
import FiltersSubmitButtonEnablerExtension
from '@components/grid/extension/filters-submit-button-enabler-extension';
import ReloadListActionExtension from '@components/grid/extension/reload-list-extension';
import ExportToSqlManagerExtension
from '@components/grid/extension/export-to-sql-manager-extension';
import ShowcaseCard from '@components/showcase-card/showcase-card';
import ShowcaseCardCloseExtension from '@components/showcase-card/extension/showcase-card-close-extension';
import BulkActionCheckboxExtension from '@components/grid/extension/bulk-action-checkbox-extension';
const {$} = window;
$(() => {
const emptyCategoriesGrid = new Grid('empty_category');
emptyCategoriesGrid.addExtension(new FiltersResetExtension());
emptyCategoriesGrid.addExtension(new SortingExtension());
emptyCategoriesGrid.addExtension(new ReloadListActionExtension());
emptyCategoriesGrid.addExtension(new SubmitRowActionExtension());
emptyCategoriesGrid.addExtension(new LinkRowActionExtension());
emptyCategoriesGrid.addExtension(new AsyncToggleColumnExtension());
emptyCategoriesGrid.addExtension(new DeleteCategoryRowActionExtension());
emptyCategoriesGrid.addExtension(new FiltersSubmitButtonEnablerExtension());
[
'no_qty_product_with_combination',
'no_qty_product_without_combination',
'disabled_product',
'product_without_image',
'product_without_description',
'product_without_price',
].forEach((gridName) => {
const grid = new Grid(gridName);
grid.addExtension(new SortingExtension());
grid.addExtension(new ExportToSqlManagerExtension());
grid.addExtension(new ReloadListActionExtension());
grid.addExtension(new FiltersResetExtension());
grid.addExtension(new AsyncToggleColumnExtension());
grid.addExtension(new SubmitRowActionExtension());
grid.addExtension(new BulkActionCheckboxExtension());
grid.addExtension(new SubmitBulkExtension());
grid.addExtension(new LinkRowActionExtension());
grid.addExtension(new FiltersSubmitButtonEnablerExtension());
});
const showcaseCard = new ShowcaseCard('monitoringShowcaseCard');
showcaseCard.addExtension(new ShowcaseCardCloseExtension());
});

View File

@@ -0,0 +1,32 @@
/**
* 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 TermsAndConditionsOptionHandler from './terms-and-conditions-option-handler';
const {$} = window;
$(() => {
new TermsAndConditionsOptionHandler();
});

View File

@@ -0,0 +1,53 @@
/**
* 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)
*/
const {$} = window;
class TermsAndConditionsOptionHandler {
constructor() {
this.handle();
$('input[name="general[enable_tos]"]').on('change', () => this.handle());
}
handle() {
const tosEnabledVal = $('input[name="general[enable_tos]"]:checked').val();
const isTosEnabled = parseInt(tosEnabledVal, 10);
this.handleTermsAndConditionsCmsSelect(isTosEnabled);
}
/**
* If terms and conditions option is disabled, then terms and conditions
* cms select must be disabled.
*
* @param {int} isTosEnabled
*/
handleTermsAndConditionsCmsSelect(isTosEnabled) {
$('#form_general_tos_cms_id').prop('disabled', !isTosEnabled);
}
}
export default TermsAndConditionsOptionHandler;

View File

@@ -0,0 +1,34 @@
/**
* 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 initColorPickers from '@app/utils/colorpicker';
import TranslatableInput from '@components/translatable-input';
const {$} = window;
$(() => {
initColorPickers();
new TranslatableInput();
});

View File

@@ -0,0 +1,33 @@
/**
* 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)
*/
/**
* Defines all selectors that are used in currency add/edit form.
*/
export default {
sendEmailSelector: '#order_state_send_email',
mailTemplateSelector: '.order_state_template_select',
mailTemplatePreview: '#order_state_template_preview',
};

View 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)
*/
import initColorPickers from '@app/utils/colorpicker';
import TranslatableChoice from '@components/form/translatable-choice';
import TranslatableInput from '@components/translatable-input';
import FormMap from '@pages/order-states/form-map';
const {$} = window;
$(() => {
initColorPickers();
new TranslatableInput();
new TranslatableChoice();
let templatePreviewWindow = null;
function viewTemplates($uri) {
if (templatePreviewWindow != null && !templatePreviewWindow.closed) {
templatePreviewWindow.close();
}
templatePreviewWindow = window.open(
$uri,
'tpl_viewing',
'toolbar=0,'
+ 'location=0,'
+ 'directories=0,'
+ 'statfr=no,'
+ 'menubar=0,'
+ 'scrollbars=yes,'
+ 'resizable=yes,'
+ 'width=520,'
+ 'height=400,'
+ 'top=50,'
+ 'left=300',
);
templatePreviewWindow.focus();
}
$(document).ready(() => {
if (!$(FormMap.sendEmailSelector).is(':checked')) {
$(FormMap.mailTemplateSelector).hide();
}
$(document).on('change', FormMap.sendEmailSelector, () => {
$(FormMap.mailTemplateSelector).slideToggle();
});
$(document).on('click', FormMap.mailTemplatePreview, (event) => {
const $element = $(event.currentTarget);
const $select = $element.closest('.form-group').find('select.translatable_choice:visible');
const $uri = $select.find('option:selected').attr('data-preview');
viewTemplates($uri);
});
});
});

View File

@@ -0,0 +1,50 @@
/**
* 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 Grid from '@components/grid/grid';
import ReloadListActionExtension from '@components/grid/extension/reload-list-extension';
import ExportToSqlManagerExtension from '@components/grid/extension/export-to-sql-manager-extension';
import FiltersResetExtension from '@components/grid/extension/filters-reset-extension';
import SortingExtension from '@components/grid/extension/sorting-extension';
import ColumnTogglingExtension from '@components/grid/extension/column-toggling-extension';
const {$} = window;
$(() => {
const orderStatesGrid = new Grid('order_states');
orderStatesGrid.addExtension(new ReloadListActionExtension());
orderStatesGrid.addExtension(new ExportToSqlManagerExtension());
orderStatesGrid.addExtension(new FiltersResetExtension());
orderStatesGrid.addExtension(new SortingExtension());
orderStatesGrid.addExtension(new ColumnTogglingExtension());
const orderReturnStatusesGrid = new Grid('order_return_states');
orderReturnStatusesGrid.addExtension(new ReloadListActionExtension());
orderReturnStatusesGrid.addExtension(new ExportToSqlManagerExtension());
orderReturnStatusesGrid.addExtension(new FiltersResetExtension());
orderReturnStatusesGrid.addExtension(new SortingExtension());
});

View File

@@ -0,0 +1,210 @@
/**
* 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)
*/
/* eslint-disable max-len */
export default {
mainDiv: '#order-view-page',
orderPaymentDetailsBtn: '.js-payment-details-btn',
orderPaymentFormAmountInput: '#order_payment_amount',
orderPaymentInvoiceSelect: '#order_payment_id_invoice',
viewOrderPaymentsBlock: '#view_order_payments_block',
viewOrderPaymentsAlert: '.js-view-order-payments-alert',
privateNoteToggleBtn: '.js-private-note-toggle-btn',
privateNoteBlock: '.js-private-note-block',
privateNoteInput: '#private_note_note',
privateNoteSubmitBtn: '.js-private-note-btn',
addCartRuleModal: '#addOrderDiscountModal',
addCartRuleInvoiceIdSelect: '#add_order_cart_rule_invoice_id',
addCartRuleNameInput: '#add_order_cart_rule_name',
addCartRuleTypeSelect: '#add_order_cart_rule_type',
addCartRuleValueInput: '#add_order_cart_rule_value',
addCartRuleValueUnit: '#add_order_cart_rule_value_unit',
addCartRuleSubmit: '#add_order_cart_rule_submit',
cartRuleHelpText: '.js-cart-rule-value-help',
updateOrderStatusActionBtn: '#update_order_status_action_btn',
updateOrderStatusActionInput: '#update_order_status_action_input',
updateOrderStatusActionInputWrapper: '#update_order_status_action_input_wrapper',
updateOrderStatusActionForm: '#update_order_status_action_form',
showOrderShippingUpdateModalBtn: '.js-update-shipping-btn',
updateOrderShippingTrackingNumberInput: '#update_order_shipping_tracking_number',
updateOrderShippingCurrentOrderCarrierIdInput: '#update_order_shipping_current_order_carrier_id',
updateCustomerAddressModal: '#updateCustomerAddressModal',
openOrderAddressUpdateModalBtn: '.js-update-customer-address-modal-btn',
updateOrderAddressTypeInput: '#change_order_address_address_type',
deliveryAddressEditBtn: '#js-delivery-address-edit-btn',
invoiceAddressEditBtn: '#js-invoice-address-edit-btn',
orderMessageNameSelect: '#order_message_order_message',
orderMessagesContainer: '.js-order-messages-container',
orderMessage: '#order_message_message',
orderMessageChangeWarning: '.js-message-change-warning',
orderDocumentsTabCount: '#orderDocumentsTab .count',
orderDocumentsTabBody: '#orderDocumentsTabContent .card-body',
orderShippingTabCount: '#orderShippingTab .count',
orderShippingTabBody: '#orderShippingTabContent .card-body',
allMessagesModal: '#view_all_messages_modal',
allMessagesList: '#all-messages-list',
openAllMessagesBtn: '.js-open-all-messages-btn',
// Products table elements
productOriginalPosition: '#orderProductsOriginalPosition',
productModificationPosition: '#orderProductsModificationPosition',
productsPanel: '#orderProductsPanel',
productsCount: '#orderProductsPanelCount',
productDeleteBtn: '.js-order-product-delete-btn',
productsTable: '#orderProductsTable',
productsPagination: '.order-product-pagination',
productsNavPagination: '#orderProductsNavPagination',
productsTablePagination: '#orderProductsTablePagination',
productsTablePaginationNext: '#orderProductsTablePaginationNext',
productsTablePaginationPrev: '#orderProductsTablePaginationPrev',
productsTablePaginationLink: '.page-item:not(.d-none):not(#orderProductsTablePaginationNext):not(#orderProductsTablePaginationPrev) .page-link',
productsTablePaginationActive: '#orderProductsTablePagination .page-item.active span',
productsTablePaginationTemplate: '#orderProductsTablePagination .page-item.d-none',
productsTablePaginationNumberSelector: '#orderProductsTablePaginationNumberSelector',
productsTableRow: (productId) => `#orderProduct_${productId}`,
productsTableRowEdited: (productId) => `#editOrderProduct_${productId}`,
productsTableRows: 'tr.cellProduct',
productsCellLocation: 'tr .cellProductLocation',
productsCellRefunded: 'tr .cellProductRefunded',
productsCellLocationDisplayed: 'tr:not(.d-none) .cellProductLocation',
productsCellRefundedDisplayed: 'tr:not(.d-none) .cellProductRefunded',
productsTableCustomizationRows: '#orderProductsTable .order-product-customization',
productEditButtons: '.js-order-product-edit-btn',
productEditBtn: (productId) => `#orderProduct_${productId} .js-order-product-edit-btn`,
productAddBtn: '#addProductBtn',
productActionBtn: '.js-product-action-btn',
productAddActionBtn: '#add_product_row_add',
productCancelAddBtn: '#add_product_row_cancel',
productAddRow: '#addProductTableRow',
productSearchInput: '#add_product_row_search',
productSearchInputAutocomplete: '#addProductTableRow .dropdown',
productSearchInputAutocompleteMenu: '#addProductTableRow .dropdown .dropdown-menu',
productAddIdInput: '#add_product_row_product_id',
productAddTaxRateInput: '#add_product_row_tax_rate',
productAddCombinationsBlock: '#addProductCombinations',
productAddCombinationsSelect: '#addProductCombinationId',
productAddPriceTaxExclInput: '#add_product_row_price_tax_excluded',
productAddPriceTaxInclInput: '#add_product_row_price_tax_included',
productAddQuantityInput: '#add_product_row_quantity',
productAddAvailableText: '#addProductAvailable',
productAddLocationText: '#addProductLocation',
productAddTotalPriceText: '#addProductTotalPrice',
productAddInvoiceSelect: '#add_product_row_invoice',
productAddFreeShippingSelect: '#add_product_row_free_shipping',
productAddNewInvoiceInfo: '#addProductNewInvoiceInfo',
productEditSaveBtn: '.productEditSaveBtn',
productEditCancelBtn: '.productEditCancelBtn',
productEditRowTemplate: '#editProductTableRowTemplate',
productEditRow: '.editProductRow',
productEditImage: '.cellProductImg',
productEditName: '.cellProductName',
productEditUnitPrice: '.cellProductUnitPrice',
productEditQuantity: '.cellProductQuantity',
productEditAvailableQuantity: '.cellProductAvailableQuantity',
productEditTotalPrice: '.cellProductTotalPrice',
productEditPriceTaxExclInput: '.editProductPriceTaxExcl',
productEditPriceTaxInclInput: '.editProductPriceTaxIncl',
productEditInvoiceSelect: '.editProductInvoice',
productEditQuantityInput: '.editProductQuantity',
productEditLocationText: '.editProductLocation',
productEditAvailableText: '.editProductAvailable',
productEditTotalPriceText: '.editProductTotalPrice',
// Product Discount List
productDiscountList: {
list: '.table.discountList',
},
// Product Pack Modal
productPackModal: {
modal: '#product-pack-modal',
table: '#product-pack-modal-table tbody',
rows: '#product-pack-modal-table tbody tr:not(#template-pack-table-row)',
template: '#template-pack-table-row',
product: {
img: '.cell-product-img img',
link: '.cell-product-name a',
name: '.cell-product-name .product-name',
ref: '.cell-product-name .product-reference',
supplierRef: '.cell-product-name .product-supplier-reference',
quantity: '.cell-product-quantity',
availableQuantity: '.cell-product-available-quantity',
},
},
// Order price elements
orderProductsTotal: '#orderProductsTotal',
orderDiscountsTotalContainer: '#order-discounts-total-container',
orderDiscountsTotal: '#orderDiscountsTotal',
orderWrappingTotal: '#orderWrappingTotal',
orderShippingTotalContainer: '#order-shipping-total-container',
orderShippingTotal: '#orderShippingTotal',
orderTaxesTotal: '#orderTaxesTotal',
orderTotal: '#orderTotal',
orderHookTabsContainer: '#order_hook_tabs',
// Product cancel/refund elements
cancelProduct: {
form: 'form[name="cancel_product"]',
buttons: {
abort: 'button.cancel-product-element-abort',
save: '#cancel_product_save',
partialRefund: 'button.partial-refund-display',
standardRefund: 'button.standard-refund-display',
returnProduct: 'button.return-product-display',
cancelProducts: 'button.cancel-product-display',
},
inputs: {
quantity: '.cancel-product-quantity input',
amount: '.cancel-product-amount input',
selector: '.cancel-product-selector input',
},
table: {
cell: '.cancel-product-cell',
header: 'th.cancel-product-element p',
actions: 'td.cellProductActions, th.product_actions',
},
checkboxes: {
restock: '#cancel_product_restock',
creditSlip: '#cancel_product_credit_slip',
voucher: '#cancel_product_voucher',
},
radios: {
voucherRefundType: {
productPrices: 'input[voucher-refund-type="0"]',
productPricesVoucherExcluded: 'input[voucher-refund-type="1"]',
negativeErrorMessage: '.voucher-refund-type-negative-error',
},
},
toggle: {
partialRefund: '.cancel-product-element:not(.hidden):not(.shipping-refund), .cancel-product-amount',
standardRefund: '.cancel-product-element:not(.hidden):not(.shipping-refund-amount):not(.restock-products), .cancel-product-selector',
returnProduct: '.cancel-product-element:not(.hidden):not(.shipping-refund-amount), .cancel-product-selector',
cancelProducts: '.cancel-product-element:not(.hidden):not(.shipping-refund-amount):not(.shipping-refund):not(.restock-products):not(.refund-credit-slip):not(.refund-voucher):not(.voucher-refund-type), .cancel-product-selector',
},
},
printOrderViewPageButton: '.js-print-order-view-page',
orderNoteToggleBtn: '.js-order-notes-toggle-btn',
orderNoteBlock: '.js-order-notes-block',
orderNoteInput: '#internal_note_note',
orderNoteSubmitBtn: '.js-order-notes-btn',
refreshProductsListLoadingSpinner: '#orderProductsPanel .spinner-order-products-container#orderProductsLoading',
};

View File

@@ -0,0 +1,70 @@
/**
* 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 CreateOrderPage from './create/create-order-page';
const {$} = window;
let orderPageManager = null;
/**
* proxy to allow other scripts within the page to trigger the search
* @param string
*/
function searchCustomerByString(string) {
if (orderPageManager !== null) {
orderPageManager.search(string);
} else {
console.log('Error: Could not search customer as orderPageManager is null');
}
}
/**
* proxy to allow other scripts within the page to refresh addresses list
*/
function refreshAddressesList(refreshCartAddresses) {
if (orderPageManager !== null) {
orderPageManager.refreshAddressesList(refreshCartAddresses);
} else {
console.log('Error: Could not refresh addresses list as orderPageManager is null');
}
}
/**
* proxy to allow other scripts within the Create Order page to refresh cart
*/
function refreshCart() {
if (orderPageManager === null) {
console.log('Error: Could not refresh addresses list as orderPageManager is null');
return;
}
orderPageManager.refreshCart();
}
$(document).ready(() => {
orderPageManager = new CreateOrderPage();
});
export {searchCustomerByString};
export {refreshAddressesList};
export {refreshCart};

View File

@@ -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;

View File

@@ -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');
}
}

View 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));
}
}

View File

@@ -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);
});
}
}

View File

@@ -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);
});
}
}

View File

@@ -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();
}
}

View File

@@ -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',
};

View File

@@ -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);
}
}

View File

@@ -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);
});
}
}

View File

@@ -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();
}
}

View 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',
};

View 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;
}
}
}
}

View File

@@ -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);
}
}

View File

@@ -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');
}
}

View File

@@ -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);
});
}
}

View File

@@ -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();
}
}

Some files were not shown because too many files have changed in this diff Show More