From 45faa3a9414631f73764a2e6fbf3b7ecb93c8a7e Mon Sep 17 00:00:00 2001 From: Nicolas Lempereur Date: Wed, 1 Jul 2015 10:04:47 +0200 Subject: [PATCH 01/11] [FIX] base: fixing fix, attachment file size and None In commit 44f2c8d54 we unified the return value of the function to int, but it seems the returned size could be None which is not a valid input of the int() built-in function. --- openerp/addons/base/ir/ir_attachment.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/addons/base/ir/ir_attachment.py b/openerp/addons/base/ir/ir_attachment.py index 97edffd6ada..ad257b418c3 100644 --- a/openerp/addons/base/ir/ir_attachment.py +++ b/openerp/addons/base/ir/ir_attachment.py @@ -133,7 +133,7 @@ class ir_attachment(osv.osv): else: result[attach.id] = attach.db_datas if bin_size: - result[attach.id] = int(result[attach.id]) + result[attach.id] = int(result[attach.id] or 0) return result From 2326bb7a54c2dc93944f31c3499464e1cf022c54 Mon Sep 17 00:00:00 2001 From: Odoo Translation Bot Date: Wed, 1 Jul 2015 10:45:16 +0200 Subject: [PATCH 02/11] [I18N] Update translation terms from Transifex --- openerp/addons/base/i18n/es.po | 88 +++++++++++++++++----------------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/openerp/addons/base/i18n/es.po b/openerp/addons/base/i18n/es.po index 6e6c164f412..99f0a821423 100644 --- a/openerp/addons/base/i18n/es.po +++ b/openerp/addons/base/i18n/es.po @@ -3,14 +3,16 @@ # * base # # Translators: +# Antonio Espinosa , 2015 # FIRST AUTHOR , 2012 +# Pedro M. Baeza , 2015 msgid "" msgstr "" "Project-Id-Version: Odoo 7.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-08-14 00:10+0000\n" -"PO-Revision-Date: 2015-05-29 13:01+0000\n" -"Last-Translator: Martin Trigaux\n" +"PO-Revision-Date: 2015-06-25 23:41+0000\n" +"Last-Translator: Antonio Espinosa \n" "Language-Team: Spanish (http://www.transifex.com/projects/p/odoo-7/language/es/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -40,7 +42,7 @@ msgstr "Santa Helena" #. module: base #: view:ir.actions.report.xml:0 msgid "Other Configuration" -msgstr "" +msgstr "Otra configuración" #. module: base #: code:addons/base/res/res_partner.py:522 @@ -130,7 +132,7 @@ msgid "" " * Manufacturer Product Code\n" " * Product Attributes\n" " " -msgstr "" +msgstr "\nMódulo que añade fabricantes y atributos en el formulario de producto.\n===========================================================\n\nPuede definir los siguientes campos para un producto:\n-------------------------------------------------\n* Fabricante\n* Nombre del producto del fabricante\n* Código del producto del fabricante\n* Atributos del producto\n " #. module: base #: field:ir.actions.client,params:0 @@ -176,7 +178,7 @@ msgstr "Ventana destino" #. module: base #: field:ir.actions.report.xml,report_rml:0 msgid "Main Report File Path" -msgstr "" +msgstr "Ruta de archivo del informe principal" #. module: base #: model:ir.module.module,shortdesc:base.module_sale_analytic_plans @@ -217,12 +219,12 @@ msgstr "¡Las propiedades de los campos base no se pueden modificar de esta form #: code:addons/osv.py:153 #, python-format msgid "Constraint Error" -msgstr "" +msgstr "Error en la restricción (constraint)" #. module: base #: model:ir.model,name:base.model_ir_ui_view_custom msgid "ir.ui.view.custom" -msgstr "" +msgstr "ir.ui.view.custom" #. module: base #: code:addons/base/ir/ir_model.py:389 @@ -239,7 +241,7 @@ msgstr "Suazilandia" #: code:addons/orm.py:4585 #, python-format msgid "created." -msgstr "" +msgstr "creado." #. module: base #: field:ir.actions.report.xml,report_xsl:0 @@ -346,7 +348,7 @@ msgstr "activa" #. module: base #: field:ir.actions.wizard,wiz_name:0 msgid "Wizard Name" -msgstr "" +msgstr "Nombre del asistente" #. module: base #: model:ir.module.module,description:base.module_knowledge @@ -388,7 +390,7 @@ msgstr "Ya existe un filtro compartido por defecto para %(model)s, elimínelo o #: code:addons/orm.py:2711 #, python-format msgid "Invalid group_by" -msgstr "" +msgstr "group_by no válido" #. module: base #: field:ir.module.category,child_ids:0 @@ -403,7 +405,7 @@ msgstr "Crédito concedido" #. module: base #: model:ir.module.module,shortdesc:base.module_portal_project_long_term msgid "Portal Project Long Term" -msgstr "" +msgstr "Portal para la planificación a largo plazo" #. module: base #: field:ir.model.constraint,date_update:0 field:ir.model.data,date_update:0 @@ -439,7 +441,7 @@ msgstr "Pasos de los asistentes de configuración" #. module: base #: model:ir.model,name:base.model_ir_ui_view_sc msgid "ir.ui.view_sc" -msgstr "" +msgstr "ir.ui.view_sc" #. module: base #: view:ir.model.access:0 field:ir.model.access,group_id:0 view:res.groups:0 @@ -459,7 +461,7 @@ msgstr "Se ha especificado una directiva de formato fecha/hora no válida. Consu msgid "" "One of the records you are trying to modify has already been deleted " "(Document type: %s)." -msgstr "" +msgstr "Uno de los registros que está intentando modificar ya ha sido eliminado (tipo documento: %s)." #. module: base #: help:ir.actions.act_window,views:0 @@ -488,7 +490,7 @@ msgstr "Tuvalu" #. module: base #: field:ir.actions.configuration.wizard,note:0 msgid "Next Wizard" -msgstr "" +msgstr "Siguiente asistente" #. module: base #: field:res.lang,date_format:0 @@ -511,7 +513,7 @@ msgstr "Antillas holandesas" msgid "" "You can not remove the admin user as it is used internally for resources " "created by OpenERP (updates, module installation, ...)" -msgstr "" +msgstr "No puede eliminar el usuario admin ya que es utilizado internamente por los recursos creados por OpenERP (actualizaciones, instalación de módulos, ...)" #. module: base #: view:workflow.transition:0 @@ -666,7 +668,7 @@ msgstr "México - Contabilidad" #. module: base #: help:ir.actions.server,action_id:0 msgid "Select the Action Window, Report, Wizard to be executed." -msgstr "" +msgstr "Seleccione la acción de ventana, informe o asistente que se ejecutará." #. module: base #: sql_constraint:ir.config_parameter:0 @@ -676,7 +678,7 @@ msgstr "La clave debe ser única." #. module: base #: model:ir.module.module,shortdesc:base.module_plugin_outlook msgid "Outlook Plug-In" -msgstr "" +msgstr "Conector Outlook" #. module: base #: model:ir.module.module,description:base.module_account @@ -705,7 +707,7 @@ msgid "" "The processes like maintaining of general ledger is done through the defined financial Journals (entry move line orgrouping is maintained through journal) \n" "for a particular financial year and for preparation of vouchers there is a module named account_voucher.\n" " " -msgstr "" +msgstr "\nGestión contable y financiera.\n============================\n\nEl módulo de gestión contable y financiera cubre:\n--------------------------------------------\n * Contabilidad general\n *Contabilidad analítica/costes\n * Contabilidad de terceros\n * Gestión de impuestos\n * Presupuestos\n * Facturas de cliente y proveedor\n * Extractos bancarios\n * Proceso de reconciliación por empresa\n\nCrea un tablero para contables que incluye:\n--------------------------------------------------\n * Lista de facturas de cliente pendientes de aprobación\n * Análisis de la compañía\n * Gráfico de tesorería\n\nLos procesos de mantenimiento del Libro Mayor se hacen a través de la definición de diarios fiscales (apuntes contables o su agrupación se mantienen a través de los diarios) \nPara un ejercicio determinado y para la preparación de recibos hay un módulo de nombre account_voucher.\n " #. module: base #: view:ir.model:0 field:ir.model,name:0 @@ -762,7 +764,7 @@ msgstr "Fecha de la próxima ejecución programada para esta acción." #. module: base #: model:ir.model,name:base.model_ir_ui_view msgid "ir.ui.view" -msgstr "" +msgstr "ir.ui.view" #. module: base #: model:res.country,name:base.er @@ -787,7 +789,7 @@ msgstr "Rumanía - Contabilidad" #. module: base #: model:ir.model,name:base.model_res_config_settings msgid "res.config.settings" -msgstr "" +msgstr "Parámetros de configuración" #. module: base #: help:res.partner,image_small:0 @@ -803,7 +805,7 @@ msgid "" "Provides fields that be used to fetch the mobile number, e.g. you select the" " invoice, then `object.invoice_address_id.mobile` is the field which gives " "the correct mobile number" -msgstr "" +msgstr "Indique los campos que se utilizarán para extraer el número de móvil. Por ej. cuándo selecciona la factura, entonces `object.invoice_address_id.mobile` es el campo que contiene el número de móvil correcto." #. module: base #: view:ir.mail_server:0 @@ -850,7 +852,7 @@ msgstr "Sobrescribir términos existentes" #: code:addons/base/res/res_currency.py:60 #, python-format msgid "No currency rate associated for currency %d for the given period" -msgstr "" +msgstr "No hay tasa de cambio asociada a la moneda %d para el periodo dado" #. module: base #: model:ir.module.module,description:base.module_hr_holidays @@ -885,7 +887,7 @@ msgstr "Oportunidades" #. module: base #: model:ir.model,name:base.model_base_language_export msgid "base.language.export" -msgstr "" +msgstr "base.language.export" #. module: base #: model:res.country,name:base.pg @@ -895,12 +897,12 @@ msgstr "Papúa Nueva Guinea" #. module: base #: help:ir.actions.report.xml,report_type:0 msgid "Report Type, e.g. pdf, html, raw, sxw, odt, html2html, mako2html, ..." -msgstr "" +msgstr "Tipo de informe, por ejemplo: pdf, html, raw, sxw, odt, html2html, mako2html, ..." #. module: base #: model:ir.module.module,shortdesc:base.module_document_webdav msgid "Shared Repositories (WebDAV)" -msgstr "" +msgstr "Repositorios compartidos (WebDAV)" #. module: base #: view:res.users:0 @@ -1023,7 +1025,7 @@ msgstr "India" #: model:ir.actions.act_window,name:base.res_request_link-act #: model:ir.ui.menu,name:base.menu_res_request_link_act msgid "Request Reference Types" -msgstr "" +msgstr "Tipos de referencias en solicitudes" #. module: base #: model:ir.module.module,shortdesc:base.module_google_base_account @@ -1170,7 +1172,7 @@ msgstr "\nMódulo base para la localización brasileña\n======================= msgid "" "Language with code \"%s\" is not defined in your system !\n" "Define it through the Administration menu." -msgstr "" +msgstr "¡No se ha definido el idioma con el código \"%s\" en su sistema!\nDefínalo mediante el menú de Administración." #. module: base #: model:res.country,name:base.gu @@ -1205,7 +1207,7 @@ msgstr "Ficticio" #. module: base #: constraint:ir.ui.view:0 msgid "Invalid XML for View Architecture!" -msgstr "" +msgstr "¡XML inválido para la definición de la vista!" #. module: base #: model:res.country,name:base.ky @@ -1231,7 +1233,7 @@ msgstr "Plan contable para las empresas" #: code:addons/orm.py:5044 #, python-format msgid "Record #%d of %s not found, cannot copy!" -msgstr "" +msgstr "¡No se ha encontrado el registro #%d de %s, no se puede copiar!" #. module: base #: field:ir.module.module,contributors:0 @@ -1313,7 +1315,7 @@ msgstr "Utilizado para conectarse al sistema." msgid "" "TGZ format: this is a compressed archive containing a PO file, directly suitable\n" " for uploading to OpenERP's translation platform," -msgstr "" +msgstr "Formato TGZ: archivo comprimido que contiene un archivo PO, adecuado para subirlo directamente a la plataforma de traducción de OpenERP." #. module: base #: view:res.lang:0 @@ -1342,7 +1344,7 @@ msgstr "Prefijo del adjunto al guardar como" #. module: base #: field:ir.ui.view_sc,res_id:0 msgid "Resource Ref." -msgstr "" +msgstr "Ref. recurso" #. module: base #: field:ir.actions.act_url,url:0 @@ -5969,7 +5971,7 @@ msgid "" " module, but this will also install the CRM application as it depends on\n" " CRM Leads.\n" " " -msgstr "" +msgstr "\nEste módulo provee una automatización de las iniciativas a través de las campañas de marketing (campañas que de hecho pueden definir cualquier recurso, no sólo iniciativas CRM)\n================================================================================================================================================================================\n\nLas campañas son dinámicas y multi-canal. El proceso es como sigue:\n-------------------------------------------------------------------\n* Diseñe campañas de marketing como flujos, incluyendo plantillas de correo\n electrónico a enviar, informes a imprimir y enviar por correo y acciones\n personalizadas.\n* Defina segmentos de entrada que seleccionarán los elementos que deben entrar\n en la campaña (por ejemplo, iniciativas de varios países)\n* Ejecute su campaña en modo simulación para comprobarla en tiempo real o\n acelerado y afínela.\n* Puede iniciar la campaña real en modo manual, donde cada acción requiere una\n validación manual\n* Finalmente lance su campaña, y vea las estadísticas puesto que la campaña \n realiza todo de forma totalmente automática.\n\nMientras la campaña esté en marcha, puede por supuesto seguir afinando los\nparámetros, segmentos de entrada y flujo.\n\n**Nota:** Si necesita datos demo, puede instalar el módulo \nmarketing_campaign_crm_demo, pero esto instalará también la aplicación CRM,\nya que depende de las iniciativas CRM." #. module: base #: help:ir.mail_server,smtp_debug:0 @@ -6021,7 +6023,7 @@ msgstr "El usuario tendrá acceso a sus propios datos en la aplicación ventas." #: code:addons/orm.py:1393 #, python-format msgid "Unknown error during import:" -msgstr "" +msgstr "Error desconocido durante la importación" #. module: base #: code:addons/orm.py:2275 @@ -8126,7 +8128,7 @@ msgid "" "* The evaluation is done according to a plan in which various surveys can be created. Each survey can be answered by a particular level in the employees hierarchy. The final review and evaluation is done by the manager.\n" "* Every evaluation filled by employees can be viewed in a PDF form.\n" "* Interview Requests are generated automatically by OpenERP according to employees evaluation plans. Each user receives automatic emails and requests to perform a periodical evaluation of their colleagues.\n" -msgstr "" +msgstr "\nEvaluaciones y percepciones periódicas de los empleados\n=======================================================\n\nUsando esta aplicación puede mantener el proceso motivacional de los empleados realizando evaluaciones periódicas al rendimiento de sus empleados. La evaluación regular de Recursos Humanos puede beneficiar a sus empleados y a su organización.\n\nPuede asignar un plan de evaluación a cada empleado. Estos planes definen la frecuencia y la manera que gestiona las evaluaciones periódicas de su personal. Podrá definir pasos y adjuntar formularios de entrevista a cada paso.\n\nGestione varios tipos de evaluación: de arriba abajo, de abajo arriba, auto-evaluación y evaluación final del responsable.\n\nFuncionalidad clave\n-------------------\n* Posibilidad de crear evaluaciones de empleados\n* Una evaluación puede ser creada por un empleado para sus subordinados, juniors y también para su responsable.\n* La evaluación se hace basada en un plan en el que pueden ser incluidas varias encuestas. Cada encuesta puede ser respondida por un nivel particular en la jerarquía de empleados. La entrevista final y la evaluación es realizada por el responsable.\n* Cada valoración rellenada por empleados puede ser visualizada en un formulario PDF.\n* Las solicitudes de entrevista se generan automáticamente acorde a los planes de evaluación del empleado. Cada usuario recibe correos electrónicos automáticos y solicitudes para ejecutar la evaluación periódica de sus compañeros.\n" #. module: base #: model:ir.ui.menu,name:base.menu_view_base_module_update @@ -8845,7 +8847,7 @@ msgstr "Planificación 'Just in time' (bajo demanda)" #. module: base #: model:ir.module.module,shortdesc:base.module_saas_worker msgid "SAAS Worker" -msgstr "" +msgstr "Worker del SaaS" #. module: base #: view:ir.actions.server:0 field:ir.actions.server,code:0 @@ -9170,7 +9172,7 @@ msgid "" " stored to shelf 2.\n" " - When delivering the customer: Pick List -> Packing -> Delivery Order from Gate A\n" " " -msgstr "" +msgstr "\nThis module supplements the Warehouse application by effectively implementing Push and Pull inventory flows.\n============================================================================================================\n\nTypically this could be used to:\n--------------------------------\n * Manage product manufacturing chains\n * Manage default locations per product\n * Define routes within your warehouse according to business needs, such as:\n - Quality Control\n - After Sales Services\n - Supplier Returns\n\n * Help rental management, by generating automated return moves for rented products\n\nOnce this module is installed, an additional tab appear on the product form,\nwhere you can add Push and Pull flow specifications. The demo data of CPU1\nproduct for that push/pull :\n\nPush flows:\n-----------\nPush flows are useful when the arrival of certain products in a given location\nshould always be followed by a corresponding move to another location, optionally\nafter a certain delay. The original Warehouse application already supports such\nPush flow specifications on the Locations themselves, but these cannot be\nrefined per-product.\n\nA push flow specification indicates which location is chained with which location,\nand with what parameters. As soon as a given quantity of products is moved in the\nsource location, a chained move is automatically foreseen according to the\nparameters set on the flow specification (destination location, delay, type of\nmove, journal). The new move can be automatically processed, or require a manual\nconfirmation, depending on the parameters.\n\nPull flows:\n-----------\nPull flows are a bit different from Push flows, in the sense that they are not\nrelated to the processing of product moves, but rather to the processing of\nprocurement orders. What is being pulled is a need, not directly products. A\nclassical example of Pull flow is when you have an Outlet company, with a parent\nCompany that is responsible for the supplies of the Outlet.\n\n [ Customer ] <- A - [ Outlet ] <- B - [ Holding ] <~ C ~ [ Supplier ]\n\nWhen a new procurement order (A, coming from the confirmation of a Sale Order\nfor example) arrives in the Outlet, it is converted into another procurement\n(B, via a Pull flow of type 'move') requested from the Holding. When procurement\norder B is processed by the Holding company, and if the product is out of stock,\nit can be converted into a Purchase Order (C) from the Supplier (Pull flow of\ntype Purchase). The result is that the procurement order, the need, is pushed\nall the way between the Customer and Supplier.\n\nTechnically, Pull flows allow to process procurement orders differently, not\nonly depending on the product being considered, but also depending on which\nlocation holds the 'need' for that product (i.e. the destination location of\nthat procurement order).\n\nUse-Case:\n---------\n\nYou can use the demo data as follow:\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n **CPU1:** Sell some CPU1 from Chicago Shop and run the scheduler\n - Warehouse: delivery order, Chicago Shop: reception\n **CPU3:**\n - When receiving the product, it goes to Quality Control location then\n stored to shelf 2.\n - When delivering the customer: Pick List -> Packing -> Delivery Order from Gate A\n " #. module: base #: selection:ir.property,type:0 @@ -11001,7 +11003,7 @@ msgid "" "**LOGIN:** ${object.moodle_username}\n" "\n" "**PASSWORD:** ${object.moodle_user_password}\n" -msgstr "" +msgstr "\nConfigure su servidor Moodle\n============================ \n\nCon este módulo podrá conectar su OpenERP a una plataforma Moodle. Creará cursos y\nestudiantes automáticamente en su plataforma Moodle para evitar perder tiempo.\nAhora tiene una forma sencilla de crear cursos y formaciones con OpenERP y Moodle.\n\nPASOS PARA CONFIGURAR\n---------------------\n\n1. Activar el servicio web en Moodle\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n>Administración del sitio >Plugins >Servicios web >Gestionar protocolos - Activar el servicio xmlrpc\n\n\n>Administración del sitio >Plugins >Servicios web >Gestionar tokens - Crear un token\n\n\n>Administración del sitio >Plugins >Servicios web >Vistazo general - Activar servicio web\n\n\n2. Crear confirmación de correo electrónico con usuario y contraseña\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nRecomendamos encarecidamente añadir estas líneas al final del correo del evento de confirmación para\ncomunicar el usuario y contraseña de Moodle a sus suscriptores.\n\n\n........su texto de configuración.......\n\n**URL:** su enlace a Moodle - por ejemplo: http://openerp.moodle.com\n\n**USUARIO:** ${object.moodle_username}\n\n**CONTRASEÑA:** ${object.moodle_user_password}\n" #. module: base #: model:ir.module.module,description:base.module_report_webkit @@ -11052,7 +11054,7 @@ msgid "" " * Collated and book format support\n" " * Zip return for separated PDF\n" " * Web client WYSIWYG\n" -msgstr "" +msgstr "\nEste módulo añade un nuevo motor de informes basado en la librería WebKit (wkhtmltopdf) para soportar informes diseñados en HTML + CSS.\n=====================================================================================================================\n\nLa estructura del módulo y algo de código es inspirado en el módulo report_openoffice.\n\nEste módulo permite:\n--------------------------\n - Definición de imformes HTML \n - Soporte multi cabecera \n - Multi logo\n - Soporte multi-compañía\n - Soporte HTML y CSS-3 (En el límite de la versión actual de WebKit) \n - Soporte JavaScript\n - Debugger líneas HTML\n - Capacidad de imprimir libros\n - Definición de Márgenes \n - Definición de tamaño de papel\n\nLas cabeceras y logos múltiples pueden ser definidos por compañía. El estilo CSS, cabecera y pie se definen por compañía.\n\nPara un informe de ejemplo vea también el módulo webkit_report_sample y este video:\n http://files.me.com/nbessi/06n92k.mov\n\nRequerimientos e instalación:\n------------------------------------\nEste módulo requiere la librería ``wkhtmltopdf`` para renderizar documentos HTML como PDF. \n Version 0.9.9 o posterior. Se puede encontrar aquí: \nhttp://code.google.com/p/wkhtmltopdf/ para Linux, Mac OS X (i386) y Windows (32bits).\n\nDespués de instalar la librería en el servidor, puede requerir aplicar el parche al fichero ejecutable ``wkhtmltopdf`` en un parámetro del sistema que se llama ``webkit_path`` \n``webkit_path`` en Settings -> Customization -> Parameters -> System Parameters\n\nSi experimenta que falta la cabecera o el pie en linux, asegúrese de instalar una versión estática de la librería. La instalación por defecto en ubutu tiene este problema conocido.\n\nPara hacer:\n-------------\n * Soporte a la activación desactivación de JavaScript \n * Soporte al formato libro y cotejado\n * Devolución de un ZIP para PDFs separados \n * WYSIWYG en el cliente web\n" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_uk @@ -11587,7 +11589,7 @@ msgid "" "\n" "If you install this module, and select Custom chart a basic chart will be proposed, \n" "but you will need set manually account defaults for taxes.\n" -msgstr "" +msgstr "\nPlan de cuentas de Venezuela\n============================\n\nVenezuela no tiene ningún plan de cuentas por ley, pero el propuesto por defecto \nen Odoo debería cumplir con las mejores prácticas aceptadas allí.\n\nEste módulo ha sido probado como base para más de 1000 empresas, porque \nestá basado en una mezcla de lo encontrado en el software más común en el \nmercado venezolano , lo que permite a los contables sentirse más cómodos en\nsus primeros pasos con Odoo.\n\nEste módulo no pretende ser la localización completa para Venezuela, pero le \nayudará a comenzar muy rápido con Odoo en este país.\n\nWe recomend install account_anglo_saxon if you want valued your\nstocks as Venezuela does with out invoices.\n\nIf you install this module, and select Custom chart a basic chart will be proposed,\nbut you will need set manually account defaults for taxes.\n\nEste módulo propociona:\n-----------------------\n\n- Impuestos básicos para Venezuela.\n- Tener datos básicos para ejecutar tests con la localización de la comunidad.\n- Comenzar una compañía desde 0 en Odoo si sus necesidades contables son básicas.\n\nLe recomendamos instalar el módulo _account_anglo_saxon_ si quiere valorar las \nexistencias como se realiza en Venezuela con las facturas de cliente.\n\nSi instala este módulo, y selecciona el plan de cuentas personalizado, se le \npropondrá un plan básico, y tendrá que configurar manualmente las cuenta por \ndefecto para los impuestos.\n" #. module: base #: selection:base.language.install,lang:0 @@ -13245,7 +13247,7 @@ msgstr "Multi-Compañías" #: code:addons/orm.py:1395 #, python-format msgid "Resolve other errors first" -msgstr "" +msgstr "Resuelva otros errores primero" #. module: base #: field:workflow,osv:0 view:workflow.instance:0 @@ -13660,7 +13662,7 @@ msgid "" "procurement line is updated accordingly. For example, if this procurement corresponds\n" "to a sale order line, the sale order line will be considered delivered when the\n" "task is completed.\n" -msgstr "" +msgstr "\nCrea automáticamente tareas de proyecto desde líneas de abastecimientos\n=======================================================================\n\nEste modulo creará automáticamente una tarea nueva por cada línea de\nabastecimiento (p.ej.: para líneas de pedidos de ventas), si el producto\ncorrespondiente reúne las siguientes características:\n\n * Tipo de producto = servicio\n * Método de abastecimiento (cumplimentación del pedido) = MTO (Obtener desde pedido)\n * Método de suministro = Fabricar\n\nSi además de esto está especificado un proyecto en el formulario del producto\n(en la pestaña de Abastecimientos), entonces la nueva tarea se creará en este\nproyecto específico. Si no, la nueva tarea no pertenecerá a ningún proyecto y\nse podrá añadir a un proyecto manualmente más tarde.\n\nCuando la tarea del proyecto se complete o se cancele, el abastecimiento\ncorrespondiente será actualizado adecuadamente. Por ejemplo, si este\nabastecimiento corresponde a una línea de pedido de venta, ésta se considerará\nentregada cuando se complete la tarea.\n" #. module: base #: field:ir.actions.act_window,limit:0 @@ -14284,7 +14286,7 @@ msgid "" " user to a username that does not exist in LDAP, and setup its groups\n" " the way you want.\n" " " -msgstr "" +msgstr "\nAñade soporte para la autenticación por un servidor LDAP.\n=========================================================\n\nEste módulo permite a los usuarios acceder al sistema con su usuario y contraseña \nLDAP, y creará automáticamente usuarios OpenERP para ellos.\n\n**Nota:** Este módulo sólo funcionará en servidores que tengan el módulo Python\n``ldap`` instalado.\n\nConfiguración:\n--------------\nAfter installing this module, you need to configure the LDAP parameters in the\nConfiguration tab of the Company details. Different companies may have different\nLDAP servers, as long as they have unique usernames (usernames need to be unique\nin OpenERP, even across multiple companies).\n\nAnonymous LDAP binding is also supported (for LDAP servers that allow it), by\nsimply keeping the LDAP user and password empty in the LDAP configuration.\nThis does not allow anonymous authentication for users, it is only for the master\nLDAP account that is used to verify if a user exists before attempting to\nauthenticate it.\n\nSecuring the connection with STARTTLS is available for LDAP servers supporting\nit, by enabling the TLS option in the LDAP configuration.\n\nFor further options configuring the LDAP settings, refer to the ldap.conf\nmanpage: manpage:`ldap.conf(5)`.\n\nSecurity Considerations:\n------------------------\nUsers' LDAP passwords are never stored in the OpenERP database, the LDAP server\nis queried whenever a user needs to be authenticated. No duplication of the\npassword occurs, and passwords are managed in one place only.\n\nOpenERP does not manage password changes in the LDAP, so any change of password\nshould be conducted by other means in the LDAP directory directly (for LDAP users).\n\nIt is also possible to have local OpenERP users in the database along with\nLDAP-authenticated users (the Administrator account is one obvious example).\n\nHere is how it works:\n---------------------\n * The system first attempts to authenticate users against the local OpenERP\n database;\n * if this authentication fails (for example because the user has no local\n password), the system then attempts to authenticate against LDAP;\n\nAs LDAP users have blank passwords by default in the local OpenERP database\n(which means no access), the first step always fails and the LDAP server is\nqueried to do the authentication.\n\nEnabling STARTTLS ensures that the authentication query to the LDAP server is\nencrypted.\n\nUser Template:\n--------------\nIn the LDAP configuration on the Company form, it is possible to select a *User\nTemplate*. If set, this user will be used as template to create the local users\nwhenever someone authenticates for the first time via LDAP authentication. This\nallows pre-setting the default groups and menus of the first-time users.\n\n**Warning:** if you set a password for the user template, this password will be\n assigned as local password for each new LDAP user, effectively setting\n a *master password* for these users (until manually changed). You\n usually do not want this. One easy way to setup a template user is to\n login once with a valid LDAP user, let OpenERP create a blank local\n user with the same login (and a blank password), then rename this new\n user to a username that does not exist in LDAP, and setup its groups" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_pt @@ -14327,7 +14329,7 @@ msgid "" "* Last Product Inventories\n" "* Moves Analysis\n" " " -msgstr "" +msgstr "\nGestión multi-almacén y multi-ubicaciones estructuradas\n=======================================================\n\nEl almacén y gestión de inventario está basado en una estructura de ubicaciones jerárquica, desde almacén hasta unidades de almacenamiento. \nEl sistema de inventario de doble entrada le permite gestionar el inventario de clientes, proveedores y de fabricación.\n\nOpenERP tiene la capacidad de gestionar lotes y números de serie, asegurando compatibilidad con los requerimientos de trazabilidad impuestos por la mayoría de industrias.\n\nFuncionalidad clave\n-------------------\n* Histórico de movimientos y planificación\n* Valoración de inventario (estándar o precio medio, ...)\n* Robustez mediante la comparacióln de las diferencias de inventario\n* Reglas de reabastecimiento automáticas\n* Soporte a códigos de barras\n* Detección rápida de problemas mediante el sistema de doble entrada\n* Trazabilidad (Ascendente y descendente, números de serie, ... )\n\nLos tableros / informes para la gestión de almacén incluidos son:\n-----------------------------------------------------------------\n* Entrada de productos (Gráfico)\n* Salida de productos (Gráfico)\n* Abastecimientos en excepción\n* Análisis de inventario\n* Inventario de los últimos productos\n* Análisis de movimientos" #. module: base #: model:ir.module.module,description:base.module_l10n_ch From f2c807d99d8f89fe3eeae39e719db8d39e9df483 Mon Sep 17 00:00:00 2001 From: Matthieu Dietrich Date: Wed, 1 Jul 2015 15:47:31 +0200 Subject: [PATCH 03/11] [IMP] account_report_company: performance on partner name_search The field display_name is present in account_report_company but not in base on the res.partner (has been added in v8 in base). Create a hook method to keep using the slow CASE in base and switch to the faster display_name when installing account_report_company. --- .../account_report_company.py | 5 ++++ openerp/addons/base/res/res_partner.py | 27 ++++++++++--------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/addons/account_report_company/account_report_company.py b/addons/account_report_company/account_report_company.py index fe5d237adf2..be77be8d0b6 100644 --- a/addons/account_report_company/account_report_company.py +++ b/addons/account_report_company/account_report_company.py @@ -43,6 +43,11 @@ class res_partner(osv.Model): 'display_name': fields.function(_display_name, type='char', string='Name', store=_display_name_store_triggers, select=1), } + def _get_display_name(self, unaccent): + # use stored display name for better performances + return unaccent('res_partner.display_name') + + class account_invoice(osv.Model): _inherit = 'account.invoice' diff --git a/openerp/addons/base/res/res_partner.py b/openerp/addons/base/res/res_partner.py index 4f2dcaf4b85..414a513f918 100644 --- a/openerp/addons/base/res/res_partner.py +++ b/openerp/addons/base/res/res_partner.py @@ -622,6 +622,20 @@ class res_partner(osv.osv, format_address): return super(res_partner, self)._search(cr, user, args, offset=offset, limit=limit, order=order, context=context, count=count, access_rights_uid=access_rights_uid) + def _get_display_name(self, unaccent): + # TODO: simplify this in trunk with `display_name`, once it is stored + # Perf note: a CTE expression (WITH ...) seems to have an even higher cost + # than this query with duplicated CASE expressions. The bulk of + # the cost is the ORDER BY, and it is inevitable if we want + # relevant results for the next step, otherwise we'd return + # a random selection of `limit` results. + + return """CASE WHEN company.id IS NULL OR res_partner.is_company + THEN {partner_name} + ELSE {company_name} || ', ' || {partner_name} + END""".format(partner_name=unaccent('res_partner.name'), + company_name=unaccent('company.name')) + def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100): if not args: args = [] @@ -642,18 +656,7 @@ class res_partner(osv.osv, format_address): unaccent = get_unaccent_wrapper(cr) - # TODO: simplify this in trunk with `display_name`, once it is stored - # Perf note: a CTE expression (WITH ...) seems to have an even higher cost - # than this query with duplicated CASE expressions. The bulk of - # the cost is the ORDER BY, and it is inevitable if we want - # relevant results for the next step, otherwise we'd return - # a random selection of `limit` results. - - display_name = """CASE WHEN company.id IS NULL OR res_partner.is_company - THEN {partner_name} - ELSE {company_name} || ', ' || {partner_name} - END""".format(partner_name=unaccent('res_partner.name'), - company_name=unaccent('company.name')) + display_name = self._get_display_name(unaccent) query = """SELECT res_partner.id FROM res_partner From 6af7c636c2a1c7a8558fb6355c6211f374283c67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ana=C3=ABl=20Closson?= Date: Tue, 3 Jun 2014 16:19:05 +0200 Subject: [PATCH 04/11] [FIX] sale: cannot filter on paid = False Closes #2211 --- addons/sale/sale.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 1244cf09f5f..be4e4a01e1d 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -151,13 +151,12 @@ class sale_order(osv.osv): sale_clause = '' no_invoiced = False for arg in args: - if arg[1] == '=': - if arg[2]: - clause += 'AND inv.state = \'paid\'' - else: - clause += 'AND inv.state != \'cancel\' AND sale.state != \'cancel\' AND inv.state <> \'paid\' AND rel.order_id = sale.id ' - sale_clause = ', sale_order AS sale ' - no_invoiced = True + if (arg[1] == '=' and arg[2]) or (arg[1] == '!=' and not arg[2]): + clause += 'AND inv.state = \'paid\'' + else: + clause += 'AND inv.state != \'cancel\' AND sale.state != \'cancel\' AND inv.state <> \'paid\' AND rel.order_id = sale.id ' + sale_clause = ', sale_order AS sale ' + no_invoiced = True cursor.execute('SELECT rel.order_id ' \ 'FROM sale_order_invoice_rel AS rel, account_invoice AS inv '+ sale_clause + \ From 2c37f834351090210ac57c29b974a636e9fea3a8 Mon Sep 17 00:00:00 2001 From: Christophe Combelles Date: Fri, 17 Apr 2015 17:10:17 +0300 Subject: [PATCH 05/11] [FIX] analytic: duplication of analytic lines When duplicating analytic accounts, child accounts are duplicated as well. The custom copy method removes the analytic lines but this applies only on the first copy. As the copy_data method recursively copies child accounts, these child accounts did not use the custom copy method but the basic copy_data. Move to copy_data Fixes #6368, lp:1149676 --- addons/account/__openerp__.py | 1 + addons/account/test/analytic_hierarchy.yml | 56 ++++++++++++++++++++++ addons/analytic/analytic.py | 12 ++++- 3 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 addons/account/test/analytic_hierarchy.yml diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py index 18277dbb4dd..d236d2643b8 100644 --- a/addons/account/__openerp__.py +++ b/addons/account/__openerp__.py @@ -157,6 +157,7 @@ for a particular financial year and for preparation of vouchers there is a modul #'test/account_cash_statement.yml', 'test/test_edi_invoice.yml', 'test/account_report.yml', + 'test/analytic_hierarchy.yml', 'test/account_fiscalyear_close.yml', #last test, as it will definitively close the demo fiscalyear ], 'installable': True, diff --git a/addons/account/test/analytic_hierarchy.yml b/addons/account/test/analytic_hierarchy.yml new file mode 100644 index 00000000000..117d6506b21 --- /dev/null +++ b/addons/account/test/analytic_hierarchy.yml @@ -0,0 +1,56 @@ +- + We create a simple hierarchy like this + Toplevel view account + ├ Real analytic account 1 + └ Real analytic account 2 +- + !record {model: account.analytic.account, id: analytic_account_view1}: + name: 'Toplevel view account' + type: 'view' +- + !record {model: account.analytic.account, id: analytic_account1}: + name: 'Real analytic account 1' + type: 'normal' + parent_id: analytic_account_view1 +- + !record {model: account.analytic.account, id: analytic_account2}: + name: 'Real analytic account 2' + type: 'normal' + parent_id: analytic_account_view1 +- + We add analytic lines in real accounts and journal +- + !record {model: account.analytic.journal, id: analytic_journal1}: + name: 'Analytic journal' +- + !record {model: account.analytic.line, id: analytic_line1}: + name: 'Analytic line 1' + account_id: analytic_account1 + journal_id: analytic_journal1 + general_account_id: account.a_expense +- + !record {model: account.analytic.line, id: analytic_line2}: + name: 'Analytic line 2' + account_id: analytic_account2 + journal_id: analytic_journal1 + general_account_id: account.a_expense +- + Now we copy the toplevel account +- + !function {model: account.analytic.account, name: copy, id: analytic_account_view1}: + - eval: "ref('analytic_account_view1')" +- + !python {model: account.analytic.account}: | + # the toplevel account has been copied with the (copy) suffix + accounts = self.search(cr, uid, [('name', 'like', '%Toplevel view account%')]) + assert len(accounts) == 2, 'The toplevel account has not been copied' + accounts = self.search(cr, uid, [('name', '=', 'Toplevel view account')]) + assert len(accounts) == 1, 'The toplevel account copy has a bad name' + # the sub-accounts and sub-accounts have been copied without the (copy) suffix + accounts = self.search(cr, uid, [('name', '=', 'Real analytic account 1')]) + assert len(accounts) == 2, 'The sub-account has not been copied' + accounts = self.search(cr, uid, [('name', '=', 'Real analytic account 2')]) + assert len(accounts) == 2, 'The sub-account has not been copied' + # the analytic lines should not be duplicated + lines = self.pool.get('account.analytic.line').search(cr, uid, [('name', 'like', '%Analytic line %')]) + assert len(lines) == 2, "The analytic lines shouldn't have been copied" diff --git a/addons/analytic/analytic.py b/addons/analytic/analytic.py index 5c91caad3a5..3e402f91cf8 100644 --- a/addons/analytic/analytic.py +++ b/addons/analytic/analytic.py @@ -261,13 +261,21 @@ class account_analytic_account(osv.osv): def name_create(self, cr, uid, name, context=None): raise osv.except_osv(_('Warning'), _("Quick account creation disallowed.")) + def copy_data(self, cr, uid, id, default=None, context=None): + """executed for all the objects down the hierarchy during copy""" + if not default: + default = {} + default.setdefault('code', False) + default.setdefault('line_ids', []) + return super(account_analytic_account, self).copy_data(cr, uid, id, default, context=context) + def copy(self, cr, uid, id, default=None, context=None): + """ executed only on the toplevel copied object of the hierarchy. + Subobject are actually copied with copy_data""" if not default: default = {} analytic = self.browse(cr, uid, id, context=context) default.update( - code=False, - line_ids=[], name=_("%s (copy)") % (analytic['name'])) return super(account_analytic_account, self).copy(cr, uid, id, default, context=context) From dc0e126b537d9539cf8132a414e7af81165547ad Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Wed, 23 Oct 2013 18:29:28 +0200 Subject: [PATCH 06/11] [FIX] hr_holidays: leave holiday overlap should ignore cancelled/refused ones Obviously a cancelled leave does not really overlap with a new one. bzr revid: odo@openerp.com-20131023162928-56vdsjxr8sa4n3jv Closes #2329 --- addons/hr_holidays/hr_holidays.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/hr_holidays/hr_holidays.py b/addons/hr_holidays/hr_holidays.py index cdfc86b8539..f12492903b1 100644 --- a/addons/hr_holidays/hr_holidays.py +++ b/addons/hr_holidays/hr_holidays.py @@ -141,7 +141,9 @@ class hr_holidays(osv.osv): def _check_date(self, cr, uid, ids): for holiday in self.browse(cr, uid, ids): - holiday_ids = self.search(cr, uid, [('date_from', '<=', holiday.date_to), ('date_to', '>=', holiday.date_from), ('employee_id', '=', holiday.employee_id.id), ('id', '<>', holiday.id)]) + holiday_ids = self.search(cr, uid, [('date_from', '<=', holiday.date_to), ('date_to', '>=', holiday.date_from), + ('employee_id', '=', holiday.employee_id.id), ('id', '<>', holiday.id), + ('state', 'not in', ['cancel', 'refuse'])]) if holiday_ids: return False return True From 0f82346167698fb7349ff16618d1cecf8984cca9 Mon Sep 17 00:00:00 2001 From: Lorenzo Battistini Date: Mon, 24 Nov 2014 18:41:08 +0100 Subject: [PATCH 07/11] [FIX] email_template: keep email_from and outgoing server When sending an email from mail.compose.message using a template, the system should use the outgoing mail server associated to the template. Introduce context hack to keep these values. This should NOT to be forward ported to version 8 where a proper fix exists. Fixes #3848 --- addons/email_template/wizard/mail_compose_message.py | 10 +++++++++- addons/mail/mail_followers.py | 8 +++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/addons/email_template/wizard/mail_compose_message.py b/addons/email_template/wizard/mail_compose_message.py index 22bb53beae3..d9b5f5fe6ba 100644 --- a/addons/email_template/wizard/mail_compose_message.py +++ b/addons/email_template/wizard/mail_compose_message.py @@ -66,10 +66,18 @@ class mail_compose_message(osv.TransientModel): Indeed, basic mail.compose.message wizard duplicates attachments in mass mailing mode. But in 'single post' mode, attachments of an email template also have to be duplicated to avoid changing their ownership. """ + email_context = dict(context or {}) for wizard in self.browse(cr, uid, ids, context=context): if not wizard.attachment_ids or wizard.composition_mode == 'mass_mail' or not wizard.template_id: continue template = self.pool.get('email.template').browse(cr, uid, wizard.template_id, context=context) + # TODO v8, remove me + # template specific outgoing mail server and email from is lost in super send_mail + # store them in the context to avoid falling back to default values + if template.mail_server_id: + email_context['mail_server_id'] = template.mail_server_id.id + if template.email_from: + email_context['email_from'] = template.email_from new_attachment_ids = [] for attachment in wizard.attachment_ids: if attachment in template.attachment_ids: @@ -77,7 +85,7 @@ class mail_compose_message(osv.TransientModel): else: new_attachment_ids.append(attachment.id) self.write(cr, uid, wizard.id, {'attachment_ids': [(6, 0, new_attachment_ids)]}, context=context) - return super(mail_compose_message, self).send_mail(cr, uid, ids, context=context) + return super(mail_compose_message, self).send_mail(cr, uid, ids, context=email_context) def onchange_template_id(self, cr, uid, ids, template_id, composition_mode, model, res_id, context=None): """ - mass_mailing: we cannot render, so return the template values diff --git a/addons/mail/mail_followers.py b/addons/mail/mail_followers.py index f4c74b0c996..29bd64ef5fa 100644 --- a/addons/mail/mail_followers.py +++ b/addons/mail/mail_followers.py @@ -156,7 +156,10 @@ class mail_notification(osv.Model): body_html = tools.append_content_to_html(body_html, signature, plaintext=True, container_tag='div') # email_from: partner-user alias or partner email or mail.message email_from - if msg.author_id and msg.author_id.user_ids and msg.author_id.user_ids[0].alias_domain and msg.author_id.user_ids[0].alias_name: + if 'email_from' in context: + # temporary workaround for mail from send mail wizard + email_from = context['email_from'] + elif msg.author_id and msg.author_id.user_ids and msg.author_id.user_ids[0].alias_domain and msg.author_id.user_ids[0].alias_name: email_from = formataddr((msg.author_id.name, '%s@%s' % (msg.author_id.user_ids[0].alias_name, msg.author_id.user_ids[0].alias_domain))) elif msg.author_id: email_from = formataddr((msg.author_id.name, msg.author_id.email)) @@ -174,6 +177,9 @@ class mail_notification(osv.Model): 'email_from': email_from, 'references': references, } + if 'mail_server_id' in context: + # temporary workaround for mail from send mail wizard + mail_values['mail_server_id'] = context['mail_server_id'] email_notif_id = mail_mail.create(cr, uid, mail_values, context=context) try: return mail_mail.send(cr, uid, [email_notif_id], recipient_ids=notify_partner_ids, context=context) From 2a49c1a7fbbcfd5ebd52f03ad031b54a7c9e4911 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Tue, 30 Jun 2015 12:24:30 +0200 Subject: [PATCH 08/11] [FIX] purchase: take into account the currency of unit price The currency of the unit price of the stock.move is the currency of the company, which can be different from the currency of the invoice. opw-643077 --- addons/purchase/stock.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/addons/purchase/stock.py b/addons/purchase/stock.py index c211f39e719..00ded4c91f1 100644 --- a/addons/purchase/stock.py +++ b/addons/purchase/stock.py @@ -87,7 +87,12 @@ class stock_picking(osv.osv): def _get_price_unit_invoice(self, cursor, user, move_line, type): if move_line.purchase_line_id: if move_line.purchase_line_id.order_id.invoice_method == 'picking': - return move_line.price_unit + price_unit = move_line.price_unit + order = move_line.purchase_line_id.order_id + if order.currency_id.id != order.company_id.currency_id.id: + price_unit = self.pool.get('res.currency').compute(cursor, user, + order.company_id.currency_id.id, order.currency_id.id, move_line.price_unit, round=False, context=dict({}, date=order.date_order)) + return price_unit else: return move_line.purchase_line_id.price_unit return super(stock_picking, self)._get_price_unit_invoice(cursor, user, move_line, type) From 6e346f0adbf6b62347b1d86429a345fc0ac2ae26 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Fri, 3 Jul 2015 16:40:02 +0200 Subject: [PATCH 09/11] [FIX] stock: product_uos_qty must have the precision of Product UoS If 'Product UoS' has a higher precision than 'Product Unit of Measure', the method onchange_uos_quantity will be called over and over by an infinite loop if 'product_uos_qty' doesn't have the sufficient number of decimals. opw-643651 --- addons/stock/stock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 16deddcca5b..3a500ce5ad5 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1610,7 +1610,7 @@ class stock_move(osv.osv): "the product reservation, and should be done with care." ), 'product_uom': fields.many2one('product.uom', 'Unit of Measure', required=True,states={'done': [('readonly', True)]}), - 'product_uos_qty': fields.float('Quantity (UOS)', digits_compute=dp.get_precision('Product Unit of Measure'), states={'done': [('readonly', True)]}), + 'product_uos_qty': fields.float('Quantity (UOS)', digits_compute=dp.get_precision('Product UoS'), states={'done': [('readonly', True)]}), 'product_uos': fields.many2one('product.uom', 'Product UOS', states={'done': [('readonly', True)]}), 'product_packaging': fields.many2one('product.packaging', 'Packaging', help="It specifies attributes of packaging like type, quantity of packaging,etc."), From 34b9f43011b1e92d998ed25a5ebbc74a6293c266 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20BELLIER?= Date: Mon, 1 Dec 2014 15:34:17 +0100 Subject: [PATCH 10/11] [FIX] stock: add location in context on prodlot search To be consistant with the results of _get_stock. Otherwise search made on stock_available may not display results with the same value than the search criteria. Fixes #3976 --- addons/stock/stock.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 3a500ce5ad5..7336edd56b7 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1437,7 +1437,15 @@ class stock_production_lot(osv.osv): """ Searches Ids of products @return: Ids of locations """ - locations = self.pool.get('stock.location').search(cr, uid, [('usage', '=', 'internal')]) + if context is None: + context = {} + + if 'location_id' not in context: + locations = self.pool['stock.location'].search( + cr, uid, [('usage', '=', 'internal')], context=context) + else: + locations = context['location_id'] and [context['location_id']] or [] + cr.execute('''select prodlot_id, sum(qty) From 9fa7624e254bf63df26e39fc8d55295ccb5c3c5e Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Tue, 7 Jul 2015 11:00:58 +0200 Subject: [PATCH 11/11] [FIX] stock: onchange_quantity and onchange_uos_quantity use rounding It is necessary to round the quantities with the appropriate precision. Indeed, since onchange_quantity and onchange_uos_quantity trigger each other indirectly, it is quite easy to fall in an infinite loop if the uom and uos precisions are different. Follows commit 6e346f0adbf6b62347b1d86429a345fc0ac2ae26 opw-643651 --- addons/stock/stock.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 7336edd56b7..c234a951b1c 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -29,7 +29,7 @@ from openerp.osv import fields, osv, orm from openerp.tools.translate import _ from openerp import netsvc from openerp import tools -from openerp.tools import float_compare, DEFAULT_SERVER_DATETIME_FORMAT +from openerp.tools import float_compare, float_round, DEFAULT_SERVER_DATETIME_FORMAT import openerp.addons.decimal_precision as dp import logging _logger = logging.getLogger(__name__) @@ -1873,7 +1873,8 @@ class stock_move(osv.osv): break if product_uos and product_uom and (product_uom != product_uos): - result['product_uos_qty'] = product_qty * uos_coeff['uos_coeff'] + precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Product UoS') + result['product_uos_qty'] = float_round(product_qty * uos_coeff['uos_coeff'], precision_digits=precision) else: result['product_uos_qty'] = product_qty @@ -1903,7 +1904,8 @@ class stock_move(osv.osv): # The clients should call onchange_quantity too anyway if product_uos and product_uom and (product_uom != product_uos): - result['product_qty'] = product_uos_qty / uos_coeff['uos_coeff'] + precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Product Unit of Measure') + result['product_qty'] = float_round(product_uos_qty / uos_coeff['uos_coeff'], precision_digits=precision) else: result['product_qty'] = product_uos_qty return {'value': result}