diff --git a/addons/account/account.py b/addons/account/account.py index bfd48d55b00..b7b866e8f79 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -30,6 +30,7 @@ import pooler import mx.DateTime from mx.DateTime import RelativeDateTime, now, DateTime, localtime +from tools import config class account_payment_term(osv.osv): _name = "account.payment.term" @@ -53,11 +54,11 @@ class account_payment_term(osv.osv): result = [] for line in pt.line_ids: if line.value == 'fixed': - amt = round(line.value_amount, 2) + amt = round(line.value_amount, int(config['price_accuracy'])) elif line.value == 'procent': - amt = round(value * line.value_amount, 2) + amt = round(value * line.value_amount, int(config['price_accuracy'])) elif line.value == 'balance': - amt = round(amount, 2) + amt = round(amount, int(config['price_accuracy'])) if amt: next_date = mx.DateTime.strptime(date_ref, '%Y-%m-%d') + RelativeDateTime(days=line.days) if line.days2 < 0: @@ -267,9 +268,9 @@ class account_account(osv.osv): 'child_parent_ids': fields.one2many('account.account','parent_id','Children'), 'child_consol_ids': fields.many2many('account.account', 'account_account_consol_rel', 'child_id', 'parent_id', 'Consolidated Children'), 'child_id': fields.function(_get_child_ids, method=True, type='many2many', relation="account.account", string="Child Accounts"), - 'balance': fields.function(__compute, digits=(16, 2), method=True, string='Balance', multi='balance'), - 'credit': fields.function(__compute, digits=(16, 2), method=True, string='Credit', multi='balance'), - 'debit': fields.function(__compute, digits=(16, 2), method=True, string='Debit', multi='balance'), + 'balance': fields.function(__compute, digits=(16, int(config['price_accuracy'])), method=True, string='Balance', multi='balance'), + 'credit': fields.function(__compute, digits=(16, int(config['price_accuracy'])), method=True, string='Credit', multi='balance'), + 'debit': fields.function(__compute, digits=(16, int(config['price_accuracy'])), method=True, string='Debit', multi='balance'), 'reconcile': fields.boolean('Reconcile', help="Check this if the user is allowed to reconcile entries in this account."), 'shortcut': fields.char('Shortcut', size=12), 'tax_ids': fields.many2many('account.tax', 'account_account_tax_default_rel', @@ -743,7 +744,7 @@ class account_move(osv.osv): 'line_id': fields.one2many('account.move.line', 'move_id', 'Entries', states={'posted':[('readonly',True)]}), 'to_check': fields.boolean('To Be Verified'), 'partner_id': fields.related('line_id', 'partner_id', type="many2one", relation="res.partner", string="Partner"), - 'amount': fields.function(_amount_compute, method=True, string='Amount', digits=(16,2)), + 'amount': fields.function(_amount_compute, method=True, string='Amount', digits=(16,int(config['price_accuracy']))), 'date': fields.date('Date', required=True), 'type': fields.selection([ ('pay_voucher','Cash Payment'), @@ -1109,7 +1110,7 @@ class account_tax_code(osv.osv): for rec in record.child_ids: amount += _rec_get(rec) * rec.sign return amount - res[record.id] = round(_rec_get(record), 2) + res[record.id] = round(_rec_get(record), int(config['price_accuracy'])) return res def _sum_year(self, cr, uid, ids, name, args, context): @@ -1380,9 +1381,9 @@ class account_tax(osv.osv): total = 0.0 for r in res: if r.get('balance',False): - r['amount'] = round(r['balance'] * quantity, 2) - total + r['amount'] = round(r['balance'] * quantity, int(config['price_accuracy'])) - total else: - r['amount'] = round(r['amount'] * quantity, 2) + r['amount'] = round(r['amount'] * quantity, int(config['price_accuracy'])) total += r['amount'] return res @@ -1477,9 +1478,9 @@ class account_tax(osv.osv): total = 0.0 for r in res: if r.get('balance',False): - r['amount'] = round(r['balance'] * quantity, 2) - total + r['amount'] = round(r['balance'] * quantity, int(config['price_accuracy'])) - total else: - r['amount'] = round(r['amount'] * quantity, 2) + r['amount'] = round(r['amount'] * quantity, int(config['price_accuracy'])) total += r['amount'] return res account_tax() @@ -1545,9 +1546,9 @@ class account_model_line(osv.osv): _columns = { 'name': fields.char('Name', size=64, required=True), 'sequence': fields.integer('Sequence', required=True, help="The sequence field is used to order the resources from lower sequences to higher ones"), - 'quantity': fields.float('Quantity', digits=(16,2), help="The optional quantity on entries"), - 'debit': fields.float('Debit', digits=(16,2)), - 'credit': fields.float('Credit', digits=(16,2)), + 'quantity': fields.float('Quantity', digits=(16, int(config['price_accuracy'])), help="The optional quantity on entries"), + 'debit': fields.float('Debit', digits=(16, int(config['price_accuracy']))), + 'credit': fields.float('Credit', digits=(16, int(config['price_accuracy']))), 'account_id': fields.many2one('account.account', 'Account', required=True, ondelete="cascade"), diff --git a/addons/account/account_invoice_view.xml b/addons/account/account_invoice_view.xml index d7ca374a64c..484796f8d3e 100644 --- a/addons/account/account_invoice_view.xml +++ b/addons/account/account_invoice_view.xml @@ -52,7 +52,7 @@
- + diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index 49ebdd8ea11..1974d2c70e4 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -28,6 +28,8 @@ from tools.translate import _ import mx.DateTime from mx.DateTime import RelativeDateTime, now, DateTime, localtime +import tools + class account_move_line(osv.osv): _name = "account.move.line" _description = "Entry lines" @@ -908,7 +910,7 @@ class account_move_line(osv.osv): 'move_id': vals['move_id'], 'journal_id': vals['journal_id'], 'period_id': vals['period_id'], - 'name': vals['name']+' '+tax['name'], + 'name': tools.ustr(vals['name'] or '') + ' ' + tools.ustr(tax['name'] or ''), 'date': vals['date'], 'partner_id': vals.get('partner_id',False), 'ref': vals.get('ref',False), @@ -927,7 +929,7 @@ class account_move_line(osv.osv): 'move_id': vals['move_id'], 'journal_id': vals['journal_id'], 'period_id': vals['period_id'], - 'name': vals['name']+' '+tax['name'], + 'name': tools.ustr(vals['name'] or '') + ' ' + tools.ustr(tax['name'] or ''), 'date': vals['date'], 'partner_id': vals.get('partner_id',False), 'ref': vals.get('ref',False), diff --git a/addons/account/company.py b/addons/account/company.py index 403b886e012..e724b3a9775 100644 --- a/addons/account/company.py +++ b/addons/account/company.py @@ -25,7 +25,7 @@ from osv import fields, osv class res_company(osv.osv): _inherit = "res.company" _columns = { - 'overdue_msg' : fields.text('Overdue Payments Message'), + 'overdue_msg' : fields.text('Overdue Payments Message', translate=True), } _defaults = { diff --git a/addons/account/invoice.py b/addons/account/invoice.py index be9b4f63246..559f0a88156 100644 --- a/addons/account/invoice.py +++ b/addons/account/invoice.py @@ -233,21 +233,21 @@ class account_invoice(osv.osv): 'tax_line': fields.one2many('account.invoice.tax', 'invoice_id', 'Tax Lines', readonly=True, states={'draft':[('readonly',False)]}), 'move_id': fields.many2one('account.move', 'Invoice Movement', readonly=True, help="Link to the automatically generated account moves."), - 'amount_untaxed': fields.function(_amount_all, method=True, digits=(16,2),string='Untaxed', + 'amount_untaxed': fields.function(_amount_all, method=True, digits=(16, int(config['price_accuracy'])),string='Untaxed', store={ 'account.invoice': (lambda self, cr, uid, ids, c={}: ids, ['invoice_line'], 20), 'account.invoice.tax': (_get_invoice_tax, None, 20), 'account.invoice.line': (_get_invoice_line, ['price_unit','invoice_line_tax_id','quantity','discount'], 20), }, multi='all'), - 'amount_tax': fields.function(_amount_all, method=True, digits=(16,2), string='Tax', + 'amount_tax': fields.function(_amount_all, method=True, digits=(16, int(config['price_accuracy'])), string='Tax', store={ 'account.invoice': (lambda self, cr, uid, ids, c={}: ids, ['invoice_line'], 20), 'account.invoice.tax': (_get_invoice_tax, None, 20), 'account.invoice.line': (_get_invoice_line, ['price_unit','invoice_line_tax_id','quantity','discount'], 20), }, multi='all'), - 'amount_total': fields.function(_amount_all, method=True, digits=(16,2), string='Total', + 'amount_total': fields.function(_amount_all, method=True, digits=(16, int(config['price_accuracy'])), string='Total', store={ 'account.invoice': (lambda self, cr, uid, ids, c={}: ids, ['invoice_line'], 20), 'account.invoice.tax': (_get_invoice_tax, None, 20), @@ -257,7 +257,7 @@ class account_invoice(osv.osv): 'currency_id': fields.many2one('res.currency', 'Currency', required=True, readonly=True, states={'draft':[('readonly',False)]}), 'journal_id': fields.many2one('account.journal', 'Journal', required=True,readonly=True, states={'draft':[('readonly',False)]}), 'company_id': fields.many2one('res.company', 'Company', required=True), - 'check_total': fields.float('Total', digits=(16,2), states={'open':[('readonly',True)],'close':[('readonly',True)]}), + 'check_total': fields.float('Total', digits=(16, int(config['price_accuracy'])), states={'open':[('readonly',True)],'close':[('readonly',True)]}), 'reconciled': fields.function(_reconciled, method=True, string='Paid/Reconciled', type='boolean', store={ 'account.invoice': (lambda self, cr, uid, ids, c={}: ids, None, 50), # Check if we can remove ? @@ -267,7 +267,7 @@ class account_invoice(osv.osv): 'partner_bank': fields.many2one('res.partner.bank', 'Bank Account', help='The bank account to pay to or to be paid from'), 'move_lines':fields.function(_get_lines , method=True,type='many2many' , relation='account.move.line',string='Move Lines'), - 'residual': fields.function(_amount_residual, method=True, digits=(16,2),string='Residual', + 'residual': fields.function(_amount_residual, method=True, digits=(16, int(config['price_accuracy'])),string='Residual', store={ 'account.invoice': (lambda self, cr, uid, ids, c={}: ids, ['invoice_line'], 50), 'account.invoice.tax': (_get_invoice_tax, None, 50), @@ -435,7 +435,7 @@ class account_invoice(osv.osv): for taxe in ait_obj.compute(cr, uid, id, context=context).values(): ait_obj.create(cr, uid, taxe) # Update the stored value (fields.function), so we write to trigger recompute - self.pool.get('account.invoice').write(cr, uid, ids, {}, context=context) + self.pool.get('account.invoice').write(cr, uid, ids, {'invoice_line':[]}, context=context) # self.pool.get('account.invoice').write(cr, uid, ids, {}, context=context) return True @@ -916,7 +916,7 @@ class account_invoice_line(osv.osv): cur = line.invoice_id.currency_id res[line.id] = cur_obj.round(cr, uid, cur, res[line.id]) else: - res[line.id] = round(line.price_unit * line.quantity * (1-(line.discount or 0.0)/100.0),2) + res[line.id] = round(line.price_unit * line.quantity * (1-(line.discount or 0.0)/100.0),int(config['price_accuracy'])) return res @@ -948,9 +948,9 @@ class account_invoice_line(osv.osv): 'product_id': fields.many2one('product.product', 'Product', ondelete='set null'), 'account_id': fields.many2one('account.account', 'Account', required=True, domain=[('type','<>','view'), ('type', '<>', 'closed')], help="The income or expense account related to the selected product."), 'price_unit': fields.float('Unit Price', required=True, digits=(16, int(config['price_accuracy']))), - 'price_subtotal': fields.function(_amount_line, method=True, string='Subtotal',store=True), + 'price_subtotal': fields.function(_amount_line, method=True, string='Subtotal',store=True, type="float", digits=(16, int(config['price_accuracy']))), 'quantity': fields.float('Quantity', required=True), - 'discount': fields.float('Discount (%)', digits=(16,2)), + 'discount': fields.float('Discount (%)', digits=(16, int(config['price_accuracy']))), 'invoice_line_tax_id': fields.many2many('account.tax', 'account_invoice_line_tax', 'invoice_line_id', 'tax_id', 'Taxes', domain=[('parent_id','=',False)]), 'note': fields.text('Notes'), 'account_analytic_id': fields.many2one('account.analytic.account', 'Analytic Account'), @@ -1100,15 +1100,15 @@ class account_invoice_tax(osv.osv): 'invoice_id': fields.many2one('account.invoice', 'Invoice Line', ondelete='cascade', select=True), 'name': fields.char('Tax Description', size=64, required=True), 'account_id': fields.many2one('account.account', 'Tax Account', required=True, domain=[('type','<>','view'),('type','<>','income'), ('type', '<>', 'closed')]), - 'base': fields.float('Base', digits=(16,2)), - 'amount': fields.float('Amount', digits=(16,2)), + 'base': fields.float('Base', digits=(16,int(config['price_accuracy']))), + 'amount': fields.float('Amount', digits=(16,int(config['price_accuracy']))), 'manual': fields.boolean('Manual'), 'sequence': fields.integer('Sequence'), 'base_code_id': fields.many2one('account.tax.code', 'Base Code', help="The account basis of the tax declaration."), - 'base_amount': fields.float('Base Code Amount', digits=(16,2)), + 'base_amount': fields.float('Base Code Amount', digits=(16,int(config['price_accuracy']))), 'tax_code_id': fields.many2one('account.tax.code', 'Tax Code', help="The tax basis of the tax declaration."), - 'tax_amount': fields.float('Tax Code Amount', digits=(16,2)), + 'tax_amount': fields.float('Tax Code Amount', digits=(16,int(config['price_accuracy']))), } def base_change(self, cr, uid, ids, base,currency_id=False,company_id=False,date_invoice=False): cur_obj = self.pool.get('res.currency') diff --git a/addons/account/report/overdue.py b/addons/account/report/overdue.py index 76ebbe7efa4..861ad82ef9c 100644 --- a/addons/account/report/overdue.py +++ b/addons/account/report/overdue.py @@ -35,6 +35,7 @@ class Overdue(report_sxw.rml_parse): 'adr_get' : self._adr_get, 'getLines' : self._lines_get, 'tel_get' : self._tel_get, + 'message' : self._message, }) self.context = context def _adr_get(self, partner, type): @@ -80,7 +81,12 @@ class Overdue(report_sxw.rml_parse): ('state', '<>', 'draft'), ('reconcile_id', '=', False)]) movelines = moveline_obj.browse(self.cr, self.uid, movelines) return movelines - + + def _message(self, obj, company): + company_pool = pooler.get_pool(self.cr.dbname).get('res.company') + message = company_pool.browse(self.cr, self.uid, company.id, {'lang':obj.lang}).overdue_msg + return message + report_sxw.report_sxw('report.account.overdue', 'res.partner', 'addons/account/report/overdue.rml', parser=Overdue) diff --git a/addons/account/report/overdue.rml b/addons/account/report/overdue.rml index df4c69c45b4..2713b665d06 100644 --- a/addons/account/report/overdue.rml +++ b/addons/account/report/overdue.rml @@ -127,7 +127,7 @@ - [[ company.overdue_msg ]] + [[ message(o, company) ]] diff --git a/addons/account/report/partner_balance.py b/addons/account/report/partner_balance.py index 4551aca1ed4..ddd6ad1ecb4 100755 --- a/addons/account/report/partner_balance.py +++ b/addons/account/report/partner_balance.py @@ -217,6 +217,7 @@ class partner_balance(report_sxw.rml_parse): "JOIN account_account ac ON (l.account_id = ac.id)" \ "WHERE ac.type IN " + self.ACCOUNT_TYPE + " " \ "AND l.date IN (" + self.date_lst_string + ") " \ + "AND ac.company_id = "+ str(data['form']['company_id']) +" " \ "GROUP BY p.id, p.ref, p.name,l.account_id,ac.name,ac.code " \ "ORDER BY l.account_id,p.name") res = self.cr.dictfetchall() diff --git a/addons/account/wizard/wizard_fiscalyear_close.py b/addons/account/wizard/wizard_fiscalyear_close.py index 68e69941b5c..ac9518e006b 100644 --- a/addons/account/wizard/wizard_fiscalyear_close.py +++ b/addons/account/wizard/wizard_fiscalyear_close.py @@ -192,21 +192,24 @@ def _data_save(self, cr, uid, data, context): }) pool.get('account.move.line').create(cr, uid, move) offset += limit - ids = pool.get('account.move.line').search(cr, uid, [('journal_id','=',new_journal.id), - ('period_id.fiscalyear_id','=',old_fyear.id)]) + ('period_id.fiscalyear_id','=',new_fyear.id)]) context['fy_closing'] = True - if not ids: - raise wizard.except_wizard(_('UserError'), - _('The old fiscal year does not have any entry to reconcile!')) - pool.get('account.move.line').reconcile(cr, uid, ids, context=context) + if ids: + pool.get('account.move.line').reconcile(cr, uid, ids, context=context) new_period = data['form']['period_id'] ids = pool.get('account.journal.period').search(cr, uid, [('journal_id','=',new_journal.id),('period_id','=',new_period)]) - if ids: - cr.execute('UPDATE account_fiscalyear ' \ + if not ids: + ids = [pool.get('account.journal.period').create(cr, uid, { + 'name': (new_journal.name or '')+':'+(period.code or ''), + 'journal_id': new_journal.id, + 'period_id': period.id + })] + cr.execute('UPDATE account_fiscalyear ' \ 'SET end_journal_period_id = %s ' \ - 'WHERE id = %s', (ids[0], new_fyear.id)) + 'WHERE id = %s', (ids[0], old_fyear.id)) + return {} class wiz_journal_close(wizard.interface): diff --git a/addons/account_analytic_plans/account_analytic_plans.py b/addons/account_analytic_plans/account_analytic_plans.py index 6132baee654..e7b6006ab8b 100644 --- a/addons/account_analytic_plans/account_analytic_plans.py +++ b/addons/account_analytic_plans/account_analytic_plans.py @@ -163,7 +163,7 @@ class account_analytic_plan_instance(osv.osv): """%(i,tools.to_xml(line.name),tools.to_xml(line.name),line.root_analytic_id and line.root_analytic_id.id or 0) i+=1 res['arch'] += "" - doc = dom.minidom.parseString(res['arch']) + doc = dom.minidom.parseString(res['arch'].encode('utf8')) xarch, xfields = self._view_look_dom_arch(cr, uid, doc, view_id, context=context) res['arch'] = xarch res['fields'] = xfields diff --git a/addons/account_followup/__terp__.py b/addons/account_followup/__terp__.py index 00e86ef2d96..5122204fa68 100644 --- a/addons/account_followup/__terp__.py +++ b/addons/account_followup/__terp__.py @@ -53,6 +53,7 @@ 'wizard/wizard_view.xml', 'followup_report_view.xml', 'followup_view.xml', + 'followup_data.xml' ], 'demo_xml': ['followup_demo.xml'], 'installable': True, diff --git a/addons/account_followup/followup.py b/addons/account_followup/followup.py index 459e3e38e3c..9efd1d0a1ff 100644 --- a/addons/account_followup/followup.py +++ b/addons/account_followup/followup.py @@ -55,6 +55,29 @@ class account_move_line(osv.osv): } account_move_line() +class res_company(osv.osv): + _inherit = "res.company" + _columns = { + 'follow_up_msg' : fields.text('Follow-up Message', translate=True), + } + + _defaults = { + 'overdue_msg': lambda *a: ''' +Date : %(date)s + +Dear %(partner_name)s, + +Please find in attachment a reminder of all your unpaid invoices, for a total amount due of: + +%(followup_amount).2f %(company_currency)s + +Thanks, +-- +%(user_signature)s +%(company_name)s + ''' + } +res_company() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_followup/followup_data.xml b/addons/account_followup/followup_data.xml new file mode 100644 index 00000000000..2a33e65b2c8 --- /dev/null +++ b/addons/account_followup/followup_data.xml @@ -0,0 +1,19 @@ + + + + + Date : %(date)s + +Dear %(partner_name)s, + +Please find in attachment a reminder of all your unpaid invoices, for a total amount due of: + +%(followup_amount).2f %(company_currency)s + +Thanks, +-- +%(user_signature)s +%(company_name)s + + + diff --git a/addons/account_followup/followup_view.xml b/addons/account_followup/followup_view.xml index 1b2d40a7cd9..cd02355dc7e 100644 --- a/addons/account_followup/followup_view.xml +++ b/addons/account_followup/followup_view.xml @@ -125,7 +125,6 @@ - @@ -136,6 +135,17 @@ - + + res.company.followup.form.inherit + + res.company + form + + + + + + + diff --git a/addons/account_followup/wizard/wizard_followup_print.py b/addons/account_followup/wizard/wizard_followup_print.py index e271d1dbd27..7729d267365 100644 --- a/addons/account_followup/wizard/wizard_followup_print.py +++ b/addons/account_followup/wizard/wizard_followup_print.py @@ -60,8 +60,9 @@ _followup_wizard_all_form = """ + - + @@ -94,6 +95,12 @@ _followup_wizard_all_fields = { 'size': 64, 'default': 'Invoices Reminder' }, + 'partner_lang':{ + 'string': "Send Email in Partner Language", + 'type': 'boolean', + 'default':True, + 'help':'Do not change message text, if you want to send email in partner language, or configre from company' + }, 'email_body': { 'string': "Email body", 'type': 'text', @@ -156,7 +163,13 @@ class followup_all_print(wizard.interface): if adr.email: dest = [adr.email] src = tools.config.options['smtp_user'] - body=data['form']['email_body'] + if not data['form']['partner_lang']: + body = data['form']['email_body'] + else: + cxt = context.copy() + cxt['lang'] = partner.lang + body = pool.get('res.users').browse(cr, uid, uid, context=cxt).company_id.follow_up_msg + total_amt = followup_data.debit - followup_data.credit move_line = '' subtotal_due = 0.0 @@ -166,7 +179,7 @@ class followup_all_print(wizard.interface): l = '--------------------------------------------------------------------------------------------------------------------------' head = l+ '\n' + 'Date'.rjust(10) + '\t' + 'Description'.rjust(10) + '\t' + 'Ref'.rjust(10) + '\t' + 'Maturity date'.rjust(10) + '\t' + 'Due'.rjust(10) + '\t' + 'Paid'.rjust(10) + '\t' + 'Maturity'.rjust(10) + '\t' + 'Litigation'.rjust(10) + '\n' + l for i in data_lines: - maturity = '' + maturity = 0.00 if i.date_maturity < time.strftime('%Y-%m-%d') and (i.debit - i.credit): maturity = i.debit - i.credit subtotal_due = subtotal_due + i.debit @@ -187,7 +200,7 @@ class followup_all_print(wizard.interface): 'date':time.strftime('%Y-%m-%d'), } body = body%val - sub = str(data['form']['email_subject']) + sub = tools.ustr(data['form']['email_subject']) msg = '' if dest: tools.email_send(src,dest,sub,body) @@ -196,15 +209,15 @@ class followup_all_print(wizard.interface): msg += partner.name + '\n' msg_unsent += msg if not msg_unsent: - summary = _("All emails have been successfully sent to Partners:.\n\n") + msg_sent + summary = _("All E-mails have been successfully sent to Partners:.\n\n") + msg_sent else: - msg_unsent = _("Mail not sent to following Partners, Email not available !\n\n") + msg_unsent - msg_sent = msg_sent and _("\n\nMail sent to following Partners successfully, !\n\n") + msg_sent + msg_unsent = _("E-Mail not sent to following Partners, Email not available !\n\n") + msg_unsent + msg_sent = msg_sent and _("\n\nE-Mail sent to following Partners successfully. !\n\n") + msg_sent line = '==========================================================================' summary = msg_unsent + line + msg_sent return {'summary' : summary} else: - return {'summary' : '\n\n\nMail not sent to any partner if you want to sent it please tick send email confirmation on wizard'} + return {'summary' : '\n\n\nE-Mail has not been sent to any partner. If you want to send it, please tick send email confirmation on wizard.'} def _get_partners(self, cr, uid, data, context): pool = pooler.get_pool(cr.dbname) @@ -256,8 +269,10 @@ class followup_all_print(wizard.interface): if partner_id not in partner_list: partner_list.append(partner_id) to_update[str(id)] = fups[followup_line_id][1] - - return {'partner_ids': partner_list, 'to_update': to_update} + + message = pool.get('res.users').browse(cr, uid, uid, context=context).company_id.follow_up_msg + + return {'partner_ids': partner_list, 'to_update': to_update, 'email_body':message} def _get_screen1_values(self, cr, uid, data, context): pool = pooler.get_pool(cr.dbname) diff --git a/addons/base_module_quality/base_module_quality.py b/addons/base_module_quality/base_module_quality.py index d584177a993..70568090439 100644 --- a/addons/base_module_quality/base_module_quality.py +++ b/addons/base_module_quality/base_module_quality.py @@ -161,6 +161,38 @@ class abstract_quality_check(object): def add_quatation(self, x_no, y_no): return x_no/y_no + def get_style(self): + # This function return style tag with specified styles for html pages + style = ''' + ''' + return style + + class module_quality_check(osv.osv): _name = 'module.quality.check' _columns = { diff --git a/addons/base_module_quality/object_test/object_test.py b/addons/base_module_quality/object_test/object_test.py index d319d3f3a50..87329b480c7 100644 --- a/addons/base_module_quality/object_test/object_test.py +++ b/addons/base_module_quality/object_test/object_test.py @@ -40,7 +40,6 @@ Test checks for fields, views, security rules, dependancy level return None def run_test(self, cr, uid, module_path): - pool = pooler.get_pool(cr.dbname) module_name = module_path.split('/')[-1] obj_list = self.get_objects(cr, uid, module_name) @@ -184,9 +183,9 @@ Test checks for fields, views, security rules, dependancy level def get_result_details(self, dict_obj): res = "" if dict_obj != {}: - str_html = ''' Fields Result''' + str_html = ''' Fields Result%s'''%(self.get_style()) res += str_html - header = ('%s%s%s', [_('Object Name'), _('Field name'), _('Suggestion')]) + header = ('%s%s%s', [_('Object Name'), _('Field name'), _('Suggestion')]) if not self.error: for key in dict_obj.keys(): data_list = [] @@ -196,17 +195,18 @@ Test checks for fields, views, security rules, dependancy level for i in data_list: count = count + 1 final_dict[key + str(count)] = i - res += '' + self.format_html_table(header, data_list=final_dict) + '

' + res_str = '' + self.format_html_table(header, data_list=final_dict) + '

' + res += res_str.replace('''' return "" def get_result_general(self, dict_obj, name=''): - str_html = ''' %s Result'''% (name) - header = ('', [_('Object Name'), _('Suggestion')]) + str_html = ''' %s Result%s
%s%s
'''% (name, self.get_style()) + header = ('', [_('Object Name'), _('Suggestion')]) if not self.error: res = str_html + self.format_html_table(header, data_list=dict_obj) + '
%s%s
' + res = res.replace('''Result''' - header = ('', [_('Object Name'), _('Line number'), _('Suggestion')]) + str_html = '''Result%s
%s%s%s
'''%(self.get_style()) + header = ('', [_('Object Name'), _('Line number'), _('Suggestion')]) if not self.error: res = str_html + self.format_html_table(header, data_list=dict_obj) + '
%s%s%s
' + res = res.replace(''' - - - - ''' + self.result_details += '''%s'''%(self.get_style()) for file_py in list_files: if file_py.split('.')[-1] == 'py' and not file_py.endswith('__init__.py') and not file_py.endswith('__terp__.py'): if not flag: @@ -84,7 +80,19 @@ class quality_test(base_module_quality.abstract_quality_check): score += 0 #self.result += file + ": "+_("Unable to parse the result. Check the details.")+"\n" dict_py[file_py] = [file_py, _("Unable to parse the result. Check the details.")] - self.result_details += res.replace('''O(1) means that the number of SQL requests to read the object does not depand on the number of objects we are reading. This feature is hardly wished.\n") for obj, ids in obj_ids.items(): + code_base_complexity = 0 + code_half_complexity = 0 + code_size_complexity = 0 obj_counter += 1 ids = ids[:100] size = len(ids) @@ -71,34 +74,38 @@ This test checks the speed of the module. Note that at least 5 demo data is need if size: speed_list = [] #we perform the operation twice, and count the number of queries in the second run. This allows to avoid the cache effect. (like translated terms that asks for more queries) - pool.get(obj).read(cr, uid, [ids[0]]) - cnt = cr.count - pool.get(obj).read(cr, uid, [ids[0]]) - code_base_complexity = cr.count - cnt + try: + pool.get(obj).read(cr, uid, [ids[0]]) + cnt = cr.count + pool.get(obj).read(cr, uid, [ids[0]]) + code_base_complexity = cr.count - cnt - pool.get(obj).read(cr, uid, ids[:size/2]) - cnt = cr.count - pool.get(obj).read(cr, uid, ids[:size/2]) - code_half_complexity = cr.count - cnt + pool.get(obj).read(cr, uid, ids[:size/2]) + cnt = cr.count + pool.get(obj).read(cr, uid, ids[:size/2]) + code_half_complexity = cr.count - cnt - pool.get(obj).read(cr, uid, ids) - cnt = cr.count - pool.get(obj).read(cr, uid, ids) - code_size_complexity = cr.count - cnt - - if size < 5: - speed_list = [obj, size, code_base_complexity, code_half_complexity, code_size_complexity, _("Warning! Not enough demo data")] - list2 = [obj, _("No enough data")] + pool.get(obj).read(cr, uid, ids) + cnt = cr.count + pool.get(obj).read(cr, uid, ids) + code_size_complexity = cr.count - cnt + except Exception, e: + list2 = [obj, _("Error in Read method")] + speed_list = [obj, size, code_base_complexity, code_half_complexity, code_size_complexity, _("Error in Read method:" + str(e))] else: - if code_size_complexity <= (code_base_complexity + size): - complexity = _("O(1)") - score += 1 - list2 = [obj, _("Efficient")] + if size < 5: + speed_list = [obj, size, code_base_complexity, code_half_complexity, code_size_complexity, _("Warning! Not enough demo data")] + list2 = [obj, _("No enough data")] else: - complexity = _("O(n) or worst") - list2 = [obj, _("Not Efficient")] + if code_size_complexity <= (code_base_complexity + size): + complexity = _("O(1)") + score += 1 + list2 = [obj, _("Efficient")] + else: + complexity = _("O(n) or worst") + list2 = [obj, _("Not Efficient")] - speed_list = [obj, size, code_base_complexity, code_half_complexity, code_size_complexity, complexity] + speed_list = [obj, size, code_base_complexity, code_half_complexity, code_size_complexity, complexity] else: speed_list = [obj, size, "", "", "", _("Warning! Object has no demo data")] list2 = [obj, _("No data")] @@ -118,10 +125,11 @@ This test checks the speed of the module. Note that at least 5 demo data is need return "" def get_result_details(self, dict_speed): - str_html = '''''' - header = ('', [_('Object Name'), _('N (Number of Records)'), _('1'), _('N/2'), _('N'), _('Reading Complexity')]) + str_html = '''%s
%s%s%s%s%s%s
'''%(self.get_style()) + header = ('', [_('Object Name'), _('N (Number of Records)'), _('1'), _('N/2'), _('N'), _('Reading Complexity')]) if not self.error: res = str_html + self.format_html_table(header, data_list=dict_speed) + '
%s%s%s%s%s%s
' + res = res.replace('''''' - header = ('', [_('File Name'), _('Feedback about structure of module')]) + str_html = '''%s
%s%s
'''%(self.get_style()) + header = ('', [_('File Name'), _('Feedback about structure of module')]) if not self.error: res = str_html + self.format_html_table(header, data_list=dict_struct) + '
%s%s
' + res = res.replace('''''' - header = ('', [_('Tag Name'), _('Feed back About terp file of Module')]) + str_html = '''%s
%s%s
'''%(self.get_style()) + header = ('', [_('Tag Name'), _('Feed back About terp file of Module')]) if not self.error: res = str_html + self.format_html_table(header, data_list=dict_terp) + '
%s%s
' + res = res.replace('''''' - header = ('', [_('Object Name'), _('Feed back About Workflow of Module')]) + str_html = '''%s
%s%s
'''%(self.get_style()) + header = ('', [_('Object Name'), _('Feed back About Workflow of Module')]) if not self.error: res = str_html + self.format_html_table(header, data_list=dict_wf) + '
%s%s
' + res = res.replace(''' Check cases rules - 1 + 4 hours -1 diff --git a/addons/document/document.py b/addons/document/document.py index 21aa59661a7..460c52a9698 100644 --- a/addons/document/document.py +++ b/addons/document/document.py @@ -125,16 +125,7 @@ class node_class(object): def get_translation(self,value,lang): result = value - pool = pooler.get_pool(self.cr.dbname) - translation_ids = pool.get('ir.translation').search(self.cr, self.uid, [('value','=',value),('lang','=',lang),('type','=','model')]) - if len(translation_ids): - tran_id = translation_ids[0] - translation = pool.get('ir.translation').read(self.cr, self.uid, tran_id, ['res_id','name']) - res_model,field_name = tuple(translation['name'].split(',')) - res_id = translation['res_id'] - res = pool.get(res_model).read(self.cr, self.uid, res_id, [field_name]) - if res: - result = res[field_name] + #TODO : to get translation term return result def directory_list_for_child(self,nodename,parent=False): @@ -346,12 +337,9 @@ class document_directory(osv.osv): object: the object.directory or object.directory.content object2: the other object linked (if object.directory.content) """ - def get_object(self, cr, uid, uri, context={}): - lang = context.get('lang',False) - if not lang: - user = self.pool.get('res.users').browse(cr, uid, uid) - lang = user.context_lang - context['lang'] = lang + def get_object(self, cr, uid, uri, context={}): + #TODO : set user's context_lang in context + context.update({'lang':False}) if not uri: return node_class(cr, uid, '', False, context=context, type='database') turi = tuple(uri) @@ -667,6 +655,7 @@ class document_file(osv.osv): vals['res_id']=context.get('default_res_id',False) if not vals.get('res_model', False) and context.get('default_res_model',False): vals['res_model']=context.get('default_res_model',False) + if vals.get('res_id', False) and vals.get('res_model',False): obj_model=self.pool.get(vals['res_model']) result = obj_model.read(cr, uid, [vals['res_id']], context=context) @@ -705,7 +694,7 @@ class document_file(osv.osv): try: res = content_index(base64.decodestring(datas), vals['datas_fname'], vals.get('content_type', None)) super(document_file,self).write(cr, uid, [result], { - 'index_content': res, + 'index_content' : res, }) cr.commit() except: diff --git a/addons/hr_holidays/hr.py b/addons/hr_holidays/hr.py index 4081f9863e2..733f90f48cd 100644 --- a/addons/hr_holidays/hr.py +++ b/addons/hr_holidays/hr.py @@ -207,8 +207,11 @@ class hr_holidays(osv.osv): 'state':'validate', } ids2 = self.pool.get('hr.employee').search(cr, uid, [('user_id','=', uid)]) + if ids2: vals['manager_id'] = ids2[0] + else: + raise osv.except_osv(_('Warning !'),_('Either there is no Employee defined, or no User attached with it.')) self.write(cr, uid, ids, vals) return True diff --git a/addons/hr_timesheet_invoice/hr_timesheet_invoice.py b/addons/hr_timesheet_invoice/hr_timesheet_invoice.py index 6f29c056d34..0c16fb4ffd4 100644 --- a/addons/hr_timesheet_invoice/hr_timesheet_invoice.py +++ b/addons/hr_timesheet_invoice/hr_timesheet_invoice.py @@ -44,7 +44,7 @@ class account_analytic_account(osv.osv): res = {} for account in self.browse(cr, uid, ids): invoiced = {} - cr.execute('select distinct l.invoice_id from hr_analytic_timesheet h left join account_analytic_line l on (h.line_id=l.id) where account_id=1', (account.id,)) + cr.execute('select distinct(l.invoice_id) from hr_analytic_timesheet h left join account_analytic_line l on (h.line_id=l.id) where account_id=%s', (account.id,)) invoice_ids = filter(None, map(lambda x: x[0], cr.fetchall())) for invoice in self.pool.get('account.invoice').browse(cr, uid, invoice_ids, context): res.setdefault(account.id, 0.0) diff --git a/addons/hr_timesheet_sheet/hr_timesheet_sheet.py b/addons/hr_timesheet_sheet/hr_timesheet_sheet.py index 3f8ac28dc8f..e700e404c2f 100644 --- a/addons/hr_timesheet_sheet/hr_timesheet_sheet.py +++ b/addons/hr_timesheet_sheet/hr_timesheet_sheet.py @@ -587,7 +587,7 @@ class hr_timesheet_sheet_sheet_day(osv.osv): sheet_id, total_timesheet, total_attendance, - round(cast((total_attendance - total_timesheet) as Numeric),2) AS total_difference + cast(round(cast(total_attendance - total_timesheet as Numeric),2) as Double Precision) AS total_difference FROM (( SELECT diff --git a/addons/mrp/report/workcenter_load.py b/addons/mrp/report/workcenter_load.py index 2bb1572d170..46d0d34628a 100644 --- a/addons/mrp/report/workcenter_load.py +++ b/addons/mrp/report/workcenter_load.py @@ -35,7 +35,7 @@ theme.use_color = 1 random.seed(0) # -# Pinky: Bad code, seems buggy, TO CHECK ! +# TODO: Bad code, seems buggy, TO CHECK ! # class external_pdf(render): @@ -101,7 +101,7 @@ class report_custom(report_int): colors = choice_colors(len(ids)) ids_str = ','.join(map(str, ids)) cr.execute( - "SELECT MAX(date_planned) AS stop "\ + "SELECT MAX(mrp_production.date_planned) AS stop,MIN(mrp_production.date_planned) AS start "\ "FROM mrp_workcenter, mrp_production, mrp_production_workcenter_line "\ "WHERE mrp_production_workcenter_line.production_id=mrp_production.id "\ "AND mrp_production_workcenter_line.workcenter_id=mrp_workcenter.id "\ @@ -109,8 +109,10 @@ class report_custom(report_int): "AND mrp_workcenter.id IN (%s)" % ids_str) res = cr.dictfetchone() if not res['stop']: - res['stop'] = time.strftime('%Y-%m-%d') - dates = self._compute_dates(datas['form']['time_unit'], time.strftime('%Y-%m-%d'), res['stop'][:10]) + res['stop'] = time.strftime('%Y-%m-%d %H:%M:%S') + if not res['start']: + res['start'] = time.strftime('%Y-%m-%d %H:%M:%S') + dates = self._compute_dates(datas['form']['time_unit'], res['start'][:10], res['stop'][:10]) dates_list = dates.keys() dates_list.sort() x_index = [] @@ -174,8 +176,8 @@ class report_custom(report_int): workcenter_num += 1 #plot = bar_plot.T(label=workcenter['name'], data=data, hcol=1, fill_style=fill_style.white, cluster=(color_index,len(ids))) - if (len(data[0]) <= 1): - ar = self._empty_graph(data[0][0]) + if (not data) or (len(data[0]) <= 1): + ar = self._empty_graph(time.strftime('%Y-%m-%d')) ar.draw(can) # close canvas so that the file is written to "disk" can.close() diff --git a/addons/mrp_repair/mrp_repair.py b/addons/mrp_repair/mrp_repair.py index c5cefd61267..a34f6c844b6 100644 --- a/addons/mrp_repair/mrp_repair.py +++ b/addons/mrp_repair/mrp_repair.py @@ -300,7 +300,7 @@ class mrp_repair(osv.osv): 'invoice_id': inv_id, 'name': name, 'origin':repair.name, - 'account_id': a, + 'account_id': operation.product_id and operation.product_id.property_account_income and operation.product_id.property_account_income.id, 'quantity' : operation.product_uom_qty, 'invoice_line_tax_id': [(6,0,[x.id for x in operation.tax_id])], 'uos_id' : operation.product_uom.id, diff --git a/addons/purchase/purchase_view.xml b/addons/purchase/purchase_view.xml index 51434162854..f41e6e05cd2 100644 --- a/addons/purchase/purchase_view.xml +++ b/addons/purchase/purchase_view.xml @@ -51,7 +51,18 @@ - + + + + + + + + + + + + @@ -71,7 +82,7 @@