[MERGE] trunk
bzr revid: al@openerp.com-20120930141638-bw50m7b5a8wnu2yh
This commit is contained in:
commit
6dd16f2613
|
@ -159,6 +159,5 @@ for a particular financial year and for preparation of vouchers there is a modul
|
|||
],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate': '0080331923549',
|
||||
}
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -31,7 +31,7 @@ import decimal_precision as dp
|
|||
from tools.translate import _
|
||||
from tools.float_utils import float_round
|
||||
from openerp import SUPERUSER_ID
|
||||
|
||||
import tools
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -227,7 +227,7 @@ class account_account(osv.osv):
|
|||
while pos < len(args):
|
||||
|
||||
if args[pos][0] == 'code' and args[pos][1] in ('like', 'ilike') and args[pos][2]:
|
||||
args[pos] = ('code', '=like', str(args[pos][2].replace('%', ''))+'%')
|
||||
args[pos] = ('code', '=like', tools.ustr(args[pos][2].replace('%', ''))+'%')
|
||||
if args[pos][0] == 'journal_id':
|
||||
if not args[pos][2]:
|
||||
del args[pos]
|
||||
|
@ -601,7 +601,7 @@ class account_account(osv.osv):
|
|||
if not default:
|
||||
default = {}
|
||||
default = default.copy()
|
||||
default['code'] = (account['code'] or '') + '(copy)'
|
||||
default.update(code=_("%s (copy)") % (account['code'] or ''))
|
||||
if not local:
|
||||
done_list = []
|
||||
if account.id in done_list:
|
||||
|
@ -682,7 +682,7 @@ class account_journal_view(osv.osv):
|
|||
_name = "account.journal.view"
|
||||
_description = "Journal View"
|
||||
_columns = {
|
||||
'name': fields.char('Journal View', size=64, required=True),
|
||||
'name': fields.char('Journal View', size=64, required=True, translate=True),
|
||||
'columns_id': fields.one2many('account.journal.column', 'view_id', 'Columns')
|
||||
}
|
||||
_order = "name"
|
||||
|
@ -782,9 +782,10 @@ class account_journal(osv.osv):
|
|||
if not default:
|
||||
default = {}
|
||||
default = default.copy()
|
||||
default['code'] = (journal['code'] or '') + '(copy)'
|
||||
default['name'] = (journal['name'] or '') + '(copy)'
|
||||
default['sequence_id'] = False
|
||||
default.update(
|
||||
code=_("%s (copy)") % (journal['code'] or ''),
|
||||
name=_("%s (copy)") % (journal['name'] or ''),
|
||||
sequence_id=False)
|
||||
return super(account_journal, self).copy(cr, uid, id, default, context=context)
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
|
@ -1907,7 +1908,7 @@ class account_tax(osv.osv):
|
|||
'ref_tax_sign': fields.float('Tax Code Sign', help="Usually 1 or -1."),
|
||||
'include_base_amount': fields.boolean('Included in base amount', help="Indicates if the amount of tax must be included in the base amount for the computation of the next taxes"),
|
||||
'company_id': fields.many2one('res.company', 'Company', required=True),
|
||||
'description': fields.char('Tax Code',size=32),
|
||||
'description': fields.char('Tax Code'),
|
||||
'price_include': fields.boolean('Tax Included in Price', help="Check this if the price you use on the product and invoices includes this tax."),
|
||||
'type_tax_use': fields.selection([('sale','Sale'),('purchase','Purchase'),('all','All')], 'Tax Application', required=True)
|
||||
|
||||
|
@ -2827,7 +2828,7 @@ class account_tax_template(osv.osv):
|
|||
'ref_base_sign': fields.float('Base Code Sign', help="Usually 1 or -1."),
|
||||
'ref_tax_sign': fields.float('Tax Code Sign', help="Usually 1 or -1."),
|
||||
'include_base_amount': fields.boolean('Include in Base Amount', help="Set if the amount of tax must be included in the base amount before computing the next taxes."),
|
||||
'description': fields.char('Internal Name', size=32),
|
||||
'description': fields.char('Internal Name'),
|
||||
'type_tax_use': fields.selection([('sale','Sale'),('purchase','Purchase'),('all','All')], 'Tax Use In', required=True,),
|
||||
'price_include': fields.boolean('Tax Included in Price', help="Check this if the price you use on the product and invoices includes this tax."),
|
||||
}
|
||||
|
|
|
@ -447,11 +447,13 @@ class account_bank_statement(osv.osv):
|
|||
return self.write(cr, uid, done, {'state':'draft'}, context=context)
|
||||
|
||||
def _compute_balance_end_real(self, cr, uid, journal_id, context=None):
|
||||
cr.execute('SELECT balance_end_real \
|
||||
FROM account_bank_statement \
|
||||
WHERE journal_id = %s AND NOT state = %s \
|
||||
ORDER BY date DESC,id DESC LIMIT 1', (journal_id, 'draft'))
|
||||
res = cr.fetchone()
|
||||
res = False
|
||||
if journal_id:
|
||||
cr.execute('SELECT balance_end_real \
|
||||
FROM account_bank_statement \
|
||||
WHERE journal_id = %s AND NOT state = %s \
|
||||
ORDER BY date DESC,id DESC LIMIT 1', (journal_id, 'draft'))
|
||||
res = cr.fetchone()
|
||||
return res and res[0] or 0.0
|
||||
|
||||
def onchange_journal_id(self, cr, uid, statement_id, journal_id, context=None):
|
||||
|
|
|
@ -508,8 +508,10 @@ class account_invoice(osv.osv):
|
|||
if journal_id:
|
||||
journal = self.pool.get('account.journal').browse(cr, uid, journal_id, context=context)
|
||||
currency_id = journal.currency and journal.currency.id or journal.company_id.currency_id.id
|
||||
company_id = journal.company_id.id
|
||||
result = {'value': {
|
||||
'currency_id': currency_id,
|
||||
'company_id': company_id,
|
||||
}
|
||||
}
|
||||
return result
|
||||
|
@ -1373,7 +1375,10 @@ class account_invoice_line(osv.osv):
|
|||
'partner_id': fields.related('invoice_id','partner_id',type='many2one',relation='res.partner',string='Partner',store=True)
|
||||
}
|
||||
|
||||
def _default_account_id(self, cr, uid, ids, context=None):
|
||||
def _default_account_id(self, cr, uid, context=None):
|
||||
# XXX this gets the default account for the user's company,
|
||||
# it should get the default account for the invoice's company
|
||||
# however, the invoice's company does not reach this point
|
||||
prop = self.pool.get('ir.property').get(cr, uid, 'property_account_income_categ', 'product.category', context=context)
|
||||
return prop and prop.id or False
|
||||
|
||||
|
@ -1403,7 +1408,7 @@ class account_invoice_line(osv.osv):
|
|||
context = {}
|
||||
company_id = company_id if company_id != None else context.get('company_id',False)
|
||||
context = dict(context)
|
||||
context.update({'company_id': company_id})
|
||||
context.update({'company_id': company_id, 'force_company': company_id})
|
||||
if not partner_id:
|
||||
raise osv.except_osv(_('No Partner Defined !'),_("You must first select a partner !") )
|
||||
if not product:
|
||||
|
@ -1558,12 +1563,14 @@ class account_invoice_line(osv.osv):
|
|||
def onchange_account_id(self, cr, uid, ids, product_id, partner_id, inv_type, fposition_id, account_id):
|
||||
if not account_id:
|
||||
return {}
|
||||
taxes = self.pool.get('account.account').browse(cr, uid, account_id).tax_ids
|
||||
account = self.pool.get('account.account').browse(cr, uid, account_id)
|
||||
taxes = account.tax_ids
|
||||
fpos = fposition_id and self.pool.get('account.fiscal.position').browse(cr, uid, fposition_id) or False
|
||||
tax_ids = self.pool.get('account.fiscal.position').map_tax(cr, uid, fpos, taxes)
|
||||
|
||||
product_change_result = self.product_id_change(cr, uid, ids, product_id, False, type=inv_type,
|
||||
partner_id=partner_id, fposition_id=fposition_id)
|
||||
partner_id=partner_id, fposition_id=fposition_id,
|
||||
company_id=account.company_id.id)
|
||||
unique_tax_ids = set(tax_ids)
|
||||
if product_change_result and 'value' in product_change_result and 'invoice_line_tax_id' in product_change_result['value']:
|
||||
unique_tax_ids |= set(product_change_result['value']['invoice_line_tax_id'])
|
||||
|
@ -1652,14 +1659,13 @@ class account_invoice_tax(osv.osv):
|
|||
|
||||
for line in inv.invoice_line:
|
||||
for tax in tax_obj.compute_all(cr, uid, line.invoice_line_tax_id, (line.price_unit* (1-(line.discount or 0.0)/100.0)), line.quantity, line.product_id, inv.partner_id)['taxes']:
|
||||
tax['price_unit'] = cur_obj.round(cr, uid, cur, tax['price_unit'])
|
||||
val={}
|
||||
val['invoice_id'] = inv.id
|
||||
val['name'] = tax['name']
|
||||
val['amount'] = tax['amount']
|
||||
val['manual'] = False
|
||||
val['sequence'] = tax['sequence']
|
||||
val['base'] = tax['price_unit'] * line['quantity']
|
||||
val['base'] = cur_obj.round(cr, uid, cur, tax['price_unit'] * line['quantity'])
|
||||
|
||||
if inv.type in ('out_invoice','in_invoice'):
|
||||
val['base_code_id'] = tax['base_code_id']
|
||||
|
|
|
@ -562,6 +562,7 @@ class account_move_line(osv.osv):
|
|||
'journal_id': lambda self, cr, uid, c: c.get('journal_id', False),
|
||||
'credit': 0.0,
|
||||
'debit': 0.0,
|
||||
'amount_currency': 0.0,
|
||||
'account_id': lambda self, cr, uid, c: c.get('account_id', False),
|
||||
'period_id': lambda self, cr, uid, c: c.get('period_id', False),
|
||||
'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'account.move.line', context=c)
|
||||
|
@ -736,7 +737,7 @@ class account_move_line(osv.osv):
|
|||
WHERE debit > 0 AND credit > 0
|
||||
ORDER BY last_reconciliation_date""")
|
||||
ids = cr.fetchall()
|
||||
ids = len(ids) and list(ids[0]) or []
|
||||
ids = len(ids) and [x[0] for x in ids] or []
|
||||
return self.pool.get('res.partner').name_get(cr, uid, ids, context=context)
|
||||
|
||||
def reconcile_partial(self, cr, uid, ids, type='auto', context=None, writeoff_acc_id=False, writeoff_period_id=False, writeoff_journal_id=False):
|
||||
|
@ -1193,12 +1194,12 @@ class account_move_line(osv.osv):
|
|||
jour_period_obj = self.pool.get('account.journal.period')
|
||||
cr.execute('SELECT state FROM account_journal_period WHERE journal_id = %s AND period_id = %s', (journal_id, period_id))
|
||||
result = cr.fetchall()
|
||||
journal = journal_obj.browse(cr, uid, journal_id, context=context)
|
||||
period = period_obj.browse(cr, uid, period_id, context=context)
|
||||
for (state,) in result:
|
||||
if state == 'done':
|
||||
raise osv.except_osv(_('Error!'), _('You cannot add/modify entries in a closed journal.'))
|
||||
raise osv.except_osv(_('Error !'), _('You can not add/modify entries in a closed period %s of journal %s.' % (period.name,journal.name)))
|
||||
if not result:
|
||||
journal = journal_obj.browse(cr, uid, journal_id, context=context)
|
||||
period = period_obj.browse(cr, uid, period_id, context=context)
|
||||
jour_period_obj.create(cr, uid, {
|
||||
'name': (journal.code or journal.name)+':'+(period.name or ''),
|
||||
'journal_id': journal.id,
|
||||
|
|
|
@ -1305,16 +1305,6 @@
|
|||
Account.Entry Edition
|
||||
-->
|
||||
|
||||
<record id="account_move_graph" model="ir.ui.view">
|
||||
<field name="name">account.move.graph</field>
|
||||
<field name="model">account.move</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Account Statistics" type="bar">
|
||||
<field name="period_id"/>
|
||||
<field name="amount" operator="+"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_move_tree" model="ir.ui.view">
|
||||
<field name="name">account.move.tree</field>
|
||||
<field name="model">account.move</field>
|
||||
|
@ -1338,8 +1328,8 @@
|
|||
<field name="arch" type="xml">
|
||||
<form string="Account Entry" version="7.0">
|
||||
<header>
|
||||
<button name="button_validate" states="draft" string="Post" type="object" class="oe_highlight"/>
|
||||
<button name="button_cancel" states="posted" string="Cancel" type="object"/>
|
||||
<button name="button_validate" states="draft" string="Post" type="object" class="oe_highlight" groups="account.group_account_invoice"/>
|
||||
<button name="button_cancel" states="posted" string="Cancel" type="object" groups="account.group_account_invoice"/>
|
||||
<field name="state" widget="statusbar"/>
|
||||
</header>
|
||||
<sheet string="Journal Entries" >
|
||||
|
@ -1488,7 +1478,7 @@
|
|||
<field name="name">Journal Entries</field>
|
||||
<field name="res_model">account.move</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,graph</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="view_move_tree"/>
|
||||
<field name="search_view_id" ref="view_account_move_filter"/>
|
||||
<field name="help" type="html">
|
||||
|
@ -2037,7 +2027,7 @@
|
|||
src_model="account.journal"/>
|
||||
|
||||
<act_window
|
||||
context="{'search_default_reconcile_id':False, 'search_default_partner_id':[active_id], 'default_partner_id': active_id}"
|
||||
context="{'search_default_unreconciled':True, 'search_default_partner_id':[active_id], 'default_partner_id': active_id}"
|
||||
domain="[('account_id.reconcile', '=', True),('account_id.type', 'in', ['receivable', 'payable'])]"
|
||||
id="act_account_partner_account_move_all"
|
||||
name="Receivables & Payables"
|
||||
|
|
|
@ -122,6 +122,14 @@
|
|||
<field name="type">other</field>
|
||||
<field name="user_type" ref="data_account_type_income"/>
|
||||
</record>
|
||||
<record id="usd_bnk" model="account.account">
|
||||
<field name="code">X11007</field>
|
||||
<field name="name">USD Bank Account - (test)</field>
|
||||
<field ref="cas" name="parent_id"/>
|
||||
<field name="type">liquidity</field>
|
||||
<field name="user_type" ref="data_account_type_asset"/>
|
||||
<field name="currency_id" ref="base.USD"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account" id="liabilities_view">
|
||||
<field name="name">Liabilities - (test)</field>
|
||||
|
@ -360,8 +368,8 @@
|
|||
<field name="type">bank</field>
|
||||
<field name="view_id" ref="account_journal_bank_view"/>
|
||||
<field name="sequence_id" ref="sequence_bank_journal"/>
|
||||
<field model="account.account" name="default_debit_account_id" ref="cash"/>
|
||||
<field model="account.account" name="default_credit_account_id" ref="cash"/>
|
||||
<field model="account.account" name="default_debit_account_id" ref="bnk"/>
|
||||
<field model="account.account" name="default_credit_account_id" ref="bnk"/>
|
||||
<field name="analytic_journal_id" ref="sit"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
</record>
|
||||
|
@ -384,7 +392,12 @@
|
|||
<field name="loss_account_id" model="account.account" ref="rsa" />
|
||||
<field name="internal_account_id" model="account.account" ref="rsa" />
|
||||
<field name="with_last_closing_balance" eval="True" />
|
||||
<field name="cash_control" eval="True" />
|
||||
<!--
|
||||
Usually, cash payment methods requires a control at opening and closing.
|
||||
Bot for demo data, it's better to avoid the control step so that people
|
||||
that test OpenERP arrive directly in the touchscreen UI.
|
||||
-->
|
||||
<field name="cash_control" eval="False"/>
|
||||
<field name="view_id" ref="account_journal_bank_view"/>
|
||||
<field name="sequence_id" ref="sequence_cash_journal"/>
|
||||
<field model="account.account" name="default_debit_account_id" ref="cash"/>
|
||||
|
@ -412,6 +425,16 @@
|
|||
<field eval="True" name="centralisation"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
</record>
|
||||
|
||||
<record id="bank_journal_usd" model="account.journal">
|
||||
<field name="name">USD Bank Journal - (test)</field>
|
||||
<field name="code">TUBK</field>
|
||||
<field name="type">bank</field>
|
||||
<field name="view_id" ref="account_journal_bank_view"/>
|
||||
<field model="account.account" name="default_debit_account_id" ref="usd_bnk"/>
|
||||
<field model="account.account" name="default_credit_account_id" ref="usd_bnk"/>
|
||||
<field name="currency" ref="base.USD"/>
|
||||
</record>
|
||||
<!--
|
||||
Product income and expense accounts, default parameters
|
||||
-->
|
||||
|
|
|
@ -44,17 +44,17 @@ class account_fiscal_position(osv.osv):
|
|||
return []
|
||||
if not fposition_id:
|
||||
return map(lambda x: x.id, taxes)
|
||||
result = []
|
||||
result = set()
|
||||
for t in taxes:
|
||||
ok = False
|
||||
for tax in fposition_id.tax_ids:
|
||||
if tax.tax_src_id.id == t.id:
|
||||
if tax.tax_dest_id:
|
||||
result.append(tax.tax_dest_id.id)
|
||||
result.add(tax.tax_dest_id.id)
|
||||
ok=True
|
||||
if not ok:
|
||||
result.append(t.id)
|
||||
return result
|
||||
result.add(t.id)
|
||||
return list(result)
|
||||
|
||||
def map_account(self, cr, uid, fposition_id, account_id, context=None):
|
||||
if not fposition_id:
|
||||
|
@ -77,6 +77,12 @@ class account_fiscal_position_tax(osv.osv):
|
|||
'tax_dest_id': fields.many2one('account.tax', 'Replacement Tax')
|
||||
}
|
||||
|
||||
_sql_constraints = [
|
||||
('tax_src_dest_uniq',
|
||||
'unique (position_id,tax_src_id,tax_dest_id)',
|
||||
'A tax fiscal position could be defined only once time on same taxes.')
|
||||
]
|
||||
|
||||
account_fiscal_position_tax()
|
||||
|
||||
class account_fiscal_position_account(osv.osv):
|
||||
|
@ -89,6 +95,12 @@ class account_fiscal_position_account(osv.osv):
|
|||
'account_dest_id': fields.many2one('account.account', 'Account Destination', domain=[('type','<>','view')], required=True)
|
||||
}
|
||||
|
||||
_sql_constraints = [
|
||||
('account_src_dest_uniq',
|
||||
'unique (position_id,account_src_id,account_dest_id)',
|
||||
'An account fiscal position could be defined only once time on same accounts.')
|
||||
]
|
||||
|
||||
account_fiscal_position_account()
|
||||
|
||||
class res_partner(osv.osv):
|
||||
|
|
|
@ -92,34 +92,7 @@
|
|||
<field name="debit"/>
|
||||
</group>
|
||||
</group>
|
||||
<field name="bank_ids">
|
||||
<form string="Bank account" version="7.0">
|
||||
<group col="4">
|
||||
<field name="state"/>
|
||||
<field name="acc_number"/>
|
||||
</group>
|
||||
<group>
|
||||
<group name="owner" string="Bank Account Owner">
|
||||
<field name="partner_id" on_change="onchange_partner_id(partner_id)"/>
|
||||
<field name="owner_name"/>
|
||||
<label for="street" string="Address"/>
|
||||
<div>
|
||||
<field name="street" placeholder="Street..."/>
|
||||
<div>
|
||||
<field name="zip" class="oe_inline" placeholder="ZIP"/>
|
||||
<field name="city" class="oe_inline" placeholder="City"/>
|
||||
</div>
|
||||
<field name="state_id" placeholder="State" options='{"no_open": true}'/>
|
||||
<field name="country_id" placeholder="Country" options='{"no_open": true}'/>
|
||||
</div>
|
||||
</group>
|
||||
<group name="bank" string="Information About the Bank">
|
||||
<field name="bank" on_change="onchange_bank_id(bank)"/>
|
||||
<field name="bank_name"/>
|
||||
<field name="bank_bic" placeholder="e.g. GEBABEBB"/>
|
||||
</group>
|
||||
</group>
|
||||
</form>
|
||||
<field name="bank_ids" context="{'default_partner_id': active_id, 'form_view_ref': 'base.view_partner_bank_form'}">
|
||||
<tree string="Bank Details">
|
||||
<field name="sequence" invisible="1"/>
|
||||
<field name="acc_number"/>
|
||||
|
@ -141,7 +114,7 @@
|
|||
context="{'search_default_partner_id':[active_id], 'default_partner_id': active_id}"
|
||||
src_model="res.partner"
|
||||
view_type="form"
|
||||
view_mode="tree,form,graph,calendar"/>
|
||||
view_mode="tree,form,calendar"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">account.analytic.account</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,graph,form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="view_account_analytic_account_tree"/>
|
||||
<field name="search_view_id" ref="account.view_account_analytic_account_search"/>
|
||||
</record>
|
||||
|
@ -114,9 +114,6 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem groups="analytic.group_analytic_accounting" id="next_id_40"
|
||||
name="Analytic" parent="account.menu_finance_generic_reporting"
|
||||
sequence="4"/>
|
||||
|
||||
<record id="view_account_analytic_line_form" model="ir.ui.view">
|
||||
<field name="name">account.analytic.line.form</field>
|
||||
|
@ -351,15 +348,6 @@
|
|||
# Reporting
|
||||
#
|
||||
|
||||
<record id="action_account_analytic_journal_tree" model="ir.actions.act_window">
|
||||
<field name="name">Print Analytic Journals</field>
|
||||
<field name="res_model">account.analytic.journal</field>
|
||||
<field name="view_type">tree</field>
|
||||
<field name="help">To print an analytics (or costs) journal for a given period. The report give code, move name, account number, general amount and analytic amount.</field>
|
||||
</record>
|
||||
<menuitem groups="analytic.group_analytic_accounting"
|
||||
action="action_account_analytic_journal_tree"
|
||||
id="account_analytic_journal_print" parent="account.next_id_40"/>
|
||||
|
||||
<record id="view_account_journal_1" model="ir.ui.view">
|
||||
<field name="name">account.journal.form.1</field>
|
||||
|
@ -372,16 +360,5 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<record id="analytic_accounts_graph" model="ir.ui.view">
|
||||
<field name="name">analytic.accounts.graph</field>
|
||||
<field name="model">account.analytic.account</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Analytic Account Statistics" type="bar">
|
||||
<field name="complete_name"/>
|
||||
<field name="balance" operator="+"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -29,6 +29,7 @@ class account_analytic_journal_report(osv.osv_memory):
|
|||
_columns = {
|
||||
'date1': fields.date('Start of period', required=True),
|
||||
'date2': fields.date('End of period', required=True),
|
||||
'analytic_account_journal_id': fields.many2many('account.analytic.journal', 'account_analytic_journal_name', 'journal_line_id', 'journal_print_id', 'Analytic Journals', required=True),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
|
@ -40,8 +41,15 @@ class account_analytic_journal_report(osv.osv_memory):
|
|||
if context is None:
|
||||
context = {}
|
||||
data = self.read(cr, uid, ids)[0]
|
||||
ids_list = []
|
||||
if context.get('active_id',False):
|
||||
ids_list.append(context.get('active_id',False))
|
||||
else:
|
||||
record = self.browse(cr,uid,ids[0],context=context)
|
||||
for analytic_record in record.analytic_account_journal_id:
|
||||
ids_list.append(analytic_record.id)
|
||||
datas = {
|
||||
'ids': context.get('active_ids',[]),
|
||||
'ids': ids_list,
|
||||
'model': 'account.analytic.journal',
|
||||
'form': data
|
||||
}
|
||||
|
@ -50,6 +58,14 @@ class account_analytic_journal_report(osv.osv_memory):
|
|||
'report_name': 'account.analytic.journal',
|
||||
'datas': datas,
|
||||
}
|
||||
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
res = super(account_analytic_journal_report, self).default_get(cr, uid, fields, context=context)
|
||||
if 'analytic_account_journal_id' in fields:
|
||||
res.update({'analytic_account_journal_id': context.get('active_ids',[])})
|
||||
return res
|
||||
|
||||
account_analytic_journal_report()
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -7,15 +7,16 @@
|
|||
<field name="model">account.analytic.journal.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Select Period" version="7.0">
|
||||
<header>
|
||||
<button name="check_report" string="Print" type="object" class="oe_highlight"/>
|
||||
or
|
||||
<button string="Cancel" class="oe_link" special="cancel"/>
|
||||
</header>
|
||||
<group col="4">
|
||||
<field name="date1"/>
|
||||
<field name="date2"/>
|
||||
<field name="analytic_account_journal_id" widget="many2many_tags" class="oe_inline" required="1"/>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="check_report" string="Print" type="object" class="oe_highlight"/>
|
||||
or
|
||||
<button string="Cancel" class="oe_link" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -38,6 +39,13 @@
|
|||
<field name="key">action</field>
|
||||
<field name="model">account.analytic.journal</field>
|
||||
</record>
|
||||
|
||||
<menuitem groups="analytic.group_analytic_accounting" id="next_id_40"
|
||||
name="Analytic" parent="account.menu_finance_generic_reporting"
|
||||
sequence="4"/>
|
||||
<menuitem groups="analytic.group_analytic_accounting"
|
||||
action="account.action_account_analytic_journal"
|
||||
id="account_analytic_journal_print" parent="account.next_id_40"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -117,6 +117,9 @@ class account_config_settings(osv.osv_memory):
|
|||
'group_multi_currency': fields.boolean('Allow multi currencies',
|
||||
implied_group='base.group_multi_currency',
|
||||
help="Allows you multi currency environment"),
|
||||
'group_analytic_accounting': fields.boolean('Analytic accounting',
|
||||
implied_group='analytic.group_analytic_accounting',
|
||||
help="Allows you to use the analytic accounting."),
|
||||
}
|
||||
|
||||
def _default_company(self, cr, uid, context=None):
|
||||
|
|
|
@ -129,6 +129,10 @@
|
|||
<field name="module_account_accountant" class="oe_inline"/>
|
||||
<label for="module_account_accountant"/>
|
||||
</div>
|
||||
<div>
|
||||
<field name="group_analytic_accounting" class="oe_inline"/>
|
||||
<label for="group_analytic_accounting"/>
|
||||
</div>
|
||||
<div>
|
||||
<field name="module_account_asset" class="oe_inline"/>
|
||||
<label for="module_account_asset"/>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp><data>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="group_account_invoice" model="res.groups">
|
||||
<field name="name">Invoicing & Payments</field>
|
||||
|
@ -7,13 +8,15 @@
|
|||
<field name="users" eval="[(4, ref('base.user_root'))]"/>
|
||||
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="group_account_user" model="res.groups">
|
||||
<field name="name">Accountant</field>
|
||||
<field name="category_id" ref="base.module_category_accounting_and_finance"/>
|
||||
<field name="implied_ids" eval="[(4, ref('group_account_invoice'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="group_account_manager" model="res.groups">
|
||||
<field name="name">Manager</field>
|
||||
<field name="name">Financial Manager</field>
|
||||
<field name="category_id" ref="base.module_category_accounting_and_finance"/>
|
||||
<field name="implied_ids" eval="[(4, ref('group_account_user'))]"/>
|
||||
</record>
|
||||
|
@ -25,100 +28,107 @@
|
|||
|
||||
<record id="account_move_comp_rule" model="ir.rule">
|
||||
<field name="name">Account Entry</field>
|
||||
<field ref="model_account_move" name="model_id"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="model_id" ref="model_account_move"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="account_move_line_comp_rule" model="ir.rule">
|
||||
<field name="name">Entry lines</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_move_line"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="name">Entry lines</field>
|
||||
<field name="model_id" ref="model_account_move_line"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="journal_period_comp_rule" model="ir.rule">
|
||||
<field name="name">Journal Period</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_journal_period"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="model_id" ref="model_account_journal_period"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
<record id="journal_comp_rule" model="ir.rule">
|
||||
<field name="name">Journal multi-company</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_journal"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="model_id" ref="model_account_journal"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="analytic_journal_comp_rule" model="ir.rule">
|
||||
<field name="name">Analytic journal multi-company</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_analytic_journal"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="model_id" ref="model_account_analytic_journal"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="period_comp_rule" model="ir.rule">
|
||||
<field name="name">Period multi-company</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_period"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="model_id" ref="model_account_period"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="fiscal_year_comp_rule" model="ir.rule">
|
||||
<field name="name">Fiscal year multi-company</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_fiscalyear"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="model_id" ref="model_account_fiscalyear"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="account_comp_rule" model="ir.rule">
|
||||
<field name="name">Account multi-company</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_account"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="model_id" ref="model_account_account"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="tax_comp_rule" model="ir.rule">
|
||||
<field name="name">Tax multi-company</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_tax"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="name">Tax multi-company</field>
|
||||
<field name="model_id" ref="model_account_tax"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="tax_code_comp_rule" model="ir.rule">
|
||||
<field name="name">Tax code multi-company</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_tax_code"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="model_id" ref="model_account_tax_code"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="invoice_comp_rule" model="ir.rule">
|
||||
<field name="name">Invoice multi-company</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_invoice"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="model_id" ref="model_account_invoice"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="invoice_analysis_comp_rule" model="ir.rule">
|
||||
<field name="name">Invoice Analysis multi-company</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_invoice_report"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="model_id" ref="model_account_invoice_report"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="entry_analysis_comp_rule" model="ir.rule">
|
||||
<field name="name">Entries Analysis multi-company</field>
|
||||
<field name="model_id" ref="model_account_entries_report"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="account_fiscal_position_comp_rule" model="ir.rule">
|
||||
<field name="name">Account fiscal Mapping company rule</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_fiscal_position"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="model_id" ref="model_account_fiscal_position"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="account_model_comp_rule" model="ir.rule">
|
||||
<field name="name">Account model company rule</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_model"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="model_id" ref="model_account_model"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
|
@ -143,4 +153,5 @@
|
|||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
</data></openerp>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -23,6 +23,7 @@ import time
|
|||
|
||||
from osv import fields, osv
|
||||
from tools.translate import _
|
||||
import decimal_precision as dp
|
||||
|
||||
class account_move_line_reconcile(osv.osv_memory):
|
||||
"""
|
||||
|
@ -32,9 +33,9 @@ class account_move_line_reconcile(osv.osv_memory):
|
|||
_description = 'Account move line reconcile'
|
||||
_columns = {
|
||||
'trans_nbr': fields.integer('# of Transaction', readonly=True),
|
||||
'credit': fields.float('Credit amount', readonly=True),
|
||||
'debit': fields.float('Debit amount', readonly=True),
|
||||
'writeoff': fields.float('Write-Off amount', readonly=True),
|
||||
'credit': fields.float('Credit amount', readonly=True, digits_compute=dp.get_precision('Account')),
|
||||
'debit': fields.float('Debit amount', readonly=True, digits_compute=dp.get_precision('Account')),
|
||||
'writeoff': fields.float('Write-Off amount', readonly=True, digits_compute=dp.get_precision('Account')),
|
||||
}
|
||||
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
|
|
|
@ -43,6 +43,5 @@ It assigns manager and user access rights to the Administrator and only user rig
|
|||
'installable': True,
|
||||
'auto_install': False,
|
||||
'application': True,
|
||||
'certificate': '00395091383933390541',
|
||||
}
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -26,9 +26,11 @@
|
|||
<field name="res_id" ref="mail.group_all_employees"/>
|
||||
<field name="type">notification</field>
|
||||
<field name="subject">Accounting and Finance application installed!</field>
|
||||
<field name="body">With OpenERP's accounting, you get instant access to your financial data, and can setup analytic accounting, forecast taxes, control budgets, easily create and send invoices, record bank statements, etc.
|
||||
<field name="body"><![CDATA[
|
||||
With OpenERP's accounting, you get instant access to your financial data, and can setup analytic accounting, forecast taxes, control budgets, easily create and send invoices, record bank statements, etc.
|
||||
|
||||
The accounting features are fully integrated with other OpenERP applications to automate all your processes: creation of customer invoices, control of supplier invoices, point-of-sale integration, automated follow-ups, etc.</field>
|
||||
<p>The accounting features are fully integrated with other OpenERP applications to automate all your processes: creation of customer invoices, control of supplier invoices, point-of-sale integration, automated follow-ups, etc.</p>
|
||||
]]></field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -47,7 +47,6 @@ Adds menu to show relevant information to each manager.You can also view the rep
|
|||
'demo': [],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate': '0042927202589',
|
||||
}
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
<field name="name">Contracts to Renew</field>
|
||||
<field name="res_model">account.analytic.account</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,graph</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="context">{'search_default_user_id':uid, 'search_default_draft':1, 'search_default_pending':1, 'search_default_open':1, 'search_default_renew':1}</field>
|
||||
<field name="domain">[('type','=','contract')]</field>
|
||||
<field name="search_view_id" ref="view_account_analytic_account_overdue_search"/>
|
||||
|
@ -72,7 +72,7 @@
|
|||
<field name="name">Contracts</field>
|
||||
<field name="res_model">account.analytic.account</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,graph</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="context">{'default_type':'contract', 'search_default_open':1, 'search_default_pending':1}</field>
|
||||
<field name="domain">[('type','=','contract')]</field>
|
||||
<field name="search_view_id" ref="view_account_analytic_account_overdue_search"/>
|
||||
|
|
|
@ -47,7 +47,6 @@ Allows to automatically select analytic accounts based on criterions:
|
|||
'demo': [],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate': '0074229833581',
|
||||
}
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -79,7 +79,6 @@ The analytic plan validates the minimum and maximum percentage at the time of cr
|
|||
'test': ['test/acount_analytic_plans_report.yml'],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate': '0036417675373',
|
||||
}
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -262,6 +262,7 @@ account_analytic_plan_instance()
|
|||
class account_analytic_plan_instance_line(osv.osv):
|
||||
_name = "account.analytic.plan.instance.line"
|
||||
_description = "Analytic Instance Line"
|
||||
_rec_name = "analytic_account_id"
|
||||
_columns = {
|
||||
'plan_id': fields.many2one('account.analytic.plan.instance', 'Plan Id'),
|
||||
'analytic_account_id': fields.many2one('account.analytic.account', 'Analytic Account', required=True, domain=[('type','<>','view')]),
|
||||
|
|
|
@ -46,7 +46,6 @@ account.""",
|
|||
'data': ['product_view.xml',],
|
||||
'auto_install': False,
|
||||
'installable': True,
|
||||
'certificate':'00557423080410733581',
|
||||
}
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -350,7 +350,7 @@ class account_asset_depreciation_line(osv.osv):
|
|||
'amount': fields.float('Depreciation Amount', required=True),
|
||||
'remaining_value': fields.float('Amount to Depreciate', required=True),
|
||||
'depreciated_value': fields.float('Amount Already Depreciated', required=True),
|
||||
'depreciation_date': fields.char('Depreciation Date', size=64, select=1),
|
||||
'depreciation_date': fields.date('Depreciation Date', select=1),
|
||||
'move_id': fields.many2one('account.move', 'Depreciation Entry'),
|
||||
'move_check': fields.function(_get_move_check, method=True, type='boolean', string='Posted', store=True)
|
||||
}
|
||||
|
@ -368,7 +368,7 @@ class account_asset_depreciation_line(osv.osv):
|
|||
for line in self.browse(cr, uid, ids, context=context):
|
||||
if currency_obj.is_zero(cr, uid, line.asset_id.currency_id, line.remaining_value):
|
||||
can_close = True
|
||||
depreciation_date = line.asset_id.prorata and line.asset_id.purchase_date or time.strftime('%Y-%m-%d')
|
||||
depreciation_date = time.strftime('%Y-%m-%d')
|
||||
period_ids = period_obj.find(cr, uid, depreciation_date, context=context)
|
||||
company_currency = line.asset_id.company_id.currency_id.id
|
||||
current_currency = line.asset_id.currency_id.id
|
||||
|
|
|
@ -57,6 +57,7 @@ class account_invoice_line(osv.osv):
|
|||
'partner_id': line.invoice_id.partner_id.id,
|
||||
'company_id': line.invoice_id.company_id.id,
|
||||
'currency_id': line.invoice_id.currency_id.id,
|
||||
'purchase_date' : line.invoice_id.date_invoice,
|
||||
}
|
||||
changed_vals = asset_obj.onchange_category_id(cr, uid, [], vals['category_id'], context=context)
|
||||
vals.update(changed_vals['value'])
|
||||
|
|
|
@ -50,7 +50,7 @@ class asset_asset_report(osv.osv):
|
|||
select
|
||||
min(dl.id) as id,
|
||||
dl.name as name,
|
||||
to_date(dl.depreciation_date, 'YYYY-MM-DD') as depreciation_date,
|
||||
dl.depreciation_date as depreciation_date,
|
||||
a.purchase_date as purchase_date,
|
||||
(CASE WHEN (select min(d.id) from account_asset_depreciation_line as d
|
||||
left join account_asset_asset as ac ON (ac.id=d.asset_id)
|
||||
|
@ -77,7 +77,7 @@ class asset_asset_report(osv.osv):
|
|||
from account_asset_depreciation_line dl
|
||||
left join account_asset_asset a on (dl.asset_id=a.id)
|
||||
group by
|
||||
dl.amount,dl.asset_id,to_date(dl.depreciation_date, 'YYYY-MM-DD'),dl.name,
|
||||
dl.amount,dl.asset_id,dl.depreciation_date,dl.name,
|
||||
a.purchase_date, dl.move_check, a.state, a.category_id, a.partner_id, a.company_id,
|
||||
a.purchase_value, a.id, a.salvage_value
|
||||
)""")
|
||||
|
|
|
@ -69,6 +69,5 @@ Three reports are available:
|
|||
],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate': '0043819694157',
|
||||
}
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -38,9 +38,6 @@ If set to true it allows user to cancel entries & invoices.
|
|||
'demo': [],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate': '001101250473177981989',
|
||||
|
||||
|
||||
}
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -36,6 +36,5 @@ Deactivates minimal chart of accounts.
|
|||
'data': [],
|
||||
'demo': [],
|
||||
'installable': True,
|
||||
'certificate': '0073332443901',
|
||||
}
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -64,7 +64,6 @@ Note that if you want to check the follow-up level for a given partner/account e
|
|||
],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate': '0072481076453',
|
||||
}
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -65,6 +65,5 @@ have a new option to import payment orders as bank statement lines.
|
|||
],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate': '0061703998541',
|
||||
}
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -49,7 +49,6 @@ You can customize the following attributes of the sequence:
|
|||
'demo': [],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate': '00475376442024623469',
|
||||
}
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -72,7 +72,6 @@ This module manages:
|
|||
'test/case4_cad_chf.yml',
|
||||
'test/case_eur_usd.yml',
|
||||
],
|
||||
'certificate': '0037580727101',
|
||||
'auto_install': False,
|
||||
'application': True,
|
||||
'installable': True,
|
||||
|
|
|
@ -32,11 +32,11 @@ class res_company(osv.osv):
|
|||
_columns = {
|
||||
'income_currency_exchange_account_id': fields.many2one(
|
||||
'account.account',
|
||||
string="Income Currency Rate",
|
||||
string="Gain Exchange Rate Account",
|
||||
domain="[('type', '=', 'other')]",),
|
||||
'expense_currency_exchange_account_id': fields.many2one(
|
||||
'account.account',
|
||||
string="Expense Currency Rate",
|
||||
string="Loss Exchange Rate Account",
|
||||
domain="[('type', '=', 'other')]",),
|
||||
}
|
||||
|
||||
|
@ -782,9 +782,16 @@ class account_voucher(osv.osv):
|
|||
vals[key].update(res[key])
|
||||
return vals
|
||||
|
||||
def button_proforma_voucher(self, cr, uid, ids, context=None):
|
||||
context = context or {}
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
for vid in ids:
|
||||
wf_service.trg_validate(uid, 'account.voucher', vid, 'proforma_voucher', cr)
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
def proforma_voucher(self, cr, uid, ids, context=None):
|
||||
self.action_move_line_create(cr, uid, ids, context=context)
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
return True
|
||||
|
||||
def action_cancel_draft(self, cr, uid, ids, context=None):
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
|
|
|
@ -8,7 +8,11 @@
|
|||
<field name="res_id" ref="mail.group_all_employees"/>
|
||||
<field name="type">notification</field>
|
||||
<field name="subject">eInvoicing & Payments application installed!</field>
|
||||
<field name="body">OpenERP's electronic invoicing accelerates the creation of invoices and collection of customer payments. Invoices are created in a few clicks and your customers receive them by email. They can pay online and/or import them in their own system. You can track customer payments easily and automate follow-ups. You get an overview of the discussion with your customers on each invoice for easier traceability. For advanced accounting features, you should install the "Accounting and Finance" module.</field>
|
||||
<field name="body"><![CDATA[
|
||||
OpenERP's electronic invoicing accelerates the creation of invoices and collection of customer payments. Invoices are created in a few clicks and your customers receive them by email. They can pay online and/or import them in their own system.
|
||||
|
||||
<p>You can track customer payments easily and automate follow-ups. You get an overview of the discussion with your customers on each invoice for easier traceability. For advanced accounting features, you should install the "Accounting and Finance" module.</p>
|
||||
]]></field>
|
||||
</record>
|
||||
|
||||
<!-- mail: subtypes -->
|
||||
|
|
|
@ -27,11 +27,12 @@ class invoice(osv.osv):
|
|||
|
||||
def invoice_pay_customer(self, cr, uid, ids, context=None):
|
||||
if not ids: return []
|
||||
mod,modid = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'account_voucher', 'view_vendor_receipt_dialog_form')
|
||||
inv = self.browse(cr, uid, ids[0], context=context)
|
||||
return {
|
||||
'name':_("Pay Invoice"),
|
||||
'view_mode': 'form',
|
||||
'view_id': False,
|
||||
'view_id': modid,
|
||||
'view_type': 'form',
|
||||
'res_model': 'account.voucher',
|
||||
'type': 'ir.actions.act_window',
|
||||
|
@ -41,13 +42,13 @@ class invoice(osv.osv):
|
|||
'context': {
|
||||
'default_partner_id': inv.partner_id.id,
|
||||
'default_amount': inv.type in ('out_refund', 'in_refund') and -inv.residual or inv.residual,
|
||||
'default_name':inv.name,
|
||||
'default_number':inv.name,
|
||||
'close_after_process': True,
|
||||
'invoice_type':inv.type,
|
||||
'invoice_id':inv.id,
|
||||
'invoice_type': inv.type,
|
||||
'invoice_id': inv.id,
|
||||
'default_type': inv.type in ('out_invoice','out_refund') and 'receipt' or 'payment',
|
||||
'type': inv.type in ('out_invoice','out_refund') and 'receipt' or 'payment'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
invoice()
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
</group>
|
||||
<notebook>
|
||||
<page string="Payment Information">
|
||||
<label for="line_dr_ids" attrs="{'invisible': [('type', '=', 'receipt')]}"/>
|
||||
<field name="line_dr_ids" attrs="{'invisible': [('type', '=', 'receipt')]}" context="{'journal_id':journal_id, 'type':type, 'partner_id':partner_id}" colspan="4" nolabel="1" height="140" on_change="onchange_line_ids(line_dr_ids, line_cr_ids, amount, currency_id, type, context)">
|
||||
<tree string="Open Supplier Journal Entries" editable="bottom" colors="gray:amount==0">
|
||||
<field name="move_line_id" context="{'journal_id':parent.journal_id, 'partner_id':parent.partner_id}"
|
||||
|
@ -84,6 +85,7 @@
|
|||
<field name="amount" sum="Total Allocation"/>
|
||||
</tree>
|
||||
</field>
|
||||
<label for="line_cr_ids" attrs="{'invisible': [('type', '=', 'payment')]}"/>
|
||||
<field name="line_cr_ids" attrs="{'invisible': [('type', '=', 'payment')]}" context="{'journal_id':journal_id, 'partner_id':partner_id}" on_change="onchange_line_ids(line_dr_ids, line_cr_ids, amount, currency_id, type, context)">
|
||||
<tree string="Open Customer Journal Entries" editable="bottom" colors="gray:amount==0">
|
||||
<field name="move_line_id" context="{'journal_id':parent.journal_id, 'partner_id':parent.partner_id}"
|
||||
|
@ -155,6 +157,7 @@
|
|||
</group>
|
||||
<notebook>
|
||||
<page string="Payment Information">
|
||||
<label for="line_dr_ids"/>
|
||||
<field name="line_dr_ids" context="{'journal_id':journal_id, 'type':type, 'partner_id':partner_id}">
|
||||
<tree string="Supplier Invoices and Outstanding transactions" editable="bottom" colors="gray:amount==0">
|
||||
<field name="move_line_id" context="{'journal_id':parent.journal_id, 'partner_id':parent.partner_id}"
|
||||
|
@ -170,6 +173,7 @@
|
|||
<field name="amount" sum="Total Allocation" on_change="onchange_amount(amount, amount_unreconciled, context)"/>
|
||||
</tree>
|
||||
</field>
|
||||
<label for="line_cr_ids" attrs="{'invisible': [('pre_line','=',False)]}"/>
|
||||
<field name="line_cr_ids" attrs="{'invisible': [('pre_line','=',False)]}" context="{'journal_id':journal_id, 'partner_id':partner_id}">
|
||||
<tree string="Credits" editable="bottom" colors="gray:amount==0">
|
||||
<field name="move_line_id" context="{'journal_id':parent.journal_id, 'partner_id':parent.partner_id}"
|
||||
|
@ -280,6 +284,111 @@
|
|||
<menuitem action="action_vendor_payment" icon="STOCK_JUSTIFY_FILL" sequence="12"
|
||||
id="menu_action_vendor_payment" parent="account.menu_finance_payables"/>
|
||||
|
||||
<record model="ir.ui.view" id="view_vendor_receipt_dialog_form">
|
||||
<field name="name">account.voucher.receipt.dialog.form</field>
|
||||
<field name="model">account.voucher</field>
|
||||
<field name="priority">30</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Payment" version="7.0">
|
||||
<group>
|
||||
<group>
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="partner_id" required="1" on_change="onchange_partner_id(partner_id, journal_id, amount, currency_id, type, date, context)" string="Customer" context="{'search_default_customer': 1}"/>
|
||||
<label for="amount" string="Paid Amount"/>
|
||||
<div>
|
||||
<field name="amount" class="oe_inline"
|
||||
invisible="context.get('line_type', False)"
|
||||
on_change="onchange_amount(amount, payment_rate, partner_id, journal_id, currency_id, type, date, payment_rate_currency_id, company_id, context)"/>
|
||||
<field name="currency_id" class="oe_inline"/>
|
||||
</div>
|
||||
<field name="journal_id"
|
||||
domain="[('type','in',['bank', 'cash'])]"
|
||||
invisible="context.get('line_type', False)"
|
||||
widget="selection"
|
||||
on_change="onchange_journal(journal_id, line_cr_ids, False, partner_id, date, amount, type, company_id, context)"
|
||||
string="Payment Method"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="date" invisible="context.get('line_type', False)" on_change="onchange_date(date, currency_id, payment_rate_currency_id, amount, company_id, context)"/>
|
||||
<field name="reference" invisible="context.get('line_type', False)" string="Payment Ref" placeholder="e.g. 003/10"/>
|
||||
<field name="name" colspan="2" invisible="context.get('line_type', False)" placeholder="e.g. Invoice SAJ/0042"/>
|
||||
<field name="company_id" widget="selection" groups="base.group_multi_company"/>
|
||||
|
||||
<field name="account_id"
|
||||
widget="selection"
|
||||
invisible="True"/>
|
||||
<field name="pre_line" invisible="1"/>
|
||||
<field name="type" invisible="True"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook invisible="1">
|
||||
<page string="Payment Information" groups="base.group_user">
|
||||
<label for="line_cr_ids"/>
|
||||
<field name="line_cr_ids" context="{'journal_id':journal_id, 'type':type, 'partner_id':partner_id}" on_change="onchange_line_ids(line_dr_ids, line_cr_ids, amount, currency_id, type, context)">
|
||||
<tree string="Invoices and outstanding transactions" editable="bottom" colors="gray:amount==0">
|
||||
<field name="move_line_id" context="{'journal_id':parent.journal_id, 'partner_id':parent.partner_id}"
|
||||
on_change="onchange_move_line_id(move_line_id)"
|
||||
domain="[('account_id.type','in',('receivable','payable')), ('reconcile_id','=', False), ('partner_id','=',parent.partner_id)]"
|
||||
required="1"
|
||||
groups="account.group_account_user"/>
|
||||
<field name="account_id" groups="base.group_no_one" domain="[('type','=','receivable')]"/>
|
||||
<field name="date_original" readonly="1"/>
|
||||
<field name="date_due" readonly="1"/>
|
||||
<field name="amount_original" readonly="1"/>
|
||||
<field name="amount_unreconciled" readonly="1" groups="account.group_account_user"/>
|
||||
<field name="reconcile" on_change="onchange_reconcile(reconcile, amount, amount_unreconciled, context)" groups="account.group_account_user"/>
|
||||
<field name="amount" sum="Total Allocation" on_change="onchange_amount(amount, amount_unreconciled, context)" string="Allocation"/>
|
||||
</tree>
|
||||
</field>
|
||||
<label for="line_dr_ids" attrs="{'invisible': [('pre_line','=',False)]}"/>
|
||||
<field name="line_dr_ids" attrs="{'invisible': [('pre_line','=',False)]}" context="{'journal_id':journal_id, 'partner_id':partner_id}" on_change="onchange_line_ids(line_dr_ids, line_cr_ids, amount, currency_id, type, context)">
|
||||
<tree string="Credits" editable="bottom" colors="gray:amount==0">
|
||||
<field name="move_line_id" context="{'journal_id':parent.journal_id, 'partner_id':parent.partner_id}"
|
||||
on_change="onchange_move_line_id(move_line_id)"
|
||||
domain="[('account_id.type','in',('receivable','payable')), ('reconcile_id','=', False), ('partner_id','=',parent.partner_id)]"
|
||||
required="1"/>
|
||||
<field name="account_id" groups="base.group_no_one" domain="[('type','=','receivable')]"/>
|
||||
<field name="date_original" readonly="1"/>
|
||||
<field name="date_due" readonly="1"/>
|
||||
<field name="amount_original" readonly="1"/>
|
||||
<field name="amount_unreconciled" readonly="1"/>
|
||||
<field name="reconcile" on_change="onchange_reconcile(reconcile, amount, amount_unreconciled, context)"/>
|
||||
<field name="amount" sum="Total Allocation" on_change="onchange_amount(amount, amount_unreconciled, context)" string="Allocation"/>
|
||||
</tree>
|
||||
</field>
|
||||
<group col="3">
|
||||
<group>
|
||||
<field name="narration" colspan="2" nolabel="1"/>
|
||||
</group>
|
||||
<group col="4" attrs="{'invisible':[('currency_id','=',False),('is_multi_currency','=',False)]}">
|
||||
<field name="is_multi_currency" invisible="1"/>
|
||||
<field name="payment_rate" required="1" on_change="onchange_rate(payment_rate, amount, currency_id, payment_rate_currency_id, company_id, context)" colspan="3"/>
|
||||
<field name="payment_rate_currency_id" colspan="1" nolabel="1" on_change="onchange_payment_rate_currency(currency_id, payment_rate, payment_rate_currency_id, date, amount, company_id, context)" groups="base.group_multi_currency"/>
|
||||
<field name="paid_amount_in_company_currency" colspan="4" invisible="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="writeoff_amount"/>
|
||||
<field name="payment_option" required="1"/>
|
||||
<field name="writeoff_acc_id"
|
||||
attrs="{'invisible':[('payment_option','!=','with_writeoff')], 'required':[('payment_option','=','with_writeoff')]}"
|
||||
domain="[('type','=','other')]"/>
|
||||
<field name="comment"
|
||||
attrs="{'invisible':[('payment_option','!=','with_writeoff')]}"/>
|
||||
<field name="analytic_id"
|
||||
groups="analytic.group_analytic_accounting"/>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
<footer>
|
||||
<button name="button_proforma_voucher" string="Pay" class="oe_highlight" type="object"/> or
|
||||
<button string="Cancel" class="oe_link" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="view_vendor_receipt_form">
|
||||
<field name="name">account.voucher.receipt.form</field>
|
||||
<field name="model">account.voucher</field>
|
||||
|
@ -293,7 +402,7 @@
|
|||
<field name="state" widget="statusbar" statusbar_visible="draft,posted" statusbar_colors='{"proforma":"blue"}'/>
|
||||
</header>
|
||||
<sheet>
|
||||
<h1><field name="number"/></h1>
|
||||
<h1 attrs="{'invisible': [('number','=',False)]}"><field name="number"/></h1>
|
||||
<group>
|
||||
<group>
|
||||
<field name="partner_id" domain="[('customer','=',True)]" required="1" invisible="context.get('line_type', False)" on_change="onchange_partner_id(partner_id, journal_id, amount, currency_id, type, date, context)" string="Customer" context="{'search_default_customer': 1}"/>
|
||||
|
@ -325,9 +434,9 @@
|
|||
<field name="type" invisible="True"/>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<notebook>
|
||||
<page string="Payment Information" groups="base.group_user">
|
||||
<label for="line_cr_ids"/>
|
||||
<field name="line_cr_ids" context="{'journal_id':journal_id, 'type':type, 'partner_id':partner_id}" on_change="onchange_line_ids(line_dr_ids, line_cr_ids, amount, currency_id, type, context)">
|
||||
<tree string="Invoices and outstanding transactions" editable="bottom" colors="gray:amount==0">
|
||||
<field name="move_line_id" context="{'journal_id':parent.journal_id, 'partner_id':parent.partner_id}"
|
||||
|
@ -344,6 +453,7 @@
|
|||
<field name="amount" sum="Total Allocation" on_change="onchange_amount(amount, amount_unreconciled, context)" string="Allocation"/>
|
||||
</tree>
|
||||
</field>
|
||||
<label for="line_dr_ids" attrs="{'invisible': [('pre_line','=',False)]}"/>
|
||||
<field name="line_dr_ids" attrs="{'invisible': [('pre_line','=',False)]}" context="{'journal_id':journal_id, 'partner_id':partner_id}" on_change="onchange_line_ids(line_dr_ids, line_cr_ids, amount, currency_id, type, context)">
|
||||
<tree string="Credits" editable="bottom" colors="gray:amount==0">
|
||||
<field name="move_line_id" context="{'journal_id':parent.journal_id, 'partner_id':parent.partner_id}"
|
||||
|
|
|
@ -44,6 +44,5 @@ that have no counterpart in the general financial accounts.
|
|||
'demo': [],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate' : '00462253285027988541',
|
||||
}
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -223,9 +223,10 @@ class account_analytic_account(osv.osv):
|
|||
if not default:
|
||||
default = {}
|
||||
analytic = self.browse(cr, uid, id, context=context)
|
||||
default['code'] = False
|
||||
default['line_ids'] = []
|
||||
default['name'] = analytic['name'] + ' (' + _('copy') + ')'
|
||||
default.update(
|
||||
code=False,
|
||||
line_ids=[],
|
||||
name=_("%s (copy)") % (analytic['name']))
|
||||
return super(account_analytic_account, self).copy(cr, uid, id, default, context=context)
|
||||
|
||||
def on_change_company(self, cr, uid, id, company_id):
|
||||
|
|
|
@ -45,6 +45,5 @@ compatible with older configurations.
|
|||
'demo': [],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate': '0082277138269',
|
||||
}
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -48,7 +48,6 @@ anonymization process to recover your previous data.
|
|||
],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate': '00719010980872226045',
|
||||
'images': ['images/anonymization1.jpeg','images/anonymization2.jpeg','images/anonymization3.jpeg'],
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@ membership products (schemes).
|
|||
'demo': [],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate': '0078696047261',
|
||||
'images': ['images/association1.jpeg'],
|
||||
}
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -42,7 +42,6 @@ and can check logs.
|
|||
'demo': ['audittrail_demo.xml'],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate': '0062572348749',
|
||||
'images': ['images/audittrail1.jpeg','images/audittrail2.jpeg','images/audittrail3.jpeg'],
|
||||
}
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -442,11 +442,13 @@ class audittrail_objects_proxy(object_proxy):
|
|||
|
||||
# if at least one modification has been found
|
||||
for model_id, resource_id in lines:
|
||||
name = pool.get(model.model).name_get(cr, uid, [resource_id])[0][1]
|
||||
vals = {
|
||||
'method': method,
|
||||
'object_id': model_id,
|
||||
'user_id': uid,
|
||||
'res_id': resource_id,
|
||||
'name': name,
|
||||
}
|
||||
if (model_id, resource_id) not in old_values and method not in ('copy', 'read'):
|
||||
# the resource was not existing so we are forcing the method to 'create'
|
||||
|
|
|
@ -107,7 +107,6 @@ authentication if installed at the same time.
|
|||
],
|
||||
'auto_install': False,
|
||||
'installable': True,
|
||||
'certificate' : '001141446349334700221',
|
||||
'external_dependencies' : {
|
||||
'python' : ['ldap'],
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<field name="ldap_server"/>
|
||||
<field name="ldap_server_port"/>
|
||||
<field name="ldap_binddn"/>
|
||||
<field name="ldap_password"/>
|
||||
<field name="ldap_password" password="True"/>
|
||||
<field name="ldap_base"/>
|
||||
<field name="ldap_filter"/>
|
||||
<field name="create_user"/>
|
||||
|
|
|
@ -44,7 +44,6 @@ trigger an automatic reminder email.
|
|||
'demo': [],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate' : '001017908446466333429',
|
||||
'images': ['images/base_action_rule1.jpeg','images/base_action_rule2.jpeg','images/base_action_rule3.jpeg'],
|
||||
}
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -21,6 +21,5 @@
|
|||
|
||||
import base_calendar
|
||||
import crm_meeting
|
||||
import wizard
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
'name': 'Calendar',
|
||||
'version': '1.0',
|
||||
'depends': ['base', 'base_status', 'mail', 'base_action_rule'],
|
||||
'summary': 'Personal & Shared Calendar',
|
||||
'description': """
|
||||
This is a full-featured calendar system.
|
||||
========================================
|
||||
|
@ -30,9 +31,7 @@ This is a full-featured calendar system.
|
|||
It supports:
|
||||
------------
|
||||
- Calendar of events
|
||||
- Alerts (create requests)
|
||||
- Recurring events
|
||||
- Invitations to people
|
||||
|
||||
If you need to manage your meetings, you should install the CRM module.
|
||||
""",
|
||||
|
@ -43,7 +42,6 @@ If you need to manage your meetings, you should install the CRM module.
|
|||
'data': [
|
||||
'security/calendar_security.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'wizard/base_calendar_invite_attendee_view.xml',
|
||||
'base_calendar_view.xml',
|
||||
'crm_meeting_view.xml',
|
||||
'base_calendar_data.xml',
|
||||
|
@ -53,7 +51,6 @@ If you need to manage your meetings, you should install the CRM module.
|
|||
'installable': True,
|
||||
'application': True,
|
||||
'auto_install': False,
|
||||
'certificate': '00694071962960352821',
|
||||
'images': ['images/base_calendar1.jpeg','images/base_calendar2.jpeg','images/base_calendar3.jpeg','images/base_calendar4.jpeg',],
|
||||
}
|
||||
|
||||
|
|
|
@ -971,8 +971,8 @@ class calendar_event(osv.osv):
|
|||
event = datas['id']
|
||||
if datas.get('interval', 0) < 0:
|
||||
raise osv.except_osv(_('Warning!'), _('Interval cannot be negative.'))
|
||||
if datas.get('count', 0) < 0:
|
||||
raise osv.except_osv(_('Warning!'), _('Count cannot be negative.'))
|
||||
if datas.get('count', 0) <= 0:
|
||||
raise osv.except_osv(_('Warning!'), _('Count cannot be negative or 0.'))
|
||||
if datas['recurrency']:
|
||||
result[event] = self.compute_rule_string(datas)
|
||||
else:
|
||||
|
@ -996,7 +996,7 @@ class calendar_event(osv.osv):
|
|||
'sequence': fields.integer('Sequence'),
|
||||
'name': fields.char('Description', size=64, required=False, states={'done': [('readonly', True)]}),
|
||||
'date': fields.datetime('Date', states={'done': [('readonly', True)]}, required=True,),
|
||||
'date_deadline': fields.datetime('Deadline', states={'done': [('readonly', True)]}, required=True,),
|
||||
'date_deadline': fields.datetime('End Date', states={'done': [('readonly', True)]}, required=True,),
|
||||
'create_date': fields.datetime('Created', readonly=True),
|
||||
'duration': fields.float('Duration', states={'done': [('readonly', True)]}),
|
||||
'description': fields.text('Description', states={'done': [('readonly', True)]}),
|
||||
|
@ -1058,8 +1058,40 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
|||
'active': fields.boolean('Active', help="If the active field is set to \
|
||||
true, it will allow you to hide the event alarm information without removing it."),
|
||||
'recurrency': fields.boolean('Recurrent', help="Recurrent Meeting"),
|
||||
'partner_ids': fields.many2many('res.partner', string='Attendees', states={'done': [('readonly', True)]}),
|
||||
}
|
||||
|
||||
def create_attendees(self, cr, uid, ids, context):
|
||||
att_obj = self.pool.get('calendar.attendee')
|
||||
user_obj = self.pool.get('res.users')
|
||||
current_user = user_obj.browse(cr, uid, uid, context=context)
|
||||
for event in self.browse(cr, uid, ids, context):
|
||||
attendees = {}
|
||||
for att in event.attendee_ids:
|
||||
attendees[att.partner_id.id] = True
|
||||
new_attendees = []
|
||||
mail_to = []
|
||||
for partner in event.partner_ids:
|
||||
if partner.id in attendees:
|
||||
continue
|
||||
att_id = self.pool.get('calendar.attendee').create(cr, uid, {
|
||||
'partner_id': partner.id,
|
||||
'user_id': partner.user_ids and partner.user_ids[0].id or False,
|
||||
'ref': self._name+','+str(event.id),
|
||||
'email': partner.email
|
||||
}, context=context)
|
||||
if partner.email:
|
||||
mail_to.append(partner.email)
|
||||
self.write(cr, uid, [event.id], {
|
||||
'attendee_ids': [(4, att_id)]
|
||||
}, context=context)
|
||||
new_attendees.append(att_id)
|
||||
|
||||
if mail_to and current_user.email:
|
||||
att_obj._send_mail(cr, uid, new_attendees, mail_to,
|
||||
email_from = current_user.email)
|
||||
return True
|
||||
|
||||
def default_organizer(self, cr, uid, context=None):
|
||||
user_pool = self.pool.get('res.users')
|
||||
user = user_pool.browse(cr, uid, uid, context=context)
|
||||
|
@ -1366,6 +1398,8 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
|||
vals['vtimezone'] = vals['vtimezone'][40:]
|
||||
|
||||
res = super(calendar_event, self).write(cr, uid, ids, vals, context=context)
|
||||
if vals.get('partner_ids', False):
|
||||
self.create_attendees(cr, uid, ids, context)
|
||||
|
||||
if ('alarm_id' in vals or 'base_calendar_alarm_id' in vals)\
|
||||
or ('date' in vals or 'duration' in vals or 'date_deadline' in vals):
|
||||
|
@ -1489,17 +1523,10 @@ rule or repeating pattern of time to exclude from the recurring rule."),
|
|||
if vals.get('vtimezone', '') and vals.get('vtimezone', '').startswith('/freeassociation.sourceforge.net/tzfile/'):
|
||||
vals['vtimezone'] = vals['vtimezone'][40:]
|
||||
|
||||
#updated_vals = self.onchange_dates(cr, uid, [],
|
||||
# vals.get('date', False),
|
||||
# vals.get('duration', False),
|
||||
# vals.get('date_deadline', False),
|
||||
# vals.get('allday', False),
|
||||
# context=context)
|
||||
#vals.update(updated_vals.get('value', {}))
|
||||
|
||||
res = super(calendar_event, self).create(cr, uid, vals, context)
|
||||
alarm_obj = self.pool.get('res.alarm')
|
||||
alarm_obj.do_alarm_create(cr, uid, [res], self._name, 'date', context=context)
|
||||
self.create_attendees(cr, uid, [res], context)
|
||||
return res
|
||||
|
||||
def do_tentative(self, cr, uid, ids, context=None, *args):
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
<header>
|
||||
<button name="do_tentative" states="needs-action,declined,accepted" string="Uncertain" type="object" class="oe_highlight"/>
|
||||
<button name="do_accept" string="Accept" states="needs-action,tentative,declined" type="object" class="oe_highlight"/>
|
||||
<button name="%(base_calendar.action_view_calendar_invite_attendee_wizard)d" string="Delegate" type="action" states="needs-action,tentative,declined,accepted" context="{'model' : 'calendar.attendee', 'attendee_field' : 'child_ids'}"/>
|
||||
<button name="do_decline" string="Decline" states="needs-action,tentative,accepted" type="object" class="oe_highlight"/>
|
||||
<field name="state" widget="statusbar"
|
||||
statusbar_visible="tentative,needs-action,accepted" statusbar_colors='{"proforma":"blue"}'/>
|
||||
|
@ -226,10 +225,6 @@
|
|||
<field name="description"/>
|
||||
</page>
|
||||
<page string="Invitation Detail">
|
||||
<button string="Invite People"
|
||||
name="%(base_calendar.action_view_calendar_invite_attendee_wizard)d"
|
||||
icon="terp-partner" type="action"
|
||||
context="{'model' : 'calendar.event', 'attendee_field':'attendee_ids'}" colspan="2"/>
|
||||
<field name="attendee_ids" colspan="4"
|
||||
nolabel="1" widget="one2many" mode="tree">
|
||||
<tree string="Invitation details" editable="top">
|
||||
|
@ -248,12 +243,6 @@
|
|||
<button name="do_decline" string="Decline"
|
||||
states="needs-action,tentative,accepted"
|
||||
type="object" icon="gtk-cancel"/>
|
||||
<button
|
||||
name="%(base_calendar.action_view_calendar_invite_attendee_wizard)d"
|
||||
string="Delegate" type="action"
|
||||
icon="gtk-sort-descending"
|
||||
states="needs-action,tentative,declined,accepted"
|
||||
context="{'model' : 'calendar.attendee', 'attendee_field' : 'child_ids'}"/>
|
||||
</tree>
|
||||
<form string="Invitation details" version="7.0">
|
||||
<notebook colspan="4">
|
||||
|
@ -281,13 +270,6 @@
|
|||
states="needs-action,tentative,accepted"
|
||||
type="object"
|
||||
icon="gtk-cancel"/>
|
||||
<button
|
||||
name="%(base_calendar.action_view_calendar_invite_attendee_wizard)d"
|
||||
string="Delegate"
|
||||
type="action"
|
||||
icon="gtk-sort-descending"
|
||||
states="needs-action,tentative,declined,accepted"
|
||||
context="{'model' : 'calendar.attendee', 'attendee_field' : 'child_ids'}"/>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
|
@ -428,6 +410,5 @@
|
|||
name="Events" parent="base.menu_calendar_configuration"
|
||||
sequence="15" action="action_view_event"/>
|
||||
|
||||
<menuitem name="Agenda" id="mail_menu_agenda" parent="mail.mail_my_stuff" sequence="10" action="action_view_event"/>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -71,6 +71,34 @@ class crm_meeting(base_state, osv.Model):
|
|||
default['attendee_ids'] = False
|
||||
return super(crm_meeting, self).copy(cr, uid, id, default, context)
|
||||
|
||||
def onchange_partner_ids(self, cr, uid, ids, value, context=None):
|
||||
""" The basic purpose of this method is to check that destination partners
|
||||
effectively have email addresses. Otherwise a warning is thrown.
|
||||
:param value: value format: [[6, 0, [3, 4]]]
|
||||
"""
|
||||
res = {'value': {}}
|
||||
if not value or not value[0] or not value[0][0] == 6:
|
||||
return
|
||||
res.update(self.check_partners_email(cr, uid, value[0][2], context=context))
|
||||
return res
|
||||
|
||||
def check_partners_email(self, cr, uid, partner_ids, context=None):
|
||||
""" Verify that selected partner_ids have an email_address defined.
|
||||
Otherwise throw a warning. """
|
||||
partner_wo_email_lst = []
|
||||
for partner in self.pool.get('res.partner').browse(cr, uid, partner_ids, context=context):
|
||||
if not partner.email:
|
||||
partner_wo_email_lst.append(partner)
|
||||
if not partner_wo_email_lst:
|
||||
return {}
|
||||
warning_msg = _('The following contacts have no email address :')
|
||||
for partner in partner_wo_email_lst:
|
||||
warning_msg += '\n- %s' % (partner.name)
|
||||
return {'warning': {
|
||||
'title': _('Email addresses not found'),
|
||||
'message': warning_msg,
|
||||
}
|
||||
}
|
||||
# ----------------------------------------
|
||||
# OpenChatter
|
||||
# ----------------------------------------
|
||||
|
@ -80,7 +108,7 @@ class crm_meeting(base_state, osv.Model):
|
|||
return [('date','<=',time.strftime('%Y-%M-%D 23:59:59')), ('date_deadline','>=', time.strftime('%Y-%M-%D 00:00:00')), ('user_id','=',uid)]
|
||||
|
||||
def case_get_note_msg_prefix(self, cr, uid, id, context=None):
|
||||
return 'Meeting'
|
||||
return _('Meeting')
|
||||
|
||||
def case_open_send_note(self, cr, uid, ids, context=None):
|
||||
return self.message_post(cr, uid, ids, body=_("Meeting <b>confirmed</b>."), context=context)
|
||||
|
|
|
@ -80,43 +80,48 @@
|
|||
</h1>
|
||||
<label for="partner_ids" class="oe_edit_only"/>
|
||||
<h2>
|
||||
<field name="partner_ids" widget="many2many_tags"/>
|
||||
<field name="partner_ids" widget="many2many_tags"
|
||||
context="{'force_email':True}"
|
||||
on_change="onchange_partner_ids(partner_ids)"/>
|
||||
</h2>
|
||||
</div>
|
||||
<notebook>
|
||||
<page string="Meeting Detail">
|
||||
<group>
|
||||
<group>
|
||||
<field name="user_id"/>
|
||||
<field name="date" string="Starting at"/>
|
||||
<label for="duration"/>
|
||||
<div>
|
||||
<field name="duration" widget="float_time"
|
||||
on_change="onchange_dates(date,duration,False,allday)"
|
||||
class="oe_inline" attrs="{'invisible': [('allday','=',True)]}"/>
|
||||
<label string="hours" attrs="{'invisible': [('allday','=',True)]}"/>
|
||||
(<field name="allday" on_change="onchange_dates(date,False,False,allday)" class="oe_inline"/>
|
||||
<label for="allday" string="All Day?"/>)
|
||||
</div>
|
||||
<field name="date_deadline" groups="base.group_no_one"
|
||||
attrs="{'invisible': [('allday','=',True)]}"
|
||||
on_change="onchange_dates(date,False,date_deadline)"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="user_id" groups="base.group_no_one"/>
|
||||
<field name="categ_ids" widget="many2many_tags"/>
|
||||
<field name="location"/>
|
||||
<field name="organizer" groups="base.group_no_one"/>
|
||||
</group>
|
||||
|
||||
</group>
|
||||
<label for="description"/>
|
||||
<field name="description"/>
|
||||
</page>
|
||||
<page string="Options">
|
||||
<group>
|
||||
<group>
|
||||
<label for="date" string="Starting at"/>
|
||||
<div>
|
||||
<field name="date"/>
|
||||
<span attrs="{'invisible': [('allday','=',True)]}">
|
||||
(<field name="duration" widget="float_time"
|
||||
on_change="onchange_dates(date,duration,False,allday)"
|
||||
class="oe_inline"/> hours)
|
||||
</span>
|
||||
|
||||
</div>
|
||||
|
||||
<label for="date_deadline" />
|
||||
<div>
|
||||
<field name="date_deadline"
|
||||
string="End Date" attrs="{'invisible': [('allday','=',True)]}"
|
||||
on_change="onchange_dates(date,False,date_deadline)"/>
|
||||
(<field name="allday" on_change="onchange_dates(date,False,False,allday)" class="oe_inline"/>
|
||||
<label for="allday" string="All Day?"/>)
|
||||
</div>
|
||||
<field name="recurrency"
|
||||
attrs="{'readonly': [('recurrent_uid','!=',False)]}"/>
|
||||
<field name="recurrency"
|
||||
attrs="{'readonly': [('recurrent_uid','!=',False)]}"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="alarm_id" widget="selection" />
|
||||
<field name="alarm_id" widget="selection" groups="base.group_no_one"/>
|
||||
<field name="class"/>
|
||||
<field name="show_as"/>
|
||||
<field name="rrule" invisible="1" readonly="1"/>
|
||||
|
@ -136,7 +141,7 @@
|
|||
<field name="end_date" attrs="{'invisible' : [('end_type', '!=', 'end_date')], 'required': [('end_type', '=', 'end_date')]}" class="oe_inline"/>
|
||||
</div>
|
||||
<label string="Select Weekdays" attrs="{'invisible' :[('rrule_type','not in', ['weekly'])]}"/>
|
||||
<group col="4" colspan="1" name="weekdays" attrs="{'invisible' :[('rrule_type','not in', ['weekly'])]}">
|
||||
<group col="2" colspan="1" name="weekdays" attrs="{'invisible' :[('rrule_type','not in', ['weekly'])]}">
|
||||
<field name="mo" />
|
||||
<field name="tu" />
|
||||
<field name="we" />
|
||||
|
@ -162,21 +167,17 @@
|
|||
|
||||
</group>
|
||||
</group>
|
||||
<label for="description"/>
|
||||
<field name="description"/>
|
||||
</page>
|
||||
<page string="Invitation Detail">
|
||||
<button string="Invite People"
|
||||
name="%(base_calendar.action_view_calendar_invite_attendee_wizard)d"
|
||||
type="action"
|
||||
attrs="{'readonly': [('state', '=', 'done')]}"
|
||||
context="{'model' : 'crm.meeting', 'attendee_field':'attendee_ids'}" colspan="2"/>
|
||||
<!--
|
||||
Temporarily removing invitation feature as the implementation
|
||||
was not clean. Invitation should be trigerred automatically
|
||||
based on partner_ids.
|
||||
-->
|
||||
<page string="Invitations">
|
||||
<field name="attendee_ids" widget="one2many" mode="tree">
|
||||
<tree string="Invitation details" editable="top">
|
||||
<field name="sent_by_uid" string="From"/>
|
||||
<field name="user_id" string="To"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="email" string="Mail To"/>
|
||||
<field name="role" />
|
||||
<field name="state" />
|
||||
<button name="do_tentative"
|
||||
states="needs-action,declined,accepted"
|
||||
|
@ -188,11 +189,6 @@
|
|||
<button name="do_decline" string="Decline"
|
||||
states="needs-action,tentative,accepted"
|
||||
type="object" />
|
||||
<button
|
||||
name="%(base_calendar.action_view_calendar_invite_attendee_wizard)d"
|
||||
string="Delegate" type="action"
|
||||
states="needs-action,tentative,declined,accepted"
|
||||
context="{'model' : 'calendar.attendee', 'attendee_field' : 'child_ids'}" />
|
||||
</tree>
|
||||
<form string="Invitation details" version="7.0">
|
||||
<header>
|
||||
|
@ -205,10 +201,6 @@
|
|||
<button name="do_decline" type="object"
|
||||
states="needs-action,tentative,accepted"
|
||||
string="Decline" />
|
||||
<button name="%(base_calendar.action_view_calendar_invite_attendee_wizard)d" type="action"
|
||||
states="needs-action,tentative,declined,accepted"
|
||||
string="Delegate"
|
||||
context="{'model' : 'calendar.attendee', 'attendee_field' : 'child_ids'}" />
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,open,done"/>
|
||||
</header>
|
||||
<group>
|
||||
|
@ -219,6 +211,7 @@
|
|||
<field name="role" />
|
||||
</group>
|
||||
<group>
|
||||
<field name="partner_id"/>
|
||||
<field name="user_id"/>
|
||||
</group>
|
||||
</group>
|
||||
|
@ -307,7 +300,7 @@
|
|||
<p class="oe_view_nocontent_create">
|
||||
Click to schedule a new meeting.
|
||||
</p><p>
|
||||
The agenda is shared between employees and fully integrated with
|
||||
The calendar is shared between employees and fully integrated with
|
||||
other applications such as the employee holidays or the business
|
||||
opportunities.
|
||||
</p>
|
||||
|
@ -339,7 +332,11 @@
|
|||
</record>
|
||||
|
||||
<menuitem id="menu_crm_meeting" parent="base.menu_sales" sequence="8"
|
||||
name="Meetings" action="action_crm_meeting"/>
|
||||
name="Calendar" action="action_crm_meeting"/>
|
||||
|
||||
<menuitem name="Calendar"
|
||||
id="mail_menu_calendar" parent="mail.mail_my_stuff"
|
||||
sequence="10" action="action_crm_meeting"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -54,24 +54,3 @@
|
|||
-
|
||||
!python {model: calendar.event}: |
|
||||
self.write(cr, uid, [ref("calendar_event_alldaytestevent0")], {'alarm_id': ref("res_alarm_daybeforeeventstarts0")})
|
||||
-
|
||||
In order to assign attendee I will invite Demo user
|
||||
-
|
||||
!record {model: base_calendar.invite.attendee, id: base_calendar_invite_attendee_0}:
|
||||
type: internal
|
||||
send_mail: False
|
||||
partner_id: base.res_partner_9 # Put bcz of problem in read
|
||||
user_ids:
|
||||
- base.user_demo
|
||||
-
|
||||
Then I click on Invite Button
|
||||
-
|
||||
!python {model: base_calendar.invite.attendee}: |
|
||||
self.do_invite(cr, uid, [ref("base_calendar_invite_attendee_0")], {'active_id': ref("calendar_event_alldaytestevent0"), 'model' : 'calendar.event', 'attendee_field':'attendee_ids'})
|
||||
-
|
||||
Now I will Accept this invitation
|
||||
-
|
||||
!python {model: calendar.attendee}: |
|
||||
ids = self.search(cr, uid, [('ref', '=', 'calendar.event' + ',' + str(ref("calendar_event_alldaytestevent0")))])
|
||||
if ids:
|
||||
self.do_accept(cr, uid, ids, context=context)
|
||||
|
|
|
@ -1,170 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from .. import base_calendar
|
||||
from osv import fields, osv
|
||||
from tools.translate import _
|
||||
import tools
|
||||
|
||||
|
||||
class base_calendar_invite_attendee(osv.osv_memory):
|
||||
"""
|
||||
Invite attendee.
|
||||
"""
|
||||
|
||||
_name = "base_calendar.invite.attendee"
|
||||
_description = "Invite Attendees"
|
||||
|
||||
_columns = {
|
||||
'type': fields.selection([('internal', 'Internal User'), \
|
||||
('external', 'External Email'), \
|
||||
('partner', 'Partner Contacts')], 'Type', required=True, help="Select whom you want to Invite"),
|
||||
'user_ids': fields.many2many('res.users', 'invite_user_rel',
|
||||
'invite_id', 'user_id', 'Users'),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner'),
|
||||
'email': fields.char('Email', size=124, help="Provide external email address who will receive this invitation."),
|
||||
'contact_ids': fields.many2many('res.partner', 'invite_contact_rel',
|
||||
'invite_id', 'contact_id', 'Contacts'),
|
||||
'send_mail': fields.boolean('Send mail?', help='Check this if you want to \
|
||||
send an Email to Invited Person')
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'type': 'internal',
|
||||
'send_mail': True
|
||||
}
|
||||
|
||||
def do_invite(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
Invites attendee for meeting..
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of base calendar invite attendee’s IDs.
|
||||
@param context: A standard dictionary for contextual values
|
||||
@return: Dictionary of {}.
|
||||
"""
|
||||
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
model = False
|
||||
context_id = context and context.get('active_id', False) or False
|
||||
if not context or not context.get('model'):
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
else:
|
||||
model = context.get('model')
|
||||
|
||||
model_field = context.get('attendee_field', False)
|
||||
obj = self.pool.get(model)
|
||||
res_obj = obj.browse(cr, uid, context_id, context=context)
|
||||
att_obj = self.pool.get('calendar.attendee')
|
||||
user_obj = self.pool.get('res.users')
|
||||
current_user = user_obj.browse(cr, uid, uid, context=context)
|
||||
|
||||
for datas in self.read(cr, uid, ids, context=context):
|
||||
type = datas.get('type')
|
||||
vals = []
|
||||
mail_to = []
|
||||
attendees = []
|
||||
ref = {}
|
||||
|
||||
if not model == 'calendar.attendee':
|
||||
if context_id:
|
||||
ref = {'ref': '%s,%s' % (model, base_calendar.base_calendar_id2real_id(context_id))}
|
||||
else:
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
if type == 'internal':
|
||||
|
||||
if not datas.get('user_ids'):
|
||||
raise osv.except_osv(_('Error!'), ("Please select any user."))
|
||||
for user_id in datas.get('user_ids'):
|
||||
user = user_obj.browse(cr, uid, user_id)
|
||||
res = {
|
||||
'user_id': user_id,
|
||||
'email': user.email
|
||||
}
|
||||
res.update(ref)
|
||||
vals.append(res)
|
||||
if user.email:
|
||||
mail_to.append(user.email)
|
||||
|
||||
elif type == 'external' and datas.get('email'):
|
||||
res = {'email': datas['email']}
|
||||
res.update(ref)
|
||||
vals.append(res)
|
||||
mail_to.append(datas['email'])
|
||||
|
||||
elif type == 'partner':
|
||||
add_obj = self.pool.get('res.partner')
|
||||
for contact in add_obj.browse(cr, uid, datas['contact_ids']):
|
||||
res = {
|
||||
'partner_id': contact.id,
|
||||
'email': contact.email
|
||||
}
|
||||
res.update(ref)
|
||||
vals.append(res)
|
||||
if contact.email:
|
||||
mail_to.append(contact.email)
|
||||
|
||||
for att_val in vals:
|
||||
if model == 'calendar.attendee':
|
||||
att = att_obj.browse(cr, uid, context_id)
|
||||
att_val.update({
|
||||
'parent_ids': [(4, att.id)],
|
||||
'ref': att.ref and (att.ref._name + ',' +str(att.ref.id)) or False
|
||||
})
|
||||
|
||||
attendees.append(att_obj.create(cr, uid, att_val))
|
||||
if model_field:
|
||||
for attendee in attendees:
|
||||
obj.write(cr, uid, res_obj.id, {model_field: [(4, attendee)]})
|
||||
|
||||
if datas.get('send_mail'):
|
||||
if not mail_to:
|
||||
name = map(lambda x: x[1], filter(lambda x: type==x[0], \
|
||||
self._columns['type'].selection))
|
||||
raise osv.except_osv(_('Error!'), _("%s must have an email address to send mail.") %(name[0]))
|
||||
att_obj._send_mail(cr, uid, attendees, mail_to, \
|
||||
email_from = current_user.email or tools.config.get('email_from', False))
|
||||
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
|
||||
def onchange_partner_id(self, cr, uid, ids, partner_id, *args, **argv):
|
||||
"""
|
||||
Make entry on contact_ids on change of partner_id field.
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of base calendar invite attendee’s IDs.
|
||||
@param partner_id: id of Partner
|
||||
@return: dictionary of value.
|
||||
"""
|
||||
|
||||
if not partner_id:
|
||||
return {'value': {'contact_ids': []}}
|
||||
cr.execute('SELECT id FROM res_partner \
|
||||
WHERE id=%s or parent_id =%s' , (partner_id,partner_id,))
|
||||
contacts = map(lambda x: x[0], cr.fetchall())
|
||||
return {'value': {'contact_ids': contacts}}
|
||||
|
||||
base_calendar_invite_attendee()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -1,55 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<!-- Attendee invite wizard-->
|
||||
|
||||
<record id="view_calendar_invite_attendee_wizard"
|
||||
model="ir.ui.view">
|
||||
<field name="name">Invite Attendees</field>
|
||||
<field name="model">base_calendar.invite.attendee</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Invite People" version="7.0">
|
||||
<separator string="Invite People" colspan="4"/>
|
||||
<field name="type"/>
|
||||
<field name="send_mail"/>
|
||||
<notebook colspan="4">
|
||||
<page string="Data">
|
||||
<group col="2" colspan="6" attrs="{'invisible': [('type', '!=', 'external')]}">
|
||||
<field name="email" colspan="4" attrs="{'required': [('type', '=', 'external')]}"/>
|
||||
</group>
|
||||
<group col="2" colspan="6" attrs="{'invisible': [('type', '!=', 'internal')]}">
|
||||
<separator string="Users" colspan="4"/>
|
||||
<field name="user_ids" colspan="4" nolabel="1" height="180"/>
|
||||
<newline/>
|
||||
</group>
|
||||
<group col="2" colspan="6" attrs="{'invisible': [('type', '!=', 'partner')]}">
|
||||
<field name="partner_id" colspan="2" on_change="onchange_partner_id(partner_id)" attrs="{'required': [('type', '=', 'partner')]}"/>
|
||||
<newline/>
|
||||
<separator string="Partner Contacts" colspan="6"/>
|
||||
<field name="contact_ids" colspan="4" nolabel="1" domain="[('id', 'child_of', [partner_id])]" attrs="{'readonly': [('type', '!=', 'partner')]}"/>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
<footer>
|
||||
<button name="do_invite" string="Invite" type="object" class="oe_highlight"/>
|
||||
or
|
||||
<button string="Cancel" class="oe_link" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<!-- Attendee invite action-->
|
||||
|
||||
<record id="action_view_calendar_invite_attendee_wizard" model="ir.actions.act_window">
|
||||
<field name="name">Invite Attendees</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">base_calendar.invite.attendee</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -58,7 +58,6 @@ will disable LDAP authentication completely if installed at the same time.
|
|||
'data': [],
|
||||
'auto_install': False,
|
||||
'installable': True,
|
||||
'certificate': '00721290471310299725',
|
||||
}
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -35,7 +35,6 @@ with a single statement.
|
|||
'data': ['base_iban_data.xml' , 'base_iban_view.xml'],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate': '0050014379549',
|
||||
'images': ['images/base_iban1.jpeg'],
|
||||
}
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -42,7 +42,6 @@ This module generates the Technical Guides of selected modules in Restructured T
|
|||
],
|
||||
'demo': [],
|
||||
'installable': True,
|
||||
'certificate': '001288481437217734509',
|
||||
'images': ['images/base_module_doc_rst1.jpeg'],
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,6 @@ Select datetime criteria of recording and objects to be recorded and Record modu
|
|||
],
|
||||
'demo': [],
|
||||
'installable': True,
|
||||
'certificate': '0083134865813',
|
||||
'images': ['images/base_module_record1.jpeg','images/base_module_record2.jpeg','images/base_module_record3.jpeg',]
|
||||
}
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -38,7 +38,6 @@ Once you have modified it you can upload the report using the same wizard.
|
|||
'demo': [],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate': '0056379010493',
|
||||
'images': ['images/base_report_designer1.jpeg','images/base_report_designer2.jpeg',],
|
||||
}
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -43,7 +43,6 @@ Shows you a list of applications features to install from.
|
|||
'demo': [],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate': '0086711085869',
|
||||
'images': ['images/base_setup1.jpeg','images/base_setup2.jpeg','images/base_setup3.jpeg','images/base_setup4.jpeg',],
|
||||
'js': ['static/src/js/base_setup.js'],
|
||||
'css': ['static/src/css/base_setup.css'],
|
||||
|
|
|
@ -307,7 +307,7 @@ class base_stage(object):
|
|||
destination=False)
|
||||
|
||||
def remind_user(self, cr, uid, ids, context=None, attach=False, destination=True):
|
||||
if 'message_post' in self:
|
||||
if hasattr(self, 'message_post'):
|
||||
for case in self.browse(cr, uid, ids, context=context):
|
||||
if destination:
|
||||
recipient_id = case.user_id.partner_id.id
|
||||
|
|
|
@ -13,7 +13,6 @@ Creates menu link for Tools from where tools like survey, lunch, idea are access
|
|||
""",
|
||||
'data': ['tools_view.xml'],
|
||||
'installable': True,
|
||||
'certificate' : '00571588675379342237'
|
||||
}
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -58,7 +58,6 @@ only the country code will be validated.
|
|||
'data': ['base_vat_view.xml'],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate': '0084849360989',
|
||||
'images': ['images/1_partner_vat.jpeg'],
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@ Allows users to create custom dashboard.
|
|||
'qweb': ['static/src/xml/*.xml'],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate': '0076912305725',
|
||||
'images': ['images/1_dashboard_definition.jpeg','images/2_publish_note.jpeg','images/3_admin_dashboard.jpeg',],
|
||||
}
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -69,7 +69,6 @@ To access OpenERP Calendar using WebCal to remote site use the URL like:
|
|||
],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate': '00924841426645403741',
|
||||
'images': ['images/calendar_collections.jpeg','images/calendars.jpeg','images/export_ics_file.jpeg'],
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,819 @@
|
|||
# Bengali translation for openobject-addons
|
||||
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2012-09-25 17:39+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Bengali <bn@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-09-26 04:36+0000\n"
|
||||
"X-Generator: Launchpad (build 16022)\n"
|
||||
|
||||
#. module: caldav
|
||||
#: view:basic.calendar:0
|
||||
msgid "Value Mapping"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: help:caldav.browse,url:0
|
||||
msgid "Url of the caldav server, use for synchronization"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: code:addons/caldav/wizard/caldav_browse.py:99
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
"Prerequire\n"
|
||||
"----------\n"
|
||||
"There is no buit-in way to synchronize calendar with caldav.\n"
|
||||
"So you need to install a third part software : Calendar (CalDav)\n"
|
||||
"for now it's the only one\n"
|
||||
"\n"
|
||||
"configuration\n"
|
||||
"-------------\n"
|
||||
"\n"
|
||||
"1. Open Calendar Sync\n"
|
||||
" I'll get an interface with 2 tabs\n"
|
||||
" Stay on the first one\n"
|
||||
"\n"
|
||||
"2. CaDAV Calendar URL : put the URL given above (ie : "
|
||||
"http://host.com:8069/webdav/db/calendars/users/demo/c/Meetings)\n"
|
||||
"\n"
|
||||
"3. Put your openerp username and password\n"
|
||||
"\n"
|
||||
"4. If your server don't use SSL, you'll get a warnign, say \"Yes\"\n"
|
||||
"\n"
|
||||
"5. Then you can synchronize manually or custom the settings to synchronize "
|
||||
"every x minutes.\n"
|
||||
"\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: field:basic.calendar.alias,name:0
|
||||
msgid "Filename"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: model:ir.model,name:caldav.model_calendar_event_export
|
||||
msgid "Event Export"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:calendar.event.subscribe:0
|
||||
msgid "Provide Path for Remote Calendar"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: model:ir.actions.act_window,name:caldav.action_calendar_event_import_values
|
||||
msgid "Import .ics File"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:caldav.browse:0
|
||||
#: view:calendar.event.export:0
|
||||
msgid "_Close"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: selection:basic.calendar.attributes,type:0
|
||||
#: selection:basic.calendar.lines,name:0
|
||||
msgid "Attendee"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: sql_constraint:basic.calendar.fields:0
|
||||
msgid "Can not map a field more than once"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: model:ir.actions.act_window,help:caldav.action_caldav_form
|
||||
msgid ""
|
||||
"\"Calendars\" allow you to Customize calendar event and todo attribute with "
|
||||
"any of OpenERP model.Caledars provide iCal Import/Export "
|
||||
"functionality.Webdav server that provides remote access to calendar.Help You "
|
||||
"to synchronize Meeting with Calendars client.You can access Calendars using "
|
||||
"CalDAV clients, like sunbird, Calendar Evaluation, Mobile."
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: code:addons/caldav/calendar.py:789
|
||||
#: code:addons/caldav/calendar.py:879
|
||||
#: code:addons/caldav/wizard/calendar_event_import.py:63
|
||||
#, python-format
|
||||
msgid "Warning !"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: field:basic.calendar.lines,object_id:0
|
||||
msgid "Object"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:basic.calendar:0
|
||||
msgid "Todo"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: model:ir.model,name:caldav.model_user_preference
|
||||
msgid "User preference Form"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: field:user.preference,service:0
|
||||
msgid "Services"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: selection:basic.calendar.fields,fn:0
|
||||
msgid "Expression as constant"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: selection:user.preference,device:0
|
||||
msgid "Evolution"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:calendar.event.import:0
|
||||
#: view:calendar.event.subscribe:0
|
||||
msgid "Ok"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: code:addons/caldav/wizard/caldav_browse.py:123
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" 1. Go to Calendar View\n"
|
||||
"\n"
|
||||
" 2. File -> New -> Calendar\n"
|
||||
"\n"
|
||||
" 3. Fill the form\n"
|
||||
" - type : CalDav\n"
|
||||
" - name : Whaterver you want (ie : Meeting)\n"
|
||||
" - url : "
|
||||
"http://HOST:PORT/webdav/DB_NAME/calendars/users/USER/c/Meetings (ie : "
|
||||
"http://localhost:8069/webdav/db_1/calendars/users/demo/c/Meetings) the one "
|
||||
"given on the top of this window\n"
|
||||
" - uncheck \"User SSL\"\n"
|
||||
" - Username : Your username (ie : Demo)\n"
|
||||
" - Refresh : everytime you want that evolution synchronize the data "
|
||||
"with the server\n"
|
||||
"\n"
|
||||
" 4. Click ok and give your openerp password\n"
|
||||
"\n"
|
||||
" 5. A new calendar named with the name you gave should appear on the left "
|
||||
"side.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: code:addons/caldav/calendar.py:879
|
||||
#, python-format
|
||||
msgid "Please provide proper configuration of \"%s\" in Calendar Lines"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:user.preference:0
|
||||
msgid "Caldav's host name configuration"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: field:caldav.browse,url:0
|
||||
msgid "Caldav Server"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: selection:basic.calendar.fields,fn:0
|
||||
msgid "Datetime In UTC"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: selection:user.preference,device:0
|
||||
msgid "iPhone"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: selection:basic.calendar,type:0
|
||||
#: selection:basic.calendar.attributes,type:0
|
||||
#: selection:basic.calendar.lines,name:0
|
||||
msgid "TODO"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:calendar.event.export:0
|
||||
msgid "Export ICS"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: selection:basic.calendar.fields,fn:0
|
||||
msgid "Use the field"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: code:addons/caldav/calendar.py:789
|
||||
#, python-format
|
||||
msgid "Can not create line \"%s\" more than once"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:basic.calendar:0
|
||||
msgid "Webcal Calendar"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:basic.calendar:0
|
||||
#: field:basic.calendar,line_ids:0
|
||||
#: model:ir.model,name:caldav.model_basic_calendar_lines
|
||||
msgid "Calendar Lines"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: model:ir.model,name:caldav.model_calendar_event_subscribe
|
||||
msgid "Event subscribe"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:calendar.event.import:0
|
||||
msgid "Import ICS"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:calendar.event.import:0
|
||||
#: view:calendar.event.subscribe:0
|
||||
#: view:user.preference:0
|
||||
msgid "_Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: model:ir.model,name:caldav.model_basic_calendar_event
|
||||
msgid "basic.calendar.event"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:basic.calendar:0
|
||||
#: selection:basic.calendar,type:0
|
||||
#: selection:basic.calendar.attributes,type:0
|
||||
#: selection:basic.calendar.lines,name:0
|
||||
msgid "Event"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: field:document.directory,calendar_collection:0
|
||||
#: field:user.preference,collection:0
|
||||
msgid "Calendar Collection"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: constraint:document.directory:0
|
||||
msgid "Error! You can not create recursive Directories."
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:user.preference:0
|
||||
msgid "_Open"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:user.preference:0
|
||||
msgid "Next"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: field:basic.calendar,type:0
|
||||
#: field:basic.calendar.attributes,type:0
|
||||
#: field:basic.calendar.fields,type_id:0
|
||||
#: field:basic.calendar.lines,name:0
|
||||
msgid "Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: help:calendar.event.export,name:0
|
||||
msgid "Save in .ics format"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: code:addons/caldav/calendar.py:1293
|
||||
#, python-format
|
||||
msgid "Error !"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: model:ir.model,name:caldav.model_basic_calendar_attributes
|
||||
msgid "Calendar attributes"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: model:ir.model,name:caldav.model_caldav_browse
|
||||
msgid "Caldav Browse"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: selection:user.preference,device:0
|
||||
msgid "Android based device"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:user.preference:0
|
||||
msgid "Configure your openerp hostname. For example : "
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: field:basic.calendar,create_date:0
|
||||
msgid "Created Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:basic.calendar:0
|
||||
msgid "Attributes Mapping"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: model:ir.model,name:caldav.model_document_directory
|
||||
msgid "Directory"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: field:calendar.event.subscribe,url_path:0
|
||||
msgid "Provide path for remote calendar"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: field:basic.calendar.lines,domain:0
|
||||
msgid "Domain"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:calendar.event.subscribe:0
|
||||
msgid "_Subscribe"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: field:basic.calendar,user_id:0
|
||||
msgid "Owner"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:basic.calendar:0
|
||||
#: field:basic.calendar.alias,cal_line_id:0
|
||||
#: field:basic.calendar.lines,calendar_id:0
|
||||
#: model:ir.ui.menu,name:caldav.menu_calendar
|
||||
#: field:user.preference,calendar:0
|
||||
msgid "Calendar"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: code:addons/caldav/calendar.py:41
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Please install python-vobject from http://vobject.skyhouseconsulting.com/"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: code:addons/caldav/wizard/calendar_event_import.py:63
|
||||
#, python-format
|
||||
msgid "Invalid format of the ics, file can not be imported"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: selection:user.preference,service:0
|
||||
msgid "CalDAV"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: field:basic.calendar.fields,field_id:0
|
||||
msgid "OpenObject Field"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: field:basic.calendar.alias,res_id:0
|
||||
msgid "Res. ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:calendar.event.subscribe:0
|
||||
msgid "Message..."
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:basic.calendar:0
|
||||
#: field:basic.calendar,has_webcal:0
|
||||
msgid "WebCal"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:document.directory:0
|
||||
#: model:ir.actions.act_window,name:caldav.action_calendar_collection_form
|
||||
#: model:ir.ui.menu,name:caldav.menu_calendar_collection
|
||||
msgid "Calendar Collections"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: code:addons/caldav/calendar.py:815
|
||||
#: sql_constraint:basic.calendar.alias:0
|
||||
#, python-format
|
||||
msgid "The same filename cannot apply to two records!"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: sql_constraint:document.directory:0
|
||||
msgid "Directory cannot be parent of itself!"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:basic.calendar:0
|
||||
#: field:document.directory,calendar_ids:0
|
||||
#: model:ir.actions.act_window,name:caldav.action_caldav_form
|
||||
#: model:ir.ui.menu,name:caldav.menu_caldav_directories
|
||||
msgid "Calendars"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: field:basic.calendar,collection_id:0
|
||||
msgid "Collection"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: field:basic.calendar,write_date:0
|
||||
msgid "Write Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: code:addons/caldav/wizard/caldav_browse.py:32
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" * Webdav server that provides remote access to calendar\n"
|
||||
" * Synchronisation of calendar using WebDAV\n"
|
||||
" * Customize calendar event and todo attribute with any of OpenERP model\n"
|
||||
" * Provides iCal Import/Export functionality\n"
|
||||
"\n"
|
||||
" To access Calendars using CalDAV clients, point them to:\n"
|
||||
" "
|
||||
"http://HOSTNAME:PORT/webdav/DATABASE_NAME/calendars/users/USERNAME/c\n"
|
||||
"\n"
|
||||
" To access OpenERP Calendar using WebCal to remote site use the URL "
|
||||
"like:\n"
|
||||
" "
|
||||
"http://HOSTNAME:PORT/webdav/DATABASE_NAME/Calendars/CALENDAR_NAME.ics\n"
|
||||
"\n"
|
||||
" Where,\n"
|
||||
" HOSTNAME: Host on which OpenERP server(With webdav) is running\n"
|
||||
" PORT : Port on which OpenERP server is running (By Default : 8069)\n"
|
||||
" DATABASE_NAME: Name of database on which OpenERP Calendar is "
|
||||
"created\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: sql_constraint:document.directory:0
|
||||
msgid "The directory name must be unique !"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:user.preference:0
|
||||
msgid "User Preference"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: code:addons/caldav/wizard/calendar_event_subscribe.py:59
|
||||
#, python-format
|
||||
msgid "Please provide Proper URL !"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: model:ir.model,name:caldav.model_basic_calendar_timezone
|
||||
msgid "basic.calendar.timezone"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: field:basic.calendar.fields,expr:0
|
||||
msgid "Expression"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: model:ir.model,name:caldav.model_basic_calendar_attendee
|
||||
msgid "basic.calendar.attendee"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: model:ir.model,name:caldav.model_basic_calendar_alias
|
||||
msgid "basic.calendar.alias"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:calendar.event.import:0
|
||||
#: field:calendar.event.import,file_path:0
|
||||
msgid "Select ICS File"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: field:user.preference,device:0
|
||||
msgid "Software/Devices"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: field:basic.calendar.lines,mapping_ids:0
|
||||
msgid "Fields Mapping"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: code:addons/caldav/wizard/caldav_browse.py:141
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
"Prerequire\n"
|
||||
"----------\n"
|
||||
"If you are using thunderbird, first you need to install the lightning "
|
||||
"module\n"
|
||||
"http://www.mozilla.org/projects/calendar/lightning/\n"
|
||||
"\n"
|
||||
"configuration\n"
|
||||
"-------------\n"
|
||||
"\n"
|
||||
"1. Go to Calendar View\n"
|
||||
"\n"
|
||||
"2. File -> New Calendar\n"
|
||||
"\n"
|
||||
"3. Chosse \"On the Network\"\n"
|
||||
"\n"
|
||||
"4. for format choose CalDav\n"
|
||||
" and as location the url given above (ie : "
|
||||
"http://host.com:8069/webdav/db/calendars/users/demo/c/Meetings)\n"
|
||||
"\n"
|
||||
"5. Choose a name and a color for the Calendar, and we advice you to uncheck "
|
||||
"\"alarm\"\n"
|
||||
"\n"
|
||||
"6. Then put your openerp login and password (to give the password only check "
|
||||
"the box \"Use password Manager to remember this password\"\n"
|
||||
"\n"
|
||||
"7. Then Finish, your meetings should appear now in your calendar view\n"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:caldav.browse:0
|
||||
msgid "Browse Caldav"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: field:user.preference,host_name:0
|
||||
msgid "Host Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: model:ir.model,name:caldav.model_basic_calendar
|
||||
msgid "basic.calendar"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:basic.calendar:0
|
||||
msgid "Other Info"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: selection:user.preference,device:0
|
||||
msgid "Other"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:basic.calendar:0
|
||||
msgid "My Calendar(s)"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: help:basic.calendar,has_webcal:0
|
||||
msgid ""
|
||||
"Also export a <name>.ics entry next to the calendar folder, with WebCal "
|
||||
"content."
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: field:basic.calendar.fields,fn:0
|
||||
msgid "Function"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:user.preference:0
|
||||
msgid "database.my.openerp.com or companyserver.com"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:basic.calendar:0
|
||||
#: field:basic.calendar,description:0
|
||||
#: view:caldav.browse:0
|
||||
#: field:caldav.browse,description:0
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: help:basic.calendar.alias,cal_line_id:0
|
||||
msgid "The calendar/line this mapping applies to"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: field:basic.calendar.fields,mapping:0
|
||||
msgid "Mapping"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: code:addons/caldav/wizard/calendar_event_import.py:86
|
||||
#, python-format
|
||||
msgid "Import Sucessful"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:calendar.event.import:0
|
||||
msgid "_Import"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: model:ir.model,name:caldav.model_calendar_event_import
|
||||
msgid "Event Import"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: selection:basic.calendar.fields,fn:0
|
||||
msgid "Interval in hours"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: field:calendar.event.export,name:0
|
||||
msgid "File name"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:calendar.event.subscribe:0
|
||||
msgid "Subscribe to Remote Calendar"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: help:basic.calendar,calendar_color:0
|
||||
msgid "For supporting clients, the color of the calendar entries"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: field:basic.calendar,name:0
|
||||
#: field:basic.calendar.attributes,name:0
|
||||
#: field:basic.calendar.fields,name:0
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: selection:basic.calendar.attributes,type:0
|
||||
#: selection:basic.calendar.lines,name:0
|
||||
msgid "Alarm"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: model:ir.model,name:caldav.model_basic_calendar_alarm
|
||||
msgid "basic.calendar.alarm"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: code:addons/caldav/calendar.py:1293
|
||||
#, python-format
|
||||
msgid "Attendee must have an Email Id"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: model:ir.actions.act_window,name:caldav.action_calendar_event_export_values
|
||||
msgid "Export .ics File"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: code:addons/caldav/calendar.py:41
|
||||
#, python-format
|
||||
msgid "vobject Import Error!"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: field:calendar.event.export,file_path:0
|
||||
msgid "Save ICS file"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: code:addons/caldav/wizard/caldav_browse.py:50
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" For SSL specific configuration see the documentation below\n"
|
||||
"\n"
|
||||
"Now, to setup the calendars, you need to:\n"
|
||||
"\n"
|
||||
"1. Click on the \"Settings\" and go to the \"Mail, Contacts, Calendars\" "
|
||||
"page.\n"
|
||||
"2. Go to \"Add account...\"\n"
|
||||
"3. Click on \"Other\"\n"
|
||||
"4. From the \"Calendars\" group, select \"Add CalDAV Account\"\n"
|
||||
"\n"
|
||||
"5. Enter the host's name\n"
|
||||
" (ie : if the url is http://openerp.com:8069/webdav/db_1/calendars/ , "
|
||||
"openerp.com is the host)\n"
|
||||
"\n"
|
||||
"6. Fill Username and password with your openerp login and password\n"
|
||||
"\n"
|
||||
"7. As a description, you can either leave the server's name or\n"
|
||||
" something like \"OpenERP calendars\".\n"
|
||||
"\n"
|
||||
"9. If you are not using a SSL server, you'll get an error, do not worry and "
|
||||
"push \"Continue\"\n"
|
||||
"\n"
|
||||
"10. Then click to \"Advanced Settings\" to specify the right\n"
|
||||
" ports and paths.\n"
|
||||
"\n"
|
||||
"11. Specify the port for the OpenERP server: 8071 for SSL, 8069 without.\n"
|
||||
"\n"
|
||||
"12. Set the \"Account URL\" to the right path of the OpenERP webdav:\n"
|
||||
" the url given by the wizard (ie : "
|
||||
"http://my.server.ip:8069/webdav/dbname/calendars/ )\n"
|
||||
"\n"
|
||||
"11. Click on Done. The phone will hopefully connect to the OpenERP server\n"
|
||||
" and verify it can use the account.\n"
|
||||
"\n"
|
||||
"12. Go to the main menu of the iPhone and enter the Calendar application.\n"
|
||||
" Your OpenERP calendars will be visible inside the selection of the\n"
|
||||
" \"Calendars\" button.\n"
|
||||
" Note that when creating a new calendar entry, you will have to specify\n"
|
||||
" which calendar it should be saved at.\n"
|
||||
"\n"
|
||||
"IF you need SSL (and your certificate is not a verified one, as usual),\n"
|
||||
"then you first will need to let the iPhone trust that. Follow these\n"
|
||||
"steps:\n"
|
||||
"\n"
|
||||
" s1. Open Safari and enter the https location of the OpenERP server:\n"
|
||||
" https://my.server.ip:8071/\n"
|
||||
" (assuming you have the server at \"my.server.ip\" and the HTTPS port\n"
|
||||
" is the default 8071)\n"
|
||||
" s2. Safari will try to connect and issue a warning about the "
|
||||
"certificate\n"
|
||||
" used. Inspect the certificate and click \"Accept\" so that iPhone\n"
|
||||
" now trusts it.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: selection:user.preference,device:0
|
||||
msgid "Sunbird/Thunderbird"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: field:basic.calendar,calendar_order:0
|
||||
msgid "Order"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: code:addons/caldav/wizard/calendar_event_subscribe.py:59
|
||||
#, python-format
|
||||
msgid "Error!"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: field:basic.calendar,calendar_color:0
|
||||
msgid "Color"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:basic.calendar:0
|
||||
msgid "MY"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: model:ir.model,name:caldav.model_basic_calendar_fields
|
||||
msgid "Calendar fields"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: view:calendar.event.import:0
|
||||
msgid "Import Message"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: model:ir.actions.act_window,name:caldav.action_calendar_event_subscribe
|
||||
#: model:ir.actions.act_window,name:caldav.action_calendar_event_subscribe_values
|
||||
msgid "Subscribe"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: sql_constraint:document.directory:0
|
||||
msgid "Directory must have a parent or a storage"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: model:ir.model,name:caldav.model_basic_calendar_todo
|
||||
msgid "basic.calendar.todo"
|
||||
msgstr ""
|
||||
|
||||
#. module: caldav
|
||||
#: help:basic.calendar,calendar_order:0
|
||||
msgid "For supporting clients, the order of this folder among the calendars"
|
||||
msgstr ""
|
|
@ -35,7 +35,6 @@ Adds a Claim link to the delivery order.
|
|||
'claim_delivery_data.xml',],
|
||||
'auto_install': False,
|
||||
'installable': True,
|
||||
'certificate' : '001101649349223746957',
|
||||
'images': ['images/1_claim_link_delivery_order.jpeg'],
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ It manages key tasks such as communication, identification, prioritization, assi
|
|||
|
||||
OpenERP ensures that all cases are successfully tracked by users, customers and suppliers. It can automatically send reminders, escalate the request, trigger specific methods and many other actions based on your own enterprise rules.
|
||||
|
||||
The greatest thing about this system is that users don't need to do anything special. The CRM module has an email gateway for the synchronization interface between mails and OpenERP. That way, users can just send emails to the request tracker.
|
||||
The greatest thing about this system is that users don't need to do anything special. The CRM module has an email gateway for the synchronization interface between mails and OpenERP. That way, users can just send emails to the request tracker.
|
||||
|
||||
OpenERP will take care of thanking them for their message, automatically routing it to the appropriate staff and make sure all future correspondence gets to the right place.
|
||||
|
||||
|
@ -99,7 +99,7 @@ Dashboard for CRM will include:
|
|||
|
||||
'res_partner_view.xml',
|
||||
'board_crm_view.xml',
|
||||
|
||||
|
||||
'res_config_view.xml',
|
||||
|
||||
],
|
||||
|
@ -115,6 +115,7 @@ Dashboard for CRM will include:
|
|||
'test/process/cancel_lead.yml',
|
||||
'test/process/action_rule.yml',
|
||||
'test/process/segmentation.yml',
|
||||
'test/process/phonecalls.yml',
|
||||
'test/ui/crm_demo.yml',
|
||||
'test/ui/duplicate_lead.yml',
|
||||
'test/ui/delete_lead.yml',
|
||||
|
@ -123,7 +124,6 @@ Dashboard for CRM will include:
|
|||
'installable': True,
|
||||
'application': True,
|
||||
'auto_install': False,
|
||||
'certificate': '0079056041421',
|
||||
'images': ['images/sale_crm_crm_dashboard.png', 'images/crm_dashboard.jpeg','images/leads.jpeg','images/meetings.jpeg','images/opportunities.jpeg','images/outbound_calls.jpeg','images/stages.jpeg'],
|
||||
}
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -102,6 +102,7 @@ class crm_case_section(osv.osv):
|
|||
""" Model for sales teams. """
|
||||
_name = "crm.case.section"
|
||||
_inherits = {'mail.alias': 'alias_id'}
|
||||
_inherit = "mail.thread"
|
||||
_description = "Sales Teams"
|
||||
_order = "complete_name"
|
||||
|
||||
|
|
|
@ -1,46 +1,47 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
|
||||
<record id="base.user_demo" model="res.users">
|
||||
<field name="groups_id" eval="[(4,ref('base.group_sale_salesman'))]"/>
|
||||
<field name="groups_id" eval="[(4,ref('base.group_sale_salesman'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="ir_ui_view_sc_calendar_demo" model="ir.ui.view_sc">
|
||||
<field name="name">Meetings</field>
|
||||
<field name="resource">ir.ui.menu</field>
|
||||
<field name="user_id" ref="base.user_demo"/>
|
||||
<field name="res_id" ref="base_calendar.menu_crm_meeting"/>
|
||||
</record>
|
||||
<record id="ir_ui_view_sc_calendar_demo" model="ir.ui.view_sc">
|
||||
<field name="name">Meetings</field>
|
||||
<field name="resource">ir.ui.menu</field>
|
||||
<field name="user_id" ref="base.user_demo"/>
|
||||
<field name="res_id" ref="base_calendar.menu_crm_meeting"/>
|
||||
</record>
|
||||
|
||||
<record model="crm.case.section" id="crm_case_section_1">
|
||||
<record model="crm.case.section" id="crm_case_section_1">
|
||||
<field name="name">Sales Marketing Department</field>
|
||||
<field name="code">SMD</field>
|
||||
<field name="parent_id" ref="crm.section_sales_department"></field>
|
||||
</record>
|
||||
<field name="parent_id" ref="crm.section_sales_department"/>
|
||||
</record>
|
||||
|
||||
<record model="crm.case.section" id="crm_case_section_2">
|
||||
<record model="crm.case.section" id="crm_case_section_2">
|
||||
<field name="name">Support Department</field>
|
||||
<field name="code">SPD</field>
|
||||
<field name="parent_id" ref="crm.section_sales_department"></field>
|
||||
</record>
|
||||
<field name="parent_id" ref="crm.section_sales_department"/>
|
||||
</record>
|
||||
|
||||
<record model="crm.case.section" id="crm_case_section_3">
|
||||
<record model="crm.case.section" id="crm_case_section_3">
|
||||
<field name="name">Direct Marketing</field>
|
||||
<field name="code">DM</field>
|
||||
<field name="parent_id" ref="crm.section_sales_department"></field>
|
||||
</record>
|
||||
<field name="parent_id" ref="crm.section_sales_department"/>
|
||||
</record>
|
||||
|
||||
<record model="crm.case.section" id="crm_case_section_4">
|
||||
<record model="crm.case.section" id="crm_case_section_4">
|
||||
<field name="name">Online Support</field>
|
||||
<field name="code">OS</field>
|
||||
<field name="parent_id" ref="crm.crm_case_section_2"></field>
|
||||
</record>
|
||||
<field name="parent_id" ref="crm.crm_case_section_2"/>
|
||||
</record>
|
||||
|
||||
<record model="crm.segmentation" id="crm_segmentation0">
|
||||
<field name="name">OpenERP partners</field>
|
||||
<field name="exclusif">True</field>
|
||||
<field name="categ_id" ref="base.res_partner_category_2"/>
|
||||
</record>
|
||||
<record model="crm.segmentation" id="crm_segmentation0">
|
||||
<field name="name">OpenERP partners</field>
|
||||
<field name="exclusif">True</field>
|
||||
<field name="categ_id" ref="base.res_partner_category_2"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -297,12 +297,16 @@ class crm_lead(base_stage, format_address, osv.osv):
|
|||
if partner_id:
|
||||
partner = self.pool.get('res.partner').browse(cr, uid, partner_id, context=context)
|
||||
values = {
|
||||
'partner_name' : partner.name,
|
||||
'partner_name' : partner.name,
|
||||
'street' : partner.street,
|
||||
'street2' : partner.street2,
|
||||
'city' : partner.city,
|
||||
'state_id' : partner.state_id and partner.state_id.id or False,
|
||||
'country_id' : partner.country_id and partner.country_id.id or False,
|
||||
'email_from' : partner.email,
|
||||
'phone' : partner.phone,
|
||||
'mobile' : partner.mobile,
|
||||
'fax' : partner.fax,
|
||||
}
|
||||
return {'value' : values}
|
||||
|
||||
|
@ -490,7 +494,8 @@ class crm_lead(base_stage, format_address, osv.osv):
|
|||
title = "%s : %s" % (merge_message, opportunity.name)
|
||||
details.append(self._mail_body(cr, uid, opportunity, fields, title=title, context=context))
|
||||
|
||||
subject = subject[0] + ", ".join(subject[1:])
|
||||
# Chatter message's subject
|
||||
subject = subject[0] + ": " + ", ".join(subject[1:])
|
||||
details = "\n\n".join(details)
|
||||
return self.message_post(cr, uid, [opportunity_id], body=details, subject=subject, context=context)
|
||||
|
||||
|
@ -559,19 +564,18 @@ class crm_lead(base_stage, format_address, osv.osv):
|
|||
|
||||
data = self._merge_data(cr, uid, ids, oldest, fields, context=context)
|
||||
|
||||
# merge data into first opportunity
|
||||
self.write(cr, uid, [first_opportunity.id], data, context=context)
|
||||
|
||||
#copy message and attachements into the first opportunity
|
||||
# Merge messages 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)
|
||||
|
||||
#Notification about loss of information
|
||||
# Merge notifications about loss of information
|
||||
self._merge_notification(cr, uid, first_opportunity, opportunities, context=context)
|
||||
#delete tail opportunities
|
||||
# Write merged data into first opportunity
|
||||
self.write(cr, uid, [first_opportunity.id], data, context=context)
|
||||
# Delete tail opportunities
|
||||
self.unlink(cr, uid, [x.id for x in tail_opportunities], context=context)
|
||||
|
||||
#open first opportunity
|
||||
# Open first opportunity
|
||||
self.case_open(cr, uid, [first_opportunity.id])
|
||||
return first_opportunity.id
|
||||
|
||||
|
@ -580,13 +584,16 @@ class crm_lead(base_stage, format_address, osv.osv):
|
|||
contact_id = False
|
||||
if customer:
|
||||
contact_id = self.pool.get('res.partner').address_get(cr, uid, [customer.id])['default']
|
||||
|
||||
if not section_id:
|
||||
section_id = lead.section_id and lead.section_id.id or False
|
||||
|
||||
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_id = stage_ids and stage_ids[0] or False
|
||||
|
||||
return {
|
||||
'planned_revenue': lead.planned_revenue,
|
||||
'probability': lead.probability,
|
||||
|
@ -597,11 +604,12 @@ class crm_lead(base_stage, format_address, osv.osv):
|
|||
'stage_id': stage_id or False,
|
||||
'date_action': time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'date_open': time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'email_from': customer and customer.email or lead.email_from,
|
||||
'phone': customer and customer.phone or lead.phone,
|
||||
}
|
||||
|
||||
def convert_opportunity(self, cr, uid, ids, partner_id, user_ids=False, section_id=False, context=None):
|
||||
partner = self.pool.get('res.partner')
|
||||
mail_message = self.pool.get('mail.message')
|
||||
customer = False
|
||||
if partner_id:
|
||||
customer = partner.browse(cr, uid, partner_id, context=context)
|
||||
|
@ -787,7 +795,12 @@ class crm_lead(base_stage, format_address, osv.osv):
|
|||
stage = self.pool.get('crm.case.stage').browse(cr, uid, vals['stage_id'], context=context)
|
||||
if stage.on_change:
|
||||
vals['probability'] = stage.probability
|
||||
return super(crm_lead,self).write(cr, uid, ids, vals, context)
|
||||
if vals.get('section_id'):
|
||||
section_id = self.pool.get('crm.case.section').browse(cr, uid, vals.get('section_id'), context=context)
|
||||
if section_id:
|
||||
vals.setdefault('message_follower_ids', [])
|
||||
vals['message_follower_ids'] += [(4, follower.id) for follower in section_id.message_follower_ids]
|
||||
return super(crm_lead,self).write(cr, uid, ids, vals, context)
|
||||
|
||||
# ----------------------------------------
|
||||
# Mail Gateway
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
<!--
|
||||
Demo Leads
|
||||
-->
|
||||
|
||||
<!-- Demo Leads -->
|
||||
<record id="crm_case_1" model="crm.lead">
|
||||
<field name="type">lead</field>
|
||||
<field name="name">Plan to Attend a Training</field>
|
||||
|
@ -26,9 +24,9 @@
|
|||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="stage_id" ref="stage_lead1"/>
|
||||
<field name="description">Hello,
|
||||
I am Jason from Le Club SARL,
|
||||
I am intertested to attend Training organized in your company,
|
||||
Can you send details,</field>
|
||||
I am Jason from Le Club SARL.
|
||||
I am intertested to attend a training organized in your company.
|
||||
Can you send me the details ?</field>
|
||||
<field eval="1" name="active"/>
|
||||
</record>
|
||||
|
||||
|
@ -110,7 +108,8 @@ Can you send details,</field>
|
|||
<field name="section_id" ref="section_sales_department"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="stage_id" ref="stage_lead1"/>
|
||||
<field name="description">Hi, Can you send a quotation for 20 Computers with speakers?
|
||||
<field name="description">Hi,
|
||||
Can you send me a quotation for 20 computers with speakers?
|
||||
Regards,
|
||||
Carrie Helle,
|
||||
Purchase Manager
|
||||
|
@ -215,8 +214,9 @@ Contact: +1 813 494 5005</field>
|
|||
<field name="section_id" ref="crm_case_section_3"/>
|
||||
<field name="user_id" ref=""/>
|
||||
<field name="stage_id" ref="stage_lead1"/>
|
||||
<field name="description">hi,
|
||||
I want to know specification and cost of laptops of your company.
|
||||
<field name="description">Hi,
|
||||
I would like to know more about specification and cost of laptops of your company.
|
||||
|
||||
Thanks,
|
||||
Andrew</field>
|
||||
<field eval="1" name="active"/>
|
||||
|
@ -260,25 +260,20 @@ Andrew</field>
|
|||
<field eval="1" name="active"/>
|
||||
</record>
|
||||
|
||||
|
||||
<!-- Call Function to Cancel the leads (set as Dead) -->
|
||||
<!-- Call Function to Cancel the leads (set as Dead) -->
|
||||
<function model="crm.lead" name="case_cancel"
|
||||
eval="[ ref('crm_case_12'), ref('crm_case_7'),
|
||||
ref('crm_case_3'), ref('crm_case_8')],
|
||||
{'install_mode': True}"
|
||||
/>
|
||||
<!-- Call Function to set the leads as Unread -->
|
||||
|
||||
<!-- Call Function to set the leads as Unread -->
|
||||
<function model="crm.lead" name="message_mark_as_unread"
|
||||
eval="[ ref('crm_case_1'), ref('crm_case_2'),
|
||||
ref('crm_case_5'), ref('crm_case_11')], {}"
|
||||
/>
|
||||
|
||||
|
||||
<!--
|
||||
Demo Opportunities
|
||||
-->
|
||||
|
||||
|
||||
<!-- Demo Opportunities -->
|
||||
<record id="crm_case_13" model="crm.lead">
|
||||
<field name="type">opportunity</field>
|
||||
<field name="name">Plan to buy 60 keyboards and mouses</field>
|
||||
|
@ -563,9 +558,9 @@ Andrew</field>
|
|||
<field name="body">Dear Customer,
|
||||
Thanks for showing interest in our products.
|
||||
We have attached the catalogue,
|
||||
We would like to know your interests, Let us know if we can call you for more details.
|
||||
We would like to know your interests, so let us know when we can call you for more details.
|
||||
|
||||
Thanks</field>
|
||||
Regards</field>
|
||||
<field name="parent_id" ref="message_email0"/>
|
||||
<field name="author_id" ref="base.partner_root"/>
|
||||
</record>
|
||||
|
@ -600,9 +595,9 @@ Thanks</field>
|
|||
<field name="model">crm.lead</field>
|
||||
<field name="res_id" ref="crm_case_1"/>
|
||||
<field name="body">Hello,
|
||||
I am Jason from Le Club SARL,
|
||||
I am intertested to attend Training organized in your company,
|
||||
Can you send details,</field>
|
||||
I am Jason from Le Club SARL.
|
||||
I am intertested to attend a training organized in your company.
|
||||
Can you send me the details ?</field>
|
||||
<field name="type">email</field>
|
||||
</record>
|
||||
<record id="message_email_13" model="mail.message">
|
||||
|
@ -613,7 +608,7 @@ Can you send details,</field>
|
|||
<field name="type">comment</field>
|
||||
</record>
|
||||
|
||||
<!-- Call Function to set the opportunities as Unread -->
|
||||
<!-- Call Function to set the opportunities as Unread -->
|
||||
<function model="crm.lead" name="message_mark_as_unread"
|
||||
eval="[ ref('crm_case_15'), ref('crm_case_16'),
|
||||
ref('crm_case_23'), ref('crm_case_19')], {}"
|
||||
|
|
|
@ -14,12 +14,13 @@
|
|||
<p class="oe_view_nocontent_create">
|
||||
Click to create an unqualified lead.
|
||||
</p><p>
|
||||
A lead is usually the first step in your sales cycle. It can be
|
||||
a contact with a new prospect, a company you target, a contact form
|
||||
filled in your website, etc.
|
||||
Use leads if you need a qualification step before creating an
|
||||
opportunity or a customer. It can be a business card you received,
|
||||
a contact form filled in your website, or a file of unqualified
|
||||
prospects you import, etc.
|
||||
</p><p>
|
||||
Once qualified, the lead can be converted into a business
|
||||
opportunity and a new customer in your address book.
|
||||
opportunity and/or a new customer in your address book.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
<!--
|
||||
((((((((((( Demo Cases )))))))))))
|
||||
-->
|
||||
|
||||
<!-- Demo Cases -->
|
||||
<record id="crm_phonecall_1" model="crm.phonecall">
|
||||
<field eval="time.strftime('%Y-%m-04 10:45:36')" name="date"/>
|
||||
<field name="partner_id" ref="base.res_partner_11"/>
|
||||
|
@ -47,7 +46,7 @@
|
|||
<field eval="time.strftime('%Y-%m-21 14:10:23')" name="date"/>
|
||||
<field eval="'3'" name="priority"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="name">Wanted information about pricing of Laptops</field>
|
||||
<field name="name">Wanted information about pricing of laptops</field>
|
||||
<field name="state">done</field>
|
||||
<field name="partner_phone">(077) 582-4035</field>
|
||||
<field name="partner_mobile">(077) 341-3591</field>
|
||||
|
@ -79,6 +78,7 @@
|
|||
<field eval="time.strftime('%Y-%m-28 14:15:30')" name="date"/>
|
||||
<field name="categ_id" ref="crm.categ_phone2"/>
|
||||
<field eval="8.56" name="duration"/>
|
||||
</record>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
id="crm_case_categ_phone_create_partner"
|
||||
name="Schedule a Call"
|
||||
res_model="crm.phonecall"
|
||||
view_mode="calendar,tree,form"
|
||||
context="{'search_default_partner_id': [active_id], 'default_duration': 1.0, 'default_partner_id': active_id}"
|
||||
view_mode="tree,form,calendar"
|
||||
context="{'search_default_partner_id': active_id, 'default_duration': 1.0, 'default_partner_id': active_id}"
|
||||
groups="base.group_sale_salesman"
|
||||
/>
|
||||
|
||||
|
|
|
@ -115,6 +115,10 @@
|
|||
<field name="note"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_ids" widget="mail_thread"/>
|
||||
<field name="message_follower_ids" widget="mail_followers" help="Followers of this salesteam follow automatically all opportunities related to this salesteam."/>
|
||||
</div>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -446,13 +450,11 @@
|
|||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_crm_payment_mode" name="Fund Raising"
|
||||
parent="base.menu_base_config" sequence="85" groups="crm.group_fund_raising"/>
|
||||
|
||||
<menuitem action="action_crm_payment_mode"
|
||||
id="menu_crm_payment_mode_act"
|
||||
groups="base.group_no_one"
|
||||
name="Payment Modes"
|
||||
parent="menu_crm_payment_mode" />
|
||||
parent="base.menu_crm_config_lead" />
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -26,12 +26,16 @@ class res_partner(osv.osv):
|
|||
_inherit = 'res.partner'
|
||||
|
||||
def _opportunity_meeting_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||
res = {}
|
||||
for partner in self.browse(cr, uid, ids, context):
|
||||
res[partner.id] = {
|
||||
'opportunity_count': len(partner.opportunity_ids),
|
||||
'meeting_count': len(partner.meeting_ids),
|
||||
}
|
||||
res = dict(map(lambda x: (x,{'opportunity_count': 0, 'meeting_count': 0}), ids))
|
||||
# the user may not have access rights for opportunities or meetings
|
||||
try:
|
||||
for partner in self.browse(cr, uid, ids, context):
|
||||
res[partner.id] = {
|
||||
'opportunity_count': len(partner.opportunity_ids),
|
||||
'meeting_count': len(partner.meeting_ids),
|
||||
}
|
||||
except:
|
||||
pass
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
<field name="src_model">res.partner</field>
|
||||
<field name="res_model">crm.meeting</field>
|
||||
<field name="view_mode">calendar,tree,form,gantt</field>
|
||||
<field name="context">{'search_default_partner_ids': active_id}</field>
|
||||
<field name="context">{'default_partner_ids': [active_id]}</field>
|
||||
</record>
|
||||
|
||||
<!-- open opportunities related to given partner -->
|
||||
|
|
|
@ -60,5 +60,18 @@
|
|||
<field name="domain_force">['|',('user_id','=',user.id),('show_as','=','busy')]</field>
|
||||
</record>
|
||||
|
||||
<record id="crm_rule_personal_phonecall" model="ir.rule">
|
||||
<field name="name">Personal Phone Calls</field>
|
||||
<field ref="model_crm_phonecall" name="model_id"/>
|
||||
<field name="domain_force">['|',('user_id','=',user.id),('user_id','=',False)]</field>
|
||||
<field name="groups" eval="[(4, ref('base.group_sale_salesman'))]"/>
|
||||
</record>
|
||||
<record id="crm_rule_all_phones" model="ir.rule">
|
||||
<field name="name">All Phones</field>
|
||||
<field ref="model_crm_phonecall" name="model_id"/>
|
||||
<field name="domain_force">[(1,'=',1)]</field>
|
||||
<field name="groups" eval="[(4, ref('base.group_sale_salesman_all_leads'))]"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -7,14 +7,14 @@
|
|||
new_id = self.create(cr, uid, {'name': 'New Rule', 'model_id': model_ids[0], 'trg_user_id': ref('base.user_root'), 'trg_partner_id': ref('base.res_partner_1'), 'act_user_id': ref('base.user_demo') })
|
||||
self._check(cr, uid)
|
||||
-
|
||||
I create new lead to check record rule.
|
||||
I create a new lead to check the record rule.
|
||||
-
|
||||
!record {model: crm.lead, id: crm_lead_test_rules_id}:
|
||||
name: 'Test lead rules'
|
||||
partner_id: base.res_partner_1
|
||||
-
|
||||
I check record rule is apply and responsible is changed.
|
||||
I check if the record rule is applied and the responsible is changed.
|
||||
-
|
||||
!python {model: crm.lead}: |
|
||||
lead_user = self.browse(cr, uid, ref('crm_lead_test_rules_id'))
|
||||
assert lead_user.user_id.id == ref('base.user_demo'), "Responsible of lead is not changed."
|
||||
assert lead_user.user_id.id == ref('base.user_demo'), "Responsible of lead is not changed."
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
lead = self.browse(cr, uid, ref('crm_case_1'))
|
||||
assert lead.stage_id.id == ref('crm.stage_lead7'), "Stage should be 'Dead' and is %s." % (lead.stage_id.name)
|
||||
assert lead.state == 'cancel', "Opportunity is not in 'cancel' state."
|
||||
assert lead.probability == 0.0, 'Opportunity probability is wrong and should be 0.0.'
|
||||
assert lead.probability == 0.0, 'Opportunity is probably wrong and should be 0.0.'
|
||||
-
|
||||
I reset cancelled lead into unqualified lead.
|
||||
-
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
-
|
||||
Customer interested in our product. so he send request by email to get more details.
|
||||
Customer interested in our product, so he sends request by email to get more details.
|
||||
-
|
||||
Mail script will be fetched him request from mail server. so I process that mail after read EML file
|
||||
Mail script will fetch his request from mail server. Then I process that mail after read EML file.
|
||||
-
|
||||
!python {model: mail.thread}: |
|
||||
import addons
|
||||
|
@ -15,27 +15,27 @@
|
|||
lead_ids = self.search(cr, uid, [('email_from','=', 'Mr. John Right <info@customer.com>')])
|
||||
assert lead_ids and len(lead_ids), "Lead is not created after getting request"
|
||||
lead = self.browse(cr, uid, lead_ids[0], context=context)
|
||||
assert not lead.partner_id, "Customer should be a new"
|
||||
assert not lead.partner_id, "Customer should be a new one"
|
||||
assert lead.name == "Fournir votre devis avec le meilleur prix.", "Subject does not match"
|
||||
-
|
||||
I reply him request with welcome message. TODO revert mail.mail to mail.compose.message (conversion to customer should be automatic).
|
||||
I reply his request with welcome message. TODO revert mail.mail to mail.compose.message (conversion to customer should be automatic).
|
||||
-
|
||||
!python {model: mail.mail}: |
|
||||
lead_ids = self.pool.get('crm.lead').search(cr, uid, [('email_from','=', 'Mr. John Right <info@customer.com>')])
|
||||
context.update({'active_model': 'crm.lead','active_id': lead_ids[0]})
|
||||
id = self.create(cr, uid, {'body': "Merci à l'intérêt pour notre produit.nous vous contacterons bientôt. Merci", 'email_from': 'sales@mycompany.com'}, context=context)
|
||||
id = self.create(cr, uid, {'body': "Merci de votre intérêt pour notre produit, nous vous contacterons bientôt. Bien à vous", 'email_from': 'sales@mycompany.com'}, context=context)
|
||||
try:
|
||||
self.send_mail(cr, uid, [id], context=context)
|
||||
except:
|
||||
pass
|
||||
-
|
||||
Now, I convert him into customer and put into regular customer list.
|
||||
Now, I convert him into customer and put him into regular customer list.
|
||||
-
|
||||
!python {model: crm.lead}: |
|
||||
lead_ids = self.search(cr, uid, [('email_from','=', 'Mr. John Right <info@customer.com>')])
|
||||
self.convert_partner(cr, uid, lead_ids, context=context)
|
||||
-
|
||||
I convert one phonecall request as a customer and put into regular customer list.
|
||||
I convert one phonecall request to a customer and put him into regular customer list.
|
||||
-
|
||||
!python {model: crm.phonecall2partner}: |
|
||||
context.update({'active_model': 'crm.phonecall', 'active_ids': [ref("crm.crm_phonecall_4")], 'active_id': ref("crm.crm_phonecall_4")})
|
||||
|
@ -48,5 +48,5 @@
|
|||
partner_id = self.search(cr, uid, [('phonecall_ids', '=', ref('crm.crm_phonecall_4'))])
|
||||
assert partner_id, "Customer is not found in regular customer list."
|
||||
data = self.browse(cr, uid, partner_id, context=context)[0]
|
||||
assert data.user_id.id == ref("base.user_root"), "User not assign properly"
|
||||
assert data.name == "Wanted information about pricing of Laptops", "Bad partner name"
|
||||
assert data.user_id.id == ref("base.user_root"), "User not assigned properly"
|
||||
assert data.name == "Wanted information about pricing of laptops", "Bad partner name"
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
-
|
||||
In order to test convert customer lead into opportunity,
|
||||
In order to test convert customer lead into opportunity,
|
||||
-
|
||||
I open customer lead.
|
||||
-
|
||||
!python {model: crm.lead}: |
|
||||
self.case_open(cr, uid, [ref("crm_case_4")])
|
||||
-
|
||||
I check lead state is "Open".
|
||||
-
|
||||
I check lead state is "Open".
|
||||
-
|
||||
!assert {model: crm.lead, id: crm.crm_case_4, string: Lead in open state}:
|
||||
- state == "open"
|
||||
-
|
||||
I create partner from lead.
|
||||
I create partner from lead.
|
||||
-
|
||||
!record {model: crm.lead2partner, id: crm_lead2partner_id1, context: '{"active_model": "crm.lead", "active_ids": [ref("crm_case_4")]}'}:
|
||||
-
|
||||
|
@ -24,7 +24,7 @@
|
|||
!python {model: crm.lead}: |
|
||||
self.convert_opportunity(cr, uid ,[ref("crm_case_4")], ref("base.res_partner_2"))
|
||||
-
|
||||
I check details of converted opportunity.
|
||||
I check details of converted opportunity.
|
||||
-
|
||||
!python {model: crm.lead}: |
|
||||
lead = self.browse(cr, uid, ref('crm_case_4'))
|
||||
|
@ -37,15 +37,15 @@
|
|||
!python {model: crm.opportunity2phonecall}: |
|
||||
import time
|
||||
context.update({'active_model': 'crm.lead', 'active_ids': [ref('crm_case_4')]})
|
||||
call_id = self.create(cr, uid, {'date': time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'name': "Bonjour M. Jean, Comment êtes-vous? J'ai obtenu votre demande. peut-on parler au sujet de ce pour quelques minutes?"}, context=context)
|
||||
call_id = self.create(cr, uid, {'date': time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'name': "Bonjour M. Jean, Comment allez-vous? J'ai bien reçu votre demande, pourrions-nous en parler quelques minutes?"}, context=context)
|
||||
self.action_schedule(cr, uid, [call_id], context=context)
|
||||
-
|
||||
I check that phonecall is scheduled for that opportunity.
|
||||
-
|
||||
!python {model: crm.phonecall}: |
|
||||
ids = self.search(cr, uid, [('opportunity_id', '=', ref('crm_case_4'))])
|
||||
assert len(ids), 'phonecall is not scheduled'
|
||||
assert len(ids), 'Phonecall is not scheduled'
|
||||
-
|
||||
Now I schedule meeting with customer.
|
||||
-
|
||||
|
@ -55,7 +55,7 @@
|
|||
After communicated with customer, I put some notes with contract details.
|
||||
-
|
||||
!python {model: crm.lead}: |
|
||||
self.message_post(cr, uid, [ref('crm_case_4')], subject='Test note', body='ces détails envoyés par le client sur le FAX pour la qualité')
|
||||
self.message_post(cr, uid, [ref('crm_case_4')], subject='Test note', body='Détails envoyés par le client sur le FAX pour la qualité')
|
||||
-
|
||||
I win this opportunity
|
||||
-
|
||||
|
@ -73,7 +73,7 @@
|
|||
I convert mass lead into opportunity customer.
|
||||
-
|
||||
!python {model: crm.lead2opportunity.partner.mass}: |
|
||||
context.update({'active_model': 'crm.lead', 'active_ids': [ref("crm_case_11"), ref("crm_case_2")], 'active_id': ref("crm_case_11")})
|
||||
context.update({'active_model': 'crm.lead', 'active_ids': [ref("crm_case_11"), ref("crm_case_2")], 'active_id': ref("crm_case_11")})
|
||||
id = self.create(cr, uid, {'user_ids': [ref('base.user_root')], 'section_id': ref('crm.section_sales_department')}, context=context)
|
||||
self.mass_convert(cr, uid, [id], context=context)
|
||||
-
|
||||
|
@ -111,7 +111,7 @@
|
|||
I confirm review needs meeting.
|
||||
-
|
||||
!python {model: crm.meeting}: |
|
||||
context.update({'active_model': 'crm.meeting'})
|
||||
context.update({'active_model': 'crm.meeting'})
|
||||
self.case_open(cr, uid, [ref('base_calendar.crm_meeting_4')])
|
||||
-
|
||||
I invite a user for meeting.
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
-
|
||||
I make direct opportunity for customer.
|
||||
I make an opportunity from customer.
|
||||
-
|
||||
!python {model: crm.partner2opportunity}: |
|
||||
context.update({'active_model': 'res.partner', 'active_ids': [ref("base.res_partner_9")]})
|
||||
res_id = self.create(cr, uid, {'name': "enquête pour l'achat de services"}, context=context)
|
||||
res_id = self.create(cr, uid, {'name': "Enquête pour l'achat de services"}, context=context)
|
||||
self.make_opportunity(cr, uid, [res_id], context=context)
|
||||
-
|
||||
I make another opportunity from phonecall for same customer.
|
||||
I make another opportunity from a phone call with the same customer.
|
||||
-
|
||||
!python {model: crm.phonecall2opportunity}: |
|
||||
context.update({'active_model': 'crm.phonecall', 'active_ids': [ref("crm.crm_phonecall_6")]})
|
||||
res_id = self.create(cr, uid, {'name': "Quoi de prix de votre autre service?", 'partner_id': ref("base.res_partner_9")}, context=context)
|
||||
res_id = self.create(cr, uid, {'name': "À propos du prix de votre autre service", 'partner_id': ref("base.res_partner_9")}, context=context)
|
||||
self.make_opportunity(cr, uid, [res_id], context=context)
|
||||
-
|
||||
Now I merge all opportunities of customer.
|
||||
Now I merge these opportunities.
|
||||
-
|
||||
!python {model: crm.lead}: |
|
||||
opportunity_ids = self.search(cr, uid, [('partner_id','=', ref("base.res_partner_9"))])
|
||||
|
@ -24,7 +24,7 @@
|
|||
!python {model: crm.merge.opportunity}: |
|
||||
self.action_merge(cr, uid, [ref("opportunity_merge_id")], context=context)
|
||||
-
|
||||
I check for merged opportunities for customer.
|
||||
I check for merged opportunities for customer.
|
||||
-
|
||||
!python {model: crm.lead}: |
|
||||
merge_id = self.search(cr, uid, [('partner_id','=', ref("base.res_partner_9"))])
|
||||
|
@ -32,55 +32,3 @@
|
|||
merge_data = self.browse(cr, uid, merge_id)[0]
|
||||
assert merge_data.type == 'opportunity', 'Merged opportunity type not change!'
|
||||
assert merge_data.partner_id.id == ref("base.res_partner_9"), 'Partner missmatch!'
|
||||
-
|
||||
Now I schedule another phonecall to customer after merged.
|
||||
-
|
||||
!python {model: crm.phonecall2phonecall}: |
|
||||
context.update({'active_model': 'crm.phonecall', 'active_ids': [ref("crm.crm_phonecall_6")], 'active_id': ref("crm.crm_phonecall_6")})
|
||||
res_id = self.create(cr, uid, {'name': "vos chances sont fusionnés en un seul"}, context=context)
|
||||
self.action_schedule(cr, uid, [res_id], context=context)
|
||||
-
|
||||
I schedule meeting on this phonecall.
|
||||
-
|
||||
!python {model: crm.phonecall}: |
|
||||
self.action_make_meeting(cr, uid, [ref("crm.crm_phonecall_6")])
|
||||
-
|
||||
I set phone call to not held.
|
||||
-
|
||||
!python {model: crm.phonecall}: |
|
||||
self.case_pending(cr, uid, [ref("crm.crm_phonecall_6")])
|
||||
-
|
||||
I check that the phone call is in 'Not Held' state.
|
||||
-
|
||||
!assert {model: crm.phonecall, id: crm.crm_phonecall_6, string: Phone call held.}:
|
||||
- state == "pending"
|
||||
-
|
||||
I cancelled the phone call.
|
||||
-
|
||||
!python {model: crm.phonecall}: |
|
||||
self.case_cancel(cr, uid, [ref("crm.crm_phonecall_6")])
|
||||
-
|
||||
I check that the phone call is in 'Cancelled' state.
|
||||
-
|
||||
!assert {model: crm.phonecall, id: crm.crm_phonecall_6, string: Phone call is not cancelled.}:
|
||||
- state == "cancel"
|
||||
-
|
||||
I reset the phone call.
|
||||
-
|
||||
!python {model: crm.phonecall}: |
|
||||
self.case_reset(cr, uid, [ref("crm.crm_phonecall_6")])
|
||||
-
|
||||
I check that the phone call is reset or not.
|
||||
-
|
||||
!assert {model: crm.phonecall, id: crm.crm_phonecall_6, string: Phone call is not reset.}:
|
||||
- state == "open"
|
||||
-
|
||||
I set phone call to held (done).
|
||||
-
|
||||
!python {model: crm.phonecall}: |
|
||||
self.case_close(cr, uid, [ref("crm.crm_phonecall_6")])
|
||||
-
|
||||
I check that the phone call is in 'Held' state.
|
||||
-
|
||||
!assert {model: crm.phonecall, id: crm.crm_phonecall_6, string: Phone call is not held.}:
|
||||
- state == "done"
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
-
|
||||
I schedule a phone call with a customer.
|
||||
-
|
||||
!python {model: crm.phonecall2phonecall}: |
|
||||
context.update({'active_model': 'crm.phonecall', 'active_ids': [ref("crm.crm_phonecall_6")], 'active_id': ref("crm.crm_phonecall_6")})
|
||||
res_id = self.create(cr, uid, {'name': "Proposition de réduction"}, context=context)
|
||||
self.action_schedule(cr, uid, [res_id], context=context)
|
||||
-
|
||||
I schedule a meeting based on this phone call.
|
||||
-
|
||||
!python {model: crm.phonecall}: |
|
||||
self.action_make_meeting(cr, uid, [ref("crm.crm_phonecall_6")])
|
||||
-
|
||||
I set the phone call to not held.
|
||||
-
|
||||
!python {model: crm.phonecall}: |
|
||||
self.case_pending(cr, uid, [ref("crm.crm_phonecall_6")])
|
||||
-
|
||||
I check that the phone call is in 'Not Held' state.
|
||||
-
|
||||
!assert {model: crm.phonecall, id: crm.crm_phonecall_6, string: Phone call held.}:
|
||||
- state == "pending"
|
||||
-
|
||||
I cancel the phone call.
|
||||
-
|
||||
!python {model: crm.phonecall}: |
|
||||
self.case_cancel(cr, uid, [ref("crm.crm_phonecall_6")])
|
||||
-
|
||||
I check that the phone call is in 'Cancelled' state.
|
||||
-
|
||||
!assert {model: crm.phonecall, id: crm.crm_phonecall_6, string: Phone call is not cancelled.}:
|
||||
- state == "cancel"
|
||||
-
|
||||
I reset the phone call.
|
||||
-
|
||||
!python {model: crm.phonecall}: |
|
||||
self.case_reset(cr, uid, [ref("crm.crm_phonecall_6")])
|
||||
-
|
||||
I check that the phone call is reset.
|
||||
-
|
||||
!assert {model: crm.phonecall, id: crm.crm_phonecall_6, string: Phone call is not reset.}:
|
||||
- state == "open"
|
||||
-
|
||||
I set phone call to held (done).
|
||||
-
|
||||
!python {model: crm.phonecall}: |
|
||||
self.case_close(cr, uid, [ref("crm.crm_phonecall_6")])
|
||||
-
|
||||
I check that the phone call is in 'Held' state.
|
||||
-
|
||||
!assert {model: crm.phonecall, id: crm.crm_phonecall_6, string: Phone call is not held.}:
|
||||
- state == "done"
|
|
@ -34,15 +34,17 @@ class crm_lead2opportunity_partner(osv.osv_memory):
|
|||
('create', 'Create a new customer'), \
|
||||
('nothing', 'Do not link to a customer')], \
|
||||
'Related Customer', required=True),
|
||||
'name': fields.selection([('convert', 'Convert to Opportunities'), ('merge', 'Merge with existing Opportunities')], 'Conversion Action', required=True),
|
||||
'name': fields.selection([('convert', 'Convert to opportunity'), \
|
||||
('merge', 'Merge with existing opportunities')], \
|
||||
'Conversion Action', required=True),
|
||||
'opportunity_ids': fields.many2many('crm.lead', string='Opportunities', domain=[('type', '=', 'opportunity')]),
|
||||
}
|
||||
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
"""
|
||||
Default get for name, opportunity_ids
|
||||
if there is an exisitng partner link to the lead, find all existing opportunity link with this partnet to merge
|
||||
all information together
|
||||
Default get for name, opportunity_ids.
|
||||
If there is an exisitng partner link to the lead, find all existing
|
||||
opportunities links with this partner to merge all information together
|
||||
"""
|
||||
lead_obj = self.pool.get('crm.lead')
|
||||
|
||||
|
@ -62,12 +64,13 @@ class crm_lead2opportunity_partner(osv.osv_memory):
|
|||
|
||||
ids = []
|
||||
if partner_id:
|
||||
# Search for opportunities that have the same partner and that arent done or cancelled
|
||||
ids = lead_obj.search(cr, uid, [('partner_id', '=', partner_id), ('type', '=', 'opportunity'), '!', ('state', 'in', ['done', 'cancel'])])
|
||||
if ids:
|
||||
opportunities.append(ids[0])
|
||||
if not partner_id:
|
||||
if email:
|
||||
# Find email of existing opportunity matches the email_from of the lead
|
||||
# Find email of existing opportunity matching the email_from of the lead
|
||||
cr.execute("""select id from crm_lead where type='opportunity' and
|
||||
substring(email_from from '([^ ,<@]+@[^> ,]+)') in (%s)""" % (','.join(email)))
|
||||
ids = map(lambda x:x[0], cr.fetchall())
|
||||
|
@ -83,12 +86,11 @@ class crm_lead2opportunity_partner(osv.osv_memory):
|
|||
if 'opportunity_ids' in fields:
|
||||
res.update({'opportunity_ids': opportunities})
|
||||
|
||||
|
||||
return res
|
||||
|
||||
def view_init(self, cr, uid, fields, context=None):
|
||||
"""
|
||||
This function checks for precondition before wizard executes
|
||||
Check some preconditions before the wizard executes.
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
|
@ -110,7 +112,7 @@ class crm_lead2opportunity_partner(osv.osv_memory):
|
|||
partner_id = partner_ids_map.get(lead_id, False)
|
||||
# FIXME: cannot pass user_ids as the salesman allocation only works in batch
|
||||
res = lead.convert_opportunity(cr, uid, [lead_id], partner_id, [], team_id, context=context)
|
||||
# FIXME: must perform salesman allocation in batch separately here
|
||||
# FIXME: must perform salesman allocation in batch separately here
|
||||
user_ids = vals.get('user_ids', False)
|
||||
if user_ids:
|
||||
lead.allocate_salesman(cr, uid, lead_ids, user_ids, team_id=team_id, context=context)
|
||||
|
@ -136,9 +138,10 @@ class crm_lead2opportunity_partner(osv.osv_memory):
|
|||
|
||||
def action_apply(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
This converts lead to opportunity and opens Opportunity view
|
||||
Convert lead to opportunity or merge lead and opportunity and open
|
||||
the freshly created opportunity view.
|
||||
"""
|
||||
if not context:
|
||||
if context is None:
|
||||
context = {}
|
||||
lead = self.pool.get('crm.lead')
|
||||
lead_ids = context.get('active_ids', [])
|
||||
|
|
|
@ -7,15 +7,9 @@
|
|||
<field name="model">crm.lead2opportunity.partner</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Convert to Opportunity" version="7.0">
|
||||
<group>
|
||||
<field name="action" class="oe_inline"/>
|
||||
<field name="partner_id"
|
||||
attrs="{'required': [('action', '=', 'exist')], 'invisible':[('action','!=','exist')]}"
|
||||
class="oe_inline"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="name" class="oe_inline"/>
|
||||
<field name="opportunity_ids" attrs="{'invisible': [('name', '=', 'convert')]}">
|
||||
<field name="opportunity_ids" attrs="{'invisible': [('name', '!=', 'merge')]}">
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="partner_id"/>
|
||||
|
@ -24,6 +18,12 @@
|
|||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('name', '!=', 'convert')]}">
|
||||
<field name="action" class="oe_inline"/>
|
||||
<field name="partner_id"
|
||||
attrs="{'required': [('action', '=', 'exist')], 'invisible':[('action','!=','exist')]}"
|
||||
class="oe_inline"/>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="action_apply" string="Create Opportunity" type="object" class="oe_highlight"/>
|
||||
or
|
||||
|
@ -38,23 +38,28 @@
|
|||
<field name="model">crm.lead2opportunity.partner.mass</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Convert to Opportunity" version="7.0">
|
||||
<group string="Conversion Options">
|
||||
<field name="action"/>
|
||||
<field name="partner_id" attrs="{'invisible':[('action','!=','exist')],'required': [('action', '=', 'exist')]}"/>
|
||||
<field name="name"/>
|
||||
<separator string="Conversion Options"/>
|
||||
<group>
|
||||
<field name="name" class="oe_inline"/>
|
||||
</group>
|
||||
<group string="Select Opportunities" attrs="{'invisible': [('name', '=', 'convert')]}">
|
||||
<field name="opportunity_ids" colspan="4" nolabel="1" attrs="{'invisible': [('name', '=', 'convert')]}">
|
||||
<tree>
|
||||
<field name="name" />
|
||||
<field name="partner_id" />
|
||||
<field name="user_id" />
|
||||
<field name="section_id" />
|
||||
</tree>
|
||||
</field>
|
||||
<group attrs="{'invisible': [('name', '!=', 'convert')]}">
|
||||
<field name="action" class="oe_inline"/>
|
||||
<field name="partner_id"
|
||||
attrs="{'required': [('action', '=', 'exist')], 'invisible':[('action','!=','exist')]}"
|
||||
class="oe_inline"/>
|
||||
</group>
|
||||
|
||||
<group string="Assign opportunities to">
|
||||
<group string="Select Opportunities" attrs="{'invisible': [('name', '!=', 'merge')]}">
|
||||
<field name="opportunity_ids" colspan="4" nolabel="1" attrs="{'invisible': [('name', '=', 'convert')]}">
|
||||
<tree>
|
||||
<field name="name" />
|
||||
<field name="partner_id" />
|
||||
<field name="user_id" />
|
||||
<field name="section_id" />
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
|
||||
<group string="Assign opportunities to" attrs="{'invisible': [('name', '=', '')]}">
|
||||
<field name="section_id" />
|
||||
<field name="user_ids" colspan="4">
|
||||
<tree>
|
||||
|
@ -62,14 +67,14 @@
|
|||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
|
||||
|
||||
<footer>
|
||||
<button name="mass_convert" string="Convert to Opportunities" type="object" class="oe_highlight"/>
|
||||
or
|
||||
<button string="Cancel" class="oe_link" special="cancel"/>
|
||||
</footer>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_crm_lead2opportunity_partner" model="ir.actions.act_window">
|
||||
|
@ -83,10 +88,11 @@
|
|||
|
||||
<act_window id="action_crm_send_mass_convert"
|
||||
multi="True"
|
||||
key2="client_action_multi" name="Convert opportunities"
|
||||
key2="client_action_multi" name="Convert to opportunities"
|
||||
res_model="crm.lead2opportunity.partner.mass" src_model="crm.lead"
|
||||
view_mode="form" target="new" view_type="form"
|
||||
context="{'mass_convert' : True}"
|
||||
view_id="view_crm_lead2opportunity_partner_mass"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -55,6 +55,8 @@ class crm_lead2partner(osv.osv_memory):
|
|||
partner = self.pool.get('res.partner')
|
||||
lead = self.pool.get('crm.lead')
|
||||
this = lead.browse(cr, uid, context.get('active_id'), context=context)
|
||||
if this.partner_id:
|
||||
return this.partner_id.id
|
||||
partner_id = False
|
||||
if this.email_from:
|
||||
partner_ids = partner.search(cr, uid, [('email', '=', this.email_from)], context=context)
|
||||
|
|
|
@ -27,6 +27,8 @@ class crm_merge_opportunity(osv.osv_memory):
|
|||
_description = 'Merge two Opportunities'
|
||||
|
||||
def action_merge(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
lead = self.pool.get('crm.lead')
|
||||
record = self.browse(cr, uid, ids[0], context=context)
|
||||
opportunities = record.opportunity_ids
|
||||
|
@ -38,7 +40,7 @@ class crm_merge_opportunity(osv.osv_memory):
|
|||
return lead.redirect_opportunity_view(cr, uid, merge_id, context=context)
|
||||
|
||||
_columns = {
|
||||
'opportunity_ids' : fields.many2many('crm.lead', 'merge_opportunity_rel', 'merge_id', 'opportunity_id', 'Opportunities', domain=[('type', '=', 'opportunity')]),
|
||||
'opportunity_ids': fields.many2many('crm.lead', rel='merge_opportunity_rel', id1='merge_id', id2='opportunity_id', string='Leads/Opportunities'),
|
||||
}
|
||||
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
|
|
|
@ -3,13 +3,12 @@
|
|||
<data>
|
||||
|
||||
<!-- Merge Opportunities -->
|
||||
|
||||
<record model="ir.ui.view" id="merge_opportunity_form">
|
||||
<field name="name">crm.merge.opportunity.form</field>
|
||||
<field name="model">crm.merge.opportunity</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Merge Opportunities" version="7.0">
|
||||
<separator string="Select Opportunities"/>
|
||||
<form string="Merge Leads/Opportunities" version="7.0">
|
||||
<separator string="Select Leads/Opportunities"/>
|
||||
<field name="opportunity_ids">
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
|
@ -19,7 +18,7 @@
|
|||
</tree>
|
||||
</field>
|
||||
<footer>
|
||||
<button name="action_merge" type="object" string="_Merge" class="oe_highlight"/>
|
||||
<button name="action_merge" type="object" string="Merge" class="oe_highlight"/>
|
||||
or
|
||||
<button string="Cancel" class="oe_link" special="cancel"/>
|
||||
</footer>
|
||||
|
@ -27,10 +26,9 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Merge Opportunities action -->
|
||||
|
||||
<!-- Merge leads/opportunities action -->
|
||||
<record model="ir.actions.act_window" id="merge_opportunity_act">
|
||||
<field name="name">Merge Opportunities</field>
|
||||
<field name="name">Merge leads/opportunities</field>
|
||||
<field name="res_model">crm.merge.opportunity</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
|
@ -40,7 +38,7 @@
|
|||
|
||||
<act_window id="action_merge_opportunities"
|
||||
multi="True"
|
||||
key2="client_action_multi" name="Merge Opportunities"
|
||||
key2="client_action_multi" name="Merge leads/opportunities"
|
||||
res_model="crm.merge.opportunity" src_model="crm.lead"
|
||||
view_mode="form" target="new" view_type="form"/>
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@ Caldav features in Meeting.
|
|||
'demo': [],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate' : '001088048737252670109',
|
||||
'images': ['images/caldav_browse_step1.jpeg','images/caldav_browse_step2.jpeg'],
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,6 @@ automatically new claims based on incoming emails.
|
|||
],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate' : '00612027414703404749',
|
||||
'images': ['images/claim_categories.jpeg','images/claim_stages.jpeg','images/claims.jpeg'],
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
<menuitem id="base.menu_aftersale" name="After-Sale Services"
|
||||
groups="base.group_sale_salesman"
|
||||
parent="base.menu_main_pm" sequence="2" />
|
||||
parent="base.menu_base_partner" sequence="2" />
|
||||
|
||||
<!-- Claims Menu -->
|
||||
<record model="ir.actions.act_window" id="crm_case_categ_claim0">
|
||||
|
|
|
@ -241,7 +241,7 @@
|
|||
<attribute name="invisible">False</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//page[@name='page_history']" position="inside">
|
||||
<group name="grp_claim" string="Claim">
|
||||
<group name="grp_claim" string="Claims">
|
||||
<field name="claims_ids" colspan="4" nolabel="1">
|
||||
<tree string="Partners Claim" editable="bottom">
|
||||
<field name="name"/>
|
||||
|
|
|
@ -47,7 +47,6 @@ and categorize your interventions with a channel and a priority level.
|
|||
'test': ['test/process/help-desk.yml'],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate' : '00830691522781519309',
|
||||
'images': ['images/helpdesk_analysis.jpeg','images/helpdesk_categories.jpeg','images/helpdesk_requests.jpeg'],
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue