[IMP] improved error message, constraints must allways propose a solution
bzr revid: fp@fp-laptop-20111231075720-4kak7o320td4wxqc
This commit is contained in:
parent
917d171804
commit
8aff5209ea
|
@ -620,7 +620,7 @@ class account_account(osv.osv):
|
|||
if method == 'write':
|
||||
raise osv.except_osv(_('Error !'), _('You can not desactivate an account that contains some journal items.'))
|
||||
elif method == 'unlink':
|
||||
raise osv.except_osv(_('Error !'), _('You can not remove an account containing journal items!. '))
|
||||
raise osv.except_osv(_('Error !'), _('You can not remove an account containing journal items.'))
|
||||
#Checking whether the account is set as a property to any Partner or not
|
||||
value = 'account.account,' + str(ids[0])
|
||||
partner_prop_acc = self.pool.get('ir.property').search(cr, uid, [('value_reference','=',value)], context=context)
|
||||
|
@ -660,7 +660,7 @@ class account_account(osv.osv):
|
|||
# Allow the write if the value is the same
|
||||
for i in [i['company_id'][0] for i in self.read(cr,uid,ids,['company_id'])]:
|
||||
if vals['company_id']!=i:
|
||||
raise osv.except_osv(_('Warning !'), _('You cannot modify Company of account as its related record exist in Entry Lines'))
|
||||
raise osv.except_osv(_('Warning !'), _('You cannot modify the company as its related to existing journal items.'))
|
||||
if 'active' in vals and not vals['active']:
|
||||
self._check_moves(cr, uid, ids, "write", context=context)
|
||||
if 'type' in vals.keys():
|
||||
|
@ -959,7 +959,7 @@ class account_fiscalyear(osv.osv):
|
|||
ids = self.search(cr, uid, args, context=context)
|
||||
if not ids:
|
||||
if exception:
|
||||
raise osv.except_osv(_('Error !'), _('No fiscal year defined for this date !\nPlease create one.'))
|
||||
raise osv.except_osv(_('Error !'), _('No fiscal year defined for this date !\nPlease create one from the configuration of the accounting menu.'))
|
||||
else:
|
||||
return []
|
||||
return ids
|
||||
|
|
|
@ -297,7 +297,7 @@ class account_bank_statement(osv.osv):
|
|||
context=context):
|
||||
if line.state <> 'valid':
|
||||
raise osv.except_osv(_('Error !'),
|
||||
_('Journal Item "%s" is not valid') % line.name)
|
||||
_('Journal item "%s" is not valid.') % line.name)
|
||||
|
||||
# Bank statements will not consider boolean on journal entry_posted
|
||||
account_move_obj.post(cr, uid, [move_id], context=context)
|
||||
|
@ -352,7 +352,7 @@ class account_bank_statement(osv.osv):
|
|||
for st_line in st.line_ids:
|
||||
if st_line.analytic_account_id:
|
||||
if not st.journal_id.analytic_journal_id:
|
||||
raise osv.except_osv(_('No Analytic Journal !'),_("You have to define an analytic journal on the '%s' journal!") % (st.journal_id.name,))
|
||||
raise osv.except_osv(_('No Analytic Journal !'),_("You have to assign an analytic journal on the '%s' journal!") % (st.journal_id.name,))
|
||||
if not st_line.amount:
|
||||
continue
|
||||
st_line_number = self.get_next_st_line_number(cr, uid, st_number, st_line, context)
|
||||
|
|
|
@ -311,7 +311,7 @@ class account_cash_statement(osv.osv):
|
|||
if journal_type == 'bank':
|
||||
return super(account_cash_statement, self).balance_check(cr, uid, cash_id, journal_type, context)
|
||||
if not self._equal_balance(cr, uid, cash_id, context):
|
||||
raise osv.except_osv(_('Error !'), _('The closing balance should be the same than the computed balance !'))
|
||||
raise osv.except_osv(_('Error !'), _('The closing balance should be the same than the computed balance!'))
|
||||
return True
|
||||
|
||||
def statement_close(self, cr, uid, ids, journal_type='bank', context=None):
|
||||
|
|
|
@ -68,7 +68,7 @@ class account_invoice(osv.osv):
|
|||
tt = type2journal.get(type_inv, 'sale')
|
||||
result = self.pool.get('account.analytic.journal').search(cr, uid, [('type','=',tt)], context=context)
|
||||
if not result:
|
||||
raise osv.except_osv(_('No Analytic Journal !'),_("You must define an analytic journal of type '%s' !") % (tt,))
|
||||
raise osv.except_osv(_('No Analytic Journal !'),_("You must define an analytic journal of type '%s'!") % (tt,))
|
||||
return result[0]
|
||||
|
||||
def _get_type(self, cr, uid, context=None):
|
||||
|
@ -261,7 +261,7 @@ class account_invoice(osv.osv):
|
|||
'partner_bank_id': fields.many2one('res.partner.bank', 'Bank Account',
|
||||
help='Bank Account Number, Company bank account if Invoice is customer or supplier refund, otherwise Partner bank account number.', readonly=True, states={'draft':[('readonly',False)]}),
|
||||
'move_lines':fields.function(_get_lines, type='many2many', relation='account.move.line', string='Entry Lines'),
|
||||
'residual': fields.function(_amount_residual, digits_compute=dp.get_precision('Account'), string='To Pay',
|
||||
'residual': fields.function(_amount_residual, digits_compute=dp.get_precision('Account'), string='Balance',
|
||||
store={
|
||||
'account.invoice': (lambda self, cr, uid, ids, c={}: ids, ['invoice_line','move_id'], 50),
|
||||
'account.invoice.tax': (_get_invoice_tax, None, 50),
|
||||
|
@ -414,7 +414,7 @@ class account_invoice(osv.osv):
|
|||
pay_res_id = pay_line_data and pay_line_data[0].get('value_reference',False) and int(pay_line_data[0]['value_reference'].split(',')[1]) or False
|
||||
if not rec_res_id and not pay_res_id:
|
||||
raise osv.except_osv(_('Configuration Error !'),
|
||||
_('Can not find account chart for this company, Please Create account.'))
|
||||
_('Can not find a chart of accounts for this company, you should create one.'))
|
||||
account_obj = self.pool.get('account.account')
|
||||
rec_obj_acc = account_obj.browse(cr, uid, [rec_res_id])
|
||||
pay_obj_acc = account_obj.browse(cr, uid, [pay_res_id])
|
||||
|
@ -481,7 +481,7 @@ class account_invoice(osv.osv):
|
|||
pterm_list.sort()
|
||||
res = {'value':{'date_due': pterm_list[-1]}}
|
||||
else:
|
||||
raise osv.except_osv(_('Data Insufficient !'), _('The Payment Term of Supplier does not have Payment Term Lines(Computation) defined !'))
|
||||
raise osv.except_osv(_('Data Insufficient !'), _('The payment term of supplier does not have a payment term line!'))
|
||||
return res
|
||||
|
||||
def onchange_invoice_line(self, cr, uid, ids, lines):
|
||||
|
@ -514,7 +514,7 @@ class account_invoice(osv.osv):
|
|||
pay_res_id = pay_line_data and pay_line_data[0].get('value_reference',False) and int(pay_line_data[0]['value_reference'].split(',')[1]) or False
|
||||
if not rec_res_id and not pay_res_id:
|
||||
raise osv.except_osv(_('Configuration Error !'),
|
||||
_('Can not find account chart for this company, Please Create account.'))
|
||||
_('Can not find a chart of account, you should create one from the configuration of the accounting menu.'))
|
||||
if type in ('out_invoice', 'out_refund'):
|
||||
acc_id = rec_res_id
|
||||
else:
|
||||
|
@ -529,7 +529,7 @@ class account_invoice(osv.osv):
|
|||
result_id = account_obj.search(cr, uid, [('name','=',line.account_id.name),('company_id','=',company_id)])
|
||||
if not result_id:
|
||||
raise osv.except_osv(_('Configuration Error !'),
|
||||
_('Can not find account chart for this company in invoice line account, Please Create account.'))
|
||||
_('Can not find a chart of account, you should create one from the configuration of the accounting menu.'))
|
||||
inv_line_obj.write(cr, uid, [line.id], {'account_id': result_id[-1]})
|
||||
else:
|
||||
if invoice_line:
|
||||
|
@ -730,13 +730,13 @@ class account_invoice(osv.osv):
|
|||
key = (tax.tax_code_id.id, tax.base_code_id.id, tax.account_id.id)
|
||||
tax_key.append(key)
|
||||
if not key in compute_taxes:
|
||||
raise osv.except_osv(_('Warning !'), _('Global taxes defined, but are not in invoice lines !'))
|
||||
raise osv.except_osv(_('Warning !'), _('Global taxes defined, but they are not in invoice lines !'))
|
||||
base = compute_taxes[key]['base']
|
||||
if abs(base - tax.base) > inv.company_id.currency_id.rounding:
|
||||
raise osv.except_osv(_('Warning !'), _('Tax base different !\nClick on compute to update tax base'))
|
||||
raise osv.except_osv(_('Warning !'), _('Tax base different!\nClick on compute to update the tax base.'))
|
||||
for key in compute_taxes:
|
||||
if not key in tax_key:
|
||||
raise osv.except_osv(_('Warning !'), _('Taxes missing !'))
|
||||
raise osv.except_osv(_('Warning !'), _('Taxes are missing!\nClick on compute button.'))
|
||||
|
||||
def compute_invoice_totals(self, cr, uid, inv, company_currency, ref, invoice_move_lines):
|
||||
total = 0
|
||||
|
@ -802,7 +802,7 @@ class account_invoice(osv.osv):
|
|||
context = {}
|
||||
for inv in self.browse(cr, uid, ids):
|
||||
if not inv.journal_id.sequence_id:
|
||||
raise osv.except_osv(_('Error !'), _('Please define sequence on invoice journal'))
|
||||
raise osv.except_osv(_('Error !'), _('Please define sequence on the journal related to this invoice.'))
|
||||
if not inv.invoice_line:
|
||||
raise osv.except_osv(_('No Invoice Lines !'), _('Please create some invoice lines.'))
|
||||
if inv.move_id:
|
||||
|
@ -832,7 +832,7 @@ class account_invoice(osv.osv):
|
|||
total_percent += line.value_amount
|
||||
total_fixed = (total_fixed * 100) / (inv.amount_total or 1.0)
|
||||
if (total_fixed + total_percent) > 100:
|
||||
raise osv.except_osv(_('Error !'), _("Can not create the invoice !\nThe related payment term is probably misconfigured as it gives a computed amount greater than the total invoiced amount."))
|
||||
raise osv.except_osv(_('Error !'), _("Can not create the invoice !\nThe related payment term is probably misconfigured as it gives a computed amount greater than the total invoiced amount. The latest line of your payment term must be of type 'balance' to avoid rounding issues."))
|
||||
|
||||
# one move line per tax line
|
||||
iml += ait_obj.move_line_get(cr, uid, inv.id)
|
||||
|
|
|
@ -94,7 +94,7 @@ class account_move_line(osv.osv):
|
|||
if initial_bal and not context.get('periods', False) and not where_move_lines_by_date:
|
||||
#we didn't pass any filter in the context, and the initial balance can't be computed using only the fiscalyear otherwise entries will be summed twice
|
||||
#so we have to invalidate this query
|
||||
raise osv.except_osv(_('Warning !'),_("You haven't supplied enough argument to compute the initial balance"))
|
||||
raise osv.except_osv(_('Warning !'),_("You haven't supplied enough argument to compute the initial balance, please select a period and journal in the context."))
|
||||
|
||||
|
||||
if context.get('journal_ids', False):
|
||||
|
@ -581,14 +581,14 @@ class account_move_line(osv.osv):
|
|||
lines = self.browse(cr, uid, ids, context=context)
|
||||
for l in lines:
|
||||
if l.account_id.type == 'view':
|
||||
raise osv.except_osv(_('Error :'), _('You can not create move line on view account %s %s') % (l.account_id.code, l.account_id.name))
|
||||
raise osv.except_osv(_('Error :'), _('You can not create journal items on a "view" account %s %s') % (l.account_id.code, l.account_id.name))
|
||||
return True
|
||||
|
||||
def _check_no_closed(self, cr, uid, ids, context=None):
|
||||
lines = self.browse(cr, uid, ids, context=context)
|
||||
for l in lines:
|
||||
if l.account_id.type == 'closed':
|
||||
raise osv.except_osv(_('Error :'), _('You can not create move line on closed account %s %s') % (l.account_id.code, l.account_id.name))
|
||||
raise osv.except_osv(_('Error :'), _('You can not create journal items on a closed account %s %s') % (l.account_id.code, l.account_id.name))
|
||||
return True
|
||||
|
||||
def _check_company_id(self, cr, uid, ids, context=None):
|
||||
|
@ -613,11 +613,11 @@ class account_move_line(osv.osv):
|
|||
return True
|
||||
|
||||
_constraints = [
|
||||
(_check_no_view, 'You can not create move line on view account.', ['account_id']),
|
||||
(_check_no_closed, 'You can not create move line on closed account.', ['account_id']),
|
||||
(_check_company_id, 'Company must be same for its related account and period.', ['company_id']),
|
||||
(_check_date, 'The date of your Journal Entry is not in the defined period!', ['date']),
|
||||
(_check_currency, 'The selected account of your Journal Entry must receive a value in its secondary currency', ['currency_id']),
|
||||
(_check_no_view, 'You can not create journal items on an account of type view.', ['account_id']),
|
||||
(_check_no_closed, 'You can not create journal items on closed account.', ['account_id']),
|
||||
(_check_company_id, 'Company must be the same for its related account and period.', ['company_id']),
|
||||
(_check_date, 'The date of your Journal Entry is not in the defined period! You should change the date or remove this constraint from the journal.', ['date']),
|
||||
(_check_currency, 'The selected account of your Journal Entry forces to provide a secondary currency. You should remove the secondary currency on the account or select a multi-currency view on the journal.', ['currency_id']),
|
||||
]
|
||||
|
||||
#TODO: ONCHANGE_ACCOUNT_ID: set account_tax_id
|
||||
|
@ -832,7 +832,7 @@ class account_move_line(osv.osv):
|
|||
raise osv.except_osv(_('Error'), _('Entry is already reconciled'))
|
||||
account = account_obj.browse(cr, uid, account_id, context=context)
|
||||
if not context.get('fy_closing', False) and not account.reconcile:
|
||||
raise osv.except_osv(_('Error'), _('The account is not defined to be reconciled !'))
|
||||
raise osv.except_osv(_('Error'), _('This account does not allow reconciliation! You should update the account definition to change this.'))
|
||||
if r[0][1] != None:
|
||||
raise osv.except_osv(_('Error'), _('Some entries are already reconciled !'))
|
||||
|
||||
|
@ -1212,9 +1212,9 @@ class account_move_line(osv.osv):
|
|||
for line in self.browse(cr, uid, ids, context=context):
|
||||
err_msg = _('Move name (id): %s (%s)') % (line.move_id.name, str(line.move_id.id))
|
||||
if line.move_id.state <> 'draft' and (not line.journal_id.entry_posted):
|
||||
raise osv.except_osv(_('Error !'), _('You can not do this modification on a confirmed entry ! Please note that you can just change some non important fields ! \n%s') % err_msg)
|
||||
raise osv.except_osv(_('Error !'), _('You can not do this modification on a confirmed entry! You can just change some non legal fields or you must unconfirm the journal entry first! \n%s') % err_msg)
|
||||
if line.reconcile_id:
|
||||
raise osv.except_osv(_('Error !'), _('You can not do this modification on a reconciled entry ! Please note that you can just change some non important fields ! \n%s') % err_msg)
|
||||
raise osv.except_osv(_('Error !'), _('You can not do this modification on a reconciled entry! You can just change some non legal fields or you must unreconcile first!\n%s') % err_msg)
|
||||
t = (line.journal_id.id, line.period_id.id)
|
||||
if t not in done:
|
||||
self._update_journal_check(cr, uid, line.journal_id.id, line.period_id.id, context)
|
||||
|
@ -1247,7 +1247,7 @@ class account_move_line(osv.osv):
|
|||
if 'period_id' not in context or not isinstance(context.get('period_id', ''), (int, long)):
|
||||
period_candidate_ids = self.pool.get('account.period').name_search(cr, uid, name=context.get('period_id',''))
|
||||
if len(period_candidate_ids) != 1:
|
||||
raise osv.except_osv(_('Encoding error'), _('No period found or period given is ambigous.'))
|
||||
raise osv.except_osv(_('Encoding error'), _('No period found or more than one period found for the given date.'))
|
||||
context['period_id'] = period_candidate_ids[0][0]
|
||||
if not context.get('journal_id', False) and context.get('search_default_journal_id', False):
|
||||
context['journal_id'] = context.get('search_default_journal_id')
|
||||
|
|
|
@ -116,7 +116,7 @@ class crossovered_budget_lines(osv.osv):
|
|||
for line in self.browse(cr, uid, ids, context=context):
|
||||
acc_ids = [x.id for x in line.general_budget_id.account_ids]
|
||||
if not acc_ids:
|
||||
raise osv.except_osv(_('Error!'),_("The General Budget '%s' has no Accounts!") % str(line.general_budget_id.name))
|
||||
raise osv.except_osv(_('Error!'),_("The Budget '%s' has no accounts!") % str(line.general_budget_id.name))
|
||||
date_to = line.date_to
|
||||
date_from = line.date_from
|
||||
if context.has_key('wizard_date_from'):
|
||||
|
|
|
@ -441,7 +441,7 @@ class account_voucher(osv.osv):
|
|||
tr_type = 'purchase'
|
||||
else:
|
||||
if not journal.default_credit_account_id or not journal.default_debit_account_id:
|
||||
raise osv.except_osv(_('Error !'), _('Please define default credit/debit account on the %s !') % (journal.name))
|
||||
raise osv.except_osv(_('Error !'), _('Please define default credit/debit accounts on the journal "%s" !') % (journal.name))
|
||||
account_id = journal.default_credit_account_id.id or journal.default_debit_account_id.id
|
||||
tr_type = 'receipt'
|
||||
|
||||
|
|
|
@ -427,7 +427,7 @@ class crm_case(crm_base):
|
|||
if case.section_id.parent_id.user_id:
|
||||
data['user_id'] = case.section_id.parent_id.user_id.id
|
||||
else:
|
||||
raise osv.except_osv(_('Error !'), _('You can not escalate, You are already at the top level regarding your sales-team category.'))
|
||||
raise osv.except_osv(_('Error !'), _('You can not escalate, you are already at the top level regarding your sales-team category.'))
|
||||
self.write(cr, uid, [case.id], data)
|
||||
cases = self.browse(cr, uid, ids)
|
||||
self.message_append(cr, uid, cases, _('Escalate'))
|
||||
|
|
|
@ -194,7 +194,7 @@ class crm_lead(crm_case, osv.osv):
|
|||
|
||||
|
||||
# Only used for type opportunity
|
||||
'partner_address_id': fields.many2one('res.partner.address', 'Partner Contact', domain="[('partner_id','=',partner_id)]"),
|
||||
'partner_address_id': fields.many2one('res.partner.address', 'Partner Contact', domain="[('partner_id','=',partner_id)]"),
|
||||
'probability': fields.float('Probability (%)',group_operator="avg"),
|
||||
'planned_revenue': fields.float('Expected Revenue'),
|
||||
'ref': fields.reference('Reference', selection=crm._links_get, size=128),
|
||||
|
@ -352,7 +352,7 @@ class crm_lead(crm_case, osv.osv):
|
|||
"""
|
||||
return self.set_priority(cr, uid, ids, '3')
|
||||
|
||||
|
||||
|
||||
def _merge_data(self, cr, uid, ids, oldest, fields, context=None):
|
||||
# prepare opportunity data into dictionary for merging
|
||||
opportunities = self.browse(cr, uid, ids, context=context)
|
||||
|
@ -367,7 +367,7 @@ class crm_lead(crm_case, osv.osv):
|
|||
def _get_first_not_null_id(attr):
|
||||
res = _get_first_not_null(attr)
|
||||
return res and res.id or False
|
||||
|
||||
|
||||
def _concat_all(attr):
|
||||
return ', '.join(filter(lambda x: x, [getattr(opportunity, attr) or '' for opportunity in opportunities if hasattr(opportunity, attr)]))
|
||||
|
||||
|
@ -378,7 +378,7 @@ class crm_lead(crm_case, osv.osv):
|
|||
continue
|
||||
field = field_info.column
|
||||
if field._type in ('many2many', 'one2many'):
|
||||
continue
|
||||
continue
|
||||
elif field._type == 'many2one':
|
||||
data[field_name] = _get_first_not_null_id(field_name) # !!
|
||||
elif field._type == 'text':
|
||||
|
@ -437,18 +437,18 @@ class crm_lead(crm_case, osv.osv):
|
|||
subject.append(opportunity.name)
|
||||
title = "%s : %s" % (merge_message, opportunity.name)
|
||||
details.append(self._mail_body_text(cr, uid, opportunity, fields, title=title, context=context))
|
||||
|
||||
|
||||
subject = subject[0] + ", ".join(subject[1:])
|
||||
details = "\n\n".join(details)
|
||||
return self.message_append(cr, uid, [opportunity_id], subject, body_text=details, context=context)
|
||||
|
||||
|
||||
def _merge_opportunity_history(self, cr, uid, opportunity_id, opportunities, context=None):
|
||||
message = self.pool.get('mail.message')
|
||||
for opportunity in opportunities:
|
||||
for history in opportunity.message_ids:
|
||||
message.write(cr, uid, history.id, {
|
||||
'res_id': opportunity_id,
|
||||
'subject' : _("From %s : %s") % (opportunity.name, history.subject)
|
||||
'res_id': opportunity_id,
|
||||
'subject' : _("From %s : %s") % (opportunity.name, history.subject)
|
||||
}, context=context)
|
||||
|
||||
return True
|
||||
|
@ -474,8 +474,8 @@ class crm_lead(crm_case, osv.osv):
|
|||
)
|
||||
attachment.write(values)
|
||||
count+=1
|
||||
|
||||
return True
|
||||
|
||||
return True
|
||||
|
||||
def merge_opportunity(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
|
@ -483,12 +483,12 @@ class crm_lead(crm_case, osv.osv):
|
|||
:param ids: list of opportunities ids to merge
|
||||
"""
|
||||
if context is None: context = {}
|
||||
|
||||
|
||||
#TOCHECK: where pass lead_ids in context?
|
||||
lead_ids = context and context.get('lead_ids', []) or []
|
||||
|
||||
if len(ids) <= 1:
|
||||
raise osv.except_osv(_('Warning !'),_('Please select more than one opportunities.'))
|
||||
raise osv.except_osv(_('Warning !'),_('Please select more than one opportunity from the list view.'))
|
||||
|
||||
ctx_opportunities = self.browse(cr, uid, lead_ids, context=context)
|
||||
opportunities = self.browse(cr, uid, ids, context=context)
|
||||
|
@ -501,11 +501,11 @@ class crm_lead(crm_case, osv.osv):
|
|||
first_opportunity = opportunities_list[0]
|
||||
tail_opportunities = opportunities_list[1:]
|
||||
|
||||
fields = ['partner_id', 'title', 'name', 'categ_id', 'channel_id', 'city', 'company_id', 'contact_name', 'country_id',
|
||||
fields = ['partner_id', 'title', 'name', 'categ_id', 'channel_id', 'city', 'company_id', 'contact_name', 'country_id',
|
||||
'partner_address_id', 'type_id', 'user_id', 'section_id', 'state_id', 'description', 'email', 'fax', 'mobile',
|
||||
'partner_name', 'phone', 'probability', 'planned_revenue', 'street', 'street2', 'zip', 'create_date', 'date_action_last',
|
||||
'date_action_next', 'email_from', 'email_cc', 'partner_name']
|
||||
|
||||
|
||||
data = self._merge_data(cr, uid, ids, oldest, fields, context=context)
|
||||
|
||||
# merge data into first opportunity
|
||||
|
@ -513,8 +513,8 @@ class crm_lead(crm_case, osv.osv):
|
|||
|
||||
#copy message and attachements into the first opportunity
|
||||
self._merge_opportunity_history(cr, uid, first_opportunity.id, tail_opportunities, context=context)
|
||||
self._merge_opportunity_attachments(cr, uid, first_opportunity.id, tail_opportunities, context=context)
|
||||
|
||||
self._merge_opportunity_attachments(cr, uid, first_opportunity.id, tail_opportunities, context=context)
|
||||
|
||||
#Notification about loss of information
|
||||
self._merge_notification(cr, uid, first_opportunity, opportunities, context=context)
|
||||
#delete tail opportunities
|
||||
|
@ -534,7 +534,7 @@ class crm_lead(crm_case, osv.osv):
|
|||
if section_id:
|
||||
stage_ids = crm_stage.search(cr, uid, [('sequence','>=',1), ('section_ids','=', section_id)])
|
||||
else:
|
||||
stage_ids = crm_stage.search(cr, uid, [('sequence','>=',1)])
|
||||
stage_ids = crm_stage.search(cr, uid, [('sequence','>=',1)])
|
||||
stage_id = stage_ids and stage_ids[0] or False
|
||||
return {
|
||||
'planned_revenue': lead.planned_revenue,
|
||||
|
@ -565,10 +565,10 @@ class crm_lead(crm_case, osv.osv):
|
|||
continue
|
||||
if user_ids or section_id:
|
||||
self.allocate_salesman(cr, uid, [lead.id], user_ids, section_id, context=context)
|
||||
|
||||
|
||||
vals = self._convert_opportunity_data(cr, uid, lead, customer, section_id, context=context)
|
||||
self.write(cr, uid, [lead.id], vals, context=context)
|
||||
|
||||
|
||||
self._convert_opportunity_notification(cr, uid, lead, context=context)
|
||||
#TOCHECK: why need to change partner details in all messages of lead ?
|
||||
if lead.partner_id:
|
||||
|
@ -596,7 +596,7 @@ class crm_lead(crm_case, osv.osv):
|
|||
res_partner.write(cr, uid, partner_id, {'section_id': lead.section_id.id or False})
|
||||
contact_id = res_partner.address_get(cr, uid, [partner_id])['default']
|
||||
res = lead.write({'partner_id' : partner_id, 'partner_address_id': contact_id}, context=context)
|
||||
|
||||
|
||||
return res
|
||||
|
||||
def _lead_create_partner_address(self, cr, uid, lead, partner_id, context=None):
|
||||
|
@ -628,7 +628,7 @@ class crm_lead(crm_case, osv.osv):
|
|||
context = {}
|
||||
partner_ids = {}
|
||||
for lead in self.browse(cr, uid, ids, context=context):
|
||||
if action == 'create':
|
||||
if action == 'create':
|
||||
if not partner_id:
|
||||
partner_id = self._lead_create_partner(cr, uid, lead, context=context)
|
||||
self._lead_create_partner_address(cr, uid, lead, partner_id, context=context)
|
||||
|
@ -641,12 +641,12 @@ class crm_lead(crm_case, osv.osv):
|
|||
Send mail to salesman with updated Lead details.
|
||||
@ lead: browse record of 'crm.lead' object.
|
||||
"""
|
||||
#TOFIX: mail template should be used here instead of fix subject, body text.
|
||||
#TOFIX: mail template should be used here instead of fix subject, body text.
|
||||
message = self.pool.get('mail.message')
|
||||
email_to = lead.user_id and lead.user_id.user_email
|
||||
if not email_to:
|
||||
return False
|
||||
|
||||
|
||||
email_from = lead.section_id and lead.section_id.user_id and lead.section_id.user_id.user_email or email_to
|
||||
partner = lead.partner_id and lead.partner_id.name or lead.partner_name
|
||||
subject = "lead %s converted into opportunity" % lead.name
|
||||
|
@ -697,7 +697,7 @@ class crm_lead(crm_case, osv.osv):
|
|||
'partner_mobile' : lead.partner_address_id and lead.partner_address_id.mobile or False,
|
||||
'priority': lead.priority,
|
||||
}
|
||||
|
||||
|
||||
new_id = phonecall.create(cr, uid, vals, context=context)
|
||||
phonecall.case_open(cr, uid, [new_id])
|
||||
if action == 'log':
|
||||
|
@ -799,10 +799,10 @@ class crm_lead(crm_case, osv.osv):
|
|||
context.update({
|
||||
'default_opportunity_id': opp.id,
|
||||
'default_partner_id': opp.partner_id and opp.partner_id.id or False,
|
||||
'default_user_id': uid,
|
||||
'default_user_id': uid,
|
||||
'default_section_id': opp.section_id and opp.section_id.id or False,
|
||||
'default_email_from': opp.email_from,
|
||||
'default_state': 'open',
|
||||
'default_state': 'open',
|
||||
'default_name': opp.name
|
||||
})
|
||||
value = {
|
||||
|
|
|
@ -212,7 +212,7 @@ class delivery_grid(osv.osv):
|
|||
ok = True
|
||||
break
|
||||
if not ok:
|
||||
raise osv.except_osv(_('No price available !'), _('No line matched this order in the choosed delivery grids !'))
|
||||
raise osv.except_osv(_('No price available!'), _('No line matched this product or order in the choosed delivery grid.'))
|
||||
|
||||
return price
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
|
@ -15,7 +15,7 @@
|
|||
# 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 <http://www.gnu.org/licenses/>.
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
import logging
|
||||
|
@ -29,20 +29,20 @@ class NhException(Exception):
|
|||
|
||||
class indexer(object):
|
||||
""" An indexer knows how to parse the content of some file.
|
||||
|
||||
|
||||
Typically, one indexer should be instantiated per file
|
||||
type.
|
||||
Override this class to add more functionality. Note that
|
||||
you should only override the Content or the File methods
|
||||
that give an optimal result. """
|
||||
|
||||
|
||||
def _getMimeTypes(self):
|
||||
""" Return supported mimetypes """
|
||||
return []
|
||||
|
||||
|
||||
def _getExtensions(self):
|
||||
return []
|
||||
|
||||
|
||||
def _getDefMime(self, ext):
|
||||
""" Return a mimetype for this document type, ideally the
|
||||
closest to the extension ext. """
|
||||
|
@ -63,23 +63,23 @@ class indexer(object):
|
|||
return self._doIndexContent(content)
|
||||
except NhException:
|
||||
pass
|
||||
|
||||
|
||||
if realfile != None:
|
||||
try:
|
||||
return self._doIndexFile(realfile)
|
||||
except NhException:
|
||||
pass
|
||||
|
||||
|
||||
fp = open(realfile,'rb')
|
||||
try:
|
||||
content2 = fp.read()
|
||||
finally:
|
||||
finally:
|
||||
fp.close()
|
||||
|
||||
|
||||
# The not-handled exception may be raised here
|
||||
return self._doIndexContent(content2)
|
||||
|
||||
|
||||
|
||||
|
||||
# last try, with a tmp file
|
||||
if content:
|
||||
try:
|
||||
|
@ -94,7 +94,7 @@ class indexer(object):
|
|||
pass
|
||||
|
||||
raise NhException('No appropriate method to index file')
|
||||
|
||||
|
||||
def _doIndexContent(self,content):
|
||||
raise NhException("Content not handled here")
|
||||
|
||||
|
@ -103,7 +103,7 @@ class indexer(object):
|
|||
|
||||
def __repr__(self):
|
||||
return "<indexer %s.%s>" %(self.__module__, self.__class__.__name__)
|
||||
|
||||
|
||||
|
||||
def mime_match(mime, mdict):
|
||||
if mdict.has_key(mime):
|
||||
|
@ -112,7 +112,7 @@ def mime_match(mime, mdict):
|
|||
mpat = mime.split('/')[0]+'/*'
|
||||
if mdict.has_key(mpat):
|
||||
return (mime, mdict[mpat])
|
||||
|
||||
|
||||
return (None, None)
|
||||
|
||||
class contentIndex(object):
|
||||
|
@ -120,22 +120,22 @@ class contentIndex(object):
|
|||
def __init__(self):
|
||||
self.mimes = {}
|
||||
self.exts = {}
|
||||
|
||||
|
||||
def register(self, obj):
|
||||
f = False
|
||||
for mime in obj._getMimeTypes():
|
||||
self.mimes[mime] = obj
|
||||
f = True
|
||||
|
||||
|
||||
for ext in obj._getExtensions():
|
||||
self.exts[ext] = obj
|
||||
f = True
|
||||
|
||||
|
||||
if f:
|
||||
self.__logger.debug('Register content indexer: %r', obj)
|
||||
if not f:
|
||||
raise Exception("Your indexer should at least suport a mimetype or extension")
|
||||
|
||||
|
||||
def doIndex(self, content, filename=None, content_type=None, realfname = None, debug=False):
|
||||
fobj = None
|
||||
fname = None
|
||||
|
@ -148,10 +148,10 @@ class contentIndex(object):
|
|||
if self.exts.has_key(ext):
|
||||
fobj = self.exts[ext]
|
||||
mime = fobj._getDefMime(ext)
|
||||
|
||||
|
||||
if content_type and not fobj:
|
||||
mime,fobj = mime_match(content_type, self.mimes)
|
||||
|
||||
|
||||
if not fobj:
|
||||
try:
|
||||
if realfname :
|
||||
|
@ -164,10 +164,10 @@ class contentIndex(object):
|
|||
fd, fname = tempfile.mkstemp(suffix=ext)
|
||||
os.write(fd, content)
|
||||
os.close(fd)
|
||||
|
||||
|
||||
pop = Popen(['file','-b','--mime',fname], shell=False, stdout=PIPE)
|
||||
(result, _) = pop.communicate()
|
||||
|
||||
|
||||
mime2 = result.split(';')[0]
|
||||
self.__logger.debug('File gave us: %s', mime2)
|
||||
# Note that the temporary file still exists now.
|
||||
|
@ -176,7 +176,7 @@ class contentIndex(object):
|
|||
mime = mime2
|
||||
except Exception:
|
||||
self.__logger.exception('Cannot determine mime type')
|
||||
|
||||
|
||||
try:
|
||||
if fobj:
|
||||
res = (mime, fobj.indexContent(content,filename,fname or realfname) )
|
||||
|
@ -187,14 +187,14 @@ class contentIndex(object):
|
|||
self.__logger.exception("Could not index file %s (%s)",
|
||||
filename, fname or realfname)
|
||||
res = None
|
||||
|
||||
|
||||
# If we created a tmp file, unlink it now
|
||||
if not realfname and fname:
|
||||
try:
|
||||
os.unlink(fname)
|
||||
except Exception:
|
||||
self.__logger.exception("Could not unlink %s", fname)
|
||||
|
||||
|
||||
return res
|
||||
|
||||
cntIndex = contentIndex()
|
||||
|
|
|
@ -214,7 +214,7 @@ class email_template(osv.osv):
|
|||
ir_values_obj = self.pool.get('ir.values')
|
||||
ir_values_obj.unlink(cr, uid, template.ref_ir_value.id, context)
|
||||
except:
|
||||
raise osv.except_osv(_("Warning"), _("Deletion of Record failed"))
|
||||
raise osv.except_osv(_("Warning"), _("Deletion of the action record failed."))
|
||||
return True
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
|
|
|
@ -433,9 +433,8 @@ class hr_applicant(crm.crm_case, osv.osv):
|
|||
})
|
||||
self.case_close(cr, uid, [applicant.id], *args)
|
||||
else:
|
||||
raise osv.except_osv(_('Warning!'),_('You must define Applied Job for Applicant !'))
|
||||
raise osv.except_osv(_('Warning!'),_('You must define Applied Job for this applicant.'))
|
||||
|
||||
|
||||
action_model, action_id = model_data.get_object_reference(cr, uid, 'hr', 'open_view_employee_list')
|
||||
dict_act_window = act_window.read(cr, uid, action_id, [])
|
||||
if emp_id:
|
||||
|
|
|
@ -271,7 +271,7 @@ class idea_idea(osv.osv):
|
|||
|
||||
if vals.get('my_vote', False):
|
||||
if vals.get('state', state) != 'open':
|
||||
raise osv.except_osv(_("Warning !"), _("Draft/Accepted/Cancelled ideas Could not be voted"))
|
||||
raise osv.except_osv(_("Warning !"), _("You can not vote on a Draft/Accepted/Cancelled ideas."))
|
||||
|
||||
res = super(idea_idea, self).write(cr, user, ids, vals, context=context)
|
||||
return res
|
||||
|
|
|
@ -42,12 +42,12 @@ class import_framework(Thread):
|
|||
for advanced purpose get_default_hook can also be extended
|
||||
@see dummy import for a minimal exemple
|
||||
"""
|
||||
|
||||
|
||||
"""
|
||||
for import_object, this domain will avoid to find an already existing object
|
||||
"""
|
||||
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)
|
||||
|
@ -64,34 +64,34 @@ class import_framework(Thread):
|
|||
self.initialize()
|
||||
|
||||
"""
|
||||
Abstract Method to be implemented in
|
||||
Abstract Method to be implemented in
|
||||
the real instance
|
||||
"""
|
||||
"""
|
||||
def initialize(self):
|
||||
"""
|
||||
init before import
|
||||
usually for the login
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def init_run(self):
|
||||
"""
|
||||
call after intialize run in the thread, not in the main process
|
||||
TO use for long initialization operation
|
||||
TO use for long initialization operation
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def get_data(self, table):
|
||||
"""
|
||||
@return: a list of dictionaries
|
||||
each dictionnaries contains the list of pair external_field_name : value
|
||||
each dictionnaries contains the list of pair external_field_name : value
|
||||
"""
|
||||
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: a dictionaries that contains the association between the id (from_table)
|
||||
and the list (to table) of id linked
|
||||
"""
|
||||
return {}
|
||||
|
||||
|
@ -103,14 +103,14 @@ class import_framework(Thread):
|
|||
of self.external_id_field
|
||||
"""
|
||||
return data[self.external_id_field]
|
||||
|
||||
|
||||
def get_mapping(self):
|
||||
"""
|
||||
@return: { TABLE_NAME : {
|
||||
'model' : 'openerp.model.name',
|
||||
#if true import the table if not just resolve dependencies, use for meta package, by default => True
|
||||
#if true import the table if not just resolve dependencies, use for meta package, by default => True
|
||||
#Not required
|
||||
'import' : True or False,
|
||||
'import' : True or False,
|
||||
#Not required
|
||||
'dependencies' : [TABLE_1, TABLE_2],
|
||||
#Not required
|
||||
|
@ -127,40 +127,40 @@ class import_framework(Thread):
|
|||
'field' : call(method, val('external_field') interface of method is self, val where val is the value of the field
|
||||
'field' : const(value) #always set this field to value
|
||||
+ any custom mapper that you will define
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
"""
|
||||
return {}
|
||||
|
||||
|
||||
def default_hook(self, val):
|
||||
"""
|
||||
this hook will be apply on each table that don't have hook
|
||||
here we define the identity hook
|
||||
"""
|
||||
return val
|
||||
|
||||
|
||||
def _import_table(self, table):
|
||||
data = self.get_data(table)
|
||||
map = self.get_mapping()[table]['map']
|
||||
hook = self.get_mapping()[table].get('hook', self.default_hook)
|
||||
model = self.get_mapping()[table]['model']
|
||||
|
||||
|
||||
final_data = []
|
||||
for val in data:
|
||||
res = hook(val)
|
||||
if res:
|
||||
final_data.append(res)
|
||||
return self._save_data(model, dict(map), final_data, table)
|
||||
|
||||
|
||||
def _save_data(self, model, mapping, datas, table):
|
||||
"""
|
||||
@param model: the model of the object to import
|
||||
@param table : the external table where the data come from
|
||||
@param table : the external table where the data come from
|
||||
@param mapping : definition of the mapping
|
||||
@see: get_mapping
|
||||
@param datas : list of dictionnaries
|
||||
@param datas : list of dictionnaries
|
||||
datas = [data_1, data_2, ..]
|
||||
data_i is a map external field_name => value
|
||||
and each data_i have a external id => in data_id['id']
|
||||
|
@ -170,21 +170,21 @@ class import_framework(Thread):
|
|||
return (0, 'No data found')
|
||||
mapping['id'] = 'id_new'
|
||||
res = []
|
||||
|
||||
|
||||
|
||||
|
||||
self_dependencies = []
|
||||
for k in mapping.keys():
|
||||
if '_parent' in k:
|
||||
self_dependencies.append((k[:-7], mapping.pop(k)))
|
||||
|
||||
|
||||
for data in datas:
|
||||
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(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)
|
||||
|
@ -193,13 +193,13 @@ class import_framework(Thread):
|
|||
for (field, field_name) in self_dependencies:
|
||||
self._import_self_dependencies(model_obj, field, datas)
|
||||
return (len(res), warning)
|
||||
|
||||
|
||||
def _import_self_dependencies(self, obj, parent_field, datas):
|
||||
"""
|
||||
@param parent_field: the name of the field that generate a self_dependencies, we call the object referenced in this
|
||||
field the parent of the object
|
||||
@param datas: a list of dictionnaries
|
||||
Dictionnaries need to contains
|
||||
Dictionnaries need to contains
|
||||
id_new : the xml_id of the object
|
||||
field_new : the xml_id of the parent
|
||||
"""
|
||||
|
@ -207,14 +207,14 @@ class import_framework(Thread):
|
|||
for data in datas:
|
||||
if data.get(parent_field):
|
||||
values = [data['id_new'], data[parent_field]]
|
||||
obj.import_data(self.cr, self.uid, fields, [values], mode='update', current_module=self.module_name, noupdate=True, context=self.context)
|
||||
|
||||
obj.import_data(self.cr, self.uid, fields, [values], mode='update', current_module=self.module_name, noupdate=True, context=self.context)
|
||||
|
||||
def _preprocess_mapping(self, mapping):
|
||||
"""
|
||||
Preprocess the mapping :
|
||||
after the preprocces, everything is
|
||||
after the preprocces, everything is
|
||||
callable in the val of the dictionary
|
||||
|
||||
|
||||
use to allow syntaxical sugar like 'field': 'external_field'
|
||||
instead of 'field' : value('external_field')
|
||||
"""
|
||||
|
@ -223,14 +223,14 @@ class import_framework(Thread):
|
|||
if isinstance(value, basestring):
|
||||
map[key] = mapper.value(value)
|
||||
#set parent for instance of dbmapper
|
||||
elif isinstance(value, mapper.dbmapper):
|
||||
elif isinstance(value, mapper.dbmapper):
|
||||
value.set_parent(self)
|
||||
return map
|
||||
|
||||
|
||||
return map
|
||||
|
||||
|
||||
def _fields_mapp(self,dict_sugar, openerp_dict, table):
|
||||
"""
|
||||
call all the mapper and transform data
|
||||
call all the mapper and transform data
|
||||
to be compatible with import_data
|
||||
"""
|
||||
fields=[]
|
||||
|
@ -242,7 +242,7 @@ class import_framework(Thread):
|
|||
value = val(dict(dict_sugar))
|
||||
data_lst.append(value)
|
||||
return fields, data_lst
|
||||
|
||||
|
||||
def _generate_xml_id(self, name, table):
|
||||
"""
|
||||
@param name: name of the object, has to be unique in for a given table
|
||||
|
@ -253,8 +253,8 @@ class import_framework(Thread):
|
|||
sugar_instance = self.instance_name
|
||||
name = name.replace('.', '_').replace(',', '_')
|
||||
return sugar_instance + "_" + table + "_" + name
|
||||
|
||||
|
||||
|
||||
|
||||
"""
|
||||
Public interface of the framework
|
||||
those function can be use in the callable function defined in the mapping
|
||||
|
@ -268,11 +268,11 @@ class import_framework(Thread):
|
|||
"""
|
||||
if not external_id:
|
||||
return False
|
||||
|
||||
|
||||
xml_id = self._generate_xml_id(external_id, table)
|
||||
id = self.obj.pool.get('ir.model.data').search(self.cr, self.uid, [('name', '=', xml_id), ('module', '=', self.module_name)])
|
||||
return id and xml_id or False
|
||||
|
||||
|
||||
def name_exist(self, table, name, model):
|
||||
"""
|
||||
Check if the object with the name exist in the openerp database
|
||||
|
@ -282,21 +282,21 @@ class import_framework(Thread):
|
|||
fields = ['name']
|
||||
data = [name]
|
||||
return self.import_object(fields, data, model, table, name, [('name', '=', name)])
|
||||
|
||||
|
||||
def get_mapped_id(self, table, external_id, context=None):
|
||||
"""
|
||||
@return return the databse id linked with the external_id
|
||||
"""
|
||||
if not external_id:
|
||||
return False
|
||||
|
||||
|
||||
xml_id = self._generate_xml_id(external_id, table)
|
||||
return self.obj.pool.get('ir.model.data').get_object_reference(self.cr, self.uid, self.module_name, xml_id)[1]
|
||||
|
||||
|
||||
def import_object_mapping(self, mapping, data, model, table, name, domain_search=False):
|
||||
"""
|
||||
same as import_objects but instead of two list fields and data,
|
||||
this method take a dictionnaries : external_field : value
|
||||
same as import_objects but instead of two list fields and data,
|
||||
this method take a dictionnaries : external_field : value
|
||||
and the mapping similar to the one define in 'map' key
|
||||
@see import_object, get_mapping
|
||||
"""
|
||||
|
@ -308,7 +308,7 @@ class import_framework(Thread):
|
|||
This method will import an object in the openerp, usefull for field that is only a char in sugar and is an object in openerp
|
||||
use import_data that will take care to create/update or do nothing with the data
|
||||
this method return the xml_id
|
||||
|
||||
|
||||
To be use, when you want to create an object or link if already exist
|
||||
use DO_NOT_LINK_DOMAIN to create always a new object
|
||||
@param fields: list of fields needed to create the object without id
|
||||
|
@ -318,21 +318,21 @@ class import_framework(Thread):
|
|||
@param table: the table where data come from in sugarcrm, no need to fit the real name of openerp name, just need to be unique
|
||||
@param unique_name: the name of the object that we want to create/update get the id
|
||||
@param domain_search : the domain that should find the unique existing record
|
||||
|
||||
|
||||
@return: the xml_id of the ressources
|
||||
"""
|
||||
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
|
||||
|
||||
|
||||
|
||||
def mapped_id_if_exist(self, model, domain, table, name):
|
||||
"""
|
||||
|
@ -354,8 +354,8 @@ class import_framework(Thread):
|
|||
noupdate=True, res_id=ids[0], context=self.context)
|
||||
return xml_id
|
||||
return False
|
||||
|
||||
|
||||
|
||||
|
||||
def set_table_list(self, table_list):
|
||||
"""
|
||||
Set the list of table to import, this method should be call before run
|
||||
|
@ -363,13 +363,13 @@ class import_framework(Thread):
|
|||
['Leads', 'Opportunity']
|
||||
"""
|
||||
self.table_list = table_list
|
||||
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
Import all data into openerp,
|
||||
Import all data into openerp,
|
||||
this is the Entry point to launch the process of import
|
||||
|
||||
|
||||
|
||||
|
||||
"""
|
||||
self.data_started = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
self.cr = pooler.get_db(self.cr.dbname).cursor()
|
||||
|
@ -388,21 +388,21 @@ class import_framework(Thread):
|
|||
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
|
||||
|
||||
|
||||
|
||||
|
||||
self.date_ended = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
self._send_notification_email(result, error)
|
||||
|
||||
|
||||
self.cr.close()
|
||||
|
||||
|
||||
def _resolve_dependencies(self, dep, imported):
|
||||
"""
|
||||
"""
|
||||
import dependencies recursively
|
||||
and avoid to import twice the same table
|
||||
"""
|
||||
|
@ -418,13 +418,13 @@ class import_framework(Thread):
|
|||
result.append((dependency, position, warning))
|
||||
imported.add(dependency)
|
||||
return result
|
||||
|
||||
|
||||
def _send_notification_email(self, result, error):
|
||||
if not self.email:
|
||||
return False
|
||||
return False
|
||||
email_obj = self.obj.pool.get('mail.message')
|
||||
email_id = email_obj.create(self.cr, self.uid, {
|
||||
'email_from' : 'import@module.openerp',
|
||||
'email_from' : 'import@module.openerp',
|
||||
'email_to' : self.email,
|
||||
'body_text' : self.get_email_body(result, error),
|
||||
'subject' : self.get_email_subject(result, error),
|
||||
|
@ -434,34 +434,34 @@ class import_framework(Thread):
|
|||
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, error=False):
|
||||
"""
|
||||
This method define the subject of the email send by openerp at the end of import
|
||||
@param result: a list of tuple
|
||||
@param result: a list of tuple
|
||||
(table_name, number_of_record_created/updated, warning) for each table
|
||||
@return the subject of the mail
|
||||
|
||||
|
||||
"""
|
||||
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, 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.
|
||||
If you want to keep this it's better to overwrite get_body_header
|
||||
@param result: a list of tuple
|
||||
@param result: a list of tuple
|
||||
(table_name, number_of_record_created/updated, warning) for each table
|
||||
@return the subject of the mail
|
||||
|
||||
|
||||
"""
|
||||
|
||||
|
||||
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
|
||||
|
||||
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")
|
||||
|
@ -469,13 +469,13 @@ class import_framework(Thread):
|
|||
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
|
||||
|
||||
|
||||
|
||||
#TODO documentation test
|
||||
def run_test(self):
|
||||
|
@ -489,13 +489,13 @@ class import_framework(Thread):
|
|||
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
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ Normal - the campaign runs normally and automatically sends all emails and repor
|
|||
campaign = self.browse(cr, uid, ids[0])
|
||||
|
||||
if not campaign.activity_ids:
|
||||
raise osv.except_osv(_("Error"), _("The campaign cannot be started: there are no activities in it"))
|
||||
raise osv.except_osv(_("Error"), _("The campaign cannot be started: there are no activities in it."))
|
||||
|
||||
has_start = False
|
||||
has_signal_without_from = False
|
||||
|
@ -145,7 +145,7 @@ Normal - the campaign runs normally and automatically sends all emails and repor
|
|||
has_signal_without_from = True
|
||||
|
||||
if not has_start and not has_signal_without_from:
|
||||
raise osv.except_osv(_("Error"), _("The campaign cannot be started: it doesn't have any starting activity (or any activity with a signal and no previous activity)"))
|
||||
raise osv.except_osv(_("Error"), _("The campaign cannot be started: it doesn't have any starting activity. Modify campaign's activities to mark one as the starting point."))
|
||||
|
||||
return self.write(cr, uid, ids, {'state': 'running'})
|
||||
|
||||
|
@ -155,7 +155,7 @@ Normal - the campaign runs normally and automatically sends all emails and repor
|
|||
[('campaign_id', 'in', ids),
|
||||
('state', '=', 'running')])
|
||||
if segment_ids :
|
||||
raise osv.except_osv(_("Error"), _("The campaign cannot be marked as done before all segments are done"))
|
||||
raise osv.except_osv(_("Error"), _("The campaign cannot be marked as done before all segments are closed."))
|
||||
self.write(cr, uid, ids, {'state': 'done'})
|
||||
return True
|
||||
|
||||
|
@ -211,7 +211,7 @@ Normal - the campaign runs normally and automatically sends all emails and repor
|
|||
|
||||
# prevent duplication until the server properly duplicates several levels of nested o2m
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
raise osv.except_osv(_("Operation not supported"), _("Sorry, campaign duplication is not supported at the moment."))
|
||||
raise osv.except_osv(_("Operation not supported"), _("You can not duplicate a campaign, it's not supported yet."))
|
||||
|
||||
def _find_duplicate_workitems(self, cr, uid, record, campaign_rec, context=None):
|
||||
"""Finds possible duplicates workitems for a record in this campaign, based on a uniqueness
|
||||
|
|
|
@ -600,7 +600,7 @@ class mrp_production(osv.osv):
|
|||
self.write(cr, uid, [production.id], {'bom_id': bom_id, 'routing_id': routing_id})
|
||||
|
||||
if not bom_id:
|
||||
raise osv.except_osv(_('Error'), _("Couldn't find bill of material for product"))
|
||||
raise osv.except_osv(_('Error'), _("Couldn't find a bill of material for this product."))
|
||||
factor = uom_obj._compute_qty(cr, uid, production.product_uom.id, production.product_qty, bom_point.product_uom.id)
|
||||
res = bom_obj._bom_explode(cr, uid, bom_point, factor / bom_point.product_qty, properties, routing_id=production.routing_id.id)
|
||||
results = res[0]
|
||||
|
|
|
@ -278,7 +278,7 @@ class pos_order(osv.osv):
|
|||
('user_id', '=', uid),
|
||||
('state', '=', 'open')], context=context)
|
||||
if len(statement_id) == 0:
|
||||
raise osv.except_osv(_('Error !'), _('You have to open at least one cashbox'))
|
||||
raise osv.except_osv(_('Error !'), _('You have to open at least one cashbox.'))
|
||||
if statement_id:
|
||||
statement_id = statement_id[0]
|
||||
args['statement_id'] = statement_id
|
||||
|
|
|
@ -135,7 +135,7 @@ class procurement_order(osv.osv):
|
|||
unlink_ids.append(s['id'])
|
||||
else:
|
||||
raise osv.except_osv(_('Invalid action !'),
|
||||
_('Cannot delete Procurement Order(s) which are in %s State!') % \
|
||||
_('Cannot delete Procurement Order(s) which are in %s state!') % \
|
||||
s['state'])
|
||||
return osv.osv.unlink(self, cr, uid, unlink_ids, context=context)
|
||||
|
||||
|
@ -325,7 +325,7 @@ class procurement_order(osv.osv):
|
|||
for procurement in self.browse(cr, uid, ids, context=context):
|
||||
if procurement.product_qty <= 0.00:
|
||||
raise osv.except_osv(_('Data Insufficient !'),
|
||||
_('Please check the Quantity in Procurement Order(s), it should not be less than 1!'))
|
||||
_('Please check the quantity in procurement order(s), it should not be 0 or less!'))
|
||||
if procurement.product_id.type in ('product', 'consu'):
|
||||
if not procurement.move_id:
|
||||
source = procurement.location_id.id
|
||||
|
|
|
@ -142,7 +142,7 @@ class account_invoice_line(osv.osv):
|
|||
if not price_unit and partner_id:
|
||||
pricelist =partner_obj.browse(cr, uid, partner_id).property_product_pricelist_purchase.id
|
||||
if not pricelist:
|
||||
raise osv.except_osv(_('No Purchase Pricelist Found !'),_("You must first define a pricelist for Supplier !"))
|
||||
raise osv.except_osv(_('No Purchase Pricelist Found!'),_("You must first define a pricelist on the supplier form!"))
|
||||
price_unit_res = pricelist_obj.price_get(cr, uid, [pricelist], product.id, qty or 1.0, partner_id, {'uom': uom})
|
||||
price_unit = price_unit_res[pricelist]
|
||||
real_price = get_real_price(price_unit_res, product.id, qty, uom, pricelist)
|
||||
|
@ -150,7 +150,7 @@ class account_invoice_line(osv.osv):
|
|||
if partner_id:
|
||||
pricelist = partner_obj.browse(cr, uid, partner_id).property_product_pricelist.id
|
||||
if not pricelist:
|
||||
raise osv.except_osv(_('No Sale Pricelist Found '),_("You must first define a pricelist for Customer !"))
|
||||
raise osv.except_osv(_('No Sale Pricelist Found!'),_("You must first define a pricelist on the customer form!"))
|
||||
price_unit_res = pricelist_obj.price_get(cr, uid, [pricelist], product.id, qty or 1.0, partner_id, {'uom': uom})
|
||||
price_unit = price_unit_res[pricelist]
|
||||
|
||||
|
|
Loading…
Reference in New Issue