diff --git a/addons/account/account.py b/addons/account/account.py index 61e1fb021a9..38ed96d4aac 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -139,7 +139,7 @@ class account_account_type(osv.osv): 'Balance' will generally be used for cash accounts. 'Detail' will copy each existing journal item of the previous year, even the reconciled ones. 'Unreconciled' will copy only the journal items that were unreconciled on the first day of the new fiscal year."""), - 'sign': fields.selection([(-1, 'Negative'), (1, 'Positive')], 'Sign on Reports', required=True, help='Allows you to change the sign of the balance amount displayed in the reports, so that you can see positive figures instead of negative ones in expenses accounts.'), + 'sign': fields.selection([(-1, 'Reverse balance sign'), (1, 'Preserve balance sign')], 'Sign on Reports', required=True, help='For accounts that are typically more debited than credited and that you would like to print as negative amounts in your reports, you should reverse the sign of the balance; e.g.: Expense account. The same applies for accounts that are typically more credited than debited and that you would like to print as positive amounts in your reports; e.g.: Income account.'), 'report_type':fields.selection([ ('none','/'), ('income','Profit & Loss (Income Accounts)'), @@ -2637,6 +2637,10 @@ class account_fiscal_position_account_template(osv.osv): account_fiscal_position_account_template() +# --------------------------------------------------------- +# Account Financial Report +# --------------------------------------------------------- + class account_financial_report(osv.osv): _name = "account.financial.report" _description = "Account Report" @@ -2691,17 +2695,19 @@ class account_financial_report(osv.osv): 'parent_id': fields.many2one('account.financial.report', 'Parent'), 'children_ids': fields.one2many('account.financial.report', 'parent_id', 'Account Report'), 'sequence': fields.integer('Sequence'), + 'note': fields.text('Notes'), + 'balance': fields.function(_get_balance, 'Balance'), + 'level': fields.function(_get_level, string='Level', store=True, type='integer'), 'type': fields.selection([ - ('sum','Sum'), + ('sum','View'), ('accounts','Accounts'), - ('account_report','Account Report'), + ('account_type','Account Type'), + ('account_report','Report Value'), ],'Type'), 'account_ids': fields.many2many('account.account', 'account_account_financial_report', 'report_line_id', 'account_id', 'Accounts'), - 'note': fields.text('Notes'), - 'account_report_id': fields.many2one('account.financial.report', 'Account Report'), - 'balance': fields.function(_get_balance, 'Balance'), - 'display_detail': fields.boolean('Display the account list'), - 'level': fields.function(_get_level, string='Level', store=True, type='integer'), + 'display_detail': fields.boolean('Display details', help='Display every account with its balance instead of the sum.'), + 'account_report_id': fields.many2one('account.financial.report', 'Report Value'), + 'account_type_ids': fields.many2many('account.account.type', 'account_account_financial_report_type', 'report_id', 'account_type_id', 'Account Types'), } _defaults = { @@ -2710,7 +2716,9 @@ class account_financial_report(osv.osv): account_financial_report() - # Multi charts of Accounts wizard +# --------------------------------------------------------- +# Account generation from template wizards +# --------------------------------------------------------- class wizard_multi_charts_accounts(osv.osv_memory): """ diff --git a/addons/account/account_view.xml b/addons/account/account_view.xml index 1055a4a164a..b22274f4546 100644 --- a/addons/account/account_view.xml +++ b/addons/account/account_view.xml @@ -749,6 +749,7 @@ + @@ -2713,16 +2714,27 @@ action = pool.get('res.config').next(cr, uid, [], context) form
- - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + @@ -2763,7 +2775,7 @@ action = pool.get('res.config').next(cr, uid, [], context) - Account Reports + Financial Reports ir.actions.act_window account.financial.report form @@ -2790,7 +2802,7 @@ action = pool.get('res.config').next(cr, uid, [], context) - Account Reports Hierarchy + Financial Reports Hierarchy account.financial.report tree diff --git a/addons/account/i18n/ar.po b/addons/account/i18n/ar.po index c0c60f617c3..d8dcf40a2d3 100644 --- a/addons/account/i18n/ar.po +++ b/addons/account/i18n/ar.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 6.0dev\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2011-09-05 23:09+0000\n" +"PO-Revision-Date: 2011-09-22 02:55+0000\n" "Last-Translator: Majed Majbour \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-17 04:55+0000\n" -"X-Generator: Launchpad (build 13955)\n" +"X-Launchpad-Export-Date: 2011-09-22 04:48+0000\n" +"X-Generator: Launchpad (build 13996)\n" #. module: account #: model:process.transition,name:account.process_transition_supplierreconcilepaid0 @@ -48,7 +48,7 @@ msgstr "" #. module: account #: field:account.installer.modules,account_voucher:0 msgid "Voucher Management" -msgstr "" +msgstr "إدارة القسائم" #. module: account #: view:account.account:0 @@ -68,7 +68,7 @@ msgstr "متبقي" #: code:addons/account/invoice.py:785 #, python-format msgid "Please define sequence on invoice journal" -msgstr "" +msgstr "يرجى تحديد تسلسل على الفاتورة" #. module: account #: constraint:account.period:0 @@ -134,7 +134,7 @@ msgstr "المدخلات المحاسبية -" #: code:addons/account/account.py:1291 #, python-format msgid "You can not delete posted movement: \"%s\"!" -msgstr "" +msgstr "لا يمكنك حذف حركة تم ترحيلها: \"%s\"!" #. module: account #: report:account.invoice:0 @@ -173,6 +173,8 @@ msgid "" "If the active field is set to False, it will allow you to hide the payment " "term without removing it." msgstr "" +"إذا تم تعيين الحقل النشط إلى خطأ ، فإنه سيسمح لك بإخفاء مدة السداد دون " +"إزالتها." #. module: account #: code:addons/account/invoice.py:1421 diff --git a/addons/account/partner.py b/addons/account/partner.py index 6ff3879889c..36fd88183f2 100644 --- a/addons/account/partner.py +++ b/addons/account/partner.py @@ -28,12 +28,17 @@ class account_fiscal_position(osv.osv): _description = 'Fiscal Position' _columns = { 'name': fields.char('Fiscal Position', size=64, required=True), + 'active': fields.boolean('Active', help="By unchecking the active field, you may hide a fiscal position without deleting it."), 'company_id': fields.many2one('res.company', 'Company'), 'account_ids': fields.one2many('account.fiscal.position.account', 'position_id', 'Account Mapping'), 'tax_ids': fields.one2many('account.fiscal.position.tax', 'position_id', 'Tax Mapping'), 'note': fields.text('Notes', translate=True), } + _defaults = { + 'active': True, + } + def map_tax(self, cr, uid, fposition_id, taxes, context=None): if not taxes: return [] diff --git a/addons/account/partner_view.xml b/addons/account/partner_view.xml index fbee97875ae..706fa4683cb 100644 --- a/addons/account/partner_view.xml +++ b/addons/account/partner_view.xml @@ -8,8 +8,11 @@ form
- - + + + + + diff --git a/addons/account/report/account_aged_partner_balance.rml b/addons/account/report/account_aged_partner_balance.rml index ace66af0584..fb79ab0d199 100644 --- a/addons/account/report/account_aged_partner_balance.rml +++ b/addons/account/report/account_aged_partner_balance.rml @@ -196,25 +196,25 @@ Account Total - [[ formatLang(get_direction('6')) ]] [[ company.currency_id.symbol ]] + [[ formatLang(get_direction('6'), currency_obj=company.currency_id) ]] - [[ formatLang(get_for_period('4')) ]] [[ company.currency_id.symbol ]] + [[ formatLang(get_for_period('4'), currency_obj=company.currency_id) ]] - [[ formatLang(get_for_period('3')) ]] [[ company.currency_id.symbol ]] + [[ formatLang(get_for_period('3'), currency_obj=company.currency_id) ]] - [[ formatLang(get_for_period('2')) ]] [[ company.currency_id.symbol ]] + [[ formatLang(get_for_period('2'), currency_obj=company.currency_id) ]] - [[ formatLang(get_for_period('1')) ]] [[ company.currency_id.symbol ]] + [[ formatLang(get_for_period('1'), currency_obj=company.currency_id) ]] - [[ formatLang(get_for_period('0')) ]] [[ company.currency_id.symbol ]] + [[ formatLang(get_for_period('0'), currency_obj=company.currency_id) ]] - [[ formatLang(get_total('5')) ]] [[ company.currency_id.symbol ]] + [[ formatLang(get_total('5'), currency_obj=company.currency_id) ]] @@ -224,25 +224,25 @@ [[ partner['name'] ]] - [[ formatLang(partner['direction']) ]] [[ company.currency_id.symbol ]] + [[ formatLang(partner['direction'], currency_obj=company.currency_id) ]] - [[ formatLang(partner['4'])]] [[ company.currency_id.symbol ]] + [[ formatLang(partner['4'], currency_obj=company.currency_id) ]] - [[ formatLang(partner['3'])]] [[ company.currency_id.symbol ]] + [[ formatLang(partner['3'], currency_obj=company.currency_id) ]] - [[ formatLang(partner['2']) ]] [[ company.currency_id.symbol ]] + [[ formatLang(partner['2'], currency_obj=company.currency_id) ]] - [[ formatLang(partner['1']) ]] [[ company.currency_id.symbol ]] + [[ formatLang(partner['1'], currency_obj=company.currency_id) ]] - [[ formatLang(partner['0']) ]] [[ company.currency_id.symbol ]] + [[ formatLang(partner['0'], currency_obj=company.currency_id) ]] - [[ formatLang(partner['total']) ]] [[ company.currency_id.symbol ]] + [[ formatLang(partner['total'], currency_obj=company.currency_id) ]] @@ -251,25 +251,25 @@ [[ not_partner['name'] ]] - [[ formatLang(not_partner['direction']) ]] [[ company.currency_id.symbol ]] + [[ formatLang(not_partner['direction'], currency_obj=company.currency_id) ]] - [[ formatLang(not_partner['4'])]] [[ company.currency_id.symbol ]] + [[ formatLang(not_partner['4'], currency_obj=company.currency_id) ]] - [[ formatLang(not_partner['3'])]] [[ company.currency_id.symbol ]] + [[ formatLang(not_partner['3'], currency_obj=company.currency_id) ]] - [[ formatLang(not_partner['2']) ]] [[ company.currency_id.symbol ]] + [[ formatLang(not_partner['2'], currency_obj=company.currency_id) ]] - [[ formatLang(not_partner['1']) ]] [[ company.currency_id.symbol ]] + [[ formatLang(not_partner['1'], currency_obj=company.currency_id) ]] - [[ formatLang(not_partner['0']) ]] [[ company.currency_id.symbol ]] + [[ formatLang(not_partner['0'], currency_obj=company.currency_id) ]] - [[ formatLang(not_partner['total']) ]] [[ company.currency_id.symbol ]] + [[ formatLang(not_partner['total'], currency_obj=company.currency_id) ]] diff --git a/addons/account/report/account_balance.rml b/addons/account/report/account_balance.rml index fac964eb46d..b7e729a738e 100644 --- a/addons/account/report/account_balance.rml +++ b/addons/account/report/account_balance.rml @@ -296,7 +296,7 @@ [[ (a['type']<>'view' and setTag('para','para',{'fontName':"Helvetica"})) or removeParentNode('font') ]][[ '..'*(a['level']-1) ]][[ a['name'] ]] [[ (a['type']<>'view' and setTag('para','para',{'fontName':"Helvetica"})) or removeParentNode('font') ]][[ a['type']=='view' and removeParentNode('font') ]][[ formatLang(a['debit']) ]][[ a['type']<>'view' and removeParentNode('font') ]] [[formatLang(a['debit']) ]] [[ (a['type']<>'view' and setTag('para','para',{'fontName':"Helvetica"})) or removeParentNode('font')]][[ a['type']=='view' and removeParentNode('font') ]][[ formatLang(a['credit']) ]][[ a['type']<>'view' and removeParentNode('font') ]] [[ formatLang(a['credit']) ]] - [[ (a['type']<>'view' and setTag('para','para',{'fontName':"Helvetica"})) or removeParentNode('font') ]][[ a['type']=='view' and removeParentNode('font') ]][[ formatLang(a['balance']) ]] [[ company.currency_id.symbol ]][[ a['type']<>'view' and removeParentNode('font') ]] [[ formatLang(a['balance']) ]] [[ company.currency_id.symbol ]] + [[ (a['type']<>'view' and setTag('para','para',{'fontName':"Helvetica"})) or removeParentNode('font') ]][[ a['type']=='view' and removeParentNode('font') ]][[ formatLang(a['balance'], currency_obj=company.currency_id) ]][[ a['type']<>'view' and removeParentNode('font') ]] [[ formatLang(a['balance'], currency = company.currency_id) ]] diff --git a/addons/account/report/account_balance_sheet.py b/addons/account/report/account_balance_sheet.py index b1e51e6fc46..ce9e3c51f06 100644 --- a/addons/account/report/account_balance_sheet.py +++ b/addons/account/report/account_balance_sheet.py @@ -136,7 +136,7 @@ class report_balancesheet_horizontal(report_sxw.rml_parse, common_report_header) 'code': account.code, 'name': account.name, 'level': account.level, - 'balance':account.balance, + 'balance': account.balance != 0 and account.balance * account.user_type.sign or account.balance, 'type': account.type, } currency = account.currency_id and account.currency_id or account.company_id.currency_id diff --git a/addons/account/report/account_balance_sheet.rml b/addons/account/report/account_balance_sheet.rml index 8b9f6d1b5a3..11b37af6abe 100644 --- a/addons/account/report/account_balance_sheet.rml +++ b/addons/account/report/account_balance_sheet.rml @@ -240,8 +240,8 @@ [[ setTag('tr','tr',{'style': 'Table'+str(min(3,a['level']))}) ]] [[ (a['type'] =='view' and a['level'] >= 3) and setTag('para','para',{'style': 'terp_level_3_code_bold'}) or setTag('para','para',{'style': 'terp_level_'+str(min(3,a['level']))+'_code'}) ]][[ a['code'] ]] [[ (a['type'] =='view' and a['level'] >= 3) and setTag('para','para',{'style': 'terp_level_'+str(min(3,a['level']))+'_name_bold'}) or setTag('para','para',{'style': 'terp_level_'+str(min(4,a['level']))+'_name'}) ]][[ a['name'] ]] - [[ (a['level'] <>2) or removeParentNode('td') ]][[ (a['type'] =='view' and a['level'] >= 3) and setTag('para','para',{'style': 'terp_level_3_balance_bold'}) or setTag('para','para',{'style': 'terp_level_'+str(min(3,a['level']))+'_balance'}) ]][[ formatLang(a['balance']) ]] [[company.currency_id.symbol ]] - [[ a['level'] == 2 or removeParentNode('td') ]][[ formatLang(a['balance']) ]] [[company.currency_id.symbol ]] + [[ (a['level'] <>2) or removeParentNode('td') ]][[ (a['type'] =='view' and a['level'] >= 3) and setTag('para','para',{'style': 'terp_level_3_balance_bold'}) or setTag('para','para',{'style': 'terp_level_'+str(min(3,a['level']))+'_balance'}) ]][[ formatLang(a['balance'], currency = company.currency_id) ]] + [[ a['level'] == 2 or removeParentNode('td') ]][[ formatLang(a['balance'], currency = company.currency_id) ]] @@ -250,7 +250,7 @@ Balance: - [[ formatLang(sum_cr()) ]] [[ company.currency_id.symbol ]] + [[ formatLang(sum_cr(), currency = company.currency_id) ]] @@ -282,8 +282,8 @@ [[ setTag('tr','tr',{'style': 'Table'+str(min(3,a['level']))}) ]] [[ (a['type'] =='view' and a['level'] >= 3) and setTag('para','para',{'style': 'terp_level_3_code_bold'}) or setTag('para','para',{'style': 'terp_level_'+str(min(3,a['level']))+'_code'}) ]][[ a['code'] ]] [[ (a['type'] =='view' and a['level'] >= 3) and setTag('para','para',{'style': 'terp_level_'+str(min(3,a['level']))+'_name_bold'}) or setTag('para','para',{'style': 'terp_level_'+str(min(4,a['level']))+'_name'}) ]][[ a['name'] ]] - [[ (a['level'] <>2) or removeParentNode('td') ]][[ (a['type'] =='view' and a['level'] >= 3) and setTag('para','para',{'style': 'terp_level_3_balance_bold'}) or setTag('para','para',{'style': 'terp_level_'+str(min(3,a['level']))+'_balance'}) ]][[ formatLang(a['balance']) ]] [[company.currency_id.symbol ]] - [[ a['level'] == 2 or removeParentNode('td') ]][[ formatLang(a['balance']) ]] [[company.currency_id.symbol ]] + [[ (a['level'] <>2) or removeParentNode('td') ]][[ (a['type'] =='view' and a['level'] >= 3) and setTag('para','para',{'style': 'terp_level_3_balance_bold'}) or setTag('para','para',{'style': 'terp_level_'+str(min(3,a['level']))+'_balance'}) ]][[ formatLang(a['balance'], currency = company.currency_id) ]] + [[ a['level'] == 2 or removeParentNode('td') ]][[ formatLang(a['balance'], currency = company.currency_id) ]] @@ -292,7 +292,7 @@ Balance: - [[ formatLang(sum_dr()) ]] [[ company.currency_id.symbol ]] + [[ formatLang(sum_dr(), currency = company.currency_id) ]] diff --git a/addons/account/report/account_balance_sheet_horizontal.rml b/addons/account/report/account_balance_sheet_horizontal.rml index 0ecc907e0b4..ce442b7b136 100644 --- a/addons/account/report/account_balance_sheet_horizontal.rml +++ b/addons/account/report/account_balance_sheet_horizontal.rml @@ -207,7 +207,7 @@ - [[ a['level1']<4 and ( setTag('para','para',{'style':'terp_default_Right_9_Bold'})) or removeParentNode('font') ]][[ formatLang(a['balance1']) ]] [[ company.currency_id.symbol ]] + [[ a['level1']<4 and ( setTag('para','para',{'style':'terp_default_Right_9_Bold'})) or removeParentNode('font') ]][[ formatLang(a['balance1'], currency_obj=company.currency_id) ]] @@ -224,7 +224,7 @@ [[ ( a['level']<4 or a['name']=='Net Profit') and ( setTag('para','para',{'style':'terp_default_Right_9_Bold'})) or removeParentNode('font') ]] - [[(a['code'] and a['name']) and formatLang(a['balance']) or removeParentNode('font')]] [[ company.currency_id.symbol ]] + [[(a['code'] and a['name']) and formatLang(a['balance'], currency_obj=company.currency_id) or removeParentNode('font')]] @@ -235,13 +235,13 @@ Balance: - [[ formatLang(sum_cr()) ]] [[ company.currency_id.symbol ]] + [[ formatLang(sum_cr(), currency_obj=company.currency_id) ) ]] Balance: - [[ formatLang(sum_dr()) ]] [[ company.currency_id.symbol ]] + [[ formatLang(sum_dr(), currency_obj=company.currency_id) ) ]] diff --git a/addons/account/report/account_central_journal.rml b/addons/account/report/account_central_journal.rml index fe064132cbc..534baf05abe 100644 --- a/addons/account/report/account_central_journal.rml +++ b/addons/account/report/account_central_journal.rml @@ -298,7 +298,7 @@ [[ formatLang( sum_debit(o.period_id.id, o.journal_id.id)) ]] [[ formatLang( sum_credit(o.period_id.id, o.journal_id.id)) ]] - [[ formatLang( sum_credit(o.period_id.id, o.journal_id.id)-sum_debit(o.period_id.id, o.journal_id.id) ) ]] [[ company.currency_id.symbol ]] + [[ formatLang( sum_credit(o.period_id.id, o.journal_id.id)-sum_debit(o.period_id.id, o.journal_id.id), currency_obj=company.currency_id ) ]] [[ display_currency(data) or removeParentNode('blockTable') ]] @@ -307,7 +307,7 @@ [[ formatLang( sum_debit(o.period_id.id, o.journal_id.id)) ]] [[ formatLang( sum_credit(o.period_id.id, o.journal_id.id)) ]] - [[ formatLang( sum_credit(o.period_id.id, o.journal_id.id)-sum_debit(o.period_id.id, o.journal_id.id) ) ]] [[ company.currency_id.symbol ]] + [[ formatLang( sum_credit(o.period_id.id, o.journal_id.id)-sum_debit(o.period_id.id, o.journal_id.id), currency_obj=company.currency_id ) ]] @@ -319,7 +319,7 @@ [[ line['name'] ]] [[ formatLang(line['debit']) ]] [[ formatLang(line['credit'])]] - [[ formatLang(line['credit']-line['debit']) ]] [[ company.currency_id.symbol ]] + [[ formatLang(line['credit']-line['debit'], currency_obj=company.currency_id ) ]] [[ display_currency(data) or removeParentNode('blockTable') ]] @@ -328,7 +328,7 @@ [[ line['name'] ]] [[ formatLang(line['debit']) ]] [[ formatLang(line['credit'])]] - [[ formatLang(line['credit']-line['debit']) ]] [[ company.currency_id.symbol ]] + [[ formatLang(line['credit']-line['debit'], currency_obj=company.currency_id ) ]] [[ (line['currency_id']==None or line['amount_currency']==None) and removeParentNode('font') ]] [[ formatLang(line['amount_currency'] ) ]] [[ line['currency_code'] or '' ]] diff --git a/addons/account/report/account_financial_report.py b/addons/account/report/account_financial_report.py index 6b0ada74708..6b42bb1875d 100644 --- a/addons/account/report/account_financial_report.py +++ b/addons/account/report/account_financial_report.py @@ -63,14 +63,18 @@ class report_account_common(report_sxw.rml_parse, common_report_header): if data['form']['enable_filter']: vals['balance_cmp'] = self.pool.get('account.financial.report').browse(self.cr, self.uid, report.id, context=data['form']['comparison_context']).balance lines.append(vals) + account_ids = [] if report.type == 'accounts' and report.display_detail and report.account_ids: account_ids = account_obj._get_children_and_consol(self.cr, self.uid, [x.id for x in report.account_ids]) + elif report.type == 'account_type' and report.account_type_ids: + account_ids = account_obj.search(self.cr, self.uid, [('user_type','in', [x.id for x in report.account_type_ids])]) + if account_ids: for account in account_obj.browse(self.cr, self.uid, account_ids, context=data['form']['used_context']): if account.type != 'view': flag = False vals = { 'name': account.code + ' ' + account.name, - 'balance': account.balance, + 'balance': account.balance != 0 and account.balance * account.user_type.sign or account.balance, 'type': 'account', 'level': 6, 'account_type': account.type, diff --git a/addons/account/report/account_general_journal.rml b/addons/account/report/account_general_journal.rml index 6424a24f8aa..5ca6e828e49 100644 --- a/addons/account/report/account_general_journal.rml +++ b/addons/account/report/account_general_journal.rml @@ -273,7 +273,7 @@ [[ formatLang(sum_debit()) ]] [[ formatLang( sum_credit()) ]] - [[ formatLang( sum_debit()- sum_credit()) ]] [[ company.currency_id.symbol ]] + [[ formatLang( sum_debit()- sum_credit(), currency_obj=company.currency_id) ]] [[ display_currency(data) or removeParentNode('blockTable') ]] @@ -290,7 +290,7 @@ [[ formatLang(sum_debit()) ]] [[ formatLang( sum_credit()) ]] - [[ formatLang( sum_credit()- sum_debit()) ]] [[ company.currency_id.symbol ]] + [[ formatLang( sum_credit()- sum_debit(), currency_obj=company.currency_id) ]] @@ -311,7 +311,7 @@ [[ formatLang(sum_credit_period(o.id)) ]] - [[ formatLang(sum_credit_period(o.id)-sum_debit_period(o.id)) ]] [[ company.currency_id.symbol ]] + [[ formatLang(sum_credit_period(o.id)-sum_debit_period(o.id), currency_obj=company.currency_id) ]] @@ -337,7 +337,7 @@ [[ formatLang(sum_credit_period(o.id)) ]] - [[ formatLang(sum_credit_period(o.id)-sum_debit_period(o.id)) ]] [[ company.currency_id.symbol ]] + [[ formatLang(sum_credit_period(o.id)-sum_debit_period(o.id), currency_obj=company.currency_id) ]] @@ -358,7 +358,7 @@ [[ formatLang(line['credit']) ]] - [[ formatLang(line['credit']-line['debit'] ) ]] [[ company.currency_id.symbol ]] + [[ formatLang(line['credit']-line['debit'], currency_obj=company.currency_id ) ]] @@ -371,7 +371,7 @@ [[ line['name'] ]] [[ formatLang(line['debit'] )]] [[ formatLang(line['credit']) ]] - [[ formatLang(line['credit']-line['debit'] ) ]] [[ company.currency_id.symbol ]] + [[ formatLang(line['credit']-line['debit'], currency_obj=company.currency_id ) ]] [[ (line['currency_id']==None or line['amount_currency']==None) and removeParentNode('font') ]] [[ formatLang(line['amount_currency'] ) ]] [[ line['currency_code'] or '' ]] diff --git a/addons/account/report/account_general_ledger.rml b/addons/account/report/account_general_ledger.rml index 7a8454d714a..d19afed52aa 100644 --- a/addons/account/report/account_general_ledger.rml +++ b/addons/account/report/account_general_ledger.rml @@ -476,10 +476,10 @@ [[ formatLang(sum_credit_account(o), digits=get_digits(dp='Account')) ]] - [[ formatLang(sum_balance_account(o), digits=get_digits(dp='Account')) ]] [[ company.currency_id.symbol ]] + [[ formatLang(sum_balance_account(o), digits=get_digits(dp='Account'),currency_obj=company.currency_id) ]] - [[ o.currency_id and formatLang(sum_currency_amount_account(o), digits=get_digits(dp='Account')) + o.currency_id.symbol or '' ]] + [[ o.currency_id and formatLang(sum_currency_amount_account(o), digits=get_digits(dp='Account'),currency_obj=o.currency_id) or '' ]] @@ -515,7 +515,7 @@ [[ formatLang(line['credit'], digits=get_digits(dp='Account')) ]] - [[ formatLang(line['progress'], digits=get_digits(dp='Account')) ]] [[ company.currency_id.symbol ]] + [[ formatLang(line['progress'], digits=get_digits(dp='Account'),currency_obj=company.currency_id) ]] [[ (line.has_key('currency_id') and line['currency_id']==None or line['amount_currency']==None) and removeParentNode('font') ]] [[ formatLang(line['amount_currency'])]] [[ line['currency_code'] or '']] @@ -572,7 +572,7 @@ [[ formatLang(sum_credit_account(o), digits=get_digits(dp='Account')) ]] - [[ formatLang(sum_balance_account(o), digits=get_digits(dp='Account')) ]] [[ company.currency_id.symbol ]] + [[ formatLang(sum_balance_account(o), digits=get_digits(dp='Account'),currency_obj=company.currency_id) ]] @@ -608,7 +608,7 @@ [[ formatLang(line['credit'], digits=get_digits(dp='Account')) ]] - [[ formatLang(line['progress'], digits=get_digits(dp='Account')) ]] [[ company.currency_id.symbol ]] + [[ formatLang(line['progress'], digits=get_digits(dp='Account'),currency_obj=company.currency_id) ]] diff --git a/addons/account/report/account_general_ledger_landscape.rml b/addons/account/report/account_general_ledger_landscape.rml index 96a78b5fd9b..7495d889b52 100644 --- a/addons/account/report/account_general_ledger_landscape.rml +++ b/addons/account/report/account_general_ledger_landscape.rml @@ -505,10 +505,10 @@ [[ formatLang(sum_credit_account(o), digits=get_digits(dp='Account')) ]] - [[ formatLang(sum_balance_account(o), digits=get_digits(dp='Account')) ]] [[ company.currency_id.symbol ]] + [[ formatLang(sum_balance_account(o), digits=get_digits(dp='Account'), currency = company.currency_id) ]] - [[ o.currency_id and formatLang(sum_currency_amount_account(o), digits=get_digits(dp='Account')) + o.currency_id.symbol or '' ]] + [[ o.currency_id and formatLang(sum_currency_amount_account(o), digits=get_digits(dp='Account'),currency_obj=o.currency_id) or '' ]] @@ -547,7 +547,7 @@ [[ formatLang(line['credit'], digits=get_digits(dp='Account')) ]] - [[ formatLang(line['progress'], digits=get_digits(dp='Account')) ]] [[ company.currency_id.symbol ]] + [[ formatLang(line['progress'], digits=get_digits(dp='Account'), currency_obj=company.currency_id) ]] [[ (line.has_key('currency_id') and line['currency_id']==None or line['amount_currency']==None) and removeParentNode('font') ]] [[ formatLang(line['amount_currency'])]] [[ line['currency_code'] or '']] @@ -607,7 +607,7 @@ [[ formatLang(sum_credit_account(o), digits=get_digits(dp='Account')) ]] - [[ formatLang(sum_balance_account(o), digits=get_digits(dp='Account')) ]] [[ company.currency_id.symbol ]] + [[ formatLang(sum_balance_account(o), digits=get_digits(dp='Account'), currency_obj=company.currency_id) ]] @@ -646,7 +646,7 @@ [[ formatLang(line['credit'], digits=get_digits(dp='Account')) ]] - [[ formatLang(line['progress'], digits=get_digits(dp='Account')) ]] [[ company.currency_id.symbol ]] + [[ formatLang(line['progress'], digits=get_digits(dp='Account'),currency_obj=company.currency_id) ]] diff --git a/addons/account/report/account_journal.rml b/addons/account/report/account_journal.rml index 3825eb58d76..76bf1bb4bfa 100644 --- a/addons/account/report/account_journal.rml +++ b/addons/account/report/account_journal.rml @@ -247,8 +247,8 @@ - [[ formatLang(sum_debit(o.period_id.id, o.journal_id.id)) ]] [[ company.currency_id.symbol ]] - [[ formatLang(sum_credit(o.period_id.id, o.journal_id.id)) ]] [[ company.currency_id.symbol ]] + [[ formatLang(sum_debit(o.period_id.id, o.journal_id.id), currency_obj=company.currency_id) ]] + [[ formatLang(sum_credit(o.period_id.id, o.journal_id.id), currency_obj=company.currency_id) ]] [[lines(o.period_id.id, o.journal_id.id) or removeParentNode('story') ]] @@ -258,8 +258,8 @@ [[ line.account_id.code ]] [[ line.partner_id and strip_name(line.partner_id.name,17) ]] [[ strip_name(line.name,27) ]] - [[ formatLang(line.debit) ]] [[ company.currency_id.symbol ]] - [[ formatLang(line.credit) ]] [[ company.currency_id.symbol ]] + [[ formatLang(line.debit, currency_obj=company.currency_id) ]] + [[ formatLang(line.credit, currency_obj=company.currency_id) ]] @@ -282,8 +282,8 @@ - [[ formatLang(sum_debit(o.period_id.id, o.journal_id.id)) ]] [[ company.currency_id.symbol ]] - [[ formatLang(sum_credit(o.period_id.id, o.journal_id.id)) ]] [[ company.currency_id.symbol ]] + [[ formatLang(sum_debit(o.period_id.id, o.journal_id.id), currency_obj=company.currency_id) ]] + [[ formatLang(sum_credit(o.period_id.id, o.journal_id.id), currency_obj=company.currency_id) ]] @@ -295,9 +295,9 @@ [[ line.account_id.code ]] [[ line.partner_id and strip_name(line.partner_id.name,15) ]] [[ strip_name(line.name,17) ]] - [[ formatLang(line.debit) ]] [[ company.currency_id.symbol ]] - [[ formatLang(line.credit) ]] [[ company.currency_id.symbol ]] - [[ line.currency_id and formatLang(line.amount_currency) or '' ]] [[ line.currency_id.symbol or '']] + [[ formatLang(line.debit, currency_obj=company.currency_id) ]] + [[ formatLang(line.credit, currency_obj=company.currency_id) ]] + [[ line.currency_id and formatLang(line.amount_currency, currency_obj=line.currency_id) or '' ]] diff --git a/addons/account/report/account_partner_balance.rml b/addons/account/report/account_partner_balance.rml index baf43435a44..8953aa8d1cf 100644 --- a/addons/account/report/account_partner_balance.rml +++ b/addons/account/report/account_partner_balance.rml @@ -241,16 +241,16 @@ [[ formatLang(sum_debit()) ]] [[ formatLang(sum_credit()) ]] - [[ formatLang((sum_debit()-sum_credit())) ]] [[ company.currency_id.symbol ]] - [[ formatLang(sum_litige()) ]] [[ company.currency_id.symbol ]] + [[ formatLang((sum_debit()-sum_credit()), currency_obj=company.currency_id) ]] + [[ formatLang(sum_litige(), currency_obj=company.currency_id) ]] [[ repeatIn(lines(), 'a') ]][[ (a['type']==3 and setTag('para','para',{'fontName':'Helvetica-Bold'})) or removeParentNode('font') ]][[ a['ref'] ]] [[ a['type']==3 and a['code'] ]] [[ (a['type']==3 and setTag('para','para',{'fontName':'Helvetica-Bold'})) or removeParentNode('font') ]][[ a['name'] ]] [[ (a['type']==3 and setTag('para','para',{'fontName':'Helvetica-Bold'})) or removeParentNode('font') ]][[ formatLang(a['debit']) ]] [[ (a['type']==3 and setTag('para','para',{'fontName':'Helvetica-Bold'})) or removeParentNode('font') ]][[ formatLang(a['credit']) ]] - [[ (a['type']==3 and setTag('para','para',{'fontName':'Helvetica-Bold'})) or removeParentNode('font') ]][[ formatLang(a['balance']) ]] [[ company.currency_id.symbol ]] - [[ (a['type']==3 and setTag('para','para',{'fontName':'Helvetica-Bold'})) or removeParentNode('font') ]][[ formatLang(a['enlitige'] or 0.0) ]] [[ company.currency_id.symbol ]] + [[ (a['type']==3 and setTag('para','para',{'fontName':'Helvetica-Bold'})) or removeParentNode('font') ]][[ formatLang(a['balance'], currency_obj=company.currency_id) ]] + [[ (a['type']==3 and setTag('para','para',{'fontName':'Helvetica-Bold'})) or removeParentNode('font') ]][[ formatLang(a['enlitige'] or 0.0, currency_obj=company.currency_id) ]] diff --git a/addons/account/report/account_partner_ledger.rml b/addons/account/report/account_partner_ledger.rml index b1fc8ae712f..11d9f6eff1b 100644 --- a/addons/account/report/account_partner_ledger.rml +++ b/addons/account/report/account_partner_ledger.rml @@ -477,7 +477,7 @@ [[ formatLang((sum_credit_partner(p))) ]] - [[ formatLang((sum_debit_partner(p) - sum_credit_partner(p))) ]] [[ company.currency_id.symbol ]] + [[ formatLang((sum_debit_partner(p) - sum_credit_partner(p)), currency_obj=company.currency_id) ]] @@ -497,7 +497,7 @@ [[ formatLang(get_intial_balance(p)[0][1]) ]] - [[ formatLang(get_intial_balance(p)[0][2]) ]] [[ company.currency_id.symbol ]] + [[ formatLang(get_intial_balance(p)[0][2], currency_obj=company.currency_id) ]] @@ -528,7 +528,7 @@ [[ formatLang((line['credit'])) ]] - [[ formatLang((line['progress'])) ]] [[ company.currency_id.symbol ]] + [[ formatLang((line['progress']), currency_obj=company.currency_id) ]] @@ -581,7 +581,7 @@ [[ formatLang((sum_credit_partner(p))) ]] - [[ formatLang((sum_debit_partner(p) - sum_credit_partner(p))) ]] [[ company.currency_id.symbol ]] + [[ formatLang((sum_debit_partner(p) - sum_credit_partner(p)), currency_obj=company.currency_id) ]] @@ -604,7 +604,7 @@ [[ formatLang(get_intial_balance(p)[0][1]) ]] - [[ formatLang(get_intial_balance(p)[0][2]) ]] [[ company.currency_id.symbol ]] + [[ formatLang(get_intial_balance(p)[0][2], currency_obj=company.currency_id) ]] @@ -640,7 +640,7 @@ [[ formatLang((line['credit'])) ]] - [[ formatLang((line['progress'])) ]] [[ company.currency_id.symbol ]] + [[ formatLang((line['progress']), currency_obj=company.currency_id) ]] diff --git a/addons/account/report/account_partner_ledger_other.rml b/addons/account/report/account_partner_ledger_other.rml index 7c134270c5c..54842096496 100644 --- a/addons/account/report/account_partner_ledger_other.rml +++ b/addons/account/report/account_partner_ledger_other.rml @@ -482,7 +482,7 @@ [[ formatLang((sum_credit_partner(p))) ]] - [[ formatLang((sum_debit_partner(p) - sum_credit_partner(p))) ]] [[ company.currency_id.symbol ]] + [[ formatLang((sum_debit_partner(p) - sum_credit_partner(p)), currency_obj=company.currency_id) ]] @@ -502,7 +502,7 @@ [[ formatLang(get_intial_balance(p)[0][1]) ]] - [[ formatLang(get_intial_balance(p)[0][2]) ]] [[ company.currency_id.symbol ]] + [[ formatLang(get_intial_balance(p)[0][2], currency_obj=company.currency_id) ]] @@ -533,7 +533,7 @@ [[ formatLang((line['credit'])) ]] - [[ formatLang((line['progress'])) ]] [[ company.currency_id.symbol ]] + [[ formatLang((line['progress']), currency_obj=company.currency_id) ]] @@ -590,7 +590,7 @@ [[ formatLang((sum_credit_partner(p))) ]] - [[ formatLang((sum_debit_partner(p) - sum_credit_partner(p))) ]] [[ company.currency_id.symbol ]] + [[ formatLang((sum_debit_partner(p) - sum_credit_partner(p)), currency_obj=company.currency_id) ]] @@ -613,7 +613,7 @@ [[ formatLang(get_intial_balance(p)[0][1]) ]] - [[ formatLang(get_intial_balance(p)[0][2]) ]] [[ company.currency_id.symbol ]] + [[ formatLang(get_intial_balance(p)[0][2], currency_obj=company.currency_id) ]] @@ -649,7 +649,7 @@ [[ formatLang((line['credit'])) ]] - [[ formatLang((line['progress'])) ]] [[ company.currency_id.symbol ]] + [[ formatLang((line['progress']), currency_obj=company.currency_id) ]] diff --git a/addons/account/report/account_print_invoice.rml b/addons/account/report/account_print_invoice.rml index 0350fbf7379..db8f752a56d 100644 --- a/addons/account/report/account_print_invoice.rml +++ b/addons/account/report/account_print_invoice.rml @@ -263,7 +263,7 @@ [[ formatLang(l.discount, dp='Account') ]] - [[ formatLang(l.price_subtotal, dp='Account') ]] [[ o.currency_id.symbol ]] + [[ formatLang(l.price_subtotal, dp='Account', currency_obj=o.currency_id) ]] @@ -309,7 +309,7 @@ Net Total: - [[ formatLang(o.amount_untaxed, digits=get_digits(dp='Account')) ]] [[ o.currency_id.symbol ]] + [[ formatLang(o.amount_untaxed, digits=get_digits(dp='Account'), currency_obj=o.currency_id) ]] @@ -322,7 +322,7 @@ Taxes: - [[ formatLang(o.amount_tax, dp='Account') ]] [[ o.currency_id.symbol ]] + [[ formatLang(o.amount_tax, dp='Account', currency_obj=o.currency_id) ]] @@ -335,7 +335,7 @@ Total: - [[ formatLang(o.amount_total, digits=get_digits(dp='Account')) ]] [[ o.currency_id.symbol ]] + [[ formatLang(o.amount_total, digits=get_digits(dp='Account'), currency_obj=o.currency_id) ]] @@ -368,10 +368,10 @@ [[ t.name ]] - [[ formatLang(t.base, dp='Account') ]] [[ o.currency_id.symbol ]] + [[ formatLang(t.base, dp='Account', currency_obj=o.currency_id) ]] - [[ (t.tax_code_id and t.tax_code_id.notprintable) and removeParentNode('blockTable') or '' ]] [[ formatLang(t.amount, digits=get_digits(dp='Account')) ]] [[ o.currency_id.symbol ]] + [[ (t.tax_code_id and t.tax_code_id.notprintable) and removeParentNode('blockTable') or '' ]] [[ formatLang(t.amount, digits=get_digits(dp='Account'), currency_obj=o.currency_id) ]] diff --git a/addons/account/report/account_print_overdue.rml b/addons/account/report/account_print_overdue.rml index 0797d544f9b..25ccad25377 100644 --- a/addons/account/report/account_print_overdue.rml +++ b/addons/account/report/account_print_overdue.rml @@ -219,7 +219,7 @@ [[ (line['account_id']['type'] == 'receivable' and formatLang(line['credit']) or 0) or (line['account_id']['type'] == 'payable' and formatLang(line['debit'] * -1) or 0) ]] - [[ formatLang((line['date_maturity'] < time.strftime('%Y-%m-%d'))) and formatLang(line['debit'] - line['credit']) ]] [[ company.currency_id.symbol ]] + [[ formatLang((line['date_maturity'] < time.strftime('%Y-%m-%d'))) and formatLang(line['debit'] - line['credit'], currency_obj=company.currency_id) ] [[ line['blocked'] and 'X' or '' ]] @@ -244,7 +244,7 @@ [[ formatLang((reduce(lambda x, y: x + ((y['account_id']['type'] == 'receivable' and y['credit'] or 0) or (y['account_id']['type'] == 'payable' and y['debit'] * -1 or 0)), getLines(o), 0))) ]] - [[ formatLang((reduce(lambda x, y: x + (y['debit'] - y['credit']), filter(lambda x: x['date_maturity'] < time.strftime('%Y-%m-%d'), getLines(o)), 0))) ]] [[ company.currency_id.symbol ]] + [[ formatLang((reduce(lambda x, y: x + (y['debit'] - y['credit']), filter(lambda x: x['date_maturity'] < time.strftime('%Y-%m-%d'), getLines(o)), 0)), currency_obj=company.currency_id) ]] @@ -264,7 +264,7 @@ Balance : - [[ formatLang((reduce(lambda x, y: x +(y['debit'] - y['credit']), getLines(o), 0))) ]] [[ company.currency_id.symbol ]] + [[ formatLang((reduce(lambda x, y: x +(y['debit'] - y['credit']), getLines(o), 0)), currency_obj=company.currency_id) ]] @@ -279,10 +279,10 @@ - Total amount due: [[ formatLang((reduce(lambda x, y: x + (y['debit'] - y['credit']), getLines(o), 0))) ]] [[ company.currency_id.symbol ]]. + Total amount due: [[ formatLang((reduce(lambda x, y: x + (y['debit'] - y['credit']), getLines(o), 0)), currency_obj=company.currency_id) ]]. - \ No newline at end of file + diff --git a/addons/account/report/account_profit_horizontal.rml b/addons/account/report/account_profit_horizontal.rml index bf19d0b61fc..e4ed9139fa0 100644 --- a/addons/account/report/account_profit_horizontal.rml +++ b/addons/account/report/account_profit_horizontal.rml @@ -221,7 +221,7 @@ - [[ a['level']<4 and ( setTag('para','para',{'style':'terp_default_Right_9_Bold'})) or removeParentNode('font') ]][[ formatLang(abs(a['balance'])) ]] [[ company.currency_id.symbol ]] + [[ a['level']<4 and ( setTag('para','para',{'style':'terp_default_Right_9_Bold'})) or removeParentNode('font') ]][[ formatLang(abs(a['balance']), currency_obj=company.currency_id) ]] @@ -234,7 +234,7 @@ - [[ a['level1']<4 and ( setTag('para','para',{'style':'terp_default_Right_9_Bold'})) or removeParentNode('font') ]][[(a['code1'] and a['name1']) and formatLang(abs(a['balance1'])) or removeParentNode('font') ]] [[ company.currency_id.symbol ]] + [[ a['level']<4 and ( setTag('para','para',{'style':'terp_default_Right_9_Bold'})) or removeParentNode('font') ]][[(a['code1'] and a['name1']) and formatLang(abs(a['balance1']), currency_obj=company.currency_id) or removeParentNode('font') ]] @@ -247,7 +247,7 @@ [[ final_result()['type'] == 'Net Profit' and final_result()['type'] or '' ]] - [[ final_result()['balance'] and final_result()['type'] == 'Net Profit' and formatLang(abs(final_result()['balance'])) ]] [[ company.currency_id.symbol ]] + [[ final_result()['balance'] and final_result()['type'] == 'Net Profit' and formatLang(abs(final_result()['balance']), currency_obj=company.currency_id) ]] @@ -256,7 +256,7 @@ [[ final_result()['type'] == 'Net Loss' and final_result()['type'] or '' ]] - [[ final_result()['balance'] and final_result()['type'] == 'Net Loss' and formatLang(abs(final_result()['balance'])) ]] [[ final_result()['balance'] and final_result()['type'] == 'Net Loss' and company.currency_id.symbol ]] + [[ final_result()['balance'] and final_result()['type'] == 'Net Loss' and formatLang(abs(final_result()['balance']), currency_obj=company.currency_id) ]] @@ -267,13 +267,13 @@ Total: - [[ formatLang(abs(sum_dr())) ]] [[ company.currency_id.symbol ]] + [[ formatLang(abs(sum_dr()), currency_obj=company.currency_id) ]] Total: - [[ formatLang(abs(sum_cr())) ]] [[ company.currency_id.symbol ]] + [[ formatLang(abs(sum_cr()), currency_obj=company.currency_id) ]] diff --git a/addons/account/report/account_profit_loss.py b/addons/account/report/account_profit_loss.py index 4c8896ee630..27182cdbd21 100644 --- a/addons/account/report/account_profit_loss.py +++ b/addons/account/report/account_profit_loss.py @@ -141,11 +141,15 @@ class report_pl_account_horizontal(report_sxw.rml_parse, common_report_header): 'code': cal_list['expense'][i].code, 'name': cal_list['expense'][i].name, 'level': cal_list['expense'][i].level, - 'balance':cal_list['expense'][i].balance, + 'balance': cal_list['expense'][i].balance != 0 and \ + cal_list['expense'][i].balance * cal_list['expense'][i].user_type.sign or \ + cal_list['expense'][i].balance, 'code1': cal_list['income'][i].code, 'name1': cal_list['income'][i].name, 'level1': cal_list['income'][i].level, - 'balance1':cal_list['income'][i].balance, + 'balance1': cal_list['income'][i].balance != 0 and \ + cal_list['income'][i].balance * cal_list['income'][i].user_type.sign or \ + cal_list['income'][i].balance, } self.result_temp.append(temp) else: @@ -158,7 +162,9 @@ class report_pl_account_horizontal(report_sxw.rml_parse, common_report_header): 'code1': cal_list['income'][i].code, 'name1': cal_list['income'][i].name, 'level1': cal_list['income'][i].level, - 'balance1':cal_list['income'][i].balance, + 'balance1': cal_list['income'][i].balance != 0 and \ + cal_list['income'][i].balance * cal_list['income'][i].user_type.sign \ + or cal_list['income'][i].balance, } self.result_temp.append(temp) if i < len(cal_list['expense']): @@ -166,7 +172,9 @@ class report_pl_account_horizontal(report_sxw.rml_parse, common_report_header): 'code': cal_list['expense'][i].code, 'name': cal_list['expense'][i].name, 'level': cal_list['expense'][i].level, - 'balance':cal_list['expense'][i].balance, + 'balance': cal_list['expense'][i].balance != 0 and \ + cal_list['expense'][i].balance * cal_list['expense'][i].user_type.sign \ + or cal_list['expense'][i].balance, 'code1': '', 'name1': '', 'level1': False, diff --git a/addons/account/report/account_profit_loss.rml b/addons/account/report/account_profit_loss.rml index f0c549e7412..362381be6a8 100644 --- a/addons/account/report/account_profit_loss.rml +++ b/addons/account/report/account_profit_loss.rml @@ -228,8 +228,8 @@ [[ setTag('tr','tr',{'style': 'Table'+str(min(3,a.level))}) ]] [[ (a.type =='view' and a.level >= 3) and setTag('para','para',{'style': 'terp_level_3_code_bold'}) or setTag('para','para',{'style': 'terp_level_'+str(min(3,a.level))+'_code'}) ]][[ a.code ]] [[ (a.type =='view' and a.level >= 3) and setTag('para','para',{'style': 'terp_level_'+str(min(3,a.level))+'_name_bold'}) or setTag('para','para',{'style': 'terp_level_'+str(min(4,a.level))+'_name'}) ]][[ a.name ]] - [[ (a.level <>2) or removeParentNode('td') ]][[ (a.type =='view' and a.level >= 3) and setTag('para','para',{'style': 'terp_level_3_balance_bold'}) or setTag('para','para',{'style': 'terp_level_'+str(min(3,a.level))+'_balance'}) ]][[ formatLang(a.balance) ]] [[company.currency_id.symbol ]] - [[ a.level == 2 or removeParentNode('td') ]][[ formatLang(a.balance) ]] [[company.currency_id.symbol ]] + [[ (a.level <>2) or removeParentNode('td') ]][[ (a.type =='view' and a.level >= 3) and setTag('para','para',{'style': 'terp_level_3_balance_bold'}) or setTag('para','para',{'style': 'terp_level_'+str(min(3,a.level))+'_balance'}) ]][[ formatLang(a.balance * a.user_type.sign, currency_obj=company.currency_id.symbol) + [[ a.level == 2 or removeParentNode('td') ]][[ formatLang(a.balance * a.user_type.sign, currency_obj=company.currency_id) ]] @@ -241,7 +241,7 @@ [[ final_result()['type'] == 'Net Profit' and final_result()['type'] or removeParentNode('blockTable') ]] - [[ final_result()['balance'] and final_result()['type'] == 'Net Profit' and formatLang(final_result()['balance']) ]] [[ final_result()['balance'] and final_result()['type'] == 'Net Profit' and company.currency_id.symbol ]] + [[ final_result()['balance'] and final_result()['type'] == 'Net Profit' and formatLang(final_result()['balance'], currency_obj=company.currency_id) ]] @@ -251,7 +251,7 @@ Total: - [[ formatLang(sum_dr()) ]] [[ company.currency_id.symbol ]] + [[ formatLang(sum_dr(), currency_obj=company.currency_id) ]] @@ -277,8 +277,8 @@ [[ setTag('tr','tr',{'style': 'Table'+str(min(3,a.level))}) ]] [[ (a.type =='view' and a.level >= 3) and setTag('para','para',{'style': 'terp_level_3_code_bold'}) or setTag('para','para',{'style': 'terp_level_'+str(min(3,a.level))+'_code'}) ]][[ a.code ]] [[ (a.type =='view' and a.level >= 3) and setTag('para','para',{'style': 'terp_level_'+str(min(3,a.level))+'_name_bold'}) or setTag('para','para',{'style': 'terp_level_'+str(min(4,a.level))+'_name'}) ]][[ a.name ]] - [[ (a.level <>2) or removeParentNode('td') ]][[ (a.type =='view' and a.level >= 3) and setTag('para','para',{'style': 'terp_level_3_balance_bold'}) or setTag('para','para',{'style': 'terp_level_'+str(min(3,a.level))+'_balance'}) ]][[ formatLang(a.balance) ]] [[company.currency_id.symbol ]] - [[ a.level == 2 or removeParentNode('td') ]][[ formatLang(a.balance) ]] [[company.currency_id.symbol ]] + [[ (a.level <>2) or removeParentNode('td') ]][[ (a.type =='view' and a.level >= 3) and setTag('para','para',{'style': 'terp_level_3_balance_bold'}) or setTag('para','para',{'style': 'terp_level_'+str(min(3,a.level))+'_balance'}) ]][[ formatLang(a.balance * a.user_type.sign, currency_obj=company.currency_id) ]] + [[ a.level == 2 or removeParentNode('td') ]][[ formatLang(a.balance * a.user_type.sign, currency_obj=company.currency_id) ]] @@ -290,7 +290,7 @@ [[ final_result()['type'] == 'Net Loss' and final_result()['type'] or removeParentNode('blockTable') ]] - [[ final_result()['balance'] and final_result()['type'] == 'Net Loss' and formatLang(final_result()['balance']) ]] [[ final_result()['balance'] and final_result()['type'] == 'Net Loss' and company.currency_id.symbol ]] + [[ final_result()['balance'] and final_result()['type'] == 'Net Loss' and formatLang(final_result()['balance'], currency_obj=company.currency_id) ]] @@ -300,7 +300,7 @@ Total: - [[ formatLang(sum_cr()) ]] [[ company.currency_id.symbol ]] + [[ formatLang(sum_cr(), currency_obj=company.currency_id) ]] diff --git a/addons/account/report/account_tax_code.rml b/addons/account/report/account_tax_code.rml index 7489ac72a39..10a7c76a821 100644 --- a/addons/account/report/account_tax_code.rml +++ b/addons/account/report/account_tax_code.rml @@ -129,10 +129,10 @@ [[ line['name'] ]] - [[ formatLang(line['debit']) ]] [[ company.currency_id.symbol]] + [[ formatLang(line['debit'], currency_obj=company.currency_id) ]] - [[ formatLang(line['credit']) ]] [[ company.currency_id.symbol]] + [[ formatLang(line['credit'], currency_obj=company.currency_id) ]] @@ -141,4 +141,4 @@ - \ No newline at end of file + diff --git a/addons/account/report/account_tax_report.rml b/addons/account/report/account_tax_report.rml index de4aa415fef..f489ee1143e 100644 --- a/addons/account/report/account_tax_report.rml +++ b/addons/account/report/account_tax_report.rml @@ -153,7 +153,7 @@ [[ repeatIn(get_lines(data['form']['based_on'], data['form']['company_id']), 'o') ]][[ (o['level']) ]] [[ (len(o['level'])<5 and setTag('para','para',{'fontName':'Helvetica-Bold'})) or removeParentNode('font') ]][[ o['code'] ]] [[ o['name'] ]] [[ len(o['level'])<5 and setTag('para','para',{'fontName':"Helvetica-Bold"}) or removeParentNode('font')]][[ o['type']=='view' and removeParentNode('font') ]][[ formatLang(o['debit']) ]][[ o['type']<>'view' and removeParentNode('font') ]][[ formatLang(o['debit']) ]] [[ len(o['level'])<5 and setTag('para','para',{'fontName':"Helvetica-Bold"}) or removeParentNode('font')]][[ o['type']=='view' and removeParentNode('font') ]][[ formatLang(o['credit']) ]][[ o['type']<>'view' and removeParentNode('font') ]][[ formatLang(o['credit'])]] - [[ len(o['level'])<5 and setTag('para','para',{'fontName':"Helvetica-Bold"}) or removeParentNode('font')]][[ o['type']=='view' and removeParentNode('font') ]][[ formatLang(o['tax_amount']) ]] [[ company.currency_id.symbol ]][[ o['type']<>'view' and removeParentNode('font') ]][[ formatLang(o['tax_amount']) ]] [[ company.currency_id.symbol ]] + [[ len(o['level'])<5 and setTag('para','para',{'fontName':"Helvetica-Bold"}) or removeParentNode('font')]][[ o['type']=='view' and removeParentNode('font') ]][[ formatLang(o['tax_amount'], currency_obj=company.currency_id) ]][[ o['type']<>'view' and removeParentNode('font') ]][[ formatLang(o['tax_amount'], currency_obj=company.currency_id) ]] diff --git a/addons/account/wizard/account_financial_report_view.xml b/addons/account/wizard/account_financial_report_view.xml index 2083fd0ed53..1472da4ba87 100644 --- a/addons/account/wizard/account_financial_report_view.xml +++ b/addons/account/wizard/account_financial_report_view.xml @@ -31,7 +31,7 @@ - Financial Report + Financial Reports accounting.report ir.actions.act_window form diff --git a/addons/account_analytic_plans/report/crossovered_analytic.rml b/addons/account_analytic_plans/report/crossovered_analytic.rml index 6e331ed1b83..f374aa5a2c2 100644 --- a/addons/account_analytic_plans/report/crossovered_analytic.rml +++ b/addons/account_analytic_plans/report/crossovered_analytic.rml @@ -240,7 +240,7 @@ [[ formatLang(a['ref_qty']) ]] - [[ formatLang(a['ref_amt']) ]] [[ company.currency_id.symbol ]] + [[ formatLang(a['ref_amt'], currency_obj=company.currency_id) ]] 100.00% @@ -288,7 +288,7 @@ [[formatLang(a['qty']) ]] - [[ formatLang(a['amt']) ]] [[ company.currency_id.symbol ]] + [[ formatLang(a['amt'], currency_obj=company.currency_id) ]] [[ formatLang(a['perc']) ]]% diff --git a/addons/account_budget/report/analytic_account_budget_report.rml b/addons/account_budget/report/analytic_account_budget_report.rml index a8b957f52a5..ba89c7ed1ea 100644 --- a/addons/account_budget/report/analytic_account_budget_report.rml +++ b/addons/account_budget/report/analytic_account_budget_report.rml @@ -185,13 +185,13 @@ [['.....' *(a['status']-1) ]] [[ (a['status']==1 and (setTag('para','para',{'fontName':'Helvetica-bold'}))) or removeParentNode('font') ]] [[ a['name'] ]] - [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-bold'}))) or removeParentNode('font') ]] [[ formatLang(a['theo']) ]] [[ company.currency_id.symbol ]] + [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-bold'}))) or removeParentNode('font') ]] [[ formatLang(a['theo'], currency_obj=company.currency_id) ]] - [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-bold'}))) or removeParentNode('font') ]] [[ formatLang(a['pln']) ]] [[ company.currency_id.symbol ]] + [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-bold'}))) or removeParentNode('font') ]] [[ formatLang(a['pln'], currency_obj=company.currency_id) ]] - [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-bold'}))) or removeParentNode('font') ]] [[ formatLang(a['prac']) ]] [[ company.currency_id.symbol ]] + [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-bold'}))) or removeParentNode('font') ]] [[ formatLang(a['prac'], currency_obj=company.currency_id) ]] [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-bold'}))) or removeParentNode('font') ]] [[ formatLang(a['perc']) ]]% @@ -205,13 +205,13 @@ [[ repeatIn(funct_total(data['form']),'b') ]] Total: - [[ formatLang(b['tot_theo']) ]] [[ company.currency_id.symbol ]] + [[ formatLang(b['tot_theo'], currency_obj=company.currency_id) ]] - [[ formatLang(b['tot_pln']) ]] [[ company.currency_id.symbol ]] + [[ formatLang(b['tot_pln'], currency_obj=company.currency_id) ]] - [[ formatLang(b['tot_prac']) ]] [[ company.currency_id.symbol ]] + [[ formatLang(b['tot_prac'], currency_obj=company.currency_id) ]] [[ formatLang(b['tot_perc']) ]]% @@ -223,4 +223,4 @@ - \ No newline at end of file + diff --git a/addons/account_budget/report/budget_report.rml b/addons/account_budget/report/budget_report.rml index 0533042822a..4d82e8d8c1d 100644 --- a/addons/account_budget/report/budget_report.rml +++ b/addons/account_budget/report/budget_report.rml @@ -148,13 +148,13 @@ [['.....' *(a['status']-1) ]][[ (a['status']==1 and (setTag('para','para',{'fontName':'Helvetica-bold'}))) or removeParentNode('font') ]] [[ a['name'] ]] - [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-bold'}))) or removeParentNode('font') ]] [[ formatLang(a['theo'], digits=get_digits(dp='Account')) ]] [[ company.currency_id.symbol ]] + [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-bold'}))) or removeParentNode('font') ]] [[ formatLang(a['theo'], digits=get_digits(dp='Account'), currency_obj=company.currency_id) ]] - [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-bold'}))) or removeParentNode('font') ]] [[ formatLang(a['pln'], digits=get_digits(dp='Account')) ]] [[ company.currency_id.symbol ]] + [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-bold'}))) or removeParentNode('font') ]] [[ formatLang(a['pln'], digits=get_digits(dp='Account'), currency_obj=company.currency_id) ]] - [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-bold'}))) or removeParentNode('font') ]] [[ formatLang(a['prac'], digits=get_digits(dp='Account')) ]] [[ company.currency_id.symbol ]] + [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-bold'}))) or removeParentNode('font') ]] [[ formatLang(a['prac'], digits=get_digits(dp='Account'), currency_obj=company.currency_id) ]] [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-bold'}))) or removeParentNode('font') ]] [[ formatLang(a['perc'], digits=2) ]]% @@ -168,13 +168,13 @@ [[ repeatIn(funct_total(data['form']),'b') ]]Total: - [[ formatLang(b['tot_theo'], digits=get_digits(dp='Account')) ]] [[ company.currency_id.symbol ]] + [[ formatLang(b['tot_theo'], digits=get_digits(dp='Account'), currency_obj=company.currency_id) ]] - [[ formatLang(b['tot_pln'], digits=get_digits(dp='Account')) ]] [[ company.currency_id.symbol ]] + [[ formatLang(b['tot_pln'], digits=get_digits(dp='Account'), currency_obj=company.currency_id) ]] - [[ formatLang(b['tot_prac'], digits=get_digits(dp='Account')) ]] [[ company.currency_id.symbol ]] + [[ formatLang(b['tot_prac'], digits=get_digits(dp='Account'), currency_obj=company.currency_id) ]] [[ formatLang(b['tot_perc'], digits=2) ]]% diff --git a/addons/account_budget/report/crossovered_budget_report.rml b/addons/account_budget/report/crossovered_budget_report.rml index 63db53ab5ce..b4e8e963b7d 100644 --- a/addons/account_budget/report/crossovered_budget_report.rml +++ b/addons/account_budget/report/crossovered_budget_report.rml @@ -163,13 +163,13 @@ [['.....' *(a['status']-1) ]][[ (a['status']==1 and (setTag('para','para',{'fontName':'Helvetica-bold'}))) or removeParentNode('font') ]] [[ a['name'] ]] - [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-bold'}))) or removeParentNode('font') ]] [[ formatLang(a['theo'], dp='Account') ]] [[ company.currency_id.symbol ]] + [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-bold'}))) or removeParentNode('font') ]] [[ formatLang(a['theo'], dp='Account', currency_obj=company.currency_id) ]] - [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-bold'}))) or removeParentNode('font') ]] [[ formatLang(a['pln'], dp='Account') ]] [[ company.currency_id.symbol ]] + [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-bold'}))) or removeParentNode('font') ]] [[ formatLang(a['pln'], dp='Account', currency_obj=company.currency_id) ]] - [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-bold'}))) or removeParentNode('font') ]] [[ formatLang(a['prac'], dp='Account') ]] [[ company.currency_id.symbol ]] + [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-bold'}))) or removeParentNode('font') ]] [[ formatLang(a['prac'], dp='Account', currency_obj=company.currency_id) ]] [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-bold'}))) or removeParentNode('font') ]] [[ formatLang(a['perc'],digits=2) ]]% @@ -183,13 +183,13 @@ [[ repeatIn(funct_total(data['form']),'b') ]] Total : - [[ formatLang(b['tot_theo'], dp='Account') ]] [[ company.currency_id.symbol ]] + [[ formatLang(b['tot_theo'], dp='Account', currency_obj=company.currency_id) ]] - [[ formatLang(b['tot_pln'], dp='Account') ]] [[ company.currency_id.symbol ]] + [[ formatLang(b['tot_pln'], dp='Account', currency_obj=company.currency_id) ]] - [[ formatLang(b['tot_prac'], dp='Account') ]] [[ company.currency_id.symbol ]] + [[ formatLang(b['tot_prac'], dp='Account', currency_obj=company.currency_id) ]] [[ formatLang(b['tot_perc'],digits=2) ]]% diff --git a/addons/analytic/i18n/ar.po b/addons/analytic/i18n/ar.po index ee7a5f9319e..036a3ef8c46 100644 --- a/addons/analytic/i18n/ar.po +++ b/addons/analytic/i18n/ar.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2011-09-05 23:03+0000\n" -"Last-Translator: Majed Majbour \n" +"PO-Revision-Date: 2011-09-22 02:41+0000\n" +"Last-Translator: kifcaliph \n" "Language-Team: Arabic \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-07 04:35+0000\n" -"X-Generator: Launchpad (build 13861)\n" +"X-Launchpad-Export-Date: 2011-09-22 04:48+0000\n" +"X-Generator: Launchpad (build 13996)\n" #. module: analytic #: field:account.analytic.account,child_ids:0 @@ -25,7 +25,7 @@ msgstr "حساب فرعي" #. module: analytic #: field:account.analytic.account,name:0 msgid "Account Name" -msgstr "" +msgstr "اسم الحساب" #. module: analytic #: help:account.analytic.line,unit_amount:0 @@ -44,12 +44,12 @@ msgstr "" #. module: analytic #: field:account.analytic.account,state:0 msgid "State" -msgstr "" +msgstr "المحافظة / الولاية" #. module: analytic #: field:account.analytic.account,user_id:0 msgid "Account Manager" -msgstr "" +msgstr "مدير المحاسبة" #. module: analytic #: selection:account.analytic.account,state:0 @@ -114,7 +114,7 @@ msgstr "وصف" #. module: analytic #: selection:account.analytic.account,type:0 msgid "Normal" -msgstr "" +msgstr "عادي" #. module: analytic #: field:account.analytic.account,company_id:0 @@ -185,7 +185,7 @@ msgstr "جهة الإتصال" msgid "" "Error! The currency has to be the same as the currency of the selected " "company" -msgstr "" +msgstr "خطأ! العملة لابد و أن تكون مثل العملة للشركة المختارة" #. module: analytic #: selection:account.analytic.account,state:0 @@ -208,11 +208,13 @@ msgid "" "If you select the View Type, it means you won't allow to create journal " "entries using that account." msgstr "" +"اذا اخترت نوع العرض، فذلك يعني انك لن تسمح بإنشاء قيود اليومية بإستخدام ذلك " +"الحساب." #. module: analytic #: field:account.analytic.account,date:0 msgid "Date End" -msgstr "" +msgstr "نهاية التاريخ" #. module: analytic #: field:account.analytic.account,code:0 diff --git a/addons/base_setup/base_setup_views.xml b/addons/base_setup/base_setup_views.xml index a6059148b51..fab929b239b 100644 --- a/addons/base_setup/base_setup_views.xml +++ b/addons/base_setup/base_setup_views.xml @@ -70,7 +70,6 @@ - 2 @@ -222,7 +221,6 @@ - 1 diff --git a/addons/base_vat/__init__.py b/addons/base_vat/__init__.py index e1999d38b87..43dbd0c1418 100644 --- a/addons/base_vat/__init__.py +++ b/addons/base_vat/__init__.py @@ -21,5 +21,4 @@ import base_vat -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file diff --git a/addons/base_vat/__openerp__.py b/addons/base_vat/__openerp__.py index 92af5664336..29f402aa286 100644 --- a/addons/base_vat/__openerp__.py +++ b/addons/base_vat/__openerp__.py @@ -18,26 +18,34 @@ # along with this program. If not, see . # ############################################################################## + { - 'name': 'Base VAT', + 'name': 'VAT Number Validation', 'version': '1.0', - 'category': 'Tools', - 'category': 'Generic Modules/Base', + 'category': 'Finance', 'complexity': "easy", 'description': """ -Enable VAT Number for a partner and check its validity. -======================================================= +VAT validation for Partners' VAT numbers +======================================== + +After installing this module, values entered in the VAT field of Partners will +be validated for all supported countries. The country is inferred from the +2-letter country code that prefixes the VAT number, e.g. ``BE0477472701`` +will be validated using the Belgian rules. + +Supported countries currently include EU countries, and a few non-EU countries +such as Chile, Colombia, Mexico, Norway or Russia. For unsupported countries, +only the country code will be validated. -This module follows the methods stated at http://sima-pc.com/nif.php for -checking the validity of VAT Number assigned to partners in European countries. """, 'author': 'OpenERP SA', 'depends': ['account'], 'website': 'http://www.openerp.com', - 'update_xml': ['base_vat_view.xml'], + 'data': ['base_vat_view.xml'], 'installable': True, 'active': False, 'certificate': '0084849360989', 'images': ['images/1_partner_vat.jpeg'], } + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/base_vat/base_vat.py b/addons/base_vat/base_vat.py index 58e5670b589..ba858d10e64 100644 --- a/addons/base_vat/base_vat.py +++ b/addons/base_vat/base_vat.py @@ -2,8 +2,7 @@ ############################################################################## # # OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (). All Rights Reserved -# Copyright (C) 2008-2009 B2CK, Cedric Krier, Bertrand Chenal (the methods "check_vat_[a-z]{2}" +# Copyright (C) 2004-2011 OpenERP SA () # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -19,13 +18,22 @@ # along with this program. If not, see . # ############################################################################## + +import logging import string +import datetime +import re + +try: + import vatnumber +except ImportError: + logging.getLogger('base_vat').warning("VAT validation partially unavailable because the `vatnumber` Python library cannot be found. " + "Install it to support more countries, for example with `easy_install vatnumber`.") + vatnumber = None from osv import osv, fields -from tools.translate import _ from tools.misc import ustr -import re -import datetime +from tools.translate import _ _ref_vat = { 'be': 'BE0477472701', 'at': 'ATU12345675', @@ -42,13 +50,9 @@ _ref_vat = { 'pt': 'PT123456789', 'ro': 'RO1234567897', 'se': 'SE123456789701', 'si': 'SI12345679', 'sk': 'SK0012345675', 'el': 'EL12345670', - 'mx': 'MXABC123456T1B', 'no': 'NO123456785' - - } - -def mult_add(i, j): - """Sum each digits of the multiplication of i and j.""" - return reduce(lambda x, y: x + int(y), str(i*j), 0) + 'mx': 'MXABC123456T1B', 'no': 'NO123456785', + 'hr': 'HR01234567896', # Croatia, contributed by Milan Tribuson +} class res_partner(osv.osv): _inherit = 'res.partner' @@ -67,16 +71,17 @@ class res_partner(osv.osv): if not partner.vat: continue vat_country, vat_number = self._split_vat(partner.vat) - if not hasattr(self, 'check_vat_' + vat_country): - #We didn't find the validation method for the country code. If that country code can be found in openerp, this means that it is a valid country code - #and we simply didn't have implemented that function. In that case we continue. + check_func_name = 'check_vat_' + vat_country + check_func = getattr(self, check_func_name, None) or \ + getattr(vatnumber, check_func_name, None) + if not check_func: + # No VAT validation available, default to check that the country code + # exists. if country_obj.search(cr, uid, [('code', 'ilike', vat_country)], context=context): continue - #Otherwise, it means that the country code isn't valid and we return False. - return False - check = getattr(self, 'check_vat_' + vat_country) - if not check(vat_number): + # Country code not found, considered invalid return False + return check_func(vat_number) return True def vat_change(self, cr, uid, ids, value, context=None): @@ -93,997 +98,24 @@ class res_partner(osv.osv): # has more than 3 characters return cn[0] in string.ascii_lowercase and cn[1] in string.ascii_lowercase vat_country, vat_number = self._split_vat(self.browse(cr, uid, ids)[0].vat) + vat_no = "'CC##' (CC=Country Code, ##=VAT Number)" if default_vat_check(vat_country, vat_number): - vat_no = vat_country in _ref_vat and _ref_vat[vat_country] or 'Country Code + Vat Number' - return _('The Vat does not seems to be correct. You should have entered something like this %s'), (vat_no) - return _('The VAT is invalid, It should begin with the country code'), () + vat_no = _ref_vat[vat_country] if vat_country in _ref_vat else vat_no + return '\n' + _('This VAT number does not seem to be valid.\nNote: the expected format is %s') % vat_no _constraints = [(check_vat, _construct_constraint_msg, ["vat"])] - # code from the following methods come from Tryton (B2CK) - # http://www.tryton.org/hgwebdir.cgi/modules/relationship/file/544d1de586d9/party.py - def check_vat_at(self, vat): - ''' - Check Austria VAT number. - ''' - if len(vat) != 9: - return False - if vat[0] != 'U': - return False - num = vat[1:] - try: - int(num) - except: - return False - sum = int(num[0]) + mult_add(2, int(num[1])) + \ - int(num[2]) + mult_add(2, int(num[3])) + \ - int(num[4]) + mult_add(2, int(num[5])) + \ - int(num[6]) - check = 10 - ((sum + 4) % 10) - if check == 10: - check = 0 - if int(vat[-1:]) != check: - return False - return True - - def check_vat_be(self, vat): - ''' - Check Belgium VAT number. - ''' - if len(vat) != 10: - return False - try: - int(vat) - except: - return False - if int(vat[-2:]) != \ - 97 - (int(vat[:8]) % 97): - return False - return True - - def check_vat_bg(self, vat): - ''' - Check Bulgaria VAT number. - ''' - if len(vat) not in [9,10]: - return False - try: - int(vat) - except: - return False - if int(vat[0]) in (2, 3) and \ - int(vat[1:2]) != 22: - return False - sum = 4 * int(vat[0]) + 3 * int(vat[1]) + 2 * int(vat[2]) + \ - 7 * int(vat[3]) + 6 * int(vat[4]) + 5 * int(vat[5]) + \ - 4 * int(vat[6]) + 3 * int(vat[7]) + 2 * int(vat[8]) - check = 11 - (sum % 11) - if check == 11: - check = 0 - return True - - def check_vat_cy(self, vat): - ''' - Check Cyprus VAT number. - ''' - if len(vat) != 9: - return False - try: - int(vat[:8]) - except: - return False - n0 = int(vat[0]) - n1 = int(vat[1]) - n2 = int(vat[2]) - n3 = int(vat[3]) - n4 = int(vat[4]) - n5 = int(vat[5]) - n6 = int(vat[6]) - n7 = int(vat[7]) - - def conv(x): - if x == 0: - return 1 - elif x == 1: - return 0 - elif x == 2: - return 5 - elif x == 3: - return 7 - elif x == 4: - return 9 - elif x == 5: - return 13 - elif x == 6: - return 15 - elif x == 7: - return 17 - elif x == 8: - return 19 - elif x == 9: - return 21 - return x - n0 = conv(n0) - n2 = conv(n2) - n4 = conv(n4) - n6 = conv(n6) - - sum = n0 + n1 + n2 + n3 + n4 + n5 + n6 + n7 - check = chr(sum % 26 + 65) - if check != vat[8]: - return False - return True - - def check_vat_cz(self, vat): - ''' - Check Czech Republic VAT number. - ''' - if len(vat) not in (8, 9, 10): - return False - try: - int(vat) - except: - return False - - if len(vat) == 8: - if int(vat[0]) not in (0, 1, 2, 3, 4, 5, 6, 7, 8): - return False - sum = 8 * int(vat[0]) + 7 * int(vat[1]) + 6 * int(vat[2]) + \ - 5 * int(vat[3]) + 4 * int(vat[4]) + 3 * int(vat[5]) + \ - 2 * int(vat[6]) - check = 11 - (sum % 11) - if check == 10: - check = 0 - if check == 11: - check = 1 - if check != int(vat[7]): - return False - elif len(vat) == 9 and int(vat[0]) == 6: - sum = 8 * int(vat[1]) + 7 * int(vat[2]) + 6 * int(vat[3]) + \ - 5 * int(vat[4]) + 4 * int(vat[5]) + 3 * int(vat[6]) + \ - 2 * int(vat[7]) - check = 9 - ((11 - (sum % 11)) % 10) - if check != int(vat[8]): - return False - elif len(vat) == 9: - if int(vat[0:2]) > 53 and int(vat[0:2]) < 80: - return False - if int(vat[2:4]) < 1: - return False - if int(vat[2:4]) > 12 and int(vat[2:4]) < 51: - return False - if int(vat[2:4]) > 62: - return False - if int(vat[2:4]) in (2, 52) and int(vat[0:2]) % 4 > 0: - if int(vat[4:6]) < 1: - return False - if int(vat[4:6]) > 28: - return False - if int(vat[2:4]) in (2, 52) and int(vat[0:2]) % 4 == 0: - if int(vat[4:6]) < 1: - return False - if int(vat[4:6]) > 29: - return False - if int(vat[2:4]) in (4, 6, 9, 11, 54, 56, 59, 61): - if int(vat[4:6]) < 1: - return False - if int(vat[4:6]) > 30: - return False - if int(vat[2:4]) in (1, 3, 5, 7, 8, 10, 12, 51, - 53, 55, 57, 58, 60, 62): - if int(vat[4:6]) < 1: - return False - if int(vat[4:6]) > 31: - return False - elif len(vat) == 10: - if int(vat[0:2]) < 54: - return False - if int(vat[2:4]) < 1: - return False - if int(vat[2:4]) > 12 and int(vat[2:4]) < 51: - return False - if int(vat[2:4]) > 62: - return False - if int(vat[2:4]) in (2, 52) and int(vat[0:2]) % 4 > 0: - if int(vat[4:6]) < 1: - return False - if int(vat[4:6]) > 28: - return False - if int(vat[2:4]) in (2, 52) and int(vat[0:2]) % 4 == 0: - if int(vat[4:6]) < 1: - return False - if int(vat[4:6]) > 29: - return False - if int(vat[2:4]) in (4, 6, 9, 11, 54, 56, 59, 61): - if int(vat[4:6]) < 1: - return False - if int(vat[4:6]) > 30: - return False - if int(vat[2:4]) in (1, 3, 5, 7, 8, 10, 12, 51, - 53, 55, 57, 58, 60, 62): - if int(vat[4:6]) < 1: - return False - if int(vat[4:6]) > 31: - return False - if (int(vat[0:2]) + int(vat[2:4]) + int(vat[4:6]) + int(vat[6:8]) + - int(vat[8:10])) % 11 != 0: - return False - if int(vat[0:10]) % 11 != 0: - return False - return True - - def check_vat_de(self, vat): - ''' - Check Germany VAT number. - ''' - if len(vat) != 9: - return False - try: - int(vat) - except: - return False - if int(vat[0:7]) <= 0: - return False - sum = 0 - for i in range(8): - sum = (2 * ((int(vat[i]) + sum + 9) % 10 + 1)) % 11 - check = 11 - sum - if check == 10: - check = 0 - if int(vat[8]) != check: - return False - return True - - def check_vat_dk(self, vat): - ''' - Check Denmark VAT number. - ''' - if len(vat) != 8: - return False - try: - int(vat) - except: - return False - if int(vat[0]) <= 0: - return False - sum = 2 * int(vat[0]) + 7 * int(vat[1]) + 6 * int(vat[2]) + \ - 5 * int(vat[3]) + 4 * int(vat[4]) + 3 * int(vat[5]) + \ - 2 * int(vat[6]) + int(vat[7]) - if sum % 11 != 0: - return False - return True - - def check_vat_ee(self, vat): - ''' - Check Estonia VAT number. - ''' - if len(vat) != 9: - return False - try: - int(vat) - except: - return False - sum = 3 * int(vat[0]) + 7 * int(vat[1]) + 1 * int(vat[2]) + \ - 3 * int(vat[3]) + 7 * int(vat[4]) + 1 * int(vat[5]) + \ - 3 * int(vat[6]) + 7 * int(vat[7]) - check = 10 - (sum % 10) - if check == 10: - check = 0 - if check != int(vat[8]): - return False - return True - - def check_vat_es(self, vat): - ''' - Check Spain VAT number. - ''' - if len(vat) != 9: - return False - - conv = { - 1: 'T', - 2: 'R', - 3: 'W', - 4: 'A', - 5: 'G', - 6: 'M', - 7: 'Y', - 8: 'F', - 9: 'P', - 10: 'D', - 11: 'X', - 12: 'B', - 13: 'N', - 14: 'J', - 15: 'Z', - 16: 'S', - 17: 'Q', - 18: 'V', - 19: 'H', - 20: 'L', - 21: 'C', - 22: 'K', - 23: 'E', - } - #Legal persons with profit aim - if vat[0] in ('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'U', 'V'): - try: - int(vat[1:8]) - except: - return False - sum = mult_add(2, int(vat[1])) + int(vat[2]) + \ - mult_add(2, int(vat[3])) + int(vat[4]) + \ - mult_add(2, int(vat[5])) + int(vat[6]) + \ - mult_add(2, int(vat[7])) - check = 10 - (sum % 10) - if check == 10: - check = 0 - return True - #Legal persons with non-profit aim - elif vat[0] in ('N', 'P', 'Q', 'R', 'S', 'W'): - try: - int(vat[1:8]) - except: - return False - sum = mult_add(2, int(vat[1])) + int(vat[2]) + \ - mult_add(2, int(vat[3])) + int(vat[4]) + \ - mult_add(2, int(vat[5])) + int(vat[6]) + \ - mult_add(2, int(vat[7])) - check = 10 - (sum % 10) - check = chr(check + 64) - if check != vat[8]: - return False - return True - #Foreign natural persons, under age 14 or non-residents - elif vat[0] in ('K', 'L', 'M', 'X', 'Y', 'Z'): - if vat[0] == 'Y': - check_value = '1' + vat[1:8] - elif vat[0] == 'Z': - check_value = '2' + vat[1:8] - else: - check_value = vat[1:8] - - try: - int(check_value) - except: - return False - check = 1 + (int(check_value) % 23) - - check = conv[check] - if check != vat[8]: - return False - return True - #Spanish natural persons - else: - try: - int(vat[:8]) - except: - return False - check = 1 + (int(vat[:8]) % 23) - - check = conv[check] - if check != vat[8]: - return False - return True - - def check_vat_fi(self, vat): - ''' - Check Finland VAT number. - ''' - if len(vat) != 8: - return False - try: - int(vat) - except: - return False - sum = 7 * int(vat[0]) + 9 * int(vat[1]) + 10 * int(vat[2]) + \ - 5 * int(vat[3]) + 8 * int(vat[4]) + 4 * int(vat[5]) + \ - 2 * int(vat[6]) - check = 11 - (sum % 11) - if check == 11: - check = 0 - if check == 10: - return False - if check != int(vat[7]): - return False - return True - - def check_vat_fr(self, vat): - ''' - Check France VAT number. - ''' - if len(vat) != 11: - return False - - try: - int(vat[2:11]) - except: - return False - - system = None - try: - int(vat[0:2]) - system = 'old' - except: - system = 'new' - - if system == 'old': - check = ((int(vat[2:11]) * 100) + 12) % 97 - if check != int(vat[0:2]): - return False - return True - else: - conv = ['0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', - 'U', 'V', 'W', 'X', 'Y', 'Z'] - if vat[0] not in conv \ - or vat[1] not in conv: - return False - c1 = conv.index(vat[0]) - c2 = conv.index(vat[1]) - - if c1 < 10: - sum = c1 * 24 + c2 - 10 - else: - sum = c1 * 34 + c2 - 100 - - x = sum % 11 - sum = (int(sum) / 11) + 1 - y = (int(vat[2:11]) + sum) % 11 - if x != y: - return False - return True - - def check_vat_gb(self, vat): - ''' - Check United Kingdom VAT number. - ''' - - if len(vat) == 5: - try: - int(vat[2:5]) - except: - return False - - if vat[0:2] == 'GD': - if int(vat[2:5]) >= 500: - return False - return True - if vat[0:2] == 'HA': - if int(vat[2:5]) < 500: - return False - return True - return False - elif len(vat) in (9, 10): - try: - int(vat) - except: - return False - - if int(vat[0:7]) < 1: - return False - if int(vat[0:7]) > 19999 and int(vat[0:7]) < 1000000: - return False - if int(vat[7:9]) > 97: - return False - if len(vat) == 10 and int(vat[9]) != 3: - return False - - sum = 8 * int(vat[0]) + 7 * int(vat[1]) + 6 * int(vat[2]) + \ - 5 * int(vat[3]) + 4 * int(vat[4]) + 3 * int(vat[5]) + \ - 2 * int(vat[6]) + 10 * int(vat[7]) + int(vat[8]) - if int(vat[0:3]) > 100: - if sum % 97 not in (0, 55, 42): - return False - else: - if sum % 97 != 0: - return False - return True - elif len(vat) in (12, 13): - try: - int(vat) - except: - return False - - if int(vat[0:3]) not in (0, 1): - return False - - if int(vat[3:10]) < 1: - return False - if int(vat[3:10]) > 19999 and int(vat[3:10]) < 1000000: - return False - if int(vat[10:12]) > 97: - return False - if len(vat) == 13 and int(vat[12]) != 3: - return False - - sum = 8 * int(vat[3]) + 7 * int(vat[4]) + 6 * int(vat[5]) + \ - 5 * int(vat[6]) + 4 * int(vat[7]) + 3 * int(vat[8]) + \ - 2 * int(vat[9]) + 10 * int(vat[10]) + int(vat[11]) - if sum % 97 != 0: - return False - return True - return False - - def check_vat_gr(self, vat): - ''' - Check Greece VAT number. - ''' - try: - int(vat) - except: - return False - if len(vat) == 8: - sum = 128 * int(vat[0]) + 64 * int(vat[1]) + 32 * int(vat[2]) + \ - 16 * int(vat[3]) + 8 * int(vat[4]) + 4 * int(vat[5]) + \ - 2 * int(vat[6]) - check = sum % 11 - if check == 10: - check = 0 - if check != int(vat[7]): - return False - return True - elif len(vat) == 9: - sum = 256 * int(vat[0]) + 128 * int(vat[1]) + 64 * int(vat[2]) + \ - 32 * int(vat[3]) + 16 * int(vat[4]) + 8 * int(vat[5]) + \ - 4 * int(vat[6]) + 2 * int(vat[7]) - check = sum % 11 - if check == 10: - check = 0 - if check != int(vat[8]): - return False - return True - return False - - def check_vat_el(self, vat): - return self.check_vat_gr(vat) - - def check_vat_hu(self, vat): - ''' - Check Hungary VAT number. - ''' - if len(vat) != 8: - return False - try: - int(vat) - except: - return False - if int(vat[0]) <= 0: - return False - sum = 9 * int(vat[0]) + 7 * int(vat[1]) + 3 * int(vat[2]) + \ - 1 * int(vat[3]) + 9 * int(vat[4]) + 7 * int(vat[5]) + \ - 3 * int(vat[6]) - check = 10 - (sum % 10) - if check == 10: - check = 0 - if check != int(vat[7]): - return False - return True - - def check_vat_ie(self, vat): - ''' - Check Ireland VAT number. - ''' - if len(vat) != 8: - return False - if (ord(vat[1]) >= 65 and ord(vat[1]) <= 90) \ - or vat[1] in ('+', '*'): - try: - int(vat[0]) - int(vat[2:7]) - except: - return False - - if int(vat[0]) <= 6: - return False - - sum = 7 * int(vat[2]) + 6 * int(vat[3]) + 5 * int(vat[4]) + \ - 4 * int(vat[5]) + 3 * int(vat[6]) + 2 * int(vat[0]) - check = sum % 23 - if check == 0: - check = 'W' - else: - check = chr(check + 64) - if check != vat[7]: - return False - return True - else: - try: - int(vat[0:7]) - except: - return False - - sum = 8 * int(vat[0]) + 7 * int(vat[1]) + 6 * int(vat[2]) + \ - 5 * int(vat[3]) + 4 * int(vat[4]) + 3 * int(vat[5]) + \ - 2 * int(vat[6]) - check = sum % 23 - if check == 0: - check = 'W' - else: - check = chr(check + 64) - if check != vat[7]: - return False - return True - - def check_vat_it(self, vat): - ''' - Check Italy VAT number. - ''' - if len(vat) != 11: - return False - try: - int(vat) - except: - return False - if int(vat[0:7]) <= 0: - return False - if int(vat[7:10]) <= 0: - return False - if int(vat[7:10]) > 100 and int(vat[7:10]) < 120: - return False - - sum = int(vat[0]) + mult_add(2, int(vat[1])) + int(vat[2]) + \ - mult_add(2, int(vat[3])) + int(vat[4]) + \ - mult_add(2, int(vat[5])) + int(vat[6]) + \ - mult_add(2, int(vat[7])) + int(vat[8]) + \ - mult_add(2, int(vat[9])) - check = 10 - (sum % 10) - if check == 10: - check = 0 - if check != int(vat[10]): - return False - return True - - def check_vat_lt(self, vat): - ''' - Check Lithuania VAT number. - ''' - try: - int(vat) - except: - return False - - if len(vat) == 9: - if int(vat[7]) != 1: - return False - sum = 1 * int(vat[0]) + 2 * int(vat[1]) + 3 * int(vat[2]) + \ - 4 * int(vat[3]) + 5 * int(vat[4]) + 6 * int(vat[5]) + \ - 7 * int(vat[6]) + 8 * int(vat[7]) - if sum % 11 == 10: - sum = 3 * int(vat[0]) + 4 * int(vat[1]) + 5 * int(vat[2]) + \ - 6 * int(vat[3]) + 7 * int(vat[4]) + 8 * int(vat[5]) + \ - 9 * int(vat[6]) + 1 * int(vat[7]) - check = sum % 11 - if check == 10: - check = 0 - if check != int(vat[8]): - return False - return True - elif len(vat) == 12: - if int(vat[10]) != 1: - return False - sum = 1 * int(vat[0]) + 2 * int(vat[1]) + 3 * int(vat[2]) + \ - 4 * int(vat[3]) + 5 * int(vat[4]) + 6 * int(vat[5]) + \ - 7 * int(vat[6]) + 8 * int(vat[7]) + 9 * int(vat[8]) + \ - 1 * int(vat[9]) + 2 * int(vat[10]) - if sum % 11 == 10: - sum = 3 * int(vat[0]) + 4 * int(vat[1]) + 5 * int(vat[2]) + \ - 6 * int(vat[3]) + 7 * int(vat[4]) + 8 * int(vat[5]) + \ - 9 * int(vat[6]) + 1 * int(vat[7]) + 2 * int(vat[8]) + \ - 3 * int(vat[9]) + 4 * int(vat[10]) - check = sum % 11 - if check == 10: - check = 0 - if check != int(vat[11]): - return False - return True - return False - - def check_vat_lu(self, vat): - ''' - Check Luxembourg VAT number. - ''' - if len(vat) != 8: - return False - try: - int(vat) - except: - return False - if int(vat[0:6]) <= 0: - return False - check = int(vat[0:6]) % 89 - if check != int(vat[6:8]): - return False - return True - - def check_vat_lv(self, vat): - ''' - Check Latvia VAT number. - ''' - if len(vat) != 11: - return False - try: - int(vat) - except: - return False - if int(vat[0]) >= 4: - sum = 9 * int(vat[0]) + 1 * int(vat[1]) + 4 * int(vat[2]) + \ - 8 * int(vat[3]) + 3 * int(vat[4]) + 10 * int(vat[5]) + \ - 2 * int(vat[6]) + 5 * int(vat[7]) + 7 * int(vat[8]) + \ - 6 * int(vat[9]) - if sum % 11 == 4 and int(vat[0]) == 9: - sum = sum - 45 - if sum % 11 == 4: - check = 4 - (sum % 11) - elif sum % 11 > 4: - check = 14 - (sum % 11) - elif sum % 11 < 4: - check = 3 - (sum % 11) - if check != int(vat[10]): - return False - return True - else: - if int(vat[2:4]) == 2 and int(vat[4:6]) % 4 > 0: - if int(vat[0:2]) < 1 or int(vat[0:2]) > 28: - return False - if int(vat[2:4]) == 2 and int(vat[4:6]) % 4 == 0: - if int(vat[0:2]) < 1 or int(vat[0:2]) > 29: - return False - if int(vat[2:4]) in (4, 6, 9, 11): - if int(vat[0:2]) < 1 or int(vat[0:2]) > 30: - return False - if int(vat[2:4]) in (1, 3, 5, 7, 8, 10, 12): - if int(vat[0:2]) < 1 or int(vat[0:2]) > 31: - return False - if int(vat[2:4]) < 1 or int(vat[2:4]) > 12: - return False - return True - - def check_vat_mt(self, vat): - ''' - Check Malta VAT number. - ''' - if len(vat) != 8: - return False - try: - int(vat) - except: - return False - - if int(vat[0:6]) < 100000: - return False - - sum = 3 * int(vat[0]) + 4 * int(vat[1]) + 6 * int(vat[2]) + \ - 7 * int(vat[3]) + 8 * int(vat[4]) + 9 * int(vat[5]) - check = 37 - (sum % 37) - if check != int(vat[6:8]): - return False - return True - - def check_vat_nl(self, vat): - ''' - Check Netherlands VAT number. - ''' - if len(vat) != 12: - return False - try: - int(vat[0:9]) - int(vat[10:12]) - except: - return False - if int(vat[0:8]) <= 0: - return False - if vat[9] != 'B': - return False - - sum = 9 * int(vat[0]) + 8 * int(vat[1]) + 7 * int(vat[2]) + \ - 6 * int(vat[3]) + 5 * int(vat[4]) + 4 * int(vat[5]) + \ - 3 * int(vat[6]) + 2 * int(vat[7]) - - check = sum % 11 - if check == 10: - return False - if check != int(vat[8]): - return False - return True - - def check_vat_pl(self, vat): - ''' - Check Poland VAT number. - ''' - if len(vat) != 10: - return False - try: - int(vat) - except: - return False - - sum = 6 * int(vat[0]) + 5 * int(vat[1]) + 7 * int(vat[2]) + \ - 2 * int(vat[3]) + 3 * int(vat[4]) + 4 * int(vat[5]) + \ - 5 * int(vat[6]) + 6 * int(vat[7]) + 7 * int(vat[8]) - check = sum % 11 - if check == 10: - return False - if check != int(vat[9]): - return False - return True - - def check_vat_pt(self, vat): - ''' - Check Portugal VAT number. - ''' - if len(vat) != 9: - return False - try: - int(vat) - except: - return False - - if int(vat[0]) <= 0: - return False - - sum = 9 * int(vat[0]) + 8 * int(vat[1]) + 7 * int(vat[2]) + \ - 6 * int(vat[3]) + 5 * int(vat[4]) + 4 * int(vat[5]) + \ - 3 * int(vat[6]) + 2 * int(vat[7]) - check = 11 - (sum % 11) - if check == 10 or check == 11: - check = 0 - return True - - def check_vat_ro(self, vat): - ''' - Check Romania VAT number. - ''' - try: - int(vat) - except: - return False - - if len(vat) >= 2 and len(vat) <= 10: - vat = (10 - len(vat)) * '0' + vat - sum = 7 * int(vat[0]) + 5 * int(vat[1]) + 3 * int(vat[2]) + \ - 2 * int(vat[3]) + 1 * int(vat[4]) + 7 * int(vat[5]) + \ - 5 * int(vat[6]) + 3 * int(vat[7]) + 2 * int(vat[8]) - check = (sum * 10) % 11 - if check == 10: - check = 0 - if check != int(vat[9]): - return False - return True - elif len(vat) == 13: - if int(vat[0]) not in (1, 2, 3, 4, 6): - return False - if int(vat[3:5]) < 1 or int(vat[3:5]) > 12: - return False - if int(vat[3:5]) == 2 and int(vat[1:3]) % 4 > 0: - if int(vat[5:7]) < 1 or int(vat[5:7]) > 28: - return False - if int(vat[3:5]) == 2 and int(vat[1:3]) % 4 == 0: - if int(vat[5:7]) < 1 or int(vat[5:7]) > 29: - return False - if int(vat[3:5]) in (4, 6, 9, 11): - if int(vat[5:7]) < 1 or int(vat[5:7]) > 30: - return False - if int(vat[3:5]) in (1, 3, 5, 7, 8, 10, 12): - if int(vat[5:7]) < 1 or int(vat[5:7]) > 31: - return False - - sum = 2 * int(vat[0]) + 7 * int(vat[1]) + 9 * int(vat[2]) + \ - 1 * int(vat[3]) + 4 * int(vat[4]) + 6 * int(vat[5]) + \ - 3 * int(vat[6]) + 5 * int(vat[7]) + 8 * int(vat[8]) + \ - 2 * int(vat[9]) + 7 * int(vat[10]) + 9 * int(vat[11]) - check = sum % 11 - if check == 10: - check = 1 - if check != int(vat[12]): - return False - return True - return False - - def check_vat_se(self, vat): - ''' - Check Sweden VAT number. - ''' - if len(vat) != 12: - return False - try: - int(vat) - except: - return False - - if int(vat[9:11]) < 0: - return False - - sum = mult_add(2, int(vat[0])) + int(vat[1]) + \ - mult_add(2, int(vat[2])) + int(vat[3]) + \ - mult_add(2, int(vat[4])) + int(vat[5]) + \ - mult_add(2, int(vat[6])) + int(vat[7]) + \ - mult_add(2, int(vat[8])) - check = 10 - (sum % 10) - if check == 10: - check = 0 - if check != int(vat[9]): - return False - return True - - def check_vat_si(self, vat): - ''' - Check Slovenia VAT number. - ''' - if len(vat) != 8: - return False - try: - int(vat) - except: - return False - if int(vat[0:7]) <= 999999: - return False - - sum = 8 * int(vat[0]) + 7 * int(vat[1]) + 6 * int(vat[2]) + \ - 5 * int(vat[3]) + 4 * int(vat[4]) + 3 * int(vat[5]) + \ - 2 * int(vat[6]) - check = 11 - (sum % 11) - if check == 10: - check = 0 - if check == 11: - check = 1 - if check != int(vat[7]): - return False - return True - - def check_vat_sk(self, vat): - ''' - Check Slovakia VAT number. - ''' - try: - int(vat) - except: - return False - if len(vat) not in(9, 10): - return False - - if int(vat[0:2]) in (0, 10, 20) and len(vat) == 10: - return True - - if len(vat) == 10: - if int(vat[0:2]) < 54 or int(vat[0:2]) > 99: - return False - - if len(vat) == 9: - if int(vat[0:2]) > 53 : - return False - - if int(vat[2:4]) < 1: - return False - if int(vat[2:4]) > 12 and int(vat[2:4]) < 51: - return False - if int(vat[2:4]) > 62: - return False - if int(vat[2:4]) in (2, 52) and int(vat[0:2]) % 4 > 0: - if int(vat[4:6]) < 1 or int(vat[4:6]) > 28: - return False - if int(vat[2:4]) in (2, 52) and int(vat[0:2]) % 4 == 0: - if int(vat[4:6]) < 1 or int(vat[4:6]) > 29: - return False - if int(vat[2:4]) in (4, 6, 9, 11, 54, 56, 59, 61): - if int(vat[4:6]) < 1 or int(vat[4:6]) > 30: - return False - if int(vat[2:4]) in (1, 3, 5, 7, 8, 10, 12, - 51, 53, 55, 57, 58, 60, 62): - if int(vat[4:6]) < 1 or int(vat[4:6]) > 31: - return False - return True + # Mexican VAT verification, contributed by + # and Panos Christeas __check_vat_mx_re = re.compile(r"(?P[A-Za-z\xd1\xf1&]{3,4})" \ r"[ \-_]?" \ r"(?P[0-9]{2})(?P[01][0-9])(?P[0-3][0-9])" \ r"[ \-_]?" \ r"(?P[A-Za-z0-9&\xd1\xf1]{3})$") - def check_vat_mx(self, vat): ''' Mexican VAT verification - + Verificar RFC México ''' # we convert to 8-bit encoding, to help the regex parse only bytes @@ -1101,12 +133,12 @@ class res_partner(osv.osv): datetime.date(ano, int(m.group('mes')), int(m.group('dia'))) except ValueError: return False - + #Valid format and valid date return True - # check_vat_no contributed by Rolv Råen (adEgo) + # Norway VAT validation, contributed by Rolv Råen (adEgo) def check_vat_no(self, vat): ''' Check Norway VAT number.See http://www.brreg.no/english/coordination/number.html diff --git a/addons/base_vat/base_vat_view.xml b/addons/base_vat/base_vat_view.xml index 6e00fc61ae0..69a1870ea72 100644 --- a/addons/base_vat/base_vat_view.xml +++ b/addons/base_vat/base_vat_view.xml @@ -1,21 +1,21 @@ - + - - res.partner.vat.inherit - res.partner - - - - - - - - - - + + res.partner.vat.inherit + res.partner + + + + + + + + + + - + diff --git a/addons/crm/crm_installer.py b/addons/crm/crm_installer.py index 595cfbc2382..fc3816c80fa 100644 --- a/addons/crm/crm_installer.py +++ b/addons/crm/crm_installer.py @@ -30,6 +30,7 @@ class crm_installer(osv.osv_memory): 'crm_helpdesk': fields.boolean('Helpdesk', help="Manages a Helpdesk service."), 'crm_fundraising': fields.boolean('Fundraising', help="This may help associations in their fundraising process and tracking."), 'crm_claim': fields.boolean('Claims', help="Manages the suppliers and customers claims, including your corrective or preventive actions."), + 'import_sugarcrm': fields.boolean('Import Data from SugarCRM', help="Help you to import and update data from SugarCRM to OpenERP"), 'crm_caldav': fields.boolean('Calendar Synchronizing', help="Helps you to synchronize the meetings with other calendar clients and mobiles."), 'sale_crm': fields.boolean('Opportunity to Quotation', help="Create a Quotation from an Opportunity."), 'fetchmail': fields.boolean('Fetch Emails', help="Allows you to receive E-Mails from POP/IMAP server."), @@ -49,6 +50,7 @@ class crm_installer(osv.osv_memory): nodes = doc.xpath("//field[@name='sale_crm']") for node in nodes: node.set('invisible', '0') + node.set('modifiers', '{}') res['arch'] = etree.tostring(doc) return res diff --git a/addons/crm/crm_installer_view.xml b/addons/crm/crm_installer_view.xml index b2abddefbf3..cca8fc8560e 100644 --- a/addons/crm/crm_installer_view.xml +++ b/addons/crm/crm_installer_view.xml @@ -16,6 +16,7 @@ + diff --git a/addons/crm/crm_lead_demo.xml b/addons/crm/crm_lead_demo.xml index e1366266c0a..390932c9e0a 100644 --- a/addons/crm/crm_lead_demo.xml +++ b/addons/crm/crm_lead_demo.xml @@ -44,7 +44,6 @@ - @@ -266,12 +265,17 @@ - + + BalmerInc S.A. + Rue des Palais 51, bte 33 + Bruxelles + + @@ -282,15 +286,65 @@ - + + Lucie Vonck + Chaussée de Namur + Grand-Rosière + + + + + + opportunity + + + + + + + + + + + + + + + Université de Liège + Place du 20Août + Liège + + + + + + opportunity + + + + + + + + + + + + + + Bank Wealthy and sons + 1 rue Rockfeller + Paris + + - + opportunity @@ -308,7 +362,7 @@ - + opportunity @@ -324,6 +378,11 @@ + Dubois sprl + Avenue de la Liberté 56 + Brussels + + @@ -370,6 +429,82 @@ + Axelor + 12 rue Albert Einstein + Champs sur Marne + + + + + + + + opportunity + + + + + + + + + + + + Thymbra + Palermo, Capital Federal + C1414CMS Capital Federal + Buenos Aires + + + + + + + + opportunity + + + + + + + + + + + + Eric Dubois + Chaussée de Binche, 27 + Mons + + + + + + + opportunity + + + + + + + + + + + + + opportunity + + + + + + + + diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml index 118bf117035..1a2e1f706ac 100644 --- a/addons/crm/crm_lead_view.xml +++ b/addons/crm/crm_lead_view.xml @@ -341,7 +341,6 @@
- diff --git a/addons/crm/crm_meeting_view.xml b/addons/crm/crm_meeting_view.xml index befcbd7bcad..636cb8289fb 100644 --- a/addons/crm/crm_meeting_view.xml +++ b/addons/crm/crm_meeting_view.xml @@ -58,7 +58,7 @@ - + \n" -"Language-Team: \n" +"PO-Revision-Date: 2011-09-20 07:48+0000\n" +"Last-Translator: Jiří Hajda \n" +"Language-Team: Czech \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-05 05:31+0000\n" -"X-Generator: Launchpad (build 13830)\n" +"X-Launchpad-Export-Date: 2011-09-21 04:50+0000\n" +"X-Generator: Launchpad (build 13996)\n" +"X-Poedit-Language: Czech\n" #. module: hr_contract #: view:hr.contract.wage.type:0 msgid "Hourly cost computation" -msgstr "" +msgstr "Výpočet hodinové ceny" #. module: hr_contract #: selection:hr.contract.wage.type,type:0 msgid "Gross" -msgstr "" +msgstr "Hrubého" #. module: hr_contract #: view:hr.contract:0 msgid "Trial Period" -msgstr "" +msgstr "Zkušební období" #. module: hr_contract #: field:hr.contract,trial_date_start:0 msgid "Trial Start Date" -msgstr "" +msgstr "Zkušební počáteční datum" #. module: hr_contract #: view:hr.contract:0 msgid "Passport" -msgstr "" +msgstr "Pas" #. module: hr_contract #: view:hr.employee:0 msgid "Medical Examination" -msgstr "" +msgstr "Zdravotní vyšetření" #. module: hr_contract #: field:hr.employee,vehicle:0 msgid "Company Vehicle" -msgstr "" +msgstr "Firemní vozidlo" #. module: hr_contract #: field:hr.contract.wage.type,name:0 msgid "Wage Type Name" -msgstr "" +msgstr "Jméno typu mzdy" #. module: hr_contract #: view:hr.employee:0 msgid "Miscellaneous" -msgstr "" +msgstr "Různé" #. module: hr_contract #: view:hr.contract:0 msgid "Current" -msgstr "" +msgstr "Aktuální" #. module: hr_contract #: field:hr.contract.wage.type,factor_type:0 msgid "Factor for hour cost" -msgstr "" +msgstr "Koeficient pro cenu hodiny" #. module: hr_contract #: view:hr.contract:0 msgid "Overpassed" -msgstr "" +msgstr "Uplynulý" #. module: hr_contract #: view:hr.contract.wage.type:0 msgid "Wage Types" -msgstr "" +msgstr "Typ mzdy" #. module: hr_contract #: field:hr.contract,department_id:0 msgid "Department" -msgstr "" +msgstr "Oddělení" #. module: hr_contract #: selection:hr.contract.wage.type,type:0 msgid "Basic" -msgstr "" +msgstr "Základní" #. module: hr_contract #: view:hr.contract:0 #: field:hr.contract,employee_id:0 #: model:ir.model,name:hr_contract.model_hr_employee msgid "Employee" -msgstr "" +msgstr "Zaměstnanec" #. module: hr_contract #: selection:hr.contract.wage.type,type:0 msgid "Net" -msgstr "" +msgstr "Čistého" #. module: hr_contract #: model:ir.module.module,shortdesc:hr_contract.module_meta_information msgid "Human Resources Contracts" -msgstr "" +msgstr "Smlouvy lidských zdrojů" #. module: hr_contract #: field:hr.contract.wage.type.period,factor_days:0 msgid "Hours in the period" -msgstr "" +msgstr "Hodin v období" #. module: hr_contract #: field:hr.employee,vehicle_distance:0 msgid "Home-Work Distance" -msgstr "" +msgstr "Vzdálenost z domu do práce" #. module: hr_contract #: view:hr.contract:0 @@ -125,32 +126,32 @@ msgstr "" #: model:ir.actions.act_window,name:hr_contract.action_hr_contract #: model:ir.ui.menu,name:hr_contract.hr_menu_contract msgid "Contracts" -msgstr "" +msgstr "Smlouvy" #. module: hr_contract #: view:hr.employee:0 msgid "Personal Info" -msgstr "" +msgstr "Osobní informace" #. module: hr_contract #: view:hr.contract:0 msgid "Job" -msgstr "" +msgstr "Práce" #. module: hr_contract #: view:hr.contract:0 msgid "Search Contract" -msgstr "" +msgstr "Hledat smlouvu" #. module: hr_contract #: help:hr.employee,contract_id:0 msgid "Latest contract of the employee" -msgstr "" +msgstr "Poslední smlouva zaměstnance" #. module: hr_contract #: field:hr.contract,advantages_net:0 msgid "Deductions" -msgstr "" +msgstr "Odpočty" #. module: hr_contract #: model:ir.module.module,description:hr_contract.module_meta_information @@ -163,33 +164,40 @@ msgid "" " You can assign several contracts per employee.\n" " " msgstr "" +"\n" +" Přidává všechny informace zaměstnance ke správě smluv:\n" +" * Rodinný stav,\n" +" * Bezpečnostní číslo,\n" +" * Místo narození, datum narození, ...\n" +" Ke každému zaměstnanci můžete přiřadit několik smluv.\n" +" " #. module: hr_contract #: view:hr.contract:0 #: field:hr.contract,advantages:0 msgid "Advantages" -msgstr "" +msgstr "Výhody" #. module: hr_contract #: view:hr.contract:0 msgid "Valid for" -msgstr "" +msgstr "Platné pro" #. module: hr_contract #: view:hr.contract:0 msgid "Work Permit" -msgstr "" +msgstr "Pracovní povolení" #. module: hr_contract #: field:hr.employee,children:0 msgid "Number of Children" -msgstr "" +msgstr "Počet dětí" #. module: hr_contract #: model:ir.actions.act_window,name:hr_contract.action_hr_contract_type #: model:ir.ui.menu,name:hr_contract.hr_menu_contract_type msgid "Contract Types" -msgstr "" +msgstr "Typy smluv" #. module: hr_contract #: field:hr.contract,wage_type_id:0 @@ -198,44 +206,44 @@ msgstr "" #: model:ir.model,name:hr_contract.model_hr_contract_wage_type #: model:ir.ui.menu,name:hr_contract.hr_menu_contract_wage_type msgid "Wage Type" -msgstr "" +msgstr "Typ mzdy" #. module: hr_contract #: constraint:hr.employee:0 msgid "Error ! You cannot create recursive Hierarchy of Employees." -msgstr "" +msgstr "Chyba ! Nemůžete vytvořit rekurzivní Hiearchii zaměstnanců" #. module: hr_contract #: field:hr.contract,date_end:0 msgid "End Date" -msgstr "" +msgstr "Datum ukončení" #. module: hr_contract #: field:hr.contract,wage:0 msgid "Wage" -msgstr "" +msgstr "Mzda" #. module: hr_contract #: field:hr.contract,name:0 msgid "Contract Reference" -msgstr "" +msgstr "Odkaz smlouvy" #. module: hr_contract #: help:hr.employee,vehicle_distance:0 msgid "In kilometers" -msgstr "" +msgstr "V kilometrech" #. module: hr_contract #: view:hr.contract:0 #: field:hr.contract,notes:0 msgid "Notes" -msgstr "" +msgstr "Poznámky" #. module: hr_contract #: constraint:hr.employee:0 msgid "" "Error ! You cannot select a department for which the employee is the manager." -msgstr "" +msgstr "Chyba ! Nemůžete vybrat oddělení, kterého je zaměstnance vedoucí." #. module: hr_contract #: view:hr.contract:0 @@ -243,7 +251,7 @@ msgstr "" #: model:ir.model,name:hr_contract.model_hr_contract #: model:ir.ui.menu,name:hr_contract.next_id_56 msgid "Contract" -msgstr "" +msgstr "Smlouva" #. module: hr_contract #: view:hr.contract:0 @@ -252,92 +260,92 @@ msgstr "" #: field:hr.contract.type,name:0 #: model:ir.model,name:hr_contract.model_hr_contract_type msgid "Contract Type" -msgstr "" +msgstr "Typ smlouvy" #. module: hr_contract #: view:hr.contract.wage.type.period:0 msgid "Search Wage Period" -msgstr "" +msgstr "Hledat mzdové období" #. module: hr_contract #: view:hr.contract:0 #: field:hr.contract,working_hours:0 msgid "Working Schedule" -msgstr "" +msgstr "Pracovní plán" #. module: hr_contract #: view:hr.employee:0 msgid "Job Info" -msgstr "" +msgstr "Pracovní informace" #. module: hr_contract #: field:hr.contract.wage.type,period_id:0 #: view:hr.contract.wage.type.period:0 #: model:ir.model,name:hr_contract.model_hr_contract_wage_type_period msgid "Wage Period" -msgstr "" +msgstr "Mzdové období" #. module: hr_contract #: field:hr.contract,job_id:0 msgid "Job Title" -msgstr "" +msgstr "Název pozice" #. module: hr_contract #: field:hr.employee,manager:0 msgid "Is a Manager" -msgstr "" +msgstr "Je vedoucí" #. module: hr_contract #: field:hr.contract,date_start:0 msgid "Start Date" -msgstr "" +msgstr "Počáteční datum" #. module: hr_contract #: constraint:hr.contract:0 msgid "Error! contract start-date must be lower then contract end-date." -msgstr "" +msgstr "Chyba! Počáteční datum smlouvy musí být nižší než konečné datum." #. module: hr_contract #: view:hr.contract.wage.type:0 msgid "Search Wage Type" -msgstr "" +msgstr "Hledat typ mzdy" #. module: hr_contract #: field:hr.contract.wage.type,type:0 msgid "Type" -msgstr "" +msgstr "Typ" #. module: hr_contract #: field:hr.contract,trial_date_end:0 msgid "Trial End Date" -msgstr "" +msgstr "Zkušební koncové datum" #. module: hr_contract #: view:hr.contract:0 #: view:hr.contract.wage.type:0 msgid "Group By..." -msgstr "" +msgstr "Seskupit podle..." #. module: hr_contract #: field:hr.contract.wage.type.period,name:0 msgid "Period Name" -msgstr "" +msgstr "Název období" #. module: hr_contract #: view:hr.contract.wage.type:0 msgid "Period" -msgstr "" +msgstr "Období" #. module: hr_contract #: field:hr.employee,place_of_birth:0 msgid "Place of Birth" -msgstr "" +msgstr "Místo narození" #. module: hr_contract #: model:ir.actions.act_window,name:hr_contract.action_hr_contract_wage_type_period #: model:ir.ui.menu,name:hr_contract.hr_menu_contract_wage_type_period msgid "Wage period" -msgstr "" +msgstr "Mzdové období" #. module: hr_contract #: help:hr.contract.wage.type,factor_type:0 @@ -346,28 +354,30 @@ msgid "" "This field is used by the timesheet system to compute the price of an hour " "of work wased on the contract of the employee" msgstr "" +"Toto pole je použito časovým rozvrhem systému pro výpočet ceny za hodinu " +"práce vynaložené na smlouvu zaměstnance" #. module: hr_contract #: view:hr.contract:0 msgid "Duration" -msgstr "" +msgstr "Trvání" #. module: hr_contract #: field:hr.employee,medic_exam:0 msgid "Medical Examination Date" -msgstr "" +msgstr "Datum zdravotní prohlídky" #. module: hr_contract #: field:hr.contract,advantages_gross:0 msgid "Allowances" -msgstr "" +msgstr "Dávky" #. module: hr_contract #: view:hr.contract:0 msgid "Main Data" -msgstr "" +msgstr "Hlavní data" #. module: hr_contract #: view:hr.contract.type:0 msgid "Search Contract Type" -msgstr "" +msgstr "Hledat typ smlouvy" diff --git a/addons/hr_holidays/hr_holidays.py b/addons/hr_holidays/hr_holidays.py index 4b04b566e35..9ca68bdb55e 100644 --- a/addons/hr_holidays/hr_holidays.py +++ b/addons/hr_holidays/hr_holidays.py @@ -204,14 +204,17 @@ class hr_holidays(osv.osv): def onchange_sec_id(self, cr, uid, ids, status, context=None): warning = {} + double_validation = False + obj_holiday_status = self.pool.get('hr.holidays.status') if status: - brows_obj = self.pool.get('hr.holidays.status').browse(cr, uid, status, context=context) - if brows_obj.categ_id and brows_obj.categ_id.section_id and not brows_obj.categ_id.section_id.allow_unlink: + holiday_status = obj_holiday_status.browse(cr, uid, status, context=context) + double_validation = holiday_status.double_validation + if holiday_status.categ_id and holiday_status.categ_id.section_id and not holiday_status.categ_id.section_id.allow_unlink: warning = { 'title': "Warning for ", 'message': "You won\'t be able to cancel this leave request because the CRM Sales Team of the leave type disallows." } - return {'warning': warning} + return {'warning': warning, 'value': {'double_validation': double_validation}} def set_to_draft(self, cr, uid, ids, *args): self.write(cr, uid, ids, { diff --git a/addons/hr_timesheet/i18n/cs.po b/addons/hr_timesheet/i18n/cs.po index c6dd897c9a0..089a96b1d85 100644 --- a/addons/hr_timesheet/i18n/cs.po +++ b/addons/hr_timesheet/i18n/cs.po @@ -4,45 +4,46 @@ # msgid "" msgstr "" -"Project-Id-Version: OpenERP Server 5.0.4\n" +"Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:15+0000\n" -"PO-Revision-Date: 2009-02-03 20:59+0000\n" -"Last-Translator: Fabien (Open ERP) \n" -"Language-Team: \n" +"PO-Revision-Date: 2011-09-20 08:48+0000\n" +"Last-Translator: Jiří Hajda \n" +"Language-Team: Czech \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-05 05:24+0000\n" -"X-Generator: Launchpad (build 13830)\n" +"X-Launchpad-Export-Date: 2011-09-21 04:50+0000\n" +"X-Generator: Launchpad (build 13996)\n" +"X-Poedit-Language: Czech\n" #. module: hr_timesheet #: model:product.template,name:hr_timesheet.product_consultant_product_template msgid "Service on Timesheet" -msgstr "" +msgstr "SLužby v časovém rozvrhu" #. module: hr_timesheet #: code:addons/hr_timesheet/report/user_timesheet.py:43 #: code:addons/hr_timesheet/report/users_timesheet.py:77 #, python-format msgid "Wed" -msgstr "" +msgstr "St" #. module: hr_timesheet #: view:hr.sign.out.project:0 msgid "(Keep empty for current_time)" -msgstr "" +msgstr "(Nechejte prázdné pro aktuální čas)" #. module: hr_timesheet #: code:addons/hr_timesheet/wizard/hr_timesheet_sign_in_out.py:132 #, python-format msgid "No employee defined for your user !" -msgstr "" +msgstr "Pro vašeho uživatele nebyl určen zaměstnanec !" #. module: hr_timesheet #: view:hr.analytic.timesheet:0 msgid "Group By..." -msgstr "" +msgstr "Seskupit podle..." #. module: hr_timesheet #: model:ir.actions.act_window,help:hr_timesheet.action_hr_timesheet_sign_in @@ -52,16 +53,20 @@ msgid "" "analytic account. This feature allows to record at the same time the " "attendance and the timesheet." msgstr "" +"Zaměstnanci mohou vkládat své časy strávené na různých projektech. Projekt " +"je analytický účet a čas strávený na projektu generuje ceny na na " +"analytickém účtu. Tato funkce umožňuje zaznamenat ve stejný čas docházku a " +"časový rozvrh." #. module: hr_timesheet #: view:hr.analytic.timesheet:0 msgid "Today" -msgstr "" +msgstr "Dnes" #. module: hr_timesheet #: field:hr.employee,journal_id:0 msgid "Analytic Journal" -msgstr "" +msgstr "Analytický deník" #. module: hr_timesheet #: view:hr.sign.out.project:0 @@ -72,31 +77,31 @@ msgstr "Ukončit práci" #: model:ir.actions.act_window,name:hr_timesheet.action_hr_timesheet_employee #: model:ir.ui.menu,name:hr_timesheet.menu_hr_timesheet_employee msgid "Employee Timesheet" -msgstr "" +msgstr "Časový rozvrh zaměstnance" #. module: hr_timesheet #: view:account.analytic.account:0 msgid "Work done stats" -msgstr "" +msgstr "Statistika dokončené práce" #. module: hr_timesheet #: view:hr.analytic.timesheet:0 #: model:ir.ui.menu,name:hr_timesheet.menu_hr_reporting_timesheet msgid "Timesheet" -msgstr "" +msgstr "Časový rozvrh" #. module: hr_timesheet #: selection:hr.analytical.timesheet.employee,month:0 #: selection:hr.analytical.timesheet.users,month:0 msgid "janvier" -msgstr "" +msgstr "leden" #. module: hr_timesheet #: code:addons/hr_timesheet/report/user_timesheet.py:43 #: code:addons/hr_timesheet/report/users_timesheet.py:77 #, python-format msgid "Mon" -msgstr "" +msgstr "Po" #. module: hr_timesheet #: view:hr.sign.in.project:0 @@ -111,27 +116,31 @@ msgid "" "project generates costs on the analytic account. This feature allows to " "record at the same time the attendance and the timesheet." msgstr "" +"Zaměstnanci mohou vkládat své časy strávené na různých projektech, ke kterým " +"jsou přiřazeni. Projekt je analytický účet a čas strávený na projektu " +"generuje ceny na na analytickém účtu. Tato funkce umožňuje zaznamenat ve " +"stejný čas docházku a časový rozvrh." #. module: hr_timesheet #: field:hr.sign.out.project,analytic_amount:0 msgid "Minimum Analytic Amount" -msgstr "" +msgstr "Minimální analytická částka" #. module: hr_timesheet #: view:hr.analytical.timesheet.employee:0 msgid "Monthly Employee Timesheet" -msgstr "" +msgstr "Měsíční časový rozvrh zaměstnance" #. module: hr_timesheet #: view:hr.sign.out.project:0 msgid "Work done in the last period" -msgstr "" +msgstr "Dokončená práce v minulém období" #. module: hr_timesheet #: constraint:hr.employee:0 msgid "" "Error ! You cannot select a department for which the employee is the manager." -msgstr "" +msgstr "Chyba ! Nemůžete vybrat oddělení, kterého je zaměstnance vedoucí." #. module: hr_timesheet #: field:hr.sign.in.project,state:0 @@ -143,39 +152,39 @@ msgstr "Současné datum" #: field:hr.sign.in.project,name:0 #: field:hr.sign.out.project,name:0 msgid "Employees name" -msgstr "" +msgstr "Jméno zaměstnance" #. module: hr_timesheet #: model:ir.model,name:hr_timesheet.model_hr_analytical_timesheet_users msgid "Print Employees Timesheet" -msgstr "" +msgstr "Tisknou časový rozvrh zaměstnance" #. module: hr_timesheet #: code:addons/hr_timesheet/hr_timesheet.py:174 #: code:addons/hr_timesheet/hr_timesheet.py:176 #, python-format msgid "Warning !" -msgstr "" +msgstr "Varování !" #. module: hr_timesheet #: code:addons/hr_timesheet/wizard/hr_timesheet_sign_in_out.py:77 #: code:addons/hr_timesheet/wizard/hr_timesheet_sign_in_out.py:132 #, python-format msgid "UserError" -msgstr "" +msgstr "UserError" #. module: hr_timesheet #: code:addons/hr_timesheet/wizard/hr_timesheet_sign_in_out.py:77 #, python-format msgid "No cost unit defined for this employee !" -msgstr "" +msgstr "Pro tohoto zaměstnance nebyla určena cenová jednotka !" #. module: hr_timesheet #: code:addons/hr_timesheet/report/user_timesheet.py:43 #: code:addons/hr_timesheet/report/users_timesheet.py:77 #, python-format msgid "Tue" -msgstr "" +msgstr "Út" #. module: hr_timesheet #: field:hr.sign.out.project,account_id:0 @@ -186,32 +195,32 @@ msgstr "Analytický účet" #: code:addons/hr_timesheet/wizard/hr_timesheet_print_employee.py:42 #, python-format msgid "Warning" -msgstr "" +msgstr "Varování" #. module: hr_timesheet #: model:ir.module.module,shortdesc:hr_timesheet.module_meta_information msgid "Human Resources (Timesheet encoding)" -msgstr "" +msgstr "Lidské zdroje (Kódování časových rozvrhů)" #. module: hr_timesheet #: view:hr.sign.in.project:0 #: view:hr.sign.out.project:0 msgid "Sign In/Out By Project" -msgstr "" +msgstr "Přihlášení/Odhlášení podle projektu" #. module: hr_timesheet #: code:addons/hr_timesheet/report/user_timesheet.py:43 #: code:addons/hr_timesheet/report/users_timesheet.py:77 #, python-format msgid "Sat" -msgstr "" +msgstr "So" #. module: hr_timesheet #: code:addons/hr_timesheet/report/user_timesheet.py:43 #: code:addons/hr_timesheet/report/users_timesheet.py:77 #, python-format msgid "Sun" -msgstr "" +msgstr "Ne" #. module: hr_timesheet #: view:hr.analytical.timesheet.employee:0 @@ -222,18 +231,18 @@ msgstr "Tisk" #. module: hr_timesheet #: view:hr.analytic.timesheet:0 msgid "Timesheet Lines" -msgstr "" +msgstr "Řádky časového rozvrhu" #. module: hr_timesheet #: selection:hr.analytical.timesheet.employee,month:0 #: selection:hr.analytical.timesheet.users,month:0 msgid "juillet" -msgstr "" +msgstr "červenec" #. module: hr_timesheet #: view:hr.analytical.timesheet.users:0 msgid "Monthly Employees Timesheet" -msgstr "" +msgstr "Měsíční časový rozvrh zaměstnance" #. module: hr_timesheet #: code:addons/hr_timesheet/report/user_timesheet.py:40 @@ -242,7 +251,7 @@ msgstr "" #: selection:hr.analytical.timesheet.users,month:0 #, python-format msgid "July" -msgstr "" +msgstr "Červenec" #. module: hr_timesheet #: field:hr.sign.in.project,date:0 @@ -253,13 +262,13 @@ msgstr "Počáteční datum" #. module: hr_timesheet #: view:hr.employee:0 msgid "Categories" -msgstr "" +msgstr "Kategorie" #. module: hr_timesheet #: selection:hr.analytical.timesheet.employee,month:0 #: selection:hr.analytical.timesheet.users,month:0 msgid "novembre" -msgstr "" +msgstr "listopad" #. module: hr_timesheet #: model:ir.actions.act_window,help:hr_timesheet.act_hr_timesheet_line_evry1_all_form @@ -267,6 +276,8 @@ msgid "" "Through Working Hours you can register your working hours by project every " "day." msgstr "" +"Pomocí pracovních hodin můžete každý den registrovat vaše pracovní hodiny " +"podle projektu." #. module: hr_timesheet #: model:ir.module.module,description:hr_timesheet.module_meta_information @@ -283,6 +294,18 @@ msgid "" "to set up a management by affair.\n" " " msgstr "" +"\n" +"Tento modul realizuje systém časového rozvrhu. Každý zaměstnanec může " +"zadávat a\n" +"sledovat svůj čas strávený na různých projektech. Projekt je \n" +"analytický účet a čas strávený na projektu generuje ceny na\n" +"analytickém účtu.\n" +"\n" +"Je poskytováno mnoho vykazování nad časem a sledováním zaměstnanců.\n" +"\n" +"Je celkově integrováno s module účtování cen. Umožňuje vám\n" +"nastavit správu podle poměru.\n" +" " #. module: hr_timesheet #: code:addons/hr_timesheet/report/user_timesheet.py:40 @@ -291,18 +314,18 @@ msgstr "" #: selection:hr.analytical.timesheet.users,month:0 #, python-format msgid "March" -msgstr "" +msgstr "Březen" #. module: hr_timesheet #: view:hr.analytic.timesheet:0 msgid "Total cost" -msgstr "" +msgstr "Celková cena" #. module: hr_timesheet #: selection:hr.analytical.timesheet.employee,month:0 #: selection:hr.analytical.timesheet.users,month:0 msgid "décembre" -msgstr "" +msgstr "prosinec" #. module: hr_timesheet #: code:addons/hr_timesheet/report/user_timesheet.py:40 @@ -311,22 +334,22 @@ msgstr "" #: selection:hr.analytical.timesheet.users,month:0 #, python-format msgid "September" -msgstr "" +msgstr "Září" #. module: hr_timesheet #: model:ir.model,name:hr_timesheet.model_hr_analytic_timesheet msgid "Timesheet Line" -msgstr "" +msgstr "Řádek časového rozvrhu" #. module: hr_timesheet #: field:hr.analytical.timesheet.users,employee_ids:0 msgid "employees" -msgstr "" +msgstr "zaměstnanci" #. module: hr_timesheet #: view:account.analytic.account:0 msgid "Stats by month" -msgstr "" +msgstr "Statistika podle měsíce" #. module: hr_timesheet #: view:account.analytic.account:0 @@ -343,25 +366,25 @@ msgstr "Popis práce" #. module: hr_timesheet #: view:account.analytic.account:0 msgid "To be invoiced" -msgstr "" +msgstr "K fakturaci" #. module: hr_timesheet #: model:ir.actions.report.xml,name:hr_timesheet.report_user_timesheet msgid "Employee timesheet" -msgstr "" +msgstr "Časový rozvrh zaměstnance" #. module: hr_timesheet #: model:ir.actions.act_window,name:hr_timesheet.action_hr_timesheet_sign_in #: model:ir.actions.act_window,name:hr_timesheet.action_hr_timesheet_sign_out msgid "Sign in / Sign out by project" -msgstr "" +msgstr "Přihlášení / Odhlášení podle projektu" #. module: hr_timesheet #: code:addons/hr_timesheet/report/user_timesheet.py:43 #: code:addons/hr_timesheet/report/users_timesheet.py:77 #, python-format msgid "Fri" -msgstr "" +msgstr "Pá" #. module: hr_timesheet #: view:hr.sign.in.project:0 @@ -375,27 +398,29 @@ msgid "" "Analytic journal is not defined for employee %s \n" "Define an employee for the selected user and assign an analytic journal!" msgstr "" +"Pro zaměstnance %s není určen Analytický deník \n" +"Určete zaměstnance pro vybraného uživatele a přiřaďte analxtický deník!" #. module: hr_timesheet #: view:hr.sign.in.project:0 msgid "(Keep empty for current time)" -msgstr "" +msgstr "(Nechejte prázdné pro aktuální čas)" #. module: hr_timesheet #: view:hr.employee:0 msgid "Timesheets" -msgstr "" +msgstr "Časové rozvrhy" #. module: hr_timesheet #: help:hr.employee,product_id:0 msgid "Specifies employee's designation as a product with type 'service'." -msgstr "" +msgstr "Určuje zařazení zaměstnance jako výrobek s typem 'služba'." #. module: hr_timesheet #: selection:hr.analytical.timesheet.employee,month:0 #: selection:hr.analytical.timesheet.users,month:0 msgid "août" -msgstr "" +msgstr "srpen" #. module: hr_timesheet #: code:addons/hr_timesheet/report/user_timesheet.py:40 @@ -404,7 +429,7 @@ msgstr "" #: selection:hr.analytical.timesheet.users,month:0 #, python-format msgid "August" -msgstr "" +msgstr "Srpen" #. module: hr_timesheet #: code:addons/hr_timesheet/report/user_timesheet.py:40 @@ -413,23 +438,23 @@ msgstr "" #: selection:hr.analytical.timesheet.users,month:0 #, python-format msgid "June" -msgstr "" +msgstr "Červen" #. module: hr_timesheet #: view:hr.analytical.timesheet.employee:0 msgid "Print My Timesheet" -msgstr "" +msgstr "Tisknout můj časový rozvrh" #. module: hr_timesheet #: selection:hr.analytical.timesheet.employee,month:0 #: selection:hr.analytical.timesheet.users,month:0 msgid "mars" -msgstr "" +msgstr "březen" #. module: hr_timesheet #: view:hr.analytic.timesheet:0 msgid "Date" -msgstr "" +msgstr "Datum" #. module: hr_timesheet #: code:addons/hr_timesheet/report/user_timesheet.py:40 @@ -438,12 +463,12 @@ msgstr "" #: selection:hr.analytical.timesheet.users,month:0 #, python-format msgid "November" -msgstr "" +msgstr "Listopad" #. module: hr_timesheet #: constraint:hr.employee:0 msgid "Error ! You cannot create recursive Hierarchy of Employees." -msgstr "" +msgstr "Chyba ! Nemůžete vytvořit rekurzivní Hierarchii zaměstnanců" #. module: hr_timesheet #: field:hr.sign.out.project,date:0 @@ -457,7 +482,7 @@ msgstr "Koncové datum" #: selection:hr.analytical.timesheet.users,month:0 #, python-format msgid "October" -msgstr "" +msgstr "Říjen" #. module: hr_timesheet #: code:addons/hr_timesheet/report/user_timesheet.py:40 @@ -466,35 +491,35 @@ msgstr "" #: selection:hr.analytical.timesheet.users,month:0 #, python-format msgid "January" -msgstr "" +msgstr "Leden" #. module: hr_timesheet #: view:account.analytic.account:0 msgid "Key dates" -msgstr "" +msgstr "Klíčové dny" #. module: hr_timesheet #: code:addons/hr_timesheet/report/user_timesheet.py:43 #: code:addons/hr_timesheet/report/users_timesheet.py:77 #, python-format msgid "Thu" -msgstr "" +msgstr "Čt" #. module: hr_timesheet #: view:account.analytic.account:0 msgid "Analysis stats" -msgstr "" +msgstr "Statistiká analýza" #. module: hr_timesheet #: model:ir.model,name:hr_timesheet.model_hr_analytical_timesheet_employee msgid "Print Employee Timesheet & Print My Timesheet" -msgstr "" +msgstr "Tisknout Časový rozvrh zaměstnance & Tisknou můj časový rozvrh" #. module: hr_timesheet #: field:hr.sign.in.project,emp_id:0 #: field:hr.sign.out.project,emp_id:0 msgid "Employee ID" -msgstr "" +msgstr "ID zaměstnance" #. module: hr_timesheet #: view:hr.sign.out.project:0 @@ -504,12 +529,12 @@ msgstr "Obecné informace" #. module: hr_timesheet #: model:ir.actions.act_window,name:hr_timesheet.action_hr_timesheet_my msgid "My Timesheet" -msgstr "" +msgstr "Moje časové rozvrhy" #. module: hr_timesheet #: view:account.analytic.account:0 msgid "Analysis summary" -msgstr "" +msgstr "Souhrn analýzy" #. module: hr_timesheet #: code:addons/hr_timesheet/report/user_timesheet.py:40 @@ -518,7 +543,7 @@ msgstr "" #: selection:hr.analytical.timesheet.users,month:0 #, python-format msgid "December" -msgstr "" +msgstr "Prosinec" #. module: hr_timesheet #: view:hr.analytical.timesheet.employee:0 @@ -526,7 +551,7 @@ msgstr "" #: view:hr.sign.in.project:0 #: view:hr.sign.out.project:0 msgid "Cancel" -msgstr "Storno" +msgstr "Zrušit" #. module: hr_timesheet #: model:ir.actions.act_window,name:hr_timesheet.action_hr_timesheet_users @@ -534,30 +559,30 @@ msgstr "Storno" #: model:ir.actions.wizard,name:hr_timesheet.wizard_hr_timesheet_users #: model:ir.ui.menu,name:hr_timesheet.menu_hr_timesheet_users msgid "Employees Timesheet" -msgstr "" +msgstr "Časové rozvrhy zaměstnanců" #. module: hr_timesheet #: selection:hr.analytical.timesheet.employee,month:0 #: selection:hr.analytical.timesheet.users,month:0 msgid "février" -msgstr "" +msgstr "únor" #. module: hr_timesheet #: view:hr.analytic.timesheet:0 msgid "Information" -msgstr "" +msgstr "Informace" #. module: hr_timesheet #: field:hr.analytical.timesheet.employee,employee_id:0 #: model:ir.model,name:hr_timesheet.model_hr_employee msgid "Employee" -msgstr "" +msgstr "Zaměstnanec" #. module: hr_timesheet #: selection:hr.analytical.timesheet.employee,month:0 #: selection:hr.analytical.timesheet.users,month:0 msgid "avril" -msgstr "" +msgstr "duben" #. module: hr_timesheet #: field:hr.sign.in.project,server_date:0 @@ -568,23 +593,23 @@ msgstr "Současné datum" #. module: hr_timesheet #: view:hr.analytic.timesheet:0 msgid "Anlytic account" -msgstr "" +msgstr "Analytický účet" #. module: hr_timesheet #: view:hr.analytical.timesheet.employee:0 msgid "This wizard will print monthly timesheet" -msgstr "" +msgstr "Tento průvodce bude tisknout měsíční časový rozvrh" #. module: hr_timesheet #: view:hr.analytic.timesheet:0 #: field:hr.employee,product_id:0 msgid "Product" -msgstr "" +msgstr "Výrobek" #. module: hr_timesheet #: view:hr.analytic.timesheet:0 msgid "Invoicing" -msgstr "" +msgstr "Fakturace" #. module: hr_timesheet #: code:addons/hr_timesheet/report/user_timesheet.py:40 @@ -593,34 +618,34 @@ msgstr "" #: selection:hr.analytical.timesheet.users,month:0 #, python-format msgid "May" -msgstr "" +msgstr "Květen" #. module: hr_timesheet #: view:hr.analytic.timesheet:0 msgid "Total time" -msgstr "" +msgstr "Celkový čas" #. module: hr_timesheet #: selection:hr.analytical.timesheet.employee,month:0 #: selection:hr.analytical.timesheet.users,month:0 msgid "juin" -msgstr "" +msgstr "červen" #. module: hr_timesheet #: view:hr.sign.in.project:0 msgid "(local time on the server side)" -msgstr "(lokální čas na serveru)" +msgstr "(místní čas na straně serveru)" #. module: hr_timesheet #: model:ir.actions.act_window,name:hr_timesheet.act_hr_timesheet_line_evry1_all_form #: model:ir.ui.menu,name:hr_timesheet.menu_hr_working_hours msgid "Working Hours" -msgstr "" +msgstr "Pracovní hodiny" #. module: hr_timesheet #: model:ir.model,name:hr_timesheet.model_hr_sign_in_project msgid "Sign In By Project" -msgstr "" +msgstr "Přihlášení podle projektu" #. module: hr_timesheet #: code:addons/hr_timesheet/report/user_timesheet.py:40 @@ -629,28 +654,28 @@ msgstr "" #: selection:hr.analytical.timesheet.users,month:0 #, python-format msgid "February" -msgstr "" +msgstr "Únor" #. module: hr_timesheet #: field:hr.analytic.timesheet,line_id:0 msgid "Analytic line" -msgstr "" +msgstr "Analytický řádek" #. module: hr_timesheet #: model:ir.model,name:hr_timesheet.model_hr_sign_out_project msgid "Sign Out By Project" -msgstr "" +msgstr "Odhlášení podle projektu" #. module: hr_timesheet #: view:hr.analytical.timesheet.users:0 msgid "Employees" -msgstr "" +msgstr "Zaměstnanci" #. module: hr_timesheet #: selection:hr.analytical.timesheet.employee,month:0 #: selection:hr.analytical.timesheet.users,month:0 msgid "octobre" -msgstr "" +msgstr "říjen" #. module: hr_timesheet #: code:addons/hr_timesheet/report/user_timesheet.py:40 @@ -659,7 +684,7 @@ msgstr "" #: selection:hr.analytical.timesheet.users,month:0 #, python-format msgid "April" -msgstr "" +msgstr "Duben" #. module: hr_timesheet #: code:addons/hr_timesheet/hr_timesheet.py:176 @@ -668,12 +693,14 @@ msgid "" "No analytic account defined on the project.\n" "Please set one or we can not automatically fill the timesheet." msgstr "" +"U projektu nebyl určen analytický účet.\n" +"Prosíme nastavte jej nebo nemůžeme automaticky vyplnit časový rozvrh." #. module: hr_timesheet #: selection:hr.analytical.timesheet.employee,month:0 #: selection:hr.analytical.timesheet.users,month:0 msgid "mai" -msgstr "" +msgstr "květen" #. module: hr_timesheet #: view:account.analytic.account:0 @@ -689,13 +716,13 @@ msgstr "Začít pracovat" #. module: hr_timesheet #: view:account.analytic.account:0 msgid "Stats by user" -msgstr "" +msgstr "Statistiky podle uživatele" #. module: hr_timesheet #: code:addons/hr_timesheet/wizard/hr_timesheet_print_employee.py:42 #, python-format msgid "No employee defined for this user" -msgstr "" +msgstr "Pro tohoto uživatele nebyl určen zaměstnanec" #. module: hr_timesheet #: field:hr.analytical.timesheet.employee,year:0 @@ -706,23 +733,23 @@ msgstr "Rok" #. module: hr_timesheet #: view:hr.analytic.timesheet:0 msgid "Accounting" -msgstr "" +msgstr "Účetnictví" #. module: hr_timesheet #: field:hr.analytic.timesheet,partner_id:0 msgid "Partner Id" -msgstr "" +msgstr "Id partnera" #. module: hr_timesheet #: view:hr.sign.out.project:0 msgid "Change Work" -msgstr "" +msgstr "Změnit práci" #. module: hr_timesheet #: selection:hr.analytical.timesheet.employee,month:0 #: selection:hr.analytical.timesheet.users,month:0 msgid "septembre" -msgstr "" +msgstr "září" #~ msgid "Choose Users" #~ msgstr "Uživatelé" diff --git a/addons/import_base/__openerp__.py b/addons/import_base/__openerp__.py index 962541f427a..f244338a7e3 100644 --- a/addons/import_base/__openerp__.py +++ b/addons/import_base/__openerp__.py @@ -31,7 +31,7 @@ 'website': 'http://www.openerp.com', 'depends': ['base'], 'init_xml': [], - 'update_xml': [], + 'update_xml': ["import_base_view.xml"], 'demo_xml': [], 'test': [], #TODO provide test 'installable': True, diff --git a/addons/import_base/import_base_view.xml b/addons/import_base/import_base_view.xml new file mode 100644 index 00000000000..1368b50b6e4 --- /dev/null +++ b/addons/import_base/import_base_view.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/addons/import_base/import_framework.py b/addons/import_base/import_framework.py index 9b25ecb1ecf..b558b24696f 100644 --- a/addons/import_base/import_framework.py +++ b/addons/import_base/import_framework.py @@ -22,11 +22,13 @@ import pprint import mapper import pooler import tools - +from tools.translate import _ from threading import Thread import datetime import logging +import StringIO +import traceback pp = pprint.PrettyPrinter(indent=4) @@ -46,8 +48,10 @@ class import_framework(Thread): """ DO_NOT_FIND_DOMAIN = [('id', '=', 0)] + #TODO don't use context to pass credential parameters def __init__(self, obj, cr, uid, instance_name, module_name, email_to_notify=False, context=None): Thread.__init__(self) + self.external_id_field = 'id' self.obj = obj self.cr = cr self.uid = uid @@ -56,10 +60,9 @@ class import_framework(Thread): self.context = context or {} self.email = email_to_notify self.table_list = [] + self.logger = logging.getLogger('import_framework') self.initialize() - - - + """ Abstract Method to be implemented in the real instance @@ -71,6 +74,13 @@ class import_framework(Thread): """ pass + def init_run(self): + """ + call after intialize run in the thread, not in the main process + TO use for long initialization operation + """ + pass + def get_data(self, table): """ @return: a list of dictionaries @@ -78,6 +88,22 @@ class import_framework(Thread): """ return [{}] + def get_link(self, from_table, ids, to_table): + """ + @return: a dictionaries that contains the association between the id (from_table) + and the list (to table) of id linked + """ + return {} + + def get_external_id(self, data): + """ + @return the external id + the default implementation return self.external_id_field (that has 'id') by default + if the name of id field is different, you can overwrite this method or change the value + of self.external_id_field + """ + return data[self.external_id_field] + def get_mapping(self): """ @return: { TABLE_NAME : { @@ -140,7 +166,7 @@ class import_framework(Thread): and each data_i have a external id => in data_id['id'] """ if not datas: - return (0, 'No data in this table') + return (0, 'No data found') mapping['id'] = 'id_new' res = [] @@ -154,14 +180,15 @@ class import_framework(Thread): for k, field_name in self_dependencies: data[k] = data.get(field_name) and self._generate_xml_id(data.get(field_name), table) - data['id_new'] = self._generate_xml_id(data['id'], table) + data['id_new'] = self._generate_xml_id(self.get_external_id(data), table) fields, values = self._fields_mapp(data, mapping, table) res.append(values) model_obj = self.obj.pool.get(model) if not model_obj: - raise ValueError("%s is not a valid model name" % model) - + raise ValueError(_("%s is not a valid model name") % model) + self.logger.debug(_("fields imported : ")) + self.logger.debug(fields) (p, r, warning, s) = model_obj.import_data(self.cr, self.uid, fields, res, mode='update', current_module=self.module_name, noupdate=True, context=self.context) for (field, field_name) in self_dependencies: self._import_self_dependencies(model_obj, field, datas) @@ -296,10 +323,14 @@ class import_framework(Thread): """ domain_search = not domain_search and [('name', 'ilike', name)] or domain_search obj = self.obj.pool.get(model) + if not obj: #if the model doesn't exist + return False + xml_id = self._generate_xml_id(name, table) xml_ref = self.mapped_id_if_exist(model, domain_search, table, name) fields.append('id') data.append(xml_id) + obj.import_data(self.cr, self.uid, fields, [data], mode='update', current_module=self.module_name, noupdate=True, context=self.context) return xml_ref or xml_id @@ -343,8 +374,10 @@ class import_framework(Thread): """ self.data_started = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") self.cr = pooler.get_db(self.cr.dbname).cursor() + error = False + result = [] try: - result = [] + self.init_run() imported = set() #to invoid importing 2 times the sames modules for table in self.table_list: to_import = self.get_mapping()[table].get('import', True) @@ -352,16 +385,22 @@ class import_framework(Thread): res = self._resolve_dependencies(self.get_mapping()[table].get('dependencies', []), imported) result.extend(res) if to_import: + self.logger.debug(_("import : ") + table ) (position, warning) = self._import_table(table) result.append((table, position, warning)) imported.add(table) self.cr.commit() - + + except Exception, err: + sh = StringIO.StringIO() + traceback.print_exc(file=sh) + error = sh.getvalue() + print error finally: self.cr.close() + self.date_ended = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") - self._send_notification_email(result) - + self._send_notification_email(result, error) def _resolve_dependencies(self, dep, imported): """ @@ -375,25 +414,29 @@ class import_framework(Thread): res = self._resolve_dependencies(self.get_mapping()[dependency].get('dependencies', []), imported) result.extend(res) if to_import: + self.logger.debug("import dependency : " + dependency) r = self._import_table(dependency) (position, warning) = r result.append((dependency, position, warning)) imported.add(dependency) return result - def _send_notification_email(self, result): - if not self.email: - return + def _send_notification_email(self, result, error): + if not self.email or not self.email[0]: + return False + tools.email_send( - 'import_sugarcrm@module.openerp', + 'import@module.openerp', self.email, - self.get_email_subject(result), - self.get_email_body(result), + self.get_email_subject(result, error), + self.get_email_body(result, error), ) - logger = logging.getLogger('import_sugarcam') - logger.info("Import finished, notification email sended") + if error: + self.logger.error(_("Import failed due to an unexpected error")) + else: + self.logger.info(_("Import finished, notification email sended")) - def get_email_subject(self, result): + def get_email_subject(self, result, error=False): """ This method define the subject of the email send by openerp at the end of import @param result: a list of tuple @@ -401,9 +444,11 @@ class import_framework(Thread): @return the subject of the mail """ - return "Import of your data finished at %s" % self.date_ended + if error: + return _("Data Import failed at %s due to an unexpected error") % self.date_ended + return _("Import of your data finished at %s") % self.date_ended - def get_email_body(self, result): + def get_email_body(self, result, error=False): """ This method define the body of the email send by openerp at the end of import. The body is separated in two part the header (@see get_body_header), and the generate body with the list of table and number of record imported. @@ -414,19 +459,43 @@ class import_framework(Thread): """ - body = "started at %s and finished at %s \n" % (self.data_started, self.date_ended) + body = _("started at %s and finished at %s \n") % (self.data_started, self.date_ended) + if error: + body += _("but failed, in consequence no data were imported to keep database consistency \n error : \n") + error + for (table, nb, warning) in result: if not warning: - warning = "with no warning" + warning = _("with no warning") else: - warning = "with warning : %s" % warning - body += "%s records were imported from table %s, %s \n" % (nb, table, warning) + warning = _("with warning : %s") % warning + body += _("%s has been successfully imported from %s %s, %s \n") % (nb, self.instance_name, table, warning) return self.get_body_header(result) + "\n\n" + body def get_body_header(self, result): """ @return the first sentences written in the mail's body """ - return "The import of data \n instance name : %s \n" % self.instance_name + return _("The import of data \n instance name : %s \n") % self.instance_name -#For example of use see import_sugarcrm + + #TODO documentation test + def run_test(self): + back_get_data = self.get_data + back_get_link = self.get_link + back_init = self.initialize + self.get_data = self.get_data_test + self.get_link = self.get_link_test + self.initialize = self.intialize_test + self.run() + self.get_data = back_get_data + self.get_link = back_get_link + self.initialize = back_init + + def get_data_test(self, table): + return [{}] + + def get_link_test(self, from_table, ids, to_table): + return {} + + def intialize_test(self): + pass diff --git a/addons/import_base/mapper.py b/addons/import_base/mapper.py index 7f97ed0b615..0827509ffab 100644 --- a/addons/import_base/mapper.py +++ b/addons/import_base/mapper.py @@ -18,7 +18,7 @@ # along with this program. If not, see . # ############################################################################## - +import tools class mapper(object): """ @@ -50,14 +50,13 @@ class concat(mapper): Use : contact('field_name1', 'field_name2', delimiter='_') concat value of fields using the delimiter, delimiter is optional and by default is a space - """ def __init__(self, *arg, **delimiter): self.arg = arg self.delimiter = delimiter and delimiter.get('delimiter', ' ') or ' ' def __call__(self, external_values): - return self.delimiter.join(map(lambda x : external_values.get(x,''), self.arg)) + return self.delimiter.join(map(lambda x : tools.ustr(external_values.get(x,'')), self.arg)) class ppconcat(mapper): """ @@ -71,7 +70,7 @@ class ppconcat(mapper): self.delimiter = delimiter and delimiter.get('delimiter', ' ') or '\n\n' def __call__(self, external_values): - return self.delimiter.join(map(lambda x : x + ": " + external_values.get(x,''), self.arg)) + return self.delimiter.join(map(lambda x : x + ": " + tools.ustr(external_values.get(x,'')), self.arg)) class const(mapper): """ @@ -105,7 +104,6 @@ class value(mapper): val = external_values.get(self.fallback, self.default) return val - class map_val(mapper): """ @@ -169,5 +167,3 @@ class call(mapper): else: args.append(arg) return self.fun(external_values, *args) - - \ No newline at end of file diff --git a/addons/import_sugarcrm/__init__.py b/addons/import_sugarcrm/__init__.py new file mode 100644 index 00000000000..250589105b0 --- /dev/null +++ b/addons/import_sugarcrm/__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 import_sugarcrm +import sugar +import wizard + diff --git a/addons/import_sugarcrm/__openerp__.py b/addons/import_sugarcrm/__openerp__.py new file mode 100644 index 00000000000..071f58099b3 --- /dev/null +++ b/addons/import_sugarcrm/__openerp__.py @@ -0,0 +1,39 @@ +# -*- 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': 'Import SugarCRM Data into OpenERP Module.', + 'version': '1.0', + 'category': 'Generic Modules', + 'description': """This Module Import SugarCRM "Leads", "Opportunities", "Users", "Accounts", + "Contacts", "Employees", Meetings, Phonecalls, Emails, and Project, Project Tasks Data into OpenERP Module.""", + 'author': 'OpenERP SA', + 'website': 'http://www.openerp.com', + 'depends': ['import_base','crm', 'document'], + 'init_xml': [], + 'update_xml': ["wizard/import_message_view.xml", + "import_sugarcrm_view.xml"], + 'demo_xml': [], + 'test': [], + 'installable': True, + 'active': False, +} +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/import_sugarcrm/doc/import_sugarcrm_installation_manual.odt b/addons/import_sugarcrm/doc/import_sugarcrm_installation_manual.odt new file mode 100644 index 00000000000..2dfde16bc97 Binary files /dev/null and b/addons/import_sugarcrm/doc/import_sugarcrm_installation_manual.odt differ diff --git a/addons/import_sugarcrm/doc/import_sugarcrm_user_manual.odt b/addons/import_sugarcrm/doc/import_sugarcrm_user_manual.odt new file mode 100644 index 00000000000..2a16eeb566c Binary files /dev/null and b/addons/import_sugarcrm/doc/import_sugarcrm_user_manual.odt differ diff --git a/addons/import_sugarcrm/doc/import_sugarcrm_zsi_installation.txt b/addons/import_sugarcrm/doc/import_sugarcrm_zsi_installation.txt new file mode 100644 index 00000000000..e399d63120b --- /dev/null +++ b/addons/import_sugarcrm/doc/import_sugarcrm_zsi_installation.txt @@ -0,0 +1,8 @@ +Install the SOAP framwwork for Python : + 1. download the soap framework from http://pypi.python.org/pypi/ZSI/ + extract the file “ZSI-2.0-rc3.tar.gz” and run following 2 commands + ./setup.py build + ./setup.py install + this will install soap framework for python. + +or use the ZSI package of your distribution diff --git a/addons/import_sugarcrm/import_sugarcrm.py b/addons/import_sugarcrm/import_sugarcrm.py new file mode 100644 index 00000000000..b27748d48be --- /dev/null +++ b/addons/import_sugarcrm/import_sugarcrm.py @@ -0,0 +1,1147 @@ +# -*- 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 fields, osv +import sugar +from tools.translate import _ +from import_base.import_framework import * +from import_base.mapper import * +from datetime import datetime +import base64 +import pprint +pp = pprint.PrettyPrinter(indent=4) +#copy old import here + +import htmllib + +def unescape_htmlentities(s): + p = htmllib.HTMLParser(None) + p.save_bgn() + p.feed(s) + return p.save_end() + +class related_ref(dbmapper): + def __init__(self, type): + self.type = type + + def __call__(self, external_val): + if external_val.get('parent_type') in self.type and external_val.get('parent_id'): + return self.parent.xml_id_exist(external_val['parent_type'], external_val['parent_id']) + return '' + +class sugar_import(import_framework): + URL = False + TABLE_CONTACT = 'Contacts' + TABLE_ACCOUNT = 'Accounts' + TABLE_USER = 'Users' + TABLE_EMPLOYEE = 'Employees' + TABLE_RESSOURCE = "resource" + TABLE_OPPORTUNITY = 'Opportunities' + TABLE_LEAD = 'Leads' + TABLE_STAGE = 'crm_stage' + TABLE_ATTENDEE = 'calendar_attendee' + TABLE_CALL = 'Calls' + TABLE_MEETING = 'Meetings' + TABLE_TASK = 'Tasks' + TABLE_PROJECT = 'Project' + TABLE_PROJECT_TASK = 'ProjectTask' + TABLE_BUG = 'Bugs' + TABLE_CASE = 'Cases' + TABLE_NOTE = 'Notes' + TABLE_EMAIL = 'Emails' + TABLE_COMPAIGN = 'Campaigns' + TABLE_DOCUMENT = 'Documents' + TABLE_HISTORY_ATTACHMNET = 'history_attachment' + + MAX_RESULT_PER_PAGE = 200 + + def initialize(self): + #login + PortType,sessionid = sugar.login(self.context.get('username',''), self.context.get('password',''), self.context.get('url','')) + if sessionid == '-1': + raise osv.except_osv(_('Error !'), _('Authentication error !\nBad Username or Password or bad SugarSoap Api url !')) + self.context['port'] = PortType + self.context['session_id'] = sessionid + + def get_data(self, table): + offset = 0 + res = [] + while True: + r = sugar.search(self.context.get('port'), self.context.get('session_id'), table, offset, self.MAX_RESULT_PER_PAGE) + res.extend(r) + if len(r) < self.MAX_RESULT_PER_PAGE: + break; + offset += self.MAX_RESULT_PER_PAGE + return res + + #def get_link(self, from_table, ids, to_table): + #return sugar.relation_search(self.context.get('port'), self.context.get('session_id'), from_table, module_id=ids, related_module=to_table) + + """ + Common import method + """ + def get_category(self, val, model, name): + fields = ['name', 'object_id'] + data = [name, model] + return self.import_object(fields, data, 'crm.case.categ', 'crm_categ', name, [('object_id.model','=',model), ('name', 'ilike', name)]) + + def get_job_title(self, dict, salutation): + fields = ['shortcut', 'name', 'domain'] + if salutation: + data = [salutation, salutation, 'Contact'] + return self.import_object(fields, data, 'res.partner.title', 'contact_title', salutation, [('shortcut', '=', salutation)]) + + def get_channel_id(self, dict, val): + if not val: + return False + fields = ['name'] + data = [val] + return self.import_object(fields, data, 'res.partner.canal', 'crm_channel', val) + + def get_all_states(self, external_val, country_id): + """Get states or create new state unless country_id is False""" + state_code = external_val[0:3] #take the tree first char + fields = ['country_id/id', 'name', 'code'] + data = [country_id, external_val, state_code] + if country_id: + return self.import_object(fields, data, 'res.country.state', 'country_state', external_val) + return False + + def get_all_countries(self, val): + """Get Country, if no country match do not create anything, to avoid duplicate country code""" + return self.mapped_id_if_exist('res.country', [('name', 'ilike', val)], 'country', val) + + def get_float_time(self, dict, hour, min): + min = int(min) * 100 / 60 + return "%s.%i" % (hour, min) + + """ + import Documents + """ + + def import_related_document(self, val): + res_model = False + res_id = False + sugar_document_account = sugar.relation_search(self.context.get('port'), self.context.get('session_id'), 'Documents', module_id=val.get('id'), related_module='Accounts', query=None, deleted=None) + sugar_document_contact = sugar.relation_search(self.context.get('port'), self.context.get('session_id'), 'Documents', module_id=val.get('id'), related_module=self.TABLE_CONTACT, query=None, deleted=None) + sugar_document_opportunity = sugar.relation_search(self.context.get('port'), self.context.get('session_id'), 'Documents', module_id=val.get('id'), related_module=self.TABLE_OPPORTUNITY, query=None, deleted=None) + sugar_document_case = sugar.relation_search(self.context.get('port'), self.context.get('session_id'), 'Documents', module_id=val.get('id'), related_module=self.TABLE_CASE, query=None, deleted=None) + sugar_document_bug = sugar.relation_search(self.context.get('port'), self.context.get('session_id'), 'Documents', module_id=val.get('id'), related_module=self.TABLE_BUG, query=None, deleted=None) + if sugar_document_account: + res_id = self.get_mapped_id(self.TABLE_ACCOUNT,sugar_document_account[0]) + res_model = 'res.partner' + elif sugar_document_contact: + res_id = self.get_mapped_id(self.TABLE_CONTACT, sugar_document_contact[0]) + res_model = 'res.partner.address' + elif sugar_document_opportunity: + res_id = self.get_mapped_id(self.TABLE_OPPORTUNITY, sugar_document_opportunity[0]) + res_model = 'crm.lead' + elif sugar_document_case: + res_id = self.get_mapped_id(self.TABLE_CASE, sugar_document_case[0]) + res_model = 'crm.claim' + elif sugar_document_bug: + res_id = self.get_mapped_id(self.TABLE_BUG, sugar_document_bug[0]) + res_model = 'project.issue' + return res_id,res_model + + def import_document(self, val): + File,Filename = sugar.get_document_revision_search(self.context.get('port'), self.context.get('session_id'), val.get('document_revision_id')) + #File = base64.encodestring(File) + res_id, res_model = self.import_related_document(val) + val['res_id'] = res_id + val['res_model'] = res_model + if File: + val['datas'] = File + val['datas_fname'] = Filename + return val + + def get_document_mapping(self): + return { + 'model' : 'ir.attachment', + 'dependencies' : [self.TABLE_USER], + 'hook' : self.import_document, + 'map' : { + 'name':'document_name', + 'description': ppconcat('description'), + 'datas': 'datas', + 'datas_fname': 'datas_fname', + 'res_model': 'res_model', + 'res_id': 'res_id', + } + } + + + """ + import Emails + """ + + + def import_email(self, val): + vals = sugar.email_search(self.context.get('port'), self.context.get('session_id'), self.TABLE_EMAIL, val.get('id')) + model_obj = self.obj.pool.get('ir.model.data') + for val in vals: + xml_id = self.xml_id_exist(val.get('parent_type'), val.get('parent_id')) + model_ids = model_obj.search(self.cr, self.uid, [('name', 'like', xml_id)]) + if model_ids: + model = model_obj.browse(self.cr, self.uid, model_ids)[0] + if model.model == 'res.partner': + val['partner_id/.id'] = model.res_id + else: + val['res_id'] = model.res_id + val['model'] = model.model + return val + + def get_email_mapping(self): + return { + 'model' : 'mailgate.message', + 'dependencies' : [self.TABLE_USER, self.TABLE_ACCOUNT, self.TABLE_CONTACT, self.TABLE_LEAD, self.TABLE_OPPORTUNITY, self.TABLE_MEETING, self.TABLE_CALL], + 'hook' : self.import_email, + 'map' : { + 'name':'name', + 'history' : const("1"), + 'date':'date_sent', + 'email_from': 'from_addr_name', + 'email_to': 'to_addrs_names', + 'email_cc': 'cc_addrs_names', + 'email_bcc': 'bcc_addrs_names', + 'message_id': 'message_id', + 'res_id': 'res_id', + 'model': 'model', + 'partner_id/.id': 'partner_id/.id', + 'user_id/id': ref(self.TABLE_USER, 'assigned_user_id'), + 'description': ppconcat('description', 'description_html'), + } + } + + """ + import History(Notes) + """ + + + def import_history(self, val): + model_obj = self.obj.pool.get('ir.model.data') + xml_id = self.xml_id_exist(val.get('parent_type'), val.get('parent_id')) + model_ids = model_obj.search(self.cr, self.uid, [('name', 'like', xml_id)]) + if model_ids: + model = model_obj.browse(self.cr, self.uid, model_ids)[0] + if model.model == 'res.partner': + val['partner_id/.id'] = model.res_id + val['res_id'] = model.res_id + val['model'] = model.model + File, Filename = sugar.attachment_search(self.context.get('port'), self.context.get('session_id'), self.TABLE_NOTE, val.get('id')) + if File: + val['datas'] = File + val['datas_fname'] = Filename + return val + + def get_history_mapping(self): + return { + 'model' : 'ir.attachment', + 'dependencies' : [self.TABLE_USER, self.TABLE_ACCOUNT, self.TABLE_CONTACT, self.TABLE_LEAD, self.TABLE_OPPORTUNITY, self.TABLE_MEETING, self.TABLE_CALL, self.TABLE_EMAIL], + 'hook' : self.import_history, + 'map' : { + 'name':'name', + 'user_id/id': ref(self.TABLE_USER, 'created_by'), + 'description': ppconcat('description', 'description_html'), + 'res_id': 'res_id', + 'res_model': 'model', + 'partner_id/.id' : 'partner_id/.id', + 'datas' : 'datas', + 'datas_fname' : 'datas_fname' + } + } + + """ + import Claims(Cases) + """ + def get_claim_priority(self, val): + priority_dict = { + 'P1': '2', + 'P2': '3', + 'P3': '4' + } + return priority_dict.get(val.get('priority'), '') + + def get_contact_info_from_account(self, val): + partner_id = self.get_mapped_id(self.TABLE_ACCOUNT, val.get('account_id')) + partner_address_id = False + partner_phone = False + partner_email = False + partner = self.obj.pool.get('res.partner').browse(self.cr, self.uid, [partner_id])[0] + if partner.address and partner.address[0]: + address = partner.address[0] + partner_address_id = address.id + partner_phone = address.phone + partner_email = address.email + return partner_address_id, partner_phone,partner_email + + def import_crm_claim(self, val): + partner_address_id, partner_phone,partner_email = self.get_contact_info_from_account(val) + val['partner_address_id/.id'] = partner_address_id + val['partner_phone'] = partner_phone + val['email_from'] = partner_email + return val + + def get_crm_claim_mapping(self): + return { + 'model' : 'crm.claim', + 'dependencies' : [self.TABLE_USER, self.TABLE_ACCOUNT, self.TABLE_CONTACT, self.TABLE_LEAD], + 'hook' : self.import_crm_claim, + 'map' : { + 'name': concat('case_number','name', delimiter='-'), + 'date': 'date_entered', + 'user_id/id': ref(self.TABLE_USER, 'assigned_user_id'), + 'description': ppconcat('description', 'resolution', 'work_log'), + 'partner_id/id': ref(self.TABLE_ACCOUNT, 'account_id'), + 'partner_address_id/.id': 'partner_address_id/.id', + 'categ_id/id': call(self.get_category, 'crm.claim', value('type')), + 'partner_phone': 'partner_phone', + 'email_from': 'email_from', + 'priority': self.get_claim_priority, + 'state': map_val('status', self.project_issue_state) + } + } + """ + Import Project Issue(Bugs) + """ + project_issue_state = { + 'New' : 'draft', + 'Assigned':'open', + 'Closed': 'done', + 'Pending': 'pending', + 'Rejected': 'cancel', + } + + def get_project_issue_priority(self, val): + priority_dict = { + 'Urgent': '1', + 'High': '2', + 'Medium': '3', + 'Low': '4' + } + return priority_dict.get(val.get('priority'), '') + + def get_bug_project_id(self, dict, val): + fields = ['name'] + data = [val] + return self.import_object(fields, data, 'project.project', 'project_issue', val) + + def get_project_issue_mapping(self): + return { + 'model' : 'project.issue', + 'dependencies' : [self.TABLE_USER], + 'map' : { + 'name': concat('bug_number', 'name', delimiter='-'), + 'project_id/id': call(self.get_bug_project_id, 'sugarcrm_bugs'), + 'categ_id/id': call(self.get_category, 'project.issue', value('type')), + 'description': ppconcat('description', 'source', 'resolution', 'work_log', 'found_in_release', 'release_name', 'fixed_in_release_name', 'fixed_in_release'), + 'priority': self.get_project_issue_priority, + 'state': map_val('status', self.project_issue_state), + 'assigned_to/id' : ref(self.TABLE_USER, 'assigned_user_id'), + } + } + + """ + import Project Tasks + """ + project_task_state = { + 'Not Started': 'draft', + 'In Progress': 'open', + 'Completed': 'done', + 'Pending Input': 'pending', + 'Deferred': 'cancelled', + } + + def get_project_task_priority(self, val): + priority_dict = { + 'High': '0', + 'Medium': '2', + 'Low': '3' + } + return priority_dict.get(val.get('priority'), '') + + def get_project_task_mapping(self): + return { + 'model' : 'project.task', + 'dependencies' : [self.TABLE_USER, self.TABLE_PROJECT], + 'map' : { + 'name': 'name', + 'date_start': 'date_start', + 'date_end': 'date_finish', + 'project_id/id': ref(self.TABLE_PROJECT, 'project_id'), + 'planned_hours': 'estimated_effort', + 'priority': self.get_project_task_priority, + 'description': ppconcat('description','milestone_flag', 'project_task_id', 'task_number', 'percent_complete'), + 'user_id/id': ref(self.TABLE_USER, 'assigned_user_id'), + 'partner_id/id': 'partner_id/id', + 'contact_id/id': 'contact_id/id', + 'state': map_val('status', self.project_task_state) + } + } + + """ + import Projects + """ + project_state = { + 'Draft' : 'draft', + 'In Review': 'open', + 'Published': 'close' + } + + def import_project_account(self, val): + partner_id = False + partner_invoice_id = False + sugar_project_account = sugar.relation_search(self.context.get('port'), self.context.get('session_id'), 'Project', module_id=val.get('id'), related_module=self.TABLE_ACCOUNT, query=None, deleted=None) + sugar_project_contact = sugar.relation_search(self.context.get('port'), self.context.get('session_id'), 'Project', module_id=val.get('id'), related_module=self.TABLE_CONTACT, query=None, deleted=None) + for contact_id in sugar_project_contact: + partner_invoice_id = self.get_mapped_id(self.TABLE_CONTACT, contact_id) + for account_id in sugar_project_account: + partner_id = self.get_mapped_id(self.TABLE_ACCOUNT, account_id) + return partner_id, partner_invoice_id + + def import_project(self, val): + partner_id, partner_invoice_id = self.import_project_account(val) + val['partner_id/.id'] = partner_id + val['contact_id/.id'] = partner_invoice_id + return val + + def get_project_mapping(self): + return { + 'model' : 'project.project', + 'dependencies' : [self.TABLE_CONTACT, self.TABLE_ACCOUNT, self.TABLE_USER], + 'hook' : self.import_project, + 'map' : { + 'name': 'name', + 'date_start': 'estimated_start_date', + 'date': 'estimated_end_date', + 'user_id/id': ref(self.TABLE_USER, 'assigned_user_id'), + 'partner_id/.id': 'partner_id/.id', + 'contact_id/.id': 'contact_id/.id', + 'state': map_val('status', self.project_state) + } + } + + """ + import Tasks + """ + task_state = { + 'Completed' : 'done', + 'Not Started':'draft', + 'In Progress': 'open', + 'Pending Input': 'draft', + 'deferred': 'cancel' + } + + def import_task(self, val): + date = val.get('date_start') or datetime.now().strftime('%Y-%m-%d %H:%M:%S'), + val['date'] = ''.join(date) + date_deadline = val.get('date_due') or datetime.now().strftime('%Y-%m-%d %H:%M:%S'), + val['date_deadline'] = ''.join(date_deadline) + return val + + def get_task_mapping(self): + return { + 'model' : 'crm.meeting', + 'dependencies' : [self.TABLE_CONTACT, self.TABLE_ACCOUNT, self.TABLE_USER], + 'hook' : self.import_task, + 'map' : { + 'name': 'name', + 'date': 'date', + 'date_deadline': 'date_deadline', + 'user_id/id': ref(self.TABLE_USER, 'assigned_user_id'), + 'categ_id/id': call(self.get_category, 'crm.meeting', const('Tasks')), + 'partner_id/id': related_ref(self.TABLE_ACCOUNT), + 'partner_address_id/id': ref(self.TABLE_CONTACT,'contact_id'), + 'state': map_val('status', self.task_state) + } + } + + """ + import Calls + """ + #TODO adapt with project trunk-crm-imp + call_state = { + 'Planned' : 'open', + 'Held':'done', + 'Not Held': 'pending', + } + + def get_calls_mapping(self): + return { + 'model' : 'crm.phonecall', + 'dependencies' : [self.TABLE_ACCOUNT, self.TABLE_CONTACT, self.TABLE_OPPORTUNITY, self.TABLE_LEAD], + 'map' : { + 'name': 'name', + 'date': 'date_start', + 'duration': call(self.get_float_time, value('duration_hours'), value('duration_minutes')), + 'user_id/id': ref(self.TABLE_USER, 'assigned_user_id'), + 'partner_id/id': related_ref(self.TABLE_ACCOUNT), + 'partner_address_id/id': related_ref(self.TABLE_CONTACT), + 'categ_id/id': call(self.get_category, 'crm.phonecall', value('direction')), + 'opportunity_id/id': related_ref(self.TABLE_OPPORTUNITY), + 'description': ppconcat('description'), + 'state': map_val('status', self.call_state) + } + } + + """ + import meeting + """ + meeting_state = { + 'Planned' : 'draft', + 'Held': 'open', + 'Not Held': 'draft', + } +#TODO + def get_attendee_id(self, cr, uid, module_name, module_id): + contact_id = False + user_id = False + attendee_id= [] + attendee_dict = sugar.user_get_attendee_list(self.context.get('port'), self.context.get('session_id'), module_name, module_id) + for attendee in attendee_dict: + user_id = self.xml_id_exist(self.TABLE_USER, attendee.get('id', False)) + contact_id = False + if not user_id: + contact_id = self.xml_id_exist(self.TABLE_CONTACT, attendee.get('id', False)) + fields = ['user_id/id', 'email', 'partner_address_id/id'] + data = [user_id, attendee.get('email1'), contact_id] + attendee_xml_id = self.import_object(fields, data, 'calendar.attendee', self.TABLE_ATTENDEE, user_id or contact_id or attendee.get('email1'), ['|',('user_id', '=', attendee.get('id')),('partner_address_id','=',attendee.get('id')),('email', '=', attendee.get('email1'))]) + attendee_id.append(attendee_xml_id) + return ','.join(attendee_id) + + def get_alarm_id(self, dict_val, val): + alarm_dict = { + '60': '1 minute before', + '300': '5 minutes before', + '600': '10 minutes before', + '900': '15 minutes before', + '1800':'30 minutes before', + '3600': '1 hour before', + } + return self.mapped_id_if_exist('res.alarm', [('name', 'like', alarm_dict.get(val))], 'alarm', val) + + #TODO attendees + + def import_meeting(self, val): + attendee_id = self.get_attendee_id(self.cr, self.uid, 'Meetings', val.get('id')) #TODO + val['attendee_ids/id'] = attendee_id + return val + + def get_meeting_mapping(self): + return { + 'model' : 'crm.meeting', + 'dependencies' : [self.TABLE_CONTACT, self.TABLE_OPPORTUNITY, self.TABLE_LEAD, self.TABLE_TASK], + 'hook': self.import_meeting, + 'map' : { + 'name': 'name', + 'date': 'date_start', + 'duration': call(self.get_float_time, value('duration_hours'), value('duration_minutes')), + 'location': 'location', + 'attendee_ids/id':'attendee_ids/id', + 'alarm_id/id': call(self.get_alarm_id, value('reminder_time')), + 'user_id/id': ref(self.TABLE_USER, 'assigned_user_id'), + 'partner_id/id': related_ref(self.TABLE_ACCOUNT), + 'partner_address_id/id': related_ref(self.TABLE_CONTACT), + 'state': map_val('status', self.meeting_state) + } + } + + """ + import Opportunity + """ + opp_state = { + 'Need Analysis' : 'New', + 'Closed Lost': 'Lost', + 'Closed Won': 'Won', + 'Value Proposition': 'Proposition', + 'Negotiation/Review': 'Negotiation' + } + + def get_opportunity_status(self, sugar_val): + fields = ['name', 'type'] + name = 'Opportunity_' + sugar_val['sales_stage'] + data = [sugar_val['sales_stage'], 'Opportunity'] + return self.import_object(fields, data, 'crm.case.stage', self.TABLE_STAGE, name, [('type', '=', 'opportunity'), ('name', 'ilike', sugar_val['sales_stage'])]) + + def import_opportunity_contact(self, val): + sugar_opportunities_contact = set(sugar.relation_search(self.context.get('port'), self.context.get('session_id'), 'Opportunities', module_id=val.get('id'), related_module='Contacts', query=None, deleted=None)) + + partner_contact_id = False + partner_contact_email = False + partner_address_obj = self.obj.pool.get('res.partner.address') + partner_xml_id = self.name_exist(self.TABLE_ACCOUNT, val['account_name'], 'res.partner') + + for contact in sugar_opportunities_contact: + address_id = self.get_mapped_id(self.TABLE_CONTACT, contact) + if address_id: + address = partner_address_obj.browse(self.cr, self.uid, address_id) + partner_name = address.partner_id and address.partner_id.name or False + if not partner_name: #link with partner id + fields = ['partner_id/id'] + data = [partner_xml_id] + self.import_object(fields, data, 'res.partner.address', self.TABLE_CONTACT, contact, self.DO_NOT_FIND_DOMAIN) + if not partner_name or partner_name == val.get('account_name'): + partner_contact_id = self.xml_id_exist(self.TABLE_CONTACT, contact) + partner_contact_email = address.email + return partner_contact_id, partner_contact_email + + def import_opp(self, val): + partner_contact_id, partner_contact_email = self.import_opportunity_contact(val) + val['partner_address_id/id'] = partner_contact_id + val['email_from'] = partner_contact_email + return val + + def get_opp_mapping(self): + return { + 'model' : 'crm.lead', + 'dependencies' : [self.TABLE_USER, self.TABLE_ACCOUNT, self.TABLE_CONTACT,self.TABLE_COMPAIGN], + 'hook' : self.import_opp, + 'map' : { + 'name': 'name', + 'probability': 'probability', + 'partner_id/id': refbyname(self.TABLE_ACCOUNT, 'account_name', 'res.partner'), + 'title_action': 'next_step', + 'partner_address_id/id': 'partner_address_id/id', + 'planned_revenue': 'amount', + 'date_deadline': 'date_closed', + 'user_id/id' : ref(self.TABLE_USER, 'assigned_user_id'), + 'stage_id/id' : self.get_opportunity_status, + 'type' : const('opportunity'), + 'categ_id/id': call(self.get_category, 'crm.lead', value('opportunity_type')), + 'email_from': 'email_from', + 'state': map_val('status', self.opp_state), + 'description' : 'description', + } + } + + """ + import campaign + """ + + def get_compaign_mapping(self): + return { + 'model' : 'crm.case.resource.type', + 'map' : { + 'name': 'name', + } + } + + """ + import lead + """ + def get_lead_status(self, sugar_val): + fields = ['name', 'type'] + name = 'lead_' + sugar_val.get('status', '') + data = [sugar_val.get('status', ''), 'lead'] + return self.import_object(fields, data, 'crm.case.stage', self.TABLE_STAGE, name, [('type', '=', 'lead'), ('name', 'ilike', sugar_val.get('status', ''))]) + + lead_state = { + 'New' : 'draft', + 'Assigned':'open', + 'In Progress': 'open', + 'Recycled': 'cancel', + 'Dead': 'done', + 'Converted': 'done', + } + + def import_lead(self, val): + if val.get('opportunity_id'): #if lead is converted into opp, don't import as lead + return False + if val.get('primary_address_country'): + country_id = self.get_all_countries(val.get('primary_address_country')) + val['country_id/id'] = country_id + val['state_id/id'] = self.get_all_states(val.get('primary_address_state'), country_id) + return val + + def get_lead_mapping(self): + return { + 'model' : 'crm.lead', + 'dependencies' : [self.TABLE_COMPAIGN, self.TABLE_USER], + 'hook' : self.import_lead, + 'map' : { + 'name': concat('first_name', 'last_name'), + 'contact_name': concat('first_name', 'last_name'), + 'description': ppconcat('description', 'refered_by', 'lead_source', 'lead_source_description', 'website', 'email2', 'status_description', 'lead_source_description', 'do_not_call'), + 'partner_name': 'account_name', + 'email_from': 'email1', + 'phone': 'phone_work', + 'mobile': 'phone_mobile', + 'title/id': call(self.get_job_title, value('salutation')), + 'function':'title', + 'street': 'primary_address_street', + 'street2': 'alt_address_street', + 'zip': 'primary_address_postalcode', + 'city':'primary_address_city', + 'user_id/id' : ref(self.TABLE_USER, 'assigned_user_id'), + 'stage_id/id' : self.get_lead_status, + 'type' : const('lead'), + 'state': map_val('status', self.lead_state) , + 'fax': 'phone_fax', + 'referred': 'refered_by', + 'optout': 'do_not_call', + 'channel_id/id': call(self.get_channel_id, value('lead_source')), + 'type_id/id': ref(self.TABLE_COMPAIGN, 'campaign_id'), + 'country_id/id': 'country_id/id', + 'state_id/id': 'state_id/id', + } + } + + """ + import contact + """ + + def get_email(self, val): + email_address = sugar.get_contact_by_email(self.context.get('port'), self.context.get('username'), self.context.get('password'), val.get('email1')) + if email_address: + return ','.join(email_address) + + def import_contact(self, val): + if val.get('primary_address_country'): + country_id = self.get_all_countries(val.get('primary_address_country')) + state = self.get_all_states(val.get('primary_address_state'), country_id) + val['country_id/id'] = country_id + val['state_id/id'] = state + return val + + def get_contact_mapping(self): + return { + 'model' : 'res.partner.address', + 'dependencies' : [self.TABLE_ACCOUNT], + 'hook' : self.import_contact, + 'map' : { + 'name': concat('first_name', 'last_name'), + 'partner_id/id': ref(self.TABLE_ACCOUNT,'account_id'), + 'phone': 'phone_work', + 'mobile': 'phone_mobile', + 'fax': 'phone_fax', + 'function': 'title', + 'street': 'primary_address_street', + 'zip': 'primary_address_postalcode', + 'city': 'primary_address_city', + 'country_id/id': 'country_id/id', + 'state_id/id': 'state_id/id', + 'email': self.get_email, + 'type': const('contact') + } + } + + """ + import Account + """ + + def get_address_type(self, val, type): + if type == 'invoice': + type_address = 'billing' + else: + type_address = 'shipping' + + if type == 'default': + map_partner_address = { + 'name': 'name', + 'type': const('default'), + 'email': 'email1' + } + else: + map_partner_address = { + 'name': 'name', + 'phone': 'phone_office', + 'mobile': 'phone_mobile', + 'fax': 'phone_fax', + 'type': 'type', + 'street': type_address + '_address_street', + 'zip': type_address +'_address_postalcode', + 'city': type_address +'_address_city', + 'country_id/id': 'country_id/id', + 'type': 'type', + } + + if val.get(type_address +'_address_country'): + country_id = self.get_all_countries(val.get(type_address +'_address_country')) + state = self.get_all_states(val.get(type_address +'_address_state'), country_id) + val['country_id/id'] = country_id + val['state_id/id'] = state + + val['type'] = type + val['id_new'] = val['id'] + '_address_' + type + return self.import_object_mapping(map_partner_address, val, 'res.partner.address', self.TABLE_CONTACT, val['id_new'], self.DO_NOT_FIND_DOMAIN) + + def get_partner_address(self, val): + address_id=[] + type_dict = {'billing_address_street' : 'invoice', 'shipping_address_street' : 'delivery', 'type': 'default'} + for key, type_value in type_dict.items(): + if val.get(key): + id = self.get_address_type(val, type_value) + address_id.append(id) + + return ','.join(address_id) + + def get_partner_mapping(self): + return { + 'model' : 'res.partner', + 'dependencies' : [self.TABLE_USER], + 'map' : { + 'name': 'name', + 'website': 'website', + 'user_id/id': ref(self.TABLE_USER,'assigned_user_id'), + 'ref': 'sic_code', + 'comment': ppconcat('description', 'employees', 'ownership', 'annual_revenue', 'rating', 'industry', 'ticker_symbol'), + 'customer': const('1'), + 'supplier': const('0'), + 'address/id':'address/id', + 'parent_id/id_parent' : 'parent_id', + 'address/id' : self.get_partner_address, + } + } + + """ + import Employee + """ + def get_ressource(self, val): + map_resource = { + 'name': concat('first_name', 'last_name'), + } + return self.import_object_mapping(map_resource, val, 'resource.resource', self.TABLE_RESSOURCE, val['id'], self.DO_NOT_FIND_DOMAIN) + + def get_job_id(self, val): + fields = ['name'] + data = [val.get('title')] + return self.import_object(fields, data, 'hr.job', 'hr_job', val.get('title')) + + def get_user_address(self, val): + map_user_address = { + 'name': concat('first_name', 'last_name'), + 'city': 'address_city', + 'country_id/id': 'country_id/id', + 'state_id/id': 'state_id/id', + 'street': 'address_street', + 'zip': 'address_postalcode', + 'fax': 'phone_fax', + 'phone': 'phone_work', + 'mobile':'phone_mobile', + 'email': 'email1' + } + + if val.get('address_country'): + country_id = self.get_all_countries(val.get('address_country')) + state_id = self.get_all_states(val.get('address_state'), country_id) + val['country_id/id'] = country_id + val['state_id/id'] = state_id + + return self.import_object_mapping(map_user_address, val, 'res.partner.address', self.TABLE_CONTACT, val['id'], self.DO_NOT_FIND_DOMAIN) + + def get_employee_mapping(self): + return { + 'model' : 'hr.employee', + 'dependencies' : [self.TABLE_USER], + 'map' : { + 'resource_id/id': self.get_ressource, + 'name': concat('first_name', 'last_name'), + 'work_phone': 'phone_work', + 'mobile_phone': 'phone_mobile', + 'user_id/id': ref(self.TABLE_USER, 'id'), + 'address_home_id/id': self.get_user_address, + 'notes': ppconcat('messenger_type', 'messenger_id', 'description'), + 'job_id/id': self.get_job_id, + 'work_email' : 'email1', + 'coach_id/id_parent' : 'reports_to_id', + } + } + + """ + import user + """ + def import_user(self, val): + user_obj = self.obj.pool.get('res.users') + user_ids = user_obj.search(self.cr, self.uid, [('login', '=', val.get('user_name'))]) + if user_ids: + val['.id'] = str(user_ids[0]) + else: + val['password'] = 'sugarcrm' #default password for all user #TODO needed in documentation + + val['context_lang'] = self.context.get('lang','en_US') + return val + + def get_users_department(self, val): + dep = val.get('department') + fields = ['name'] + data = [dep] + if not dep: + return False + return self.import_object(fields, data, 'hr.department', 'hr_department_user', dep) + + def get_user_mapping(self): + return { + 'model' : 'res.users', + 'hook' : self.import_user, + 'map' : { + 'name': concat('first_name', 'last_name'), + 'login': value('user_name', fallback='last_name'), + 'context_lang' : 'context_lang', + 'password' : 'password', + '.id' : '.id', + 'context_department_id/id': self.get_users_department, + 'user_email' : 'email1', + } + } + + + def get_mapping(self): + return { + self.TABLE_USER : self.get_user_mapping(), + self.TABLE_EMPLOYEE : self.get_employee_mapping(), + self.TABLE_ACCOUNT : self.get_partner_mapping(), + self.TABLE_CONTACT : self.get_contact_mapping(), + self.TABLE_LEAD : self.get_lead_mapping(), + self.TABLE_OPPORTUNITY : self.get_opp_mapping(), + self.TABLE_MEETING : self.get_meeting_mapping(), + self.TABLE_CALL : self.get_calls_mapping(), + self.TABLE_TASK : self.get_task_mapping(), + self.TABLE_PROJECT : self.get_project_mapping(), + self.TABLE_PROJECT_TASK: self.get_project_task_mapping(), + self.TABLE_BUG: self.get_project_issue_mapping(), + self.TABLE_CASE: self.get_crm_claim_mapping(), + self.TABLE_NOTE: self.get_history_mapping(), + self.TABLE_EMAIL: self.get_email_mapping(), + self.TABLE_DOCUMENT: self.get_document_mapping(), + self.TABLE_COMPAIGN: self.get_compaign_mapping() + } + + """ + Email notification + """ + def get_email_subject(self, result, error=False): + if error: + return "Sugarcrm data import failed at %s due to an unexpected error" % self.date_ended + return "your sugarcrm data were successfully imported at %s" % self.date_ended + + def get_body_header(self, result): + return "Sugarcrm import : report of last import" + + +class import_sugarcrm(osv.osv): + """Import SugarCRM DATA""" + + _name = "import.sugarcrm" + _description = __doc__ + _columns = { + 'username': fields.char('User Name', size=64, required=True), + 'password': fields.char('Password', size=24,required=True), + 'url' : fields.char('SugarSoap Api url:', size=264, required=True, help="Webservice's url where to get the data.\ + example : 'http://example.com/sugarcrm/soap.php', or copy the address of your sugarcrm application http://trial.sugarcrm.com/qbquyj4802/index.php?module=Home&action=index"), + 'user' : fields.boolean('User', help="Check this box to import sugarCRM Users into OpenERP users, warning if a user with the same login exist in OpenERP, user information will be erase by sugarCRM user information", readonly=True), + 'opportunity': fields.boolean('Leads & Opp', help="Check this box to import sugarCRM Leads and Opportunities into OpenERP Leads and Opportunities"), + 'contact': fields.boolean('Contacts', help="Check this box to import sugarCRM Contacts into OpenERP addresses"), + 'account': fields.boolean('Accounts', help="Check this box to import sugarCRM Accounts into OpenERP partners"), + 'employee': fields.boolean('Employee', help="Check this box to import sugarCRM Employees into OpenERP employees"), + 'meeting': fields.boolean('Meetings', help="Check this box to import sugarCRM Meetings and Tasks into OpenERP meetings"), + 'call': fields.boolean('Calls', help="Check this box to import sugarCRM Calls into OpenERP calls"), + 'claim': fields.boolean('Cases', help="Check this box to import sugarCRM Cases into OpenERP claims"), + 'email_history': fields.boolean('Email and Note',help="Check this box to import sugarCRM Emails, Notes and Attachments into OpenERP Messages and Attachments"), + 'project': fields.boolean('Projects', help="Check this box to import sugarCRM Projects into OpenERP projects"), + 'project_task': fields.boolean('Project Tasks', help="Check this box to import sugarCRM Project Tasks into OpenERP tasks"), + 'bug': fields.boolean('Bugs', help="Check this box to import sugarCRM Bugs into OpenERP project issues"), + 'document': fields.boolean('Documents', help="Check this box to import sugarCRM Documents into OpenERP documents"), + 'email_from': fields.char('Notify End Of Import To:', size=128), + 'instance_name': fields.char("Instance's Name", size=64, help="Prefix of SugarCRM id to differentiate xml_id of SugarCRM models datas come from different server."), + } + + def _get_email_id(self, cr, uid, context=None): + return self.pool.get('res.users').browse(cr, uid, uid, context=context).user_email + + def _module_installed(self, cr, uid, model, context=None): + module_id = self.pool.get('ir.module.module').search(cr, uid, [('name', '=', model), ('state', "=", "installed")], context=context) + return bool(module_id) + + def _project_installed(self, cr, uid, context=None): + return self._module_installed(cr,uid,'project',context=context) + + def _crm_claim_installed(self, cr, uid, context=None): + return self._module_installed(cr,uid,'crm_claim',context=context) + + def _project_issue_installed(self, cr, uid, context=None): + return self._module_installed(cr,uid,'project_issue',context=context) + + def _hr_installed(self, cr, uid, context=None): + return self._module_installed(cr,uid,'hr',context=context) + + _defaults = {#to be set to true, but easier for debugging + 'user' : True, + 'opportunity': True, + 'contact' : True, + 'account' : True, + 'employee' : _hr_installed, + 'meeting' : True, + 'call' : True, + 'claim' : _crm_claim_installed, + 'email_history' : True, + 'project' : _project_installed, + 'project_task': _project_installed, + 'bug': _project_issue_installed, + 'document': True, + 'instance_name': 'sugarcrm', + 'email_from': _get_email_id, + 'username' : 'admin', + 'password' : '', + 'url': "http://sugarcrm.example.com/soap.php" + } + + def check_url(self, url, context): + if not context: + context = {} + user = context.get('username') + password = context.get('password') + + try : + sugar.login(user, password, url) + return True + except Exception: + return False + + + def parse_valid_url(self, context=None): + if not context: + context = {} + url = context.get('url') + url_split = str(url).split('/') + while len(url_split) >= 3: + #3 case, soap.php is already at the end of url should be valid + #url end by / or not + if url_split[-1] == 'soap.php': + url = "/".join(url_split) + elif url_split[-1] == '': + url = "/".join(url_split) + "soap.php" + else: + url = "/".join(url_split) + "/soap.php" + + if self.check_url(url, context): + return url + else: + url_split = url_split[:-1] #take parent folder + return url + + def get_key(self, cr, uid, ids, context=None): + """Select Key as For which Module data we want import data.""" + if not context: + context = {} + key_list = [] + module = {} + for current in self.browse(cr, uid, ids, context): + context.update({'username': current.username, 'password': current.password, 'url': current.url, 'email_user': current.email_from or False, 'instance_name': current.instance_name or False}) + if current.user: + key_list.append('Users') + if current.contact: + key_list.append('Contacts') + if current.account: + key_list.append('Accounts') + if current.opportunity: + key_list.append('Leads') + key_list.append('Opportunities') + if current.employee: + key_list.append('Employees') + module.update({'Employees':'hr'}) + if current.meeting: + key_list.append('Meetings') + if current.call: + key_list.append('Calls') + if current.claim: + key_list.append('Cases') + module.update({'Cases':'crm_claim'}) + if current.email_history: + key_list.append('Emails') + key_list.append('Notes') + if current.project: + key_list.append('Project') + module.update({'Project':'project'}) + if current.project_task: + key_list.append('ProjectTask') + module.update({'ProjectTask':'project'}) + if current.bug: + key_list.append('Bugs') + module.update({'Bugs':'project_issue'}) + if current.document: + key_list.append('Documents') + return key_list,module + + + def do_import_all(self, cr, uid, *args): + """ + scheduler Method + """ + context = {'username': args[4], 'password': args[5], 'url': args[3], 'instance_name': args[3]} + imp = sugar_import(self, cr, uid, args[2], "import_sugarcrm", [args[1]], context) + imp.set_table_list(args[0]) + imp.start() + return True + + def import_from_scheduler_all(self, cr, uid, ids, context=None): + keys, module_list = self.get_key(cr, uid, ids, context) + if not keys: + raise osv.except_osv(_('Warning !'), _('Select Module to Import.')) + key_list = module_list.keys() + for module in key_list : + module = module_list[module] + state = self.get_all(cr,uid,module,context=context) + if state == False: + keys = ', '.join(key_list) + raise osv.except_osv(_('Error !!'), _("%s data required %s Module to be installed, Please install %s module") %(keys,module,module)) + cron_obj = self.pool.get('ir.cron') + url = self.parse_valid_url(context) + args = (keys,context.get('email_user'), context.get('instance_name'), url, context.get('username'), context.get('password') ) + new_create_id = cron_obj.create(cr, uid, {'name': 'Import SugarCRM datas','interval_type': 'hours','interval_number': 1, 'numbercall': -1,'model': 'import.sugarcrm','function': 'do_import_all', 'args': args, 'active': False}) + return { + 'name': 'SugarCRM Scheduler', + 'view_type': 'form', + 'view_mode': 'form,tree', + 'res_model': 'ir.cron', + 'res_id': new_create_id, + 'type': 'ir.actions.act_window', + } + + def import_all(self, cr, uid, ids, context=None): + +# """Import all sugarcrm data into openerp module""" + keys, module_list = self.get_key(cr, uid, ids, context) + if not keys: + raise osv.except_osv(_('Warning !'), _('Select Module to Import.')) + key_list = module_list.keys() + for module in key_list : + module = module_list[module] + state = self._module_installed(cr,uid,module,context=context) + if state == False: + keys = ', '.join(key_list) + raise osv.except_osv(_('Error !!'), _("%s data required %s Module to be installed, Please install %s module") %(keys,module,module)) + url = self.parse_valid_url(context) + context.update({'url': url}) + imp = sugar_import(self, cr, uid, context.get('instance_name'), "import_sugarcrm", [context.get('email_user')], context) + imp.set_table_list(keys) + imp.start() + obj_model = self.pool.get('ir.model.data') + model_data_ids = obj_model.search(cr,uid,[('model','=','ir.ui.view'),('name','=','import.message.form')]) + resource_id = obj_model.read(cr, uid, model_data_ids, fields=['res_id']) + return { + 'view_type': 'form', + 'view_mode': 'form', + 'res_model': 'import.message', + 'views': [(resource_id,'form')], + 'type': 'ir.actions.act_window', + 'target': 'new', + } + +import_sugarcrm() diff --git a/addons/import_sugarcrm/import_sugarcrm_view.xml b/addons/import_sugarcrm/import_sugarcrm_view.xml new file mode 100644 index 00000000000..1f12a8fde57 --- /dev/null +++ b/addons/import_sugarcrm/import_sugarcrm_view.xml @@ -0,0 +1,105 @@ + + + + + + + import.sugarcrm.form + import.sugarcrm + form + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +