[MERGE] Merged with addons/trunk.

bzr revid: tde@openerp.com-20121029091455-9izbtivnnb2q5bpv
This commit is contained in:
Thibault Delavallée 2012-10-29 10:14:55 +01:00
commit 373eb136cd
50 changed files with 1021 additions and 823 deletions

File diff suppressed because it is too large Load Diff

View File

@ -74,36 +74,18 @@ class account_analytic_account(osv.osv):
for id in ids:
res[id][f] = 0.0
res2 = {}
if parent_ids:
# Amount uninvoiced hours to invoice at sale price
# Warning
# This computation doesn't take care of pricelist !
# Just consider list_price
cr.execute("""SELECT account_analytic_account.id, \
COALESCE(SUM (product_template.list_price * \
account_analytic_line.unit_amount * \
((100-hr_timesheet_invoice_factor.factor)/100)), 0.0) \
AS ca_to_invoice \
FROM product_template \
JOIN product_product \
ON product_template.id = product_product.product_tmpl_id \
JOIN account_analytic_line \
ON account_analytic_line.product_id = product_product.id \
JOIN account_analytic_journal \
ON account_analytic_line.journal_id = account_analytic_journal.id \
JOIN account_analytic_account \
ON account_analytic_account.id = account_analytic_line.account_id \
JOIN hr_timesheet_invoice_factor \
ON hr_timesheet_invoice_factor.id = account_analytic_account.to_invoice \
WHERE account_analytic_account.id IN %s \
AND account_analytic_line.invoice_id IS NULL \
AND account_analytic_line.to_invoice IS NOT NULL \
AND account_analytic_journal.type = 'general' \
GROUP BY account_analytic_account.id;""", (parent_ids,))
for account_id, sum in cr.fetchall():
if account_id not in res:
res[account_id] = {}
res[account_id][f] = round(sum, dp)
for account in accounts:
cr.execute("SELECT product_id, user_id, to_invoice, sum(unit_amount), product_uom_id, name " \
"FROM account_analytic_line as line " \
"WHERE account_id = %s " \
"AND invoice_id is NULL AND to_invoice IS NOT NULL " \
"GROUP BY product_id, user_id, to_invoice, product_uom_id, name", (account.id,))
res[account.id][f] = 0.0
for product_id, user_id, factor_id, qty, uom, line_name in cr.fetchall():
price = self.pool.get('account.analytic.line')._get_invoice_price(cr, uid, account, product_id, user_id, qty, context)
factor = self.pool.get('hr_timesheet_invoice.factor').browse(cr, uid, factor_id, context=context)
res[account.id][f] += price * qty * (100-factor.factor or 0.0) / 100.0
# sum both result on account_id
for id in ids:

View File

@ -30,18 +30,18 @@
<separator name="toinvoice" string="Invoicing"/>
<table class="oe_form_analytic_account">
<tr>
<th class="oe_grey" width="160px"></th>
<th class="oe_grey" width="25px"></th>
<th class="oe_grey" width="100px"><label string="Expected"/></th>
<th class="oe_grey" width="100px"><label string="Invoiced"/></th>
<th class="oe_grey" width="100px"><label string="Remaining"/></th>
<th class="oe_grey" width="100px"><label string="To Invoice"/></th>
<th class="oe_timesheet_grey" width="160px"></th>
<th class="oe_timesheet_grey" width="25px"></th>
<th class="oe_timesheet_grey" width="100px"><label string="Expected"/></th>
<th class="oe_timesheet_grey" width="100px"><label string="Invoiced"/></th>
<th class="oe_timesheet_grey" width="100px"><label string="Remaining"/></th>
<th class="oe_timesheet_grey" width="100px"><label string="To Invoice"/></th>
<th width="30px"></th>
<th></th>
</tr><tr>
<td class="oe_grey">
<td class="oe_timesheet_grey">
<label for="fix_price_invoices"/>
</td><td class="oe_grey">
</td><td class="oe_timesheet_grey">
<field name="fix_price_invoices" class="oe_inline"/>
</td><td>
<field class="oe_inline" name="amount_max" attrs="{'invisible': [('fix_price_invoices','=',False)]}"/>
@ -51,23 +51,28 @@
<field class="oe_inline" name="remaining_ca" attrs="{'invisible': [('fix_price_invoices','=',False)]}"/>
</td><td>
<field class="oe_inline" name="fix_price_to_invoice" attrs="{'invisible': [('fix_price_invoices','=',False)]}"/>
</td><td>
<button name="open_sale_order_lines"
class="oe_link oe_e"
string="/" type="object"
context="{'default_partner_id': [partner_id],'default_project_id': active_id,'search_default_uninvoiced': 1,'search_default_project_id': active_id,'search_default_partner_id': [partner_id]}"
attrs="{'invisible': [('fix_price_to_invoice','=',0)]}"/>
</td><td>
</td><td attrs="{'invisible': [('fix_price_invoices','=',False)]}" class="oe_timesheet_action">
<span attrs="{'invisible': [('fix_price_to_invoice','=',0.0)]}" class="oe_grey">
<button name="open_sale_order_lines"
class="oe_link"
string="⇒ Invoice" type="object"
context="{'default_partner_id': [partner_id],'default_project_id': active_id,'search_default_uninvoiced': 1,'search_default_project_id': active_id,'search_default_partner_id': [partner_id]}"/>
or view
</span>
<span attrs="{'invisible': [('fix_price_to_invoice','&lt;&gt;',0.0)]}" class="oe_grey">
No order to invoice, create
</span>
<button name="%(action_sales_order)d" string="Sale Orders"
type="action"
class="oe_link"
context="{'default_partner_id': [partner_id], 'search_default_partner_id': [partner_id],'search_default_project_id': [active_id],'default_project_id': [active_id]}"
attrs="{'invisible': [('fix_price_invoices','=',False)]}"/>
/>
</td>
</tr><tr>
<td class="oe_grey">
<td class="oe_timesheet_grey">
<label for="invoice_on_timesheets"/>
</td><td class="oe_grey">
</td><td class="oe_timesheet_grey">
<field name="invoice_on_timesheets"/>
</td><td>
<field class="oe_inline" name="hours_qtt_est" attrs="{'invisible': [('invoice_on_timesheets','=',False)]}"/>
@ -77,44 +82,55 @@
<field class="oe_inline" name="remaining_hours_to_invoice" attrs="{'invisible': [('invoice_on_timesheets','=',False)]}"/>
</td><td>
<field class="oe_inline" name="ca_to_invoice" attrs="{'invisible': [('invoice_on_timesheets','=',False)]}"/>
</td><td>
<button name="%(hr_timesheet_invoice.act_acc_analytic_acc_2_report_acc_analytic_line_to_invoice)d"
type="action"
class="oe_link oe_e"
string="/"
attrs="{'invisible': [('ca_to_invoice','=',0.0)]}"/>
</td><td class="oe_timesheet_action" attrs="{'invisible': [('invoice_on_timesheets','=',False)]}">
<span attrs="{'invisible': [('ca_to_invoice','=',0.0)]}" class="oe_grey">
<button name="%(hr_timesheet_invoice.action_hr_timesheet_invoice_create_final)d"
type="action"
class="oe_link"
string="⇒ Invoice"/>
or view
</span>
<span attrs="{'invisible': [('ca_to_invoice','&lt;&gt;',0.0)]}" class="oe_grey">
Nothing to invoice, create
</span>
</td><td>
<button name="%(hr_timesheet.act_hr_timesheet_line_evry1_all_form)d"
string="Timesheets" type="action"
class="oe_link"
attrs="{'invisible': [('invoice_on_timesheets','=',False)]}"
context="{'default_account_id': active_id,'search_default_account_id': active_id}"/>
</td>
</tr><tr name='total'>
<th class="oe_grey">
<th class="oe_timesheet_grey">
<label string="Total"/>
</th><td class="oe_grey">
</td><td class="oe_grey">
</th><td class="oe_timesheet_grey">
</td><td class="oe_timesheet_grey">
<field name="est_total" class="oe_inline" attrs="{'invisible': [('invoice_on_timesheets','=',False)]}"/>
</td><td class="oe_grey">
</td><td class="oe_timesheet_grey">
<field name="invoiced_total" class="oe_inline"/>
</td><td class="oe_grey">
</td><td class="oe_timesheet_grey">
<field name="remaining_total" class="oe_inline"/>
</td><td class="oe_grey">
</td><td class="oe_timesheet_grey">
<field name="toinvoice_total" class="oe_inline"/>
</td><td>
</td>
</tr>
</table>
<group name='invoice_on_timesheets' attrs="{'invisible': [('invoice_on_timesheets','=',False)]}">
<field name="pricelist_id"
class="oe_inline"
attrs="{'required': [('invoice_on_timesheets', '=', True)]}"/>
<field name="to_invoice"
class="oe_inline"
widget="selection"
attrs="{'required': [('invoice_on_timesheets', '=', True)]}"/>
<p class="oe_grey oe_edit_only" colspan="2">
When invoicing on timesheet, OpenERP uses the
pricelist of the contract which uses the price
defined on the product related to each employee to
define the customer invoice price rate.
</p>
<group>
<field name="pricelist_id"
class="oe_inline"
attrs="{'required': [('invoice_on_timesheets', '=', True)]}"/>
<field name="to_invoice"
class="oe_inline"
widget="selection"
attrs="{'required': [('invoice_on_timesheets', '=', True)]}"/>
</group>
</group>
</xpath>
</field>

View File

@ -9,7 +9,11 @@
float: right;
width: auto !important;
}
.openerp .oe_form table.oe_form_analytic_account .oe_grey {
.openerp .oe_form table.oe_form_analytic_account tr td.oe_timesheet_action {
width: 250px;
padding-left: 7px;
}
.openerp .oe_form table.oe_form_analytic_account .oe_timesheet_grey {
background-color: #eeeeee;
color: #404040;
}

View File

@ -9,7 +9,10 @@
.oe_form_field_float
float: right
width: auto !important
.oe_grey
td.oe_timesheet_action
width: 250px
padding-left: 7px
.oe_timesheet_grey
background-color: #eeeeee
color: #404040

View File

@ -89,7 +89,7 @@
<page string="Sales Information">
<field name="line_cr_ids" on_change="onchange_price(line_cr_ids, tax_id, partner_id)" context="{'journal_id':journal_id, 'type':type, 'partner_id':partner_id}">
<tree string="Sales Lines" editable="bottom">
<field name="account_id" domain="[('user_type.report_type','=','income'),('type','!=','view')]" widget="selection" groups="account.group_account_user"/>
<field name="account_id" domain="[('user_type.report_type','=','income'),('type','!=','view')]" widget="selection"/>
<field name="name"/>
<field name="amount" sum="Total"/>
<field name="account_analytic_id" groups="analytic.group_analytic_accounting"/>
@ -243,7 +243,7 @@
<page string="Bill Information">
<field name="line_dr_ids" on_change="onchange_price(line_dr_ids, tax_id, partner_id)" context="{'journal_id':journal_id,'partner_id':partner_id}">
<tree string="Expense Lines" editable="bottom">
<field name="account_id" widget="selection" domain="[('user_type.report_type','=','expense'), ('type','!=','view')]" groups="account.group_account_user"/>
<field name="account_id" widget="selection" domain="[('user_type.report_type','=','expense'), ('type','!=','view')]"/>
<field name="name"/>
<field name="amount"/>
<field name="account_analytic_id" groups="analytic.group_analytic_accounting"/>

View File

@ -141,11 +141,11 @@ class account_analytic_account(osv.osv):
'name': fields.char('Account/Contract Name', size=128, required=True),
'complete_name': fields.function(_complete_name_calc, type='char', string='Full Account Name'),
'code': fields.char('Reference', size=24, select=True),
'type': fields.selection([('view','Analytic View'), ('normal','Analytic Account'),('contract','Contract or Project'),('template','Template of Project')], 'Type of Account', required=True,
'type': fields.selection([('view','Analytic View'), ('normal','Analytic Account'),('contract','Contract or Project'),('template','Template of Contract')], 'Type of Account', required=True,
help="If you select the View Type, it means you won\'t allow to create journal entries using that account.\n"\
"The type 'Analytic account' stands for usual accounts that you only want to use in accounting.\n"\
"If you select Contract or Project, it offers you the possibility to manage the validity and the invoicing options for this account.\n"\
"The special type 'Template of Project' allows you to define a template with default data that you can reuse easily."),
"The special type 'Template of Contract' allows you to define a template with default data that you can reuse easily."),
'template_id': fields.many2one('account.analytic.account', 'Template of Contract'),
'description': fields.text('Description'),
'parent_id': fields.many2one('account.analytic.account', 'Parent Analytic Account', select=2),
@ -156,7 +156,7 @@ class account_analytic_account(osv.osv):
'debit': fields.function(_debit_credit_bal_qtty, type='float', string='Debit', multi='debit_credit_bal_qtty', digits_compute=dp.get_precision('Account')),
'credit': fields.function(_debit_credit_bal_qtty, type='float', string='Credit', multi='debit_credit_bal_qtty', digits_compute=dp.get_precision('Account')),
'quantity': fields.function(_debit_credit_bal_qtty, type='float', string='Quantity', multi='debit_credit_bal_qtty'),
'quantity_max': fields.float('Prepaid Units', help='Sets the higher limit of time to work on the contract.'),
'quantity_max': fields.float('Prepaid Service Units', help='Sets the higher limit of time to work on the contract, based on the timesheet. (for instance, number of hours in a limited support contract.)'),
'partner_id': fields.many2one('res.partner', 'Customer'),
'user_id': fields.many2one('res.users', 'Project Manager'),
'manager_id': fields.many2one('res.users', 'Account Manager'),

View File

@ -21,7 +21,7 @@
<group name="main">
<group>
<field name="partner_id" on_change="on_change_partner_id(partner_id, name)" attrs="{'required':[('type','=','contract')]}"/>
<field name="partner_id" on_change="on_change_partner_id(partner_id, name)"/>
<field name="manager_id"/>
<field name="code"/>
<field name="currency_id" attrs="{'invisible': ['|',('type', '&lt;&gt;', 'view'), ('company_id', '&lt;&gt;', False)]}"/>
@ -39,8 +39,10 @@
<p colspan="2" class="oe_grey oe_edit_only">
Once the end date of the contract is
passed or the maximum number of service
units is reached, the account manager
is warned by email to renew the contract.
units (e.g. support contract) is
reached, the account manager is warned
by email to renew the contract with the
customer.
</p>
<field name="date_start"/>
<label for="date" string="End Date"/>

View File

@ -9,9 +9,9 @@
<field name="arch" type="xml">
<xpath expr='//tr[@name="total"]' position='before'>
<tr>
<td class="oe_grey">
<td class="oe_timesheet_grey">
<label for="charge_expenses"/>
</td><td class="oe_grey">
</td><td class="oe_timesheet_grey">
<field name="charge_expenses"/>
</td><td>
<field class="oe_form_inline" name="est_expenses" attrs="{'invisible': [('charge_expenses','=',False)]}"/>
@ -21,17 +21,22 @@
<field class="oe_form_inline" name="remaining_expense" attrs="{'invisible': [('charge_expenses','=',False)]}"/>
</td><td>
<field class="oe_form_inline" name="expense_to_invoice" attrs="{'invisible': [('charge_expenses','=',False)]}"/>
</td><td>
<button
name="hr_to_invoice_expense"
class="oe_link oe_e"
string="/" type="object"
attrs="{'invisible': [('expense_to_invoice','=',0)]}"/>
</td><td>
</td><td attrs="{'invisible': [('charge_expenses','=',False)]}" class="oe_timesheet_action">
<span attrs="{'invisible': [('expense_to_invoice','=',0)]}" class="oe_grey">
<button
name="hr_to_invoice_expense"
class="oe_link"
string="⇒ Invoice" type="object"
/>
or view
</span>
<span attrs="{'invisible': [('expense_to_invoice','&lt;&gt;',0)]}" class="oe_grey">
Nothing to invoice, create
</span>
<button
name="open_hr_expense"
class="oe_link"
string="Expenses" type="object" attrs="{'invisible': [('charge_expenses','=',False)]}"/>
string="expenses" type="object"/>
</td>
</tr>
</xpath>

View File

@ -21,39 +21,51 @@
from osv import fields,osv
from tools.translate import _
import decimal_precision as dp
class analytic_user_funct_grid(osv.osv):
_name="analytic.user.funct.grid"
_description= "Relation table between users and products on a analytic account"
_description= "Price per User"
_columns={
'user_id': fields.many2one("res.users", "User", required=True,),
'product_id': fields.many2one("product.product", "Product", required=True,),
'product_id': fields.many2one("product.product", "Service", required=True,),
'account_id': fields.many2one("account.analytic.account", "Analytic Account", required=True,),
}
'uom_id': fields.related("product_id", "uom_id", relation="product.uom", string="Unit of Measure", type="many2one", readonly=True),
'price': fields.float('Price', digits_compute=dp.get_precision('Product Price'), help="Price per hour for this user.", required=True),
}
def onchange_user_product_id(self, cr, uid, ids, user_id, product_id, context=None):
if not user_id:
return {}
emp_obj = self.pool.get('hr.employee')
emp_id = emp_obj.search(cr, uid, [('user_id', '=', user_id)], context=context)
if not emp_id:
return {}
analytic_user_funct_grid()
value = {}
emp = emp_obj.browse(cr, uid, emp_id[0], context=context)
if emp.product_id and not product_id:
value['product_id'] = emp.product_id.id
prod = emp.product_id
if product_id:
prod = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
if prod:
value['price'] = prod.list_price
value['uom_id'] = prod.uom_id.id
return {'value': value}
class account_analytic_account(osv.osv):
_inherit = "account.analytic.account"
_columns = {
'user_product_ids': fields.one2many('analytic.user.funct.grid', 'account_id', 'Users/Products Rel.'),
}
account_analytic_account()
class hr_analytic_timesheet(osv.osv):
_inherit = "hr.analytic.timesheet"
# Look in account, if no value for the user => look in parent until there is no more parent to look
# Take the first found... if nothing found => return False
def _get_related_user_account_recursiv(self, cr, uid, user_id, account_id):
temp=self.pool.get('analytic.user.funct.grid').search(cr, uid, [('user_id', '=', user_id),('account_id', '=', account_id) ])
account=self.pool.get('account.analytic.account').browse(cr, uid, account_id)
if temp:
@ -64,7 +76,6 @@ class hr_analytic_timesheet(osv.osv):
else:
return False
def on_change_account_id(self, cr, uid, ids, account_id, user_id=False, unit_amount=0):
res = {}
if not (account_id):
@ -106,12 +117,6 @@ class hr_analytic_timesheet(osv.osv):
return res
def on_change_user_id(self, cr, uid, ids, user_id, account_id, unit_amount=0):
res = {}
if not (user_id):
#avoid a useless call to super
return res
#get the old values from super
res = super(hr_analytic_timesheet, self).on_change_user_id(cr, uid, ids, user_id)
if account_id:
@ -141,7 +146,11 @@ class hr_analytic_timesheet(osv.osv):
res ['value']['general_account_id']= a
return res
hr_analytic_timesheet()
class account_analytic_line(osv.osv):
_inherit = "account.analytic.line"
def _get_invoice_price(self, cr, uid, account, product_id, user_id, qty, context = {}):
for grid in account.user_product_ids:
if grid.user_id.id==user_id:
return grid.price
return super(account_analytic_line, self)._get_invoice_price(cr, uid, account, product_id, user_id, qty, context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -7,9 +7,11 @@
<field name="name">analytic_user_funct_grid.tree</field>
<field name="model">analytic.user.funct.grid</field>
<field name="arch" type="xml">
<tree string="User's Product for this Analytic Account" editable="bottom">
<field name="user_id" required="1"/>
<field name="product_id" required="1" />
<tree string="Invoicing Data" editable="bottom">
<field name="user_id" on_change="onchange_user_product_id(user_id, product_id)"/>
<field name="product_id" on_change="onchange_user_product_id(user_id, product_id)" domain="[('type','=','service')]"/>
<field name="price"/>
<field name="uom_id"/>
</tree>
</field>
</record>
@ -18,9 +20,13 @@
<field name="name">analytic_user_funct_grid.form</field>
<field name="model">analytic.user.funct.grid</field>
<field name="arch" type="xml">
<form string="User's Product for this Analytic Account">
<field name="user_id" required="1"/>
<field name="product_id" required="1"/>
<form string="Invoicing Data">
<group>
<field name="user_id" on_change="onchange_user_product_id(user_id, product_id)"/>
<field name="product_id" domain="[('type','=','service')]" on_change="onchange_user_product_id(user_id, product_id)"/>
<field name="price"/>
<field name="uom_id"/>
</group>
</form>
</field>
</record>
@ -29,13 +35,26 @@
<record model="ir.ui.view" id="view_account_analytic_account_form_inherit">
<field name="name">account.analytic.account.form</field>
<field name="model">account.analytic.account</field>
<field eval="60" name="priority"/>
<field name="inherit_id" ref="analytic.view_account_analytic_account_form"/>
<field name="arch" type="xml">
<xpath expr="//notebook/page" position="after">
<page string="Users/Products Rel.">
<field name="user_product_ids" colspan="4" nolabel="1"/>
</page>
</xpath>
<separator name="description" position="before">
<div name="user_function_price" attrs="{'invisible': [('invoice_on_timesheets','=',False)]}">
<separator string="Invoice Price Rate per User"/>
<p class="oe_grey oe_edit_only">
Define a specific service (e.g. Senior Consultant)
and price for some users to use these data instead
of the default values when invoicing the customer.
</p>
<p class="oe_grey oe_edit_only">
OpenERP will recursively search on parent accounts
to check if specific conditions are defined for a
specific user. This allows to set invoicing
conditions for a group of contracts.
</p>
<field name="user_product_ids"/>
</div>
</separator>
</field>
</record>

View File

@ -328,9 +328,6 @@
<field name="view_id" ref="view_crm_meeting_gantt"/>
</record>
<menuitem id="menu_crm_meeting" parent="base.menu_sales" sequence="8"
name="Calendar" action="action_crm_meeting"/>
<menuitem name="Calendar"
id="mail_menu_calendar" parent="mail.mail_my_stuff"
sequence="10" action="action_crm_meeting"/>

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 00:36+0000\n"
"PO-Revision-Date: 2010-10-30 10:01+0000\n"
"Last-Translator: OpenERP Administrators <Unknown>\n"
"PO-Revision-Date: 2012-10-26 09:05+0000\n"
"Last-Translator: Chertykov Denis <chertykov@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-19 05:20+0000\n"
"X-Generator: Launchpad (build 16165)\n"
"X-Launchpad-Export-Date: 2012-10-27 04:59+0000\n"
"X-Generator: Launchpad (build 16194)\n"
#. module: board
#: view:res.log.report:0
@ -103,7 +103,7 @@ msgstr "Месячная активность на документ"
#. module: board
#: view:board.board:0
msgid "Configuration Overview"
msgstr ""
msgstr "Обзор конфигурации"
#. module: board
#: model:ir.actions.act_window,name:board.action_view_board_list_form
@ -211,7 +211,7 @@ msgstr "Январь"
#. module: board
#: view:board.board:0
msgid "Users"
msgstr ""
msgstr "Пользователи"
#. module: board
#: selection:res.log.report,month:0
@ -262,7 +262,7 @@ msgstr "Модель"
#. module: board
#: model:ir.actions.act_window,name:board.board_homepage_action
msgid "Home Page"
msgstr ""
msgstr "Домашняя страница"
#. module: board
#: model:ir.actions.act_window,name:board.action_latest_activities_tree

View File

@ -86,7 +86,6 @@ Dashboard for CRM will include:
'crm_lead_menu.xml',
'crm_meeting_menu.xml',
'crm_meeting_shortcut_data.xml',
'crm_phonecall_view.xml',
'crm_phonecall_menu.xml',

View File

@ -6,13 +6,6 @@
<field name="groups_id" eval="[(4,ref('base.group_sale_salesman'))]"/>
</record>
<record id="ir_ui_view_sc_calendar_demo" model="ir.ui.view_sc">
<field name="name">Meetings</field>
<field name="resource">ir.ui.menu</field>
<field name="user_id" ref="base.user_demo"/>
<field name="res_id" ref="base_calendar.menu_crm_meeting"/>
</record>
<record model="crm.case.section" id="crm_case_section_1">
<field name="name">Sales Marketing Department</field>
<field name="code">SMD</field>

View File

@ -1,13 +0,0 @@
<?xml version="1.0"?>
<openerp>
<data noupdate="1">
<record id="ir_ui_view_sc_calendar0" model="ir.ui.view_sc">
<field name="name">Meetings</field>
<field name="resource">ir.ui.menu</field>
<field name="user_id" ref="base.user_root"/>
<field name="res_id" ref="base_calendar.menu_crm_meeting"/>
</record>
</data>
</openerp>

View File

@ -28,7 +28,7 @@ class hr_config_settings(osv.osv_memory):
_columns = {
'module_hr_timesheet_sheet': fields.boolean('Allow timesheets validation by managers',
help ="""This installs the module hr_timesheet_sheet."""),
'module_hr_attendance': fields.boolean('Track attendances',
'module_hr_attendance': fields.boolean('Install attendances feature',
help ="""This installs the module hr_attendance."""),
'module_hr_timesheet': fields.boolean('Manage timesheets',
help ="""This installs the module hr_timesheet."""),
@ -42,6 +42,8 @@ class hr_config_settings(osv.osv_memory):
help ="""This installs the module hr_contract."""),
'module_hr_evaluation': fields.boolean('Organize employees periodic evaluation',
help ="""This installs the module hr_evaluation."""),
'module_account_analytic_analysis': fields.boolean('Allow invoicing based on timesheets (will install the sale application)',
help ="""This installs the module account_analytic_analysis, which will install sales management too."""),
'module_hr_payroll': fields.boolean('Manage payroll',
help ="""This installs the module hr_payroll."""),
}

View File

@ -69,6 +69,10 @@
<field name="module_hr_timesheet_sheet" class="oe_inline"/>
<label for="module_hr_timesheet_sheet"/>
</div>
<div name="account_analytic_analysis">
<field name="module_account_analytic_analysis" class="oe_inline"/>
<label for="module_account_analytic_analysis"/>
</div>
<div name="hr_attendance">
<field name="module_hr_attendance" on_change="onchange_hr_attendance(module_hr_attendance)" class="oe_inline"/>
<label for="module_hr_attendance"/>

View File

@ -25,7 +25,7 @@ class hr_attendance_config_settings(osv.osv_memory):
_inherit = 'hr.config.settings'
_columns = {
'group_hr_attendance': fields.boolean('Track attendances',
'group_hr_attendance': fields.boolean('Track attendances for all employees',
implied_group='base.group_hr_attendance',
help="Allocates attendance group to all users."),
}

View File

@ -154,7 +154,7 @@ class hr_analytic_timesheet(osv.osv):
'date': lambda self, cr, uid, ctx: ctx.get('date', fields.date.context_today(self,cr,uid,context=ctx)),
'user_id': lambda obj, cr, uid, ctx: ctx.get('user_id', uid),
}
def on_change_account_id(self, cr, uid, ids, account_id):
def on_change_account_id(self, cr, uid, ids, account_id, context=None):
return {'value':{}}
def on_change_date(self, cr, uid, ids, date):
@ -190,17 +190,14 @@ class hr_analytic_timesheet(osv.osv):
'journal_id': self._getAnalyticJournal(cr, uid, context),
}}
hr_analytic_timesheet()
class account_analytic_account(osv.osv):
_inherit = 'account.analytic.account'
_description = 'Analytic Account'
_columns = {
'use_timesheets': fields.boolean('Timesheets', help="Check this field if this project manages timesheets"),
'use_timesheets': fields.boolean('Use Timesheets', help="Check this field if this project manages timesheets"),
}
def on_change_template(self, cr, uid, ids, template_id, context=None):
res = super(account_analytic_account, self).on_change_template(cr, uid, ids, template_id, context=context)
if template_id and 'value' in res:
@ -208,6 +205,4 @@ class account_analytic_account(osv.osv):
res['value']['use_timesheets'] = template.use_timesheets
return res
account_analytic_account()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -6,12 +6,12 @@
<field name="name">hr.analytic.timesheet.tree</field>
<field name="model">hr.analytic.timesheet</field>
<field name="arch" type="xml">
<tree editable="bottom" string="Timesheet Lines">
<tree editable="bottom" string="Timesheet Activities">
<field name="date" on_change="on_change_date(date)"/>
<field name="user_id" on_change="on_change_user_id(user_id)" required="1"/>
<field name="user_id" on_change="on_change_user_id(user_id)" required="1" options='{"no_open": True}'/>
<field name="journal_id" invisible="1"/>
<field name="name"/>
<field domain="[('type','=','normal'),('use_timesheets','=',1)]" name="account_id" context="{'default_use_timesheets': 1}"/>
<field domain="[('type','=','normal'),('use_timesheets','=',1)]" name="account_id" context="{'default_use_timesheets': 1, 'default_type': 'contract'}"/>
<field name="product_id" on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id)" required="1" domain="[('type','=','service')]" invisible="1"/>
<field name="unit_amount" string="Duration" on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id)" sum="Total time" widget="float_time"/>
<field name="product_uom_id" on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id)" invisible="1"/>
@ -24,7 +24,7 @@
<field name="name">hr.analytic.timesheet.form</field>
<field name="model">hr.analytic.timesheet</field>
<field name="arch" type="xml">
<form string="Timesheet Lines" version="7.0">
<form string="Timesheet Activities" version="7.0">
<sheet>
<group>
<group>
@ -85,6 +85,23 @@
<field name="src_model">account.analytic.account</field>
<field name="view_mode">tree,form</field>
<field name="view_type">form</field>
<field name="help" type="html">
<p>
No activity yet on this contract.
</p><p>
In OpenERP, contracts and projects are implemented using
analytic account. So, you can track costs and revenues to analyse
your margins easily.
</p><p>
Costs will be created automatically when you register supplier
invoices, expenses or timesheets.
</p><p>
Revenues will be created automatically when you create customer
invoices. Customer invoices can be created based on sale orders
(fixed price invoices), on timesheets (based on the work done) or
on expenses (e.g. reinvoicing of travel costs).
</p>
</field>
</record>
@ -107,7 +124,7 @@
</record>
<record id="act_hr_timesheet_line_evry1_all_form" model="ir.actions.act_window">
<field name="name">Timesheet Lines</field>
<field name="name">Timesheet Activities</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">hr.analytic.timesheet</field>
<field name="view_type">form</field>
@ -116,12 +133,12 @@
<field name="search_view_id" ref="hr_timesheet_line_search"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to record your timesheets.
Click to record activities.
</p><p>
You can register and track your workings hours by project every
day. Every time spent on a project will become a cost in the
analytic accounting and can be re-invoiced to customers if
required.
analytic accounting/contract and can be re-invoiced to
customers if required.
</p>
</field>
</record>

View File

@ -70,8 +70,7 @@ class account_analytic_account(osv.osv):
'amount_invoiced': fields.function(_invoiced_calc, string='Invoiced Amount',
help="Total invoiced"),
'to_invoice': fields.many2one('hr_timesheet_invoice.factor', 'Timesheet Invoicing Ratio',
help="This field allows you to define the rate in case you plan to reinvoice " \
"the costs in this analytic account: timesheets, expenses, ..."),
help="You usually invoice 100% of the timesheets. But if you mix fixed price and timesheet invoicing, you may use another ratio. For instance, if you do a 20% advance invoice (fixed price, based on a sale order), you should invoice the rest on timesheet with a 80% ratio."),
}
_defaults = {
'pricelist_id': lambda self, cr, uid, ctx: ctx.get('pricelist_id', False),

View File

@ -16,5 +16,10 @@
<field name="customer_name">50%</field>
<field name="factor">50.0</field>
</record>
<record id="timesheet_invoice_factor4" model="hr_timesheet_invoice.factor">
<field name="name">80%</field>
<field name="customer_name">80%</field>
<field name="factor">20.0</field>
</record>
</data>
</openerp>

View File

@ -9,8 +9,8 @@
<field name="arch" type="xml">
<xpath expr='//separator[@name="description"]' position='before'>
<group string="Invoice on Timesheets Options" name="invoice_on_timesheets" col="4">
<field name="pricelist_id" />
<field name="to_invoice" widget="selection"/>
<field name="pricelist_id" groups="product.group_sale_pricelist"/>
<field name="to_invoice"/>
</group>
</xpath>
<xpath expr="//field[@name='use_timesheets']" position="replace">
@ -91,6 +91,20 @@
</field>
</record>
<record id="view_hr_timesheet_line_search_to_invoice" model="ir.ui.view">
<field name="name">hr.analytic.timesheet.search.to_invoice</field>
<field name="model">hr.analytic.timesheet</field>
<field name="inherit_id" ref="hr_timesheet.hr_timesheet_line_search"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='account_id']" position="after">
<separator/>
<filter name="to_invoice" string="To Invoice" context="{'to_invoice': 1}" domain="[('invoice_id','=',False), ('to_invoice','&lt;&gt;',False)]" icon="terp-dolar"/>
<filter name="invoiced" string="Invoiced" domain="[('invoice_id','!=',False), ('to_invoice','&lt;&gt;',False)]" icon="terp-dolar"/>
</xpath>
</field>
</record>
<record id="view_account_analytic_line_tree_inherit" model="ir.ui.view">
<field name="name">account.analytic.line.tree.to_invoice</field>
<field name="model">account.analytic.line</field>

View File

@ -36,14 +36,17 @@ class final_invoice_create(osv.osv_memory):
_description = 'Create invoice from timesheet final'
_columns = {
'date': fields.boolean('Date', help='Display date in the history of works'),
'time': fields.boolean('Time spent', help='Display time in the history of works'),
'name': fields.boolean('Name of entry', help='Display detail of work in the invoice line.'),
'time': fields.boolean('Time Spent', help='Display time in the history of works'),
'name': fields.boolean('Log of Activity', help='Display detail of work in the invoice line.'),
'price': fields.boolean('Cost', help='Display cost of the item you reinvoice'),
'product': fields.many2one('product.product', 'Product', help='The product that will be used to invoice the remaining amount'),
}
def do_create(self, cr, uid, ids, context=None):
data = self.read(cr, uid, ids, [], context=context)[0]
# hack for fixing small issue (context should not propagate implicitly between actions)
if 'default_type' in context:
del context['default_type']
ids = self.pool.get('account.analytic.line').search(cr, uid, [('invoice_id','=',False),('to_invoice','<>', False), ('account_id', 'in', context['active_ids'])], context=context)
invs = self.pool.get('account.analytic.line').invoice_cost_create(cr, uid, ids, data, context=context)
mod_obj = self.pool.get('ir.model.data')

View File

@ -29,6 +29,15 @@ from tools.translate import _
class account_analytic_line(osv.osv):
_inherit = "account.analytic.line"
def _get_invoice_price(self, cr, uid, account, product_id, user_id, qty, context = {}):
pro_price_obj = self.pool.get('product.pricelist')
if account.pricelist_id:
pl = account.pricelist_id.id
price = pro_price_obj.price_get(cr,uid,[pl], product_id, qty or 1.0, account.partner_id.id, context=context)[pl]
else:
price = 0.0
return price
#
# data = {
@ -45,7 +54,6 @@ class account_analytic_line(osv.osv):
invoice_obj = self.pool.get('account.invoice')
product_obj = self.pool.get('product.product')
invoice_factor_obj = self.pool.get('hr_timesheet_invoice.factor')
pro_price_obj = self.pool.get('product.pricelist')
fiscal_pos_obj = self.pool.get('account.fiscal.position')
product_uom_obj = self.pool.get('product.uom')
invoice_line_obj = self.pool.get('account.invoice.line')
@ -99,13 +107,13 @@ class account_analytic_line(osv.osv):
last_invoice = invoice_obj.create(cr, uid, curr_invoice, context=context2)
invoices.append(last_invoice)
cr.execute("SELECT product_id, to_invoice, sum(unit_amount), product_uom_id, name " \
cr.execute("SELECT product_id, user_id, to_invoice, sum(unit_amount), product_uom_id, name " \
"FROM account_analytic_line as line " \
"WHERE account_id = %s " \
"AND id IN %s AND to_invoice IS NOT NULL " \
"GROUP BY product_id, to_invoice, product_uom_id, name", (account.id, tuple(ids),))
"GROUP BY product_id, user_id, to_invoice, product_uom_id, name", (account.id, tuple(ids),))
for product_id, factor_id, qty, uom, line_name in cr.fetchall():
for product_id, user_id, factor_id, qty, uom, line_name in cr.fetchall():
if data.get('product'):
product_id = data['product'][0]
product = product_obj.browse(cr, uid, product_id, context=context2)
@ -118,11 +126,8 @@ class account_analytic_line(osv.osv):
ctx = context.copy()
ctx.update({'uom':uom})
if account.pricelist_id:
pl = account.pricelist_id.id
price = pro_price_obj.price_get(cr,uid,[pl], product_id, qty or 1.0, account.partner_id.id, context=ctx)[pl]
else:
price = 0.0
price = self._get_invoice_price(cr, uid, account, product_id, user_id, qty, ctx)
general_account = product.product_tmpl_id.property_account_income or product.categ_id.property_account_income_categ
if not general_account:
@ -164,7 +169,8 @@ class account_analytic_line(osv.osv):
details.append(line['name'])
note.append(u' - '.join(map(lambda x: unicode(x) or '',details)))
curr_line['name'] += "\n".join(map(lambda x: unicode(x) or '',note))
if note:
curr_line['name'] += "\n" + ("\n".join(map(lambda x: unicode(x) or '',note)))
invoice_line_obj.create(cr, uid, curr_line, context=context)
cr.execute("update account_analytic_line set invoice_id=%s WHERE account_id = %s and id IN %s", (last_invoice, account.id, tuple(ids)))

View File

@ -26,13 +26,19 @@
<field name="model">hr.timesheet.invoice.create.final</field>
<field name="arch" type="xml">
<form string="Invoice contract" version="7.0">
<separator string="Do you want to display work details on the invoice?" colspan="4"/>
<field name="date"/>
<field name="time"/>
<field name="name"/>
<field name="price"/>
<separator string="Force to use a special product" colspan="4"/>
<field name="product"/>
<p>Do you want to show details of each activity to your customer?</p>
<group>
<group>
<field name="date"/>
<field name="time"/>
</group><group>
<field name="name"/>
<field name="price"/>
</group>
</group>
<group string="Force to use a special product" groups="base.group_no_one">
<field name="product"/>
</group>
<footer>
<button name="do_create" string="Create Invoice" type="object" class="oe_highlight"/>
or

View File

@ -34,103 +34,22 @@ class hr_timesheet_sheet(osv.osv):
_order = "id desc"
_description="Timesheet"
def _total_attendances(self, cr, uid, ids, name, args, context=None):
""" Get the total attendance for the timesheets
Returns a dict like :
{id: {'total_per_day': {day: timedelta, ...},
},
...
}
"""
context = context or {}
attendance_obj = self.pool.get('hr.attendance')
res = {}
for sheet_id in ids:
sheet = self.browse(cr, uid, sheet_id, context=context)
# field attendances_ids of hr_timesheet_sheet.sheet only
# returns attendances of timesheet's current date
attendance_ids = attendance_obj.search(cr, uid, [('sheet_id', '=', sheet_id)], context=context)
attendances = attendance_obj.browse(cr, uid, attendance_ids, context=context)
total_attendance = {}
for attendance in [att for att in attendances
if att.action in ('sign_in', 'sign_out')]:
day = attendance.name[:10]
if not total_attendance.get(day, False):
total_attendance[day] = timedelta(seconds=0)
attendance_in_time = datetime.strptime(attendance.name, '%Y-%m-%d %H:%M:%S')
attendance_interval = timedelta(hours=attendance_in_time.hour,
minutes=attendance_in_time.minute,
seconds=attendance_in_time.second)
if attendance.action == 'sign_in':
total_attendance[day] -= attendance_interval
else:
total_attendance[day] += attendance_interval
res[sheet_id] = {'total_per_day': total_attendance}
return res
def _total_timesheet(self, cr, uid, ids, name, args, context=None):
""" Get the total of analytic lines for the timesheets
Returns a dict like :
{id: {day: timedelta, ...}}
"""
context = context or {}
sheet_line_obj = self.pool.get('hr.analytic.timesheet')
res = {}
for sheet_id in ids:
# field timesheet_ids of hr_timesheet_sheet.sheet only
# returns lines of timesheet's current date
sheet_lines_ids = sheet_line_obj.search(cr, uid, [('sheet_id', '=', sheet_id)], context=context)
sheet_lines = sheet_line_obj.browse(cr, uid, sheet_lines_ids, context=context)
total_timesheet = {}
for line in sheet_lines:
day = line.date
if not total_timesheet.get(day, False):
total_timesheet[day] = timedelta(seconds=0)
total_timesheet[day] += timedelta(hours=line.unit_amount)
res[sheet_id] = total_timesheet
return res
def _total(self, cr, uid, ids, name, args, context=None):
""" Compute the attendances, analytic lines timesheets and differences between them
for all the days of a timesheet and the current day
"""
def sum_all_days(sheet_amounts):
if not sheet_amounts:
return timedelta(seconds=0)
total = reduce(lambda memo, value: memo + value, sheet_amounts.values())
return total
def timedelta_to_hours(delta):
hours = 0.0
seconds = float(delta.seconds)
if delta.microseconds:
seconds += float(delta.microseconds) / 100000
hours += delta.days * 24
if seconds:
hours += seconds / 3600
return hours
res = {}
all_timesheet_attendances = self._total_attendances(cr, uid, ids, name, args, context=context)
all_timesheet_lines = self._total_timesheet(cr, uid, ids, name, args, context=context)
for id in ids:
res[id] = {}
all_attendances_sheet = all_timesheet_attendances[id]
total_attendances_sheet = all_attendances_sheet['total_per_day']
total_attendances_all_days = sum_all_days(total_attendances_sheet)
total_timesheets_sheet = all_timesheet_lines[id]
total_timesheets_all_days = sum_all_days(total_timesheets_sheet)
total_difference_all_days = total_attendances_all_days - total_timesheets_all_days
res[id]['total_attendance'] = timedelta_to_hours(total_attendances_all_days)
res[id]['total_timesheet'] = timedelta_to_hours(total_timesheets_all_days)
res[id]['total_difference'] = timedelta_to_hours(total_difference_all_days)
for sheet in self.browse(cr, uid, ids, context=context or {}):
res.setdefault(sheet.id, {
'total_attendance': 0.0,
'total_timesheet': 0.0,
'total_difference': 0.0,
})
for period in sheet.period_ids:
res[sheet.id]['total_attendance'] += period.total_attendance
res[sheet.id]['total_timesheet'] += period.total_timesheet
res[sheet.id]['total_difference'] += period.total_attendance - period.total_timesheet
return res
def check_employee_attendance_state(self, cr, uid, sheet_id, context=None):
@ -283,8 +202,8 @@ class hr_timesheet_sheet(osv.osv):
return []
if isinstance(ids, (long, int)):
ids = [ids]
return [(r['id'], r['date_from'] + ' - ' + r['date_to']) \
for r in self.read(cr, uid, ids, ['date_from', 'date_to'],
return [(r['id'], _('Week ')+datetime.strptime(r['date_from'], '%Y-%m-%d').strftime('%U')) \
for r in self.read(cr, uid, ids, ['date_from'],
context=context, load='_classic_write')]
def unlink(self, cr, uid, ids, context=None):

View File

@ -40,6 +40,23 @@
</field>
</record>
<record model="ir.actions.act_window" id="act_hr_timesheet_sheet_sheet_2_hr_analytic_timesheet">
<field name="context">{'search_default_sheet_id': [active_id]}</field>
<field name="name">Timesheet Activities</field>
<field name="res_model">hr.analytic.timesheet</field>
<field name="src_model">hr_timesheet_sheet.sheet</field>
</record>
<record model="ir.actions.act_window" id="act_hr_timesheet_sheet_sheet_2_hr_attendance">
<field name="context">{'search_default_sheet_id': [active_id]}</field>
<field name="name">Attendances</field>
<field name="res_model">hr.attendance</field>
<field name="src_model">hr_timesheet_sheet.sheet</field>
</record>
<record id="hr_timesheet_sheet_form" model="ir.ui.view">
<field name="name">hr.timesheet.sheet.form</field>
<field name="model">hr_timesheet_sheet.sheet</field>
@ -53,8 +70,18 @@
<field name="state" widget="statusbar" statusbar_visible="new,confirm,done"/>
</header>
<sheet>
<label for="employee_id" class="oe_edit_only"/>
<h1><field name="employee_id" on_change="onchange_employee_id(employee_id)" class="oe_inline"/></h1>
<div class="oe_right oe_button_box" name="buttons">
<button type="action"
name="%(act_hr_timesheet_sheet_sheet_2_hr_analytic_timesheet)d"
string="Timesheet Activities" />
<button type="action" groups="base.group_hr_attendance"
name="%(act_hr_timesheet_sheet_sheet_2_hr_attendance)d"
string="Attendances" />
</div>
<div class="oe_title">
<label for="employee_id" class="oe_edit_only"/>
<h1><field name="employee_id" on_change="onchange_employee_id(employee_id)" class="oe_inline"/></h1>
</div>
<group>
<group>
<label for="date_from" string="Timesheet Period"/>
@ -63,41 +90,25 @@
<field name="department_id" invisible="1"/>
<field name="company_id" groups="base.group_multi_company"/>
</group>
<group>
<field name="total_attendance" widget="float_time" groups="base.group_hr_attendance"/>
<field name="total_timesheet" widget="float_time" groups="base.group_hr_attendance"/>
<field name="total_difference" widget="float_time" groups="base.group_hr_attendance"/>
<group groups="base.group_hr_attendance">
<field name="total_attendance" widget="float_time"/>
<field name="total_timesheet" widget="float_time"/>
<field name="total_difference" widget="float_time"/>
<field name="user_id" invisible="1"/>
</group>
</group>
<notebook>
<page string="Weekly">
<page string="Summary">
<widget type="weekly_timesheet">
</widget>
</page>
<page string="Daily">
<group groups="base.group_hr_attendance">
<field context="{'user_id':user_id}" name="attendances_ids" nolabel="1">
<tree string="Attendances" editable="bottom">
<field name="name"/>
<field name="action"/>
<field invisible="1" name="employee_id"/>
</tree>
</field>
<group>
<field name="state_attendance" nolabel="1"/>
<div align="right" groups="base.group_hr_manager">
<button name="attendance_action_change" attrs="{'invisible': [('state_attendance', '=', 'present')]}" type="object" string="Sign In"/>
<button name="attendance_action_change" attrs="{'invisible': ['|', ('state_attendance','=',False), ('state_attendance', '=', 'absent')]}" type="object" string="Sign Out"/>
</div>
</group>
</group>
<page string="Details">
<field context="{'user_id':user_id}" name="timesheet_ids" nolabel="1">
<tree editable="top" string="Timesheet Lines">
<tree editable="top" string="Timesheet Activities">
<field name="date"/>
<field domain="[('type','in',['normal', 'contract']), ('state', '&lt;&gt;', 'close'),('use_timesheets','=',1)]" name="account_id" on_change="on_change_account_id(account_id, user_id)" context="{'default_use_timesheets': 1}"/>
<field name="name"/>
<field name="unit_amount" on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id)" widget="float_time" string="Hours"/>
<field name="unit_amount" on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id)" widget="float_time" string="Hours" sum="Hours"/>
<field name="to_invoice" widget="selection"/>
<field invisible="1" name="journal_id"/>
<field invisible="1" name="product_id" domain="[('type','=','service')]" on_change="on_change_unit_amount(product_id, unit_amount, False, product_uom_id,journal_id)"/>
@ -106,7 +117,7 @@
<field invisible="1" name="general_account_id"/>
<field invisible="1" name="user_id" required="1"/>
</tree>
<form string="Timesheet Lines" version="7.0">
<form string="Timesheet Activities" version="7.0">
<field name="date"/>
<field domain="[('type','=','normal'), ('state', '&lt;&gt;', 'close')]" name="account_id" on_change="on_change_account_id(account_id, user_id)"/>
<field name="name"/>
@ -121,13 +132,30 @@
</form>
</field>
</page>
<page string="Summary" groups="base.group_hr_attendance">
<page string="Attendances" groups="base.group_hr_attendance">
<group>
<field context="{'user_id':user_id}" name="attendances_ids" nolabel="1">
<tree string="Attendances" editable="bottom">
<field name="name"/>
<field name="action"/>
<field invisible="1" name="employee_id"/>
</tree>
</field>
<group>
<label for="state_attendance"/>
<div>
<field name="state_attendance"/>
<button name="attendance_action_change" attrs="{'invisible': [('state_attendance', '=', 'present')]}" type="object" string="Sign In" class="oe_link"/>
<button name="attendance_action_change" attrs="{'invisible': ['|', ('state_attendance','=',False), ('state_attendance', '=', 'absent')]}" type="object" string="Sign Out" class="oe_link"/>
</div>
</group>
</group>
<field name="period_ids">
<tree colors="red:total_difference&lt;0.1;blue:total_difference&gt;=0.1" string="Period">
<field name="name"/>
<field name="total_attendance" widget="float_time"/>
<field name="total_timesheet" widget="float_time"/>
<field name="total_difference" widget="float_time"/>
<field name="total_attendance" widget="float_time" sum="Attendances"/>
<field name="total_timesheet" widget="float_time" sum="Timesheets"/>
<field name="total_difference" widget="float_time" sum="Differences"/>
</tree>
</field>
</page>
@ -147,8 +175,8 @@
<field name="arch" type="xml">
<search string="Search Timesheet">
<field name="date_from"/>
<filter icon="terp-document-new" string="In Draft" domain="[('state','in',('draft', 'new'))]" help="Unvalidated Timesheets"/>
<filter icon="terp-camera_test" string="To Approve" domain="[('state','=','confirm')]" help="Confirmed Timesheets"/>
<filter name="new" string="In Draft" domain="[('state','in',('draft', 'new'))]" help="Unvalidated Timesheets"/>
<filter name="to_approve" string="To Approve" domain="[('state','=','confirm')]" help="Confirmed Timesheets"/>
<field name="employee_id"/>
<field name="department_id"/>
<group expand="0" string="Group By...">
@ -160,23 +188,23 @@
</record>
<record id="act_hr_timesheet_sheet_form" model="ir.actions.act_window">
<field name="name">Timesheets</field>
<field name="name">Timesheets to Validate</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">hr_timesheet_sheet.sheet</field>
<field name="view_type">form</field>
<field name="view_id" eval="False"/>
<field name="context">{'search_default_my_timesheet':1}</field>
<field name="context">{'search_default_to_approve':1}</field>
<field name="search_view_id" ref="view_hr_timesheet_sheet_filter"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to go to your timesheet.
New timesheet to approve.
</p><p>
You must record timesheets every day and confirm at the end
of the week. Once the timesheet is confirmed, it his sent to
the manager for validation.
of the week. Once the timesheet is confirmed, it should be
validated by a manager.
</p><p>
Timesheets can also be invoiced to customers, depending on the
configuration of the project.
configuration of each project's related contract.
</p>
</field>
</record>
@ -287,22 +315,6 @@
name="Timesheet by Day"
res_model="hr_timesheet_sheet.sheet.day"
src_model="hr_timesheet_sheet.sheet"/>
<act_window
context="{'search_default_sheet_id': [active_id]}"
id="act_hr_timesheet_sheet_sheet_2_hr_analytic_timesheet"
name="Timesheet Lines"
res_model="hr.analytic.timesheet"
src_model="hr_timesheet_sheet.sheet"/>
<act_window
context="{'search_default_sheet_id': [active_id]}"
id="act_hr_timesheet_sheet_sheet_2_hr_attendance"
name="Attendances"
res_model="hr.attendance"
src_model="hr_timesheet_sheet.sheet"/>
<record id="hr_timesheet_sheet_tree_simplified" model="ir.ui.view">
<field name="name">hr.timesheet.sheet.tree</field>
<field name="model">hr_timesheet_sheet.sheet</field>
@ -312,7 +324,7 @@
<field name="employee_id"/>
<field name="date_from"/>
<field name="date_to"/>
<field name="department_id"/>
<field name="department_id" invisible="1"/>
<field name="total_attendance" widget="float_time" groups="base.group_hr_attendance"/>
<field name="total_timesheet" widget="float_time"/>
<field name="total_difference" widget="float_time" groups="base.group_hr_attendance"/>

View File

@ -0,0 +1,3 @@
timesheet.css: timesheet.sass
sass -t expanded timesheet.sass timesheet.css

View File

@ -1,79 +1,65 @@
@charset "utf-8";
.openerp .oe_form_readonly .oe_timesheet_weekly .oe_timesheet_button_add {
display: none;
}
.openerp .oe_form_readonly .oe_timesheet_weekly div.oe_view_nocontent {
display: none;
}
.openerp .oe_timesheet_weekly {
overflow-x: auto;
overflow-x: auto;
}
.openerp .oe_timesheet_weekly table {
width: 100%;
width: 100%;
}
.openerp .oe_timesheet_weekly td {
padding-top: 15px;
padding: 3px;
text-align: right;
}
.openerp .oe_timesheet_weekly th {
text-align: right;
color: #069;
font-family: 'Helvetica Neue', Arial, Verdana, 'Nimbus Sans L', sans-serif;
font-size: 10px;
text-align: center;
color: #006699;
font-family: "Helvetica Neue", Arial, Verdana, "Nimbus Sans L", sans-serif;
font-size: 10px;
background: #eeeeee;
min-width: 47px;
}
.openerp .oe_timesheet_weekly th.oe_timesheet_weekly_date_head {
width: 60px;
.openerp .oe_timesheet_weekly .oe_timesheet_total {
background: #eeeeee;
}
.openerp .oe_timesheet_weekly td {
text-align: right;
vertical-align: middle;
}
.openerp .oe_timesheet_weekly .oe_timesheet_weekly_account {
text-align: left;
padding-right: 30px;
text-align: left;
}
.openerp .oe_timesheet_weekly .oe_timesheet_first_col {
min-width: 130px;
}
.openerp .oe_timesheet_weekly td input.oe_timesheet_weekly_input {
border: 1px solid #CCC;
padding: 5px 2px !important;
color: #666 !important;
font-size: 14px;
font-weight: bold;
width: 38px;
text-align: right;
min-width: 0 !important;
padding: 5px 2px !important;
width: 40px;
text-align: right;
min-width: 0 !important;
}
.openerp .oe_timesheet_weekly td .oe_timesheet_weekly_box {
padding: 5px 2px !important;
color: #666 !important;
font-size: 14px;
font-weight: bold;
width: 38px;
display: inline-block;
.openerp .oe_timesheet_weekly td.oe_timesheet_total {
font-weight: bold;
padding: 5px 3px !important;
}
.openerp .oe_timesheet_weekly .oe_timesheet_weekly_adding_tot {
display: table;
width: 100%;
display: table;
width: 100%;
}
.openerp .oe_timesheet_weekly .oe_timesheet_weekly_adding {
display: table-cell;
text-align: left;
display: table-cell;
text-align: left;
}
.openerp .oe_timesheet_weekly .oe_timesheet_weekly_tottot {
display: table-cell;
display: table-cell;
}
.openerp .oe_timesheet_weekly .oe_timesheet_weekly_add_row td {
text-align: left;
text-align: left;
}
.openerp .oe_timesheet_weekly .oe_timesheet_weekly_add_row .oe_form_field_many2one {
display: inline-block;
width: 200px;
display: inline-block;
width: 200px;
}
.openerp .oe_timesheet_weekly_today {
.openerp .oe_timesheet_weekly .oe_timesheet_weekly_today {
background: #ffddee;
}

View File

@ -0,0 +1,52 @@
@charset "utf-8"
.openerp
.oe_form_readonly
.oe_timesheet_weekly
.oe_timesheet_button_add
display: none
div.oe_view_nocontent
display: none
.oe_timesheet_weekly
overflow-x: auto
table
width: 100%
td
padding: 3px
text-align: right
th
text-align: center
color: #069
font-family: 'Helvetica Neue', Arial, Verdana, 'Nimbus Sans L', sans-serif
font-size: 10px
background: #eee
min-width: 47px
.oe_timesheet_total
background: #eee
.oe_timesheet_weekly_account
text-align: left
.oe_timesheet_first_col
min-width: 130px
td input.oe_timesheet_weekly_input
padding: 5px 2px !important
width: 40px
text-align: right
min-width: 0 !important
td.oe_timesheet_total
font-weight: bold
padding: 5px 3px !important
.oe_timesheet_weekly_adding_tot
display: table
width: 100%
.oe_timesheet_weekly_adding
display: table-cell
text-align: left
.oe_timesheet_weekly_tottot
display: table-cell
.oe_timesheet_weekly_add_row td
text-align: left
.oe_timesheet_weekly_add_row .oe_form_field_many2one
display: inline-block
width: 200px
.oe_timesheet_weekly_today
background: #fde

View File

@ -4,6 +4,9 @@ openerp.hr_timesheet_sheet = function(instance) {
var _t = instance.web._t;
instance.hr_timesheet_sheet.WeeklyTimesheet = instance.web.form.FormWidget.extend(instance.web.form.ReinitializeWidgetMixin, {
events: {
"click .oe_timesheet_weekly_account a": "go_to",
},
init: function() {
this._super.apply(this, arguments);
this.set({
@ -26,6 +29,16 @@ openerp.hr_timesheet_sheet = function(instance) {
this.render_drop = new instance.web.DropMisordered();
this.description_line = _t("/");
},
go_to: function(event) {
var id = JSON.parse($(event.target).data("id"));
this.do_action({
type: 'ir.actions.act_window',
res_model: "account.analytic.account",
res_id: id,
views: [[false, 'form']],
target: 'current'
});
},
query_sheets: function() {
var self = this;
if (self.updating)
@ -194,6 +207,10 @@ openerp.hr_timesheet_sheet = function(instance) {
['use_timesheets','=',1],
['id', 'not in', _.pluck(self.accounts, "account")],
],
context: {
default_use_timesheets: 1,
default_type: "contract",
},
modifiers: '{"required": true}',
},
});

View File

@ -5,7 +5,7 @@
<div class="oe_timesheet_weekly">
<table>
<tr>
<th> </th>
<th class="oe_timesheet_first_col"> </th>
<t t-foreach="widget.dates" t-as="date">
<th t-att-class="'oe_timesheet_weekly_date_head' + (Date.compare(date, Date.today()) === 0 ? ' oe_timesheet_weekly_today' : '')">
<t t-esc="date.toString('ddd')"/><br />
@ -15,7 +15,7 @@
<th class="oe_timesheet_weekly_date_head">Total</th>
</tr>
<tr t-foreach="widget.accounts" t-as="account">
<td class="oe_timesheet_weekly_account"><t t-esc="widget.account_names[account.account]"/></td>
<td class="oe_timesheet_weekly_account"><a href="javascript:void(0)" t-att-data-id="JSON.stringify(account.account)"><t t-esc="widget.account_names[account.account]"/></a></td>
<t t-set="day_count" t-value="0"/>
<t t-foreach="account.days" t-as="day">
<td t-att-class="(Date.compare(day.day, Date.today()) === 0 ? 'oe_timesheet_weekly_today' : '')">
@ -26,31 +26,47 @@
<t t-set="day_count" t-value="day_count + 1"/>
</td>
</t>
<td t-att-data-account-total="account.account"> </td>
<td t-att-data-account-total="account.account" class="oe_timesheet_total"> </td>
</tr>
<tr class="oe_timesheet_weekly_add_row" style="display: none">
<td t-att-colspan="widget.dates.length + 2">
<button>Add</button>
<button class="oe_highlight">Add</button>
</td>
</tr>
<tr>
<tr class="oe_timesheet_total">
<td>
<div class="oe_timesheet_weekly_adding_tot">
<div class="oe_timesheet_weekly_adding"><button>Add a Project</button></div>
<div class="oe_timesheet_weekly_adding"><button class="oe_timesheet_button_add">Add a Line</button></div>
<div class="oe_timesheet_weekly_tottot"><span>Total</span></div>
</div>
</td>
<t t-set="day_count" t-value="0"/>
<t t-foreach="widget.dates" t-as="date">
<td t-att-class="(Date.compare(date, Date.today()) === 0 ? 'oe_timesheet_weekly_today' : '')">
<td class="oe_timesheet_total">
<span class="oe_timesheet_weekly_box" t-att-data-day-total="day_count">
</span>
<t t-set="day_count" t-value="day_count + 1"/>
</td>
</t>
<td class="oe_timesheet_weekly_supertotal"> </td>
<td class="oe_timesheet_weekly_supertotal oe_timesheet_total"> </td>
</tr>
</table>
<div t-if="widget.accounts.length == 0">
<div class="oe_view_nocontent">
<p class="oe_view_nocontent_create">
Click to add projects/analytic accounts you worked on.
</p><p>
You will be able to register your working hours and
activities.
</p><p>
By default, you record timesheets on analytic accounts.
But if an analytic account represents a customer
contract, you can change the type of the analytic
account to 'Contract or Project' to setup the invoicing
options.
</p>
</div>
</div>
</div>
</t>
</templates>

View File

@ -36,7 +36,7 @@ class hr_timesheet_current_open(osv.osv_memory):
user_ids = self.pool.get('hr.employee').search(cr, uid, [('user_id','=',uid)], context=context)
if not len(user_ids):
raise osv.except_osv(_('Error!'), _('Please create an employee and associate it with this user.'))
ids = ts.search(cr, uid, [('user_id','=',uid),('state','=','draft'),('date_from','<=',time.strftime('%Y-%m-%d')), ('date_to','>=',time.strftime('%Y-%m-%d'))], context=context)
ids = ts.search(cr, uid, [('user_id','=',uid),('state','in',('draft','new')),('date_from','<=',time.strftime('%Y-%m-%d')), ('date_to','>=',time.strftime('%Y-%m-%d'))], context=context)
if len(ids) > 1:
view_type = 'tree,form'

View File

@ -5,7 +5,7 @@
<field name="name">hr_timesheet_current_open.form</field>
<field name="model">hr.timesheet.current.open</field>
<field name="arch" type="xml">
<form string="My Current Timesheet" version="7.0">
<form string="My Timesheet" version="7.0">
<group>
<separator string="It will open your current timesheet"/>
</group>
@ -19,7 +19,7 @@
</record>
<record id="action_hr_timesheet_current_open" model="ir.actions.act_window">
<field name="name">My Current Timesheet</field>
<field name="name">My Timesheet</field>
<field name="res_model">hr.timesheet.current.open</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
@ -28,7 +28,7 @@
<field name="help">My Timesheet opens your timesheet so that you can book your activities into the system. From the same form, you can register your attendances (Sign In/Out) and describe the working hours made on the different projects. At the end of the period defined in the company, the timesheet is confirmed by the user and can be validated by his manager. If required, as defined on the project, you can generate the invoices based on the timesheet.</field>
</record>
<menuitem action="action_hr_timesheet_current_open" icon="STOCK_NEW" id="menu_act_hr_timesheet_sheet_form_my_current" name="My Current Timesheet" parent="hr_attendance.menu_hr_time_tracking" sequence="1"/>
<menuitem action="action_hr_timesheet_current_open" icon="STOCK_NEW" id="menu_act_hr_timesheet_sheet_form_my_current" name="My Timesheet" parent="hr_attendance.menu_hr_time_tracking" sequence="1"/>
</data>
</openerp>

View File

@ -8,45 +8,45 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-09 00:36+0000\n"
"PO-Revision-Date: 2011-12-22 17:13+0000\n"
"Last-Translator: Tomislav Bosnjakovic <Unknown>\n"
"PO-Revision-Date: 2012-10-28 19:42+0000\n"
"Last-Translator: Marijan Rajic <Unknown>\n"
"Language-Team: Croatian <hr@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-19 05:36+0000\n"
"X-Generator: Launchpad (build 16165)\n"
"X-Launchpad-Export-Date: 2012-10-29 05:00+0000\n"
"X-Generator: Launchpad (build 16194)\n"
#. module: mail
#: field:mail.compose.message,subtype:0 field:mail.message,subtype:0
#: field:mail.message.common,subtype:0
msgid "Message Type"
msgstr ""
msgstr "Tip poruke"
#. module: mail
#: help:mail.compose.message,auto_delete:0
msgid "Permanently delete emails after sending"
msgstr ""
msgstr "Trajno obrisati e-poštu nakon slanja"
#. module: mail
#: view:mail.message:0
msgid "Open Related Document"
msgstr ""
msgstr "Otvori povezani dokument"
#. module: mail
#: view:mail.message:0
msgid "Open Attachments"
msgstr "Otvori privitke"
msgstr "Otvori priloge"
#. module: mail
#: view:mail.message:0
msgid "Message Details"
msgstr "Detalji poruke"
msgstr "Detalji porukue"
#. module: mail
#: view:mail.thread:0
msgid "Communication History"
msgstr ""
msgstr "Povijest komunikacije"
#. module: mail
#: view:mail.message:0
@ -57,73 +57,73 @@ msgstr "Grupiraj po..."
#: model:ir.actions.act_window,name:mail.action_email_compose_message_wizard
#: view:mail.compose.message:0
msgid "Compose Email"
msgstr ""
msgstr "Sastavi e-poštu"
#. module: mail
#: help:mail.compose.message,body_text:0 help:mail.message,body_text:0
#: help:mail.message.common,body_text:0
msgid "Plain-text version of the message"
msgstr ""
msgstr "Verzija poruke u običnom tekstu"
#. module: mail
#: view:mail.compose.message:0
msgid "Body"
msgstr ""
msgstr "Sadržaj"
#. module: mail
#: help:mail.compose.message,email_to:0 help:mail.message,email_to:0
#: help:mail.message.common,email_to:0
msgid "Message recipients"
msgstr ""
msgstr "Primatelji poruke"
#. module: mail
#: field:mail.compose.message,body_text:0 field:mail.message,body_text:0
#: field:mail.message.common,body_text:0
msgid "Text Contents"
msgstr ""
msgstr "Sadržaj"
#. module: mail
#: view:mail.message:0 selection:mail.message,state:0
msgid "Received"
msgstr ""
msgstr "Primljeno"
#. module: mail
#: view:mail.message:0
msgid "Thread"
msgstr ""
msgstr "Nit"
#. module: mail
#: field:mail.message,mail_server_id:0
msgid "Outgoing mail server"
msgstr ""
msgstr "Izlazni poslužitelj e-pošte"
#. module: mail
#: selection:mail.message,state:0
msgid "Cancelled"
msgstr ""
msgstr "Otkazano"
#. module: mail
#: field:mail.compose.message,reply_to:0 field:mail.message,reply_to:0
#: field:mail.message.common,reply_to:0
msgid "Reply-To"
msgstr ""
msgstr "Odgovori na"
#. module: mail
#: help:mail.compose.message,body_html:0 help:mail.message,body_html:0
#: help:mail.message.common,body_html:0
msgid "Rich-text/HTML version of the message"
msgstr ""
msgstr "Verzija poruke u Rich-text/HTML formatu"
#. module: mail
#: field:mail.compose.message,auto_delete:0 field:mail.message,auto_delete:0
msgid "Auto Delete"
msgstr ""
msgstr "Auto brisanje"
#. module: mail
#: help:mail.compose.message,email_bcc:0 help:mail.message,email_bcc:0
#: help:mail.message.common,email_bcc:0
msgid "Blind carbon copy message recipients"
msgstr ""
msgstr "Primatelji skrivene kopije poruke"
#. module: mail
#: model:ir.model,name:mail.model_res_partner view:mail.message:0
@ -134,13 +134,13 @@ msgstr "Partner"
#: field:mail.compose.message,subject:0 field:mail.message,subject:0
#: field:mail.message.common,subject:0
msgid "Subject"
msgstr ""
msgstr "Naslov"
#. module: mail
#: code:addons/mail/wizard/mail_compose_message.py:152
#, python-format
msgid "On %(date)s, "
msgstr ""
msgstr "Na %(date)s, "
#. module: mail
#: field:mail.compose.message,email_from:0 field:mail.message,email_from:0
@ -151,32 +151,32 @@ msgstr "Od"
#. module: mail
#: view:mail.message:0
msgid "Email message"
msgstr ""
msgstr "Poruka e-pošte"
#. module: mail
#: view:mail.compose.message:0
msgid "Send"
msgstr ""
msgstr "Pošalji"
#. module: mail
#: view:mail.message:0
msgid "Failed"
msgstr ""
msgstr "Neuspjelo"
#. module: mail
#: view:mail.message:0 field:mail.message,state:0
msgid "State"
msgstr ""
msgstr "Stanje"
#. module: mail
#: view:mail.message:0
msgid "Reply"
msgstr ""
msgstr "Odgovor"
#. module: mail
#: view:mail.message:0 selection:mail.message,state:0
msgid "Sent"
msgstr ""
msgstr "Poslano"
#. module: mail
#: help:mail.compose.message,subtype:0 help:mail.message,subtype:0
@ -185,39 +185,41 @@ msgid ""
"Type of message, usually 'html' or 'plain', used to select plaintext or rich "
"text contents accordingly"
msgstr ""
"Tip poruke, obično 'html' ili 'običan tekst', koristi se za odabir običnog "
"ili bogatije formatiranog teksta"
#. module: mail
#: view:mail.message:0
msgid "Recipients"
msgstr ""
msgstr "Primatelji"
#. module: mail
#: model:ir.model,name:mail.model_mail_compose_message
msgid "Email composition wizard"
msgstr ""
msgstr "Čarobnjak za sastavljanje e-pošte"
#. module: mail
#: field:mail.compose.message,res_id:0 field:mail.message,res_id:0
#: field:mail.message.common,res_id:0
msgid "Related Document ID"
msgstr ""
msgstr "Povezani ID dokumenta"
#. module: mail
#: view:mail.message:0
msgid "Advanced"
msgstr ""
msgstr "Napredno"
#. module: mail
#: code:addons/mail/wizard/mail_compose_message.py:157
#, python-format
msgid "Re:"
msgstr ""
msgstr "Re:"
#. module: mail
#: field:mail.compose.message,model:0 field:mail.message,model:0
#: field:mail.message.common,model:0
msgid "Related Document Model"
msgstr ""
msgstr "Povezani model dokumenta"
#. module: mail
#: view:mail.message:0
@ -227,42 +229,42 @@ msgstr "Mjesec"
#. module: mail
#: view:mail.message:0
msgid "Email Search"
msgstr "Pretraživanje e-mailova"
msgstr "Pretraga e-pošte"
#. module: mail
#: help:mail.message,original:0
msgid "Original version of the message, as it was sent on the network"
msgstr ""
msgstr "Originalna varijanta poruke, kakva je poslana na mrežu"
#. module: mail
#: view:mail.message:0
msgid "Partner Name"
msgstr "Naziv partnera"
msgstr "Ime partnera"
#. module: mail
#: view:mail.message:0
msgid "Retry"
msgstr ""
msgstr "Pokušaj ponovo"
#. module: mail
#: view:mail.message:0 selection:mail.message,state:0
msgid "Outgoing"
msgstr ""
msgstr "Odlazno"
#. module: mail
#: view:mail.message:0
msgid "Send Now"
msgstr ""
msgstr "Pošalji odmah"
#. module: mail
#: field:mail.message,partner_id:0
msgid "Related partner"
msgstr ""
msgstr "Povezani partner"
#. module: mail
#: view:mail.message:0
msgid "User"
msgstr ""
msgstr "Korisnik"
#. module: mail
#: field:mail.compose.message,date:0 field:mail.message,date:0
@ -273,19 +275,19 @@ msgstr "Datum"
#. module: mail
#: view:mail.message:0
msgid "Extended Filters..."
msgstr ""
msgstr "Prošireni filteri..."
#. module: mail
#: code:addons/mail/wizard/mail_compose_message.py:153
#, python-format
msgid "%(sender_name)s wrote:"
msgstr ""
msgstr "%(sender_name)s je napisao:"
#. module: mail
#: field:mail.compose.message,body_html:0 field:mail.message,body_html:0
#: field:mail.message.common,body_html:0
msgid "Rich-text Contents"
msgstr ""
msgstr "Formatirani tekst"
#. module: mail
#: field:mail.message,original:0
@ -346,18 +348,18 @@ msgstr ""
#. module: mail
#: view:mail.message:0
msgid "Open"
msgstr ""
msgstr "Otvori"
#. module: mail
#: code:addons/mail/mail_thread.py:434
#, python-format
msgid "[OpenERP-Forward-Failed] %s"
msgstr ""
msgstr "[OpenERP-Forward-Failed] %s"
#. module: mail
#: field:mail.message,user_id:0
msgid "Related User"
msgstr ""
msgstr "Povezani korisnik"
#. module: mail
#: help:mail.compose.message,headers:0 help:mail.message,headers:0
@ -366,11 +368,13 @@ msgid ""
"Full message headers, e.g. SMTP session headers (usually available on "
"inbound messages only)"
msgstr ""
"Cjelovito zaglavlje poruke, npr. zaglavlje SMTP sesije (obično dostupno samo "
"kod dolaznih poruka)"
#. module: mail
#: view:mail.message:0
msgid "Creation Month"
msgstr ""
msgstr "Mjesec kreiranja"
#. module: mail
#: field:mail.compose.message,email_to:0 field:mail.message,email_to:0
@ -387,7 +391,7 @@ msgstr "Detalji"
#: model:ir.actions.act_window,name:mail.action_view_mailgate_thread
#: view:mail.thread:0
msgid "Email Threads"
msgstr ""
msgstr "Niti e-pošte"
#. module: mail
#: help:mail.compose.message,email_from:0 help:mail.message,email_from:0
@ -396,28 +400,30 @@ msgid ""
"Message sender, taken from user preferences. If empty, this is not a mail "
"but a message."
msgstr ""
"Pošiljatelj poruke, preuzet iz korisničkih preferenci. Ukoliko je prazno, "
"biti će poruka a ne e-pošta."
#. module: mail
#: view:mail.message:0
msgid "Body (Plain)"
msgstr ""
msgstr "Tijelo (obično)"
#. module: mail
#: code:addons/mail/wizard/mail_compose_message.py:153
#, python-format
msgid "You"
msgstr ""
msgstr "Vi"
#. module: mail
#: help:mail.compose.message,message_id:0 help:mail.message,message_id:0
#: help:mail.message.common,message_id:0
msgid "Message unique identifier"
msgstr ""
msgstr "Jedinstveni identifikator poruke"
#. module: mail
#: view:mail.message:0
msgid "Body (Rich)"
msgstr ""
msgstr "Tijelo (formatirano)"
#. module: mail
#: code:addons/mail/mail_message.py:155
@ -427,6 +433,9 @@ msgid ""
" Subject: %s \n"
"\t"
msgstr ""
"%s napisano %s: \n"
" Predmet: %s \n"
"\t"
#. module: mail
#: model:ir.actions.act_window,name:mail.act_res_partner_emails
@ -445,64 +454,64 @@ msgstr "Poruke"
#: field:mail.compose.message,headers:0 field:mail.message,headers:0
#: field:mail.message.common,headers:0
msgid "Message Headers"
msgstr ""
msgstr "Zaglavlja poruke"
#. module: mail
#: field:mail.compose.message,email_bcc:0 field:mail.message,email_bcc:0
#: field:mail.message.common,email_bcc:0
msgid "Bcc"
msgstr "Bcc"
msgstr "Skrivena kopija"
#. module: mail
#: model:ir.model,name:mail.model_mail_message_common
msgid "mail.message.common"
msgstr ""
msgstr "mail.message.common"
#. module: mail
#: help:mail.compose.message,references:0 help:mail.message,references:0
#: help:mail.message.common,references:0
msgid "Message references, such as identifiers of previous messages"
msgstr ""
msgstr "Reference poruke, poput identifikatora prethodnih poruka"
#. module: mail
#: constraint:res.partner:0
msgid "Error ! You cannot create recursive associated members."
msgstr ""
msgstr "Greška! Nije moguće kreirati pridružene članove rekurzivno."
#. module: mail
#: help:mail.compose.message,email_cc:0 help:mail.message,email_cc:0
#: help:mail.message.common,email_cc:0
msgid "Carbon copy message recipients"
msgstr ""
msgstr "Primatelji skrivene kopije"
#. module: mail
#: selection:mail.message,state:0
msgid "Delivery Failed"
msgstr ""
msgstr "Isporuka nije uspjela"
#. module: mail
#: model:ir.model,name:mail.model_mail_message
msgid "Email Message"
msgstr ""
msgstr "Poruka e-pošte"
#. module: mail
#: model:ir.model,name:mail.model_mail_thread view:mail.thread:0
msgid "Email Thread"
msgstr ""
msgstr "Nit e-pošte"
#. module: mail
#: field:mail.compose.message,filter_id:0
msgid "Filters"
msgstr ""
msgstr "Filteri"
#. module: mail
#: code:addons/mail/mail_thread.py:220
#, python-format
msgid "Mail attachment"
msgstr ""
msgstr "Prilog e-pošte"
#. module: mail
#: help:mail.compose.message,reply_to:0 help:mail.message,reply_to:0
#: help:mail.message.common,reply_to:0
msgid "Preferred response address for the message"
msgstr ""
msgstr "Željena povratna adresa za poruku"

View File

@ -7,21 +7,20 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-02-09 00:36+0000\n"
"PO-Revision-Date: 2011-01-21 12:01+0000\n"
"Last-Translator: NOVOTRADE RENDSZERHÁZ ( novotrade.hu ) "
"<openerp@novotrade.hu>\n"
"PO-Revision-Date: 2012-10-26 12:29+0000\n"
"Last-Translator: Herczeg Péter <herczegp@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-19 05:36+0000\n"
"X-Generator: Launchpad (build 16165)\n"
"X-Launchpad-Export-Date: 2012-10-27 04:59+0000\n"
"X-Generator: Launchpad (build 16194)\n"
#. module: mail
#: field:mail.compose.message,subtype:0 field:mail.message,subtype:0
#: field:mail.message.common,subtype:0
msgid "Message Type"
msgstr ""
msgstr "Üzenettípus"
#. module: mail
#: help:mail.compose.message,auto_delete:0
@ -31,7 +30,7 @@ msgstr ""
#. module: mail
#: view:mail.message:0
msgid "Open Related Document"
msgstr ""
msgstr "Kapcsolódó dokumentum megnyitása"
#. module: mail
#: view:mail.message:0
@ -57,7 +56,7 @@ msgstr "Csoportosítás..."
#: model:ir.actions.act_window,name:mail.action_email_compose_message_wizard
#: view:mail.compose.message:0
msgid "Compose Email"
msgstr ""
msgstr "Email írás"
#. module: mail
#: help:mail.compose.message,body_text:0 help:mail.message,body_text:0
@ -68,7 +67,7 @@ msgstr ""
#. module: mail
#: view:mail.compose.message:0
msgid "Body"
msgstr ""
msgstr "Levéltörzs"
#. module: mail
#: help:mail.compose.message,email_to:0 help:mail.message,email_to:0
@ -85,7 +84,7 @@ msgstr ""
#. module: mail
#: view:mail.message:0 selection:mail.message,state:0
msgid "Received"
msgstr ""
msgstr "Fogadott"
#. module: mail
#: view:mail.message:0
@ -95,18 +94,18 @@ msgstr ""
#. module: mail
#: field:mail.message,mail_server_id:0
msgid "Outgoing mail server"
msgstr ""
msgstr "Kimenő levelező szerver"
#. module: mail
#: selection:mail.message,state:0
msgid "Cancelled"
msgstr ""
msgstr "Megszakítva"
#. module: mail
#: field:mail.compose.message,reply_to:0 field:mail.message,reply_to:0
#: field:mail.message.common,reply_to:0
msgid "Reply-To"
msgstr ""
msgstr "Válaszcím"
#. module: mail
#: help:mail.compose.message,body_html:0 help:mail.message,body_html:0
@ -117,7 +116,7 @@ msgstr ""
#. module: mail
#: field:mail.compose.message,auto_delete:0 field:mail.message,auto_delete:0
msgid "Auto Delete"
msgstr ""
msgstr "Automatikus törlés"
#. module: mail
#: help:mail.compose.message,email_bcc:0 help:mail.message,email_bcc:0
@ -146,37 +145,37 @@ msgstr ""
#: field:mail.compose.message,email_from:0 field:mail.message,email_from:0
#: field:mail.message.common,email_from:0
msgid "From"
msgstr ""
msgstr "Feladó"
#. module: mail
#: view:mail.message:0
msgid "Email message"
msgstr ""
msgstr "Email üzenet"
#. module: mail
#: view:mail.compose.message:0
msgid "Send"
msgstr ""
msgstr "Küldés"
#. module: mail
#: view:mail.message:0
msgid "Failed"
msgstr ""
msgstr "Sikertelen"
#. module: mail
#: view:mail.message:0 field:mail.message,state:0
msgid "State"
msgstr ""
msgstr "Állapot"
#. module: mail
#: view:mail.message:0
msgid "Reply"
msgstr ""
msgstr "Válasz"
#. module: mail
#: view:mail.message:0 selection:mail.message,state:0
msgid "Sent"
msgstr ""
msgstr "Elküldött"
#. module: mail
#: help:mail.compose.message,subtype:0 help:mail.message,subtype:0
@ -189,7 +188,7 @@ msgstr ""
#. module: mail
#: view:mail.message:0
msgid "Recipients"
msgstr ""
msgstr "Címzettek"
#. module: mail
#: model:ir.model,name:mail.model_mail_compose_message
@ -205,7 +204,7 @@ msgstr ""
#. module: mail
#: view:mail.message:0
msgid "Advanced"
msgstr ""
msgstr "Speciális"
#. module: mail
#: code:addons/mail/wizard/mail_compose_message.py:157
@ -242,17 +241,17 @@ msgstr "Partner neve"
#. module: mail
#: view:mail.message:0
msgid "Retry"
msgstr ""
msgstr "Újra"
#. module: mail
#: view:mail.message:0 selection:mail.message,state:0
msgid "Outgoing"
msgstr ""
msgstr "Kimenő"
#. module: mail
#: view:mail.message:0
msgid "Send Now"
msgstr ""
msgstr "Küldés most"
#. module: mail
#: field:mail.message,partner_id:0
@ -262,7 +261,7 @@ msgstr ""
#. module: mail
#: view:mail.message:0
msgid "User"
msgstr ""
msgstr "Felhasználó"
#. module: mail
#: field:mail.compose.message,date:0 field:mail.message,date:0
@ -273,7 +272,7 @@ msgstr "Dátum"
#. module: mail
#: view:mail.message:0
msgid "Extended Filters..."
msgstr ""
msgstr "Kiterjesztett szűrők…"
#. module: mail
#: code:addons/mail/wizard/mail_compose_message.py:153
@ -290,7 +289,7 @@ msgstr ""
#. module: mail
#: field:mail.message,original:0
msgid "Original"
msgstr ""
msgstr "Eredeti"
#. module: mail
#: code:addons/mail/mail_thread.py:247 view:res.partner:0
@ -341,12 +340,12 @@ msgstr ""
#. module: mail
#: view:mail.compose.message:0 view:mail.message:0
msgid "Cancel"
msgstr ""
msgstr "Mégsem"
#. module: mail
#: view:mail.message:0
msgid "Open"
msgstr ""
msgstr "Megnyitás"
#. module: mail
#: code:addons/mail/mail_thread.py:434
@ -357,7 +356,7 @@ msgstr ""
#. module: mail
#: field:mail.message,user_id:0
msgid "Related User"
msgstr ""
msgstr "Kapcsolódó felhasználó"
#. module: mail
#: help:mail.compose.message,headers:0 help:mail.message,headers:0

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-09 00:36+0000\n"
"PO-Revision-Date: 2011-01-25 08:25+0000\n"
"Last-Translator: Alexey Y. Fedotov <Unknown>\n"
"PO-Revision-Date: 2012-10-26 17:02+0000\n"
"Last-Translator: Chertykov Denis <chertykov@gmail.com>\n"
"Language-Team: Russian <ru@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-19 05:36+0000\n"
"X-Generator: Launchpad (build 16165)\n"
"X-Launchpad-Export-Date: 2012-10-27 04:59+0000\n"
"X-Generator: Launchpad (build 16194)\n"
#. module: mail
#: field:mail.compose.message,subtype:0 field:mail.message,subtype:0
@ -26,12 +26,12 @@ msgstr ""
#. module: mail
#: help:mail.compose.message,auto_delete:0
msgid "Permanently delete emails after sending"
msgstr ""
msgstr "Не сохранять сообщения после отправки"
#. module: mail
#: view:mail.message:0
msgid "Open Related Document"
msgstr ""
msgstr "Открыть связанный документ"
#. module: mail
#: view:mail.message:0
@ -46,7 +46,7 @@ msgstr "Подробности сообщения"
#. module: mail
#: view:mail.thread:0
msgid "Communication History"
msgstr ""
msgstr "История общения"
#. module: mail
#: view:mail.message:0
@ -57,24 +57,24 @@ msgstr "Объеденить по..."
#: model:ir.actions.act_window,name:mail.action_email_compose_message_wizard
#: view:mail.compose.message:0
msgid "Compose Email"
msgstr ""
msgstr "Написать письмо"
#. module: mail
#: help:mail.compose.message,body_text:0 help:mail.message,body_text:0
#: help:mail.message.common,body_text:0
msgid "Plain-text version of the message"
msgstr ""
msgstr "Простая текстовая версия сообщения"
#. module: mail
#: view:mail.compose.message:0
msgid "Body"
msgstr ""
msgstr "Содержимое"
#. module: mail
#: help:mail.compose.message,email_to:0 help:mail.message,email_to:0
#: help:mail.message.common,email_to:0
msgid "Message recipients"
msgstr ""
msgstr "Получатели сообщения"
#. module: mail
#: field:mail.compose.message,body_text:0 field:mail.message,body_text:0
@ -85,7 +85,7 @@ msgstr ""
#. module: mail
#: view:mail.message:0 selection:mail.message,state:0
msgid "Received"
msgstr ""
msgstr "Получено"
#. module: mail
#: view:mail.message:0
@ -95,40 +95,40 @@ msgstr "Цепочка"
#. module: mail
#: field:mail.message,mail_server_id:0
msgid "Outgoing mail server"
msgstr ""
msgstr "Сервер исходящей почты"
#. module: mail
#: selection:mail.message,state:0
msgid "Cancelled"
msgstr ""
msgstr "Отменено"
#. module: mail
#: field:mail.compose.message,reply_to:0 field:mail.message,reply_to:0
#: field:mail.message.common,reply_to:0
msgid "Reply-To"
msgstr ""
msgstr "Адрес ответа"
#. module: mail
#: help:mail.compose.message,body_html:0 help:mail.message,body_html:0
#: help:mail.message.common,body_html:0
msgid "Rich-text/HTML version of the message"
msgstr ""
msgstr "Форматный текст/HTML версия сообщения"
#. module: mail
#: field:mail.compose.message,auto_delete:0 field:mail.message,auto_delete:0
msgid "Auto Delete"
msgstr ""
msgstr "Авто удаление"
#. module: mail
#: help:mail.compose.message,email_bcc:0 help:mail.message,email_bcc:0
#: help:mail.message.common,email_bcc:0
msgid "Blind carbon copy message recipients"
msgstr ""
msgstr "Получатели скрытой копии сообщения"
#. module: mail
#: model:ir.model,name:mail.model_res_partner view:mail.message:0
msgid "Partner"
msgstr "Контрагент"
msgstr "Партнёр"
#. module: mail
#: field:mail.compose.message,subject:0 field:mail.message,subject:0
@ -140,7 +140,7 @@ msgstr "Тема"
#: code:addons/mail/wizard/mail_compose_message.py:152
#, python-format
msgid "On %(date)s, "
msgstr ""
msgstr "За %(date)s, "
#. module: mail
#: field:mail.compose.message,email_from:0 field:mail.message,email_from:0
@ -151,32 +151,32 @@ msgstr "От"
#. module: mail
#: view:mail.message:0
msgid "Email message"
msgstr ""
msgstr "Сообщение эл. почты"
#. module: mail
#: view:mail.compose.message:0
msgid "Send"
msgstr ""
msgstr "Отправить"
#. module: mail
#: view:mail.message:0
msgid "Failed"
msgstr ""
msgstr "Ошибка"
#. module: mail
#: view:mail.message:0 field:mail.message,state:0
msgid "State"
msgstr ""
msgstr "Состояние"
#. module: mail
#: view:mail.message:0
msgid "Reply"
msgstr ""
msgstr "Ответить"
#. module: mail
#: view:mail.message:0 selection:mail.message,state:0
msgid "Sent"
msgstr ""
msgstr "Отправлено"
#. module: mail
#: help:mail.compose.message,subtype:0 help:mail.message,subtype:0
@ -185,11 +185,13 @@ msgid ""
"Type of message, usually 'html' or 'plain', used to select plaintext or rich "
"text contents accordingly"
msgstr ""
"Тип сообщения, обычно 'html' или 'простой', используемый для выбора "
"содержимого соответственно простого текста или форматного текста"
#. module: mail
#: view:mail.message:0
msgid "Recipients"
msgstr ""
msgstr "Получатели"
#. module: mail
#: model:ir.model,name:mail.model_mail_compose_message
@ -200,18 +202,18 @@ msgstr ""
#: field:mail.compose.message,res_id:0 field:mail.message,res_id:0
#: field:mail.message.common,res_id:0
msgid "Related Document ID"
msgstr ""
msgstr "ID связанного документа"
#. module: mail
#: view:mail.message:0
msgid "Advanced"
msgstr ""
msgstr "Дополнительно"
#. module: mail
#: code:addons/mail/wizard/mail_compose_message.py:157
#, python-format
msgid "Re:"
msgstr ""
msgstr "Ответ:"
#. module: mail
#: field:mail.compose.message,model:0 field:mail.message,model:0
@ -232,37 +234,37 @@ msgstr "Искать эл. почту"
#. module: mail
#: help:mail.message,original:0
msgid "Original version of the message, as it was sent on the network"
msgstr ""
msgstr "Оригинальная версия сообщения, как было отправлено в сеть"
#. module: mail
#: view:mail.message:0
msgid "Partner Name"
msgstr "Имя партнера"
msgstr "Название партнера"
#. module: mail
#: view:mail.message:0
msgid "Retry"
msgstr ""
msgstr "Повторить"
#. module: mail
#: view:mail.message:0 selection:mail.message,state:0
msgid "Outgoing"
msgstr ""
msgstr "Исходящее"
#. module: mail
#: view:mail.message:0
msgid "Send Now"
msgstr ""
msgstr "Отправить сейчас"
#. module: mail
#: field:mail.message,partner_id:0
msgid "Related partner"
msgstr ""
msgstr "Связанный партнер"
#. module: mail
#: view:mail.message:0
msgid "User"
msgstr ""
msgstr "Пользователь"
#. module: mail
#: field:mail.compose.message,date:0 field:mail.message,date:0
@ -273,13 +275,13 @@ msgstr "Дата"
#. module: mail
#: view:mail.message:0
msgid "Extended Filters..."
msgstr ""
msgstr "Расширенные фильтры..."
#. module: mail
#: code:addons/mail/wizard/mail_compose_message.py:153
#, python-format
msgid "%(sender_name)s wrote:"
msgstr ""
msgstr "%(sender_name)s написал:"
#. module: mail
#: field:mail.compose.message,body_html:0 field:mail.message,body_html:0
@ -290,7 +292,7 @@ msgstr ""
#. module: mail
#: field:mail.message,original:0
msgid "Original"
msgstr ""
msgstr "Оригинал"
#. module: mail
#: code:addons/mail/mail_thread.py:247 view:res.partner:0
@ -302,13 +304,13 @@ msgstr "История"
#: field:mail.compose.message,message_id:0 field:mail.message,message_id:0
#: field:mail.message.common,message_id:0
msgid "Message-Id"
msgstr ""
msgstr "ID сообщения"
#. module: mail
#: view:mail.compose.message:0 field:mail.compose.message,attachment_ids:0
#: view:mail.message:0 field:mail.message,attachment_ids:0
msgid "Attachments"
msgstr "Прикрепленные файлы"
msgstr "Вложения"
#. module: mail
#: field:mail.compose.message,email_cc:0 field:mail.message,email_cc:0
@ -325,7 +327,7 @@ msgstr " на "
#. module: mail
#: help:mail.message,auto_delete:0
msgid "Permanently delete this email after sending it, to save space"
msgstr ""
msgstr "Навсегда удалить это письмо после отправки, для экономии места"
#. module: mail
#: field:mail.compose.message,references:0 field:mail.message,references:0
@ -341,18 +343,18 @@ msgstr "Вывести текст"
#. module: mail
#: view:mail.compose.message:0 view:mail.message:0
msgid "Cancel"
msgstr ""
msgstr "Отмена"
#. module: mail
#: view:mail.message:0
msgid "Open"
msgstr ""
msgstr "Открыть"
#. module: mail
#: code:addons/mail/mail_thread.py:434
#, python-format
msgid "[OpenERP-Forward-Failed] %s"
msgstr ""
msgstr "[OpenERP-Forward-Failed] %s"
#. module: mail
#: field:mail.message,user_id:0
@ -366,11 +368,13 @@ msgid ""
"Full message headers, e.g. SMTP session headers (usually available on "
"inbound messages only)"
msgstr ""
"Полные заголовки сообщения, т.е. заголовки сессии SMTP (обычно доступные "
"только во входящих сообщениях)"
#. module: mail
#: view:mail.message:0
msgid "Creation Month"
msgstr ""
msgstr "Месяц создания"
#. module: mail
#: field:mail.compose.message,email_to:0 field:mail.message,email_to:0
@ -387,7 +391,7 @@ msgstr "Подробности"
#: model:ir.actions.act_window,name:mail.action_view_mailgate_thread
#: view:mail.thread:0
msgid "Email Threads"
msgstr ""
msgstr "Цепочки эл.писем"
#. module: mail
#: help:mail.compose.message,email_from:0 help:mail.message,email_from:0
@ -396,28 +400,30 @@ msgid ""
"Message sender, taken from user preferences. If empty, this is not a mail "
"but a message."
msgstr ""
"Отправитель сообщения, взятый из параметров пользователя. Если пусто, то это "
"не почта, а сообщение."
#. module: mail
#: view:mail.message:0
msgid "Body (Plain)"
msgstr ""
msgstr "Текст (простой)"
#. module: mail
#: code:addons/mail/wizard/mail_compose_message.py:153
#, python-format
msgid "You"
msgstr ""
msgstr "Вы"
#. module: mail
#: help:mail.compose.message,message_id:0 help:mail.message,message_id:0
#: help:mail.message.common,message_id:0
msgid "Message unique identifier"
msgstr ""
msgstr "Уникальный идентификатор сообщения"
#. module: mail
#: view:mail.message:0
msgid "Body (Rich)"
msgstr ""
msgstr "Текст (форматный)"
#. module: mail
#: code:addons/mail/mail_message.py:155
@ -427,6 +433,9 @@ msgid ""
" Subject: %s \n"
"\t"
msgstr ""
"%s написал на %s: \n"
" Тема: %s \n"
"\t"
#. module: mail
#: model:ir.actions.act_window,name:mail.act_res_partner_emails
@ -456,53 +465,74 @@ msgstr "Скрытая копия"
#. module: mail
#: model:ir.model,name:mail.model_mail_message_common
msgid "mail.message.common"
msgstr ""
msgstr "mail.message.common"
#. module: mail
#: help:mail.compose.message,references:0 help:mail.message,references:0
#: help:mail.message.common,references:0
msgid "Message references, such as identifiers of previous messages"
msgstr ""
msgstr "Ссылки сообщения, такие как идентификаторы предыдущих сообщений"
#. module: mail
#: constraint:res.partner:0
msgid "Error ! You cannot create recursive associated members."
msgstr ""
msgstr "Ошибка! Вы не можете создавать рекурсивные ссылки на участников."
#. module: mail
#: help:mail.compose.message,email_cc:0 help:mail.message,email_cc:0
#: help:mail.message.common,email_cc:0
msgid "Carbon copy message recipients"
msgstr ""
msgstr "Получатели скрытой копии сообщения"
#. module: mail
#: selection:mail.message,state:0
msgid "Delivery Failed"
msgstr ""
msgstr "Доставка не удалась"
#. module: mail
#: model:ir.model,name:mail.model_mail_message
msgid "Email Message"
msgstr ""
msgstr "Сообщение эл.почты"
#. module: mail
#: model:ir.model,name:mail.model_mail_thread view:mail.thread:0
msgid "Email Thread"
msgstr ""
msgstr "Цепочка эл.почты"
#. module: mail
#: field:mail.compose.message,filter_id:0
msgid "Filters"
msgstr ""
msgstr "Фильтры"
#. module: mail
#: code:addons/mail/mail_thread.py:220
#, python-format
msgid "Mail attachment"
msgstr ""
msgstr "Почтовое вложение"
#. module: mail
#: help:mail.compose.message,reply_to:0 help:mail.message,reply_to:0
#: help:mail.message.common,reply_to:0
msgid "Preferred response address for the message"
msgstr ""
msgstr "Предпочтительный адрес ответа для сообщения"
#~ msgid "Message type"
#~ msgstr "Тип сообщения"
#~ msgid "Text contents"
#~ msgstr "Текстовое содержимое"
#~ msgid "Related Document model"
#~ msgstr "Модель связанного документа"
#~ msgid "E-mail composition wizard"
#~ msgstr "Мастер создания электронной почты"
#~ msgid "Rich-text contents"
#~ msgstr "Форматное текстовое сообщение"
#~ msgid "Related user"
#~ msgstr "Связанный пользователь"
#~ msgid "Message headers"
#~ msgstr "Заголовки сообщения"

View File

@ -117,7 +117,7 @@
<field name="tag_ids" widget="many2many_tags" class="oe_inline" placeholder="Tags"/>
<field name="stage_id" domain="[('user_id','=',uid)]" widget="statusbar" clickable="1"/>
</header>
<field name="memo" widget="html"/><!-- editor_width="100%%" editor_height="60%%" -->
<field name="memo" widget="html" class="oe_memo" editor_height="450px" />
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field class="oe_chatter" name="message_ids" widget="mail_thread"/>
@ -176,6 +176,20 @@
<field name="view_mode">kanban,tree,form</field>
<field name="search_view_id" ref="view_note_note_filter"/>
<field name="context">{'search_default_open_true':True}</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to add a personal note.
</p><p>
Use notes to organize personal tasks or notes. All
notes are private; no one else will be able to see them. However
you can share some notes with other people by inviting followers
on the note. (Useful for meeting minutes, especially if
you activate the pad feature for collaborative writings).
</p><p>
You can customize how you process your notes/tasks by adding,
removing or modifying columns.
</p>
</field>
</record>
<menuitem name="Notes" id="menu_note_notes" parent="mail.mail_my_stuff" sequence="20" action="note.action_note_note"/>

View File

@ -0,0 +1,3 @@
note.css: note.sass
sass --trace -t expanded note.sass note.css

View File

@ -3,6 +3,16 @@
text-decoration: line-through;
}
.openerp .oe_form .oe_form_field.oe_memo {
margin: 0 -16px 0 -16px;
padding: 0px;
width: 100%;
min-height: 200px;
}
.openerp .oe_form .oe_form_field.oe_memo .cleditorMain {
border: none;
padding: 0px;
}
.openerp .oe_kanban_view.oe_notes .oe_kanban_card_fancy.oe_kanban_color_0 {
box-shadow: 0px 4px 9px rgba(48, 48, 48, 0.15);
}

View File

@ -1,9 +1,5 @@
@charset "utf-8"
.oe_kanban_column
.note_text_line_through
text-decoration: line-through
@mixin rotate($a)
-webkit-transform: rotate($a)
-o-transform: rotate($a)
@ -15,8 +11,20 @@
-ms-transition: $what $duration cubic-bezier(0.5,0,0.5,1)
transition: $what $duration cubic-bezier(0.5,0,0.5,1)
.oe_kanban_column
.note_text_line_through
text-decoration: line-through
.openerp
.oe_form
.oe_form_field.oe_memo
margin: 0 -16px 0 -16px
padding: 0px
width: 100%
min-height: 200px
.cleditorMain
border: none
padding: 0px
.oe_kanban_view.oe_notes
.oe_kanban_card_fancy.oe_kanban_color_0
box-shadow: 0px 4px 9px rgba(48,48,48,0.15)
@ -39,7 +47,7 @@
.oe_kanban_card_fancy.oe_kanban_color_9
box-shadow: 0px 4px 9px rgba(102,0,116,0.15)
.oe_kanban_record
.oe_kanban_card_fancy
.oe_kanban_card_fancy
text-shadow: none
border-radius: 2px
padding: 12px
@ -48,9 +56,9 @@
padding-bottom: 16px
margin-bottom: 16px
@include rotate(-2deg)
@include transition($what:all, $duration:300ms)
@include transition(all, 300ms)
.oe_kanban_record:nth-of-type(even)
.oe_kanban_card_fancy
.oe_kanban_card_fancy
@include rotate(1deg)
.oe_kanban_record:nth-of-type(3n)
.oe_kanban_card_fancy
@ -87,7 +95,7 @@
position: relative
z-index: 5
border-color: rgba(0,0,0,0.4)
@include transition($what:all, $duration:150ms)
@include transition(all, 150ms)
-webkit-transform: rotate(0) !important
-o-transform: rotate(0) !important
-moz-transform: rotate(0) !important

View File

@ -97,7 +97,9 @@
</group>
<group>
<field name="partner_id" on_change="onchange_partner_id(partner_id)"/>
<field name="analytic_account_id" readonly="1" required="0" attrs="{'invisible': [('analytic_account_id','=',False)]}"/>
<p colspan="2" attrs="{'invisible': [('analytic_account_id','=',False)]}">
To invoice or setup invoicing and renewal options, go to the related contract: <field name="analytic_account_id" readonly="1" required="0" class="oe_inline"/>.
</p>
</group>
</group>
<notebook>
@ -237,7 +239,7 @@
<h4><field name="name"/></h4>
<div class="oe_kanban_project_list">
<a t-if="record.use_tasks.raw_value" name="%(act_project_project_2_project_task_all)d" type="action"> <field name="task_count"/> Tasks</a>
<a t-if="record.use_tasks.raw_value" name="%(act_project_project_2_project_task_all)d" type="action" style="margin-right: 10px"> <field name="task_count"/> Tasks</a>
</div>
<div class="oe_kanban_footer_left">
<span groups="project.group_time_work_estimation_tasks">
@ -518,13 +520,13 @@
<div><b><field name="name"/></b></div>
<div>
<field name="project_id"/><br/>
<t t-esc="kanban_text_ellipsis(record.description.value, 160)"/><br/>
<t t-esc="kanban_text_ellipsis(record.description.value, 160)"/><br t-if="record.description.value"/>
<t t-if="record.date_deadline.raw_value and record.date_deadline.raw_value lt (new Date())" t-set="red">oe_kanban_text_red</t>
<span t-attf-class="#{red || ''}"><i><field name="date_deadline"/></i></span>
</div>
<div class="oe_kanban_bottom_right">
<a t-if="record.kanban_state.raw_value === 'normal'" type="object" string="Ready to Pull" name="set_kanban_state_done" class="oe_kanban_status"> </a>
<a t-if="record.kanban_state.raw_value === 'done'" type="object" string="Ready to Pull" name="set_kanban_state_blocked" class="oe_kanban_status oe_kanban_status_green"> </a>
<a t-if="record.kanban_state.raw_value === 'normal'" type="object" string="In Progress" name="set_kanban_state_done" class="oe_kanban_status"> </a>
<a t-if="record.kanban_state.raw_value === 'done'" type="object" string="Stage Done" name="set_kanban_state_blocked" class="oe_kanban_status oe_kanban_status_green"> </a>
<a t-if="record.kanban_state.raw_value === 'blocked'" type="object" string="Blocked" name="set_kanban_state_normal" class="oe_kanban_status oe_kanban_status_red"> </a>
<a t-if="record.priority.raw_value == 1" type="object" string="Priority" name="set_normal_priority" class="oe_e oe_star_on">7</a>
<a t-if="record.priority.raw_value != 1" type="object" string="Priority" name="set_high_priority" class="oe_e oe_star_off">7</a>

View File

@ -378,7 +378,7 @@
<field name="issue_count" invisible="1"/>
</field>
<xpath expr="//div[contains(@class, 'oe_kanban_project_list')]" position="inside">
<a t-if="record.use_issues.raw_value"
<a t-if="record.use_issues.raw_value" style="margin-right: 10px"
name="%(act_project_project_2_project_issue_all)d" type="action">
<field name="issue_count"/> Issues</a>
</xpath>

View File

@ -15,7 +15,7 @@
</field>
<xpath expr="//div[contains(@class, 'oe_kanban_project_list')]" position="inside">
<a t-if="record.use_timesheets.raw_value"
name="open_timesheets" type="object"><field name="hours_quantity"/> Timesheets</a>
name="open_timesheets" type="object"><field name="hours_quantity"/> Hours</a>
</xpath>
</field>
</record>

View File

@ -202,7 +202,7 @@ class sale_order(osv.osv):
- With 'Before Delivery', a draft invoice is created, and it must be paid before delivery."""),
'pricelist_id': fields.many2one('product.pricelist', 'Pricelist', required=True, readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, help="Pricelist for current sales order."),
'currency_id': fields.related('pricelist_id', 'currency_id', type="many2one", relation="res.currency", readonly=True, required=True),
'project_id': fields.many2one('account.analytic.account', 'Contract/Analytic Account', readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, help="The analytic account related to a sales order."),
'project_id': fields.many2one('account.analytic.account', 'Contract / Analytic', readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, help="The analytic account related to a sales order."),
'order_line': fields.one2many('sale.order.line', 'order_id', 'Order Lines', readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}),
'invoice_ids': fields.many2many('account.invoice', 'sale_order_invoice_rel', 'order_id', 'invoice_id', 'Invoices', readonly=True, help="This is the list of invoices that have been generated for this sales order. The same sales order may have been invoiced in several times (by line for example)."),

View File

@ -286,11 +286,8 @@
</div>
<field name="amount_total" nolabel="1" class="oe_subtotal_footer_separator" widget='monetary' options="{'currency_field': 'currency_id'}"/>
</group>
<group name="sale_margin_grp">
</group>
<div class="oe_clear"/>
<label for="note"/><br/>
<field name="note" class="oe_inline"/>
<field name="note" class="oe_inline" placeholder="Terms and conditions..."/>
</page>
<page string="Other Information" groups="base.group_user">
<group>
@ -309,20 +306,6 @@
</group>
</group>
</page>
<page string="History">
<separator string="Invoices"/>
<field name="invoice_ids" context="{'form_view_ref':'account.invoice_form'}">
<tree string="Invoices" colors="blue:state == 'draft';black:state in ('proforma','proforma2','open');gray:state == 'cancel'">
<field name="date_invoice"/>
<field name="number"/>
<field name="partner_id" string="Customer"/>
<field name="user_id"/>
<field name="date_due"/>
<field name="amount_total"/>
<field name="state"/>
</tree>
</field>
</page>
</notebook>
</sheet>
<div class="oe_chatter">
@ -363,6 +346,7 @@
<filter string="My Sale Orders" domain="[('user_id','=',uid)]" help="My Sale Orders" icon="terp-personal" name="my_sale_orders_filter"/>
<field name="partner_id"/>
<field name="user_id"/>
<field name="project_id"/>
<group expand="0" string="Group By...">
<filter string="Customer" icon="terp-personal" domain="[]" context="{'group_by':'partner_id'}"/>
<filter string="Salesperson" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>

View File

@ -7,12 +7,9 @@
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<xpath expr="//group[@name='sale_margin_grp']" position="inside">
<group>
<label for="margin"/>
<div>
<field name="margin" widget='monetary' options="{'currency_field': 'currency_id'}"/>
</div>
<xpath expr="//group[@name='sale_total']" position="after">
<group name="sale_margin_grp">
<field name="margin" widget='monetary' options="{'currency_field': 'currency_id'}"/>
</group>
</xpath>
</field>

View File

@ -68,18 +68,6 @@
<field name="shipped"/>
<field name="invoice_exists" invisible="1"/>
</field>
<field name="invoice_ids" position="after">
<separator string="Delivery Orders"/>
<field name="picking_ids" context="{'default_type': 'out'}">
<tree colors="blue:state == 'draft';grey:state == 'cancel';red:state not in ('cancel', 'done') and min_date &lt; current_date" string="Delivery Orders">
<field name="name"/>
<field name="partner_id" string="Customer"/>
<field name="min_date"/>
<field name="state"/>
<button name="action_process" states="assigned" string="Deliver" type="object" icon="gtk-go-forward" context="{'default_type': 'out'}"/>
</tree>
</field>
</field>
<xpath expr="//page[@string='Order Lines']/field[@name='order_line']/form[@string='Sales Order Lines']/group/group/field[@name='type']" position="before">
<label for="delay"/>
<div>