[MERGE] trunk

bzr revid: qdp-launchpad@openerp.com-20121113111638-lwlcno51ule5aq54
This commit is contained in:
Quentin (OpenERP) 2012-11-13 12:16:38 +01:00
commit b3a8ad5d2d
148 changed files with 20925 additions and 1162 deletions

View File

@ -107,7 +107,7 @@ class account_analytic_line(osv.osv):
if journal_id:
journal = analytic_journal_obj.browse(cr, uid, journal_id, context=context)
if journal.type == 'sale':
product_price_type_ids = product_price_type_obj.search(cr, uid, [('field','=','list_price')], context)
product_price_type_ids = product_price_type_obj.search(cr, uid, [('field','=','list_price')], context=context)
if product_price_type_ids:
pricetype = product_price_type_obj.browse(cr, uid, product_price_type_ids, context=context)[0]
# Take the company currency as the reference one

View File

@ -983,13 +983,13 @@ class account_invoice(osv.osv):
for i in line:
i[2]['period_id'] = period_id
ctx.update(invoice=inv)
move_id = move_obj.create(cr, uid, move, context=ctx)
new_move_name = move_obj.browse(cr, uid, move_id, context=ctx).name
# make the invoice point to that move
self.write(cr, uid, [inv.id], {'move_id': move_id,'period_id':period_id, 'move_name':new_move_name}, context=ctx)
# Pass invoice in context in method post: used if you want to get the same
# account move reference when creating the same invoice after a cancelled one:
ctx.update({'invoice':inv})
move_obj.post(cr, uid, [move_id], context=ctx)
self._log_event(cr, uid, ids)
return True

View File

@ -208,7 +208,7 @@ class account_move_line(osv.osv):
if type(period_id) == str:
ids = period_obj.search(cr, uid, [('name', 'ilike', period_id)])
context.update({
'period_id': ids[0]
'period_id': ids and ids[0] or False
})
return context
@ -582,7 +582,7 @@ class account_move_line(osv.osv):
lines = self.browse(cr, uid, ids, context=context)
for l in lines:
if l.account_id.type == 'view':
raise osv.except_osv(_('Error!'), _('You cannot create journal items on “View” type account %s %s.') % (l.account_id.code, l.account_id.name))
return False
return True
def _check_no_closed(self, cr, uid, ids, context=None):
@ -917,7 +917,7 @@ class account_move_line(osv.osv):
if lines and lines[0]:
partner_id = lines[0].partner_id and lines[0].partner_id.id or False
if not partner_obj.has_something_to_reconcile(cr, uid, partner_id, context=context):
if partner_id and not partner_obj.has_something_to_reconcile(cr, uid, partner_id, context=context):
partner_obj.mark_as_reconciled(cr, uid, [partner_id], context=context)
return r_id

View File

@ -41,13 +41,5 @@
groups="group_account_user,group_account_manager"
parent="account.menu_finance_generic_reporting" sequence="3"/>
<report id="account_account_balance_landscape"
string="Account balance"
model="account.account"
name="account.account.balance.landscape"
rml="account/report/account_balance_landscape.rml"
auto="False"
menu="False"/>
</data>
</openerp>

View File

@ -306,7 +306,7 @@
<field name="name">Unrealized Gain or Loss</field>
<field name="model">account.account</field>
<field name="arch" type="xml">
<tree string="Unrealized Gains and losses">
<tree string="Unrealized Gains and losses" create="false">
<field name="code"/>
<field name="name"/>
<field name="parent_id" invisible="1"/>
@ -2168,7 +2168,8 @@
<field name="visible" />
<field name="complete_tax_set" />
</group>
<field name="tax_template_ids" colspan="4" readonly="1" nolabel="1"/>
<separator string="Default Taxes" colspan="4"/>
<field name="tax_template_ids" colspan="4" nolabel="1"/>
<separator string="Properties" colspan="4"/>
<group col="4">
<field name="property_account_receivable" domain="[('id', 'child_of', [account_root_id])]"/>

View File

@ -6,7 +6,7 @@
<field name="name">account.fiscal.position.form</field>
<field name="model">account.fiscal.position</field>
<field name="arch" type="xml">
<form string="Fiscal Position">
<form string="Fiscal Position" version="7.0">
<group col="4">
<field name="name"/>
<field name="active"/>
@ -114,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,calendar"/>
view_mode="tree,form"/>
</data>
</openerp>

View File

@ -170,12 +170,12 @@
<tr>
<td><para style="terp_tblheader_General_Centre">Chart of Accounts</para></td>
<td><para style="terp_tblheader_General_Centre">Fiscal Year</para></td>
<td><para style="terp_tblheader_General_Centre">Filter By [[ get_filter(data)!='No Filter' and get_filter(data) ]]</para></td>
<td><para style="terp_tblheader_General_Centre">Filter By [[ get_filter(data)!='No Filters' and get_filter(data) ]]</para></td>
</tr>
<tr>
<td><para style="terp_default_Centre_8">[[ get_account(data) or removeParentNode('para') ]]</para></td>
<td><para style="terp_default_Centre_8">[[ get_fiscalyear(data) or '' ]]</para></td>
<td><para style="terp_default_Centre_8">[[ get_filter(data)=='No Filter' and get_filter(data) or removeParentNode('para') ]] </para>
<td><para style="terp_default_Centre_8">[[ get_filter(data)=='No Filters' and get_filter(data) or removeParentNode('para') ]] </para>
<blockTable colWidths="60.0,60.0" style="Table3">[[ get_filter(data)=='Date' or removeParentNode('blockTable') ]]
<tr>
<td><para style="terp_tblheader_General_Centre">Start Date</para></td>

View File

@ -299,10 +299,10 @@ class general_ledger(report_sxw.rml_parse, common_report_header):
def _get_sortby(self, data):
if self.sortby == 'sort_date':
return 'Date'
return self._translate('Date')
elif self.sortby == 'sort_journal_partner':
return 'Journal & Partner'
return 'Date'
return self._translate('Journal & Partner')
return self._translate('Date')
report_sxw.report_sxw('report.account.general.ledger', 'account.account', 'addons/account/report/account_general_ledger.rml', parser=general_ledger, header='internal')
report_sxw.report_sxw('report.account.general.ledger_landscape', 'account.account', 'addons/account/report/account_general_ledger_landscape.rml', parser=general_ledger, header='internal landscape')

View File

@ -94,10 +94,10 @@ class common_report_header(object):
def _get_filter(self, data):
if data.get('form', False) and data['form'].get('filter', False):
if data['form']['filter'] == 'filter_date':
return 'Date'
return self._translate('Date')
elif data['form']['filter'] == 'filter_period':
return 'Periods'
return 'No Filter'
return self._translate('Periods')
return self._translate('No Filters')
def _sum_debit_period(self, period_id, journal_id=None):
journals = journal_id or self.journal_ids

View File

@ -31,7 +31,6 @@
-
!python {model: account.account}: |
ctx={}
ctx.update({'model': 'account.account','active_ids':[ref('account.chart0')],'active_id':ref('account.chart0')})
data_dict = {'chart_account_id':ref('account.chart0')}
from tools import test_reports
test_reports.try_report_action(cr, uid, 'action_account_aged_balance_view',wiz_data=data_dict, context=ctx, our_module='account')
@ -40,7 +39,6 @@
-
!python {model: account.account}: |
ctx={}
ctx.update({'model': 'account.account','active_ids':[ref('account.chart0')]})
data_dict = {'chart_account_id':ref('account.chart0'), 'account_report_id': ref('account_financial_report_balancesheet0')}
from tools import test_reports
test_reports.try_report_action(cr, uid, 'action_account_report',wiz_data=data_dict, context=ctx, our_module='account')
@ -49,7 +47,6 @@
-
!python {model: account.account}: |
ctx={}
ctx.update({'model': 'account.account','active_ids':[ref('account.chart0')]})
data_dict = {'chart_account_id':ref('account.chart0')}
from tools import test_reports
test_reports.try_report_action(cr, uid, 'action_account_balance_menu',wiz_data=data_dict, context=ctx, our_module='account')
@ -60,7 +57,6 @@
journal_ids = [ref('account.sales_journal'),ref('account.refund_sales_journal'),ref('account.expenses_journal'),ref('account.refund_expenses_journal'),
ref('account.bank_journal'),ref('account.check_journal'),ref('account.cash_journal')]
ctx={}
ctx.update({'model': 'account.journal.period','active_ids':journal_ids})
data_dict = {'chart_account_id':ref('account.chart0')}
from tools import test_reports
test_reports.try_report_action(cr, uid, 'action_account_central_journal',wiz_data=data_dict, context=ctx, our_module='account')
@ -71,7 +67,6 @@
journal_ids = [ref('account.sales_journal'),ref('account.refund_sales_journal'),ref('account.expenses_journal'),ref('account.refund_expenses_journal'),
ref('account.bank_journal'),ref('account.check_journal'),ref('account.cash_journal')]
ctx={}
ctx.update({'model': 'account.journal.period','active_ids':journal_ids})
data_dict = {'chart_account_id':ref('account.chart0')}
from tools import test_reports
test_reports.try_report_action(cr, uid, 'action_account_general_journal',wiz_data=data_dict, context=ctx, our_module='account')
@ -80,7 +75,6 @@
-
!python {model: account.account}: |
ctx={}
ctx.update({'model': 'account.account','active_ids':[ref('account.chart0')]})
data_dict = {'chart_account_id':ref('account.chart0'),'landscape':False}
from tools import test_reports
test_reports.try_report_action(cr, uid, 'action_account_general_ledger_menu',wiz_data=data_dict, context=ctx, our_module='account')
@ -89,7 +83,6 @@
-
!python {model: account.account}: |
ctx={}
ctx.update({'model': 'account.account','active_ids':[ref('account.chart0')]})
data_dict = {'chart_account_id':ref('account.chart0'),'landscape':True}
from tools import test_reports
test_reports.try_report_action(cr, uid, 'action_account_general_ledger_menu',wiz_data=data_dict, context=ctx, our_module='account')
@ -99,7 +92,6 @@
!python {model: account.journal.period}: |
journal_ids = [ref('account.sales_journal'),ref('account.refund_sales_journal'),ref('account.expenses_journal'),ref('account.refund_expenses_journal'),ref('account.bank_journal'),ref('account.check_journal'),ref('account.cash_journal')]
ctx={}
ctx.update({'model': 'account.journal.period','active_ids':journal_ids})
data_dict = {'chart_account_id':ref('account.chart0'), 'period_from':ref('period_1'), 'period_to':ref('period_12')}
from tools import test_reports
test_reports.try_report_action(cr, uid, 'action_account_print_journal',wiz_data=data_dict, context=ctx, our_module='account')
@ -109,7 +101,6 @@
!python {model: account.account}: |
ctx={}
data_dict = {'chart_account_id':ref('account.chart0')}
ctx.update({'model': 'account.account','active_ids':[ref('account.chart0')],'active_id':ref('account.chart0')})
from tools import test_reports
test_reports.try_report_action(cr, uid, 'action_account_partner_balance',wiz_data=data_dict, context=ctx, our_module='account')
-
@ -118,7 +109,6 @@
!python {model: account.account}: |
ctx={}
data_dict = {'chart_account_id':ref('account.chart0'),'page_split': True}
ctx.update({'model': 'account.account','active_ids':[ref('account.chart0')],'active_id':ref('account.chart0')})
from tools import test_reports
test_reports.try_report_action(cr, uid, 'action_account_partner_ledger',wiz_data=data_dict, context=ctx, our_module='account')
-
@ -127,7 +117,6 @@
!python {model: res.partner}: |
ctx={}
data_dict = {'chart_account_id':ref('account.chart0'),'page_split': False}
ctx.update({'model': 'account.account','active_ids':[ref('account.chart0')],'active_id':ref('account.chart0')})
from tools import test_reports
test_reports.try_report_action(cr, uid, 'action_account_partner_ledger',wiz_data=data_dict, context=ctx, our_module='account')
-
@ -135,7 +124,6 @@
-
!python {model: account.account}: |
ctx={}
ctx.update({'model': 'account.account','active_ids':[ref('account.chart0')]})
data_dict = {'chart_account_id':ref('account.chart0'), 'target_move': 'all', 'account_report_id': ref('account_financial_report_balancesheet0')}
from tools import test_reports
test_reports.try_report_action(cr, uid, 'action_account_report',wiz_data=data_dict, context=ctx, our_module='account')

View File

@ -226,7 +226,7 @@ class account_fiscalyear_close(osv.osv_memory):
for account in obj_acc_account.browse(cr, uid, account_ids, context={'fiscalyear': fy_id}):
balance_in_currency = 0.0
if account.currency_id:
cr.execute('SELECT sum(amount_currency) as balance_in_currency FROM account_move_line ' \
cr.execute('SELECT sum(COALESCE(amount_currency,0.0)) as balance_in_currency FROM account_move_line ' \
'WHERE account_id = %s ' \
'AND ' + query_line + ' ' \
'AND currency_id = %s', (account.id, account.currency_id.id))

View File

@ -119,7 +119,11 @@ class account_common_report(osv.osv_memory):
def _get_fiscalyear(self, cr, uid, context=None):
now = time.strftime('%Y-%m-%d')
fiscalyears = self.pool.get('account.fiscalyear').search(cr, uid, [('date_start', '<', now), ('date_stop', '>', now)], limit=1 )
company_id = False
ids = context.get('active_ids', [])
if ids:
company_id = self.browse(cr, uid, ids[0], context=context).company_id.id
fiscalyears = self.pool.get('account.fiscalyear').search(cr, uid, [('date_start', '<', now), ('date_stop', '>', now), ('company_id', '=', company_id)], limit=1)
return fiscalyears and fiscalyears[0] or False
def _get_all_journal(self, cr, uid, context=None):

View File

@ -21,17 +21,17 @@
<field name="inherit_id" ref="account.view_move_form"/>
<field name="arch" type="xml">
<xpath expr="/form/sheet/notebook/page/field[@name='line_id']/tree/field[@name='analytic_account_id']" position="replace">
<field name="analytics_id" context="{'journal_id':journal_id}" groups="analytic.group_analytic_accounting"/>
<field name="analytics_id" context="{'journal_id':parent.journal_id}" groups="analytic.group_analytic_accounting"/>
</xpath>
<xpath expr="/form/sheet/notebook/page/field[@name='line_id']/form/notebook/page/group/group/field[@name='analytic_account_id']" position="replace">
<field name="analytics_id" context="{'journal_id':journal_id}" groups="analytic.group_analytic_accounting"/>
<field name="analytics_id" context="{'journal_id':parent.journal_id}" groups="analytic.group_analytic_accounting"/>
</xpath>
</field>
</record>
<record id="journal_col11" model="account.journal.column">
<field eval="&quot;&quot;&quot;Analytic Distribution&quot;&quot;&quot;" name="name"/>
<field eval="11" name="sequence"/>
<field eval="15" name="sequence"/>
<field name="view_id" ref="account.account_journal_view"/>
<field eval="0" name="required"/>
<field eval="&quot;&quot;&quot;analytics_id&quot;&quot;&quot;" name="field"/>

View File

@ -40,7 +40,7 @@ class account_invoice_line(osv.osv):
if inv.type in ('out_invoice','out_refund'):
for i_line in inv.invoice_line:
if i_line.product_id:
if i_line.product_id and i_line.product_id.valuation == 'real_time':
if inv.type == 'out_invoice':
# debit account dacc will be the output account
# first check the product, if empty check the category
@ -87,7 +87,7 @@ class account_invoice_line(osv.osv):
})
elif inv.type in ('in_invoice','in_refund'):
for i_line in inv.invoice_line:
if i_line.product_id:
if i_line.product_id and i_line.product_id.valuation == 'real_time':
if i_line.product_id.type != 'service':
# get the price difference account at the product
acc = i_line.product_id.property_account_creditor_price_difference and i_line.product_id.property_account_creditor_price_difference.id

View File

@ -386,7 +386,7 @@ class account_asset_depreciation_line(osv.osv):
current_currency = line.asset_id.currency_id.id
context.update({'date': depreciation_date})
amount = currency_obj.compute(cr, uid, current_currency, company_currency, line.amount, context=context)
sign = line.asset_id.category_id.journal_id.type = 'purchase' and 1 or -1
sign = (line.asset_id.category_id.journal_id.type == 'purchase' and 1) or -1
asset_name = line.asset_id.name
reference = line.name
move_vals = {

View File

@ -220,7 +220,18 @@
<menuitem parent="next_id_31"
id="menu_act_crossovered_budget_view"
action="act_crossovered_budget_view" sequence="1" />
<record id="view_crossovered_budget_line_search" model="ir.ui.view">
<field name="name">account.budget.line.search</field>
<field name="model">crossovered.budget.lines</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Budget Lines">
<field name="analytic_account_id"/>
</search>
</field>
</record>
<record model="ir.ui.view" id="view_crossovered_budget_line_tree">
<field name="name">crossovered.budget.line.tree</field>
<field name="model">crossovered.budget.lines</field>

View File

@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-08 00:35+0000\n"
"PO-Revision-Date: 2012-02-09 19:28+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"PO-Revision-Date: 2012-11-09 12:09+0000\n"
"Last-Translator: Pedro Manuel Baeza <pedro.baeza@gmail.com>\n"
"Language-Team: Spanish <es@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-10-30 05:36+0000\n"
"X-Generator: Launchpad (build 16206)\n"
"X-Launchpad-Export-Date: 2012-11-10 04:59+0000\n"
"X-Generator: Launchpad (build 16251)\n"
#. module: account_check_writing
#: selection:res.company,check_layout:0
@ -154,7 +154,7 @@ msgstr "Compañías"
#. module: account_check_writing
#: view:res.company:0
msgid "Default Check Layout"
msgstr ""
msgstr "Comprobar formato por defecto"
#. module: account_check_writing
#: constraint:account.journal:0

View File

@ -43,6 +43,18 @@
<field eval="True" name="required"/>
<field eval="2" name="sequence"/>
</record>
<record id="sequence_journal" model="ir.sequence.type">
<field name="name">Account Journal</field>
<field name="code">account.journal</field>
</record>
<record id="sequence_journal_seq" model="ir.sequence">
<field name="name">Account journal sequence</field>
<field name="code">account.journal</field>
<field name="prefix">AJ</field>
<field eval="1" name="number_next"/>
<field eval="1" name="number_increment"/>
</record>
</data>
</openerp>

View File

@ -955,6 +955,9 @@ class account_voucher(osv.osv):
if voucher_brw.number:
name = voucher_brw.number
elif voucher_brw.journal_id.sequence_id:
if not voucher_brw.journal_id.sequence_id.active:
raise osv.except_osv(_('Configuration Error !'),
_('Please activate the sequence of selected journal !'))
name = seq_obj.next_by_id(cr, uid, voucher_brw.journal_id.sequence_id.id, context=context)
else:
raise osv.except_osv(_('Error!'),

View File

@ -54,6 +54,8 @@
<form string="Bill Payment" version="7.0">
<group col="6">
<field name="partner_id" required="1" on_change="onchange_partner_id(partner_id, journal_id, amount, currency_id, type, date, context)" string="Supplier" context="{'default_customer': 0, 'search_default_supplier': 1, 'default_supplier': 1, 'invoice_currency': currency_id}"/>
<field name="state" invisible="1"/>
<field name="company_id" invisible="1"/>
<field name="amount" on_change="onchange_amount(amount, payment_rate, partner_id, journal_id, currency_id, type, date, payment_rate_currency_id, company_id, context)"/>
<field name="journal_id"
domain="[('type','in',['bank', 'cash'])]"

View File

@ -50,7 +50,7 @@
<field name="res_model">account.voucher</field>
<field name="view_type">form</field>
<field name="domain">[('journal_id.type', 'in', ['bank', 'cash']), ('type','=','receipt'), ('partner_id','=',partner_id)]</field>
<field name="context">{'type':'receipt', 'partner_id': partner_id, 'default_reference':reference}</field>
<field name="context">{'default_type':'receipt', 'type':'receipt', 'partner_id': partner_id, 'default_reference':reference}</field>
<field name="view_id" ref="view_vendor_receipt_form"/>
<field name="target">current</field>
</record>

View File

@ -98,6 +98,10 @@ class account_analytic_account(osv.osv):
def name_get(self, cr, uid, ids, context=None):
res = []
if not ids:
return res
if isinstance(ids, (int, long)):
ids = [ids]
for id in ids:
elmt = self.browse(cr, uid, id, context=context)
res.append((id, self._get_one_full_name(elmt)))

View File

@ -388,6 +388,8 @@ class audittrail_objects_proxy(object_proxy):
}
# loop on all the fields
for field_name, field_definition in pool.get(model.model)._all_columns.items():
if field_name in ('__last_update', 'id'):
continue
#if the field_list param is given, skip all the fields not in that list
if field_list and field_name not in field_list:
continue

View File

@ -99,7 +99,7 @@
<field name="res_id" readonly="1"/>
<field name="object_id" readonly="1"/>
</group>
<field name="line_ids" mode="tree,form"
<field name="line_ids" mode="tree"
widget="one2many_list" readonly="1">
<form string="Log Lines" version="7.0">
<group col="4">

View File

@ -8,15 +8,14 @@ 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-05-10 17:24+0000\n"
"Last-Translator: Jordi Esteve (www.zikzakmedia.com) "
"<jesteve@zikzakmedia.com>\n"
"PO-Revision-Date: 2012-11-09 12:09+0000\n"
"Last-Translator: Pedro Manuel Baeza <pedro.baeza@gmail.com>\n"
"Language-Team: Spanish <es@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-10-30 05:32+0000\n"
"X-Generator: Launchpad (build 16206)\n"
"X-Launchpad-Export-Date: 2012-11-10 04:59+0000\n"
"X-Generator: Launchpad (build 16251)\n"
#. module: base_action_rule
#: help:base.action.rule,act_mail_to_user:0
@ -340,7 +339,7 @@ msgstr "Activo"
#: code:addons/base_action_rule/base_action_rule.py:329
#, python-format
msgid "No Email ID Found for your Company address!"
msgstr ""
msgstr "¡No se ha encontrado Id del e-mail para la dirección de su compañía!"
#. module: base_action_rule
#: field:base.action.rule,act_remind_user:0

View File

@ -99,6 +99,8 @@ class res_partner_bank(osv.osv):
@param iban: IBAN as string
@return: True if IBAN is valid, False otherwise
"""
if not iban:
return False
iban = _format_iban(iban).lower()
if iban[:2] in _ref_iban and len(iban) != len(_format_iban(_ref_iban[iban[:2]])):
return False
@ -128,9 +130,9 @@ class res_partner_bank(osv.osv):
def _construct_constraint_msg(self, cr, uid, ids, context=None):
def default_iban_check(iban_cn):
return iban_cn[0] in string.ascii_lowercase and iban_cn[1] in string.ascii_lowercase
return iban_cn and iban_cn[0] in string.ascii_lowercase and iban_cn[1] in string.ascii_lowercase
iban_country = self.browse(cr, uid, ids)[0].acc_number[:2].lower()
iban_country = self.browse(cr, uid, ids)[0].acc_number and self.browse(cr, uid, ids)[0].acc_number[:2].lower()
if default_iban_check(iban_country):
if iban_country in _ref_iban:
return _('The IBAN does not seem to be correct. You should have entered something like this %s'), \

View File

@ -79,7 +79,7 @@ class base_action_rule(osv.osv):
write['section_id'] = action.act_section_id.id
if hasattr(action, 'act_categ_id') and action.act_categ_id:
write['categ_ids'] = [4, action.act_categ_id.id]
write['categ_ids'] = [(4, action.act_categ_id.id)]
model_obj.write(cr, uid, [obj.id], write, context)
return res

View File

@ -26,7 +26,7 @@
<menuitem id="base.next_id_64" name="Sales"
parent="base.menu_reporting" sequence="1" />
<menuitem id="base.menu_sales_configuration_misc" name="Miscellaneous" parent="base.menu_base_config" sequence="75"/>
<menuitem id="base.menu_sales_configuration_misc" name="Miscellaneous" parent="base.menu_base_config" sequence="81"/>
<!-- crm.case.channel -->

View File

@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-02-08 01:37+0100\n"
"PO-Revision-Date: 2012-02-10 17:48+0000\n"
"Last-Translator: Carlos Ch. <Unknown>\n"
"PO-Revision-Date: 2012-11-09 12:10+0000\n"
"Last-Translator: Pedro Manuel Baeza <pedro.baeza@gmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-10-30 04:57+0000\n"
"X-Generator: Launchpad (build 16206)\n"
"X-Launchpad-Export-Date: 2012-11-10 04:59+0000\n"
"X-Generator: Launchpad (build 16251)\n"
#. module: crm
#: view:crm.lead.report:0
@ -172,7 +172,7 @@ msgstr "Mes esperado de cierre"
#. module: crm
#: view:crm.lead2opportunity.partner.mass:0
msgid "Assigned Opportunities to"
msgstr ""
msgstr "Oportunidades asignadas a"
#. module: crm
#: view:crm.lead:0 field:crm.lead,partner_id:0 view:crm.lead.report:0
@ -598,7 +598,7 @@ msgstr "Fecha de fin"
#. module: crm
#: view:crm.opportunity2phonecall:0 view:crm.phonecall2phonecall:0
msgid "Schedule/Log a Call"
msgstr ""
msgstr "Planificar/Registrar una llamada"
#. module: crm
#: constraint:base.action.rule:0
@ -792,7 +792,7 @@ msgstr "Siguiente"
#. module: crm
#: field:crm.segmentation,som_interval:0
msgid "Days per Period"
msgstr ""
msgstr "Días por periodo"
#. module: crm
#: field:crm.meeting,byday:0
@ -959,7 +959,7 @@ msgstr "Días para abrir"
#. module: crm
#: view:crm.meeting:0
msgid "Show Time as"
msgstr ""
msgstr "Mostrar hora como"
#. module: crm
#: view:crm.phonecall2partner:0
@ -1342,7 +1342,7 @@ msgstr "Fecha escritura"
#. module: crm
#: view:crm.meeting:0
msgid "End of Recurrency"
msgstr ""
msgstr "Fin de recurrencia"
#. module: crm
#: view:crm.meeting:0
@ -1392,6 +1392,12 @@ msgid ""
" \n"
"If the call needs to be done then the state is set to 'Not Held'."
msgstr ""
"El estado se establece a 'Para hacer' cuando se crea el caso.\n"
"Si es caso está en marcha, el estado se establece a 'Abierto.\n"
"Cuando la llamada se termina, el estado se establece en 'Realizada'. "
" \n"
"Si la llamada está pendiente de ser realizada, entonces el estado se "
"establece en 'Pendiente'."
#. module: crm
#: selection:crm.meeting,week_list:0
@ -1449,7 +1455,7 @@ msgstr "Oportunidades por categorías"
#. module: crm
#: model:crm.case.section,name:crm.section_sales_marketing_department
msgid "Sales Marketing Department"
msgstr ""
msgstr "Departamento de ventas y marketing"
#. module: crm
#: view:crm.phonecall.report:0
@ -1900,7 +1906,7 @@ msgstr "Responder a"
#. module: crm
#: view:crm.case.section:0
msgid "Select Stages for this Sales Team"
msgstr ""
msgstr "Seleccione etapas para este equipo de ventas"
#. module: crm
#: view:board.board:0
@ -2015,7 +2021,7 @@ msgstr "Ubicación"
#. module: crm
#: model:ir.model,name:crm.model_crm_lead2opportunity_partner_mass
msgid "Mass Lead To Opportunity Partner"
msgstr ""
msgstr "Transformación masiva de iniciativa a oportunidad"
#. module: crm
#: view:crm.lead:0
@ -2777,7 +2783,7 @@ msgstr "e-mail del contacto"
#. module: crm
#: field:crm.lead,referred:0
msgid "Referred by"
msgstr ""
msgstr "Referido por"
#. module: crm
#: view:crm.lead:0 model:ir.model,name:crm.model_crm_add_note
@ -3541,7 +3547,7 @@ msgstr "Nuevas oportunidades"
#: code:addons/crm/crm_action_rule.py:61
#, python-format
msgid "No E-Mail Found for your Company address!"
msgstr ""
msgstr "No se encontró dirección de e-mail para el contacto de su compañía"
#. module: crm
#: field:crm.lead.report,email:0
@ -3561,7 +3567,7 @@ msgstr "Oportunidades por usuario y equipo"
#. module: crm
#: view:crm.phonecall:0
msgid "Reset to Todo"
msgstr ""
msgstr "Cambiar a 'Para hacer'"
#. module: crm
#: field:crm.case.section,working_hours:0
@ -3643,6 +3649,10 @@ msgid ""
"partner. From the phone call form, you can trigger a request for another "
"call, a meeting or an opportunity."
msgstr ""
"Esta herramienta permite registrar sus llamadas entrantes sobre la marcha. "
"Cada llamada que recibe aparecerá en el formulario de la empresa para trazar "
"cada contacto que tiene con una empresa. Desde el formulario de llamadas, "
"puede lanzar una petición para otra llamada, una reunión u oportunidad."
#. module: crm
#: selection:crm.lead.report,creation_month:0
@ -3673,6 +3683,10 @@ msgid ""
"channels that will be maintained at the creation of a document in the "
"system. Some examples of channels can be: Website, Phone Call, Reseller, etc."
msgstr ""
"Controle el origen de sus iniciativas y oportunidades de venta mediante la "
"creación de canales específicos que se usarán en la creación de documentos "
"en el sistema. Algunos ejemplos de canales son: Sitio web, llamada "
"telefónica, distribuidores, ..."
#. module: crm
#: selection:crm.lead2opportunity.partner,name:0
@ -3740,7 +3754,7 @@ msgstr "Año"
#. module: crm
#: constraint:res.partner:0
msgid "Error ! You cannot create recursive associated members."
msgstr ""
msgstr "¡Error! No puede crear miembros asociados recursivamente."
#. module: crm
#: model:crm.case.resource.type,name:crm.type_lead8

View File

@ -91,7 +91,7 @@
<field name="res_model">crm.phonecall.report</field>
<field name="view_type">form</field>
<field name="view_mode">tree,graph</field>
<field name="context">{"search_default_year":1,"search_default_User":1,"search_default_This Month":1,'group_by_no_leaf':1,'group_by':[]}</field>
<field name="context">{"search_default_year":1,"search_default_Salesperson":1,"search_default_This Month":1,'group_by_no_leaf':1,'group_by':[]}</field>
<field name="view_id" ref="view_report_crm_phonecall_tree"/>
<field name="search_view_id" ref="view_report_crm_phonecall_filter"/>
<field name="help">From this report, you can analyse the performance of your sales team, based on their phone calls. You can group or filter the information according to several criteria and drill down the information, by adding more groups in the report.</field>

View File

@ -105,7 +105,7 @@ class crm_claim(base_stage, osv.osv):
'email_from': fields.char('Email', size=128, help="Destination email for email gateway."),
'partner_phone': fields.char('Phone', size=32),
'stage_id': fields.many2one ('crm.claim.stage', 'Stage',
domain="['|', ('section_ids', '=', section_id), ('case_default', '=', True)]"),
domain="['&',('fold', '=', False),'|', ('section_ids', '=', section_id), ('case_default', '=', True)]"),
'cause': fields.text('Root Cause'),
'state': fields.related('stage_id', 'state', type="selection", store=True,
selection=crm.AVAILABLE_STATES, string="Status", readonly=True,

View File

@ -43,38 +43,32 @@
-->
<record model="crm.claim.stage" id="stage_claim1">
<field name="name">Draft claim</field>
<field name="name">New</field>
<field name="state">draft</field>
<field name="sequence">26</field>
<field name="case_default" eval="True"/>
</record>
<record model="crm.claim.stage" id="stage_claim5">
<field name="name">Actions Defined</field>
<field name="name">In Progress</field>
<field name="state">open</field>
<field name="sequence">27</field>
<field name="case_default" eval="True"/>
</record>
<record model="crm.claim.stage" id="stage_claim2">
<field name="name">Actions Done</field>
<field name="name">Settled</field>
<field name="state">done</field>
<field name="sequence">28</field>
<field name="case_default" eval="True"/>
</record>
<record model="crm.claim.stage" id="stage_claim3">
<field name="name">Refused</field>
<field name="state">done</field>
<field name="name">Rejected</field>
<field name="state">cancel</field>
<field name="sequence">29</field>
<field name="case_default" eval="True"/>
<field name="case_refused" eval="True"/>
<field name="fold" eval="True"/>
</record>
<record model="crm.claim.stage" id="stage_claim3">
<field name="name">Cancelled</field>
<field name="state">cancel</field>
<field name="sequence">30</field>
<field name="case_default" eval="True"/>
<field name="fold" eval="True"/>
</record>
</data>
</openerp>

View File

@ -52,7 +52,7 @@
<!-- Claim Stages -->
<menuitem id="base.menu_definitions" name="Configuration" parent="base.menu_main_pm" sequence="60"/>
<menuitem id="base.menu_project_config_project" name="Stages" parent="base.menu_definitions" sequence="1"/>
<menuitem id="menu_claim_stage_view" name="Claim Stages" action="crm_claim_stage_act" parent="base.menu_project_config_project" sequence="20"/>
<menuitem id="menu_claim_stage_view" name="Stages" action="crm_claim_stage_act" parent="menu_config_claim" sequence="20"/>
</data>
</openerp>

View File

@ -102,16 +102,11 @@
<field name="arch" type="xml">
<form string="Claim" version="7.0">
<header>
<button name="case_open" string="Open" type="object" class="oe_highlight"
states="draft,pending" groups="base.group_user"/>
<button name="case_close" string="Done" type="object" class="oe_highlight"
states="open,pending" groups="base.group_user"/>
<button name="case_reset" string="Reset to Draft" type="object" groups="base.group_user"
states="cancel,done"/>
<button name="case_cancel" string="Cancel" type="object" groups="base.group_user"
<button name="case_close" string="Settle" type="object" class="oe_highlight"
states="draft,open,pending" groups="base.group_user"/>
<button name="case_cancel" string="Reject" type="object" groups="base.group_user"
states="draft,open,pending"/>
<field name="stage_id" widget="statusbar"
on_change="onchange_stage_id(stage_id)"/>
<field name="stage_id" widget="statusbar" clickable="True"/>
</header>
<sheet string="Claims">
<group>

View File

@ -8,14 +8,14 @@ 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: 2011-01-16 17:13+0000\n"
"Last-Translator: mgaja (GrupoIsep.com) <Unknown>\n"
"PO-Revision-Date: 2012-11-09 12:10+0000\n"
"Last-Translator: Pedro Manuel Baeza <pedro.baeza@gmail.com>\n"
"Language-Team: Spanish <es@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-10-30 05:33+0000\n"
"X-Generator: Launchpad (build 16206)\n"
"X-Launchpad-Export-Date: 2012-11-10 04:59+0000\n"
"X-Generator: Launchpad (build 16251)\n"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,send_to:0
@ -25,12 +25,12 @@ msgstr "Enviar a"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,subtype:0
msgid "Message type"
msgstr ""
msgstr "Tipo de mensaje"
#. module: crm_partner_assign
#: help:crm.lead.forward.to.partner,auto_delete:0
msgid "Permanently delete emails after sending"
msgstr ""
msgstr "Eliminar permanentemente los emails depués de su envío"
#. module: crm_partner_assign
#: field:crm.lead.report.assign,delay_close:0
@ -40,7 +40,7 @@ msgstr "Retraso para cerrar"
#. module: crm_partner_assign
#: help:crm.lead.forward.to.partner,email_to:0
msgid "Message recipients"
msgstr ""
msgstr "Destinatarios del mensaje"
#. module: crm_partner_assign
#: field:crm.lead.report.assign,planned_revenue:0
@ -61,7 +61,7 @@ msgstr "Agrupar por..."
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,template_id:0
msgid "Template"
msgstr ""
msgstr "Plantilla"
#. module: crm_partner_assign
#: view:crm.lead:0
@ -76,12 +76,12 @@ msgstr "Geo localizar"
#. module: crm_partner_assign
#: help:crm.lead.forward.to.partner,body:0
msgid "Plain-text version of the message"
msgstr ""
msgstr "Versión en texto plano del mensaje"
#. module: crm_partner_assign
#: view:crm.lead.forward.to.partner:0
msgid "Body"
msgstr ""
msgstr "Cuerpo"
#. module: crm_partner_assign
#: selection:crm.lead.report.assign,month:0
@ -101,7 +101,7 @@ msgstr "Demora cierre"
#. module: crm_partner_assign
#: view:crm.partner.report.assign:0
msgid "#Partner"
msgstr ""
msgstr "Nº empresa"
#. module: crm_partner_assign
#: selection:crm.lead.forward.to.partner,history:0
@ -137,7 +137,7 @@ msgstr "Más alta"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,body:0
msgid "Text contents"
msgstr ""
msgstr "Contenido del texto"
#. module: crm_partner_assign
#: view:crm.lead.report.assign:0
@ -148,7 +148,7 @@ msgstr "Día"
#. module: crm_partner_assign
#: help:crm.lead.forward.to.partner,message_id:0
msgid "Message unique identifier"
msgstr ""
msgstr "Identificador único del mensaje"
#. module: crm_partner_assign
#: selection:crm.lead.forward.to.partner,history:0
@ -167,6 +167,8 @@ msgid ""
"Add here all attachments of the current document you want to include in the "
"Email."
msgstr ""
"Añada aquí todos los datos adjuntos del documento que quiere incluir en el "
"correo."
#. module: crm_partner_assign
#: selection:crm.lead.report.assign,state:0
@ -195,17 +197,17 @@ msgstr ""
#. module: crm_partner_assign
#: help:crm.lead.forward.to.partner,body_html:0
msgid "Rich-text/HTML version of the message"
msgstr ""
msgstr "Versión en texto enriquecido / HTML del mensaje"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,auto_delete:0
msgid "Auto Delete"
msgstr ""
msgstr "Auto eliminar"
#. module: crm_partner_assign
#: help:crm.lead.forward.to.partner,email_bcc:0
msgid "Blind carbon copy message recipients"
msgstr ""
msgstr "Destinatarios de la copia oculta"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,partner_id:0
@ -254,7 +256,7 @@ msgstr "Sección"
#. module: crm_partner_assign
#: view:crm.lead.forward.to.partner:0
msgid "Send"
msgstr ""
msgstr "Enviar"
#. module: crm_partner_assign
#: view:res.partner:0
@ -286,7 +288,7 @@ msgstr "Tipo"
#. module: crm_partner_assign
#: view:crm.partner.report.assign:0
msgid "Name"
msgstr ""
msgstr "Nombre"
#. module: crm_partner_assign
#: selection:crm.lead.report.assign,priority:0
@ -299,11 +301,13 @@ msgid ""
"Type of message, usually 'html' or 'plain', used to select plaintext or rich "
"text contents accordingly"
msgstr ""
"Tipo de mensaje, normalmente 'html' o 'plano', utilizado para seleccionar "
"contenidos en texto plano o en texto enriquecido"
#. module: crm_partner_assign
#: view:crm.lead.report.assign:0
msgid "Assign Date"
msgstr ""
msgstr "Fecha de asignación"
#. module: crm_partner_assign
#: view:crm.lead.report.assign:0
@ -318,7 +322,7 @@ msgstr "Fecha creación"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,res_id:0
msgid "Related Document ID"
msgstr ""
msgstr "ID del docuemtno relacionado"
#. module: crm_partner_assign
#: view:crm.lead.report.assign:0
@ -349,7 +353,7 @@ msgstr "Etapa"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,model:0
msgid "Related Document model"
msgstr ""
msgstr "Modelo del documento relacionado"
#. module: crm_partner_assign
#: code:addons/crm_partner_assign/wizard/crm_forward_to_partner.py:192
@ -392,7 +396,7 @@ msgstr "Cerrar"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,use_template:0
msgid "Use Template"
msgstr ""
msgstr "Usar plantilla"
#. module: crm_partner_assign
#: model:ir.actions.act_window,name:crm_partner_assign.action_report_crm_opportunity_assign
@ -464,12 +468,12 @@ msgstr "nº oportunidades"
#. module: crm_partner_assign
#: view:crm.lead:0
msgid "Team"
msgstr ""
msgstr "Equipo"
#. module: crm_partner_assign
#: view:crm.lead:0
msgid "Referred Partner"
msgstr ""
msgstr "Empresa referida"
#. module: crm_partner_assign
#: selection:crm.lead.report.assign,state:0
@ -490,7 +494,7 @@ msgstr "Cerrado"
#. module: crm_partner_assign
#: model:ir.actions.act_window,name:crm_partner_assign.action_crm_send_mass_forward
msgid "Mass forward to partner"
msgstr ""
msgstr "Envío masivo a empresa"
#. module: crm_partner_assign
#: view:res.partner:0
@ -570,7 +574,7 @@ msgstr "Longitud Geo"
#. module: crm_partner_assign
#: field:crm.partner.report.assign,opp:0
msgid "# of Opportunity"
msgstr ""
msgstr "Nº oportunidad"
#. module: crm_partner_assign
#: view:crm.lead.report.assign:0
@ -600,12 +604,12 @@ msgstr "Empresa a la que este caso ha sido reenviado/asignado."
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,date:0
msgid "Date"
msgstr ""
msgstr "Fecha"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,body_html:0
msgid "Rich-text contents"
msgstr ""
msgstr "Contenido en texto enriquecido"
#. module: crm_partner_assign
#: view:crm.lead.report.assign:0
@ -620,18 +624,18 @@ msgstr "res.empresa.nivel"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,message_id:0
msgid "Message-Id"
msgstr ""
msgstr "Id del mensaje"
#. module: crm_partner_assign
#: view:crm.lead.forward.to.partner:0
#: field:crm.lead.forward.to.partner,attachment_ids:0
msgid "Attachments"
msgstr ""
msgstr "Adjuntos"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,email_cc:0
msgid "Cc"
msgstr ""
msgstr "Cc"
#. module: crm_partner_assign
#: selection:crm.lead.report.assign,month:0
@ -641,7 +645,7 @@ msgstr "Septiembre"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,references:0
msgid "References"
msgstr ""
msgstr "Referencias"
#. module: crm_partner_assign
#: view:crm.lead.report.assign:0
@ -668,7 +672,7 @@ msgstr "Abierto"
#. module: crm_partner_assign
#: help:crm.lead.forward.to.partner,email_cc:0
msgid "Carbon copy message recipients"
msgstr ""
msgstr "Destinatarios de la copia"
#. module: crm_partner_assign
#: help:crm.lead.forward.to.partner,headers:0
@ -676,6 +680,8 @@ msgid ""
"Full message headers, e.g. SMTP session headers (usually available on "
"inbound messages only)"
msgstr ""
"Cabeceras completas del mensaje, por ejemplo las cabeceras de sesión SMTP "
"(normalmente disponibles sólo en mensajes entrantes)"
#. module: crm_partner_assign
#: field:res.partner,date_localization:0
@ -698,11 +704,13 @@ msgid ""
"Message sender, taken from user preferences. If empty, this is not a mail "
"but a message."
msgstr ""
"Remitente del mensaje, proveniente de las preferencias del usuario. Si está "
"vacío, esto no es correo electrónico, sino un mensaje."
#. module: crm_partner_assign
#: field:crm.partner.report.assign,nbr:0
msgid "# of Partner"
msgstr ""
msgstr "Nº empresa"
#. module: crm_partner_assign
#: view:crm.lead.forward.to.partner:0
@ -713,7 +721,7 @@ msgstr "Reenviar a empresa"
#. module: crm_partner_assign
#: field:crm.partner.report.assign,name:0
msgid "Partner name"
msgstr ""
msgstr "Nombre de la empresa"
#. module: crm_partner_assign
#: selection:crm.lead.report.assign,month:0
@ -728,7 +736,7 @@ msgstr "Ingreso estimado"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,reply_to:0
msgid "Reply-To"
msgstr ""
msgstr "Responder a"
#. module: crm_partner_assign
#: field:crm.lead,partner_assigned_id:0
@ -748,7 +756,7 @@ msgstr "Oportunidad"
#. module: crm_partner_assign
#: view:crm.lead.forward.to.partner:0
msgid "Send Mail"
msgstr ""
msgstr "Enviar correo"
#. module: crm_partner_assign
#: field:crm.lead.report.assign,partner_id:0
@ -776,7 +784,7 @@ msgstr "País"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,headers:0
msgid "Message headers"
msgstr ""
msgstr "Cabeceras del mensaje"
#. module: crm_partner_assign
#: view:res.partner:0
@ -786,7 +794,7 @@ msgstr "Convertir en oportunidad"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,email_bcc:0
msgid "Bcc"
msgstr ""
msgstr "Cco"
#. module: crm_partner_assign
#: view:crm.lead:0
@ -802,7 +810,7 @@ msgstr "Abril"
#: model:ir.actions.act_window,name:crm_partner_assign.action_report_crm_partner_assign
#: model:ir.ui.menu,name:crm_partner_assign.menu_report_crm_partner_assign_tree
msgid "Partnership Analysis"
msgstr ""
msgstr "Análisis de la relación"
#. module: crm_partner_assign
#: model:ir.model,name:crm_partner_assign.model_crm_lead
@ -817,7 +825,7 @@ msgstr "Pendiente"
#. module: crm_partner_assign
#: view:crm.partner.report.assign:0
msgid "Partner assigned Analysis"
msgstr ""
msgstr "Análisis de la empresa asignada"
#. module: crm_partner_assign
#: model:ir.model,name:crm_partner_assign.model_crm_lead_report_assign
@ -828,11 +836,12 @@ msgstr "Informe de iniciativas CRM"
#: help:crm.lead.forward.to.partner,references:0
msgid "Message references, such as identifiers of previous messages"
msgstr ""
"Referencias del mensaje, tales como identificadores de mensajes anteriores"
#. module: crm_partner_assign
#: constraint:res.partner:0
msgid "Error ! You cannot create recursive associated members."
msgstr ""
msgstr "¡Error! No puede crear miembros asociados recursivamente."
#. module: crm_partner_assign
#: selection:crm.lead.forward.to.partner,history:0
@ -847,12 +856,12 @@ msgstr "Secuencia"
#. module: crm_partner_assign
#: model:ir.model,name:crm_partner_assign.model_crm_partner_report_assign
msgid "CRM Partner Report"
msgstr ""
msgstr "Informe de la empresa CRM"
#. module: crm_partner_assign
#: model:ir.model,name:crm_partner_assign.model_crm_lead_forward_to_partner
msgid "Email composition wizard"
msgstr ""
msgstr "Asistente de composición de e-mail"
#. module: crm_partner_assign
#: selection:crm.lead.report.assign,priority:0
@ -873,7 +882,7 @@ msgstr "Fecha de creación"
#. module: crm_partner_assign
#: field:crm.lead.forward.to.partner,filter_id:0
msgid "Filters"
msgstr ""
msgstr "Filtros"
#. module: crm_partner_assign
#: view:crm.lead.report.assign:0
@ -884,7 +893,7 @@ msgstr "Año"
#. module: crm_partner_assign
#: help:crm.lead.forward.to.partner,reply_to:0
msgid "Preferred response address for the message"
msgstr ""
msgstr "Dirección de correo de respuesta preferida para este mensaje"
#~ msgid "Reply-to of the Sales team defined on this case"
#~ msgstr "\"Responder a\" del equipo de ventas definido en este caso"
@ -941,3 +950,6 @@ msgstr ""
#~ "partners o asesores,\n"
#~ "basándose en geo-localización.\n"
#~ " "
#~ msgid "E-mail composition wizard"
#~ msgstr "Asistente de composición de e-mail"

View File

@ -823,6 +823,7 @@ class node_res_dir(node_class):
uid = self.context.uid
ctx = self.context.context.copy()
ctx.update(self.dctx)
ctx.update(self.context.extra_ctx)
where = []
if self.domain:
app = safe_eval(self.domain, ctx)

View File

@ -272,7 +272,7 @@ class abstracted_fs(object):
if path.startswith('/'):
path = path[1:]
p_parts = path.split('/') # hard-code the unix sep here, by spec.
p_parts = path.split(os.sep)
assert '..' not in p_parts

View File

@ -43,7 +43,7 @@ class showdiff(osv.osv_memory):
elif len(ids) == 1:
old = history.browse(cr, uid, ids[0])
nids = history.search(cr, uid, [('document_id', '=', old.document_id.id)])
nids = history.search(cr, uid, [('page_id', '=', old.page_id.id)])
nids.sort()
diff = history.getDiff(cr, uid, ids[0], nids[-1])
else:

View File

@ -51,9 +51,10 @@ class document_davdir(osv.osv):
# that might be not worth preparing.
nctx.extra_ctx['webdav_path'] = '/'+config.get_misc('webdav','vdir','webdav')
usr_obj = self.pool.get('res.users')
res = usr_obj.read(cr, uid, uid, ['login'])
res = usr_obj.read(cr, uid, uid, ['login','lang'])
if res:
nctx.extra_ctx['username'] = res['login']
nctx.extra_ctx['lang'] = res['lang']
# TODO group
return

View File

@ -39,7 +39,7 @@ class sale_order_line(osv.osv):
_columns = {
'event_id': fields.many2one('event.event', 'Event', help="Choose an event and it will automatically create a registration for this event."),
#those 2 fields are used for dynamic domains and filled by onchange
'event_type_id': fields.related('event_type_id', type='many2one', relation="event.type", string="Event Type"),
'event_type_id': fields.related('product_id','event_type_id', type='many2one', relation="event.type", string="Event Type"),
'event_ok': fields.related('product_id', 'event_ok', string='event_ok', type='boolean'),
}

21
addons/fleet/__init__.py Normal file
View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 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/>.
#
##############################################################################
import fleet

View File

@ -0,0 +1,61 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 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/>.
#
##############################################################################
{
'name' : 'Fleet Management',
'version' : '0.1',
'author' : 'OpenERP S.A.',
'category': 'Managing vehicles and contracts',
'website' : 'http://www.openerp.com',
'summary' : 'Vehicle, leasing, insurances, costs',
'description' : """
Vehicle, leasing, insurances, cost
==================================
With this module, OpenERP helps you managing all your vehicles, the
contracts associated to those vehicle as well as services, fuel log
entries, costs and many other features necessary to the management
of your fleet of vehicle(s)
Main Features
-------------
* Add vehicles to your fleet
* Manage contracts for vehicles
* Reminder when a contract reach its expiration date
* Add services, fuel log entry, odometer values for all vehicles
* Show all costs associated to a vehicle or to a type of service
* Analysis graph for costs
""",
'depends' : [
'base',
'mail',
'board'
],
'data' : [
'fleet_view.xml',
'fleet_data.xml',
'fleet_board_view.xml',
],
'update_xml' : ['security/ir.model.access.csv'],
'demo': ['fleet_cars.xml','fleet_demo.xml'],
'installable' : True,
'application' : True,
}

820
addons/fleet/fleet.py Normal file
View File

@ -0,0 +1,820 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 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 osv import osv, fields
import time
import datetime
import tools
from osv.orm import except_orm
from tools.translate import _
from dateutil.relativedelta import relativedelta
def str_to_datetime(strdate):
return datetime.datetime.strptime(strdate, tools.DEFAULT_SERVER_DATE_FORMAT)
class fleet_vehicle_cost(osv.Model):
_name = 'fleet.vehicle.cost'
_description = 'Cost related to a vehicle'
_order = 'date desc, vehicle_id asc'
def _get_odometer(self, cr, uid, ids, odometer_id, arg, context):
res = dict.fromkeys(ids, False)
for record in self.browse(cr,uid,ids,context=context):
if record.odometer_id:
res[record.id] = record.odometer_id.value
return res
def _set_odometer(self, cr, uid, id, name, value, args=None, context=None):
if not value:
raise except_orm(_('Operation not allowed!'), _('Emptying the odometer value of a vehicle is not allowed.'))
date = self.browse(cr, uid, id, context=context).date
if not(date):
date = fields.date.context_today(self, cr, uid, context=context)
vehicle_id = self.browse(cr, uid, id, context=context).vehicle_id
data = {'value': value, 'date': date, 'vehicle_id': vehicle_id.id}
odometer_id = self.pool.get('fleet.vehicle.odometer').create(cr, uid, data, context=context)
return self.write(cr, uid, id, {'odometer_id': odometer_id}, context=context)
def _year_get_fnc(self, cr, uid, ids, name, unknow_none, context=None):
res = {}
for record in self.browse(cr, uid, ids, context=context):
if (record.date):
res[record.id] = str(time.strptime(record.date, tools.DEFAULT_SERVER_DATE_FORMAT).tm_year)
else:
res[record.id] = _('Unknown')
return res
def _cost_name_get_fnc(self, cr, uid, ids, name, unknow_none, context=None):
res = {}
for record in self.browse(cr, uid, ids, context=context):
name = record.vehicle_id.name
if record.cost_subtype.name:
name += ' / '+ record.cost_subtype.name
if record.date:
name += ' / '+ record.date
res[record.id] = name
return res
_columns = {
'name': fields.function(_cost_name_get_fnc, type="char", string='Name', store=True),
'vehicle_id': fields.many2one('fleet.vehicle', 'Vehicle', required=True, help='Vehicle concerned by this log'),
'cost_subtype': fields.many2one('fleet.service.type', 'Type', help='Cost type purchased with this cost'),
'amount': fields.float('Total Price'),
'cost_type': fields.selection([('contract', 'Contract'), ('services','Services'), ('fuel','Fuel'), ('other','Other')], 'Category of the cost', help='For internal purpose only', required=True),
'parent_id': fields.many2one('fleet.vehicle.cost', 'Parent', help='Parent cost to this current cost'),
'cost_ids': fields.one2many('fleet.vehicle.cost', 'parent_id', 'Included Services'),
'odometer_id': fields.many2one('fleet.vehicle.odometer', 'Odometer', help='Odometer measure of the vehicle at the moment of this log'),
'odometer': fields.function(_get_odometer, fnct_inv=_set_odometer, type='float', string='Odometer Value', help='Odometer measure of the vehicle at the moment of this log'),
'odometer_unit': fields.related('vehicle_id', 'odometer_unit', type="char", string="Unit", readonly=True),
'date' :fields.date('Date',help='Date when the cost has been executed'),
'contract_id': fields.many2one('fleet.vehicle.log.contract', 'Contract', help='Contract attached to this cost'),
'auto_generated': fields.boolean('Automatically Generated', readonly=True, required=True),
'year': fields.function(_year_get_fnc, type="char", string='Year', store=True),
}
_defaults ={
'cost_type': 'other',
}
def create(self, cr, uid, data, context=None):
#make sure that the data are consistent with values of parent and contract records given
if 'parent_id' in data and data['parent_id']:
parent = self.browse(cr, uid, data['parent_id'], context=context)
data['vehicle_id'] = parent.vehicle_id.id
data['date'] = parent.date
data['cost_type'] = parent.cost_type
if 'contract_id' in data and data['contract_id']:
contract = self.pool.get('fleet.vehicle.log.contract').browse(cr, uid, data['contract_id'], context=context)
data['vehicle_id'] = contract.vehicle_id.id
data['cost_subtype'] = contract.cost_subtype.id
data['cost_type'] = contract.cost_type
if 'odometer' in data and not data['odometer']:
#if received value for odometer is 0, then remove it from the data as it would result to the creation of a
#odometer log with 0, which is to be avoided
del(data['odometer'])
return super(fleet_vehicle_cost, self).create(cr, uid, data, context=context)
class fleet_vehicle_tag(osv.Model):
_name = 'fleet.vehicle.tag'
_columns = {
'name': fields.char('Name', required=True, translate=True),
}
class fleet_vehicle_state(osv.Model):
_name = 'fleet.vehicle.state'
_order = 'sequence asc'
_columns = {
'name': fields.char('Name', required=True),
'sequence': fields.integer('Order', help="Used to order the note stages")
}
_sql_constraints = [('fleet_state_name_unique','unique(name)', 'State name already exists')]
class fleet_vehicle_model(osv.Model):
def _model_name_get_fnc(self, cr, uid, ids, field_name, arg, context=None):
res = {}
for record in self.browse(cr, uid, ids, context=context):
name = record.modelname
if record.brand.name:
name = record.brand.name + ' / ' + name
res[record.id] = name
return res
def on_change_brand(self, cr, uid, ids, model_id, context=None):
if not model_id:
return {'value': {'image_medium': False}}
brand = self.pool.get('fleet.vehicle.model.brand').browse(cr, uid, model_id, context=context)
return {
'value': {
'image_medium': brand.image,
}
}
_name = 'fleet.vehicle.model'
_description = 'Model of a vehicle'
_order = 'name asc'
_columns = {
'name': fields.function(_model_name_get_fnc, type="char", string='Name', store=True),
'modelname': fields.char('Model name', size=32, required=True),
'brand': fields.many2one('fleet.vehicle.model.brand', 'Model Brand', required=True, help='Brand of the vehicle'),
'vendors': fields.many2many('res.partner', 'fleet_vehicle_model_vendors', 'model_id', 'partner_id', string='Vendors'),
'image': fields.related('brand', 'image', type="binary", string="Logo"),
'image_medium': fields.related('brand', 'image_medium', type="binary", string="Logo"),
'image_small': fields.related('brand', 'image_small', type="binary", string="Logo"),
}
class fleet_vehicle_model_brand(osv.Model):
_name = 'fleet.vehicle.model.brand'
_description = 'Brand model of the vehicle'
_order = 'name asc'
def _get_image(self, cr, uid, ids, name, args, context=None):
result = dict.fromkeys(ids, False)
for obj in self.browse(cr, uid, ids, context=context):
result[obj.id] = tools.image_get_resized_images(obj.image)
return result
def _set_image(self, cr, uid, id, name, value, args, context=None):
return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context)
_columns = {
'name': fields.char('Brand Name', size=64, required=True),
'image': fields.binary("Logo",
help="This field holds the image used as logo for the brand, limited to 1024x1024px."),
'image_medium': fields.function(_get_image, fnct_inv=_set_image,
string="Medium-sized photo", type="binary", multi="_get_image",
store = {
'fleet.vehicle.model.brand': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
},
help="Medium-sized logo of the brand. It is automatically "\
"resized as a 128x128px image, with aspect ratio preserved. "\
"Use this field in form views or some kanban views."),
'image_small': fields.function(_get_image, fnct_inv=_set_image,
string="Smal-sized photo", type="binary", multi="_get_image",
store = {
'fleet.vehicle.model.brand': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
},
help="Small-sized photo of the brand. It is automatically "\
"resized as a 64x64px image, with aspect ratio preserved. "\
"Use this field anywhere a small image is required."),
}
class fleet_vehicle(osv.Model):
_inherit = 'mail.thread'
def _vehicle_name_get_fnc(self, cr, uid, ids, prop, unknow_none, context=None):
res = {}
for record in self.browse(cr, uid, ids, context=context):
res[record.id] = record.model_id.brand.name + '/' + record.model_id.modelname + ' / ' + record.license_plate
return res
def return_action_to_open(self, cr, uid, ids, context=None):
""" This opens the xml view specified in xml_id for the current vehicle """
if context is None:
context = {}
if context.get('xml_id'):
res = self.pool.get('ir.actions.act_window').for_xml_id(cr, uid ,'fleet', context['xml_id'], context=context)
res['context'] = context
res['context'].update({'default_vehicle_id': ids[0]})
res['domain'] = [('vehicle_id','=', ids[0])]
return res
return False
def act_show_log_cost(self, cr, uid, ids, context=None):
""" This opens log view to view and add new log for this vehicle, groupby default to only show effective costs
@return: the costs log view
"""
if context is None:
context = {}
res = self.pool.get('ir.actions.act_window').for_xml_id(cr, uid ,'fleet','fleet_vehicle_costs_act', context=context)
res['context'] = context
res['context'].update({
'default_vehicle_id': ids[0],
'search_default_parent_false': True
})
res['domain'] = [('vehicle_id','=', ids[0])]
return res
def _get_odometer(self, cr, uid, ids, odometer_id, arg, context):
res = dict.fromkeys(ids, 0)
for record in self.browse(cr,uid,ids,context=context):
ids = self.pool.get('fleet.vehicle.odometer').search(cr, uid, [('vehicle_id', '=', record.id)], limit=1, order='value desc')
if len(ids) > 0:
res[record.id] = self.pool.get('fleet.vehicle.odometer').browse(cr, uid, ids[0], context=context).value
return res
def _set_odometer(self, cr, uid, id, name, value, args=None, context=None):
if value:
date = fields.date.context_today(self, cr, uid, context=context)
data = {'value': value, 'date': date, 'vehicle_id': id}
return self.pool.get('fleet.vehicle.odometer').create(cr, uid, data, context=context)
def _search_get_overdue_contract_reminder(self, cr, uid, obj, name, args, context):
res = []
for field, operator, value in args:
assert operator in ('=', '!=', '<>') and value in (True, False), 'Operation not supported'
if (operator == '=' and value == True) or (operator in ('<>', '!=') and value == False):
search_operator = 'in'
else:
search_operator = 'not in'
today = fields.date.context_today(self, cr, uid, context=context)
cr.execute('select cost.vehicle_id, count(contract.id) as contract_number FROM fleet_vehicle_cost cost left join fleet_vehicle_log_contract contract on contract.cost_id = cost.id WHERE contract.expiration_date is not null AND contract.expiration_date < %s AND contract.state IN (\'open\', \'toclose\') GROUP BY cost.vehicle_id', (today,))
res_ids = [x[0] for x in cr.fetchall()]
res.append(('id', search_operator, res_ids))
return res
def _search_contract_renewal_due_soon(self, cr, uid, obj, name, args, context):
res = []
for field, operator, value in args:
assert operator in ('=', '!=', '<>') and value in (True, False), 'Operation not supported'
if (operator == '=' and value == True) or (operator in ('<>', '!=') and value == False):
search_operator = 'in'
else:
search_operator = 'not in'
today = fields.date.context_today(self, cr, uid, context=context)
datetime_today = datetime.datetime.strptime(today, tools.DEFAULT_SERVER_DATE_FORMAT)
limit_date = str((datetime_today + relativedelta(days=+15)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT))
cr.execute('select cost.vehicle_id, count(contract.id) as contract_number FROM fleet_vehicle_cost cost left join fleet_vehicle_log_contract contract on contract.cost_id = cost.id WHERE contract.expiration_date is not null AND contract.expiration_date > %s AND contract.expiration_date < %s AND contract.state IN (\'open\', \'toclose\') GROUP BY cost.vehicle_id', (today, limit_date))
res_ids = [x[0] for x in cr.fetchall()]
res.append(('id', search_operator, res_ids))
return res
def _get_contract_reminder_fnc(self, cr, uid, ids, field_names, unknow_none, context=None):
res= {}
for record in self.browse(cr, uid, ids, context=context):
overdue = False
due_soon = False
total = 0
name = ''
for element in record.log_contracts:
if element.state in ('open', 'toclose') and element.expiration_date:
current_date_str = fields.date.context_today(self, cr, uid, context=context)
due_time_str = element.expiration_date
current_date = str_to_datetime(current_date_str)
due_time = str_to_datetime(due_time_str)
diff_time = (due_time-current_date).days
if diff_time < 0:
overdue = True
total += 1
if diff_time < 15 and diff_time >= 0:
due_soon = True;
total += 1
if overdue or due_soon:
ids = self.pool.get('fleet.vehicle.log.contract').search(cr,uid,[('vehicle_id', '=', record.id), ('state', 'in', ('open', 'toclose'))], limit=1, order='expiration_date asc')
if len(ids) > 0:
#we display only the name of the oldest overdue/due soon contract
name=(self.pool.get('fleet.vehicle.log.contract').browse(cr, uid, ids[0], context=context).cost_subtype.name)
res[record.id] = {
'contract_renewal_overdue': overdue,
'contract_renewal_due_soon': due_soon,
'contract_renewal_total': (total - 1), #we remove 1 from the real total for display purposes
'contract_renewal_name': name,
}
return res
def _get_default_state(self, cr, uid, context):
try:
model, model_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'fleet', 'vehicle_state_active')
except ValueError:
model_id = False
return model_id
_name = 'fleet.vehicle'
_description = 'Information on a vehicle'
_order= 'license_plate asc'
_columns = {
'name': fields.function(_vehicle_name_get_fnc, type="char", string='Name', store=True),
'company_id': fields.many2one('res.company', 'Company'),
'license_plate': fields.char('License Plate', size=32, required=True, help='License plate number of the vehicle (ie: plate number for a car)'),
'vin_sn': fields.char('Chassis Number', size=32, help='Unique number written on the vehicle motor (VIN/SN number)'),
'driver': fields.many2one('res.partner', 'Driver', help='Driver of the vehicle'),
'model_id': fields.many2one('fleet.vehicle.model', 'Model', required=True, help='Model of the vehicle'),
'log_fuel': fields.one2many('fleet.vehicle.log.fuel', 'vehicle_id', 'Fuel Logs'),
'log_services': fields.one2many('fleet.vehicle.log.services', 'vehicle_id', 'Services Logs'),
'log_contracts': fields.one2many('fleet.vehicle.log.contract', 'vehicle_id', 'Contracts'),
'acquisition_date': fields.date('Acquisition Date', required=False, help='Date when the vehicle has been bought'),
'color': fields.char('Color', size=32, help='Color of the vehicle'),
'state': fields.many2one('fleet.vehicle.state', 'State', help='Current state of the vehicle', ondelete="set null"),
'location': fields.char('Location', size=128, help='Location of the vehicle (garage, ...)'),
'seats': fields.integer('Seats Number', help='Number of seats of the vehicle'),
'doors': fields.integer('Doors Number', help='Number of doors of the vehicle'),
'tag_ids' :fields.many2many('fleet.vehicle.tag', 'fleet_vehicle_vehicle_tag_rel', 'vehicle_tag_id','tag_id', 'Tags'),
'odometer': fields.function(_get_odometer, fnct_inv=_set_odometer, type='float', string='Last Odometer', help='Odometer measure of the vehicle at the moment of this log'),
'odometer_unit': fields.selection([('kilometers', 'Kilometers'),('miles','Miles')], 'Odometer Unit', help='Unit of the odometer ',required=True),
'transmission': fields.selection([('manual', 'Manual'), ('automatic', 'Automatic')], 'Transmission', help='Transmission Used by the vehicle'),
'fuel_type': fields.selection([('gasoline', 'Gasoline'), ('diesel', 'Diesel'), ('electric', 'Electric'), ('hybrid', 'Hybrid')], 'Fuel Type', help='Fuel Used by the vehicle'),
'horsepower': fields.integer('Horsepower'),
'horsepower_tax': fields.float('Horsepower Taxation'),
'power': fields.integer('Power (kW)', help='Power in kW of the vehicle'),
'co2': fields.float('CO2 Emissions', help='CO2 emissions of the vehicle'),
'image': fields.related('model_id', 'image', type="binary", string="Logo"),
'image_medium': fields.related('model_id', 'image_medium', type="binary", string="Logo"),
'image_small': fields.related('model_id', 'image_small', type="binary", string="Logo"),
'contract_renewal_due_soon': fields.function(_get_contract_reminder_fnc, fnct_search=_search_contract_renewal_due_soon, type="boolean", string='Has Contracts to renew', multi='contract_info'),
'contract_renewal_overdue': fields.function(_get_contract_reminder_fnc, fnct_search=_search_get_overdue_contract_reminder, type="boolean", string='Has Contracts Overdued', multi='contract_info'),
'contract_renewal_name': fields.function(_get_contract_reminder_fnc, type="text", string='Name of contract to renew soon', multi='contract_info'),
'contract_renewal_total': fields.function(_get_contract_reminder_fnc, type="integer", string='Total of contracts due or overdue minus one', multi='contract_info'),
'car_value': fields.float('Car Value', help='Value of the bought vehicle'),
}
_defaults = {
'doors': 5,
'odometer_unit': 'kilometers',
'state': _get_default_state,
}
def copy(self, cr, uid, id, default=None, context=None):
if not default:
default = {}
default.update({
'log_fuel':[],
'log_contracts':[],
'log_services':[],
'tag_ids':[],
'vin_sn':'',
})
return super(fleet_vehicle, self).copy(cr, uid, id, default, context=context)
def on_change_model(self, cr, uid, ids, model_id, context=None):
if not model_id:
return {}
model = self.pool.get('fleet.vehicle.model').browse(cr, uid, model_id, context=context)
return {
'value': {
'image_medium': model.image,
}
}
def create(self, cr, uid, data, context=None):
vehicle_id = super(fleet_vehicle, self).create(cr, uid, data, context=context)
vehicle = self.browse(cr, uid, vehicle_id, context=context)
self.message_post(cr, uid, [vehicle_id], body=_('Vehicle %s has been added to the fleet!') % (vehicle.license_plate), context=context)
return vehicle_id
def write(self, cr, uid, ids, vals, context=None):
"""
This function write an entry in the openchatter whenever we change important information
on the vehicle like the model, the drive, the state of the vehicle or its license plate
"""
for vehicle in self.browse(cr, uid, ids, context):
changes = []
if 'model_id' in vals and vehicle.model_id.id != vals['model_id']:
value = self.pool.get('fleet.vehicle.model').browse(cr,uid,vals['model_id'],context=context).name
oldmodel = vehicle.model_id.name or _('None')
changes.append(_("Model: from '%s' to '%s'") %(oldmodel, value))
if 'driver' in vals and vehicle.driver.id != vals['driver']:
value = self.pool.get('res.partner').browse(cr,uid,vals['driver'],context=context).name
olddriver = (vehicle.driver.name) or _('None')
changes.append(_("Driver: from '%s' to '%s'") %(olddriver, value))
if 'state' in vals and vehicle.state.id != vals['state']:
value = self.pool.get('fleet.vehicle.state').browse(cr,uid,vals['state'],context=context).name
oldstate = vehicle.state.name or _('None')
changes.append(_("State: from '%s' to '%s'") %(oldstate, value))
if 'license_plate' in vals and vehicle.license_plate != vals['license_plate']:
old_license_plate = vehicle.license_plate or _('None')
changes.append(_("License Plate: from '%s' to '%s'") %(old_license_plate, vals['license_plate']))
if len(changes) > 0:
self.message_post(cr, uid, [vehicle.id], body=", ".join(changes), context=context)
vehicle_id = super(fleet_vehicle,self).write(cr, uid, ids, vals, context)
return True
class fleet_vehicle_odometer(osv.Model):
_name='fleet.vehicle.odometer'
_description='Odometer log for a vehicle'
_order='date desc'
def _vehicle_log_name_get_fnc(self, cr, uid, ids, prop, unknow_none, context=None):
res = {}
for record in self.browse(cr, uid, ids, context=context):
name = record.vehicle_id.name
if record.date:
name = name+ ' / '+ str(record.date)
res[record.id] = name
return res
def on_change_vehicle(self, cr, uid, ids, vehicle_id, context=None):
if not vehicle_id:
return {}
odometer_unit = self.pool.get('fleet.vehicle').browse(cr, uid, vehicle_id, context=context).odometer_unit
return {
'value': {
'unit': odometer_unit,
}
}
_columns = {
'name': fields.function(_vehicle_log_name_get_fnc, type="char", string='Name', store=True),
'date': fields.date('Date'),
'value': fields.float('Odometer Value', group_operator="max"),
'vehicle_id': fields.many2one('fleet.vehicle', 'Vehicle', required=True),
'unit': fields.related('vehicle_id', 'odometer_unit', type="char", string="Unit", readonly=True),
}
_defaults = {
'date': fields.date.context_today,
}
class fleet_vehicle_log_fuel(osv.Model):
def on_change_vehicle(self, cr, uid, ids, vehicle_id, context=None):
if not vehicle_id:
return {}
odometer_unit = self.pool.get('fleet.vehicle').browse(cr, uid, vehicle_id, context=context).odometer_unit
return {
'value': {
'odometer_unit': odometer_unit,
}
}
def on_change_liter(self, cr, uid, ids, liter, price_per_liter, amount, context=None):
#need to cast in float because the value receveid from web client maybe an integer (Javascript and JSON do not
#make any difference between 3.0 and 3). This cause a problem if you encode, for example, 2 liters at 1.5 per
#liter => total is computed as 3.0, then trigger an onchange that recomputes price_per_liter as 3/2=1 (instead
#of 3.0/2=1.5)
liter = float(liter)
price_per_liter = float(price_per_liter)
amount = float(amount)
if liter > 0 and price_per_liter > 0:
return {'value' : {'amount' : liter * price_per_liter,}}
elif liter > 0 and amount > 0:
return {'value' : {'price_per_liter' : amount / liter,}}
elif price_per_liter > 0 and amount > 0:
return {'value' : {'liter' : amount / price_per_liter,}}
else :
return {}
def on_change_price_per_liter(self, cr, uid, ids, liter, price_per_liter, amount, context=None):
#need to cast in float because the value receveid from web client maybe an integer (Javascript and JSON do not
#make any difference between 3.0 and 3). This cause a problem if you encode, for example, 2 liters at 1.5 per
#liter => total is computed as 3.0, then trigger an onchange that recomputes price_per_liter as 3/2=1 (instead
#of 3.0/2=1.5)
liter = float(liter)
price_per_liter = float(price_per_liter)
amount = float(amount)
if price_per_liter > 0 and liter > 0:
return {'value' : {'amount' : liter * price_per_liter,}}
elif price_per_liter > 0 and amount > 0:
return {'value' : {'liter' : amount / price_per_liter,}}
elif liter > 0 and amount > 0:
return {'value' : {'price_per_liter' : amount / liter,}}
else :
return {}
def on_change_amount(self, cr, uid, ids, liter, price_per_liter, amount, context=None):
#need to cast in float because the value receveid from web client maybe an integer (Javascript and JSON do not
#make any difference between 3.0 and 3). This cause a problem if you encode, for example, 2 liters at 1.5 per
#liter => total is computed as 3.0, then trigger an onchange that recomputes price_per_liter as 3/2=1 (instead
#of 3.0/2=1.5)
liter = float(liter)
price_per_liter = float(price_per_liter)
amount = float(amount)
if amount > 0 and liter > 0:
return {'value': {'price_per_liter': amount / liter,}}
elif amount > 0 and price_per_liter > 0:
return {'value': {'liter': amount / price_per_liter,}}
elif liter > 0 and price_per_liter > 0:
return {'value': {'amount': liter * price_per_liter,}}
return {}
def _get_default_service_type(self, cr, uid, context):
try:
model, model_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'fleet', 'type_service_refueling')
except ValueError:
model_id = False
return model_id
_name = 'fleet.vehicle.log.fuel'
_description = 'Fuel log for vehicles'
_inherits = {'fleet.vehicle.cost': 'cost_id'}
_columns = {
'liter': fields.float('Liter'),
'price_per_liter': fields.float('Price Per Liter'),
'purchaser_id': fields.many2one('res.partner', 'Purchaser', domain="['|',('customer','=',True),('employee','=',True)]"),
'inv_ref': fields.char('Invoice Reference', size=64),
'vendor_id': fields.many2one('res.partner', 'Supplier', domain="[('supplier','=',True)]"),
'notes': fields.text('Notes'),
'cost_amount': fields.related('cost_id', 'amount', string='Amount', type='float', store=True), #we need to keep this field as a related with store=True because the graph view doesn't support (1) to address fields from inherited table and (2) fields that aren't stored in database
}
_defaults = {
'purchaser_id': lambda self, cr, uid, ctx: uid,
'date': fields.date.context_today,
'cost_subtype': _get_default_service_type,
'cost_type': 'fuel',
}
class fleet_vehicle_log_services(osv.Model):
def on_change_vehicle(self, cr, uid, ids, vehicle_id, context=None):
if not vehicle_id:
return {}
odometer_unit = self.pool.get('fleet.vehicle').browse(cr, uid, vehicle_id, context=context).odometer_unit
return {
'value': {
'odometer_unit': odometer_unit,
}
}
def _get_default_service_type(self, cr, uid, context):
try:
model, model_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'fleet', 'type_service_service_8')
except ValueError:
model_id = False
return model_id
_inherits = {'fleet.vehicle.cost': 'cost_id'}
_name = 'fleet.vehicle.log.services'
_description = 'Services for vehicles'
_columns = {
'purchaser_id': fields.many2one('res.partner', 'Purchaser', domain="['|',('customer','=',True),('employee','=',True)]"),
'inv_ref': fields.char('Invoice Reference', size=64),
'vendor_id': fields.many2one('res.partner', 'Supplier', domain="[('supplier','=',True)]"),
'cost_amount': fields.related('cost_id', 'amount', string='Amount', type='float', store=True), #we need to keep this field as a related with store=True because the graph view doesn't support (1) to address fields from inherited table and (2) fields that aren't stored in database
'notes': fields.text('Notes'),
}
_defaults = {
'purchaser_id': lambda self, cr, uid, ctx: uid,
'date': fields.date.context_today,
'cost_subtype': _get_default_service_type,
'cost_type': 'services'
}
class fleet_service_type(osv.Model):
_name = 'fleet.service.type'
_description = 'Type of services available on a vehicle'
_columns = {
'name': fields.char('Name', required=True, translate=True),
'category': fields.selection([('contract', 'Contract'), ('service', 'Service'), ('both', 'Both')], 'Category', required=True, help='Choose wheter the service refer to contracts, vehicle services or both'),
}
class fleet_vehicle_log_contract(osv.Model):
def scheduler_manage_auto_costs(self, cr, uid, context=None):
#This method is called by a cron task
#It creates costs for contracts having the "recurring cost" field setted, depending on their frequency
#For example, if a contract has a reccuring cost of 200 with a weekly frequency, this method creates a cost of 200 on the first day of each week, from the date of the last recurring costs in the database to today
#If the contract has not yet any recurring costs in the database, the method generates the recurring costs from the start_date to today
#The created costs are associated to a contract thanks to the many2one field contract_id
#If the contract has no start_date, no cost will be created, even if the contract has recurring costs
vehicle_cost_obj = self.pool.get('fleet.vehicle.cost')
d = datetime.datetime.strptime(fields.date.context_today(self, cr, uid, context=context), tools.DEFAULT_SERVER_DATE_FORMAT).date()
contract_ids = self.pool.get('fleet.vehicle.log.contract').search(cr, uid, [('state','!=','closed')], offset=0, limit=None, order=None,context=None, count=False)
deltas = {'yearly': relativedelta(years=+1), 'monthly': relativedelta(months=+1), 'weekly': relativedelta(weeks=+1), 'daily': relativedelta(days=+1)}
for contract in self.pool.get('fleet.vehicle.log.contract').browse(cr, uid, contract_ids, context=context):
if not contract.start_date or contract.cost_frequency == 'no':
continue
found = False
last_cost_date = contract.start_date
if contract.generated_cost_ids:
last_autogenerated_cost_id = vehicle_cost_obj.search(cr, uid, ['&', ('contract_id','=',contract.id), ('auto_generated','=',True)], offset=0, limit=1, order='date desc',context=context, count=False)
if last_autogenerated_cost_id:
found = True
last_cost_date = vehicle_cost_obj.browse(cr, uid, last_autogenerated_cost_id[0], context=context).date
startdate = datetime.datetime.strptime(last_cost_date, tools.DEFAULT_SERVER_DATE_FORMAT).date()
if found:
startdate += deltas.get(contract.cost_frequency)
while (startdate < d) & (startdate < datetime.datetime.strptime(contract.expiration_date, tools.DEFAULT_SERVER_DATE_FORMAT).date()):
data = {
'amount': contract.cost_generated,
'date': startdate.strftime(tools.DEFAULT_SERVER_DATE_FORMAT),
'vehicle_id': contract.vehicle_id.id,
'cost_subtype': contract.cost_subtype.id,
'contract_id': contract.id,
'auto_generated': True
}
cost_id = self.pool.get('fleet.vehicle.cost').create(cr, uid, data, context=context)
startdate += deltas.get(contract.cost_frequency)
return True
def scheduler_manage_contract_expiration(self, cr, uid, context=None):
#This method is called by a cron task
#It manages the state of a contract, possibly by posting a message on the vehicle concerned and updating its status
datetime_today = datetime.datetime.strptime(fields.date.context_today(self, cr, uid, context=context), tools.DEFAULT_SERVER_DATE_FORMAT)
limit_date = (datetime_today + relativedelta(days=+15)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
ids = self.search(cr, uid, ['&', ('state', '=', 'open'), ('expiration_date', '<', limit_date)], offset=0, limit=None, order=None, context=context, count=False)
res = {}
for contract in self.browse(cr, uid, ids, context=context):
if contract.vehicle_id.id in res:
res[contract.vehicle_id.id] += 1
else:
res[contract.vehicle_id.id] = 1
for vehicle, value in res.items():
self.pool.get('fleet.vehicle').message_post(cr, uid, vehicle, body=_('%s contract(s) need(s) to be renewed and/or closed!') % (str(value)), context=context)
return self.write(cr, uid, ids, {'state': 'toclose'}, context=context)
def run_scheduler(self, cr, uid, context=None):
self.scheduler_manage_auto_costs(cr, uid, context=context)
self.scheduler_manage_contract_expiration(cr, uid, context=context)
return True
def _vehicle_contract_name_get_fnc(self, cr, uid, ids, prop, unknow_none, context=None):
res = {}
for record in self.browse(cr, uid, ids, context=context):
name = record.vehicle_id.name
if record.cost_subtype.name:
name += ' / '+ record.cost_subtype.name
if record.date:
name += ' / '+ record.date
res[record.id] = name
return res
def on_change_vehicle(self, cr, uid, ids, vehicle_id, context=None):
if not vehicle_id:
return {}
odometer_unit = self.pool.get('fleet.vehicle').browse(cr, uid, vehicle_id, context=context).odometer_unit
return {
'value': {
'odometer_unit': odometer_unit,
}
}
def compute_next_year_date(self, strdate):
oneyear = datetime.timedelta(days=365)
curdate = str_to_datetime(strdate)
return datetime.datetime.strftime(curdate + oneyear, tools.DEFAULT_SERVER_DATE_FORMAT)
def on_change_start_date(self, cr, uid, ids, strdate, enddate, context=None):
if (strdate):
return {'value': {'expiration_date': self.compute_next_year_date(strdate),}}
return {}
def get_days_left(self, cr, uid, ids, prop, unknow_none, context=None):
"""return a dict with as value for each contract an integer
if contract is in an open state and is overdue, return 0
if contract is in a closed state, return -1
otherwise return the number of days before the contract expires
"""
res = {}
for record in self.browse(cr, uid, ids, context=context):
if (record.expiration_date and (record.state == 'open' or record.state == 'toclose')):
today = str_to_datetime(time.strftime(tools.DEFAULT_SERVER_DATE_FORMAT))
renew_date = str_to_datetime(record.expiration_date)
diff_time = (renew_date-today).days
res[record.id] = diff_time > 0 and diff_time or 0
else:
res[record.id] = -1
return res
def act_renew_contract(self, cr, uid, ids, context=None):
assert len(ids) == 1, "This operation should only be done for 1 single contract at a time, as it it suppose to open a window as result"
for element in self.browse(cr, uid, ids, context=context):
#compute end date
startdate = str_to_datetime(element.start_date)
enddate = str_to_datetime(element.expiration_date)
diffdate = (enddate - startdate)
default = {
'date': fields.date.context_today(self, cr, uid, context=context),
'start_date': datetime.datetime.strftime(str_to_datetime(element.expiration_date) + datetime.timedelta(days=1), tools.DEFAULT_SERVER_DATE_FORMAT),
'expiration_date': datetime.datetime.strftime(enddate + diffdate, tools.DEFAULT_SERVER_DATE_FORMAT),
}
newid = super(fleet_vehicle_log_contract, self).copy(cr, uid, [element.id], default, context=context)
mod, modid = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'fleet', 'fleet_vehicle_log_contract_form')
return {
'name':_("Renew Contract"),
'view_mode': 'form',
'view_id': modid,
'view_type': 'tree,form',
'res_model': 'fleet.vehicle.log.contract',
'type': 'ir.actions.act_window',
'nodestroy': True,
'domain': '[]',
'res_id': newid,
'context': {'active_id':newid},
}
def _get_default_contract_type(self, cr, uid, context=None):
try:
model, model_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'fleet', 'type_contract_leasing')
except ValueError:
model_id = False
return model_id
def on_change_indic_cost(self, cr, uid, ids, cost_ids, context=None):
totalsum = 0.0
for element in cost_ids:
if element and len(element) == 3 and element[2] is not False:
totalsum += element[2].get('amount', 0.0)
return {
'value': {
'sum_cost': totalsum,
}
}
def _get_sum_cost(self, cr, uid, ids, field_name, arg, context=None):
res = {}
for contract in self.browse(cr, uid, ids, context=context):
totalsum = 0
for cost in contract.cost_ids:
totalsum += cost.amount
res[contract.id] = totalsum
return res
_inherits = {'fleet.vehicle.cost': 'cost_id'}
_name = 'fleet.vehicle.log.contract'
_description = 'Contract information on a vehicle'
_order='state desc,expiration_date'
_columns = {
'name': fields.function(_vehicle_contract_name_get_fnc, type="text", string='Name', store=True),
'start_date': fields.date('Contract Start Date', help='Date when the coverage of the contract begins'),
'expiration_date': fields.date('Contract Expiration Date', help='Date when the coverage of the contract expirates (by default, one year after begin date)'),
'days_left': fields.function(get_days_left, type='integer', string='Warning Date'),
'insurer_id' :fields.many2one('res.partner', 'Supplier'),
'purchaser_id': fields.many2one('res.partner', 'Contractor', help='Person to which the contract is signed for'),
'ins_ref': fields.char('Contract Reference', size=64),
'state': fields.selection([('open', 'In Progress'), ('toclose','To Close'), ('closed', 'Terminated')], 'Status', readonly=True, help='Choose wheter the contract is still valid or not'),
'notes': fields.text('Terms and Conditions', help='Write here all supplementary informations relative to this contract'),
'cost_generated': fields.float('Recurring Cost Amount', help="Costs paid at regular intervals, depending on the cost frequency. If the cost frequency is set to unique, the cost will be logged at the start date"),
'cost_frequency': fields.selection([('no','No'), ('daily', 'Daily'), ('weekly','Weekly'), ('monthly','Monthly'), ('yearly','Yearly')], 'Recurring Cost Frequency', help='Frequency of the recuring cost', required=True),
'generated_cost_ids': fields.one2many('fleet.vehicle.cost', 'contract_id', 'Generated Costs', ondelete='cascade'),
'sum_cost': fields.function(_get_sum_cost, type='float', string='Indicative Costs Total'),
'cost_amount': fields.related('cost_id', 'amount', string='Amount', type='float', store=True), #we need to keep this field as a related with store=True because the graph view doesn't support (1) to address fields from inherited table and (2) fields that aren't stored in database
}
_defaults = {
'purchaser_id': lambda self, cr, uid, ctx: uid,
'date': fields.date.context_today,
'start_date': fields.date.context_today,
'state':'open',
'expiration_date': lambda self, cr, uid, ctx: self.compute_next_year_date(fields.date.context_today(self, cr, uid, context=ctx)),
'cost_frequency': 'no',
'cost_subtype': _get_default_contract_type,
'cost_type': 'contract',
}
def copy(self, cr, uid, id, default=None, context=None):
if default is None:
default = {}
today = fields.date.context_today(self, cr, uid, context=context)
default['date'] = today
default['start_date'] = today
default['expiration_date'] = self.compute_next_year_date(today)
default['ins_ref'] = ''
default['state'] = 'open'
default['notes'] = ''
return super(fleet_vehicle_log_contract, self).copy(cr, uid, id, default, context=context)
def contract_close(self, cr, uid, ids, context=None):
return self.write(cr, uid, ids, {'state': 'closed'}, context=context)
def contract_open(self, cr, uid, ids, context=None):
return self.write(cr, uid, ids, {'state': 'open'}, context=context)
class fleet_contract_state(osv.Model):
_name = 'fleet.contract.state'
_description = 'Contains the different possible status of a leasing contract'
_columns = {
'name':fields.char('Contract Status', size=64, required=True),
}

View File

@ -0,0 +1,151 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record model="ir.actions.act_window" id="action_fleet_vehicle_log_fuel_graph">
<field name="name">Fuel Costs by Month</field>
<field name="res_model">fleet.vehicle.cost</field>
<field name="view_id" ref="fleet_vehicle_costs_graph"></field>
<field name="view_type">form</field>
<field name="view_mode">tree</field>
<field name="domain">['&amp;',('parent_id','=',False),('cost_type','=','fuel')]</field>
</record>
<record model="ir.actions.act_window" id="action_fleet_vehicle_log_services_graph">
<field name="name">Services Costs by Month</field>
<field name="res_model">fleet.vehicle.cost</field>
<field name="view_id" ref="fleet_vehicle_costs_graph" />
<field name="view_type">form</field>
<field name="view_mode">tree</field>
<field name="domain">['&amp;',('parent_id','=',False),('cost_type','=','services')]</field>
</record>
<record model="ir.actions.act_window" id="action_fleet_vehicle_log_contract_graph">
<field name="name">Contracts Costs by Month</field>
<field name="res_model">fleet.vehicle.cost</field>
<field name="view_id" ref="fleet_vehicle_costs_graph"></field>
<field name="view_type">form</field>
<field name="view_mode">tree</field>
<field name="domain">['&amp;',('parent_id','=',False),('cost_type','=','contract')]</field>
</record>
<record model="ir.actions.act_window" id="action_fleet_vehicle_costs_graph">
<field name="name">Costs by Month</field>
<field name="res_model">fleet.vehicle.cost</field>
<field name="view_id" ref="fleet_vehicle_costs_graph"></field>
<field name="view_type">form</field>
<field name="view_mode">tree</field>
<field name="domain">[('parent_id','=',False)]</field>
</record>
<record model="ir.actions.act_window" id="action_fleet_vehicle_kanban">
<field name="name">Vehicles with alerts</field>
<field name="res_model">fleet.vehicle</field>
<field name="view_id" ref="fleet_vehicle_kanban"></field>
<field name="view_type">form</field>
<field name="view_mode">tree</field>
<field name="domain">['|',('contract_renewal_due_soon','=',True),('contract_renewal_overdue','=',True)]</field>
<field name="help" type="html">
<p>
Here are displayed vehicles for which one or more contracts need to be renewed. If you see this message, then there is no contracts to renew.
</p>
</field>
</record>
<record model="ir.actions.act_window" id="action_fleet_reporting_costs">
<field name="name">Costs Analysis</field>
<field name="res_model">fleet.vehicle.cost</field>
<field name="view_id" ref="fleet_vehicle_costs_tree"></field>
<field name="view_type">form</field>
<field name="view_mode">tree</field>
<field name="context">{"search_default_parent_false" : True,"search_default_groupby_year" : True,"search_default_groupby_cost_type" : True,"search_default_groupby_cost_subtype" : True, "search_default_groupby_vehicle_id" : True,}</field>
<field name="help" type="html">
<p>
OpenERP helps you managing the costs for your different vehicles
Costs are generally created from services and contract and appears here.
</p>
<p>
Thanks to the different filters, OpenERP can only print the effective
costs, sort them by type and by vehicle.
</p>
</field>
</record>
<record model="ir.actions.act_window" id="action_fleet_reporting_costs_non_effective">
<field name="name">Indicative Costs Analysis</field>
<field name="res_model">fleet.vehicle.cost</field>
<field name="view_id" ref="fleet_vehicle_costs_tree"></field>
<field name="view_type">form</field>
<field name="view_mode">tree</field>
<field name="context">{"search_default_parent_true" : True,"search_default_groupby_cost_subtype" : True,"search_default_groupby_cost_type" : True,"search_default_groupby_parent_id" : True,}</field>
<field name="help" type="html">
<p>
OpenERP helps you managing the costs for your different vehicles
Costs are generally created from services and contract and appears here.
</p>
<p>
Thanks to the different filters, OpenERP can only print the effective
costs, sort them by type and by vehicle.
</p>
</field>
</record>
<record id="board_fleet_form" model="ir.ui.view">
<field name="name">board.fleet.form</field>
<field name="model">board.board</field>
<field name="arch" type="xml">
<form string="Fleet Dashboard" version="7.0">
<board style="2-1">
<column>
<action string="Vehicles With Alerts" name="%(fleet.action_fleet_vehicle_kanban)d" view_mode="kanban"/>
<action string="Costs by Month" name="%(fleet.action_fleet_vehicle_costs_graph)d" view_mode="graph,tree"/>
</column>
<column>
<action string="Fuel Costs" name="%(fleet.action_fleet_vehicle_log_fuel_graph)d" view_mode="graph,tree"/>
<action string="Services Costs" name="%(fleet.action_fleet_vehicle_log_services_graph)d" view_mode="graph,tree"/>
<action string="Contracts Costs" name="%(fleet.action_fleet_vehicle_log_contract_graph)d" view_mode="graph,tree"/>
</column>
</board>
</form>
</field>
</record>
<record id="open_board_fleet" model="ir.actions.act_window">
<field name="name">Fleet</field>
<field name="res_model">board.board</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="usage">menu</field>
<field name="view_id" ref="board_fleet_form"/>
<field name="help" type="html">
<div class="oe_empty_custom_dashboard">
<p>
<b>Fleet dashboard is empty.</b>
</p><p>
To add your first report into this dashboard, go to any
menu, switch to list or graph view, and click <i>'Add to
Dashboard'</i> in the extended search options.
</p><p>
You can filter and group data before inserting into the
dashboard using the search options.
</p>
</div>
</field>
</record>
<menuitem id="menu_fleet_dashboard"
parent="base.menu_reporting_dashboard"
action="open_board_fleet"
sequence="50"/>
<menuitem name="Fleet" parent="base.menu_reporting" id="menu_fleet_reporting" sequence="50" />
<menuitem id="menu_fleet_reporting_costs"
parent="menu_fleet_reporting"
action="action_fleet_reporting_costs"
sequence="1"/>
<menuitem id="menu_fleet_reporting_indicative_costs"
parent="menu_fleet_reporting"
action="action_fleet_reporting_costs_non_effective"
sequence="2"/>
</data>
</openerp>

13736
addons/fleet/fleet_cars.xml Normal file

File diff suppressed because it is too large Load Diff

440
addons/fleet/fleet_data.xml Normal file
View File

@ -0,0 +1,440 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="0">
<!--
<record forcecreate="True" id="ir_cron_service_services_reminders" model="ir.cron">
<field name="name">Creation of Vehicle services and Services renewals reminders</field>
<field eval="True" name="active" />
<field name="user_id" ref="base.user_root" />
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall" />
<field eval="'fleet.vehicle'" name="model" />
<field eval="'run_scheduler'" name="function" />
<field eval="'()'" name="args" />
</record>
-->
<record forcecreate="True" id="ir_cron_contract_costs_generator" model="ir.cron">
<field name="name">Generation of contracts costs based on the costs frequency</field>
<field eval="True" name="active" />
<field name="user_id" ref="base.user_root" />
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall" />
<field eval="'fleet.vehicle.log.contract'" name="model" />
<field eval="'run_scheduler'" name="function" />
<field eval="'()'" name="args" />
</record>
<record id="type_service_service_1" model="fleet.service.type">
<field name="name">Calculation Benefit In Kind</field>
<field name="category">service</field>
</record>
<record id="type_service_service_2" model="fleet.service.type">
<field name="name">Depreciation and Interests</field>
<field name="category">service</field>
</record>
<record id="type_service_service_3" model="fleet.service.type">
<field name="name">Tax roll</field>
<field name="category">service</field>
</record>
<record id="type_service_service_5" model="fleet.service.type">
<field name="name">Summer tires</field>
<field name="category">service</field>
</record>
<record id="type_service_service_6" model="fleet.service.type">
<field name="name">Snow tires</field>
<field name="category">service</field>
</record>
<record id="type_service_service_7" model="fleet.service.type">
<field name="name">Summer tires</field>
<field name="category">service</field>
</record>
<record id="type_service_service_8" model="fleet.service.type">
<field name="name">Repair and maintenance</field>
<field name="category">service</field>
</record>
<record id="type_service_service_9" model="fleet.service.type">
<field name="name">Assistance</field>
<field name="category">service</field>
</record>
<record id="type_service_service_10" model="fleet.service.type">
<field name="name">Replacement Vehicle</field>
<field name="category">service</field>
</record>
<record id="type_service_service_11" model="fleet.service.type">
<field name="name">Management Fee</field>
<field name="category">service</field>
</record>
<record id="type_service_service_12" model="fleet.service.type">
<field name="name">Rent (Excluding VAT)</field>
<field name="category">service</field>
</record>
<record id="type_service_service_13" model="fleet.service.type">
<field name="name">Entry into service tax</field>
<field name="category">service</field>
</record>
<record id="type_service_service_14" model="fleet.service.type">
<field name="name">Total expenses (Excluding VAT)</field>
<field name="category">service</field>
</record>
<record id="type_service_service_15" model="fleet.service.type">
<field name="name">Residual value (Excluding VAT)</field>
<field name="category">service</field>
</record>
<record id="type_service_service_16" model="fleet.service.type">
<field name="name">Options</field>
<field name="category">service</field>
</record>
<record id="type_service_service_17" model="fleet.service.type">
<field name="name">Emissions</field>
<field name="category">service</field>
</record>
<record id="type_service_service_18" model="fleet.service.type">
<field name="name">Touring Assistance</field>
<field name="category">service</field>
</record>
<record id="type_service_service_19" model="fleet.service.type">
<field name="name">Residual value in %</field>
<field name="category">service</field>
</record>
<record id="type_service_1" model="fleet.service.type">
<field name="name">A/C Compressor Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_2" model="fleet.service.type">
<field name="name">A/C Condenser Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_3" model="fleet.service.type">
<field name="name">A/C Diagnosis</field>
<field name="category">service</field>
</record>
<record id="type_service_4" model="fleet.service.type">
<field name="name">A/C Evaporator Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_5" model="fleet.service.type">
<field name="name">A/C Recharge</field>
<field name="category">service</field>
</record>
<record id="type_service_6" model="fleet.service.type">
<field name="name">Air Filter Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_7" model="fleet.service.type">
<field name="name">Alternator Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_8" model="fleet.service.type">
<field name="name">Ball Joint Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_9" model="fleet.service.type">
<field name="name">Battery Inspection</field>
<field name="category">service</field>
</record>
<record id="type_service_10" model="fleet.service.type">
<field name="name">Battery Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_11" model="fleet.service.type">
<field name="name">Brake Caliper Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_12" model="fleet.service.type">
<field name="name">Brake Inspection</field>
<field name="category">service</field>
</record>
<record id="type_service_13" model="fleet.service.type">
<field name="name">Brake Pad(s) Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_14" model="fleet.service.type">
<field name="name">Car Wash</field>
<field name="category">service</field>
</record>
<record id="type_service_15" model="fleet.service.type">
<field name="name">Catalytic Converter Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_16" model="fleet.service.type">
<field name="name">Charging System Diagnosis</field>
<field name="category">service</field>
</record>
<record id="type_service_17" model="fleet.service.type">
<field name="name">Door Window Motor/Regulator Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_18" model="fleet.service.type">
<field name="name">Engine Belt Inspection</field>
<field name="category">service</field>
</record>
<record id="type_service_19" model="fleet.service.type">
<field name="name">Engine Coolant Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_20" model="fleet.service.type">
<field name="name">Engine/Drive Belt(s) Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_21" model="fleet.service.type">
<field name="name">Exhaust Manifold Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_22" model="fleet.service.type">
<field name="name">Fuel Injector Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_23" model="fleet.service.type">
<field name="name">Fuel Pump Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_24" model="fleet.service.type">
<field name="name">Head Gasket(s) Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_25" model="fleet.service.type">
<field name="name">Heater Blower Motor Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_26" model="fleet.service.type">
<field name="name">Heater Control Valve Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_27" model="fleet.service.type">
<field name="name">Heater Core Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_28" model="fleet.service.type">
<field name="name">Heater Hose Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_29" model="fleet.service.type">
<field name="name">Ignition Coil Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_30" model="fleet.service.type">
<field name="name">Intake Manifold Gasket Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_31" model="fleet.service.type">
<field name="name">Oil Change</field>
<field name="category">service</field>
</record>
<record id="type_service_32" model="fleet.service.type">
<field name="name">Oil Pump Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_33" model="fleet.service.type">
<field name="name">Other Maintenance</field>
<field name="category">service</field>
</record>
<record id="type_service_34" model="fleet.service.type">
<field name="name">Oxygen Sensor Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_35" model="fleet.service.type">
<field name="name">Power Steering Hose Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_36" model="fleet.service.type">
<field name="name">Power Steering Pump Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_37" model="fleet.service.type">
<field name="name">Radiator Repair</field>
<field name="category">service</field>
</record>
<record id="type_service_38" model="fleet.service.type">
<field name="name">Resurface Rotors</field>
<field name="category">service</field>
</record>
<record id="type_service_39" model="fleet.service.type">
<field name="name">Rotate Tires</field>
<field name="category">service</field>
</record>
<record id="type_service_40" model="fleet.service.type">
<field name="name">Rotor Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_41" model="fleet.service.type">
<field name="name">Spark Plug Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_42" model="fleet.service.type">
<field name="name">Starter Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_43" model="fleet.service.type">
<field name="name">Thermostat Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_44" model="fleet.service.type">
<field name="name">Tie Rod End Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_45" model="fleet.service.type">
<field name="name">Tire Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_46" model="fleet.service.type">
<field name="name">Tire Service</field>
<field name="category">service</field>
</record>
<record id="type_service_47" model="fleet.service.type">
<field name="name">Transmission Filter Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_48" model="fleet.service.type">
<field name="name">Transmission Fluid Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_49" model="fleet.service.type">
<field name="name">Transmission Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_50" model="fleet.service.type">
<field name="name">Water Pump Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_51" model="fleet.service.type">
<field name="name">Wheel Alignment</field>
<field name="category">service</field>
</record>
<record id="type_service_52" model="fleet.service.type">
<field name="name">Wheel Bearing Replacement</field>
<field name="category">service</field>
</record>
<record id="type_service_53" model="fleet.service.type">
<field name="name">Windshield Wiper(s) Replacement</field>
<field name="category">service</field>
</record>
<record id="type_contract_omnium" model="fleet.service.type">
<field name="name">Omnium</field>
<field name="category">contract</field>
</record>
<record id="type_contract_leasing" model="fleet.service.type">
<field name="name">Leasing</field>
<field name="category">contract</field>
</record>
<record id="type_contract_repairing" model="fleet.service.type">
<field name="name">Repairing</field>
<field name="category">both</field>
</record>
<record id="type_service_refueling" model="fleet.service.type">
<field name="name">Refueling</field>
<field name="category">service</field>
</record>
<record id="vehicle_tag_junior" model="fleet.vehicle.tag" >
<field name="name">Junior</field>
</record>
<record id="vehicle_tag_senior" model="fleet.vehicle.tag" >
<field name="name">Senior</field>
</record>
<record id="vehicle_tag_leasing" model="fleet.vehicle.tag" >
<field name="name">Employee Car</field>
</record>
<record id="vehicle_tag_purchased" model="fleet.vehicle.tag" >
<field name="name">Purchased</field>
</record>
<record id="vehicle_tag_compact" model="fleet.vehicle.tag" >
<field name="name">Compact</field>
</record>
<record id="vehicle_tag_sedan" model="fleet.vehicle.tag" >
<field name="name">Sedan</field>
</record>
<record id="vehicle_tag_convertible" model="fleet.vehicle.tag" >
<field name="name">Convertible</field>
</record>
<record id="vehicle_tag_break" model="fleet.vehicle.tag" >
<field name="name">Break</field>
</record>
</data>
</openerp>

1166
addons/fleet/fleet_demo.xml Normal file

File diff suppressed because it is too large Load Diff

907
addons/fleet/fleet_view.xml Normal file
View File

@ -0,0 +1,907 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<record model='ir.ui.view' id='fleet_vehicle_model_form'>
<field name="name">fleet.vehicle.model.form</field>
<field name="model">fleet.vehicle.model</field>
<field name="arch" type="xml">
<form string="Model" version="7.0">
<sheet>
<field name="image_medium" widget='image' class="oe_left oe_avatar"/>
<group col="2">
<group>
<field name="brand" on_change="on_change_brand(brand)"/>
</group>
<group>
<field name="modelname" />
</group>
</group>
<notebook>
<page string="Vendors">
<field name="vendors" widget="many2many_kanban"/>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record model='ir.ui.view' id='fleet_vehicle_model_tree'>
<field name="name">fleet.vehicle.model.tree</field>
<field name="model">fleet.vehicle.model</field>
<field name="arch" type="xml">
<tree string="Models" version="7.0">
<field name="brand" />
<field name="modelname" />
</tree>
</field>
</record>
<record model='ir.actions.act_window' id='fleet_vehicle_model_act'>
<field name="name">Vehicle Model</field>
<field name="res_model">fleet.vehicle.model</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new model.
</p><p>
You can define several models (e.g. A3, A4) for each brand (Audi).
</p>
</field>
</record>
<record model='ir.ui.view' id='fleet_vehicle_model_brand_tree'>
<field name="name">fleet.vehicle.model.brand.tree</field>
<field name="model">fleet.vehicle.model.brand</field>
<field name="arch" type="xml">
<tree string="Model Brand" version="7.0">
<field name="name" />
</tree>
</field>
</record>
<record model='ir.ui.view' id='fleet_vehicle_model_brand_form'>
<field name="name">fleet.vehicle.model.brand.form</field>
<field name="model">fleet.vehicle.model.brand</field>
<field name="arch" type="xml">
<form string="Model Brand" version="7.0">
<sheet>
<group>
<div>
<field name="image_medium" widget="image" class="oe_left oe_avatar"/>
<label for="name" class="oe_edit_only"/>
<h1>
<field name="name" class="oe_inline" />
</h1>
</div>
</group>
</sheet>
</form>
</field>
</record>
<record model='ir.ui.view' id='fleet_vehicle_model_brand_kanban'>
<field name="name">fleet.vehicle.model.brandkanban</field>
<field name="model">fleet.vehicle.model.brand</field>
<field name="arch" type="xml">
<kanban>
<field name="name" />
<field name="image" />
<templates>
<t t-name="kanban-box">
<div class="oe_kanban_vignette oe_semantic_html_override">
<a type="open" href="#" class="oe_kanban_action oe_kanban_action_a">
<img t-att-src="kanban_image('fleet.vehicle.model.brand', 'image_small', record.id.value)" class="oe_employee_picture"/>
</a>
<div style="text-align:center;">
<h4 class="oe_partner_heading">
<a type="open">
<field name="name"/>
</a>
</h4>
</div>
</div>
<script>
$('.oe_picture').load(function() { if($(this).width() > $(this).height()) { $(this).addClass('oe_employee_picture_wide') } });
</script>
</t>
</templates>
</kanban>
</field>
</record>
<record model='ir.actions.act_window' id='fleet_vehicle_model_brand_act'>
<field name="name">Model brand of Vehicle</field>
<field name="res_model">fleet.vehicle.model.brand</field>
<field name="view_type">form</field>
<field name="view_mode">kanban,tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new brand.
</p>
</field>
</record>
<record model='ir.ui.view' id='fleet_vehicle_state_tree'>
<field name="name">fleet.vehicle.state.tree</field>
<field name="model">fleet.vehicle.state</field>
<field name="arch" type="xml">
<tree string="State" version="7.0" editable="bottom">
<field name="sequence" widget="handler" invisible="1"/>
<field name="name" />
</tree>
</field>
</record>
<record model='ir.actions.act_window' id='fleet_vehicle_state_act'>
<field name="name">States of Vehicle</field>
<field name="res_model">fleet.vehicle.state</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a vehicule status.
</p><p>
You can customize available status to track the evolution of
each vehicule. Example: Active, Being Repaired, Sold.
</p>
</field>
</record>
<menuitem name="Fleet" id="menu_root" sequence="70" />
<menuitem name="Configuration" parent="menu_root" id="fleet_configuration" sequence="3" />
<menuitem action="fleet_vehicle_model_act" parent="fleet_configuration" id="fleet_vehicle_model_menu" groups="base.group_no_one"/>
<menuitem action="fleet_vehicle_model_brand_act" parent="fleet_configuration" id="fleet_vehicle_model_brand_menu" groups="base.group_no_one"/>
<menuitem action="fleet_vehicle_state_act" parent="fleet_configuration" id="fleet_vehicle_state_menu" />
<record model='ir.ui.view' id='fleet_vehicle_form'>
<field name="name">fleet.vehicle.form</field>
<field name="model">fleet.vehicle</field>
<field name="arch" type="xml">
<form string="Vehicle" version="7.0">
<header>
<field name="state" widget="statusbar" clickable="True" />
</header>
<sheet>
<field name="image_medium" widget='image' class="oe_left oe_avatar"/>
<div class="oe_title">
<label for="model_id" class="oe_edit_only"/>
<h1>
<field name="model_id" class="oe_inline" on_change="on_change_model(model_id)"/>
</h1>
<label for="license_plate" class="oe_edit_only"/>
<h2>
<field name="license_plate" class="oe_inline"/>
</h2>
<label for="tag_ids" class="oe_edit_only"/>
<field name="tag_ids" widget="many2many_tags" />
</div>
<div class="oe_right oe_button_box">
<button name="return_action_to_open" type="object" context="{'xml_id':'fleet_vehicle_log_contract_act'}" string="Contracts" help="show the contract for this vehicle" />
<button name="act_show_log_cost" type="object" string="Costs" help="show all the costs for this vehicle" />
<button name="return_action_to_open" type="object" context="{'xml_id':'fleet_vehicle_log_services_act'}" string="Services" help="show the services logs for this vehicle" />
<button name="return_action_to_open" type="object" context="{'xml_id':'fleet_vehicle_log_fuel_act'}" string="Fuel Logs" help="show the fuel logs for this vehicle" />
<button name="return_action_to_open" type="object" context="{'xml_id':'fleet_vehicle_odometer_act'}" string="Odometer Logs" help="show the odometer logs for this vehicle" />
</div>
<group col="2" string="General Properties">
<group >
<field name="driver" />
<field name="location" />
<field name="vin_sn" />
<field name="company_id" groups="base.group_multi_company"/>
</group>
<group >
<label for="odometer" />
<div>
<field name="odometer" class="oe_inline"/>
<field name="odometer_unit" class="oe_inline"/>
</div>
<field name="acquisition_date" />
<field name="car_value" />
</group>
</group>
<group col="2">
<group string="Additional Properties">
<field name="seats" />
<field name="doors" />
<field name="color" />
</group>
<group string="Engine Options">
<field name="transmission" />
<field name="fuel_type" />
<field name="co2" />
<field name="horsepower" />
<field name="horsepower_tax" />
<field name="power" />
</group>
</group>
</sheet>
<div class="oe_chatter">
<field name="message_ids" widget="mail_thread" options='{"thread_level": 1}'/>
<field name="message_follower_ids" widget="mail_followers"/>
</div>
</form>
</field>
</record>
<record model='ir.ui.view' id='fleet_vehicle_tree'>
<field name="name">fleet.vehicle.tree</field>
<field name="model">fleet.vehicle</field>
<field name="sequence">1</field>
<field name="arch" type="xml">
<tree string="Vehicle" version="7.0" colors="orange:contract_renewal_due_soon and not contract_renewal_overdue;red:contract_renewal_overdue">
<field name="license_plate" />
<field name="model_id" />
<field name="driver" />
<field name="vin_sn" />
<field name="acquisition_date" />
<field name="state"/>
<field name="odometer" />
<field name="odometer_unit" />
<field name="contract_renewal_due_soon" invisible="1"/>
<field name="contract_renewal_overdue" invisible="1" />
<field name="contract_renewal_total" invisible="1"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="fleet_vehicle_search">
<field name="name">fleet.vehicle.search</field>
<field name="model">fleet.vehicle</field>
<field name="arch" type="xml">
<search string="All vehicles">
<field name="name" filter_domain="['|', ('name','ilike',self), ('license_plate','ilike',self)]" string="Vehicle"/>
<field name="driver"/>
<field name="tag_ids"/>
<field name="location"/>
<field name="state" />
<field name="state" />
<filter name="alert_true" domain="['|',('contract_renewal_due_soon','=',True),('contract_renewal_overdue','=',True)]" string="Has Alert(s)"/>
</search>
</field>
</record>
<record model='ir.ui.view' id='fleet_vehicle_kanban'>
<field name="name">fleet.vehicle.kanban</field>
<field name="model">fleet.vehicle</field>
<field name="arch" type="xml">
<kanban>
<field name="license_plate" />
<field name="model_id" />
<field name="driver" />
<field name="location" />
<field name="state" />
<field name="image" />
<field name="tag_ids" />
<field name="contract_renewal_due_soon" />
<field name="contract_renewal_overdue" />
<field name="contract_renewal_name" />
<field name="contract_renewal_total" />
<templates>
<t t-name="kanban-box">
<div class="oe_kanban_vignette oe_semantic_html_override">
<a type="open" href="#" class="oe_kanban_action oe_kanban_action_a">
<img t-att-src="kanban_image('fleet.vehicle', 'image_small', record.id.value)"/>
</a>
<div class="oe_kanban_details">
<h4 class="oe_partner_heading">
<a type="open">
<field name="license_plate"/><br/>
<field name="model_id" />
</a>
</h4>
<t t-if="record.contract_renewal_due_soon.raw_value and !record.contract_renewal_overdue.raw_value">
<a data-type="object" data-name="return_action_to_open" href="#" class="oe_kanban_action oe_kanban_action_a" data-context='{"xml_id":"fleet_vehicle_log_contract_act"}'>
<span class="oe_tag oe_kanban_color_3"><field name="contract_renewal_name" />
<t t-if="record.contract_renewal_total.raw_value > 0"> and <field name="contract_renewal_total" /> other(s) </t>
</span>
</a>
</t>
<t t-if="record.contract_renewal_overdue.raw_value">
<a data-type="object" data-name="return_action_to_open" href="#" class="oe_kanban_action oe_kanban_action_a" data-context='{"xml_id":"fleet_vehicle_log_contract_act"}'>
<span class="oe_tag oe_kanban_color_2"><field name="contract_renewal_name" />
<t t-if="record.contract_renewal_total.raw_value > 0"> and <field name="contract_renewal_total" /> other(s) </t>
</span>
</a>
</t>
<ul>
<li>
<t t-if="record.driver.raw_value"><field name="driver"/></t>
</li>
<li>
<t t-if="record.location.raw_value"><field name="location"/></t>
</li>
</ul>
<div class="oe_kanban_partner_categories">
<span class="oe_kanban_list_many2many">
<div modifiers="{}" name="tag_ids" class="oe_form_field oe_tags" model="fleet.vehicle.tag" t-att-data="record.tag_ids.raw_value" />
</span>
</div>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</record>
<record model='ir.actions.act_window' id='fleet_vehicle_act'>
<field name="name">Vehicles</field>
<field name="res_model">fleet.vehicle</field>
<field name="view_type">form</field>
<field name="view_mode">kanban,tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new vehicle.
</p><p>
You will be able to manage your fleet by keeping track of the
contracts, services, fixed and recurring costs, odometers and
fuel logs associated to each vehicle.
</p><p>
OpenERP will warn you when services or contract have to be
renewed.
</p>
</field>
</record>
<menuitem name="Vehicles" parent="menu_root" id="fleet_vehicles" sequence="2" />
<menuitem action="fleet_vehicle_act" parent="fleet_vehicles" id="fleet_vehicle_menu" />
<record model='ir.ui.view' id='fleet_vehicle_log_contract_form'>
<field name="name">fleet.vehicle.log_contract.form</field>
<field name="model">fleet.vehicle.log.contract</field>
<field name="arch" type="xml">
<form string="Contract logs" version="7.0">
<header>
<button modifiers="{'invisible': [['state', '=', 'closed']]}" name="contract_close" states="open" type="object" class="oe_highlight" string="Terminate Contract"/>
<button modifiers="{'invisible': [['state', '=', 'closed']]}" name="contract_close" states="toclose" type="object" class="oe_highlight" string="Terminate Contract"/>
<button modifiers="{'invisible': [['state', 'not in', ['closed']]]}" name="contract_open" states="closed" type="object" class="oe_highlight" string="Set Contract In Progress"/>
<button class="oe_highlight" name="act_renew_contract" type="object" string="Renew Contract" help="Create a new contract automatically with all the same informations except for the date that will start at the end of current contract" />
<field name="state" widget="statusbar" />
</header>
<sheet>
<group col="2">
<group string="Contract details">
<field name="vehicle_id" on_change="on_change_vehicle(vehicle_id)"/>
<field name="cost_subtype" required="1" domain="['|',('category','=','contract'),('category','=','both')]"/>
<field name="amount" string="Activation Cost"/>
<label for="cost_generated"/>
<div>
<field name="cost_generated" class="oe_inline" attrs="{'invisible': [('cost_frequency','=','no')]}" />
<field name="cost_frequency" class="oe_inline" />
</div>
</group>
<group string="Odometer details">
<label for="odometer"/>
<div>
<field name="odometer" class="oe_inline"/>
<field name="odometer_unit" class="oe_inline"/>
</div>
</group>
</group>
<group col="2">
<group>
<field name="date" string="Invoice Date"/>
<field name="start_date"/>
<field name="expiration_date" />
</group>
<group>
<field name="insurer_id" />
<field name="purchaser_id" />
<field name="ins_ref" />
</group>
</group>
<notebook>
<page string="Included Services">
<group>
<field name="cost_ids" context="{'vehicle_id': vehicle_id}" nolabel="1" on_change="on_change_indic_cost(cost_ids)">
<tree version="7.0" editable="bottom">
<field name="cost_subtype" string="Service" domain="[('category','=','service')]"/>
<field name="amount" sum="Price" string="Indicative Cost" />
</tree>
</field>
</group>
<div class="oe_right"><group><field name="sum_cost" string="Indicative Costs Total"/></group></div>
</page>
<page string="Generated Costs">
<group>
<field name="generated_cost_ids" context="{'vehicle_id': vehicle_id}" nolabel="1" sum="amount">
<tree version="7.0" editable="bottom" >
<field name="date" />
<field name="amount" sum="amount"/>
</tree>
</field>
</group>
</page>
</notebook>
<group string="Terms and Conditions">
<field name="notes" nolabel="1" placeholder="Write here all other information relative to this contract" />
</group>
</sheet>
</form>
</field>
</record>
<act_window
id="act_renew_contract"
name="Renew Contract"
res_model="fleet.vehicle.log.contract"
src_model="fleet.vehicle.log.contract"
view_mode="form"
view_type="form"
/>
<record model='ir.ui.view' id='fleet_vehicle_log_contract_tree'>
<field name="name">fleet.vehicle.log.contract.tree</field>
<field name="model">fleet.vehicle.log.contract</field>
<field name="arch" type="xml">
<tree string="Contract logs" version="7.0" colors="orange:days_left>0 and days_left&lt;15;red:days_left==0;grey:state=='closed'">
<field name="start_date" />
<field name="expiration_date" />
<field name="days_left" invisible="1"/>
<field name="vehicle_id" />
<field name="cost_subtype"/>
<field name="insurer_id" />
<field name="amount" string="Activation Cost"/>
<field name="cost_generated"/>
<field name="cost_frequency"/>
<field name="state" />
</tree>
</field>
</record>
<record model="ir.ui.view" id="fleet_vehicle_log_contract_graph">
<field name="name">fleet.vehicle.log.contract.graph</field>
<field name="model">fleet.vehicle.log.contract</field>
<!--<field name="type">graph</field>-->
<field name="arch" type="xml">
<graph string="Contract Costs Per Month">
<field name="date" />
<field name="cost_amount" operator="+"/>
<field name="vehicle_id" group="True"/>
</graph>
</field>
</record>
<record model='ir.actions.act_window' id='fleet_vehicle_log_contract_act'>
<field name="name">Vehicles Contracts</field>
<field name="res_model">fleet.vehicle.log.contract</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,graph</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new contract.
</p><p>
Manage all your contracts (leasing, insurances, etc.) with
their related services, costs. OpenERP will automatically warn
you when some contracts have to be renewed.
</p><p>
Each contract (e.g.: leasing) may include several services
(reparation, insurances, periodic maintenance).
</p>
</field>
</record>
<menuitem action="fleet_vehicle_log_contract_act" parent="fleet_vehicles" id="fleet_vehicle_log_contract_menu" />
<record model='ir.ui.view' id='fleet_vehicle_odometer_form'>
<field name="name">fleet.vehicle.odometer.form</field>
<field name="model">fleet.vehicle.odometer</field>
<field name="arch" type="xml">
<form string="Odometer Logs" version="7.0">
<sheet>
<group>
<field name="vehicle_id" on_change="on_change_vehicle(vehicle_id)"/>
<div>
<field name="value" class="oe_inline"/>
<field name="unit" class="oe_inline"/>
</div>
<field name="date" />
</group>
</sheet>
</form>
</field>
</record>
<record model='ir.ui.view' id='fleet_vehicle_odometer_tree'>
<field name="name">fleet.vehicle.odometer.tree</field>
<field name="model">fleet.vehicle.odometer</field>
<field name="arch" type="xml">
<tree string="Odometer Logs" version="7.0" editable="bottom">
<field name="date" />
<field name="vehicle_id" on_change="on_change_vehicle(vehicle_id)"/>
<field name="value" />
<field name="unit" />
</tree>
</field>
</record>
<!--
<record model='ir.ui.view' id='fleet_vehicle_odometer_search'>
<field name="name">fleet.vehicle.odometer.search</field>
<field name="model">fleet.vehicle.odometer</field>
<field name="arch" type="xml">
<search string="Vehicles odometers" >
<field name="vehicle_id" />
<field name="value"/>
<field name="unit"/>
<field name="date"/>
<filter name="groupby_vehicle" context="{'group_by' : 'vehicle_id'}" string="Vehicle"/>
</search>
</field>
</record>
-->
<record model="ir.ui.view" id="fleet_vehicle_odometer_graph">
<field name="name">fleet.vehicle.odometer.graph</field>
<field name="model">fleet.vehicle.odometer</field>
<!--<field name="type">graph</field>-->
<field name="arch" type="xml">
<graph string="Odometer Values Per Month">
<field name="date" />
<field name="value" operator="+"/>
<field name="vehicle_id" group="True"/>
</graph>
</field>
</record>
<record model='ir.actions.act_window' id='fleet_vehicle_odometer_act'>
<field name="name">Vehicles Odometer</field>
<field name="res_model">fleet.vehicle.odometer</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,graph</field>
<field name="context">{"search_default_groupby_vehicle" : True}</field>
<field name="help" type="html">
<p>
Here you can add various odometer entries for all vehicles.
You can also show odometer value for a particular vehicle using
the search field.
</p>
</field>
</record>
<menuitem action="fleet_vehicle_odometer_act" parent="fleet_vehicles" id="fleet_vehicle_odometer_menu" />
<record model='ir.ui.view' id='fleet_vehicle_log_fuel_form'>
<field name="name">fleet.vehicle.log.fuel.form</field>
<field name="model">fleet.vehicle.log.fuel</field>
<field name="arch" type="xml">
<form string="Fuel Logs" version="7.0">
<sheet>
<group col="2">
<group string="Vehicle Details">
<field name="vehicle_id" on_change="on_change_vehicle(vehicle_id)"/>
</group>
<group string="Refueling Details">
<field name="liter" on_change="on_change_liter(liter,price_per_liter,amount)"/>
<field name="price_per_liter" on_change="on_change_price_per_liter(liter,price_per_liter,amount)" />
<field name="amount" on_change="on_change_amount(liter,price_per_liter,amount)"/>
</group>
</group>
<group col="2">
<group string="Odometer Details">
<label for="odometer"/>
<div>
<field name="odometer" class="oe_inline"/>
<field name="odometer_unit" class="oe_inline"/>
</div>
</group>
<group string="Additional Details">
<field name="date" />
<field name="purchaser_id" />
<field name="inv_ref" />
<field name="vendor_id" />
</group>
</group>
<group string="Notes">
<field nolabel="1" name="notes" placeholder="Write here any other information"/>
</group>
</sheet>
</form>
</field>
</record>
<record model='ir.ui.view' id='fleet_vehicle_log_fuel_tree'>
<field name="name">fleet.vehicle.log.fuel.tree</field>
<field name="model">fleet.vehicle.log.fuel</field>
<field name="arch" type="xml">
<tree string="Fuel Logs">
<field name="date" />
<field name="vehicle_id" />
<field name="odometer" invisible="1"/>
<field name="odometer_unit" invisible="1"/>
<field name="purchaser_id" />
<field name="inv_ref" invisible="1"/>
<field name="vendor_id" invisible="1"/>
<field name="liter" />
<field name="price_per_liter" invisible="1"/>
<field name="amount" sum="Price"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="fleet_vehicle_log_fuel_graph">
<field name="name">fleet.vehicle.log.fuel.graph</field>
<field name="model">fleet.vehicle.log.fuel</field>
<!--<field name="type">graph</field>-->
<field name="arch" type="xml">
<graph string="Fuel Costs Per Month">
<field name="date" />
<field name="cost_amount" operator="+"/>
<field name="vehicle_id" group="True"/>
</graph>
</field>
</record>
<record model='ir.actions.act_window' id='fleet_vehicle_log_fuel_act'>
<field name="name">Vehicles Fuel Logs</field>
<field name="res_model">fleet.vehicle.log.fuel</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,graph</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new fuel log.
</p><p>
Here you can add refuelling entries for all vehicles. You can
also filter logs of a particular vehicle using the search
field.
</p>
</field>
</record>
<menuitem action="fleet_vehicle_log_fuel_act" parent="fleet_vehicles" id="fleet_vehicle_log_fuel_menu" />
<record model='ir.ui.view' id='fleet_vehicle_log_services_form'>
<field name="name">fleet.vehicle.log.services.form</field>
<field name="model">fleet.vehicle.log.services</field>
<field name="arch" type="xml">
<form string="Services Logs" version="7.0">
<sheet>
<group col="2">
<group string="Services Details">
<field name="vehicle_id" on_change="on_change_vehicle(vehicle_id)"/>
<field name="cost_subtype" string="Service Type" domain="['|',('category','=','service'),('category','=','both')]" required="1"/>
<field name="amount" string="Price"/>
</group>
<group string="Odometer Details">
<label for="odometer"/>
<div>
<field name="odometer" class="oe_inline"/>
<field name="odometer_unit" class="oe_inline"/>
</div>
</group>
</group>
<group col="2">
<group string="Additional Details">
<field name="date" />
<field name="purchaser_id" />
<field name="vendor_id" />
<field name="inv_ref" />
</group>
</group>
<group string="Included Services">
<field name="cost_ids" nolabel="1">
<tree string="Included Services" version="7.0" editable="bottom">
<field name="cost_subtype" string="Service" domain="[('category','=','service')]"/>
<field name="amount" sum="Price" string="Cost"/>
</tree>
</field>
</group>
<group string="Notes">
<field nolabel="1" name="notes" placeholder="Write here any other information related to the service completed."/>
</group>
</sheet>
</form>
</field>
</record>
<record model='ir.ui.view' id='fleet_vehicle_log_services_tree'>
<field name="name">fleet.vehicle.log.services.tree</field>
<field name="model">fleet.vehicle.log.services</field>
<field name="arch" type="xml">
<tree string="Services Logs">
<field name="date" />
<field name="vehicle_id" />
<field name="cost_subtype"/>
<field name="purchaser_id"/>
<field name="vendor_id" />
<field name="inv_ref" />
<field name="notes" />
<field name="amount" sum="Total"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="fleet_vehicle_log_services_graph">
<field name="name">fleet.vehicle.log.services.graph</field>
<field name="model">fleet.vehicle.log.services</field>
<field name="arch" type="xml">
<graph string="Services Costs Per Month">
<field name="date" />
<field name="cost_amount" operator="+"/>
<field name="vehicle_id" group="True"/>
</graph>
</field>
</record>
<record model='ir.actions.act_window' id='fleet_vehicle_log_services_act'>
<field name="name">Vehicles Services Logs</field>
<field name="res_model">fleet.vehicle.log.services</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,graph</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new service entry.
</p><p>
OpenERP helps you keeping track of all the services done
on your vehicle. Services can be of many type: occasional
repair, fixed maintenance, etc.
</p>
</field>
</record>
<menuitem action="fleet_vehicle_log_services_act" parent="fleet_vehicles" id="fleet_vehicle_log_services_menu" />
<record model='ir.ui.view' id='fleet_vehicle_service_types_tree'>
<field name="name">fleet.service.type.tree</field>
<field name="model">fleet.service.type</field>
<field name="arch" type="xml">
<tree string="Service types" editable="bottom">
<field name="name" />
<field name="category"/>
</tree>
</field>
</record>
<record model='ir.actions.act_window' id='fleet_vehicle_service_types_act'>
<field name="name">Service Types</field>
<field name="res_model">fleet.service.type</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new type of service.
</p><p>
Each service can used in contracts, as a standalone service or both.
</p>
</field>
</record>
<menuitem action="fleet_vehicle_service_types_act" parent="fleet_configuration" id="fleet_vehicle_service_types_menu" groups="base.group_no_one"/>
<record model='ir.ui.view' id='fleet_vehicle_costs_tree'>
<field name="name">fleet.vehicle.cost.tree</field>
<field name="model">fleet.vehicle.cost</field>
<field name="arch" type="xml">
<tree string="Vehicles costs" >
<field name="date"/>
<field name="vehicle_id" />
<field name="cost_type"/>
<field name="cost_subtype"/>
<field name="amount" sum="Total Cost"/>
<field name="parent_id" invisible="1" />
<field name="year" invisible="1"/>
</tree>
</field>
</record>
<record model='ir.ui.view' id='fleet_vehicle_costs_search'>
<field name="name">fleet.vehicle.cost.search</field>
<field name="model">fleet.vehicle.cost</field>
<field name="arch" type="xml">
<search string="Vehicles costs" >
<field name="vehicle_id" />
<field name="cost_subtype"/>
<field name="year"/>
<field name="date"/>
<field name="parent_id"/>
<filter name="parent_false" domain="[('parent_id','=',False)]" string="Effective Costs"/>
<filter name="parent_true" domain="[('parent_id','!=',False)]" string="Indicative Costs"/>
<group expand="1" string="Group By...">
<filter name="groupby_year" context="{'group_by' : 'year'}" string="Year"/>
<filter name="groupby_date" context="{'group_by' : 'date'}" string="Date"/>
<filter name="groupby_cost_type" context="{'group_by' : 'cost_type'}" string="Cost Type"/>
<filter name="groupby_cost_subtype" context="{'group_by' : 'cost_subtype'}" string="Cost Subtype"/>
<filter name="groupby_vehicle_id" context="{'group_by' : 'vehicle_id'}" string="Vehicle"/>
<filter name="groupby_parent_id" context="{'group_by' : 'parent_id'}" string="Parent"/>
</group>
</search>
</field>
</record>
<record model='ir.ui.view' id='fleet_vehicle_costs_form'>
<field name="name">fleet.vehicle.cost.form</field>
<field name="model">fleet.vehicle.cost</field>
<field name="arch" type="xml">
<form string="Vehicle costs" version="7.0">
<sheet>
<group col="2" string="Cost Details">
<group>
<field name="vehicle_id" />
<field name="cost_subtype"/>
<field name="amount"/>
</group>
<group>
<field name="date"/>
<field name="parent_id"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<record model="ir.ui.view" id="fleet_vehicle_costs_graph">
<field name="name">fleet.vehicle.cost.graph</field>
<field name="model">fleet.vehicle.cost</field>
<field name="arch" type="xml">
<graph string="Costs Per Month">
<field name="date" />
<field name="amount"/>
<field name="vehicle_id" group="True"/>
</graph>
</field>
</record>
<record model='ir.actions.act_window' id='fleet_vehicle_costs_act'>
<field name="name">Vehicle Costs</field>
<field name="res_model">fleet.vehicle.cost</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,graph</field>
<field name="context">{"search_default_parent_false" : True, "search_default_groupby_vehicle_id" : True,}</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new cost.
</p><p>
OpenERP helps you managing the costs for your different
vehicles. Costs are created automatically from services,
contracts (fixed or recurring) and fuel logs.
</p>
</field>
</record>
<menuitem action="fleet_vehicle_costs_act" parent="fleet_vehicles" id="fleet_vehicle_costs_menu" />
<!--
<record model='ir.ui.view' id='fleet_hr_employee_form'>
<field name="name">fleet.hr.employee.form</field>
<field name="model">hr.employee</field>
<field name="type">form</field>
<field name="inherit_id" ref="hr.view_employee_form" />
<field name="arch" type="xml">
<notebook position="inside">
<page string="Vehicle">
<group>
<field name="vehicle_id" widget="many2many_tags"/>
</group>
</page>
</notebook>
</field>
</record>
<record model="fleet.vehicle.model" id="citroen">
<field name="name">Citroen</field>
</record>
<record model="fleet.vehicle" id="stw_vehicle">
<field name="name">240BTN</field>
<field name="model_id" ref="citroen" />
</record>
-->
</data>
</openerp>

View File

@ -0,0 +1,11 @@
id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
fleet_vehicle_model_access_right,fleet_vehicle_model_access_right,model_fleet_vehicle_model,,1,1,1,1
fleet_vehicle_tag_access_right,fleet_vehicle_tag_access_right,model_fleet_vehicle_tag,,1,1,1,1
fleet_vehicle_state_access_right,fleet_vehicle_state_access_right,model_fleet_vehicle_state,,1,1,1,1
fleet_vehicle_odometer_access_right,fleet_vehicle_odometer_access_right,model_fleet_vehicle_odometer,,1,1,1,1
fleet_vehicle_model_brand_access_right,fleet_vehicle_model_brand_access_right,model_fleet_vehicle_model_brand,,1,1,1,1
fleet_vehicle_access_right,fleet_vehicle_access_right,model_fleet_vehicle,,1,1,1,1
fleet_vehicle_log_fuel_access_right,fleet_vehicle_log_fuel_access_right,model_fleet_vehicle_log_fuel,,1,1,1,1
fleet_vehicle_log_services_access_right,fleet_vehicle_log_services_access_right,model_fleet_vehicle_log_services,,1,1,1,1
fleet_vehicle_log_contract_access_right,fleet_vehicle_log_contract_access_right,model_fleet_vehicle_log_contract,,1,1,1,1
fleet_service_type_access_right,fleet_service_type_access_right,model_fleet_service_type,,1,1,1,1
1 id name model_id/id group_id/id perm_read perm_write perm_create perm_unlink
2 fleet_vehicle_model_access_right fleet_vehicle_model_access_right model_fleet_vehicle_model 1 1 1 1
3 fleet_vehicle_tag_access_right fleet_vehicle_tag_access_right model_fleet_vehicle_tag 1 1 1 1
4 fleet_vehicle_state_access_right fleet_vehicle_state_access_right model_fleet_vehicle_state 1 1 1 1
5 fleet_vehicle_odometer_access_right fleet_vehicle_odometer_access_right model_fleet_vehicle_odometer 1 1 1 1
6 fleet_vehicle_model_brand_access_right fleet_vehicle_model_brand_access_right model_fleet_vehicle_model_brand 1 1 1 1
7 fleet_vehicle_access_right fleet_vehicle_access_right model_fleet_vehicle 1 1 1 1
8 fleet_vehicle_log_fuel_access_right fleet_vehicle_log_fuel_access_right model_fleet_vehicle_log_fuel 1 1 1 1
9 fleet_vehicle_log_services_access_right fleet_vehicle_log_services_access_right model_fleet_vehicle_log_services 1 1 1 1
10 fleet_vehicle_log_contract_access_right fleet_vehicle_log_contract_access_right model_fleet_vehicle_log_contract 1 1 1 1
11 fleet_service_type_access_right fleet_service_type_access_right model_fleet_service_type 1 1 1 1

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-11-08 04:47+0000\n"
"X-Generator: Launchpad (build 16232)\n"
"X-Launchpad-Export-Date: 2012-11-09 04:39+0000\n"
"X-Generator: Launchpad (build 16250)\n"
#. module: google_base_account
#: field:res.users,gmail_user:0

View File

@ -288,7 +288,7 @@
</record>
<record id="open_view_categ_form" model="ir.actions.act_window">
<field name="name">Categories of Employee</field>
<field name="name">Categories of Employees</field>
<field name="res_model">hr.employee.category</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
@ -342,8 +342,8 @@
<group>
<group>
<field name="no_of_employee" groups="base.group_user"/>
<field name="expected_employees" groups="base.group_user"/>
<field name="no_of_recruitment" on_change="on_change_expected_employee(no_of_recruitment,no_of_employee)"/>
<field name="expected_employees" groups="base.group_user"/>
</group>
<group>
<field name="company_id" widget="selection" groups="base.group_multi_company"/>

View File

@ -8,15 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-08 01:37+0100\n"
"PO-Revision-Date: 2012-01-03 02:55+0000\n"
"Last-Translator: Christopher Ormaza - (Ecuadorenlinea.net) "
"<chris.ormaza@gmail.com>\n"
"PO-Revision-Date: 2012-11-10 17:20+0000\n"
"Last-Translator: Cristian Salamea (Gnuthink) <ovnicraft@gmail.com>\n"
"Language-Team: Spanish (Ecuador) <es_EC@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-10-30 05:17+0000\n"
"X-Generator: Launchpad (build 16206)\n"
"X-Launchpad-Export-Date: 2012-11-11 04:57+0000\n"
"X-Generator: Launchpad (build 16251)\n"
#. module: hr
#: model:process.node,name:hr.process_node_openerpuser0
@ -199,6 +198,8 @@ msgstr "Mujer"
msgid ""
"Expected number of employees for this job position after new recruitment."
msgstr ""
"Número de Empleados para este puesto de trabajo después de las nuevas "
"contrataciones"
#. module: hr
#: model:ir.ui.menu,name:hr.menu_open_view_attendance_reason_new_config
@ -291,7 +292,7 @@ msgstr "Categorías"
#. module: hr
#: field:hr.job,expected_employees:0
msgid "Total Employees"
msgstr ""
msgstr "Total de Empleados"
#. module: hr
#: selection:hr.employee,marital:0
@ -435,7 +436,7 @@ msgstr "Estado"
#: model:ir.actions.act_window,name:hr.open_view_categ_tree
#: model:ir.ui.menu,name:hr.menu_view_employee_category_tree
msgid "Categories Structure"
msgstr ""
msgstr "Estructura de categorías"
#. module: hr
#: field:hr.employee,partner_id:0
@ -465,7 +466,7 @@ msgstr "¡Error! No se puede crear una jerarquía recursiva de empleados."
#. module: hr
#: model:ir.actions.act_window,name:hr.action2
msgid "Subordinate Hierarchy"
msgstr ""
msgstr "Jerarquía subirdinada"
#. module: hr
#: model:ir.actions.act_window,help:hr.view_department_form_installer
@ -715,12 +716,12 @@ msgstr "Subordinados"
#. module: hr
#: field:hr.job,no_of_employee:0
msgid "Number of employees currently occupying this job position."
msgstr ""
msgstr "Número de empleados ocupando actualmente este puesto de trabajo"
#. module: hr
#: field:hr.job,no_of_recruitment:0
msgid "Number of new employees you expect to recruit."
msgstr ""
msgstr "Número de empleados que espera contratar"
#~ msgid "Working Time Categories"
#~ msgstr "Categorías de Horarios de Trabajo"

View File

@ -31,6 +31,7 @@ from report.interface import toxml
from report import report_sxw
from tools import ustr
from tools.translate import _
from tools import to_xml
one_day = relativedelta(days=1)
month2name = [0, 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
@ -111,7 +112,7 @@ class report_custom(report_rml):
<date>%s</date>
<company>%s</company>
</header>
''' % (str(rml_obj.formatLang(time.strftime("%Y-%m-%d"),date=True))+' ' + str(time.strftime("%H:%M")),pooler.get_pool(cr.dbname).get('res.users').browse(cr,uid,uid).company_id.name)
''' % (str(rml_obj.formatLang(time.strftime("%Y-%m-%d"),date=True))+' ' + str(time.strftime("%H:%M")),to_xml(pooler.get_pool(cr.dbname).get('res.users').browse(cr,uid,uid).company_id.name))
first_date = str(month)
som = datetime.strptime(first_date, '%Y-%m-%d %H:%M:%S')

View File

@ -64,22 +64,22 @@ class hr_expense_expense(osv.osv):
_description = "Expense"
_order = "id desc"
_columns = {
'name': fields.char('Description', size=128),
'name': fields.char('Description', size=128, required=True, readonly=True, states={'draft':[('readonly',False)], 'confirm':[('readonly',False)]}),
'id': fields.integer('Sheet ID', readonly=True),
'date': fields.date('Date', select=True),
'date': fields.date('Date', select=True, readonly=True, states={'draft':[('readonly',False)], 'confirm':[('readonly',False)]}),
'journal_id': fields.many2one('account.journal', 'Force Journal', help = "The journal used when the expense is done."),
'employee_id': fields.many2one('hr.employee', "Employee", required=True),
'employee_id': fields.many2one('hr.employee', "Employee", required=True, readonly=True, states={'draft':[('readonly',False)], 'confirm':[('readonly',False)]}),
'user_id': fields.many2one('res.users', 'User', required=True),
'date_confirm': fields.date('Confirmation Date', select=True, help="Date of the confirmation of the sheet expense. It's filled when the button Confirm is pressed."),
'date_valid': fields.date('Validation Date', select=True, help="Date of the acceptation of the sheet expense. It's filled when the button Accept is pressed."),
'user_valid': fields.many2one('res.users', 'Validation By'),
'user_valid': fields.many2one('res.users', 'Validation By', readonly=True, states={'draft':[('readonly',False)], 'confirm':[('readonly',False)]}),
'account_move_id': fields.many2one('account.move', 'Ledger Posting'),
'line_ids': fields.one2many('hr.expense.line', 'expense_id', 'Expense Lines', readonly=True, states={'draft':[('readonly',False)]} ),
'note': fields.text('Note'),
'amount': fields.function(_amount, string='Total Amount', digits_compute= dp.get_precision('Account')),
'voucher_id': fields.many2one('account.voucher', "Employee's Receipt"),
'currency_id': fields.many2one('res.currency', 'Currency', required=True),
'department_id':fields.many2one('hr.department','Department'),
'currency_id': fields.many2one('res.currency', 'Currency', required=True, readonly=True, states={'draft':[('readonly',False)], 'confirm':[('readonly',False)]}),
'department_id':fields.many2one('hr.department','Department', readonly=True, states={'draft':[('readonly',False)], 'confirm':[('readonly',False)]}),
'company_id': fields.many2one('res.company', 'Company', required=True),
'state': fields.selection([
('draft', 'New'),
@ -100,6 +100,12 @@ class hr_expense_expense(osv.osv):
'currency_id': _get_currency,
}
def unlink(self, cr, uid, ids, context=None):
for rec in self.browse(cr, uid, ids, context=context):
if rec.state != 'draft':
raise osv.except_osv(_('Warning!'),_('You can only delete draft expenses!'))
return super(hr_expense_expense, self).unlink(cr, uid, ids, context)
def onchange_currency_id(self, cr, uid, ids, currency_id=False, company_id=False, context=None):
res = {'value': {'journal_id': False}}
journal_ids = self.pool.get('account.journal').search(cr, uid, [('type','=','purchase'), ('currency','=',currency_id), ('company_id', '=', company_id)], context=context)
@ -236,16 +242,6 @@ class product_product(osv.osv):
'hr_expense_ok': fields.boolean('Can be Expensed', help="Specify if the product can be selected in an HR expense line."),
}
def on_change_hr_expense_ok(self, cr, uid, id, hr_expense_ok):
if not hr_expense_ok:
return {}
data_obj = self.pool.get('ir.model.data')
cat_id = data_obj._get_id(cr, uid, 'hr_expense', 'cat_expense')
categ_id = data_obj.browse(cr, uid, cat_id).res_id
res = {'value' : {'type':'service','sale_ok' :False,'categ_id':categ_id }}
return res
product_product()
class hr_expense_line(osv.osv):

View File

@ -195,7 +195,7 @@
<field name="inherit_id" ref="product.product_normal_form_view"/>
<field name="arch" type="xml">
<div name="options" position="inside">
<field name="hr_expense_ok" on_change="on_change_hr_expense_ok(hr_expense_ok)"/>
<field name="hr_expense_ok"/>
<label for="hr_expense_ok"/>
</div>
</field>

View File

@ -90,6 +90,18 @@ class hr_holidays_status(osv.osv):
'color_name': 'red',
'active': True,
}
def name_get(self, cr, uid, ids, context=None):
if not ids:
return []
res = []
for record in self.browse(cr, uid, ids, context=context):
name = record.name
if not record.limit:
name = name + (' (%d/%d)' % (record.leaves_taken or 0.0, record.max_leaves or 0.0))
res.append((record.id, name))
return res
hr_holidays_status()
class hr_holidays(osv.osv):

View File

@ -31,6 +31,7 @@ import time
from report import report_sxw
from tools import ustr
from tools.translate import _
from tools import to_xml
def lengthmonth(year, month):
if month == 2 and ((year % 4 == 0) and ((year % 100 != 0) or (year % 400 == 0))):
@ -240,7 +241,7 @@ class report_custom(report_rml):
<date>%s</date>
<company>%s</company>
</header>
''' % (str(rml_obj.formatLang(time.strftime("%Y-%m-%d"),date=True))+' ' + str(time.strftime("%H:%M")),pooler.get_pool(cr.dbname).get('res.users').browse(cr,uid,uid).company_id.name)
''' % (str(rml_obj.formatLang(time.strftime("%Y-%m-%d"),date=True))+' ' + str(time.strftime("%H:%M")),to_xml(pooler.get_pool(cr.dbname).get('res.users').browse(cr,uid,uid).company_id.name))
# Computing the xml
xml='''<?xml version="1.0" encoding="UTF-8" ?>

View File

@ -326,6 +326,7 @@ class hr_payslip(osv.osv):
return self.write(cr, uid, ids, {'paid': True, 'state': 'done'}, context=context)
def hr_verify_sheet(self, cr, uid, ids, context=None):
self.compute_sheet(cr, uid, ids, context)
return self.write(cr, uid, ids, {'state': 'verify'}, context=context)
def refund_sheet(self, cr, uid, ids, context=None):
@ -358,6 +359,12 @@ class hr_payslip(osv.osv):
def check_done(self, cr, uid, ids, context=None):
return True
def unlink(self, cr, uid, ids, context=None):
for payslip in self.browse(cr, uid, ids, context=context):
if payslip.state not in ['draft','cancel']:
raise osv.except_osv(_('Warning!'),_('You cannot delete a payslip which is not draft or cancelled!'))
return super(hr_payslip, self).unlink(cr, uid, ids, context)
#TODO move this function into hr_contract module, on hr.employee object
def get_contract(self, cr, uid, employee, date_from, date_to, context=None):
"""

View File

@ -75,7 +75,7 @@
<record id="hr_salary_rule_meal_voucher" model="hr.salary.rule">
<field name="amount_select">fix</field>
<field eval="10" name="amount_fix"/>
<field name="quantity">worked_days.WORK100.number_of_days</field>
<field name="quantity">worked_days.WORK100 and worked_days.WORK100.number_of_days</field>
<field name="code">MA</field>
<field name="category_id" ref="hr_payroll.ALW"/>
<field name="register_id" ref="hr_meal_voucher_register"/>
@ -89,7 +89,7 @@
<field name="category_id" ref="hr_payroll.ALW"/>
<field name="name">Get 1% of sales</field>
<field name="sequence" eval="17"/>
<field name="amount_python_compute">result = (inputs.SALEURO.amount + inputs.SALASIA.amount) * 0.01</field>
<field name="amount_python_compute">result = ((inputs.SALEURO and inputs.SALEURO.amount) + (inputs.SALASIA and inputs.SALASIA.amount)) * 0.01</field>
</record>
<!-- Rule Inputs -->

View File

@ -106,7 +106,7 @@
<field name="arch" type="xml">
<form string="Jobs - Recruitment Form" version="7.0">
<header>
<button name="case_close_with_emp" string="Hire" type="object"
<button name="case_close_with_emp" string="Hire &amp; Create Employee" type="object"
states="draft,open,pending,done" class="oe_highlight"/>
<button name="case_cancel" string="Refuse" type="object"
states="draft,open,pending" class="oe_highlight"/>
@ -333,7 +333,7 @@
<field name="model">hr.job</field>
<field name="inherit_id" ref="hr.view_hr_job_form"/>
<field name="arch" type="xml">
<field name="no_of_recruitment" version="7.0" position="after">
<field name="expected_employees" version="7.0" position="after">
<label for="survey_id" groups="base.group_user"/>
<div groups="base.group_user">
<field name="survey_id" class="oe_inline" domain="[('type','=','Human Resources')]"/>

View File

@ -28,6 +28,7 @@ import time
import pooler
from report import report_sxw
from tools import ustr
from tools import to_xml
def lengthmonth(year, month):
if month == 2 and ((year % 4 == 0) and ((year % 100 != 0) or (year % 400 == 0))):
@ -94,7 +95,7 @@ class report_custom(report_rml):
<date>%s</date>
<company>%s</company>
</header>
''' % (str(rml_obj.formatLang(time.strftime("%Y-%m-%d"),date=True))+' ' + str(time.strftime("%H:%M")),pooler.get_pool(cr.dbname).get('res.users').browse(cr,uid,user_id).company_id.name)
''' % (str(rml_obj.formatLang(time.strftime("%Y-%m-%d"),date=True))+' ' + str(time.strftime("%H:%M")),to_xml(pooler.get_pool(cr.dbname).get('res.users').browse(cr,uid,user_id).company_id.name))
account_xml = []
for account, telems in accounts.iteritems():

View File

@ -27,8 +27,9 @@ class analytical_timesheet_employee(osv.osv_memory):
_name = 'hr.analytical.timesheet.employee'
_description = 'Print Employee Timesheet & Print My Timesheet'
_columns = {
'month': fields.selection([(x, datetime.date(2000, x, 1).strftime('%B')) for x in range(1, 13)],
'Month', required=True),
'month': fields.selection([(1,'January'), (2,'February'), (3,'March'), (4,'April'),
(5,'May'), (6,'June'), (7,'July'), (8,'August'), (9,'September'),
(10,'October'), (11,'November'), (12,'December')], 'Month', required=True),
'year': fields.integer('Year', required=True),
'employee_id': fields.many2one('hr.employee', 'Employee', required=True)

View File

@ -27,8 +27,9 @@ class analytical_timesheet_employees(osv.osv_memory):
_name = 'hr.analytical.timesheet.users'
_description = 'Print Employees Timesheet'
_columns = {
'month': fields.selection([(x, datetime.date(2000, x, 1).strftime('%B')) for x in range(1, 13)],
'Month', required=True),
'month': fields.selection([(1,'January'), (2,'February'), (3,'March'), (4,'April'),
(5,'May'), (6,'June'), (7,'July'), (8,'August'), (9,'September'),
(10,'October'), (11,'November'), (12,'December')], 'Month', required=True),
'year': fields.integer('Year', required=True),
'employee_ids': fields.many2many('hr.employee', 'timesheet_employee_rel', 'timesheet_id', 'employee_id', 'employees', required=True)
}

View File

@ -110,7 +110,7 @@ openerp.hr_timesheet_sheet = function(instance) {
return new instance.web.Model("hr.analytic.timesheet").call("multi_on_change_account_id", [[], account_ids,
new instance.web.CompoundContext({'user_id': self.get('user_id')})]).then(function(accounts_defaults) {
accounts = _(accounts).chain().map(function(lines, account_id) {
account_defaults = _.extend({}, default_get, accounts_defaults[account_id]);
account_defaults = _.extend({}, default_get, (accounts_defaults[account_id] || {}).value || {});
// group by days
account_id = account_id === "false" ? false : Number(account_id);
var index = _.groupBy(lines, "date");

View File

@ -65,6 +65,8 @@ class partner_vat(osv.osv_memory):
partners = []
partner_ids = obj_partner.search(cr, uid, [('vat_subjected', '!=', False), ('vat','ilike','BE%')], context=context)
if not partner_ids:
raise osv.except_osv(_('Error'),_('No belgian contact with a VAT number in your database.'))
cr.execute("""SELECT sub1.partner_id, sub1.name, sub1.vat, sub1.turnover, sub2.vat_amount
FROM (SELECT l.partner_id, p.name, p.vat, SUM(CASE WHEN c.code ='49' THEN -l.tax_amount ELSE l.tax_amount END) as turnover
FROM account_move_line l
@ -190,7 +192,7 @@ class partner_vat_list(osv.osv_memory):
addr = obj_partner.address_get(cr, uid, [obj_cmpny.partner_id.id], ['invoice'])
if addr.get('invoice',False):
ads = obj_partner.browse(cr, uid, [addr['invoice']], context=context)[0]
phone = ads.phone.replace(' ','') or ''
phone = ads.phone and ads.phone.replace(' ','') or ''
email = ads.email or ''
name = ads.name or ''
city = ads.city or ''
@ -259,6 +261,8 @@ class partner_vat_list(osv.osv_memory):
# Turnover and Farmer tags are not included
client_datas = self._get_datas(cr, uid, ids, context=context)
if not client_datas:
raise osv.except_osv(_('Data Insufficient!'),_('No data available for the client.'))
data_client_info = ''
for amount_data in client_datas:
data_client_info += """
@ -309,6 +313,8 @@ class partner_vat_list(osv.osv_memory):
datas['year'] = context['year']
datas['limit_amount'] = context['limit_amount']
datas['client_datas'] = self._get_datas(cr, uid, ids, context=context)
if not datas['client_datas']:
raise osv.except_osv(_('Error!'),_('No record to print.'))
return {
'type': 'ir.actions.report.xml',
'report_name': 'partner.vat.listing.print',

View File

@ -0,0 +1,158 @@
# Spanish 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-11-12 16:09+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Spanish <es@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-11-13 05:17+0000\n"
"X-Generator: Launchpad (build 16251)\n"
#. module: l10n_be_hr_payroll
#: help:hr.employee,disabled_spouse_bool:0
msgid "if recipient spouse is declared disabled by law"
msgstr ""
#. module: l10n_be_hr_payroll
#: help:hr.employee,disabled_children_bool:0
msgid "if recipient children is/are declared disabled by law"
msgstr ""
#. module: l10n_be_hr_payroll
#: field:hr.contract,misc_onss_deduction:0
msgid "Miscellaneous exempt ONSS "
msgstr ""
#. module: l10n_be_hr_payroll
#: model:ir.model,name:l10n_be_hr_payroll.model_hr_employee
msgid "Employee"
msgstr ""
#. module: l10n_be_hr_payroll
#: field:hr.employee,disabled_spouse_bool:0
msgid "Disabled Spouse"
msgstr ""
#. module: l10n_be_hr_payroll
#: field:hr.contract,retained_net_amount:0
msgid "Net retained "
msgstr ""
#. module: l10n_be_hr_payroll
#: field:hr.employee,resident_bool:0
msgid "Nonresident"
msgstr ""
#. module: l10n_be_hr_payroll
#: help:hr.employee,resident_bool:0
msgid "if recipient lives in a foreign country"
msgstr ""
#. module: l10n_be_hr_payroll
#: view:hr.employee:0
msgid "if spouse has professionnel income or not"
msgstr ""
#. module: l10n_be_hr_payroll
#: view:hr.contract:0
msgid "Miscellaneous"
msgstr ""
#. module: l10n_be_hr_payroll
#: field:hr.contract,insurance_employee_deduction:0
msgid "Insurance Group - by worker "
msgstr ""
#. module: l10n_be_hr_payroll
#: selection:hr.employee,spouse_fiscal_status:0
msgid "With Income"
msgstr ""
#. module: l10n_be_hr_payroll
#: selection:hr.employee,spouse_fiscal_status:0
msgid "Without Income"
msgstr ""
#. module: l10n_be_hr_payroll
#: field:hr.employee,disabled_children_number:0
msgid "Number of disabled children"
msgstr ""
#. module: l10n_be_hr_payroll
#: field:hr.contract,additional_net_amount:0
msgid "Net supplements"
msgstr ""
#. module: l10n_be_hr_payroll
#: constraint:hr.employee:0
msgid "Error ! You cannot create recursive Hierarchy of Employees."
msgstr ""
#. module: l10n_be_hr_payroll
#: field:hr.contract,car_company_amount:0
msgid "Company car employer"
msgstr ""
#. module: l10n_be_hr_payroll
#: field:hr.contract,misc_advantage_amount:0
msgid "Benefits of various nature "
msgstr ""
#. module: l10n_be_hr_payroll
#: field:hr.contract,car_employee_deduction:0
msgid "Company Car Deduction for Worker"
msgstr ""
#. module: l10n_be_hr_payroll
#: field:hr.employee,disabled_children_bool:0
msgid "Disabled Children"
msgstr ""
#. module: l10n_be_hr_payroll
#: model:ir.model,name:l10n_be_hr_payroll.model_hr_contract
msgid "Contract"
msgstr ""
#. module: l10n_be_hr_payroll
#: field:hr.contract,meal_voucher_amount:0
msgid "Check Value Meal "
msgstr ""
#. module: l10n_be_hr_payroll
#: field:hr.contract,travel_reimbursement_amount:0
msgid "Reimbursement of travel expenses"
msgstr ""
#. module: l10n_be_hr_payroll
#: constraint:hr.contract:0
msgid "Error! contract start-date must be lower then contract end-date."
msgstr ""
#. module: l10n_be_hr_payroll
#: field:hr.employee,spouse_fiscal_status:0
msgid "Tax status for spouse"
msgstr ""
#. module: l10n_be_hr_payroll
#: view:hr.contract:0
msgid "by Worker"
msgstr ""
#. module: l10n_be_hr_payroll
#: view:hr.employee:0
msgid "number of dependent children declared as disabled"
msgstr ""
#. module: l10n_be_hr_payroll
#: field:hr.contract,meal_voucher_employee_deduction:0
msgid "Check Value Meal - by worker "
msgstr ""

View File

@ -0,0 +1,141 @@
# Spanish 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-11-12 16:43+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Spanish <es@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-11-13 05:17+0000\n"
"X-Generator: Launchpad (build 16251)\n"
#. module: l10n_be_invoice_bba
#: sql_constraint:account.invoice:0
msgid "Invoice Number must be unique per Company!"
msgstr ""
#. module: l10n_be_invoice_bba
#: model:ir.model,name:l10n_be_invoice_bba.model_account_invoice
msgid "Invoice"
msgstr ""
#. module: l10n_be_invoice_bba
#: constraint:res.partner:0
msgid "Error ! You cannot create recursive associated members."
msgstr ""
#. module: l10n_be_invoice_bba
#: constraint:account.invoice:0
msgid "Invalid BBA Structured Communication !"
msgstr ""
#. module: l10n_be_invoice_bba
#: selection:res.partner,out_inv_comm_algorithm:0
msgid "Random"
msgstr ""
#. module: l10n_be_invoice_bba
#: help:res.partner,out_inv_comm_type:0
msgid "Select Default Communication Type for Outgoing Invoices."
msgstr ""
#. module: l10n_be_invoice_bba
#: help:res.partner,out_inv_comm_algorithm:0
msgid ""
"Select Algorithm to generate the Structured Communication on Outgoing "
"Invoices."
msgstr ""
#. module: l10n_be_invoice_bba
#: code:addons/l10n_be_invoice_bba/invoice.py:114
#: code:addons/l10n_be_invoice_bba/invoice.py:140
#, python-format
msgid ""
"The daily maximum of outgoing invoices with an automatically generated BBA "
"Structured Communications has been exceeded!\n"
"Please create manually a unique BBA Structured Communication."
msgstr ""
#. module: l10n_be_invoice_bba
#: code:addons/l10n_be_invoice_bba/invoice.py:155
#, python-format
msgid "Error!"
msgstr ""
#. module: l10n_be_invoice_bba
#: code:addons/l10n_be_invoice_bba/invoice.py:126
#, python-format
msgid ""
"The Partner should have a 3-7 digit Reference Number for the generation of "
"BBA Structured Communications!\n"
"Please correct the Partner record."
msgstr ""
#. module: l10n_be_invoice_bba
#: code:addons/l10n_be_invoice_bba/invoice.py:113
#: code:addons/l10n_be_invoice_bba/invoice.py:125
#: code:addons/l10n_be_invoice_bba/invoice.py:139
#: code:addons/l10n_be_invoice_bba/invoice.py:167
#: code:addons/l10n_be_invoice_bba/invoice.py:177
#: code:addons/l10n_be_invoice_bba/invoice.py:202
#, python-format
msgid "Warning!"
msgstr ""
#. module: l10n_be_invoice_bba
#: selection:res.partner,out_inv_comm_algorithm:0
msgid "Customer Reference"
msgstr ""
#. module: l10n_be_invoice_bba
#: field:res.partner,out_inv_comm_type:0
msgid "Communication Type"
msgstr ""
#. module: l10n_be_invoice_bba
#: code:addons/l10n_be_invoice_bba/invoice.py:178
#: code:addons/l10n_be_invoice_bba/invoice.py:203
#, python-format
msgid ""
"The BBA Structured Communication has already been used!\n"
"Please create manually a unique BBA Structured Communication."
msgstr ""
#. module: l10n_be_invoice_bba
#: selection:res.partner,out_inv_comm_algorithm:0
msgid "Date"
msgstr ""
#. module: l10n_be_invoice_bba
#: model:ir.model,name:l10n_be_invoice_bba.model_res_partner
msgid "Partner"
msgstr ""
#. module: l10n_be_invoice_bba
#: code:addons/l10n_be_invoice_bba/invoice.py:156
#, python-format
msgid ""
"Unsupported Structured Communication Type Algorithm '%s' !\n"
"Please contact your OpenERP support channel."
msgstr ""
#. module: l10n_be_invoice_bba
#: field:res.partner,out_inv_comm_algorithm:0
msgid "Communication Algorithm"
msgstr ""
#. module: l10n_be_invoice_bba
#: code:addons/l10n_be_invoice_bba/invoice.py:168
#, python-format
msgid ""
"Empty BBA Structured Communication!\n"
"Please fill in a unique BBA Structured Communication."
msgstr ""

View File

@ -52,21 +52,6 @@ class ResPartnerBank(osv.osv):
'my_bank': fields.boolean('Use my account to print BVR ?', help="Check to print BVR invoices"),
}
def name_get(self, cursor, uid, ids, context=None):
if not len(ids):
return []
bank_type_obj = self.pool.get('res.partner.bank.type')
type_ids = bank_type_obj.search(cursor, uid, [])
bank_type_names = {}
for bank_type in bank_type_obj.browse(cursor, uid, type_ids,
context=context):
bank_type_names[bank_type.code] = bank_type.name
res = []
for r in self.read(cursor, uid, ids, ['name','state'], context):
res.append((r['id'], r['name']+' : '+bank_type_names.get(r['state'], '')))
return res
def _prepare_name(self, bank):
"Hook to get bank number of bank account"
res = u''

View File

@ -131,8 +131,8 @@
<field name="tax_code_id" ref="tax_acq_196"/>
<field name="tax_sign" eval="-1"/>
<field name="account_collected_id" ref="pcg_44566"/>
<field name="account_paid_id" ref="pcg_44566"/>
<field name="account_collected_id" ref="pcg_445662"/>
<field name="account_paid_id" ref="pcg_445662"/>
<field name="ref_base_code_id" ref="tax_acq_196_ht"/>
<field name="ref_base_sign" eval="1"/>

View File

@ -3903,7 +3903,7 @@
<field name="name">Associés - Comptes courants</field>
<field name="code">455</field>
<field name="type">view</field>
<field name="user_type" ref="account.data_account_type_view"/>
<field name="user_type" ref="account.data_account_type_payable"/>
<field name="note">Pour frais avancés personnellement</field>
<field name="parent_id" ref="pcg_45"/>
<field name="reconcile" eval="True"/>
@ -3912,8 +3912,8 @@
<record id="pcg_4551" model="account.account.template">
<field name="name">Principal</field>
<field name="code">4551</field>
<field name="type">receivable</field>
<field name="user_type" ref="account.data_account_type_receivable"/>
<field name="type">payable</field>
<field name="user_type" ref="account.data_account_type_payable"/>
<field name="parent_id" ref="pcg_455"/>
<field name="reconcile" eval="True"/>
</record>
@ -3921,8 +3921,8 @@
<record id="pcg_4558" model="account.account.template">
<field name="name">Intérêts courus</field>
<field name="code">4558</field>
<field name="type">receivable</field>
<field name="user_type" ref="account.data_account_type_receivable"/>
<field name="type">payable</field>
<field name="user_type" ref="account.data_account_type_payable"/>
<field name="parent_id" ref="pcg_455"/>
<field name="reconcile" eval="True"/>
</record>

View File

@ -0,0 +1,136 @@
# Spanish 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-11-08 16:01+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Spanish <es@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-11-09 04:39+0000\n"
"X-Generator: Launchpad (build 16250)\n"
#. module: l10n_fr_rib
#: constraint:res.partner.bank:0
msgid ""
"\n"
"Please define BIC/Swift code on bank for bank type IBAN Account to make "
"valid payments"
msgstr ""
"\n"
"Por favor defina el código BIC/Swift del banco para una cuenta de tipo IBAN "
"para realizar pagos válidos"
#. module: l10n_fr_rib
#: model:res.partner.bank.type,name:l10n_fr_rib.bank_rib
msgid "RIB and optional IBAN"
msgstr "CC e IBAN opcional"
#. module: l10n_fr_rib
#: field:res.partner.bank,rib_acc_number:0
msgid "RIB account number"
msgstr "Número de la cuenta"
#. module: l10n_fr_rib
#: field:res.partner.bank,bank_code:0
msgid "Bank Code"
msgstr "Código de banco"
#. module: l10n_fr_rib
#: code:addons/l10n_fr_rib/bank.py:54
#, python-format
msgid "The RIB key %s does not correspond to the other codes: %s %s %s."
msgstr "La clave de la CC %s no se corresponde con otros códigos: %s %s %s."
#. module: l10n_fr_rib
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_office_field
msgid "office"
msgstr "oficina"
#. module: l10n_fr_rib
#: field:res.bank,rib_code:0
msgid "RIB Bank Code"
msgstr "Código CC"
#. module: l10n_fr_rib
#: code:addons/l10n_fr_rib/bank.py:58
#, python-format
msgid "The IBAN %s is not valid."
msgstr "El IBAN %s no es válido."
#. module: l10n_fr_rib
#: model:ir.model,name:l10n_fr_rib.model_res_partner_bank
msgid "Bank Accounts"
msgstr "Cuentas bancarias"
#. module: l10n_fr_rib
#: field:res.partner.bank,office:0
msgid "Office Code"
msgstr "Código de oficina"
#. module: l10n_fr_rib
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_bic_field
msgid "bank_bic"
msgstr "Número BIC"
#. module: l10n_fr_rib
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_bank_code_field
msgid "bank_code"
msgstr "código bancario"
#. module: l10n_fr_rib
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_key_field
msgid "key"
msgstr "clave"
#. module: l10n_fr_rib
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_rib_acc_number_field
msgid "rib_acc_number"
msgstr "Número CC"
#. module: l10n_fr_rib
#: help:res.partner.bank,key:0
msgid ""
"The key is a number allowing to check the correctness of the other codes."
msgstr ""
"La clave es un número que permite comprobar si el resto de códigos son "
"correctos."
#. module: l10n_fr_rib
#: field:res.partner.bank,key:0
msgid "Key"
msgstr "Clave"
#. module: l10n_fr_rib
#: code:addons/l10n_fr_rib/bank.py:53
#: code:addons/l10n_fr_rib/bank.py:58
#, python-format
msgid "Error"
msgstr "Error"
#. module: l10n_fr_rib
#: model:res.partner.bank.type,format_layout:l10n_fr_rib.bank_rib
msgid "%(bank_name)s: %(bank_code)s %(office)s %(rib_acc_number)s %(key)s"
msgstr "%(bank_name)s: %(bank_code)s %(office)s %(rib_acc_number)s %(key)s"
#. module: l10n_fr_rib
#: constraint:res.partner.bank:0
msgid "The RIB and/or IBAN is not valid"
msgstr "La CC y/o IBAN no es válida"
#. module: l10n_fr_rib
#: model:ir.model,name:l10n_fr_rib.model_res_bank
msgid "Bank"
msgstr "Banco"
#. module: l10n_fr_rib
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_acc_number_field
msgid "acc_number"
msgstr "Número cuenta"

View File

@ -0,0 +1,942 @@
# Spanish 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-08-17 06:46+0000\n"
"PO-Revision-Date: 2012-11-12 17:08+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Spanish <es@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-11-13 05:17+0000\n"
"X-Generator: Launchpad (build 16251)\n"
#. module: l10n_in_hr_payroll
#: report:salary.detail.byyear:0
msgid "E-mail Address"
msgstr ""
#. module: l10n_in_hr_payroll
#: field:payment.advice.report,employee_bank_no:0
msgid "Employee Bank Account"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:payment.advice.report:0
msgid "Payment Advices which are in draft state"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:salary.detail.byyear:0
msgid "Title"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:payroll.advice:0
msgid "Payment Advice from"
msgstr ""
#. module: l10n_in_hr_payroll
#: model:ir.model,name:l10n_in_hr_payroll.model_yearly_salary_detail
msgid "Hr Salary Employee By Category Report"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:salary.detail.byyear:0
msgid "Employees Salary Details"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:salary.detail.byyear:0
msgid "Allowances with Basic:"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:salary.detail.byyear:0
msgid "Department"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:salary.detail.byyear:0
msgid "Deductions:"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:payroll.advice:0
msgid "A/C no."
msgstr ""
#. module: l10n_in_hr_payroll
#: field:hr.contract,driver_salay:0
msgid "Driver Salary"
msgstr ""
#. module: l10n_in_hr_payroll
#: model:ir.actions.act_window,name:l10n_in_hr_payroll.action_yearly_salary_detail
#: model:ir.actions.report.xml,name:l10n_in_hr_payroll.yearly_salary
#: model:ir.ui.menu,name:l10n_in_hr_payroll.menu_yearly_salary_detail
msgid "Yearly Salary by Employee"
msgstr ""
#. module: l10n_in_hr_payroll
#: model:ir.actions.act_window,name:l10n_in_hr_payroll.act_hr_emp_payslip_list
msgid "Payslips"
msgstr ""
#. module: l10n_in_hr_payroll
#: selection:payment.advice.report,month:0
msgid "March"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:paylip.details.in:0
msgid "("
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.payroll.advice:0
#: field:hr.payroll.advice,company_id:0
#: field:hr.payroll.advice.line,company_id:0
#: view:payment.advice.report:0
#: field:payment.advice.report,company_id:0
msgid "Company"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:payroll.advice:0
msgid "The Manager"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.payroll.advice:0
msgid "Letter Details"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:paylip.details.in:0
msgid ","
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.payroll.advice:0
msgid "Set to Draft"
msgstr ""
#. module: l10n_in_hr_payroll
#: help:hr.employee,number_of_year:0
msgid "Total years of work experience"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:payroll.advice:0
msgid "to"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:payroll.advice:0
msgid "Total :"
msgstr ""
#. module: l10n_in_hr_payroll
#: field:hr.payslip.run,available_advice:0
msgid "Made Payment Advice?"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:payment.advice.report:0
msgid "Advices which are paid using NEFT transfer"
msgstr ""
#. module: l10n_in_hr_payroll
#: help:hr.contract,tds:0
msgid "Amount for Tax Deduction at Source"
msgstr ""
#. module: l10n_in_hr_payroll
#: model:ir.model,name:l10n_in_hr_payroll.model_hr_payslip
msgid "Pay Slip"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:payment.advice.report:0
#: field:payment.advice.report,day:0
msgid "Day"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:payment.advice.report:0
msgid "Month of Payment Advices"
msgstr ""
#. module: l10n_in_hr_payroll
#: constraint:hr.payslip:0
msgid "Payslip 'Date From' must be before 'Date To'."
msgstr ""
#. module: l10n_in_hr_payroll
#: field:hr.payroll.advice,batch_id:0
msgid "Batch"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:paylip.details.in:0
msgid "Code"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.payroll.advice:0
msgid "Other Information"
msgstr ""
#. module: l10n_in_hr_payroll
#: selection:hr.payroll.advice,state:0
#: selection:payment.advice.report,state:0
msgid "Cancelled"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:payroll.advice:0
msgid "For"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:paylip.details.in:0
msgid "Details by Salary Rule Category:"
msgstr ""
#. module: l10n_in_hr_payroll
#: help:hr.contract,voluntary_provident_fund:0
msgid "VPF computed as percentage(%)"
msgstr ""
#. module: l10n_in_hr_payroll
#: field:hr.payroll.advice,number:0
#: report:paylip.details.in:0
msgid "Reference"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.payroll.advice:0
#: view:payment.advice.report:0
msgid "Group By..."
msgstr ""
#. module: l10n_in_hr_payroll
#: field:hr.contract,medical_insurance:0
msgid "Medical Insurance"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:paylip.details.in:0
msgid "Identification No"
msgstr ""
#. module: l10n_in_hr_payroll
#: selection:hr.payroll.advice,state:0
#: selection:payment.advice.report,state:0
msgid "Confirmed"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:salary.detail.byyear:0
#: report:salary.employee.bymonth:0
msgid "From"
msgstr ""
#. module: l10n_in_hr_payroll
#: field:hr.payroll.advice.line,bysal:0
#: field:payment.advice.report,bysal:0
#: report:payroll.advice:0
msgid "By Salary"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.payroll.advice:0
#: view:payment.advice.report:0
msgid "Confirm"
msgstr ""
#. module: l10n_in_hr_payroll
#: field:hr.payroll.advice,chaque_nos:0
#: field:payment.advice.report,cheque_nos:0
msgid "Cheque Numbers"
msgstr ""
#. module: l10n_in_hr_payroll
#: constraint:res.company:0
msgid "Error! You can not create recursive companies."
msgstr ""
#. module: l10n_in_hr_payroll
#: model:ir.actions.act_window,name:l10n_in_hr_payroll.action_salary_employee_month
#: model:ir.actions.report.xml,name:l10n_in_hr_payroll.hr_salary_employee_bymonth
#: model:ir.ui.menu,name:l10n_in_hr_payroll.menu_salary_employee_month
msgid "Yearly Salary by Head"
msgstr ""
#. module: l10n_in_hr_payroll
#: code:addons/l10n_in_hr_payroll/l10n_in_hr_payroll.py:184
#, python-format
msgid "You can not confirm Payment advice without advice lines."
msgstr ""
#. module: l10n_in_hr_payroll
#: field:hr.payroll.advice,state:0
#: field:payment.advice.report,state:0
msgid "State"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:payroll.advice:0
msgid "Yours Sincerely"
msgstr ""
#. module: l10n_in_hr_payroll
#: help:hr.contract,medical_insurance:0
msgid "Deduction towards company provided medical insurance"
msgstr ""
#. module: l10n_in_hr_payroll
#: model:ir.model,name:l10n_in_hr_payroll.model_hr_payroll_advice_line
msgid "Bank Advice Lines"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:paylip.details.in:0
msgid "Email"
msgstr ""
#. module: l10n_in_hr_payroll
#: help:hr.payslip.run,available_advice:0
msgid ""
"If this box is checked which means that Payment Advice exists for current "
"batch"
msgstr ""
#. module: l10n_in_hr_payroll
#: code:addons/l10n_in_hr_payroll/l10n_in_hr_payroll.py:158
#: code:addons/l10n_in_hr_payroll/l10n_in_hr_payroll.py:184
#: code:addons/l10n_in_hr_payroll/l10n_in_hr_payroll.py:240
#: code:addons/l10n_in_hr_payroll/l10n_in_hr_payroll.py:257
#, python-format
msgid "Error !"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.salary.employee.month:0
#: view:yearly.salary.detail:0
msgid "Print"
msgstr ""
#. module: l10n_in_hr_payroll
#: model:ir.model,name:l10n_in_hr_payroll.model_hr_payslip_run
msgid "Payslip Batches"
msgstr ""
#. module: l10n_in_hr_payroll
#: field:hr.payroll.advice.line,debit_credit:0
#: report:payroll.advice:0
msgid "C/D"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:salary.employee.bymonth:0
msgid "Yearly Salary Details"
msgstr ""
#. module: l10n_in_hr_payroll
#: model:ir.actions.report.xml,name:l10n_in_hr_payroll.payroll_advice
msgid "Print Advice"
msgstr ""
#. module: l10n_in_hr_payroll
#: field:hr.payroll.advice,line_ids:0
msgid "Employee Salary"
msgstr ""
#. module: l10n_in_hr_payroll
#: selection:payment.advice.report,month:0
msgid "July"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:res.company:0
msgid "Configuration"
msgstr ""
#. module: l10n_in_hr_payroll
#: model:ir.actions.act_window,name:l10n_in_hr_payroll.action_view_hr_bank_advice_tree
#: model:ir.ui.menu,name:l10n_in_hr_payroll.hr_menu_payment_advice
msgid "Payment Advices"
msgstr ""
#. module: l10n_in_hr_payroll
#: model:ir.actions.act_window,name:l10n_in_hr_payroll.action_payment_advice_report_all
#: model:ir.ui.menu,name:l10n_in_hr_payroll.menu_reporting_payment_advice
#: view:payment.advice.report:0
msgid "Advices Analysis"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.salary.employee.month:0
msgid ""
"This wizard will print report which displays employees break-up of Net Head "
"for a specified dates."
msgstr ""
#. module: l10n_in_hr_payroll
#: field:hr.payroll.advice.line,ifsc:0
msgid "IFSC"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:paylip.details.in:0
msgid "Date To"
msgstr ""
#. module: l10n_in_hr_payroll
#: field:hr.contract,tds:0
msgid "TDS"
msgstr ""
#. module: l10n_in_hr_payroll
#: field:hr.employee,join_date:0
msgid "Join Date"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.payroll.advice:0
msgid "Confirm Advices"
msgstr ""
#. module: l10n_in_hr_payroll
#: constraint:hr.contract:0
msgid "Error! Contract start-date must be less than contract end-date."
msgstr ""
#. module: l10n_in_hr_payroll
#: field:res.company,dearness_allowance:0
msgid "Dearness Allowance"
msgstr ""
#. module: l10n_in_hr_payroll
#: selection:payment.advice.report,month:0
msgid "August"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.contract:0
msgid "Deduction"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.payroll.advice:0
msgid "Search Payment advice"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:payroll.advice:0
msgid "SI. No."
msgstr ""
#. module: l10n_in_hr_payroll
#: view:payment.advice.report:0
msgid "Payment Advices which are in confirm state"
msgstr ""
#. module: l10n_in_hr_payroll
#: selection:payment.advice.report,month:0
msgid "December"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.payroll.advice:0
msgid "Confirm Sheet"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:payment.advice.report:0
#: field:payment.advice.report,month:0
msgid "Month"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:salary.detail.byyear:0
msgid "Employee Code"
msgstr ""
#. module: l10n_in_hr_payroll
#: selection:hr.contract,city_type:0
msgid "Non Metro"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.salary.employee.month:0
#: view:yearly.salary.detail:0
msgid "or"
msgstr ""
#. module: l10n_in_hr_payroll
#: model:ir.model,name:l10n_in_hr_payroll.model_hr_salary_employee_month
msgid "Hr Salary Employee By Month Report"
msgstr ""
#. module: l10n_in_hr_payroll
#: field:hr.salary.employee.month,category_id:0
msgid "Category"
msgstr ""
#. module: l10n_in_hr_payroll
#: code:addons/l10n_in_hr_payroll/l10n_in_hr_payroll.py:240
#, python-format
msgid ""
"Payment advice already exists for %s, 'Set to Draft' to create a new advice."
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.payslip.run:0
msgid "To Advice"
msgstr ""
#. module: l10n_in_hr_payroll
#: field:hr.employee,number_of_year:0
msgid "No. of Years of Service"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:paylip.details.in:0
msgid "Note"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:paylip.details.in:0
msgid "Salary Rule Category"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.payroll.advice:0
#: selection:hr.payroll.advice,state:0
#: view:payment.advice.report:0
#: selection:payment.advice.report,state:0
msgid "Draft"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:paylip.details.in:0
msgid "Date From"
msgstr ""
#. module: l10n_in_hr_payroll
#: field:hr.contract,voluntary_provident_fund:0
msgid "Voluntary Provident Fund"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:salary.detail.byyear:0
msgid "Employee Name"
msgstr ""
#. module: l10n_in_hr_payroll
#: model:ir.model,name:l10n_in_hr_payroll.model_payment_advice_report
msgid "Payment Advice Analysis"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.payroll.advice:0
#: view:payment.advice.report:0
msgid "Status"
msgstr ""
#. module: l10n_in_hr_payroll
#: field:hr.contract,city_type:0
msgid "Type of City"
msgstr ""
#. module: l10n_in_hr_payroll
#: help:res.company,dearness_allowance:0
msgid "Check this box if your company provide Dearness Allowance to employee"
msgstr ""
#. module: l10n_in_hr_payroll
#: field:hr.payroll.advice.line,ifsc_code:0
#: field:payment.advice.report,ifsc_code:0
#: report:payroll.advice:0
msgid "IFSC Code"
msgstr ""
#. module: l10n_in_hr_payroll
#: selection:payment.advice.report,month:0
msgid "June"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:payment.advice.report:0
#: field:payment.advice.report,nbr:0
msgid "# Payment Lines"
msgstr ""
#. module: l10n_in_hr_payroll
#: model:ir.actions.report.xml,name:l10n_in_hr_payroll.payslip_details_report
msgid "PaySlip Details"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.payroll.advice:0
msgid "Payment Lines"
msgstr ""
#. module: l10n_in_hr_payroll
#: field:hr.payroll.advice,date:0
#: field:payment.advice.report,date:0
msgid "Date"
msgstr ""
#. module: l10n_in_hr_payroll
#: selection:payment.advice.report,month:0
msgid "November"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:payment.advice.report:0
msgid "Extended Filters..."
msgstr ""
#. module: l10n_in_hr_payroll
#: model:ir.actions.act_window,help:l10n_in_hr_payroll.action_payment_advice_report_all
msgid "This report performs analysis on Payment Advices"
msgstr ""
#. module: l10n_in_hr_payroll
#: selection:payment.advice.report,month:0
msgid "October"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:paylip.details.in:0
#: report:salary.detail.byyear:0
msgid "Designation"
msgstr ""
#. module: l10n_in_hr_payroll
#: selection:payment.advice.report,month:0
msgid "January"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:yearly.salary.detail:0
msgid "Pay Head Employee Breakup"
msgstr ""
#. module: l10n_in_hr_payroll
#: model:ir.model,name:l10n_in_hr_payroll.model_res_company
msgid "Companies"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:paylip.details.in:0
#: report:payroll.advice:0
msgid "Authorized Signature"
msgstr ""
#. module: l10n_in_hr_payroll
#: model:ir.model,name:l10n_in_hr_payroll.model_hr_contract
msgid "Contract"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.payroll.advice.line:0
msgid "Advice Lines"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:payroll.advice:0
msgid "To,"
msgstr ""
#. module: l10n_in_hr_payroll
#: help:hr.contract,driver_salay:0
msgid "Check this box if you provide allowance for driver"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.payroll.advice:0
#: field:hr.payroll.advice.line,advice_id:0
#: field:hr.payslip,advice_id:0
#: model:ir.model,name:l10n_in_hr_payroll.model_hr_payroll_advice
msgid "Bank Advice"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:salary.detail.byyear:0
msgid "Other No."
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.payroll.advice:0
msgid "Draft Advices"
msgstr ""
#. module: l10n_in_hr_payroll
#: help:hr.payroll.advice,neft:0
msgid "Check this box if your company use online transfer for salary"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:salary.detail.byyear:0
msgid "To"
msgstr ""
#. module: l10n_in_hr_payroll
#: field:payment.advice.report,number:0
msgid "Number"
msgstr ""
#. module: l10n_in_hr_payroll
#: selection:payment.advice.report,month:0
msgid "September"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.payroll.advice:0
#: view:hr.salary.employee.month:0
#: view:yearly.salary.detail:0
msgid "Cancel"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:payment.advice.report:0
msgid "Day of Payment Advices"
msgstr ""
#. module: l10n_in_hr_payroll
#: constraint:hr.employee:0
msgid "Error! You cannot create recursive hierarchy of Employee(s)."
msgstr ""
#. module: l10n_in_hr_payroll
#: view:yearly.salary.detail:0
msgid ""
"This wizard will print report which display a pay head employee breakup for "
"a specified dates."
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.payslip.run:0
msgid "Payslip Batches ready to be Adviced"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:paylip.details.in:0
msgid "Pay Slip Details"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:payment.advice.report:0
msgid "Total Salary"
msgstr ""
#. module: l10n_in_hr_payroll
#: field:hr.payroll.advice.line,employee_id:0
#: model:ir.model,name:l10n_in_hr_payroll.model_hr_employee
#: view:payment.advice.report:0
#: field:payment.advice.report,employee_id:0
msgid "Employee"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.payroll.advice:0
msgid "Compute Advice"
msgstr ""
#. module: l10n_in_hr_payroll
#: help:hr.employee,join_date:0
msgid "Joining date of employee"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:payroll.advice:0
msgid "Dear Sir/Madam,"
msgstr ""
#. module: l10n_in_hr_payroll
#: field:hr.payroll.advice,note:0
msgid "Description"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:paylip.details.in:0
msgid ")"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:res.company:0
msgid "Payroll"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:payment.advice.report:0
msgid "NEFT"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:paylip.details.in:0
#: report:salary.detail.byyear:0
msgid "Address"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.payroll.advice:0
#: field:hr.payroll.advice,bank_id:0
#: view:payment.advice.report:0
#: field:payment.advice.report,bank_id:0
#: report:payroll.advice:0
#: report:salary.detail.byyear:0
msgid "Bank"
msgstr ""
#. module: l10n_in_hr_payroll
#: field:hr.salary.employee.month,end_date:0
#: field:yearly.salary.detail,date_to:0
msgid "End Date"
msgstr ""
#. module: l10n_in_hr_payroll
#: selection:payment.advice.report,month:0
msgid "February"
msgstr ""
#. module: l10n_in_hr_payroll
#: sql_constraint:res.company:0
msgid "The company name must be unique !"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.payroll.advice:0
#: field:hr.payroll.advice,name:0
#: report:paylip.details.in:0
#: field:payment.advice.report,name:0
#: report:salary.employee.bymonth:0
msgid "Name"
msgstr ""
#. module: l10n_in_hr_payroll
#: selection:hr.contract,city_type:0
msgid "Metro"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.salary.employee.month:0
#: field:hr.salary.employee.month,employee_ids:0
#: view:yearly.salary.detail:0
#: field:yearly.salary.detail,employee_ids:0
msgid "Employees"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:paylip.details.in:0
msgid "Bank Account"
msgstr ""
#. module: l10n_in_hr_payroll
#: selection:payment.advice.report,month:0
msgid "April"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:payroll.advice:0
msgid "Name of the Employe"
msgstr ""
#. module: l10n_in_hr_payroll
#: code:addons/l10n_in_hr_payroll/l10n_in_hr_payroll.py:158
#: code:addons/l10n_in_hr_payroll/l10n_in_hr_payroll.py:257
#, python-format
msgid "Please define bank account for the %s employee"
msgstr ""
#. module: l10n_in_hr_payroll
#: field:hr.salary.employee.month,start_date:0
#: field:yearly.salary.detail,date_from:0
msgid "Start Date"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.contract:0
msgid "Allowance"
msgstr ""
#. module: l10n_in_hr_payroll
#: help:hr.payroll.advice,bank_id:0
msgid "Select the Bank from which the salary is going to be paid"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.salary.employee.month:0
msgid "Employee Pay Head Breakup"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:salary.detail.byyear:0
msgid "Phone No."
msgstr ""
#. module: l10n_in_hr_payroll
#: report:paylip.details.in:0
msgid "Credit"
msgstr ""
#. module: l10n_in_hr_payroll
#: field:hr.payroll.advice.line,name:0
#: report:payroll.advice:0
msgid "Bank Account No."
msgstr ""
#. module: l10n_in_hr_payroll
#: help:hr.payroll.advice,date:0
msgid "Advice Date is used to search Payslips"
msgstr ""
#. module: l10n_in_hr_payroll
#: selection:payment.advice.report,month:0
msgid "May"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:hr.payslip.run:0
msgid "Create Advice"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:payment.advice.report:0
#: field:payment.advice.report,year:0
msgid "Year"
msgstr ""
#. module: l10n_in_hr_payroll
#: field:hr.payroll.advice,neft:0
#: field:payment.advice.report,neft:0
msgid "NEFT Transaction"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:paylip.details.in:0
#: report:salary.detail.byyear:0
#: report:salary.employee.bymonth:0
msgid "Total"
msgstr ""
#. module: l10n_in_hr_payroll
#: report:payroll.advice:0
msgid "form period"
msgstr ""
#. module: l10n_in_hr_payroll
#: view:payment.advice.report:0
msgid "Year of Payment Advices"
msgstr ""

View File

@ -60,6 +60,3 @@ IVC21det40,template_ivacode_pagata_21det40,IVA a credito 21% detraibile 40%,temp
IVC21Idet40,template_impcode_pagata_21det40,IVA a credito 21% detraibile 40% (imponibile),template_impcode_pagata
IVC21det50,template_ivacode_pagata_21det50,IVA a credito 21% detraibile 50%,template_ivacode_pagata
IVC21Idet50,template_impcode_pagata_21det50,IVA a credito 21% detraibile 50% (imponibile),template_impcode_pagata
Rit,template_ra,Ritenute d'acconto,vat_code_chart_root
RitD20,template_ritcode_20,Ritenute a debito 20%,template_ra
RitD20I,template_ritimpcode_20,Ritenute a debito 20% (imponibile),template_ra

1 code id name parent_id:id
60 IVC21Idet40 template_impcode_pagata_21det40 IVA a credito 21% detraibile 40% (imponibile) template_impcode_pagata
61 IVC21det50 template_ivacode_pagata_21det50 IVA a credito 21% detraibile 50% template_ivacode_pagata
62 IVC21Idet50 template_impcode_pagata_21det50 IVA a credito 21% detraibile 50% (imponibile) template_impcode_pagata
Rit template_ra Ritenute d'acconto vat_code_chart_root
RitD20 template_ritcode_20 Ritenute a debito 20% template_ra
RitD20I template_ritimpcode_20 Ritenute a debito 20% (imponibile) template_ra

View File

@ -62,4 +62,3 @@ id,description,chart_template_id:id,name,sequence,amount,parent_id:id,child_depe
21I5,21I5,l10n_it_chart_template_generic,IVA al 21% detraibile al 50%,,0.21,,True,percent,,,purchase,template_impcode_pagata_21det50,,template_impcode_pagata_21det50,,,,False,-1,-1
21I5b,21I5b,l10n_it_chart_template_generic,IVA al 21% detraibile al 50% (I),1,0.5,21I5,False,percent,,,purchase,,,,,,,False,,
21I5a,21I5a,l10n_it_chart_template_generic,IVA al 21% detraibile al 50% (D),2,0,21I5,False,balance,1601,1601,purchase,,template_ivacode_pagata_21det50,,template_ivacode_pagata_21det50,,,False,,
rit-20,rit-20,l10n_it_chart_template_generic,Ritenuta d'acconto al 20% (debito),,-0.2,,False,percent,2602,2602,purchase,template_ritimpcode_20,template_ritcode_20,template_ritimpcode_20,template_ritcode_20,-1,1,False,1,-1

1 id description chart_template_id:id name sequence amount parent_id:id child_depend type account_collected_id:id account_paid_id:id type_tax_use base_code_id:id tax_code_id:id ref_base_code_id:id ref_tax_code_id:id ref_base_sign ref_tax_sign price_include base_sign tax_sign
62 21I5 21I5 l10n_it_chart_template_generic IVA al 21% detraibile al 50% 0.21 True percent purchase template_impcode_pagata_21det50 template_impcode_pagata_21det50 False -1 -1
63 21I5b 21I5b l10n_it_chart_template_generic IVA al 21% detraibile al 50% (I) 1 0.5 21I5 False percent purchase False
64 21I5a 21I5a l10n_it_chart_template_generic IVA al 21% detraibile al 50% (D) 2 0 21I5 False balance 1601 1601 purchase template_ivacode_pagata_21det50 template_ivacode_pagata_21det50 False
rit-20 rit-20 l10n_it_chart_template_generic Ritenuta d'acconto al 20% (debito) -0.2 False percent 2602 2602 purchase template_ritimpcode_20 template_ritcode_20 template_ritimpcode_20 template_ritcode_20 -1 1 False 1 -1

View File

@ -0,0 +1,177 @@
# Spanish 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 01:06+0000\n"
"PO-Revision-Date: 2012-11-08 14:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Spanish <es@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-11-09 04:39+0000\n"
"X-Generator: Launchpad (build 16250)\n"
#. module: l10n_multilang
#: model:ir.model,name:l10n_multilang.model_account_fiscal_position_template
msgid "Template for Fiscal Position"
msgstr "Plantilla para posición fiscal"
#. module: l10n_multilang
#: sql_constraint:account.account:0
msgid "The code of the account must be unique per company !"
msgstr "¡El código de la cuenta debe ser único por compañía!"
#. module: l10n_multilang
#: constraint:account.account.template:0
msgid ""
"Configuration Error!\n"
"You can not define children to an account with internal type different of "
"\"View\"! "
msgstr ""
"Error de configuración!\n"
"¡No puede definir hijos para una cuenta con el tipo interno distinto de "
"\"Vista\"! "
#. module: l10n_multilang
#: model:ir.model,name:l10n_multilang.model_account_analytic_journal
msgid "Analytic Journal"
msgstr "Diario analítico"
#. module: l10n_multilang
#: constraint:account.account.template:0
msgid "Error ! You can not create recursive account templates."
msgstr "¡Error! No puede crear plantillas de cuentas recursivas."
#. module: l10n_multilang
#: model:ir.model,name:l10n_multilang.model_account_journal
msgid "Journal"
msgstr "Diario"
#. module: l10n_multilang
#: model:ir.model,name:l10n_multilang.model_account_chart_template
msgid "Templates for Account Chart"
msgstr "Plantillas para el plan contable"
#. module: l10n_multilang
#: sql_constraint:account.tax:0
msgid "The description must be unique per company!"
msgstr "¡La descripción debe ser única por compañia!"
#. module: l10n_multilang
#: constraint:account.tax.code.template:0
msgid "Error ! You can not create recursive Tax Codes."
msgstr "¡Error! No puede crear códigos de impuestos recursivos."
#. module: l10n_multilang
#: model:ir.model,name:l10n_multilang.model_account_tax_template
msgid "account.tax.template"
msgstr "Plantilla de impuestos"
#. module: l10n_multilang
#: model:ir.model,name:l10n_multilang.model_account_tax
msgid "account.tax"
msgstr "Impuesto"
#. module: l10n_multilang
#: model:ir.model,name:l10n_multilang.model_account_account
msgid "Account"
msgstr "Cuenta"
#. module: l10n_multilang
#: model:ir.model,name:l10n_multilang.model_wizard_multi_charts_accounts
msgid "wizard.multi.charts.accounts"
msgstr "Asistente de plan de cuentas"
#. module: l10n_multilang
#: constraint:account.journal:0
msgid ""
"Configuration error! The currency chosen should be shared by the default "
"accounts too."
msgstr ""
"¡Error de configuración! La moneda elegida debería ser también la misma en "
"las cuentas por defecto"
#. module: l10n_multilang
#: model:ir.model,name:l10n_multilang.model_account_account_template
msgid "Templates for Accounts"
msgstr "Plantillas para cuentas"
#. module: l10n_multilang
#: help:account.chart.template,spoken_languages:0
msgid ""
"State here the languages for which the translations of templates could be "
"loaded at the time of installation of this localization module and copied in "
"the final object when generating them from templates. You must provide the "
"language codes separated by ';'"
msgstr ""
"Indique aquí los idiomas para los que las traducciones de las plantillas "
"pueden ser cargadas en el momento de la instalación de este módulo de "
"localización y copiados en el objeto final cuando se generen desde las "
"plantillas. Debe proveer los códigos de idioma separados por ';'."
#. module: l10n_multilang
#: constraint:account.account:0
msgid "Error ! You can not create recursive accounts."
msgstr "¡Error! No se pueden crear cuentas recursivas."
#. module: l10n_multilang
#: constraint:account.account:0
msgid ""
"Configuration Error! \n"
"You can not select an account type with a deferral method different of "
"\"Unreconciled\" for accounts with internal type \"Payable/Receivable\"! "
msgstr ""
"¡Error de configuración! \n"
"¡No puede seleccionar un tipo de cuenta con un método de cierre diferente de "
"\"Reconciliado\" para las cuentas con tipo interno \"A pagar/A cobrar\"! "
#. module: l10n_multilang
#: sql_constraint:account.journal:0
msgid "The name of the journal must be unique per company !"
msgstr "¡El nombre del diaro debe ser único por compañía!"
#. module: l10n_multilang
#: model:ir.model,name:l10n_multilang.model_account_analytic_account
msgid "Analytic Account"
msgstr "Cuenta analítica"
#. module: l10n_multilang
#: sql_constraint:account.journal:0
msgid "The code of the journal must be unique per company !"
msgstr "¡El código del diario debe ser único por compañía!"
#. module: l10n_multilang
#: model:ir.model,name:l10n_multilang.model_account_fiscal_position
msgid "Fiscal Position"
msgstr "Posición fiscal"
#. module: l10n_multilang
#: constraint:account.account:0
msgid ""
"Configuration Error! \n"
"You can not define children to an account with internal type different of "
"\"View\"! "
msgstr ""
"¡Error de configuración! \n"
"¡No puede definir hijos en una cuenta con tipo interno distinto a \"Vista\"! "
#. module: l10n_multilang
#: constraint:account.analytic.account:0
msgid "Error! You can not create recursive analytic accounts."
msgstr "¡Error! No puede crear cuentas analíticas recursivas."
#. module: l10n_multilang
#: model:ir.model,name:l10n_multilang.model_account_tax_code_template
msgid "Tax Code Template"
msgstr "Plantilla códigos de impuestos"
#. module: l10n_multilang
#: field:account.chart.template,spoken_languages:0
msgid "Spoken Languages"
msgstr "Idiomas hablados"

View File

@ -22,12 +22,12 @@
import mail_message_subtype
import mail_alias
import mail_followers
import mail_vote
import mail_favorite
import mail_message
import mail_mail
import mail_thread
import mail_group
import mail_vote
import res_partner
import res_users
import report

View File

@ -2,6 +2,12 @@
<openerp>
<data noupdate="1">
<!-- Update demo user to avoid mail bombing -->
<record id="base.partner_demo" model="res.partner">
<field name="notification_email_send">none</field>
</record>
<!-- Pushed to all employees -->
<record id="message_blogpost0" model="mail.message">
<field name="model">mail.group</field>
<field name="res_id" ref="mail.group_all_employees"/>
@ -10,7 +16,6 @@ This month you also get 250 EUR of eco-vouchers if you have been in the company
<field name="type">comment</field>
<field name="subtype_id" ref="mt_comment"/>
</record>
<record id="message_blogpost0_comment0" model="mail.message">
<field name="model">mail.group</field>
<field name="res_id" ref="group_all_employees"/>
@ -19,7 +24,6 @@ This month you also get 250 EUR of eco-vouchers if you have been in the company
<field name="type">comment</field>
<field name="subtype_id" ref="mt_comment"/>
</record>
<record id="message_blogpost0_comment1" model="mail.message">
<field name="model">mail.group</field>
<field name="res_id" ref="group_all_employees"/>
@ -28,7 +32,7 @@ This month you also get 250 EUR of eco-vouchers if you have been in the company
<field name="type">comment</field>
<field name="subtype_id" ref="mt_comment"/>
</record>
<!-- This one is starred for having mailboxes with demo data -->
<record id="message_blogpost0_comment2" model="mail.message">
<field name="model">mail.group</field>
<field name="res_id" ref="group_all_employees"/>
@ -36,8 +40,8 @@ This month you also get 250 EUR of eco-vouchers if you have been in the company
<field name="parent_id" ref="message_blogpost0"/>
<field name="type">comment</field>
<field name="subtype_id" ref="mt_comment"/>
<field name="favorite_user_ids" eval="[(6, 0, [ref('base.user_root'), ref('base.user_demo')])]"/>
</record>
<record id="message_blogpost0_comment3" model="mail.message">
<field name="model">mail.group</field>
<field name="res_id" ref="group_all_employees"/>
@ -47,5 +51,196 @@ This month you also get 250 EUR of eco-vouchers if you have been in the company
<field name="subtype_id" ref="mt_comment"/>
</record>
<!-- Demo user and admin conversation -->
<record id="message_discussion" model="mail.message">
<field name="body">Hello Demo User! I was wondering whether you had some issues with our secret task about putting cats everywhere in OpenERP.</field>
<field name="type">comment</field>
<field name="subtype_id" ref="mt_comment"/>
<field name="author_id" ref="base.partner_root"/>
<field name="partner_ids" eval="[(6, 0, [ref('base.partner_demo')])]"/>
</record>
<record id="message_discussion_answer1" model="mail.message">
<field name="body">No specific issues, I think everything is clear.</field>
<field name="parent_id" ref="message_discussion"/>
<field name="type">comment</field>
<field name="subtype_id" ref="mt_comment"/>
<field name="author_id" ref="base.partner_demo"/>
<field name="partner_ids" eval="[(6, 0, [ref('base.partner_root')])]"/>
</record>
<record id="message_discussion_answer2" model="mail.message">
<field name="body">Ow, just to be sure... we were talking about lolcats, right ?</field>
<field name="parent_id" ref="message_discussion"/>
<field name="type">comment</field>
<field name="subtype_id" ref="mt_comment"/>
<field name="author_id" ref="base.partner_demo"/>
<field name="partner_ids" eval="[(6, 0, [ref('base.partner_root')])]"/>
</record>
<record id="message_discussion_answer3" model="mail.message">
<field name="body">Absolutely!</field>
<field name="parent_id" ref="message_discussion"/>
<field name="type">comment</field>
<field name="subtype_id" ref="mt_comment"/>
<field name="author_id" ref="base.partner_root"/>
<field name="partner_ids" eval="[(6, 0, [ref('base.partner_demo')])]"/>
</record>
<!-- External mail + reply with attachment conversation -->
<record id="message_video2" model="mail.message">
<field name="subject">Plan to install OpenERP</field>
<field name="model">mail.message</field>
<field name="body">
&lt;![CDATA[Email0 inquiry]]&gt;
&lt;div&gt;&lt;font size="2"&gt;Hello,&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;br&gt;&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;font size="2"&gt;I am interested in your company's product and I plan to install OpenERP for my company and affordable price.&lt;/font&gt;&lt;/div&gt;&lt;br/&gt;
&lt;div&gt;&lt;font size="2"&gt;Can you please send me services catalogue?&lt;/font&gt;&lt;/div&gt;&lt;br/&gt;
Sophie
</field>
<field name="type">email</field>
<field name="author_id" ref="base.res_partner_2"/>
<field name="partner_ids" eval="[(6, 0, [ref('base.partner_demo'), ref('base.partner_root')])]"/>
</record>
<record id="message_video2_attachment1" model="ir.attachment">
<field name="model">ir.attachment</field>
<field name="datas">bWlncmF0aW9uIHRlc3Q=</field>
<field name="datas_fname">catalogue 2012.pdf</field>
<field name="name">catalogue 2012.pdf</field>
</record>
<record id="message_video2_message1" model="mail.message">
<field name="subject">Re: Plan to install OpenERP</field>
<field name="body">
Dear Customer,&lt;br/&gt;
Thanks for showing interest in our products.&lt;br/&gt;
We have attached the catalogue,&lt;br/&gt;
We would like to know your interests, so let us know when we can call you for more details.&lt;br/&gt;
Regards
</field>
<field name="type">comment</field>
<field name="subtype_id" ref="mt_comment"/>
<field name="parent_id" ref="message_video2"/>
<field name="author_id" ref="base.partner_demo"/>
<field name="attachment_ids" eval="[(6, 0, [ref('message_video2_attachment1')])]"/>
<field name="partner_ids" eval="[(6, 0, [ref('base.partner_demo'),ref('base.partner_root'),ref('base.res_partner_2')])]"/>
</record>
<!-- Employee & other + attachments conversation -->
<record id="message_video1_attachment1" model="ir.attachment">
<field name="model">ir.attachment</field>
<field name="datas">bWlncmF0aW9uIHRlc3Q=</field>
<field name="datas_fname">migration.doc</field>
<field name="name">migration.doc</field>
</record>
<record id="message_video1_attachment2" model="ir.attachment">
<field name="model">ir.attachment</field>
<field name="datas">
/9j/4AAQSkZJRgABAQEASABIAAD/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkz
ODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2Nj
Y2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wAARCABkAGQDAREA
AhEBAxEB/8QAGgAAAwEBAQEAAAAAAAAAAAAAAAQFAwIBBv/EAD0QAAEDAgMDCAcHAwUAAAAAAAEA
AgMEEQUSsiExchMzNDVBUXFzIjJhkbGzwRQVJGKBwtElg6FCUlPh8P/EABoBAQADAQEBAAAAAAAA
AAAAAAADBAUBAgb/xAAwEQACAQIDBgYBBAMBAAAAAAAAAQIDBBEyMwUSMUFx8BMhNFGx0cEUgZGh
I0LhNf/aAAwDAQACEQMRAD8A+55QFzgA4lpsbDttf6qqoN8D0e5z/sf7l3w5HMQz/kd7k8OQxOJX
SOheIgWyFpDXFtwDbYV1U5DETLcVFwySnDQLNuHOO/Zc227LBevDGJ1kxE2DpYiA6+xrgSMzT3dw
d7wm4xiZtZiwLS+andZrb+g4XdcZuzdbNb22TcGINbi4YbzU7nZTuY7a6+zs3Af5HtTwxidPbihe
MksDWAvuCxxJF/R7O7f4puDE8DcVLiXSwZc7TZrHXDRa43du33puDEoZ/wAjvcvHhyGIZ/yO9yeH
IYgx4e27d1yP1BsvLWDwZ0Uyh9VVB2W4y5Mx2XLf+h7lIm1FYHBSsldTcoMkBIaXNsHG/d2+Kb7X
mzkvJNoq0ji6khcd5YCfcplwBtddAXQBdAF0AXQBdAF0AXQCWI17qIR5YhIX3vd+WwFvYe9V69wq
LimscSalR8TF48DWm5t3mP1FcnmIkZfZYqmSflWkjlG7jbc0W+JUkEnHzB6cMpizKWOItl9Y7QvW
5FjFoajYIo2xsFmtAA8F7OHSANqANqAEBnJPFE9jJJGtc82aCdpXUmzjkk8GabVw6Iy4i3NPFGwi
WJjnAuHom2z4leazdKm5ik41Km4FNVzS4Uahwj5UZ9wOW4cQNl/YvNtN1YRk+Z6uEqTaXIm108lR
SU8kuXOTKDlFhscB9FS2kt2pBL3+ixYycqcm++JYpubd5j9RVipmKyPafnKjzBpapafAM3Uhwxkq
oo6hkD3ESP8AVGU2O/t/Qrqi2sTy5pPd5my4eidh1RPNV1LJZM7WhrmjKBluXbPbuClqRUUsCClN
ybxGMQLhRvLXFpuNrTY7wvNNYy8z3VbUHgGHlzqGEucXEt2lxuSuTzM7T84oUxLpsHFF8wKSGRkN
TUR1RVM8mKVEMkmaNoJa3KBb0rb1mW9adSrOL4I0qtOMacWuLFH9Nq/Kk1BXLz0z6FK19QM0PUTv
GTW5Q2GlAsXuaXfInz9X0/FNrVfaerDr9Emz9KXfuXKbm3eY/UVNUzECFKwuEU+V7mEzja02PqBW
bdJ8SGu2o+Q5RFz6Gnc5xLnRNJPebLsuLPccqEq3rel4h8HKWOmyGWqipb2lQlgk4SL11XwR/F6n
q8EVqHGXfuOYgPwb9p3t1BR08xJWyMlGWRn2BrJHtb6FwDsN32P+FnXVWcbqME/Jl22hF27bXeA3
iXTYOKP5gWpDIzOqaiOMP65quF2pY1prVOr+TVr6Ue+Ri/p1X5MmoLSvfTPoZ9r6jv3GaLqJ3jJr
cobDSgWL3NLvkT5+r6fim1qvtPVh1+iTZ+lLv3LlNzbvMfqKmqZiBClZzU3njQFatiC4yjdAB930
1/8Aib8AkuLJIZUJ1vW9LxD4OUsdNkMtVFOwUJYJWF2FbVlxsAyPb+r1NV4IrUMz79xyvymieQbg
lu2/5gvFLMiStkZIf61B/a+Ysq89bDv3L9r6Z98h3Eh+Ng4o/mBbEMjMypqI4w/rmq4XaljWmtU6
v5NWvpR75GL+m1fkyagtK99M+hn2vqO/cYoR/QneMmtyhsNKBYvc0u+QhP1fT8U2tV9p6sOv0SbP
0pd+5cpubd5j9RU1TMQIUrebm88aArVsQXGU8wOpfPA6ORrAIWta0gb9ltvuVW3ruvjJor2VxKvF
4rgc4g9kWJ0z3uDWBzSSdw2OV1zjCk3J4ElWUYVE5PBFCCop6jNyMjH5bXt2KCFSM8rxLji0k2uJ
EADm14IBBbFsPG5c2l5W779iPZ+s+/cdYAMBi2D1W6gu2eSPQ9XnGXUSf61B/a+YqF562HfuWrX0
z75DmJW+2wW3Zo/mBbEMjMypqI5w+33zU7rZTqWNaa1Tq/k1a+lHvkYv6bV93IyagtK99M+hn2vq
Biit9xO3XvJrKhsNKBYvc0u+QhP1fT8U2tV9p6sOv0SbP0pd+5cpubd5j9RU1TMQIUrObm88aArV
sQXGUTwGojhkkjeSHSloZs37CsmwqRWMHxZT2VSm6Mp4eWJ1j22UeDfqrd/6b9/wyLaeX+Pya4Hz
1Tws/cqmzOEv2PpLz/UnzSvZUPY02bKGhwtvsSR8VLtWtJYUuWGP9/8ADGs60o3saa4PH4ZVZ1DH
wt1BXrPJHoXLzjLqThKyR9GGkkxuja7Z28oFmXNSM7yO6+H/AEmsqkZ20t3liv6KGJdNg4o/mBbc
MjKFTURxh/XNTwnUsa01qnV/JrV9KPfIxf02r8mTUFpXvpn0M619QMUR/oTvGTWVDYaUCxe5pd8h
Cfq+n4ptar7T1Ydfok2fpS79y5T827zH6ipqmYgQpWc1N540BWrYguMpJw3ptN5v7Svn7TXQ2R6G
XV/gcx7nR4D6rVv/AE37/hmdtPL/AB+TXA+eqeFn7lU2Zll+x9Jef6k2p6W3/wB2lNraq6flmBa/
+jT6P4ZXZ1DHwt1Badllh0NK74y6/kkU/SGefHrCwo+qXUj2R6ap1fwijjZIeHNJa4NaQR2EOut2
vOVO3lKPH/qKd7Jwi5R4pfk4wRznVz3OJc4xXJPacyy9ntynJs2HJytqbfsvgyqZhDWz5gTyjXsF
u8uH8K/tCtGFHcfFozaFaNO6jF82O0PUTvGTW5LDSgXr3NLvkT5+r6fim1qvtPVh1+iTZ+lLv3Ll
PzbvMfqKmnmIBarhmeJGxxhwdIHg5gP9IH0U1GoocSOrBzWCEKTDquCoikdE0hj8xs8dxH1WZQtn
TqKbYsYO3t3Slxbx+DfEqWqrHgshDdg3vHt/lXbnCtS3F74lW8tpV1hF9+Zph0FTSPlc+EHOGgAP
HZf+VBaUvAT3nxNWvVVTDAUlw6sknDxE0AdheEvaX6ialF8sDNo0JU7qNdvyWPw/sdEdQMNZTch6
QAF847DdW7eapKKfItV/8jeHMRhw2sZK1xibYSNf647HA/RZytmqyqY+WOJ5sYu3ozhLi23/AChr
Eaeqqz6EAHogbXjvutCtJVKMqa4v7RXuqEqsWlz+znDqWqpJnSPhBuwNADx3qpa0fBbcnxL29/hh
T5pJfwjKqoKuecyNhaBmJ2vHaV7vYfqN3dfAofp5fqIVcfJPEbp4qmLDjTGAFxzbQ8drifqprZql
CMXyL1w/Fba5k/7srM7rxtyuJIHKbrlU61CdSrvuXljiQ2MZW7qObx3sMP7+y3A1zY/TFiXOda97
XcT9Vbk8XiSDKsnAQAgBACAEAIAQAgBACAEAIAQAgBACAEAIAQAgBACAEAIAQAgBACAEAIAQAgBA
CAEAIAQAgP/Z
</field>
<field name="datas_fname">activity graph 2012.jpg</field>
<field name="name">activity graph 2012</field>
</record>
<record id="message_video1" model="mail.message">
<field name="model">mail.group</field>
<field name="body">
Hi,&lt;br/&gt;
The beta OpenERP 7 is scheduled for November 12.&lt;br/&gt;
You will find attached the document for migration from version 6 to 7, and the activity graph for the current year. Good reading.&lt;br/&gt;
Sincerely
</field>
<field name="type">comment</field>
<field name="subtype_id" ref="mt_comment"/>
<field name="author_id" ref="base.partner_demo"/>
<field name="attachment_ids" eval="[(6, 0, [ref('message_video1_attachment1'), ref('message_video1_attachment2')])]"/>
<field name="notified_partner_ids" eval="[(6, 0, [ref('base.partner_demo'), ref('base.partner_root')])]"/>
</record>
<record id="message_video1_message1" model="mail.message">
<field name="model">mail.group</field>
<field name="body">
Thank you,&lt;br/&gt;
Could you prepare and send us also the document for version 7.1 which will come soon?&lt;br/&gt;
Sincerely
</field>
<field name="type">comment</field>
<field name="subtype_id" ref="mt_comment"/>
<field name="parent_id" ref="message_video1"/>
<field name="author_id" ref="base.partner_root"/>
<field name="notified_partner_ids" eval="[(6, 0, [ref('base.partner_demo'), ref('base.partner_root')])]"/>
</record>
<!-- Network admin & employee conversation -->
<record id="message_video0" model="mail.message">
<field name="model">mail.group</field>
<field name="body">I changed the infrastructure of networks, if there are still changes to be made please do not hesitate to contact me.</field>
<field name="type">comment</field>
<field name="subtype_id" ref="mt_comment"/>
<field name="author_id" ref="base.partner_root"/>
<field name="notified_partner_ids" eval="[(6, 0, [ref('base.partner_demo'), ref('base.partner_root')])]"/>
</record>
<record id="message_video0_message1" model="mail.message">
<field name="model">mail.group</field>
<field name="body">Thank you, the networks is perfect now ! Could you add a IP phone for Jhon ?</field>
<field name="parent_id" ref="message_video0"/>
<field name="type">comment</field>
<field name="subtype_id" ref="mt_comment"/>
<field name="author_id" ref="base.partner_demo"/>
<field name="notified_partner_ids" eval="[(6, 0, [ref('base.partner_demo'), ref('base.partner_root')])]"/>
</record>
<record id="message_video0_message2" model="mail.message">
<field name="model">mail.group</field>
<field name="body">It's right, his internal phone number is 0093</field>
<field name="parent_id" ref="message_video0"/>
<field name="type">comment</field>
<field name="subtype_id" ref="mt_comment"/>
<field name="author_id" ref="base.partner_root"/>
<field name="notified_partner_ids" eval="[(6, 0, [ref('base.partner_demo'), ref('base.partner_root')])]"/>
</record>
</data>
</openerp>

View File

@ -9,7 +9,7 @@
<record model="mail.group" id="group_all_employees">
<field name="name">Whole Company</field>
<field name="group_ids" eval="[(4, ref('base.group_user'))]"/>
<field name="description">Discussion about best sales practices and deals.</field>
<field name="description">General announces for all employees.</field>
</record>
<!-- notify all employees of module installation -->

View File

@ -61,10 +61,10 @@ class mail_notification(osv.Model):
_columns = {
'partner_id': fields.many2one('res.partner', string='Contact',
ondelete='cascade', required=True),
'read': fields.boolean('Read'),
ondelete='cascade', required=True, select=1),
'read': fields.boolean('Read', select=1),
'message_id': fields.many2one('mail.message', string='Message',
ondelete='cascade', required=True),
ondelete='cascade', required=True, select=1),
}
_defaults = {
@ -102,7 +102,7 @@ class mail_notification(osv.Model):
# some messages do not have notifications: find which one, create notification, update read status
exist_notification = dict.fromkeys(msg_ids, False)
for notification in self.browse(cr, uid, notif_ids, context=context):
exist_notification[notification.message_id] = True
exist_notification[notification.message_id.id] = True
for msg_id in exist_notification.keys():
self.create(cr, uid, {'partner_id': user_pid, 'read': read, 'message_id': msg_id}, context=context)
return self.write(cr, uid, notif_ids, {'read': read}, context=context)

View File

@ -32,17 +32,18 @@
</div>
<div class="oe_group_details">
<h4><a type="open"><field name="name"/></a></h4>
<ul>
<li><t t-raw="record.message_summary.raw_value"/></li>
<li t-if="! record.message_is_follower.raw_value"><a name="action_follow" string="Join" type="object" class="oe_group_join">Not following</a></li>
<li t-if="record.message_is_follower.raw_value"><a name="action_unfollow" string="Leave" type="object" class="oe_group_leave">Following</a></li>
</ul>
<div class="oe_grey">
<field name="description"/>
</div>
<div class="oe_kanban_footer_left">
<t t-raw="record.message_summary.raw_value"/>
</div>
<div class="oe_group_button">
<button t-if="record.message_is_follower.raw_value" name="action_unfollow" type="object" class="oe_group_join">Unfollow</button>
<button t-if="! record.message_is_follower.raw_value" name="action_follow" type="object">Join Group</button>
</div>
</div>
</div>
<script>
$('.oe_group_join').mouseover(function () { $(this).html('Follow'); }).mouseleave(function () { $(this).html('Not following'); });
$('.oe_group_leave').mouseover(function () { $(this).html('Unfollow'); }).mouseleave(function () { $(this).html('Following'); });
</script>
</t>
</templates>
</kanban>

View File

@ -50,8 +50,9 @@ class mail_message(osv.Model):
_description = 'Message'
_inherit = ['ir.needaction_mixin']
_order = 'id desc'
_rec_name = 'record_name'
_message_read_limit = 10
_message_read_limit = 30
_message_read_fields = ['id', 'parent_id', 'model', 'res_id', 'body', 'subject', 'date', 'to_read', 'email_from',
'type', 'vote_user_ids', 'attachment_ids', 'author_id', 'partner_ids', 'record_name', 'favorite_user_ids']
_message_record_name_length = 18
@ -120,21 +121,26 @@ class mail_message(osv.Model):
"message, comment for other messages such as user replies"),
'email_from': fields.char('From',
help="Email address of the sender. This field is set when no matching partner is found for incoming emails."),
'author_id': fields.many2one('res.partner', 'Author',
'author_id': fields.many2one('res.partner', 'Author', select=1,
ondelete='set null',
help="Author of the message. If not set, email_from may hold an email address that did not match any partner."),
'partner_ids': fields.many2many('res.partner', string='Recipients'),
'notified_partner_ids': fields.many2many('res.partner', 'mail_notification',
'message_id', 'partner_id', 'Recipients'),
'message_id', 'partner_id', 'Notified partners',
help='Partners that have a notification pushing this message in their mailboxes'),
'attachment_ids': fields.many2many('ir.attachment', 'message_attachment_rel',
'message_id', 'attachment_id', 'Attachments'),
'parent_id': fields.many2one('mail.message', 'Parent Message', select=True, ondelete='set null', help="Initial thread message."),
'parent_id': fields.many2one('mail.message', 'Parent Message', select=True,
ondelete='set null', help="Initial thread message."),
'child_ids': fields.one2many('mail.message', 'parent_id', 'Child Messages'),
'model': fields.char('Related Document Model', size=128, select=1),
'res_id': fields.integer('Related Document ID', select=1),
'record_name': fields.function(_get_record_name, type='char',
store=True, string='Message Record Name',
help="Name get of the related document."),
'notification_ids': fields.one2many('mail.notification', 'message_id', 'Notifications'),
'notification_ids': fields.one2many('mail.notification', 'message_id',
string='Notifications',
help='Technical field holding the message notifications. Use notified_partner_ids to access notified partners.'),
'subject': fields.char('Subject'),
'date': fields.datetime('Date'),
'message_id': fields.char('Message-Id', help='Message unique identifier', select=1, readonly=1),
@ -142,7 +148,8 @@ class mail_message(osv.Model):
'to_read': fields.function(_get_to_read, fnct_search=_search_to_read,
type='boolean', string='To read',
help='Functional field to search for messages the current user has to read'),
'subtype_id': fields.many2one('mail.message.subtype', 'Subtype'),
'subtype_id': fields.many2one('mail.message.subtype', 'Subtype',
ondelete='set null', select=1,),
'vote_user_ids': fields.many2many('res.users', 'mail_vote',
'message_id', 'user_id', string='Votes',
help='Users that voted for this message'),
@ -200,67 +207,99 @@ class mail_message(osv.Model):
# Message loading for web interface
#------------------------------------------------------
def _message_get_dict(self, cr, uid, message, context=None):
""" Return a dict representation of the message. This representation is
used in the JS client code, to display the messages.
def _message_read_dict_postprocess(self, cr, uid, messages, message_tree, context=None):
""" Post-processing on values given by message_read. This method will
handle partners in batch to avoid doing numerous queries.
:param dict message: read result of a mail.message
:param list messages: list of message, as get_dict result
:param dict message_tree: {[msg.id]: msg browse record}
"""
# TDE note: this method should be optimized, to lessen the number of queries, will be done ASAP
is_author = False
if message['author_id']:
is_author = message['author_id'][0] == self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=None)['partner_id'][0]
author_id = message['author_id']
elif message['email_from']:
author_id = (0, message['email_from'])
res_partner_obj = self.pool.get('res.partner')
ir_attachment_obj = self.pool.get('ir.attachment')
pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=None)['partner_id'][0]
has_voted = False
if uid in message.get('vote_user_ids'):
has_voted = True
# 1. Aggregate partners (author_id and partner_ids) and attachments
partner_ids = set()
attachment_ids = set()
for key, message in message_tree.iteritems():
if message.author_id:
partner_ids |= set([message.author_id.id])
if message.partner_ids:
partner_ids |= set([partner.id for partner in message.partner_ids])
if message.attachment_ids:
attachment_ids |= set([attachment.id for attachment in message.attachment_ids])
is_favorite = False
if uid in message.get('favorite_user_ids'):
is_favorite = True
# Filter author_ids uid can see
# partner_ids = self.pool.get('res.partner').search(cr, uid, [('id', 'in', partner_ids)], context=context)
partners = res_partner_obj.name_get(cr, uid, list(partner_ids), context=context)
partner_tree = dict((partner[0], partner) for partner in partners)
is_private = True
if message.get('model') and message.get('res_id'):
is_private = False
# 2. Attachments
attachments = ir_attachment_obj.read(cr, uid, list(attachment_ids), ['id', 'datas_fname'], context=context)
attachments_tree = dict((attachment['id'], {'id': attachment['id'], 'filename': attachment['datas_fname']}) for attachment in attachments)
try:
attachment_ids = [{'id': attach[0], 'name': attach[1]} for attach in self.pool.get('ir.attachment').name_get(cr, uid, message['attachment_ids'], context=context)]
except (orm.except_orm, osv.except_osv):
attachment_ids = []
# TDE note: should we send partner_ids ?
# TDE note: shouldn't we separated followers and other partners ? costly to compute maybe ,
try:
partner_ids = self.pool.get('res.partner').name_get(cr, uid, message['partner_ids'], context=context)
except (orm.except_orm, osv.except_osv):
# 3. Update message dictionaries
for message_dict in messages:
message_id = message_dict.get('id')
message = message_tree[message_id]
if message.author_id:
author = partner_tree[message.author_id.id]
else:
author = (0, message.email_from)
partner_ids = []
for partner in message.partner_ids:
if partner.id in partner_tree:
partner_ids.append(partner_tree[partner.id])
attachment_ids = []
for attachment in message.attachment_ids:
if attachment.id in attachments_tree:
attachment_ids.append(attachments_tree[attachment.id])
message_dict.update({
'is_author': pid == author[0],
'author_id': author,
'partner_ids': partner_ids,
'attachment_ids': attachment_ids,
})
return True
return {
'id': message['id'],
'type': message['type'],
'attachment_ids': attachment_ids,
'body': message['body'],
'model': message['model'],
'res_id': message['res_id'],
'record_name': message['record_name'],
'subject': message['subject'],
'date': message['date'],
'author_id': author_id,
'is_author': is_author,
'partner_ids': partner_ids,
'parent_id': False,
'vote_nb': len(message['vote_user_ids']),
'has_voted': has_voted,
'is_private': is_private,
'is_favorite': is_favorite,
'to_read': message['to_read'],
}
def _message_read_dict(self, cr, uid, message, parent_id=False, context=None):
""" Return a dict representation of the message. This representation is
used in the JS client code, to display the messages. Partners and
attachments related stuff will be done in post-processing in batch.
def _message_read_add_expandables(self, cr, uid, message_list, read_messages,
thread_level=0, message_loaded_ids=[], domain=[], parent_id=False, context=None, limit=None):
:param dict message: mail.message browse record
"""
# private message: no model, no res_id
is_private = False
if not message.model or not message.res_id:
is_private = True
# votes and favorites: res.users ids, no prefetching should be done
vote_nb = len(message.vote_user_ids)
has_voted = uid in [user.id for user in message.vote_user_ids]
is_favorite = uid in [user.id for user in message.favorite_user_ids]
return {'id': message.id,
'type': message.type,
'body': message.body,
'model': message.model,
'res_id': message.res_id,
'record_name': message.record_name,
'subject': message.subject,
'date': message.date,
'to_read': message.to_read,
'parent_id': parent_id,
'is_private': is_private,
'author_id': False,
'is_author': False,
'partner_ids': [],
'vote_nb': vote_nb,
'has_voted': has_voted,
'is_favorite': is_favorite,
'attachment_ids': [],
}
def _message_read_add_expandables(self, cr, uid, messages, message_tree, parent_tree,
message_unload_ids=[], thread_level=0, domain=[], parent_id=False, context=None):
""" Create expandables for message_read, to load new messages.
1. get the expandable for new threads
if display is flat (thread_level == 0):
@ -275,96 +314,82 @@ class mail_message(osv.Model):
for each hole in the child list based on message displayed,
create an expandable
:param list message_list:list of message structure for the Chatter
:param list messages: list of message structure for the Chatter
widget to which expandables are added
:param dict read_messages: dict [id]: read result of the messages to
easily have access to their values, given their ID
:param dict message_tree: dict [id]: browse record of this message
:param dict parent_tree: dict [parent_id]: [child_ids]
:param list message_unload_ids: list of message_ids we do not want
to load
:return bool: True
"""
def _get_expandable(domain, message_nb, parent_id, id, model):
def _get_expandable(domain, message_nb, parent_id, max_limit):
return {
'domain': domain,
'nb_messages': message_nb,
'type': 'expandable',
'parent_id': parent_id,
'id': id,
# TDE note: why do we need model sometimes, and sometimes not ???
'model': model,
'max_limit': max_limit,
}
# all_not_loaded_ids = []
id_list = sorted(read_messages.keys())
if not id_list:
return message_list
if not messages:
return True
message_ids = sorted(message_tree.keys())
# 1. get the expandable for new threads
if thread_level == 0:
exp_domain = domain + [('id', '<', min(message_loaded_ids + id_list))]
exp_domain = domain + [('id', '<', min(message_unload_ids + message_ids))]
else:
exp_domain = domain + ['!', ('id', 'child_of', message_loaded_ids + id_list)]
exp_domain = domain + ['!', ('id', 'child_of', message_unload_ids + parent_tree.keys())]
ids = self.search(cr, uid, exp_domain, context=context, limit=1)
if ids:
message_list.append(_get_expandable(exp_domain, -1, parent_id, -1, None))
# inside a thread: prepend
if parent_id:
messages.insert(0, _get_expandable(exp_domain, -1, parent_id, True))
# new threads: append
else:
messages.append(_get_expandable(exp_domain, -1, parent_id, True))
# 2. get the expandables for new messages inside threads if display is not flat
if thread_level == 0:
return True
for message_id in id_list:
message = read_messages[message_id]
for message_id in message_ids:
message = message_tree[message_id]
# message is not a thread header (has a parent_id)
# TDE note: parent_id is false is there is a parent we can not see -> ok
if message.get('parent_id'):
# generate only for thread header messages (TDE note: parent_id may be False is uid cannot see parent_id, seems ok)
if message.parent_id:
continue
# TDE note: check search is correctly implemented in mail.message
not_loaded_ids = self.search(cr, uid, [
('id', 'child_of', message['id']),
('id', 'not in', message_loaded_ids),
], context=context, limit=self._message_read_more_limit)
if not not_loaded_ids:
# check there are message for expandable
child_ids = set([child.id for child in message.child_ids]) - set(message_unload_ids)
child_ids = sorted(list(child_ids), reverse=True)
if not child_ids:
continue
# all_not_loaded_ids += not_loaded_ids
# group childs not read
id_min, id_max, nb = max(not_loaded_ids), 0, 0
for not_loaded_id in not_loaded_ids:
if not read_messages.get(not_loaded_id):
# make groups of unread messages
id_min, id_max, nb = max(child_ids), 0, 0
for child_id in child_ids:
if not child_id in message_ids:
nb += 1
if id_min > not_loaded_id:
id_min = not_loaded_id
if id_max < not_loaded_id:
id_max = not_loaded_id
if id_min > child_id:
id_min = child_id
if id_max < child_id:
id_max = child_id
elif nb > 0:
exp_domain = [('id', '>=', id_min), ('id', '<=', id_max), ('id', 'child_of', message_id)]
message_list.append(_get_expandable(exp_domain, nb, message_id, id_min, message.get('model')))
id_min, id_max, nb = max(not_loaded_ids), 0, 0
messages.append(_get_expandable(exp_domain, nb, message_id, False))
id_min, id_max, nb = max(child_ids), 0, 0
else:
id_min, id_max, nb = max(not_loaded_ids), 0, 0
id_min, id_max, nb = max(child_ids), 0, 0
if nb > 0:
exp_domain = [('id', '>=', id_min), ('id', '<=', id_max), ('id', 'child_of', message_id)]
message_list.append(_get_expandable(exp_domain, nb, message_id, id_min, message.get('model')))
# message_loaded_ids = list(set(message_loaded_ids + read_messages.keys() + all_not_loaded_ids))
idx = [msg.get('id') for msg in messages].index(message_id) + 1
# messages.append(_get_expandable(exp_domain, nb, message_id, id_min))
messages.insert(idx, _get_expandable(exp_domain, nb, message_id, False))
return True
def _get_parent(self, cr, uid, message, context=None):
""" Tools method that tries to get the parent of a mail.message. If
no parent, or if uid has no access right on the parent, False
is returned.
:param dict message: read result of a mail.message
"""
if not message['parent_id']:
return False
parent_id = message['parent_id'][0]
try:
return self.read(cr, uid, parent_id, self._message_read_fields, context=context)
except (orm.except_orm, osv.except_osv):
return False
def message_read(self, cr, uid, ids=None, domain=None, message_unload_ids=None, thread_level=0, context=None, parent_id=False, limit=None):
def message_read(self, cr, uid, ids=None, domain=None, message_unload_ids=None,
thread_level=0, context=None, parent_id=False, limit=None):
""" Read messages from mail.message, and get back a list of structured
messages to be displayed as discussion threads. If IDs is set,
fetch these records. Otherwise use the domain to fetch messages.
@ -388,46 +413,56 @@ class mail_message(osv.Model):
ancestors and expandables
:return list: list of message structure for the Chatter widget
"""
# print 'message_read', ids, domain, message_unload_ids, thread_level, context, parent_id, limit
assert thread_level in [0, 1], 'message_read() thread_level should be 0 (flat) or 1 (1 level of thread); given %s.' % thread_level
domain = domain if domain is not None else []
message_unload_ids = message_unload_ids if message_unload_ids is not None else []
if message_unload_ids:
domain += [('id', 'not in', message_unload_ids)]
limit = limit or self._message_read_limit
read_messages = {}
message_tree = {}
message_list = []
parent_tree = {}
# no specific IDS given: fetch messages according to the domain, add their parents if uid has access to
if ids is None:
ids = self.search(cr, uid, domain, context=context, limit=limit)
for message in self.read(cr, uid, ids, self._message_read_fields, context=context):
message_id = message['id']
# if not in tree and not in message_loaded list
if not message_id in read_messages and not message_id in message_unload_ids:
read_messages[message_id] = message
message_list.append(self._message_get_dict(cr, uid, message, context=context))
# fetch parent if threaded, sort messages
for message in self.browse(cr, uid, ids, context=context):
message_id = message.id
if message_id in message_tree:
continue
message_tree[message_id] = message
# get the older ancestor the user can read, update its ancestor field
if not thread_level:
message_list[-1]['parent_id'] = parent_id
continue
parent = self._get_parent(cr, uid, message, context=context)
while parent and parent.get('id') != parent_id:
message_list[-1]['parent_id'] = parent.get('id')
message = parent
parent = self._get_parent(cr, uid, message, context=context)
# if in thread: add its ancestor to the list of messages
if not message['id'] in read_messages and not message['id'] in message_unload_ids:
read_messages[message['id']] = message
message_list.append(self._message_get_dict(cr, uid, message, context=context))
# find parent_id
if thread_level == 0:
tree_parent_id = parent_id
else:
tree_parent_id = message_id
parent = message
while parent.parent_id and parent.parent_id.id != parent_id:
parent = parent.parent_id
tree_parent_id = parent.id
if not parent.id in message_tree:
message_tree[parent.id] = parent
# newest messages first
parent_tree.setdefault(tree_parent_id, [])
if tree_parent_id != message_id:
parent_tree[tree_parent_id].append(self._message_read_dict(cr, uid, message_tree[message_id], parent_id=tree_parent_id, context=context))
if thread_level:
for key, message_id_list in parent_tree.iteritems():
message_id_list.sort(key=lambda item: item['id'])
message_id_list.insert(0, self._message_read_dict(cr, uid, message_tree[key], context=context))
parent_list = parent_tree.items()
parent_list = sorted(parent_list, key=lambda item: max([msg.get('id') for msg in item[1]]) if item[1] else item[0], reverse=True)
message_list = [message for (key, msg_list) in parent_list for message in msg_list]
# get the child expandable messages for the tree
message_list = sorted(message_list, key=lambda k: k['id'])
self._message_read_add_expandables(cr, uid, message_list, read_messages, thread_level=thread_level,
message_loaded_ids=message_unload_ids, domain=domain, parent_id=parent_id, context=context, limit=limit)
self._message_read_dict_postprocess(cr, uid, message_list, message_tree, context=context)
self._message_read_add_expandables(cr, uid, message_list, message_tree, parent_tree,
thread_level=thread_level, message_unload_ids=message_unload_ids, domain=domain, parent_id=parent_id, context=context)
return message_list
# TDE Note: do we need this ?
@ -461,7 +496,6 @@ class mail_message(osv.Model):
- otherwise: remove the id
"""
# Rules do not apply to administrator
# print '_search', uid, args
if uid == SUPERUSER_ID:
return super(mail_message, self)._search(cr, uid, args, offset=offset, limit=limit, order=order,
context=context, count=count, access_rights_uid=access_rights_uid)

View File

@ -59,21 +59,26 @@
<field name="type"/>
<field name="author_id"/>
<field name="partner_ids"/>
<filter string="Read"
name="message_read" help="Show messages to read"
domain="[('to_read', '=', False)]"/>
<filter string="Unread"
name="message_unread" help="Show messages to read"
domain="[('to_read', '=', True)]"/>
<separator/>
<filter string="Comments"
name="comments" help="Comments"
domain="[('type', '=', 'comment')]"/>
<filter string="Has attachments"
name="attachments"
domain="[('attachment_ids', '!=', False)]"/>
<filter string="Notifications"
name="notifications" help="Notifications"
domain="[('type', '=', 'notification')]"/>
<filter string="Emails"
name="emails" help="Emails"
domain="[('type', '=', 'email')]"/>
<separator/>
<filter string="Has attachments"
name="attachments"
domain="[('attachment_ids', '!=', False)]"/>
</search>
</field>
</record>
@ -84,7 +89,6 @@
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="search_view_id" ref="view_message_search"/>
<field name="context">{'search_default_to_read_message':True}</field>
</record>
<!-- Add menu entry in Settings/Email -->

View File

@ -74,17 +74,17 @@ class mail_thread(osv.AbstractModel):
- message_unread: has uid unread message for the document
- message_summary: html snippet summarizing the Chatter for kanban views """
res = dict((id, dict(message_unread=False, message_summary='')) for id in ids)
user_pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0]
# search for unread messages, by reading directly mail.notification, as SUPERUSER
notif_obj = self.pool.get('mail.notification')
notif_ids = notif_obj.search(cr, SUPERUSER_ID, [
('partner_id.user_ids', 'in', [uid]),
('message_id.res_id', 'in', ids),
('message_id.model', '=', self._name),
('read', '=', False)
], context=context)
for notif in notif_obj.browse(cr, SUPERUSER_ID, notif_ids, context=context):
res[notif.message_id.res_id]['message_unread'] = True
# search for unread messages, directly in SQL to improve performances
cr.execute(""" SELECT m.res_id FROM mail_message m
RIGHT JOIN mail_notification n
ON (n.message_id = m.id AND n.partner_id = %s AND n.read = False)
WHERE m.model = %s AND m.res_id in %s""",
(user_pid, self._name, tuple(ids),))
msg_ids = [result[0] for result in cr.fetchall()]
for msg_id in msg_ids:
res[msg_id]['message_unread'] = True
for thread in self.browse(cr, uid, ids, context=context):
cls = res[thread.id]['message_unread'] and ' class="oe_kanban_mail_new"' or ''

View File

@ -4,48 +4,126 @@
<record id="action_mail_inbox_feeds" model="ir.actions.client">
<field name="name">Inbox</field>
<field name="tag">mail.wall</field>
<field name="params" eval="&quot;{'domain': [('notification_ids.partner_id.user_ids', 'in', [uid]), ('to_read', '=', True)],
'context': {'default_model': 'res.users', 'default_res_id': uid, 'typeof_thread': 'inbox'} }&quot;"/>
<field name="res_model">mail.message</field>
<field name="context">{
'default_model': 'res.users',
'default_res_id': uid
}</field>
<field name="params" eval="&quot;{
'domain': [
('notification_ids.partner_id.user_ids', 'in', [uid]),
('to_read', '=', True),
('favorite_user_ids', 'not in', [uid])
],
'view_mailbox': True,
'view_inbox': True,
'read_action': 'read'
}&quot;"/>
<field name="help" type="html">
<p>
<b>Good Job!</b> Your inbox is empty.
</p><p>
Your inbox contains private messages or emails sent to you
as well as information related to documents or people you
follow.
</p>
</field>
</record>
<record id="action_mail_to_me_feeds" model="ir.actions.client">
<field name="name">To: me</field>
<field name="tag">mail.wall</field>
<field name="params" eval="&quot;{'domain': [('partner_ids.user_ids', 'in', [uid]), ('to_read', '=', True), ('author_id.user_ids', 'in', [uid])],
'context': {'default_model': 'res.users', 'default_res_id': uid, 'typeof_thread': 'inbox'} }&quot;"/>
<field name="res_model">mail.message</field>
<field name="context">{
'default_model': 'res.users',
'default_res_id': uid,
'search_default_message_unread': True
}</field>
<field name="params" eval="&quot;{
'domain': [('partner_ids.user_ids', 'in', [uid])],
'view_mailbox': True,
'read_action': 'read', }&quot;"/>
<field name="help" type="html">
<p>
<b>No private message.</b>
</p><p>
This list contains messages sent to you.
</p>
</field>
</record>
<record id="action_mail_star_feeds" model="ir.actions.client">
<field name="name">Favorites</field>
<field name="name">Todo</field>
<field name="tag">mail.wall</field>
<field name="params" eval="&quot;{'domain': [('favorite_user_ids.user_ids', 'in', [uid])],
'context': {'default_model': 'res.users', 'default_res_id': uid, 'typeof_thread': 'stared'} }&quot;"/>
<field name="res_model">mail.message</field>
<field name="context">{
'default_model': 'res.users',
'default_res_id': uid,
'search_default_message_unread': True
}</field>
<field name="params" eval="&quot;{
'domain': [('favorite_user_ids', 'in', [uid])],
'view_mailbox': True,
'read_action': 'read', }&quot;"/>
<field name="help" type="html">
<p>
<b>No todo!</b>
</p><p>
When you process messages in your inbox, you can mark some
as <i>todo</i>. From this menu, you can process all your todo.
</p>
</field>
</record>
<record id="action_mail_archives_feeds" model="ir.actions.client">
<field name="name">Archives</field>
<field name="tag">mail.wall</field>
<field name="params" eval="&quot;{'domain': [('notification_ids.partner_id.user_ids', 'in', [uid]), ('to_read', '=', False)],
'context': {'default_model': 'res.users', 'default_res_id': uid, 'typeof_thread': 'archives'} }&quot;"/>
<field name="context">{
'default_model': 'res.users',
'default_res_id': uid,
'search_default_message_read': True
}</field>
<field name="params" eval="&quot;{
'domain': [('notification_ids.partner_id.user_ids', 'in', [uid])],
'view_mailbox': True,
'read_action': 'unread', }&quot;"/>
<field name="help" type="html">
<p>
No message found.
</p>
</field>
</record>
<record id="action_mail_sent_feeds" model="ir.actions.client">
<field name="name">Sent</field>
<field name="tag">mail.wall</field>
<field name="params" eval="&quot;{'domain': [('author_id.user_ids', 'in', [uid])],
'context': {'default_model': 'res.users', 'default_res_id': uid, 'typeof_thread': 'send'} }&quot;"/>
<field name="context">{
'default_model': 'res.users',
'default_res_id': uid
}</field>
<field name="params" eval="&quot;{
'domain': [('author_id.user_ids', 'in', [uid])],
'view_mailbox': True, }&quot;"/>
<field name="help" type="html">
<p>
<b>No message sent yet.</b>
</p><p>
Click on the top-right icon to compose a message. This
message will be sent by email if it's an internal contact.
</p>
</field>
</record>
<!-- MENU -->
<!-- Top menu item -->
<menuitem name="Emails"
<menuitem name="Messaging"
id="mail.mail_feeds_main"
groups="base.group_user"
sequence="10"/>
<!-- Left-side menu: Feeds -->
<menuitem id="mail.mail_feeds" name="Messages" parent="mail.mail_feeds_main" groups="base.group_user" sequence="10"/>
<menuitem id="mail.mail_feeds" name="Messaging" parent="mail.mail_feeds_main" groups="base.group_user" sequence="10"/>
<menuitem id="mail_my_stuff" name="Organizer" parent="mail.mail_feeds_main"/>
<record id="mail_inboxfeeds" model="ir.ui.menu">
@ -61,7 +139,7 @@
<field name="parent_id" ref="mail.mail_feeds"/>
</record>
<record id="mail_starfeeds" model="ir.ui.menu">
<field name="name">Favorites</field>
<field name="name">Todo</field>
<field name="sequence" eval="14"/>
<field name="action" ref="action_mail_star_feeds"/>
<field name="parent_id" ref="mail.mail_feeds"/>

View File

@ -1,7 +1,36 @@
/* ------------ TOPBAR MAIL BUTTON --------------- */
/* FIXME this css is not very pretty because it uses a
* 'button' element wich comes with a lot of inappropriate
* styling. Entypo is also a headache to center properly
* */
.openerp .oe_topbar_item.oe_topbar_compose_full_email{
padding: 0px;
width: 32px;
height: 32px;
}
.openerp .oe_topbar_item.oe_topbar_compose_full_email button{
position: relative;
top: -3px; /* centering entypo ... urgh */
box-sizing: border-box;
border: none;
box-shadow: none;
color: white;
background: none;
text-shadow: 0px 1px 2px black;
width: 32px;
height: 32px;
padding: 0px;
margin: 0px
border-radius: 0px;
}
/* ------------ MAIL WIDGET --------------- */
.openerp .oe_mail, .openerp .oe_mail *{
box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.openerp .oe_mail {
display: block;
@ -42,9 +71,10 @@
}
.openerp .oe_mail .oe_msg .oe_msg_footer{
padding-left: 4px;
padding-top: 3px;
overflow: hidden;
opacity:0.8;
-webkit-transition: opacity 0.2s linear;
margin-bottom: 4px;
font-size: 11px;
}
.openerp .oe_mail .oe_msg .oe_msg_content{
display: block;
@ -80,18 +110,24 @@
.openerp .oe_mail .oe_msg.oe_msg_indented .oe_msg_content{
padding-top:2px;
}
.openerp .oe_mail .oe_msg.oe_msg_indented .oe_msg_footer{
margin-bottom: 0px;
}
/* b) Votes (likes) */
.openerp .oe_mail .oe_mail_vote_count{
display: inline;
position: relative;
background: #7C7BAD;
color: white;
background: white;
box-shadow: 0px 0px 0px 1px rgba(124, 123, 173, 0.36) inset;
color: #7c7bad;
text-shadow: none;
border-radius: 3px;
margin: 0px;
padding-left: 3px;
padding-right: 18px;
margin-right: 3px;
padding-right: 15px;
margin-right: 5px;
}
.openerp .oe_mail .oe_mail_vote_count .oe_e{
position: absolute;
@ -102,12 +138,6 @@
/* c) Message action icons */
.openerp .oe_mail .oe_msg.oe_msg_unread .oe_unread{
display:none;
}
.openerp .oe_mail .oe_msg.oe_msg_read .oe_read{
display:none;
}
.openerp .oe_mail .oe_msg .oe_msg_icons{
float: right;
margin-top: 4px;
@ -115,6 +145,9 @@
margin-left: 8px;
height: 24px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.openerp .oe_mail .oe_msg .oe_msg_icons span{
float:right;
@ -128,10 +161,16 @@
color: #FFF;
text-shadow: 0px 1px #AAA,0px -1px #AAA, -1px 0px #AAA, 1px 0px #AAA, 0px 3px 3px rgba(0,0,0,0.1);
-webkit-transition: all 0.2s linear;
-moz-transition: all 0.2s linear;
-o-transition: all 0.2s linear;
transition: all 0.2s linear;
}
.openerp .oe_mail .oe_msg:hover .oe_msg_icons a{
opacity: 1;
-webkit-transition: all 0.1s linear;
-moz-transition: all 0.1s linear;
-o-transition: all 0.1s linear;
transition: all 0.1s linear;
}
.openerp .oe_mail .oe_msg .oe_msg_icons .oe_star:hover a{
color: #FFF6C0;
@ -155,7 +194,7 @@
}
.openerp .oe_mail .oe_msg .oe_msg_content textarea{
width: 100%;
height: 32px;
height: 64px;
margin: 0px;
padding: 0px;
resize: vertical;
@ -171,6 +210,150 @@
width: 100%;
}
/* --------------------- ATTACHMENTS --------------------- */
.openerp .oe_mail .oe_msg_attachment_list{
display: none;
margin-top: 12px;
margin-bottom: 12px;
}
.openerp .oe_mail .oe_msg_composer .oe_msg_attachment_list{
display: block;
}
.openerp .oe_mail .oe_attachment{
display: inline-block;
width: 100px;
margin: 2px;
min-height: 80px;
position: relative;
border-radius: 3px;
text-align: center;
vertical-align: top;
}
.openerp .oe_mail .oe_attachment .oe_name{
display: inline-block;
max-width: 100%;
padding: 1px 3px;
margin-top: 50px;
margin-bottom: 5px;
background: rgba(124, 123, 173, 0.13);
overflow: hidden;
color: #4c4c4c;
text-shadow: none;
border-radius: 3px;
}
.openerp .oe_mail .oe_attachment.oe_preview{
background: url( data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAJ0lEQVQYV2MsLS39z4AGLCws0IUYGIeCwrVr12J45sSJE5ieGQIKAbuZKf/EMCs7AAAAAElFTkSuQmCC );
}
.openerp .oe_mail .oe_attachment .oe_progress_bar{
display: none;
position: absolute;
top: 18px;
left: 16px;
right: 16px;
height: 17px;
line-height: 13px;
padding: 0px;
background: #4BBD00;
color: white;
text-align: center;
border-radius: 3px;
border: solid 1px rgba(0,0,0,0.2);
box-shadow: 0px 3px 10px rgba(0, 0, 0, 0.34);
-webkit-animation: oe_mail_attach_loading_anim 0.75s infinite linear;
-moz-animation: oe_mail_attach_loading_anim 0.75s infinite linear;
-o-animation: oe_mail_attach_loading_anim 0.75s infinite linear;
animation: oe_mail_attach_loading_anim 0.75s infinite linear;
}
.openerp .oe_mail .oe_attachment.oe_uploading .oe_progress_bar{
display: block;
}
@-webkit-keyframes oe_mail_attach_loading_anim{
0% { background: #4BBD00 }
50% { background: #009123 }
100% { background: #4BBD00 }
}
@-moz-keyframes oe_mail_attach_loading_anim{
0% { background: #4BBD00 }
50% { background: #009123 }
100% { background: #4BBD00 }
}
@-o-keyframes oe_mail_attach_loading_anim{
0% { background: #4BBD00 }
50% { background: #009123 }
100% { background: #4BBD00 }
}
@keyframes oe_mail_attach_loading_anim{
0% { background: #4BBD00 }
50% { background: #009123 }
100% { background: #4BBD00 }
}
.openerp .oe_mail .oe_attachment.oe_preview .oe_name{
position: absolute;
bottom: 0px;
margin: 0px;
left: 0px;
right: 0px;
max-height: 64px;
background: rgba(0,0,0,0.8);
color: white;
border-top-left-radius: 0px;
border-top-right-radius: 0px;
opacity: 0;
-webkit-transition: opacity 0.2s linear;
-moz-transition: opacity 0.2s linear;
-o-transition: opacity 0.2s linear;
transition: opacity 0.2s linear;
}
.openerp .oe_mail .oe_attachment.oe_preview:hover .oe_name{
opacity: 1;
-webkit-transition: opacity 0.2s linear;
-moz-transition: opacity 0.2s linear;
-o-transition: opacity 0.2s linear;
transition: opacity 0.2s linear;
}
.openerp .oe_mail .oe_attachment img{
position: absolute;
width: 48px;
height: 48px;
top: 0px;
left: 50%;
margin-left: -24px;
}
.openerp .oe_mail .oe_attachment.oe_preview img{
display: block;
position: relative;
margin:0px;
width: 100px;
height: 100px;
border-radius: 3px;
margin-left: -50px;
}
.openerp .oe_mail .oe_attachment .oe_delete{
display: none;
}
.openerp .oe_mail .oe_msg_composer .oe_attachment .oe_delete{
display: block;
position: absolute;
top: -7px;
right: 0px;
color: black;
text-shadow: 1px 0px white, -1px 0px white, 0px 1px white, 0px -1px white;
cursor: pointer;
opacity: 0;
-webkit-transition: opacity 0.2s linear;
-moz-transition: opacity 0.2s linear;
-o-transition: opacity 0.2s linear;
transition: opacity 0.2s linear;
}
.openerp .oe_mail .oe_msg_composer .oe_attachment:hover .oe_delete{
opacity: 1;
-webkit-transition: opacity 0.2s linear;
-moz-transition: opacity 0.2s linear;
-o-transition: opacity 0.2s linear;
transition: opacity 0.2s linear;
}
/* ---------------- MESSAGE QUICK COMPOSER --------------- */
.openerp .oe_mail .oe_msg_composer .oe_msg_footer{
@ -178,37 +361,6 @@
padding-top: 2px;
padding-bottom:6px;
}
.openerp .oe_mail .oe_msg_attachments.oe_hidden,
.openerp .oe_mail .oe_msg_images.oe_hidden{
margin:0px;
border: none;
display: none;
}
.openerp .oe_mail .oe_msg_attachments{
margin-bottom: 4px;
margin-right: 0px;
font-size: 12px;
border-radius: 2px;
border: solid 1px rgba(124,123,173,0.14);
}
.openerp .oe_mail .oe_msg_attachments .oe_attachment{
padding: 2px;
padding-left: 4px;
padding-right: 4px;
}
.openerp .oe_mail .oe_msg_attachments .oe_attachment .oe_e{
font-size: 23px;
margin-top: -5px;
}
.openerp .oe_mail .oe_msg_attachments .oe_attachment .oe_e:hover{
text-decoration: none;
}
.openerp .oe_mail .oe_msg_attachments .oe_attachment:nth-child(odd){
background:white;
}
.openerp .oe_mail .oe_msg_attachments .oe_attachment:nth-child(even){
background: #F4F5FA;
}
.openerp .oe_mail .oe_msg_images {
display: block;
}
@ -269,6 +421,7 @@
.openerp .oe_mail .oe_msg_content.oe_msg_more_message{
text-align: right;
cursor: pointer;
}
.openerp .oe_mail .oe_msg_content.oe_msg_more_message .oe_separator{
height: 0;
@ -280,7 +433,7 @@
}
.openerp .oe_mail .oe_msg_more_message .oe_msg_fetch_more {
background: white;
margin-right: 280px;
margin-right: 210px;
padding-left: 8px;
padding-right: 8px;
text-decoration: none;
@ -298,6 +451,7 @@
padding-top: 5px;
width: 160px;
float: right;
margin-right: 16px;
}
/* a) THE FOLLOW BUTTON */
@ -308,9 +462,22 @@
width:100%;
}
.openerp .oe_followers button.oe_follower.oe_following{
color: white;
background-color: #3465A4;
background-image: -webkit-linear-gradient(top, #729FCF, #3465A4);
background-image: -moz-linear-gradient(top, #729FCF, #3465A4);
background-image: -ms-linear-gradient(top, #729FCF, #3465A4);
background-image: -o-linear-gradient(top, #729FCF, #3465A4);
background-image: linear-gradient(to bottom, #729FCF, #3465A4);
}
.openerp .oe_followers button.oe_follower.oe_following:hover{
color: white;
background-color: #A21A1A;
background-image: -webkit-linear-gradient(top, #DF3F3F, #A21A1A);
background-image: -moz-linear-gradient(top, #DF3F3F, #A21A1A);
background-image: -ms-linear-gradient(top, #DF3F3F, #A21A1A);
background-image: -o-linear-gradient(top, #DF3F3F, #A21A1A);
background-image: linear-gradient(to bottom, #DF3F3F, #A21A1A);
}
.openerp .oe_followers button.oe_follower .oe_follow,
@ -371,12 +538,17 @@
.openerp .oe_record_thread{
display: block;
margin-right: 180px;
margin-left: 16px;
margin-right: 212px;
}
/* ----------- INBOX INTEGRATION ----------- */
.openerp .oe_mail_wall .oe_mail{
margin: 16px;
width: 720px;
width: 600px;
}
.openerp .oe_mail .oe_view_nocontent > p {
padding-left: 15px;
}

View File

@ -68,30 +68,31 @@
min-height: 120px;
}
.oe_group_details a, .oe_group_details a:hover {
font-weight: bold;
color: #4c4c4c;
}
.oe_group_details h4 {
margin: 0;
font-size: 13px;
}
.oe_group_details h4 a {
color: #4c4c4c;
}
.oe_group_details h4 a:hover {
text-decoration: underline;
}
.oe_group_details ul {
margin: 3px 0 5px;
padding: 0;
list-style: none;
}
.oe_group_details li {
.openerp .oe_group_details li {
margin: 2px 0;
}
.openerp .oe_group_button {
padding-top: 7px;
}
.openerp .oe_group_button .oe_group_join {
color: white;
background-color: #3465A4;
background-image: -webkit-linear-gradient(top, #729FCF, #3465A4);
background-image: -moz-linear-gradient(top, #729FCF, #3465A4);
background-image: -ms-linear-gradient(top, #729FCF, #3465A4);
background-image: -o-linear-gradient(top, #729FCF, #3465A4);
background-image: linear-gradient(to bottom, #729FCF, #3465A4);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Some files were not shown because too many files have changed in this diff Show More