From 21bc53d02392a06137ab5e637b6efa7bafa7592d Mon Sep 17 00:00:00 2001 From: "Dhara (OpenERP)" <> Date: Thu, 13 Oct 2011 14:11:47 -0700 Subject: [PATCH 001/248] [NEW] Account Check Writing-1 bzr revid: dhara_openerp-20111013211147-hs0qruje2t6vnyl5 --- addons/account_check_writing/__init__.py | 26 ++ addons/account_check_writing/__openerp__.py | 48 +++ addons/account_check_writing/account.py | 50 +++ .../account_check_writing_data.xml | 15 + .../account_check_writing_report.xml | 29 ++ addons/account_check_writing/account_demo.xml | 9 + addons/account_check_writing/account_view.xml | 42 ++ .../account_check_writing/account_voucher.py | 121 ++++++ .../account_voucher_view.xml | 56 +++ .../account_check_writing/report/__init__.py | 25 ++ .../report/check_print.py | 108 ++++++ .../report/check_print_bottom.rml | 321 ++++++++++++++++ .../report/check_print_middle.rml | 359 ++++++++++++++++++ .../report/check_print_top.rml | 338 +++++++++++++++++ 14 files changed, 1547 insertions(+) create mode 100644 addons/account_check_writing/__init__.py create mode 100644 addons/account_check_writing/__openerp__.py create mode 100644 addons/account_check_writing/account.py create mode 100644 addons/account_check_writing/account_check_writing_data.xml create mode 100644 addons/account_check_writing/account_check_writing_report.xml create mode 100644 addons/account_check_writing/account_demo.xml create mode 100644 addons/account_check_writing/account_view.xml create mode 100644 addons/account_check_writing/account_voucher.py create mode 100644 addons/account_check_writing/account_voucher_view.xml create mode 100644 addons/account_check_writing/report/__init__.py create mode 100644 addons/account_check_writing/report/check_print.py create mode 100644 addons/account_check_writing/report/check_print_bottom.rml create mode 100644 addons/account_check_writing/report/check_print_middle.rml create mode 100644 addons/account_check_writing/report/check_print_top.rml diff --git a/addons/account_check_writing/__init__.py b/addons/account_check_writing/__init__.py new file mode 100644 index 00000000000..0451b2bdb6a --- /dev/null +++ b/addons/account_check_writing/__init__.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +import account +import account_voucher +import wizard +import report +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_check_writing/__openerp__.py b/addons/account_check_writing/__openerp__.py new file mode 100644 index 00000000000..c09288f6955 --- /dev/null +++ b/addons/account_check_writing/__openerp__.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +{ + "name" : "Check writing", + "version" : "1.1", + "author" : "OpenERP SA, NovaPoint Group", + "category": "Generic Modules/Accounting", + "description": """ + Module for the Check writing and check printing + """, + 'website': 'http://www.openerp.com', + 'init_xml': [], + "depends" : [ + "account_voucher", + ], + 'update_xml': [ + 'account_check_writing_report.xml', + 'account_view.xml', + 'account_voucher_view.xml', + 'account_check_writing_data.xml', + ], + 'demo_xml': [ + 'account_demo.xml', + ], + 'test': [ + ], + 'installable': True, + 'active': False, +} +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_check_writing/account.py b/addons/account_check_writing/account.py new file mode 100644 index 00000000000..4dbbc245033 --- /dev/null +++ b/addons/account_check_writing/account.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from osv import osv,fields + +class account_journal(osv.osv): + _inherit = "account.journal" + + _columns = { + 'allow_check_writing': fields.boolean('Allow Check writing', help='Check this if the journal is to be used for writing checks.'), + 'use_preprint_check': fields.boolean('Use Preprinted Check'), + } + +account_journal() + +class res_company(osv.osv): + _inherit = "res.company" + _columns = { + 'check_layout': fields.selection([ + ('top', 'Check on Top'), + ('middle', 'Check in middle'), + ('bottom', 'Check on bottom'), + ],"Choose Check layout", + help="Check on top is compatible with Quicken, QuickBooks and Microsoft Money. Check in middle is compatible with Peachtree, ACCPAC and DacEasy. Check on bottom is compatible with Peachtree, ACCPAC and DacEasy only" ), + } + + _defaults = { + 'check_layout' : lambda *a: 'top', + } + +res_company() +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_check_writing/account_check_writing_data.xml b/addons/account_check_writing/account_check_writing_data.xml new file mode 100644 index 00000000000..324967836c2 --- /dev/null +++ b/addons/account_check_writing/account_check_writing_data.xml @@ -0,0 +1,15 @@ + + + + + Check Number + check.number + + + + Check Number + check.number + + + + diff --git a/addons/account_check_writing/account_check_writing_report.xml b/addons/account_check_writing/account_check_writing_report.xml new file mode 100644 index 00000000000..062827d3aa2 --- /dev/null +++ b/addons/account_check_writing/account_check_writing_report.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + diff --git a/addons/account_check_writing/account_demo.xml b/addons/account_check_writing/account_demo.xml new file mode 100644 index 00000000000..d4d772f597a --- /dev/null +++ b/addons/account_check_writing/account_demo.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/addons/account_check_writing/account_view.xml b/addons/account_check_writing/account_view.xml new file mode 100644 index 00000000000..529bfab2537 --- /dev/null +++ b/addons/account_check_writing/account_view.xml @@ -0,0 +1,42 @@ + + + + + + + + account.journal.form + account.journal + form + + + + + + + + + + + + + + res.company.check.format + res.company + form + 17 + + + + + + + + + + + diff --git a/addons/account_check_writing/account_voucher.py b/addons/account_check_writing/account_voucher.py new file mode 100644 index 00000000000..5d1d08018a8 --- /dev/null +++ b/addons/account_check_writing/account_voucher.py @@ -0,0 +1,121 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from osv import osv,fields +from tools.translate import _ +from tools.amount_to_text_en import amount_to_text +from lxml import etree + +check_layout_report = { + 'top' : 'account.print.check.top', + 'middle' : 'account.print.check.middle', + 'bottom' : 'account.print.check.bottom', +} + +class account_voucher(osv.osv): + _inherit = 'account.voucher' + + def _get_journal(self, cr, uid, context=None): + + if context is None: context = {} + + journal_pool = self.pool.get('account.journal') + invoice_pool = self.pool.get('account.invoice') + + if context.get('invoice_id', False): + currency_id = invoice_pool.browse(cr, uid, context['invoice_id'], context=context).currency_id.id + journal_id = journal_pool.search(cr, uid, [('currency', '=', currency_id)], limit=1) + return journal_id and journal_id[0] or False + + if context.get('journal_id', False): + return context.get('journal_id') + + if not context.get('journal_id', False) and context.get('search_default_journal_id', False): + return context.get('search_default_journal_id') + + ttype = context.get('type', 'bank') + + if ttype in ('payment', 'receipt'): + ttype = 'bank' + if context.get('write_check',False) : + res = journal_pool.search(cr, uid, [('allow_check_writing', '=', True)], limit=1) + else : + res = journal_pool.search(cr, uid, [('type', '=', ttype)], limit=1) + return res and res[0] or False + + _columns = { + 'amount_in_word' : fields.char("Amount in word" , size=128, readonly=True, states={'draft':[('readonly',False)]}), + 'allow_check' : fields.boolean('Allow Check Writing'), + 'number': fields.char('Number', size=32), + } + + _defaults = { + 'journal_id':_get_journal, + } + + def onchange_partner_id(self, cr, uid, ids, partner_id, journal_id, price, currency_id, ttype, date, context=None): + """ Inherited - add amount_in_word in return value dictionary """ + + if not context: + context = {} + default = super(account_voucher, self).onchange_partner_id(cr, uid, ids, partner_id, journal_id, price, currency_id, ttype, date, context=context) + if 'value' in default: + amount = 'amount' in default['value'] and default['value']['amount'] or price + + #TODO : generic amount_to_text is not ready yet, otherwise language and currency can be passed + + amount_in_word = amount_to_text(amount) + default['value'].update({'amount_in_word':amount_in_word}) + + if journal_id: + allow_check_writing = self.pool.get('account.journal').browse(cr, uid, journal_id).allow_check_writing + default['value'].update({'allow_check':allow_check_writing}) + + return default + + def print_check(self, cr, uid, ids, context=None): + if not ids: return [] + + check_layout = self.browse(cr, uid, ids[0], context=context).company_id.check_layout + + return { + 'type': 'ir.actions.report.xml', + 'report_name':check_layout_report[check_layout], + 'datas': { + 'model':'account.voucher', + 'id': ids and ids[0] or False, + 'ids': ids and ids or [], + 'report_type': 'pdf' + }, + 'nodestroy': True + } + + def fields_view_get(self, cr, uid, view_id=None, view_type=False, context=None, toolbar=False, submenu=False): + res = super(account_voucher, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=submenu) + doc = etree.XML(res['arch']) + nodes = doc.xpath("//field[@name='journal_id']") + if context.get('write_check', False) : + for node in nodes: + node.set('domain', "[('type', '=', 'bank')]") + res['arch'] = etree.tostring(doc) + return res + +account_voucher() diff --git a/addons/account_check_writing/account_voucher_view.xml b/addons/account_check_writing/account_voucher_view.xml new file mode 100644 index 00000000000..65d388ab42b --- /dev/null +++ b/addons/account_check_writing/account_voucher_view.xml @@ -0,0 +1,56 @@ + + + + + + + + account.voucher.payment.check.form + account.voucher + form + + + + + + + + + + + + + + + + + Write Checks + account.voucher + form + form,tree + [('journal_id.type', '=', 'bank'), ('type','=','payment'), ('journal_id.allow_check_writing','=',True)] + {'type':'payment','write_check':True} + + current + The check payment form allows you to track the payment you do to your suppliers specially by check. When you select a supplier, the payment method and an amount for the payment, OpenERP will propose to reconcile your payment with the open supplier invoices or bills.You can print the check + + + + + form + + + + + + + tree + + + + + + diff --git a/addons/account_check_writing/report/__init__.py b/addons/account_check_writing/report/__init__.py new file mode 100644 index 00000000000..e160380caea --- /dev/null +++ b/addons/account_check_writing/report/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +import check_print + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: + diff --git a/addons/account_check_writing/report/check_print.py b/addons/account_check_writing/report/check_print.py new file mode 100644 index 00000000000..e0460964be5 --- /dev/null +++ b/addons/account_check_writing/report/check_print.py @@ -0,0 +1,108 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +import time +from report import report_sxw +from tools import amount_to_text_en + +class report_print_check(report_sxw.rml_parse): + def __init__(self, cr, uid, name, context): + super(report_print_check, self).__init__(cr, uid, name, context) + self.number_lines = 0 + self.number_add = 0 + self.localcontext.update({ + 'time': time, + 'get_lines': self.get_lines, + 'fill_stars' : self.fill_stars, + 'get_zip_line': self.get_zip_line, + }) + def fill_stars(self, amount): + amount = amount.replace('Dollars','') + if len(amount) < 100: #TODO + stars = 100 - len(amount) + return ' '.join([amount,'*'*stars]) + + else: return amount + + def get_zip_line(self, address): + ''' + Get the address line + ''' + ret = '' + if address: + if address.city: + ret += address.city + if address.state_id: + if address.state_id.name: + if ret: + ret += ', ' + ret += address.state_id.name + if address.zip: + if ret: + ret += ' ' + ret += address.zip + return ret + + def get_lines(self, voucher_lines): + result = [] + self.number_lines = len(voucher_lines) + print "==============",voucher_lines + for i in range(0, min(10,self.number_lines)): + if i < self.number_lines: + res = { + 'date_due' : voucher_lines[i].date_due, + 'name' : voucher_lines[i].name, + 'amount_original' : voucher_lines[i].amount_original and voucher_lines[i].amount_original or False, + 'amount_unreconciled' : voucher_lines[i].amount_unreconciled and voucher_lines[i].amount_unreconciled or False, + 'amount' : voucher_lines[i].amount and voucher_lines[i].amount or False, + } + else : + res = { + 'date_due' : False, + 'name' : False, + 'amount_original' : False, + 'amount_due' : False, + 'amount' : False, + } + result.append(res) + return result + +report_sxw.report_sxw( + 'report.account.print.check.top', + 'account.voucher', + 'addons/account_check_writing/report/check_print_top.rml', + parser=report_print_check,header=False +) + +report_sxw.report_sxw( + 'report.account.print.check.middle', + 'account.voucher', + 'addons/account_check_writing/report/check_print_middle.rml', + parser=report_print_check,header=False +) + +report_sxw.report_sxw( + 'report.account.print.check.bottom', + 'account.voucher', + 'addons/account_check_writing/report/check_print_bottom.rml', + parser=report_print_check,header=False +) +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_check_writing/report/check_print_bottom.rml b/addons/account_check_writing/report/check_print_bottom.rml new file mode 100644 index 00000000000..231edb65547 --- /dev/null +++ b/addons/account_check_writing/report/check_print_bottom.rml @@ -0,0 +1,321 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [[repeatIn(objects,'voucher')]] + + + + + + + [[voucher.partner_id.name]] + + + [[ formatLang(voucher.date , date=True) or '' ]] [[ voucher.journal_id.use_preprint_check and voucher.chk_seq or '' ]] + + + + + + + Due Date + + + Description + + + Original Amount + + + Balance Due + + + Discount + + + Payment + + + + + [[ repeatIn(get_lines(voucher.line_dr_ids),'l') ]] [[ formatLang(l['date_original'] ,date=True) or '' ]] + + + [[ l['name'] ]] + + + [[formatLang( l['amount_original']) ]] + + + [[ formatLang( l['amount_due']) ]] + + + + + + + + [[ formatLang (l['amount']) ]] + + + + + + + Check Amount + + + [[ formatLang (voucher.amount) ]] + + + + + + + + + + + + + + + + [[voucher.partner_id.name]] + + + [[ formatLang(voucher.date , date=True) or '' ]] [[ voucher.journal_id.use_preprint_check and voucher.chk_seq or '' ]] + + + + + + + Due Date + + + Description + + + Original Amount + + + Balance Due + + + Discount + + + Payment + + + + + [[ repeatIn(get_lines(voucher.line_dr_ids),'l') ]] [[ formatLang(l['date_original'] ,date=True) or '' ]] + + + [[ l['name'] ]] + + + [[ formatLang (l['amount_original']) ]] + + + [[ formatLang (l['amount_due']) ]] + + + + + + + + [[ formatLang (l['amount']) ]] + + + + + + + Check Amount + + + [[ formatLang (voucher.amount) ]] + + + + + + + + + + + + + + + + + + + + + + + + [[ voucher.journal_id.use_preprint_check and voucher.chk_seq or '' ]] + + + + + + + + [[ formatLang(voucher.date , date=True) or '' ]] + + + [[ formatLang (voucher.amount) ]] + + + + + + + + + + + + [[ voucher.partner_id.name ]] + [[ voucher.partner_id.address and voucher.partner_id.address[0] and voucher.partner_id.address[0].street or removeParentNode('para') ]] + [[ voucher.partner_id.address and voucher.partner_id.address[0] and voucher.partner_id.address[0].street2 or removeParentNode('para') ]] + [[ get_zip_line(voucher.partner_id.address) ]] + [[ voucher.partner_id.address[0].country_id.name]] + + + + + + + [[ fill_stars(voucher.amount_in_word) ]] + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/account_check_writing/report/check_print_middle.rml b/addons/account_check_writing/report/check_print_middle.rml new file mode 100644 index 00000000000..a6416f9aeb2 --- /dev/null +++ b/addons/account_check_writing/report/check_print_middle.rml @@ -0,0 +1,359 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [[repeatIn(objects,'voucher')]] + + + + + + + + + + [[ voucher.journal_id.use_preprint_check and voucher.chk_seq or '' ]] + + + + + [[voucher.partner_id.name]] + + + [[ formatLang(voucher.date , date=True) or '' ]] + + + + + + + Due Date + + + Description + + + Original Amount + + + Balance Due + + + Discount + + + Payment + + + + + [[ repeatIn(get_lines(voucher.line_dr_ids),'l') ]] [[ formatLang(l['date_original'] ,date=True) or '' ]] + + + [[ l['name'] ]] + + + [[formatLang( l['amount_original']) ]] + + + [[ formatLang( l['amount_due']) ]] + + + + + + + + [[ formatLang (l['amount']) ]] + + + + + + + Check Amount + + + [[ formatLang (voucher.amount) ]] + + + + + + + + + + + + + + + [[ voucher.journal_id.use_preprint_check and voucher.chk_seq or '' ]] + + + + + + + + + + + + + [[ str(fill_stars(voucher.amount_in_word)) ]] + + + + + + + + + + + + + + + + + + + + + + + + [[ formatLang(voucher.date , date=True) or '' ]] + + + [[ formatLang (voucher.amount) ]] + + + + + + + + + + + + [[ voucher.partner_id.name ]] + [[ voucher.partner_id.address and voucher.partner_id.address[0] and voucher.partner_id.address[0].street or removeParentNode('para') ]] + [[ voucher.partner_id.address and voucher.partner_id.address[0] and voucher.partner_id.address[0].street2 or removeParentNode('para') ]] + [[ get_zip_line(voucher.partner_id.address) ]] + [[ voucher.partner_id.address[0].country_id.name]] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [[voucher.partner_id.name]] + + + [[ formatLang(voucher.date , date=True) or '' ]] + + + [[ voucher.journal_id.use_preprint_check and voucher.chk_seq or '' ]] + + + + + + + Due Date + + + Description + + + Original Amount + + + Balance Due + + + Discount + + + Payment + + + + + [[ repeatIn(get_lines(voucher.line_dr_ids),'l') ]] [[ formatLang(l['date_original'] ,date=True) or '' ]] + + + [[ l['name'] ]] + + + [[ formatLang (l['amount_original']) ]] + + + [[ formatLang (l['amount_due']) ]] + + + + + + + + [[ formatLang (l['amount']) ]] + + + + + + + Check Amount + + + [[ formatLang (voucher.amount) ]] + + + + + + + + + + + + + + diff --git a/addons/account_check_writing/report/check_print_top.rml b/addons/account_check_writing/report/check_print_top.rml new file mode 100644 index 00000000000..a5068617ebe --- /dev/null +++ b/addons/account_check_writing/report/check_print_top.rml @@ -0,0 +1,338 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [[repeatIn(objects,'voucher')]] + + + + + + + + + + + + + + + + + + + + + + + + [[ formatLang(voucher.date , date=True) or '' ]] [[ voucher.journal_id.use_preprint_check and voucher.chk_seq or '' ]] + + + + + + + + + + + + [[ voucher.partner_id.name ]] + + + [[ formatLang (voucher.amount) ]] + + + + + + + [[ fill_stars(voucher.amount_in_word) ]] + + + + + + + + + + [[ voucher.partner_id.name ]] + [[ voucher.partner_id.address and voucher.partner_id.address[0] and voucher.partner_id.address[0].street2 or removeParentNode('para') ]] + [[ get_zip_line(voucher.partner_id.address[0]) ]] + [[ voucher.partner_id.address[0].country_id.name]] + + + + + + + + + + + + + + + [[ voucher.name ]] + + + + + + + + + + + + + + + + + + + + + [[voucher.partner_id.name]] + + + [[ formatLang(voucher.date , date=True) or '' ]] [[ voucher.journal_id.use_preprint_check and voucher.chk_seq or '' ]] + + + + + + + Due Date + + + Description + + + Original Amount + + + Open Balance + + + Discount + + + Payment + + + + + [[ repeatIn(get_lines(voucher.line_dr_ids),'l') ]] [[ formatLang(l['date_due'] ,date=True) or '' ]] + + + [[ l['name'] ]] + + + [[formatLang( l['amount_original']) ]] + + + [[ formatLang( l['amount_unreconciled']) ]] + + + + + + + + [[ formatLang (l['amount']) ]] + + + + + + + Check Amount + + + [[ formatLang (voucher.amount) ]] + + + + + + + + + + + + + + + + [[voucher.partner_id.name]] + + + [[ formatLang(voucher.date , date=True) or '' ]] [[ voucher.journal_id.use_preprint_check and voucher.chk_seq or '' ]] + + + + + + + Due Date + + + Description + + + Original Amount + + + Open Balance + + + Discount + + + Payment + + + + + [[ repeatIn(get_lines(voucher.line_dr_ids),'l') ]] [[ formatLang(l['date_due'] ,date=True) or '' ]] + + + [[ l['name'] ]] + + + [[ formatLang (l['amount_original']) ]] + + + [[ formatLang (l['amount_unreconciled']) ]] + + + + + + + + [[ formatLang (l['amount']) ]] + + + + + + + Check Amount + + + [[ formatLang (voucher.amount) ]] + + + + + + + + + + + + + + From dde556db2e2cf78426d59c468da7950e5b2f8d21 Mon Sep 17 00:00:00 2001 From: "Divyesh Makwana (Open ERP)" Date: Mon, 14 Nov 2011 17:58:23 +0530 Subject: [PATCH 002/248] [FIX] hr_attendance : timesheet - sign in - out : must not allow overlaps bzr revid: mdi@tinyerp.com-20111114122823-7ehd1axt0l0b2euz --- addons/hr_attendance/hr_attendance.py | 28 ++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/addons/hr_attendance/hr_attendance.py b/addons/hr_attendance/hr_attendance.py index a138d66a285..31061459426 100644 --- a/addons/hr_attendance/hr_attendance.py +++ b/addons/hr_attendance/hr_attendance.py @@ -64,19 +64,21 @@ class hr_attendance(osv.osv): } def _altern_si_so(self, cr, uid, ids, context=None): - for id in ids: - sql = ''' - SELECT action, name - FROM hr_attendance AS att - WHERE employee_id = (SELECT employee_id FROM hr_attendance WHERE id=%s) - AND action IN ('sign_in','sign_out') - AND name <= (SELECT name FROM hr_attendance WHERE id=%s) - ORDER BY name DESC - LIMIT 2 ''' - cr.execute(sql,(id,id)) - atts = cr.fetchall() - if not ((len(atts)==1 and atts[0][0] == 'sign_in') or (len(atts)==2 and atts[0][0] != atts[1][0] and atts[0][1] != atts[1][1])): - return False + current_attendance_data = self.browse(cr, uid, ids, context=context)[0] + obj_attendance_ids = self.search(cr, uid, [('employee_id', '=', current_attendance_data.employee_id.id)], context=context) + obj_attendance_ids.remove(ids[0]) + hr_attendance_data = self.browse(cr, uid, obj_attendance_ids, context=context) + + for old_attendance in hr_attendance_data: + if old_attendance.employee_id.id == current_attendance_data['employee_id'].id: + if old_attendance.action == current_attendance_data['action']: + return False + elif old_attendance.name >= current_attendance_data['name']: + return False + else: + return True + if current_attendance_data['action'] == 'sign_out': + return False return True _constraints = [(_altern_si_so, 'Error: Sign in (resp. Sign out) must follow Sign out (resp. Sign in)', ['action'])] From 8cfb45d5504376a9ade6e486af0375140a7d91c8 Mon Sep 17 00:00:00 2001 From: "Kirti Savalia (OpenERP)" Date: Wed, 30 Nov 2011 16:13:34 +0530 Subject: [PATCH 003/248] [ADD]:demo data for the product with account information bzr revid: ksa@tinyerp.com-20111130104334-h7zjiuvq922n43nq --- addons/purchase/purchase_demo.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/addons/purchase/purchase_demo.xml b/addons/purchase/purchase_demo.xml index 6999f85b076..406e8d89abc 100644 --- a/addons/purchase/purchase_demo.xml +++ b/addons/purchase/purchase_demo.xml @@ -14,6 +14,13 @@ + + + + + + + From 8029e57b00f9a2fddfec3f9034dc36e1930fbc6b Mon Sep 17 00:00:00 2001 From: "Kirti Savalia (OpenERP)" Date: Wed, 30 Nov 2011 16:16:18 +0530 Subject: [PATCH 004/248] [ADD]:yml for stock real time accounting valuation bzr revid: ksa@tinyerp.com-20111130104618-r3p550bnov9wjjhf --- addons/purchase/__openerp__.py | 1 + .../test/process/real_time_valuation.yml | 42 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 addons/purchase/test/process/real_time_valuation.yml diff --git a/addons/purchase/__openerp__.py b/addons/purchase/__openerp__.py index b4f3a9adf30..68e490d23f1 100644 --- a/addons/purchase/__openerp__.py +++ b/addons/purchase/__openerp__.py @@ -67,6 +67,7 @@ Dashboard for purchase management that includes: 'test/process/run_scheduler.yml', 'test/process/merge_order.yml', 'test/process/edi_purchase_order.yml', + 'test/process/real_time_valuation.yml', 'test/ui/print_report.yml', 'test/ui/duplicate_order.yml', 'test/ui/delete_order.yml', diff --git a/addons/purchase/test/process/real_time_valuation.yml b/addons/purchase/test/process/real_time_valuation.yml new file mode 100644 index 00000000000..d1b4cb267f1 --- /dev/null +++ b/addons/purchase/test/process/real_time_valuation.yml @@ -0,0 +1,42 @@ +- + In order to test real time stock valuation flow,I start by creating a new product 'Sugar' +- + !record {model: product.product, id: product_sugar_id_50kg}: + name: Sugar + procure_method: make_to_stock + supply_method: buy + cost_method: standard + standard_price: 3600.0 + uom_id: product.product_uom_kgm + uom_po_id: product.product_uom_gram + valuation: real_time + categ_id: product.product_category_rawmaterial0 +- + I create a draft Purchase Order +- + !record {model: purchase.order, id: purchase_order_sugar}: + partner_id: base.res_partner_agrolait + partner_address_id: base.res_partner_address_8invoice + pricelist_id: 1 + order_line: + - product_id: product_sugar_id_50kg + product_qty: 1.0 + product_uom: product.product_uom_gram + price_unit: 3600000 + name: 'Sugar' + date_planned: '2011-08-31' +- + I confirm the purchase order +- + !workflow {model: purchase.order, ref: purchase_order_sugar, action: purchase_confirm} +- + I check that the invoice of order and values. +- + !python {model: purchase.order}: | + purchase_order = self.browse(cr, uid, ref("purchase_order_sugar")) + for purchase_line in purchase_order.order_line: + assert purchase_line.price_unit == 3600000.0 + assert len(purchase_order.invoice_ids) == 1, "Invoice should be generated." + for invoice_line in purchase_order.invoice_ids: + for data in invoice_line.invoice_line: + assert data.price_unit == 3600000.0, "unit price is not same, got %s, expected 3600000.0"%(purchase_line.price_unit,) From 296622e5f755ed7bab5f44a7825e80bbe6c9ed0d Mon Sep 17 00:00:00 2001 From: "Kirti Savalia (OpenERP)" Date: Mon, 5 Dec 2011 16:13:22 +0530 Subject: [PATCH 005/248] [ADD]: demo data for different uom bzr revid: ksa@tinyerp.com-20111205104322-f63d4ujlt64kl0p1 --- addons/product/product_demo.xml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/addons/product/product_demo.xml b/addons/product/product_demo.xml index 3aebec13715..a95b41e546c 100644 --- a/addons/product/product_demo.xml +++ b/addons/product/product_demo.xml @@ -636,6 +636,20 @@ + + SUGAR50KG + buy + + 110.0 + 3600.0 + + + SUGAR of 50KG + + product + + + @@ -777,6 +791,15 @@ 5 + + + 10 + 1 + 5 + + 5 + + From 8af8d336375d6f0ddc4e278b9bfddb695713cccd Mon Sep 17 00:00:00 2001 From: "Kirti Savalia (OpenERP)" Date: Mon, 5 Dec 2011 16:14:59 +0530 Subject: [PATCH 006/248] [IMP]:code for product onchange when uom is different bzr revid: ksa@tinyerp.com-20111205104459-p2hnekd0tazuia2n --- addons/purchase/purchase.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index 0dc015834a0..cea5aeeef4f 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -727,10 +727,12 @@ class purchase_order_line(osv.osv): # - name of method should "onchange_product_id" # - docstring # - merge 'product_uom_change' method - # - split into small internal methods for clearity + # - split into small internal methods for clearity def product_id_change(self, cr, uid, ids, pricelist, product, qty, uom, partner_id, date_order=False, fiscal_position=False, date_planned=False, - name=False, price_unit=False, notes=False, context={}): + name=False, price_unit=False, notes=False, context=None): + if context is None: + context = {} if not pricelist: raise osv.except_osv(_('No Pricelist !'), _('You have to select a pricelist or a supplier in the purchase form !\nPlease set one before choosing a product.')) if not partner_id: @@ -744,11 +746,14 @@ class purchase_order_line(osv.osv): lang=False if partner_id: lang=self.pool.get('res.partner').read(cr, uid, partner_id, ['lang'])['lang'] - context={'lang':lang} + context['lang'] = lang context['partner_id'] = partner_id prod = self.pool.get('product.product').browse(cr, uid, product, context=context) prod_uom_po = prod.uom_po_id.id + + if uom and prod and (uom <> prod_uom_po): + uom = prod_uom_po if not uom: uom = prod_uom_po if not date_order: @@ -773,6 +778,7 @@ class purchase_order_line(osv.osv): if qty < temp_qty: # If the supplier quantity is greater than entered from user, set minimal. qty = temp_qty res.update({'warning': {'title': _('Warning'), 'message': _('The selected supplier has a minimal quantity set to %s, you should not purchase less.') % qty}}) + uom = context.get('uom_change', uom) qty_in_product_uom = product_uom_pool._compute_qty(cr, uid, uom, qty, to_uom_id=prod.uom_id.id) price = self.pool.get('product.pricelist').price_get(cr,uid,[pricelist], product, qty_in_product_uom or 1.0, partner_id, { @@ -786,7 +792,7 @@ class purchase_order_line(osv.osv): 'taxes_id':map(lambda x: x.id, prod.supplier_taxes_id), 'date_planned': date_planned or dt,'notes': notes or prod.description_purchase, 'product_qty': qty, - 'product_uom': prod.uom_id.id}}) + 'product_uom': uom or prod_uom_po}}) domain = {} taxes = self.pool.get('account.tax').browse(cr, uid,map(lambda x: x.id, prod.supplier_taxes_id)) @@ -808,7 +814,7 @@ class purchase_order_line(osv.osv): name=False, price_unit=False, notes=False, context={}): res = self.product_id_change(cr, uid, ids, pricelist, product, qty, uom, partner_id, date_order=date_order, fiscal_position=fiscal_position, date_planned=date_planned, - name=name, price_unit=price_unit, notes=notes, context=context) + name=name, price_unit=price_unit, notes=notes, context={'uom_change': uom}) if 'product_uom' in res['value']: if uom and (uom != res['value']['product_uom']) and res['value']['product_uom']: seller_uom_name = self.pool.get('product.uom').read(cr, uid, [res['value']['product_uom']], ['name'])[0]['name'] From 6709a80bbcb8f7f2fe3dccd528cd7743c54182d9 Mon Sep 17 00:00:00 2001 From: "Kirti Savalia (OpenERP)" Date: Mon, 5 Dec 2011 16:15:41 +0530 Subject: [PATCH 007/248] [IMP]:yml for real time valuation value bzr revid: ksa@tinyerp.com-20111205104541-suka3mhly9ry8xdc --- addons/purchase/purchase_order_demo.yml | 5 +++ .../test/process/real_time_valuation.yml | 42 ++----------------- 2 files changed, 9 insertions(+), 38 deletions(-) diff --git a/addons/purchase/purchase_order_demo.yml b/addons/purchase/purchase_order_demo.yml index abfaa102033..8cd9271de45 100644 --- a/addons/purchase/purchase_order_demo.yml +++ b/addons/purchase/purchase_order_demo.yml @@ -74,3 +74,8 @@ - product_id: product.product_product_1 product_qty: 15 +- + !record {model: purchase.order, id: order_purchase8}: + partner_id: base.res_partner_asus + order_line: + - product_id: product.product_sugar_id_50kg diff --git a/addons/purchase/test/process/real_time_valuation.yml b/addons/purchase/test/process/real_time_valuation.yml index d1b4cb267f1..69b04071f40 100644 --- a/addons/purchase/test/process/real_time_valuation.yml +++ b/addons/purchase/test/process/real_time_valuation.yml @@ -1,42 +1,8 @@ - - In order to test real time stock valuation flow,I start by creating a new product 'Sugar' -- - !record {model: product.product, id: product_sugar_id_50kg}: - name: Sugar - procure_method: make_to_stock - supply_method: buy - cost_method: standard - standard_price: 3600.0 - uom_id: product.product_uom_kgm - uom_po_id: product.product_uom_gram - valuation: real_time - categ_id: product.product_category_rawmaterial0 -- - I create a draft Purchase Order -- - !record {model: purchase.order, id: purchase_order_sugar}: - partner_id: base.res_partner_agrolait - partner_address_id: base.res_partner_address_8invoice - pricelist_id: 1 - order_line: - - product_id: product_sugar_id_50kg - product_qty: 1.0 - product_uom: product.product_uom_gram - price_unit: 3600000 - name: 'Sugar' - date_planned: '2011-08-31' -- - I confirm the purchase order -- - !workflow {model: purchase.order, ref: purchase_order_sugar, action: purchase_confirm} -- - I check that the invoice of order and values. + In order to test real time stock valuation flow, when default UoM and purchase UoM is different - !python {model: purchase.order}: | - purchase_order = self.browse(cr, uid, ref("purchase_order_sugar")) + purchase_order = self.browse(cr, uid, ref("order_purchase8")) + assert len(purchase_order.order_line) == 1, "orderline should be generated." for purchase_line in purchase_order.order_line: - assert purchase_line.price_unit == 3600000.0 - assert len(purchase_order.invoice_ids) == 1, "Invoice should be generated." - for invoice_line in purchase_order.invoice_ids: - for data in invoice_line.invoice_line: - assert data.price_unit == 3600000.0, "unit price is not same, got %s, expected 3600000.0"%(purchase_line.price_unit,) + assert purchase_line.price_unit == 3.6 ,"unit price is not same, got %s, expected 3.6"%(purchase_line.price_unit,) \ No newline at end of file From 31f3f8651031f4c4de3c16f6e90bf4d1f6619600 Mon Sep 17 00:00:00 2001 From: "Kirti Savalia (OpenERP)" Date: Thu, 8 Dec 2011 15:25:59 +0530 Subject: [PATCH 008/248] [IMP]:check the flow when default UoM and purchase UoM is different bzr revid: ksa@tinyerp.com-20111208095559-9qt47pftmtr55yh1 --- addons/product/product_demo.xml | 23 ----------- addons/purchase/purchase_demo.xml | 7 ---- addons/purchase/purchase_order_demo.yml | 19 ++++++++- .../test/process/real_time_valuation.yml | 39 ++++++++++++++++--- 4 files changed, 51 insertions(+), 37 deletions(-) diff --git a/addons/product/product_demo.xml b/addons/product/product_demo.xml index a95b41e546c..3aebec13715 100644 --- a/addons/product/product_demo.xml +++ b/addons/product/product_demo.xml @@ -636,20 +636,6 @@ - - SUGAR50KG - buy - - 110.0 - 3600.0 - - - SUGAR of 50KG - - product - - - @@ -791,15 +777,6 @@ 5 - - - 10 - 1 - 5 - - 5 - - diff --git a/addons/purchase/purchase_demo.xml b/addons/purchase/purchase_demo.xml index 406e8d89abc..6999f85b076 100644 --- a/addons/purchase/purchase_demo.xml +++ b/addons/purchase/purchase_demo.xml @@ -14,13 +14,6 @@ - - - - - - - diff --git a/addons/purchase/purchase_order_demo.yml b/addons/purchase/purchase_order_demo.yml index 8cd9271de45..0ea29b2a242 100644 --- a/addons/purchase/purchase_order_demo.yml +++ b/addons/purchase/purchase_order_demo.yml @@ -75,7 +75,22 @@ product_qty: 15 - - !record {model: purchase.order, id: order_purchase8}: + !record {model: product.product, id: product_sugar_id_50kg}: + default_code: SUGAR50KG + supply_method: buy + list_price: 110.0 + standard_price: 3600.0 + uom_id: product.product_uom_kgm + uom_po_id: product.product_uom_gram + name: SUGAR of 50KG + valuation: real_time + property_stock_account_input: account.o_expense + property_stock_account_output: account.o_income + categ_id: product.product_category_rawmaterial0 + +- + !record {model: purchase.order, id: order_purchase_sugar}: partner_id: base.res_partner_asus order_line: - - product_id: product.product_sugar_id_50kg + - product_id: product_sugar_id_50kg + diff --git a/addons/purchase/test/process/real_time_valuation.yml b/addons/purchase/test/process/real_time_valuation.yml index 69b04071f40..f0234888ba6 100644 --- a/addons/purchase/test/process/real_time_valuation.yml +++ b/addons/purchase/test/process/real_time_valuation.yml @@ -1,8 +1,37 @@ - - In order to test real time stock valuation flow, when default UoM and purchase UoM is different + In order to test real time stock valuation flow, I confirmed the purchase order. +- + !workflow {model: purchase.order, action: purchase_confirm, ref: order_purchase_sugar} +- + I check that the order which was initially in the draft state has transmit to approved state. +- + !assert {model: purchase.order, id: order_purchase_sugar}: + - state == 'approved' +- + In order to test check that picking is generated or not. - !python {model: purchase.order}: | - purchase_order = self.browse(cr, uid, ref("order_purchase8")) - assert len(purchase_order.order_line) == 1, "orderline should be generated." - for purchase_line in purchase_order.order_line: - assert purchase_line.price_unit == 3.6 ,"unit price is not same, got %s, expected 3.6"%(purchase_line.price_unit,) \ No newline at end of file + purchase_order = self.browse(cr, uid, ref("order_purchase_sugar")) + assert len(purchase_order.picking_ids) >= 1, "You should have only one reception order" + for picking in purchase_order.picking_ids: + assert picking.purchase_id.id == purchase_order.id +- + Reception is ready for process so now done the reception. +- + !python {model: stock.partial.picking}: | + pick_ids = self.pool.get('purchase.order').browse(cr, uid, ref("order_purchase_sugar")).picking_ids + partial_id = self.create(cr, uid, {},context={'active_model': 'stock.picking','active_ids': [pick_ids[0].id]}) + self.do_partial(cr, uid, [partial_id]) +- + Check the Journal having proper amount or not. +- + !python {model: account.move.line}: | + pick_ids = self.pool.get('purchase.order').browse(cr, uid, ref("order_purchase_sugar")).picking_ids + for data in pick_ids: + for moveline in data.move_lines: + ids = self.pool.get('account.move.line').search(cr, uid, [('ref','=',data.name),('partner_id','=',data.partner_id.id)]) + item_data = self.pool.get('account.move.line').browse(cr, uid, ids) + for item in item_data: + if item.account_id.id == moveline.product_id.property_stock_account_input.id: + assert item.credit == 3.6, "Journal items have not proper credit amount" + assert item.debit == 0.0, "Journal items have not proper debit amount" From 573227209615c0f30bb5b9d2efd28dd2ea36ed8d Mon Sep 17 00:00:00 2001 From: "Divyesh Makwana (Open ERP)" Date: Tue, 20 Dec 2011 15:15:52 +0530 Subject: [PATCH 009/248] [FIX] hr_attendance : timesheet - sign in - out : must not allow overlaps lp bug: https://launchpad.net/bugs/885387 fixed bzr revid: mdi@tinyerp.com-20111220094552-jfwpgzy7f0lmig44 --- addons/hr_attendance/hr_attendance.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/addons/hr_attendance/hr_attendance.py b/addons/hr_attendance/hr_attendance.py index 31061459426..9987beae248 100644 --- a/addons/hr_attendance/hr_attendance.py +++ b/addons/hr_attendance/hr_attendance.py @@ -63,6 +63,14 @@ class hr_attendance(osv.osv): 'employee_id': _employee_get, } + def write(self, cr, uid, ids, vals, context=None): + current_attendance_data = self.browse(cr, uid, ids, context=context)[0] + obj_attendance_ids = self.search(cr, uid, [('employee_id', '=', current_attendance_data.employee_id.id)], context=context) + if obj_attendance_ids[0] != ids[0]: + if ('name' in vals) or ('action' in vals): + raise osv.except_osv(_('Warning !'), _('You can not modify existing entries. To modify the entry , remove the prior entries.')) + return super(hr_attendance, self).write(cr, uid, ids, vals, context=context) + def _altern_si_so(self, cr, uid, ids, context=None): current_attendance_data = self.browse(cr, uid, ids, context=context)[0] obj_attendance_ids = self.search(cr, uid, [('employee_id', '=', current_attendance_data.employee_id.id)], context=context) @@ -70,13 +78,13 @@ class hr_attendance(osv.osv): hr_attendance_data = self.browse(cr, uid, obj_attendance_ids, context=context) for old_attendance in hr_attendance_data: - if old_attendance.employee_id.id == current_attendance_data['employee_id'].id: - if old_attendance.action == current_attendance_data['action']: - return False - elif old_attendance.name >= current_attendance_data['name']: - return False - else: - return True + if old_attendance.action == current_attendance_data['action']: + return False + elif old_attendance.name >= current_attendance_data['name']: + return False + else: + return True + # First entry in the system must not be 'sign_out' if current_attendance_data['action'] == 'sign_out': return False return True From 8394afcf8a8b87cd450e259753a117416a56c3d8 Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Thu, 5 Jan 2012 17:06:35 +0100 Subject: [PATCH 010/248] Extend the function action_invoice_create() so that the dict of the invoice is generated inside a dedicated function. We can now inherit this function in custom modules to add/modify values easily. bzr revid: alexis@via.ecp.fr-20120105160635-ac6drtj2ei363r8l --- addons/stock/stock.py | 87 ++++++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 39 deletions(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index cd9242c6b1f..ce344804347 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -968,6 +968,49 @@ class stock_picking(osv.osv): inv_type = 'out_invoice' return inv_type + def _prepare_invoice_group(self, cr, uid, picking, partner, invoice, context=None): + """Builds the dict for grouped invoices""" + comment = self._get_comment_invoice(cr, uid, picking) + + return { + 'name': (invoice.name or '') + ', ' + (picking.name or ''), + 'origin': (invoice.origin or '') + ', ' + (picking.name or '') + (picking.origin and (':' + picking.origin) or ''), + 'comment': (comment and (invoice.comment and invoice.comment + "\n" + comment or comment)) or (invoice.comment and invoice.comment or ''), + 'date_invoice': context.get('date_inv', False), + 'user_id': uid + } + + def _prepare_invoice(self, cr, uid, picking, partner, inv_type, journal_id, context=None): + """Builds the dict containing the values for the invoice""" + if inv_type in ('out_invoice', 'out_refund'): + account_id = partner.property_account_receivable.id + else: + account_id = partner.property_account_payable.id + address_contact_id, address_invoice_id = \ + self._get_address_invoice(cr, uid, picking).values() + comment = self._get_comment_invoice(cr, uid, picking) + invoice_vals = { + 'name': picking.name, + 'origin': (picking.name or '') + (picking.origin and (':' + picking.origin) or ''), + 'type': inv_type, + 'account_id': account_id, + 'partner_id': partner.id, + 'address_invoice_id': address_invoice_id, + 'address_contact_id': address_contact_id, + 'comment': comment, + 'payment_term': self._get_payment_term(cr, uid, picking), + 'fiscal_position': partner.property_account_position.id, + 'date_invoice': context.get('date_inv', False), + 'company_id': picking.company_id.id, + 'user_id': uid + } + cur_id = self.get_currency_id(cr, uid, picking) + if cur_id: + invoice_vals['currency_id'] = cur_id + if journal_id: + invoice_vals['journal_id'] = journal_id + return invoice_vals + def action_invoice_create(self, cr, uid, ids, journal_id=False, group=False, type='out_invoice', context=None): """ Creates invoice based on the invoice state selected for picking. @@ -981,7 +1024,6 @@ class stock_picking(osv.osv): invoice_obj = self.pool.get('account.invoice') invoice_line_obj = self.pool.get('account.invoice.line') - address_obj = self.pool.get('res.partner.address') invoices_group = {} res = {} inv_type = type @@ -996,48 +1038,15 @@ class stock_picking(osv.osv): if not inv_type: inv_type = self._get_invoice_type(picking) - if inv_type in ('out_invoice', 'out_refund'): - account_id = partner.property_account_receivable.id - else: - account_id = partner.property_account_payable.id - address_contact_id, address_invoice_id = \ - self._get_address_invoice(cr, uid, picking).values() - address = address_obj.browse(cr, uid, address_contact_id, context=context) - - comment = self._get_comment_invoice(cr, uid, picking) if group and partner.id in invoices_group: invoice_id = invoices_group[partner.id] invoice = invoice_obj.browse(cr, uid, invoice_id) - invoice_vals = { - 'name': (invoice.name or '') + ', ' + (picking.name or ''), - 'origin': (invoice.origin or '') + ', ' + (picking.name or '') + (picking.origin and (':' + picking.origin) or ''), - 'comment': (comment and (invoice.comment and invoice.comment+"\n"+comment or comment)) or (invoice.comment and invoice.comment or ''), - 'date_invoice':context.get('date_inv',False), - 'user_id':uid - } - invoice_obj.write(cr, uid, [invoice_id], invoice_vals, context=context) + invoice_obj.write(cr, uid, [invoice_id], + self._prepare_invoice_group(cr, uid, picking, partner, invoice, context=context), + context=context) else: - invoice_vals = { - 'name': picking.name, - 'origin': (picking.name or '') + (picking.origin and (':' + picking.origin) or ''), - 'type': inv_type, - 'account_id': account_id, - 'partner_id': address.partner_id.id, - 'address_invoice_id': address_invoice_id, - 'address_contact_id': address_contact_id, - 'comment': comment, - 'payment_term': self._get_payment_term(cr, uid, picking), - 'fiscal_position': partner.property_account_position.id, - 'date_invoice': context.get('date_inv',False), - 'company_id': picking.company_id.id, - 'user_id':uid - } - cur_id = self.get_currency_id(cr, uid, picking) - if cur_id: - invoice_vals['currency_id'] = cur_id - if journal_id: - invoice_vals['journal_id'] = journal_id - invoice_id = invoice_obj.create(cr, uid, invoice_vals, + invoice_id = invoice_obj.create(cr, uid, + self._prepare_invoice(cr, uid, picking, partner, inv_type, journal_id, context=context), context=context) invoices_group[partner.id] = invoice_id res[picking.id] = invoice_id From 638ca9122e950b4b91f80748f4edf888dbbc07bd Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Thu, 5 Jan 2012 17:08:45 +0100 Subject: [PATCH 011/248] Modularize the selection of the partner to invoice when invoicing from the picking. With this modification, all the parameters of the invoice are correct even when the goods are delivered to a third party company i.e. when the partner who receives the goods (picking.address_id.partner_id) is not to partner who ordered the goods (picking.sale_id.partner_id). bzr revid: alexis@via.ecp.fr-20120105160845-c6wk08k7v7i64zyl --- addons/sale/stock.py | 7 ++++++- addons/stock/stock.py | 9 ++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/addons/sale/stock.py b/addons/sale/stock.py index 653b147d3d0..618867821fb 100644 --- a/addons/sale/stock.py +++ b/addons/sale/stock.py @@ -48,6 +48,11 @@ class stock_picking(osv.osv): else: return super(stock_picking, self).get_currency_id(cursor, user, picking) + def _get_partner_to_invoice(self, cr, uid, picking, context=None): + if picking.sale_id: + return picking.sale_id.partner_id + return super(stock_picking, self)._get_partner_to_invoice(cr, uid, picking, context=context) + def _get_payment_term(self, cursor, user, picking): if picking.sale_id and picking.sale_id.payment_term: return picking.sale_id.payment_term.id @@ -195,4 +200,4 @@ class stock_picking(osv.osv): }) return result -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/stock/stock.py b/addons/stock/stock.py index ce344804347..c1a334a4b6d 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -874,6 +874,13 @@ class stock_picking(osv.osv): def get_currency_id(self, cr, uid, picking): return False + def _get_partner_to_invoice(self, cr, uid, picking, context=None): + """ Gets the partner that will be invoiced + Note that this function is inherited in the sale module + @return: partner object + """ + return picking.address_id and picking.address_id.partner_id + def _get_payment_term(self, cr, uid, picking): """ Gets payment term from partner. @return: Payment term @@ -1030,7 +1037,7 @@ class stock_picking(osv.osv): for picking in self.browse(cr, uid, ids, context=context): if picking.invoice_state != '2binvoiced': continue - partner = picking.address_id and picking.address_id.partner_id + partner = self._get_partner_to_invoice(cr, uid, picking, context=context) if not partner: raise osv.except_osv(_('Error, no partner !'), _('Please put a partner on the picking list if you want to generate invoice.')) From 752186173fed4c2a3b71f4e504a0e8336cfb12a9 Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Thu, 5 Jan 2012 17:23:43 +0100 Subject: [PATCH 012/248] If the fiscal position has been changed on the sale order, the invoice should use the fiscal posion of the sale order and not the fiscal position of the partner. bzr revid: alexis@via.ecp.fr-20120105162343-tf8359d8hrk7r2j1 --- addons/sale/stock.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/addons/sale/stock.py b/addons/sale/stock.py index 618867821fb..30b9367cf4c 100644 --- a/addons/sale/stock.py +++ b/addons/sale/stock.py @@ -71,6 +71,12 @@ class stock_picking(osv.osv): return picking.note or picking.sale_id.note return super(stock_picking, self)._get_comment_invoice(cursor, user, picking) + def _prepare_invoice(self, cr, uid, picking, partner, inv_type, journal_id, context=None): + invoice_vals = super(stock_picking, self)._prepare_invoice(cr, uid, picking, partner, inv_type, journal_id, context=context) + if picking.sale_id and picking.sale_id.fiscal_position: + invoice_vals['fiscal_position'] = picking.sale_id.fiscal_position.id + return invoice_vals + def _get_price_unit_invoice(self, cursor, user, move_line, type): if move_line.sale_line_id and move_line.sale_line_id.product_id.id == move_line.product_id.id: uom_id = move_line.product_id.uom_id.id From 1f9401bf416cf7c3b7dc553bdff6e33ca986b9b5 Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Thu, 5 Jan 2012 22:42:30 +0100 Subject: [PATCH 013/248] Add _get_partner_to_invoice() to purchase module. Inheritance of _prepare_invoice() now replaces the functions _get_payment_term() and _get_address_invoice(). I have checked that these two functions are not used elsewere in the addons and extra-addons. bzr revid: alexis@via.ecp.fr-20120105214230-3wetu0v1foyeate3 --- addons/purchase/stock.py | 27 ++++++++++++++++----------- addons/sale/stock.py | 27 ++++++++++++--------------- addons/stock/stock.py | 22 ++++------------------ 3 files changed, 32 insertions(+), 44 deletions(-) diff --git a/addons/purchase/stock.py b/addons/purchase/stock.py index c212a171b21..ca84d88babd 100644 --- a/addons/purchase/stock.py +++ b/addons/purchase/stock.py @@ -58,18 +58,23 @@ class stock_picking(osv.osv): 'purchase_id': False, } - def _get_address_invoice(self, cr, uid, picking): - """ Gets invoice address of a partner - @return {'contact': address, 'invoice': address} for invoice - """ - res = super(stock_picking, self)._get_address_invoice(cr, uid, picking) + def _get_partner_to_invoice(self, cr, uid, picking, context=None): if picking.purchase_id: - partner_obj = self.pool.get('res.partner') - partner = picking.purchase_id.partner_id or picking.address_id.partner_id - data = partner_obj.address_get(cr, uid, [partner.id], - ['contact', 'invoice']) - res.update(data) - return res + return picking.purchase_id.partner_id + return super(stock_picking, self)._get_partner_to_invoice(cr, uid, picking, context=context) + + def _prepare_invoice(self, cr, uid, picking, partner, inv_type, journal_id, context=None): + """Inherit the original function of the 'stock' module in order to override some + values if the picking has been generated by a purchase order + """ + invoice_vals = super(stock_picking, self)._prepare_invoice(cr, uid, picking, partner, inv_type, journal_id, context=context) + if picking.purchase_id: + invoice_vals['address_contact_id'], invoice_vals['address_invoice_id'] = \ + self.pool.get('res.partner').address_get(cr, uid, [partner.id], + ['contact', 'invoice']).values() + if picking.purchase_id.fiscal_position: + invoice_vals['fiscal_position'] = picking.purchase_id.fiscal_position.id + return invoice_vals def get_currency_id(self, cursor, user, picking): if picking.purchase_id: diff --git a/addons/sale/stock.py b/addons/sale/stock.py index 30b9367cf4c..6daff3a83b0 100644 --- a/addons/sale/stock.py +++ b/addons/sale/stock.py @@ -53,28 +53,25 @@ class stock_picking(osv.osv): return picking.sale_id.partner_id return super(stock_picking, self)._get_partner_to_invoice(cr, uid, picking, context=context) - def _get_payment_term(self, cursor, user, picking): - if picking.sale_id and picking.sale_id.payment_term: - return picking.sale_id.payment_term.id - return super(stock_picking, self)._get_payment_term(cursor, user, picking) - - def _get_address_invoice(self, cursor, user, picking): - res = {} - if picking.sale_id: - res['contact'] = picking.sale_id.partner_order_id.id - res['invoice'] = picking.sale_id.partner_invoice_id.id - return res - return super(stock_picking, self)._get_address_invoice(cursor, user, picking) - def _get_comment_invoice(self, cursor, user, picking): if picking.note or (picking.sale_id and picking.sale_id.note): return picking.note or picking.sale_id.note return super(stock_picking, self)._get_comment_invoice(cursor, user, picking) def _prepare_invoice(self, cr, uid, picking, partner, inv_type, journal_id, context=None): + """Inherit the original function of the 'stock' module in order to override some + values if the picking has been generated by a sale order + """ invoice_vals = super(stock_picking, self)._prepare_invoice(cr, uid, picking, partner, inv_type, journal_id, context=context) - if picking.sale_id and picking.sale_id.fiscal_position: - invoice_vals['fiscal_position'] = picking.sale_id.fiscal_position.id + if picking.sale_id: + invoice_vals['address_contact_id'] = picking.sale_id.partner_order_id.id + invoice_vals['address_invoice_id'] = picking.sale_id.partner_invoice_id.id + if picking.sale_id.fiscal_position: + invoice_vals['fiscal_position'] = picking.sale_id.fiscal_position.id + if picking.sale_id.payment_term: + invoice_vals['payment_term'] = picking.sale_id.payment_term.id + if picking.sale_id.user_id: + invoice_vals['user_id'] = picking.sale_id.user_id.id return invoice_vals def _get_price_unit_invoice(self, cursor, user, move_line, type): diff --git a/addons/stock/stock.py b/addons/stock/stock.py index c1a334a4b6d..a1b06adedc6 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -881,22 +881,6 @@ class stock_picking(osv.osv): """ return picking.address_id and picking.address_id.partner_id - def _get_payment_term(self, cr, uid, picking): - """ Gets payment term from partner. - @return: Payment term - """ - partner = picking.address_id.partner_id - return partner.property_payment_term and partner.property_payment_term.id or False - - def _get_address_invoice(self, cr, uid, picking): - """ Gets invoice address of a partner - @return {'contact': address, 'invoice': address} for invoice - """ - partner_obj = self.pool.get('res.partner') - partner = picking.address_id.partner_id - return partner_obj.address_get(cr, uid, [partner.id], - ['contact', 'invoice']) - def _get_comment_invoice(self, cr, uid, picking): """ @return: comment string for invoice @@ -994,7 +978,8 @@ class stock_picking(osv.osv): else: account_id = partner.property_account_payable.id address_contact_id, address_invoice_id = \ - self._get_address_invoice(cr, uid, picking).values() + self.pool.get('res.partner').address_get(cr, uid, [partner.id], + ['contact', 'invoice']).values() comment = self._get_comment_invoice(cr, uid, picking) invoice_vals = { 'name': picking.name, @@ -1005,7 +990,8 @@ class stock_picking(osv.osv): 'address_invoice_id': address_invoice_id, 'address_contact_id': address_contact_id, 'comment': comment, - 'payment_term': self._get_payment_term(cr, uid, picking), + 'payment_term': partner.property_payment_term and partner.property_payment_term.id + or False, 'fiscal_position': partner.property_account_position.id, 'date_invoice': context.get('date_inv', False), 'company_id': picking.company_id.id, From 3d54f085653b6bbfcbd0154af90792ad9c6796a0 Mon Sep 17 00:00:00 2001 From: "Mayur Maheshwari (OpenERP)" Date: Fri, 6 Jan 2012 15:48:50 +0530 Subject: [PATCH 014/248] [IMP]delivery:add size 64 on name field bzr revid: mma@tinyerp.com-20120106101850-qubjt41c739ky7fu --- addons/delivery/delivery.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/delivery/delivery.py b/addons/delivery/delivery.py index e747e6871b3..dc28d1efb93 100644 --- a/addons/delivery/delivery.py +++ b/addons/delivery/delivery.py @@ -223,7 +223,7 @@ class delivery_grid_line(osv.osv): _name = "delivery.grid.line" _description = "Delivery Grid Line" _columns = { - 'name': fields.char('Name', size=32, required=True), + 'name': fields.char('Name', size=64, required=True), 'grid_id': fields.many2one('delivery.grid', 'Grid',required=True, ondelete='cascade'), 'type': fields.selection([('weight','Weight'),('volume','Volume'),\ ('wv','Weight * Volume'), ('price','Price')],\ From 85993fb85ff4a9697b70b4982f5df20acb1e0cf5 Mon Sep 17 00:00:00 2001 From: "Mayur Maheshwari (OpenERP)" Date: Wed, 11 Jan 2012 14:50:08 +0530 Subject: [PATCH 015/248] [IMP]auction: added a separator and changes in password field bzr revid: mma@tinyerp.com-20120111092008-hr7jxcos2ccvuy8d --- addons/auction/auction_view.xml | 6 ++++-- addons/auction/wizard/auction_lots_sms_send_view.xml | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/addons/auction/auction_view.xml b/addons/auction/auction_view.xml index abcf53490a5..d52b3a3b36b 100644 --- a/addons/auction/auction_view.xml +++ b/addons/auction/auction_view.xml @@ -307,13 +307,14 @@ - + + @@ -560,7 +561,8 @@ - + + diff --git a/addons/auction/wizard/auction_lots_sms_send_view.xml b/addons/auction/wizard/auction_lots_sms_send_view.xml index f0bf665a882..d7d0ab06e5c 100644 --- a/addons/auction/wizard/auction_lots_sms_send_view.xml +++ b/addons/auction/wizard/auction_lots_sms_send_view.xml @@ -11,7 +11,7 @@ - + From 45a9b89cf499d551589e381c656c5913388e5a38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20L=C3=B3pez=20L=C3=B3pez=20=28OpenERP=29?= Date: Wed, 11 Jan 2012 12:10:28 +0100 Subject: [PATCH 016/248] [IMP] content management configuration should be accesible by all content management group members bzr revid: rlo@openerp.com-20120111111028-y76miqurbaghbafo --- addons/document/security/document_security.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/addons/document/security/document_security.xml b/addons/document/security/document_security.xml index 74f3426fc50..9fba954aa0e 100644 --- a/addons/document/security/document_security.xml +++ b/addons/document/security/document_security.xml @@ -11,10 +11,6 @@ - - - - ['|','|',('group_ids','in',[g.id for g in user.groups_id]), ('user_id', '=', user.id), '&', ('user_id', '=', False), ('group_ids','=',False), '|','|', ('company_id','=',False), ('company_id','child_of',[user.company_id.id]),('company_id.child_ids','child_of',[user.company_id.id])] From 7438ed5e88f7153b216b5079ccc95b880b431489 Mon Sep 17 00:00:00 2001 From: "Mayur Maheshwari (OpenERP)" Date: Wed, 11 Jan 2012 17:18:37 +0530 Subject: [PATCH 017/248] [IMP]auction: remove a separator bzr revid: mma@tinyerp.com-20120111114837-joly8423b415k31o --- addons/auction/auction_view.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/auction/auction_view.xml b/addons/auction/auction_view.xml index d52b3a3b36b..995ffa78959 100644 --- a/addons/auction/auction_view.xml +++ b/addons/auction/auction_view.xml @@ -307,14 +307,13 @@ + - - From eb6c9087f2247b077e15662f01ca13f65a92f3bb Mon Sep 17 00:00:00 2001 From: "Mayur Maheshwari (OpenERP)" Date: Wed, 11 Jan 2012 17:31:22 +0530 Subject: [PATCH 018/248] [IMP]crm: added a email_from field in convert_opportunity method bzr revid: mma@tinyerp.com-20120111120122-8kneus873a5mhsl9 --- addons/crm/crm_phonecall.py | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/crm/crm_phonecall.py b/addons/crm/crm_phonecall.py index 4246fa43a98..8d9a47b15eb 100644 --- a/addons/crm/crm_phonecall.py +++ b/addons/crm/crm_phonecall.py @@ -251,6 +251,7 @@ class crm_phonecall(crm_base, osv.osv): 'priority': call.priority, 'type': 'opportunity', 'phone': call.partner_phone or False, + 'email_from': default_contact and default_contact.email, }) vals = { 'partner_id': partner_id, From 20ed63d59809061118cb32c3734c874b4ddc966d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 11 Jan 2012 14:01:21 +0100 Subject: [PATCH 019/248] [IMP] Refactored _altern_si_so code. Added limits to searches. Code now validates only new data, not all past data. Cleaned algorithm documentation. bzr revid: tde@openerp.com-20120111130121-8bcgnjt233nv0izj --- addons/hr_attendance/hr_attendance.py | 37 ++++++++++++--------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/addons/hr_attendance/hr_attendance.py b/addons/hr_attendance/hr_attendance.py index 9987beae248..80741510785 100644 --- a/addons/hr_attendance/hr_attendance.py +++ b/addons/hr_attendance/hr_attendance.py @@ -63,30 +63,25 @@ class hr_attendance(osv.osv): 'employee_id': _employee_get, } - def write(self, cr, uid, ids, vals, context=None): - current_attendance_data = self.browse(cr, uid, ids, context=context)[0] - obj_attendance_ids = self.search(cr, uid, [('employee_id', '=', current_attendance_data.employee_id.id)], context=context) - if obj_attendance_ids[0] != ids[0]: - if ('name' in vals) or ('action' in vals): - raise osv.except_osv(_('Warning !'), _('You can not modify existing entries. To modify the entry , remove the prior entries.')) - return super(hr_attendance, self).write(cr, uid, ids, vals, context=context) - def _altern_si_so(self, cr, uid, ids, context=None): - current_attendance_data = self.browse(cr, uid, ids, context=context)[0] - obj_attendance_ids = self.search(cr, uid, [('employee_id', '=', current_attendance_data.employee_id.id)], context=context) - obj_attendance_ids.remove(ids[0]) - hr_attendance_data = self.browse(cr, uid, obj_attendance_ids, context=context) - - for old_attendance in hr_attendance_data: - if old_attendance.action == current_attendance_data['action']: + """ Alternance sign_in/sign_out check + Previous (if exists) must be of opposite action + Next (if exists) must be of opposite action + """ + atts = self.browse(cr, uid, ids, context=context) + for att in atts: + # search and browse for first previous and first next records + prev_att_ids = self.search(cr, uid, [('employee_id', '=', att.employee_id.id), ('name', '<', att.name), ('action', 'in', ('sign_in', 'sign_out'))], limit=1, order='name DESC') + next_add_ids = self.search(cr, uid, [('employee_id', '=', att.employee_id.id), ('name', '>', att.name), ('action', 'in', ('sign_in', 'sign_out'))], limit=1, order='name ASC') + prev_atts = self.browse(cr, uid, prev_att_ids, context=context) if (len(prev_att_ids) != 0) else [] + next_atts = self.browse(cr, uid, next_add_ids, context=context) if (len(next_add_ids) != 0) else [] + # perform alternance check, return False if at least one condition is not satisfied + if len(prev_atts) != 0 and prev_atts[0].action == att.action: # previous exists and is same action return False - elif old_attendance.name >= current_attendance_data['name']: + if len(next_atts) != 0 and next_atts[0].action == att.action: # next exists and is same action + return False + if len(prev_atts) == 0 and len(next_atts) == 0 and att.action != 'sign_in': # first attendance must be sign_in return False - else: - return True - # First entry in the system must not be 'sign_out' - if current_attendance_data['action'] == 'sign_out': - return False return True _constraints = [(_altern_si_so, 'Error: Sign in (resp. Sign out) must follow Sign out (resp. Sign in)', ['action'])] From afd266bf6a544937ce26d4948c356fdac3a7f0b8 Mon Sep 17 00:00:00 2001 From: "Nimesh (Open ERP)" Date: Thu, 12 Jan 2012 11:46:36 +0530 Subject: [PATCH 020/248] [FIX]import_google: i have change the external_id_field in initialize. bzr revid: nco@tinyerp.com-20120112061636-xw78p1gog5til567 --- addons/import_google/wizard/import_google.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/import_google/wizard/import_google.py b/addons/import_google/wizard/import_google.py index 936a6d17649..cfeaa623f76 100644 --- a/addons/import_google/wizard/import_google.py +++ b/addons/import_google/wizard/import_google.py @@ -51,7 +51,7 @@ class google_import(import_framework): def initialize(self): google = self.obj.pool.get('google.login') - self.external_id_field = 'Id' + self.external_id_field = 'id' self.gd_client = google.google_login(self.context.get('user'), self.context.get('password'), self.context.get('instance')) From a4eb2a04b56483dacfe00e999cf396c299e96104 Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Thu, 12 Jan 2012 12:32:40 +0530 Subject: [PATCH 021/248] [REF] purchase: refactor product_id_change and rename with onchange_product_id bzr revid: hmo@tinyerp.com-20120112070240-zgsic6tjiy7j7g30 --- addons/purchase/purchase.py | 101 ++++++++++++++++++------------ addons/purchase/purchase_view.xml | 6 +- 2 files changed, 63 insertions(+), 44 deletions(-) diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index bb748d68329..f63b86f11f2 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -697,56 +697,74 @@ class purchase_order_line(osv.osv): default.update({'state':'draft', 'move_ids':[],'invoiced':0,'invoice_lines':[]}) return super(purchase_order_line, self).copy_data(cr, uid, id, default, context) - #TOFIX: - # - name of method should "onchange_product_id" - # - docstring - # - split into small internal methods for clearity - def product_id_change(self, cr, uid, ids, pricelist_id, product_id, qty, uom_id, + + def _onchange_check_partner_pricelist(self, pricelist_id, partner_id): + return True + + def onchange_product_uom(self, cr, uid, ids, pricelist_id, product_id, qty, uom_id, partner_id, date_order=False, fiscal_position_id=False, date_planned=False, name=False, price_unit=False, notes=False, context=None): + """ + onchange handler of product_uom. + """ + if not uom_id: + return {'value': {'price_unit': price_unit or 0.0, 'name': name or '', 'notes': notes or'', 'product_uom' : uom_id or False}} + return self.onchange_product_id(cr, uid, ids, pricelist_id, product_id, qty, uom_id, + partner_id, date_order=date_order, fiscal_position_id=fiscal_position_id, date_planned=date_planned, + name=name, price_unit=price_unit, notes=notes, context=context) + + def onchange_product_id(self, cr, uid, ids, pricelist_id, product_id, qty, uom_id, + partner_id, date_order=False, fiscal_position_id=False, date_planned=False, + name=False, price_unit=False, notes=False, context=None): + """ + onchange handler of product_id. + """ + res = {} if context is None: context = {} - - res = {'price_unit': price_unit or 0.0, 'name': name or '', 'notes': notes or'', 'product_uom' : uom_id or False} - uom_change = context.get('uom_change', False) + res_value = {'price_unit': price_unit or 0.0, 'name': name or '', 'notes': notes or'', 'product_uom' : uom_id or False} + if not product_id: + return {'value': res_value} + + product_product = self.pool.get('product.product') + product_uom = self.pool.get('product.uom') + res_partner = self.pool.get('res.partner') + product_supplierinfo = self.pool.get('product.supplierinfo') + product_pricelist = self.pool.get('product.pricelist') + account_fiscal_position = self.pool.get('account.fiscal.position') + account_tax = self.pool.get('account.tax') + + # - check for the presence of partner_id and pricelist_id if not pricelist_id: raise osv.except_osv(_('No Pricelist !'), _('You have to select a pricelist or a supplier in the purchase form !\nPlease set one before choosing a product.')) if not partner_id: raise osv.except_osv(_('No Partner!'), _('You have to select a partner in the purchase form !\nPlease set one partner before choosing a product.')) - if not product_id: - return {'value': res} - - product_uom_pool = self.pool.get('product.uom') - product_supplierinfo = self.pool.get('product.supplierinfo') - res_partner = self.pool.get('res.partner') - product_product = self.pool.get('product.product') - account_fiscal_position = self.pool.get('account.fiscal.position') - account_tax = self.pool.get('account.tax') - - # set supplier langauage in context + # - determine name and notes based on product in partner lang. lang = res_partner.browse(cr, uid, partner_id).lang if lang: context['lang'] = lang context['partner_id'] = partner_id - product = product_product.browse(cr, uid, product_id, context=context) + res_value.update({'name': product.name, 'notes': notes or product.description_purchase}) + + # - set a domain on product_uom domain = {'product_uom':[('category_id','=',product.uom_id.category_id.id)]} - res['domain'] = domain - - if uom_change and not uom_id: - return {'value': res} + res.update({'domain': domain}) + # - check that uom and product uom belong to the same category product_uom_po_id = product.uom_po_id.id if not uom_id: uom_id = product_uom_po_id - # checking UOM category - if product.uom_id.category_id.id != product_uom_pool.browse(cr, uid, uom_id).category_id.id: + if product.uom_id.category_id.id != product_uom.browse(cr, uid, uom_id, context=context).category_id.id: res.update({'warning': {'title': _('Warning'), 'message': _('Selected UOM does not have same category of default UOM')}}) uom_id = product_uom_po_id - + + res_value.update({'product_uom': uom_id}) + + # - determine product_qty and date_planned based on seller info if not date_order: date_order = time.strftime('%Y-%m-%d') @@ -758,31 +776,32 @@ class purchase_order_line(osv.osv): seller_delay = supplierinfo.delay if supplierinfo.product_uom.id != uom_id: res.update({'warning': {'title': _('Warning'), 'message': _('The selected supplier only sells this product by %s') % supplierinfo.product_uom.name }}) - min_qty = product_uom_pool._compute_qty(cr, uid, supplierinfo.product_uom.id, supplierinfo.min_qty, to_uom_id=uom_id) + min_qty = product_uom._compute_qty(cr, uid, supplierinfo.product_uom.id, supplierinfo.min_qty, to_uom_id=uom_id) if qty < min_qty: # If the supplier quantity is greater than entered from user, set minimal. res.update({'warning': {'title': _('Warning'), 'message': _('The selected supplier has a minimal quantity set to %s %s, you should not purchase less.') % (supplierinfo.min_qty, supplierinfo.product_uom.name)}}) qty = min_qty - - price = self.pool.get('product.pricelist').price_get(cr, uid, [pricelist_id], + + dt = (datetime.strptime(date_order, '%Y-%m-%d') + relativedelta(days=int(seller_delay) or 0.0)).strftime('%Y-%m-%d %H:%M:%S') + res_value.update({'date_planned': date_planned or dt, 'product_qty': qty}) + + # - determine price_unit and taxes_id + price = product_pricelist.price_get(cr, uid, [pricelist_id], product.id, qty or 1.0, partner_id, { 'uom': uom_id, 'date': date_order, })[pricelist_id] - dt = (datetime.now() + relativedelta(days=int(seller_delay) or 0.0)).strftime('%Y-%m-%d %H:%M:%S') - - - res.update({'value': {'price_unit': price, 'name': product.name, - 'taxes_id':map(lambda x: x.id, product.supplier_taxes_id), - 'date_planned': date_planned or dt,'notes': notes or product.description_purchase, - 'product_qty': qty, - 'product_uom': uom_id}}) - + taxes = account_tax.browse(cr, uid, map(lambda x: x.id, product.supplier_taxes_id)) fpos = fiscal_position_id and account_fiscal_position.browse(cr, uid, fiscal_position_id, context=context) or False - res['value']['taxes_id'] = account_fiscal_position.map_tax(cr, uid, fpos, taxes) + taxes_ids = account_fiscal_position.map_tax(cr, uid, fpos, taxes) + res_value.update({'price_unit': price, 'taxes_id': taxes_ids}) + + + res.update({'value': res_value}) return res - product_uom_change = product_id_change + product_id_change = onchange_product_id + product_uom_change = onchange_product_uom def action_confirm(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state': 'confirmed'}, context=context) diff --git a/addons/purchase/purchase_view.xml b/addons/purchase/purchase_view.xml index 14f5354f970..221c0b854a1 100644 --- a/addons/purchase/purchase_view.xml +++ b/addons/purchase/purchase_view.xml @@ -359,9 +359,9 @@
- - - + + + From cdabe44260423cebf266f80e0655fc3d3a15a53b Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Thu, 12 Jan 2012 12:48:56 +0530 Subject: [PATCH 022/248] [IMP] purchase: remove unused method bzr revid: hmo@tinyerp.com-20120112071856-zh0bl7tn7zv0x21i --- addons/purchase/purchase.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index 3895fd39667..908720eccd1 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -697,10 +697,6 @@ class purchase_order_line(osv.osv): default.update({'state':'draft', 'move_ids':[],'invoiced':0,'invoice_lines':[]}) return super(purchase_order_line, self).copy_data(cr, uid, id, default, context) - - def _onchange_check_partner_pricelist(self, pricelist_id, partner_id): - return True - def onchange_product_uom(self, cr, uid, ids, pricelist_id, product_id, qty, uom_id, partner_id, date_order=False, fiscal_position_id=False, date_planned=False, name=False, price_unit=False, notes=False, context=None): From 4cc5c14273ea39b9fcbba5c117c1b1c2b22dd2fd Mon Sep 17 00:00:00 2001 From: "hbto(humbertoarocha)" <> Date: Thu, 12 Jan 2012 14:51:49 +0530 Subject: [PATCH 023/248] [FIX] account: add Missing date on fiscalyear clousure wizard account.fiscalyear.close lp bug: https://launchpad.net/bugs/912623 fixed bzr revid: jap@tinyerp.com-20120112092149-ism5impd38iliz2u --- addons/account/wizard/account_fiscalyear_close.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/addons/account/wizard/account_fiscalyear_close.py b/addons/account/wizard/account_fiscalyear_close.py index d2295b5bbf2..849a7a9f514 100644 --- a/addons/account/wizard/account_fiscalyear_close.py +++ b/addons/account/wizard/account_fiscalyear_close.py @@ -105,6 +105,7 @@ class account_fiscalyear_close(osv.osv_memory): 'name': '/', 'ref': '', 'period_id': period.id, + 'date': period.date_start, 'journal_id': new_journal.id, } move_id = obj_acc_move.create(cr, uid, vals, context=context) @@ -118,7 +119,6 @@ class account_fiscalyear_close(osv.osv_memory): AND a.type != 'view' AND t.close_method = %s''', ('unreconciled', )) account_ids = map(lambda x: x[0], cr.fetchall()) - if account_ids: cr.execute(''' INSERT INTO account_move_line ( @@ -130,11 +130,11 @@ class account_fiscalyear_close(osv.osv_memory): (SELECT name, create_uid, create_date, write_uid, write_date, statement_id, %s,currency_id, date_maturity, partner_id, blocked, credit, 'draft', debit, ref, account_id, - %s, date, %s, amount_currency, quantity, product_id, company_id + %s, (%s) AS date, %s, amount_currency, quantity, product_id, company_id FROM account_move_line WHERE account_id IN %s AND ''' + query_line + ''' - AND reconcile_id IS NULL)''', (new_journal.id, period.id, move_id, tuple(account_ids),)) + AND reconcile_id IS NULL)''', (new_journal.id, period.id, period.date_start, move_id, tuple(account_ids),)) #We have also to consider all move_lines that were reconciled #on another fiscal year, and report them too @@ -149,7 +149,7 @@ class account_fiscalyear_close(osv.osv_memory): b.name, b.create_uid, b.create_date, b.write_uid, b.write_date, b.statement_id, %s, b.currency_id, b.date_maturity, b.partner_id, b.blocked, b.credit, 'draft', b.debit, - b.ref, b.account_id, %s, b.date, %s, b.amount_currency, + b.ref, b.account_id, %s, (%s) AS date, %s, b.amount_currency, b.quantity, b.product_id, b.company_id FROM account_move_line b WHERE b.account_id IN %s @@ -157,7 +157,7 @@ class account_fiscalyear_close(osv.osv_memory): AND b.period_id IN ('''+fy_period_set+''') AND b.reconcile_id IN (SELECT DISTINCT(reconcile_id) FROM account_move_line a - WHERE a.period_id IN ('''+fy2_period_set+''')))''', (new_journal.id, period.id, move_id, tuple(account_ids),)) + WHERE a.period_id IN ('''+fy2_period_set+''')))''', (new_journal.id, period.id, period.date_start, move_id, tuple(account_ids),)) #2. report of the accounts with defferal method == 'detail' cr.execute(''' @@ -180,11 +180,11 @@ class account_fiscalyear_close(osv.osv_memory): (SELECT name, create_uid, create_date, write_uid, write_date, statement_id, %s,currency_id, date_maturity, partner_id, blocked, credit, 'draft', debit, ref, account_id, - %s, date, %s, amount_currency, quantity, product_id, company_id + %s, (%s) AS date, %s, amount_currency, quantity, product_id, company_id FROM account_move_line WHERE account_id IN %s AND ''' + query_line + ''') - ''', (new_journal.id, period.id, move_id, tuple(account_ids),)) + ''', (new_journal.id, period.id, period.date_start, move_id, tuple(account_ids),)) #3. report of the accounts with defferal method == 'balance' From 59cbdd3341721226ef6f8ddfdd8f143273077806 Mon Sep 17 00:00:00 2001 From: "Divyesh Makwana (Open ERP)" Date: Thu, 12 Jan 2012 15:19:04 +0530 Subject: [PATCH 024/248] [ADD] hr_attendance : Added Test Cases For Hr Attendance bzr revid: mdi@tinyerp.com-20120112094904-b10x1mx4c2uxitzj --- .../hr_attendance/test/attendance_process.yml | 55 ++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/addons/hr_attendance/test/attendance_process.yml b/addons/hr_attendance/test/attendance_process.yml index 1d8308c2f45..5c83ba25aa1 100644 --- a/addons/hr_attendance/test/attendance_process.yml +++ b/addons/hr_attendance/test/attendance_process.yml @@ -28,4 +28,57 @@ - !assert {model: hr.employee, id: hr.employee_al, severity: error, string: Employee should be in absent state}: - state == 'absent' - +- + In order to check that first attendance must be Sign In. +- + !python {model: hr.attendance}: | + try: + self.create(cr, uid, {employee_id: hr.employee_fp, name: time.strftime('%Y-%m-%d 09:59:25'), action: 'sign_out'}, None) + except Exception, e: + assert e, 'The first attendance must be Sign In' +- + First of all, Employee Sign's In. +- + !record {model: hr.attendance, id: hr_attendance_1}: + employee_id: hr.employee_fp + name: !eval time.strftime('%Y-%m-%d 09:59:25') + action: 'sign_in' +- + Now Employee is going to Sign In prior to First Sign In. +- + !python {model: hr.attendance}: | + try: + self.create(cr, uid, {employee_id: hr.employee_fp, name: time.strftime('%Y-%m-%d 08:59:25'), action: 'sign_in'}, None) + except Exception, e: + assert e, 'Sign In (resp. Sign Out) must follow Sign Out (resp. Sign In)' +- + After that Employee is going to Sign In after First Sign In. +- + !python {model: hr.attendance}: | + try: + self.create(cr, uid, {employee_id: hr.employee_fp, name: time.strftime('%Y-%m-%d 10:59:25'), action: 'sign_in'}, None) + except Exception, e: + assert e, 'Sign In (resp. Sign Out) must follow Sign Out (resp. Sign In)' +- + After two hours, Employee Sign's Out. +- + !record {model: hr.attendance, id: hr_attendance_4}: + employee_id: hr.employee_fp + name: !eval time.strftime('%Y-%m-%d 11:59:25') + action: 'sign_out' +- + Now Employee is going to Sign Out prior to First Sign Out. +- + !python {model: hr.attendance}: | + try: + self.create(cr, uid, {employee_id: hr.employee_fp, name: time.strftime('%Y-%m-%d 10:59:25'), action: 'sign_out'}, None) + except Exception, e: + assert e, 'Sign In (resp. Sign Out) must follow Sign Out (resp. Sign In)' +- + After that Employee is going to Sign Out After First Sign Out. +- + !python {model: hr.attendance}: | + try: + self.create(cr, uid, {employee_id: hr.employee_fp, name: time.strftime('%Y-%m-%d 12:59:25'), action: 'sign_out'}, None) + except Exception, e: + assert e, 'Sign In (resp. Sign Out) must follow Sign Out (resp. Sign In)' From 815f27fedf5da0b1772f231cd565982da5df836c Mon Sep 17 00:00:00 2001 From: "Mayur Maheshwari (OpenERP)" Date: Thu, 12 Jan 2012 17:14:57 +0530 Subject: [PATCH 025/248] [IMP]mrp_repair: added a message when repair order without repair line bzr revid: mma@tinyerp.com-20120112114457-yheegsrhr8tikbuy --- addons/mrp_repair/mrp_repair.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/addons/mrp_repair/mrp_repair.py b/addons/mrp_repair/mrp_repair.py index e1216332ae4..e420ebdbf68 100644 --- a/addons/mrp_repair/mrp_repair.py +++ b/addons/mrp_repair/mrp_repair.py @@ -330,6 +330,8 @@ class mrp_repair(osv.osv): self.write(cr, uid, [o.id], {'state': '2binvoiced'}) else: self.write(cr, uid, [o.id], {'state': 'confirmed'}) + if not o.operations: + raise osv.except_osv(_('Error !'),_('You cannot confirm a repair order which has no line.')) for line in o.operations: if line.product_id.track_production and not line.prodlot_id: raise osv.except_osv(_('Warning'), _("Production lot is required for opration line with product '%s'") % (line.product_id.name)) From 447cf0e2b32f384ff209bb66608260b294106dd8 Mon Sep 17 00:00:00 2001 From: "Mayur Maheshwari (OpenERP)" Date: Thu, 12 Jan 2012 17:28:34 +0530 Subject: [PATCH 026/248] [IMP]mrp_repair: pass a workflow in make invoice wizard bzr revid: mma@tinyerp.com-20120112115834-8gma20bjj0bbf64h --- addons/mrp_repair/wizard/make_invoice.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/addons/mrp_repair/wizard/make_invoice.py b/addons/mrp_repair/wizard/make_invoice.py index 61f82a3d57c..6b49aab5aba 100644 --- a/addons/mrp_repair/wizard/make_invoice.py +++ b/addons/mrp_repair/wizard/make_invoice.py @@ -45,6 +45,8 @@ class make_invoice(osv.osv_memory): order_obj = self.pool.get('mrp.repair') newinv = order_obj.action_invoice_create(cr, uid, context['active_ids'], group=inv.group,context=context) + wf_service = netsvc.LocalService("workflow") + wf_service.trg_validate(uid, 'mrp.repair', context.get('active_id'), 'action_invoice_create' , cr) return { 'domain': [('id','in', newinv.values())], From 7449274b63c6539ea023ac6f6239fc0b07433736 Mon Sep 17 00:00:00 2001 From: Benoit Guillot Date: Thu, 12 Jan 2012 15:44:56 +0100 Subject: [PATCH 027/248] [REF] refactor _calc_seller and create the function _get_main_product_supplier bzr revid: benoit.guillot@akretion.com.br-20120112144456-pg8vg1stpm9y78ky --- addons/product/product.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/addons/product/product.py b/addons/product/product.py index e6b4b4c6348..601c47d8f91 100644 --- a/addons/product/product.py +++ b/addons/product/product.py @@ -257,20 +257,23 @@ product_category() class product_template(osv.osv): _name = "product.template" _description = "Product Template" + + def _get_main_product_supplier(self, cr, uid, product, context=None): + sellers = [(seller_info.sequence, seller_info) + for seller_info in product.seller_ids or [] + if seller_info and isinstance(seller_info.sequence, (int, long))] + return sellers and sellers[0][1] or False + def _calc_seller(self, cr, uid, ids, fields, arg, context=None): result = {} for product in self.browse(cr, uid, ids, context=context): - for field in fields: - result[product.id] = {field:False} - result[product.id]['seller_delay'] = 1 - if product.seller_ids: - partner_list = [(partner_id.sequence, partner_id) - for partner_id in product.seller_ids - if partner_id and isinstance(partner_id.sequence, (int, long))] - main_supplier = partner_list and partner_list[0] and partner_list[0][1] or False - result[product.id]['seller_delay'] = main_supplier and main_supplier.delay or 1 - result[product.id]['seller_qty'] = main_supplier and main_supplier.qty or 0.0 - result[product.id]['seller_id'] = main_supplier and main_supplier.name.id or False + main_supplier = self._get_main_product_supplier(cr, uid, product, context=context) + result[product.id] = { + 'seller_info_id': main_supplier and main_supplier.id or False, + 'seller_delay': main_supplier and main_supplier.delay or 1, + 'seller_qty': main_supplier and main_supplier.qty or 0.0, + 'seller_id': main_supplier and main_supplier.name.id or False + } return result _columns = { @@ -317,6 +320,7 @@ class product_template(osv.osv): 'loc_row': fields.char('Row', size=16), 'loc_case': fields.char('Case', size=16), 'company_id': fields.many2one('res.company', 'Company',select=1), + 'seller_info_id': fields.function(_calc_seller, type='many2one', relation="product.supplierinfo", multi="seller_info"), } def _get_uom_id(self, cr, uid, *args): From f1b0a82ff6b4786d8283ffc646066f9fde671175 Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Fri, 13 Jan 2012 14:14:42 +0530 Subject: [PATCH 028/248] [FIX]:Survey: if send invitation log in with that account it shows only that survey bzr revid: sgo@tinyerp.com-20120113084442-9uhynv0ut54h9dad --- addons/survey/wizard/survey_selection.py | 26 ++++++++++++++++++++++- addons/survey/wizard/survey_selection.xml | 3 +-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/addons/survey/wizard/survey_selection.py b/addons/survey/wizard/survey_selection.py index 82c9fd385ed..e865330fac9 100644 --- a/addons/survey/wizard/survey_selection.py +++ b/addons/survey/wizard/survey_selection.py @@ -22,12 +22,13 @@ from osv import osv from osv import fields from tools.translate import _ +from lxml import etree class survey_name_wiz(osv.osv_memory): _name = 'survey.name.wiz' _columns = { - 'survey_id': fields.many2one('survey', 'Survey', required=True, ondelete='cascade'), + 'survey_id': fields.many2one('survey', 'Survey', required=True, ondelete='cascade' ,domain= [('state', '=', 'open')]), 'page_no': fields.integer('Page Number'), 'note': fields.text("Description"), 'page': fields.char('Page Position',size = 12), @@ -44,6 +45,27 @@ class survey_name_wiz(osv.osv_memory): 'store_ans': '{}' #Setting the default pattern as '{}' as the field is of type text. The field always gets the value in dict format } + def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): + survey_obj = self.pool.get('survey') + lines_ids=[] + res = super(survey_name_wiz, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=False) + survey_user_group_id = self.pool.get('res.groups').search(cr, uid, [('name', '=', 'Survey / User')]) + group_id = self.pool.get('res.groups').search(cr, uid, [('name', 'in', ('Tools / Manager','Tools / User','Survey / User'))]) + user_obj = self.pool.get('res.users') + user_rec = user_obj.read(cr, uid, uid) + if uid!=1: + if survey_user_group_id: + if survey_user_group_id == user_rec['groups_id']: + lines_ids=survey_obj.search(cr, uid, [ ('invited_user_ids','in',uid)], context=context) + domain = '[("id", "in", '+ str(lines_ids)+')]' + doc = etree.XML(res['arch']) + nodes = doc.xpath("//field[@name='survey_id']") + for node in nodes: + node.set('domain', domain) + res['arch'] = etree.tostring(doc) + return res + + def action_next(self, cr, uid, ids, context=None): """ Start the survey, Increment in started survey field but if set the max_response_limit of @@ -87,5 +109,7 @@ class survey_name_wiz(osv.osv_memory): return {} notes = self.pool.get('survey').read(cr, uid, survey_id, ['note'])['note'] return {'value': {'note': notes}} + +survey_name_wiz() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file diff --git a/addons/survey/wizard/survey_selection.xml b/addons/survey/wizard/survey_selection.xml index 144525979dd..a72566f7888 100644 --- a/addons/survey/wizard/survey_selection.xml +++ b/addons/survey/wizard/survey_selection.xml @@ -15,8 +15,7 @@ + on_change="on_change_survey(survey_id)" width="250"/> From 37530335e1ece8ada40e2b0f4110738141a0b40d Mon Sep 17 00:00:00 2001 From: Tejas Tank Date: Fri, 13 Jan 2012 14:46:45 +0530 Subject: [PATCH 029/248] survey set nolable=1 with questations bzr revid: tta@openerp.com-20120113091645-qza696j2ju2dvdi5 --- addons/survey/survey_view.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/survey/survey_view.xml b/addons/survey/survey_view.xml index 3dd7ca17f6f..0f1a68145aa 100644 --- a/addons/survey/survey_view.xml +++ b/addons/survey/survey_view.xml @@ -39,7 +39,7 @@ - + From e5f375ce0d07ee60e2cf242258d3f13f1bb6316a Mon Sep 17 00:00:00 2001 From: "Sanjay Gohel (Open ERP)" Date: Fri, 13 Jan 2012 15:09:11 +0530 Subject: [PATCH 030/248] [FIX]Survey: improve code remove unused code remove users bzr revid: sgo@tinyerp.com-20120113093911-cd1vvavmqo5p735p --- addons/survey/wizard/survey_selection.py | 29 +++++++++--------------- 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/addons/survey/wizard/survey_selection.py b/addons/survey/wizard/survey_selection.py index e865330fac9..37d8e3bade2 100644 --- a/addons/survey/wizard/survey_selection.py +++ b/addons/survey/wizard/survey_selection.py @@ -46,23 +46,18 @@ class survey_name_wiz(osv.osv_memory): } def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): + survey_obj = self.pool.get('survey') - lines_ids=[] - res = super(survey_name_wiz, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=False) - survey_user_group_id = self.pool.get('res.groups').search(cr, uid, [('name', '=', 'Survey / User')]) - group_id = self.pool.get('res.groups').search(cr, uid, [('name', 'in', ('Tools / Manager','Tools / User','Survey / User'))]) - user_obj = self.pool.get('res.users') - user_rec = user_obj.read(cr, uid, uid) - if uid!=1: - if survey_user_group_id: - if survey_user_group_id == user_rec['groups_id']: - lines_ids=survey_obj.search(cr, uid, [ ('invited_user_ids','in',uid)], context=context) - domain = '[("id", "in", '+ str(lines_ids)+')]' - doc = etree.XML(res['arch']) - nodes = doc.xpath("//field[@name='survey_id']") - for node in nodes: - node.set('domain', domain) - res['arch'] = etree.tostring(doc) + lines_ids = [] + res = super(survey_name_wiz, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=False) + if uid != 1: + lines_ids = survey_obj.search(cr, uid,[('invited_user_ids','in',uid)], context=context) + domain = '[("id", "in", '+ str(lines_ids)+')]' + doc = etree.XML(res['arch']) + nodes = doc.xpath("//field[@name='survey_id']") + for node in nodes: + node.set('domain',domain) + res['arch'] = etree.tostring(doc) return res @@ -110,6 +105,4 @@ class survey_name_wiz(osv.osv_memory): notes = self.pool.get('survey').read(cr, uid, survey_id, ['note'])['note'] return {'value': {'note': notes}} -survey_name_wiz() - # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file From 664de510ad8e29951bd7a19e8e5b4cdd25f6214a Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 13 Jan 2012 12:17:36 +0100 Subject: [PATCH 031/248] [IMP] edi: remove debug in edi url bzr revid: chs@openerp.com-20120113111736-w542872mwozrhbpp --- addons/edi/models/edi.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/edi/models/edi.py b/addons/edi/models/edi.py index c573115618e..589922ff178 100644 --- a/addons/edi/models/edi.py +++ b/addons/edi/models/edi.py @@ -2,7 +2,7 @@ ############################################################################## # # OpenERP, Open Source Business Applications -# Copyright (c) 2011 OpenERP S.A. +# Copyright (c) 2011-2012 OpenERP S.A. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -37,7 +37,7 @@ from tools.translate import _ from tools.safe_eval import safe_eval as eval EXTERNAL_ID_PATTERN = re.compile(r'^([^.:]+)(?::([^.]+))?\.(\S+)$') -EDI_VIEW_WEB_URL = '%s/edi/view?debug=1&db=%s&token=%s' +EDI_VIEW_WEB_URL = '%s/edi/view?db=%s&token=%s' EDI_PROTOCOL_VERSION = 1 # arbitrary ever-increasing version number EDI_GENERATOR = 'OpenERP ' + release.major_version EDI_GENERATOR_VERSION = release.version_info @@ -682,4 +682,4 @@ class EDIMixin(object): return record_id -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From fb2e5f04c00d492b6edfab0c73b230ab6c0ef591 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 13 Jan 2012 12:20:34 +0100 Subject: [PATCH 032/248] [FIX] edi: correct design bzr revid: chs@openerp.com-20120113112034-zr1v1qsvwn6ya0x7 --- addons/edi/static/src/js/edi.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/edi/static/src/js/edi.js b/addons/edi/static/src/js/edi.js index 73bcfa267e5..352177156e1 100644 --- a/addons/edi/static/src/js/edi.js +++ b/addons/edi/static/src/js/edi.js @@ -109,7 +109,7 @@ openerp.edi.EdiView = openerp.web.Widget.extend({ openerp.edi.edi_view = function (db, token) { openerp.connection.bind().then(function () { - new openerp.edi.EdiView(null,db,token).appendTo($("body")); + new openerp.edi.EdiView(null,db,token).appendTo($("body").addClass('openerp')); }); } @@ -172,7 +172,7 @@ openerp.edi.EdiImport = openerp.web.Widget.extend({ openerp.edi.edi_import = function (url) { openerp.connection.bind().then(function () { - new openerp.edi.EdiImport(null,url).appendTo($("body")); + new openerp.edi.EdiImport(null,url).appendTo($("body").addClass('openerp')); }); } From db1ffb561b704d76a6ee80faf94fbce906df82e5 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 13 Jan 2012 12:21:21 +0100 Subject: [PATCH 033/248] [FIX] edi: ask login before import bzr revid: chs@openerp.com-20120113112121-5tlnb2he9sw8cbe0 --- addons/edi/static/src/js/edi.js | 47 +++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/addons/edi/static/src/js/edi.js b/addons/edi/static/src/js/edi.js index 352177156e1..d62a4c3b780 100644 --- a/addons/edi/static/src/js/edi.js +++ b/addons/edi/static/src/js/edi.js @@ -114,30 +114,49 @@ openerp.edi.edi_view = function (db, token) { } openerp.edi.EdiImport = openerp.web.Widget.extend({ - init: function(parent,url) { - this._super(); - this.url = url; - var params = {}; + template: "EdiImport", - this.template = "EdiImport"; - this.session = openerp.connection; - this.login = new openerp.web.Login(this); - this.header = new openerp.web.Header(this); + init: function(parent, url) { + this._super(parent); + this.url = url; }, start: function() { - // TODO fix by explicitly asking login if needed - //this.session.on_session_invalid.add_last(this.do_ask_login); - this.header.appendTo($("#oe_header")); - this.login.appendTo($('#oe_login')); + if (!this.session.session_is_valid()) { + this.show_login(); + this.session.on_session_valid.add({ + callback: this.proxy('show_import'), + unique: true, + }); + } else { + this.show_import(); + } + }, + + show_import: function() { + this.destroy_content(); this.do_import(); }, + + show_login: function() { + this.destroy_content(); + this.login = new openerp.web.Login(this); + this.login.appendTo(this.$element); + }, + + destroy_content: function() { + _.each(_.clone(this.widget_children), function(el) { + el.stop(); + }); + this.$element.children().remove(); + }, + do_import: function() { this.rpc('/edi/import_edi_url', {url: this.url}, this.on_imported, this.on_imported_error); }, on_imported: function(response) { if ('action' in response) { this.rpc("/web/session/save_session_action", {the_action: response.action}, function(key) { - window.location = "/web/webclient/home?debug=1&s_action="+encodeURIComponent(key); + window.location = "/web/webclient/home#sa="+encodeURIComponent(key); }); } else { @@ -147,7 +166,7 @@ openerp.edi.EdiImport = openerp.web.Widget.extend({ buttons: { Ok: function() { $(this).dialog("close"); - window.location = "/web/webclient/home"; + window.location = "/"; } } }).html('The document has been successfully imported!'); From b84f9fe2d7937b023a79bea30b05fc93671c21be Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 13 Jan 2012 12:36:08 +0100 Subject: [PATCH 034/248] [IMP] handle session actions bzr revid: chs@openerp.com-20120113113608-am1cbzs6z0urfh4k --- addons/web/static/src/js/views.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index f8bdd58bc3e..87e3861fc87 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -80,6 +80,16 @@ session.web.ActionManager = session.web.Widget.extend({ }; action_loaded = this.do_action(action); } + else if (state.sa) { + // load session action + var self = this; + this.null_action(); + action_loaded = this.rpc('/web/session/get_session_action', {key: state.sa}).pipe(function(action) { + if (action) { + return self.do_action(action); + } + }); + } else if (state.client_action) { this.null_action(); this.ir_actions_client(state.client_action); From cf252dd6c14779619483820abaecc856692d9456 Mon Sep 17 00:00:00 2001 From: "Atul Patel (OpenERP)" Date: Fri, 13 Jan 2012 19:06:15 +0530 Subject: [PATCH 035/248] [FIX]crm_partner_assign: Add user_id insted of "partner_id" in crm_lead_view.xml under the crm.lead Search View. bzr revid: atp@tinyerp.com-20120113133615-twtc2sntv373y5b3 --- addons/crm_partner_assign/crm_lead_view.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/crm_partner_assign/crm_lead_view.xml b/addons/crm_partner_assign/crm_lead_view.xml index 14e160fb397..224a52a104c 100644 --- a/addons/crm_partner_assign/crm_lead_view.xml +++ b/addons/crm_partner_assign/crm_lead_view.xml @@ -61,7 +61,7 @@ - + From 293ee2f2d457038c14df853733688175d0b2a02f Mon Sep 17 00:00:00 2001 From: "Divyesh Makwana (Open ERP)" Date: Mon, 16 Jan 2012 12:15:26 +0530 Subject: [PATCH 036/248] [IMP] hr_attendance : Improved Test Cases. bzr revid: mdi@tinyerp.com-20120116064526-i1o9qwq4nxlv01yx --- .../hr_attendance/test/attendance_process.yml | 40 ++++++++++++++----- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/addons/hr_attendance/test/attendance_process.yml b/addons/hr_attendance/test/attendance_process.yml index 5c83ba25aa1..7d76ee79e74 100644 --- a/addons/hr_attendance/test/attendance_process.yml +++ b/addons/hr_attendance/test/attendance_process.yml @@ -43,42 +43,62 @@ employee_id: hr.employee_fp name: !eval time.strftime('%Y-%m-%d 09:59:25') action: 'sign_in' +- + In order to check that first attendance must be Sign In. +- + !python {model: hr.attendance}: | + import time + try: + self.create(cr, uid, {'employee_id': ref('hr.employee_niv'), 'name': time.strftime('%Y-%m-%d 09:59:25'), 'action': 'sign_out'}, None) + except Exception, e: + assert e[0]=='ValidateError', e +- + First of all, Employee Sign's In. +- + !record {model: hr.attendance, id: hr_attendance_0}: + employee_id: hr.employee_niv + name: !eval time.strftime('%Y-%m-%d 09:59:25') + action: 'sign_in' - Now Employee is going to Sign In prior to First Sign In. - !python {model: hr.attendance}: | + import time try: - self.create(cr, uid, {employee_id: hr.employee_fp, name: time.strftime('%Y-%m-%d 08:59:25'), action: 'sign_in'}, None) + self.create(cr, uid, {'employee_id': ref('hr.employee_niv'), 'name': time.strftime('%Y-%m-%d 08:59:25'), 'action': 'sign_in'}, None) except Exception, e: - assert e, 'Sign In (resp. Sign Out) must follow Sign Out (resp. Sign In)' + assert e[0]=='ValidateError', e - After that Employee is going to Sign In after First Sign In. - !python {model: hr.attendance}: | + import time try: - self.create(cr, uid, {employee_id: hr.employee_fp, name: time.strftime('%Y-%m-%d 10:59:25'), action: 'sign_in'}, None) + self.create(cr, uid, {'employee_id': ref('hr.employee_niv'), 'name': time.strftime('%Y-%m-%d 10:59:25'), 'action': 'sign_in'}, None) except Exception, e: - assert e, 'Sign In (resp. Sign Out) must follow Sign Out (resp. Sign In)' + assert e[0]=='ValidateError', e - After two hours, Employee Sign's Out. - - !record {model: hr.attendance, id: hr_attendance_4}: - employee_id: hr.employee_fp + !record {model: hr.attendance, id: hr_attendance_1}: + employee_id: hr.employee_niv name: !eval time.strftime('%Y-%m-%d 11:59:25') action: 'sign_out' - Now Employee is going to Sign Out prior to First Sign Out. - !python {model: hr.attendance}: | + import time try: - self.create(cr, uid, {employee_id: hr.employee_fp, name: time.strftime('%Y-%m-%d 10:59:25'), action: 'sign_out'}, None) + self.create(cr, uid, {'employee_id': ref('hr.employee_niv'), 'name': time.strftime('%Y-%m-%d 10:59:25'), 'action': 'sign_out'}, None) except Exception, e: - assert e, 'Sign In (resp. Sign Out) must follow Sign Out (resp. Sign In)' + assert e[0]=='ValidateError', e - After that Employee is going to Sign Out After First Sign Out. - !python {model: hr.attendance}: | + import time try: - self.create(cr, uid, {employee_id: hr.employee_fp, name: time.strftime('%Y-%m-%d 12:59:25'), action: 'sign_out'}, None) + self.create(cr, uid, {'employee_id': ref('hr.employee_niv'), 'name': time.strftime('%Y-%m-%d 12:59:25'), 'action': 'sign_out'}, None) except Exception, e: - assert e, 'Sign In (resp. Sign Out) must follow Sign Out (resp. Sign In)' + assert e[0]=='ValidateError', e From 7db3e24af994a60cdb26cb8074717aa153e506c8 Mon Sep 17 00:00:00 2001 From: "Divyesh Makwana (Open ERP)" Date: Mon, 16 Jan 2012 12:30:12 +0530 Subject: [PATCH 037/248] [IMP] hr_attendance : Improved Test Cases. bzr revid: mdi@tinyerp.com-20120116070012-8blt2ov12b0qx74b --- addons/hr_attendance/test/attendance_process.yml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/addons/hr_attendance/test/attendance_process.yml b/addons/hr_attendance/test/attendance_process.yml index 7d76ee79e74..4ad765d65df 100644 --- a/addons/hr_attendance/test/attendance_process.yml +++ b/addons/hr_attendance/test/attendance_process.yml @@ -30,21 +30,6 @@ - state == 'absent' - In order to check that first attendance must be Sign In. -- - !python {model: hr.attendance}: | - try: - self.create(cr, uid, {employee_id: hr.employee_fp, name: time.strftime('%Y-%m-%d 09:59:25'), action: 'sign_out'}, None) - except Exception, e: - assert e, 'The first attendance must be Sign In' -- - First of all, Employee Sign's In. -- - !record {model: hr.attendance, id: hr_attendance_1}: - employee_id: hr.employee_fp - name: !eval time.strftime('%Y-%m-%d 09:59:25') - action: 'sign_in' -- - In order to check that first attendance must be Sign In. - !python {model: hr.attendance}: | import time From 8dfb00969cd1a0d9fc9c9e0642f5cad59ce38064 Mon Sep 17 00:00:00 2001 From: "tfr@openerp.com" <> Date: Mon, 16 Jan 2012 15:04:53 +0100 Subject: [PATCH 038/248] [FIX] Fix base contact, when create an address from a contact you can link to a partner + delete useless definition of partner_id in location + add domain when select a location bzr revid: tfr@openerp.com-20120116140453-k3m6busjbk29aygr --- addons/base_contact/base_contact.py | 1 - addons/base_contact/base_contact_view.xml | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/base_contact/base_contact.py b/addons/base_contact/base_contact.py index 40653f01ff3..7df5c444ecb 100644 --- a/addons/base_contact/base_contact.py +++ b/addons/base_contact/base_contact.py @@ -120,7 +120,6 @@ class res_partner_location(osv.osv): 'city': fields.char('City', size=128), 'state_id': fields.many2one("res.country.state", 'Fed. State', domain="[('country_id','=',country_id)]"), 'country_id': fields.many2one('res.country', 'Country'), - 'partner_id': fields.many2one('res.partner', 'Partner Name', ondelete='set null', select=True, help="Keep empty for a private address, not related to partner."), 'company_id': fields.many2one('res.company', 'Company',select=1), 'job_ids': fields.one2many('res.partner.address', 'location_id', 'Contacts'), 'partner_id': fields.related('job_ids', 'partner_id', type='many2one',\ diff --git a/addons/base_contact/base_contact_view.xml b/addons/base_contact/base_contact_view.xml index 10d8de984c2..16a9a966e25 100644 --- a/addons/base_contact/base_contact_view.xml +++ b/addons/base_contact/base_contact_view.xml @@ -50,7 +50,8 @@ - + + @@ -135,7 +136,7 @@ form - + From da9d5063499fecbee58681ce55010ecab9afc262 Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Mon, 16 Jan 2012 15:16:43 +0100 Subject: [PATCH 039/248] Override values even when they are empty (a user may empty a value on a sale order or purchase order and would like the empty field to be "copied" on the invoice). bzr revid: alexis@via.ecp.fr-20120116141643-boglddgratoro59p --- addons/purchase/stock.py | 3 +-- addons/sale/stock.py | 9 +++------ 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/addons/purchase/stock.py b/addons/purchase/stock.py index ca84d88babd..acb4ae13c05 100644 --- a/addons/purchase/stock.py +++ b/addons/purchase/stock.py @@ -72,8 +72,7 @@ class stock_picking(osv.osv): invoice_vals['address_contact_id'], invoice_vals['address_invoice_id'] = \ self.pool.get('res.partner').address_get(cr, uid, [partner.id], ['contact', 'invoice']).values() - if picking.purchase_id.fiscal_position: - invoice_vals['fiscal_position'] = picking.purchase_id.fiscal_position.id + invoice_vals['fiscal_position'] = picking.purchase_id.fiscal_position.id return invoice_vals def get_currency_id(self, cursor, user, picking): diff --git a/addons/sale/stock.py b/addons/sale/stock.py index 6daff3a83b0..f42f09eb20c 100644 --- a/addons/sale/stock.py +++ b/addons/sale/stock.py @@ -66,12 +66,9 @@ class stock_picking(osv.osv): if picking.sale_id: invoice_vals['address_contact_id'] = picking.sale_id.partner_order_id.id invoice_vals['address_invoice_id'] = picking.sale_id.partner_invoice_id.id - if picking.sale_id.fiscal_position: - invoice_vals['fiscal_position'] = picking.sale_id.fiscal_position.id - if picking.sale_id.payment_term: - invoice_vals['payment_term'] = picking.sale_id.payment_term.id - if picking.sale_id.user_id: - invoice_vals['user_id'] = picking.sale_id.user_id.id + invoice_vals['fiscal_position'] = picking.sale_id.fiscal_position.id + invoice_vals['payment_term'] = picking.sale_id.payment_term.id + invoice_vals['user_id'] = picking.sale_id.user_id.id return invoice_vals def _get_price_unit_invoice(self, cursor, user, move_line, type): From 13e80f5e0e7ad934d386c06ce3ead24d5298a5fe Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Mon, 16 Jan 2012 15:18:24 +0100 Subject: [PATCH 040/248] Make the creation of the invoice lines extensible too. This change also fixes a bug when the fiscal position is changed on the sale order/purchase order : now, the account on the invoice line uses the fiscal position of the sale order/purchase order and not the fiscal position of the partner. bzr revid: alexis@via.ecp.fr-20120116141824-iw7y1wdnueahahuz --- addons/stock/stock.py | 109 ++++++++++++++++++++++-------------------- 1 file changed, 57 insertions(+), 52 deletions(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index a1b06adedc6..e16b982aee9 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- ############################################################################## # # OpenERP, Open Source Management Solution @@ -1004,6 +1005,53 @@ class stock_picking(osv.osv): invoice_vals['journal_id'] = journal_id return invoice_vals + def _prepare_invoice_line(self, cr, uid, group, picking, move_line, invoice_id, + invoice_vals, context=None): + """Builds the dict containing the values for the invoice line""" + if group: + name = (picking.name or '') + '-' + move_line.name + else: + name = move_line.name + origin = move_line.picking_id.name or '' + if move_line.picking_id.origin: + origin += ':' + move_line.picking_id.origin + + if invoice_vals['type'] in ('out_invoice', 'out_refund'): + account_id = move_line.product_id.product_tmpl_id.\ + property_account_income.id + if not account_id: + account_id = move_line.product_id.categ_id.\ + property_account_income_categ.id + else: + account_id = move_line.product_id.product_tmpl_id.\ + property_account_expense.id + if not account_id: + account_id = move_line.product_id.categ_id.\ + property_account_expense_categ.id + if invoice_vals['fiscal_position']: + fp_obj = self.pool.get('account.fiscal.position') + fiscal_position = fp_obj.browse(cr, uid, invoice_vals['fiscal_position'], context=context) + account_id = fp_obj.map_account(cr, uid, fiscal_position, account_id) + # set UoS if it's a sale and the picking doesn't have one + uos_id = move_line.product_uos and move_line.product_uos.id or False + if not uos_id and invoice_vals['type'] in ('out_invoice', 'out_refund'): + uos_id = move_line.product_uom.id + + return { + 'name': name, + 'origin': origin, + 'invoice_id': invoice_id, + 'uos_id': uos_id, + 'product_id': move_line.product_id.id, + 'account_id': account_id, + 'price_unit': self._get_price_unit_invoice(cr, uid, move_line, invoice_vals['type']), + 'discount': self._get_discount_invoice(cr, uid, move_line), + 'quantity': move_line.product_uos_qty or move_line.product_qty, + 'invoice_line_tax_id': [(6, 0, + self._get_taxes_invoice(cr, uid, move_line, invoice_vals['type']))], + 'account_analytic_id': self._get_account_analytic_invoice(cr, uid, picking, move_line), + } + def action_invoice_create(self, cr, uid, ids, journal_id=False, group=False, type='out_invoice', context=None): """ Creates invoice based on the invoice state selected for picking. @@ -1034,64 +1082,21 @@ class stock_picking(osv.osv): if group and partner.id in invoices_group: invoice_id = invoices_group[partner.id] invoice = invoice_obj.browse(cr, uid, invoice_id) - invoice_obj.write(cr, uid, [invoice_id], - self._prepare_invoice_group(cr, uid, picking, partner, invoice, context=context), - context=context) + invoice_vals_group = self._prepare_invoice_group(cr, uid, picking, partner, invoice, context=context) + invoice_obj.write(cr, uid, [invoice_id], invoice_vals_group, context=context) else: - invoice_id = invoice_obj.create(cr, uid, - self._prepare_invoice(cr, uid, picking, partner, inv_type, journal_id, context=context), - context=context) + invoice_vals = self._prepare_invoice(cr, uid, picking, partner, inv_type, journal_id, context=context) + invoice_id = invoice_obj.create(cr, uid, invoice_vals, context=context) invoices_group[partner.id] = invoice_id res[picking.id] = invoice_id for move_line in picking.move_lines: if move_line.state == 'cancel': continue - origin = move_line.picking_id.name or '' - if move_line.picking_id.origin: - origin += ':' + move_line.picking_id.origin - if group: - name = (picking.name or '') + '-' + move_line.name - else: - name = move_line.name - - if inv_type in ('out_invoice', 'out_refund'): - account_id = move_line.product_id.product_tmpl_id.\ - property_account_income.id - if not account_id: - account_id = move_line.product_id.categ_id.\ - property_account_income_categ.id - else: - account_id = move_line.product_id.product_tmpl_id.\ - property_account_expense.id - if not account_id: - account_id = move_line.product_id.categ_id.\ - property_account_expense_categ.id - - price_unit = self._get_price_unit_invoice(cr, uid, - move_line, inv_type) - discount = self._get_discount_invoice(cr, uid, move_line) - tax_ids = self._get_taxes_invoice(cr, uid, move_line, inv_type) - account_analytic_id = self._get_account_analytic_invoice(cr, uid, picking, move_line) - - #set UoS if it's a sale and the picking doesn't have one - uos_id = move_line.product_uos and move_line.product_uos.id or False - if not uos_id and inv_type in ('out_invoice', 'out_refund'): - uos_id = move_line.product_uom.id - - account_id = self.pool.get('account.fiscal.position').map_account(cr, uid, partner.property_account_position, account_id) - invoice_line_id = invoice_line_obj.create(cr, uid, { - 'name': name, - 'origin': origin, - 'invoice_id': invoice_id, - 'uos_id': uos_id, - 'product_id': move_line.product_id.id, - 'account_id': account_id, - 'price_unit': price_unit, - 'discount': discount, - 'quantity': move_line.product_uos_qty or move_line.product_qty, - 'invoice_line_tax_id': [(6, 0, tax_ids)], - 'account_analytic_id': account_analytic_id, - }, context=context) + print "invoice_vals=", invoice_vals + invoice_line_id = invoice_line_obj.create(cr, uid, + self._prepare_invoice_line(cr, uid, group, picking, move_line, + invoice_id, invoice_vals, context=context), + context=context) self._invoice_line_hook(cr, uid, move_line, invoice_line_id) invoice_obj.button_compute(cr, uid, [invoice_id], context=context, From 299026589d9e9e8574f5ebcfed79a605c4a1f59f Mon Sep 17 00:00:00 2001 From: Numerigraphe - Lionel Sausin Date: Mon, 16 Jan 2012 16:37:35 +0100 Subject: [PATCH 041/248] [FIX] l10n_fr: incorrect name for chart of accounts template bzr revid: ls@numerigraphe.fr-20120116153735-htsceg2a8fpu3r5b --- addons/l10n_fr/fr_pcg_taxes_demo.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/l10n_fr/fr_pcg_taxes_demo.xml b/addons/l10n_fr/fr_pcg_taxes_demo.xml index 54a8d2d7444..de078b4a82a 100644 --- a/addons/l10n_fr/fr_pcg_taxes_demo.xml +++ b/addons/l10n_fr/fr_pcg_taxes_demo.xml @@ -358,7 +358,7 @@ - France PCMN + Plan Comptable Général (France) From 5c3df6b9cd7e64db6934af82de6a61cf06d2bcaf Mon Sep 17 00:00:00 2001 From: "Jagdish Panchal (Open ERP)" Date: Tue, 17 Jan 2012 12:58:41 +0530 Subject: [PATCH 042/248] [FIX] Account_analytic_default_view.xml: correct the help string on company button lp bug: https://launchpad.net/bugs/916187 fixed bzr revid: jap@tinyerp.com-20120117072841-0ifxcf6hfyisz94x --- .../account_analytic_default/account_analytic_default_view.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/account_analytic_default/account_analytic_default_view.xml b/addons/account_analytic_default/account_analytic_default_view.xml index 753765019f6..d3d8a8c2022 100644 --- a/addons/account_analytic_default/account_analytic_default_view.xml +++ b/addons/account_analytic_default/account_analytic_default_view.xml @@ -61,7 +61,7 @@ - + From 5f4c443a02c572f3255c5c730e79afe2c3ba4c55 Mon Sep 17 00:00:00 2001 From: "ksa (OpenERP)" Date: Tue, 17 Jan 2012 14:10:38 +0530 Subject: [PATCH 043/248] [FIX]:mrp unclear text lp bug: https://launchpad.net/bugs/916539 fixed bzr revid: ksa@tinyerp.com-20120117084038-r65jh2j7dcnrion1 --- addons/mrp_operations/mrp_operations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/mrp_operations/mrp_operations.py b/addons/mrp_operations/mrp_operations.py index 12e30ca9b0b..e8e83cef7ff 100644 --- a/addons/mrp_operations/mrp_operations.py +++ b/addons/mrp_operations/mrp_operations.py @@ -97,7 +97,7 @@ class mrp_production_workcenter_line(osv.osv): 'date_planned_end': fields.function(_get_date_end, string='End Date', type='datetime'), 'date_start': fields.datetime('Start Date'), 'date_finished': fields.datetime('End Date'), - 'delay': fields.float('Working Hours',help="This is lead time between operation start and stop in this Work Center",readonly=True), + 'delay': fields.float('Working Hours',help="This is delay time between operation start and stop in this Work Center",readonly=True), 'production_state':fields.related('production_id','state', type='selection', selection=[('draft','Draft'),('picking_except', 'Picking Exception'),('confirmed','Waiting Goods'),('ready','Ready to Produce'),('in_production','In Production'),('cancel','Canceled'),('done','Done')], From 31db4ea87c2c250f28bc92eb715a4711f4ac8445 Mon Sep 17 00:00:00 2001 From: "ksa (OpenERP)" Date: Tue, 17 Jan 2012 15:38:36 +0530 Subject: [PATCH 044/248] [FIX]:string correction for purchase lp bug: https://launchpad.net/bugs/916485 fixed bzr revid: ksa@tinyerp.com-20120117100836-38ecauwmtgtu2kdv --- addons/purchase/wizard/purchase_installer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/purchase/wizard/purchase_installer.py b/addons/purchase/wizard/purchase_installer.py index a96d07f6caf..74b557b9b35 100644 --- a/addons/purchase/wizard/purchase_installer.py +++ b/addons/purchase/wizard/purchase_installer.py @@ -28,7 +28,7 @@ class purchase_config_wizard(osv.osv_memory): 'default_method' : fields.selection( [('manual', 'Based on Purchase Order Lines'), ('picking', 'Based on Receptions'), - ('order', 'Pre-Generate Draft Invoices on Based Purchase Orders'), + ('order', 'Pre-Generate Draft Invoices Based on Purchase Orders'), ], 'Default Invoicing Control Method', required=True, ) } From 04c98a8a9986a7541ec845a10454d5c88db1721e Mon Sep 17 00:00:00 2001 From: Vishal Parmar Date: Tue, 17 Jan 2012 16:21:16 +0530 Subject: [PATCH 045/248] [FIX] email_template: set colspan lp bug: https://launchpad.net/bugs/917516 fixed bzr revid: kjo@tinyerp.com-20120117105116-yc8eo5ij0d2owo1v --- addons/email_template/email_template_view.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/email_template/email_template_view.xml b/addons/email_template/email_template_view.xml index 1f3b9aef949..3d56f4e6601 100644 --- a/addons/email_template/email_template_view.xml +++ b/addons/email_template/email_template_view.xml @@ -24,7 +24,7 @@ - + @@ -79,7 +79,7 @@ - + From 79ceef507d380831ab6ca1d555bf08100ab13140 Mon Sep 17 00:00:00 2001 From: "Mayur Maheshwari (OpenERP)" Date: Tue, 17 Jan 2012 16:35:50 +0530 Subject: [PATCH 046/248] [FIX]delivery:added a normal price field in demo data and set a variable lp bug: https://launchpad.net/bugs/915404 fixed bzr revid: mma@tinyerp.com-20120117110550-u8g36mguxeh53fgg --- addons/delivery/delivery.py | 4 ++-- addons/delivery/delivery_demo.xml | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/delivery/delivery.py b/addons/delivery/delivery.py index 4b1d588a53e..2ee0544c82e 100644 --- a/addons/delivery/delivery.py +++ b/addons/delivery/delivery.py @@ -124,9 +124,8 @@ class delivery_carrier(osv.osv): grid_line_pool.unlink(cr, uid, lines, context=context) #create the grid lines - line_data = None if record.free_if_more_than: - line_data = { + data = { 'grid_id': grid_id and grid_id[0], 'name': _('Free if more than %.2f') % record.amount, 'type': 'price', @@ -135,6 +134,7 @@ class delivery_carrier(osv.osv): 'standard_price': 0.0, 'list_price': 0.0, } + grid_line_pool.create(cr, uid, data, context=context) if record.normal_price: line_data = { 'grid_id': grid_id and grid_id[0], diff --git a/addons/delivery/delivery_demo.xml b/addons/delivery/delivery_demo.xml index acc17e20eae..427f943890b 100644 --- a/addons/delivery/delivery_demo.xml +++ b/addons/delivery/delivery_demo.xml @@ -31,6 +31,7 @@ Free delivery charges + 10 True 1000 From 45d3b74350743bcaa8ba0a2dd148d741b599ef75 Mon Sep 17 00:00:00 2001 From: "Mayur Maheshwari (OpenERP)" Date: Tue, 17 Jan 2012 16:43:33 +0530 Subject: [PATCH 047/248] [FIX]delivery:remove a if line bzr revid: mma@tinyerp.com-20120117111333-eogxcf539s3rb4o2 --- addons/delivery/delivery.py | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/delivery/delivery.py b/addons/delivery/delivery.py index 2ee0544c82e..19913ac6837 100644 --- a/addons/delivery/delivery.py +++ b/addons/delivery/delivery.py @@ -145,7 +145,6 @@ class delivery_carrier(osv.osv): 'standard_price': record.normal_price, 'list_price': record.normal_price, } - if line_data: grid_line_pool.create(cr, uid, line_data, context=context) return True From 3635ade2e4cb00972c95f21305cfd9e4e67663e0 Mon Sep 17 00:00:00 2001 From: "Mayur Maheshwari (OpenERP)" Date: Tue, 17 Jan 2012 17:35:31 +0530 Subject: [PATCH 048/248] [FIX]procurement: added read method instead of browse method lp bug: https://launchpad.net/bugs/915404 fixed bzr revid: mma@tinyerp.com-20120117120531-xg0acpsb4vt3gwe3 --- addons/procurement/schedulers.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/procurement/schedulers.py b/addons/procurement/schedulers.py index 6ad04bb6759..0c6731c40c2 100644 --- a/addons/procurement/schedulers.py +++ b/addons/procurement/schedulers.py @@ -180,10 +180,11 @@ class procurement_order(osv.osv): for warehouse in warehouse_obj.browse(cr, uid, warehouse_ids, context=context): context['warehouse'] = warehouse - for product in product_obj.browse(cr, uid, products_id, context=context): - if product.virtual_available >= 0.0: + for product_availability in product_obj.read(cr, uid, products_id, ['virtual_available'], context=context): + if product_availability['virtual_available'] >= 0.0: continue + product = product_obj.browse(cr, uid, [product_availability['id']], context=context)[0] if product.supply_method == 'buy': location_id = warehouse.lot_input_id.id elif product.supply_method == 'produce': From f554ff10861c061aaafa5854b5188aca3f68c995 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulius=20Sladkevi=C4=8Dius?= Date: Tue, 17 Jan 2012 18:43:18 +0200 Subject: [PATCH 049/248] [FIX] account_asset, _compute_entries method depreciation line search bzr revid: paulius@inovera.lt-20120117164318-oqko4wba68577hpz --- addons/account_asset/account_asset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/account_asset/account_asset.py b/addons/account_asset/account_asset.py index 0b6f5b7feac..97aec1d8487 100644 --- a/addons/account_asset/account_asset.py +++ b/addons/account_asset/account_asset.py @@ -309,7 +309,7 @@ class account_asset_asset(osv.osv): period_obj = self.pool.get('account.period') depreciation_obj = self.pool.get('account.asset.depreciation.line') period = period_obj.browse(cr, uid, period_id, context=context) - depreciation_ids = depreciation_obj.search(cr, uid, [('asset_id', 'in', ids), ('depreciation_date', '<', period.date_stop), ('depreciation_date', '>', period.date_start), ('move_check', '=', False)], context=context) + depreciation_ids = depreciation_obj.search(cr, uid, [('asset_id', 'in', ids), ('depreciation_date', '<=', period.date_stop), ('depreciation_date', '>=', period.date_start), ('move_check', '=', False)], context=context) return depreciation_obj.create_move(cr, uid, depreciation_ids, context=context) def create(self, cr, uid, vals, context=None): From 26e17799a492e22682dbe04c5014dac9b93edfce Mon Sep 17 00:00:00 2001 From: "Mayur Maheshwari (OpenERP)" Date: Wed, 18 Jan 2012 14:18:54 +0530 Subject: [PATCH 050/248] [FIX]stock: set a read rights to the user in stock.move lp bug: https://launchpad.net/bugs/917333 fixed bzr revid: mma@tinyerp.com-20120118084854-rpq7u420uxdvcepy --- addons/purchase/security/ir.model.access.csv | 2 +- addons/stock/security/ir.model.access.csv | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/purchase/security/ir.model.access.csv b/addons/purchase/security/ir.model.access.csv index efee0adc589..0ea49a9900b 100644 --- a/addons/purchase/security/ir.model.access.csv +++ b/addons/purchase/security/ir.model.access.csv @@ -6,7 +6,7 @@ access_purchase_order_line_manager,purchase.order.line manager,model_purchase_or access_stock_location_purchase_user,stock.location,stock.model_stock_location,group_purchase_user,1,0,0,0 access_stock_warehouse_purchase_user,stock.warehouse,stock.model_stock_warehouse,group_purchase_user,1,0,0,0 access_stock_picking_purchase_user,stock.picking,stock.model_stock_picking,group_purchase_user,1,1,1,1 -access_stock_move_purchase_user,stock.move,stock.model_stock_move,group_purchase_user,1,1,1,1 +access_stock_move_purchase_user,stock.move,stock.model_stock_move,group_purchase_user,1,0,0,0 access_purchase_order_stock_worker,purchase.order,model_purchase_order,stock.group_stock_user,1,0,0,0 access_purchase_order_line_stock_worker,purchase.order.line,model_purchase_order_line,stock.group_stock_user,1,0,0,0 access_account_tax_purchase_user,account.tax,account.model_account_tax,group_purchase_user,1,0,0,0 diff --git a/addons/stock/security/ir.model.access.csv b/addons/stock/security/ir.model.access.csv index f65ef8d5e79..a391f117393 100644 --- a/addons/stock/security/ir.model.access.csv +++ b/addons/stock/security/ir.model.access.csv @@ -17,7 +17,7 @@ access_stock_production_lot_manager,stock.production.lot manager,model_stock_pro access_stock_production_lot_user,stock.production.lot user,model_stock_production_lot,stock.group_stock_user,1,1,1,1 access_stock_production_lot_revision,stock.production.lot.revision,model_stock_production_lot_revision,stock.group_stock_user,1,1,1,1 access_stock_move_manager,stock.move manager,model_stock_move,stock.group_stock_manager,1,1,0,0 -access_stock_move_user,stock.move user,model_stock_move,stock.group_stock_user,1,1,1,1 +access_stock_move_user,stock.move user,model_stock_move,stock.group_stock_user,1,0,0,0 access_stock_inventory_user,stock.inventory user,model_stock_inventory,stock.group_stock_user,1,1,1,1 access_stock_inventory_manager,stock.inventory manager,model_stock_inventory,stock.group_stock_manager,1,0,0,0 access_stock_inventory_line_user,stock.inventory.line user,model_stock_inventory_line,stock.group_stock_user,1,1,1,1 From 3bc2de99d29f2a701578a27395926161737e72a6 Mon Sep 17 00:00:00 2001 From: "Jagdish Panchal (Open ERP)" Date: Wed, 18 Jan 2012 15:44:28 +0530 Subject: [PATCH 051/248] [FIX] account_invoice.py: Replace the domain on partner_bank_id in customer refund and supplier refund lp bug: https://launchpad.net/bugs/914282 fixed bzr revid: jap@tinyerp.com-20120118101428-dxv29dtld7ufhqb7 --- addons/account/account_invoice.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py index 166d146829b..6b3d8468368 100644 --- a/addons/account/account_invoice.py +++ b/addons/account/account_invoice.py @@ -316,6 +316,15 @@ class account_invoice(osv.osv): res['fields'][field]['selection'] = journal_select doc = etree.XML(res['arch']) + + if context.get('type', False): + for node in doc.xpath("//field[@name='partner_bank_id']"): + if context['type'] == 'in_refund': + node.set('domain', "[('partner_id.ref_companies', 'in', [company_id])]") + if context['type'] == 'out_refund': + node.set('domain', "[('parnter_id', '=', parnter_id)]") + res['arch'] = etree.tostring(doc) + if view_type == 'search': if context.get('type', 'in_invoice') in ('out_invoice', 'out_refund'): for node in doc.xpath("//group[@name='extended filter']"): From 0694c25836f54fde3f5fbf1f51f6ca3f028a5a14 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Wed, 18 Jan 2012 11:40:15 +0100 Subject: [PATCH 052/248] [FIX] convert XML documents to HTML in MSIE so jQuery does not bork its parsing done via DOM traversal, slow as shit and currently drops half the attributes bzr revid: xmo@openerp.com-20120118104015-ot102e8yniqjd4bf --- addons/web/static/lib/qweb/qweb2.js | 51 +++++++++++++++++++---------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/addons/web/static/lib/qweb/qweb2.js b/addons/web/static/lib/qweb/qweb2.js index 8657a8b20be..7dcac2e5909 100644 --- a/addons/web/static/lib/qweb/qweb2.js +++ b/addons/web/static/lib/qweb/qweb2.js @@ -93,10 +93,10 @@ var QWeb2 = { } return r.join(''); } else { - if (node.xml !== undefined) { - return node.xml; - } else { + if (typeof XMLSerializer !== 'undefined') { return (new XMLSerializer()).serializeToString(node); + } else { + return node.outerHTML; } } }, @@ -265,11 +265,16 @@ QWeb2.Engine = (function() { } req.open('GET', s, false); req.send(null); - if (req.responseXML) { - if (req.responseXML.documentElement.nodeName == "parsererror") { - return this.tools.exception(req.responseXML.documentElement.childNodes[0].nodeValue); + var xDoc = req.responseXML; + if (xDoc) { + if (xDoc.documentElement.nodeName == "parsererror") { + return this.tools.exception(xDoc.documentElement.childNodes[0].nodeValue); } - return req.responseXML; + if (xDoc.xml !== undefined) { + // MSIE + return this.convert_xml_to_html(xDoc.documentElement); + } + return xDoc; } else { return this.load_xml_string(req.responseText); } @@ -295,7 +300,27 @@ QWeb2.Engine = (function() { xDoc.async = false; xDoc.preserveWhiteSpace = true; xDoc.loadXML(s); - return xDoc; + return this.convert_xml_to_html(xDoc.documentElement); + }, + convert_xml_to_html: function (node) { + var character_data = { + 3: document.createTextNode, + 4: document.createCDATASection, + 8: document.createComment + }; + if (node.nodeType in character_data) { + return character_data[node.nodeType](node.data); + } + + var hnode = document.createElement(node.nodeName); + for(var i=0, alen=node.attributes.length; i < alen; ++i) { + var attr = node.attributes[i]; + hnode.setAttribute(attr.name, attr.value); + } + for(var j=0, clen=node.childNodes.length; j < clen; ++j) { + hnode.appendChild(this.convert_xml_to_html(node.childNodes[j])); + } + return hnode; }, has_template : function(template) { return !!this.templates[template]; @@ -373,12 +398,7 @@ QWeb2.Engine = (function() { if (!this.jQuery) { return this.tools.exception("Can't extend template " + template + " without jQuery"); } - var template_dest = this.templates[template], - msie_trololo = false; - if (template_dest.xml !== undefined) { - template_dest = this.jQuery(template_dest.xml); - msie_trololo = true; - } + var template_dest = this.templates[template]; for (var i = 0, ilen = extend_node.childNodes.length; i < ilen; i++) { var child = extend_node.childNodes[i]; if (child.nodeType === 1) { @@ -421,9 +441,6 @@ QWeb2.Engine = (function() { } } } - if (msie_trololo) { - this.templates[template] = template_dest[0]; - } } }); return Engine; From 44f4444807ffa6b7641e79a3965aef4628fa5d91 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Wed, 18 Jan 2012 11:46:46 +0100 Subject: [PATCH 053/248] [REM] incorrect link to local jQuery bzr revid: xmo@openerp.com-20120118104646-2auwjwcr5lag2g5c --- addons/web/static/lib/qweb/qweb-test.js.html | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/web/static/lib/qweb/qweb-test.js.html b/addons/web/static/lib/qweb/qweb-test.js.html index fda837497c4..5c08d10d57c 100644 --- a/addons/web/static/lib/qweb/qweb-test.js.html +++ b/addons/web/static/lib/qweb/qweb-test.js.html @@ -5,7 +5,6 @@ -