diff --git a/addons/account/account.py b/addons/account/account.py index ed460c041c7..516c185b652 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -77,7 +77,10 @@ class account_payment_term_line(osv.osv): _columns = { 'name': fields.char('Line Name', size=32, required=True), 'sequence': fields.integer('Sequence', required=True, help="The sequence field is used to order the payment term lines from the lowest sequences to the higher ones"), - 'value': fields.selection([('procent', 'Percent'), ('balance', 'Balance'), ('fixed', 'Fixed Amount')], 'Value', required=True, help="""Example: 14 days 2%, 30 days net + 'value': fields.selection([('procent', 'Percent'), + ('balance', 'Balance'), + ('fixed', 'Fixed Amount')], 'Value', + required=True, help="""Example: 14 days 2%, 30 days net 1. Line 1: percent 0.02 14 days 2. Line 2: balance 30 days"""), @@ -204,43 +207,50 @@ class account_account(osv.osv): #compute for each account the balance/debit/credit from the move lines accounts = {} if ids2: - query = self.pool.get('account.move.line')._query_get(cr, uid, - context=context) + aml_query = self.pool.get('account.move.line')._query_get(cr, uid, context=context) + + wheres = [""] + if query: + wheres.append(query.strip()) + if aml_query: + wheres.append(aml_query.strip()) + query = " AND ".join(wheres) + cr.execute("SELECT l.account_id as id, " +\ ' , '.join(map(lambda x: mapping[x], field_names)) + "FROM " \ "account_move_line l " \ "WHERE " \ "l.account_id =ANY(%s) " \ - "AND " + query + " " \ - "GROUP BY l.account_id",(ids2,)) + + query + + " GROUP BY l.account_id",(ids2,)) for res in cr.dictfetchall(): accounts[res['id']] = res - #for the asked accounts, get from the dictionnary 'accounts' the value of it + + # consolidate accounts with direct children + brs = list(self.browse(cr, uid, ids2, context=context)) + sums = {} + while brs: + current = brs[0] + can_compute = True + for child in current.child_id: + if child.id not in sums: + can_compute = False + try: + brs.insert(0, brs.pop(brs.index(child))) + except ValueError: + brs.insert(0, child) + if can_compute: + brs.pop(0) + for fn in field_names: + sums.setdefault(current.id, {})[fn] = accounts.get(current.id, {}).get(fn, 0.0) + if current.child_id: + sums[current.id][fn] += sum(sums[child.id][fn] for child in current.child_id) res = {} for id in ids: - res[id] = self._get_account_values(cr, uid, id, accounts, field_names, context) - return res - - def _get_account_values(self, cr, uid, id, accounts, field_names, context={}): - res = {}.fromkeys(field_names, 0.0) - browse_rec = self.browse(cr, uid, id) - if browse_rec.type == 'consolidation': - ids2 = self.read(cr, uid, [browse_rec.id], ['child_consol_ids'], context)[0]['child_consol_ids'] - for t in self.search(cr, uid, [('parent_id', 'child_of', [browse_rec.id])]): - if t not in ids2 and t != browse_rec.id: - ids2.append(t) - for i in ids2: - tmp = self._get_account_values(cr, uid, i, accounts, field_names, context) - for a in field_names: - res[a] += tmp[a] - else: - ids2 = self.search(cr, uid, [('parent_id', 'child_of', [browse_rec.id])]) - for i in ids2: - for a in field_names: - res[a] += accounts.get(i, {}).get(a, 0.0) + res[id] = sums[id] return res def _get_company_currency(self, cr, uid, ids, field_name, arg, context={}): @@ -259,7 +269,8 @@ class account_account(osv.osv): if record.child_consol_ids: for acc in record.child_consol_ids: - result[record.id].append(acc.id) + if acc.id not in result[record.id]: + result[record.id].append(acc.id) return result @@ -1488,8 +1499,8 @@ class account_tax(osv.osv): exec tax.python_compute_inv in localdict amount = localdict['result'] elif tax.type=='balance': - data['amount'] = cur_price_unit - reduce(lambda x,y: y.get('amount',0.0)+x, res, 0.0) - data['balance'] = cur_price_unit + amount = cur_price_unit - reduce(lambda x,y: y.get('amount',0.0)+x, res, 0.0) +# data['balance'] = cur_price_unit if tax.include_base_amount: diff --git a/addons/account/account_analytic_line.py b/addons/account/account_analytic_line.py index 08f36f65e53..b41ef632477 100644 --- a/addons/account/account_analytic_line.py +++ b/addons/account/account_analytic_line.py @@ -91,7 +91,7 @@ class account_analytic_line(osv.osv): 'account.analytic.line': (lambda self,cr,uid,ids,c={}: ids, ['amount','unit_amount'],10), }, help="The amount expressed in the related account currency if not equal to the company one."), - 'ref': fields.char('Reference', size=32), + 'ref': fields.char('Ref.', size=64), } _defaults = { 'date': lambda *a: time.strftime('%Y-%m-%d'), diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py index 88c8e53fa6a..01c1eb7fa37 100644 --- a/addons/account/account_bank_statement.py +++ b/addons/account/account_bank_statement.py @@ -107,7 +107,7 @@ class account_bank_statement(osv.osv): _name = "account.bank.statement" _description = "Bank Statement" _columns = { - 'name': fields.char('Name', size=64, required=True), + 'name': fields.char('Name', size=64, required=True, states={'confirm': [('readonly', True)]}), 'date': fields.date('Date', required=True, states={'confirm': [('readonly', True)]}), 'journal_id': fields.many2one('account.journal', 'Journal', required=True, @@ -290,7 +290,14 @@ class account_bank_statement(osv.osv): torec += map(lambda x: x.id, move.reconcile_id.line_ids) #try: if abs(move.reconcile_amount-move.amount)<0.0001: - account_move_line_obj.reconcile(cr, uid, torec, 'statement', writeoff_period_id=st.period_id.id, writeoff_journal_id=st.journal_id.id, context=context) + + writeoff_acc_id = False + #There should only be one write-off account! + for entry in move.reconcile_id.line_new_ids: + writeoff_acc_id = entry.account_id.id + break + + account_move_line_obj.reconcile(cr, uid, torec, 'statement', writeoff_acc_id=writeoff_acc_id, writeoff_period_id=st.period_id.id, writeoff_journal_id=st.journal_id.id, context=context) else: account_move_line_obj.reconcile_partial(cr, uid, torec, 'statement', context) #except: @@ -339,6 +346,17 @@ class account_bank_statement(osv.osv): context=context)[0] return {'value': {'balance_start': balance_start, 'currency': currency}} + def unlink(self, cr, uid, ids, context=None): + stat = self.read(cr, uid, ids, ['state']) + unlink_ids = [] + for t in stat: + if t['state'] in ('draft'): + unlink_ids.append(t['id']) + else: + raise osv.except_osv(_('Invalid action !'), _('Cannot delete bank statement which are already confirmed !')) + osv.osv.unlink(self, cr, uid, unlink_ids, context=context) + return True + account_bank_statement() diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index e5e16ee73cc..9470c6fc01e 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -357,7 +357,7 @@ class account_move_line(osv.osv): 'account_id': fields.many2one('account.account', 'Account', required=True, ondelete="cascade", domain=[('type','<>','view'), ('type', '<>', 'closed')], select=2), 'move_id': fields.many2one('account.move', 'Move', ondelete="cascade", states={'valid':[('readonly',True)]}, help="The move of this entry line.", select=2), - 'ref': fields.char('Reference', size=32), + 'ref': fields.char('Ref.', size=64), 'statement_id': fields.many2one('account.bank.statement', 'Statement', help="The bank statement used for bank reconciliation", select=1), 'reconcile_id': fields.many2one('account.move.reconcile', 'Reconcile', readonly=True, ondelete='set null', select=2), 'reconcile_partial_id': fields.many2one('account.move.reconcile', 'Partial Reconcile', readonly=True, ondelete='set null', select=2), diff --git a/addons/account/demo/account_minimal.xml b/addons/account/demo/account_minimal.xml index 8ab449af66a..9f15acb0449 100644 --- a/addons/account/demo/account_minimal.xml +++ b/addons/account/demo/account_minimal.xml @@ -62,7 +62,6 @@ your own accounts. Main Receivable x 40000 receivable - @@ -78,7 +77,6 @@ your own chart of account. Main Payable x 440000 payable - @@ -94,7 +92,6 @@ your own chart of account. Petty Cash x 570000 other - @@ -109,7 +106,6 @@ your own chart of account. Products Purchase x 600000 other - @@ -124,7 +120,6 @@ your own chart of account. Products Sales x 701000 other - diff --git a/addons/account/invoice.py b/addons/account/invoice.py index 0227b37dd3b..912095110e7 100644 --- a/addons/account/invoice.py +++ b/addons/account/invoice.py @@ -64,9 +64,10 @@ class account_invoice(osv.osv): user = self.pool.get('res.users').browse(cr, uid, uid) company_id = context.get('company_id', user.company_id.id) type2journal = {'out_invoice': 'sale', 'in_invoice': 'purchase', 'out_refund': 'sale', 'in_refund': 'purchase'} + refund_journal = {'out_invoice': False, 'in_invoice': False, 'out_refund': True, 'in_refund': True} journal_obj = self.pool.get('account.journal') res = journal_obj.search(cr, uid, [('type', '=', type2journal.get(type_inv, 'sale')), - ('company_id', '=', company_id)], + ('company_id', '=', company_id),('refund_journal', '=', refund_journal.get(type_inv, False))], limit=1) if res: return res[0] @@ -855,7 +856,7 @@ class account_invoice(osv.osv): def action_cancel(self, cr, uid, ids, *args): account_move_obj = self.pool.get('account.move') - invoices = self.read(cr, uid, ids, ['move_id']) + invoices = self.read(cr, uid, ids, ['move_id', 'payment_ids']) for i in invoices: if i['move_id']: account_move_obj.button_cancel(cr, uid, [i['move_id'][0]]) @@ -863,6 +864,8 @@ class account_invoice(osv.osv): # Note that the corresponding move_lines and move_reconciles # will be automatically deleted too account_move_obj.unlink(cr, uid, [i['move_id'][0]]) + if i['payment_ids']: + self.pool.get('account.move.line').write(cr, uid, i['payment_ids'], {'reconcile_partial_id': False}) self.write(cr, uid, ids, {'state':'cancel', 'move_id':False}) self._log_event(cr, uid, ids,-1.0, 'Cancel Invoice') return True @@ -1231,13 +1234,13 @@ class account_invoice_line(osv.osv): taxes = res.supplier_taxes_id and res.supplier_taxes_id or (a and self.pool.get('account.account').browse(cr, uid,a).tax_ids or False) tax_id = self.pool.get('account.fiscal.position').map_tax(cr, uid, fpos, taxes) if type in ('in_invoice', 'in_refund'): - to_update = self.product_id_change_unit_price_inv(cr, uid, tax_id, price_unit, qty, address_invoice_id, product, partner_id, context=context) + to_update = self.product_id_change_unit_price_inv(cr, uid, tax_id, price_unit or res.standard_price, qty, address_invoice_id, product, partner_id, context=context) result.update(to_update) else: result.update({'price_unit': res.list_price, 'invoice_line_tax_id': tax_id}) if not name: - result['name'] = res.name + result['name'] = res.partner_ref domain = {} result['uos_id'] = uom or res.uom_id.id or False diff --git a/addons/account/report/general_ledger.py b/addons/account/report/general_ledger.py index 5db2545d070..43c298866ed 100644 --- a/addons/account/report/general_ledger.py +++ b/addons/account/report/general_ledger.py @@ -258,7 +258,7 @@ class general_ledger(rml_parse.rml_parse): else: sorttag = 'j.code' sql = """ - SELECT l.id, l.date, j.code,c.code AS currency_code,l.amount_currency,l.ref, l.name , l.debit, l.credit, l.period_id + SELECT l.id, l.date, j.code,c.code AS currency_code,l.amount_currency,l.ref, l.name , COALESCE(l.debit,0) as debit, COALESCE(l.credit,0) as credit, l.period_id FROM account_move_line as l LEFT JOIN res_currency c on (l.currency_id=c.id) JOIN account_journal j on (l.journal_id=j.id) diff --git a/addons/account/report/general_ledger_landscape.py b/addons/account/report/general_ledger_landscape.py index c0d48ad6e0e..dcb4e47fbdd 100644 --- a/addons/account/report/general_ledger_landscape.py +++ b/addons/account/report/general_ledger_landscape.py @@ -261,7 +261,7 @@ class general_ledger_landscape(rml_parse.rml_parse): else: sorttag = 'j.code' sql = """ - SELECT l.id, l.date, j.code,c.code AS currency_code,l.amount_currency,l.ref, l.name , l.debit, l.credit, l.period_id + SELECT l.id, l.date, j.code,c.code AS currency_code,l.amount_currency,l.ref, l.name , COALESCE(l.debit,0) as debit, COALESCE(l.credit,0) as credit, l.period_id FROM account_move_line as l LEFT JOIN res_currency c on (l.currency_id=c.id) JOIN account_journal j on (l.journal_id=j.id) diff --git a/addons/account/sequence.py b/addons/account/sequence.py index 498e997dc2b..d48f23eb1cf 100644 --- a/addons/account/sequence.py +++ b/addons/account/sequence.py @@ -30,6 +30,11 @@ class ir_sequence_fiscalyear(osv.osv): "sequence_main_id": fields.many2one("ir.sequence", 'Main Sequence', required=True, ondelete='cascade'), "fiscalyear_id": fields.many2one('account.fiscalyear', 'Fiscal Year', required=True, ondelete='cascade') } + + _sql_constraints = [ + ('main_id', 'CHECK (sequence_main_id != sequence_id)', 'Main Sequence must be different from current !'), + ] + ir_sequence_fiscalyear() class ir_sequence(osv.osv): diff --git a/addons/account/wizard/wizard_pay_invoice.py b/addons/account/wizard/wizard_pay_invoice.py index b924d56e389..b8ec568f0f8 100644 --- a/addons/account/wizard/wizard_pay_invoice.py +++ b/addons/account/wizard/wizard_pay_invoice.py @@ -65,6 +65,13 @@ def _pay_and_reconcile(self, cr, uid, data, context): currency_id = journal.currency.id # Put the paid amount in currency, and the currency, in the context if currency is different from company's currency context.update({'amount_currency':form['amount'],'currency_id':currency_id}) + + if invoice.company_id.currency_id.id<>invoice.currency_id.id: + ctx = {'date':data['form']['date']} + amount = cur_obj.compute(cr, uid, invoice.currency_id.id, invoice.company_id.currency_id.id, amount, context=ctx) + currency_id = invoice.currency_id.id + # Put the paid amount in currency, and the currency, in the context if currency is different from company's currency + context.update({'amount_currency':form['amount'],'currency_id':currency_id}) # Take the choosen date if form.has_key('comment'): @@ -91,7 +98,13 @@ def _wo_check(self, cr, uid, data, context): # => Ask to a write-off of the difference. This could happen even if both amount are equal, # because if the currency rate # Get the amount in company currency for the invoice (according to move lines) - inv_amount_company_currency=invoice.move_id.amount + inv_amount_company_currency = 0 + for aml in invoice.move_id.line_id: + if aml.account_id.id == invoice.account_id.id or aml.account_id.type in ('receivable', 'payable'): + inv_amount_company_currency += aml.debit + inv_amount_company_currency -= aml.credit + inv_amount_company_currency = abs(inv_amount_company_currency) + # Get the current amount paid in company currency if journal.currency and invoice.company_id.currency_id.id<>journal.currency.id: ctx = {'date':data['form']['date']} diff --git a/addons/account/wizard/wizard_statement_from_invoice.py b/addons/account/wizard/wizard_statement_from_invoice.py index 5bb9a0d9772..92d33f329c7 100644 --- a/addons/account/wizard/wizard_statement_from_invoice.py +++ b/addons/account/wizard/wizard_statement_from_invoice.py @@ -71,7 +71,7 @@ def _search_invoices(obj, cr, uid, data, context): move_line_id = line_obj.search(cr, uid, args_move_line,context=context) if move_line_id: - repeated_move_line_ids.append(move_line_id) + repeated_move_line_ids += move_line_id journal_ids = data['form']['journal_id'][0][2] diff --git a/addons/account_tax_include/invoice_tax_incl.py b/addons/account_tax_include/invoice_tax_incl.py index f47c587babc..d4255bb96a9 100644 --- a/addons/account_tax_include/invoice_tax_incl.py +++ b/addons/account_tax_include/invoice_tax_incl.py @@ -36,6 +36,20 @@ class account_invoice(osv.osv): _defaults = { 'price_type': lambda *a: 'tax_excluded', } + + def refund(self, cr, uid, ids, date=None, period_id=None, description=None): + map_old_new = {} + refund_ids = [] + for old_inv_id in ids: + new_id = super(account_invoice,self).refund(cr, uid, ids, date=date, period_id=period_id, description=description) + refund_ids += new_id + map_old_new[old_inv_id] = new_id[0] + + for old_inv_id in map_old_new.keys(): + old_inv_record = self.read(cr, uid, [old_inv_id], ['price_type'])[0]['price_type'] + self.write(cr, uid, [map_old_new[old_inv_id]], {'price_type' : old_inv_record}) + return refund_ids + account_invoice() class account_invoice_line(osv.osv): @@ -85,8 +99,8 @@ class account_invoice_line(osv.osv): res[line.id]['price_subtotal'] = res[line.id]['price_subtotal'] - tax['amount'] res[line.id]['data'].append( tax) - res[line.id]['price_subtotal']= round(res[line.id]['price_subtotal'], int(config['price_accuracy'])) - res[line.id]['price_subtotal_incl']= round(res[line.id]['price_subtotal_incl'], int(config['price_accuracy'])) + res[line.id]['price_subtotal']= round(res[line.id]['price_subtotal'], int(config['price_accuracy'])) + res[line.id]['price_subtotal_incl']= round(res[line.id]['price_subtotal_incl'], int(config['price_accuracy'])) return res def _price_unit_default(self, cr, uid, context=None): diff --git a/addons/account_voucher/account.py b/addons/account_voucher/account.py index 521767fa410..4e01e275988 100644 --- a/addons/account_voucher/account.py +++ b/addons/account_voucher/account.py @@ -62,38 +62,12 @@ class account_account(osv.osv): 'type1':fields.selection([('dr','Debit'),('cr','Credit'),('none','None')], 'Dr/Cr',store=True), } - def compute_total(self, cr, uid, ids, yr_st_date, yr_end_date, st_date, end_date, field_names, context={}, query=''): - #compute the balance/debit/credit accordingly to the value of field_name for the given account ids - mapping = { - 'credit': "COALESCE(SUM(l.credit), 0) as credit ", - 'balance': "COALESCE(SUM(l.debit),0) - COALESCE(SUM(l.credit), 0) as balance ", - 'debit': "COALESCE(SUM(l.debit), 0) as debit ", - } - #get all the necessary accounts - ids2 = self._get_children_and_consol(cr, uid, ids, context) - acc_set = ",".join(map(str, ids2)) - #compute for each account the balance/debit/credit from the move lines + def compute_total(self, cr, uid, ids, yr_st_date, yr_end_date, st_date, end_date, field_names, context={}): if not (st_date >= yr_st_date and end_date <= yr_end_date): return {} - accounts = {} - if ids2: - query = self.pool.get('account.move.line')._query_get(cr, uid, - context=context) - cr.execute("SELECT l.account_id as id, " \ - + ' , '.join(map(lambda x: mapping[x], field_names.keys() )) + \ - "FROM account_move_line l " \ - "WHERE l.account_id IN ("+ acc_set +") " \ - "AND " + query + " " \ - " AND l.date >= "+"'"+ st_date +"'"+" AND l.date <= "+"'"+ end_date +""+"'"" " \ - "GROUP BY l.account_id ") - for res in cr.dictfetchall(): - accounts[res['id']] = res - #for the asked accounts, get from the dictionnary 'accounts' the value of it - res = {} - for id in ids: - res[id] = self._get_account_values(cr, uid, id, accounts, field_names, context) - return res - + query = "l.date >= '%s' AND l.date <= '%s'" (st_date, end_date) + return self.__compute(cr, uid, ids, field_names, context=context, query=query) + def create(self, cr, uid, vals, context={}): name=self.search(cr,uid,[('name','ilike',vals['name']),('company_id','=',vals['name'])]) if name: diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py index 5b9c111ce14..e6c39afcaf7 100644 --- a/addons/base_calendar/base_calendar.py +++ b/addons/base_calendar/base_calendar.py @@ -405,7 +405,7 @@ request was delegated to"), 'state': lambda *x: 'needs-action', } - response_re = response_re = re.compile("Are you coming\?.*\n*.*(YES|NO|MAYBE).*", re.UNICODE) + response_re = re.compile("Are you coming\?.*\n*.*(YES|NO|MAYBE).*", re.UNICODE) def msg_new(self, cr, uid, msg): return False diff --git a/addons/base_contact/base_contact.py b/addons/base_contact/base_contact.py index 457a96a1c6b..ea8680b8247 100644 --- a/addons/base_contact/base_contact.py +++ b/addons/base_contact/base_contact.py @@ -134,17 +134,29 @@ class res_partner_job(osv.osv): res = [] for r in self.browse(cr, uid, ids): funct = r.function_id and (", " + r.function_id.name) or "" - res.append((r.id, self.pool.get('res.partner.contact').name_get(cr, uid, [r.contact_id.id])[0][1] + funct )) + res.append((r.id, self.pool.get('res.partner.contact').name_get(cr, uid, [r.contact_id.id])[0][1] + funct)) return res - def search(self, cr, user, args, offset=0, limit=None, order=None, - context=None, count=False): + def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False): + job_ids = [] for arg in args: - if arg[0]=='address_id': + if arg[0] == 'address_id': self._order = 'sequence_partner' - if arg[0]=='contact_id': + elif arg[0] == 'contact_id': self._order = 'sequence_contact' - return super(res_partner_job,self).search(cr, user, args, offset, limit, order, context, count) + + contact_obj = self.pool.get('res.partner.contact') + search_arg = ['|', ('first_name', 'ilike', arg[2]), ('name', 'ilike', arg[2])] + contact_ids = contact_obj.search(cr, user, search_arg, offset=offset, limit=limit, order=order, context=context, count=count) + contacts = contact_obj.browse(cr, user, contact_ids, context=context) + for contact in contacts: + job_ids.extend([item.id for item in contact.job_ids]) + + res = super(res_partner_job,self).search(cr, user, args, offset=offset, limit=limit, order=order, context=context, count=count) + if job_ids: + res = list(set(res + job_ids)) + + return res _name = 'res.partner.job' _description ='Contact Partner Function' diff --git a/addons/base_report_creator/base_report_creator.py b/addons/base_report_creator/base_report_creator.py index 36547f68ae5..b9ddba5385c 100644 --- a/addons/base_report_creator/base_report_creator.py +++ b/addons/base_report_creator/base_report_creator.py @@ -54,6 +54,21 @@ class report_creator(osv.osv): # # Should request only used fields # + def export_data(self, cr, uid, ids, fields_to_export, context=None): + data_l = self.read(cr, uid, ids, ['sql_query'], context) + final_datas =[] + for i in data_l: + datas = [] + for key,value in i.items(): + if key not in fields_to_export: + continue + if isinstance(value,tuple): + datas.append(str(value[1])) + else: + datas.append(str(value)) + final_datas += [datas] + return {'datas':final_datas} + def fields_get(self, cr, user, fields=None, context=None): if (not context) or 'report_id' not in context: return super(report_creator, self).fields_get(cr, user, fields, context) diff --git a/addons/base_report_creator/wizard/wiz_set_filter_fields.py b/addons/base_report_creator/wizard/wiz_set_filter_fields.py index cf4accf56e9..064e54264c4 100644 --- a/addons/base_report_creator/wizard/wiz_set_filter_fields.py +++ b/addons/base_report_creator/wizard/wiz_set_filter_fields.py @@ -84,13 +84,13 @@ def set_field_operator(self,field_name,field_type,search_operator,search_value): field_search[2] = "("+','.join([str(x) for x in search_value])+")" else: field_search[1] = 'ilike' - field_search[2] = "'%"+str(search_value)+"%'" + field_search[2] = "'%%"+str(search_value)+"%%'" elif search_operator == 'not in': if field_type=='many2one': field_search[2] = "("+','.join([str(x) for x in search_value])+")" else: field_search[1] = 'not ilike' - field_search[2] = "'%"+str(search_value)+"%'" + field_search[2] = "'%%"+str(search_value)+"%%'" elif search_operator == '^': if field_type in char_type: field_search[1]='~' diff --git a/addons/base_report_designer/wizard/tiny_sxw2rml/tiny_sxw2rml.py b/addons/base_report_designer/wizard/tiny_sxw2rml/tiny_sxw2rml.py index 3ff81bee311..9ba1fc6dfaa 100644 --- a/addons/base_report_designer/wizard/tiny_sxw2rml/tiny_sxw2rml.py +++ b/addons/base_report_designer/wizard/tiny_sxw2rml/tiny_sxw2rml.py @@ -193,7 +193,7 @@ class DomApi(DomApiGeneral): s.appendChild(temp) c = self.findChildrenByName(s,"style:properties") c = c[0] - dict = self.style_properties_dict[(s.getAttribute("style:name")).encode("latin-1")] or {} + dict = self.style_properties_dict[(s.getAttribute("style:name")).encode("utf-8")] or {} for attribute in dict.keys(): c.setAttribute(self.openOfficeStringUtf8(attribute),self.openOfficeStringUtf8(dict[attribute])) @@ -242,7 +242,7 @@ class DomApi(DomApiGeneral): Caution: in this dict the nodes from two dom apis are merged!""" for st in (self.styles_dom,self.content_dom): for s in st.getElementsByTagName("style:style"): - name = s.getAttribute("style:name").encode("latin-1") + name = s.getAttribute("style:name").encode("utf-8") self.style_dict[name] = s return True @@ -253,14 +253,14 @@ class DomApi(DomApiGeneral): res = {} if self.style_dict[style_name].hasAttribute("style:parent-style-name"): - parent = self.style_dict[style_name].getAttribute("style:parent-style-name").encode("latin-1") + parent = self.style_dict[style_name].getAttribute("style:parent-style-name").encode("utf-8") res = self.getStylePropertiesDict(parent) childs = self.style_dict[style_name].childNodes for c in childs: if c.nodeType == c.ELEMENT_NODE and c.nodeName.find("properties")>0 : for attr in c._attrs.keys(): - res[attr] = c.getAttribute(attr).encode("latin-1") + res[attr] = c.getAttribute(attr).encode("utf-8") return res class PyOpenOffice(object): diff --git a/addons/crm/crm.py b/addons/crm/crm.py index 2b4075e4f7f..1289b44a0cd 100644 --- a/addons/crm/crm.py +++ b/addons/crm/crm.py @@ -25,12 +25,17 @@ import os import base64 import tools import mx.DateTime +import datetime -from tools.translate import _ -from osv import fields -from osv import osv +from datetime import datetime +from datetime import timedelta +from osv import fields from osv import orm +from osv import osv from osv.orm import except_orm +from tools.translate import _ + + MAX_LEVEL = 15 AVAILABLE_STATES = [ @@ -270,6 +275,7 @@ class crm_case(osv.osv): 'email_from': _get_default_email, 'state': lambda *a: 'draft', 'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'), + 'date_deadline': lambda *a:(datetime.today() + timedelta(days=3)).strftime('%Y-%m-%d %H:%M:%S'), 'section_id': _get_section, } _order = 'date_deadline desc, date desc,id desc' @@ -282,16 +288,7 @@ class crm_case(osv.osv): return super(crm_case, self).unlink(cr, uid, ids, context) def stage_next(self, cr, uid, ids, context={}): - ok = False - sid = self.pool.get('crm.case.stage').search(cr, uid, [('object_id.model', '=', self._name)], context=context) - s = {} - previous = {} - for stage in self.pool.get('crm.case.stage').browse(cr, uid, sid, context=context): - section = stage.section_id.id or False - s.setdefault(section, {}) - s[section][previous.get(section, False)] = stage.id - previous[section] = stage.id - + s = self.get_stage_dict(cr, uid, ids, context=context) for case in self.browse(cr, uid, ids, context): section = (case.section_id.id or False) if section in s: @@ -300,7 +297,29 @@ class crm_case(osv.osv): self.write(cr, uid, [case.id], {'stage_id': s[section][st]}) return True - + + def get_stage_dict(self, cr, uid, ids, context={}): + sid = self.pool.get('crm.case.stage').search(cr, uid, [('object_id.model', '=', self._name)], context=context) + s = {} + previous = {} + for stage in self.pool.get('crm.case.stage').browse(cr, uid, sid, context=context): + section = stage.section_id.id or False + s.setdefault(section, {}) + s[section][previous.get(section, False)] = stage.id + previous[section] = stage.id + return s + + def stage_previous(self, cr, uid, ids, context={}): + s = self.get_stage_dict(cr, uid, ids, context=context) + for case in self.browse(cr, uid, ids, context): + section = (case.section_id.id or False) + if section in s: + st = case.stage_id.id or False + s[section] = dict([(v, k) for (k, v) in s[section].iteritems()]) + if st in s[section]: + self.write(cr, uid, [case.id], {'stage_id': s[section][st]}) + return True + def onchange_categ_id(self, cr, uid, ids, categ, context={}): if not categ: return {'value':{}} diff --git a/addons/crm/crm_claims_view.xml b/addons/crm/crm_claims_view.xml index c9b7ac5a825..b693545654f 100644 --- a/addons/crm/crm_claims_view.xml +++ b/addons/crm/crm_claims_view.xml @@ -53,10 +53,11 @@ + - + -