diff --git a/pchcustomerfield/Readme.md b/pchcustomerfield/Readme.md new file mode 100644 index 0000000..f8be1fd --- /dev/null +++ b/pchcustomerfield/Readme.md @@ -0,0 +1 @@ +# Additional Customer Field \ No newline at end of file diff --git a/pchcustomerfield/config.xml b/pchcustomerfield/config.xml new file mode 100644 index 0000000..c685889 --- /dev/null +++ b/pchcustomerfield/config.xml @@ -0,0 +1,11 @@ + + + pchcustomerfield + + + + + + 1 + 1 + diff --git a/pchcustomerfield/config_nl.xml b/pchcustomerfield/config_nl.xml new file mode 100644 index 0000000..1f312c8 --- /dev/null +++ b/pchcustomerfield/config_nl.xml @@ -0,0 +1,13 @@ + + + pchcustomerfield + + + + + + + 1 + 0 + + \ No newline at end of file diff --git a/pchcustomerfield/controllers/admin/AdminPchCustomerfield.php b/pchcustomerfield/controllers/admin/AdminPchCustomerfield.php new file mode 100644 index 0000000..0ba1f58 --- /dev/null +++ b/pchcustomerfield/controllers/admin/AdminPchCustomerfield.php @@ -0,0 +1,234 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +class AdminPchCustomerfieldController extends ModuleAdminController +{ + public function __construct() + { + $this->className = 'PchCustomerfieldModel'; + $this->table = 'pchcustomerfield'; + $this->deleted = false; + $this->identifier = 'id_pchcustomerfield'; + $this->lang = true; + $this->bootstrap = true; + $this->explicitSelect = true; + $this->context = Context::getContext(); + parent::__construct(); + + $this->position_identifier = 'position'; + $this->_orderBy = 'position'; + + $this->fields_list = array( + 'id_pchcustomerfield' => array( + 'title' => $this->l('ID'), + 'align' => 'center', + 'class' => 'fixed-width-xs' + ), + 'title' => array( + 'title' => $this->l('Field value'), + 'lang' => true + ), + 'active' => array( + 'title' => $this->l('Status'), + 'active' => 'status', + 'type' => 'bool', + 'align' => 'center', + 'orderby' => false, + 'search' => false, + 'class' => 'fixed-width-xs' + ), + 'position' => array( + 'title' => $this->l('Position'), + 'filter_key' => 'a!position', + 'align' => 'center', + 'class' => 'fixed-width-sm', + 'position' => 'position', + 'search' => false, + ) + ); + /*$this->bulk_actions = array( + 'delete' => array( + 'text' => $this->l('Delete selected'), + 'confirm' => $this->l('Delete selected items?'), + 'icon' => 'icon-trash' + ) + );*/ + } + + protected function _childValidation() + { + $definition = ObjectModel::getDefinition($this->className); + + /** @var $object ObjectModel */ + $object = new $this->className(); + + $default_language = new Language((int) Configuration::get('PS_LANG_DEFAULT')); + $languages = Language::getLanguages(false); + + foreach ($definition['fields'] as $field => $def) { + if (isset($def['lang']) && $def['lang']) { + if (isset($def['required']) && $def['required']) { + foreach ($languages as $language) { + if ($language['id_lang'] !== $default_language->id) { + $value = Tools::getValue($field . '_' . $language['id_lang']); + if (!isset($value) || '' == $value) { + $this->errors[$field . '_' . $language['id_lang']] = $this->trans( + 'The field %field_name% is required at in %lang%.', + array('%field_name%' => $object->displayFieldName($field, $this->className), '%lang%' => $language['name']), + 'Admin.Notifications.Error' + ); + } + } + } + } + } + } + } + + public function renderList() + { + $this->addRowAction('edit'); + //$this->addRowAction('delete'); + return parent::renderList(); + } + + public function renderForm() + { + $this->fields_form = array( + 'tinymce' => false, + 'legend' => array( + 'title' => $this->l('Specialization Field value'), + 'icon' => 'icon-link' + ), + 'input' => array( + array( + 'type' => 'text', + 'label' => $this->l('Field value'), + 'name' => 'title', + 'lang' => true, + 'required' => true, + 'hint' => $this->l('Invalid characters:').' <>;=#{}', + 'desc' => $this->l('You can use this heading in creating a specialization value.'), + ), + array( + 'type' => 'switch', + 'label' => $this->l('Enabled'), + 'name' => 'active', + 'is_bool' => true, + 'values' => array( + array( + 'id' => 'active_on', + 'value' => 1, + 'label' => $this->l('Yes') + ), + array( + 'id' => 'active_off', + 'value' => 0, + 'label' => $this->l('No') + ) + ), + ), + ), + 'submit' => array( + 'title' => $this->l('Save'), + ), + ); + + $languages = Language::getLanguages(false); + + if (count($languages) > 1) { + return $this->getMultiLanguageInfoMsg() . parent::renderForm(); + } else { + return parent::renderForm(); + } + } + + protected function getMultiLanguageInfoMsg() + { + return '

'. + $this->l('Since multiple languages are activated on your shop, please mind to add field value for each one of them'). + '

'; + } + + public function setMedia($isNewTheme = false) + { + parent::setMedia($isNewTheme); + $this->addJqueryUI('ui.sortable'); + } + + protected function beforeAdd($object) + { + if (empty($object->position) || !PchCustomerfieldModel::positionOccupied($object->position)) { + $object->position = PchCustomerfieldModel::getHigherPosition() + 1; + } + parent::beforeAdd($object); + } + + public function ajaxProcessUpdatePositions() + { + $way = (int)(Tools::getValue('way')); + $id_field = (int)(Tools::getValue('id')); + $positions = Tools::getValue('pchcustomerfield'); + + foreach ($positions as $position => $value) { + $pos = explode('_', $value); + + if (isset($pos[2]) && (int)$pos[2] === $id_field) { + if ($field = new PchCustomerfieldModel((int)$pos[2])) { + if (isset($position) && $field->updatePosition($way, $position)) { + echo 'ok position '.(int)$position.' for field '.(int)$pos[1].'\r\n'; + } else { + echo '{"hasError" : true, "errors" : "Can not update field '.(int)$id_field.' to position '.(int)$position.' "}'; + } + } else { + echo '{"hasError" : true, "errors" : "This field ('.(int)$id_field.') can t be loaded"}'; + } + break; + } + } + } + + public function processPosition() + { + if (Tools::getIsset('update'.$this->table)) { + $object = new PchCustomerfieldModel((int)Tools::getValue('id_pchcustomerfield')); + self::$currentIndex = self::$currentIndex.'&update'.$this->table; + } else { + $object = new PchCustomerfieldModel((int)Tools::getValue('id')); + } + if (!Validate::isLoadedObject($object)) { + $this->errors[] = $this->l('An error occurred while updating the status for an object.'). + ' '.$this->table.' '.$this->l('(cannot load object)'); + } elseif (!$object->updatePosition((int)Tools::getValue('way'), (int)Tools::getValue('position'))) { + $this->errors[] = $this->l('Failed to update the position.'); + } else { + $id_identifier_str = ($id_identifier = (int)Tools::getValue($this->identifier)) ? '&'.$this->identifier.'='.$id_identifier : ''; + $redirect = self::$currentIndex.'&'.$this->table.'Orderby=position&'.$this->table.'Orderway=asc&conf=5'.$id_identifier_str.'&token='.$this->token; + $this->redirect_after = $redirect; + } + return $object; + } +} diff --git a/pchcustomerfield/controllers/admin/index.php b/pchcustomerfield/controllers/admin/index.php new file mode 100644 index 0000000..87daa20 --- /dev/null +++ b/pchcustomerfield/controllers/admin/index.php @@ -0,0 +1,34 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/pchcustomerfield/controllers/index.php b/pchcustomerfield/controllers/index.php new file mode 100644 index 0000000..87daa20 --- /dev/null +++ b/pchcustomerfield/controllers/index.php @@ -0,0 +1,34 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/pchcustomerfield/index.php b/pchcustomerfield/index.php new file mode 100644 index 0000000..87daa20 --- /dev/null +++ b/pchcustomerfield/index.php @@ -0,0 +1,34 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/pchcustomerfield/logo.png b/pchcustomerfield/logo.png new file mode 100644 index 0000000..95d87b4 Binary files /dev/null and b/pchcustomerfield/logo.png differ diff --git a/pchcustomerfield/mails/de/index.php b/pchcustomerfield/mails/de/index.php new file mode 100644 index 0000000..87daa20 --- /dev/null +++ b/pchcustomerfield/mails/de/index.php @@ -0,0 +1,34 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/pchcustomerfield/mails/de/order_conf.html b/pchcustomerfield/mails/de/order_conf.html new file mode 100644 index 0000000..d4bea2b --- /dev/null +++ b/pchcustomerfield/mails/de/order_conf.html @@ -0,0 +1,1291 @@ + + + + + Bestätigung der Bestellung + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
 
+ +
+ + + + + + +
+ + + + +
+ + + + + + +
+ +
+ + + + +
+ + + + + + +
+ + + +
+
+
+ +
+
+ + + + + +
+ + + + + + +
+ +
+ + + + + + +
+ + + + + + + + + + + +
+
+ Hallo {firstname} {lastname}, +
+
+
+ Thank you for shopping on {shop_name}! +
+
+
+
+ +
+
+ + + +
+ + + + + + +
+ +
+ + + + +
+

+

+ +
+
+ +
+
+ + + + +
+ + + + + + +
+ +
+ + + + + + +
+ + + + +
+
+ Details zu Ihrer Bestellung +
+
+
+
+ +
+
+ + + + +
+ + + + + + +
+ +
+ + + + + + +
+ + + + + + + + + + +
+
+ Spezialisierung: {specialization}
+
+
+ Bestellung: {order_name} vom {date}
+
+
+ Zahlung: {payment}
+
+
+
+ +
+
+ + + + +
+ + + + + + +
+ +
+ + + + +
+ + + + + + + + + + + + + + + + {products} + {discounts} + + + + + + + + + + + + + + + + + + + + + + + + +
Artikel-Nr.ArtikelStückpreisMengeGesamtpreis
+ Artikel + {total_products}
+ Rabatt + {total_discounts}
+ Geschenkverpackung + {total_wrapping}
+ Versand + {total_shipping}
+ Including total tax + {total_tax_paid}
+ Gesamt + {total_paid}
+
+
+ +
+
+ + + + +
+ + + + + + +
+ +
+ + + + + + +
+ + + + +
+
+ + Versand +
+
+
+
+ +
+
+ + + + +
+ + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+
+ Versanddienst: {carrier}
+
+
+ Zahlung: {payment}
+
+
+
+ +
+
+ + + + +
+ + + + + + +
+ +
+ + + + +
+ + + + + +
+ + + + + + + +
+

+ + Lieferadresse: +

+

+ {delivery_block_html} +

+
 
+
+ + + + + + +
+

+ + Rechnungsadresse +

+

+ {invoice_block_html} +

+
+
+
+
+ +
+
+ + + + +
+ + + + + + +
+ +
+ + + + +
+
+ Follow your order and download your invoice on our shop, go to the Order history and details section of your customer account. +
+
+
+ +
+
+ + + + +
+ + + + + + +
+ +
+ + + + +
+
+ If you have a guest account, you can follow your order via the Guest Tracking section on our shop. +
+
+
+ +
+
+ + + + + + + +
+
+ + + + +
+ + + + + + +
+ +
+ + + + + + + +
+ +
+
Powered by PrestaShop +
+
+
+ +
+
+ + + + +
+ + + diff --git a/pchcustomerfield/mails/de/order_conf.txt b/pchcustomerfield/mails/de/order_conf.txt new file mode 100644 index 0000000..057563b --- /dev/null +++ b/pchcustomerfield/mails/de/order_conf.txt @@ -0,0 +1,43 @@ +{shop_url} + +Hallo {firstname} {lastname}, + +Thank you for shopping on {shop_name}! + +Details zu Ihrer Bestellung + +Spezialisierung: {specialization} + +Bestellung: {order_name} vom {date} + +Zahlung: {payment} + +Artikel-Nr. Artikel Stückpreis Menge Gesamtpreis {products_txt} {discounts_txt} +Artikel {total_products} +Rabatt {total_discounts} +Geschenkverpackung {total_wrapping} +Versand {total_shipping} +Including total tax {total_tax_paid} +Gesamt {total_paid} + +Versand + +Versanddienst: {carrier} + +Zahlung: {payment} + +Lieferadresse: + +{delivery_block_txt} + +Rechnungsadresse + +{invoice_block_txt} + +Follow your order and download your invoice on our shop, go to the [Order history and details]({history_url}) section of your customer account. + +If you have a guest account, you can follow your order via the [Guest Tracking]({guest_tracking_url}) section on our shop. + +[{shop_name}]({shop_url}) + +Powered by [PrestaShop](https://www.prestashop.com/?utm_source=marchandprestashop&utm_medium=e-mail=utm_campaign=footer_1-7) diff --git a/pchcustomerfield/mails/en/index.php b/pchcustomerfield/mails/en/index.php new file mode 100644 index 0000000..87daa20 --- /dev/null +++ b/pchcustomerfield/mails/en/index.php @@ -0,0 +1,34 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/pchcustomerfield/mails/en/order_conf.html b/pchcustomerfield/mails/en/order_conf.html new file mode 100644 index 0000000..3f6b33c --- /dev/null +++ b/pchcustomerfield/mails/en/order_conf.html @@ -0,0 +1,1291 @@ + + + + + Order confirmation + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
 
+ +
+ + + + + + +
+ + + + +
+ + + + + + +
+ +
+ + + + +
+ + + + + + +
+ + + +
+
+
+ +
+
+ + + + + +
+ + + + + + +
+ +
+ + + + + + +
+ + + + + + + + + + + +
+
+ Hi {firstname} {lastname}, +
+
+
+ Thank you for shopping on {shop_name}! +
+
+
+
+ +
+
+ + + +
+ + + + + + +
+ +
+ + + + +
+

+

+ +
+
+ +
+
+ + + + +
+ + + + + + +
+ +
+ + + + + + +
+ + + + +
+
+ Order details +
+
+
+
+ +
+
+ + + + +
+ + + + + + +
+ +
+ + + + + + +
+ + + + + + + + + + +
+
+ Specialization: {specialization}
+
+
+ Order: {order_name} Placed on {date}
+
+
+ Payment: {payment}
+
+
+
+ +
+
+ + + + +
+ + + + + + +
+ +
+ + + + +
+ + + + + + + + + + + + + + + + {products} + {discounts} + + + + + + + + + + + + + + + + + + + + + + + + +
ReferenceProductUnit priceQuantityTotal price
+ Products + {total_products}
+ Discounts + {total_discounts}
+ Gift-wrapping + {total_wrapping}
+ Shipping + {total_shipping}
+ Including total tax + {total_tax_paid}
+ Total paid + {total_paid}
+
+
+ +
+
+ + + + +
+ + + + + + +
+ +
+ + + + + + +
+ + + + +
+
+ + Shipping +
+
+
+
+ +
+
+ + + + +
+ + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+
+ Carrier: {carrier}
+
+
+ Payment: {payment}
+
+
+
+ +
+
+ + + + +
+ + + + + + +
+ +
+ + + + +
+ + + + + +
+ + + + + + + +
+

+ + Delivery address +

+

+ {delivery_block_html} +

+
 
+
+ + + + + + +
+

+ + Billing address +

+

+ {invoice_block_html} +

+
+
+
+
+ +
+
+ + + + +
+ + + + + + +
+ +
+ + + + +
+
+ Follow your order and download your invoice on our shop, go to the Order history and details section of your customer account. +
+
+
+ +
+
+ + + + +
+ + + + + + +
+ +
+ + + + +
+
+ If you have a guest account, you can follow your order via the Guest Tracking section on our shop. +
+
+
+ +
+
+ + + + + + + +
+
+ + + + +
+ + + + + + +
+ +
+ + + + + + + +
+ +
+
Powered by PrestaShop +
+
+
+ +
+
+ + + + +
+ + + diff --git a/pchcustomerfield/mails/en/order_conf.txt b/pchcustomerfield/mails/en/order_conf.txt new file mode 100644 index 0000000..c153876 --- /dev/null +++ b/pchcustomerfield/mails/en/order_conf.txt @@ -0,0 +1,43 @@ +{shop_url} + +Hi {firstname} {lastname}, + +Thank you for shopping on {shop_name}! + +Order details + +Specialization: {specialization} + +Order: {order_name} Placed on {date} + +Payment: {payment} + +Reference Product Unit price Quantity Total price {products_txt} {discounts_txt} +Products {total_products} +Discounts {total_discounts} +Gift-wrapping {total_wrapping} +Shipping {total_shipping} +Including total tax {total_tax_paid} +Total paid {total_paid} + +Shipping + +Carrier: {carrier} + +Payment: {payment} + +Delivery address + +{delivery_block_txt} + +Billing address + +{invoice_block_txt} + +Follow your order and download your invoice on our shop, go to the [Order history and details]({history_url}) section of your customer account. + +If you have a guest account, you can follow your order via the [Guest Tracking]({guest_tracking_url}) section on our shop. + +[{shop_name}]({shop_url}) + +Powered by [PrestaShop](https://www.prestashop.com/?utm_source=marchandprestashop&utm_medium=e-mail=utm_campaign=footer_1-7) diff --git a/pchcustomerfield/mails/fr/index.php b/pchcustomerfield/mails/fr/index.php new file mode 100644 index 0000000..87daa20 --- /dev/null +++ b/pchcustomerfield/mails/fr/index.php @@ -0,0 +1,34 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/pchcustomerfield/mails/fr/order_conf.html b/pchcustomerfield/mails/fr/order_conf.html new file mode 100644 index 0000000..42fb533 --- /dev/null +++ b/pchcustomerfield/mails/fr/order_conf.html @@ -0,0 +1,1291 @@ + + + + + Confirmation de commande + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
 
+ +
+ + + + + + +
+ + + + +
+ + + + + + +
+ +
+ + + + +
+ + + + + + +
+ + + +
+
+
+ +
+
+ + + + + +
+ + + + + + +
+ +
+ + + + + + +
+ + + + + + + + + + + +
+
+ Bonjour {firstname} {lastname}, +
+
+
+ Merci d'avoir effectué vos achats sur {shop_name} ! +
+
+
+
+ +
+
+ + + +
+ + + + + + +
+ +
+ + + + +
+

+

+ +
+
+ +
+
+ + + + +
+ + + + + + +
+ +
+ + + + + + +
+ + + + +
+
+ Détails de la commande +
+
+
+
+ +
+
+ + + + +
+ + + + + + +
+ +
+ + + + + + +
+ + + + + + + + + + +
+
+ Spécialisation : {specialization}
+
+
+ Commande : {order_name} passée le {date}
+
+
+ Paiement : {payment}
+
+
+
+ +
+
+ + + + +
+ + + + + + +
+ +
+ + + + +
+ + + + + + + + + + + + + + + + {products} + {discounts} + + + + + + + + + + + + + + + + + + + + + + + + +
RéférenceProduitPrix unitaireQuantitéPrix total
+ Produits + {total_products}
+ Réductions + {total_discounts}
+ Paquet cadeau + {total_wrapping}
+ Livraison + {total_shipping}
+ Incluant un total de taxes + {total_tax_paid}
+ Total payé + {total_paid}
+
+
+ +
+
+ + + + +
+ + + + + + +
+ +
+ + + + + + +
+ + + + +
+
+ + Livraison +
+
+
+
+ +
+
+ + + + +
+ + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+
+ Transporteur : {carrier}
+
+
+ Paiement : {payment}
+
+
+
+ +
+
+ + + + +
+ + + + + + +
+ +
+ + + + +
+ + + + + +
+ + + + + + + +
+

+ + Adresse de livraison +

+

+ {delivery_block_html} +

+
 
+
+ + + + + + +
+

+ + Adresse de facturation +

+

+ {invoice_block_html} +

+
+
+
+
+ +
+
+ + + + +
+ + + + + + +
+ +
+ + + + +
+
+ Suivez votre commande et téléchargez votre facture sur notre site, rendez-vous dans la section Historique et détails de mes commandes de votre compte client. +
+
+
+ +
+
+ + + + +
+ + + + + + +
+ +
+ + + + +
+
+ Si vous avez un compte invité, vous pouvez suivre votre commande via la section Suivi invité sur notre boutique. +
+
+
+ +
+
+ + + + + + + +
+
+ + + + +
+ + + + + + +
+ +
+ + + + + + + +
+ +
+
Powered by PrestaShop +
+
+
+ +
+
+ + + + +
+ + + diff --git a/pchcustomerfield/mails/fr/order_conf.txt b/pchcustomerfield/mails/fr/order_conf.txt new file mode 100644 index 0000000..036a995 --- /dev/null +++ b/pchcustomerfield/mails/fr/order_conf.txt @@ -0,0 +1,43 @@ +{shop_url} + +Bonjour {firstname} {lastname}, + +Merci d'avoir effectué vos achats sur {shop_name} ! + +Détails de la commande + +Spécialisation: {specialization} + +Commande : {order_name} passée le {date} + +Paiement : {payment} + +Référence Produit Prix unitaire Quantité Prix total {products_txt} {discounts_txt} +Produits {total_products} +Réductions {total_discounts} +Paquet cadeau {total_wrapping} +Livraison {total_shipping} +Incluant un total de taxes {total_tax_paid} +Total payé {total_paid} + +Livraison + +Transporteur : {carrier} + +Paiement : {payment} + +Adresse de livraison + +{delivery_block_txt} + +Adresse de facturation + +{invoice_block_txt} + +Suivez votre commande et téléchargez votre facture sur notre site, rendez-vous dans la section [Historique et détails de mes commandes]({history_url}) de votre compte client. + +Si vous avez un compte invité, vous pouvez suivre votre commande via la section [Suivi invité]({guest_tracking_url}) sur notre boutique. + +[{shop_name}]({shop_url}) + +Powered by [PrestaShop](https://www.prestashop.com/?utm_source=marchandprestashop&utm_medium=e-mail=utm_campaign=footer_1-7) diff --git a/pchcustomerfield/mails/index.php b/pchcustomerfield/mails/index.php new file mode 100644 index 0000000..87daa20 --- /dev/null +++ b/pchcustomerfield/mails/index.php @@ -0,0 +1,34 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/pchcustomerfield/mails/nl/_order_conf.html b/pchcustomerfield/mails/nl/_order_conf.html new file mode 100644 index 0000000..e97eae0 --- /dev/null +++ b/pchcustomerfield/mails/nl/_order_conf.html @@ -0,0 +1,1216 @@ + + + + + Order confirmation + + + + + + + + + + + + + + + + + + + + + + + + +
+
 
+ +
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+ + + + + + +
+
+
+
+
+ +
+ + + + + + +
+
+ + + + + + +
+ + + + + + + + + + +
+
Hartelijk dank voor uw bestelling!
+
+
Beste {firstname} {lastname}, bedankt voor het winkelen bij {shop_name}!
+
+
+
+
+
+ +
+ + + + + + +
+
+ + +
+
+
+
+ +
+ + + + + + +
+
+ + + + + + +
+ + + + + + +
+
Bestellingsdetails
+
+
+
+
+
+ +
+ + + + + + +
+
+ + + + + + +
+ + + + + + + + + + + + +
+
Specialisatie: {specialization}
+
+
Bestelling: {order_name} Geplaatst op {date}
+
+
Betaling: {payment}
+
+
+
+
+
+ +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReferentieProductEenheidsprijsAantalTotale prijs
{products}
{discounts}
Producten{total_products}
Korting{total_discounts}
Levering{total_shipping}
BTW{total_tax_paid}
Total (incl. BTW){total_paid}
+
+
+
+
+
+
+ +

+ +

+ +

+ +
+ + + + + + +
+
+ + + + + + +
+ + + + + + +
+
 Levering
+
+
+
+
+
+ +

+ +

+ +

+ +

+ +
+ + + + + + +
+
+ + + + + + +
+ + + + + + + + + +
+
Leveringsmethode: {carrier}
+
+
Betaling: {payment}
+
+
+
+
+
+ +
+ + + + + + +
+
+ + + + + + +
+ + + + + + + +
+ + + + + + + +
+

 Leveringsadres

+

{delivery_block_html}

+
 
+
+ + + + + + +
+

 Facturatieadres

+

{invoice_block_html}

+
+
+
+
+
+
+ +

+ +

+ +

+ +
+ + + + + + +
+
+ + + + + + +
+
+

Volg uw bestelling in onze winkel, ga naar Bestelgeschiedenis en details in uw account.

+ + + + + + +
+
+ + + + + + +
+

Vragen over uw bestelling? Aarzel niet om contact met ons op te nemen via het nummer 0032/285.95.81

+
+
+
+

 

+
+
+
+
+
+ +

+ +

+ +

+ +
+ + + + + + +
+
+
+
+ +

+ +

+ +

+ +

+ +

+ +

+ +

+ +
+ + + + + + +
+
+ + + + + + + + + +
+
+

{shop_name}

+

Ceintuurbaan 213a, 3051 KC Rotterdam

+
+
+
Powered by Farla Medical BVBA
+
+
+
+
+ +

+ +

+ +

+ + + \ No newline at end of file diff --git a/pchcustomerfield/mails/nl/_order_conf.txt b/pchcustomerfield/mails/nl/_order_conf.txt new file mode 100644 index 0000000..483797d --- /dev/null +++ b/pchcustomerfield/mails/nl/_order_conf.txt @@ -0,0 +1,40 @@ +{shop_url} + +Hi {firstname} {lastname}, + +Thank you for shopping on {shop_name}! + +Order details + +Specialisatie: {specialization} + +Order: {order_name} Placed on {date} + +Payment: {payment} + +Referentie Product Eenheidsprijs Aantal Totale prijs {products_txt} {discounts_txt} +{products} +{discounts} +Producten {total_products} +Korting {total_discounts} +Levering {total_shipping} +BTW {total_tax_paid} +Totaal (incl. BTW) {total_paid} + +Levering + +Leveringsmethode: {carrier} + +Leveringsadres + +{delivery_block_txt} + +Facturatieadres + +{invoice_block_txt} + +Volg uw bestelling en download uw factuur in onze winkel, ga naar [Order history and details]({history_url}) in uw account. + +[{shop_name}]({shop_url}) + +Gemaakt door Farla Medical BVBA diff --git a/pchcustomerfield/mails/nl/index.php b/pchcustomerfield/mails/nl/index.php new file mode 100644 index 0000000..87daa20 --- /dev/null +++ b/pchcustomerfield/mails/nl/index.php @@ -0,0 +1,34 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/pchcustomerfield/mails/nl/order_conf.html b/pchcustomerfield/mails/nl/order_conf.html new file mode 100644 index 0000000..d5af2be --- /dev/null +++ b/pchcustomerfield/mails/nl/order_conf.html @@ -0,0 +1,1224 @@ + + + + + Order confirmation + + + + + + + + + + + + + + + + + + + + + + + + +
+
 
+ +
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+ + + + + + +
+
+
+
+
+ +
+ + + + + + +
+
+ + + + + + +
+ + + + + + + + + + +
+
Hartelijk dank voor uw bestelling!!
+
+
Beste {firstname} {lastname}, bedankt voor het winkelen bij {shop_name}!
+
+
+
+
+
+

Ons team gaat meteen voor u aan de slag. U ontvangt een e-mail zodra uw bestelling onderweg is.

+
+
+
+
+
+
+
+
+ +
+ + + + + + +
+
+ + +
+
+
+
+ +
+ + + + + + +
+
+ + + + + + +
+ + + + + + +
+
Bestellingsdetails
+
+
+
+
+
+ +
+ + + + + + +
+
+ + + + + + +
+ + + + + + + + + + + + +
+
Specialisatie: {specialization}
+
+
Bestelling: {order_name} Geplaatst op {date}
+
+
Betaling: {payment}
+
+
+
+
+
+ +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReferentieProductEenheidsprijsAantalTotale prijs
{products}
{discounts}
Producten{total_products}
Korting{total_discounts}
Levering{total_shipping}
BTW{total_tax_paid}
Total (incl. BTW){total_paid}
+
+
+
+
+
+
+ +

+ +

+ +

+ +
+ + + + + + +
+
+ + + + + + +
+ + + + + + +
+
 Levering
+
+
+
+
+
+ +

+ +

+ +

+ +

+ +
+ + + + + + +
+
+ + + + + + +
+ + + + + + + + + +
+
Leveringsmethode: {carrier}
+
+
Betaling: {payment}
+
+
+
+
+
+ +
+ + + + + + +
+
+ + + + + + +
+ + + + + + + +
+ + + + + + + +
+

 Leveringsadres

+

{delivery_block_html}

+
 
+
+ + + + + + +
+

 Facturatieadres

+

{invoice_block_html}

+
+
+
+
+
+
+ +

+ +

+ +

+ +
+ + + + + + +
+
+ + + + + + +
+
+

Volg uw bestelling op onze website via Bestelgeschiedenis en details in uw account.

+ + + + + + +
+
+ + + + + + +
+

Vragen over uw bestelling? Aarzel niet om contact op te nemen via info@farlamedical.nl.

+
+
+
+

 

+
+
+
+
+
+ +

+ +

+ +

+ +
+ + + + + + +
+
+
+
+ +

+ +

+ +

+ +

+ +

+ +

+ +

+ +
+ + + + + + +
+
+ + + + + + + + + +
+ +
Putsmolentje 3, 4641 SK Ossendrecht, Nederland
+
Facebook     Twitter     Instagram     Instagram
+
+
Powered by Farla Medical BV
+
+
+
+
+ +

+ +

+ +

+ + + \ No newline at end of file diff --git a/pchcustomerfield/mails/nl/order_conf.txt b/pchcustomerfield/mails/nl/order_conf.txt new file mode 100644 index 0000000..ca693ab --- /dev/null +++ b/pchcustomerfield/mails/nl/order_conf.txt @@ -0,0 +1,46 @@ +{shop_url} + +Hi {firstname} {lastname}, + +Thank you for shopping on {shop_name}! + +Order details + +Specialisatie: {specialization} + +Order: {order_name} Placed on {date} + +Payment: {payment} + +Reference Product Unit price Quantity Total price +{products_txt} +{discounts_txt} +Products {total_products} +Discounts {total_discounts} +Shipping {total_shipping} +Including total tax {total_tax_paid} +Total paid {total_paid} + +Message: {message} + +Shipping + +Carrier: {carrier} + +Payment: {payment} + +Delivery address + +{delivery_block_txt} + +Billing address + +{invoice_block_txt} + +Follow your order and download your invoice on our shop, go to the [Order history and details]({history_url}) section of your customer account. + +If you have a guest account, you can follow your order via the [Guest Tracking]({guest_tracking_url}) section on our shop. + +[{shop_name}]({shop_url}) + +Powered by [PrestaShop](https://www.prestashop.com/?utm_source=marchandprestashop&utm_medium=e-mail=utm_campaign=footer_1-7) diff --git a/pchcustomerfield/models/PchCustomerfieldModel.php b/pchcustomerfield/models/PchCustomerfieldModel.php new file mode 100644 index 0000000..649ba8e --- /dev/null +++ b/pchcustomerfield/models/PchCustomerfieldModel.php @@ -0,0 +1,165 @@ + + * @copyright 2007-2022 PrestaShop SA + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + * International Registered Trademark & Property of PrestaShop SA + */ + +class PchCustomerfieldModel extends ObjectModel +{ + public $id_pchcustomerfield; + public $title; + public $position; + public $active; + + public static $definition = array( + 'table' => 'pchcustomerfield', + 'primary' => 'id_pchcustomerfield', + 'multilang' => true, + 'fields' => array( + 'id_pchcustomerfield' => array( + 'type' => self::TYPE_INT + ), + 'title' => array( + 'type' => self::TYPE_STRING, + 'validate' => 'isString', + 'lang' => true, + 'required' => true + ), + 'position' => array( + 'type' => self::TYPE_INT, + 'validate' => 'isunsignedInt', + 'required' => true + ), + 'active' => array( + 'type' => self::TYPE_BOOL, + 'validate' => 'isBool', + 'required' => true + ), + ), + ); + + public function updatePosition($way, $position) + { + if (!$res = Db::getInstance()->executeS( + 'SELECT `id_pchcustomerfield`, `position` + FROM `'._DB_PREFIX_.'pchcustomerfield` + WHERE id_pchcustomerfield = '.(int)Tools::getValue('id').' + ORDER BY `position` ASC' + )) { + return false; + } + + foreach ($res as $field) { + if ((int) $field['id_pchcustomerfield'] == (int) $this->id) { + $moved_field = $field; + } + } + + if (!isset($moved_field) || !isset($position)) { + return false; + } + + // < and > statements rather than BETWEEN operator + // since BETWEEN is treated differently according to databases + return Db::getInstance()->execute(' + UPDATE `'._DB_PREFIX_.'pchcustomerfield` + SET `position`= `position` '.($way? '- 1' : '+ 1').' + WHERE `position` + '.($way + ? '> '.(int)$moved_field['position'].' AND `position` <= '.(int)$position + : '< '.(int)$moved_field['position'].' AND `position` >= '.(int)$position)) + && Db::getInstance()->execute(' + UPDATE `'._DB_PREFIX_.'pchcustomerfield` + SET `position` = '.(int)$position.' + WHERE `id_pchcustomerfield` = '.(int)$moved_field['id_pchcustomerfield']); + } + + public static function getHigherPosition() + { + $sql = 'SELECT MAX(`position`) FROM `'._DB_PREFIX_.'pchcustomerfield`'; + $position = DB::getInstance()->getValue($sql); + return (is_numeric($position)) ? $position : -1; + } + + public static function positionOccupied($position) + { + if (!$position) { + return false; + } + + $sql = 'SELECT * FROM `'._DB_PREFIX_.'pchcustomerfield` WHERE position = '.(int)$position; + return (bool)DB::getInstance()->getRow($sql); + } + + public static function getSpecializationValues($id_lang = null, $all_fields = false, $active = true) + { + if (!$id_lang) { + $id_lang = (int)Context::getContext()->language->id; + } + + $specializationQuery = 'SELECT cf.`id_pchcustomerfield`, cfl.`title` + FROM `'._DB_PREFIX_.'pchcustomerfield` cf + INNER JOIN `'._DB_PREFIX_.'pchcustomerfield_lang` cfl + ON (cf.id_pchcustomerfield = cfl.id_pchcustomerfield AND cfl.id_lang = '.(int)$id_lang.')'; + + if (!$all_fields) { + $specializationQuery .= ' WHERE cf.active = '.(int)$active; + } + + $specializationQuery .= ' ORDER BY cf.`position` ASC'; + + return Db::getInstance()->executeS($specializationQuery); + } + + public static function getSpecializationByCustomerId($id_lang = null, $id_customer) + { + if (!$id_customer) { + return false; + } + + if (!$id_lang) { + $id_lang = (int)Context::getContext()->language->id; + } + + $specializationQuery = 'SELECT cfl.`title` FROM `'._DB_PREFIX_.'customer` c INNER JOIN `'._DB_PREFIX_.'pchcustomerfield_lang` cfl + ON (c.specialization = cfl.id_pchcustomerfield AND c.id_customer = '.$id_customer.' AND cfl.id_lang = '.(int)$id_lang.')'; + + return Db::getInstance()->getValue($specializationQuery); + } + + public static function getSpecializationBySpecializationId($id_lang = null, $id_specialization) + { + if (!$id_specialization) { + return false; + } + + if (!$id_lang) { + $id_lang = (int)Context::getContext()->language->id; + } + + $specializationQuery = 'SELECT cfl.`title` FROM `'._DB_PREFIX_.'customer` c INNER JOIN `'._DB_PREFIX_.'pchcustomerfield_lang` cfl + ON (c.specialization = cfl.id_pchcustomerfield AND c.specialization = '.$id_specialization.' AND cfl.id_lang = '.(int)$id_lang.')'; + + return Db::getInstance()->getValue($specializationQuery); + } +} diff --git a/pchcustomerfield/models/index.php b/pchcustomerfield/models/index.php new file mode 100644 index 0000000..8f81758 --- /dev/null +++ b/pchcustomerfield/models/index.php @@ -0,0 +1,36 @@ + +* @copyright 2007-2014 PrestaShop SA +* @version Release: $Revision$ +* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; \ No newline at end of file diff --git a/pchcustomerfield/override/classes/Customer.php b/pchcustomerfield/override/classes/Customer.php new file mode 100644 index 0000000..2f98efd --- /dev/null +++ b/pchcustomerfield/override/classes/Customer.php @@ -0,0 +1,21 @@ + self::TYPE_INT, 'validate' => 'isUnsignedId'); + parent::__construct($id); + } +} diff --git a/pchcustomerfield/override/classes/PaymentModule.php b/pchcustomerfield/override/classes/PaymentModule.php new file mode 100644 index 0000000..2841427 --- /dev/null +++ b/pchcustomerfield/override/classes/PaymentModule.php @@ -0,0 +1,602 @@ + + * @copyright 2007-2019 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) + * International Registered Trademark & Property of PrestaShop SA + */ + +use PrestaShop\PrestaShop\Adapter\StockManager; + +class PaymentModule extends PaymentModuleCore +{ + /** + * Validate an order in database + * Function called from a payment module. + * + * @param int $id_cart + * @param int $id_order_state + * @param float $amount_paid Amount really paid by customer (in the default currency) + * @param string $payment_method Payment method (eg. 'Credit card') + * @param null $message Message to attach to order + * @param array $extra_vars + * @param null $currency_special + * @param bool $dont_touch_amount + * @param bool $secure_key + * @param Shop $shop + * + * @return bool + * + * @throws PrestaShopException + */ + public function validateOrder( + $id_cart, + $id_order_state, + $amount_paid, + $payment_method = 'Unknown', + $message = null, + $extra_vars = array(), + $currency_special = null, + $dont_touch_amount = false, + $secure_key = false, + Shop $shop = null + ) { + + /* ****** Begin1: Display specialization field in new order email ****** */ + if (false === Module::isInstalled('pchcustomerfield') || false === Module::isEnabled('pchcustomerfield') || !Configuration::get('PCHCUSTOMERFIELD_LIVE_MODE')) { + return parent::validateOrder( + $id_cart, + $id_order_state, + $amount_paid, + $payment_method, + $message, + $extra_vars, + $currency_special, + $dont_touch_amount, + $secure_key, + $shop + ); + } + /* ****** End1: Display specialization field in new order email ****** */ + + if (self::DEBUG_MODE) { + PrestaShopLogger::addLog('PaymentModule::validateOrder - Function called', 1, null, 'Cart', (int) $id_cart, true); + } + + if (!isset($this->context)) { + $this->context = Context::getContext(); + } + $this->context->cart = new Cart((int) $id_cart); + $this->context->customer = new Customer((int) $this->context->cart->id_customer); + // The tax cart is loaded before the customer so re-cache the tax calculation method + $this->context->cart->setTaxCalculationMethod(); + + $this->context->language = new Language((int) $this->context->cart->id_lang); + $this->context->shop = ($shop ? $shop : new Shop((int) $this->context->cart->id_shop)); + ShopUrl::resetMainDomainCache(); + $id_currency = $currency_special ? (int) $currency_special : (int) $this->context->cart->id_currency; + $this->context->currency = new Currency((int) $id_currency, null, (int) $this->context->shop->id); + if (Configuration::get('PS_TAX_ADDRESS_TYPE') == 'id_address_delivery') { + $context_country = $this->context->country; + } + + $order_status = new OrderState((int) $id_order_state, (int) $this->context->language->id); + if (!Validate::isLoadedObject($order_status)) { + PrestaShopLogger::addLog('PaymentModule::validateOrder - Order Status cannot be loaded', 3, null, 'Cart', (int) $id_cart, true); + + throw new PrestaShopException('Can\'t load Order status'); + } + + if (!$this->active) { + PrestaShopLogger::addLog('PaymentModule::validateOrder - Module is not active', 3, null, 'Cart', (int) $id_cart, true); + die(Tools::displayError()); + } + + // Does order already exists ? + if (Validate::isLoadedObject($this->context->cart) && $this->context->cart->OrderExists() == false) { + if ($secure_key !== false && $secure_key != $this->context->cart->secure_key) { + PrestaShopLogger::addLog('PaymentModule::validateOrder - Secure key does not match', 3, null, 'Cart', (int) $id_cart, true); + die(Tools::displayError()); + } + + // For each package, generate an order + $delivery_option_list = $this->context->cart->getDeliveryOptionList(); + $package_list = $this->context->cart->getPackageList(); + $cart_delivery_option = $this->context->cart->getDeliveryOption(); + + // If some delivery options are not defined, or not valid, use the first valid option + foreach ($delivery_option_list as $id_address => $package) { + if (!isset($cart_delivery_option[$id_address]) || !array_key_exists($cart_delivery_option[$id_address], $package)) { + foreach ($package as $key => $val) { + $cart_delivery_option[$id_address] = $key; + + break; + } + } + } + + $order_list = array(); + $order_detail_list = array(); + + do { + $reference = Order::generateReference(); + } while (Order::getByReference($reference)->count()); + + $this->currentOrderReference = $reference; + + $cart_total_paid = (float) Tools::ps_round((float) $this->context->cart->getOrderTotal(true, Cart::BOTH), 2); + + foreach ($cart_delivery_option as $id_address => $key_carriers) { + foreach ($delivery_option_list[$id_address][$key_carriers]['carrier_list'] as $id_carrier => $data) { + foreach ($data['package_list'] as $id_package) { + // Rewrite the id_warehouse + $package_list[$id_address][$id_package]['id_warehouse'] = (int) $this->context->cart->getPackageIdWarehouse($package_list[$id_address][$id_package], (int) $id_carrier); + $package_list[$id_address][$id_package]['id_carrier'] = $id_carrier; + } + } + } + // Make sure CartRule caches are empty + CartRule::cleanCache(); + $cart_rules = $this->context->cart->getCartRules(); + foreach ($cart_rules as $cart_rule) { + if (($rule = new CartRule((int) $cart_rule['obj']->id)) && Validate::isLoadedObject($rule)) { + if ($error = $rule->checkValidity($this->context, true, true)) { + $this->context->cart->removeCartRule((int) $rule->id); + if (isset($this->context->cookie, $this->context->cookie->id_customer) && $this->context->cookie->id_customer && !empty($rule->code)) { + Tools::redirect('index.php?controller=order&submitAddDiscount=1&discount_name=' . urlencode($rule->code)); + } else { + $rule_name = isset($rule->name[(int) $this->context->cart->id_lang]) ? $rule->name[(int) $this->context->cart->id_lang] : $rule->code; + $error = $this->trans('The cart rule named "%1s" (ID %2s) used in this cart is not valid and has been withdrawn from cart', array($rule_name, (int) $rule->id), 'Admin.Payment.Notification'); + PrestaShopLogger::addLog($error, 3, '0000002', 'Cart', (int) $this->context->cart->id); + } + } + } + } + + // Amount paid by customer is not the right one -> Status = payment error + // We don't use the following condition to avoid the float precision issues : http://www.php.net/manual/en/language.types.float.php + // if ($order->total_paid != $order->total_paid_real) + // We use number_format in order to compare two string + if ($order_status->logable && number_format($cart_total_paid, _PS_PRICE_COMPUTE_PRECISION_) != number_format($amount_paid, _PS_PRICE_COMPUTE_PRECISION_)) { + $id_order_state = Configuration::get('PS_OS_ERROR'); + } + + foreach ($package_list as $id_address => $packageByAddress) { + foreach ($packageByAddress as $id_package => $package) { + $orderData = $this->createOrderFromCart( + $this->context->cart, + $this->context->currency, + $package['product_list'], + $id_address, + $this->context, + $reference, + $secure_key, + $payment_method, + $this->name, + $dont_touch_amount, + $amount_paid, + $package_list[$id_address][$id_package]['id_warehouse'], + $cart_total_paid, + self::DEBUG_MODE, + $order_status, + $id_order_state, + isset($package['id_carrier']) ? $package['id_carrier'] : null + ); + $order = $orderData['order']; + $order_list[] = $order; + $order_detail_list[] = $orderData['orderDetail']; + } + } + + // The country can only change if the address used for the calculation is the delivery address, and if multi-shipping is activated + if (Configuration::get('PS_TAX_ADDRESS_TYPE') == 'id_address_delivery') { + $this->context->country = $context_country; + } + + if (!$this->context->country->active) { + PrestaShopLogger::addLog('PaymentModule::validateOrder - Country is not active', 3, null, 'Cart', (int) $id_cart, true); + + throw new PrestaShopException('The order address country is not active.'); + } + + if (self::DEBUG_MODE) { + PrestaShopLogger::addLog('PaymentModule::validateOrder - Payment is about to be added', 1, null, 'Cart', (int) $id_cart, true); + } + + // Register Payment only if the order status validate the order + if ($order_status->logable) { + // $order is the last order loop in the foreach + // The method addOrderPayment of the class Order make a create a paymentOrder + // linked to the order reference and not to the order id + if (isset($extra_vars['transaction_id'])) { + $transaction_id = $extra_vars['transaction_id']; + } else { + $transaction_id = null; + } + + if (!$order->addOrderPayment($amount_paid, null, $transaction_id)) { + PrestaShopLogger::addLog('PaymentModule::validateOrder - Cannot save Order Payment', 3, null, 'Cart', (int) $id_cart, true); + + throw new PrestaShopException('Can\'t save Order Payment'); + } + } + + // Next ! + $only_one_gift = false; + $products = $this->context->cart->getProducts(); + + // Make sure CartRule caches are empty + CartRule::cleanCache(); + foreach ($order_detail_list as $key => $order_detail) { + /** @var OrderDetail $order_detail */ + $order = $order_list[$key]; + if (isset($order->id)) { + if (!$secure_key) { + $message .= '
' . $this->trans('Warning: the secure key is empty, check your payment account before validation', array(), 'Admin.Payment.Notification'); + } + // Optional message to attach to this order + if (isset($message) & !empty($message)) { + $msg = new Message(); + $message = strip_tags($message, '
'); + if (Validate::isCleanHtml($message)) { + if (self::DEBUG_MODE) { + PrestaShopLogger::addLog('PaymentModule::validateOrder - Message is about to be added', 1, null, 'Cart', (int) $id_cart, true); + } + $msg->message = $message; + $msg->id_cart = (int) $id_cart; + $msg->id_customer = (int) ($order->id_customer); + $msg->id_order = (int) $order->id; + $msg->private = 1; + $msg->add(); + } + } + + // Insert new Order detail list using cart for the current order + //$orderDetail = new OrderDetail(null, null, $this->context); + //$orderDetail->createList($order, $this->context->cart, $id_order_state); + + // Construct order detail table for the email + $products_list = ''; + $virtual_product = true; + + $product_var_tpl_list = array(); + foreach ($order->product_list as $product) { + $price = Product::getPriceStatic((int) $product['id_product'], false, ($product['id_product_attribute'] ? (int) $product['id_product_attribute'] : null), 6, null, false, true, $product['cart_quantity'], false, (int) $order->id_customer, (int) $order->id_cart, (int) $order->{Configuration::get('PS_TAX_ADDRESS_TYPE')}, $specific_price, true, true, null, true, $product['id_customization']); + $price_wt = Product::getPriceStatic((int) $product['id_product'], true, ($product['id_product_attribute'] ? (int) $product['id_product_attribute'] : null), 2, null, false, true, $product['cart_quantity'], false, (int) $order->id_customer, (int) $order->id_cart, (int) $order->{Configuration::get('PS_TAX_ADDRESS_TYPE')}, $specific_price, true, true, null, true, $product['id_customization']); + + $product_price = Product::getTaxCalculationMethod() == PS_TAX_EXC ? Tools::ps_round($price, 2) : $price_wt; + + $product_var_tpl = array( + 'id_product' => $product['id_product'], + 'reference' => $product['reference'], + 'name' => $product['name'] . (isset($product['attributes']) ? ' - ' . $product['attributes'] : ''), + 'price' => Tools::displayPrice($product_price * $product['quantity'], $this->context->currency, false), + 'quantity' => $product['quantity'], + 'customization' => array(), + ); + + if (isset($product['price']) && $product['price']) { + $product_var_tpl['unit_price'] = Tools::displayPrice($product_price, $this->context->currency, false); + $product_var_tpl['unit_price_full'] = Tools::displayPrice($product_price, $this->context->currency, false) + . ' ' . $product['unity']; + } else { + $product_var_tpl['unit_price'] = $product_var_tpl['unit_price_full'] = ''; + } + + $customized_datas = Product::getAllCustomizedDatas((int) $order->id_cart, null, true, null, (int) $product['id_customization']); + if (isset($customized_datas[$product['id_product']][$product['id_product_attribute']])) { + $product_var_tpl['customization'] = array(); + foreach ($customized_datas[$product['id_product']][$product['id_product_attribute']][$order->id_address_delivery] as $customization) { + $customization_text = ''; + if (isset($customization['datas'][Product::CUSTOMIZE_TEXTFIELD])) { + foreach ($customization['datas'][Product::CUSTOMIZE_TEXTFIELD] as $text) { + $customization_text .= '' . $text['name'] . ': ' . $text['value'] . '
'; + } + } + + if (isset($customization['datas'][Product::CUSTOMIZE_FILE])) { + $customization_text .= $this->trans('%d image(s)', array(count($customization['datas'][Product::CUSTOMIZE_FILE])), 'Admin.Payment.Notification') . '
'; + } + + $customization_quantity = (int) $customization['quantity']; + + $product_var_tpl['customization'][] = array( + 'customization_text' => $customization_text, + 'customization_quantity' => $customization_quantity, + 'quantity' => Tools::displayPrice($customization_quantity * $product_price, $this->context->currency, false), + ); + } + } + + $product_var_tpl_list[] = $product_var_tpl; + // Check if is not a virutal product for the displaying of shipping + if (!$product['is_virtual']) { + $virtual_product &= false; + } + } // end foreach ($products) + + $product_list_txt = ''; + $product_list_html = ''; + if (count($product_var_tpl_list) > 0) { + $product_list_txt = $this->getEmailTemplateContent('order_conf_product_list.txt', Mail::TYPE_TEXT, $product_var_tpl_list); + $product_list_html = $this->getEmailTemplateContent('order_conf_product_list.tpl', Mail::TYPE_HTML, $product_var_tpl_list); + } + + $total_reduction_value_ti = 0; + $total_reduction_value_tex = 0; + + $cart_rules_list = $this->createOrderCartRules( + $order, + $this->context->cart, + $order_list, + $total_reduction_value_ti, + $total_reduction_value_tex, + $id_order_state + ); + + $cart_rules_list_txt = ''; + $cart_rules_list_html = ''; + if (count($cart_rules_list) > 0) { + $cart_rules_list_txt = $this->getEmailTemplateContent('order_conf_cart_rules.txt', Mail::TYPE_TEXT, $cart_rules_list); + $cart_rules_list_html = $this->getEmailTemplateContent('order_conf_cart_rules.tpl', Mail::TYPE_HTML, $cart_rules_list); + } + + // Specify order id for message + $old_message = Message::getMessageByCartId((int) $this->context->cart->id); + if ($old_message && !$old_message['private']) { + $update_message = new Message((int) $old_message['id_message']); + $update_message->id_order = (int) $order->id; + $update_message->update(); + + // Add this message in the customer thread + $customer_thread = new CustomerThread(); + $customer_thread->id_contact = 0; + $customer_thread->id_customer = (int) $order->id_customer; + $customer_thread->id_shop = (int) $this->context->shop->id; + $customer_thread->id_order = (int) $order->id; + $customer_thread->id_lang = (int) $this->context->language->id; + $customer_thread->email = $this->context->customer->email; + $customer_thread->status = 'open'; + $customer_thread->token = Tools::passwdGen(12); + $customer_thread->add(); + + $customer_message = new CustomerMessage(); + $customer_message->id_customer_thread = $customer_thread->id; + $customer_message->id_employee = 0; + $customer_message->message = $update_message->message; + $customer_message->private = 1; + + if (!$customer_message->add()) { + $this->errors[] = $this->trans('An error occurred while saving message', array(), 'Admin.Payment.Notification'); + } + } + + if (self::DEBUG_MODE) { + PrestaShopLogger::addLog('PaymentModule::validateOrder - Hook validateOrder is about to be called', 1, null, 'Cart', (int) $id_cart, true); + } + + // Hook validate order + Hook::exec('actionValidateOrder', array( + 'cart' => $this->context->cart, + 'order' => $order, + 'customer' => $this->context->customer, + 'currency' => $this->context->currency, + 'orderStatus' => $order_status, + )); + + foreach ($this->context->cart->getProducts() as $product) { + if ($order_status->logable) { + ProductSale::addProductSale((int) $product['id_product'], (int) $product['cart_quantity']); + } + } + + if (self::DEBUG_MODE) { + PrestaShopLogger::addLog('PaymentModule::validateOrder - Order Status is about to be added', 1, null, 'Cart', (int) $id_cart, true); + } + + // Set the order status + $new_history = new OrderHistory(); + $new_history->id_order = (int) $order->id; + $new_history->changeIdOrderState((int) $id_order_state, $order, true); + $new_history->addWithemail(true, $extra_vars); + + // Switch to back order if needed + if (Configuration::get('PS_STOCK_MANAGEMENT') && + ($order_detail->getStockState() || + $order_detail->product_quantity_in_stock < 0)) { + $history = new OrderHistory(); + $history->id_order = (int) $order->id; + $history->changeIdOrderState(Configuration::get($order->hasBeenPaid() ? 'PS_OS_OUTOFSTOCK_PAID' : 'PS_OS_OUTOFSTOCK_UNPAID'), $order, true); + $history->addWithemail(); + } + + unset($order_detail); + + // Order is reloaded because the status just changed + $order = new Order((int) $order->id); + + // Send an e-mail to customer (one order = one email) + if ($id_order_state != Configuration::get('PS_OS_ERROR') && $id_order_state != Configuration::get('PS_OS_CANCELED') && $this->context->customer->id) { + $invoice = new Address((int) $order->id_address_invoice); + $delivery = new Address((int) $order->id_address_delivery); + $delivery_state = $delivery->id_state ? new State((int) $delivery->id_state) : false; + $invoice_state = $invoice->id_state ? new State((int) $invoice->id_state) : false; + $carrier = $order->id_carrier ? new Carrier($order->id_carrier) : false; + + $data = array( + '{firstname}' => $this->context->customer->firstname, + '{lastname}' => $this->context->customer->lastname, + '{email}' => $this->context->customer->email, + '{delivery_block_txt}' => $this->_getFormatedAddress($delivery, AddressFormat::FORMAT_NEW_LINE), + '{invoice_block_txt}' => $this->_getFormatedAddress($invoice, AddressFormat::FORMAT_NEW_LINE), + '{delivery_block_html}' => $this->_getFormatedAddress($delivery, '
', array( + 'firstname' => '%s', + 'lastname' => '%s', + )), + '{invoice_block_html}' => $this->_getFormatedAddress($invoice, '
', array( + 'firstname' => '%s', + 'lastname' => '%s', + )), + '{delivery_company}' => $delivery->company, + '{delivery_firstname}' => $delivery->firstname, + '{delivery_lastname}' => $delivery->lastname, + '{delivery_address1}' => $delivery->address1, + '{delivery_address2}' => $delivery->address2, + '{delivery_city}' => $delivery->city, + '{delivery_postal_code}' => $delivery->postcode, + '{delivery_country}' => $delivery->country, + '{delivery_state}' => $delivery->id_state ? $delivery_state->name : '', + '{delivery_phone}' => ($delivery->phone) ? $delivery->phone : $delivery->phone_mobile, + '{delivery_other}' => $delivery->other, + '{invoice_company}' => $invoice->company, + '{invoice_vat_number}' => $invoice->vat_number, + '{invoice_firstname}' => $invoice->firstname, + '{invoice_lastname}' => $invoice->lastname, + '{invoice_address2}' => $invoice->address2, + '{invoice_address1}' => $invoice->address1, + '{invoice_city}' => $invoice->city, + '{invoice_postal_code}' => $invoice->postcode, + '{invoice_country}' => $invoice->country, + '{invoice_state}' => $invoice->id_state ? $invoice_state->name : '', + '{invoice_phone}' => ($invoice->phone) ? $invoice->phone : $invoice->phone_mobile, + '{invoice_other}' => $invoice->other, + '{order_name}' => $order->getUniqReference(), + '{date}' => Tools::displayDate(date('Y-m-d H:i:s'), null, 1), + '{carrier}' => ($virtual_product || !isset($carrier->name)) ? $this->trans('No carrier', array(), 'Admin.Payment.Notification') : $carrier->name, + '{payment}' => Tools::substr($order->payment, 0, 255), + '{products}' => $product_list_html, + '{products_txt}' => $product_list_txt, + '{discounts}' => $cart_rules_list_html, + '{discounts_txt}' => $cart_rules_list_txt, + '{total_paid}' => Tools::displayPrice($order->total_paid, $this->context->currency, false), + '{total_products}' => Tools::displayPrice(Product::getTaxCalculationMethod() == PS_TAX_EXC ? $order->total_products : $order->total_products_wt, $this->context->currency, false), + '{total_discounts}' => Tools::displayPrice($order->total_discounts, $this->context->currency, false), + '{total_shipping}' => Tools::displayPrice($order->total_shipping, $this->context->currency, false), + '{total_shipping_tax_excl}' => Tools::displayPrice($order->total_shipping_tax_excl, $this->context->currency, false), + '{total_shipping_tax_incl}' => Tools::displayPrice($order->total_shipping_tax_incl, $this->context->currency, false), + '{total_wrapping}' => Tools::displayPrice($order->total_wrapping, $this->context->currency, false), + '{total_tax_paid}' => Tools::displayPrice(($order->total_products_wt - $order->total_products) + ($order->total_shipping_tax_incl - $order->total_shipping_tax_excl), $this->context->currency, false), + '{specialization}' => $this->getCustomerSpecialization($this->context->customer->specialization), /* ****** Begin2: Display specialization field in new order email ****** */ + ); + + if (is_array($extra_vars)) { + $data = array_merge($data, $extra_vars); + } + + // Join PDF invoice + if ((int) Configuration::get('PS_INVOICE') && $order_status->invoice && $order->invoice_number) { + $order_invoice_list = $order->getInvoicesCollection(); + Hook::exec('actionPDFInvoiceRender', array('order_invoice_list' => $order_invoice_list)); + $pdf = new PDF($order_invoice_list, PDF::TEMPLATE_INVOICE, $this->context->smarty); + $file_attachement['content'] = $pdf->render(false); + $file_attachement['name'] = Configuration::get('PS_INVOICE_PREFIX', (int) $order->id_lang, null, $order->id_shop) . sprintf('%06d', $order->invoice_number) . '.pdf'; + $file_attachement['mime'] = 'application/pdf'; + } else { + $file_attachement = null; + } + + if (self::DEBUG_MODE) { + PrestaShopLogger::addLog('PaymentModule::validateOrder - Mail is about to be sent', 1, null, 'Cart', (int) $id_cart, true); + } + + $orderLanguage = new Language((int) $order->id_lang); + + if (Validate::isEmail($this->context->customer->email)) { + Mail::Send( + (int) $order->id_lang, + 'order_conf', + Context::getContext()->getTranslator()->trans( + 'Order confirmation', + array(), + 'Emails.Subject', + $orderLanguage->locale + ), + $data, + $this->context->customer->email, + $this->context->customer->firstname . ' ' . $this->context->customer->lastname, + null, + null, + $file_attachement, + null, + _PS_MODULE_DIR_.'pchcustomerfield/mails/',//_PS_MAIL_DIR_, /* ****** Begin3: Display specialization field in new order email ****** */ + false, + (int) $order->id_shop + ); + } + } + + // updates stock in shops + if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) { + $product_list = $order->getProducts(); + foreach ($product_list as $product) { + // if the available quantities depends on the physical stock + if (StockAvailable::dependsOnStock($product['product_id'])) { + // synchronizes + StockAvailable::synchronize($product['product_id'], $order->id_shop); + } + } + } + + $order->updateOrderDetailTax(); + + // sync all stock + (new StockManager())->updatePhysicalProductQuantity( + (int) $order->id_shop, + (int) Configuration::get('PS_OS_ERROR'), + (int) Configuration::get('PS_OS_CANCELED'), + null, + (int) $order->id + ); + } else { + $error = $this->trans('Order creation failed', array(), 'Admin.Payment.Notification'); + PrestaShopLogger::addLog($error, 4, '0000002', 'Cart', (int) ($order->id_cart)); + die(Tools::displayError($error)); + } + } // End foreach $order_detail_list + + // Use the last order as currentOrder + if (isset($order) && $order->id) { + $this->currentOrder = (int) $order->id; + } + + if (self::DEBUG_MODE) { + PrestaShopLogger::addLog('PaymentModule::validateOrder - End of validateOrder', 1, null, 'Cart', (int) $id_cart, true); + } + + return true; + } else { + $error = $this->trans('Cart cannot be loaded or an order has already been placed using this cart', array(), 'Admin.Payment.Notification'); + PrestaShopLogger::addLog($error, 4, '0000001', 'Cart', (int) ($this->context->cart->id)); + die(Tools::displayError($error)); + } + } + + protected function getCustomerSpecialization($specialization_id) + { + $module = Module::getInstanceByName('pchcustomerfield'); + if(!$specialization = $module->getSpecializationBySpecializationId($specialization_id)) { + return '--'; + } + else { + return $specialization; + } + } +} diff --git a/pchcustomerfield/override/classes/form/CustomerAddressFormatter.php b/pchcustomerfield/override/classes/form/CustomerAddressFormatter.php new file mode 100644 index 0000000..6487dc0 --- /dev/null +++ b/pchcustomerfield/override/classes/form/CustomerAddressFormatter.php @@ -0,0 +1,208 @@ +country = $country; + $this->translator = $translator; + $this->availableCountries = $availableCountries; + $this->definition = Address::$definition['fields']; + } + + public function getFormat() + { + $fields = AddressFormat::getOrderedAddressFields( + $this->country->id, + true, + true + ); + $required = array_flip(AddressFormat::getFieldsRequired()); + + $format = [ + 'back' => (new FormField()) + ->setName('back') + ->setType('hidden'), + 'token' => (new FormField()) + ->setName('token') + ->setType('hidden'), + 'alias' => (new FormField()) + ->setName('alias') + ->setLabel( + $this->getFieldLabel('alias') + ), + ]; + + foreach ($fields as $field) { + $formField = new FormField(); + $formField->setName($field); + + $fieldParts = explode(':', $field, 2); + + if (count($fieldParts) === 1) { + if ($field === 'postcode') { + if ($this->country->need_zip_code) { + $formField->setRequired(true); + } + } elseif ($field === 'phone') { + $formField->setType('tel'); + } elseif ($field === 'dni' && null !== $this->country) { + if ($this->country->need_identification_number) { + $formField->setRequired(true); + } + } + } elseif (count($fieldParts) === 2) { + list($entity, $entityField) = $fieldParts; + + // Fields specified using the Entity:field + // notation are actually references to other + // entities, so they should be displayed as a select + $formField->setType('select'); + + // Also, what we really want is the id of the linked entity + $formField->setName('id_' . strtolower($entity)); + + if ($entity === 'Country') { + $formField->setType('countrySelect'); + $formField->setValue($this->country->id); + foreach ($this->availableCountries as $country) { + $formField->addAvailableValue( + $country['id_country'], + $country[$entityField] + ); + } + } elseif ($entity === 'State') { + if ($this->country->contains_states) { + $states = State::getStatesByIdCountry($this->country->id, true); + foreach ($states as $state) { + $formField->addAvailableValue( + $state['id_state'], + $state[$entityField] + ); + } + $formField->setRequired(true); + } + } + } + + $formField->setLabel($this->getFieldLabel($field)); + if (!$formField->isRequired()) { + // Only trust the $required array for fields + // that are not marked as required. + // $required doesn't have all the info, and fields + // may be required for other reasons than what + // AddressFormat::getFieldsRequired() says. + $formField->setRequired( + array_key_exists($field, $required) + ); + } + + $format[$formField->getName()] = $formField; + } + + //To add the extra fields in address form + //$additionalAddressFormFields = Hook::exec('additionalCustomerAddressFields', array(), null, true); + $additionalAddressFormFields = Hook::exec('additionalCustomerAddressFields', ['fields' => &$format], null, true); + if (is_array($additionalAddressFormFields)) { + foreach ($additionalAddressFormFields as $moduleName => $additionnalFormFields) { + if (!is_array($additionnalFormFields)) { + continue; + } + + foreach ($additionnalFormFields as $formField) { + $formField->moduleName = $moduleName; + $format[$moduleName . '_' . $formField->getName()] = $formField; + } + } + } + + return $this->addConstraints( + $this->addMaxLength( + $format + ) + ); + } + + private function addConstraints(array $format) + { + foreach ($format as $field) { + if (!empty($this->definition[$field->getName()]['validate'])) { + $field->addConstraint( + $this->definition[$field->getName()]['validate'] + ); + } + } + + return $format; + } + + private function addMaxLength(array $format) + { + foreach ($format as $field) { + if (!empty($this->definition[$field->getName()]['size'])) { + $field->setMaxLength( + $this->definition[$field->getName()]['size'] + ); + } + } + + return $format; + } + + private function getFieldLabel($field) + { + // Country:name => Country, Country:iso_code => Country, + // same label regardless of which field is used for mapping. + $field = explode(':', $field)[0]; + + switch ($field) { + case 'alias': + return $this->translator->trans('Alias', [], 'Shop.Forms.Labels'); + case 'firstname': + return $this->translator->trans('First name', [], 'Shop.Forms.Labels'); + case 'lastname': + return $this->translator->trans('Last name', [], 'Shop.Forms.Labels'); + case 'address1': + return $this->translator->trans('Address', [], 'Shop.Forms.Labels'); + case 'address2': + return $this->translator->trans('Address Complement', [], 'Shop.Forms.Labels'); + case 'postcode': + return $this->translator->trans('Zip/Postal Code', [], 'Shop.Forms.Labels'); + case 'city': + return $this->translator->trans('City', [], 'Shop.Forms.Labels'); + case 'Country': + return $this->translator->trans('Country', [], 'Shop.Forms.Labels'); + case 'State': + return $this->translator->trans('State', [], 'Shop.Forms.Labels'); + case 'phone': + return $this->translator->trans('Phone', [], 'Shop.Forms.Labels'); + case 'phone_mobile': + return $this->translator->trans('Mobile phone', [], 'Shop.Forms.Labels'); + case 'company': + return $this->translator->trans('Company', [], 'Shop.Forms.Labels'); + case 'vat_number': + return $this->translator->trans('VAT number', [], 'Shop.Forms.Labels'); + case 'dni': + return $this->translator->trans('Identification number', [], 'Shop.Forms.Labels'); + case 'other': + return $this->translator->trans('Other', [], 'Shop.Forms.Labels'); + default: + return $field; + } + } +} diff --git a/pchcustomerfield/override/classes/form/CustomerFormatter.php b/pchcustomerfield/override/classes/form/CustomerFormatter.php new file mode 100644 index 0000000..08e3dd6 --- /dev/null +++ b/pchcustomerfield/override/classes/form/CustomerFormatter.php @@ -0,0 +1,242 @@ +translator = $translator; + $this->language = $language; + } + + public function setAskForBirthdate($ask_for_birthdate) + { + $this->ask_for_birthdate = $ask_for_birthdate; + + return $this; + } + + public function setAskForPartnerOptin($ask_for_partner_optin) + { + $this->ask_for_partner_optin = $ask_for_partner_optin; + + return $this; + } + + public function setPartnerOptinRequired($partner_optin_is_required) + { + $this->partner_optin_is_required = $partner_optin_is_required; + + return $this; + } + + public function setAskForPassword($ask_for_password) + { + $this->ask_for_password = $ask_for_password; + + return $this; + } + + public function setAskForNewPassword($ask_for_new_password) + { + $this->ask_for_new_password = $ask_for_new_password; + + return $this; + } + + public function setPasswordRequired($password_is_required) + { + $this->password_is_required = $password_is_required; + + return $this; + } + + public function getFormat() + { + $format = []; + + $genders = Gender::getGenders($this->language->id); + if ($genders->count() > 0) { + $genderField = (new FormField()) + ->setName('id_gender') + ->setType('radio-buttons') + ->setLabel( + $this->translator->trans( + 'Social title', + [], + 'Shop.Forms.Labels' + ) + ); + foreach ($genders as $gender) { + $genderField->addAvailableValue($gender->id, $gender->name); + } + $format[$genderField->getName()] = $genderField; + } + + $format['firstname'] = (new FormField()) + ->setName('firstname') + ->setLabel( + $this->translator->trans( + 'First name', + [], + 'Shop.Forms.Labels' + ) + ) + ->setRequired(true); + + $format['lastname'] = (new FormField()) + ->setName('lastname') + ->setLabel( + $this->translator->trans( + 'Last name', + [], + 'Shop.Forms.Labels' + ) + ) + ->setRequired(true); + + if (Configuration::get('PS_B2B_ENABLE')) { + $format['company'] = (new FormField()) + ->setName('company') + ->setType('text') + ->setLabel($this->translator->trans( + 'Company', + [], + 'Shop.Forms.Labels' + )); + $format['siret'] = (new FormField()) + ->setName('siret') + ->setType('text') + ->setLabel($this->translator->trans( + // Please localize this string with the applicable registration number type in your country. For example : "SIRET" in France and "Código fiscal" in Spain. + 'Identification number', + [], + 'Shop.Forms.Labels' + )); + } + + $format['email'] = (new FormField()) + ->setName('email') + ->setType('email') + ->setLabel( + $this->translator->trans( + 'Email', + [], + 'Shop.Forms.Labels' + ) + ) + ->setRequired(true); + + if ($this->ask_for_password) { + $format['password'] = (new FormField()) + ->setName('password') + ->setType('password') + ->setLabel( + $this->translator->trans( + 'Password', + [], + 'Shop.Forms.Labels' + ) + ) + ->setRequired($this->password_is_required); + } + + if ($this->ask_for_new_password) { + $format['new_password'] = (new FormField()) + ->setName('new_password') + ->setType('password') + ->setLabel( + $this->translator->trans( + 'New password', + [], + 'Shop.Forms.Labels' + ) + ); + } + + if ($this->ask_for_birthdate) { + $format['birthday'] = (new FormField()) + ->setName('birthday') + ->setType('text') + ->setLabel( + $this->translator->trans( + 'Birthdate', + [], + 'Shop.Forms.Labels' + ) + ) + ->addAvailableValue('placeholder', Tools::getDateFormat()) + ->addAvailableValue( + 'comment', + $this->translator->trans('(E.g.: %date_format%)', array('%date_format%' => Tools::formatDateStr('31 May 1970')), 'Shop.Forms.Help') + ); + } + + if ($this->ask_for_partner_optin) { + $format['optin'] = (new FormField()) + ->setName('optin') + ->setType('checkbox') + ->setLabel( + $this->translator->trans( + 'Receive offers from our partners', + [], + 'Shop.Theme.Customeraccount' + ) + ) + ->setRequired($this->partner_optin_is_required); + } + + // ToDo, replace the hook exec with HookFinder when the associated PR will be merged + //$additionalCustomerFormFields = Hook::exec('additionalCustomerFormFields', array(), null, true); + $additionalCustomerFormFields = Hook::exec('additionalCustomerFormFields', ['fields' => &$format], null, true); + + if (is_array($additionalCustomerFormFields)) { + foreach ($additionalCustomerFormFields as $moduleName => $additionnalFormFields) { + if (!is_array($additionnalFormFields)) { + continue; + } + + foreach ($additionnalFormFields as $formField) { + $formField->moduleName = $moduleName; + $format[$moduleName . '_' . $formField->getName()] = $formField; + } + } + } + + // TODO: TVA etc.? + + return $this->addConstraints($format); + } + + private function addConstraints(array $format) + { + $constraints = Customer::$definition['fields']; + + foreach ($format as $field) { + if (!empty($constraints[$field->getName()]['validate'])) { + $field->addConstraint( + $constraints[$field->getName()]['validate'] + ); + } + } + + return $format; + } +} diff --git a/pchcustomerfield/override/classes/form/index.php b/pchcustomerfield/override/classes/form/index.php new file mode 100644 index 0000000..87daa20 --- /dev/null +++ b/pchcustomerfield/override/classes/form/index.php @@ -0,0 +1,34 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/pchcustomerfield/override/classes/index.php b/pchcustomerfield/override/classes/index.php new file mode 100644 index 0000000..87daa20 --- /dev/null +++ b/pchcustomerfield/override/classes/index.php @@ -0,0 +1,34 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/pchcustomerfield/override/index.php b/pchcustomerfield/override/index.php new file mode 100644 index 0000000..87daa20 --- /dev/null +++ b/pchcustomerfield/override/index.php @@ -0,0 +1,34 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/pchcustomerfield/pchcustomerfield.php b/pchcustomerfield/pchcustomerfield.php new file mode 100644 index 0000000..c21fffc --- /dev/null +++ b/pchcustomerfield/pchcustomerfield.php @@ -0,0 +1,567 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerException; +use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; +use PrestaShop\PrestaShop\Core\Grid\Definition\GridDefinitionInterface; +use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; + +if (!defined('_PS_VERSION_')) { + exit; +} + +include_once dirname(__FILE__) . '/models/PchCustomerfieldModel.php'; + +class Pchcustomerfield extends Module +{ + protected $config_form = false; + private $tab_class = 'AdminPchCustomerFields'; + + public function __construct() + { + $this->name = 'pchcustomerfield'; + $this->tab = 'front_office_features'; + $this->version = '1.0.0'; + $this->author = 'Prestachamps'; + $this->need_instance = 0; + + /** + * Set $this->bootstrap to true if your module is compliant with bootstrap (PrestaShop 1.6) + */ + $this->bootstrap = true; + + parent::__construct(); + + $this->displayName = $this->l('Additional Customer Field'); + $this->description = $this->l('Display specialization field on the customer form'); + + $this->confirmUninstall = $this->l('Are you sure you want to uninstall the module?'); + + $this->ps_versions_compliancy = array('min' => '1.7', 'max' => _PS_VERSION_); + } + + /** + * Don't forget to create update methods if needed: + * http://doc.prestashop.com/display/PS16/Enabling+the+Auto-Update + */ + public function install() + { + if (!$this->existsTab()) { + if (!$this->addTab()) { + return false; + } + } + + Configuration::updateValue('PCHCUSTOMERFIELD_LIVE_MODE', false); + + include dirname(__FILE__) . '/sql/install.php'; + + return parent::install() && + $this->registerHook('backOfficeHeader') && + $this->registerHook('displayAdminCustomers') && + $this->registerHook('actionCustomerGridDefinitionModifier') && + $this->registerHook('actionCustomerGridQueryBuilderModifier') && + $this->registerHook('additionalCustomerFormFields') && + $this->registerHook('actionCustomerFormBuilderModifier') && + $this->registerHook('actionAfterCreateCustomerFormHandler') && + $this->registerHook('actionAfterUpdateCustomerFormHandler') && + $this->alterCustomerTable(); + } + + public function uninstall() + { + if (!$this->removeTab()) { + return false; + } + + Configuration::deleteByName('PCHCUSTOMERFIELD_LIVE_MODE'); + + include dirname(__FILE__) . '/sql/uninstall.php'; + + return parent::uninstall() && + $this->uninstallAlterCustomerTable(); + } + + private function addTab() + { + $return = true; + $tab = new Tab(); + $tab->class_name = $this->tab_class; + $tab->id_parent = 0; + $tab->module = $this->name; + $tab->name[(int) Configuration::get('PS_LANG_DEFAULT')] = $this->l('Customer specialization fields'); + $return &= $tab->add(); + + $subTab = new Tab(); + $subTab->class_name = 'AdminPchCustomerfield'; + $subTab->id_parent = $tab->id; + $subTab->module = $this->name; + $subTab->name[(int) Configuration::get('PS_LANG_DEFAULT')] = $this->l('Manage Customer specialization values'); + if (true === Tools::version_compare(_PS_VERSION_, '1.7', '>=')) { + $subTab->icon = 'settings'; + } + $return &= $subTab->add(); + + return $return; + } + + private function removeTab() + { + $return = true; + $tabs = ['PchCustomerfield', $this->tab_class]; + foreach ($tabs as $tab) { + if (Validate::isLoadedObject($tab = Tab::getInstanceFromClassName($tab))) { + return $return &= $tab->delete(); + } + } + return $return; + } + + public function existsTab() + { + $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('SELECT id_tab AS id + FROM `' . _DB_PREFIX_ . 'tab` t WHERE LOWER(t.`class_name`) = \'' . pSQL($this->tab_class) . '\''); + if (count($result) == 0) { + return false; + } + return true; + } + + /** + * Alter customer table, add module fields + * + * @return bool true if success or already done. + */ + protected function alterCustomerTable() + { + // check if the column already exists: + $column_exists = Db::getInstance()->getValue("SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE + TABLE_SCHEMA = '" . pSQL(_DB_NAME_) . "' AND TABLE_NAME = '" . pSQL(_DB_PREFIX_) . "customer' AND + COLUMN_NAME = 'specialization'"); + + if((int) !$column_exists) { + $sql = 'ALTER TABLE `' . pSQL(_DB_PREFIX_) . 'customer` ADD `specialization` INT NOT NULL'; + // CLEAN_INSTALATION 1/2 (if you want to delete all data after an installation) + // comment: + Db::getInstance()->execute($sql); + return true; + // and uncomment: + // return Db::getInstance()->execute($sql); + } + + return true; + } + + /** + * Uninstalls sample tables required for demonstration. + * + * @return bool + */ + private function uninstallAlterCustomerTable() + { + // CLEAN_INSTALATION 2/2 (if you want to delete all data after an installation) + // uncomment: + // $sql = 'ALTER TABLE `' . pSQL(_DB_PREFIX_) . 'customer` DROP `specialization`'; + // return Db::getInstance()->execute($sql); + // + // and comment: + return true; + } + + /** + * Load the configuration form + */ + public function getContent() + { + /** + * If values have been submitted in the form, process. + */ + if (((bool)Tools::isSubmit('submitPchcustomerfieldModule')) == true) { + $this->postProcess(); + } + + $output = $this->renderForm(); + + return $output; + } + + /** + * Create the form that will be displayed in the configuration of your module. + */ + protected function renderForm() + { + $helper = new HelperForm(); + + $helper->show_toolbar = false; + $helper->table = $this->table; + $helper->module = $this; + $helper->default_form_language = $this->context->language->id; + $helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG', 0); + + $helper->identifier = $this->identifier; + $helper->submit_action = 'submitPchcustomerfieldModule'; + $helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false) + .'&configure='.$this->name.'&tab_module='.$this->tab.'&module_name='.$this->name; + $helper->token = Tools::getAdminTokenLite('AdminModules'); + + $helper->tpl_vars = array( + 'fields_value' => $this->getConfigFormValues(), /* Add values for your inputs */ + 'languages' => $this->context->controller->getLanguages(), + 'id_language' => $this->context->language->id, + ); + + return $helper->generateForm(array($this->getConfigForm())); + } + + /** + * Create the structure of your form. + */ + protected function getConfigForm() + { + return array( + 'form' => array( + 'legend' => array( + 'title' => $this->l('Settings'), + 'icon' => 'icon-cogs', + ), + 'input' => array( + array( + 'type' => 'switch', + 'label' => $this->l('Live mode'), + 'name' => 'PCHCUSTOMERFIELD_LIVE_MODE', + 'is_bool' => true, + 'desc' => $this->l('Use this module in live mode'), + 'values' => array( + array( + 'id' => 'active_on', + 'value' => true, + 'label' => $this->l('Enabled') + ), + array( + 'id' => 'active_off', + 'value' => false, + 'label' => $this->l('Disabled') + ) + ), + ), + ), + 'submit' => array( + 'title' => $this->l('Save'), + ), + ), + ); + } + + /** + * Set values for the inputs. + */ + protected function getConfigFormValues() + { + return array( + 'PCHCUSTOMERFIELD_LIVE_MODE' => Configuration::get('PCHCUSTOMERFIELD_LIVE_MODE', true), + ); + } + + /** + * Save form data. + */ + protected function postProcess() + { + $form_values = $this->getConfigFormValues(); + + foreach (array_keys($form_values) as $key) { + Configuration::updateValue($key, Tools::getValue($key)); + } + } + + /** + * Add the CSS & JavaScript files you want to be loaded in the BO. + */ + public function hookBackOfficeHeader() + { + if (Tools::getValue('controller') == 'AdminCustomers') { + $this->context->controller->addJS($this->_path.'views/js/back.js'); + } + } + + /** + * This hook displays a new block on the admin customer page + * + * @param array $params + * + * @return string + */ + public function hookDisplayAdminCustomers(array $params) + { + if (isset($params['id_customer'])) { + if (!$specialization = PchCustomerfieldModel::getSpecializationByCustomerId($this->context->language->id, $params['id_customer'])) { + return; + } + + $this->smarty->assign([ + 'specialization' => $specialization, + ]); + + return $this->fetch('module:pchcustomerfield/views/templates/hook/displayAdminCustomers.tpl'); + } + } + + /** + * Hook allows to modify Customers grid definition. + * This hook is a right place to add/remove columns or actions (bulk, grid). + * + * @param array $params + */ + public function hookActionCustomerGridDefinitionModifier(array $params) + { + if (empty($params['definition'])) { + return; + } + + /** @var GridDefinitionInterface $definition */ + $definition = $params['definition']; + + $definition + ->getColumns() + ->addBefore( + 'social_title', + (new DataColumn('specialization')) + ->setName($this->l('Specialization')) + ->setOptions([ + 'field' => 'specialization', + ]) + ); + + if (!$specializationFields = PchCustomerfieldModel::getSpecializationValues($this->context->language->id, true)) { + return; + } + $specializationFieldsKeys = array_column($specializationFields, 'id_pchcustomerfield'); + $specializationFieldsValues = array_column($specializationFields, 'title'); + $specializationFieldsKeyValues = array_flip(array_combine($specializationFieldsKeys, $specializationFieldsValues)); + + $definition->getFilters()->add( + (new Filter('specialization', ChoiceType::class)) + ->setTypeOptions([ + 'choices' => array_merge(['--' => 0], $specializationFieldsKeyValues), + 'required' => false + ]) + ->setAssociatedColumn('specialization') + ); + } + + + /** + * Hook allows to modify Customers query builder and add custom sql statements. + * + * @param array $params + */ + public function hookActionCustomerGridQueryBuilderModifier(array $params) + { + /** @var QueryBuilder $searchQueryBuilder */ + $searchQueryBuilder = $params['search_query_builder']; + /** @var CustomerFilters $searchCriteria */ + $searchCriteria = $params['search_criteria']; + + $id_lang = (int)Context::getContext()->language->id; + $select_specialization_sql = '(SELECT cfl.`title` + FROM `'._DB_PREFIX_.'pchcustomerfield_lang` cfl + WHERE c.specialization = cfl.id_pchcustomerfield AND cfl.id_lang = '.(int)$id_lang.')'; + + $searchQueryBuilder->addSelect( + 'IF(' . $select_specialization_sql . ' IS NULL,"--",'.$select_specialization_sql.') AS `specialization`' + ); + + if ('specialization' === $searchCriteria->getOrderBy()) { + $searchQueryBuilder->orderBy('specialization', $searchCriteria->getOrderWay()); + } + + foreach ($searchCriteria->getFilters() as $filterName => $filterValue) { + if ('specialization' === $filterName) { + $searchQueryBuilder->andWhere('c.`specialization` = :specialization'); + $searchQueryBuilder->setParameter('specialization', $filterValue); + //dump($filterValue);die(); + if (!$filterValue) { + $searchQueryBuilder->orWhere('c.`specialization` IS NULL'); + } + } + } + } + + + /** + * Hook allows to modify Customers form and add additional form fields as well as modify or add new data to the forms. + * FRONT_END + * @param array $params + * @return array + */ + public function hookAdditionalCustomerFormFields($params) + { + if (!Configuration::get('PCHCUSTOMERFIELD_LIVE_MODE')) { + return; + } + + if (!$specializationFields = PchCustomerfieldModel::getSpecializationValues($this->context->language->id)) { + return; + } + $specializationFieldsKeys = array_column($specializationFields, 'id_pchcustomerfield'); + $specializationFieldsValues = array_column($specializationFields, 'title'); + $specializationFieldsKeyValues = array_combine($specializationFieldsKeys, $specializationFieldsValues); + + $specializationField = [ + (new FormField) + ->setName('specialization') + ->setType('select') + ->setRequired(true) // is Required + ->setAvailableValues($specializationFieldsKeyValues) + ->setLabel($this->l('Specialization')) + ]; + + // We want to insert it after Email + if (isset($params['fields'])) { + // Where is Email? + $position = (int)array_search('email', array_keys($params['fields']), null) + 1; + + // How many fields do we have? + $fieldCount = count($params['fields']); + + // Lets insert it... + $result = array_merge( + array_slice($params['fields'], 0, $position), + $specializationField, + array_slice($params['fields'], $position - $fieldCount) + ); + + $params['fields'] = $result; + + return; + } + else { + return $specializationField; + } + } + + + /** + * Hook allows to modify Customers form and add additional form fields as well as modify or add new data to the forms. + * BACK_END + * @param array $params + */ + public function hookActionCustomerFormBuilderModifier(array $params) + { + /** @var FormBuilderInterface $formBuilder */ + $formBuilder = $params['form_builder']; + + if (!$specializationFields = PchCustomerfieldModel::getSpecializationValues($this->context->language->id, false)) { + return; + } + $specializationFieldsKeys = array_column($specializationFields, 'id_pchcustomerfield'); + $specializationFieldsValues = array_column($specializationFields, 'title'); + $specializationFieldsKeyValues = array_flip(array_combine($specializationFieldsKeys, $specializationFieldsValues)); + + $formBuilder->add('specialization', ChoiceType::class, [ + 'choices' => $specializationFieldsKeyValues, + 'label' => $this->l('Specialization'), + 'required' => true, + 'placeholder' => $this->l('Please select'), + ]); + + $customer = new Customer($params['id']); + $params['data']['specialization'] = $customer->specialization; + + $formBuilder->setData($params['data']); + } + + + /** + * Hook allows to modify Customers form and add additional form fields as well as modify or add new data to the forms. + * + * @param array $params + * + * @throws CustomerException + * @throws PrestaShopDatabaseException + * @throws PrestaShopException + */ + public function hookActionAfterUpdateCustomerFormHandler(array $params) + { + $this->updateCustomerSpecialization($params); + } + + /** + * Hook allows to modify Customers form and add additional form fields as well as modify or add new data to the forms. + * + * @param array $params + * + * @throws CustomerException + * @throws PrestaShopDatabaseException + * @throws PrestaShopException + */ + public function hookActionAfterCreateCustomerFormHandler(array $params) + { + $this->updateCustomerSpecialization($params); + } + + + /** + * Update / Create + * + * @param array $params + * + * @throws CustomerException + * @throws PrestaShopDatabaseException + * @throws PrestaShopException + */ + private function updateCustomerSpecialization(array $params) + { + $customerId = (int)$params['id']; + /** @var array $customerFormData */ + $customerFormData = $params['form_data']; + $specialization = $customerFormData['specialization']; + + try { + + $customer = new Customer($customerId); + $customer->specialization = $specialization; + $customer->update(); + + } catch (CustomerException $exception) { + throw new CustomerException($exception); + } catch (PrestaShopDatabaseException $e) { + throw new PrestaShopDatabaseException($e); + } catch (PrestaShopException $e) { + throw new PrestaShopException($e); + } + } + + public function getSpecializationBySpecializationId($specializationId) + { + if (!(int)$specializationId) { + return false; + } + + return PchCustomerfieldModel::getSpecializationBySpecializationId($this->context->language->id, (int)$specializationId); + } +} diff --git a/pchcustomerfield/sql/index.php b/pchcustomerfield/sql/index.php new file mode 100644 index 0000000..87daa20 --- /dev/null +++ b/pchcustomerfield/sql/index.php @@ -0,0 +1,34 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/pchcustomerfield/sql/install.php b/pchcustomerfield/sql/install.php new file mode 100644 index 0000000..af219dd --- /dev/null +++ b/pchcustomerfield/sql/install.php @@ -0,0 +1,46 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ +$sql = array(); + +$sql[] = 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'pchcustomerfield` ( + `id_pchcustomerfield` int(11) NOT NULL AUTO_INCREMENT, + `position` int(10) unsigned NOT NULL DEFAULT 0, + `active` tinyint(1) unsigned NOT NULL DEFAULT 0, + PRIMARY KEY (`id_pchcustomerfield`) +) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8;'; + +$sql[] = 'CREATE TABLE IF NOT EXISTS ' . _DB_PREFIX_ . 'pchcustomerfield_lang( + `id_pchcustomerfield` int(11) NOT NULL, + `id_lang` int(11) NOT NULL, + `title` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id_pchcustomerfield`,`id_lang`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8;'; + +foreach ($sql as $query) { + if (Db::getInstance()->execute($query) == false) { + return false; + } +} diff --git a/pchcustomerfield/sql/uninstall.php b/pchcustomerfield/sql/uninstall.php new file mode 100644 index 0000000..61b92b5 --- /dev/null +++ b/pchcustomerfield/sql/uninstall.php @@ -0,0 +1,41 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +/** + * In some cases you should not drop the tables. + * Maybe the merchant will just try to reset the module + * but does not want to loose all of the data associated to the module. + */ +$sql = array(); + +//$sql[] = 'DROP TABLE IF EXISTS '._DB_PREFIX_.'pchcustomerfield'; +//$sql[] = 'DROP TABLE IF EXISTS '._DB_PREFIX_.'pchcustomerfield_lang'; + +foreach ($sql as $query) { + if (Db::getInstance()->execute($query) == false) { + return false; + } +} diff --git a/pchcustomerfield/translations/index.php b/pchcustomerfield/translations/index.php new file mode 100644 index 0000000..87daa20 --- /dev/null +++ b/pchcustomerfield/translations/index.php @@ -0,0 +1,34 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/pchcustomerfield/translations/nl.php b/pchcustomerfield/translations/nl.php new file mode 100644 index 0000000..e69de29 diff --git a/pchcustomerfield/views/PrestaShop/Admin/Sell/Customer/Blocks/View/index.php b/pchcustomerfield/views/PrestaShop/Admin/Sell/Customer/Blocks/View/index.php new file mode 100644 index 0000000..87daa20 --- /dev/null +++ b/pchcustomerfield/views/PrestaShop/Admin/Sell/Customer/Blocks/View/index.php @@ -0,0 +1,34 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/pchcustomerfield/views/PrestaShop/Admin/Sell/Customer/Blocks/View/personal_information.html.twig b/pchcustomerfield/views/PrestaShop/Admin/Sell/Customer/Blocks/View/personal_information.html.twig new file mode 100644 index 0000000..0d8206a --- /dev/null +++ b/pchcustomerfield/views/PrestaShop/Admin/Sell/Customer/Blocks/View/personal_information.html.twig @@ -0,0 +1,195 @@ +{#** + * 2007-2019 PrestaShop and Contributors + * + * 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.txt. + * 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://www.prestashop.com for more information. + * + * @author PrestaShop SA + * @copyright 2007-2019 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) + * International Registered Trademark & Property of PrestaShop SA + *#} + +
+

+ person + {{ customerInformation.personalInformation.firstName }} + {{ customerInformation.personalInformation.lastName }} + {{ '[%06d]'|format(customerInformation.customerId.value) }} + - + + {{ customerInformation.personalInformation.email }} + + + + edit + +

+
+
+
+ {{ 'Social Title'|trans({}, 'Admin.Global') }} +
+
+ {{ customerInformation.personalInformation.socialTitle }} +
+
+ +
+
+ {{ 'Age'|trans({}, 'Admin.Orderscustomers.Feature') }} +
+
+ {{ customerInformation.personalInformation.birthday }} +
+
+ +
+
+ {{ 'Registration Date'|trans({}, 'Admin.Orderscustomers.Feature') }} +
+
+ {{ customerInformation.personalInformation.registrationDate }} +
+
+ +
+
+ {{ 'Last Visit'|trans({}, 'Admin.Orderscustomers.Feature') }} +
+
+ {{ customerInformation.personalInformation.lastVisitDate }} +
+
+ + {% if customerInformation.personalInformation.rankBySales %} +
+
+ {{ 'Best Customer Rank'|trans({}, 'Admin.Orderscustomers.Feature') }} +
+
+ {{ customerInformation.personalInformation.rankBySales }} +
+
+ {% endif %} + + {% if isMultistoreEnabled %} +
+
+ {{ 'Shop'|trans({}, 'Admin.Global') }} +
+
+ {{ customerInformation.personalInformation.shopName }} +
+
+ {% endif %} + +
+
+ {{ 'Language'|trans({}, 'Admin.Global') }} +
+
+ {{ customerInformation.personalInformation.languageName }} +
+
+ +
+
+ {{ 'Registrations'|trans({}, 'Admin.Orderscustomers.Feature') }} +
+
+ {% set isNewsletterSubscribed = customerInformation.personalInformation.subscriptions.newsletterSubscribed %} + {% set isPartnerOffersSubscribed = customerInformation.personalInformation.subscriptions.partnerOffersSubscribed %} + + + {% if isNewsletterSubscribed %}check{% else %}cancel{% endif %} + {{ 'Newsletter'|trans({}, 'Admin.Global') }} + + + + {% if isPartnerOffersSubscribed %}check{% else %}cancel{% endif %} + {{ 'Partner offers'|trans({}, 'Admin.Orderscustomers.Feature') }} + +
+
+ +
+
+ {{ 'Latest Update'|trans({}, 'Admin.Orderscustomers.Feature') }} +
+
+ {{ customerInformation.personalInformation.lastUpdateDate }} +
+
+ +
+
+ {{ 'Status'|trans({}, 'Admin.Global') }} +
+
+ {% set isCustomerActive = customerInformation.personalInformation.active %} + + + {% if isCustomerActive %} + check + {{ 'Active'|trans({}, 'Admin.Global') }} + {% else %} + cancel + {{ 'Inactive'|trans({}, 'Admin.Global') }} + {% endif %} + +
+
+ + {% if customerInformation.personalInformation.guest %} +
+
+ {{ 'This customer is registered as a Guest.'|trans({}, 'Admin.Orderscustomers.Feature') }} +
+
+ {% if customerInformation.generalInformation.customerBySameEmailExists %} +

{{ 'A registered customer account using the defined email address already exists. '|trans({}, 'Admin.Orderscustomers.Notification') }}

+ {% else %} + {{ form_start(transferGuestAccountForm, {'action': path('admin_customers_transform_guest_to_customer', {'customerId': customerInformation.customerId.value})}) }} + + +

{{ 'This feature generates a random password before sending an email to your customer.'|trans({}, 'Admin.Orderscustomers.Help') }}

+ {{ form_end(transferGuestAccountForm) }} + {% endif %} +
+
+ {% endif %} + + +
+
+ {{ 'Specialization'|trans({}, 'Admin.Orderscustomers.Feature') }} +
+
+ -- +
+
+ +
+
diff --git a/pchcustomerfield/views/PrestaShop/Admin/Sell/Customer/Blocks/index.php b/pchcustomerfield/views/PrestaShop/Admin/Sell/Customer/Blocks/index.php new file mode 100644 index 0000000..87daa20 --- /dev/null +++ b/pchcustomerfield/views/PrestaShop/Admin/Sell/Customer/Blocks/index.php @@ -0,0 +1,34 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/pchcustomerfield/views/PrestaShop/Admin/Sell/Customer/index.php b/pchcustomerfield/views/PrestaShop/Admin/Sell/Customer/index.php new file mode 100644 index 0000000..87daa20 --- /dev/null +++ b/pchcustomerfield/views/PrestaShop/Admin/Sell/Customer/index.php @@ -0,0 +1,34 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/pchcustomerfield/views/PrestaShop/Admin/Sell/index.php b/pchcustomerfield/views/PrestaShop/Admin/Sell/index.php new file mode 100644 index 0000000..87daa20 --- /dev/null +++ b/pchcustomerfield/views/PrestaShop/Admin/Sell/index.php @@ -0,0 +1,34 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/pchcustomerfield/views/PrestaShop/Admin/index.php b/pchcustomerfield/views/PrestaShop/Admin/index.php new file mode 100644 index 0000000..87daa20 --- /dev/null +++ b/pchcustomerfield/views/PrestaShop/Admin/index.php @@ -0,0 +1,34 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/pchcustomerfield/views/PrestaShop/index.php b/pchcustomerfield/views/PrestaShop/index.php new file mode 100644 index 0000000..87daa20 --- /dev/null +++ b/pchcustomerfield/views/PrestaShop/index.php @@ -0,0 +1,34 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/pchcustomerfield/views/index.php b/pchcustomerfield/views/index.php new file mode 100644 index 0000000..87daa20 --- /dev/null +++ b/pchcustomerfield/views/index.php @@ -0,0 +1,34 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/pchcustomerfield/views/js/back.js b/pchcustomerfield/views/js/back.js new file mode 100644 index 0000000..c24a2ec --- /dev/null +++ b/pchcustomerfield/views/js/back.js @@ -0,0 +1,34 @@ +/** +* 2007-2022 PrestaShop +* +* NOTICE OF LICENSE +* +* This source file is subject to the Academic Free License (AFL 3.0) +* that is bundled with this package in the file LICENSE.txt. +* It is also available through the world-wide-web at this URL: +* http://opensource.org/licenses/afl-3.0.php +* 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 http://www.prestashop.com for more information. +* +* @author PrestaShop SA +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +* +* Don't forget to prefix your containers with your own identifier +* to avoid any conflicts with others containers. +*/ + + +document.addEventListener("DOMContentLoaded", function() { + if ($('.admincustomerspecialization').length) { + $('.col-specialization-destination').text($('.admincustomerspecialization').text()); + } +}); \ No newline at end of file diff --git a/pchcustomerfield/views/js/index.php b/pchcustomerfield/views/js/index.php new file mode 100644 index 0000000..87daa20 --- /dev/null +++ b/pchcustomerfield/views/js/index.php @@ -0,0 +1,34 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/pchcustomerfield/views/templates/hook/displayAdminCustomers.tpl b/pchcustomerfield/views/templates/hook/displayAdminCustomers.tpl new file mode 100644 index 0000000..4cb2ebc --- /dev/null +++ b/pchcustomerfield/views/templates/hook/displayAdminCustomers.tpl @@ -0,0 +1,29 @@ +{** + * 2007-2020 PrestaShop and Contributors + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License 3.0 (AFL-3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * https://opensource.org/licenses/AFL-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. + * + * @author PrestaShop SA + * @copyright 2007-2020 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) + * International Registered Trademark & Property of PrestaShop SA + *} + + \ No newline at end of file diff --git a/pchcustomerfield/views/templates/hook/index.php b/pchcustomerfield/views/templates/hook/index.php new file mode 100644 index 0000000..87daa20 --- /dev/null +++ b/pchcustomerfield/views/templates/hook/index.php @@ -0,0 +1,34 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/pchcustomerfield/views/templates/index.php b/pchcustomerfield/views/templates/index.php new file mode 100644 index 0000000..87daa20 --- /dev/null +++ b/pchcustomerfield/views/templates/index.php @@ -0,0 +1,34 @@ + +* @copyright 2007-2022 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit;