bzr revid: hmo@tinyerp.com-20120912100957-y4xkoa3kdcaq5dm0
This commit is contained in:
Harry (OpenERP) 2012-09-12 15:39:57 +05:30
commit deb5bf3f3c
198 changed files with 19656 additions and 998 deletions

View File

@ -1398,7 +1398,7 @@ class account_move(osv.osv):
if not l[0]:
l[2].update({
'reconcile_id':False,
'reconcil_partial_id':False,
'reconcile_partial_id':False,
'analytic_lines':False,
'invoice':False,
'ref':False,
@ -2516,22 +2516,25 @@ class account_account_template(osv.osv):
'nocreate': False,
}
def _check_type(self, cr, uid, ids, context=None):
if context is None:
context = {}
accounts = self.browse(cr, uid, ids, context=context)
for account in accounts:
if account.parent_id and account.parent_id.type != 'view':
return False
return True
_check_recursion = check_cycle
_constraints = [
(_check_recursion, 'Error!\nYou cannot create recursive account templates.', ['parent_id']),
(_check_type, 'Configuration Error!\nYou cannot define children to an account that has internal type other than "View".', ['type']),
]
def create(self, cr, uid, vals, context=None):
if 'parent_id' in vals:
parent = self.read(cr, uid, [vals['parent_id']], ['type'])
if parent and parent[0]['type'] != 'view':
raise osv.except_osv(_('Warning!'), _("You may only select a parent account of type 'View'."))
return super(account_account_template, self).create(cr, uid, vals, context=context)
def write(self, cr, uid, ids, vals, context=None):
if 'parent_id' in vals:
parent = self.read(cr, uid, [vals['parent_id']], ['type'])
if parent and parent[0]['type'] != 'view':
raise osv.except_osv(_('Warning!'), _("You may only select a parent account of type 'View'."))
return super(account_account_template, self).write(cr, uid, ids, vals, context=context)
def name_get(self, cr, uid, ids, context=None):
if not ids:
return []
@ -2999,6 +3002,7 @@ class wizard_multi_charts_accounts(osv.osv_memory):
_columns = {
'company_id':fields.many2one('res.company', 'Company', required=True),
'currency_id': fields.many2one('res.currency', 'Currency', help="Currency as per company's country."),
'only_one_chart_template': fields.boolean('Only One Chart Template Available'),
'chart_template_id': fields.many2one('account.chart.template', 'Chart Template', required=True),
'bank_accounts_id': fields.one2many('account.bank.accounts.wizard', 'bank_account_id', 'Cash and Banks', required=True),
@ -3009,6 +3013,13 @@ class wizard_multi_charts_accounts(osv.osv_memory):
'purchase_tax_rate': fields.float('Purchase Tax(%)'),
'complete_tax_set': fields.boolean('Complete Set of Taxes', help='This boolean helps you to choose if you want to propose to the user to encode the sales and purchase rates or use the usual m2o fields. This last choice assumes that the set of tax defined for the chosen template is complete'),
}
def onchange_company_id(self, cr, uid, ids, company_id, context=None):
currency_id = False
if company_id:
currency_id = self.pool.get('res.company').browse(cr, uid, company_id, context=context).currency_id.id
return {'value': {'currency_id': currency_id}}
def onchange_tax_rate(self, cr, uid, ids, rate=False, context=None):
return {'value': {'purchase_tax_rate': rate or False}}
@ -3039,6 +3050,13 @@ class wizard_multi_charts_accounts(osv.osv_memory):
res.update({'bank_accounts_id': [{'acc_name': _('Cash'), 'account_type': 'cash'},{'acc_name': _('Bank'), 'account_type': 'bank'}]})
if 'company_id' in fields:
res.update({'company_id': self.pool.get('res.users').browse(cr, uid, [uid], context=context)[0].company_id.id})
if 'currency_id' in fields:
company_id = res.get('company_id') or False
if company_id:
company_obj = self.pool.get('res.company')
country_id = company_obj.browse(cr, uid, company_id, context=context).country_id.id
currency_id = company_obj.on_change_country(cr, uid, company_id, country_id, context=context)['value']['currency_id']
res.update({'currency_id': currency_id})
ids = self.pool.get('account.chart.template').search(cr, uid, [('visible', '=', True)], context=context)
if ids:
@ -3343,6 +3361,7 @@ class wizard_multi_charts_accounts(osv.osv_memory):
ir_values_obj = self.pool.get('ir.values')
obj_wizard = self.browse(cr, uid, ids[0])
company_id = obj_wizard.company_id.id
self.pool.get('res.company').write(cr, uid, [company_id], {'currency_id': obj_wizard.currency_id.id})
# If the floats for sale/purchase rates have been filled, create templates from them
self._create_tax_templates_from_rates(cr, uid, obj_wizard, company_id, context=context)

View File

@ -15,7 +15,7 @@
<group name="accounting" col="2" colspan="2" attrs="{'invisible': [('company_id','=', False)]}">
<separator string="Accounting Information" colspan="2"/>
<field name="journal_id"/>
<field name="currency_id"/>
<field name="currency_id" groups="base.group_multi_currency"/>
</group>
</group>
</field>
@ -28,7 +28,7 @@
<field name="inherit_id" ref="base.view_partner_bank_tree"/>
<field name="arch" type="xml">
<field name="acc_number" position="after">
<field name="currency_id"/>
<field name="currency_id" groups="base.group_multi_currency"/>
</field>
</field>
</record>

View File

@ -214,7 +214,7 @@ class account_invoice(osv.osv):
\n* The \'Cancelled\' state is used when user cancel invoice.'),
'sent': fields.boolean('Sent', readonly=True, help="It indicates that the invoice has been sent."),
'date_invoice': fields.date('Invoice Date', readonly=True, states={'draft':[('readonly',False)]}, select=True, help="Keep empty to use the current date"),
'date_due': fields.date('Due Date', states={'paid':[('readonly',True)], 'open':[('readonly',True)], 'close':[('readonly',True)]}, select=True,
'date_due': fields.date('Due Date', readonly=True, states={'draft':[('readonly',False)]}, select=True,
help="If you use payment terms, the due date will be computed automatically at the generation "\
"of accounting entries. If you keep the payment term and the due date empty, it means direct payment. The payment term may compute several due dates, for example 50% now, 50% in one month."),
'partner_id': fields.many2one('res.partner', 'Partner', change_default=True, readonly=True, required=True, states={'draft':[('readonly',False)]}),
@ -253,7 +253,7 @@ class account_invoice(osv.osv):
'currency_id': fields.many2one('res.currency', 'Currency', required=True, readonly=True, states={'draft':[('readonly',False)]}),
'journal_id': fields.many2one('account.journal', 'Journal', required=True, readonly=True, states={'draft':[('readonly',False)]}),
'company_id': fields.many2one('res.company', 'Company', required=True, change_default=True, readonly=True, states={'draft':[('readonly',False)]}),
'check_total': fields.float('Verification Total', digits_compute=dp.get_precision('Account'), states={'open':[('readonly',True)],'close':[('readonly',True)]}),
'check_total': fields.float('Verification Total', digits_compute=dp.get_precision('Account'), readonly=True, states={'draft':[('readonly',False)]}),
'reconciled': fields.function(_reconciled, string='Paid/Reconciled', type='boolean',
store={
'account.invoice': (lambda self, cr, uid, ids, c={}: ids, None, 50), # Check if we can remove ?
@ -767,17 +767,20 @@ class account_invoice(osv.osv):
if not key in tax_key:
raise osv.except_osv(_('Warning!'), _('Taxes are missing!\nClick on compute button.'))
def compute_invoice_totals(self, cr, uid, inv, company_currency, ref, invoice_move_lines):
def compute_invoice_totals(self, cr, uid, inv, company_currency, ref, invoice_move_lines, context=None):
if context is None:
context={}
total = 0
total_currency = 0
cur_obj = self.pool.get('res.currency')
for i in invoice_move_lines:
if inv.currency_id.id != company_currency:
context.update({'date': inv.date_invoice or time.strftime('%Y-%m-%d')})
i['currency_id'] = inv.currency_id.id
i['amount_currency'] = i['price']
i['price'] = cur_obj.compute(cr, uid, inv.currency_id.id,
company_currency, i['price'],
context={'date': inv.date_invoice or time.strftime('%Y-%m-%d')})
context=context)
else:
i['amount_currency'] = False
i['currency_id'] = False
@ -887,7 +890,7 @@ class account_invoice(osv.osv):
# create one move line for the total and possibly adjust the other lines amount
total = 0
total_currency = 0
total, total_currency, iml = self.compute_invoice_totals(cr, uid, inv, company_currency, ref, iml)
total, total_currency, iml = self.compute_invoice_totals(cr, uid, inv, company_currency, ref, iml, context=ctx)
acc_id = inv.account_id.id
name = inv['name'] or '/'

View File

@ -127,7 +127,7 @@
<field name="user_id"/>
<field name="date_due"/>
<field name="origin"/>
<field name="currency_id"/>
<field name="currency_id" groups="base.group_multi_currency"/>
<field name="residual" sum="Residual Amount"/>
<field name="amount_untaxed" sum="Untaxed Amount"/>
<field name="amount_total" sum="Total Amount"/>
@ -184,7 +184,7 @@
name="account_id" groups="account.group_account_user"/>
<field name="journal_id" groups="account.group_account_user"
on_change="onchange_journal_id(journal_id, context)" widget="selection"/>
<field name="currency_id"/>
<field name="currency_id" groups="base.group_multi_currency"/>
</group>
</group>
<notebook>
@ -271,7 +271,7 @@
<field name="debit"/>
<field name="credit"/>
<field name="amount_currency"/>
<field name="currency_id"/>
<field name="currency_id" groups="base.group_multi_currency"/>
</tree>
</field>
</page>
@ -332,8 +332,8 @@
<field domain="[('company_id', '=', company_id),('type','=', 'receivable')]"
name="account_id" groups="account.group_account_user"/>
<label for="currency_id"/>
<div>
<label for="currency_id" groups="base.group_multi_currency"/>
<div groups="base.group_multi_currency">
<field name="currency_id" class="oe_inline"/>
<!-- note fp: I don't think we need this feature ?
<button name="%(action_account_change_currency)d" type="action"
@ -429,8 +429,8 @@
<field name="journal_id" groups="base.group_user"/>
<field name="debit"/>
<field name="credit"/>
<field name="amount_currency"/>
<field name="currency_id"/>
<field name="amount_currency" groups="base.group_multi_currency"/>
<field name="currency_id" groups="base.group_multi_currency"/>
</tree>
</field>
</page>

View File

@ -44,7 +44,7 @@
<menuitem id="menu_finance_periodical_processing_billing" name="Billing" parent="menu_finance_periodical_processing" sequence="35"/>
<menuitem id="next_id_22" name="Partners" parent="menu_finance_generic_reporting" sequence="1"/>
<menuitem id="menu_multi_currency" name="Multi-Currencies" parent="menu_finance_generic_reporting" sequence="10"/>
<menuitem id="menu_multi_currency" name="Multi-Currencies" parent="menu_finance_generic_reporting" sequence="10" groups="base.group_multi_currency"/>
<menuitem
parent="account.menu_finance_legal_statement"
id="final_accounting_reports"

View File

@ -204,7 +204,7 @@
attrs="{'invisible':[('type','!=','consolidation')]}"
widget="many2many_tags"/>
</group>
<group>
<group groups="base.group_multi_currency">
<field name="currency_id"/>
<field name="currency_mode" attrs="{'readonly': [('currency_id','=',False)]}"/>
</group>
@ -489,7 +489,7 @@
<group>
<field name="default_debit_account_id" attrs="{'required':[('type','in', ('cash', 'bank'))]}" domain="[('type','&lt;&gt;','view'),('type','&lt;&gt;','consolidation')]"/>
<field name="default_credit_account_id" attrs="{'required':[('type','in',('cash', 'bank'))]}" domain="[('type','&lt;&gt;','view'),('type','&lt;&gt;','consolidation')]"/>
<field name="currency"/>
<field name="currency" groups="base.group_multi_currency"/>
<field name="company_id" groups="base.group_multi_company"/>
</group>
</group>
@ -1068,7 +1068,7 @@
<field name="account_tax_id"/>
<field name="analytic_account_id" groups="analytic.group_analytic_accounting" domain="[('parent_id','!=',False)]"/>
<field name="amount_currency" attrs="{'readonly':[('state','=','valid')]}"/>
<field name="currency_id" attrs="{'readonly':[('state','=','valid')]}"/>
<field name="currency_id" attrs="{'readonly':[('state','=','valid')]}" groups="base.group_multi_currency"/>
<field name="reconcile_partial_id"/>
<field name="reconcile_id"/>
<field name="state"/>
@ -1119,7 +1119,7 @@
<field name="tax_amount"/>
<field name="account_tax_id" domain="[('parent_id','=',False)]"/>
</group>
<group attrs="{'readonly':[('state','=','valid')]}" string="Currency">
<group attrs="{'readonly':[('state','=','valid')]}" string="Currency" groups="base.group_multi_currency">
<field name="currency_id"/>
<field name="amount_currency"/>
</group>
@ -1167,8 +1167,8 @@
<field name="credit"/>
<separator colspan="4" string="Optional Information"/>
<field name="currency_id"/>
<field name="amount_currency"/>
<field name="currency_id" groups="base.group_multi_currency"/>
<field name="amount_currency" groups="base.group_multi_currency"/>
<field name="quantity"/>
<field name="move_id" required="False"/>
<newline/>
@ -1395,7 +1395,7 @@
<field name="account_tax_id" domain="[('parent_id','=',False)]"/>
</group>
<group string="Currency">
<group string="Currency" groups="base.group_multi_currency">
<field name="currency_id"/>
<field name="amount_currency"/>
</group>
@ -1433,7 +1433,7 @@
<field name="credit" sum="Total Credit"/>
<field name="analytic_account_id" domain="[('parent_id','!=',False)]" groups="analytic.group_analytic_accounting"/>
<field name="amount_currency"/>
<field name="currency_id"/>
<field name="currency_id" groups="base.group_multi_currency"/>
<field name="tax_code_id"/>
<field name="tax_amount"/>
<field name="state"/>
@ -2076,7 +2076,7 @@
<field name="type"/>
<field name="user_type"/>
<field name="currency_id"/>
<field name="currency_id" groups="base.group_multi_currency"/>
<field name="reconcile"/>
<field name="chart_template_id"/>
</group>
@ -2369,20 +2369,15 @@
<group string="res_config_contents" position="replace">
<field name="only_one_chart_template" invisible="1"/>
<field name="complete_tax_set" invisible="1"/>
<div groups="base.group_multi_company">
<label for="company_id"/>
<field name="company_id" widget="selection"/> <!-- we assume that this wizard will be run only by administrators and as this field may cause problem if hidden (because of the default company of the user removed from the selection because already configured), we simply choosed to remove the group "multi company" of it -->
</div>
<group>
<div attrs="{'invisible': [('only_one_chart_template','=',True)]}">
<label for="chart_template_id"/>
<group col="1">
<group attrs="{'invisible': [('only_one_chart_template','=',True)]}">
<field name="chart_template_id" widget="selection" on_change="onchange_chart_template_id(chart_template_id)" domain="[('visible','=', True)]"/>
</div>
<newline/>
<group groups="account.group_account_user">
<field name="code_digits"/>
</group>
<group groups="base.group_multi_company">
<field name="company_id" widget="selection" on_change="onchange_company_id(company_id)"/> <!-- we assume that this wizard will be run only by administrators and as this field may cause problem if hidden (because of the default company of the user removed from the selection because already configured), we simply choosed to remove the group "multi company" of it -->
</group>
<group>
<field name="currency_id" class="oe_inline"/>
<field name="sale_tax" attrs="{'invisible': [('complete_tax_set', '!=', True)]}" domain="[('chart_template_id', '=', chart_template_id),('parent_id','=',False),('type_tax_use','in',('sale','all'))]"/>
<label for="sale_tax_rate" string="Sale Tax" attrs="{'invisible': [('complete_tax_set', '=', True)]}"/>
<div attrs="{'invisible': [('complete_tax_set', '=', True)]}">
@ -2394,17 +2389,10 @@
<field name="purchase_tax_rate" class="oe_inline"/> %%
</div>
</group>
<group groups="account.group_account_user">
<field name="code_digits"/>
</group>
</group>
<div groups="account.group_account_user">
<label for="bank_accounts_id" string="Bank Information"/>
<field name="bank_accounts_id">
<tree editable="bottom">
<field name="acc_name"/>
<field name="account_type"/>
<field name="currency_id" widget="selection"/>
</tree>
</field>
</div>
</group>
</field>
</record>
@ -2566,7 +2554,7 @@ action = pool.get('res.config').next(cr, uid, [], context)
<field name="date" attrs="{'readonly':[('state','!=','draft')]}" on_change="onchange_date(date, company_id)"/>
<field name="closing_date" readonly="1"/>
<field name="period_id" class="oe_inline"/>
<field name="currency" invisible="1"/>
<field name="currency" invisible="1" groups="base.group_multi_currency"/>
</group>
</group>
<notebook>

View File

@ -45,7 +45,6 @@
<record id="conf_chart0" model="account.account.template">
<field name="code">0</field>
<field name="name">Configurable Account Chart</field>
<field eval="0" name="parent_id"/>
<field name="type">view</field>
<field name="user_type" ref="data_account_type_view"/>
</record>

View File

@ -19,7 +19,6 @@
<record id="chart0" model="account.account">
<field name="code">X0</field>
<field name="name">Chart For Automated Tests</field>
<field eval="0" name="parent_id"/>
<field name="type">view</field>
<field name="user_type" ref="data_account_type_view"/>
</record>

View File

@ -56,7 +56,7 @@
<field name="credit"/>
<field name="balance"/>
<field name="state" invisible="1"/>
<field name="currency_id"/>
<field name="currency_id" groups="base.group_multi_currency"/>
<field name="date" invisible="1"/>
<field name="user_id" invisible="1"/>
<field name="partner_id" invisible="1"/>
@ -137,8 +137,8 @@
</group>
<group string="Amount">
<field name="amount"/>
<label for="amount_currency"/>
<div>
<label for="amount_currency" groups="base.group_multi_currency"/>
<div groups="base.group_multi_currency">
<field name="amount_currency" class="oe_inline"/>
<field name="currency_id" class="oe_inline"/>
</div>
@ -251,8 +251,8 @@
</group>
<group string="Amount">
<field name="amount"/>
<label for="amount_currency"/>
<div>
<label for="amount_currency" groups="base.group_multi_currency"/>
<div groups="base.group_multi_currency">
<field name="amount_currency" class="oe_inline"/>
<field name="currency_id" class="oe_inline"/>
</div>

View File

@ -43,8 +43,8 @@ class account_config_settings(osv.osv_memory):
string='Default company currency', help="Main currency of the company."),
'paypal_account': fields.related('company_id', 'paypal_account', type='char', size=128,
string='Paypal account', help="Paypal account (email) for receiving online payments (credit card, etc.) If you set a paypal account, the customer will be able to pay your invoices or quotations with a button \"Pay with Paypal\" in automated emails or through the OpenERP portal."),
'company_footer': fields.related('company_id', 'rml_footer2', type='char', size=250, readonly=True,
string='Bank accounts on reports will display as followed', help="Bank accounts as printed in the footer of each customer document. This is for information purpose only, you should configure these bank accounts through the above button \"Configure Bank Accounts\"."),
'company_footer': fields.related('company_id', 'rml_footer', type='text', readonly=True,
string='Bank accounts footer preview', help="Bank accounts as printed in the footer of each printed document"),
'has_chart_of_accounts': fields.boolean('Company has a chart of accounts'),
'chart_template_id': fields.many2one('account.chart.template', 'Template', domain="[('visible','=', True)]"),
@ -114,6 +114,9 @@ class account_config_settings(osv.osv_memory):
help="This purchase tax will be assigned by default on new products."),
'decimal_precision': fields.integer('Decimal precision on journal entries',
help="""As an example, a decimal precision of 2 will allow journal entries like: 9.99 EUR, whereas a decimal precision of 4 will allow journal entries like: 0.0231 EUR."""),
'group_multi_currency': fields.boolean('allow multi currencies',
implied_group='base.group_multi_currency',
help="Allows you multi currency environment"),
}
def _default_company(self, cr, uid, context=None):
@ -145,42 +148,45 @@ class account_config_settings(osv.osv_memory):
def onchange_company_id(self, cr, uid, ids, company_id):
# update related fields
company = self.pool.get('res.company').browse(cr, uid, company_id)
has_chart_of_accounts = company_id not in self.pool.get('account.installer').get_unconfigured_cmp(cr, uid)
fiscalyear_count = self.pool.get('account.fiscalyear').search_count(cr, uid,
[('date_start', '<=', time.strftime('%Y-%m-%d')), ('date_stop', '>=', time.strftime('%Y-%m-%d')),
('company_id', '=', company_id)])
values = {
'expects_chart_of_accounts': company.expects_chart_of_accounts,
'currency_id': company.currency_id.id,
'paypal_account': company.paypal_account,
'company_footer': company.rml_footer2,
'has_chart_of_accounts': has_chart_of_accounts,
'has_fiscal_year': bool(fiscalyear_count),
'chart_template_id': False,
'tax_calculation_rounding_method': company.tax_calculation_rounding_method,
}
# update journals and sequences
for journal_type in ('sale', 'sale_refund', 'purchase', 'purchase_refund'):
for suffix in ('_journal_id', '_sequence_prefix', '_sequence_next'):
values[journal_type + suffix] = False
journal_obj = self.pool.get('account.journal')
journal_ids = journal_obj.search(cr, uid, [('company_id', '=', company_id)])
for journal in journal_obj.browse(cr, uid, journal_ids):
if journal.type in ('sale', 'sale_refund', 'purchase', 'purchase_refund'):
values.update({
journal.type + '_journal_id': journal.id,
journal.type + '_sequence_prefix': journal.sequence_id.prefix,
journal.type + '_sequence_next': journal.sequence_id.number_next,
})
# update taxes
ir_values = self.pool.get('ir.values')
taxes_id = ir_values.get_default(cr, uid, 'product.product', 'taxes_id', company_id=company_id)
supplier_taxes_id = ir_values.get_default(cr, uid, 'product.product', 'supplier_taxes_id', company_id=company_id)
values.update({
'default_sale_tax': isinstance(taxes_id, list) and taxes_id[0] or taxes_id,
'default_purchase_tax': isinstance(supplier_taxes_id, list) and supplier_taxes_id[0] or supplier_taxes_id,
})
values = {}
values['currency_id'] = False
if company_id:
company = self.pool.get('res.company').browse(cr, uid, company_id)
has_chart_of_accounts = company_id not in self.pool.get('account.installer').get_unconfigured_cmp(cr, uid)
fiscalyear_count = self.pool.get('account.fiscalyear').search_count(cr, uid,
[('date_start', '<=', time.strftime('%Y-%m-%d')), ('date_stop', '>=', time.strftime('%Y-%m-%d')),
('company_id', '=', company_id)])
values = {
'expects_chart_of_accounts': company.expects_chart_of_accounts,
'currency_id': company.currency_id.id,
'paypal_account': company.paypal_account,
'company_footer': company.rml_footer,
'has_chart_of_accounts': has_chart_of_accounts,
'has_fiscal_year': bool(fiscalyear_count),
'chart_template_id': False,
'tax_calculation_rounding_method': company.tax_calculation_rounding_method,
}
# update journals and sequences
for journal_type in ('sale', 'sale_refund', 'purchase', 'purchase_refund'):
for suffix in ('_journal_id', '_sequence_prefix', '_sequence_next'):
values[journal_type + suffix] = False
journal_obj = self.pool.get('account.journal')
journal_ids = journal_obj.search(cr, uid, [('company_id', '=', company_id)])
for journal in journal_obj.browse(cr, uid, journal_ids):
if journal.type in ('sale', 'sale_refund', 'purchase', 'purchase_refund'):
values.update({
journal.type + '_journal_id': journal.id,
journal.type + '_sequence_prefix': journal.sequence_id.prefix,
journal.type + '_sequence_next': journal.sequence_id.number_next,
})
# update taxes
ir_values = self.pool.get('ir.values')
taxes_id = ir_values.get_default(cr, uid, 'product.product', 'taxes_id', company_id=company_id)
supplier_taxes_id = ir_values.get_default(cr, uid, 'product.product', 'supplier_taxes_id', company_id=company_id)
values.update({
'default_sale_tax': isinstance(taxes_id, list) and taxes_id[0] or taxes_id,
'default_purchase_tax': isinstance(supplier_taxes_id, list) and supplier_taxes_id[0] or supplier_taxes_id,
})
return {'value': values}
def onchange_chart_template_id(self, cr, uid, ids, chart_template_id, context=None):

View File

@ -121,6 +121,10 @@
</div>
<label for="id" string="Features"/>
<div>
<div>
<field name="group_multi_currency" class="oe_inline"/>
<label for="group_multi_currency"/>
</div>
<div>
<field name="module_account_accountant" class="oe_inline"/>
<label for="module_account_accountant"/>
@ -219,12 +223,12 @@
<label for="id" string="Configuration"/>
<div>
<div>
<label for="company_footer"/>
<button name="%(action_bank_tree)d"
string="Configure your bank accounts"
icon="gtk-go-forward"
type="action"
class="oe_inline oe_link"/>
<label for="company_footer"/>
<field name="company_footer"/>
</div>
<div>

View File

@ -100,7 +100,7 @@
</group>
<group>
<field name="purchase_date"/>
<field name="currency_id"/>
<field name="currency_id" groups="base.group_multi_currency"/>
<field name="company_id" widget="selection" groups="base.group_multi_company" on_change="onchange_company_id(company_id)"/>
</group>
</group>
@ -192,7 +192,7 @@
<field name="partner_id"/>
<field name="purchase_value"/>
<field name="value_residual"/>
<field name="currency_id"/>
<field name="currency_id" groups="base.group_multi_currency"/>
<field name="company_id" groups="base.group_multi_company"/>
<field name="state"/>
</tree>
@ -211,7 +211,7 @@
<field name="purchase_date"/>
<field name="purchase_value"/>
<field name="value_residual"/>
<field name="currency_id"/>
<field name="currency_id" groups="base.group_multi_currency"/>
<field name="company_id" groups="base.group_multi_company"/>
<field name="state"/>
</tree>

View File

@ -0,0 +1,385 @@
# Brazilian Portuguese translation for openobject-addons
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-08 00:35+0000\n"
"PO-Revision-Date: 2012-09-11 18:35+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Brazilian Portuguese <pt_BR@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-09-12 04:36+0000\n"
"X-Generator: Launchpad (build 15930)\n"
#. module: account_bank_statement_extensions
#: view:account.bank.statement.line:0
msgid "Search Bank Transactions"
msgstr "Procurar Transações Bancárias"
#. module: account_bank_statement_extensions
#: view:account.bank.statement.line:0
#: selection:account.bank.statement.line,state:0
msgid "Confirmed"
msgstr "Confirmado"
#. module: account_bank_statement_extensions
#: view:account.bank.statement:0
#: view:account.bank.statement.line:0
msgid "Glob. Id"
msgstr "ID Global"
#. module: account_bank_statement_extensions
#: selection:account.bank.statement.line.global,type:0
msgid "CODA"
msgstr "CODA"
#. module: account_bank_statement_extensions
#: field:account.bank.statement.line.global,parent_id:0
msgid "Parent Code"
msgstr "Código da Conta-pai"
#. module: account_bank_statement_extensions
#: view:account.bank.statement.line:0
msgid "Debit"
msgstr "Débito"
#. module: account_bank_statement_extensions
#: view:cancel.statement.line:0
#: model:ir.actions.act_window,name:account_bank_statement_extensions.action_cancel_statement_line
#: model:ir.model,name:account_bank_statement_extensions.model_cancel_statement_line
msgid "Cancel selected statement lines"
msgstr "Cancelar linhas de instrução selecionadas"
#. module: account_bank_statement_extensions
#: constraint:res.partner.bank:0
msgid "The RIB and/or IBAN is not valid"
msgstr "A RIB e/ ou IBAN não é válido."
#. module: account_bank_statement_extensions
#: view:account.bank.statement.line:0
msgid "Group By..."
msgstr "Agrupar Por..."
#. module: account_bank_statement_extensions
#: field:account.bank.statement.line,state:0
msgid "State"
msgstr "Situação"
#. module: account_bank_statement_extensions
#: view:account.bank.statement.line:0
#: selection:account.bank.statement.line,state:0
msgid "Draft"
msgstr "Provisório"
#. module: account_bank_statement_extensions
#: view:account.bank.statement.line:0
msgid "Statement"
msgstr "Demonstrativo"
#. module: account_bank_statement_extensions
#: view:confirm.statement.line:0
#: model:ir.actions.act_window,name:account_bank_statement_extensions.action_confirm_statement_line
#: model:ir.model,name:account_bank_statement_extensions.model_confirm_statement_line
msgid "Confirm selected statement lines"
msgstr "Confirme as linhas do demonstrativo selecionadas"
#. module: account_bank_statement_extensions
#: report:bank.statement.balance.report:0
#: model:ir.actions.report.xml,name:account_bank_statement_extensions.bank_statement_balance_report
msgid "Bank Statement Balances Report"
msgstr "Relatório de Balanço Bancário"
#. module: account_bank_statement_extensions
#: view:cancel.statement.line:0
msgid "Cancel Lines"
msgstr "Cancelar Linhas"
#. module: account_bank_statement_extensions
#: view:account.bank.statement.line.global:0
#: model:ir.model,name:account_bank_statement_extensions.model_account_bank_statement_line_global
msgid "Batch Payment Info"
msgstr "Informações de Pagamento em Lote"
#. module: account_bank_statement_extensions
#: view:confirm.statement.line:0
msgid "Confirm Lines"
msgstr "Confirmar Linhas"
#. module: account_bank_statement_extensions
#: code:addons/account_bank_statement_extensions/account_bank_statement.py:130
#, python-format
msgid ""
"Delete operation not allowed ! Please go to the associated bank "
"statement in order to delete and/or modify this bank statement line"
msgstr ""
"Não é permitido excluir! Vá a linha do demonstrativo bancário associada para "
"excluir ou modificar esta linha do demonstrativo"
#. module: account_bank_statement_extensions
#: field:account.bank.statement.line.global,type:0
msgid "Type"
msgstr "Tipo"
#. module: account_bank_statement_extensions
#: view:account.bank.statement.line:0
#: field:account.bank.statement.line,journal_id:0
#: report:bank.statement.balance.report:0
msgid "Journal"
msgstr "Diário"
#. module: account_bank_statement_extensions
#: view:account.bank.statement.line:0
msgid "Confirmed Statement Lines."
msgstr "Linhas do Demonstrativo Confirmadas."
#. module: account_bank_statement_extensions
#: view:account.bank.statement.line:0
msgid "Credit Transactions."
msgstr "Transações de Crédito"
#. module: account_bank_statement_extensions
#: model:ir.actions.act_window,help:account_bank_statement_extensions.action_cancel_statement_line
msgid "cancel selected statement lines."
msgstr "cancelar linhas do demonstrativo selecionadas."
#. module: account_bank_statement_extensions
#: field:account.bank.statement.line,counterparty_number:0
msgid "Counterparty Number"
msgstr "Número da Contrapartida"
#. module: account_bank_statement_extensions
#: view:account.bank.statement.line.global:0
msgid "Transactions"
msgstr "Transações"
#. module: account_bank_statement_extensions
#: code:addons/account_bank_statement_extensions/account_bank_statement.py:130
#, python-format
msgid "Warning"
msgstr "Aviso"
#. module: account_bank_statement_extensions
#: report:bank.statement.balance.report:0
msgid "Closing Balance"
msgstr "Saldo final"
#. module: account_bank_statement_extensions
#: report:bank.statement.balance.report:0
msgid "Date"
msgstr "Data"
#. module: account_bank_statement_extensions
#: view:account.bank.statement.line:0
#: field:account.bank.statement.line,globalisation_amount:0
msgid "Glob. Amount"
msgstr "Valor Global"
#. module: account_bank_statement_extensions
#: view:account.bank.statement.line:0
msgid "Debit Transactions."
msgstr "Transações de Débito."
#. module: account_bank_statement_extensions
#: view:account.bank.statement.line:0
msgid "Extended Filters..."
msgstr "Filtros Extendidos..."
#. module: account_bank_statement_extensions
#: view:confirm.statement.line:0
msgid "Confirmed lines cannot be changed anymore."
msgstr "Linhas confirmadas não podem ser alteradas."
#. module: account_bank_statement_extensions
#: constraint:res.partner.bank:0
msgid ""
"\n"
"Please define BIC/Swift code on bank for bank type IBAN Account to make "
"valid payments"
msgstr ""
"\n"
"Por favor defina o BIC/Swift code no Banco para o tipo de conta IBAN para "
"fazer pagamentos válidos"
#. module: account_bank_statement_extensions
#: field:account.bank.statement.line,val_date:0
msgid "Valuta Date"
msgstr ""
#. module: account_bank_statement_extensions
#: model:ir.actions.act_window,help:account_bank_statement_extensions.action_confirm_statement_line
msgid "Confirm selected statement lines."
msgstr "Confirmar as linhas do demonstrativo."
#. module: account_bank_statement_extensions
#: view:cancel.statement.line:0
msgid "Are you sure you want to cancel the selected Bank Statement lines ?"
msgstr ""
"Você tem certeza de que deseja cancelar as Linhas de Demonstrativo Bancário "
"selecionadas?"
#. module: account_bank_statement_extensions
#: report:bank.statement.balance.report:0
msgid "Name"
msgstr "Nome"
#. module: account_bank_statement_extensions
#: selection:account.bank.statement.line.global,type:0
msgid "ISO 20022"
msgstr "ISO 20022"
#. module: account_bank_statement_extensions
#: view:account.bank.statement.line:0
msgid "Notes"
msgstr "Notas"
#. module: account_bank_statement_extensions
#: selection:account.bank.statement.line.global,type:0
msgid "Manual"
msgstr "Manual"
#. module: account_bank_statement_extensions
#: view:account.bank.statement.line:0
msgid "Credit"
msgstr "Crédito"
#. module: account_bank_statement_extensions
#: field:account.bank.statement.line.global,amount:0
msgid "Amount"
msgstr "Valor"
#. module: account_bank_statement_extensions
#: view:account.bank.statement.line:0
msgid "Fin.Account"
msgstr "Fin.Account"
#. module: account_bank_statement_extensions
#: field:account.bank.statement.line,counterparty_currency:0
msgid "Counterparty Currency"
msgstr "Moeda da Contrapartida"
#. module: account_bank_statement_extensions
#: field:account.bank.statement.line,counterparty_bic:0
msgid "Counterparty BIC"
msgstr "BIC da Contrapartida"
#. module: account_bank_statement_extensions
#: field:account.bank.statement.line.global,child_ids:0
msgid "Child Codes"
msgstr "Códigos derivados (sub-contas)"
#. module: account_bank_statement_extensions
#: view:confirm.statement.line:0
msgid "Are you sure you want to confirm the selected Bank Statement lines ?"
msgstr ""
"Você deseja confirmar as Linhas do Demonstrativo Bancário selecionadas?"
#. module: account_bank_statement_extensions
#: constraint:account.bank.statement.line:0
msgid ""
"The amount of the voucher must be the same amount as the one on the "
"statement line"
msgstr ""
"O valor do recibo deve ser o mesmo valor da linha equivalente no extrato"
#. module: account_bank_statement_extensions
#: help:account.bank.statement.line,globalisation_id:0
msgid ""
"Code to identify transactions belonging to the same globalisation level "
"within a batch payment"
msgstr ""
"Código para identificar transações que pertencem ao nível de globalização "
"dentro de um mesmo lote de pagamento"
#. module: account_bank_statement_extensions
#: view:account.bank.statement.line:0
msgid "Draft Statement Lines."
msgstr "Linhas de Demonstrativo Provisórias."
#. module: account_bank_statement_extensions
#: view:account.bank.statement.line:0
msgid "Glob. Am."
msgstr ""
#. module: account_bank_statement_extensions
#: model:ir.model,name:account_bank_statement_extensions.model_account_bank_statement_line
msgid "Bank Statement Line"
msgstr "Linha do Demonstrativo Bancário"
#. module: account_bank_statement_extensions
#: field:account.bank.statement.line.global,code:0
msgid "Code"
msgstr "Código"
#. module: account_bank_statement_extensions
#: field:account.bank.statement.line,counterparty_name:0
msgid "Counterparty Name"
msgstr "Nome da Contrapartida"
#. module: account_bank_statement_extensions
#: field:account.bank.statement.line.global,name:0
msgid "Communication"
msgstr "Comunicação"
#. module: account_bank_statement_extensions
#: model:ir.model,name:account_bank_statement_extensions.model_res_partner_bank
msgid "Bank Accounts"
msgstr "Contas Bancárias"
#. module: account_bank_statement_extensions
#: constraint:account.bank.statement:0
msgid "The journal and period chosen have to belong to the same company."
msgstr "O diário e o período escolhido tem que pertencer à mesma empresa."
#. module: account_bank_statement_extensions
#: model:ir.model,name:account_bank_statement_extensions.model_account_bank_statement
msgid "Bank Statement"
msgstr "Extrato Bancário"
#. module: account_bank_statement_extensions
#: view:account.bank.statement.line:0
msgid "Statement Line"
msgstr "Linha do Demonstrativo"
#. module: account_bank_statement_extensions
#: sql_constraint:account.bank.statement.line.global:0
msgid "The code must be unique !"
msgstr "O código precisa ser único!"
#. module: account_bank_statement_extensions
#: field:account.bank.statement.line.global,bank_statement_line_ids:0
#: model:ir.actions.act_window,name:account_bank_statement_extensions.action_bank_statement_line
#: model:ir.ui.menu,name:account_bank_statement_extensions.bank_statement_line
msgid "Bank Statement Lines"
msgstr "Linhas do Demonstrativo Bancário"
#. module: account_bank_statement_extensions
#: view:account.bank.statement.line.global:0
msgid "Child Batch Payments"
msgstr "Lote de Pagamentos Filho"
#. module: account_bank_statement_extensions
#: view:cancel.statement.line:0
#: view:confirm.statement.line:0
msgid "Cancel"
msgstr "Cancelar"
#. module: account_bank_statement_extensions
#: view:account.bank.statement.line:0
msgid "Statement Lines"
msgstr "Linhas do Demonstrativo"
#. module: account_bank_statement_extensions
#: view:account.bank.statement.line:0
msgid "Total Amount"
msgstr "Valor Total"
#. module: account_bank_statement_extensions
#: field:account.bank.statement.line,globalisation_id:0
msgid "Globalisation ID"
msgstr "ID Globalização"

View File

@ -0,0 +1,207 @@
# Spanish (Ecuador) translation for openobject-addons
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-08 00:35+0000\n"
"PO-Revision-Date: 2012-09-12 01:39+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Spanish (Ecuador) <es_EC@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-09-12 04:36+0000\n"
"X-Generator: Launchpad (build 15930)\n"
#. module: account_check_writing
#: selection:res.company,check_layout:0
msgid "Check on Top"
msgstr "Cheque on Top"
#. module: account_check_writing
#: model:ir.actions.act_window,help:account_check_writing.action_write_check
msgid ""
"The check payment form allows you to track the payment you do to your "
"suppliers specially by check. When you select a supplier, the payment method "
"and an amount for the payment, OpenERP will propose to reconcile your "
"payment with the open supplier invoices or bills.You can print the check"
msgstr ""
"El pago de cheques permite rastrear el pago a sus proveedores. Cuando "
"selecciona un proveedor, el método de pago y monto, OpenERP propondrá "
"conciliarlo con tu factura, y podrá imprimir el cheque."
#. module: account_check_writing
#: view:account.voucher:0
#: model:ir.actions.report.xml,name:account_check_writing.account_print_check_bottom
#: model:ir.actions.report.xml,name:account_check_writing.account_print_check_middle
#: model:ir.actions.report.xml,name:account_check_writing.account_print_check_top
msgid "Print Check"
msgstr "Imprimir Cheque"
#. module: account_check_writing
#: selection:res.company,check_layout:0
msgid "Check in middle"
msgstr "Cheque in middle"
#. module: account_check_writing
#: help:res.company,check_layout:0
msgid ""
"Check on top is compatible with Quicken, QuickBooks and Microsoft Money. "
"Check in middle is compatible with Peachtree, ACCPAC and DacEasy. Check on "
"bottom is compatible with Peachtree, ACCPAC and DacEasy only"
msgstr ""
#. module: account_check_writing
#: selection:res.company,check_layout:0
msgid "Check on bottom"
msgstr "Cheque on bottom"
#. module: account_check_writing
#: constraint:res.company:0
msgid "Error! You can not create recursive companies."
msgstr "Error! No puede crear compañías recursivas."
#. module: account_check_writing
#: help:account.journal,allow_check_writing:0
msgid "Check this if the journal is to be used for writing checks."
msgstr "Activar si este diario es usado para emitir cheques"
#. module: account_check_writing
#: field:account.journal,allow_check_writing:0
msgid "Allow Check writing"
msgstr "Permitir emisión de cheques"
#. module: account_check_writing
#: report:account.print.check.bottom:0
#: report:account.print.check.middle:0
#: report:account.print.check.top:0
msgid "Description"
msgstr "Descripción"
#. module: account_check_writing
#: model:ir.model,name:account_check_writing.model_account_journal
msgid "Journal"
msgstr "Diario"
#. module: account_check_writing
#: model:ir.actions.act_window,name:account_check_writing.action_write_check
#: model:ir.ui.menu,name:account_check_writing.menu_action_write_check
msgid "Write Checks"
msgstr "Escribir Cheque"
#. module: account_check_writing
#: report:account.print.check.bottom:0
#: report:account.print.check.middle:0
#: report:account.print.check.top:0
msgid "Discount"
msgstr "Descuento"
#. module: account_check_writing
#: report:account.print.check.bottom:0
#: report:account.print.check.middle:0
#: report:account.print.check.top:0
msgid "Original Amount"
msgstr "Monto Inicial"
#. module: account_check_writing
#: view:res.company:0
msgid "Configuration"
msgstr "Configuración"
#. module: account_check_writing
#: field:account.voucher,allow_check:0
msgid "Allow Check Writing"
msgstr "Permitir Emisión de Cheques"
#. module: account_check_writing
#: report:account.print.check.bottom:0
#: report:account.print.check.middle:0
#: report:account.print.check.top:0
msgid "Payment"
msgstr "Pagos"
#. module: account_check_writing
#: field:account.journal,use_preprint_check:0
msgid "Use Preprinted Check"
msgstr "Usar cheque preimpreso"
#. module: account_check_writing
#: sql_constraint:res.company:0
msgid "The company name must be unique !"
msgstr "¡El nombre de la compañía debe ser único!"
#. module: account_check_writing
#: report:account.print.check.bottom:0
#: report:account.print.check.middle:0
#: report:account.print.check.top:0
msgid "Due Date"
msgstr "Fecha de vencimiento"
#. module: account_check_writing
#: model:ir.model,name:account_check_writing.model_res_company
msgid "Companies"
msgstr "Compañias"
#. module: account_check_writing
#: view:res.company:0
msgid "Default Check Layout"
msgstr ""
#. module: account_check_writing
#: constraint:account.journal:0
msgid ""
"Configuration error! The currency chosen should be shared by the default "
"accounts too."
msgstr ""
"Error de Configuración! La moneda seleccionada debe ser compartida por las "
"cuentas por defecto tambíen"
#. module: account_check_writing
#: report:account.print.check.bottom:0
#: report:account.print.check.middle:0
msgid "Balance Due"
msgstr "Saldo Deudor"
#. module: account_check_writing
#: report:account.print.check.bottom:0
#: report:account.print.check.middle:0
#: report:account.print.check.top:0
msgid "Check Amount"
msgstr "Monto Cheque"
#. module: account_check_writing
#: model:ir.model,name:account_check_writing.model_account_voucher
msgid "Accounting Voucher"
msgstr "Comprobantes de Pago"
#. module: account_check_writing
#: sql_constraint:account.journal:0
msgid "The name of the journal must be unique per company !"
msgstr "El nombre del diaro debe ser único por compañía !"
#. module: account_check_writing
#: sql_constraint:account.journal:0
msgid "The code of the journal must be unique per company !"
msgstr "El código del diario debe ser único por compañía !"
#. module: account_check_writing
#: field:account.voucher,amount_in_word:0
msgid "Amount in Word"
msgstr "Monto en Letras"
#. module: account_check_writing
#: report:account.print.check.top:0
msgid "Open Balance"
msgstr "Saldo Inicial"
#. module: account_check_writing
#: field:res.company,check_layout:0
msgid "Choose Check layout"
msgstr "Elegir diseño de cheque"
#~ msgid "Default Check layout"
#~ msgstr "Diseño de cheque por defecto"

View File

@ -16,11 +16,11 @@
<filter string="Info" domain="[('state','=','info')]" icon="terp-folder-yellow"/>
<field name="bank_id"/>
<field name="journal"/>
<field name="currency"/>
<field name="currency" groups="base.group_multi_currency"/>
<field name="company_id" groups="base.group_multi_company"/>
<group expand="0" string="Group By...">
<filter string="Bank Account" icon="terp-folder-yellow" domain="[]" context="{'group_by':'bank_id'}"/>
<filter string="Currency" icon="terp-dolar" domain="[]" context="{'group_by':'currency'}"/>
<filter string="Currency" icon="terp-dolar" domain="[]" context="{'group_by':'currency'}" groups="base.group_multi_currency"/>
</group>
</search>
</field>
@ -32,7 +32,7 @@
<tree string="CODA Bank Account Configuration">
<field name="name"/>
<field name="bank_id"/>
<field name="currency"/>
<field name="currency" groups="base.group_multi_currency"/>
<field name="description1"/>
<field name="journal"/>
<field name="state"/>
@ -48,7 +48,7 @@
<field name="name" colspan="4"/>
<field name="bank_id" domain="[('partner_id.ref_companies', 'in', [company_id])]"/>
<field name="description1"/>
<field name="currency"/>
<field name="currency" groups="base.group_multi_currency"/>
<field name="description2"/>
<field name="coda_st_naming"/>
<field name="state" on_change="onchange_state(state)"/>
@ -305,7 +305,7 @@
<field name="name"/>
<field name="date"/>
<field name="coda_bank_account_id"/>
<field name="currency"/>
<field name="currency" groups="base.group_multi_currency"/>
<field name="period_id"/>
<field name="type"/>
<newline/>

View File

@ -30,8 +30,8 @@
<field name="debit" sum="Total debit"/>
<field name="credit" sum="Total credit"/>
<field name="amount_to_pay"/>
<field name="amount_currency"/>
<field name="currency_id"/>
<field name="amount_currency" groups="base.group_multi_currency"/>
<field name="currency_id" groups="base.group_multi_currency"/>
<field name="period_id" invisible="1"/>
</tree>
</field>
@ -131,8 +131,8 @@
<field name="move_line_id" on_change="onchange_move_line(move_line_id,parent.mode,parent.date_prefered,parent.date_scheduled,currency,company_currency)" domain="[('reconcile_id','=', False), ('credit', '>',0),('amount_to_pay','>',0)] "/>
<separator colspan="4" string="Transaction Information"/>
<field name="date"/>
<label for="amount_currency"/>
<div>
<label for="amount_currency" groups="base.group_multi_currency"/>
<div groups="base.group_multi_currency">
<field name="amount_currency" on_change="onchange_amount(amount_currency,currency,company_currency)" class="oe_inline"/>
<field name="currency" nolabel="1" class="oe_inline"/>
</div>
@ -151,8 +151,8 @@
</page>
<page string="Information">
<group col="4" string="General Information">
<label for="amount"/>
<div>
<label for="amount" groups="base.group_multi_currency"/>
<div groups="base.group_multi_currency">
<field name="amount" class="oe_inline"/>
<field name="company_currency" class="oe_inline"/>
</div>
@ -171,8 +171,8 @@
<field name="bank_id" domain="[('partner_id', '=', partner_id)]"/>
<field name="ml_maturity_date"/>
<field name="date"/>
<field name="amount_currency" string="Amount"/>
<field name="currency"/>
<field name="amount_currency" string="Amount" groups="base.group_multi_currency"/>
<field name="currency" groups="base.group_multi_currency"/>
<field name="name"/>
<field name="amount" sum="Total in Company Currency" invisible="1"/>
</tree>
@ -257,8 +257,8 @@
<field name="move_line_id" on_change="onchange_move_line(move_line_id, False, currency, company_currency)" domain="[('reconcile_id','=', False), ('credit', '>',0),('amount_to_pay','>',0)]"/>
<separator colspan="4" string="Transaction Information"/>
<field name="date"/>
<label for="amount_currency"/>
<div>
<label for="amount_currency" groups="base.group_multi_currency"/>
<div groups="base.group_multi_currency">
<field name="amount_currency" on_change="onchange_amount(amount_currency,currency,company_currency)" class="oe_inline"/>
<field name="currency" class="oe_inline"/>
</div>
@ -277,8 +277,11 @@
</page>
<page string="Information">
<group col="4" string="General Information">
<field name="amount"/>
<field name="company_currency" nolabel="1"/>
<label for="amoun"/>
<div>
<field name="amount" class="oe_inline"/>
<field name="company_currency" class="oe_inline"/>
</div>
</group>
<group col="4" string="Entry Information">
<field name="create_date"/>
@ -302,8 +305,8 @@
<field name="partner_id"/>
<field name="communication"/>
<field name="amount" sum="Amount Total"/>
<field name="amount_currency" sum="Currency Amount Total"/>
<field name="currency"/>
<field name="amount_currency" sum="Currency Amount Total" groups="base.group_multi_currency"/>
<field name="currency" groups="base.group_multi_currency"/>
<field name="bank_id" domain="[('partner_id', '=', partner_id)]"/>
<field name="move_line_id" on_change="onchange_move_line(move_line_id,parent.mode)"/>
<field name="create_date"/>

View File

@ -75,7 +75,7 @@
</group>
<group string="Other Information">
<field name="number"/>
<field name="currency_id"/>
<field name="currency_id" groups="base.group_multi_currency"/>
</group>
<group col="4" attrs="{'invisible':[('type','in',['payment', 'receipt', False])]}">
<separator string="Total" colspan="4"/>

View File

@ -102,9 +102,9 @@
<field name="narration" nolabel="1" colspan="2"/>
</group>
<group string="Other Information" col="4">
<field name="currency_id" colspan="4"/>
<field name="currency_id" colspan="4" groups="base.group_multi_currency"/>
<field name="payment_rate" required="1" on_change="onchange_rate(payment_rate, amount, currency_id, payment_rate_currency_id, company_id, context)" colspan="3"/>
<field name="payment_rate_currency_id" colspan="1" nolabel="1" on_change="onchange_payment_rate_currency(currency_id, payment_rate, payment_rate_currency_id, date, amount, company_id, context)"/>
<field name="payment_rate_currency_id" colspan="1" nolabel="1" on_change="onchange_payment_rate_currency(currency_id, payment_rate, payment_rate_currency_id, date, amount, company_id, context)" groups="base.group_multi_currency"/>
<field name="paid_amount_in_company_currency" colspan="4" invisible="1"/>
<field name="number" colspan="4"/>
</group>
@ -194,7 +194,7 @@
<separator string="Currency Options" colspan="4"/>
<field name="is_multi_currency" invisible="1"/>
<field name="payment_rate" required="1" on_change="onchange_rate(payment_rate, amount, currency_id, payment_rate_currency_id, company_id, context)" colspan="3"/>
<field name="payment_rate_currency_id" colspan="1" nolabel="1" on_change="onchange_payment_rate_currency(currency_id, payment_rate, payment_rate_currency_id, date, amount, company_id, context)"/>
<field name="payment_rate_currency_id" colspan="1" nolabel="1" on_change="onchange_payment_rate_currency(currency_id, payment_rate, payment_rate_currency_id, date, amount, company_id, context)" groups="base.group_multi_currency"/>
<field name="paid_amount_in_company_currency" colspan="4" invisible="1"/>
</group>
<group col="2">
@ -231,8 +231,8 @@
<field name="credit"/>
<field name="state"/>
<field name="reconcile_id"/>
<field name="amount_currency"/>
<field name="currency_id"/>
<field name="amount_currency" groups="base.group_multi_currency"/>
<field name="currency_id" groups="base.group_multi_currency"/>
</tree>
</field>
</page>
@ -366,7 +366,7 @@
<group col="4" attrs="{'invisible':[('currency_id','=',False),('is_multi_currency','=',False)]}">
<field name="is_multi_currency" invisible="1"/>
<field name="payment_rate" required="1" on_change="onchange_rate(payment_rate, amount, currency_id, payment_rate_currency_id, company_id, context)" colspan="3"/>
<field name="payment_rate_currency_id" colspan="1" nolabel="1" on_change="onchange_payment_rate_currency(currency_id, payment_rate, payment_rate_currency_id, date, amount, company_id, context)"/>
<field name="payment_rate_currency_id" colspan="1" nolabel="1" on_change="onchange_payment_rate_currency(currency_id, payment_rate, payment_rate_currency_id, date, amount, company_id, context)" groups="base.group_multi_currency"/>
<field name="paid_amount_in_company_currency" colspan="4" invisible="1"/>
</group>
<group>
@ -401,7 +401,7 @@
<field name="state"/>
<field name="reconcile_id"/>
<field name="amount_currency"/>
<field name="currency_id"/>
<field name="currency_id" groups="base.group_multi_currency"/>
</tree>
</field>
</page>

View File

@ -0,0 +1,3 @@
import controllers
import models
import test_models

View File

@ -0,0 +1,39 @@
{
'name': 'Base import',
'description': """
New extensible file import for OpenERP
======================================
Re-implement openerp's file import system:
* Server side, the previous system forces most of the logic into the
client which duplicates the effort (between clients), makes the
import system much harder to use without a client (direct RPC or
other forms of automation) and makes knowledge about the
import/export system much harder to gather as it is spread over
3+ different projects.
* In a more extensible manner, so users and partners can build their
own front-end to import from other file formats (e.g. OpenDocument
files) which may be simpler to handle in their work flow or from
their data production sources.
* In a module, so that administrators and users of OpenERP who do not
need or want an online import can avoid it being available to users.
""",
'category': 'Uncategorized',
'website': 'http://www.openerp.com',
'author': 'OpenERP SA',
'depends': ['base'],
'installable': True,
'auto_install': False, # set to true and allow uninstall?
'css': [
'static/lib/select2/select2.css',
'static/src/css/import.css',
],
'js': [
'static/lib/select2/select2.js',
'static/src/js/import.js',
],
'qweb': ['static/src/xml/import.xml'],
}

View File

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
import simplejson
try:
import openerp.addons.web.common.http as openerpweb
except ImportError:
import web.common.http as openerpweb
class ImportController(openerpweb.Controller):
_cp_path = '/base_import'
@openerpweb.httprequest
def set_file(self, req, file, import_id, jsonp='callback'):
import_id = int(import_id)
written = req.session.model('base_import.import').write(import_id, {
'file': file.read(),
'file_name': file.filename,
'file_type': file.content_type,
}, req.session.eval_context(req.context))
return 'window.top.%s(%s)' % (
jsonp, simplejson.dumps({'result': written}))

View File

@ -0,0 +1,352 @@
import csv
import itertools
import logging
import operator
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
import psycopg2
from openerp.osv import orm, fields
from openerp.tools.translate import _
FIELDS_RECURSION_LIMIT = 2
ERROR_PREVIEW_BYTES = 200
_logger = logging.getLogger(__name__)
class ir_import(orm.TransientModel):
_name = 'base_import.import'
# allow imports to survive for 12h in case user is slow
_transient_max_hours = 12.0
_columns = {
'res_model': fields.char('Model', size=64),
'file': fields.binary(
'File', help="File to check and/or import, raw binary (not base64)"),
'file_name': fields.char('File Name', size=None),
'file_type': fields.char('File Type', size=None),
}
def get_fields(self, cr, uid, model, context=None,
depth=FIELDS_RECURSION_LIMIT):
""" Recursively get fields for the provided model (through
fields_get) and filter them according to importability
The output format is a list of ``Field``, with ``Field``
defined as:
.. class:: Field
.. attribute:: id (str)
A non-unique identifier for the field, used to compute
the span of the ``required`` attribute: if multiple
``required`` fields have the same id, only one of them
is necessary.
.. attribute:: name (str)
The field's logical (OpenERP) name within the scope of
its parent.
.. attribute:: string (str)
The field's human-readable name (``@string``)
.. attribute:: required (bool)
Whether the field is marked as required in the
model. Clients must provide non-empty import values
for all required fields or the import will error out.
.. attribute:: fields (list(Field))
The current field's subfields. The database and
external identifiers for m2o and m2m fields; a
filtered and transformed fields_get for o2m fields (to
a variable depth defined by ``depth``).
Fields with no sub-fields will have an empty list of
sub-fields.
:param str model: name of the model to get fields form
:param int landing: depth of recursion into o2m fields
"""
fields = [{
'id': 'id',
'name': 'id',
'string': _("External ID"),
'required': False,
'fields': [],
}]
fields_got = self.pool[model].fields_get(cr, uid, context=context)
for name, field in fields_got.iteritems():
if field.get('readonly'):
states = field.get('states')
if not states:
continue
# states = {state: [(attr, value), (attr2, value2)], state2:...}
if not any(attr == 'readonly' and value is False
for attr, value in itertools.chain.from_iterable(
states.itervalues())):
continue
f = {
'id': name,
'name': name,
'string': field['string'],
# Y U NO ALWAYS HAVE REQUIRED
'required': bool(field.get('required')),
'fields': [],
}
if field['type'] in ('many2many', 'many2one'):
f['fields'] = [
dict(f, name='id', string=_("External ID")),
dict(f, name='.id', string=_("Database ID")),
]
elif field['type'] == 'one2many' and depth:
f['fields'] = self.get_fields(
cr, uid, field['relation'], context=context, depth=depth-1)
fields.append(f)
# TODO: cache on model?
return fields
def _read_csv(self, record, options):
""" Returns a CSV-parsed iterator of all empty lines in the file
:throws csv.Error: if an error is detected during CSV parsing
:throws UnicodeDecodeError: if ``options.encoding`` is incorrect
"""
csv_iterator = csv.reader(
StringIO(record.file),
quotechar=options['quoting'],
delimiter=options['separator'])
csv_nonempty = itertools.ifilter(None, csv_iterator)
# TODO: guess encoding with chardet? Or https://github.com/aadsm/jschardet
encoding = options.get('encoding', 'utf-8')
return itertools.imap(
lambda row: [item.decode(encoding) for item in row],
csv_nonempty)
def _match_header(self, header, fields, options):
""" Attempts to match a given header to a field of the
imported model.
:param str header: header name from the CSV file
:param fields:
:param dict options:
:returns: an empty list if the header couldn't be matched, or
all the fields to traverse
:rtype: list(Field)
"""
for field in fields:
# FIXME: should match all translations & original
# TODO: use string distance (levenshtein? hamming?)
if header == field['name'] \
or header.lower() == field['string'].lower():
return [field]
if '/' not in header:
return []
# relational field path
traversal = []
subfields = fields
# Iteratively dive into fields tree
for section in header.split('/'):
# Strip section in case spaces are added around '/' for
# readability of paths
match = self._match_header(section.strip(), subfields, options)
# Any match failure, exit
if not match: return []
# prep subfields for next iteration within match[0]
field = match[0]
subfields = field['fields']
traversal.append(field)
return traversal
def _match_headers(self, rows, fields, options):
""" Attempts to match the imported model's fields to the
titles of the parsed CSV file, if the file is supposed to have
headers.
Will consume the first line of the ``rows`` iterator.
Returns a pair of (None, None) if headers were not requested
or the list of headers and a dict mapping cell indices
to key paths in the ``fields`` tree
:param Iterator rows:
:param dict fields:
:param dict options:
:rtype: (None, None) | (list(str), dict(int: list(str)))
"""
if not options.get('headers'):
return None, None
headers = next(rows)
return headers, dict(
(index, [field['name'] for field in self._match_header(header, fields, options)] or None)
for index, header in enumerate(headers)
)
def parse_preview(self, cr, uid, id, options, count=10, context=None):
""" Generates a preview of the uploaded files, and performs
fields-matching between the import's file data and the model's
columns.
If the headers are not requested (not options.headers),
``matches`` and ``headers`` are both ``False``.
:param id: identifier of the import
:param int count: number of preview lines to generate
:param options: format-specific options.
CSV: {encoding, quoting, separator, headers}
:type options: {str, str, str, bool}
:returns: {fields, matches, headers, preview} | {error, preview}
:rtype: {dict(str: dict(...)), dict(int, list(str)), list(str), list(list(str))} | {str, str}
"""
(record,) = self.browse(cr, uid, [id], context=context)
fields = self.get_fields(cr, uid, record.res_model, context=context)
try:
rows = self._read_csv(record, options)
headers, matches = self._match_headers(rows, fields, options)
# Match should have consumed the first row (iif headers), get
# the ``count`` next rows for preview
preview = itertools.islice(rows, count)
return {
'fields': fields,
'matches': matches or False,
'headers': headers or False,
'preview': list(preview),
}
except Exception, e:
# Due to lazy generators, UnicodeDecodeError (for
# instance) may only be raised when serializing the
# preview to a list in the return.
_logger.debug("Error during CSV parsing preview", exc_info=True)
return {
'error': str(e),
# iso-8859-1 ensures decoding will always succeed,
# even if it yields non-printable characters. This is
# in case of UnicodeDecodeError (or csv.Error
# compounded with UnicodeDecodeError)
'preview': record.file[:ERROR_PREVIEW_BYTES]
.decode( 'iso-8859-1'),
}
def _convert_import_data(self, record, fields, options, context=None):
""" Extracts the input browse_record and fields list (with
``False``-y placeholders for fields to *not* import) into a
format Model.import_data can use: a fields list without holes
and the precisely matching data matrix
:param browse_record record:
:param list(str|bool): fields
:returns: (data, fields)
:rtype: (list(list(str)), list(str))
:raises ValueError: in case the import data could not be converted
"""
# Get indices for non-empty fields
indices = [index for index, field in enumerate(fields) if field]
if not indices:
raise ValueError(_("You must configure at least one field to import"))
# If only one index, itemgetter will return an atom rather
# than a 1-tuple
if len(indices) == 1: mapper = lambda row: [row[indices[0]]]
else: mapper = operator.itemgetter(*indices)
# Get only list of actually imported fields
import_fields = filter(None, fields)
rows_to_import = self._read_csv(record, options)
if options.get('headers'):
rows_to_import = itertools.islice(
rows_to_import, 1, None)
data = [
row for row in itertools.imap(mapper, rows_to_import)
# don't try inserting completely empty rows (e.g. from
# filtering out o2m fields)
if any(row)
]
return data, import_fields
def do(self, cr, uid, id, fields, options, dryrun=False, context=None):
""" Actual execution of the import
:param fields: import mapping: maps each column to a field,
``False`` for the columns to ignore
:type fields: list(str|bool)
:param dict options:
:param bool dryrun: performs all import operations (and
validations) but rollbacks writes, allows
getting as much errors as possible without
the risk of clobbering the database.
:returns: A list of errors. If the list is empty the import
executed fully and correctly. If the list is
non-empty it contains dicts with 3 keys ``type`` the
type of error (``error|warning``); ``message`` the
error message associated with the error (a string)
and ``record`` the data which failed to import (or
``false`` if that data isn't available or provided)
:rtype: list({type, message, record})
"""
cr.execute('SAVEPOINT import')
(record,) = self.browse(cr, uid, [id], context=context)
try:
data, import_fields = self._convert_import_data(
record, fields, options, context=context)
except ValueError, e:
return [{
'type': 'error',
'message': str(e),
'record': False,
}]
try:
_logger.info('importing %d rows...', len(data))
(code, record, message, _wat) = self.pool[record.res_model].import_data(
cr, uid, import_fields, data, context=context)
_logger.info('done')
except Exception, e:
_logger.exception("Import failed")
# TODO: remove when exceptions stop being an "expected"
# behavior of import_data on some (most) invalid
# input.
code, record, message = -1, None, str(e)
# If transaction aborted, RELEASE SAVEPOINT is going to raise
# an InternalError (ROLLBACK should work, maybe). Ignore that.
# TODO: to handle multiple errors, create savepoint around
# write and release it in case of write error (after
# adding error to errors array) => can keep on trying to
# import stuff, and rollback at the end if there is any
# error in the results.
try:
if dryrun:
cr.execute('ROLLBACK TO SAVEPOINT import')
else:
cr.execute('RELEASE SAVEPOINT import')
except psycopg2.InternalError:
pass
if code != -1:
return []
# TODO: add key for error location?
# TODO: error not within normal preview, how to display? Re-preview
# with higher ``count``?
return [{
'type': 'error',
'message': message,
'record': record or False
}]

View File

@ -0,0 +1,12 @@
Copyright 2012 Igor Vaynberg
Version: @@ver@@ Timestamp: @@timestamp@@
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in
compliance with the License. You may obtain a copy of the License in the LICENSE file, or at:
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is
distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.

View File

@ -0,0 +1,68 @@
Select2
=================
Select2 is a jQuery based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results. Look and feel of Select2 is based on the excellent [Chosen](http://harvesthq.github.com/chosen/) library.
To get started -- checkout http://ivaynberg.github.com/select2!
What Does Select2 Support That Chosen Does Not?
-------------------------------------------------
* Working with large datasets: Chosen requires the entire dataset to be loaded as `option` tags in the DOM, which limits
it to working with small-ish datasets. Select2 uses a function to find results on-the-fly, which allows it to partially
load results.
* Paging of results: Since Select2 works with large datasets and only loads a small amount of matching results at a time
it has to support paging. Select2 will call the search function when the user scrolls to the bottom of currently loaded
result set allowing for the 'infinite scrolling' of results.
* Custom markup for results: Chosen only supports rendering text results because that is the only markup supported by
`option` tags. Select2 provides an extension point which can be used to produce any kind of markup to represent results.
* Ability to add results on the fly: Select2 provides the ability to add results from the search term entered by the user, which allows it to be used for
tagging.
Browser Compatibility
--------------------
* IE 8+ (7 mostly works except for [issue with z-index](https://github.com/ivaynberg/select2/issues/37))
* Chrome 8+
* Firefox 3.5+
* Safari 3+
* Opera 10.6+
Integrations
------------
* [Wicket-Select2](https://github.com/ivaynberg/wicket-select2) (Java / Apache Wicket)
* [select2-rails](https://github.com/argerim/select2-rails) (Ruby on Rails)
* [AngularUI](http://angular-ui.github.com/#directives-select2) ([AngularJS](angularjs.org))
* [Django](https://github.com/applegrew/django-select2)
Bug tracker
-----------
Have a bug? Please create an issue here on GitHub!
https://github.com/ivaynberg/select2/issues
Mailing list
------------
Have a question? Ask on our mailing list!
select2@googlegroups.com
https://groups.google.com/d/forum/select2
Copyright and License
---------------------
Copyright 2012 Igor Vaynberg
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in
compliance with the License. You may obtain a copy of the License in the LICENSE file, or at:
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is
distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.

View File

@ -0,0 +1,77 @@
#!/bin/bash
set -e
echo -n "Enter the version for this release: "
read ver
if [ ! $ver ]; then
echo "Invalid version."
exit
fi
name="select2"
js="$name.js"
mini="$name.min.js"
css="$name.css"
release="$name-$ver"
releasedir="/tmp/$release"
tag="release-$ver"
branch="build-$ver"
curbranch=`git branch | grep "*" | sed "s/* //"`
timestamp=$(date)
tokens="s/@@ver@@/$ver/g;s/\@@timestamp@@/$timestamp/g"
remote="github"
git branch "$branch"
git checkout "$branch"
echo "Tokenizing..."
find . -name "$js" | xargs sed -i -e "$tokens"
find . -name "$css" | xargs sed -i -e "$tokens"
git add "$js"
git add "$css"
echo "Minifying..."
echo "/*" > "$mini"
cat LICENSE | sed "$tokens" >> "$mini"
echo "*/" >> "$mini"
curl -s \
-d compilation_level=SIMPLE_OPTIMIZATIONS \
-d output_format=text \
-d output_info=compiled_code \
--data-urlencode "js_code@$js" \
http://closure-compiler.appspot.com/compile \
>> "$mini"
git add "$mini"
git commit -m "release $ver"
echo "Tagging..."
git tag -a "$tag" -m "tagged version $ver"
git push "$remote" --tags
echo "Archiving..."
rm -rf "$releasedir"
mkdir "$releasedir"
cp $name.* "$releasedir"
cp spinner.gif "$releasedir"
cp README.* "$releasedir"
zip -r "$releasedir.zip" "$releasedir"
rm -rf "$releasedir"
echo "Cleaning Up..."
git checkout "$curbranch"
git branch -D "$branch"
echo "Done. Release archive created: $releasedir.zip"

View File

@ -0,0 +1,524 @@
/*
Version: @@ver@@ Timestamp: @@timestamp@@
*/
.select2-container {
position: relative;
display: inline-block;
/* inline-block for ie7 */
zoom: 1;
*display: inline;
vertical-align: top;
}
.select2-container,
.select2-drop,
.select2-search,
.select2-search input{
/*
Force border-box so that % widths fit the parent
container without overlap because of margin/padding.
More Info : http://www.quirksmode.org/css/box.html
*/
-moz-box-sizing: border-box; /* firefox */
-ms-box-sizing: border-box; /* ie */
-webkit-box-sizing: border-box; /* webkit */
-khtml-box-sizing: border-box; /* konqueror */
box-sizing: border-box; /* css3 */
}
.select2-container .select2-choice {
background-color: #fff;
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.5, white));
background-image: -webkit-linear-gradient(center bottom, #eeeeee 0%, white 50%);
background-image: -moz-linear-gradient(center bottom, #eeeeee 0%, white 50%);
background-image: -o-linear-gradient(bottom, #eeeeee 0%, #ffffff 50%);
background-image: -ms-linear-gradient(top, #eeeeee 0%, #ffffff 50%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#eeeeee', endColorstr = '#ffffff', GradientType = 0);
background-image: linear-gradient(top, #eeeeee 0%, #ffffff 50%);
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
-moz-background-clip: padding;
-webkit-background-clip: padding-box;
background-clip: padding-box;
border: 1px solid #aaa;
display: block;
overflow: hidden;
white-space: nowrap;
position: relative;
height: 26px;
line-height: 26px;
padding: 0 0 0 8px;
color: #444;
text-decoration: none;
}
.select2-container.select2-drop-above .select2-choice
{
border-bottom-color: #aaa;
-webkit-border-radius:0px 0px 4px 4px;
-moz-border-radius:0px 0px 4px 4px;
border-radius:0px 0px 4px 4px;
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.9, white));
background-image: -webkit-linear-gradient(center bottom, #eeeeee 0%, white 90%);
background-image: -moz-linear-gradient(center bottom, #eeeeee 0%, white 90%);
background-image: -o-linear-gradient(bottom, #eeeeee 0%, white 90%);
background-image: -ms-linear-gradient(top, #eeeeee 0%,#ffffff 90%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#ffffff',GradientType=0 );
background-image: linear-gradient(top, #eeeeee 0%,#ffffff 90%);
}
.select2-container .select2-choice span {
margin-right: 26px;
display: block;
overflow: hidden;
white-space: nowrap;
-o-text-overflow: ellipsis;
-ms-text-overflow: ellipsis;
text-overflow: ellipsis;
}
.select2-container .select2-choice abbr {
display: block;
position: absolute;
right: 26px;
top: 8px;
width: 12px;
height: 12px;
font-size: 1px;
background: url('select2.png') right top no-repeat;
cursor: pointer;
text-decoration: none;
border:0;
outline: 0;
}
.select2-container .select2-choice abbr:hover {
background-position: right -11px;
cursor: pointer;
}
.select2-drop {
background: #fff;
color: #000;
border: 1px solid #aaa;
border-top: 0;
position: absolute;
top: 100%;
-webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
-moz-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
-o-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
z-index: 9999;
width:100%;
margin-top:-1px;
-webkit-border-radius: 0 0 4px 4px;
-moz-border-radius: 0 0 4px 4px;
border-radius: 0 0 4px 4px;
}
.select2-drop.select2-drop-above {
-webkit-border-radius: 4px 4px 0px 0px;
-moz-border-radius: 4px 4px 0px 0px;
border-radius: 4px 4px 0px 0px;
margin-top:1px;
border-top: 1px solid #aaa;
border-bottom: 0;
-webkit-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
-moz-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
-o-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
}
.select2-container .select2-choice div {
-webkit-border-radius: 0 4px 4px 0;
-moz-border-radius: 0 4px 4px 0;
border-radius: 0 4px 4px 0;
-moz-background-clip: padding;
-webkit-background-clip: padding-box;
background-clip: padding-box;
background: #ccc;
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee));
background-image: -webkit-linear-gradient(center bottom, #ccc 0%, #eee 60%);
background-image: -moz-linear-gradient(center bottom, #ccc 0%, #eee 60%);
background-image: -o-linear-gradient(bottom, #ccc 0%, #eee 60%);
background-image: -ms-linear-gradient(top, #cccccc 0%, #eeeeee 60%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#cccccc', endColorstr = '#eeeeee', GradientType = 0);
background-image: linear-gradient(top, #cccccc 0%, #eeeeee 60%);
border-left: 1px solid #aaa;
position: absolute;
right: 0;
top: 0;
display: block;
height: 100%;
width: 18px;
}
.select2-container .select2-choice div b {
background: url('select2.png') no-repeat 0 1px;
display: block;
width: 100%;
height: 100%;
}
.select2-search {
display: inline-block;
white-space: nowrap;
z-index: 10000;
min-height: 26px;
width: 100%;
margin: 0;
padding-left: 4px;
padding-right: 4px;
}
.select2-search-hidden {
display: block;
position: absolute;
left: -10000px;
}
.select2-search input {
background: #fff url('select2.png') no-repeat 100% -22px;
background: url('select2.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));
background: url('select2.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);
background: url('select2.png') no-repeat 100% -22px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%);
background: url('select2.png') no-repeat 100% -22px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
background: url('select2.png') no-repeat 100% -22px, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%);
background: url('select2.png') no-repeat 100% -22px, linear-gradient(top, #ffffff 85%, #eeeeee 99%);
padding: 4px 20px 4px 5px;
outline: 0;
border: 1px solid #aaa;
font-family: sans-serif;
font-size: 1em;
width:100%;
margin:0;
height:auto !important;
min-height: 26px;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
border-radius: 0;
-moz-border-radius: 0;
-webkit-border-radius: 0;
}
.select2-drop.select2-drop-above .select2-search input
{
margin-top:4px;
}
.select2-search input.select2-active {
background: #fff url('spinner.gif') no-repeat 100%;
background: url('spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));
background: url('spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);
background: url('spinner.gif') no-repeat 100%, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%);
background: url('spinner.gif') no-repeat 100%, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
background: url('spinner.gif') no-repeat 100%, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%);
background: url('spinner.gif') no-repeat 100%, linear-gradient(top, #ffffff 85%, #eeeeee 99%);
}
.select2-container-active .select2-choice,
.select2-container-active .select2-choices {
-webkit-box-shadow: 0 0 5px rgba(0,0,0,.3);
-moz-box-shadow : 0 0 5px rgba(0,0,0,.3);
-o-box-shadow : 0 0 5px rgba(0,0,0,.3);
box-shadow : 0 0 5px rgba(0,0,0,.3);
border: 1px solid #5897fb;
outline: none;
}
.select2-dropdown-open .select2-choice {
border: 1px solid #aaa;
border-bottom-color: transparent;
-webkit-box-shadow: 0 1px 0 #fff inset;
-moz-box-shadow : 0 1px 0 #fff inset;
-o-box-shadow : 0 1px 0 #fff inset;
box-shadow : 0 1px 0 #fff inset;
background-color: #eee;
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, white), color-stop(0.5, #eeeeee));
background-image: -webkit-linear-gradient(center bottom, white 0%, #eeeeee 50%);
background-image: -moz-linear-gradient(center bottom, white 0%, #eeeeee 50%);
background-image: -o-linear-gradient(bottom, white 0%, #eeeeee 50%);
background-image: -ms-linear-gradient(top, #ffffff 0%,#eeeeee 50%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eeeeee',GradientType=0 );
background-image: linear-gradient(top, #ffffff 0%,#eeeeee 50%);
-webkit-border-bottom-left-radius : 0;
-webkit-border-bottom-right-radius: 0;
-moz-border-radius-bottomleft : 0;
-moz-border-radius-bottomright: 0;
border-bottom-left-radius : 0;
border-bottom-right-radius: 0;
}
.select2-dropdown-open .select2-choice div {
background: transparent;
border-left: none;
}
.select2-dropdown-open .select2-choice div b {
background-position: -18px 1px;
}
/* results */
.select2-results {
margin: 4px 4px 4px 0;
padding: 0 0 0 4px;
position: relative;
overflow-x: hidden;
overflow-y: auto;
max-height: 200px;
}
.select2-results ul.select2-result-sub {
margin: 0 0 0 0;
}
.select2-results ul.select2-result-sub > li .select2-result-label { padding-left: 20px }
.select2-results ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 40px }
.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 60px }
.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 80px }
.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 100px }
.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 110px }
.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 120px }
.select2-results li {
list-style: none;
display: list-item;
}
.select2-results li.select2-result-with-children > .select2-result-label {
font-weight: bold;
}
.select2-results .select2-result-label {
padding: 3px 7px 4px;
margin: 0;
cursor: pointer;
}
.select2-results .select2-highlighted {
background: #3875d7;
color: #fff;
}
.select2-results li em {
background: #feffde;
font-style: normal;
}
.select2-results .select2-highlighted em {
background: transparent;
}
.select2-results .select2-no-results,
.select2-results .select2-searching,
.select2-results .select2-selection-limit {
background: #f4f4f4;
display: list-item;
}
/*
disabled look for already selected choices in the results dropdown
.select2-results .select2-disabled.select2-highlighted {
color: #666;
background: #f4f4f4;
display: list-item;
cursor: default;
}
.select2-results .select2-disabled {
background: #f4f4f4;
display: list-item;
cursor: default;
}
*/
.select2-results .select2-disabled {
display: none;
}
.select2-more-results.select2-active {
background: #f4f4f4 url('spinner.gif') no-repeat 100%;
}
.select2-more-results {
background: #f4f4f4;
display: list-item;
}
/* disabled styles */
.select2-container.select2-container-disabled .select2-choice {
background-color: #f4f4f4;
background-image: none;
border: 1px solid #ddd;
cursor: default;
}
.select2-container.select2-container-disabled .select2-choice div {
background-color: #f4f4f4;
background-image: none;
border-left: 0;
}
/* multiselect */
.select2-container-multi .select2-choices {
background-color: #fff;
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
background-image: -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
background-image: -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
background-image: -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
background-image: -ms-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
background-image: linear-gradient(top, #eeeeee 1%, #ffffff 15%);
border: 1px solid #aaa;
margin: 0;
padding: 0;
cursor: text;
overflow: hidden;
height: auto !important;
height: 1%;
position: relative;
}
.select2-container-multi .select2-choices {
min-height: 26px;
}
.select2-container-multi.select2-container-active .select2-choices {
-webkit-box-shadow: 0 0 5px rgba(0,0,0,.3);
-moz-box-shadow : 0 0 5px rgba(0,0,0,.3);
-o-box-shadow : 0 0 5px rgba(0,0,0,.3);
box-shadow : 0 0 5px rgba(0,0,0,.3);
border: 1px solid #5897fb;
outline: none;
}
.select2-container-multi .select2-choices li {
float: left;
list-style: none;
}
.select2-container-multi .select2-choices .select2-search-field {
white-space: nowrap;
margin: 0;
padding: 0;
}
.select2-container-multi .select2-choices .select2-search-field input {
color: #666;
background: transparent !important;
font-family: sans-serif;
font-size: 100%;
height: 15px;
padding: 5px;
margin: 1px 0;
outline: 0;
border: 0;
-webkit-box-shadow: none;
-moz-box-shadow : none;
-o-box-shadow : none;
box-shadow : none;
}
.select2-container-multi .select2-choices .select2-search-field input.select2-active {
background: #fff url('spinner.gif') no-repeat 100% !important;
}
.select2-default {
color: #999 !important;
}
.select2-container-multi .select2-choices .select2-search-choice {
-webkit-border-radius: 3px;
-moz-border-radius : 3px;
border-radius : 3px;
-moz-background-clip : padding;
-webkit-background-clip: padding-box;
background-clip : padding-box;
background-color: #e4e4e4;
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f4f4f4', endColorstr='#eeeeee', GradientType=0 );
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: -ms-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
-webkit-box-shadow: 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05);
-moz-box-shadow : 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05);
box-shadow : 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05);
color: #333;
border: 1px solid #aaaaaa;
line-height: 13px;
padding: 3px 5px 3px 18px;
margin: 3px 0 3px 5px;
position: relative;
cursor: default;
}
.select2-container-multi .select2-choices .select2-search-choice span {
cursor: default;
}
.select2-container-multi .select2-choices .select2-search-choice-focus {
background: #d4d4d4;
}
.select2-search-choice-close {
display: block;
position: absolute;
right: 3px;
top: 4px;
width: 12px;
height: 13px;
font-size: 1px;
background: url('select2.png') right top no-repeat;
outline: none;
}
.select2-container-multi .select2-search-choice-close {
left: 3px;
}
.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover {
background-position: right -11px;
}
.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close {
background-position: right -11px;
}
/* disabled styles */
.select2-container-multi.select2-container-disabled .select2-choices{
background-color: #f4f4f4;
background-image: none;
border: 1px solid #ddd;
cursor: default;
}
.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice {
background-image: none;
background-color: #f4f4f4;
border: 1px solid #ddd;
padding: 3px 5px 3px 5px;
}
.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close {
display: none;
}
/* end multiselect */
.select2-result-selectable .select2-match,
.select2-result-unselectable .select2-result-selectable .select2-match { text-decoration: underline; }
.select2-result-unselectable .select2-match { text-decoration: none; }
.select2-offscreen { position: absolute; left: -10000px; }
/* Retina-ize icons */
@media only screen and (-webkit-min-device-pixel-ratio: 1.5) {
.select2-search input, .select2-search-choice-close, .select2-container .select2-choice abbr, .select2-container .select2-choice div b {
background-image: url(select2x2.png) !important;
background-repeat: no-repeat !important;
background-size: 60px 40px !important;
}
.select2-search input {
background-position: 100% -21px !important;
}
}

2407
addons/base_import/static/lib/select2/select2.js vendored Executable file

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 613 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 845 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,57 @@
.openerp .oe_list_buttons .oe_alternative {
visibility: visible;
}
.openerp .oe_list_buttons.oe_editing .oe_list_button_import {
display: none;
}
.oe_import dd,
.oe_import .oe_import_toggled,
.oe_import .oe_import_grid,
.oe_import .oe_import_error_report,
.oe_import .oe_import_with_file,
.oe_import .oe_import_noheaders {
display: none;
}
.oe_import.oe_import_preview .oe_import_grid {
display: table;
}
.oe_import.oe_import_error .oe_import_error_report,
.oe_import.oe_import_with_file .oe_import_with_file,
.oe_import.oe_import_noheaders .oe_import_noheaders {
display: block;
}
.oe_import .oe_import_error_report ul .oe_import_report_error {
background-color: #FFD9DB;
}
.oe_import .oe_import_error_report ul .oe_import_report_warning {
background-color: #FEFFD9;
}
.oe_import .oe_import_noheaders {
color: #888;
}
.oe_import a.oe_import_toggle {
display: block;
}
.oe_import a.oe_import_toggle:before {
content: '> '
}
.oe_import .oe_import_options p {
margin: 0;
padding: 0;
}
.oe_import .oe_import_options label {
display: inline-block;
width: 10em;
text-align: right;
}
.oe_import_selector ul,
.oe_import_selector li {
margin: 0; padding: 0;
}

View File

@ -0,0 +1,291 @@
openerp.base_import = function (instance) {
var QWeb = instance.web.qweb;
var _t = instance.web._t;
var _lt = instance.web._lt;
/**
* Safari does not deal well at all with raw JSON data being
* returned. As a result, we're going to cheat by using a
* pseudo-jsonp: instead of getting JSON data in the iframe, we're
* getting a ``script`` tag which consists of a function call and
* the returned data (the json dump).
*
* The function is an auto-generated name bound to ``window``,
* which calls back into the callback provided here.
*
* @param {Object} form the form element (DOM or jQuery) to use in the call
* @param {Object} attributes jquery.form attributes object
* @param {Function} callback function to call with the returned data
*/
function jsonp(form, attributes, callback) {
attributes = attributes || {};
var options = {jsonp: _.uniqueId('import_callback_')};
window[options.jsonp] = function () {
delete window[options.jsonp];
callback.apply(null, arguments);
};
if ('data' in attributes) {
_.extend(attributes.data, options);
} else {
_.extend(attributes, {data: options});
}
_.extend(attributes, {
dataType: 'script',
});
$(form).ajaxSubmit(attributes);
}
// if true, the 'Import', 'Export', etc... buttons will be shown
instance.web.ListView.prototype.defaults.import_enabled = true;
instance.web.ListView.include({
on_loaded: function () {
var self = this;
var add_button = false;
if (!this.$buttons) {
add_button = true;
}
this._super.apply(this, arguments);
if(add_button) {
this.$buttons.on('click', '.oe_list_button_import', function() {
new instance.web.DataImport(self, self.dataset).open();
return false;
});
}
}
});
instance.web.DataImport = instance.web.Dialog.extend({
template: 'ImportView',
dialog_title: _lt("Import Data"),
opts: [
{name: 'encoding', label: _lt("Encoding:"), value: 'utf-8'},
{name: 'separator', label: _lt("Separator:"), value: ','},
{name: 'quoting', label: _lt("Quoting:"), value: '"'}
],
events: {
'change .oe_import_grid input': 'import_dryrun',
'change input.oe_import_file': 'file_update',
'change input.oe_import_has_header, .oe_import_options input': 'settings_updated',
'click a.oe_import_csv': function (e) {
e.preventDefault();
},
'click a.oe_import_export': function (e) {
e.preventDefault();
},
'click a.oe_import_toggle': function (e) {
e.preventDefault();
var $el = $(e.target);
($el.next().length
? $el.next()
: $el.parent().next())
.toggle();
}
},
init: function (parent, dataset) {
var self = this;
this._super(parent, {
buttons: [
{text: _t("Import File"), click: function () {
self.do_import();
}, 'class': 'oe_import_dialog_button'}
]
});
this.res_model = parent.model;
// import object id
this.id = null;
this.Import = new instance.web.Model('base_import.import');
},
start: function () {
var self = this;
return this.Import.call('create', [{
'res_model': this.res_model
}]).then(function (id) {
self.id = id;
self.$('input[name=import_id]').val(id);
});
},
import_options: function () {
var self = this;
var options = {
headers: this.$('input.oe_import_has_header').prop('checked')
};
_(this.opts).each(function (opt) {
options[opt.name] =
self.$('input.oe_import_' + opt.name).val();
});
return options;
},
//- File & settings change section
file_update: function (e) {
if (!this.$('input.oe_import_file').val()) { return; }
this.$el.removeClass('oe_import_preview oe_import_error');
jsonp(this.$el, {
url: '/base_import/set_file'
}, this.proxy('settings_updated'));
},
settings_updated: function () {
this.$el.addClass('oe_import_with_file');
// TODO: test that write // succeeded?
this.Import.call(
'parse_preview', [this.id, this.import_options()])
.then(this.proxy('preview'));
},
preview: function (result) {
this.$el.toggleClass(
'oe_import_noheaders',
!this.$('input.oe_import_has_header').prop('checked'));
if (result.error) {
this.$el.addClass('oe_import_error');
this.$('.oe_import_error_report').html(
QWeb.render('ImportView.preview.error', result));
return;
}
this.$el.addClass('oe_import_preview');
this.$('table').html(QWeb.render('ImportView.preview', result));
var $fields = this.$('.oe_import_fields input');
this.render_fields_matches(result, $fields);
var data = this.generate_fields_completion(result);
var item_finder = function (id, items) {
items = items || data;
for (var i=0; i < items.length; ++i) {
var item = items[i];
if (item.id === id) {
return item;
}
var val;
if (item.children && (val = item_finder(id, item.children))) {
return val;
}
}
return '';
};
$fields.select2({
allowClear: true,
minimumInputLength: 0,
data: data,
initSelection: function (element, callback) {
var default_value = element.val();
if (!default_value) {
callback('');
return;
}
callback(item_finder(default_value));
},
width: 'resolve',
dropdownCssClass: 'oe_import_selector'
});
this.import_dryrun();
},
generate_fields_completion: function (root) {
var basic = [];
var regulars = [];
var o2m = [];
function traverse(field, ancestors, collection) {
var subfields = field.fields;
var field_path = ancestors.concat(field);
var label = _(field_path).pluck('string').join(' / ');
var id = _(field_path).pluck('name').join('/');
// If non-relational, m2o or m2m, collection is regulars
if (!collection) {
if (field.name === 'id') {
collection = basic
} else if (_.isEmpty(subfields)
|| _.isEqual(_.pluck(subfields, 'name'), ['id', '.id'])) {
collection = regulars;
} else {
collection = o2m;
}
}
collection.push({
id: id,
text: label,
required: field.required
});
for(var i=0, end=subfields.length; i<end; ++i) {
traverse(subfields[i], field_path, collection);
}
}
_(root.fields).each(function (field) {
traverse(field, []);
});
var cmp = function (field1, field2) {
return field1.text.localeCompare(field2.text);
};
regulars.sort(cmp);
o2m.sort(cmp);
return basic.concat([
{ text: _t("Normal Fields"), children: regulars },
{ text: _t("Relation Fields"), children: o2m }
]);
},
render_fields_matches: function (result, $fields) {
if (_(result.matches).isEmpty()) { return; }
$fields.each(function (index, input) {
var match = result.matches[index];
if (!match) { return; }
var current_field = result;
input.value = _(match).chain()
.map(function (name) {
// WARNING: does both mapping and folding (over the
// ``field`` iterator variable)
return current_field = _(current_field.fields).find(function (subfield) {
return subfield.name === name;
});
})
.pluck('name')
.value()
.join('/');
});
},
//- import itself
call_import: function (options) {
var self = this;
var fields = this.$('.oe_import_fields input.oe_import_match_field').map(function (index, el) {
return $(el).select2('val') || false;
}).get();
return this.Import.call(
'do', [this.id, fields, this.import_options()], options);
},
import_dryrun: function () {
// this.call_import({ dryrun: true })
// .then(this.proxy('render_import_errors'));
},
do_import: function () {
var self = this;
this.call_import({ dryrun: false }).then(function (errors) {
if (_.isEmpty(errors)) {
if (self.getParent().reload_content) {
self.getParent().reload_content();
}
self.close();
return;
}
self.render_import_errors(errors);
});
},
render_import_errors: function (errors) {
if (_.isEmpty(errors)) {
this.$el.removeClass('oe_import_error');
return;
}
// import failed (or maybe just warnings, if we ever get
// warnings?)
this.$el.addClass('oe_import_error');
this.$('.oe_import_error_report').html(
QWeb.render('ImportView.error', {errors: errors}));
},
});
};

View File

@ -0,0 +1,103 @@
<templates>
<t t-name="ImportView">
<t t-set="_id" t-value="_.uniqueId('export')"/>
<form action="" method="post" enctype="multipart/form-data" class="oe_import">
<input type="hidden" name="session_id"
t-att-value="widget.session.session_id"/>
<input type="hidden" name="import_id"/>
<h2>Upload your file</h2>
<p>Select the <a href="#" class="oe_import_csv">.CSV</a>
file to import. If you need a sample importable file, you
can use <a href="#" class="oe_import_export">the export
tool</a> to generate one.</p>
<label t-attf-for="file_#{_id}" autofocus="autofocus">CSV File:</label>
<input type="file" id-attf-id="file_#{_id}"
name="file" class="oe_import_file"/>
<div class="oe_import_with_file">
<h2>Map your data to OpenERP</h2>
<input type="checkbox" class="oe_import_has_header"
id="oe_import_has_header" checked="checked"/>
<label for="oe_import_has_header">The first row of the
file contains the label of the column</label>
<p class="oe_import_noheaders">If the file contains
the column names, OpenERP can try auto-detecting the
field corresponding to the column. This makes imports
simpler especially when the file has many columns.</p>
<div class="oe_import_error_report"></div>
<table class="oe_import_grid" width="100%"/>
<a href="#" class="oe_import_toggle">
File Format Options…</a>
<div class="oe_import_toggled oe_import_options">
<p t-foreach="widget.opts" t-as="option">
<!-- no @name, avoid submission when file_update called -->
<label t-attf-for="#{option.name}_#{_id}">
<t t-esc="option.label"/></label>
<input t-attf-id="#{option.name}_#{_id}"
t-attf-class="oe_import_#{option.name}"
t-att-value="option.value"/>
</p>
</div>
<h2>Frequently Asked Questions</h2>
<dl>
<dt><a href="#" class="oe_import_toggle">
Need to import data from an other application?</a></dt>
<dd>
<p>In order to re-create relationships between
different records, you should use the unique
identifier from the original application and
map it to the <abbr title="External ID">ID</abbr>
column in OpenERP. When you
import an other record that links to the first
one, use <abbr title="XXX/External ID">XXX/ID</abbr>
to the original unique identifier.</p>
<p>The <abbr title="External ID">ID</abbr>
will also be used to update the original
import if you need to re-import modified data
later, it's thus good practice to specify it
whenever possible</p>
</dd>
</dl>
</div>
</form>
</t>
<t t-name="ImportView.preview">
<tr t-if="headers" class="oe_import_grid-header">
<td t-foreach="headers" t-as="header" class="oe_import_grid-cell"
><t t-esc="header"/></td>
</tr>
<tr class="oe_import_fields">
<!-- Iterate on first row to ensure we have all columns -->
<td t-foreach="preview[0]" t-as="column">
<input placeholder="Don't Import"
class="oe_import_match_field"/>
</td>
</tr>
<tr t-foreach="preview" t-as="row" class="oe_import_grid-row">
<td t-foreach="row" t-as="cell" class="oe_import_grid-cell"
><t t-esc="cell"/></td>
</tr>
</t>
<t t-name="ImportView.preview.error">
<p>Import preview failed due to: <t t-esc="error"/></p>
<p>Here is the start of the file we could not import:</p>
<pre><t t-esc="preview"/></pre>
</t>
<ul t-name="ImportView.error">
<li t-foreach="errors" t-as="error" t-attf-class="oe_import_report_#{error.type}">
<!-- can also have error.record, but may be *huge* if
e.g. has image fields -->
<t t-esc="error.message"/>
</li>
</ul>
<t t-extend="ListView.buttons">
<t t-jquery="span.oe_alternative">
this.attr('t-if', 'widget.options.import_enabled');
</t>
<t t-jquery="span.oe_alternative" t-operation="append">
<a href="#" class="oe_bold oe_list_button_import">Import</a>
</t>
</t>
</templates>

View File

@ -0,0 +1,101 @@
from openerp.osv import orm, fields
def name(n): return 'base_import.tests.models.%s' % n
class char(orm.Model):
_name = name('char')
_columns = {
'value': fields.char('unknown', size=None)
}
class char_required(orm.Model):
_name = name('char.required')
_columns = {
'value': fields.char('unknown', size=None, required=True)
}
class char_readonly(orm.Model):
_name = name('char.readonly')
_columns = {
'value': fields.char('unknown', size=None, readonly=True)
}
class char_states(orm.Model):
_name = name('char.states')
_columns = {
'value': fields.char('unknown', size=None, readonly=True, states={'draft': [('readonly', False)]})
}
class char_noreadonly(orm.Model):
_name = name('char.noreadonly')
_columns = {
'value': fields.char('unknown', size=None, readonly=True, states={'draft': [('invisible', True)]})
}
class char_stillreadonly(orm.Model):
_name = name('char.stillreadonly')
_columns = {
'value': fields.char('unknown', size=None, readonly=True, states={'draft': [('readonly', True)]})
}
# TODO: complex field (m2m, o2m, m2o)
class m2o(orm.Model):
_name = name('m2o')
_columns = {
'value': fields.many2one(name('m2o.related'))
}
class m2o_related(orm.Model):
_name = name('m2o.related')
_columns = {
'value': fields.integer()
}
_defaults = {
'value': 42
}
class m2o_required(orm.Model):
_name = name('m2o.required')
_columns = {
'value': fields.many2one(name('m2o.required.related'), required=True)
}
class m2o_required_related(orm.Model):
_name = name('m2o.required.related')
_columns = {
'value': fields.integer()
}
_defaults = {
'value': 42
}
class o2m(orm.Model):
_name = name('o2m')
_columns = {
'value': fields.one2many(name('o2m.child'), 'parent_id')
}
class o2m_child(orm.Model):
_name = name('o2m.child')
_columns = {
'parent_id': fields.many2one(name('o2m')),
'value': fields.integer()
}
class preview_model(orm.Model):
_name = name('preview')
_columns = {
'name': fields.char('Name', size=None),
'somevalue': fields.integer('Some Value', required=True),
'othervalue': fields.integer('Other Variable'),
}

View File

@ -0,0 +1,3 @@
from . import test_cases
checks = [test_cases]

View File

@ -0,0 +1,342 @@
# -*- encoding: utf-8 -*-
import unittest2
from openerp.tests.common import TransactionCase
from .. import models
ID_FIELD = {'id': 'id', 'name': 'id', 'string': "External ID", 'required': False, 'fields': []}
def make_field(name='value', string='unknown', required=False, fields=[]):
return [
ID_FIELD,
{'id': name, 'name': name, 'string': string, 'required': required, 'fields': fields},
]
class test_basic_fields(TransactionCase):
def get_fields(self, field):
return self.registry('base_import.import')\
.get_fields(self.cr, self.uid, 'base_import.tests.models.' + field)
def test_base(self):
""" A basic field is not required """
self.assertEqual(self.get_fields('char'), make_field())
def test_required(self):
""" Required fields should be flagged (so they can be fill-required) """
self.assertEqual(self.get_fields('char.required'), make_field(required=True))
def test_readonly(self):
""" Readonly fields should be filtered out"""
self.assertEqual(self.get_fields('char.readonly'), [ID_FIELD])
def test_readonly_states(self):
""" Readonly fields with states should not be filtered out"""
self.assertEqual(self.get_fields('char.states'), make_field())
def test_readonly_states_noreadonly(self):
""" Readonly fields with states having nothing to do with
readonly should still be filtered out"""
self.assertEqual(self.get_fields('char.noreadonly'), [ID_FIELD])
def test_readonly_states_stillreadonly(self):
""" Readonly fields with readonly states leaving them readonly
always... filtered out"""
self.assertEqual(self.get_fields('char.stillreadonly'), [ID_FIELD])
def test_m2o(self):
""" M2O fields should allow import of themselves (name_get),
their id and their xid"""
self.assertEqual(self.get_fields('m2o'), make_field(fields=[
{'id': 'value', 'name': 'id', 'string': 'External ID', 'required': False, 'fields': []},
{'id': 'value', 'name': '.id', 'string': 'Database ID', 'required': False, 'fields': []},
]))
def test_m2o_required(self):
""" If an m2o field is required, its three sub-fields are
required as well (the client has to handle that: requiredness
is id-based)
"""
self.assertEqual(self.get_fields('m2o.required'), make_field(required=True, fields=[
{'id': 'value', 'name': 'id', 'string': 'External ID', 'required': True, 'fields': []},
{'id': 'value', 'name': '.id', 'string': 'Database ID', 'required': True, 'fields': []},
]))
class test_o2m(TransactionCase):
def get_fields(self, field):
return self.registry('base_import.import')\
.get_fields(self.cr, self.uid, 'base_import.tests.models.' + field)
def test_shallow(self):
self.assertEqual(self.get_fields('o2m'), make_field(fields=[
{'id': 'id', 'name': 'id', 'string': 'External ID', 'required': False, 'fields': []},
# FIXME: should reverse field be ignored?
{'id': 'parent_id', 'name': 'parent_id', 'string': 'unknown', 'required': False, 'fields': [
{'id': 'parent_id', 'name': 'id', 'string': 'External ID', 'required': False, 'fields': []},
{'id': 'parent_id', 'name': '.id', 'string': 'Database ID', 'required': False, 'fields': []},
]},
{'id': 'value', 'name': 'value', 'string': 'unknown', 'required': False, 'fields': []},
]))
class test_match_headers_single(TransactionCase):
def test_match_by_name(self):
match = self.registry('base_import.import')._match_header(
'f0', [{'name': 'f0'}], {})
self.assertEqual(match, [{'name': 'f0'}])
def test_match_by_string(self):
match = self.registry('base_import.import')._match_header(
'some field', [{'name': 'bob', 'string': "Some Field"}], {})
self.assertEqual(match, [{'name': 'bob', 'string': "Some Field"}])
def test_nomatch(self):
match = self.registry('base_import.import')._match_header(
'should not be', [{'name': 'bob', 'string': "wheee"}], {})
self.assertEqual(match, [])
def test_recursive_match(self):
f = {
'name': 'f0',
'string': "My Field",
'fields': [
{'name': 'f0', 'string': "Sub field 0", 'fields': []},
{'name': 'f1', 'string': "Sub field 2", 'fields': []},
]
}
match = self.registry('base_import.import')._match_header(
'f0/f1', [f], {})
self.assertEqual(match, [f, f['fields'][1]])
def test_recursive_nomatch(self):
""" Match first level, fail to match second level
"""
f = {
'name': 'f0',
'string': "My Field",
'fields': [
{'name': 'f0', 'string': "Sub field 0", 'fields': []},
{'name': 'f1', 'string': "Sub field 2", 'fields': []},
]
}
match = self.registry('base_import.import')._match_header(
'f0/f2', [f], {})
self.assertEqual(match, [])
class test_match_headers_multiple(TransactionCase):
def test_noheaders(self):
self.assertEqual(
self.registry('base_import.import')._match_headers(
[], [], {}),
(None, None)
)
def test_nomatch(self):
self.assertEqual(
self.registry('base_import.import')._match_headers(
iter([
['foo', 'bar', 'baz', 'qux'],
['v1', 'v2', 'v3', 'v4'],
]),
[],
{'headers': True}),
(
['foo', 'bar', 'baz', 'qux'],
dict.fromkeys(range(4))
)
)
def test_mixed(self):
self.assertEqual(
self.registry('base_import.import')._match_headers(
iter(['foo bar baz qux/corge'.split()]),
[
{'name': 'bar', 'string': 'Bar'},
{'name': 'bob', 'string': 'Baz'},
{'name': 'qux', 'string': 'Qux', 'fields': [
{'name': 'corge', 'fields': []},
]}
],
{'headers': True}),
(['foo', 'bar', 'baz', 'qux/corge'], {
0: None,
1: ['bar'],
2: ['bob'],
3: ['qux', 'corge'],
})
)
class test_preview(TransactionCase):
def make_import(self):
Import = self.registry('base_import.import')
id = Import.create(self.cr, self.uid, {
'res_model': 'res.users',
'file': u"로그인,언어\nbob,1\n".encode('euc_kr'),
})
return Import, id
def test_encoding(self):
Import, id = self.make_import()
result = Import.parse_preview(self.cr, self.uid, id, {
'quoting': '"',
'separator': ',',
})
self.assertTrue('error' in result)
def test_csv_errors(self):
Import, id = self.make_import()
result = Import.parse_preview(self.cr, self.uid, id, {
'quoting': 'foo',
'separator': ',',
'encoding': 'euc_kr',
})
self.assertTrue('error' in result)
def test_csv_errors(self):
Import, id = self.make_import()
result = Import.parse_preview(self.cr, self.uid, id, {
'quoting': '"',
'separator': 'bob',
'encoding': 'euc_kr',
})
self.assertTrue('error' in result)
def test_success(self):
Import = self.registry('base_import.import')
id = Import.create(self.cr, self.uid, {
'res_model': 'base_import.tests.models.preview',
'file': 'name,Some Value,Counter\n'
'foo,1,2\n'
'bar,3,4\n'
'qux,5,6\n'
})
result = Import.parse_preview(self.cr, self.uid, id, {
'quoting': '"',
'separator': ',',
'headers': True,
})
self.assertEqual(result['matches'], {0: ['name'], 1: ['somevalue'], 2: None})
self.assertEqual(result['headers'], ['name', 'Some Value', 'Counter'])
# Order depends on iteration order of fields_get
self.assertItemsEqual(result['fields'], [
{'id': 'id', 'name': 'id', 'string': 'External ID', 'required':False, 'fields': []},
{'id': 'name', 'name': 'name', 'string': 'Name', 'required':False, 'fields': []},
{'id': 'somevalue', 'name': 'somevalue', 'string': 'Some Value', 'required':True, 'fields': []},
{'id': 'othervalue', 'name': 'othervalue', 'string': 'Other Variable', 'required':False, 'fields': []},
])
self.assertEqual(result['preview'], [
['foo', '1', '2'],
['bar', '3', '4'],
['qux', '5', '6'],
])
# Ensure we only have the response fields we expect
self.assertItemsEqual(result.keys(), ['matches', 'headers', 'fields', 'preview'])
class test_convert_import_data(TransactionCase):
""" Tests conversion of base_import.import input into data which
can be fed to Model.import_data
"""
def test_all(self):
Import = self.registry('base_import.import')
id = Import.create(self.cr, self.uid, {
'res_model': 'base_import.tests.models.preview',
'file': 'name,Some Value,Counter\n'
'foo,1,2\n'
'bar,3,4\n'
'qux,5,6\n'
})
record = Import.browse(self.cr, self.uid, id)
data, fields = Import._convert_import_data(
record, ['name', 'somevalue', 'othervalue'],
{'quoting': '"', 'separator': ',', 'headers': True,})
self.assertItemsEqual(fields, ['name', 'somevalue', 'othervalue'])
self.assertItemsEqual(data, [
('foo', '1', '2'),
('bar', '3', '4'),
('qux', '5', '6'),
])
def test_filtered(self):
""" If ``False`` is provided as field mapping for a column,
that column should be removed from importable data
"""
Import = self.registry('base_import.import')
id = Import.create(self.cr, self.uid, {
'res_model': 'base_import.tests.models.preview',
'file': 'name,Some Value,Counter\n'
'foo,1,2\n'
'bar,3,4\n'
'qux,5,6\n'
})
record = Import.browse(self.cr, self.uid, id)
data, fields = Import._convert_import_data(
record, ['name', False, 'othervalue'],
{'quoting': '"', 'separator': ',', 'headers': True,})
self.assertItemsEqual(fields, ['name', 'othervalue'])
self.assertItemsEqual(data, [
('foo', '2'),
('bar', '4'),
('qux', '6'),
])
def test_norow(self):
""" If a row is composed only of empty values (due to having
filtered out non-empty values from it), it should be removed
"""
Import = self.registry('base_import.import')
id = Import.create(self.cr, self.uid, {
'res_model': 'base_import.tests.models.preview',
'file': 'name,Some Value,Counter\n'
'foo,1,2\n'
',3,\n'
',5,6\n'
})
record = Import.browse(self.cr, self.uid, id)
data, fields = Import._convert_import_data(
record, ['name', False, 'othervalue'],
{'quoting': '"', 'separator': ',', 'headers': True,})
self.assertItemsEqual(fields, ['name', 'othervalue'])
self.assertItemsEqual(data, [
('foo', '2'),
('', '6'),
])
def test_nofield(self):
Import = self.registry('base_import.import')
id = Import.create(self.cr, self.uid, {
'res_model': 'base_import.tests.models.preview',
'file': 'name,Some Value,Counter\n'
'foo,1,2\n'
})
record = Import.browse(self.cr, self.uid, id)
self.assertRaises(
ValueError,
Import._convert_import_data,
record, [],
{'quoting': '"', 'separator': ',', 'headers': True,})
def test_falsefields(self):
Import = self.registry('base_import.import')
id = Import.create(self.cr, self.uid, {
'res_model': 'base_import.tests.models.preview',
'file': 'name,Some Value,Counter\n'
'foo,1,2\n'
})
record = Import.browse(self.cr, self.uid, id)
self.assertRaises(
ValueError,
Import._convert_import_data,
record, [False, False, False],
{'quoting': '"', 'separator': ',', 'headers': True,})

View File

@ -35,6 +35,7 @@ class base_config_settings(osv.osv_memory):
'module_auth_anonymous': fields.boolean('activate the public portal',
help="""Enable the public part of openerp, openerp becomes a public website."""),
'module_auth_oauth': fields.boolean('use external authentication providers, sign in with google, facebook, ...'),
'module_base_import': fields.boolean("Allow users to import data from CSV files"),
}
def open_company(self, cr, uid, ids, context=None):

View File

@ -14,9 +14,10 @@
</header>
<separator string="General Settings"/>
<div>
<label string="You will also find several configuration options on your company data:
address for the header and footer, overdue payments texts, etc."/>
<button type="object" name="open_company" string="Configure Your Company Data" icon="gtk-execute" class="oe_inline oe_link"/>
<p>
<label string="You will find more options in your company details: address for the header and footer, overdue payments texts, etc."/>
<button type="object" name="open_company" string="Configure Your Company Data" icon="gtk-execute" class="oe_inline oe_link"/>
</p>
</div>
<group>
<label for="id" string="Options"/>
@ -59,6 +60,15 @@
</div>
</div>
</group>
<group>
<label for="id" string="Import / Export"/>
<div>
<div>
<field name="module_base_import" class="oe_inline"/>
<label for="module_base_import"/>
</div>
</div>
</group>
</form>
</field>
</record>

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-09-07 04:57+0000\n"
"X-Launchpad-Export-Date: 2012-09-08 04:54+0000\n"
"X-Generator: Launchpad (build 15914)\n"
#. module: base_vat

View File

@ -1,3 +1,17 @@
.openerp .oe_dashboard_layout_selector ul {
white-space: nowrap;
}
.openerp .oe_dashboard_layout_selector li {
margin: 0;
padding: 0;
list-style-type: none;
float: left;
}
.openerp .oe_dashboard_layout_selector li .oe_dashboard_selected_layout {
margin-left: -30px;
vertical-align: bottom;
margin-bottom: 10px;
}
.openerp .oe_dashboard_links {
text-align: right;
margin: 0 4px 6px 0;
@ -5,11 +19,6 @@
.openerp .oe_dashboard {
width: 100%;
}
.openerp .oe_dashboard .oe_dashboard_layout_selector ul, .openerp .oe_dashboard .oe_dashboard_layout_selector li {
margin: 0;
padding: 0;
list-style-type: none;
}
.openerp .oe_dashboard .oe_action {
margin: 0 8px 8px 0;
background-color: white;

View File

@ -9,16 +9,23 @@
box-shadow: $bsval
.openerp
.oe_dashboard_layout_selector
ul
white-space: nowrap
li
margin: 0
padding: 0
list-style-type: none
float: left
.oe_dashboard_selected_layout
margin-left: -30px
vertical-align: bottom
margin-bottom: 10px
.oe_dashboard_links
text-align: right
margin: 0 4px 6px 0
.oe_dashboard
width: 100%
.oe_dashboard_layout_selector
ul, li
margin: 0
padding: 0
list-style-type: none
.oe_action
margin: 0 8px 8px 0
background-color: white

View File

@ -220,36 +220,40 @@ instance.web.form.DashBoard = instance.web.form.FormWidget.extend({
am.do_action = function (action) {
self.do_action(action);
};
if (action_attrs.creatable && action_attrs.creatable !== 'false') {
var action_id = parseInt(action_attrs.creatable, 10);
$action.parent().find('button.oe_dashboard_button_create').click(function() {
if (isNaN(action_id)) {
action_orig.flags.default_view = 'form';
self.do_action(action_orig);
} else {
self.rpc('/web/action/load', {
action_id: action_id
}, function(result) {
result.result.flags = result.result.flags || {};
result.result.flags.default_view = 'form';
self.do_action(result.result);
});
}
});
}
if (am.inner_widget) {
am.inner_widget.on_mode_switch.add(function(mode) {
var new_form_action = function(id, editable) {
var new_views = [];
_.each(action_orig.views, function(view) {
new_views[view[1] === mode ? 'unshift' : 'push'](view);
new_views[view[1] === 'form' ? 'unshift' : 'push'](view);
});
if (!new_views.length || new_views[0][1] !== mode) {
new_views.unshift([false, mode]);
if (!new_views.length || new_views[0][1] !== 'form') {
new_views.unshift([false, 'form']);
}
action_orig.views = new_views;
action_orig.res_id = am.inner_widget.dataset.ids[am.inner_widget.dataset.index];
action_orig.res_id = id;
action_orig.flags = {
form: {
"initial_mode": editable ? "edit" : "view",
}
};
self.do_action(action_orig);
});
};
var list = am.inner_widget.views.list;
if (list) {
list.deferred.then(function() {
$(list.controller.groups).off('row_link').on('row_link', function(e, id) {
new_form_action(id);
});
});
}
var kanban = am.inner_widget.views.kanban;
if (kanban) {
kanban.deferred.then(function() {
kanban.controller.open_record = function(id, editable) {
new_form_action(id, editable);
};
});
}
}
},
renderElement: function() {

View File

@ -26,7 +26,6 @@
<span class="oe_header_txt"> <t t-esc="action.attrs.string"/> </span>
<input class = "oe_header_text" type="text"/>
<t t-if="!action.attrs.string">&amp;nbsp;</t>
<button t-if="action.attrs.creatable and action.attrs.creatable !== 'false'" class="oe_button oe_button_create">Create</button>
<span class='oe_icon oe_close'></span>
<span class='oe_icon oe_minimize oe_fold' t-if="!action.attrs.fold"></span>
<span class='oe_icon oe_maximize oe_fold' t-if="action.attrs.fold"></span>

View File

@ -297,6 +297,7 @@
<field name="message_summary"/>
<field name="message_unread"/>
<templates>
<field name="date_deadline"/>
<t t-name="kanban-box">
<div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click">
<div class="oe_dropdown_toggle oe_dropdown_kanban">
@ -422,7 +423,7 @@
<label for="planned_revenue" class="oe_edit_only"/>
<h2>
<field name="planned_revenue" class="oe_inline"/>
<field name="company_currency" class="oe_inline"/> at
<field name="company_currency" class="oe_inline" groups="base.group_multi_currency"/> at
<field name="probability" class="oe_inline" widget="integer"/>%% success rate
</h2>
</div>

View File

@ -29,11 +29,13 @@ class document_page(osv.osv):
_description = "Document Page"
_order = 'name'
def _get_page_index(self, cr, uid, page):
def _get_page_index(self, cr, uid, page, link=True):
index = []
for subpage in page.child_ids:
index += ["<li>"+ self._get_page_index(cr, uid, subpage) +"</li>"]
r = '<a href="#id=%s">%s</a>'%(page.id,page.name)
r = ''
if link:
r = '<a href="#id=%s">%s</a>'%(page.id,page.name)
if index:
r += "<ul>" + "".join(index) + "</ul>"
return r
@ -42,7 +44,7 @@ class document_page(osv.osv):
res = {}
for page in self.browse(cr, uid, ids, context=context):
if page.type == "category":
content = self._get_page_index(cr, uid, page)
content = self._get_page_index(cr, uid, page, link=False)
else:
content = page.content
res[page.id] = content
@ -120,12 +122,12 @@ class document_page_history(osv.osv):
text2 = history_pool.read(cr, uid, [v2], ['content'])[0]['content']
line1 = line2 = ''
if text1:
line1 = tools.ustr(text1.splitlines(1))
line1 = text1.splitlines(1)
if text2:
line2=tools.ustr(text2.splitlines(1))
line2 = text2.splitlines(1)
if (not line1 and not line2) or (line1 == line2):
raise osv.except_osv(_('Warning!'), _('There are no changes in revisions.'))
diff = difflib.HtmlDiff()
return diff.make_file(line1, line2, "Revision-%s" % (v1), "Revision-%s" % (v2), context=False)
return diff.make_table(line1, line2, "Revision-%s" % (v1), "Revision-%s" % (v2), context=True)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -78,17 +78,6 @@
</field>
</record>
<!-- page action -->
<record id="action_category" model="ir.actions.act_window">
<field name="name">Category</field>
<field name="res_model">document.page</field>
<field name="domain">[('type','=','category')]</field>
<field name="context">{'default_type': 'category'}</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_wiki_tree"/>
<field name="search_view_id" ref="view_wiki_filter"/>
</record>
<menuitem id="menu_category" parent="menu_wiki" name="Categories" action="action_category" sequence="10"/>
<record id="action_page" model="ir.actions.act_window">
<field name="name">Pages</field>
<field name="res_model">document.page</field>
@ -100,7 +89,18 @@
<field name="search_view_id" ref="view_wiki_filter"/>
<field name="help">Create web pages</field>
</record>
<menuitem id="menu_page" parent="menu_wiki" name="Pages" action="action_page" sequence="20"/>
<menuitem id="menu_page" parent="menu_wiki" name="Pages" action="action_page" sequence="10"/>
<record id="action_category" model="ir.actions.act_window">
<field name="name">Category</field>
<field name="res_model">document.page</field>
<field name="domain">[('type','=','category')]</field>
<field name="context">{'default_type': 'category'}</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_wiki_tree"/>
<field name="search_view_id" ref="view_wiki_filter"/>
</record>
<menuitem id="menu_category" parent="menu_wiki" name="Categories" action="action_category" sequence="20"/>
<!-- History Tree view -->
<record model="ir.ui.view" id="view_wiki_history_tree">

View File

@ -1,11 +1,12 @@
.oe_document_page ul, .oe_document_page li {
padding: 2px 8px;
margin: 2px 8px;
list-style-type: circle;
}
.oe_form_editable .oe_document_page {
display: none;
}
table.diff {font-family:Courier; border:medium;}
.diff_header {background-color:#e0e0e0}
td.diff_header {text-align:right}
.diff_next {background-color:#c0c0c0}
.diff_add {background-color:#aaffaa}
.diff_chg {background-color:#ffff77}
.diff_sub {background-color:#ffaaaa}

View File

@ -8,7 +8,7 @@
<field name="model">wizard.document.page.history.show_diff</field>
<field name="arch" type="xml">
<form string="Difference" version="7.0">
<field name="diff"/>
<field name="diff" widget="html" options='{"safe": true}'/>
<footer>
<button string="Cancel" class="oe_link" special="cancel" />
</footer>

View File

@ -0,0 +1,197 @@
# Norwegian Bokmal translation for openobject-addons
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
"PO-Revision-Date: 2012-09-07 17:44+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Norwegian Bokmal <nb@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-09-08 04:54+0000\n"
"X-Generator: Launchpad (build 15914)\n"
#. module: document_webdav
#: field:document.webdav.dir.property,create_date:0
#: field:document.webdav.file.property,create_date:0
msgid "Date Created"
msgstr "Dato opprettet"
#. module: document_webdav
#: model:ir.ui.menu,name:document_webdav.menu_document_props
msgid "Documents"
msgstr "Dokumenter"
#. module: document_webdav
#: constraint:document.directory:0
msgid "Error! You can not create recursive Directories."
msgstr "Feil! Du kan opprette rekursive kataloger."
#. module: document_webdav
#: view:document.webdav.dir.property:0
#: view:document.webdav.file.property:0
msgid "Search Document properties"
msgstr "Søk Dokumentegenskaper."
#. module: document_webdav
#: view:document.webdav.dir.property:0
#: field:document.webdav.dir.property,namespace:0
#: view:document.webdav.file.property:0
#: field:document.webdav.file.property,namespace:0
msgid "Namespace"
msgstr "Navnerom"
#. module: document_webdav
#: field:document.directory,dav_prop_ids:0
msgid "DAV properties"
msgstr "DAV egenskaper"
#. module: document_webdav
#: model:ir.model,name:document_webdav.model_document_webdav_file_property
msgid "document.webdav.file.property"
msgstr "Dokumentet.WebDAV.fil.egenskap"
#. module: document_webdav
#: view:document.webdav.dir.property:0
#: view:document.webdav.file.property:0
msgid "Group By..."
msgstr "Grupper etter ..."
#. module: document_webdav
#: view:document.directory:0
msgid "These properties will be added to WebDAV requests"
msgstr "Disse egenskapene vil bli lagt til WebDAV-forespørsler"
#. module: document_webdav
#: model:ir.actions.act_window,name:document_webdav.action_file_props_form
msgid "DAV Properties for Documents"
msgstr "DAV Eiendommer for Dokumenter."
#. module: document_webdav
#: code:addons/document_webdav/webdav.py:37
#, python-format
msgid "PyWebDAV Import Error!"
msgstr "PyWebDAV importere Feil!"
#. module: document_webdav
#: view:document.webdav.file.property:0
#: field:document.webdav.file.property,file_id:0
msgid "Document"
msgstr "Dokument"
#. module: document_webdav
#: model:ir.ui.menu,name:document_webdav.menu_folder_props
msgid "Folders"
msgstr "Mapper"
#. module: document_webdav
#: sql_constraint:document.directory:0
msgid "Directory cannot be parent of itself!"
msgstr "Katalogen kan ikke være overordnede av seg selv!"
#. module: document_webdav
#: view:document.directory:0
msgid "Dynamic context"
msgstr "Dynamisk sammenheng"
#. module: document_webdav
#: view:document.directory:0
msgid "WebDAV properties"
msgstr "WebDAV egenskaper."
#. module: document_webdav
#: sql_constraint:document.directory:0
msgid "The directory name must be unique !"
msgstr "Katalogen Navnet må være unikt!"
#. module: document_webdav
#: code:addons/document_webdav/webdav.py:37
#, python-format
msgid ""
"Please install PyWebDAV from "
"http://code.google.com/p/pywebdav/downloads/detail?name=PyWebDAV-"
"0.9.4.tar.gz&can=2&q=/"
msgstr ""
"Vennligst installer PyWebDAV fra "
"http://code.google.com/p/pywebdav/downloads/detail?name=PyWebDAV-"
"0.9.4.tar.gz&can=2&q=/"
#. module: document_webdav
#: model:ir.actions.act_window,name:document_webdav.action_dir_props_form
msgid "DAV Properties for Folders"
msgstr "DAV egenskaper for mapper."
#. module: document_webdav
#: view:document.directory:0
#: view:document.webdav.dir.property:0
#: view:document.webdav.file.property:0
msgid "Properties"
msgstr "Egenskaper"
#. module: document_webdav
#: field:document.webdav.dir.property,name:0
#: field:document.webdav.file.property,name:0
msgid "Name"
msgstr "Navn"
#. module: document_webdav
#: model:ir.model,name:document_webdav.model_document_webdav_dir_property
msgid "document.webdav.dir.property"
msgstr "Dokumentet.WebDAV.dir.eiendom"
#. module: document_webdav
#: field:document.webdav.dir.property,value:0
#: field:document.webdav.file.property,value:0
msgid "Value"
msgstr "Verdi"
#. module: document_webdav
#: field:document.webdav.dir.property,dir_id:0
#: model:ir.model,name:document_webdav.model_document_directory
msgid "Directory"
msgstr "Katalog"
#. module: document_webdav
#: field:document.webdav.dir.property,write_uid:0
#: field:document.webdav.file.property,write_uid:0
msgid "Last Modification User"
msgstr "Siste endring Bruker"
#. module: document_webdav
#: view:document.webdav.dir.property:0
msgid "Dir"
msgstr "Retn"
#. module: document_webdav
#: field:document.webdav.dir.property,write_date:0
#: field:document.webdav.file.property,write_date:0
msgid "Date Modified"
msgstr "Dato endret"
#. module: document_webdav
#: field:document.webdav.dir.property,create_uid:0
#: field:document.webdav.file.property,create_uid:0
msgid "Creator"
msgstr "Opprettet av"
#. module: document_webdav
#: model:ir.ui.menu,name:document_webdav.menu_properties
msgid "DAV Properties"
msgstr "DAV Egenskaper."
#. module: document_webdav
#: sql_constraint:document.directory:0
msgid "Directory must have a parent or a storage"
msgstr "Katalog må ha en overordnede eller en lagringsplass."
#. module: document_webdav
#: field:document.webdav.dir.property,do_subst:0
#: field:document.webdav.file.property,do_subst:0
msgid "Substitute"
msgstr "Erstatte"

411
addons/edi/i18n/nb.po Normal file
View File

@ -0,0 +1,411 @@
# Norwegian Bokmal translation for openobject-addons
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-08 01:37+0100\n"
"PO-Revision-Date: 2012-09-08 19:13+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Norwegian Bokmal <nb@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-09-09 04:53+0000\n"
"X-Generator: Launchpad (build 15914)\n"
#. module: edi
#: sql_constraint:res.currency:0
msgid "The currency code must be unique per company!"
msgstr "Valutakode må være unik pr. firma!"
#. module: edi
#: model:ir.model,name:edi.model_res_partner_address
msgid "Partner Addresses"
msgstr "Partner adresser"
#. module: edi
#: sql_constraint:res.company:0
msgid "The company name must be unique !"
msgstr "Firmanavn må være unikt !"
#. module: edi
#: constraint:res.partner:0
msgid "Error ! You cannot create recursive associated members."
msgstr "Feil! Du kan ikke opprette rekursive tilknyttede medlemmer."
#. module: edi
#: field:edi.document,name:0
msgid "EDI token"
msgstr "EDI tegn."
#. module: edi
#: help:edi.document,name:0
msgid "Unique identifier for retrieving an EDI document."
msgstr "Unik identifikator for å hente en EDI dokument."
#. module: edi
#: constraint:res.company:0
msgid "Error! You can not create recursive companies."
msgstr "Feil ! Du kan ikke lage rekursive firmaer."
#. module: edi
#: model:ir.model,name:edi.model_res_company
msgid "Companies"
msgstr "Firmaer"
#. module: edi
#: sql_constraint:edi.document:0
msgid "EDI Tokens must be unique!"
msgstr "EDI tegnet må være unikt!"
#. module: edi
#: model:ir.model,name:edi.model_res_currency
msgid "Currency"
msgstr "Valuta"
#. module: edi
#: code:addons/edi/models/edi.py:153
#, python-format
msgid ""
"The document you are trying to import requires the OpenERP `%s` application. "
"You can install it by connecting as the administrator and opening the "
"configuration assistant."
msgstr ""
"Dokumentet du prøver å importere krever OpenERP `% s` søknad. Du kan "
"installere det ved å koble som administrator og åpne konfigurasjonen "
"assistent."
#. module: edi
#: help:edi.document,document:0
msgid "EDI document content"
msgstr "EDI dokumentinnhold"
#. module: edi
#: model:ir.model,name:edi.model_edi_document
msgid "EDI Document"
msgstr "EDI dokument."
#. module: edi
#: code:addons/edi/models/edi.py:48
#, python-format
msgid "'%s' is an invalid external ID"
msgstr "'% s' er en ugyldig ekstern ID."
#. module: edi
#: model:ir.model,name:edi.model_res_partner
msgid "Partner"
msgstr "Partner"
#. module: edi
#: code:addons/edi/models/edi.py:152
#, python-format
msgid "Missing Application"
msgstr "Manglende Søknad."
#. module: edi
#: field:edi.document,document:0
msgid "Document"
msgstr "Dokument"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:23
msgid "View/Print"
msgstr "Vis / Skriv ut"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:28
msgid "Import this document"
msgstr "Importer dette dokumentet."
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:33
msgid "Import it into an existing OpenERP instance"
msgstr "Importere den inn i en eksisterende OpenERP eksempel."
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:36
msgid "OpenERP instance address:"
msgstr "OpenERP eksempel adresse:"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:39
msgid "Import"
msgstr "Import"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:44
msgid "Import it into a new OpenERP Online instance"
msgstr "Importere den til en ny OpenERP Online eksempel."
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:47
msgid "Create my new OpenERP instance"
msgstr "Opprett min nye OpenERP eksempel."
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:52
msgid "Import into another application"
msgstr "Importere til et annet program."
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:54
msgid ""
"OpenERP's Electronic Data Interchange documents are based on a generic and "
"language\n"
" independent"
msgstr ""
"OpenERP's elektronisk Data utveksler dokumentene er basert på en generisk og "
"språk.\n"
"                             "
" uavhengig."
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:56
msgid "JSON"
msgstr "JSON"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:56
msgid ""
"serialization of the document's attribute.\n"
" It is usually very quick and straightforward to "
"create a small plug-in for your preferred\n"
" application that will be capable of importing "
"any OpenERP EDI document.\n"
" You can find out more details about how to do "
"this and what the content of OpenERP EDI documents\n"
" is like in the"
msgstr ""
"Serialisering av dokumentets attributtet.\n"
"                             Det er vanligvis svært rask og grei å lage en "
"liten plug-in for din foretrukne.\n"
"                             program som vil være i stand til å importere "
"noen OpenERP EDI dokument.\n"
"                             Du kan finne ut mer informasjon om hvordan du "
"gjør dette og hva innholdet i OpenERP EDI dokumenter\n"
"                             er som i."
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:60
msgid "OpenERP documentation"
msgstr "OpenERP dokumentasjon."
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:61
msgid "To get started immediately,"
msgstr "Å komme i gang umiddelbart,"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:62
msgid "see is all it takes to use this EDI document in Python"
msgstr "Se er alt som trengs for å bruke denne EDI dokumentet i Python."
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:70
msgid "You can download the raw EDI document here:"
msgstr "Du kan laste ned den rå EDI dokumentet her:"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:73
msgid "Download"
msgstr "Nedlastning"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:87
msgid "Powered by"
msgstr "Drevet av."
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:87
msgid "OpenERP"
msgstr "OpenERP"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:34
msgid "Invoice"
msgstr "Faktura"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:37
msgid "Description"
msgstr "Beskrivelse:"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:38
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:41
msgid "Date"
msgstr "Dato"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:39
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:40
msgid "Your Reference"
msgstr "Din referanse."
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:50
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:57
msgid "Product Description"
msgstr "Produktbeskrivelse"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:51
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:58
msgid "Quantity"
msgstr "Antall"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:52
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:59
msgid "Unit Price"
msgstr "Enhetspris"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:53
msgid "Discount"
msgstr "Rabatt"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:54
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:61
msgid "Price"
msgstr "Pris"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:72
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:81
msgid "Net Total:"
msgstr "Netto total:"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:83
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:92
msgid "Taxes:"
msgstr "Avgifter:"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:94
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:103
msgid "Total:"
msgstr "Totalt:"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:106
msgid "Tax"
msgstr "Skatt"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:107
msgid "Base Amount"
msgstr "Grunnbeløp"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:108
msgid "Amount"
msgstr "Beløp"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:121
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:113
msgid "Notes:"
msgstr "Notater:"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:129
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:121
msgid "Pay Online"
msgstr "Betal online."
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:133
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:125
msgid "Paypal"
msgstr "Paypal"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:135
msgid ""
"You may directly pay this invoice online via Paypal's secure payment gateway:"
msgstr ""
"Du kan betale direkte denne fakturaen online via Paypal er sikker betaling "
"gateway:"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:145
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:137
msgid "Bank Wire Transfer"
msgstr "Bank Tråd overføring."
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:147
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:139
msgid "Please transfer"
msgstr "Vennligst overfør."
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:148
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:140
msgid "to"
msgstr "til"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:149
msgid ""
"(postal address on the invoice header)\n"
" using one of the following bank accounts. Be sure to "
"mention the invoice\n"
" reference"
msgstr ""
"(postadresse på fakturaen header)\n"
"Ved hjelp av en av følgende bankkontoer. Sørg for å nevne faktura.\n"
"Referanse."
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:151
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:143
msgid "on the transfer:"
msgstr "På overføring:"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:36
msgid "Order"
msgstr "Ordre"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:42
msgid "Salesman"
msgstr "Selger"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:43
msgid "Payment terms"
msgstr "Betalingsbetingelser"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:60
msgid "Discount(%)"
msgstr "Raball(%)"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:127
msgid ""
"You may directly pay this order online via Paypal's secure payment gateway:"
msgstr ""
"Du kan betale direkte i denne rekkefølgen online via Paypal's sikker "
"betaling gateway."
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:141
msgid ""
"(postal address on the order header)\n"
" using one of the following bank accounts. Be sure to "
"mention the document\n"
" reference"
msgstr ""
"Ostal adresse på bestillingen topp)\n"
"Ved hjelp av en av følgende bankkontoer. Sørg for å nevne dokumentet.\n"
"Referanse."

390
addons/edi/i18n/ru.po Normal file
View File

@ -0,0 +1,390 @@
# Russian translation for openobject-addons
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-08 01:37+0100\n"
"PO-Revision-Date: 2012-09-10 15:12+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-09-11 04:50+0000\n"
"X-Generator: Launchpad (build 15924)\n"
#. module: edi
#: sql_constraint:res.currency:0
msgid "The currency code must be unique per company!"
msgstr "Код валюты должен быть уникальным в компании!"
#. module: edi
#: model:ir.model,name:edi.model_res_partner_address
msgid "Partner Addresses"
msgstr "Адреса контрагентов"
#. module: edi
#: sql_constraint:res.company:0
msgid "The company name must be unique !"
msgstr "Название компании должно быть уникальным!"
#. module: edi
#: constraint:res.partner:0
msgid "Error ! You cannot create recursive associated members."
msgstr "Ошибка! Вы не можете создавать рекурсивные ссылки на участников."
#. module: edi
#: field:edi.document,name:0
msgid "EDI token"
msgstr ""
#. module: edi
#: help:edi.document,name:0
msgid "Unique identifier for retrieving an EDI document."
msgstr ""
#. module: edi
#: constraint:res.company:0
msgid "Error! You can not create recursive companies."
msgstr "Ошибка ! Нельзя создать рекурсивные организации."
#. module: edi
#: model:ir.model,name:edi.model_res_company
msgid "Companies"
msgstr "Компании"
#. module: edi
#: sql_constraint:edi.document:0
msgid "EDI Tokens must be unique!"
msgstr ""
#. module: edi
#: model:ir.model,name:edi.model_res_currency
msgid "Currency"
msgstr "Валюта"
#. module: edi
#: code:addons/edi/models/edi.py:153
#, python-format
msgid ""
"The document you are trying to import requires the OpenERP `%s` application. "
"You can install it by connecting as the administrator and opening the "
"configuration assistant."
msgstr ""
#. module: edi
#: help:edi.document,document:0
msgid "EDI document content"
msgstr ""
#. module: edi
#: model:ir.model,name:edi.model_edi_document
msgid "EDI Document"
msgstr "EDI документ"
#. module: edi
#: code:addons/edi/models/edi.py:48
#, python-format
msgid "'%s' is an invalid external ID"
msgstr ""
#. module: edi
#: model:ir.model,name:edi.model_res_partner
msgid "Partner"
msgstr "Контрагент"
#. module: edi
#: code:addons/edi/models/edi.py:152
#, python-format
msgid "Missing Application"
msgstr "Отсутствие приложения"
#. module: edi
#: field:edi.document,document:0
msgid "Document"
msgstr "Документ"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:23
msgid "View/Print"
msgstr "Просмотр/Печать"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:28
msgid "Import this document"
msgstr "Импорт этого документа"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:33
msgid "Import it into an existing OpenERP instance"
msgstr "Импорт в существующую OpenERP"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:36
msgid "OpenERP instance address:"
msgstr "Адрес этой OpenERP:"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:39
msgid "Import"
msgstr "Импорт"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:44
msgid "Import it into a new OpenERP Online instance"
msgstr "Импорт в новый онлайн экземпляр OpenERP"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:47
msgid "Create my new OpenERP instance"
msgstr "Создать мой новый экземпляр OpenERP"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:52
msgid "Import into another application"
msgstr "Импорт в другое приложение"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:54
msgid ""
"OpenERP's Electronic Data Interchange documents are based on a generic and "
"language\n"
" independent"
msgstr ""
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:56
msgid "JSON"
msgstr "JSON"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:56
msgid ""
"serialization of the document's attribute.\n"
" It is usually very quick and straightforward to "
"create a small plug-in for your preferred\n"
" application that will be capable of importing "
"any OpenERP EDI document.\n"
" You can find out more details about how to do "
"this and what the content of OpenERP EDI documents\n"
" is like in the"
msgstr ""
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:60
msgid "OpenERP documentation"
msgstr "OpenERP документация"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:61
msgid "To get started immediately,"
msgstr "Чтобы приступить к работе немедленно,"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:62
msgid "see is all it takes to use this EDI document in Python"
msgstr ""
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:70
msgid "You can download the raw EDI document here:"
msgstr "Вы можете скачать исходный документ EDI здесь:"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:73
msgid "Download"
msgstr "Скачать"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:87
msgid "Powered by"
msgstr "На базе"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi.xml:87
msgid "OpenERP"
msgstr "OpenERP"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:34
msgid "Invoice"
msgstr "Счет"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:37
msgid "Description"
msgstr "Описание"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:38
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:41
msgid "Date"
msgstr "Дата"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:39
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:40
msgid "Your Reference"
msgstr "Ваша ссылка"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:50
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:57
msgid "Product Description"
msgstr "Описание товара"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:51
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:58
msgid "Quantity"
msgstr "Количество"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:52
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:59
msgid "Unit Price"
msgstr "Цена за ед."
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:53
msgid "Discount"
msgstr "Скидка"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:54
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:61
msgid "Price"
msgstr "Цена"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:72
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:81
msgid "Net Total:"
msgstr "Чистый итог:"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:83
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:92
msgid "Taxes:"
msgstr "Налоги:"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:94
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:103
msgid "Total:"
msgstr "Итого:"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:106
msgid "Tax"
msgstr "Налог"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:107
msgid "Base Amount"
msgstr "Базовая сумма"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:108
msgid "Amount"
msgstr "Сумма"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:121
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:113
msgid "Notes:"
msgstr "Примечания:"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:129
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:121
msgid "Pay Online"
msgstr "Оплата онлайн"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:133
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:125
msgid "Paypal"
msgstr "Paypal"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:135
msgid ""
"You may directly pay this invoice online via Paypal's secure payment gateway:"
msgstr ""
"Вы можете напрямую оплатить этот счет в режиме онлайн через безопасный "
"платежный шлюз PayPal:"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:145
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:137
msgid "Bank Wire Transfer"
msgstr "Банковский перевод"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:147
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:139
msgid "Please transfer"
msgstr "Пожалуйста, переведите"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:148
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:140
msgid "to"
msgstr ""
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:149
msgid ""
"(postal address on the invoice header)\n"
" using one of the following bank accounts. Be sure to "
"mention the invoice\n"
" reference"
msgstr ""
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_account.xml:151
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:143
msgid "on the transfer:"
msgstr ""
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:36
msgid "Order"
msgstr "Заказ"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:42
msgid "Salesman"
msgstr "Менеджер продаж"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:43
msgid "Payment terms"
msgstr "Условия платежа"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:60
msgid "Discount(%)"
msgstr "Скидка ( %)"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:127
msgid ""
"You may directly pay this order online via Paypal's secure payment gateway:"
msgstr ""
"Вы можете напрямую оплатить этот заказ он-лайн через безопасный платежный "
"шлюз PayPal:"
#. openerp-web
#: /home/odo/repositories/addons/trunk/edi/static/src/xml/edi_sale_purchase.xml:141
msgid ""
"(postal address on the order header)\n"
" using one of the following bank accounts. Be sure to "
"mention the document\n"
" reference"
msgstr ""

View File

@ -20,7 +20,7 @@
<field name="email_cc" readonly="1" attrs="{'invisible':[('email_cc','=',False)]}"/>
<field name="reply_to" readonly="1" attrs="{'invisible':[('reply_to','=',False)]}"/>
<field name="subject" readonly="1"/>
<field name="body_html" widget="html" readonly="1"/>
<field name="body_html" widget="html" readonly="1" options='{"safe": true}'/>
</group>
</form>
</field>

View File

@ -51,9 +51,11 @@ class mail_compose_message(osv.osv_memory):
context = {}
result = super(mail_compose_message, self).default_get(cr, uid, fields, context=context)
result['template_id'] = context.get('default_template_id', context.get('mail.compose.template_id', False))
# force html when using templates
# pre-render the template if any
if result.get('use_template'):
result['content_subtype'] = 'html'
onchange_res = self.onchange_use_template(cr, uid, [], result.get('use_template'), result.get('template_id'),
result.get('composition_mode'), result.get('model'), result.get('res_id'), context=context)
result.update(onchange_res['value'])
return result
_columns = {

View File

@ -11,14 +11,14 @@
<xpath expr="//form/footer/button" position="before">
<field name="use_template" invisible="1"/>
<button icon="gtk-paste" type="object" name="toggle_template"
string="" help="Use a message template" />
string="" help="Use a message template" invisible="1"/>
<button icon="gtk-save" type="object" name="save_as_template"
string="" help="Save as a new template"/>
string="" help="Save as a new template" invisible="1"/>
</xpath>
<xpath expr="//form/notebook" position="after">
<group attrs="{'invisible':[('use_template','=',False)]}" colspan="4" col="4">
<field name="use_template" invisible="1"/>
<field name="template_id" colspan="3"
<field name="template_id" colspan="3" invisible="1"
on_change="onchange_template_id(use_template, template_id, composition_mode, model, res_id, context)"/>
</group>
</xpath>

View File

@ -0,0 +1,114 @@
# Norwegian Bokmal translation for openobject-addons
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
"PO-Revision-Date: 2012-09-07 17:58+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Norwegian Bokmal <nb@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-09-08 04:54+0000\n"
"X-Generator: Launchpad (build 15914)\n"
#. module: event_project
#: model:ir.model,name:event_project.model_event_project
msgid "Event Project"
msgstr "Arrangement Prosjekt"
#. module: event_project
#: field:event.project,date:0
msgid "Date End"
msgstr "Sluttdato"
#. module: event_project
#: view:event.project:0
msgid "Ok"
msgstr "Ok"
#. module: event_project
#: help:event.project,project_id:0
msgid ""
"This is Template Project. Project of event is a duplicate of this Template. "
"After click on 'Create Retro-planning', New Project will be duplicated from "
"this template project."
msgstr ""
"Dette er ett mal Prosjekt. Prosjektet av arrangementet er en dublett av "
"denne malen. Etter klikk på \"Create Retro-planlegging\", vil New Project "
"dupliseres fra denne malen prosjektet."
#. module: event_project
#: view:event.project:0
#: model:ir.actions.act_window,name:event_project.action_event_project
msgid "Retro-Planning"
msgstr "Retro-Planlegging"
#. module: event_project
#: constraint:event.event:0
msgid "Error ! Closing Date cannot be set before Beginning Date."
msgstr "Feil ! Sluttdato kan ikke settes før startdato."
#. module: event_project
#: field:event.event,project_id:0
msgid "Project"
msgstr "Prosjekt"
#. module: event_project
#: field:event.project,project_id:0
msgid "Template of Project"
msgstr "Mal av prosjekt"
#. module: event_project
#: view:event.event:0
msgid "All tasks"
msgstr "Alle oppgaver"
#. module: event_project
#: view:event.event:0
#: model:ir.actions.act_window,name:event_project.act_event_task
msgid "Tasks"
msgstr "Oppgaver"
#. module: event_project
#: constraint:event.event:0
msgid "Error ! You cannot create recursive event."
msgstr "Feil! Du kan ikke opprette rekursive hendelse."
#. module: event_project
#: field:event.event,task_ids:0
msgid "Project tasks"
msgstr "Prosjektoppgaver"
#. module: event_project
#: view:event.project:0
msgid "Close"
msgstr "Lukke"
#. module: event_project
#: field:event.project,date_start:0
msgid "Date Start"
msgstr "Startdato"
#. module: event_project
#: view:event.event:0
msgid "Create Retro-Planning"
msgstr "Opprett Retro - planlegging."
#. module: event_project
#: model:ir.model,name:event_project.model_event_event
msgid "Event"
msgstr "Arrangement"
#. module: event_project
#: view:event.event:0
msgid "Tasks Management"
msgstr ""
#~ msgid "Tasks management"
#~ msgstr "Oppgaver ledelse"

335
addons/fetchmail/i18n/nb.po Normal file
View File

@ -0,0 +1,335 @@
# Norwegian Bokmal translation for openobject-addons
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
"PO-Revision-Date: 2012-09-08 18:59+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Norwegian Bokmal <nb@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-09-09 04:52+0000\n"
"X-Generator: Launchpad (build 15914)\n"
#. module: fetchmail
#: selection:fetchmail.server,state:0
msgid "Confirmed"
msgstr "Bekreftet"
#. module: fetchmail
#: field:fetchmail.server,server:0
msgid "Server Name"
msgstr "Tjener navn"
#. module: fetchmail
#: field:fetchmail.server,script:0
msgid "Script"
msgstr "Manus"
#. module: fetchmail
#: help:fetchmail.server,priority:0
msgid "Defines the order of processing, lower values mean higher priority"
msgstr ""
"Definerer rekkefølgen av behandlingen, lavere verdier betyr høyere prioritet."
#. module: fetchmail
#: help:fetchmail.server,is_ssl:0
msgid ""
"Connections are encrypted with SSL/TLS through a dedicated port (default: "
"IMAPS=993, POP3S=995)"
msgstr ""
"Tilkoblinger er kryptert med SSL / TLS gjennom en egen port (standard: IMAPS "
"= 993, POP3S = 995)"
#. module: fetchmail
#: field:fetchmail.server,attach:0
msgid "Keep Attachments"
msgstr "Hold Vedlegg"
#. module: fetchmail
#: help:fetchmail.server,original:0
msgid ""
"Whether a full original copy of each email should be kept for referenceand "
"attached to each processed message. This will usually double the size of "
"your message database."
msgstr ""
"Om en full original kopi av hver e-post bør holdes for referenceand festet "
"til hver bearbeidet melding. Dette vil vanligvis doble størrelsen på "
"meldingen database."
#. module: fetchmail
#: field:fetchmail.server,priority:0
msgid "Server Priority"
msgstr "Tjener prioritet."
#. module: fetchmail
#: field:fetchmail.server,state:0
msgid "State"
msgstr "Stat"
#. module: fetchmail
#: view:fetchmail.server:0
msgid "POP"
msgstr "POP"
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Fetch Now"
msgstr "Hente nå."
#. module: fetchmail
#: model:ir.actions.act_window,name:fetchmail.action_email_server_tree
#: model:ir.ui.menu,name:fetchmail.menu_action_fetchmail_server_tree
msgid "Incoming Mail Servers"
msgstr "Innkommende Mail Tjenere."
#. module: fetchmail
#: field:fetchmail.server,port:0
msgid "Port"
msgstr "Port"
#. module: fetchmail
#: view:fetchmail.server:0
msgid "POP/IMAP Servers"
msgstr "POP/IMAP tjenere."
#. module: fetchmail
#: selection:fetchmail.server,type:0
msgid "Local Server"
msgstr "Lokal tjener."
#. module: fetchmail
#: field:fetchmail.server,user:0
msgid "Username"
msgstr "Brukernavn:"
#. module: fetchmail
#: model:ir.model,name:fetchmail.model_fetchmail_server
msgid "POP/IMAP Server"
msgstr "POP/IMAP Tjener."
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Reset Confirmation"
msgstr "Tilbakestille Bekreftelse."
#. module: fetchmail
#: view:fetchmail.server:0
msgid "SSL"
msgstr "SSL"
#. module: fetchmail
#: model:ir.model,name:fetchmail.model_mail_message
msgid "Email Message"
msgstr "E-post Melding."
#. module: fetchmail
#: field:fetchmail.server,date:0
msgid "Last Fetch Date"
msgstr "Siste Hente Dato."
#. module: fetchmail
#: help:fetchmail.server,action_id:0
msgid ""
"Optional custom server action to trigger for each incoming mail, on the "
"record that was created or updated by this mail"
msgstr ""
"Ekstra tilpasset server tiltak for å utløse for hver innkommende e-post, på "
"plata som ble opprettet eller oppdatert i denne posten."
#. module: fetchmail
#: view:fetchmail.server:0
msgid "# of emails"
msgstr "# Av e-post."
#. module: fetchmail
#: field:fetchmail.server,original:0
msgid "Keep Original"
msgstr "Hold Original"
#. module: fetchmail
#: code:addons/fetchmail/fetchmail.py:155
#, python-format
msgid ""
"Here is what we got instead:\n"
" %s"
msgstr ""
"Her er hva vi fikk i stedet:\n"
"  % s"
#. module: fetchmail
#: view:fetchmail.server:0
#: field:fetchmail.server,configuration:0
msgid "Configuration"
msgstr "Konfigurasjon"
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Incoming Mail Server"
msgstr "Innkommende E-post tjener."
#. module: fetchmail
#: code:addons/fetchmail/fetchmail.py:155
#, python-format
msgid "Connection test failed!"
msgstr "Tilkoblingen var mislykket!"
#. module: fetchmail
#: help:fetchmail.server,server:0
msgid "Hostname or IP of the mail server"
msgstr "Vertsnavn eller IP for e-postserveren."
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Server type IMAP."
msgstr "Tjener type IMAP."
#. module: fetchmail
#: field:fetchmail.server,name:0
msgid "Name"
msgstr "Navn"
#. module: fetchmail
#: field:fetchmail.server,is_ssl:0
msgid "SSL/TLS"
msgstr "SSL/TLS"
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Test & Confirm"
msgstr "Test & Bekreft"
#. module: fetchmail
#: field:fetchmail.server,action_id:0
msgid "Server Action"
msgstr "Tjenerhandling"
#. module: fetchmail
#: field:mail.message,fetchmail_server_id:0
msgid "Inbound Mail Server"
msgstr "Inngående E-post tjener."
#. module: fetchmail
#: field:fetchmail.server,message_ids:0
#: model:ir.actions.act_window,name:fetchmail.act_server_history
msgid "Messages"
msgstr "Meldinger"
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Search Incoming Mail Servers"
msgstr "Søk innkommende post tjenere."
#. module: fetchmail
#: field:fetchmail.server,active:0
msgid "Active"
msgstr "Aktiv"
#. module: fetchmail
#: help:fetchmail.server,attach:0
msgid ""
"Whether attachments should be downloaded. If not enabled, incoming emails "
"will be stripped of any attachments before being processed"
msgstr ""
"Om vedlegg skal lastes ned. Hvis ikke er aktivert, vil innkommende e-post "
"blir fratatt eventuelle vedlegg før de behandles."
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Advanced Options"
msgstr ""
#. module: fetchmail
#: selection:fetchmail.server,type:0
msgid "IMAP Server"
msgstr "IMAP-tjener"
#. module: fetchmail
#: view:fetchmail.server:0
msgid "IMAP"
msgstr "IMAP"
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Server type POP."
msgstr "Tjener type POP."
#. module: fetchmail
#: field:fetchmail.server,password:0
msgid "Password"
msgstr "Passord:"
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Actions to Perform on Incoming Mails"
msgstr "Tiltak for å utføre på innkommende post."
#. module: fetchmail
#: field:fetchmail.server,type:0
msgid "Server Type"
msgstr "Tjener Type."
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Login Information"
msgstr "Inn loggings informasjon."
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Server Information"
msgstr "Tjenerinformasjon"
#. module: fetchmail
#: view:fetchmail.server:0
msgid "If SSL required."
msgstr "Hvis SSL nødvendig."
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Advanced"
msgstr "Avansert"
#. module: fetchmail
#: view:fetchmail.server:0
msgid "Server & Login"
msgstr "Tjener og Logg inn."
#. module: fetchmail
#: help:fetchmail.server,object_id:0
msgid ""
"Process each incoming mail as part of a conversation corresponding to this "
"document type. This will create new documents for new conversations, or "
"attach follow-up emails to the existing conversations (documents)."
msgstr ""
"Behandle hver innkommende post som del av en samtale tilsvarende denne "
"dokumenttypen. Dette vil skape nye dokumenter for nye samtaler, eller legge "
"oppfølging e-post til de eksisterende samtaler (dokumenter)."
#. module: fetchmail
#: field:fetchmail.server,object_id:0
msgid "Create a New Record"
msgstr "Oppretter en ny oppføring."
#. module: fetchmail
#: selection:fetchmail.server,state:0
msgid "Not Confirmed"
msgstr "Ikke bekreftet."
#. module: fetchmail
#: selection:fetchmail.server,type:0
msgid "POP Server"
msgstr "POP tjener."
#. module: fetchmail
#: view:mail.message:0
msgid "Mail Server"
msgstr "E-posttjener"
#~ msgid "Advanced options"
#~ msgstr "Avanserte alternativer"

View File

@ -0,0 +1,122 @@
# Norwegian Bokmal translation for openobject-addons
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
"PO-Revision-Date: 2012-09-07 19:23+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Norwegian Bokmal <nb@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-09-08 04:54+0000\n"
"X-Generator: Launchpad (build 15914)\n"
#. module: google_base_account
#: field:res.users,gmail_user:0
msgid "Username"
msgstr "Brukernavn:"
#. module: google_base_account
#: model:ir.actions.act_window,name:google_base_account.act_google_login_form
msgid "Google Login"
msgstr "Google Logg inn"
#. module: google_base_account
#: code:addons/google_base_account/wizard/google_login.py:29
#, python-format
msgid "Google Contacts Import Error!"
msgstr "Google kontakter Import Feil!"
#. module: google_base_account
#: view:res.users:0
msgid " Synchronization "
msgstr " Synkronisering "
#. module: google_base_account
#: sql_constraint:res.users:0
msgid "You can not have two users with the same login !"
msgstr "Du kan ikke ha to brukere med samme login!"
#. module: google_base_account
#: code:addons/google_base_account/wizard/google_login.py:75
#, python-format
msgid "Error"
msgstr "Feil"
#. module: google_base_account
#: view:google.login:0
msgid "Google login"
msgstr "Google Logg Inn."
#. module: google_base_account
#: model:ir.model,name:google_base_account.model_res_users
msgid "res.users"
msgstr "res.Brukere."
#. module: google_base_account
#: field:google.login,password:0
msgid "Google Password"
msgstr "Google passord."
#. module: google_base_account
#: view:google.login:0
msgid "_Cancel"
msgstr "_Avbryt"
#. module: google_base_account
#: view:res.users:0
msgid "Google Account"
msgstr "Google-konto"
#. module: google_base_account
#: field:google.login,user:0
msgid "Google Username"
msgstr "Google Brukernavn."
#. module: google_base_account
#: code:addons/google_base_account/wizard/google_login.py:29
#, python-format
msgid ""
"Please install gdata-python-client from http://code.google.com/p/gdata-"
"python-client/downloads/list"
msgstr ""
"Vennligst Installer gdata-python-client from http://code.google.com/p/gdata-"
"python-client/downloads/list"
#. module: google_base_account
#: model:ir.model,name:google_base_account.model_google_login
msgid "Google Contact"
msgstr "Google kontakt"
#. module: google_base_account
#: view:google.login:0
msgid "_Login"
msgstr "_Logg inn"
#. module: google_base_account
#: constraint:res.users:0
msgid "The chosen company is not in the allowed companies for this user"
msgstr ""
"Det valgte firmaet er ikke i listen over tillatte firmaer for denne brukeren"
#. module: google_base_account
#: field:res.users,gmail_password:0
msgid "Password"
msgstr "Passord:"
#. module: google_base_account
#: code:addons/google_base_account/wizard/google_login.py:75
#, python-format
msgid "Authentication fail check the user and password !"
msgstr "Autentisering mislykkes sjekk brukernavn og passord!"
#. module: google_base_account
#: view:google.login:0
msgid "ex: user@gmail.com"
msgstr "Ex:Bruker@gmail.com"

View File

@ -180,17 +180,16 @@ class hr_employee(osv.osv):
'resource_id': fields.many2one('resource.resource', 'Resource', ondelete='cascade', required=True),
'coach_id': fields.many2one('hr.employee', 'Coach'),
'job_id': fields.many2one('hr.job', 'Job'),
# image: all image fields are base64 encoded and PIL-supported
'image': fields.binary("Photo",
help="This field holds the image used as a photo for the "\
"employee. The image is base64 encoded, and PIL-supported. "\
"It is limited to a 1024x1024 px image."),
help="This field holds the image used as photo for the employee, limited to 1024x1024px."),
'image_medium': fields.function(_get_image, fnct_inv=_set_image,
string="Medium-sized photo", type="binary", multi="_get_image",
store = {
'hr.employee': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
},
help="Medium-sized photo of the employee. It is automatically "\
"resized as a 180x180 px image, with aspect ratio preserved. "\
"resized as a 128x128px image, with aspect ratio preserved. "\
"Use this field in form views or some kanban views."),
'image_small': fields.function(_get_image, fnct_inv=_set_image,
string="Smal-sized photo", type="binary", multi="_get_image",
@ -198,7 +197,7 @@ class hr_employee(osv.osv):
'hr.employee': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
},
help="Small-sized photo of the employee. It is automatically "\
"resized as a 50x50 px image, with aspect ratio preserved. "\
"resized as a 64x64px image, with aspect ratio preserved. "\
"Use this field anywhere a small image is required."),
'passport_id':fields.char('Passport No', size=64),
'color': fields.integer('Color Index'),
@ -290,8 +289,12 @@ class hr_department(osv.osv):
'member_ids': fields.one2many('hr.employee', 'department_id', 'Members', readonly=True),
}
hr_department()
def copy(self, cr, uid, ids, default=None, context=None):
if default is None:
default = {}
default = default.copy()
default['member_ids'] = []
return super(hr_department, self).copy(cr, uid, ids, default, context=context)
class res_users(osv.osv):
_name = 'res.users'

View File

@ -20,16 +20,12 @@
<field name="arch" type="xml">
<form string="Employee" version="7.0">
<sheet>
<field name="image_medium" widget='image' class="oe_right oe_avatar"/>
<field name="image_medium" widget='image' class="oe_left oe_avatar"/>
<div class="oe_title">
<label for="name" class="oe_edit_only"/>
<h1>
<field name="name"/>
</h1>
<label for="job_id" class="oe_edit_only"/>
<h2>
<field name="job_id" options='{"no_open": true}' domain="[('state','!=','old')]" context="{'form_view_ref': 'hr.view_hr_job_employee_form'}"/>
</h2>
<label for="category_ids" class="oe_edit_only"/>
<field name="category_ids" widget="many2many_tags" placeholder="e.g. Part Time"/>
</div>
@ -37,44 +33,55 @@
<!-- Put here related buttons -->
</div>
<notebook>
<page string="Information">
<page string="Public Information">
<group>
<group>
<group string="Contact Information">
<field name="work_email" widget="email"/>
<field name="work_phone"/>
<field name="mobile_phone"/>
</group>
<group string="Position">
<field name="department_id" on_change="onchange_department_id(department_id)"/>
<field name="company_id" groups="base.group_multi_company" on_change="onchange_company(company_id)"/>
<field name="user_id" on_change="onchange_user(user_id)"/>
<field name="job_id" options='{"no_open": true}' domain="[('state','!=','old')]" context="{'form_view_ref': 'hr.view_hr_job_employee_form'}"/>
<field name="parent_id"/>
<field name="coach_id"/>
</group>
<group>
<field name="work_email" widget="email"/>
<field name="work_phone"/>
<field name="address_id" on_change="onchange_address_id(address_id)"/>
<field name="mobile_phone"/>
<field name="identification_id" groups="base.group_hr_user"/>
<field name="passport_id" groups="base.group_hr_user"/>
<field name="otherid" groups="base.group_hr_user"/>
</group>
<group name="active_group">
<field name="active"/>
<field name="company_id" groups="base.group_multi_company" on_change="onchange_company(company_id)"/>
<field name="user_id" on_change="onchange_user(user_id)" string="Related User"/>
<field name="address_id" on_change="onchange_address_id(address_id)" context="{'show_address': 1}" options='{"always_reload": true, "highlight_first_line": true}'/>
</group>
</group>
<field name="notes" placeholder="Other Information ..." colspan="4"/>
</page>
<page string="Personal Information" groups="base.group_hr_user">
<group col="4">
<group>
<group>
<group string="Citizenship &amp; Other Info">
<field name="country_id" options='{"no_open": true}'/>
<field name="identification_id" groups="base.group_hr_user"/>
<field name="passport_id" groups="base.group_hr_user"/>
<field name="bank_account_id"/>
<field name="address_home_id"/>
<field name="otherid" groups="base.group_hr_user"/>
</group>
<group>
<group string="Contact Information">
<field name="address_home_id" context="{'show_address': 1}" options='{"always_reload": true, "highlight_first_line": true}'/>
</group>
<group string="Status">
<field name="gender"/>
<field name="marital"/>
</group>
<group string="Birth">
<field name="birthday"/>
</group>
</group>
</page>
<page string="HR Settings" groups="base.group_hr_user">
<group>
<group string="Active" name="active_group">
<field name="active"/>
</group>
</group>
</page>
</notebook>
</sheet>
</form>

View File

@ -2,13 +2,19 @@
<openerp>
<data noupdate="1">
<record model="res.groups" id="base.group_user">
<field name="comment">the user will be able to manage his own human resources stuff (leave request, timesheets, ...), if he is linked to an employee in the system.</field>
</record>
<record id="base.group_hr_user" model="res.groups">
<field name="name">Officer</field>
<field name="category_id" ref="base.module_category_human_resources"/>
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
<field name="comment">the user will be able to approve document created by employees.</field>
</record>
<record id="base.group_hr_manager" model="res.groups">
<field name="name">Manager</field>
<field name="comment">the user will have an access to the human resources configuration as well as statistic reports.</field>
<field name="category_id" ref="base.module_category_human_resources"/>
<field name="implied_ids" eval="[(4, ref('base.group_hr_user'))]"/>
<field name="users" eval="[(4, ref('base.user_root'))]"/>

View File

@ -43,7 +43,6 @@ actions(Sign in/Sign out) performed by them.
'wizard/hr_attendance_bymonth_view.xml',
'wizard/hr_attendance_byweek_view.xml',
'wizard/hr_attendance_error_view.xml',
'wizard/hr_attendance_sign_in_out_view.xml',
],
'demo': ['hr_attendance_demo.xml'],
'test': [
@ -53,5 +52,10 @@ actions(Sign in/Sign out) performed by them.
'installable': True,
'auto_install': False,
'certificate': '0063495605613',
#web
"js": ["static/src/js/attendance.js"],
'qweb' : ["static/src/xml/attendance.xml"],
'css' : ["static/src/css/slider.css"],
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -112,9 +112,23 @@ class hr_employee(osv.osv):
for res in cr.fetchall():
result[res[1]] = res[0] == 'sign_in' and 'present' or 'absent'
return result
def _last_sign(self, cr, uid, ids, name, args, context=None):
result = {}
if not ids:
return result
for id in ids:
result[id] = False
cr.execute("""select max(name) as name
from hr_attendance
where action in ('sign_in', 'sign_out') and employee_id = %s""",(id,))
for res in cr.fetchall():
result[id] = res[0]
return result
_columns = {
'state': fields.function(_state, type='selection', selection=[('absent', 'Absent'), ('present', 'Present')], string='Attendance'),
'last_sign': fields.function(_last_sign, type='datetime', string='Last Sign'),
}
def _action_check(self, cr, uid, emp_id, dt=False, context=None):
@ -122,30 +136,25 @@ class hr_employee(osv.osv):
res = cr.fetchone()
return not (res and (res[0]>=(dt or time.strftime('%Y-%m-%d %H:%M:%S'))))
def attendance_action_change(self, cr, uid, ids, type='action', context=None, dt=False, *args):
obj_attendance = self.pool.get('hr.attendance')
id = False
warning_sign = 'sign'
res = {}
def attendance_action_change(self, cr, uid, ids, context=None):
if context is None:
context = {}
action_date = context.get('action_date', False)
action = context.get('action', False)
hr_attendance = self.pool.get('hr.attendance')
warning_sign = {'sign_in': _('Sign In'), 'sign_out': _('Sign Out')}
for employee in self.browse(cr, uid, ids, context=context):
if not action:
if employee.state == 'present': action = 'sign_out'
if employee.state == 'absent': action = 'sign_in'
#Special case when button calls this method: type=context
if isinstance(type, dict):
type = type.get('type','action')
if type == 'sign_in':
warning_sign = "Sign In"
elif type == 'sign_out':
warning_sign = "Sign Out"
for emp in self.read(cr, uid, ids, ['id'], context=context):
if not self._action_check(cr, uid, emp['id'], dt, context):
raise osv.except_osv(_('Warning!'), _('You tried to %s with a date anterior to another event !\nTry to contact the administrator to correct attendances.')%(warning_sign,))
if not self._action_check(cr, uid, employee.id, action_date, context):
raise osv.except_osv(_('Warning'), _('You tried to %s with a date anterior to another event !\nTry to contact the HR Manager to correct attendances.')%(warning_sign[action],))
res = {'action': type, 'employee_id': emp['id']}
if dt:
res['name'] = dt
id = obj_attendance.create(cr, uid, res, context=context)
if type != 'action':
return id
vals = {'action': action, 'employee_id': employee.id}
if action_date:
vals['name'] = action_date
hr_attendance.create(cr, uid, vals, context=context)
return True
hr_employee()

View File

@ -136,3 +136,5 @@
</data>
</openerp>

View File

@ -0,0 +1,576 @@
# Norwegian Bokmal translation for openobject-addons
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
"PO-Revision-Date: 2012-09-10 13:06+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Norwegian Bokmal <nb@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-09-11 04:50+0000\n"
"X-Generator: Launchpad (build 15924)\n"
#. module: hr_attendance
#: model:ir.ui.menu,name:hr_attendance.menu_hr_time_tracking
msgid "Time Tracking"
msgstr "Tid Sporing"
#. module: hr_attendance
#: view:hr.attendance:0
msgid "Group By..."
msgstr "Grupper etter ..."
#. module: hr_attendance
#: view:hr.attendance:0
msgid "Today"
msgstr "I dag"
#. module: hr_attendance
#: selection:hr.attendance.month,month:0
msgid "March"
msgstr "Mars"
#. module: hr_attendance
#: view:hr.sign.in.out.ask:0
msgid ""
"You did not sign out the last time. Please enter the date and time you "
"signed out."
msgstr ""
"Du logget ikke ut siste gang. Vennligst skriv inn datoen og klokkeslettet du "
"logget ut."
#. module: hr_attendance
#: report:report.hr.timesheet.attendance.error:0
msgid "Total period:"
msgstr "Total periode:"
#. module: hr_attendance
#: field:hr.action.reason,name:0
msgid "Reason"
msgstr "Grunn"
#. module: hr_attendance
#: view:hr.attendance.error:0
msgid "Print Attendance Report Error"
msgstr "Skriv ut Oppmøte Rapporter Feil."
#. module: hr_attendance
#: code:addons/hr_attendance/wizard/hr_attendance_sign_in_out.py:161
#, python-format
msgid "The sign-out date must be in the past"
msgstr "Logg - ut må være i fortiden."
#. module: hr_attendance
#: report:report.hr.timesheet.attendance.error:0
msgid "Date Signed"
msgstr "Signeringsdato"
#. module: hr_attendance
#: model:ir.actions.act_window,help:hr_attendance.open_view_attendance
msgid ""
"The Time Tracking functionality aims to manage employee attendances from "
"Sign in/Sign out actions. You can also link this feature to an attendance "
"device using OpenERP's web service features."
msgstr ""
"Tid Sporing funksjonalitet mål er å forvalte de ansattes tilskuertall fra "
"Logg inn / Logg ut handlinger. Du kan også koble denne funksjonen til en "
"frammøte enheten ved hjelp OpenERP web-service funksjoner."
#. module: hr_attendance
#: view:hr.action.reason:0
msgid "Attendance reasons"
msgstr "Oppmøte grunner"
#. module: hr_attendance
#: view:hr.attendance:0
#: field:hr.attendance,day:0
msgid "Day"
msgstr "Dag"
#. module: hr_attendance
#: selection:hr.employee,state:0
msgid "Present"
msgstr "Presentere"
#. module: hr_attendance
#: model:ir.model,name:hr_attendance.model_hr_sign_in_out_ask
msgid "Ask for Sign In Out"
msgstr "Spør for pålogging ut."
#. module: hr_attendance
#: field:hr.attendance,action_desc:0
#: model:ir.model,name:hr_attendance.model_hr_action_reason
msgid "Action Reason"
msgstr "Handling grunn."
#. module: hr_attendance
#: view:hr.sign.in.out:0
msgid "Ok"
msgstr "Ok"
#. module: hr_attendance
#: view:hr.action.reason:0
msgid "Define attendance reason"
msgstr "Definer frammøte grunn."
#. module: hr_attendance
#: code:addons/hr_attendance/report/attendance_by_month.py:184
#: model:ir.actions.act_window,name:hr_attendance.action_hr_attendance_month
#, python-format
msgid "Attendances By Month"
msgstr "Tilskuertall Pr.mnd"
#. module: hr_attendance
#: field:hr.sign.in.out,name:0
#: field:hr.sign.in.out.ask,name:0
msgid "Employees name"
msgstr "Ansattnavn"
#. module: hr_attendance
#: model:ir.actions.act_window,name:hr_attendance.open_view_attendance_reason
#: model:ir.ui.menu,name:hr_attendance.menu_open_view_attendance_reason
msgid "Attendance Reasons"
msgstr "Oppmøte grunner"
#. module: hr_attendance
#: code:addons/hr_attendance/wizard/hr_attendance_sign_in_out.py:161
#: code:addons/hr_attendance/wizard/hr_attendance_sign_in_out.py:167
#: code:addons/hr_attendance/wizard/hr_attendance_sign_in_out.py:174
#: code:addons/hr_attendance/wizard/hr_attendance_sign_in_out.py:179
#, python-format
msgid "UserError"
msgstr "Brukerfeil"
#. module: hr_attendance
#: field:hr.attendance.error,end_date:0
#: field:hr.attendance.week,end_date:0
msgid "Ending Date"
msgstr "Sluttdato"
#. module: hr_attendance
#: code:addons/hr_attendance/hr_attendance.py:140
#, python-format
msgid "Warning"
msgstr "Advarsel"
#. module: hr_attendance
#: code:addons/hr_attendance/wizard/hr_attendance_sign_in_out.py:174
#, python-format
msgid "The Sign-in date must be in the past"
msgstr "Logg inn dato må være i fortiden."
#. module: hr_attendance
#: code:addons/hr_attendance/wizard/hr_attendance_sign_in_out.py:167
#, python-format
msgid "A sign-in must be right after a sign-out !"
msgstr "En pålogging må være rett etter en logg ut!"
#. module: hr_attendance
#: field:hr.employee,state:0
#: model:ir.model,name:hr_attendance.model_hr_attendance
msgid "Attendance"
msgstr "Oppmøte"
#. module: hr_attendance
#: field:hr.attendance.error,max_delay:0
msgid "Max. Delay (Min)"
msgstr "Maks. Forsinkelse (Min)"
#. module: hr_attendance
#: view:hr.attendance.error:0
#: view:hr.attendance.month:0
#: view:hr.attendance.week:0
msgid "Print"
msgstr "Skriv ut"
#. module: hr_attendance
#: view:hr.attendance:0
msgid "Hr Attendance Search"
msgstr "Hr Oppmøte Søk."
#. module: hr_attendance
#: model:ir.actions.act_window,name:hr_attendance.action_hr_attendance_week
msgid "Attendances By Week"
msgstr "Tilskuertall etter uke."
#. module: hr_attendance
#: constraint:hr.attendance:0
msgid "Error: Sign in (resp. Sign out) must follow Sign out (resp. Sign in)"
msgstr "Feil: Logg på (hhv. Logg ut) må følge Logg ut (hhv. Logg inn)"
#. module: hr_attendance
#: selection:hr.attendance.month,month:0
msgid "July"
msgstr "juli"
#. module: hr_attendance
#: model:ir.actions.act_window,name:hr_attendance.action_hr_attendance_error
#: model:ir.actions.report.xml,name:hr_attendance.attendance_error_report
msgid "Attendance Error Report"
msgstr "Oppmøte Feilrapport"
#. module: hr_attendance
#: field:hr.attendance.error,init_date:0
#: field:hr.attendance.week,init_date:0
msgid "Starting Date"
msgstr "Startdato"
#. module: hr_attendance
#: report:report.hr.timesheet.attendance.error:0
msgid "Min Delay"
msgstr "Minimum forsinkelse."
#. module: hr_attendance
#: selection:hr.attendance,action:0
#: view:hr.employee:0
msgid "Sign In"
msgstr "Logg Inn"
#. module: hr_attendance
#: report:report.hr.timesheet.attendance.error:0
msgid "Operation"
msgstr "Handling"
#. module: hr_attendance
#: code:addons/hr_attendance/wizard/hr_attendance_error.py:49
#, python-format
msgid "No Data Available"
msgstr "Ingen informasjon tilgjengelig"
#. module: hr_attendance
#: selection:hr.attendance.month,month:0
msgid "September"
msgstr "September"
#. module: hr_attendance
#: selection:hr.attendance.month,month:0
msgid "December"
msgstr "Desember"
#. module: hr_attendance
#: field:hr.attendance.month,month:0
msgid "Month"
msgstr "Måned"
#. module: hr_attendance
#: field:hr.action.reason,action_type:0
msgid "Action Type"
msgstr "Handlingstype"
#. module: hr_attendance
#: report:report.hr.timesheet.attendance.error:0
msgid ""
"(*) A negative delay means that the employee worked more than encoded."
msgstr ""
"(*) En negativ forsinkelse innebærer at arbeidstakeren jobbet mer enn kodet."
#. module: hr_attendance
#: view:hr.attendance:0
msgid "My Attendance"
msgstr "Min Oppmøte"
#. module: hr_attendance
#: help:hr.attendance,action_desc:0
msgid ""
"Specifies the reason for Signing In/Signing Out in case of extra hours."
msgstr "Angir årsaken til pålogging / logge ut I tilfelle ekstra timer."
#. module: hr_attendance
#: model:ir.model,name:hr_attendance.model_hr_attendance_month
msgid "Print Monthly Attendance Report"
msgstr "Skriv ut månedlig Oppmøte Rapporter."
#. module: hr_attendance
#: model:ir.model,name:hr_attendance.model_hr_sign_in_out
msgid "Sign In Sign Out"
msgstr "Logg inn - Logg ut"
#. module: hr_attendance
#: code:addons/hr_attendance/wizard/hr_attendance_sign_in_out.py:105
#: code:addons/hr_attendance/wizard/hr_attendance_sign_in_out.py:129
#: code:addons/hr_attendance/wizard/hr_attendance_sign_in_out.py:146
#: view:hr.sign.in.out:0
#: model:ir.actions.act_window,name:hr_attendance.action_hr_attendance_sigh_in_out
#: model:ir.ui.menu,name:hr_attendance.menu_hr_attendance_sigh_in_out
#, python-format
msgid "Sign in / Sign out"
msgstr "Logg inn / Logg ut"
#. module: hr_attendance
#: view:hr.sign.in.out.ask:0
msgid "hr.sign.out.ask"
msgstr "hr.signere.ut.spør."
#. module: hr_attendance
#: view:hr.attendance.week:0
msgid "Print Attendance Report Weekly"
msgstr "Skriv ut Oppmøte Rapporter Ukentlig."
#. module: hr_attendance
#: selection:hr.attendance.month,month:0
msgid "August"
msgstr "August"
#. module: hr_attendance
#: code:addons/hr_attendance/wizard/hr_attendance_sign_in_out.py:179
#, python-format
msgid "A sign-out must be right after a sign-in !"
msgstr "Et logg-ut må være rett etter en logg - inn!"
#. module: hr_attendance
#: selection:hr.attendance.month,month:0
msgid "June"
msgstr "Juni"
#. module: hr_attendance
#: model:ir.model,name:hr_attendance.model_hr_attendance_error
msgid "Print Error Attendance Report"
msgstr "Print Feil Oppmøte Rapporter."
#. module: hr_attendance
#: field:hr.attendance,name:0
msgid "Date"
msgstr "Dato"
#. module: hr_attendance
#: selection:hr.attendance.month,month:0
msgid "November"
msgstr "November"
#. module: hr_attendance
#: constraint:hr.employee:0
msgid "Error ! You cannot create recursive Hierarchy of Employees."
msgstr "Feil! Du kan ikke opprette rekursiv Hierarki av ansatte."
#. module: hr_attendance
#: selection:hr.attendance.month,month:0
msgid "October"
msgstr "Oktober"
#. module: hr_attendance
#: selection:hr.attendance.month,month:0
msgid "January"
msgstr "Januar"
#. module: hr_attendance
#: selection:hr.action.reason,action_type:0
#: view:hr.sign.in.out:0
#: view:hr.sign.in.out.ask:0
msgid "Sign in"
msgstr "Logg inn"
#. module: hr_attendance
#: view:hr.attendance.error:0
msgid "Analysis Information"
msgstr "Analyse Informasjon."
#. module: hr_attendance
#: view:hr.sign.in.out:0
msgid "Sign-out Entry Must Follow Sign-in."
msgstr ""
#. module: hr_attendance
#: report:report.hr.timesheet.attendance.error:0
msgid "Attendance Errors"
msgstr "Oppmøte feil"
#. module: hr_attendance
#: field:hr.attendance,action:0
#: selection:hr.attendance,action:0
msgid "Action"
msgstr "Handling"
#. module: hr_attendance
#: view:hr.sign.in.out:0
msgid ""
"If you need your staff to sign in when they arrive at work and sign out "
"again at the end of the day, OpenERP allows you to manage this with this "
"tool. If each employee has been linked to a system user, then they can "
"encode their time with this action button."
msgstr ""
"Hvis du trenger dine ansatte til å logge på når de kommer på jobb og logge "
"ut igjen på slutten av dagen, kan OpenERP tillate deg å administrere dette "
"med dette verktøyet. Hvis hver ansatt har vært knyttet til et system bruker, "
"så de kan kode sin tid med denne handlingen knappen."
#. module: hr_attendance
#: model:ir.model,name:hr_attendance.model_hr_attendance_week
msgid "Print Week Attendance Report"
msgstr "Skriv Ut Uke Oppmøte Rapporter."
#. module: hr_attendance
#: field:hr.sign.in.out,emp_id:0
#: field:hr.sign.in.out.ask,emp_id:0
msgid "Empoyee ID"
msgstr "Ansatt ID"
#. module: hr_attendance
#: view:hr.attendance.error:0
#: view:hr.attendance.month:0
#: view:hr.attendance.week:0
#: view:hr.sign.in.out:0
#: view:hr.sign.in.out.ask:0
msgid "Cancel"
msgstr "Avbryt"
#. module: hr_attendance
#: help:hr.action.reason,name:0
msgid "Specifies the reason for Signing In/Signing Out."
msgstr "Angir årsaken til pålogging / logger av."
#. module: hr_attendance
#: report:report.hr.timesheet.attendance.error:0
msgid ""
"(*) A positive delay means that the employee worked less than recorded."
msgstr ""
"(*) En positiv forsinkelse innebærer at arbeidstakeren jobbet mindre enn "
"registrert."
#. module: hr_attendance
#: view:hr.attendance.month:0
msgid "Print Attendance Report Monthly"
msgstr "Skriv ut Oppmøte Rapporter Månedlig."
#. module: hr_attendance
#: selection:hr.action.reason,action_type:0
#: view:hr.sign.in.out:0
#: view:hr.sign.in.out.ask:0
msgid "Sign out"
msgstr "Logg av"
#. module: hr_attendance
#: report:report.hr.timesheet.attendance.error:0
msgid "Delay"
msgstr "Forsinkelse"
#. module: hr_attendance
#: view:hr.attendance:0
#: model:ir.model,name:hr_attendance.model_hr_employee
msgid "Employee"
msgstr "Ansatt"
#. module: hr_attendance
#: code:addons/hr_attendance/hr_attendance.py:140
#, python-format
msgid ""
"You tried to %s with a date anterior to another event !\n"
"Try to contact the administrator to correct attendances."
msgstr ""
"Du prøvde å% s med en dato fremre til en annen hendelse!\n"
"Prøv å kontakte administrator for å rette tilskuertall."
#. module: hr_attendance
#: view:hr.sign.in.out.ask:0
#: field:hr.sign.in.out.ask,last_time:0
msgid "Your last sign out"
msgstr "Din siste Logg ut."
#. module: hr_attendance
#: report:report.hr.timesheet.attendance.error:0
msgid "Date Recorded"
msgstr "Dato Innspilt"
#. module: hr_attendance
#: model:ir.actions.act_window,name:hr_attendance.open_view_attendance
#: model:ir.ui.menu,name:hr_attendance.menu_hr_attendance
#: model:ir.ui.menu,name:hr_attendance.menu_open_view_attendance
msgid "Attendances"
msgstr "Tilskuertall"
#. module: hr_attendance
#: selection:hr.attendance.month,month:0
msgid "May"
msgstr "Mai"
#. module: hr_attendance
#: view:hr.sign.in.out.ask:0
msgid "Your last sign in"
msgstr "Din siste logg inn."
#. module: hr_attendance
#: selection:hr.attendance,action:0
#: view:hr.employee:0
msgid "Sign Out"
msgstr "Logg Ut"
#. module: hr_attendance
#: model:ir.actions.act_window,help:hr_attendance.action_hr_attendance_sigh_in_out
msgid ""
"Sign in / Sign out. In some companies, staff have to sign in when they "
"arrive at work and sign out again at the end of the day. If each employee "
"has been linked to a system user, then they can encode their time with this "
"action button."
msgstr ""
"Logg inn / Logg ut. I noen bedrifter, ansatte må logge inn når de kommer på "
"jobb og Logg ut igjen på slutten av dagen. Hvis hver ansatt har vært knyttet "
"til et system bruker, så de kan kode sin tid med denne handlingen knappen."
#. module: hr_attendance
#: field:hr.attendance,employee_id:0
msgid "Employee's Name"
msgstr "Ansatte's navn."
#. module: hr_attendance
#: selection:hr.employee,state:0
msgid "Absent"
msgstr "Fraværende"
#. module: hr_attendance
#: selection:hr.attendance.month,month:0
msgid "February"
msgstr "Februar"
#. module: hr_attendance
#: view:hr.attendance:0
msgid "Employee attendances"
msgstr "Ansattes tilskuertall"
#. module: hr_attendance
#: field:hr.sign.in.out,state:0
msgid "Current state"
msgstr "Nåværende tilstand."
#. module: hr_attendance
#: selection:hr.attendance.month,month:0
msgid "April"
msgstr "April"
#. module: hr_attendance
#: view:hr.attendance.error:0
msgid "Bellow this delay, the error is considered to be voluntary"
msgstr "Under denne forsinkelsen, er feilen anses å være frivillig."
#. module: hr_attendance
#: code:addons/hr_attendance/wizard/hr_attendance_error.py:49
#, python-format
msgid "No records found for your selection!"
msgstr "Ingen rader funnet med angitt utvalg!"
#. module: hr_attendance
#: view:hr.sign.in.out.ask:0
msgid ""
"You did not sign in the last time. Please enter the date and time you signed "
"in."
msgstr ""
"Du hadde ikke logget ut siste gang. Vennligst skriv inn datoen og "
"klokkeslettet du logget."
#. module: hr_attendance
#: field:hr.attendance.month,year:0
msgid "Year"
msgstr "År"
#. module: hr_attendance
#: view:hr.sign.in.out.ask:0
msgid "hr.sign.in.out.ask"
msgstr "hr.Logg.i.ut.spør"
#~ msgid "Sign-Out Entry must follow Sign-In."
#~ msgstr "Logg ut Entry må følge pålogging."

View File

@ -0,0 +1,33 @@
.openerp .oe_attendance_status {
height: 32px;
width: 32px;
display: inline-block;
}
.openerp .oe_attendance_signin {
float:left;
height: 32px;
width: 32px;
background: url(/hr_attendance/static/src/img/emp-out32.png);
cursor: pointer;
}
.openerp .oe_attendance_signin:hover {
background: url(/hr_attendance/static/src/img/emp-out-disable32.png);
}
.openerp .oe_attendance_status.oe_attendance_signed .oe_attendance_signin {
display: none;
}
.openerp .oe_attendance_signout {
float:right;
height: 32px;
width: 32px;
background: url(/hr_attendance/static/src/img/emp-in32.png);
cursor: pointer;
}
.openerp .oe_attendance_signout:hover {
background: url(/hr_attendance/static/src/img/emp-in-disable32.png);
}
.openerp .oe_attendance_status.oe_attendance_nosigned .oe_attendance_signout {
display: none;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,84 @@
openerp.hr_attendance = function (instance) {
var QWeb = instance.web.qweb;
var _t = instance.web._t;
var _lt = instance.web._lt;
instance.hr_attendance.AttendanceSlider = instance.web.Widget.extend({
template: 'AttendanceSlider',
init: function (parent) {
this._super(parent);
this.set({"signed_in": false});
},
start: function() {
var self = this;
var tmp = function() {
this.$el.toggleClass("oe_attendance_nosigned", ! this.get("signed_in"));
this.$el.toggleClass("oe_attendance_signed", this.get("signed_in"));
};
this.on("change:signed_in", this, tmp);
_.bind(tmp, this)();
this.$(".oe_attendance_signin").click(function() {
self.do_update_attendance();
});
this.$(".oe_attendance_signout").click(function() {
self.do_update_attendance();
});
this.$el.tipsy({
title: function() {
var last_text = instance.web.format_value(self.last_sign, {type: "datetime"});
var current_text = instance.web.format_value(new Date(), {type: "datetime"});
var duration = self.last_sign ? $.timeago(self.last_sign) : "none";
if (self.get("signed_in")) {
return _.str.sprintf(_t("Last sign in: %s,<br />%s.<br />Click to sign out."), last_text, duration);
} else {
return _.str.sprintf(_t("Click to Sign In at %s."), current_text);
}
},
html: true,
});
return this.check_attendance();
},
do_update_attendance: function () {
var self = this;
var hr_employee = new instance.web.DataSet(self, 'hr.employee');
hr_employee.call('attendance_action_change', [
[self.employee.id]
]).done(function (result) {
self.last_sign = new Date();
self.set({"signed_in": ! self.get("signed_in")});
});
},
check_attendance: function () {
var self = this;
self.employee = false;
this.$el.hide();
var employee = new instance.web.DataSetSearch(self, 'hr.employee', self.session.user_context, [
['user_id', '=', self.session.uid]
]);
return employee.read_slice(['id', 'name', 'state', 'last_sign']).pipe(function (res) {
if (_.isEmpty(res))
return;
self.$el.show();
self.employee = res[0];
self.last_sign = instance.web.str_to_datetime(self.employee.last_sign);
self.set({"signed_in": self.employee.state !== "absent"});
});
},
});
instance.web.UserMenu.include({
do_update: function () {
this._super();
var self = this;
this.update_promise = this.update_promise.then(function () {
if (self.attendanceslider)
return;
self.attendanceslider = new instance.hr_attendance.AttendanceSlider(self);
self.attendanceslider.prependTo(instance.webclient.$('.oe_systray'));
});
},
});
}

View File

@ -0,0 +1,13 @@
<template>
<t t-name="AttendanceSlider">
<div class="oe_attendance_status oe_attendance_nosigned" data-tipsy="true">
<div class="oe_attendance_signin"></div>
<div class="oe_attendance_signout"></div>
</div>
</t>
</template>

View File

@ -1,16 +1,8 @@
-
In order to test attendance process in OpenERP, I entry of SignIn of employee.
-
!python {model: hr.sign.in.out}: |
context.update({'emp_id': [ref('hr.employee_al')]}) #TOFIX: emp_ids instead of 'emp_id'
-
!record {model: hr.sign.in.out, id: employee_sign_in}:
{}
-
Employee Signs In.
-
!python {model: hr.sign.in.out}: |
self.si_check(cr, uid, [ref("employee_sign_in")], context=context)
!python {model: hr.employee}: |
self.attendance_action_change(cr, uid, [ref("hr.employee_al")], context=context)
-
I check that Employee is "Present".
-
@ -19,10 +11,10 @@
-
After few seconds, employee sign's out.
-
!python {model: hr.sign.in.out}: |
!python {model: hr.employee}: |
import time
time.sleep(2)
self.so_check(cr, uid, [ref("employee_sign_in")], context=context)
self.attendance_action_change(cr, uid, [ref("hr.employee_al")], context=context)
-
I check that Employee is "Absent".
-

View File

@ -19,9 +19,8 @@
#
##############################################################################
import hr_attendance_sign_in_out
import hr_attendance_error
import hr_attendance_byweek
import hr_attendance_bymonth
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,184 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import time
from osv import osv, fields
from tools.translate import _
class hr_si_so_ask(osv.osv_memory):
_name = 'hr.sign.in.out.ask'
_description = 'Ask for Sign In Out'
_columns = {
'name': fields.char('Employees name', size=32, required=True, readonly=True),
'last_time': fields.datetime('Your last sign out', required=True),
'emp_id': fields.many2one('hr.employee', 'Empoyee ID', readonly=True),
}
def _get_empname(self, cr, uid, context=None):
emp_id = context.get('emp_id', self.pool.get('hr.employee').search(cr, uid, [('user_id', '=', uid)], context=context))
if emp_id:
employee = self.pool.get('hr.employee').browse(cr, uid, emp_id, context=context)[0].name
return employee
return ''
def _get_empid(self, cr, uid, context=None):
emp_id = context.get('emp_id', self.pool.get('hr.employee').search(cr, uid, [('user_id', '=', uid)], context=context))
if emp_id:
return emp_id[0]
return False
_defaults = {
'name': _get_empname,
'emp_id': _get_empid,
}
def sign_in(self, cr, uid, ids, context=None):
data = self.read(cr, uid, ids, [], context=context)[0]
data['emp_id'] = data['emp_id'] and data['emp_id'][0]
return self.pool.get('hr.sign.in.out').sign_in(cr, uid, data, context)
def sign_out(self, cr, uid, ids, context=None):
data = self.read(cr, uid, ids, [], context=context)[0]
data['emp_id'] = data['emp_id'] and data['emp_id'][0]
return self.pool.get('hr.sign.in.out').sign_out(cr, uid, data, context)
hr_si_so_ask()
class hr_sign_in_out(osv.osv_memory):
_name = 'hr.sign.in.out'
_description = 'Sign In Sign Out'
_columns = {
'name': fields.char('Employees name', size=32, required=True, readonly=True),
'state': fields.char('Current state', size=32, required=True, readonly=True),
'emp_id': fields.many2one('hr.employee', 'Empoyee ID', readonly=True),
}
def _get_empid(self, cr, uid, context=None):
emp_id = context.get('emp_id', self.pool.get('hr.employee').search(cr, uid, [('user_id', '=', uid)], context=context))
if emp_id:
employee = self.pool.get('hr.employee').browse(cr, uid, emp_id, context=context)[0]
return {'name': employee.name, 'state': employee.state, 'emp_id': emp_id[0]}
return {}
def default_get(self, cr, uid, fields_list, context=None):
res = super(hr_sign_in_out, self).default_get(cr, uid, fields_list, context=context)
res_emp = self._get_empid(cr, uid, context=context)
res.update(res_emp)
return res
def si_check(self, cr, uid, ids, context=None):
obj_model = self.pool.get('ir.model.data')
att_obj = self.pool.get('hr.attendance')
data = self.read(cr, uid, ids, [], context=context)[0]
data['emp_id'] = data['emp_id'] and data['emp_id'][0]
emp_id = data['emp_id']
att_id = att_obj.search(cr, uid, [('employee_id', '=', emp_id)], limit=1, order='name desc')
last_att = att_obj.browse(cr, uid, att_id, context=context)
if last_att:
last_att = last_att[0]
cond = not last_att or last_att.action == 'sign_out'
if cond:
return self.sign_in(cr, uid, data, context)
else:
model_data_ids = obj_model.search(cr,uid,[('model','=','ir.ui.view'),('name','=','view_hr_attendance_so_ask')], context=context)
resource_id = obj_model.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
return {
'name': _('Sign in / Sign out'),
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'hr.sign.in.out.ask',
'views': [(resource_id,'form')],
'type': 'ir.actions.act_window',
'context': context,
'target': 'new',
}
def so_check(self, cr, uid, ids, context=None):
obj_model = self.pool.get('ir.model.data')
att_obj = self.pool.get('hr.attendance')
data = self.read(cr, uid, ids, [], context=context)[0]
data['emp_id'] = data['emp_id'] and data['emp_id'][0]
emp_id = data['emp_id']
att_id = att_obj.search(cr, uid, [('employee_id', '=', emp_id),('action', '!=', 'action')], limit=1, order='name desc')
last_att = att_obj.browse(cr, uid, att_id, context=context)
if last_att:
last_att = last_att[0]
if not att_id and not last_att:
model_data_ids = obj_model.search(cr, uid, [('model','=','ir.ui.view'),('name','=','view_hr_attendance_message')], context=context)
resource_id = obj_model.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
return {
'name': _('Sign in / Sign out'),
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'hr.sign.in.out',
'views': [(resource_id,'form')],
'type': 'ir.actions.act_window',
'context': context,
'target': 'new',
}
cond = last_att and last_att['action'] == 'sign_in'
if cond:
return self.sign_out(cr, uid, data, context)
else:
model_data_ids = obj_model.search(cr, uid, [('model','=','ir.ui.view'),('name','=','view_hr_attendance_si_ask')], context=context)
resource_id = obj_model.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
return {
'name': _('Sign in / Sign out'),
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'hr.sign.in.out.ask',
'views': [(resource_id,'form')],
'type': 'ir.actions.act_window',
'target': 'new',
}
def sign_in(self, cr, uid, data, context=None):
if context is None:
context = {}
emp_id = data['emp_id']
if 'last_time' in data:
if data['last_time'] > time.strftime('%Y-%m-%d %H:%M:%S'):
raise osv.except_osv(_('User Error!'), _('The sign-out date must be in the past.'))
self.pool.get('hr.attendance').create(cr, uid, {'name': data['last_time'], 'action': 'sign_out',
'employee_id': emp_id}, context=context)
try:
self.pool.get('hr.employee').attendance_action_change(cr, uid, [emp_id], 'sign_in')
except:
raise osv.except_osv(_('User Error!'), _('A sign-in must be right after a sign-out!'))
return {'type': 'ir.actions.act_window_close'} # To do: Return Success message
def sign_out(self, cr, uid, data, context=None):
emp_id = data['emp_id']
if 'last_time' in data:
if data['last_time'] > time.strftime('%Y-%m-%d %H:%M:%S'):
raise osv.except_osv(_('User Error!'), _('The sign-in date must be in the past.'))
self.pool.get('hr.attendance').create(cr, uid, {'name':data['last_time'], 'action':'sign_in', 'employee_id':emp_id}, context=context)
try:
self.pool.get('hr.employee').attendance_action_change(cr, uid, [emp_id], 'sign_out')
except:
raise osv.except_osv(_('User Error!'), _('A sign-out must be right after a sign-in.'))
return {'type': 'ir.actions.act_window_close'} # To do: Return Success message
hr_sign_in_out()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_hr_attendance_sigh_in_out" model="ir.ui.view">
<field name="name">hr.sign.in.out.form</field>
<field name="model">hr.sign.in.out</field>
<field name="arch" type="xml">
<form string="Sign in / Sign out" version="7.0">
<group>
<separator colspan="4" string="Sign in / Sign out"/>
<label colspan="4" nolabel="1" string="If you need your staff to sign in when they arrive at work and sign out again at the end of the day, OpenERP allows you to manage this with this tool. If each employee has been linked to a system user, then they can encode their time with this action button."/>
<newline/>
</group>
<group colspan="4" >
<field name="name" />
<field name="state" />
</group>
<footer>
<button string="Sign in" name="si_check" type="object" class="oe_highlight"/>
<button string="Sign out" name="so_check" type="object" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
</form>
</field>
</record>
<record id="view_hr_attendance_message" model="ir.ui.view">
<field name="name">hr.sign.in.out.form</field>
<field name="model">hr.sign.in.out</field>
<field name="arch" type="xml">
<form string="Sign in / Sign out" version="7.0">
<separator string="Sign-out Entry Must Follow Sign-in." colspan="4" />
</form>
</field>
</record>
<record id="action_hr_attendance_sigh_in_out" model="ir.actions.act_window">
<field name="name">Sign in / Sign out</field>
<field name="res_model">hr.sign.in.out</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_hr_attendance_sigh_in_out"/>
<field name="target">new</field>
<field name="help">Sign in / Sign out. In some companies, staff have to sign in when they arrive at work and sign out again at the end of the day. If each employee has been linked to a system user, then they can encode their time with this action button.</field>
</record>
<menuitem action="action_hr_attendance_sigh_in_out" id="menu_hr_attendance_sigh_in_out"
parent="menu_hr_attendance" sequence="4"/>
<record id="view_hr_attendance_so_ask" model="ir.ui.view">
<field name="name">hr.sign.in.out.ask.form</field>
<field name="model">hr.sign.in.out.ask</field>
<field name="arch" type="xml">
<form string="hr.sign.out.ask" version="7.0">
<header>
<button string="Sign in" name="sign_in" type="object" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</header>
<group colspan="4" >
<separator string="You did not sign out the last time. Please enter the date and time you signed out." colspan="4" />
<field name="name" />
<field name="last_time" string="Your last sign out" />
</group>
</form>
</field>
</record>
<record id="view_hr_attendance_si_ask" model="ir.ui.view">
<field name="name">hr.sign.in.out.ask.form</field>
<field name="model">hr.sign.in.out.ask</field>
<field name="arch" type="xml">
<form string="hr.sign.in.out.ask" version="7.0">
<header>
<button string="Sign out" name="sign_out" type="object" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</header>
<group colspan="4" >
<separator string="You did not sign in the last time. Please enter the date and time you signed in." colspan="4" />
<field name="name" />
<field name="last_time" string="Your last sign in" />
</group>
</form>
</field>
</record>
</data>
</openerp>

View File

@ -1,7 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- Contracts Button on Employee Form -->
<act_window
context="{'search_default_employee_id': [active_id], 'default_employee_id': active_id}"
id="act_hr_employee_2_hr_contract"
name="Contracts"
res_model="hr.contract"
src_model="hr.employee"
groups="base.group_hr_manager"/>
<menuitem id="next_id_56" name="Contract" parent="hr.menu_hr_configuration" sequence="30" groups="base.group_no_one"/>
<record id="hr_hr_employee_view_form2" model="ir.ui.view">
<field name="name">hr.hr.employee.view.form2</field>
@ -9,19 +20,20 @@
<field name="inherit_id" ref="hr.view_employee_form"/>
<field name="arch" type="xml">
<data>
<xpath expr="//field[@name='parent_id']" position="before">
<xpath expr="//div[@name='button_box']" position="inside">
<button name="%(act_hr_employee_2_hr_contract)d" string="Contracts" type="action"/>
</xpath>
<xpath expr="//field[@name='coach_id']" position="after">
<field name="manager"/>
</xpath>
<xpath expr="//group[@name='active_group']" position="before">
<group>
<group string="Contract">
<field name="medic_exam" string="Medical Exam"/>
<field name="vehicle"/>
<field name="vehicle_distance"/>
</group>
</xpath>
<field name="active" position="before">
<field name="medic_exam" string="Medical Exam"/>
</field>
<field name="birthday" position="before">
<field name="marital" position="after">
<field name="children"/>
</field>
<field name="birthday" position="after">
@ -177,15 +189,5 @@
<menuitem action="action_hr_contract_type" id="hr_menu_contract_type" parent="next_id_56" sequence="6" groups="base.group_no_one"/>
<menuitem action="action_hr_contract" id="hr_menu_contract" parent="hr.menu_hr_main" name="Contracts" sequence="4" groups="base.group_hr_manager"/>
<!-- Contracts Button on Employee Form -->
<act_window
context="{'search_default_employee_id': [active_id], 'default_employee_id': active_id}"
id="act_hr_employee_2_hr_contract"
name="Contracts"
res_model="hr.contract"
src_model="hr.employee"
groups="base.group_hr_manager"/>
</data>
</openerp>

View File

@ -0,0 +1,270 @@
# Norwegian Bokmal translation for openobject-addons
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
"PO-Revision-Date: 2012-09-08 18:49+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Norwegian Bokmal <nb@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-09-09 04:52+0000\n"
"X-Generator: Launchpad (build 15914)\n"
#. module: hr_contract
#: field:hr.contract,wage:0
msgid "Wage"
msgstr "Lønn"
#. module: hr_contract
#: view:hr.contract:0
msgid "Information"
msgstr "Informasjon"
#. module: hr_contract
#: view:hr.contract:0
msgid "Trial Period"
msgstr "Prøveperiode"
#. module: hr_contract
#: field:hr.contract,trial_date_start:0
msgid "Trial Start Date"
msgstr "Prøve Startdato"
#. module: hr_contract
#: view:hr.employee:0
msgid "Medical Examination"
msgstr "Legeundersøkelse"
#. module: hr_contract
#: field:hr.employee,vehicle:0
msgid "Company Vehicle"
msgstr "Selskapets Kjøretøy."
#. module: hr_contract
#: view:hr.employee:0
msgid "Miscellaneous"
msgstr "Diverse"
#. module: hr_contract
#: view:hr.contract:0
msgid "Current"
msgstr "Nåværende"
#. module: hr_contract
#: view:hr.contract:0
msgid "Group By..."
msgstr "Grupper etter ..."
#. module: hr_contract
#: field:hr.contract,department_id:0
msgid "Department"
msgstr "Avdeling"
#. module: hr_contract
#: view:hr.contract:0
msgid "Overpassed"
msgstr "Overpassert"
#. module: hr_contract
#: view:hr.contract:0
#: field:hr.contract,employee_id:0
#: model:ir.model,name:hr_contract.model_hr_employee
msgid "Employee"
msgstr "Ansatt"
#. module: hr_contract
#: view:hr.contract:0
msgid "Search Contract"
msgstr "Søk Kontrakt"
#. module: hr_contract
#: view:hr.contract:0
msgid "Contracts in progress"
msgstr "Kontrakter i fremgang"
#. module: hr_contract
#: field:hr.employee,vehicle_distance:0
msgid "Home-Work Distance"
msgstr "Hjem-arbeid Avstand."
#. module: hr_contract
#: view:hr.contract:0
#: field:hr.employee,contract_ids:0
#: model:ir.actions.act_window,name:hr_contract.act_hr_employee_2_hr_contract
#: model:ir.actions.act_window,name:hr_contract.action_hr_contract
#: model:ir.ui.menu,name:hr_contract.hr_menu_contract
msgid "Contracts"
msgstr "Kontrakter"
#. module: hr_contract
#: view:hr.employee:0
msgid "Personal Info"
msgstr "Personlig Info"
#. module: hr_contract
#: view:hr.contract:0
msgid "Contracts whose end date already passed"
msgstr "Kontrakter som sluttdato har allerede passert."
#. module: hr_contract
#: help:hr.employee,contract_id:0
msgid "Latest contract of the employee"
msgstr "Siste kontrakten av den ansatte"
#. module: hr_contract
#: view:hr.contract:0
msgid "Job"
msgstr "Jobb"
#. module: hr_contract
#: view:hr.contract:0
#: field:hr.contract,advantages:0
msgid "Advantages"
msgstr "Fordeler"
#. module: hr_contract
#: view:hr.contract:0
msgid "Valid for"
msgstr "Gyldig for."
#. module: hr_contract
#: view:hr.contract:0
msgid "Work Permit"
msgstr "Arbeidstillatelse"
#. module: hr_contract
#: field:hr.employee,children:0
msgid "Number of Children"
msgstr "Antall barn"
#. module: hr_contract
#: model:ir.actions.act_window,name:hr_contract.action_hr_contract_type
#: model:ir.ui.menu,name:hr_contract.hr_menu_contract_type
msgid "Contract Types"
msgstr "Kontrakt typer."
#. module: hr_contract
#: constraint:hr.employee:0
msgid "Error ! You cannot create recursive Hierarchy of Employees."
msgstr "Feil! Du kan ikke opprette rekursiv Hierarki av ansatte."
#. module: hr_contract
#: field:hr.contract,date_end:0
msgid "End Date"
msgstr "Sluttdato"
#. module: hr_contract
#: help:hr.contract,wage:0
msgid "Basic Salary of the employee"
msgstr "Grunnlønn for den ansatte."
#. module: hr_contract
#: field:hr.contract,name:0
msgid "Contract Reference"
msgstr "Kontrakt referanse."
#. module: hr_contract
#: help:hr.employee,vehicle_distance:0
msgid "In kilometers"
msgstr "I kilometer."
#. module: hr_contract
#: view:hr.contract:0
#: field:hr.contract,notes:0
msgid "Notes"
msgstr "Notater"
#. module: hr_contract
#: field:hr.contract,permit_no:0
msgid "Work Permit No"
msgstr "Arbeidstillatelse Ingen."
#. module: hr_contract
#: view:hr.contract:0
#: field:hr.employee,contract_id:0
#: model:ir.model,name:hr_contract.model_hr_contract
#: model:ir.ui.menu,name:hr_contract.next_id_56
msgid "Contract"
msgstr "Kontrakt"
#. module: hr_contract
#: view:hr.contract:0
#: field:hr.contract,type_id:0
#: view:hr.contract.type:0
#: field:hr.contract.type,name:0
#: model:ir.model,name:hr_contract.model_hr_contract_type
msgid "Contract Type"
msgstr "Kontrakt type."
#. module: hr_contract
#: view:hr.contract:0
#: field:hr.contract,working_hours:0
msgid "Working Schedule"
msgstr "Arbeidsplan"
#. module: hr_contract
#: view:hr.employee:0
msgid "Job Info"
msgstr "Jobb informasjon."
#. module: hr_contract
#: field:hr.contract,visa_expire:0
msgid "Visa Expire Date"
msgstr "Visa utløpsdato."
#. module: hr_contract
#: field:hr.contract,job_id:0
msgid "Job Title"
msgstr "Jobb Tittel"
#. module: hr_contract
#: field:hr.employee,manager:0
msgid "Is a Manager"
msgstr "Er en leder."
#. module: hr_contract
#: field:hr.contract,date_start:0
msgid "Start Date"
msgstr "Startdato"
#. module: hr_contract
#: constraint:hr.contract:0
msgid "Error! contract start-date must be lower then contract end-date."
msgstr "Feil! Kontrakten startdato må være lavere enn kontrakt sluttdato."
#. module: hr_contract
#: field:hr.contract,visa_no:0
msgid "Visa No"
msgstr "Visa Nei."
#. module: hr_contract
#: field:hr.employee,place_of_birth:0
msgid "Place of Birth"
msgstr "Fødested"
#. module: hr_contract
#: view:hr.contract:0
msgid "Duration"
msgstr "Varighet"
#. module: hr_contract
#: field:hr.employee,medic_exam:0
msgid "Medical Examination Date"
msgstr "Legeundersøkelse Dato"
#. module: hr_contract
#: field:hr.contract,trial_date_end:0
msgid "Trial End Date"
msgstr "Prøve Sluttdato ."
#. module: hr_contract
#: view:hr.contract.type:0
msgid "Search Contract Type"
msgstr "Søk Kontraktstype"

View File

@ -128,14 +128,12 @@
<field name="model">hr.employee</field>
<field name="inherit_id" ref="hr.view_employee_form"/>
<field name="arch" type="xml">
<page string="Personal Information" position="after">
<page string="Appraisal" groups="base.group_hr_user">
<group col="4">
<field name="evaluation_plan_id" on_change="onchange_evaluation_plan_id(evaluation_plan_id, evaluation_date)"/>
<field name="evaluation_date"/>
</group>
</page>
</page>
<xpath expr="//group[@name='active_group']" position="before">
<group string="Appraisals">
<field name="evaluation_plan_id" on_change="onchange_evaluation_plan_id(evaluation_plan_id, evaluation_date)"/>
<field name="evaluation_date"/>
</group>
</xpath>
</field>
</record>

View File

@ -17,7 +17,7 @@
<field name="inherit_id" ref="hr.board_hr_form"/>
<field name="arch" type="xml">
<xpath expr="/form/board/column[1]" position="inside">
<action name="%(action_my_expense)d" string="My Expenses" creatable="true"/>
<action name="%(action_my_expense)d" string="My Expenses"/>
</xpath>
</field>
</record>

View File

@ -513,13 +513,17 @@
<field name="model">hr.employee</field>
<field name="inherit_id" ref="hr.view_employee_form"/>
<field name="arch" type="xml">
<field name="active" position="before">
<label for="remaining_leaves"/>
<div>
<field name="remaining_leaves" class="oe_inline"/>
<button name="%(act_hr_employee_holiday_request)d" string="Leaves" type="action" class="oe_inline oe_right"/>
</div>
</field>
<xpath expr="//group[@name='active_group']" position="before">
<group string="Leaves">
<label for="remaining_leaves"/>
<div>
<field name="remaining_leaves" class="oe_inline"/>
</div>
</group>
</xpath>
<xpath expr="//div[@name='button_box']" position="inside">
<button name="%(act_hr_employee_holiday_request)d" string="Leaves" type="action"/>
</xpath>
</field>
</record>

View File

@ -218,6 +218,17 @@ class hr_payslip_run(osv.osv):
'journal_id': fields.many2one('account.journal', 'Expense Journal', states={'draft': [('readonly', False)]}, readonly=True, required=True),
}
def _get_default_journal(self, cr, uid, context=None):
model_data = self.pool.get('ir.model.data')
res = model_data.search(cr, uid, [('name', '=', 'expenses_journal')])
if res:
return model_data.browse(cr, uid, res[0]).res_id
return False
_defaults = {
'journal_id': _get_default_journal,
}
hr_payslip_run()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,141 @@
# Norwegian Bokmal translation for openobject-addons
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
"PO-Revision-Date: 2012-09-07 19:55+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Norwegian Bokmal <nb@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-09-08 04:54+0000\n"
"X-Generator: Launchpad (build 15914)\n"
#. module: hr_payroll_account
#: field:hr.payslip,move_id:0
msgid "Accounting Entry"
msgstr "Regnskapsmessig oppføring"
#. module: hr_payroll_account
#: field:hr.salary.rule,account_tax_id:0
msgid "Tax Code"
msgstr "Skattekode"
#. module: hr_payroll_account
#: field:hr.payslip,journal_id:0
#: field:hr.payslip.run,journal_id:0
msgid "Expense Journal"
msgstr "Bekostning Journal"
#. module: hr_payroll_account
#: code:addons/hr_payroll_account/hr_payroll_account.py:157
#: code:addons/hr_payroll_account/hr_payroll_account.py:173
#, python-format
msgid "Adjustment Entry"
msgstr "Justering oppføring"
#. module: hr_payroll_account
#: field:hr.contract,analytic_account_id:0
#: field:hr.salary.rule,analytic_account_id:0
msgid "Analytic Account"
msgstr "Analytisk konto"
#. module: hr_payroll_account
#: model:ir.model,name:hr_payroll_account.model_hr_salary_rule
msgid "hr.salary.rule"
msgstr "hr.salary.rule"
#. module: hr_payroll_account
#: model:ir.model,name:hr_payroll_account.model_hr_payslip_run
msgid "Payslip Batches"
msgstr "Lønnsslipp Batcher."
#. module: hr_payroll_account
#: field:hr.contract,journal_id:0
msgid "Salary Journal"
msgstr "lønn Journal"
#. module: hr_payroll_account
#: model:ir.model,name:hr_payroll_account.model_hr_payslip
msgid "Pay Slip"
msgstr "Lønnslipp"
#. module: hr_payroll_account
#: constraint:hr.payslip:0
msgid "Payslip 'Date From' must be before 'Date To'."
msgstr "Lønnslipp \" Dato fra \" må være før \" Dato Til \""
#. module: hr_payroll_account
#: help:hr.payslip,period_id:0
msgid "Keep empty to use the period of the validation(Payslip) date."
msgstr "Hold tom for å bruke tid på validering (lønnsslipp) dato."
#. module: hr_payroll_account
#: code:addons/hr_payroll_account/hr_payroll_account.py:171
#, python-format
msgid ""
"The Expense Journal \"%s\" has not properly configured the Debit Account!"
msgstr "Bekostning Journal \"% s\" har ikke riktig konfigurert Debet konto!"
#. module: hr_payroll_account
#: code:addons/hr_payroll_account/hr_payroll_account.py:155
#, python-format
msgid ""
"The Expense Journal \"%s\" has not properly configured the Credit Account!"
msgstr ""
"Bekostning Journal \"% s\" har ikke riktig konfigurert kreditt-konto!"
#. module: hr_payroll_account
#: field:hr.salary.rule,account_debit:0
msgid "Debit Account"
msgstr "Debetkonto"
#. module: hr_payroll_account
#: code:addons/hr_payroll_account/hr_payroll_account.py:102
#, python-format
msgid "Payslip of %s"
msgstr "Lønnslipp av %s."
#. module: hr_payroll_account
#: model:ir.model,name:hr_payroll_account.model_hr_contract
msgid "Contract"
msgstr "Kontrakt"
#. module: hr_payroll_account
#: constraint:hr.contract:0
msgid "Error! contract start-date must be lower then contract end-date."
msgstr "Feil! Kontrakten startdato må være lavere enn kontrakt sluttdato."
#. module: hr_payroll_account
#: field:hr.payslip,period_id:0
msgid "Force Period"
msgstr "Kraft Periode."
#. module: hr_payroll_account
#: field:hr.salary.rule,account_credit:0
msgid "Credit Account"
msgstr "Kredittkonto"
#. module: hr_payroll_account
#: model:ir.model,name:hr_payroll_account.model_hr_payslip_employees
msgid "Generate payslips for all selected employees"
msgstr "Generer lønnsslipper for alle utvalgte ansatte."
#. module: hr_payroll_account
#: code:addons/hr_payroll_account/hr_payroll_account.py:155
#: code:addons/hr_payroll_account/hr_payroll_account.py:171
#, python-format
msgid "Configuration Error!"
msgstr "Konfigurasjonsfeil!"
#. module: hr_payroll_account
#: view:hr.contract:0
#: view:hr.salary.rule:0
msgid "Accounting"
msgstr "Regnskap"

View File

@ -31,8 +31,9 @@ class hr_payslip_employees(osv.osv_memory):
context = {}
if context and context.get('active_id', False):
run_data = run_pool.read(cr, uid, context['active_id'], ['journal_id'])
journal_id = run_data.get('journal_id', False)[0]
context.update({'journal_id': journal_id})
journal_id = run_data.get('journal_id', False)
journal_id = journal_id and journal_id[0] or False
if journal_id: context.update({'journal_id': journal_id})
return super(hr_payslip_employees, self).compute_sheet(cr, uid, ids, context=context)
hr_payslip_employees()

View File

@ -52,6 +52,7 @@
partner_name: 'John Bruno'
state: 'done'
job_id: hr.job_developer
color: 5
stage_id: stage_job5
name: 'Marketing Job'
-
@ -100,6 +101,9 @@
partner_name: 'David Armstrong'
job_id: hr.job_developer
stage_id: stage_job2
color: 4
name: 'Advertisement'
salary_expected: 11000.0
-
!record {model: hr.job, id: hr.job_developer}:
survey_id: hr_recruitment.survey_job_0

View File

@ -115,13 +115,13 @@
<sheet>
<div class="oe_right oe_button_box">
<button name="action_makeMeeting" type="object"
string="Schedule Interview" icon="gtk-index" help="Schedule interview with this applicant"/>
string="Schedule Meeting" help="Schedule interview with this applicant"/>
<button name="%(survey.action_view_survey_question_message)d" type="action"
string="Start Interview" icon="gtk-execute" help="Answer related job question"
string="Start Interview" help="Answer related job question"
context="{'survey_id': survey, 'response_id': [response], 'response_no':0 ,'active' : response, 'object' : 'hr.applicant'}"
attrs="{'invisible':[('survey','=',False)]}"/>
<button name="action_print_survey" type="object"
string="Print Interview" icon="gtk-print" help="Print interview report"
string="Print Interview" help="Print interview report"
attrs="{'invisible':[('survey','=',False)]}"/>
</div>
<div class="oe_title">
@ -208,28 +208,28 @@
<field name="arch" type="xml">
<search string="Search Jobs">
<field name="partner_name" filter_domain="['|','|',('name','ilike',self),('partner_name','ilike',self),('email_from','ilike',self)]" string="Subject / Applicant"/>
<filter icon="terp-mail-message-new" string="Inbox" help="Unread messages" name="message_unread" domain="[('message_unread','=',True)]"/>
<filter string="Inbox" help="Unread messages" name="message_unread" domain="[('message_unread','=',True)]"/>
<separator/>
<filter icon="terp-document-new" string="New" domain="[('state','=','draft')]" help="All Initial Jobs"/>
<filter icon="terp-camera_test" string="In Progress" domain="[('state','=','open')]" help="Open Jobs"/>
<filter icon="terp-gtk-media-pause" string="Pending" domain="[('state','=','pending')]" help="Pending Jobs"/>
<filter string="New" domain="[('state','=','draft')]" help="All Initial Jobs"/>
<filter string="In Progress" domain="[('state','=','open')]" help="Open Jobs"/>
<filter string="Pending" domain="[('state','=','pending')]" help="Pending Jobs"/>
<separator/>
<filter string="Unassigned Recruitments" domain="[('user_id','=',False)]" help="Unassigned Recruitments" icon="terp-personal-"/>
<filter string="Unassigned Recruitments" domain="[('user_id','=',False)]" help="Unassigned Recruitments"/>
<separator/>
<filter icon="terp-gtk-jump-to-ltr" string="Next Actions" context="{'invisible_next_action':False, 'invisible_next_date':False}"
<filter string="Next Actions" context="{'invisible_next_action':False, 'invisible_next_date':False}"
domain="[('date_action','&lt;&gt;',False)]" help="Filter and view on next actions and date"/>
<field name="job_id"/>
<field name="user_id"/>
<group expand="0" string="Group By...">
<filter string="Responsible" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
<filter string="Department" icon="terp-personal+" domain="[]" context="{'group_by':'department_id'}"/>
<filter string="Job" icon="terp-gtk-select-all" domain="[]" context="{'group_by':'job_id'}"/>
<filter string="Degree" icon="terp-gtk-select-all" domain="[]" context="{'group_by':'type_id'}"/>
<filter string="Availability" icon="terp-camera_test" domain="[]" context="{'group_by':'availability'}"/>
<filter string="Appreciation" icon="terp-face-plain" domain="[]" context="{'group_by':'priority'}"/>
<filter string="Stage" icon="terp-stage" domain="[]" context="{'group_by':'stage_id'}"/>
<filter string="Source" icon="terp-face-plain" domain="[]" context="{'group_by':'source_id'}"/>
<filter string="Creation Date" icon="terp-go-month" domain="[]" context="{'group_by':'create_date'}" groups="base.group_no_one"/>
<filter string="Responsible" domain="[]" context="{'group_by':'user_id'}"/>
<filter string="Department" domain="[]" context="{'group_by':'department_id'}"/>
<filter string="Job" domain="[]" context="{'group_by':'job_id'}"/>
<filter string="Degree" domain="[]" context="{'group_by':'type_id'}"/>
<filter string="Availability" domain="[]" context="{'group_by':'availability'}"/>
<filter string="Appreciation" domain="[]" context="{'group_by':'priority'}"/>
<filter string="Stage" domain="[]" context="{'group_by':'stage_id'}"/>
<filter string="Source" domain="[]" context="{'group_by':'source_id'}"/>
<filter string="Creation Date" domain="[]" context="{'group_by':'create_date'}" groups="base.group_no_one"/>
</group>
</search>
</field>
@ -339,7 +339,7 @@
<div groups="base.group_user">
<field name="survey_id" class="oe_inline"/>
<button class="oe_inline"
string="Interview" icon="gtk-print"
string="Interview"
name="action_print_survey" type="object"
attrs="{'invisible':[('survey_id','=',False)]}"/>
</div>

View File

@ -131,16 +131,12 @@
<field name="model">hr.employee</field>
<field name="inherit_id" ref="hr.view_employee_form"/>
<field name="arch" type="xml">
<page string="Personal Information" position="after">
<page string="Timesheets" groups="base.group_hr_user">
<group>
<group col="2">
<field name="product_id" domain="[('type','=','service')]"/>
<field name="journal_id"/>
</group>
</group>
</page>
</page>
<xpath expr="//group[@name='active_group']" position="before">
<group string="Timesheets">
<field name="product_id" domain="[('type','=','service')]"/>
<field name="journal_id"/>
</group>
</xpath>
</field>
</record>

View File

@ -91,7 +91,7 @@ class hr_so_project(osv.osv_memory):
emp_obj = self.pool.get('hr.employee')
for data in self.browse(cr, uid, ids, context=context):
emp_id = data.emp_id.id
emp_obj.attendance_action_change(cr, uid, [emp_id], type='sign_out', dt=data.date)
emp_obj.attendance_action_change(cr, uid, [emp_id], {'action':'sign_out', 'action_date':data.date})
self._write(cr, uid, data, emp_id, context=context)
return {'type': 'ir.actions.act_window_close'}
@ -99,7 +99,7 @@ class hr_so_project(osv.osv_memory):
emp_obj = self.pool.get('hr.employee')
for data in self.browse(cr, uid, ids, context=context):
emp_id = data.emp_id.id
emp_obj.attendance_action_change(cr, uid, [emp_id], type='action', dt=data.date)
emp_obj.attendance_action_change(cr, uid, [emp_id], {'action':'action', 'action_date':data.date})
self._write(cr, uid, data, emp_id, context=context)
return {'type': 'ir.actions.act_window_close'}
@ -156,7 +156,7 @@ class hr_si_project(osv.osv_memory):
emp_obj = self.pool.get('hr.employee')
for data in self.browse(cr, uid, ids, context=context):
emp_id = data.emp_id.id
emp_obj.attendance_action_change(cr, uid, [emp_id], type = 'sign_in' ,dt=data.date or False)
emp_obj.attendance_action_change(cr, uid, [emp_id], {'action':'sign_in', 'action_date':data.date})
return {'type': 'ir.actions.act_window_close'}
def default_get(self, cr, uid, fields_list, context=None):

View File

@ -312,31 +312,12 @@ class hr_timesheet_sheet(osv.osv):
self.write(cr, uid, [sheet.id], {'date_current': sheet.date_to,}, context=context)
return True
def check_sign(self, cr, uid, ids, typ, context=None):
sheet = self.browse(cr, uid, ids, context=context)[0]
if not sheet.date_current == time.strftime('%Y-%m-%d'):
raise osv.except_osv(_('Error!'), _('You cannot sign in/sign out from other date than today.'))
return True
def sign(self, cr, uid, ids, typ, context=None):
self.check_sign(cr, uid, ids, typ, context=context)
sign_obj = self.pool.get('hr.sign.in.out')
sheet = self.browse(cr, uid, ids, context=context)[0]
context['emp_id'] = [sheet.employee_id.id]
sign_id = sign_obj.create(cr, uid, {}, context=context)
methods = {'sign_in': sign_obj.si_check,
'sign_out': sign_obj.so_check}
wizard_result = methods[typ](cr, uid, [sign_id], context=context)
if wizard_result.get('type', False) == 'ir.actions.act_window_close':
return True # ensure we do not close the main window !
wizard_result['nodestroy'] = True # do not destroy the main window !
return wizard_result
def sign_in(self, cr, uid, ids, context=None):
return self.sign(cr, uid, ids, 'sign_in', context=context)
def sign_out(self, cr, uid, ids, context=None):
return self.sign(cr, uid, ids, 'sign_out', context=context)
def attendance_action_change(self, cr, uid, ids, context=None):
hr_employee = self.pool.get('hr.employee')
employee_ids = []
for sheet in self.browse(cr, uid, ids, context=context):
if sheet.employee_id.id not in employee_ids: employee_ids.append(sheet.employee_id.id)
return hr_employee.attendance_action_change(cr, uid, employee_ids, context=context)
_columns = {
'name': fields.char('Note', size=64, select=1,

View File

@ -2,12 +2,12 @@
<openerp>
<data noupdate="1">
<record id="sheet1" model="hr_timesheet_sheet.sheet">
<!-- <record id="sheet1" model="hr_timesheet_sheet.sheet">
<field name="name">Sheet 1</field>
<field name="user_id" ref="base.user_root"/>
<field name="employee_id" ref="hr.employee_fp" />
<field eval="time.strftime('%Y-%m-%d')" name="date_current"/>
</record>
-->
</data>
</openerp>

View File

@ -92,9 +92,9 @@
</tree>
</field>
<group>
<div align="right">
<button name="sign_in" string="Sign In" type="object" icon="terp-gtk-jump-to-ltr"/>
<button name="sign_out" string="Sign Out" type="object" icon="terp-gtk-jump-to-rtl"/>
<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>

View File

@ -26,7 +26,7 @@
Now, at the time of login, I create Attendances and perform "Sign In" action.
-
!python {model: hr_timesheet_sheet.sheet}: |
self.sign_in(cr, uid, [ref('hr_timesheet_sheet_sheet_deddk0')], {})
self.attendance_action_change(cr, uid, [ref('hr_timesheet_sheet_sheet_deddk0')], {})
task_work = self.search(cr, uid, [("name","=","Quentin Paolinon")],context)[0]
task_ids = self.browse(cr, uid, task_work, context)
assert task_ids.state == "draft", "I State In Timesheet"

View File

@ -0,0 +1,105 @@
# Norwegian Bokmal translation for openobject-addons
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
"PO-Revision-Date: 2012-09-08 19:39+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Norwegian Bokmal <nb@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-09-09 04:52+0000\n"
"X-Generator: Launchpad (build 15914)\n"
#. module: import_base
#: code:addons/import_base/import_framework.py:434
#, python-format
msgid "Import failed due to an unexpected error"
msgstr "Import mislyktes på grunn av en uventet feil."
#. module: import_base
#: code:addons/import_base/import_framework.py:461
#, python-format
msgid "started at %s and finished at %s \n"
msgstr "Startet på% s og ferdig på% s \n"
#. module: import_base
#: code:addons/import_base/import_framework.py:448
#, python-format
msgid "Import of your data finished at %s"
msgstr "Import av dine data ferdig på% s"
#. module: import_base
#: code:addons/import_base/import_framework.py:463
#, python-format
msgid ""
"but failed, in consequence no data were imported to keep database "
"consistency \n"
" error : \n"
msgstr ""
"Men mislyktes, i følge ingen data ble importert for å holde databasen "
"konsistens\n"
"  feil: \n"
#. module: import_base
#: code:addons/import_base/import_framework.py:477
#, python-format
msgid ""
"The import of data \n"
" instance name : %s \n"
msgstr ""
"Import av data\n"
" Eksempel navn:% s \n"
#. module: import_base
#: code:addons/import_base/import_framework.py:470
#, python-format
msgid "%s has been successfully imported from %s %s, %s \n"
msgstr "% s har blitt importert fra% s% s,% s \n"
#. module: import_base
#: code:addons/import_base/import_framework.py:447
#, python-format
msgid "Data Import failed at %s due to an unexpected error"
msgstr "Dataimport mislyktes ved% s på grunn av en uventet feil."
#. module: import_base
#: code:addons/import_base/import_framework.py:436
#, python-format
msgid "Import finished, notification email sended"
msgstr "Import ferdig, e-postmelding sendt."
#. module: import_base
#: code:addons/import_base/import_framework.py:190
#, python-format
msgid "%s is not a valid model name"
msgstr "% s er ikke en gyldig modellnavn."
#. module: import_base
#: model:ir.ui.menu,name:import_base.menu_import_crm
msgid "Import"
msgstr "Import"
#. module: import_base
#: code:addons/import_base/import_framework.py:467
#, python-format
msgid "with no warning"
msgstr "Uten advarsel."
#. module: import_base
#: code:addons/import_base/import_framework.py:469
#, python-format
msgid "with warning : %s"
msgstr "Med advarsel :%s"
#. module: import_base
#: code:addons/import_base/import_framework.py:191
#, python-format
msgid " fields imported : "
msgstr " Felt importert: "

View File

@ -0,0 +1,226 @@
# Norwegian Bokmal translation for openobject-addons
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
"PO-Revision-Date: 2012-09-09 16:36+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Norwegian Bokmal <nb@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-09-10 04:41+0000\n"
"X-Generator: Launchpad (build 15924)\n"
#. module: import_google
#: help:synchronize.google.import,group_name:0
msgid "Choose which group to import, By default it takes all."
msgstr "Velg hvilken gruppe du vil importere, standard tar alt."
#. module: import_google
#: view:synchronize.google.import:0
msgid "Import Google Calendar Events"
msgstr "Importer Google Kalender Hendelser."
#. module: import_google
#: view:synchronize.google.import:0
msgid "_Import Events"
msgstr "_Importer hendelser."
#. module: import_google
#: code:addons/import_google/wizard/import_google_data.py:71
#, python-format
msgid ""
"No Google Username or password Defined for user.\n"
"Please define in user view"
msgstr ""
"Ingen Google-brukernavn eller passord definert for brukeren.\n"
"Vennligst angi i brukerens visning."
#. module: import_google
#: code:addons/import_google/wizard/import_google_data.py:127
#, python-format
msgid ""
"Invalid login detail !\n"
" Specify Username/Password."
msgstr ""
"Ugyldig pålogging detalj!\n"
"  Angi brukernavn / passord."
#. module: import_google
#: field:synchronize.google.import,supplier:0
msgid "Supplier"
msgstr "Leverandør"
#. module: import_google
#: view:synchronize.google.import:0
msgid "Import Options"
msgstr "Alternativer for import"
#. module: import_google
#: field:synchronize.google.import,group_name:0
msgid "Group Name"
msgstr "Gruppe Navn"
#. module: import_google
#: model:ir.model,name:import_google.model_crm_case_categ
msgid "Category of Case"
msgstr "Kategori for hendelse"
#. module: import_google
#: model:ir.actions.act_window,name:import_google.act_google_login_contact_form
#: model:ir.ui.menu,name:import_google.menu_sync_contact
msgid "Import Google Contacts"
msgstr "Importer Google kontakter."
#. module: import_google
#: view:google.import.message:0
msgid "Import Google Data"
msgstr "Importer Google data."
#. module: import_google
#: view:crm.meeting:0
msgid "Meeting Type"
msgstr "Møtetype"
#. module: import_google
#: code:addons/import_google/wizard/import_google.py:38
#: code:addons/import_google/wizard/import_google_data.py:28
#, python-format
msgid ""
"Please install gdata-python-client from http://code.google.com/p/gdata-"
"python-client/downloads/list"
msgstr ""
"Vennligst Installer gdata-python-client from http://code.google.com/p/gdata-"
"python-client/downloads/list"
#. module: import_google
#: model:ir.model,name:import_google.model_google_login
msgid "Google Contact"
msgstr "Google kontakt"
#. module: import_google
#: view:synchronize.google.import:0
msgid "Import contacts from a google account"
msgstr "Importer kontakter fra en Google-konto"
#. module: import_google
#: code:addons/import_google/wizard/import_google_data.py:133
#, python-format
msgid "Please specify correct user and password !"
msgstr "Vennligst oppgi riktig bruker og passord!"
#. module: import_google
#: field:synchronize.google.import,customer:0
msgid "Customer"
msgstr "Kunde"
#. module: import_google
#: view:synchronize.google.import:0
msgid "_Cancel"
msgstr "_Avbryt"
#. module: import_google
#: model:ir.model,name:import_google.model_synchronize_google_import
msgid "synchronize.google.import"
msgstr "Synkronisere.google.import"
#. module: import_google
#: view:synchronize.google.import:0
msgid "_Import Contacts"
msgstr "_Importer kontakter."
#. module: import_google
#: model:ir.actions.act_window,name:import_google.act_google_login_form
#: model:ir.ui.menu,name:import_google.menu_sync_calendar
msgid "Import Google Calendar"
msgstr "Importer Google kalender."
#. module: import_google
#: code:addons/import_google/wizard/import_google_data.py:50
#, python-format
msgid "Import google"
msgstr "Importer Google."
#. module: import_google
#: code:addons/import_google/wizard/import_google_data.py:127
#: code:addons/import_google/wizard/import_google_data.py:133
#, python-format
msgid "Error"
msgstr "Feil"
#. module: import_google
#: code:addons/import_google/wizard/import_google_data.py:71
#, python-format
msgid "Warning !"
msgstr "Advarsel !"
#. module: import_google
#: field:synchronize.google.import,create_partner:0
msgid "Options"
msgstr "Valg"
#. module: import_google
#: view:google.import.message:0
msgid "_Ok"
msgstr "_Ok"
#. module: import_google
#: code:addons/import_google/wizard/import_google.py:38
#: code:addons/import_google/wizard/import_google_data.py:28
#, python-format
msgid "Google Contacts Import Error!"
msgstr "Google kontakter Import Feil!"
#. module: import_google
#: model:ir.model,name:import_google.model_google_import_message
msgid "Import Message"
msgstr "Importer melding."
#. module: import_google
#: field:synchronize.google.import,calendar_name:0
msgid "Calendar Name"
msgstr "Kalendernavn"
#. module: import_google
#: help:synchronize.google.import,supplier:0
msgid "Check this box to set newly created partner as Supplier."
msgstr "Kryss av for å sette nyopprettede partner som leverandør."
#. module: import_google
#: selection:synchronize.google.import,create_partner:0
msgid "Import only address"
msgstr "Importer bare adresse."
#. module: import_google
#: field:crm.case.categ,user_id:0
msgid "User"
msgstr "Bruker"
#. module: import_google
#: view:synchronize.google.import:0
msgid "Partner Status for this Group:"
msgstr ""
#. module: import_google
#: field:google.import.message,name:0
msgid "Message"
msgstr "Melding"
#. module: import_google
#: selection:synchronize.google.import,create_partner:0
msgid "Create partner for each contact"
msgstr "Opprett partner for hver kontakt."
#. module: import_google
#: help:synchronize.google.import,customer:0
msgid "Check this box to set newly created partner as Customer."
msgstr "Kryss av for å sette nyopprettede partner som Kunden."
#~ msgid "Partner status for this group:"
#~ msgstr "Partner status for denne gruppen."

View File

@ -38,11 +38,11 @@
<record id="hr_employee_form__l10n_be_view_for" model="ir.ui.view">
<field name="name">hr.employee.inherit.form</field>
<field name="model">hr.employee</field>
<field name="inherit_id" ref="hr.view_employee_form"/>
<field name="inherit_id" ref="hr_contract.hr_hr_employee_view_form2"/>
<field name="priority">30</field>
<field name="arch" type="xml">
<data>
<xpath expr="//field[@name='gender']" position="before">
<xpath expr="//field[@name='vehicle_distance']" position="after">
<field name="resident_bool" eval="False"/>
</xpath>
<xpath expr="//field[@name='marital']" position="after">

View File

@ -6,7 +6,6 @@
<record id="chart0_en" model="account.account.template">
<field name="code">0</field>
<field name="name">Account Chart CA EN</field>
<field eval="0" name="parent_id"/>
<field name="type">view</field>
<field name="user_type" ref="account.data_account_type_view"/>
</record>

128
addons/l10n_ca/i18n/nb.po Normal file
View File

@ -0,0 +1,128 @@
# Norwegian Bokmal translation for openobject-addons
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2010-08-02 21:08+0000\n"
"PO-Revision-Date: 2012-09-09 16:43+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Norwegian Bokmal <nb@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-09-10 04:41+0000\n"
"X-Generator: Launchpad (build 15924)\n"
#. module: l10n_ca
#: model:account.account.type,name:l10n_ca.account_type_receivable
msgid "Receivable"
msgstr "Fordring"
#. module: l10n_ca
#: model:account.account.type,name:l10n_ca.acct_type_asset_view
msgid "Asset View"
msgstr "Eiendel Vis"
#. module: l10n_ca
#: model:ir.module.module,description:l10n_ca.module_meta_information
msgid ""
"This is the module to manage the canadian accounting chart in OpenERP."
msgstr ""
"Dette er modulen for å administrere kanadiske regnskap diagrammet i OpenERP."
#. module: l10n_ca
#: model:account.account.type,name:l10n_ca.acct_type_expense_view
msgid "Expense View"
msgstr "Kostnad Vis"
#. module: l10n_ca
#: constraint:account.account.template:0
msgid "Error ! You can not create recursive account templates."
msgstr "Feil ! Du kan ikke opprette rekursive konto maler."
#. module: l10n_ca
#: model:account.account.type,name:l10n_ca.acct_type_income_view
msgid "Income View"
msgstr "Inntekt Vis"
#. module: l10n_ca
#: model:ir.module.module,shortdesc:l10n_ca.module_meta_information
msgid "Canada - Chart of Accounts"
msgstr "Canada - Kontoplan"
#. module: l10n_ca
#: constraint:account.account.type:0
msgid "Error ! You can not create recursive types."
msgstr "Feil ! Du kan ikke opprette rekursive typer."
#. module: l10n_ca
#: model:account.account.type,name:l10n_ca.account_type_tax
msgid "Tax"
msgstr "Skatt"
#. module: l10n_ca
#: model:account.account.type,name:l10n_ca.account_type_cash
msgid "Cash"
msgstr "Kontant"
#. module: l10n_ca
#: model:ir.actions.todo,note:l10n_ca.config_call_account_template_ca
msgid ""
"Generate Chart of Accounts from a Chart Template. You will be asked to pass "
"the name of the company, the chart template to follow, the no. of digits to "
"generate the code for your accounts and Bank account, currency to create "
"Journals. Thus,the pure copy of chart Template is generated.\n"
"\tThis is the same wizard that runs from Financial "
"Management/Configuration/Financial Accounting/Financial Accounts/Generate "
"Chart of Accounts from a Chart Template."
msgstr ""
"Generere Kontoplan fra en diagrammal. Du vil bli bedt om å passere navnet på "
"selskapet, diagrammal til følge, nei. sifre som skal generere koden for "
"kontoene og bankkonto, valuta å skape Journals. Dermed er den rene kopi av "
"diagrammal generert.\n"
"\t Dette er den samme veiviser som går fra økonomistyring / konfigurasjon / "
"finansiell Regnskap / finansregnskapet / Generer Kontoplan fra en diagrammal."
#. module: l10n_ca
#: model:account.account.type,name:l10n_ca.account_type_payable
msgid "Payable"
msgstr "Utgift"
#. module: l10n_ca
#: model:account.account.type,name:l10n_ca.account_type_asset
msgid "Asset"
msgstr "Eiendel"
#. module: l10n_ca
#: model:account.account.type,name:l10n_ca.account_type_equity
msgid "Equity"
msgstr "Egenkapital"
#. module: l10n_ca
#: constraint:account.tax.code.template:0
msgid "Error ! You can not create recursive Tax Codes."
msgstr "Feil ! Du kan ikke opprette rekursive skatte koder."
#. module: l10n_ca
#: model:account.account.type,name:l10n_ca.acct_type_liability_view
msgid "Liability View"
msgstr "Ansvar Vis."
#. module: l10n_ca
#: model:account.account.type,name:l10n_ca.account_type_expense
msgid "Expense"
msgstr "Utgift"
#. module: l10n_ca
#: model:account.account.type,name:l10n_ca.account_type_income
msgid "Income"
msgstr "Inntekt"
#. module: l10n_ca
#: model:account.account.type,name:l10n_ca.account_type_view
msgid "View"
msgstr "Vis"

66
addons/l10n_cn/i18n/nb.po Normal file
View File

@ -0,0 +1,66 @@
# Norwegian Bokmal translation for openobject-addons
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2011-12-23 09:56+0000\n"
"PO-Revision-Date: 2012-09-08 19:45+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Norwegian Bokmal <nb@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-09-09 04:52+0000\n"
"X-Generator: Launchpad (build 15914)\n"
#. module: l10n_cn
#: model:account.account.type,name:l10n_cn.user_type_profit_and_loss
msgid "损益类"
msgstr "Gevinst eller tap kategori."
#. module: l10n_cn
#: model:account.account.type,name:l10n_cn.user_type_all
msgid "所有科目"
msgstr "Alle fag."
#. module: l10n_cn
#: model:account.account.type,name:l10n_cn.user_type_equity
msgid "所有者权益类"
msgstr "Eiernes egenkapital."
#. module: l10n_cn
#: model:ir.actions.todo,note:l10n_cn.config_call_account_template_cn_chart
msgid ""
"Generate Chart of Accounts from a Chart Template. You will be asked to pass "
"the name of the company, the chart template to follow, the no. of digits to "
"generate the code for your accounts and Bank account, currency to create "
"Journals. Thus,the pure copy of chart Template is generated.\n"
"\tThis is the same wizard that runs from Financial "
"Management/Configuration/Financial Accounting/Financial Accounts/Generate "
"Chart of Accounts from a Chart Template."
msgstr ""
"Generere Kontoplan fra en diagrammal. Du vil bli bedt om å passere navnet på "
"selskapet, diagrammal til følge, nei. sifre som skal generere koden for "
"kontoene og bankkonto, valuta å skape Journals. Dermed er den rene kopi av "
"diagrammal generert.\n"
"\t Dette er den samme veiviser som går fra økonomistyring / konfigurasjon / "
"finansiell Regnskap / finansregnskapet / Generer Kontoplan fra en diagrammal."
#. module: l10n_cn
#: model:account.account.type,name:l10n_cn.user_type_debt
msgid "负债类"
msgstr "Gjeld klasse."
#. module: l10n_cn
#: model:account.account.type,name:l10n_cn.user_type_cost
msgid "成本类"
msgstr "Kostnaden for klassen"
#. module: l10n_cn
#: model:account.account.type,name:l10n_cn.user_type_capital
msgid "资产类"
msgstr "Aktivaklasser"

66
addons/l10n_de/i18n/nb.po Normal file
View File

@ -0,0 +1,66 @@
# Norwegian Bokmal translation for openobject-addons
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2010-12-15 15:05+0000\n"
"PO-Revision-Date: 2012-09-08 19:47+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Norwegian Bokmal <nb@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-09-09 04:52+0000\n"
"X-Generator: Launchpad (build 15914)\n"
#. module: l10n_de
#: model:account.fiscal.position.template,name:l10n_de.fiscal_position_non_eu_sale_skr03
#: model:account.fiscal.position.template,name:l10n_de.fiscal_position_non_eu_sale_skr04
msgid "Kunde Ausland"
msgstr "Kunde Ausland"
#. module: l10n_de
#: model:account.fiscal.position.template,name:l10n_de.fiscal_position_eu_no_id_sale_skr03
#: model:account.fiscal.position.template,name:l10n_de.fiscal_position_eu_no_id_sale_skr04
msgid "Kunde EU (ohne USt-ID)"
msgstr "Kunde EU (ohne USt-ID)"
#. module: l10n_de
#: model:account.fiscal.position.template,name:l10n_de.fiscal_position_non_eu_purchase_skr03
#: model:account.fiscal.position.template,name:l10n_de.fiscal_position_non_eu_purchase_skr04
msgid "Lieferant Ausland"
msgstr ""
#. module: l10n_de
#: model:ir.module.module,shortdesc:l10n_de.module_meta_information
msgid "Deutschland - SKR03 and SKR04"
msgstr ""
#. module: l10n_de
#: model:ir.module.module,description:l10n_de.module_meta_information
msgid ""
"Dieses Modul beinhaltet einen deutschen Kontenrahmen basierend auf dem "
"SKR03."
msgstr ""
#. module: l10n_de
#: model:account.fiscal.position.template,name:l10n_de.fiscal_position_eu_vat_id_purchase_skr03
#: model:account.fiscal.position.template,name:l10n_de.fiscal_position_eu_vat_id_purchase_skr04
msgid "Lieferant EU Unternehmen (mit USt-ID)"
msgstr ""
#. module: l10n_de
#: model:account.fiscal.position.template,name:l10n_de.fiscal_position_eu_no_id_purchase_skr03
#: model:account.fiscal.position.template,name:l10n_de.fiscal_position_eu_no_id_purchase_skr04
msgid "Lieferant EU (ohne Ust-ID)"
msgstr ""
#. module: l10n_de
#: model:account.fiscal.position.template,name:l10n_de.fiscal_position_eu_vat_id_sale_skr03
#: model:account.fiscal.position.template,name:l10n_de.fiscal_position_eu_vat_id_sale_skr04
msgid "Kunde EU Unternehmen (mit USt-ID)"
msgstr ""

View File

@ -7,7 +7,6 @@
<record id="chartgr_0" model="account.account.template">
<field name="code">0</field>
<field name="name">Γενικό Λογιστικό Σχέδιο</field>
<!--<field eval="0" name="parent_id"/> -->
<field name="type">view</field>
<field name="user_type" ref="account_type_view"/>
</record>

View File

@ -7,7 +7,6 @@
<record id="plan_raiz" model="account.account.template">
<field name="code">-</field>
<field name="name">Plan contable de Guatemala (sencillo)</field>
<field eval="0" name="parent_id"/>
<field name="type">view</field>
<field name="user_type" ref="cuenta_vista"/>
</record>

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