xabikip Posted March 6, 2014 Share Posted March 6, 2014 Buenas, Necesito calcular el precio del producto en base a la cantidad de caracteres que introduce el usuario en un campo personalizado de texto. Por ejemplo si vendo camisetas doy la opcion de que el usuario añada un nombre para poner en la camiseta. Cada letra custa x€, entoces necesito calcular el precio final en base a las letras introducidas ppor el usuario. ¿Tendria que crearme un modulo para esto, o creeis que con algun override sera suficiente? ¿Como se os ocurre que se podria hacer? Gracias, Link to comment Share on other sites More sharing options...
jesa Posted March 6, 2014 Share Posted March 6, 2014 Posiblemente no tengas que hacer ningun módulo. Si tienes productos sencillos sin combinaciones, supongo que con ajax y/o jquery podrás hacer que cuando pongas el texto te calcule el precio. 1 Link to comment Share on other sites More sharing options...
xabikip Posted March 7, 2014 Author Share Posted March 7, 2014 Bueno, los productos tienen combinaciones para las talla. De todos modos he mirado como se podria hacer con ajax o jquery. Podria calcular el precio y mostrarle al usuario dicho precio, pero luego no sabria como hacer para decirle a prestashop que este sera el precio. He empezado a hacer un modulo para ello y lo veo factible, lo que pretendo hacer es con un actionhook calcular el nuevo precio y meterlo en la variable de precio de producto. Lo que me pasa es que no se con que actionhook usarlo. ¿Sabes si hay algun actionhook que se dispara cuando el usuario le da a guardar los campos personalizados? Link to comment Share on other sites More sharing options...
Enrique Gómez Posted March 9, 2014 Share Posted March 9, 2014 En general es mejor usar lo que ya existe de prestashop para el tema de calculo de precios, stocks, descuentos..y otros puntos que son "complicados" ya que tu puedes cambiar en la plantilla el precio pero luego evidentemente ese cambio no se guardará en todos los puntos que interesa (carrito, pedidos, facturas..etc) Como prestashop usa combinaciones y cada combinación tiene un precio diferente para el precio puedes usar un grupo de atributos que sea número de letras y hacer las combinaciones necesarias con sus correspondientes cambios en el precio. Luego ya vendría todo tema de meter mano en la plantilla y mirar si ese producto es ese "producto especial" que tiene ese grupo de atributos y entonces ya jugar con jquery/css para esconder ese selector y usar el campo personalizado. Este campo personalizado tendría asociado un evento change para mirar de cambiar el precio al meter letras y sobretodo al añadir el producto al carrito mirar en ajax-cart.js de coger esa combinación en función del número de caracteres escritos al hacer el add. Tiene bastante trabajo de código jquery. Link to comment Share on other sites More sharing options...
Feliz Garcia Posted March 9, 2014 Share Posted March 9, 2014 En general es mejor usar lo que ya existe de prestashop para el tema de calculo de precios, stocks, descuentos..y otros puntos que son "complicados" ya que tu puedes cambiar en la plantilla el precio pero luego evidentemente ese cambio no se guardará en todos los puntos que interesa (carrito, pedidos, facturas..etc) Como prestashop usa combinaciones y cada combinación tiene un precio diferente para el precio puedes usar un grupo de atributos que sea número de letras y hacer las combinaciones necesarias con sus correspondientes cambios en el precio. Luego ya vendría todo tema de meter mano en la plantilla y mirar si ese producto es ese "producto especial" que tiene ese grupo de atributos y entonces ya jugar con jquery/css para esconder ese selector y usar el campo personalizado. Este campo personalizado tendría asociado un evento change para mirar de cambiar el precio al meter letras y sobretodo al añadir el producto al carrito mirar en ajax-cart.js de coger esa combinación en función del número de caracteres escritos al hacer el add. Tiene bastante trabajo de código jquery. Hola ! Gracias por la información. Metiéndonos un poco en código, ¿podrías explicar a grosso modo, un ejemplo básico que sea funcional, para luego poder seguir el desarrollo? Muchas Gracias ! Link to comment Share on other sites More sharing options...
Enrique Gómez Posted March 9, 2014 Share Posted March 9, 2014 Lo que he comentado es a nivel conceptual, esperaremos que Xabikip obtenga una solución mas concreta y la comparta Link to comment Share on other sites More sharing options...
Feliz Garcia Posted March 9, 2014 Share Posted March 9, 2014 Lo que he comentado es a nivel conceptual, esperaremos que Xabikip obtenga una solución mas concreta y la comparta Ok, entonces quedo a la espera, ya que me interesa mucha la solución. Gracias. Link to comment Share on other sites More sharing options...
xabikip Posted March 11, 2014 Author Share Posted March 11, 2014 Pues estoy intentando pero no consigo lo que pretendo. Tengo un problema, haber si vosotros sabies. ¿Como podria coger el parametro de un atributo? Por ejemplo mi producto tiene distintas tallas, que se las he metido mediante atributo/valor. Necesito recoger el valor elegido por el usuario para luego poder tratarlo yo mediante el codigo. Me he fijado que lo guarda en descripcion como (articulo 1 - Talla: L, otroAtributo: valor, etc...). ¿Sabeis si lo guarda en algun otro lado, en algun campo de alguna tabla?¿O como podria usar el parametro elegido por el usuario? Espero que me podais ayudar, si lo consigo comparto la solucion. Link to comment Share on other sites More sharing options...
Enrique Gómez Posted March 11, 2014 Share Posted March 11, 2014 Se guarda un montón de información en arrays de javascript de forma que en product.js metiendo mano en puntos como findCombination (o otros) se puede hacer de todo. Para muchas cosas jquery va genial, se usan identificadores en el propio maquetado de product.tpl como P.ej <a id="color_{$id_attribute|intval}", <select name="{$groupName}" id="group_{$id_attribute_group|intval}" Luego para coger valores seleccionados puedes usar selectores de jquery como P.ej con $('#color_to_pick_list a.color_pick.selected'), en mi caso que tengo un solo grupo de colores, se el que esta seleccionado. De los mas importantes combinations con información de cada combinación y los attributos que la componen (en este caso sólo uno) attributesCombinations para los atributos En product.tpl se montan estos arrays al principio 3 Link to comment Share on other sites More sharing options...
xabikip Posted March 11, 2014 Author Share Posted March 11, 2014 (edited) jaja, muchas gracias Enrique. Yo habia hecho una chapuza usando la descripcion del producto y con explode ir cogiendo los atributos y valores. Y luego con substr y switch ir guardando en variables. Aunque me funciona es toda una chapuza, vamos. Ya mirare lo que me comentas aunque he de confesar que en JavaScript y Jquery estoy mas verde. Quiza te de un poco la tabarra con preguntas. Ya comentare como me va. Edited March 11, 2014 by xabikip (see edit history) Link to comment Share on other sites More sharing options...
xabikip Posted March 11, 2014 Author Share Posted March 11, 2014 Enrique, aunque de la forma que comentas tu de de coger los valores con JavaScript solo me valdria para cuando estoy en product.tpl o en alguna vista verdad? Y yo lo necesito en el hook actionPaymentConfirmation y hay me imagino que lo tendria que coger desde algun campo de la base de datos, pero no encuntro desde donde. Lo unico que he encontrado a sido en el campo "product_name" de la tabla "order_detail". Link to comment Share on other sites More sharing options...
Enrique Gómez Posted March 11, 2014 Share Posted March 11, 2014 Enrique, aunque de la forma que comentas tu de de coger los valores con JavaScript solo me valdria para cuando estoy en product.tpl o en alguna vista verdad? Y yo lo necesito en el hook actionPaymentConfirmation y hay me imagino que lo tendria que coger desde algun campo de la base de datos, pero no encuntro desde donde. Lo unico que he encontrado a sido en el campo "product_name" de la tabla "order_detail". Todo lo de Jquery es código que se ejecuta en el navegador de cliente en este caso en la página html que se genera a partir de la plantilla product.tpl. Es muy útil para añadir código en ciertos puntos como al añadir al carrito, seleccionar un color, selector,etc.. vamos cualquier acción que pueda realizar el usuario en el hook puedes sacar el id del pedido, haces una join con order_detail y allí esta el identificador del producto, de la combinación (en product_attribute_id)..etc, para cada linea de pedido (una orden tiene varias order_detail). Puedes ver los campos en classes/order/OrderDetail.. También en el diagrama de BD en http://doc.prestashop.com/display/PS15/Fundamentals#Fundamentals-Databaseschema. Vale la pena instalarse Mysql Workbench Link to comment Share on other sites More sharing options...
xabikip Posted March 12, 2014 Author Share Posted March 12, 2014 Ya tenia instalado el workbench y he mirado haber donde puede guardar los valores elegidos por el usuario y he llegado a la conclusion de que solo lo guarda en un sitio, y la verdad que no me parece una buena forma. Solo los guarda en la tabla order_detail en el campo product name y todo junto. Asi es como los guarda: Nombreproducto - Atributo1 : valor1, Atributo2: valor2, Atributo3 : valor3, etc... La verdad que no me parece una buena forma de guardar los atributos y valores escogidos, porque si o si tienes que hacer un explode si quieres obtener un atributo y su valor especifico. Por ejemplo si necesito obtener el valor del atributo2 tengo que recorrer el string y usar explode y la verdad que me parece un poco chapucero, pero bueno es lo que hay. Link to comment Share on other sites More sharing options...
Enrique Gómez Posted March 12, 2014 Share Posted March 12, 2014 En la tabla order detail hay un campo product_attribute_id que te liga con la combinación exacta (ps_product_attribute). Luego en esa combinación a través de la tabla ps_product_attribute_combination puedes llegar a los atributos exactos que la componen (ps_attribute/ps_attribute_lang) Esta función de la clase Combination tiene que a partir del id de combinación obtiene los nombres de los atributos public function getAttributesName($id_lang) { return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' SELECT al.* FROM '._DB_PREFIX_.'product_attribute_combination pac JOIN '._DB_PREFIX_.'attribute_lang al ON (pac.id_attribute = al.id_attribute AND al.id_lang='.(int)$id_lang.') WHERE pac.id_product_attribute='.(int)$this->id); } Link to comment Share on other sites More sharing options...
xabikip Posted March 12, 2014 Author Share Posted March 12, 2014 (edited) Gracias Enrique, tenias razon, de la manera que comentas puedo coger justo el valor del atributo que yo quiera. Ya me parecia raro que solo se guardase en el product_name. Ahora tengo una duda. Ya recogo los valores de los atributos y en base a los parametros introducidos por el usuario he calculado el precio que tendria que tener dicho producto. ¿Ahora como podria engañarle a prestashop y decirle que sera este el precio de este producto en este carrito? Edited March 12, 2014 by xabikip (see edit history) Link to comment Share on other sites More sharing options...
Enrique Gómez Posted March 12, 2014 Share Posted March 12, 2014 Gracias Enrique, tenias razon, de la manera que comentas puedo coger justo el valor del atributo que yo quiera. Ya me parecia raro que solo se guardase en el product_name. Ahora tengo una duda. Ya recogo los valores de los atributos y en base a los parametros introducidos por el usuario he calculado el precio que tendria que tener dicho producto. ¿Ahora como podria engañarle a prestashop y decirle que sera este el precio de este producto en este carrito? Ya te comentaba al principio que engañar a prestashop con el precio puede ser complicado (bueno ... es complicado) sobre todo por que hay un gran número de puntos donde se tiene en cuenta... carrito, pedidos, facturas .... y tiene complicaciones por que el cálculo del precio se tienen en cuenta descuentos, impuestos..etc, luego el cálculo de totales en el resumen del carrito.. Puedes empezar sobrescribiendo el carrito public function getProducts($refresh = false, $id_product = false, $id_country = null) de la clase Cart.php que es donde saca los productos para el carrito y les pone los precios (con descuento, sin descuento, impuestos...). Los productos del carrito se guardan en ps_cart_product, pero no guarda los precios ahí, realmente sale mas a cuenta crearle un campo precio y guardar ahí los precios de ese producto en ese carrito. Este post comenta los pasos http://stackoverflow.com/questions/20991271/prestashop-custom-calculated-product-price Para mí la opción mas sensata, en tu caso que puedes usar combinaciones, es tirar por lo que comentaba en el post #4 1 Link to comment Share on other sites More sharing options...
Josraso Posted March 12, 2014 Share Posted March 12, 2014 He visto este modulo http://www.jose-aguilar.com/modulos-prestashop/88-customization-prices.html no se si sera exactemente lo que buscas. Link to comment Share on other sites More sharing options...
xabikip Posted March 13, 2014 Author Share Posted March 13, 2014 Buenas Enrique, probare el metodo que comentas de crear campos adicionales en la BD, guiandome por el post de stackoverflow. He barajado la opcion que comentas en el post#4, pero veo algunas complicaciónes. Porque el precio por caracter no siempre es el mismo, varia en funcion de la talla elegida. Te explico mejor la funcionalidad que necesito y haber si te parece correcta la decision de hacer con el metodo de añadir campos en las tablas. Por un lado tengo distintas tallas que el usuario puede elegir. Por otro lado tengo una campo personalizado donde el usuario introducira un texto, que hay que calcular cuantos caracteres tiene y cobrarle x€ por cada caracter. Por ultimo hay otro campo personalizado que introduce otro texto, pero en este caso el precio por caracter varia segun la talla elegida. No se si te parece la opcion mas correcta hacerlo del modo que comentan en stackoverflow. Gracias por tu ayuda Enrique, Link to comment Share on other sites More sharing options...
Enrique Gómez Posted March 13, 2014 Share Posted March 13, 2014 (edited) Si puedes tirar de combinaciones es mejor usarlas.. luego ya haces lo que tengas que hacer en la pantalla de producto a nivel de interfaz de usuario pero internamente usar combinaciones. Si tienes 12 caracteres para el campo de texto 1, 12 para el campo de texto 2 y 6 tallas son 12x12x6=864 combinaciones. En principio esta dentro de lo que puede manejar Prestashop sin atragantarse (si es muy grande hay problemas de rendimiento http://www.prestashop.com/forums/topic/25255-big-problem-with-attributes/ -> de ahí nació un famoso módulo para saltarse este problema -> http://www.prestashop.com/forums/topic/47363-module-attribute-wizard-pro-create-an-unlimited-number-of-attributes-and-display-as-radio-button-checkbox-dropdown-textbox-teaxtarea-files/?hl=%20attribute%20%20wizard) Otra cosa es a nivel de administración manejarlo (tienes un listado de 864 donde puedes editar cada una...), pero siempre es posible crearse una capa que te genere las combinaciones a tu gusto, de hecho prestashop tiene un generador de combinaciones ideal si el impacto en el precio (o peso) de cada grupo de atributos es independiente del resto, cosa que no pasa en tu caso ya que el precio en texto 2 depende de la talla. Otro tema es que el usuario ponga cantidades "continuas" como volumen, superficie..etc, entonces es inviable trabajar con combinaciones y tendrías que hacer lo del post de stackoverflow o sino mirarte este módulo http://www.prestashop.com/forums/topic/296700-m%C3%B3dulo-venta-de-productos-por-m2-m3-lineales-y-decimales-para-prestashop/?hl=%2Bmegaproducts (que sobrescribe un buen número de clases y demás..) Desde luego si el número de combinaciones prevés que sea muy grande (>1500) no puedes usar combinaciones por problemas de rendimiento, entonces no te queda otra que meterle mano al core de Prestashop y empezar a sobrescribir clases.. (que es lo que hacen estos dos grandes módulos). Siempre puedes partir de uno de estos módulos como base. Edited March 13, 2014 by Enrique Gómez (see edit history) Link to comment Share on other sites More sharing options...
xabikip Posted March 13, 2014 Author Share Posted March 13, 2014 (edited) Al final he optado por hacerlo mediante conbinaciones. He probado con añadir campos y sobreescribir clases y demas, pero es un trabajo bastante gordo y dficil. Creo que va todo bien, solo que tengo un problemilla. He puesto una opcion como atributo "cantidad de caracteres" donde el usuario elige si quiere 1,2,3,4,5 o 6 caracteres. Luego al dar a guardar en la funcion saveCustomization() de product.js valido si los caracteres elegidos y los introducidos coinciden, y si no es asi les saco un alert. Es asi como me queda la funcion: function saveCustomization() { var valorText = $('textarea#textField0').val(); var valorNum = $('textarea#textField1').val(); var opcion_text = $('select#group_10 option:selected').text(); var opcion_num = $('select#group_11 option:selected').text(); var caractText = valorText.length; var caractNum = valorNum.length; var select_text_cant = parseInt(opcion_text); var select_num_cant = parseInt(opcion_num); if (caractText == select_text_cant) { if (caractNum == select_num_cant) { $('#quantityBackup').val($('#quantity_wanted').val()); customAction = $('#customizationForm').attr('action'); $('body select[id^="group_"]').each(function() { customAction = customAction.replace(new RegExp(this.id + '=\\d+'), this.id +'=' + this.value); }); $('#customizationForm').attr('action', customAction); $('#customizationForm').submit(); } else { alert('La cantidad de numeros introducidos no coincide con la cantidad que seleccionaste'); } } else { alert('La cantidad de caracteres introducidos en el texto no coincide con la que seleccionastes'); } } Funciona bien porque si coinciden lo guarda sin problemas y si no coinciden saca el alert. El problema es que cuando saca el alert, como no lo envia se queda el boton de guardar oculto y con el mensaje de "En curso, espere un momento por favor ..." y no se puede volver a comprobar, hay que recargar la pagina. ¿Se te ocurre que podria hacer para solucionar esto? Edited March 13, 2014 by xabikip (see edit history) 1 Link to comment Share on other sites More sharing options...
Enrique Gómez Posted March 14, 2014 Share Posted March 14, 2014 (edited) Al cargar la página de producto se le añade un evento onclick adicional al input de forma que tienes el onclick="saveCustomization" y otro enlazado via jquery en el document.ready (linea 566 de product.js) $('#customizedDatas input').click(function() { $('#customizedDatas input').hide(); $('#ajax-loader').fadeIn(); $('#customizedDatas').append(uploading_in_progress); }); No es buena practica mezclar estas dos formas de añadir eventos. Entonces puedes cargártelo de la linea 566 y ponerlo tu dentro de tu saveCustomization si todo va bien. Es decir function saveCustomization() { var valorText = $('textarea#textField0').val(); var valorNum = $('textarea#textField1').val(); var opcion_text = $('select#group_10 option:selected').text(); var opcion_num = $('select#group_11 option:selected').text(); var caractText = valorText.length; var caractNum = valorNum.length; var select_text_cant = parseInt(opcion_text); var select_num_cant = parseInt(opcion_num); if (caractText == select_text_cant) { if (caractNum == select_num_cant) { $('#quantityBackup').val($('#quantity_wanted').val()); customAction = $('#customizationForm').attr('action'); $('body select[id^="group_"]').each(function() { customAction = customAction.replace(new RegExp(this.id + '=\\d+'), this.id +'=' + this.value); }); $('#customizationForm').attr('action', customAction); $('#customizationForm').submit(); //NUEVO $('#customizedDatas input').hide(); $('#ajax-loader').fadeIn(); $('#customizedDatas').append(uploading_in_progress); } else { alert('La cantidad de numeros introducidos no coincide con la cantidad que seleccionaste'); } } else { alert('La cantidad de caracteres introducidos en el texto no coincide con la que seleccionastes'); } } Edited March 14, 2014 by Enrique Gómez (see edit history) Link to comment Share on other sites More sharing options...
xabikip Posted March 17, 2014 Author Share Posted March 17, 2014 (edited) He cambiado un poco de estrategia. Antes el usuario tenia que elegir cuantos caracteres queria para serigrafiar y despues de introducir el texto en el campo personalizado, validava si los que habia elegido y los que habia introducido en el campo personalizado de texto eran iguales. Ahora lo que intento es que directamente el usuario escriba el texto que quiera serigrafiar y cuando le de a guardar, yo en saveCustomization calcule cuantos caracteres a escrito y mediante JavaScript cambie el option del select. Para esto hago lo siguiente: function saveCustomization() { var valorText = $('textarea#textField0').val(); var valorNum = $('textarea#textField1').val(); var text_cant = valorText.length; text_cant_str = text_cant.toString(); var num_cant = valorNum.length; num_cant_str = num_cant.toString(); $("select#group_10 option:contains(" + text_cant_str + ")").attr('selected', 'selected'); $("select#group_11 option:contains(" + num_cant_str + ")").attr('selected', 'selected'); if (text_cant <= 6) { if (num_cant <= 2) { $('#quantityBackup').val($('#quantity_wanted').val()); customAction = $('#customizationForm').attr('action'); $('body select[id^="group_"]').each(function() { customAction = customAction.replace(new RegExp(this.id + '=\\d+'), this.id +'=' + this.value); }); $('#customizationForm').attr('action', customAction); $('#customizationForm').submit(); $('#customizedDatas input').hide(); $('#ajax-loader').fadeIn(); $('#customizedDatas').append(uploading_in_progress); } else { alert('La cantidad de numeros introducidos no puede ser mayor que 2'); } } else { alert('La cantidad de caracteres introducidos en el texto no puede ser mayor que 6'); } } El select lo cambia bien, por ejemplo si meto cinco caracteres se cambia al option de 5, pero el problema es que no me cambia el precio. Tengo configurado distintos precios por cantidad de caracteres. Si seleciono yo directamente el select si que me calcula bien el precio, pero si lo hago mediante JavaScript no me cambia el precio. ¿Sabeis porque puede ser? Edited March 17, 2014 by xabikip (see edit history) Link to comment Share on other sites More sharing options...
xabikip Posted March 17, 2014 Author Share Posted March 17, 2014 Al final he logrado que me calcule el precio segun las opciones del select. me faltaba pòner las llamadas a los metodos de findCombination(); y getProductAttribute(); Es asi como me queda la funcion de saveCustomization: function saveCustomization() { var valorText = $('textarea#textField0').val(); var valorNum = $('textarea#textField1').val(); var text_cant = valorText.length; text_cant_str = text_cant.toString(); var num_cant = valorNum.length; num_cant_str = num_cant.toString(); $("select#group_10 option:contains(" + text_cant_str + ")").attr('selected', true); $("select#group_11 option:contains(" + num_cant_str + ")").attr('selected', 'selected'); findCombination(); getProductAttribute(); if (text_cant <= 6) { if (num_cant <= 2) { $('#quantityBackup').val($('#quantity_wanted').val()); customAction = $('#customizationForm').attr('action'); $('body select[id^="group_"]').each(function() { customAction = customAction.replace(new RegExp(this.id + '=\\d+'), this.id +'=' + this.value); }); $('#customizationForm').attr('action', customAction); $('#customizationForm').submit(); $('#customizedDatas input').hide(); $('#ajax-loader').fadeIn(); $('#customizedDatas').append(uploading_in_progress); } else { alert('La cantidad de numeros introducidos no puede ser mayor que 2'); } } else { alert('La cantidad de caracteres introducidos en el texto no puede ser mayor que 6'); } } Ahora ya me funciona todo bien. Link to comment Share on other sites More sharing options...
Recommended Posts