[MERGE] trunk

bzr revid: al@openerp.com-20120930141638-bw50m7b5a8wnu2yh
This commit is contained in:
Antony Lesuisse 2012-09-30 16:16:38 +02:00
commit 6dd16f2613
398 changed files with 8112 additions and 4222 deletions

View File

@ -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:

View File

@ -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."),
}

View File

@ -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):

View File

@ -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']

View File

@ -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,

View File

@ -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 &amp; Payables"

View File

@ -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
-->

View File

@ -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):

View File

@ -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>

View File

@ -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>

View File

@ -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:

View File

@ -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>

View File

@ -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):

View File

@ -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"/>

View File

@ -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 &amp; 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>

View File

@ -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):

View File

@ -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:

View File

@ -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>

View File

@ -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:

View File

@ -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"/>

View File

@ -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:

View File

@ -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:

View File

@ -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')]),

View File

@ -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:

View File

@ -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

View File

@ -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'])

View File

@ -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
)""")

View File

@ -69,6 +69,5 @@ Three reports are available:
],
'installable': True,
'auto_install': False,
'certificate': '0043819694157',
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -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:

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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,

View File

@ -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")

View File

@ -8,7 +8,11 @@
<field name="res_id" ref="mail.group_all_employees"/>
<field name="type">notification</field>
<field name="subject">eInvoicing &amp; 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 -->

View File

@ -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()

View File

@ -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}"

View File

@ -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:

View File

@ -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):

View File

@ -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:

View File

@ -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'],
}

View File

@ -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:

View File

@ -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:

View File

@ -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'

View File

@ -107,7 +107,6 @@ authentication if installed at the same time.
],
'auto_install': False,
'installable': True,
'certificate' : '001141446349334700221',
'external_dependencies' : {
'python' : ['ldap'],
}

View File

@ -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"/>

View File

@ -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:

View File

@ -21,6 +21,5 @@
import base_calendar
import crm_meeting
import wizard
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -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',],
}

View File

@ -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):

View File

@ -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>

View File

@ -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)

View File

@ -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>

View File

@ -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)

View File

@ -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 users ID for security checks,
@param ids: List of base calendar invite attendees 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 users ID for security checks,
@param ids: List of base calendar invite attendees 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:

View File

@ -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>

View File

@ -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:

View File

@ -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:

View File

@ -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'],
}

View File

@ -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:

View File

@ -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:

View File

@ -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'],

View File

@ -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

View File

@ -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:

View File

@ -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'],
}

View File

@ -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:

View File

@ -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'],
}

819
addons/caldav/i18n/bn.po Normal file
View File

@ -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 ""

View File

@ -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'],
}

View File

@ -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:

View File

@ -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"

View File

@ -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>

View File

@ -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

View File

@ -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')], {}"

View File

@ -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>

View File

@ -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>

View File

@ -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"
/>

View File

@ -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

View File

@ -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 = {

View File

@ -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 -->

View File

@ -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>

View File

@ -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."

View File

@ -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.
-

View File

@ -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"

View File

@ -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.

View File

@ -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"

View File

@ -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"

View File

@ -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', [])

View File

@ -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>

View File

@ -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)

View File

@ -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):

View File

@ -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"/>

View File

@ -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'],
}

View File

@ -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'],
}

View File

@ -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">

View File

@ -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"/>

View File

@ -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