[MERGE] trunk
bzr revid: sle@openerp.com-20140403163851-v3x74jl4ekeszrbr
This commit is contained in:
commit
51a94afa5e
|
@ -543,33 +543,40 @@ class account_analytic_account(osv.osv):
|
|||
'nodestroy': True,
|
||||
}
|
||||
|
||||
def on_change_template(self, cr, uid, ids, template_id, context=None):
|
||||
def on_change_template(self, cr, uid, ids, template_id, date_start=False, fix_price_invoices=False, invoice_on_timesheets=False, recurring_invoices=False, context=None):
|
||||
if not template_id:
|
||||
return {}
|
||||
obj_analytic_line = self.pool.get('account.analytic.invoice.line')
|
||||
res = super(account_analytic_account, self).on_change_template(cr, uid, ids, template_id, context=context)
|
||||
res = super(account_analytic_account, self).on_change_template(cr, uid, ids, template_id, date_start=date_start, context=context)
|
||||
|
||||
template = self.browse(cr, uid, template_id, context=context)
|
||||
invoice_line_ids = []
|
||||
for x in template.recurring_invoice_line_ids:
|
||||
invoice_line_ids.append((0, 0, {
|
||||
'product_id': x.product_id.id,
|
||||
'uom_id': x.uom_id.id,
|
||||
'name': x.name,
|
||||
'quantity': x.quantity,
|
||||
'price_unit': x.price_unit,
|
||||
'analytic_account_id': x.analytic_account_id and x.analytic_account_id.id or False,
|
||||
}))
|
||||
res['value']['fix_price_invoices'] = template.fix_price_invoices
|
||||
res['value']['invoice_on_timesheets'] = template.invoice_on_timesheets
|
||||
res['value']['hours_qtt_est'] = template.hours_qtt_est
|
||||
res['value']['amount_max'] = template.amount_max
|
||||
res['value']['to_invoice'] = template.to_invoice.id
|
||||
res['value']['pricelist_id'] = template.pricelist_id.id
|
||||
res['value']['recurring_invoices'] = template.recurring_invoices
|
||||
res['value']['recurring_interval'] = template.recurring_interval
|
||||
res['value']['recurring_rule_type'] = template.recurring_rule_type
|
||||
res['value']['recurring_invoice_line_ids'] = invoice_line_ids
|
||||
|
||||
if not fix_price_invoices:
|
||||
res['value']['fix_price_invoices'] = template.fix_price_invoices
|
||||
res['value']['amount_max'] = template.amount_max
|
||||
if not invoice_on_timesheets:
|
||||
res['value']['invoice_on_timesheets'] = template.invoice_on_timesheets
|
||||
res['value']['hours_qtt_est'] = template.hours_qtt_est
|
||||
|
||||
if template.to_invoice.id:
|
||||
res['value']['to_invoice'] = template.to_invoice.id
|
||||
if template.pricelist_id.id:
|
||||
res['value']['pricelist_id'] = template.pricelist_id.id
|
||||
if not recurring_invoices:
|
||||
invoice_line_ids = []
|
||||
for x in template.recurring_invoice_line_ids:
|
||||
invoice_line_ids.append((0, 0, {
|
||||
'product_id': x.product_id.id,
|
||||
'uom_id': x.uom_id.id,
|
||||
'name': x.name,
|
||||
'quantity': x.quantity,
|
||||
'price_unit': x.price_unit,
|
||||
'analytic_account_id': x.analytic_account_id and x.analytic_account_id.id or False,
|
||||
}))
|
||||
res['value']['recurring_invoices'] = template.recurring_invoices
|
||||
res['value']['recurring_interval'] = template.recurring_interval
|
||||
res['value']['recurring_rule_type'] = template.recurring_rule_type
|
||||
res['value']['recurring_invoice_line_ids'] = invoice_line_ids
|
||||
return res
|
||||
|
||||
def onchange_recurring_invoices(self, cr, uid, ids, recurring_invoices, date_start=False, context=None):
|
||||
|
|
|
@ -38,6 +38,9 @@
|
|||
<field name="partner_id" position="attributes">
|
||||
<attribute name="attrs">{'required': [('type','=','contract'),'|','|',('fix_price_invoices','=',True), ('invoice_on_timesheets', '=', True), ('recurring_invoices', '=', True)]}</attribute>
|
||||
</field>
|
||||
<field name="template_id" position="attributes">
|
||||
<attribute name="on_change">on_change_template(template_id, date_start, fix_price_invoices, invoice_on_timesheets, recurring_invoices)</attribute>
|
||||
</field>
|
||||
<xpath expr='//group[@name="invoice_on_timesheets"]' position="replace">
|
||||
</xpath>
|
||||
<xpath expr='//separator[@name="description"]' position='before'>
|
||||
|
|
|
@ -0,0 +1,266 @@
|
|||
# Swedish translation for openobject-addons
|
||||
# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
|
||||
"PO-Revision-Date: 2014-03-31 21:13+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Swedish <sv@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: 2014-04-01 05:39+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_test
|
||||
#: view:accounting.assert.test:0
|
||||
msgid ""
|
||||
"Code should always set a variable named `result` with the result of your "
|
||||
"test, that can be a list or\n"
|
||||
"a dictionary. If `result` is an empty list, it means that the test was "
|
||||
"succesful. Otherwise it will\n"
|
||||
"try to translate and print what is inside `result`.\n"
|
||||
"\n"
|
||||
"If the result of your test is a dictionary, you can set a variable named "
|
||||
"`column_order` to choose in\n"
|
||||
"what order you want to print `result`'s content.\n"
|
||||
"\n"
|
||||
"Should you need them, you can also use the following variables into your "
|
||||
"code:\n"
|
||||
" * cr: cursor to the database\n"
|
||||
" * uid: ID of the current user\n"
|
||||
"\n"
|
||||
"In any ways, the code must be legal python statements with correct "
|
||||
"indentation (if needed).\n"
|
||||
"\n"
|
||||
"Example: \n"
|
||||
" sql = '''SELECT id, name, ref, date\n"
|
||||
" FROM account_move_line \n"
|
||||
" WHERE account_id IN (SELECT id FROM account_account WHERE type "
|
||||
"= 'view')\n"
|
||||
" '''\n"
|
||||
" cr.execute(sql)\n"
|
||||
" result = cr.dictfetchall()"
|
||||
msgstr ""
|
||||
"Kod ska alltid ställa en variabel med namnet `resultat` med resultatet av "
|
||||
"ditt test, kan det vara en lista eller\n"
|
||||
"en ordbok. Om `resultat` är en tom lista, betyder det att testet var lyckat. "
|
||||
"Annars kommer\n"
|
||||
"försöka översätta och skriva ut vad som finns i `resultat`.\n"
|
||||
"\n"
|
||||
"Om resultatet av testet är en ordbok kan du ställa in en variabel med namnet "
|
||||
"`column_order` för att välja in\n"
|
||||
"vilken ordning du vill skriva ut `resultat` s innehåll.\n"
|
||||
"\n"
|
||||
"Om du behöver dem, kan du även använda följande variabler i koden:\n"
|
||||
" * Cr: markören till databasen\n"
|
||||
" * Uid: ID för den aktuella användaren\n"
|
||||
"\n"
|
||||
"På något sätt måste koden vara lagliga python uttalanden med rätt indrag (om "
|
||||
"det behövs).\n"
|
||||
"\n"
|
||||
"Exempel:\n"
|
||||
" sql ='' 'SELECT id, namn, ref, datum\n"
|
||||
" FRÅN account_move_line\n"
|
||||
" VAR konto-IN (SELECT id FROM account_account WHERE typ = "
|
||||
"\"Visa\")\n"
|
||||
" '' '\n"
|
||||
" cr.execute (SQL)\n"
|
||||
" resultat = cr.dictfetchall ()"
|
||||
|
||||
#. module: account_test
|
||||
#: model:accounting.assert.test,name:account_test.account_test_02
|
||||
msgid "Test 2: Opening a fiscal year"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: model:accounting.assert.test,desc:account_test.account_test_05
|
||||
msgid ""
|
||||
"Check that reconciled invoice for Sales/Purchases has reconciled entries for "
|
||||
"Payable and Receivable Accounts"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: model:accounting.assert.test,desc:account_test.account_test_03
|
||||
msgid ""
|
||||
"Check if movement lines are balanced and have the same date and period"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: field:accounting.assert.test,name:0
|
||||
msgid "Test Name"
|
||||
msgstr "Testnamn"
|
||||
|
||||
#. module: account_test
|
||||
#: report:account.test.assert.print:0
|
||||
msgid "Accouting tests on"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: model:accounting.assert.test,name:account_test.account_test_01
|
||||
msgid "Test 1: General balance"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: model:accounting.assert.test,desc:account_test.account_test_06
|
||||
msgid "Check that paid/reconciled invoices are not in 'Open' state"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: model:accounting.assert.test,desc:account_test.account_test_05_2
|
||||
msgid ""
|
||||
"Check that reconciled account moves, that define Payable and Receivable "
|
||||
"accounts, are belonging to reconciled invoices"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: view:accounting.assert.test:0
|
||||
msgid "Tests"
|
||||
msgstr "Tester"
|
||||
|
||||
#. module: account_test
|
||||
#: field:accounting.assert.test,desc:0
|
||||
msgid "Test Description"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: view:accounting.assert.test:0
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: model:accounting.assert.test,desc:account_test.account_test_06_1
|
||||
msgid "Check that there's no move for any account with « View » account type"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: model:accounting.assert.test,name:account_test.account_test_08
|
||||
msgid "Test 9 : Accounts and partners on account moves"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: model:ir.actions.act_window,name:account_test.action_accounting_assert
|
||||
#: model:ir.actions.report.xml,name:account_test.account_assert_test_report
|
||||
#: model:ir.ui.menu,name:account_test.menu_action_license
|
||||
msgid "Accounting Tests"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: code:addons/account_test/report/account_test_report.py:74
|
||||
#, python-format
|
||||
msgid "The test was passed successfully"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: field:accounting.assert.test,active:0
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: model:accounting.assert.test,name:account_test.account_test_06
|
||||
msgid "Test 6 : Invoices status"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: model:ir.model,name:account_test.model_accounting_assert_test
|
||||
msgid "accounting.assert.test"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: model:accounting.assert.test,name:account_test.account_test_05
|
||||
msgid ""
|
||||
"Test 5.1 : Payable and Receivable accountant lines of reconciled invoices"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: field:accounting.assert.test,code_exec:0
|
||||
msgid "Python code"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: model:accounting.assert.test,desc:account_test.account_test_07
|
||||
msgid ""
|
||||
"Check on bank statement that the Closing Balance = Starting Balance + sum of "
|
||||
"statement lines"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: model:accounting.assert.test,name:account_test.account_test_07
|
||||
msgid "Test 8 : Closing balance on bank statements"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: model:accounting.assert.test,name:account_test.account_test_03
|
||||
msgid "Test 3: Movement lines"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: model:accounting.assert.test,name:account_test.account_test_05_2
|
||||
msgid "Test 5.2 : Reconcilied invoices and Payable/Receivable accounts"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: view:accounting.assert.test:0
|
||||
msgid "Expression"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: model:accounting.assert.test,name:account_test.account_test_04
|
||||
msgid "Test 4: Totally reconciled mouvements"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: model:accounting.assert.test,desc:account_test.account_test_04
|
||||
msgid "Check if the totally reconciled movements are balanced"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: field:accounting.assert.test,sequence:0
|
||||
msgid "Sequence"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: model:accounting.assert.test,desc:account_test.account_test_02
|
||||
msgid ""
|
||||
"Check if the balance of the new opened fiscal year matches with last year's "
|
||||
"balance"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: view:accounting.assert.test:0
|
||||
msgid "Python Code"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: model:ir.actions.act_window,help:account_test.action_accounting_assert
|
||||
msgid ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" Click to create Accounting Test.\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: model:accounting.assert.test,desc:account_test.account_test_01
|
||||
msgid "Check the balance: Debit sum = Credit sum"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: model:accounting.assert.test,desc:account_test.account_test_08
|
||||
msgid "Check that general accounts and partners on account moves are active"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: model:accounting.assert.test,name:account_test.account_test_06_1
|
||||
msgid "Test 7: « View » account type"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_test
|
||||
#: view:accounting.assert.test:0
|
||||
msgid "Code Help"
|
||||
msgstr ""
|
|
@ -203,7 +203,7 @@ class account_analytic_account(osv.osv):
|
|||
}, string='Currency', type='many2one', relation='res.currency'),
|
||||
}
|
||||
|
||||
def on_change_template(self, cr, uid, ids, template_id, context=None):
|
||||
def on_change_template(self, cr, uid, ids, template_id, date_start=False, context=None):
|
||||
if not template_id:
|
||||
return {}
|
||||
res = {'value':{}}
|
||||
|
@ -213,7 +213,8 @@ class account_analytic_account(osv.osv):
|
|||
to_dt = datetime.strptime(template.date, tools.DEFAULT_SERVER_DATE_FORMAT)
|
||||
timedelta = to_dt - from_dt
|
||||
res['value']['date'] = datetime.strftime(datetime.now() + timedelta, tools.DEFAULT_SERVER_DATE_FORMAT)
|
||||
res['value']['date_start'] = fields.date.today()
|
||||
if not date_start:
|
||||
res['value']['date_start'] = fields.date.today()
|
||||
res['value']['quantity_max'] = template.quantity_max
|
||||
res['value']['parent_id'] = template.parent_id and template.parent_id.id or False
|
||||
res['value']['description'] = template.description
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
</group>
|
||||
<group>
|
||||
<field name="type" invisible="context.get('default_type', False)"/>
|
||||
<field name="template_id" on_change="on_change_template(template_id,context)" domain="[('type','=','template')]" attrs="{'invisible': [('type','in',['view', 'normal','template'])]}" context="{'default_type' : 'template'}"/>
|
||||
<field name="template_id" on_change="on_change_template(template_id, date_start)" domain="[('type','=','template')]" attrs="{'invisible': [('type','in',['view', 'normal','template'])]}" context="{'default_type' : 'template'}"/>
|
||||
<field name="code"/>
|
||||
<field name="parent_id" on_change="on_change_parent(parent_id)" attrs="{'invisible': [('type','in',['contract'])]}"/>
|
||||
<field name="company_id" on_change="on_change_company(company_id)" widget="selection" groups="base.group_multi_company" attrs="{'required': [('type','<>','view')]}"/>
|
||||
|
|
|
@ -115,8 +115,8 @@ class account_analytic_account(osv.osv):
|
|||
digits_compute=dp.get_precision('Account')),
|
||||
}
|
||||
|
||||
def on_change_template(self, cr, uid, id, template_id, context=None):
|
||||
res = super(account_analytic_account, self).on_change_template(cr, uid, id, template_id, context=context)
|
||||
def on_change_template(self, cr, uid, id, template_id, date_start=False, context=None):
|
||||
res = super(account_analytic_account, self).on_change_template(cr, uid, id, template_id, date_start=date_start, context=context)
|
||||
if template_id and 'value' in res:
|
||||
template = self.browse(cr, uid, template_id, context=context)
|
||||
res['value']['charge_expenses'] = template.charge_expenses
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
# Swedish translation for openobject-addons
|
||||
# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
|
||||
"PO-Revision-Date: 2014-03-31 21:25+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Swedish <sv@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: 2014-04-01 05:39+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: analytic_contract_hr_expense
|
||||
#: view:account.analytic.account:0
|
||||
msgid "or view"
|
||||
msgstr "eller visa"
|
||||
|
||||
#. module: analytic_contract_hr_expense
|
||||
#: view:account.analytic.account:0
|
||||
msgid "Nothing to invoice, create"
|
||||
msgstr "Inget att fakturera, skapa"
|
||||
|
||||
#. module: analytic_contract_hr_expense
|
||||
#: view:account.analytic.account:0
|
||||
msgid "expenses"
|
||||
msgstr "utlägg"
|
||||
|
||||
#. module: analytic_contract_hr_expense
|
||||
#: model:ir.model,name:analytic_contract_hr_expense.model_account_analytic_account
|
||||
msgid "Analytic Account"
|
||||
msgstr "Objektkonto"
|
||||
|
||||
#. module: analytic_contract_hr_expense
|
||||
#: code:addons/analytic_contract_hr_expense/analytic_contract_hr_expense.py:144
|
||||
#, python-format
|
||||
msgid "Expenses to Invoice of %s"
|
||||
msgstr "Utlägg att fakturera av %s"
|
||||
|
||||
#. module: analytic_contract_hr_expense
|
||||
#: code:addons/analytic_contract_hr_expense/analytic_contract_hr_expense.py:136
|
||||
#, python-format
|
||||
msgid "Expenses of %s"
|
||||
msgstr "Utlägg av %s"
|
||||
|
||||
#. module: analytic_contract_hr_expense
|
||||
#: field:account.analytic.account,expense_invoiced:0
|
||||
#: field:account.analytic.account,expense_to_invoice:0
|
||||
#: field:account.analytic.account,remaining_expense:0
|
||||
msgid "unknown"
|
||||
msgstr "okänd"
|
||||
|
||||
#. module: analytic_contract_hr_expense
|
||||
#: field:account.analytic.account,est_expenses:0
|
||||
msgid "Estimation of Expenses to Invoice"
|
||||
msgstr "Uppskattning av utlägg att fakturera"
|
||||
|
||||
#. module: analytic_contract_hr_expense
|
||||
#: field:account.analytic.account,charge_expenses:0
|
||||
msgid "Charge Expenses"
|
||||
msgstr "Debitera utläggen"
|
||||
|
||||
#. module: analytic_contract_hr_expense
|
||||
#: view:account.analytic.account:0
|
||||
msgid "⇒ Invoice"
|
||||
msgstr "⇒ Faktura"
|
|
@ -0,0 +1,279 @@
|
|||
# Swedish translation for openobject-addons
|
||||
# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
|
||||
"PO-Revision-Date: 2014-03-27 12:30+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Swedish <sv@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: 2014-03-28 05:42+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: auth_signup
|
||||
#: field:res.partner,signup_type:0
|
||||
msgid "Signup Token Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#: field:base.config.settings,auth_signup_uninvited:0
|
||||
msgid "Allow external users to sign up"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
#: code:addons/auth_signup/static/src/xml/auth_signup.xml:19
|
||||
#, python-format
|
||||
msgid "Confirm Password"
|
||||
msgstr "Bekräfta lösenord"
|
||||
|
||||
#. module: auth_signup
|
||||
#: help:base.config.settings,auth_signup_uninvited:0
|
||||
msgid "If unchecked, only invited users may sign up."
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#: model:ir.model,name:auth_signup.model_base_config_settings
|
||||
msgid "base.config.settings"
|
||||
msgstr "base.config.settings"
|
||||
|
||||
#. module: auth_signup
|
||||
#: code:addons/auth_signup/res_users.py:266
|
||||
#, python-format
|
||||
msgid "Cannot send email: user has no email address."
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
#: code:addons/auth_signup/static/src/xml/auth_signup.xml:27
|
||||
#: code:addons/auth_signup/static/src/xml/auth_signup.xml:31
|
||||
#, python-format
|
||||
msgid "Reset password"
|
||||
msgstr "Återställ lösenord"
|
||||
|
||||
#. module: auth_signup
|
||||
#: field:base.config.settings,auth_signup_template_user_id:0
|
||||
msgid "Template user for new users created through signup"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#: model:email.template,subject:auth_signup.reset_password_email
|
||||
msgid "Password reset"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
#: code:addons/auth_signup/static/src/js/auth_signup.js:120
|
||||
#, python-format
|
||||
msgid "Please enter a password and confirm it."
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#: view:res.users:0
|
||||
msgid "Send an email to the user to (re)set their password."
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
#: code:addons/auth_signup/static/src/xml/auth_signup.xml:26
|
||||
#: code:addons/auth_signup/static/src/xml/auth_signup.xml:29
|
||||
#, python-format
|
||||
msgid "Sign Up"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#: selection:res.users,state:0
|
||||
msgid "New"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#: code:addons/auth_signup/res_users.py:258
|
||||
#, python-format
|
||||
msgid "Mail sent to:"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#: field:res.users,state:0
|
||||
msgid "Status"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#: model:email.template,body_html:auth_signup.reset_password_email
|
||||
msgid ""
|
||||
"\n"
|
||||
"<p>A password reset was requested for the OpenERP account linked to this "
|
||||
"email.</p>\n"
|
||||
"\n"
|
||||
"<p>You may change your password by following <a "
|
||||
"href=\"${object.signup_url}\">this link</a>.</p>\n"
|
||||
"\n"
|
||||
"<p>Note: If you do not expect this, you can safely ignore this email.</p>"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
#: code:addons/auth_signup/static/src/js/auth_signup.js:114
|
||||
#, python-format
|
||||
msgid "Please enter a name."
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#: model:ir.model,name:auth_signup.model_res_users
|
||||
msgid "Users"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#: field:res.partner,signup_url:0
|
||||
msgid "Signup URL"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
#: code:addons/auth_signup/static/src/js/auth_signup.js:117
|
||||
#, python-format
|
||||
msgid "Please enter a username."
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#: selection:res.users,state:0
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#: code:addons/auth_signup/res_users.py:270
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Cannot send email: no outgoing email server configured.\n"
|
||||
"You can configure it under Settings/General Settings."
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
#: code:addons/auth_signup/static/src/xml/auth_signup.xml:12
|
||||
#, python-format
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
#: code:addons/auth_signup/static/src/xml/auth_signup.xml:8
|
||||
#, python-format
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
#: code:addons/auth_signup/static/src/js/auth_signup.js:173
|
||||
#, python-format
|
||||
msgid "Please enter a username or email address."
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#: selection:res.users,state:0
|
||||
msgid "Resetting Password"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
#: code:addons/auth_signup/static/src/xml/auth_signup.xml:13
|
||||
#, python-format
|
||||
msgid "Username (Email)"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#: field:res.partner,signup_expiration:0
|
||||
msgid "Signup Expiration"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#: help:base.config.settings,auth_signup_reset_password:0
|
||||
msgid "This allows users to trigger a password reset from the Login page."
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
#: code:addons/auth_signup/static/src/xml/auth_signup.xml:25
|
||||
#, python-format
|
||||
msgid "Log in"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#: field:res.partner,signup_valid:0
|
||||
msgid "Signup Token is Valid"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
#: code:addons/auth_signup/static/src/js/auth_signup.js:111
|
||||
#: code:addons/auth_signup/static/src/js/auth_signup.js:114
|
||||
#: code:addons/auth_signup/static/src/js/auth_signup.js:117
|
||||
#: code:addons/auth_signup/static/src/js/auth_signup.js:120
|
||||
#: code:addons/auth_signup/static/src/js/auth_signup.js:123
|
||||
#: code:addons/auth_signup/static/src/js/auth_signup.js:170
|
||||
#: code:addons/auth_signup/static/src/js/auth_signup.js:173
|
||||
#, python-format
|
||||
msgid "Login"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
#: code:addons/auth_signup/static/src/js/auth_signup.js:97
|
||||
#, python-format
|
||||
msgid "Invalid signup token"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
#: code:addons/auth_signup/static/src/js/auth_signup.js:123
|
||||
#, python-format
|
||||
msgid "Passwords do not match; please retype them."
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
#: code:addons/auth_signup/static/src/js/auth_signup.js:111
|
||||
#: code:addons/auth_signup/static/src/js/auth_signup.js:170
|
||||
#, python-format
|
||||
msgid "No database selected !"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#: view:res.users:0
|
||||
msgid "Reset Password"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#: field:base.config.settings,auth_signup_reset_password:0
|
||||
msgid "Enable password reset from Login page"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
#: code:addons/auth_signup/static/src/xml/auth_signup.xml:30
|
||||
#, python-format
|
||||
msgid "Back to Login"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#. openerp-web
|
||||
#: code:addons/auth_signup/static/src/xml/auth_signup.xml:22
|
||||
#, python-format
|
||||
msgid "Sign up"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#: model:ir.model,name:auth_signup.model_res_partner
|
||||
msgid "Partner"
|
||||
msgstr ""
|
||||
|
||||
#. module: auth_signup
|
||||
#: field:res.partner,signup_token:0
|
||||
msgid "Signup Token"
|
||||
msgstr ""
|
|
@ -4,7 +4,7 @@
|
|||
<!--Scheduler sync Receive Request-->
|
||||
<record id="gengo_sync_receive_request_scheduler" model="ir.cron">
|
||||
<field name="name" >Gengo Sync Translation (Response)</field>
|
||||
<field eval="False" name="active"/>
|
||||
<field eval="True" name="active"/>
|
||||
<field name="interval_number">20</field>
|
||||
<field name="interval_type">minutes</field>
|
||||
<field name="numbercall">-1</field>
|
||||
|
@ -16,7 +16,7 @@
|
|||
<!--Scheduler Sync Send Request-->
|
||||
<record id="gengo_sync_send_request_scheduler" model="ir.cron">
|
||||
<field name="name" >Gengo Sync Translation (Request)</field>
|
||||
<field eval="False" name="active"/>
|
||||
<field eval="True" name="active"/>
|
||||
<field name="interval_number">20</field>
|
||||
<field name="interval_type">minutes</field>
|
||||
<field name="numbercall">-1</field>
|
||||
|
|
|
@ -0,0 +1,249 @@
|
|||
# Swedish translation for openobject-addons
|
||||
# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
|
||||
"PO-Revision-Date: 2014-03-31 16:36+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Swedish <sv@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: 2014-04-01 05:39+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: base_gengo
|
||||
#: view:res.company:0
|
||||
msgid "Comments for Translator"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: field:ir.translation,job_id:0
|
||||
msgid "Gengo Job ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: code:addons/base_gengo/wizard/base_gengo_translations.py:114
|
||||
#, python-format
|
||||
msgid "This language is not supported by the Gengo translation services."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: field:res.company,gengo_comment:0
|
||||
msgid "Comments"
|
||||
msgstr "Kommentarer"
|
||||
|
||||
#. module: base_gengo
|
||||
#: field:res.company,gengo_private_key:0
|
||||
msgid "Gengo Private Key"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: model:ir.model,name:base_gengo.model_base_gengo_translations
|
||||
msgid "base.gengo.translations"
|
||||
msgstr "base.gengo.translations"
|
||||
|
||||
#. module: base_gengo
|
||||
#: help:res.company,gengo_auto_approve:0
|
||||
msgid "Jobs are Automatically Approved by Gengo."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: field:base.gengo.translations,lang_id:0
|
||||
msgid "Language"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: field:ir.translation,gengo_comment:0
|
||||
msgid "Comments & Activity Linked to Gengo"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: code:addons/base_gengo/wizard/base_gengo_translations.py:124
|
||||
#, python-format
|
||||
msgid "Gengo Sync Translation (Response)"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: code:addons/base_gengo/wizard/base_gengo_translations.py:72
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Gengo `Public Key` or `Private Key` are missing. Enter your Gengo "
|
||||
"authentication parameters under `Settings > Companies > Gengo Parameters`."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: selection:ir.translation,gengo_translation:0
|
||||
msgid "Translation By Machine"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: code:addons/base_gengo/wizard/base_gengo_translations.py:155
|
||||
#, python-format
|
||||
msgid ""
|
||||
"%s\n"
|
||||
"\n"
|
||||
"--\n"
|
||||
" Commented on %s by %s."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: field:ir.translation,gengo_translation:0
|
||||
msgid "Gengo Translation Service Level"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: constraint:ir.translation:0
|
||||
msgid ""
|
||||
"The Gengo translation service selected is not supported for this language."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: selection:ir.translation,gengo_translation:0
|
||||
msgid "Standard"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: help:ir.translation,gengo_translation:0
|
||||
msgid ""
|
||||
"You can select here the service level you want for an automatic translation "
|
||||
"using Gengo."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: field:base.gengo.translations,restart_send_job:0
|
||||
msgid "Restart Sending Job"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: view:ir.translation:0
|
||||
msgid "To Approve In Gengo"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: view:res.company:0
|
||||
msgid "Private Key"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: view:res.company:0
|
||||
msgid "Public Key"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: field:res.company,gengo_public_key:0
|
||||
msgid "Gengo Public Key"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: code:addons/base_gengo/wizard/base_gengo_translations.py:123
|
||||
#, python-format
|
||||
msgid "Gengo Sync Translation (Request)"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: view:ir.translation:0
|
||||
msgid "Translations"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: field:res.company,gengo_auto_approve:0
|
||||
msgid "Auto Approve Translation ?"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: model:ir.actions.act_window,name:base_gengo.action_wizard_base_gengo_translations
|
||||
#: model:ir.ui.menu,name:base_gengo.menu_action_wizard_base_gengo_translations
|
||||
msgid "Gengo: Manual Request of Translation"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: code:addons/base_gengo/ir_translation.py:62
|
||||
#: code:addons/base_gengo/wizard/base_gengo_translations.py:109
|
||||
#, python-format
|
||||
msgid "Gengo Authentication Error"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: model:ir.model,name:base_gengo.model_res_company
|
||||
msgid "Companies"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: view:ir.translation:0
|
||||
msgid ""
|
||||
"Note: If the translation state is 'In Progress', it means that the "
|
||||
"translation has to be approved to be uploaded in this system. You are "
|
||||
"supposed to do that directly by using your Gengo Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: code:addons/base_gengo/wizard/base_gengo_translations.py:82
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Gengo connection failed with this message:\n"
|
||||
"``%s``"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: view:res.company:0
|
||||
msgid "Gengo Parameters"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: view:base.gengo.translations:0
|
||||
msgid "Send"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: selection:ir.translation,gengo_translation:0
|
||||
msgid "Ultra"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: model:ir.model,name:base_gengo.model_ir_translation
|
||||
msgid "ir.translation"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: view:ir.translation:0
|
||||
msgid "Gengo Translation Service"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: selection:ir.translation,gengo_translation:0
|
||||
msgid "Pro"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: view:base.gengo.translations:0
|
||||
msgid "Gengo Request Form"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: code:addons/base_gengo/wizard/base_gengo_translations.py:114
|
||||
#, python-format
|
||||
msgid "Warning"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: help:res.company,gengo_comment:0
|
||||
msgid ""
|
||||
"This comment will be automatically be enclosed in each an every request sent "
|
||||
"to Gengo"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: view:base.gengo.translations:0
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_gengo
|
||||
#: view:base.gengo.translations:0
|
||||
msgid "or"
|
||||
msgstr ""
|
|
@ -23,7 +23,7 @@ from openerp.osv import fields, osv
|
|||
from openerp.tools.translate import _
|
||||
|
||||
LANG_CODE_MAPPING = {
|
||||
'ar_SA': ('ar', 'Arabic'),
|
||||
'ar_SY': ('ar', 'Arabic'),
|
||||
'id_ID': ('id', 'Indonesian'),
|
||||
'nl_NL': ('nl', 'Dutch'),
|
||||
'fr_CA': ('fr-ca', 'French (Canada)'),
|
||||
|
@ -41,7 +41,19 @@ LANG_CODE_MAPPING = {
|
|||
'fr_BE': ('fr', 'French'),
|
||||
'ru_RU': ('ru', 'Russian'),
|
||||
'it_IT': ('it', 'Italian'),
|
||||
'pt_BR': ('pt-br', 'Portuguese (Brazil)')
|
||||
'pt_BR': ('pt-br', 'Portuguese (Brazil)'),
|
||||
'th_TH': ('th', 'Thai'),
|
||||
'nb_NO': ('no', 'Norwegian'),
|
||||
'ro_RO': ('ro', 'Romanian'),
|
||||
'tr_TR': ('tr', 'Turkish'),
|
||||
'bg_BG': ('bg', 'Bulgarian'),
|
||||
'da_DK': ('da', 'Danish'),
|
||||
'en_GB': ('en-gb', 'English (British)'),
|
||||
'el_GR': ('el', 'Greek'),
|
||||
'vi_VN': ('vi', 'Vietnamese'),
|
||||
'he_IL': ('he', 'Hebrew'),
|
||||
'hu_HU': ('hu', 'Hungarian'),
|
||||
'fi_FI': ('fi', 'Finnish')
|
||||
}
|
||||
|
||||
class ir_translation(osv.Model):
|
||||
|
@ -71,18 +83,3 @@ class ir_translation(osv.Model):
|
|||
|
||||
def _get_gengo_corresponding_language(cr, lang):
|
||||
return lang in LANG_CODE_MAPPING and LANG_CODE_MAPPING[lang][0] or lang
|
||||
|
||||
def _check_lang_support(self, cr, uid, ids, context=None):
|
||||
for term in self.browse(cr, uid, ids, context=context):
|
||||
if term.gengo_translation:
|
||||
supported_langs = self._get_all_supported_languages(cr, uid, context=context)
|
||||
if supported_langs:
|
||||
tier = "nonprofit" if term.gengo_translation == 'machine' else term.gengo_translation
|
||||
language = self._get_gengo_corresponding_language(term.lang)
|
||||
if tier not in supported_langs.get(language,[]):
|
||||
return False
|
||||
return True
|
||||
|
||||
_constraints = [
|
||||
(_check_lang_support, 'The Gengo translation service selected is not supported for this language.', ['gengo_translation'])
|
||||
]
|
||||
|
|
|
@ -30,6 +30,7 @@ class res_company(osv.Model):
|
|||
"gengo_public_key": fields.text("Gengo Public Key"),
|
||||
"gengo_comment": fields.text("Comments", help="This comment will be automatically be enclosed in each an every request sent to Gengo"),
|
||||
"gengo_auto_approve": fields.boolean("Auto Approve Translation ?", help="Jobs are Automatically Approved by Gengo."),
|
||||
"gengo_sandbox": fields.boolean("Sandbox Mode", help="Check this box if you're using the sandbox mode of Gengo, mainly used for testing purpose."),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
|
|
|
@ -17,8 +17,13 @@
|
|||
<field name="gengo_private_key" password="True" nolabel="1" placeholder="Add Gengo login Private Key..."/>
|
||||
</group>
|
||||
</group>
|
||||
<group col="4">
|
||||
<field name="gengo_auto_approve"/>
|
||||
<group>
|
||||
<group>
|
||||
<field name="gengo_auto_approve"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="gengo_sandbox"/>
|
||||
</group>
|
||||
</group>
|
||||
<group string="Comments for Translator" col="1">
|
||||
<field name="gengo_comment" nolabel="1" placeholder="Add your comments here for translator...."/>
|
||||
|
|
|
@ -40,22 +40,19 @@ except ImportError:
|
|||
|
||||
GENGO_DEFAULT_LIMIT = 20
|
||||
|
||||
DEFAULT_CRON_VALS = {
|
||||
'active': True,
|
||||
'interval_number': 20,
|
||||
'interval_type': 'minutes',
|
||||
'model': "'base.gengo.translations'",
|
||||
'args': "'(%s,)'" % (str(GENGO_DEFAULT_LIMIT)),
|
||||
}
|
||||
|
||||
class base_gengo_translations(osv.osv_memory):
|
||||
|
||||
_name = 'base.gengo.translations'
|
||||
_columns = {
|
||||
'restart_send_job': fields.boolean("Restart Sending Job"),
|
||||
'sync_type': fields.selection([('send', 'Send New Terms'),
|
||||
('receive', 'Receive Translation'),
|
||||
('both', 'Both')], "Sync Type"),
|
||||
'lang_id': fields.many2one('res.lang', 'Language', required=True),
|
||||
'sync_limit': fields.integer("No. of terms to sync"),
|
||||
}
|
||||
|
||||
_defaults = {'sync_type' : 'both',
|
||||
'sync_limit' : 20
|
||||
}
|
||||
def gengo_authentication(self, cr, uid, context=None):
|
||||
'''
|
||||
This method tries to open a connection with Gengo. For that, it uses the Public and Private
|
||||
|
@ -74,6 +71,7 @@ class base_gengo_translations(osv.osv_memory):
|
|||
gengo = MyGengo(
|
||||
public_key=user.company_id.gengo_public_key.encode('ascii'),
|
||||
private_key=user.company_id.gengo_private_key.encode('ascii'),
|
||||
sandbox = user.company_id.gengo_sandbox,
|
||||
)
|
||||
gengo.getAccountStats()
|
||||
return (True, gengo)
|
||||
|
@ -81,22 +79,6 @@ class base_gengo_translations(osv.osv_memory):
|
|||
_logger.exception('Gengo connection failed')
|
||||
return (False, _("Gengo connection failed with this message:\n``%s``") % e)
|
||||
|
||||
def do_check_schedular(self, cr, uid, xml_id, name, fn, context=None):
|
||||
"""
|
||||
This function is used to reset a cron to its default values, or to recreate it if it was deleted.
|
||||
"""
|
||||
cron_pool = self.pool.get('ir.cron')
|
||||
cron_vals = DEFAULT_CRON_VALS.copy()
|
||||
cron_vals.update({'name': name, "function": fn})
|
||||
try:
|
||||
res = []
|
||||
_, res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base_gengo', xml_id)
|
||||
cron_pool.write(cr, uid, [res], cron_vals, context=context)
|
||||
except:
|
||||
#the cron job was not found, probably deleted previously, so we create it again using default values
|
||||
cron_vals.update({'numbercall': -1})
|
||||
return cron_pool.create(cr, uid, cron_vals, context=context)
|
||||
|
||||
def act_update(self, cr, uid, ids, context=None):
|
||||
'''
|
||||
Function called by the wizard.
|
||||
|
@ -113,15 +95,14 @@ class base_gengo_translations(osv.osv_memory):
|
|||
if language not in supported_langs:
|
||||
raise osv.except_osv(_("Warning"), _('This language is not supported by the Gengo translation services.'))
|
||||
|
||||
#send immediately a new request for the selected language (if any)
|
||||
ctx = context.copy()
|
||||
ctx['gengo_language'] = wizard.lang_id.id
|
||||
self._sync_request(cr, uid, limit=GENGO_DEFAULT_LIMIT, context=ctx)
|
||||
self._sync_response( cr, uid, limit=GENGO_DEFAULT_LIMIT, context=ctx)
|
||||
#check the cron jobs and eventually restart/recreate them
|
||||
if wizard.restart_send_job:
|
||||
self.do_check_schedular(cr, uid, 'gengo_sync_send_request_scheduler', _('Gengo Sync Translation (Request)'), '_sync_request', context=context)
|
||||
self.do_check_schedular(cr, uid, 'gengo_sync_receive_request_scheduler', _('Gengo Sync Translation (Response)'), '_sync_response', context=context)
|
||||
if wizard.sync_limit > 200 or wizard.sync_limit < 1:
|
||||
raise osv.except_osv(_("Warning"), _('Sync limit should between 1 to 200 for Gengo translation services.'))
|
||||
if wizard.sync_type in ['send','both']:
|
||||
self._sync_request(cr, uid, wizard.sync_limit, context=ctx)
|
||||
if wizard.sync_type in ['receive','both']:
|
||||
self._sync_response( cr, uid, wizard.sync_limit, context=ctx)
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
def _sync_response(self, cr, uid, limit=GENGO_DEFAULT_LIMIT, context=None):
|
||||
|
@ -135,31 +116,31 @@ class base_gengo_translations(osv.osv_memory):
|
|||
if not flag:
|
||||
_logger.warning("%s", gengo)
|
||||
else:
|
||||
translation_id = translation_pool.search(cr, uid, [('state', '=', 'inprogress'), ('gengo_translation', 'in', ('machine','standard','pro','ultra'))], limit=limit, context=context)
|
||||
for term in translation_pool.browse(cr, uid, translation_id, context=context):
|
||||
up_term = up_comment = 0
|
||||
if term.job_id:
|
||||
vals={}
|
||||
job_response = gengo.getTranslationJob(id=term.job_id)
|
||||
if job_response['opstat'] != 'ok':
|
||||
_logger.warning("Invalid Response! Skipping translation Terms with `id` %s." % (term.job_id))
|
||||
continue
|
||||
if job_response['response']['job']['status'] == 'approved':
|
||||
vals.update({'state': 'translated',
|
||||
'value': job_response['response']['job']['body_tgt']})
|
||||
up_term += 1
|
||||
job_comment = gengo.getTranslationJobComments(id=term.job_id)
|
||||
if job_comment['opstat']=='ok':
|
||||
gengo_comments=""
|
||||
for comment in job_comment['response']['thread']:
|
||||
gengo_comments += _('%s\n\n--\n Commented on %s by %s.') % (comment['body'], time.ctime(comment['ctime']), comment['author'])
|
||||
vals.update({'gengo_comment': gengo_comments})
|
||||
up_comment += 1
|
||||
if vals:
|
||||
translation_pool.write(cr, uid, term.id, vals)
|
||||
_logger.info("Successfully Updated `%d` terms and %d Comments." % (up_term, up_comment ))
|
||||
else:
|
||||
_logger.warning("%s", 'Cannot retrieve the Gengo job ID for translation %s: %s' % (term.id, term.src))
|
||||
translation_id = translation_pool.search(cr, uid, [('state', '=', 'inprogress'), ('gengo_translation', 'in', ('machine','standard','pro','ultra')), ('job_id', "!=",False)], limit=limit, context=context)
|
||||
translation_terms = translation_pool.browse(cr, uid, translation_id, context=context)
|
||||
gengo_job_id = [term.job_id for term in translation_terms]
|
||||
if gengo_job_id:
|
||||
gengo_ids = ','.join(gengo_job_id)
|
||||
job_response = gengo.getTranslationJobBatch(id=gengo_ids)
|
||||
if job_response['opstat'] == 'ok':
|
||||
job_response_dict = dict([(job['job_id'],job) for job in job_response['response']['jobs']])
|
||||
for term in translation_terms:
|
||||
up_term = up_comment = 0
|
||||
vals={}
|
||||
if job_response_dict[term.job_id]['status'] == 'approved':
|
||||
vals.update({'state': 'translated',
|
||||
'value': job_response_dict[term.job_id]['body_tgt']})
|
||||
up_term += 1
|
||||
job_comment = gengo.getTranslationJobComments(id=term.job_id)
|
||||
if job_comment['opstat']=='ok':
|
||||
gengo_comments=""
|
||||
for comment in job_comment['response']['thread']:
|
||||
gengo_comments += _('%s\n-- Commented on %s by %s.\n\n') % (comment['body'], time.ctime(comment['ctime']), comment['author'])
|
||||
vals.update({'gengo_comment': gengo_comments})
|
||||
up_comment += 1
|
||||
if vals:
|
||||
translation_pool.write(cr, uid, term.id, vals)
|
||||
_logger.info("Successfully Updated `%d` terms and %d Comments." % (up_term, up_comment ))
|
||||
return True
|
||||
|
||||
def _update_terms(self, cr, uid, response, context=None):
|
||||
|
@ -200,7 +181,8 @@ class base_gengo_translations(osv.osv_memory):
|
|||
'lc_src': 'en',
|
||||
'lc_tgt': translation_pool._get_gengo_corresponding_language(term.lang),
|
||||
'auto_approve': auto_approve,
|
||||
'comment': user.company_id.gengo_comment,
|
||||
'comment': user.company_id.gengo_comment and "%s %s"%(user.company_id.gengo_comment,term.gengo_comment) or term.gengo_comment,
|
||||
'callback_url': self.pool.get('ir.config_parameter').get_param(cr, uid,'web.base.url') + '/website/gengo_callback/' + str(term.id)
|
||||
}
|
||||
return {'jobs': jobs}
|
||||
|
||||
|
@ -242,7 +224,7 @@ class base_gengo_translations(osv.osv_memory):
|
|||
lang_ids = [context.get('gengo_language')]
|
||||
langs = [lang.code for lang in language_pool.browse(cr, uid, lang_ids, context=context)]
|
||||
#search for the n first terms to translate
|
||||
term_ids = translation_pool.search(cr, uid, [('state', '=', 'to_translate'), ('gengo_translation', 'in', ('machine','standard','pro','ultra')), ('lang', 'in', langs)], limit=limit, context=context)
|
||||
term_ids = translation_pool.search(cr, uid, [('state', '=', 'to_translate'), ('gengo_translation', 'in', ('machine','standard','pro','ultra')), ('lang', 'in', langs),('job_id',"=",False)], limit=limit, context=context)
|
||||
if term_ids:
|
||||
self._send_translation_terms(cr, uid, term_ids, context=context)
|
||||
_logger.info("%s Translation terms have been posted to Gengo successfully", len(term_ids))
|
||||
|
|
|
@ -8,7 +8,14 @@
|
|||
<form string="Gengo Request Form" version="7.0">
|
||||
<group>
|
||||
<field name="lang_id"/>
|
||||
<field name="restart_send_job"/>
|
||||
</group>
|
||||
<group>
|
||||
<group>
|
||||
<field name="sync_type" widget="radio"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="sync_limit" required="1"/>
|
||||
</group>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="act_update" string="Send" type="object" class="oe_highlight"/>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -37,7 +37,7 @@ This is a complete document management system.
|
|||
""",
|
||||
'author': 'OpenERP SA',
|
||||
'website': 'http://www.openerp.com',
|
||||
'depends': ['knowledge'],
|
||||
'depends': ['knowledge', 'mail'],
|
||||
'data': [
|
||||
'security/document_security.xml',
|
||||
'document_view.xml',
|
||||
|
|
|
@ -235,7 +235,6 @@
|
|||
<field name="partner_id"/>
|
||||
<field name="type"/>
|
||||
</tree>
|
||||
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
@ -244,6 +243,7 @@
|
|||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">ir.attachment</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">kanban,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a new document.
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
# Swedish translation for openobject-addons
|
||||
# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
|
||||
"PO-Revision-Date: 2014-03-31 20:56+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Swedish <sv@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: 2014-04-01 05:39+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: event_sale
|
||||
#: model:ir.model,name:event_sale.model_product_product
|
||||
msgid "Product"
|
||||
msgstr "Produkt"
|
||||
|
||||
#. module: event_sale
|
||||
#: help:product.product,event_ok:0
|
||||
msgid ""
|
||||
"Determine if a product needs to create automatically an event registration "
|
||||
"at the confirmation of a sales order line."
|
||||
msgstr ""
|
||||
|
||||
#. module: event_sale
|
||||
#: help:sale.order.line,event_id:0
|
||||
msgid ""
|
||||
"Choose an event and it will automatically create a registration for this "
|
||||
"event."
|
||||
msgstr ""
|
||||
|
||||
#. module: event_sale
|
||||
#: model:event.event,name:event_sale.event_technical_training
|
||||
msgid "Technical training in Grand-Rosiere"
|
||||
msgstr ""
|
||||
|
||||
#. module: event_sale
|
||||
#: help:product.product,event_type_id:0
|
||||
msgid ""
|
||||
"Select event types so when we use this product in sales order lines, it will "
|
||||
"filter events of this type only."
|
||||
msgstr ""
|
||||
|
||||
#. module: event_sale
|
||||
#: field:product.product,event_type_id:0
|
||||
msgid "Type of Event"
|
||||
msgstr "Evenemangstyp"
|
||||
|
||||
#. module: event_sale
|
||||
#: field:sale.order.line,event_ok:0
|
||||
msgid "event_ok"
|
||||
msgstr "event_ok"
|
||||
|
||||
#. module: event_sale
|
||||
#: field:product.product,event_ok:0
|
||||
msgid "Event Subscription"
|
||||
msgstr ""
|
||||
|
||||
#. module: event_sale
|
||||
#: field:sale.order.line,event_type_id:0
|
||||
msgid "Event Type"
|
||||
msgstr "Evenemangstyp"
|
||||
|
||||
#. module: event_sale
|
||||
#: model:product.template,name:event_sale.event_product_product_template
|
||||
msgid "Technical Training"
|
||||
msgstr ""
|
||||
|
||||
#. module: event_sale
|
||||
#: code:addons/event_sale/event_sale.py:88
|
||||
#, python-format
|
||||
msgid "The registration %s has been created from the Sales Order %s."
|
||||
msgstr ""
|
||||
|
||||
#. module: event_sale
|
||||
#: field:sale.order.line,event_id:0
|
||||
msgid "Event"
|
||||
msgstr "Händelse"
|
||||
|
||||
#. module: event_sale
|
||||
#: model:ir.model,name:event_sale.model_sale_order_line
|
||||
msgid "Sales Order Line"
|
||||
msgstr "Orderrad"
|
|
@ -207,8 +207,8 @@ class account_analytic_account(osv.osv):
|
|||
'use_timesheets': fields.boolean('Timesheets', help="Check this field if this project manages timesheets"),
|
||||
}
|
||||
|
||||
def on_change_template(self, cr, uid, ids, template_id, context=None):
|
||||
res = super(account_analytic_account, self).on_change_template(cr, uid, ids, template_id, context=context)
|
||||
def on_change_template(self, cr, uid, ids, template_id, date_start=False, context=None):
|
||||
res = super(account_analytic_account, self).on_change_template(cr, uid, ids, template_id, date_start=date_start, context=context)
|
||||
if template_id and 'value' in res:
|
||||
template = self.browse(cr, uid, template_id, context=context)
|
||||
res['value']['use_timesheets'] = template.use_timesheets
|
||||
|
|
|
@ -288,6 +288,7 @@ class EscposDriver(Thread):
|
|||
+' '+ str(receipt['date']['hour']).zfill(2)
|
||||
+':'+ str(receipt['date']['minute']).zfill(2) )
|
||||
|
||||
|
||||
driver = EscposDriver()
|
||||
|
||||
driver.push_task('printstatus')
|
||||
|
|
|
@ -33,6 +33,8 @@ TXT_FONT_B = '\x1b\x4d\x01' # Font type B
|
|||
TXT_ALIGN_LT = '\x1b\x61\x00' # Left justification
|
||||
TXT_ALIGN_CT = '\x1b\x61\x01' # Centering
|
||||
TXT_ALIGN_RT = '\x1b\x61\x02' # Right justification
|
||||
TXT_COLOR_BLACK = '\x1b\x72\x00' # Default Color
|
||||
TXT_COLOR_RED = '\x1b\x72\x01' # Alternative Color ( Usually Red )
|
||||
|
||||
# Text Encoding
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ class StyleStack:
|
|||
'tabwidth': 2,
|
||||
'bullet': ' - ',
|
||||
'line-ratio':0.5,
|
||||
'color': 'black',
|
||||
|
||||
'value-decimals': 2,
|
||||
'value-symbol': '',
|
||||
|
@ -107,7 +108,11 @@ class StyleStack:
|
|||
'double-height': TXT_2HEIGHT,
|
||||
'double-width': TXT_2WIDTH,
|
||||
'double': TXT_DOUBLE,
|
||||
}
|
||||
},
|
||||
'color': {
|
||||
'black': TXT_COLOR_BLACK,
|
||||
'red': TXT_COLOR_RED,
|
||||
},
|
||||
}
|
||||
|
||||
self.push(self.defaults)
|
||||
|
@ -595,7 +600,7 @@ class Escpos:
|
|||
width=stylestack.get('value-width'),
|
||||
decimals_separator=stylestack.get('value-decimals-separator'),
|
||||
thousands_separator=stylestack.get('value-thousands-separator'),
|
||||
autoint=(stylestack.get('autoint') == 'on'),
|
||||
autoint=(stylestack.get('value-autoint') == 'on'),
|
||||
symbol=stylestack.get('value-symbol'),
|
||||
position=stylestack.get('value-symbol-position')
|
||||
))
|
||||
|
|
|
@ -32,7 +32,7 @@ upgrade_template = """
|
|||
$('#upgrade').html('Upgrade Successful<br \\>Click to Restart the PosBox');
|
||||
$('#upgrade').off('click');
|
||||
$('#upgrade').click(function(){
|
||||
$.ajax({ url:'hw_proxy/perform_restart' })
|
||||
$.ajax({ url:'/hw_proxy/perform_restart' })
|
||||
$('#upgrade').text('Restarting');
|
||||
$('#upgrade').off('click');
|
||||
setTimeout(function(){
|
||||
|
|
|
@ -8,13 +8,13 @@ msgstr ""
|
|||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-11-24 02:53+0000\n"
|
||||
"PO-Revision-Date: 2011-06-28 09:19+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"PO-Revision-Date: 2014-03-27 20:07+0000\n"
|
||||
"Last-Translator: Päivi Kouki <paivi.kouki@uta.fi>\n"
|
||||
"Language-Team: Finnish <fi@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: 2014-03-27 07:08+0000\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-28 05:41+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: l10n_be_coda
|
||||
|
@ -292,7 +292,7 @@ msgstr "Tuontipäivä"
|
|||
#. module: l10n_be_coda
|
||||
#: model:account.coda.trans.category,description:l10n_be_coda.actrca_039
|
||||
msgid "Telecommunications"
|
||||
msgstr ""
|
||||
msgstr "Tietoliikenne"
|
||||
|
||||
#. module: l10n_be_coda
|
||||
#: field:coda.bank.statement.line,globalisation_id:0
|
||||
|
@ -344,7 +344,7 @@ msgstr ""
|
|||
#. module: l10n_be_coda
|
||||
#: model:account.coda.trans.code,comment:l10n_be_coda.actcc_80_27
|
||||
msgid "For publications of the financial institution"
|
||||
msgstr ""
|
||||
msgstr "Taloudellisen instituution julkaisuja varten"
|
||||
|
||||
#. module: l10n_be_coda
|
||||
#: model:account.coda.trans.code,description:l10n_be_coda.actcc_47_01
|
||||
|
@ -359,7 +359,7 @@ msgstr ""
|
|||
#. module: l10n_be_coda
|
||||
#: selection:account.coda.trans.code,type:0
|
||||
msgid "Transaction Code"
|
||||
msgstr ""
|
||||
msgstr "Tapahtumakoodi"
|
||||
|
||||
#. module: l10n_be_coda
|
||||
#: model:account.coda.trans.code,description:l10n_be_coda.actcc_47_13
|
||||
|
@ -389,7 +389,7 @@ msgstr "CODA-tiliotekategoria"
|
|||
#. module: l10n_be_coda
|
||||
#: model:account.coda.trans.category,description:l10n_be_coda.actrca_067
|
||||
msgid "Fixed loan advance - extension"
|
||||
msgstr ""
|
||||
msgstr "Kiinteä lainaennakko - lisäaika"
|
||||
|
||||
#. module: l10n_be_coda
|
||||
#: model:account.coda.trans.code,description:l10n_be_coda.actcc_13_07
|
||||
|
|
|
@ -89,5 +89,36 @@
|
|||
<!-- Add menu entry in Settings/Email -->
|
||||
<menuitem name="Messages" id="menu_mail_message" parent="base.menu_email" action="action_view_mail_message"/>
|
||||
|
||||
<record model="ir.ui.view" id="view_document_file_kanban">
|
||||
<field name="name">ir.attachment kanban</field>
|
||||
<field name="model">ir.attachment</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban>
|
||||
<field name="file_type_icon"/>
|
||||
<field name="url"/>
|
||||
<field name="name"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div class="oe_kanban_global_click">
|
||||
<div t-attf-class="oe_attachment" t-if="record.file_type_icon.value != 'webimage'">
|
||||
<img t-att-src="'/mail/static/src/img/mimetypes/' + record.file_type_icon.value + '.png'"></img>
|
||||
<div class='oe_name'><t t-raw='record.name.value' />bb</div>
|
||||
</div>
|
||||
<div t-attf-class="oe_attachment oe_preview" t-if="record.file_type_icon.value == 'webimage'">
|
||||
<img t-att-src="kanban_image('ir.attachment', 'datas', record.id.value)" class="oe_kanban_image"/>
|
||||
<div class='oe_name'><t t-raw='record.name.value' />aa</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
<record id="base.action_attachment" model="ir.actions.act_window">
|
||||
<field name="view_mode">kanban,form</field>
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</openerp>
|
||||
|
|
|
@ -318,7 +318,7 @@
|
|||
.openerp .oe_mail .oe_msg_composer .oe_recipients input{
|
||||
vertical-align: middle;
|
||||
}
|
||||
.openerp .oe_mail .oe_attachment{
|
||||
.oe_attachment{
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
margin: 4px 2px;
|
||||
|
@ -328,7 +328,7 @@
|
|||
text-align: center;
|
||||
vertical-align: top;
|
||||
}
|
||||
.openerp .oe_mail .oe_attachment .oe_name{
|
||||
.oe_attachment .oe_name{
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
padding: 1px 3px;
|
||||
|
@ -341,10 +341,10 @@
|
|||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.openerp .oe_mail .oe_attachment.oe_preview{
|
||||
.oe_attachment.oe_preview{
|
||||
background: url( data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAJ0lEQVQYV2MsLS39z4AGLCws0IUYGIeCwrVr12J45sSJE5ieGQIKAbuZKf/EMCs7AAAAAElFTkSuQmCC );
|
||||
}
|
||||
.openerp .oe_mail .oe_attachment .oe_progress_bar{
|
||||
.oe_attachment .oe_progress_bar{
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 18px;
|
||||
|
@ -364,7 +364,7 @@
|
|||
-o-animation: oe_mail_attach_loading_anim 0.75s infinite linear;
|
||||
animation: oe_mail_attach_loading_anim 0.75s infinite linear;
|
||||
}
|
||||
.openerp .oe_mail .oe_attachment.oe_uploading .oe_progress_bar{
|
||||
.oe_attachment.oe_uploading .oe_progress_bar{
|
||||
display: block;
|
||||
}
|
||||
@-webkit-keyframes oe_mail_attach_loading_anim{
|
||||
|
@ -387,7 +387,7 @@
|
|||
50% { background: #009123 }
|
||||
100% { background: #4BBD00 }
|
||||
}
|
||||
.openerp .oe_mail .oe_attachment.oe_preview .oe_name{
|
||||
.oe_attachment.oe_preview .oe_name{
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
margin: 3px;
|
||||
|
@ -405,14 +405,14 @@
|
|||
-o-transition: opacity 0.2s linear;
|
||||
transition: opacity 0.2s linear;
|
||||
}
|
||||
.openerp .oe_mail .oe_attachment.oe_preview:hover .oe_name{
|
||||
.oe_attachment.oe_preview:hover .oe_name{
|
||||
opacity: 1;
|
||||
-webkit-transition: opacity 0.2s linear;
|
||||
-moz-transition: opacity 0.2s linear;
|
||||
-o-transition: opacity 0.2s linear;
|
||||
transition: opacity 0.2s linear;
|
||||
}
|
||||
.openerp .oe_mail .oe_attachment img{
|
||||
.oe_attachment img{
|
||||
position: absolute;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
|
@ -420,7 +420,7 @@
|
|||
left: 50%;
|
||||
margin-left: -24px;
|
||||
}
|
||||
.openerp .oe_mail .oe_attachment.oe_preview img{
|
||||
.oe_attachment.oe_preview img{
|
||||
display: block;
|
||||
position: relative;
|
||||
margin:0px;
|
||||
|
|
|
@ -400,7 +400,7 @@
|
|||
<t t-set='taxincluded' t-value='Math.abs(receipt.subtotal - receipt.total_with_tax) <= 0.000001' />
|
||||
<t t-if='!taxincluded'>
|
||||
<line><right>--------</right></line>
|
||||
<line><left>Subtotal</left><right> <value>receipt.subtotal</value></right></line>
|
||||
<line><left>Subtotal</left><right> <value><t t-esc="receipt.subtotal" /></value></right></line>
|
||||
<t t-foreach='receipt.tax_details' t-as='tax'>
|
||||
<line>
|
||||
<left><t t-esc='tax.name' /></left>
|
||||
|
@ -411,7 +411,7 @@
|
|||
|
||||
<!-- Total -->
|
||||
|
||||
<line><right>-------</right></line>
|
||||
<line><right>--------</right></line>
|
||||
<line size='double-height'>
|
||||
<left><pre> TOTAL</pre></left>
|
||||
<right><value><t t-esc='receipt.total_with_tax' /></value></right>
|
||||
|
|
|
@ -223,7 +223,7 @@ class project(osv.osv):
|
|||
'res_model': 'ir.attachment',
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_id': False,
|
||||
'view_mode': 'tree,form',
|
||||
'view_mode': 'kanban,form',
|
||||
'view_type': 'form',
|
||||
'limit': 80,
|
||||
'context': "{'default_res_model': '%s','default_res_id': %d}" % (self._name, res_id)
|
||||
|
@ -1202,8 +1202,8 @@ class account_analytic_account(osv.osv):
|
|||
'company_uom_id': fields.related('company_id', 'project_time_mode_id', type='many2one', relation='product.uom'),
|
||||
}
|
||||
|
||||
def on_change_template(self, cr, uid, ids, template_id, context=None):
|
||||
res = super(account_analytic_account, self).on_change_template(cr, uid, ids, template_id, context=context)
|
||||
def on_change_template(self, cr, uid, ids, template_id, date_start=False, context=None):
|
||||
res = super(account_analytic_account, self).on_change_template(cr, uid, ids, template_id, date_start=date_start, context=context)
|
||||
if template_id and 'value' in res:
|
||||
template = self.browse(cr, uid, template_id, context=context)
|
||||
res['value']['use_tasks'] = template.use_tasks
|
||||
|
|
|
@ -530,8 +530,8 @@ class account_analytic_account(osv.Model):
|
|||
'use_issues': fields.boolean('Issues', help="Check this field if this project manages issues"),
|
||||
}
|
||||
|
||||
def on_change_template(self, cr, uid, ids, template_id, context=None):
|
||||
res = super(account_analytic_account, self).on_change_template(cr, uid, ids, template_id, context=context)
|
||||
def on_change_template(self, cr, uid, ids, template_id, date_start=False, context=None):
|
||||
res = super(account_analytic_account, self).on_change_template(cr, uid, ids, template_id, date_start=date_start, context=context)
|
||||
if template_id and 'value' in res:
|
||||
template = self.browse(cr, uid, template_id, context=context)
|
||||
res['value']['use_issues'] = template.use_issues
|
||||
|
|
|
@ -273,8 +273,8 @@ class account_analytic_account(osv.osv):
|
|||
'use_phases': fields.boolean('Phases', help="Check this field if you plan to use phase-based scheduling"),
|
||||
}
|
||||
|
||||
def on_change_template(self, cr, uid, ids, template_id, context=None):
|
||||
res = super(account_analytic_account, self).on_change_template(cr, uid, ids, template_id, context=context)
|
||||
def on_change_template(self, cr, uid, ids, template_id, date_start=False, context=None):
|
||||
res = super(account_analytic_account, self).on_change_template(cr, uid, ids, template_id, date_start=date_start, context=context)
|
||||
if template_id and 'value' in res:
|
||||
template = self.browse(cr, uid, template_id, context=context)
|
||||
res['value']['use_phases'] = template.use_phases
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
# Swedish translation for openobject-addons
|
||||
# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:06+0000\n"
|
||||
"PO-Revision-Date: 2014-03-31 20:14+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Swedish <sv@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: 2014-04-01 05:39+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: web_linkedin
|
||||
#: view:sale.config.settings:0
|
||||
msgid "here:"
|
||||
msgstr "här:"
|
||||
|
||||
#. module: web_linkedin
|
||||
#: field:sale.config.settings,api_key:0
|
||||
msgid "API Key"
|
||||
msgstr "API-nyckel"
|
||||
|
||||
#. module: web_linkedin
|
||||
#. openerp-web
|
||||
#: code:addons/web_linkedin/static/src/js/linkedin.js:331
|
||||
#, python-format
|
||||
msgid "No results found"
|
||||
msgstr "Inga resultat hittades"
|
||||
|
||||
#. module: web_linkedin
|
||||
#. openerp-web
|
||||
#: code:addons/web_linkedin/static/src/js/linkedin.js:62
|
||||
#, python-format
|
||||
msgid "Ok"
|
||||
msgstr "Ok"
|
||||
|
||||
#. module: web_linkedin
|
||||
#: view:sale.config.settings:0
|
||||
msgid "Log into LinkedIn."
|
||||
msgstr "Logga in på LinkedIn"
|
||||
|
||||
#. module: web_linkedin
|
||||
#. openerp-web
|
||||
#: code:addons/web_linkedin/static/src/xml/linkedin.xml:13
|
||||
#, python-format
|
||||
msgid "People"
|
||||
msgstr "Personer"
|
||||
|
||||
#. module: web_linkedin
|
||||
#: model:ir.model,name:web_linkedin.model_sale_config_settings
|
||||
msgid "sale.config.settings"
|
||||
msgstr "sale.config.settings"
|
||||
|
||||
#. module: web_linkedin
|
||||
#: field:sale.config.settings,server_domain:0
|
||||
msgid "unknown"
|
||||
msgstr "okänd"
|
||||
|
||||
#. module: web_linkedin
|
||||
#: view:sale.config.settings:0
|
||||
msgid "https://www.linkedin.com/secure/developer"
|
||||
msgstr "https://www.linkedin.com/secure/developer"
|
||||
|
||||
#. module: web_linkedin
|
||||
#. openerp-web
|
||||
#: code:addons/web_linkedin/static/src/xml/linkedin.xml:15
|
||||
#, python-format
|
||||
msgid "Companies"
|
||||
msgstr "Bolag"
|
||||
|
||||
#. module: web_linkedin
|
||||
#: view:sale.config.settings:0
|
||||
msgid "API key"
|
||||
msgstr "API nyckel"
|
||||
|
||||
#. module: web_linkedin
|
||||
#: view:sale.config.settings:0
|
||||
msgid "Copy the"
|
||||
msgstr "Kopiera"
|
||||
|
||||
#. module: web_linkedin
|
||||
#. openerp-web
|
||||
#: code:addons/web_linkedin/static/src/js/linkedin.js:263
|
||||
#, python-format
|
||||
msgid "LinkedIn search"
|
||||
msgstr "Linkedinsökning"
|
||||
|
||||
#. module: web_linkedin
|
||||
#. openerp-web
|
||||
#: code:addons/web_linkedin/static/src/xml/linkedin.xml:31
|
||||
#, python-format
|
||||
msgid ""
|
||||
"LinkedIn access was not enabled on this server.\n"
|
||||
" Please ask your administrator to configure it in Settings > "
|
||||
"Configuration > Sales > Social Network Integration."
|
||||
msgstr ""
|
||||
|
||||
#. module: web_linkedin
|
||||
#: view:sale.config.settings:0
|
||||
msgid ""
|
||||
"To use the LinkedIn module with this database, an API Key is required. "
|
||||
"Please follow this procedure:"
|
||||
msgstr ""
|
||||
"För att använda Linkedin-modulen med denna databas krävs en API-nyckel. Följ "
|
||||
"denna procedur:"
|
||||
|
||||
#. module: web_linkedin
|
||||
#. openerp-web
|
||||
#: code:addons/web_linkedin/static/src/js/linkedin.js:60
|
||||
#, python-format
|
||||
msgid "LinkedIn is not enabled"
|
||||
msgstr "LinkedIn är inte aktiverad"
|
||||
|
||||
#. module: web_linkedin
|
||||
#: view:sale.config.settings:0
|
||||
msgid "Add a new application and fill the form:"
|
||||
msgstr ""
|
||||
|
||||
#. module: web_linkedin
|
||||
#: view:sale.config.settings:0
|
||||
msgid "Go to this URL:"
|
||||
msgstr "Gå till denna URL:"
|
||||
|
||||
#. module: web_linkedin
|
||||
#: view:sale.config.settings:0
|
||||
msgid "The programming tool is Javascript"
|
||||
msgstr "Programmeringshjälpmedlet är Javascript"
|
||||
|
||||
#. module: web_linkedin
|
||||
#: view:sale.config.settings:0
|
||||
msgid "JavaScript API Domain:"
|
||||
msgstr "JavaScript API Domän:"
|
|
@ -206,7 +206,7 @@ class Website(openerp.addons.web.controllers.main.Home):
|
|||
views_ids = [view.get('id') for view in views if view.get('active')]
|
||||
domain = [('type', '=', 'view'), ('res_id', 'in', views_ids), ('lang', '=', lang)]
|
||||
irt = request.registry.get('ir.translation')
|
||||
return irt.search_read(request.cr, request.uid, domain, ['id', 'res_id', 'value'], context=request.context)
|
||||
return irt.search_read(request.cr, request.uid, domain, ['id', 'res_id', 'value','state','gengo_translation'], context=request.context)
|
||||
|
||||
@http.route('/website/set_translations', type='json', auth='public', website=True)
|
||||
def set_translations(self, data, lang):
|
||||
|
@ -240,6 +240,9 @@ class Website(openerp.addons.web.controllers.main.Home):
|
|||
'source': initial_content,
|
||||
'value': new_content,
|
||||
}
|
||||
if t.get('gengo_translation'):
|
||||
new_trans['gengo_translation'] = t.get('gengo_translation')
|
||||
new_trans['gengo_comment'] = t.get('gengo_comment')
|
||||
irt.create(request.cr, request.uid, new_trans)
|
||||
return True
|
||||
|
||||
|
|
|
@ -414,9 +414,6 @@ div.carousel .carousel-indicators .active {
|
|||
.oe_dark {
|
||||
background: #eff8f8;
|
||||
background: rgba(200, 200, 200, 0.14);
|
||||
-webkit-box-shadow: 0px 5px 9px -7px rgba(0, 0, 255, 0.5) inset, 0px -3px 9px -7px rgba(0, 0, 255, 0.5) inset;
|
||||
-moz-box-shadow: 0px 5px 9px -7px rgba(0, 0, 255, 0.5) inset, 0px -3px 9px -7px rgba(0, 0, 255, 0.5) inset;
|
||||
box-shadow: 0px 5px 9px -7px rgba(0, 0, 255, 0.5) inset, 0px -3px 9px -7px rgba(0, 0, 255, 0.5) inset;
|
||||
}
|
||||
|
||||
.oe_black {
|
||||
|
@ -530,9 +527,3 @@ span[data-oe-type="monetary"] {
|
|||
width: 400px;
|
||||
margin: 40px auto;
|
||||
}
|
||||
|
||||
.oe_website_overflow_ellipsis{
|
||||
white-space:nowrap;
|
||||
overflow:hidden;
|
||||
text-overflow:ellipsis;
|
||||
}
|
||||
|
|
|
@ -342,7 +342,6 @@ div.carousel
|
|||
.oe_dark
|
||||
background: #eff8f8
|
||||
background: rgba(200, 200, 200, 0.14)
|
||||
+box-shadow(0px 5px 9px -7px rgba(0, 0, 255, 0.5) inset, 0px -3px 9px -7px rgba(0, 0, 255, 0.5) inset)
|
||||
|
||||
.oe_black
|
||||
background-color: rgba(0, 0, 0, 0.9)
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
}
|
||||
}).then(function (val, field, $dialog) {
|
||||
if (val) {
|
||||
var url = '/website/add' + encodeURI(val);
|
||||
var url = '/website/add/' + encodeURI(val);
|
||||
if ($dialog.find('input[type="checkbox"]').is(':checked')) url +="?add_menu=1";
|
||||
document.location = url;
|
||||
}
|
||||
|
|
|
@ -34,11 +34,17 @@
|
|||
dialog.$el.modal('hide');
|
||||
self.translate().then(function () {
|
||||
mysuper.call(self);
|
||||
if(self.gengo_translate){
|
||||
self.translation_gengo_display()
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.translate().then(function () {
|
||||
mysuper.call(self);
|
||||
if(self.gengo_translate){
|
||||
self.translation_gengo_display()
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -68,7 +74,7 @@
|
|||
var source_attr = 'data-oe-source-id';
|
||||
var $editables = $('[data-oe-model="ir.ui.view"]')
|
||||
.not('link, script')
|
||||
.not('.oe_snippets,.oe_snippet, .oe_snippet *')
|
||||
.not('.oe_snippets,.oe_snippet, .oe_snippet *, .navbar-toggle')
|
||||
.not('[data-oe-type]');
|
||||
|
||||
$editables.each(function () {
|
||||
|
@ -92,7 +98,7 @@
|
|||
self.sanitizeNode($node[0]);
|
||||
}
|
||||
if (self.getInitialContent($node[0]) !== $node.text()) {
|
||||
$node.addClass('oe_dirty').removeClass('oe_translatable_todo');
|
||||
$node.addClass('oe_dirty').removeClass('oe_translatable_todo oe_translatable_inprogress');
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
|
@ -119,6 +125,9 @@
|
|||
});
|
||||
if (trans.length) {
|
||||
node.setAttribute('data-oe-translation-id', trans[0].id);
|
||||
if(trans[0].gengo_translation && (trans[0].state == 'inprogress' || trans[0].state == 'to_translate')){
|
||||
node.className += ' oe_translatable_inprogress';
|
||||
}
|
||||
} else {
|
||||
node.className += ' oe_translatable_todo';
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
</section>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div class="pull-left">
|
||||
<div class="pull-right">
|
||||
<input type="checkbox" name="do_not_show"/>
|
||||
Do not show this dialog later.
|
||||
</div>
|
||||
|
|
|
@ -358,39 +358,6 @@
|
|||
|
||||
<div id="snippet_feature" class="tab-pane fade">
|
||||
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_portfolio.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Portfolio</span>
|
||||
</div>
|
||||
<section class="oe_snippet_body">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12 text-center mt16 mb32">
|
||||
<h2>Our Porfolio</h2>
|
||||
<h4 class="text-muted">More than 500 successful projects</h4>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<img class="img img-thumbnail img-responsive" src="/website/static/src/img/deers.jpg"/>
|
||||
<img class="img img-thumbnail img-responsive" src="/website/static/src/img/desert.jpg"/>
|
||||
<img class="img img-thumbnail img-responsive" src="/website/static/src/img/china.jpg"/>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<img class="img img-thumbnail img-responsive" src="/website/static/src/img/desert.jpg"/>
|
||||
<img class="img img-thumbnail img-responsive" src="/website/static/src/img/china.jpg"/>
|
||||
<img class="img img-thumbnail img-responsive" src="/website/static/src/img/deers.jpg"/>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<img class="img img-thumbnail img-responsive" src="/website/static/src/img/landscape.jpg"/>
|
||||
<img class="img img-thumbnail img-responsive" src="/website/static/src/img/china.jpg"/>
|
||||
<img class="img img-thumbnail img-responsive" src="/website/static/src/img/desert.jpg"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_image_gallery.png"/>
|
||||
|
@ -544,13 +511,23 @@
|
|||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_button.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Button</span>
|
||||
</div>
|
||||
<section class="oe_snippet_body oe_snippet_darken oe_dark mb32 mt32">
|
||||
<section class="oe_snippet_body jumbotron oe_dark">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12 text-center mt16 mb16">
|
||||
<a href="/page/website.contactus" class="btn btn-primary btn-lg">Contact us</a>
|
||||
<div class="row">
|
||||
<div class="col-md-9">
|
||||
<p class="mb0">
|
||||
<strong>50,000+ companies run Odoo to grow their businesses.</strong>
|
||||
</p><p class="mb0 text-muted">
|
||||
Join us and make your company a better place.
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<a href="page/contactus" class="btn btn-primary btn-lg pull-right mt8">
|
||||
<i class="fa fa-arrow-right"></i>
|
||||
Contact Us Now
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
@ -984,4 +961,4 @@
|
|||
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</openerp>
|
||||
|
|
|
@ -592,19 +592,68 @@
|
|||
<link rel='stylesheet' href='/website/static/src/css/website.css'/>
|
||||
<script type="text/javascript" src="/web/static/lib/jquery/jquery.js"></script>
|
||||
<script type="text/javascript" src="/web/static/lib/bootstrap/js/bootstrap.js"></script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
var button = $('#reset_templates_button');
|
||||
button.click(function() {
|
||||
var dialog = $('#reset_template_confirmation').modal('show');
|
||||
var input = dialog.find('input[type="text"]').val('').focus();
|
||||
var dialog_form = dialog.find('form');
|
||||
dialog_form.submit(function() {
|
||||
if (input.val() == dialog.find('.confirm_word').text()) {
|
||||
dialog.modal('hide');
|
||||
button.prop('disabled', true).text('Working...');
|
||||
$('#reset_templates_form').trigger('submit');
|
||||
} else {
|
||||
input.val('').focus();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapwrap">
|
||||
<div class="navbar navbar-default navbar-static-top">
|
||||
<div class="container">
|
||||
<div class="collapse navbar-collapse navbar-top-collapse">
|
||||
<ul class="nav navbar-nav pull-right">
|
||||
<li><a href="/">Home</a></li>
|
||||
<li><a href="javascript: window.history.back()">Back</a></li>
|
||||
</ul>
|
||||
<div id="reset_template_confirmation" class="modal" tabindex="-1" role="dialog" aria-hidden="true" t-ignore="true">
|
||||
<div class="modal-dialog">
|
||||
<form class="form-horizontal" role="form">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 class="modal-title">Reset templates</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group mb0">
|
||||
<label for="page-name" class="col-sm-9">
|
||||
<p>The selected templates will be reset to their factory settings.</p>
|
||||
<p>Type '<i class="confirm_word">yes</i>' in the box below if you want to confirm.</p>
|
||||
</label>
|
||||
<div class="col-sm-3 mt16">
|
||||
<input type="text" class="form-control" required="required" placeholder="yes"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<input type="submit" value="Confirm" class="btn btn-primary"/>
|
||||
<button type="button" class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="wrapwrap">
|
||||
<div class="navbar navbar-default navbar-static-top">
|
||||
<div class="container">
|
||||
<div class="collapse navbar-collapse navbar-top-collapse">
|
||||
<ul class="nav navbar-nav pull-right">
|
||||
<li><a href="/">Home</a></li>
|
||||
<li><a href="javascript: window.history.back()">Back</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb32">
|
||||
<div class="oe_structure">
|
||||
<h1 class="container mt32"><t t-esc="status_code"/>: <t t-esc="status_message"/></h1>
|
||||
|
@ -615,7 +664,7 @@
|
|||
<h4>Template fallback</h4>
|
||||
<p>An error occured while rendering the template <code t-esc="qweb_exception.qweb['template']"/>.</p>
|
||||
<p>If this error is caused by a change of yours in the templates, you have the possibility to reset one or more templates to their <strong>factory settings</strong>.</p>
|
||||
<form action="/website/reset_templates" method="post">
|
||||
<form action="/website/reset_templates" method="post" id="reset_templates_form">
|
||||
<ul class="oe_template_fallback">
|
||||
<li t-foreach="views" t-as="view">
|
||||
<label>
|
||||
|
@ -625,7 +674,7 @@
|
|||
</li>
|
||||
</ul>
|
||||
<input type="hidden" name="redirect" t-att-value="request.httprequest.path"/>
|
||||
<input type="submit" value="Reset selected templates"/>
|
||||
<button id="reset_templates_button">Reset selected templates</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -19,13 +19,46 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
import datetime
|
||||
import werkzeug
|
||||
|
||||
from openerp import tools
|
||||
from openerp.addons.web import http
|
||||
from openerp.addons.web.http import request
|
||||
from openerp.addons.website.models.website import slug
|
||||
from openerp.osv.orm import browse_record
|
||||
from openerp.tools.translate import _
|
||||
from openerp import SUPERUSER_ID
|
||||
|
||||
import werkzeug
|
||||
|
||||
class QueryURL(object):
|
||||
def __init__(self, path='', path_args=None, **args):
|
||||
self.path = path
|
||||
self.args = args
|
||||
self.path_args = set(path_args or [])
|
||||
|
||||
def __call__(self, path=None, path_args=None, **kw):
|
||||
path = path or self.path
|
||||
for k, v in self.args.items():
|
||||
kw.setdefault(k, v)
|
||||
path_args = set(path_args or []).union(self.path_args)
|
||||
paths, fragments = [], []
|
||||
for key, value in kw.items():
|
||||
if value and key in path_args:
|
||||
if isinstance(value, browse_record):
|
||||
paths.append((key, slug(value)))
|
||||
else:
|
||||
paths.append((key, value))
|
||||
elif value:
|
||||
if isinstance(value, list) or isinstance(value, set):
|
||||
fragments.append(werkzeug.url_encode([(key, item) for item in value]))
|
||||
else:
|
||||
fragments.append(werkzeug.url_encode([(key, value)]))
|
||||
for key, value in paths:
|
||||
path += '/' + key + '/%s' % value
|
||||
if fragments:
|
||||
path += '?' + '&'.join(fragments)
|
||||
return path
|
||||
|
||||
|
||||
class WebsiteBlog(http.Controller):
|
||||
|
@ -37,15 +70,17 @@ class WebsiteBlog(http.Controller):
|
|||
groups = blog_post_obj.read_group(request.cr, request.uid, [], ['name', 'create_date'],
|
||||
groupby="create_date", orderby="create_date asc", context=request.context)
|
||||
for group in groups:
|
||||
group['date'] = "%s_%s" % (group['__domain'][0][2], group['__domain'][1][2])
|
||||
begin_date = datetime.datetime.strptime(group['__domain'][0][2], tools.DEFAULT_SERVER_DATETIME_FORMAT).date()
|
||||
end_date = datetime.datetime.strptime(group['__domain'][1][2], tools.DEFAULT_SERVER_DATETIME_FORMAT).date()
|
||||
group['date_begin'] = '%s' % datetime.date.strftime(begin_date, tools.DEFAULT_SERVER_DATE_FORMAT)
|
||||
group['date_end'] = '%s' % datetime.date.strftime(end_date, tools.DEFAULT_SERVER_DATE_FORMAT)
|
||||
return groups
|
||||
|
||||
@http.route([
|
||||
'/blog',
|
||||
'/blog/page/<int:page>',
|
||||
], type='http', auth="public", website=True, multilang=True)
|
||||
def blogs(self, page=1):
|
||||
BYPAGE = 60
|
||||
def blogs(self, page=1, **post):
|
||||
cr, uid, context = request.cr, request.uid, request.context
|
||||
blog_obj = request.registry['blog.post']
|
||||
total = blog_obj.search(cr, uid, [], count=True, context=context)
|
||||
|
@ -53,13 +88,15 @@ class WebsiteBlog(http.Controller):
|
|||
url='/blog',
|
||||
total=total,
|
||||
page=page,
|
||||
step=BYPAGE,
|
||||
step=self._blog_post_per_page,
|
||||
)
|
||||
bids = blog_obj.search(cr, uid, [], offset=(page-1)*BYPAGE, limit=BYPAGE, context=context)
|
||||
blogs = blog_obj.browse(cr, uid, bids, context=context)
|
||||
post_ids = blog_obj.search(cr, uid, [], offset=(page-1)*self._blog_post_per_page, limit=self._blog_post_per_page, context=context)
|
||||
posts = blog_obj.browse(cr, uid, post_ids, context=context)
|
||||
blog_url = QueryURL('', ['blog', 'tag'])
|
||||
return request.website.render("website_blog.latest_blogs", {
|
||||
'blogs': blogs,
|
||||
'pager': pager
|
||||
'posts': posts,
|
||||
'pager': pager,
|
||||
'blog_url': blog_url,
|
||||
})
|
||||
|
||||
@http.route([
|
||||
|
@ -67,12 +104,8 @@ class WebsiteBlog(http.Controller):
|
|||
'/blog/<model("blog.blog"):blog>/page/<int:page>',
|
||||
'/blog/<model("blog.blog"):blog>/tag/<model("blog.tag"):tag>',
|
||||
'/blog/<model("blog.blog"):blog>/tag/<model("blog.tag"):tag>/page/<int:page>',
|
||||
'/blog/<model("blog.blog"):blog>/date/<string(length=21):date>',
|
||||
'/blog/<model("blog.blog"):blog>/date/<string(length=21):date>/page/<int:page>',
|
||||
'/blog/<model("blog.blog"):blog>/tag/<model("blog.tag"):tag>/date/<string(length=21):date>',
|
||||
'/blog/<model("blog.blog"):blog>/tag/<model("blog.tag"):tag>/date/<string(length=21):date>/page/<int:page>',
|
||||
], type='http', auth="public", website=True, multilang=True)
|
||||
def blog(self, blog=None, tag=None, date=None, page=1, **opt):
|
||||
def blog(self, blog=None, tag=None, page=1, **opt):
|
||||
""" Prepare all values to display the blog.
|
||||
|
||||
:param blog: blog currently browsed.
|
||||
|
@ -91,7 +124,7 @@ class WebsiteBlog(http.Controller):
|
|||
- 'tag': current tag, if tag_id
|
||||
- 'nav_list': a dict [year][month] for archives navigation
|
||||
"""
|
||||
BYPAGE = 10
|
||||
date_begin, date_end = opt.get('date_begin'), opt.get('date_end')
|
||||
|
||||
cr, uid, context = request.cr, request.uid, request.context
|
||||
blog_post_obj = request.registry['blog.post']
|
||||
|
@ -99,31 +132,29 @@ class WebsiteBlog(http.Controller):
|
|||
blog_posts = None
|
||||
|
||||
blog_obj = request.registry['blog.blog']
|
||||
blog_ids = blog_obj.search(cr, uid, [], context=context)
|
||||
blog_ids = blog_obj.search(cr, uid, [], order="create_date asc", context=context)
|
||||
blogs = blog_obj.browse(cr, uid, blog_ids, context=context)
|
||||
|
||||
path_filter = ""
|
||||
domain = []
|
||||
|
||||
if blog:
|
||||
path_filter += "%s" % blog.id
|
||||
domain += [("id", "in", [post.id for post in blog.blog_post_ids])]
|
||||
domain += [('blog_id', '=', blog.id)]
|
||||
if tag:
|
||||
path_filter += 'tag/%s' % tag.id
|
||||
domain += [("id", "in", [post.id for post in tag.blog_post_ids])]
|
||||
if date:
|
||||
path_filter += "date/%s" % date
|
||||
domain += [("create_date", ">=", date.split("_")[0]), ("create_date", "<=", date.split("_")[1])]
|
||||
domain += [('tag_ids', 'in', tag.id)]
|
||||
if date_begin and date_end:
|
||||
domain += [("create_date", ">=", date_begin), ("create_date", "<=", date_end)]
|
||||
|
||||
blog_post_ids = blog_post_obj.search(cr, uid, domain, context=context)
|
||||
blog_url = QueryURL('', ['blog', 'tag'], blog=blog, tag=tag, date_begin=date_begin, date_end=date_end)
|
||||
post_url = QueryURL('', ['blogpost'], tag_id=tag and tag.id or None, date_begin=date_begin, date_end=date_end)
|
||||
|
||||
blog_post_ids = blog_post_obj.search(cr, uid, domain, order="create_date asc", context=context)
|
||||
blog_posts = blog_post_obj.browse(cr, uid, blog_post_ids, context=context)
|
||||
|
||||
pager = request.website.pager(
|
||||
url="/blog/%s" % path_filter,
|
||||
url=blog_url(),
|
||||
total=len(blog_posts),
|
||||
page=page,
|
||||
step=self._blog_post_per_page,
|
||||
scope=BYPAGE
|
||||
)
|
||||
pager_begin = (page - 1) * self._blog_post_per_page
|
||||
pager_end = page * self._blog_post_per_page
|
||||
|
@ -141,15 +172,16 @@ class WebsiteBlog(http.Controller):
|
|||
'blog_posts': blog_posts,
|
||||
'pager': pager,
|
||||
'nav_list': self.nav_list(),
|
||||
'path_filter': path_filter,
|
||||
'date': date,
|
||||
'blog_url': blog_url,
|
||||
'post_url': post_url,
|
||||
'date': date_begin,
|
||||
}
|
||||
return request.website.render("website_blog.blog_post_short", values)
|
||||
|
||||
@http.route([
|
||||
'/blogpost/<model("blog.post"):blog_post>',
|
||||
], type='http', auth="public", website=True, multilang=True)
|
||||
def blog_post(self, blog_post, tag=None, date=None, page=1, enable_editor=None, **post):
|
||||
def blog_post(self, blog_post, tag_id=None, page=1, enable_editor=None, **post):
|
||||
""" Prepare all values to display the blog.
|
||||
|
||||
:param blog_post: blog post currently browsed. If not set, the user is
|
||||
|
@ -173,6 +205,7 @@ class WebsiteBlog(http.Controller):
|
|||
- 'tag': current tag, if tag_id
|
||||
- 'nav_list': a dict [year][month] for archives navigation
|
||||
"""
|
||||
date_begin, date_end = post.get('date_begin'), post.get('date_end')
|
||||
|
||||
pager_url = "/blogpost/%s" % blog_post.id
|
||||
|
||||
|
@ -187,6 +220,12 @@ class WebsiteBlog(http.Controller):
|
|||
pager_end = page * self._post_comment_per_page
|
||||
blog_post.website_message_ids = blog_post.website_message_ids[pager_begin:pager_end]
|
||||
|
||||
tag = None
|
||||
if tag_id:
|
||||
tag = request.registry['blog.tag'].browse(request.cr, request.uid, int(tag_id), context=request.context)
|
||||
post_url = QueryURL('', ['blogpost'], blogpost=blog_post, tag_id=tag_id, date_begin=date_begin, date_end=date_end)
|
||||
blog_url = QueryURL('', ['blog', 'tag'], blog=blog_post.blog_id, tag=tag, date_begin=date_begin, date_end=date_end)
|
||||
|
||||
cr, uid, context = request.cr, request.uid, request.context
|
||||
blog_obj = request.registry['blog.blog']
|
||||
blog_ids = blog_obj.search(cr, uid, [], context=context)
|
||||
|
@ -196,22 +235,19 @@ class WebsiteBlog(http.Controller):
|
|||
tag_ids = tag_obj.search(cr, uid, [], context=context)
|
||||
tags = tag_obj.browse(cr, uid, tag_ids, context=context)
|
||||
|
||||
MONTHS = [None, _('January'), _('February'), _('March'), _('April'),
|
||||
_('May'), _('June'), _('July'), _('August'), _('September'),
|
||||
_('October'), _('November'), _('December')]
|
||||
|
||||
values = {
|
||||
'blog': blog_post.blog_id,
|
||||
'blogs': blogs,
|
||||
'tags': tags,
|
||||
'tag': tag and request.registry['blog.tag'].browse(cr, uid, int(tag), context=context) or None,
|
||||
'tag': tag,
|
||||
'blog_post': blog_post,
|
||||
'main_object': blog_post,
|
||||
'pager': pager,
|
||||
'nav_list': self.nav_list(),
|
||||
'enable_editor': enable_editor,
|
||||
'date': date,
|
||||
'date_name': date and "%s %s" % (MONTHS[int(date.split("-")[1])], date.split("-")[0]) or None
|
||||
'date': date_begin,
|
||||
'post_url': post_url,
|
||||
'blog_url': blog_url,
|
||||
}
|
||||
return request.website.render("website_blog.blog_post_complete", values)
|
||||
|
||||
|
|
|
@ -43,45 +43,45 @@
|
|||
<section data-snippet-id="title" class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12 text-center">
|
||||
<h1>Latest Blogs</h1>
|
||||
<h1>Latest Posts</h1>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="container">
|
||||
<div class="row">
|
||||
<t t-set="count" t-value="0"/>
|
||||
<t t-foreach="blogs" t-as="blog">
|
||||
<t t-foreach="posts" t-as="post">
|
||||
<div class="col-md-4">
|
||||
<h4>
|
||||
<a t-attf-href="/blogpost/#{ slug(blog) }?#{ tag and 'tag=%s' % tag.id or '' }#{tag and date and '&' or ''}#{ date and 'date=%s' % date or ''}" t-field="blog.name"></a>
|
||||
<span t-if="not blog.website_published" class="text-warning">
|
||||
<a t-attf-href="#{blog_url('', ['blogpost'], blogpost=post)}" t-field="post.name"></a>
|
||||
<span t-if="not post.website_published" class="text-warning">
|
||||
&nbsp;
|
||||
<span class="fa fa-warning" title="Not published"/>
|
||||
</span>
|
||||
</h4>
|
||||
<div class="text-muted">
|
||||
<span class="fa fa-calendar"> <span t-field="blog.create_date"/> &nbsp;</span>
|
||||
<span class="fa fa-calendar"> <span t-field="post.create_date"/> &nbsp;</span>
|
||||
<span class="fa fa-folder-open"> In
|
||||
<a t-attf-href="/blog/#{ slug(blog.blog_id) }">
|
||||
<span t-field="blog.blog_id"/>
|
||||
<a t-attf-href="#{blog_url(blog=post.blog_id)}">
|
||||
<span t-field="post.blog_id"/>
|
||||
</a> &nbsp;
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-muted fa fa-tags">
|
||||
<span t-field="blog.website_meta_keywords"/>
|
||||
<span t-if="editable and not blog.website_meta_keywords" class="label label-danger">
|
||||
<span t-field="post.website_meta_keywords"/>
|
||||
<span t-if="editable and not post.website_meta_keywords" class="label label-danger">
|
||||
No keywords defined!
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-muted" t-if="len(blog.message_ids) > 0">
|
||||
<div class="text-muted" t-if="len(post.message_ids) > 0">
|
||||
<span class="fa fa-comment-o">
|
||||
<a t-attf-href="/blogpost/#{ slug(blog) }/?#{ tag and 'tag=%s' % tag.id or '' }#{tag and date and '&' or ''}#{ date and 'date=%s' % date or ''}#comments">
|
||||
<t t-if="len(blog.message_ids) <= 1" ><t t-esc="len(blog.message_ids)"/> comment</t>
|
||||
<t t-if="len(blog.message_ids) > 1"><t t-esc="len(blog.message_ids)"/> comments</t>
|
||||
<a t-attf-href="#{blog_url('', ['blogpost'], blogpost=post)}#comments">
|
||||
<t t-if="len(post.message_ids) <= 1" ><t t-esc="len(post.message_ids)"/> comment</t>
|
||||
<t t-if="len(post.message_ids) > 1"><t t-esc="len(post.message_ids)"/> comments</t>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-muted mb16" t-field="blog.website_meta_description"/>
|
||||
<div class="text-muted mb16" t-field="post.website_meta_description"/>
|
||||
</div>
|
||||
<t t-set="count" t-value="count+1"/>
|
||||
<div class="clearfix" t-if="(count % 3) == 0"/>
|
||||
|
@ -110,12 +110,12 @@
|
|||
<t t-foreach="blog_posts" t-as="blog_post">
|
||||
<div t-att-data-publish="blog_post.website_published and 'on' or 'off'">
|
||||
<h2 class="text-center">
|
||||
<a t-attf-href="/blogpost/#{ slug(blog_post) }/?#{ tag and 'tag=%s' % tag.id or '' }#{tag and date and '&' or ''}#{ date and 'date=%s' % date or ''}" t-field="blog_post.name"></a>
|
||||
<a t-attf-href="#{post_url(blogpost=blog_post)}" t-field="blog_post.name"></a>
|
||||
</h2>
|
||||
<p class="post-meta text-muted text-center" name='blog_post_data'>
|
||||
<span class="fa fa-calendar oe_date"> <span t-field="blog_post.create_date"/> &nbsp;</span>
|
||||
<span t-if="len(blog_post.message_ids) > 0" class="fa fa-comment-o">
|
||||
<a t-attf-href="/blogpost/#{ slug(blog_post) }/?#{ tag and 'tag=%s' % tag.id or '' }#{tag and date and '&' or ''}#{ date and 'date=%s' % date or ''}#comments">
|
||||
<a t-attf-href="#{post_url(blogpost=blog_post)}#comments">
|
||||
<t t-if="len(blog_post.message_ids) <= 1" ><t t-esc="len(blog_post.message_ids)"/> comment</t>
|
||||
<t t-if="len(blog_post.message_ids) > 1"><t t-esc="len(blog_post.message_ids)"/> comments</t>
|
||||
</a>
|
||||
|
@ -145,7 +145,7 @@
|
|||
<p class="post-meta text-muted text-center" t-if="len(blog_post.tag_ids)">
|
||||
<span class="fa fa-tags"/>
|
||||
<t t-foreach="blog_post.tag_ids" t-as="tag">
|
||||
<a t-attf-href="/blog/#{ slug(blog) }/tag/#{ slug(tag) }" t-esc="tag.name"/> &nbsp;
|
||||
<a t-attf-href="#{blog_url(tag=tag)}" t-esc="tag.name"/> &nbsp;
|
||||
</t>
|
||||
</p>
|
||||
</xpath>
|
||||
|
@ -210,10 +210,9 @@
|
|||
<div class="row">
|
||||
<div class="col-sm-9">
|
||||
<ol class="breadcrumb">
|
||||
<li><a t-attf-href="/blog/#{ slug(blog) }"><span t-field="blog.name"/></a></li>
|
||||
<li t-if="tag"><a t-attf-href="/blog/#{ slug(blog) }/tag/#{ slug(tag) }"><span t-field="tag.name"/></a></li>
|
||||
<li t-if="tag and date"><a t-attf-href="/blog/#{ slug(blog) }/tag/#{ slug(tag) }/date/#{ date }" t-esc="date_name"/></li>
|
||||
<li t-if="not tag and date"><a t-attf-href="/blog/#{ slug(blog) }/date/#{ date }" t-esc="date_name"/></li>
|
||||
<li><a t-attf-href="#{blog_url(tag=None, date_begin=None, date_end=None)}"><span t-field="blog.name"/></a></li>
|
||||
<li t-if="tag"><a t-attf-href="#{blog_url(date_begin=None, date_end=None)}"><span t-field="tag.name"/></a></li>
|
||||
<li t-if="date"><a t-attf-href="#{blog_url(tag=None)}" t-esc="date"/></li>
|
||||
<li class="active"><span t-field="blog_post.name"/></li>
|
||||
</ol>
|
||||
</div><div class="col-sm-3">
|
||||
|
@ -266,7 +265,7 @@
|
|||
<p class="post-meta text-muted text-center" t-if="len(blog_post.tag_ids)">
|
||||
<span class="fa fa-tags"/>
|
||||
<t t-foreach="blog_post.tag_ids" t-as="tag">
|
||||
<a t-attf-href="/blog/#{ slug(blog) }/tag/#{ slug(tag) }" t-esc="tag.name"/> &nbsp;
|
||||
<a t-attf-href="#{blog_url(tag=tag)}" t-esc="tag.name"/> &nbsp;
|
||||
</t>
|
||||
</p>
|
||||
</xpath>
|
||||
|
@ -307,9 +306,9 @@
|
|||
<section class="mt32">
|
||||
<h4>Tags</h4>
|
||||
<ul class="nav nav-pills nav-stacked">
|
||||
<t t-foreach="tags" t-as="tag_id">
|
||||
<li t-att-class="tag and tag_id.id == tag.id and 'active' or None" style="display: inline-block;">
|
||||
<a t-attf-href="/blog/#{ slug(blog) }/tag/#{ slug(tag_id) }"><span t-field="tag_id.name"/></a>
|
||||
<t t-foreach="tags" t-as="nav_tag">
|
||||
<li t-att-class="tag and tag.id == nav_tag.id and 'active' or None" style="display: inline-block;">
|
||||
<a t-attf-href="#{blog_url(tag=nav_tag)}"><span t-field="nav_tag.name"/></a>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
|
@ -325,8 +324,8 @@
|
|||
<h4>Archives</h4>
|
||||
<ul class="nav nav-pills nav-stacked">
|
||||
<t t-foreach="nav_list" t-as="months">
|
||||
<li t-att-class="months['date'] == date and 'active' or None">
|
||||
<a t-ignore="True" t-attf-href="/blog/#{ slug(blog) }/#{ tag and 'tag/%s/' % slug(tag) or '' }date/#{ months['date'] }"><t t-esc="months['create_date']"/><span class="pull-right badge" t-esc="months['create_date_count']"/></a>
|
||||
<li t-att-class="months['date_begin'] == date and 'active' or None">
|
||||
<a t-ignore="True" t-attf-href="#{blog_url(date_begin=months['date_begin'], date_end=months['date_end'])}"><t t-esc="months['create_date']"/><span class="pull-right badge" t-esc="months['create_date_count']"/></a>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
|
@ -387,7 +386,7 @@
|
|||
<ul class="nav nav-pills nav-stacked">
|
||||
<t t-foreach="blogs" t-as="nav_blog">
|
||||
<li t-att-class="nav_blog.id == blog.id and 'active' or ''">
|
||||
<a t-attf-href="/blog/#{ slug(nav_blog) }">
|
||||
<a t-attf-href="#{blog_url(blog=nav_blog)}">
|
||||
<span t-field="nav_blog.name"/>
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -25,12 +25,14 @@ from openerp.addons.website.models.website import slug
|
|||
|
||||
class event_track_tag(osv.osv):
|
||||
_name = "event.track.tag"
|
||||
_order = 'name'
|
||||
_columns = {
|
||||
'name': fields.char('Event Track Tag')
|
||||
}
|
||||
|
||||
class event_tag(osv.osv):
|
||||
_name = "event.tag"
|
||||
_order = 'name'
|
||||
_columns = {
|
||||
'name': fields.char('Event Tag')
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2013-Today OpenERP S.A. (<http://www.openerp.com>).
|
||||
#
|
||||
# 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 controllers
|
|
@ -0,0 +1,42 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2013-Today OpenERP S.A. (<http://www.openerp.com>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
{
|
||||
'name': 'Website Gengo Translator',
|
||||
'category': 'Website',
|
||||
'version': '1.0',
|
||||
'description': """
|
||||
Website Gengo Translator
|
||||
========================
|
||||
|
||||
Translate you website in one click
|
||||
""",
|
||||
'author': 'OpenERP SA',
|
||||
'depends': [
|
||||
'website',
|
||||
'base_gengo'
|
||||
],
|
||||
'data': [
|
||||
'views/website_gengo.xml',
|
||||
],
|
||||
'qweb': [],
|
||||
'installable': True,
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
import main
|
|
@ -0,0 +1,60 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import openerp
|
||||
from openerp.addons.web import http
|
||||
from openerp.addons.web.http import request
|
||||
import time
|
||||
import json
|
||||
from openerp.tools.translate import _
|
||||
|
||||
|
||||
GENGO_DEFAULT_LIMIT = 20
|
||||
|
||||
class website_gengo(http.Controller):
|
||||
|
||||
@http.route('/website/get_translated_length', type='json', auth='user', website=True)
|
||||
def get_translated_length(self, translated_ids, lang):
|
||||
ir_translation_obj = request.registry['ir.translation']
|
||||
result={"done":0}
|
||||
gengo_translation_ids = ir_translation_obj.search(request.cr, request.uid, [('id','in',translated_ids),('gengo_translation','!=', False)])
|
||||
for trans in ir_translation_obj.browse(request.cr, request.uid, gengo_translation_ids):
|
||||
result['done'] += len(trans.source.split())
|
||||
return result
|
||||
|
||||
@http.route('/website/check_gengo_set', type='json', auth='user', website=True)
|
||||
def check_gengo_set(self):
|
||||
user = request.registry['res.users'].browse(request.cr, request.uid, request.uid)
|
||||
company_flag = 0
|
||||
if not user.company_id.gengo_public_key or not user.company_id.gengo_private_key:
|
||||
company_flag = user.company_id.id
|
||||
return company_flag
|
||||
|
||||
@http.route('/website/set_gengo_config', type='json', auth='user', website=True)
|
||||
def set_gengo_config(self,config):
|
||||
user = request.registry['res.users'].browse(request.cr, request.uid, request.uid)
|
||||
if user.company_id:
|
||||
request.registry['res.company'].write(request.cr, request.uid, user.company_id.id,config)
|
||||
return True
|
||||
|
||||
@http.route('/website/post_gengo_jobs', type='json', auth='user', website=True)
|
||||
def post_gengo_jobs(self):
|
||||
request.registry['base.gengo.translations']._sync_request(request.cr, request.uid, limit=GENGO_DEFAULT_LIMIT, context=request.context)
|
||||
return True
|
||||
|
||||
@http.route('/website/gengo_callback/<model("ir.translation"):term>', type='http', auth='none')
|
||||
def gengo_callback(self,term,**post):
|
||||
if post and post.get('job'):
|
||||
translation_pool = request.registry['ir.translation']
|
||||
base_gengo_pool = request.registry['base.gengo.translations']
|
||||
job, vals = json.loads(post['job']), {}
|
||||
if job.get('status') == 'approved':
|
||||
vals.update({'state': 'translated', 'value': job.get('body_tgt')})
|
||||
flag, gengo = base_gengo_pool.gengo_authentication(request.cr, openerp.SUPERUSER_ID, context=request.context)
|
||||
job_comment = gengo.getTranslationJobComments(id=job.get('job_id'))
|
||||
if job_comment['opstat']=='ok':
|
||||
gengo_comments=""
|
||||
for comment in job_comment['response']['thread']:
|
||||
gengo_comments += _('%s\n-- Commented on %s by %s.\n\n') % (comment['body'], time.ctime(comment['ctime']), comment['author'])
|
||||
vals.update({'gengo_comment': gengo_comments})
|
||||
if vals:
|
||||
translation_pool.write(request.cr, openerp.SUPERUSER_ID, term.id, vals)
|
|
@ -0,0 +1,3 @@
|
|||
.oe_translatable_inprogress {
|
||||
background: #b7e4ff;
|
||||
}
|
|
@ -0,0 +1,188 @@
|
|||
(function () {
|
||||
'use strict';
|
||||
|
||||
var website = openerp.website;
|
||||
website.add_template_file('/website_gengo/static/src/xml/website.gengo.xml');
|
||||
|
||||
website.EditorBar.include({
|
||||
events: _.extend({}, website.EditorBar.prototype.events, {
|
||||
'click a[data-action=translation_gengo_post]': 'translation_gengo_post',
|
||||
'click a[data-action=translation_gengo_info]': 'translation_gengo_info',
|
||||
}),
|
||||
edit:function () {
|
||||
this.gengo_translate = true;
|
||||
this._super.apply(this, arguments);
|
||||
var self = this;
|
||||
var gengo_langs = ["ar_SY","id_ID","nl_NL","fr_CA","pl_PL","zh_TW","sv_SE","ko_KR","pt_PT","en_US","ja_JP","es_ES","zh_CN","de_DE","fr_FR","fr_BE","ru_RU","it_IT","pt_BR","pt_BR","th_TH","nb_NO","ro_RO","tr_TR","bg_BG","da_DK","en_GB","el_GR","vi_VN","he_IL","hu_HU","fi_FI"];
|
||||
if (gengo_langs.indexOf(website.get_context()['lang']) != -1){
|
||||
self.$('.gengo_post,.gengo_wait,.gengo_inprogress,.gengo_info').remove();
|
||||
self.$('button[data-action=save]')
|
||||
.after(openerp.qweb.render('website.ButtonGengoTranslator'));
|
||||
}
|
||||
},
|
||||
translation_gengo_display:function(){
|
||||
var self = this;
|
||||
if($('.oe_translatable_todo').length == 0){
|
||||
self.$el.find('.gengo_post').addClass("hidden");
|
||||
self.$el.find('.gengo_inprogress').removeClass("hidden");
|
||||
}
|
||||
},
|
||||
translation_gengo_post: function () {
|
||||
var self = this;
|
||||
var translatable_list = $.find('.oe_translatable_todo');
|
||||
this.new_words = 0;
|
||||
$('.oe_translatable_todo').each(function () {
|
||||
self.new_words += $(this).text().trim().replace(/ +/g," ").split(" ").length;
|
||||
});
|
||||
openerp.jsonRpc('/website/check_gengo_set', 'call', {
|
||||
}).then(function (res) {
|
||||
if (res == 0){
|
||||
var dialog = new website.GengoTranslatorPostDialog(self.new_words);
|
||||
dialog.appendTo($(document.body));
|
||||
dialog.on('service_level', this, function () {
|
||||
var gengo_service_level = dialog.$el.find(".form-control").val();
|
||||
dialog.$el.modal('hide');
|
||||
self.$el.find('.gengo_post').addClass("hidden");
|
||||
self.$el.find('.gengo_wait').removeClass("hidden");
|
||||
var trans ={}
|
||||
$('.oe_translatable_todo').each(function () {
|
||||
var $node = $(this);
|
||||
var data = $node.data();
|
||||
if (!trans[data.oeTranslationViewId]) {
|
||||
trans[data.oeTranslationViewId] = [];
|
||||
}
|
||||
trans[data.oeTranslationViewId].push({
|
||||
initial_content: self.getInitialContent(this),
|
||||
new_content:self.getInitialContent(this),
|
||||
translation_id: data.oeTranslationId || null,
|
||||
gengo_translation: gengo_service_level,
|
||||
gengo_comment:"Original page:" + document.URL
|
||||
});
|
||||
});
|
||||
openerp.jsonRpc('/website/set_translations', 'call', {
|
||||
'data': trans,
|
||||
'lang': website.get_context()['lang'],
|
||||
}).then(function () {
|
||||
$('.oe_translatable_todo').addClass('oe_translatable_inprogress').removeClass('oe_translatable_todo');
|
||||
self.$el.find('.gengo_wait').addClass("hidden");
|
||||
self.$el.find('.gengo_inprogress,.gengo_discard').removeClass("hidden");
|
||||
openerp.jsonRpc('/website/post_gengo_jobs', 'call', {});
|
||||
self.save();
|
||||
}).fail(function () {
|
||||
alert("Could not Post translation");
|
||||
});
|
||||
});
|
||||
}else{
|
||||
var dialog = new website.GengoApiConfigDialog(res);
|
||||
dialog.appendTo($(document.body));
|
||||
dialog.on('set_config', this, function () {
|
||||
dialog.$el.modal('hide');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
translation_gengo_info: function () {
|
||||
var repr = $(document.documentElement).data('mainObject');
|
||||
var view_id = repr.match(/.+\((.+), (\d+)\)/)[2];
|
||||
var translated_ids = [];
|
||||
$('.oe_translatable_text').not(".oe_translatable_inprogress").each(function(){
|
||||
translated_ids.push($(this).attr('data-oe-translation-id'));
|
||||
});
|
||||
openerp.jsonRpc('/website/get_translated_length', 'call', {
|
||||
'translated_ids': translated_ids,
|
||||
'lang': website.get_context()['lang'],
|
||||
}).done(function(res){
|
||||
var dialog = new website.GengoTranslatorStatisticDialog(res);
|
||||
dialog.appendTo($(document.body));
|
||||
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
website.GengoTranslatorPostDialog = openerp.Widget.extend({
|
||||
events: _.extend({}, website.EditorBar.prototype.events, {
|
||||
'hidden.bs.modal': 'destroy',
|
||||
'click button[data-action=service_level]': function (ev) {
|
||||
this.trigger('service_level');
|
||||
},
|
||||
}),
|
||||
template: 'website.GengoTranslatorPostDialog',
|
||||
init:function(new_words){
|
||||
this.new_words = new_words;
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
start: function () {
|
||||
this.$el.modal();
|
||||
},
|
||||
});
|
||||
|
||||
website.GengoTranslatorStatisticDialog = openerp.Widget.extend({
|
||||
events: _.extend({}, website.EditorBar.prototype.events, {
|
||||
'hidden.bs.modal': 'destroy',
|
||||
}),
|
||||
template: 'website.GengoTranslatorStatisticDialog',
|
||||
init:function(res){
|
||||
var self = this;
|
||||
this.inprogess = 0;
|
||||
this.new_words = 0;
|
||||
this.done = res.done;
|
||||
$('.oe_translatable_todo').each(function () {
|
||||
self.new_words += $(this).text().trim().replace(/ +/g," ").split(" ").length;
|
||||
});
|
||||
$('.oe_translatable_inprogress').each(function () {
|
||||
self.inprogess += $(this).text().trim().replace(/ +/g," ").split(" ").length;
|
||||
});
|
||||
this.total = this.done + this.inprogess;
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
start: function (res) {
|
||||
this.$el.modal(this.res);
|
||||
},
|
||||
});
|
||||
website.GengoApiConfigDialog = openerp.Widget.extend({
|
||||
events: _.extend({}, website.EditorBar.prototype.events, {
|
||||
'hidden.bs.modal': 'destroy',
|
||||
'click button[data-action=set_config]': 'set_config'
|
||||
}),
|
||||
template: 'website.GengoApiConfigDialog',
|
||||
init:function(company_id){
|
||||
this.company_id = company_id;
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
start: function (res) {
|
||||
this.$el.modal(this.res);
|
||||
},
|
||||
set_config:function(ev){
|
||||
var self = this;
|
||||
var public_key = this.$el.find("#gengo_public_key")[0].value;
|
||||
var private_key = this.$el.find("#gengo_private_key")[0].value;
|
||||
var auto_approve = this.$el.find("#gengo_auto_approve")[0].checked;
|
||||
var sandbox = this.$el.find("#gengo_sandbox")[0].checked;
|
||||
var pub_el = this.$el.find(".gengo_group_public")[0];
|
||||
var pri_el = this.$el.find(".gengo_group_private")[0];
|
||||
if(! public_key){
|
||||
$(pub_el).addClass("has-error");
|
||||
}
|
||||
else{
|
||||
$(pub_el).removeClass("has-error");
|
||||
}
|
||||
if(! private_key){
|
||||
$(pri_el).addClass("has-error");
|
||||
}
|
||||
else{
|
||||
$(pri_el).removeClass("has-error");
|
||||
}
|
||||
if(public_key && private_key){
|
||||
openerp.jsonRpc('/website/set_gengo_config', 'call', {
|
||||
'config': {'gengo_public_key':public_key,'gengo_private_key':private_key,'gengo_auto_approve':auto_approve,'gengo_sandbox':sandbox},
|
||||
}).then(function () {
|
||||
self.trigger('set_config');
|
||||
}).fail(function () {
|
||||
alert("Could not submit ! Try Again");
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
})();
|
|
@ -0,0 +1,163 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<templates id="template" xml:space="preserve">
|
||||
<t t-name="website.ButtonGengoTranslator">
|
||||
<a class="btn btn-danger gengo_post" data-action="translation_gengo_post" href="#">Auto Translate</a>
|
||||
<a class="btn btn-danger hidden gengo_wait disabled" href="#"><i class="fa fa-spinner fa-spin"></i> Wait</a>
|
||||
<a class="btn btn-danger hidden gengo_inprogress disabled" href="#"> <i class="fa fa-clock-o"></i> Translation in Progress</a>
|
||||
<a class="btn btn-link gengo_info" data-action="translation_gengo_info">Count Words</a>
|
||||
</t>
|
||||
<t t-name="website.TranslatorDialog">
|
||||
<div class="modal fade oe_website_translator" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button title="Close" type="button" class="close" data-dismiss="modal">×</button>
|
||||
<h2 class="modal-title">Translate this page</h2>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<section>
|
||||
<p>You are about to enter the translation mode.</p>
|
||||
<p>
|
||||
Here are the visuals used to help you translate efficiently:
|
||||
<ul class="oe_translate_examples">
|
||||
<li style="background:#ffffb6;">
|
||||
Content to translate or you can post them to <b><a href="http://gengo.com/" >Gengo</a></b> for translation.
|
||||
</li>
|
||||
<li class="oe_translatable_inprogress">
|
||||
Translation in process (Gengo)
|
||||
</li>
|
||||
<li class="oe_translatable_text">
|
||||
Already translated content
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
<p>
|
||||
In this mode, you can translate texts or post texts to Gengo for translation.
|
||||
To change the structure of the page, you must edit the
|
||||
master page.
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div>
|
||||
<input type="checkbox" name="do_not_show"/>
|
||||
Do not show this dialog later.
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" data-action="activate" class="btn btn-primary">Ok</button>
|
||||
or
|
||||
<a data-action="discard" data-dismiss="modal" href="#">Cancel</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="website.GengoTranslatorPostDialog">
|
||||
<div class="modal fade oe_website_translator" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button title="Close" type="button" class="close" data-dismiss="modal">×</button>
|
||||
<h2 class="modal-title">Select Gengo Translation Service Level</h2>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<section>
|
||||
<select class="form-control" required="required" autofocus="autofocus">
|
||||
<option value="machine">By Machine (Free)</option>
|
||||
<option value="standard">Standard - $ <t t-esc="(widget.new_words * 0.05).toFixed(2)"></t> </option>
|
||||
<option value="pro">Pro - $ <t t-esc="(widget.new_words * 0.10).toFixed(2)"></t></option>
|
||||
<option value="ultra">Ultra - $ <t t-esc="(widget.new_words * 0.15).toFixed(2)"></t></option>
|
||||
</select>
|
||||
</section>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" data-action="service_level" class="btn btn-primary">Post</button>
|
||||
or
|
||||
<a data-action="discard" data-dismiss="modal" href="#">Cancel</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="website.GengoTranslatorStatisticDialog">
|
||||
<div class="modal fade oe_website_translator" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button title="Close" type="button" class="close" data-dismiss="modal">×</button>
|
||||
<h2 class="modal-title">Translator statistics for this page</h2>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<b>
|
||||
<div class="text-muted mb16"> <i class="fa fa-search-plus"></i> <t t-esc="widget.new_words"></t> new words found on this page.</div>
|
||||
<h4><i class="fa fa-dashboard"></i> Gengo Statistics <a href="https://gengo.com/c/dashboard" class="pull-right" target="new">Gengo Dashboard</a></h4>
|
||||
<hr class="mt8"/>
|
||||
<div class="text-info mb8"> <i class="fa fa-align-left"></i> Words posted for translate <t t-esc="widget.total"></t></div>
|
||||
<div class="text-warning mb8"> <i class="fa fa-cogs"></i> Words in progress <t t-esc="widget.inprogess"></t></div>
|
||||
<div class="text-success mb8"> <i class="fa fa-check"></i> Translated words <t t-esc="widget.done"></t></div>
|
||||
</b>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a data-action="discard" data-dismiss="modal" href="#">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="website.GengoApiConfigDialog">
|
||||
<div class="modal fade oe_website_translator" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button title="Close" type="button" class="close" data-dismiss="modal">×</button>
|
||||
<h2 class="modal-title">Gengo API is not configured</h2>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<b> <h3>Steps for configure Gengo </h3>
|
||||
<div class="mb16"> 1. Go To your <b><a target="new" href="https://gengo.com/account/api_settings/">Gengo account</a></b> and generate API Keys.</div>
|
||||
<div class="mb16"> 2. Then paste generated keys in given form</div>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item form-group gengo_group_public">
|
||||
<h4 class="list-group-item-heading">
|
||||
<label class="control-label">Public key</label>
|
||||
</h4>
|
||||
<input type="text" class="form-control url url-source" id="gengo_public_key" placeholder="Paste public key here"/>
|
||||
|
||||
</li>
|
||||
<li class="list-group-item form-group gengo_group_private">
|
||||
<h4 class="list-group-item-heading">
|
||||
<label for="link-external" class="control-label">Private key</label>
|
||||
</h4>
|
||||
<input type="text" class="form-control url url-source" id="gengo_private_key" placeholder="Paste private key here"/>
|
||||
</li>
|
||||
<li class="list-group-item form-group">
|
||||
<div>
|
||||
<label>
|
||||
<input type="checkbox" id="gengo_auto_approve" class="window-new" checked="1"/>
|
||||
Auto Approve Translation <small class="text-muted">- Jobs are Automatically Approved by Gengo.</small>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label>
|
||||
<input type="checkbox" id="gengo_sandbox" class="window-new"/>
|
||||
Sandbox <small class="text-muted">- Enable if you using testing account</small>
|
||||
</label>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</b>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" data-action="set_config" class="btn btn-primary">Submit</button>
|
||||
or
|
||||
<a data-action="discard" data-dismiss="modal" href="#">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
</templates>
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<template id="gengo_editor_head" inherit_id="website.editor_head" name="Editor Head" groups="base.group_website_publisher">
|
||||
<xpath expr='//script[@src="/website/static/src/js/website.translator.js"]' position="after">
|
||||
<link rel="stylesheet" href="/website_gengo/static/src/css/website_gengo.css"></link>
|
||||
<script t-if="translatable" type="text/javascript" src="/website_gengo/static/src/js/website_gengo.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
</data>
|
||||
</openerp>
|
Loading…
Reference in New Issue