[MERGE] Sync with trunk

bzr revid: tde@openerp.com-20131206155646-yj6of6fw43vznkzo
This commit is contained in:
Thibault Delavallée 2013-12-06 16:56:46 +01:00
commit 33633157f2
113 changed files with 17478 additions and 443 deletions

View File

@ -3414,6 +3414,8 @@ class wizard_multi_charts_accounts(osv.osv_memory):
all the provided information to create the accounts, the banks, the journals, the taxes, the tax codes, the
accounting properties... accordingly for the chosen company.
'''
if uid != SUPERUSER_ID and not self.pool['res.users'].has_group(cr, uid, 'base.group_erp_manager'):
raise openerp.exceptions.AccessError(_("Only administrators can change the settings"))
obj_data = self.pool.get('ir.model.data')
ir_values_obj = self.pool.get('ir.values')
obj_wizard = self.browse(cr, uid, ids[0])
@ -3430,7 +3432,7 @@ class wizard_multi_charts_accounts(osv.osv_memory):
self.pool[tmp2[0]].write(cr, uid, tmp2[1], {
'currency_id': obj_wizard.currency_id.id
})
except ValueError, e:
except ValueError:
pass
# If the floats for sale/purchase rates have been filled, create templates from them

View File

@ -26,7 +26,7 @@ from operator import itemgetter
from lxml import etree
from openerp import netsvc
from openerp import workflow
from openerp.osv import fields, osv, orm
from openerp.tools.translate import _
import openerp.addons.decimal_precision as dp
@ -932,11 +932,10 @@ class account_move_line(osv.osv):
'line_id': map(lambda x: (4, x, False), ids),
'line_partial_ids': map(lambda x: (3, x, False), ids)
})
wf_service = netsvc.LocalService("workflow")
# the id of the move.reconcile is written in the move.line (self) by the create method above
# because of the way the line_id are defined: (4, x, False)
for id in ids:
wf_service.trg_trigger(uid, 'account.move.line', id, cr)
workflow.trg_trigger(uid, 'account.move.line', id, cr)
if lines and lines[0]:
partner_id = lines[0].partner_id and lines[0].partner_id.id or False

10849
addons/account/i18n/am.po Normal file

File diff suppressed because it is too large Load Diff

View File

@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
"PO-Revision-Date: 2012-12-27 22:48+0000\n"
"Last-Translator: Balint (eSolve) <Unknown>\n"
"PO-Revision-Date: 2013-12-02 19:56+0000\n"
"Last-Translator: krnkris <Unknown>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-09-12 05:27+0000\n"
"X-Generator: Launchpad (build 16761)\n"
"X-Launchpad-Export-Date: 2013-12-03 05:41+0000\n"
"X-Generator: Launchpad (build 16856)\n"
#. module: account
#: model:process.transition,name:account.process_transition_supplierreconcilepaid0
@ -26,6 +26,8 @@ msgstr "Kifizetési rendszer"
msgid ""
"An account fiscal position could be defined only once time on same accounts."
msgstr ""
"Egy könyvelés költségvetési évfordulóját csak egyszer lehet megadni az arra "
"hivatkozó számlákra vonatkozólag."
#. module: account
#: help:account.tax.code,sequence:0
@ -60,7 +62,7 @@ msgstr "Rendezetlen összeg"
#: code:addons/account/account_bank_statement.py:369
#, python-format
msgid "Journal item \"%s\" is not valid."
msgstr ""
msgstr "A \"%s\" könyvelési napló tétel nem érvényes."
#. module: account
#: model:ir.model,name:account.model_report_aged_receivable
@ -78,7 +80,7 @@ msgstr "Importálás számlából vagy pénzügyi rendezésből"
#: code:addons/account/account_move_line.py:1210
#, python-format
msgid "Bad Account!"
msgstr ""
msgstr "Eltévesztett könyvelési számla!"
#. module: account
#: view:account.move:0
@ -92,6 +94,8 @@ msgid ""
"Error!\n"
"You cannot create recursive account templates."
msgstr ""
"Hiba!\n"
"Nem hozhat létre visszatérő számla sablonokat."
#. module: account
#. openerp-web
@ -102,7 +106,7 @@ msgstr ""
#: code:addons/account/static/src/xml/account_move_reconciliation.xml:30
#, python-format
msgid "Reconcile"
msgstr "Párosítás"
msgstr "Egyeztetés"
#. module: account
#: field:account.bank.statement,name:0
@ -114,7 +118,7 @@ msgstr "Párosítás"
#: xsl:account.transfer:0
#: field:cash.box.in,ref:0
msgid "Reference"
msgstr "Hivatkozás"
msgstr "Információforrás"
#. module: account
#: help:account.payment.term,active:0
@ -122,7 +126,8 @@ msgid ""
"If the active field is set to False, it will allow you to hide the payment "
"term without removing it."
msgstr ""
"Ha az aktív mező nincs bejelölve, nem használható a fizetési feltétel."
"Ha az aktív mező hamisra van állatva, akkor a fizetési feltételt "
"eltüntetheti anélkül, hogy törölné azt."
#. module: account
#: code:addons/account/account.py:641
@ -151,7 +156,7 @@ msgstr "Figyelem!"
#: code:addons/account/account.py:3197
#, python-format
msgid "Miscellaneous Journal"
msgstr "Vegyes napló"
msgstr "Vegyes könyvelési napló"
#. module: account
#: code:addons/account/wizard/account_open_closed_fiscalyear.py:39
@ -161,6 +166,8 @@ msgid ""
"which is set after generating opening entries from 'Generate Opening "
"Entries'."
msgstr ""
"Be kell állítania az 'Év végi belépő könyvelési naplót' ehhez a 'Nyitási "
"tétel létrehozása' menüvel létrehozott üzlez év tételeihez."
#. module: account
#: field:account.fiscal.position.account,account_src_id:0
@ -879,7 +886,7 @@ msgstr "Párosítás visszavonása"
#. module: account
#: model:ir.model,name:account.model_account_analytic_journal_report
msgid "Account Analytic Journal"
msgstr "Gyűjtőnapló"
msgstr "Gyűjtőnapló számla"
#. module: account
#: view:account.invoice:0
@ -1475,7 +1482,7 @@ msgstr "Listázási beállítások"
#. module: account
#: field:account.fiscalyear.close.state,fy_id:0
msgid "Fiscal Year to Close"
msgstr ""
msgstr "Bezárni kívánt üzleti év"
#. module: account
#: field:account.config.settings,sale_sequence_prefix:0
@ -1553,7 +1560,7 @@ msgstr "Adók keresése"
#. module: account
#: model:ir.model,name:account.model_account_analytic_cost_ledger
msgid "Account Analytic Cost Ledger"
msgstr "Gyűjtőkód karton"
msgstr "Főkönyvi költség gyűjtőkód karton számla"
#. module: account
#: view:account.model:0
@ -1624,6 +1631,8 @@ msgid ""
"By unchecking the active field, you may hide a fiscal position without "
"deleting it."
msgstr ""
"Az aktív mező üresen hagyásával, eltüntetheti az ÁFA helyét, annak törlése "
"nélkül."
#. module: account
#: model:ir.model,name:account.model_temp_range
@ -2194,7 +2203,7 @@ msgstr "Korosított folyószámla kivonat"
#. module: account
#: view:account.fiscalyear.close.state:0
msgid "Close Fiscal Year"
msgstr ""
msgstr "Üzleti év lezárása"
#. module: account
#. openerp-web
@ -2207,6 +2216,7 @@ msgstr ""
#: sql_constraint:account.fiscal.position.tax:0
msgid "A tax fiscal position could be defined only once time on same taxes."
msgstr ""
"Az adó adóügyi pozíciója csak egyszer határozható meg ugyanarra az adóra."
#. module: account
#: view:account.tax:0
@ -2320,7 +2330,7 @@ msgstr "Részleges tételsorok"
#: view:account.fiscalyear:0
#: field:account.treasury.report,fiscalyear_id:0
msgid "Fiscalyear"
msgstr "Üzleti év"
msgstr "Üzletiév"
#. module: account
#: code:addons/account/wizard/account_move_bank_reconcile.py:53
@ -2963,6 +2973,22 @@ msgid ""
" </p>\n"
" "
msgstr ""
"<p class=\"oe_view_nocontent_create\">\n"
" Kattintson új adóügyi év létrehozásához.\n"
" </p><p>\n"
" Határozza meg a vállalkozása üzleti évét a kívánságainak "
"megfelelően.\n"
" Egy üzleti év egy idő periódus, aminek a végén a vállalkozás "
"könyvelése\n"
" elszámolásra kerül (általában 12 hónap). Az üzleti év arra a "
"dátumra\n"
" hivatkozik általában ahol az véget ér. Például,\n"
" ha a vállalkozás pénzügyi üzleti éve 2011 november 30-ára "
"esik, akkor\n"
" minden ami 2010 december 1 és 2011 november 30 közé esik\n"
" azt hívjuk 2011 évi üzleti/pénzügyi/adóügyi évnek.\n"
" </p>\n"
" "
#. module: account
#: view:account.common.report:0
@ -3912,6 +3938,8 @@ msgid ""
"There is no fiscal year defined for this date.\n"
"Please create one from the configuration of the accounting menu."
msgstr ""
"Erre a dátumra nem lett üzleti adóügyi év meghatározva.\n"
"Kérem hozzon létre egyet a könyvelési menü beállítása menüpont alatt."
#. module: account
#: view:account.addtmpl.wizard:0
@ -4282,6 +4310,8 @@ msgid ""
"The fiscalyear, periods or chart of account chosen have to belong to the "
"same company."
msgstr ""
"Az üzelti adóügyi év, periódus vagy számlatükör kiválasztása ugyanarra a "
"vállalkozásra kell, hogy vonatkozzon."
#. module: account
#: help:account.tax.code.template,notprintable:0
@ -7344,6 +7374,8 @@ msgid ""
"Error!\n"
"The start date of a fiscal year must precede its end date."
msgstr ""
"Hiba!\n"
"Az üzleti adóügyi év elejének előbb kell lennie mint a végének."
#. module: account
#: view:account.tax.template:0
@ -8276,7 +8308,8 @@ msgstr ""
msgid ""
"Select Fiscal Year which you want to remove entries for its End of year "
"entries journal"
msgstr "Válassza ki az üzleti évet, amelynek a nyitó tételeit törölni akarja"
msgstr ""
"Válassza ki az üzleti évet, amelynek a záró tételei közül törölni szeretne"
#. module: account
#: field:account.tax.template,type_tax_use:0
@ -8397,7 +8430,7 @@ msgstr "Gyűjtőkód karton"
#. module: account
#: view:account.config.settings:0
msgid "No Fiscal Year Defined for This Company"
msgstr ""
msgstr "Ehhez a vállalkozáshoz nem lett üzleti adóügyi év meghatározva"
#. module: account
#: view:account.invoice:0
@ -8548,6 +8581,9 @@ msgid ""
"This wizard will remove the end of year journal entries of selected fiscal "
"year. Note that you can run this wizard many times for the same fiscal year."
msgstr ""
"Ez a varázsló a kiválasztott üzleti adóügyi évet lezáró könyvelési napló "
"tételeit fogja eltávolítani. Megjegyezzük, hogy ezt a varázslót többször is "
"elindíthatja ugyanarra az üzleti évre."
#. module: account
#: report:account.invoice:0
@ -8732,7 +8768,7 @@ msgstr ""
#. module: account
#: model:ir.model,name:account.model_account_fiscalyear_close_state
msgid "Fiscalyear Close state"
msgstr "Üzleti év zárása"
msgstr "Üzleti év zárt állapotban"
#. module: account
#: field:account.invoice.refund,journal_id:0
@ -9161,7 +9197,7 @@ msgstr ""
#. module: account
#: field:account.config.settings,has_fiscal_year:0
msgid "Company has a fiscal year"
msgstr ""
msgstr "Vállalkozásnak van üzleti, adóügyi éve"
#. module: account
#: help:account.tax,child_depend:0
@ -9599,6 +9635,9 @@ msgid ""
"The period is invalid. Either some periods are overlapping or the period's "
"dates are not matching the scope of the fiscal year."
msgstr ""
"Hiba!\n"
"Az időszak nem érvényes. Vagy az egyes időszakok átfedik egymást vagy az "
"időszakok nem egyeznek az üzleti év határidőivel."
#. module: account
#: report:account.overdue:0
@ -9897,7 +9936,7 @@ msgstr "Gyűjtőkódokból"
#. module: account
#: view:account.installer:0
msgid "Configure your Fiscal Year"
msgstr ""
msgstr "Állítsa be az üzleti, adóügyi évét"
#. module: account
#: field:account.period,name:0
@ -10834,6 +10873,8 @@ msgstr "Könyvelési tételsorok jóváhagyása"
msgid ""
"The fiscal position will determine taxes and accounts used for the partner."
msgstr ""
"Az ÁFA pozíció meghatározza a partnerre vonatkozó adókat és főkönyvi "
"számlákat."
#. module: account
#: model:process.node,note:account.process_node_supplierpaidinvoice0
@ -10906,7 +10947,7 @@ msgstr ""
#: view:ir.sequence:0
#: model:ir.ui.menu,name:account.menu_action_account_fiscalyear
msgid "Fiscal Years"
msgstr "Üzleti év"
msgstr "Üzleti évek"
#. module: account
#: help:account.analytic.journal,active:0

View File

@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
"PO-Revision-Date: 2012-08-21 06:06+0000\n"
"Last-Translator: Boyce Huang <boyce.huang@cenoq.com>\n"
"PO-Revision-Date: 2013-12-01 17:16+0000\n"
"Last-Translator: Andy Cheng <andy@dobtor.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-09-12 05:37+0000\n"
"X-Generator: Launchpad (build 16761)\n"
"X-Launchpad-Export-Date: 2013-12-02 05:23+0000\n"
"X-Generator: Launchpad (build 16856)\n"
#. module: account
#: model:process.transition,name:account.process_transition_supplierreconcilepaid0
@ -32,12 +32,12 @@ msgstr "在相同會計科目中,只能設定一次科目財務狀況。"
msgid ""
"Determine the display order in the report 'Accounting \\ Reporting \\ "
"Generic Reporting \\ Taxes \\ Taxes Report'"
msgstr "確定以下報表的顯示順序:」會計-報表-通用報表-稅-稅報表「"
msgstr "確定以下報表的顯示順序:「會計 \\ 報表 \\ 通用報表 \\ 稅 \\ 稅報表」"
#. module: account
#: view:account.move.reconcile:0
msgid "Journal Entry Reconcile"
msgstr "日記帳分錄調節"
msgstr "帳簿分錄調節"
#. module: account
#: view:account.account:0

View File

@ -295,7 +295,7 @@
</para>
</td>
<td>
<para style="terp_tblheader_Details"><b>Total:</b></para>
<para style="terp_default_9"><b>Total:</b></para>
</td>
<td>
<para style="terp_default_Bold_Right_9"><b>[[ formatLang(o.amount_total, digits=get_digits(dp='Account'), currency_obj=o.currency_id) ]]</b></para>

View File

@ -22,13 +22,12 @@
import time
import datetime
from dateutil.relativedelta import relativedelta
from operator import itemgetter
from os.path import join as opj
import openerp
from openerp import SUPERUSER_ID
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT as DF
from openerp.tools.translate import _
from openerp.osv import fields, osv
from openerp import tools
class account_config_settings(osv.osv_memory):
_name = 'account.config.settings'
@ -276,11 +275,13 @@ class account_config_settings(osv.osv_memory):
def set_default_taxes(self, cr, uid, ids, context=None):
""" set default sale and purchase taxes for products """
if uid != SUPERUSER_ID and not self.pool['res.users'].has_group(cr, uid, 'base.group_erp_manager'):
raise openerp.exceptions.AccessError(_("Only administrators can change the settings"))
ir_values = self.pool.get('ir.values')
config = self.browse(cr, uid, ids[0], context)
ir_values.set_default(cr, uid, 'product.product', 'taxes_id',
ir_values.set_default(cr, SUPERUSER_ID, 'product.product', 'taxes_id',
config.default_sale_tax and [config.default_sale_tax.id] or False, company_id=config.company_id.id)
ir_values.set_default(cr, uid, 'product.product', 'supplier_taxes_id',
ir_values.set_default(cr, SUPERUSER_ID, 'product.product', 'supplier_taxes_id',
config.default_purchase_tax and [config.default_purchase_tax.id] or False, company_id=config.company_id.id)
def set_chart_of_accounts(self, cr, uid, ids, context=None):

View File

@ -80,8 +80,13 @@
I validate this account move by using the 'Post Journal Entries' wizard
-
!record {model: validate.account.move, id: validate_account_move_0}:
journal_id: account.bank_journal
period_id: account.period_6
journal_ids:
- bank_journal
- check_journal
period_ids:
- period_6
- period_7
- period_8
-
I click on validate Button
-

View File

@ -25,18 +25,18 @@ class validate_account_move(osv.osv_memory):
_name = "validate.account.move"
_description = "Validate Account Move"
_columns = {
'journal_id': fields.many2one('account.journal', 'Journal', required=True),
'period_id': fields.many2one('account.period', 'Period', required=True, domain=[('state','<>','done')]),
'journal_ids': fields.many2many('account.journal', 'wizard_validate_account_move_journal', 'wizard_id', 'journal_id', 'Journal', required=True),
'period_ids': fields.many2many('account.period', 'wizard_validate_account_move_period', 'wizard_id', 'period_id', 'Period', required=True, domain=[('state','<>','done')]),
}
def validate_move(self, cr, uid, ids, context=None):
obj_move = self.pool.get('account.move')
if context is None:
context = {}
data = self.browse(cr, uid, ids, context=context)[0]
ids_move = obj_move.search(cr, uid, [('state','=','draft'),('journal_id','=',data.journal_id.id),('period_id','=',data.period_id.id)])
data = self.read(cr, uid, ids[0], context=context)
ids_move = obj_move.search(cr, uid, [('state','=','draft'),('journal_id','in',tuple(data['journal_ids'])),('period_id','in',tuple(data['period_ids']))])
if not ids_move:
raise osv.except_osv(_('Warning!'), _('Specified journal does not have any account move entries in draft state for this period.'))
raise osv.except_osv(_('Warning!'), _('Specified journals do not have any account move entries in draft state for the specified periods.'))
obj_move.button_validate(cr, uid, ids_move, context=context)
return {'type': 'ir.actions.act_window_close'}

View File

@ -9,8 +9,8 @@
<field name="arch" type="xml">
<form string="Post Journal Entries" version="7.0">
<group>
<field name="journal_id"/>
<field name="period_id"/>
<field name="journal_ids"/>
<field name="period_ids"/>
</group>
<footer>
<button string="Approve" name="validate_move" type="object" class="oe_highlight"/>

View File

@ -21,21 +21,25 @@
#
##############################################################################
from openerp.osv import osv
from openerp.osv import osv, fields
class account_invoice_line(osv.osv):
_inherit = "account.invoice.line"
_columns = {
'move_id': fields.many2one('stock.move', string="Move line", help="If the invoice was generated from a stock.picking, reference to the related move line."),
}
def move_line_get(self, cr, uid, invoice_id, context=None):
res = super(account_invoice_line,self).move_line_get(cr, uid, invoice_id, context=context)
inv = self.pool.get('account.invoice').browse(cr, uid, invoice_id, context=context)
company_currency = inv.company_id.currency_id.id
def get_price(cr, uid, inv, company_currency,i_line):
def get_price(cr, uid, inv, company_currency, i_line, price_unit):
cur_obj = self.pool.get('res.currency')
if inv.currency_id.id != company_currency:
price = cur_obj.compute(cr, uid, company_currency, inv.currency_id.id, i_line.product_id.standard_price * i_line.quantity, context={'date': inv.date_invoice})
price = cur_obj.compute(cr, uid, company_currency, inv.currency_id.id, price_unit * i_line.quantity, context={'date': inv.date_invoice})
else:
price = i_line.product_id.standard_price * i_line.quantity
price = price_unit * i_line.quantity
return price
if inv.type in ('out_invoice','out_refund'):
@ -60,12 +64,13 @@ class account_invoice_line(osv.osv):
if not cacc:
cacc = i_line.product_id.categ_id.property_account_expense_categ and i_line.product_id.categ_id.property_account_expense_categ.id
if dacc and cacc:
price_unit = i_line.move_id and i_line.move_id.price_unit or i_line.product_id.standard_price
res.append({
'type':'src',
'name': i_line.name[:64],
'price_unit':i_line.product_id.standard_price,
'price_unit':price_unit,
'quantity':i_line.quantity,
'price':get_price(cr, uid, inv, company_currency, i_line),
'price':get_price(cr, uid, inv, company_currency, i_line, price_unit),
'account_id':dacc,
'product_id':i_line.product_id.id,
'uos_id':i_line.uos_id.id,
@ -76,9 +81,9 @@ class account_invoice_line(osv.osv):
res.append({
'type':'src',
'name': i_line.name[:64],
'price_unit':i_line.product_id.standard_price,
'price_unit':price_unit,
'quantity':i_line.quantity,
'price': -1 * get_price(cr, uid, inv, company_currency, i_line),
'price': -1 * get_price(cr, uid, inv, company_currency, i_line, price_unit),
'account_id':cacc,
'product_id':i_line.product_id.id,
'uos_id':i_line.uos_id.id,

View File

@ -28,6 +28,15 @@ class stock_picking(osv.osv):
_inherit = "stock.picking"
_description = "Picking List"
def _prepare_invoice_line(self, cr, uid, group, picking, move_line, invoice_id,
invoice_vals, context=None):
"""Overwrite to add move_id reference"""
res = super(stock_picking, self)._prepare_invoice_line(cr, uid, group, picking, move_line, invoice_id, invoice_vals, context=context)
res.update({
'move_id': move_line.id,
})
return res
def action_invoice_create(self, cr, uid, ids, journal_id=False,
group=False, type='out_invoice', context=None):
'''Return ids of created invoices for the pickings'''

View File

@ -0,0 +1,23 @@
# Hebrew translation for openobject-addons
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
#
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: 2013-11-26 08:55+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Hebrew <he@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: 2013-11-27 04:37+0000\n"
"X-Generator: Launchpad (build 16845)\n"
#. module: account_cancel
#: view:account.invoice:0
msgid "Cancel"
msgstr ""

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,23 @@
# Arabic translation for openobject-addons
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
#
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: 2013-11-26 18:16+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Arabic <ar@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: 2013-11-27 04:37+0000\n"
"X-Generator: Launchpad (build 16845)\n"
#. module: auth_oauth_signup
#: model:ir.model,name:auth_oauth_signup.model_res_users
msgid "Users"
msgstr "المستخدمين"

View File

@ -11,6 +11,8 @@
<field name="active" eval="False"/>
<!-- Avoid auto-including this user in any default group, just like a typical portal member -->
<field name="groups_id" eval="[(5,)]"/>
<!-- allow signuped users to have a alias -->
<field name="alias_name">_usertemplate</field>
</record>
<record id="default_template_user_config" model="ir.config_parameter">

View File

@ -234,6 +234,7 @@ class res_users(osv.Model):
# create a copy of the template user (attached to a specific partner_id if given)
values['active'] = True
context = dict(context or {}, no_reset_password=True)
return self.copy(cr, uid, template_user_id, values, context=context)
def reset_password(self, cr, uid, login, context=None):

View File

@ -2,11 +2,6 @@
<openerp>
<data>
<!-- add context in action to enable automatic reset password -->
<record id="base.action_res_users" model="ir.actions.act_window">
<field name="context">{'reset_password': True}</field>
</record>
<record id="res_users_form_view" model="ir.ui.view">
<field name="name">user.form.state</field>
<field name="model">res.users</field>

View File

@ -424,12 +424,8 @@ property or property parameter."),
event.add('location').value = event_obj.location
if event_obj.rrule:
event.add('rrule').value = event_obj.rrule
if event_obj.organizer:
# deprecated: will be removed with OpenERP v8: use organizer_id instead
event_org = event.add('organizer')
event_org.params['CN'] = [event_obj.organizer]
event_org.value = 'MAILTO:' + (event_obj.organizer)
elif event_obj.user_id or event_obj.organizer_id:
if event_obj.user_id or event_obj.organizer_id:
event_org = event.add('organizer')
organizer = event_obj.organizer_id
if not organizer:

View File

@ -1,12 +1,14 @@
.oe_import > p {
margin-left: 8px;
margin-right: 8px;
margin-top: 13px; /* Customize space according bootstrap3 */
text-align: justify
}
.oe_import h2 {
margin-top: 0;
margin-bottom: 5px;
font-size: 1.5em; /* Customize according bootstrap3 */
}
.oe_padding {
@ -22,6 +24,14 @@
border: solid 1px #dddddd;
width: 600px;
}
/* Customize according bootstrap3 */
.oe_import .oe_import_box label{
font-weight: normal;
}
.oe_import .oe_import_box .oe_import_file {
display: inline-block;
}
/* End of Customize */
.oe_import .oe_import_toggle{
margin-top: 8px;
}
@ -40,7 +50,7 @@
}
.oe_import .oe_import_options p {
margin: 0;
margin: 0 0 -7px 0; /* Customize margin-bottom of <p> according bootstrap3 */
padding: 0;
}
.oe_import .oe_import_options label {
@ -69,6 +79,14 @@
.oe_import .oe_import_report_more {
display: none;
}
/* Customize dd and label according bootstrap3 */
.oe_import dd {
-webkit-margin-start: 40px;
}
.oe_import .oe_import_with_file label {
font-weight: normal;
}
/* End of customize */
.oe_import.oe_import_preview .oe_import_grid {
display: table;

View File

@ -373,7 +373,7 @@ openerp.base_import = function (instance) {
return $.when([{
type: 'error',
record: false,
message: error.data.fault_code,
message: error.data.arguments[1],
}]);
}) ;
},

View File

@ -13,7 +13,6 @@
<field name="search_view_id" ref="crm.view_crm_case_leads_filter"/>
<field name="context">{
'search_default_section_id': [active_id],
'search_default_open': 1,
'default_section_id': active_id,
'default_type': 'lead',
'stage_type': 'lead',
@ -43,7 +42,6 @@
<field name="search_view_id" ref="crm.view_crm_case_opportunities_filter"/>
<field name="context">{
'search_default_section_id': [active_id],
'search_default_assigned_to_me': 1,
'default_section_id': active_id,
'stage_type': 'opportunity',
'default_type': 'opportunity',
@ -64,6 +62,26 @@
</field>
</record>
<record id="action_report_crm_lead_salesteam" model="ir.actions.act_window">
<field name="name">Leads Analysis</field>
<field name="res_model">crm.lead.report</field>
<field name="view_type">form</field>
<field name="context">{"search_default_month":1}</field>
<field name="view_mode">tree,graph</field>
<field name="domain">[('type','=', 'lead'),('section_id', '=', active_id)]</field>
<field name="help">Leads Analysis allows you to check different CRM related information like the treatment delays or number of leads per state. You can sort out your leads analysis by different groups to get accurate grained analysis.</field>
</record>
<record id="action_report_crm_opportunity_salesteam" model="ir.actions.act_window">
<field name="name">Opportunities Analysis</field>
<field name="res_model">crm.lead.report</field>
<field name="view_type">form</field>
<field name="context">{"search_default_month":1}</field>
<field name="view_mode">tree,graph</field>
<field name="domain">[('type','=', 'opportunity'), ('section_id', '=', active_id)]</field>
<field name="help">Opportunities Analysis gives you an instant access to your opportunities with information such as the expected revenue, planned cost, missed deadlines or the number of interactions per opportunity. This report is mainly used by the sales manager in order to do the periodic review with the teams of the sales pipeline.</field>
</record>
<!-- Case Sections Salesteams kanban view -->
<record model="ir.ui.view" id="crm_case_section_salesteams_view_kanban">
@ -99,13 +117,25 @@
<div class="oe_items_list">
<div class="oe_salesteams_leads" t-if="record.use_leads.raw_value">
<a name="%(crm_case_form_view_salesteams_lead)d" type="action">Leads</a>
<a name="%(action_report_crm_lead)d" type="action" class="oe_sparkline_bar_link"><field name="monthly_open_leads" widget="sparkline_bar" options="{'height': '20px', 'barWidth': 4, 'barSpacing': 1}">Open Leads per Month<br/>Click to see a detailed analysis of leads.</field></a>
<a name="%(action_report_crm_lead_salesteam)d" type="action" class="oe_sparkline_bar_link">
<field name="monthly_open_leads" widget="sparkline_bar"
options="{'height': '20px', 'barWidth': 4, 'barSpacing': 1, 'delayIn': '3000', 'tooltip_suffix': 'Leads'}">Open Leads per Month<br/>Click to see a detailed analysis of leads.</field>
</a>
</div>
<div class="oe_salesteams_opportunities">
<a name="%(crm_case_form_view_salesteams_opportunity)d" type="action">Opportunities</a>
<a name="%(action_report_crm_opportunity)d" type="action"><field name="monthly_planned_revenue" widget="sparkline_bar" height="20px" barWidth="4" barSpacing="1">Planned Revenue per Month<br/>Click to see a detailed analysis of opportunities.</field></a>
<a name="%(action_report_crm_opportunity_salesteam)d" type="action">
<field name="monthly_planned_revenue" widget="sparkline_bar"
options="{'height': '20px', 'barWidth': '4', 'barSpacing': '1', 'delayIn': '3000', 'tooltip_suffix': 'Opportunities'}">Planned Revenue per Month<br/>Click to see a detailed analysis of opportunities.</field>
</a>
</div>
</div>
<div class="oe_clear"></div>
<div class="oe_kanban_salesteams_avatars">
<t t-foreach="record.member_ids.raw_value.slice(0,10)" t-as="member">
<img t-att-src="kanban_image('res.users', 'image_small', member)" t-att-data-member_id="member"/>
</t>
</div>
</div>
</div>
</t>

View File

@ -6,14 +6,20 @@
<field name="groups_id" eval="[(4,ref('base.group_sale_salesman'))]"/>
</record>
<record id="crm.section_sales_department" model="crm.case.section">
<field name="member_ids" eval="[(4, ref('base.user_demo'))]"/>
</record>
<record model="crm.case.section" id="crm_case_section_1">
<field name="name">Indirect Sales</field>
<field name="code">IM</field>
<field name="member_ids" eval="[(4, ref('base.user_root')),(4, ref('base.user_demo'))]"/>
</record>
<record model="crm.case.section" id="crm_case_section_2">
<field name="name">Marketing</field>
<field name="code">SPD</field>
<field name="member_ids" eval="[(4, ref('base.user_root')),(4, ref('base.user_demo'))]"/>
</record>
<record model="crm.segmentation" id="crm_segmentation0">

View File

@ -99,6 +99,7 @@
help="Convert to Opportunity" class="oe_highlight"/>
<field name="stage_id" widget="statusbar" clickable="True"
domain="['&amp;', '|', ('case_default', '=', True), ('section_ids', '=', section_id), '|', ('type', '=', type), ('type', '=', 'both')]"
options="{'fold_field': 'fold'}"
on_change="onchange_stage_id(stage_id)"/>
</header>
<sheet>
@ -379,14 +380,11 @@
<field name="arch" type="xml">
<form string="Opportunities" version="7.0">
<header>
<!-- :deprecated: this button will be removed from the view with OpenERP v8 -->
<button name="case_mark_won" string="Mark Won" type="object" class="oe_highlight"
invisible="True"/>
<!-- :deprecated: this button will be removed from the view with OpenERP v8 -->
<button name="case_mark_lost" string="Mark Lost" type="object" class="oe_highlight"
invisible="True"/>
<button name="case_mark_won" string="Mark Won" type="object" class="oe_highlight"/>
<button name="case_mark_lost" string="Mark Lost" type="object" class="oe_highlight"/>
<field name="stage_id" widget="statusbar" clickable="True"
domain="['&amp;', ('section_ids', '=', section_id), '|', ('type', '=', type), ('type', '=', 'both')]"/>
options="{'fold_field': 'fold'}"
domain="['&amp;', ('section_ids', '=', section_id), '|', ('type', '=', type), ('type', '=', 'both')]"/>
</header>
<sheet>
<div class="oe_right oe_button_box">
@ -621,7 +619,6 @@
if context.get('active_model') == 'crm.lead' and context.get('active_ids'):
self.case_mark_lost(cr, uid, context['active_ids'], context=context)
</field>
<field name="groups_id" eval="[(4,ref('base.group_sale_salesman'))]"/>
</record>
<record id="ir_mark_as_lost" model="ir.values">

View File

@ -66,9 +66,6 @@
<field name="model">crm.lead.report</field>
<field name="arch" type="xml">
<search string="Leads Analysis">
<filter icon="terp-personal" name="lead" string="Lead" domain="[('type','=', 'lead')]" help="Show only lead"/>
<filter icon="terp-personal+" string="Opportunity" name="opportunity" domain="[('type','=','opportunity')]" help="Show only opportunity"/>
<separator/>
<filter string="New" name="new"
domain="[('probability', '=', 0), ('stage_id.sequence', '=', 1)]"/>
<filter string="Won" name="won"
@ -115,7 +112,7 @@
<separator orientation="vertical" />
<filter string="Year" icon="terp-go-year"
domain="[]" context="{'group_by':'creation_year'}"/>
<filter string="Month" icon="terp-go-month"
<filter string="Month" name="month" icon="terp-go-month"
domain="[]" context="{'group_by':'creation_month'}"/>
<filter string="Day" icon="terp-go-today"
domain="[]" context="{'group_by':'creation_day'}"/>
@ -168,9 +165,9 @@
<field name="name">Leads Analysis</field>
<field name="res_model">crm.lead.report</field>
<field name="view_type">form</field>
<field name="context">{'search_default_year': 1,'search_default_lead': 1, "search_default_user":1, "search_default_this_month":1, 'group_by_no_leaf':1, 'group_by':[]}</field>
<field name="context">{'search_default_year': 1, "search_default_user":1, "search_default_month":1, 'group_by_no_leaf':1, 'group_by':[]}</field>
<field name="view_mode">tree,graph</field>
<field name="domain">[]</field>
<field name="domain">[('type','=', 'lead')]</field>
<field name="help">Leads Analysis allows you to check different CRM related information like the treatment delays or number of leads per state. You can sort out your leads analysis by different groups to get accurate grained analysis.</field>
</record>
<record model="ir.actions.act_window.view" id="action_report_crm_lead_tree">
@ -190,8 +187,9 @@
<field name="name">Opportunities Analysis</field>
<field name="res_model">crm.lead.report</field>
<field name="view_type">form</field>
<field name="context">{"search_default_year":1,"search_default_opportunity":1, "search_default_user":1,"search_default_this_month":1,'group_by_no_leaf':1,'group_by':[]}</field>
<field name="context">{"search_default_year":1, "search_default_user":1,"search_default_month":1,'group_by_no_leaf':1,'group_by':[]}</field>
<field name="view_mode">tree,graph</field>
<field name="domain">[('type','=', 'opportunity')]</field>
<field name="help">Opportunities Analysis gives you an instant access to your opportunities with information such as the expected revenue, planned cost, missed deadlines or the number of interactions per opportunity. This report is mainly used by the sales manager in order to do the periodic review with the teams of the sales pipeline.</field>
</record>

View File

@ -91,5 +91,19 @@
<field name="groups" eval="[(4, ref('base.group_sale_salesman_all_leads'))]"/>
</record>
<record id="crm_rule_personal_lead_report" model="ir.rule">
<field name="name">Personal Leads Analysis</field>
<field ref="model_crm_lead_report" name="model_id"/>
<field name="domain_force">['|',('user_id','=',user.id),('user_id','=',False)]</field>
<field name="groups" eval="[(4, ref('base.group_sale_salesman'))]"/>
</record>
<record id="crm_rule_all_lead_report" model="ir.rule">
<field name="name">All Leads Analysis</field>
<field ref="model_crm_lead_report" name="model_id"/>
<field name="domain_force">[(1,'=',1)]</field>
<field name="groups" eval="[(4, ref('base.group_sale_salesman_all_leads'))]"/>
</record>
</data>
</openerp>

View File

@ -35,5 +35,3 @@ access_crm_lead_partner_manager,crm.lead.partner.manager,model_crm_lead,base.gro
access_crm_phonecall_partner_manager,crm.phonecall.partner.manager,model_crm_phonecall,base.group_partner_manager,1,1,1,1
access_crm_payment_mode_user,crm.payment.mode,model_crm_payment_mode,base.group_sale_salesman,1,0,0,0
access_crm_payment_mode,crm.payment.mode,model_crm_payment_mode,base.group_sale_manager,1,1,1,1
access_base_partner_merge_line_manager,base_partner_merge_line.manager,model_base_partner_merge_line,base.group_system,1,1,1,1
access_base_partner_merge_manager,base_partner_merge.manager,model_base_partner_merge_automatic_wizard,base.group_system,1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
35 access_crm_phonecall_partner_manager crm.phonecall.partner.manager model_crm_phonecall base.group_partner_manager 1 1 1 1
36 access_crm_payment_mode_user crm.payment.mode model_crm_payment_mode base.group_sale_salesman 1 0 0 0
37 access_crm_payment_mode crm.payment.mode model_crm_payment_mode base.group_sale_manager 1 1 1 1
access_base_partner_merge_line_manager base_partner_merge_line.manager model_base_partner_merge_line base.group_system 1 1 1 1
access_base_partner_merge_manager base_partner_merge.manager model_base_partner_merge_automatic_wizard base.group_system 1 1 1 1

View File

@ -0,0 +1,2 @@
crm.css: crm.sass
sass --trace -t expanded crm.sass:crm.css

View File

@ -1,64 +1,62 @@
@charset "utf-8";
.openerp .oe_kanban_view .oe_kanban_crm_salesteams {
width: 345px;
/* Customize width and height of kanban according bootstrap3 */
width: 357px;
min-height: 254px !important;
/* End of customize */
cursor: default;
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_avatars {
text-align: right;
margin: -5px 0 -10px 0;
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_avatars img {
width: 30px;
height: 30px;
padding-left: 0px;
margin-top: 3px;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
border-radius: 2px;
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list {
position: relative;
margin: 10px;
position: relative;
/* Improved margin to set alignment of list items according bootstrap3 */
margin: 10px 0 10px 9px;
min-height: 10px;
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list div {
width: 160px;
height: 22px;
margin: 0 !important;
position: relative;
display: inline-block;
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list a:hover {
text-decoration: underline !important;
width: 160px;
height: 22px;
margin: 0 !important;
position: relative;
display: inline-block;
float: left;
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list div a:nth-child(2n) {
position: absolute;
left: 90px;
top: 0;
position: absolute;
left: 90px;
top: 0;
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list div:nth-child(2n) a:nth-child(2n) {
left: 110px;
left: 110px;
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list a:hover {
text-decoration: underline !important;
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_center {
text-align: center;
margin: 3px 0;
text-align: center;
margin: 3px 0;
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_center .oe_sum {
margin: 0;
font-size: 40px;
margin: 0;
font-size: 40px;
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_center .oe_subsum {
font-size: 10px;
font-size: 10px;
}
.openerp .oe_kanban_view .oe_justgage {
color: black;
display: inline-block;
.openerp .oe_kanban_view .oe_salesteams_help {
display: inline-block;
}
.openerp .oe_kanban_view .oe_kanban_salesteams_avatars {
margin-top: 20px;
}
.openerp .oe_kanban_view .oe_kanban_salesteams_avatars img {
width: 30px;
height: 30px;
padding-left: 0px;
margin-top: 3px;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
border-radius: 2px;
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}
.openerp .oe_kanban_view .oe_sparkline_bar {
height: 20px;
width: 36px;
}

View File

@ -0,0 +1,55 @@
@charset "utf-8"
.openerp
.oe_kanban_view
.oe_kanban_crm_salesteams
/* Customize width and height of kanban according bootstrap3 */
width: 357px
min-height: 254px !important
/* End of customize */
cursor: default
.oe_items_list
position: relative
/* Improved margin to set alignment of list items according bootstrap3 */
margin: 10px 0 10px 9px
min-height: 10px
div
width: 160px
height: 22px
margin: 0 !important
position: relative
display: inline-block
float: left
a:nth-child(2n)
position: absolute
left: 90px
top: 0
div:nth-child(2n)
a:nth-child(2n)
left: 110px
a:hover
text-decoration: underline !important
.oe_center
text-align: center
margin: 3px 0
.oe_sum
margin: 0
font-size: 40px
.oe_subsum
font-size: 10px
.oe_salesteams_help
display: inline-block
.oe_kanban_salesteams_avatars
margin-top: 20px
.oe_kanban_salesteams_avatars
img
width: 30px
height: 30px
padding-left: 0px
margin-top: 3px
-moz-border-radius: 2px
-webkit-border-radius: 2px
border-radius: 2px
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2)
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2)
-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2)

View File

@ -1,4 +1,40 @@
openerp.crm = function(openerp) {
openerp.web_kanban.KanbanView.include({
crm_display_members_names: function() {
/*
* Set avatar title for members.
* In kanban views, many2many fields only return a list of ids.
* We can implement return value of m2m fields like [(1,"Adminstration"),...].
*/
var self = this;
var members_ids = [];
// Collect members ids
self.$el.find('img[data-member_id]').each(function() {
members_ids.push($(this).data('member_id'));
});
// Find their matching names
var dataset = new openerp.web.DataSetSearch(self, 'res.users', self.session.context, [['id', 'in', _.uniq(members_ids)]]);
dataset.read_slice(['id', 'name']).done(function(result) {
_.each(result, function(v, k) {
// Set the proper value in the DOM
self.$el.find('img[data-member_id=' + v.id + ']').attr('title', v.name).tipsy({
offset: 10
});
});
});
},
on_groups_started: function() {
var self = this;
self._super.apply(self, arguments);
if (self.dataset.model === 'crm.case.section') {
self.crm_display_members_names();
}
},
});
openerp.web_kanban.KanbanRecord.include({
on_card_clicked: function() {
if (this.view.dataset.model === 'crm.case.section') {
@ -8,5 +44,4 @@ openerp.crm = function(openerp) {
}
},
});
};

View File

@ -38,6 +38,9 @@ class crm_lead2opportunity_partner(osv.osv_memory):
'section_id': fields.many2one('crm.case.section', 'Sales Team', select=True),
}
def onchange_action(self, cr, uid, ids, action, context=None):
return {'value': {'partner_id': False if action != 'exist' else self._find_matching_partner(cr, uid, context=context)}}
def default_get(self, cr, uid, fields, context=None):
"""
Default get for name, opportunity_ids.

View File

@ -31,7 +31,7 @@
</field>
</group>
<group name="action" attrs="{'invisible': [('name', '!=', 'convert')]}">
<field name="action" class="oe_inline"/>
<field name="action" on_change="onchange_action(action, context)" class="oe_inline"/>
<field name="partner_id"
attrs="{'required': [('action', '=', 'exist')], 'invisible':[('action','!=','exist')]}"
class="oe_inline"/>

View File

@ -51,7 +51,9 @@
<search string="Search">
<filter string="My Sales Team(s)" icon="terp-personal+" context="{'invisible_section': False}" domain="[('section_id.user_id','=',uid)]" help="My Sales Team(s)" groups="base.group_multi_salesteams"/>
<separator/>
<filter string="My Company" icon="terp-go-home" context="{'invisible_section': False}" domain="[('section_id.user_id.company_id','=',uid)]" help="My company"/>
<!-- A 'My Company' filter makes no sense regarding record rules, and is not possible to do (uid is not a company): remove me in 8.0 -->
<filter string="My Company" icon="terp-go-home" context="{'invisible_section': False}" domain="[]" help="My company"
invisible="1"/>
<separator/>
<filter icon="terp-personal" string="My Case(s)" help="My Case(s)" domain="[('user_id','=',uid)]" />
<field name="company_id" groups="base.group_multi_company"/>

View File

@ -157,7 +157,6 @@
if ids:
self.assign_salesman_of_assigned_partner(cr, uid, ids, context=context)
</field>
<field name="groups_id" eval="[(4,ref('base.group_sale_manager'))]"/>
</record>
<record model="ir.values" id="ir_assign_salesman_according_assigned_partner">

View File

@ -69,7 +69,11 @@ class document_file(osv.osv):
def check(self, cr, uid, ids, mode, context=None, values=None):
"""Overwrite check to verify access on directory to validate specifications of doc/access_permissions.rst"""
if not isinstance(ids, list):
ids = [ids]
super(document_file, self).check(cr, uid, ids, mode, context=context, values=values)
if ids:
self.pool.get('ir.model.access').check(cr, uid, 'document.directory', mode)

View File

@ -369,7 +369,7 @@ class email_template(osv.osv):
attachment_ids=[attach.id for attach in template.attachment_ids],
)
# Add report in attachments
# Add report in attachments: generate once for all template_res_ids
if template.report_template:
for res_id in template_res_ids:
attachments = []
@ -387,8 +387,7 @@ class email_template(osv.osv):
if not report_name.endswith(ext):
report_name += ext
attachments.append((report_name, result))
values['attachments'] = attachments
results[res_id]['attachments'] = attachments
return results

View File

@ -49,13 +49,14 @@ Main Features
'board'
],
'data' : [
'security/fleet_security.xml',
'security/ir.model.access.csv',
'fleet_view.xml',
'fleet_cars.xml',
'fleet_data.xml',
'fleet_board_view.xml',
],
'images': ['images/costs_analysis.jpeg','images/indicative_costs_analysis.jpeg','images/vehicles.jpeg','images/vehicles_contracts.jpeg','images/vehicles_fuel.jpeg','images/vehicles_odometer.jpeg','images/vehicles_services.jpeg'],
'update_xml' : ['security/fleet_security.xml','security/ir.model.access.csv'],
'demo': ['fleet_demo.xml'],

View File

@ -559,7 +559,7 @@ class fleet_vehicle_log_fuel(osv.Model):
'inv_ref': fields.char('Invoice Reference', size=64),
'vendor_id': fields.many2one('res.partner', 'Supplier', domain="[('supplier','=',True)]"),
'notes': fields.text('Notes'),
'cost_id': fields.many2one('fleet.vehicle.cost', 'Cost'),
'cost_id': fields.many2one('fleet.vehicle.cost', 'Cost', required=True, ondelete='cascade'),
'cost_amount': fields.related('cost_id', 'amount', string='Amount', type='float', store=True), #we need to keep this field as a related with store=True because the graph view doesn't support (1) to address fields from inherited table and (2) fields that aren't stored in database
}
_defaults = {
@ -600,7 +600,7 @@ class fleet_vehicle_log_services(osv.Model):
'vendor_id': fields.many2one('res.partner', 'Supplier', domain="[('supplier','=',True)]"),
'cost_amount': fields.related('cost_id', 'amount', string='Amount', type='float', store=True), #we need to keep this field as a related with store=True because the graph view doesn't support (1) to address fields from inherited table and (2) fields that aren't stored in database
'notes': fields.text('Notes'),
'cost_id': fields.many2one('fleet.vehicle.cost', 'Cost'),
'cost_id': fields.many2one('fleet.vehicle.cost', 'Cost', required=True, ondelete='cascade'),
}
_defaults = {
'date': fields.date.context_today,
@ -799,7 +799,7 @@ class fleet_vehicle_log_contract(osv.Model):
'cost_frequency': fields.selection([('no','No'), ('daily', 'Daily'), ('weekly','Weekly'), ('monthly','Monthly'), ('yearly','Yearly')], 'Recurring Cost Frequency', help='Frequency of the recuring cost', required=True),
'generated_cost_ids': fields.one2many('fleet.vehicle.cost', 'contract_id', 'Generated Costs', ondelete='cascade'),
'sum_cost': fields.function(_get_sum_cost, type='float', string='Indicative Costs Total'),
'cost_id': fields.many2one('fleet.vehicle.cost', 'Cost'),
'cost_id': fields.many2one('fleet.vehicle.cost', 'Cost', required=True, ondelete='cascade'),
'cost_amount': fields.related('cost_id', 'amount', string='Amount', type='float', store=True), #we need to keep this field as a related with store=True because the graph view doesn't support (1) to address fields from inherited table and (2) fields that aren't stored in database
}
_defaults = {

View File

@ -60,10 +60,9 @@ class config(osv.Model):
def get_access_token(self, cr, uid, scope=None, context=None):
ir_config = self.pool['ir.config_parameter']
google_drive_refresh_token = ir_config.get_param(cr, SUPERUSER_ID, 'google_drive_refresh_token')
group_config = self.pool['ir.model.data'].get_object_reference(cr, uid, 'base', 'group_erp_manager')[1]
user = self.pool['res.users'].read(cr, uid, uid, "groups_id")
user_is_admin = self.pool['res.users'].has_group(cr, uid, 'base.group_erp_manager')
if not google_drive_refresh_token:
if group_config in user['groups_id']:
if user_is_admin:
raise self.pool.get('res.config.settings').get_config_warning(cr, _("You haven't configured 'Authorization Code' generated from google, Please generate and configure it in %(menu:base_setup.menu_general_configuration)s."), context=context)
else:
raise osv.except_osv(_('Error!'), _("Google Drive is not yet configured. Please contact your administrator."))
@ -81,7 +80,7 @@ class config(osv.Model):
req = urllib2.Request('https://accounts.google.com/o/oauth2/token', data, headers)
content = urllib2.urlopen(req).read()
except urllib2.HTTPError:
if group_config in user['groups_id']:
if user_is_admin:
raise self.pool.get('res.config.settings').get_config_warning(cr, _("Something went wrong during the token generation. Please request again an authorization code in %(menu:base_setup.menu_general_configuration)s."), context=context)
else:
raise osv.except_osv(_('Error!'), _("Google Drive is not yet configured. Please contact your administrator."))

View File

@ -18,6 +18,7 @@
#
##############################################################################
import cgi
import simplejson
import logging
from lxml import etree
@ -67,24 +68,24 @@ class config(osv.osv):
request = '''<feed xmlns="http://www.w3.org/2005/Atom"
xmlns:batch="http://schemas.google.com/gdata/batch"
xmlns:gs="http://schemas.google.com/spreadsheets/2006">
<id>https://spreadsheets.google.com/feeds/cells/%s/od6/private/full</id>
<id>https://spreadsheets.google.com/feeds/cells/{key}/od6/private/full</id>
<entry>
<batch:id>A1</batch:id>
<batch:operation type="update"/>
<id>https://spreadsheets.google.com/feeds/cells/%s/od6/private/full/R1C1</id>
<id>https://spreadsheets.google.com/feeds/cells/{key}/od6/private/full/R1C1</id>
<link rel="edit" type="application/atom+xml"
href="https://spreadsheets.google.com/feeds/cells/%s/od6/private/full/R1C1"/>
<gs:cell row="1" col="1" inputValue="%s"/>
href="https://spreadsheets.google.com/feeds/cells/{key}/od6/private/full/R1C1"/>
<gs:cell row="1" col="1" inputValue="{formula}"/>
</entry>
<entry>
<batch:id>A2</batch:id>
<batch:operation type="update"/>
<id>https://spreadsheets.google.com/feeds/cells/%s/od6/private/full/R60C15</id>
<id>https://spreadsheets.google.com/feeds/cells/{key}/od6/private/full/R60C15</id>
<link rel="edit" type="application/atom+xml"
href="https://spreadsheets.google.com/feeds/cells/%s/od6/private/full/R60C15"/>
<gs:cell row="60" col="15" inputValue="%s"/>
href="https://spreadsheets.google.com/feeds/cells/{key}/od6/private/full/R60C15"/>
<gs:cell row="60" col="15" inputValue="{config}"/>
</entry>
</feed>''' % (spreadsheet_key, spreadsheet_key, spreadsheet_key, formula.replace('"', '&quot;'), spreadsheet_key, spreadsheet_key, config_formula.replace('"', '&quot;'))
</feed>''' .format(key=spreadsheet_key, formula=cgi.escape(formula, quote=True), config=cgi.escape(config_formula, quote=True))
try:
req = urllib2.Request(

View File

@ -5,7 +5,7 @@
display: inline-block;
}
.openerp .oe_attendance_signin {
float:left;
float: right;
height: 32px;
width: 32px;
background: url(/hr_attendance/static/src/img/emp-out32.png);

File diff suppressed because one or more lines are too long

View File

@ -8,7 +8,6 @@
<field name="type_id" ref="degree_graduate"/>
<field name="categ_ids" eval="[(6,0,[ref('tag_applicant_sales')])]"/>
<field name="user_id" ref="base.user_demo"/>
<field eval= "time.strftime('%Y-%m-01 10:35:50')" name="date"/>
<field name="priority">2</field>
<field name="partner_name">Enrique Jones</field>
<field name="partner_mobile">9963214587</field>
@ -22,7 +21,6 @@
<field name="department_id" ref="hr.dep_rd"/>
<field name="type_id" ref="degree_licenced"/>
<field name="categ_ids" eval="[(6,0,[ref('tag_applicant_manager')])]"/>
<field eval="time.strftime('%Y-%m-10 18:15:00')" name="date"/>
<field name="user_id" ref="base.user_demo"/>
<field name="priority">3</field>
<field name="partner_name">Marie Justine</field>
@ -38,7 +36,6 @@
<field name="department_id" ref="hr.dep_administration"/>
<field name="type_id" ref="degree_bachelor"/>
<field name="categ_ids" eval="[(6,0,[ref('tag_applicant_it')])]"/>
<field eval="time.strftime('%Y-%m-10 18:15:00')" name="date"/>
<field name="user_id" ref="base.user_demo"/>
<field name="priority">1</field>
<field name="partner_name">Jose</field>
@ -53,7 +50,6 @@
<field name="department_id" ref="hr.dep_sales"/>
<field name="type_id" ref="degree_graduate"/>
<field name="categ_ids" eval="[(6,0,[ref('tag_applicant_manager')])]"/>
<field eval="time.strftime('%Y-%m-25 16:25:52')" name="date"/>
<field name="user_id" ref="base.user_root"/>
<field name="partner_name">John Bruno</field>
<field name="stage_id" ref="stage_job5"/>
@ -66,7 +62,6 @@
<field name="department_id" ref="hr.dep_rd"/>
<field name="type_id" ref="degree_licenced"/>
<field name="categ_ids" eval="[(6,0,[ref('tag_applicant_reserve')])]"/>
<field eval="time.strftime('%Y-%m-26 17:15:32')" name="date"/>
<field name="user_id" ref="base.user_demo"/>
<field name="partner_name">Sandra Elvis</field>
<field name="stage_id" ref="stage_job6"/>
@ -79,7 +74,6 @@
<field name="department_id" ref="hr.dep_administration"/>
<field name="type_id" ref="degree_licenced"/>
<field name="categ_ids" eval="[(6,0,[ref('tag_applicant_reserve')])]"/>
<field eval="time.strftime('%Y-%m-26 17:39:42')" name="date"/>
<field name="user_id" ref="base.user_root"/>
<field name="priority">4</field>
<field name="partner_name">David Armstrong</field>
@ -94,7 +88,6 @@
<field name="department_id" ref="hr.dep_rd"/>
<field name="type_id" ref="degree_licenced"/>
<field name="categ_ids" eval="[(6,0,[ref('tag_applicant_sales')])]"/>
<field eval="time.strftime('%Y-%m-12 17:49:19')" name="date"/>
<field name="partner_name">Tina Augustie</field>
<field name="partner_mobile">9898745745</field>
<field name="stage_id" ref="stage_job4"/>
@ -108,7 +101,6 @@
<field name="department_id" ref="hr.dep_rd"/>
<field name="type_id" ref="degree_licenced"/>
<field name="categ_ids" eval="[(6,0,[ref('tag_applicant_it')])]"/>
<field eval="time.strftime('%Y-%m-12 17:49:19')" name="date"/>
<field name="partner_name">Shane Williams</field>
<field name="partner_mobile">9812398524</field>
<field name="stage_id" ref="stage_job4"/>
@ -123,7 +115,6 @@
<field name="department_id" ref="hr.dep_ps"/>
<field name="type_id" ref="degree_licenced"/>
<field name="categ_ids" eval="[(6,0,[ref('tag_applicant_it')])]"/>
<field eval="time.strftime('%Y-%m-26 17:39:42')" name="date"/>
<field name="partner_name">David Armstrong</field>
<field name="partner_mobile">9988774455</field>
<field name="stage_id" ref="stage_job2"/>

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,7 @@
text-align: center;
color: #006699;
font-family: "Helvetica Neue", Arial, Verdana, "Nimbus Sans L", sans-serif;
font-size: 10px;
font-size: 11px;
background: #eeeeee;
min-width: 47px;
}
@ -33,7 +33,7 @@
min-width: 130px;
}
.openerp .oe_timesheet_weekly td input.oe_timesheet_weekly_input {
padding: 5px 2px !important;
padding-right: 2px !important;
width: 40px;
text-align: right;
min-width: 0 !important;

View File

@ -28,7 +28,7 @@
.oe_timesheet_first_col
min-width: 130px
td input.oe_timesheet_weekly_input
padding: 5px 2px !important
padding-right: 2px !important
width: 40px
text-align: right
min-width: 0 !important

View File

@ -1,5 +1,5 @@
.openerp .oe_kanban_view .oe_kanban_idea_idea {
width: 200px;
width: 212px; /* Customize width according bootstrap3 */
}
.openerp .oe_kanban_view .oe_kanban_idea_idea .oe_avatars {

View File

@ -80,7 +80,7 @@
});
},
calc_box: function() {
var $topbar = instance.client.$(".oe_topbar");
var $topbar = instance.client.$(".navbar"); // .oe_topbar is replaced with .navbar of bootstrap3
var top = $topbar.offset().top + $topbar.height();
top = Math.max(top - $(window).scrollTop(), 0);
this.$el.css("top", top);

View File

@ -211,5 +211,5 @@ class im_session(osv.osv):
_inherit = 'im.session'
_columns = {
'channel_id': fields.many2one("im.user", "Channel"),
'channel_id': fields.many2one("im_livechat.channel", "Channel"),
}

View File

@ -41,7 +41,7 @@ Plan contable boliviano e impuestos de acuerdo a disposiciones vigentes
],
"demo_xml": [
],
"update_xml": [
"data": [
],
"active": False,
"installable": True,

View File

@ -51,7 +51,7 @@ With this module you will have:
"account_chart",
],
"demo_xml" : [],
"update_xml" : ["data/account_tax_code.xml",
"data" : ["data/account_tax_code.xml",
"data/account_chart.xml",
"data/account_tax.xml",
"data/l10n_chart_mx_wizard.xml"],

View File

@ -44,7 +44,7 @@ Con la Colaboración de
],
"demo_xml": [
],
"update_xml": [
"data": [
],
"active": False,
"installable": True,

View File

@ -32,7 +32,7 @@ This is the module to manage the accounting chart, VAT structure and Registratio
Romanian accounting chart and localization.
""",
"demo_xml" : [],
"update_xml" : ['partner_view.xml','account_tax_code_template.xml','account_chart.xml','account_tax_template.xml','l10n_chart_ro_wizard.xml'],
"data" : ['partner_view.xml','account_tax_code_template.xml','account_chart.xml','account_tax_template.xml','l10n_chart_ro_wizard.xml'],
"auto_install": False,
"installable": True,
}

View File

@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
"PO-Revision-Date: 2013-02-14 16:43+0000\n"
"PO-Revision-Date: 2013-12-02 18:38+0000\n"
"Last-Translator: krnkris <Unknown>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-09-12 06:29+0000\n"
"X-Generator: Launchpad (build 16761)\n"
"X-Launchpad-Export-Date: 2013-12-03 05:41+0000\n"
"X-Generator: Launchpad (build 16856)\n"
#. module: mail
#: view:mail.followers:0
@ -1791,7 +1791,7 @@ msgstr "Altípusok"
#. module: mail
#: model:ir.model,name:mail.model_mail_alias
msgid "Email Aliases"
msgstr "e-amil álnevek"
msgstr "Email álnevek"
#. module: mail
#: field:mail.group,image_small:0

View File

@ -12,12 +12,13 @@
<button name="cancel" string="Cancel" type="object" states='outgoing'/>
</header>
<sheet>
<field name="mail_message_id" required="0" invisible="1"/>
<label for="subject" class="oe_edit_only"/>
<h2><field name="subject"/></h2>
<div style="vertical-align: top;">
by <field name="author_id" class="oe_inline" string="User"/> on <field name="date" class="oe_inline"/>
<button name="%(action_email_compose_message_wizard)d" string="Reply" type="action" icon="terp-mail-replied"
context="{'default_composition_mode':'reply', 'default_parent_id': active_id}" states='received,sent,exception,cancel'/>
context="{'default_composition_mode':'reply', 'default_parent_id': mail_message_id}" states='received,sent,exception,cancel'/>
</div>
<group>
<field name="email_from"/>

View File

@ -817,12 +817,11 @@ class mail_message(osv.Model):
return email_reply_to
def _get_message_id(self, cr, uid, values, context=None):
message_id = None
if not values.get('message_id') and values.get('reply_to'):
if values.get('reply_to'):
message_id = tools.generate_tracking_message_id('reply_to')
elif not values.get('message_id') and values.get('res_id') and values.get('model'):
elif values.get('res_id') and values.get('model'):
message_id = tools.generate_tracking_message_id('%(res_id)s-%(model)s' % values)
elif not values.get('message_id'):
else:
message_id = tools.generate_tracking_message_id('private')
return message_id
@ -833,7 +832,7 @@ class mail_message(osv.Model):
if 'email_from' not in values: # needed to compute reply_to
values['email_from'] = self._get_default_from(cr, uid, context=context)
if not values.get('message_id'):
if 'message_id' not in values:
values['message_id'] = self._get_message_id(cr, uid, values, context=context)
if 'reply_to' not in values:
values['reply_to'] = self._get_reply_to(cr, uid, values, context=context)

View File

@ -363,20 +363,27 @@ class mail_thread(osv.AbstractModel):
self.message_auto_subscribe(cr, uid, [thread_id], create_values.keys(), context=context, values=create_values)
# track values
tracked_fields = self._get_tracked_fields(cr, uid, values.keys(), context=context)
track_ctx = dict(context)
if 'lang' not in track_ctx:
track_ctx['lang'] = self.pool.get('res.users').browse(cr, uid, uid, context=context).lang
tracked_fields = self._get_tracked_fields(cr, uid, values.keys(), context=track_ctx)
if tracked_fields:
initial_values = {thread_id: dict((item, False) for item in tracked_fields)}
self.message_track(cr, uid, [thread_id], tracked_fields, initial_values, context=context)
self.message_track(cr, uid, [thread_id], tracked_fields, initial_values, context=track_ctx)
return thread_id
def write(self, cr, uid, ids, values, context=None):
if context is None:
context = {}
if isinstance(ids, (int, long)):
ids = [ids]
# Track initial values of tracked fields
tracked_fields = self._get_tracked_fields(cr, uid, values.keys(), context=context)
track_ctx = dict(context)
if 'lang' not in track_ctx:
track_ctx['lang'] = self.pool.get('res.users').browse(cr, uid, uid, context=context).lang
tracked_fields = self._get_tracked_fields(cr, uid, values.keys(), context=track_ctx)
if tracked_fields:
records = self.browse(cr, uid, ids, context=context)
records = self.browse(cr, uid, ids, context=track_ctx)
initial_values = dict((this.id, dict((key, getattr(this, key)) for key in tracked_fields.keys())) for this in records)
# Perform write, update followers
@ -385,7 +392,7 @@ class mail_thread(osv.AbstractModel):
# Perform the tracking
if tracked_fields:
self.message_track(cr, uid, ids, tracked_fields, initial_values, context=context)
self.message_track(cr, uid, ids, tracked_fields, initial_values, context=track_ctx)
return result
def unlink(self, cr, uid, ids, context=None):
@ -716,8 +723,8 @@ class mail_thread(osv.AbstractModel):
# Private message: should not contain any thread_id
if not model and thread_id:
if assert_model:
assert thread_id == 0, 'Routing: posting a message without model should be with a null res_id (private message).'
_warn('posting a message without model should be with a null res_id (private message), resetting thread_id')
assert thread_id == 0, 'Routing: posting a message without model should be with a null res_id (private message), received %s.' % thread_id
_warn('posting a message without model should be with a null res_id (private message), received %s, resetting thread_id' % thread_id)
thread_id = 0
# Private message: should have a parent_id (only answers)
if not model and not message_dict.get('parent_id'):
@ -814,6 +821,7 @@ class mail_thread(osv.AbstractModel):
:return: list of [model, thread_id, custom_values, user_id, alias]
"""
assert isinstance(message, Message), 'message must be an email.message.Message at this point'
mail_msg_obj = self.pool['mail.message']
fallback_model = model
# Get email.message.Message variables for future processing
@ -822,31 +830,54 @@ class mail_thread(osv.AbstractModel):
email_to = decode_header(message, 'To')
references = decode_header(message, 'References')
in_reply_to = decode_header(message, 'In-Reply-To')
# 1. Verify if this is a reply to an existing thread
thread_references = references or in_reply_to
# 1. message is a reply to an existing message (exact match of message_id)
msg_references = thread_references.split()
mail_message_ids = mail_msg_obj.search(cr, uid, [('message_id', 'in', msg_references)], context=context)
if mail_message_ids:
original_msg = mail_msg_obj.browse(cr, SUPERUSER_ID, mail_message_ids[0], context=context)
model, thread_id = original_msg.model, original_msg.res_id
_logger.info(
'Routing mail from %s to %s with Message-Id %s: direct reply to msg: model: %s, thread_id: %s, custom_values: %s, uid: %s',
email_from, email_to, message_id, model, thread_id, custom_values, uid)
route = self.message_route_verify(
cr, uid, message, message_dict,
(model, thread_id, custom_values, uid, None),
update_author=True, assert_model=True, create_fallback=True, context=context)
return route and [route] or []
# 2. message is a reply to an existign thread (6.1 compatibility)
ref_match = thread_references and tools.reference_re.search(thread_references)
if ref_match:
thread_id = int(ref_match.group(1))
model = ref_match.group(2) or fallback_model
if thread_id and model in self.pool:
model_obj = self.pool[model]
if model_obj.exists(cr, uid, thread_id) and hasattr(model_obj, 'message_update'):
_logger.info('Routing mail from %s to %s with Message-Id %s: direct reply to model: %s, thread_id: %s, custom_values: %s, uid: %s',
email_from, email_to, message_id, model, thread_id, custom_values, uid)
route = self.message_route_verify(cr, uid, message, message_dict,
(model, thread_id, custom_values, uid, None),
update_author=True, assert_model=True, create_fallback=True, context=context)
compat_mail_msg_ids = mail_msg_obj.search(
cr, uid, [
('message_id', '=', False),
('model', '=', model),
('res_id', '=', thread_id),
], context=context)
if compat_mail_msg_ids and model_obj.exists(cr, uid, thread_id) and hasattr(model_obj, 'message_update'):
_logger.info(
'Routing mail from %s to %s with Message-Id %s: direct thread reply (compat-mode) to model: %s, thread_id: %s, custom_values: %s, uid: %s',
email_from, email_to, message_id, model, thread_id, custom_values, uid)
route = self.message_route_verify(
cr, uid, message, message_dict,
(model, thread_id, custom_values, uid, None),
update_author=True, assert_model=True, create_fallback=True, context=context)
return route and [route] or []
# 2. Reply to a private message
if in_reply_to:
mail_message_ids = self.pool.get('mail.message').search(cr, uid, [
mail_message_ids = mail_msg_obj.search(cr, uid, [
('message_id', '=', in_reply_to),
'!', ('message_id', 'ilike', 'reply_to')
], limit=1, context=context)
if mail_message_ids:
mail_message = self.pool.get('mail.message').browse(cr, uid, mail_message_ids[0], context=context)
mail_message = mail_msg_obj.browse(cr, uid, mail_message_ids[0], context=context)
_logger.info('Routing mail from %s to %s with Message-Id %s: direct reply to a private message: %s, custom_values: %s, uid: %s',
email_from, email_to, message_id, mail_message.id, custom_values, uid)
route = self.message_route_verify(cr, uid, message, message_dict,
@ -1089,7 +1120,7 @@ class mail_thread(osv.AbstractModel):
encoding = part.get_content_charset() # None if attachment
# 1) Explicit Attachments -> attachments
if filename or part.get('content-disposition', '').strip().startswith('attachment'):
attachments.append((filename or 'attachment', part.get_payload(decode=True)))
attachments.append((decode(filename) or 'attachment', part.get_payload(decode=True)))
continue
# 2) text/plain -> <pre/>
if part.get_content_type() == 'text/plain' and (not alternative or not body):
@ -1314,6 +1345,40 @@ class mail_thread(osv.AbstractModel):
mail_message_obj.write(cr, SUPERUSER_ID, message_ids, {'author_id': partner_info['partner_id']}, context=context)
return result
def _message_preprocess_attachments(self, cr, uid, attachments, attachment_ids, attach_model, attach_res_id, context=None):
""" Preprocess attachments for mail_thread.message_post() or mail_mail.create().
:param list attachments: list of attachment tuples in the form ``(name,content)``,
where content is NOT base64 encoded
:param list attachment_ids: a list of attachment ids, not in tomany command form
:param str attach_model: the model of the attachments parent record
:param integer attach_res_id: the id of the attachments parent record
"""
Attachment = self.pool['ir.attachment']
m2m_attachment_ids = []
if attachment_ids:
filtered_attachment_ids = Attachment.search(cr, SUPERUSER_ID, [
('res_model', '=', 'mail.compose.message'),
('create_uid', '=', uid),
('id', 'in', attachment_ids)], context=context)
if filtered_attachment_ids:
Attachment.write(cr, SUPERUSER_ID, filtered_attachment_ids, {'res_model': attach_model, 'res_id': attach_res_id}, context=context)
m2m_attachment_ids += [(4, id) for id in attachment_ids]
# Handle attachments parameter, that is a dictionary of attachments
for name, content in attachments:
if isinstance(content, unicode):
content = content.encode('utf-8')
data_attach = {
'name': name,
'datas': base64.b64encode(str(content)),
'datas_fname': name,
'description': name,
'res_model': attach_model,
'res_id': attach_res_id,
}
m2m_attachment_ids.append((0, 0, data_attach))
return m2m_attachment_ids
def message_post(self, cr, uid, thread_id, body='', subject=None, type='notification',
subtype=None, parent_id=False, attachments=None, context=None,
content_subtype='html', **kwargs):
@ -1392,28 +1457,7 @@ class mail_thread(osv.AbstractModel):
# 3. Attachments
# - HACK TDE FIXME: Chatter: attachments linked to the document (not done JS-side), load the message
attachment_ids = kwargs.pop('attachment_ids', []) or [] # because we could receive None (some old code sends None)
if attachment_ids:
filtered_attachment_ids = ir_attachment.search(cr, SUPERUSER_ID, [
('res_model', '=', 'mail.compose.message'),
('create_uid', '=', uid),
('id', 'in', attachment_ids)], context=context)
if filtered_attachment_ids:
ir_attachment.write(cr, SUPERUSER_ID, filtered_attachment_ids, {'res_model': model, 'res_id': thread_id}, context=context)
attachment_ids = [(4, id) for id in attachment_ids]
# Handle attachments parameter, that is a dictionary of attachments
for name, content in attachments:
if isinstance(content, unicode):
content = content.encode('utf-8')
data_attach = {
'name': name,
'datas': base64.b64encode(str(content)),
'datas_fname': name,
'description': name,
'res_model': model,
'res_id': thread_id,
}
attachment_ids.append((0, 0, data_attach))
attachment_ids = self._message_preprocess_attachments(cr, uid, attachments, kwargs.pop('attachment_ids', []), model, thread_id, context)
# 4: mail.message.subtype
subtype_id = False

View File

@ -81,6 +81,12 @@ class res_users(osv.Model):
self._create_welcome_message(cr, uid, user, context=context)
return user_id
def copy_data(self, *args, **kwargs):
data = super(res_users, self).copy_data(*args, **kwargs)
if data.get('alias_name'):
data['alias_name'] = data['login']
return data
def _create_welcome_message(self, cr, uid, user, context=None):
if not self.has_group(cr, uid, 'base.group_user'):
return False

View File

@ -94,9 +94,7 @@
}
.openerp .oe_mail .oe_msg .oe_msg_footer{
margin-left: 4px;
padding-top: 3px;
overflow: hidden;
margin-bottom: 4px;
font-size: 11px;
}
.openerp .oe_mail .oe_msg .oe_msg_content{
@ -478,7 +476,7 @@
}
.openerp .oe_mail .oe_msg_footer button.oe_attach{
width: 24px;
overflow: hidden;
margin-bottom: 5px; /* improved margin of file attach button according bootstrap3 */
filter:none;
}
.openerp .oe_mail .oe_msg_footer button.oe_attach .oe_e{
@ -634,7 +632,7 @@
margin-bottom: 4px;
}
.openerp .oe_followers .oe_invite{
float: right;
padding-left: 5px;
}
.openerp .oe_followers .oe_partner {
height: 32px;

View File

@ -834,7 +834,9 @@ openerp.mail = function (session) {
// go to the parented message
var message = this.parent_thread.parent_message;
var parent_message = message.parent_id ? message.parent_thread.parent_message : message;
var messages = [parent_message].concat(parent_message.get_childs());
if(parent_message){
var messages = [parent_message].concat(parent_message.get_childs());
}
} else if (this.options.emails_from_on_composer) {
// get all wall messages if is not a mail.Wall
_.each(this.options.root_thread.messages, function (msg) {messages.push(msg); messages.concat(msg.get_childs());});

View File

@ -264,7 +264,7 @@ openerp_mail_followers = function(session, mail) {
var $list = this.$('.oe_subtype_list');
}
$list.empty().hide();
var records = data[this.view.datarecord.id || this.view.dataset.ids[0]].message_subtype_data;
var records = data[id].message_subtype_data;
this.records_length = $.map(records, function(value, index) { return index; }).length;
if (this.records_length > 1) { self.display_followers(); }
_(records).each(function (record, record_name) {

View File

@ -163,7 +163,7 @@ class TestMailgateway(TestMail):
self.assertIn('<div dir="ltr">Should create a multipart/mixed: from gmail, <b>bold</b>, with attachment.<br clear="all"><div><br></div>', res.get('body', ''),
'message_parse: html version should be in body after parsing multipart/mixed')
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.osv.orm')
# @mute_logger('openerp.addons.mail.mail_thread', 'openerp.osv.orm')
def test_10_message_process(self):
""" Testing incoming emails processing. """
cr, uid, user_raoul = self.cr, self.uid, self.user_raoul
@ -378,7 +378,7 @@ class TestMailgateway(TestMail):
frog_groups = format_and_process(MAIL_TEMPLATE, email_from='other4@gmail.com',
msg_id='<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>',
to='erroneous@example.com>', subject='Re: news',
extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id)
extra='In-Reply-To: <1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>\n')
# Test: no group 'Re: news' created, still only 1 Frogs group
self.assertEqual(len(frog_groups), 0,
'message_process: reply on Frogs should not have created a new group with new subject')
@ -387,16 +387,41 @@ class TestMailgateway(TestMail):
'message_process: reply on Frogs should not have created a duplicate group with old subject')
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
# Test: one new message
self.assertEqual(len(frog_group.message_ids), 3, 'message_process: group should contain 2 messages after reply')
self.assertEqual(len(frog_group.message_ids), 3, 'message_process: group should contain 3 messages after reply')
# Test: author (and not recipient) added as follower
frog_follower_ids = set([p.id for p in frog_group.message_follower_ids])
self.assertEqual(frog_follower_ids, set([p1id, p2id]),
'message_process: after reply, group should have 2 followers')
# Do: incoming email with ref holding model / res_id but that does not match any message in the thread: must raise since OpenERP saas-3
self.assertRaises(AssertionError,
format_and_process,
MAIL_TEMPLATE, email_from='other5@gmail.com',
to='noone@example.com', subject='spam',
extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>' % frog_group.id,
msg_id='<1.1.JavaMail.new@agrolait.com>')
# There are 6.1 messages, activate compat mode
tmp_msg_id = self.mail_message.create(cr, uid, {'message_id': False, 'model': 'mail.group', 'res_id': frog_group.id})
# Do: compat mode accepts partial-matching emails
frog_groups = format_and_process(MAIL_TEMPLATE, email_from='other5@gmail.com',
msg_id='<1.2.JavaMail.new@agrolait.com>',
to='noone@example.com>', subject='spam',
extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>' % frog_group.id)
self.mail_message.unlink(cr, uid, [tmp_msg_id])
# Test: no group 'Re: news' created, still only 1 Frogs group
self.assertEqual(len(frog_groups), 0,
'message_process: reply on Frogs should not have created a new group with new subject')
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
self.assertEqual(len(frog_groups), 1,
'message_process: reply on Frogs should not have created a duplicate group with old subject')
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
# Test: one new message
self.assertEqual(len(frog_group.message_ids), 4, 'message_process: group should contain 4 messages after reply')
# Do: due to some issue, same email goes back into the mailgateway
frog_groups = format_and_process(MAIL_TEMPLATE, email_from='other4@gmail.com',
msg_id='<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>',
subject='Re: news', extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id)
subject='Re: news', extra='In-Reply-To: <1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>\n')
# Test: no group 'Re: news' created, still only 1 Frogs group
self.assertEqual(len(frog_groups), 0,
'message_process: reply on Frogs should not have created a new group with new subject')
@ -405,7 +430,7 @@ class TestMailgateway(TestMail):
'message_process: reply on Frogs should not have created a duplicate group with old subject')
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
# Test: no new message
self.assertEqual(len(frog_group.message_ids), 3, 'message_process: message with already existing message_id should not have been duplicated')
self.assertEqual(len(frog_group.message_ids), 4, 'message_process: message with already existing message_id should not have been duplicated')
# Test: message_id is still unique
msg_ids = self.mail_message.search(cr, uid, [('message_id', 'ilike', '<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>')])
self.assertEqual(len(msg_ids), 1,
@ -422,7 +447,7 @@ class TestMailgateway(TestMail):
format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik <test_raoul@email.com>',
to='erroneous@example.com>', subject='Re: news (2)',
msg_id='<1198923581.41972151344608186760.JavaMail.new1@agrolait.com>',
extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id)
extra='In-Reply-To: <1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>')
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
# Test: author is A-Raoul (only existing)
@ -436,7 +461,7 @@ class TestMailgateway(TestMail):
format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik <test_raoul@email.com>',
to='erroneous@example.com>', subject='Re: news (3)',
msg_id='<1198923581.41972151344608186760.JavaMail.new2@agrolait.com>',
extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id)
extra='In-Reply-To: <1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>')
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
# Test: author is Raoul (user), not A-Raoul
@ -451,7 +476,7 @@ class TestMailgateway(TestMail):
format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik <test_raoul@email.com>',
to='erroneous@example.com>', subject='Re: news (3)',
msg_id='<1198923581.41972151344608186760.JavaMail.new3@agrolait.com>',
extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id)
extra='In-Reply-To: <1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>')
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
# Test: author is Raoul (user), not A-Raoul
@ -498,7 +523,7 @@ class TestMailgateway(TestMail):
self.assertIn('<pre>\nPlease call me as soon as possible this afternoon!\n\n--\nSylvie\n</pre>', msg.body,
'message_process: plaintext incoming email incorrectly parsed')
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.osv.orm')
# @mute_logger('openerp.addons.mail.mail_thread', 'openerp.osv.orm')
def test_20_thread_parent_resolution(self):
""" Testing parent/child relationships are correctly established when processing incoming mails """
cr, uid = self.cr, self.uid

View File

@ -19,7 +19,9 @@
#
##############################################################################
import base64
import re
from openerp import tools
from openerp import SUPERUSER_ID
from openerp.osv import osv
@ -260,6 +262,12 @@ class mail_compose_message(osv.TransientModel):
for res_id, mail_values in all_mail_values.iteritems():
if mass_mail_mode and not wizard.post:
m2m_attachment_ids = self.pool['mail.thread']._message_preprocess_attachments(
cr, uid, mail_values.pop('attachments', []),
mail_values.pop('attachment_ids', []),
'mail.message', 0,
context=context)
mail_values['attachment_ids'] = m2m_attachment_ids
self.pool.get('mail.mail').create(cr, uid, mail_values, context=context)
else:
subtype = 'mail.mt_comment'
@ -298,7 +306,12 @@ class mail_compose_message(osv.TransientModel):
if mass_mail_mode and wizard.model:
email_dict = rendered_values[res_id]
mail_values['partner_ids'] += email_dict.pop('partner_ids', [])
mail_values['attachments'] = email_dict.pop('attachments', [])
# process attachments: should not be encoded before being processed by message_post / mail_mail create
attachments = []
if email_dict.get('attachments'):
for name, enc_cont in email_dict.pop('attachments'):
attachments.append((name, base64.b64decode(enc_cont)))
mail_values['attachments'] = attachments
attachment_ids = []
for attach_id in mail_values.pop('attachment_ids'):
new_attach_id = self.pool.get('ir.attachment').copy(cr, uid, attach_id, {'res_model': self._name, 'res_id': wizard.id}, context=context)

View File

@ -2,7 +2,7 @@
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 OpenERP SA (<http://openerp.com>).
# Copyright (C) 2004-2013 OpenERP SA (<http://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
@ -32,6 +32,7 @@ import re
from openerp.addons.decimal_precision import decimal_precision as dp
from openerp.osv import fields, osv
from openerp.report import render_report
from openerp.tools.translate import _
_intervalTypes = {
@ -461,8 +462,7 @@ class marketing_campaign_activity(osv.osv):
#dead code
def _process_wi_report(self, cr, uid, activity, workitem, context=None):
service = netsvc.LocalService('report.%s'%activity.report_id.report_name)
(report_data, format) = service.create(cr, uid, [], {}, {})
report_data, format = render_report(cr, uid, [], activity.report_id.report_name, {}, context=context)
attach_vals = {
'name': '%s_%s_%s'%(activity.report_id.report_name,
activity.name,workitem.partner_id.name),

View File

@ -41,49 +41,41 @@
<field name="message_id">1111000@OpenERP.com</field>
<field name="opened" eval="(DateTime.today() - relativedelta(days=2)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="replied" eval="(DateTime.today() - relativedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="state">sent</field>
</record>
<record id="mass_mail_email_2" model="mail.mail.statistics">
<field name="mass_mailing_id" eval="ref('mass_mail_1')"/>
<field name="message_id">1111001@OpenERP.com</field>
<field name="opened" eval="(DateTime.today() - relativedelta(days=2)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="replied" eval="(DateTime.today() - relativedelta(days=0)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="state">sent</field>
</record>
<record id="mass_mail_email_3" model="mail.mail.statistics">
<field name="mass_mailing_id" eval="ref('mass_mail_1')"/>
<field name="message_id">1111002@OpenERP.com</field>
<field name="opened" eval="(DateTime.today() - relativedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="state">sent</field>
</record>
<record id="mass_mail_email_4" model="mail.mail.statistics">
<field name="mass_mailing_id" eval="ref('mass_mail_1')"/>
<field name="message_id">1111003@OpenERP.com</field>
<field name="state">sent</field>
</record>
<record id="mass_mail_email_5" model="mail.mail.statistics">
<field name="mass_mailing_id" eval="ref('mass_mail_1')"/>
<field name="message_id">1111004@OpenERP.com</field>
<field name="bounced" eval="(DateTime.today() - relativedelta(days=3)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="state">sent</field>
</record>
<record id="mass_mail_email_2_1" model="mail.mail.statistics">
<field name="mass_mailing_id" eval="ref('mass_mail_2')"/>
<field name="message_id">1111005@OpenERP.com</field>
<field name="opened" eval="(DateTime.today() - relativedelta(days=3)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="state">sent</field>
</record>
<record id="mass_mail_email_2_2" model="mail.mail.statistics">
<field name="mass_mailing_id" eval="ref('mass_mail_2')"/>
<field name="message_id">1111006@OpenERP.com</field>
<field name="opened" eval="(DateTime.today() - relativedelta(days=2)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="state">sent</field>
</record>
<record id="mass_mail_email_2_3" model="mail.mail.statistics">
<field name="mass_mailing_id" eval="ref('mass_mail_2')"/>
<field name="message_id">1111007@OpenERP.com</field>
<field name="state">sent</field>
</record>
</data>

View File

@ -1,13 +1,19 @@
.openerp .oe_kanban_view .oe_kanban_mass_mailing.oe_kanban_mass_mailing_campaign {
width: 540px;
/* Customize to manage content */
width: 552px;
min-height: 278px !important;
/* End of customize */
}
.openerp .oe_kanban_view .oe_kanban_mass_mailing.oe_kanban_mass_mailing_segment {
width: 270px;
/* Customize to manage content */
width: 282px;
min-height: 246px !important;
/* End of customize */
}
.openerp .oe_kanban_view .oe_kanban_mass_mailing .oe_mail_stats {
width: 120px;
width: 122px; /* Manage space in between stats */
display: inline-block;
margin: 2px 5px 0px 5px;
text-align: center;

View File

@ -110,8 +110,16 @@
I print a Barcode Report of Operation line.
-
!python {model: mrp_operations.operation.code}: |
from openerp import netsvc, tools
(data, format) = netsvc.LocalService('report.mrp.code.barcode').create(cr, uid, [ref('mrp_operations.mrp_op_1'),ref('mrp_operations.mrp_op_2'),ref('mrp_operations.mrp_op_3'),ref('mrp_operations.mrp_op_4'),ref('mrp_operations.mrp_op_5')], {}, {})
from openerp import tools
from openerp.report import render_report
ids = [
ref('mrp_operations.mrp_op_1'),
ref('mrp_operations.mrp_op_2'),
ref('mrp_operations.mrp_op_3'),
ref('mrp_operations.mrp_op_4'),
ref('mrp_operations.mrp_op_5')
]
data, format = render_report(cr, uid, ids, 'mrp.code.barcode', {})
if tools.config['test_report_directory']:
file(os.path.join(tools.config['test_report_directory'], 'mrp_operations-barcode_report.'+format), 'wb+').write(data)
@ -119,7 +127,9 @@
I print Workcenter's Barcode Report.
-
!python {model: mrp.workcenter}: |
from openerp import netsvc, tools
(data, format) = netsvc.LocalService('report.mrp.wc.barcode').create(cr, uid, [ref('mrp.mrp_workcenter_0'),ref('mrp.mrp_workcenter_1')], {}, {})
from openerp import tools
from openerp.report import render_report
ids = [ref('mrp.mrp_workcenter_0'), ref('mrp.mrp_workcenter_1')]
data, format = render_report(cr, uid, ids, 'mrp.wc.barcode', {})
if tools.config['test_report_directory']:
file(os.path.join(tools.config['test_report_directory'], 'mrp_operations-workcenter_barcode_report.'+format), 'wb+').write(data)

View File

@ -147,6 +147,7 @@ class note_note(osv.osv):
if result and result[0]['stage_id'][0] == current_stage_ids[0]:
dom_in = result[0]['__domain'].pop()
result[0]['__domain'] = domain + ['|', dom_in, dom_not_in]
result[0]['stage_id_count'] += nb_notes_ws
else:
# add the first stage column
result = [{

View File

@ -0,0 +1,28 @@
# Arabic translation for openobject-addons
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
#
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: 2013-11-26 19:11+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Arabic <ar@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: 2013-11-27 04:37+0000\n"
"X-Generator: Launchpad (build 16845)\n"
#. module: note_pad
#: model:ir.model,name:note_pad.model_note_note
msgid "Note"
msgstr "ملاحظة"
#. module: note_pad
#: field:note.note,note_pad_url:0
msgid "Pad Url"
msgstr ""

View File

@ -92,6 +92,7 @@
font-family: arial, sans-serif;
font-size: 15px;
line-height: 19px;
word-wrap: break-word;
}
.openerp .oe_form_nomargin .etherpad_readonly{

View File

@ -747,7 +747,6 @@ class pos_order(osv.osv):
@return: True
"""
stock_picking_obj = self.pool.get('stock.picking')
wf_service = netsvc.LocalService("workflow")
for order in self.browse(cr, uid, ids, context=context):
stock_picking_obj.signal_button_cancel(cr, uid, [order.picking_id.id])
if stock_picking_obj.browse(cr, uid, order.picking_id.id, context=context).state <> 'cancel':

View File

@ -126,6 +126,7 @@
background: #393939;
background: -moz-linear-gradient(#7b7979, #393939);
background: -webkit-gradient(linear, left top, left bottom, from(#7b7979), to(#393939));
z-index: 2; /* Customize according bootstrap3 navbar */
}
/* a) The left part of the top-bar */
@ -659,6 +660,7 @@
.point-of-sale .screen header h2 {
margin-top: 0px;
padding-top: 7px;
font-size: 1.5em /* Customize font according bootstrap3 */
}
.point-of-sale .screen p{
font-size: 18px;

View File

@ -10,7 +10,7 @@
<field name="customer" eval="True"/>
<field name="notification_email_send">none</field>
</record>
<record id="demo_user0" model="res.users">
<record id="demo_user0" model="res.users" context="{'no_reset_password': True}">
<field name="partner_id" ref="partner_demo_portal"/>
<field name="login">portal</field>
<field name="password">portal</field>

View File

@ -10,7 +10,7 @@
margin: -40px 0 -32px -24px;
position: relative;
padding: 10px 15px;
right: -153px;
right: -125px; /* improved margin according bootstrap3 */
background: #729FCF;
background-image: -webkit-gradient(linear, left top, left bottom, from(#729FCF), to(#3465A4));

View File

@ -0,0 +1,25 @@
# Arabic translation for openobject-addons
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
#
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: 2013-11-26 18:39+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Arabic <ar@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: 2013-11-27 04:37+0000\n"
"X-Generator: Launchpad (build 16845)\n"
#. module: portal_anonymous
#. openerp-web
#: code:addons/portal_anonymous/static/src/xml/portal_anonymous.xml:8
#, python-format
msgid "Login"
msgstr "تسجيل الدخول"

View File

@ -0,0 +1,25 @@
# Finnish translation for openobject-addons
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
#
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: 2013-12-01 22:23+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\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: 2013-12-02 05:23+0000\n"
"X-Generator: Launchpad (build 16856)\n"
#. module: portal_anonymous
#. openerp-web
#: code:addons/portal_anonymous/static/src/xml/portal_anonymous.xml:8
#, python-format
msgid "Login"
msgstr "Kirjautuminen"

View File

@ -71,7 +71,7 @@ openerp.portal_anonymous = function(instance) {
this.$el.find('a.login').click(function() {
var p = self.getParent();
var am = p.action_manager;
p.$el.find('.oe_leftbar, .oe_topbar').hide();
p.$el.find('.oe_leftbar, .navbar').hide(); // .oe_topbar is replaced with .navbar of bootstrap3
self.session.session_logout().done(function () {
am.do_action({
type:'ir.actions.client',

View File

@ -0,0 +1,43 @@
# Arabic translation for openobject-addons
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
#
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: 2013-11-26 19:12+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Arabic <ar@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: 2013-11-27 04:37+0000\n"
"X-Generator: Launchpad (build 16845)\n"
#. module: portal_claim
#: model:ir.actions.act_window,help:portal_claim.crm_case_categ_claim0
msgid ""
"<p class=\"oe_view_nocontent_create\">\n"
" Click to register a new claim. \n"
" </p><p>\n"
" You can track your claims from this menu and the action we\n"
" will take.\n"
" </p>\n"
" "
msgstr ""
"<p class=\"oe_view_nocontent_create\">\n"
" اضغط هنا للتسجيل مطالبة جديدة. \n"
" </p><p>\n"
" يمكنك تتبع المطالبات الخاصة بك من هذه القائمة و الإجراءات\n"
" التي سنتخذها.\n"
" </p>\n"
" "
#. module: portal_claim
#: model:ir.actions.act_window,name:portal_claim.crm_case_categ_claim0
#: model:ir.ui.menu,name:portal_claim.portal_after_sales_claims
msgid "Claims"
msgstr "مطالبات"

View File

@ -0,0 +1,36 @@
# Finnish translation for openobject-addons
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
#
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: 2013-12-01 22:24+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\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: 2013-12-02 05:23+0000\n"
"X-Generator: Launchpad (build 16856)\n"
#. module: portal_claim
#: model:ir.actions.act_window,help:portal_claim.crm_case_categ_claim0
msgid ""
"<p class=\"oe_view_nocontent_create\">\n"
" Click to register a new claim. \n"
" </p><p>\n"
" You can track your claims from this menu and the action we\n"
" will take.\n"
" </p>\n"
" "
msgstr ""
#. module: portal_claim
#: model:ir.actions.act_window,name:portal_claim.crm_case_categ_claim0
#: model:ir.ui.menu,name:portal_claim.portal_after_sales_claims
msgid "Claims"
msgstr "Reklamaatiot"

View File

@ -0,0 +1,548 @@
# Finnish translation for openobject-addons
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
#
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: 2013-12-01 22:26+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\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: 2013-12-02 05:23+0000\n"
"X-Generator: Launchpad (build 16856)\n"
#. module: portal_crm
#: selection:portal_crm.crm_contact_us,type:0
msgid "Lead"
msgstr "Liidi"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,title:0
msgid "Title"
msgstr "Titteli"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,probability:0
msgid "Success Rate (%)"
msgstr "Onnistumistodennäköisyys (%)"
#. module: portal_crm
#: view:portal_crm.crm_contact_us:0
msgid "Contact us"
msgstr "Ota yhteyttä"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,date_action:0
msgid "Next Action Date"
msgstr "Seuraava toimenpidepäivä"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,fax:0
msgid "Fax"
msgstr "Faksi"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,zip:0
msgid "Zip"
msgstr "Postinumero"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,message_unread:0
msgid "Unread Messages"
msgstr "Lukemattomia viestejä"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,company_id:0
msgid "Company"
msgstr "Yritys"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,day_open:0
msgid "Days to Open"
msgstr ""
#. module: portal_crm
#: view:portal_crm.crm_contact_us:0
msgid "Thank you for your interest, we'll respond to your request shortly."
msgstr ""
#. module: portal_crm
#: selection:portal_crm.crm_contact_us,priority:0
msgid "Highest"
msgstr "Korkein"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,mobile:0
msgid "Mobile"
msgstr "Matkapuhelin"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,description:0
msgid "Notes"
msgstr "Muistiinpanot"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,message_ids:0
msgid "Messages"
msgstr "Viestit"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,color:0
msgid "Color Index"
msgstr "Väri-indeksi"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,partner_latitude:0
msgid "Geo Latitude"
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,partner_name:0
msgid "Customer Name"
msgstr "Asiakkaan nimi"
#. module: portal_crm
#: selection:portal_crm.crm_contact_us,state:0
msgid "Cancelled"
msgstr "Peruttu"
#. module: portal_crm
#: help:portal_crm.crm_contact_us,message_unread:0
msgid "If checked new messages require your attention."
msgstr "Jos valittu, uudet viestit vaativat huomiosi."
#. module: portal_crm
#: help:portal_crm.crm_contact_us,channel_id:0
msgid "Communication channel (mail, direct, phone, ...)"
msgstr "Kommunikointikanava (sähköposti, suora, puhelin,...)"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,type_id:0
msgid "Campaign"
msgstr "Kampanja"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,ref:0
msgid "Reference"
msgstr "Viite"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,date_action_next:0
#: field:portal_crm.crm_contact_us,title_action:0
msgid "Next Action"
msgstr "Seuraava toimenpide"
#. module: portal_crm
#: help:portal_crm.crm_contact_us,message_summary:0
msgid ""
"Holds the Chatter summary (number of messages, ...). This summary is "
"directly in html format in order to be inserted in kanban views."
msgstr ""
"Sisältää viestien yhteenvedon (viestien määrän,...). Tämä yhteenveto on "
"valmiiksi html-muodossa, jotta se voidaan viedä kanban näkymään."
#. module: portal_crm
#: field:portal_crm.crm_contact_us,partner_id:0
msgid "Partner"
msgstr "Kumppani"
#. module: portal_crm
#: model:ir.actions.act_window,name:portal_crm.action_contact_us
msgid "Contact Us"
msgstr "Ota yhteyttä"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,name:0
msgid "Subject"
msgstr "Aihe"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,opt_out:0
msgid "Opt-Out"
msgstr "Jätä pois"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,priority:0
msgid "Priority"
msgstr "Tärkeys"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,state_id:0
msgid "State"
msgstr "Valtio"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,message_follower_ids:0
msgid "Followers"
msgstr "Seuraajat"
#. module: portal_crm
#: help:portal_crm.crm_contact_us,partner_id:0
msgid "Linked partner (optional). Usually created when converting the lead."
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,payment_mode:0
msgid "Payment Mode"
msgstr "Maksutapa"
#. module: portal_crm
#: selection:portal_crm.crm_contact_us,state:0
msgid "New"
msgstr "Uusi"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,type:0
msgid "Type"
msgstr "Tyyppi"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,email_from:0
msgid "Email"
msgstr "Sähköposti"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,channel_id:0
msgid "Channel"
msgstr "Kanava"
#. module: portal_crm
#: view:portal_crm.crm_contact_us:0
msgid "Name"
msgstr ""
#. module: portal_crm
#: selection:portal_crm.crm_contact_us,priority:0
msgid "Lowest"
msgstr "Alin"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,create_date:0
msgid "Creation Date"
msgstr "Luontipäivä"
#. module: portal_crm
#: view:portal_crm.crm_contact_us:0
msgid "Close"
msgstr ""
#. module: portal_crm
#: selection:portal_crm.crm_contact_us,state:0
msgid "Pending"
msgstr ""
#. module: portal_crm
#: help:portal_crm.crm_contact_us,type:0
msgid "Type is used to separate Leads and Opportunities"
msgstr "Tyyppiä käytetään erottamaan liidit ja mahdollisuudet toisistaan"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,categ_ids:0
msgid "Categories"
msgstr "Kategoriat"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,stage_id:0
msgid "Stage"
msgstr "Vaihe"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,user_login:0
msgid "User Login"
msgstr "Käyttäjätunnus"
#. module: portal_crm
#: help:portal_crm.crm_contact_us,opt_out:0
msgid ""
"If opt-out is checked, this contact has refused to receive emails or "
"unsubscribed to a campaign."
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,contact_name:0
msgid "Contact Name"
msgstr "Yhteystiedon nimi"
#. module: portal_crm
#: model:ir.ui.menu,name:portal_crm.portal_company_contact
msgid "Contact"
msgstr "Kontakti"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,partner_address_email:0
msgid "Partner Contact Email"
msgstr "Kumppanin yhteystieto, sähköposti"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,planned_revenue:0
msgid "Expected Revenue"
msgstr "Odotetut tulot"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,task_ids:0
msgid "Tasks"
msgstr "Tehtävät"
#. module: portal_crm
#: view:portal_crm.crm_contact_us:0
msgid "Contact form"
msgstr "Yhteydenottolomake"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,company_currency:0
msgid "Currency"
msgstr "Valuutta"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,write_date:0
msgid "Update Date"
msgstr "Päivityksen ajankohta"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,date_deadline:0
msgid "Expected Closing"
msgstr "Odotettu päätös"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,ref2:0
msgid "Reference 2"
msgstr "Viittaus 2"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,user_email:0
msgid "User Email"
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,date_open:0
msgid "Opened"
msgstr "Avattu"
#. module: portal_crm
#: selection:portal_crm.crm_contact_us,state:0
msgid "In Progress"
msgstr "Kesken"
#. module: portal_crm
#: help:portal_crm.crm_contact_us,partner_name:0
msgid ""
"The name of the future partner company that will be created while converting "
"the lead into opportunity"
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,planned_cost:0
msgid "Planned Costs"
msgstr ""
#. module: portal_crm
#: help:portal_crm.crm_contact_us,date_deadline:0
msgid "Estimate of the date on which the opportunity will be won."
msgstr ""
#. module: portal_crm
#: help:portal_crm.crm_contact_us,email_cc:0
msgid ""
"These email addresses will be added to the CC field of all inbound and "
"outbound emails for this record before being sent. Separate multiple email "
"addresses with a comma"
msgstr ""
#. module: portal_crm
#: selection:portal_crm.crm_contact_us,priority:0
msgid "Low"
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,date_closed:0
#: selection:portal_crm.crm_contact_us,state:0
msgid "Closed"
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,date_assign:0
msgid "Assignation Date"
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,state:0
msgid "Status"
msgstr ""
#. module: portal_crm
#: selection:portal_crm.crm_contact_us,priority:0
msgid "Normal"
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,email_cc:0
msgid "Global CC"
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,street2:0
msgid "Street2"
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,id:0
msgid "ID"
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,phone:0
msgid "Phone"
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,message_is_follower:0
msgid "Is a Follower"
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,active:0
msgid "Active"
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,user_id:0
msgid "Salesperson"
msgstr "Myyjä"
#. module: portal_crm
#: field:portal_crm.crm_contact_us,day_close:0
msgid "Days to Close"
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,company_ids:0
msgid "Companies"
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,message_summary:0
msgid "Summary"
msgstr ""
#. module: portal_crm
#: help:portal_crm.crm_contact_us,section_id:0
msgid ""
"When sending mails, the default email address is taken from the sales team."
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,partner_address_name:0
msgid "Partner Contact Name"
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,partner_longitude:0
msgid "Geo Longitude"
msgstr ""
#. module: portal_crm
#: help:portal_crm.crm_contact_us,date_assign:0
msgid "Last date this case was forwarded/assigned to a partner"
msgstr ""
#. module: portal_crm
#: help:portal_crm.crm_contact_us,email_from:0
msgid "Email address of the contact"
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,city:0
msgid "City"
msgstr ""
#. module: portal_crm
#: view:portal_crm.crm_contact_us:0
msgid "Submit"
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,function:0
msgid "Function"
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,referred:0
msgid "Referred By"
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,partner_assigned_id:0
msgid "Assigned Partner"
msgstr ""
#. module: portal_crm
#: selection:portal_crm.crm_contact_us,type:0
msgid "Opportunity"
msgstr ""
#. module: portal_crm
#: help:portal_crm.crm_contact_us,partner_assigned_id:0
msgid "Partner this case has been forwarded/assigned to."
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,country_id:0
msgid "Country"
msgstr ""
#. module: portal_crm
#: view:portal_crm.crm_contact_us:0
msgid "Thank you"
msgstr ""
#. module: portal_crm
#: help:portal_crm.crm_contact_us,state:0
msgid ""
"The Status is set to 'Draft', when a case is created. If the case is in "
"progress the Status is set to 'Open'. When the case is over, the Status is "
"set to 'Done'. If the case needs to be reviewed then the Status is set to "
"'Pending'."
msgstr ""
#. module: portal_crm
#: help:portal_crm.crm_contact_us,message_ids:0
msgid "Messages and communication history"
msgstr ""
#. module: portal_crm
#: help:portal_crm.crm_contact_us,type_id:0
msgid ""
"From which campaign (seminar, marketing campaign, mass mailing, ...) did "
"this contact come from?"
msgstr ""
#. module: portal_crm
#: selection:portal_crm.crm_contact_us,priority:0
msgid "High"
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,section_id:0
msgid "Sales Team"
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,street:0
msgid "Street"
msgstr ""
#. module: portal_crm
#: field:portal_crm.crm_contact_us,date_action_last:0
msgid "Last Action"
msgstr ""
#. module: portal_crm
#: model:ir.model,name:portal_crm.model_portal_crm_crm_contact_us
msgid "Contact form for the portal"
msgstr ""

View File

@ -0,0 +1,37 @@
# Arabic translation for openobject-addons
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
#
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: 2013-11-26 22:05+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Arabic <ar@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: 2013-11-27 04:37+0000\n"
"X-Generator: Launchpad (build 16845)\n"
#. module: portal_project
#: model:ir.actions.act_window,help:portal_project.open_view_project
msgid ""
"<p class=\"oe_view_nocontent_create\">\n"
" Click to start a new project.\n"
" </p>\n"
" "
msgstr ""
"<p class=\"oe_view_nocontent_create\">\n"
" انقر لبدء مشروع جديد.\n"
" </p>\n"
" "
#. module: portal_project
#: model:ir.actions.act_window,name:portal_project.open_view_project
#: model:ir.ui.menu,name:portal_project.portal_services_projects
msgid "Projects"
msgstr "المشروعات"

View File

@ -0,0 +1,47 @@
# Arabic translation for openobject-addons
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
#
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: 2013-11-26 22:10+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Arabic <ar@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: 2013-11-27 04:37+0000\n"
"X-Generator: Launchpad (build 16845)\n"
#. module: portal_project_issue
#: view:project.issue:0
msgid "Creation:"
msgstr "إنشاء:"
#. module: portal_project_issue
#: model:ir.actions.act_window,help:portal_project_issue.project_issue_categ_act0
msgid ""
"<p class=\"oe_view_nocontent_create\">\n"
" Click to create an issue.\n"
" </p><p>\n"
" You can track your issues from this menu and the action we\n"
" will take.\n"
" </p>\n"
" "
msgstr ""
"<p class=\"oe_view_nocontent_create\">\n"
" انقر لإنشاء مسأله.\n"
" </p><p>\n"
" يمكنك تتبع المسائل الخاصة بك من هذه القائمة و الإجراءات\n"
" المتخذة.\n"
" </p>\n"
" "
#. module: portal_project_issue
#: model:ir.actions.act_window,name:portal_project_issue.project_issue_categ_act0
msgid "Issues"
msgstr "الحالات"

View File

@ -13,6 +13,7 @@
<field name="auto_delete" eval="True"/>
<field name="report_template" ref="sale.report_sale_order"/>
<field name="report_name">${(object.name or '').replace('/','_')}_${object.state == 'draft' and 'draft' or ''}</field>
<field name="lang">${object.partner_id.lang}</field>
<field name="body_html"><![CDATA[
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: rgb(255, 255, 255); ">
@ -102,6 +103,7 @@
<field name="auto_delete" eval="True"/>
<field name="report_template" ref="account.account_invoices"/>
<field name="report_name">Invoice_${(object.number or '').replace('/','_')}_${object.state == 'draft' and 'draft' or ''}</field>
<field name="lang">${object.partner_id.lang}</field>
<field name="body_html"><![CDATA[
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: rgb(255, 255, 255); ">

View File

@ -24,7 +24,7 @@ import time
from openerp.osv import fields, osv
from openerp.tools.translate import _
from openerp import netsvc
from openerp import workflow
import openerp.addons.decimal_precision as dp
# Procurement
@ -441,9 +441,8 @@ class procurement_order(osv.osv):
if len(to_assign):
move_obj.write(cr, uid, to_assign, {'state': 'assigned'})
self.write(cr, uid, ids, {'state': 'cancel'})
wf_service = netsvc.LocalService("workflow")
for id in ids:
wf_service.trg_trigger(uid, 'procurement.order', id, cr)
workflow.trg_trigger(uid, 'procurement.order', id, cr)
return True
def action_check_finished(self, cr, uid, ids):
@ -477,9 +476,8 @@ class procurement_order(osv.osv):
if procurement.close_move and (procurement.move_id.state <> 'done'):
move_obj.action_done(cr, uid, [procurement.move_id.id])
res = self.write(cr, uid, ids, {'state': 'done', 'date_close': time.strftime('%Y-%m-%d')})
wf_service = netsvc.LocalService("workflow")
for id in ids:
wf_service.trg_trigger(uid, 'procurement.order', id, cr)
workflow.trg_trigger(uid, 'procurement.order', id, cr)
return res
class StockPicking(osv.osv):

View File

@ -173,7 +173,6 @@ class procurement_order(osv.osv):
'company_id': orderpoint.company_id.id,
'product_uom': orderpoint.product_uom.id,
'location_id': orderpoint.location_id.id,
'warehouse_id': orderpoint.warehouse_id.id,
'procure_method': 'make_to_order',
'origin': orderpoint.name}

2475
addons/product/i18n/am.po Normal file

File diff suppressed because it is too large Load Diff

View File

@ -63,14 +63,12 @@
<field name="name">Done</field>
<field name="case_default" eval="True"/>
<field name="fold" eval="True"/>
<field name="closed" eval="True"/>
</record>
<record id="project_tt_cancel" model="project.task.type">
<field name="sequence">30</field>
<field name="name">Cancelled</field>
<field name="case_default" eval="True"/>
<field name="fold" eval="True"/>
<field name="closed" eval="True"/>
</record>
</data>

View File

@ -260,9 +260,7 @@
</div>
<div class="oe_kanban_project_list">
<a t-if="record.use_tasks.raw_value" name="%(act_project_project_2_project_task_all)d" type="action" style="margin-right: 10px">
<t t-raw="record.task_ids.raw_value.length"/>
<span t-if="record.task_ids.raw_value.length == 1">Task</span>
<span t-if="record.task_ids.raw_value.length > 1">Tasks</span>
<t t-raw="record.task_ids.raw_value.length"/> Tasks
</a>
</div>
<div class="oe_kanban_project_list">
@ -370,7 +368,8 @@
<field name="arch" type="xml">
<form string="Project" version="7.0">
<header>
<field name="stage_id" widget="statusbar" clickable="True"/>
<field name="stage_id" widget="statusbar" clickable="True"
options="{'fold_field': 'fold'}"/>
</header>
<sheet string="Task">
<h1>

View File

@ -48,7 +48,8 @@
<field name="arch" type="xml">
<form string="Issue" version="7.0">
<header>
<field name="stage_id" widget="statusbar" clickable="True"/>
<field name="stage_id" widget="statusbar" clickable="True"
options="{'fold_field': 'fold'}"/>
</header>
<sheet string="Issue">
<label for="name" class="oe_edit_only"/>

View File

@ -20,7 +20,7 @@
##############################################################################
from openerp.osv import fields, osv
from openerp import netsvc
from openerp import workflow
class ProjectTaskStageMrp(osv.Model):
@ -48,10 +48,9 @@ class project_task(osv.osv):
}
def _validate_subflows(self, cr, uid, ids, context=None):
wf_service = netsvc.LocalService("workflow")
for task in self.browse(cr, uid, ids):
if task.procurement_id:
wf_service.trg_write(uid, 'procurement.order', task.procurement_id.id, cr)
workflow.trg_write(uid, 'procurement.order', task.procurement_id.id, cr)
def write(self, cr, uid, ids, values, context=None):
""" When closing tasks, validate subflows. """

View File

@ -478,7 +478,7 @@ class purchase_order(osv.osv):
if not acc_id:
raise osv.except_osv(_('Error!'), _('Define expense account for this company: "%s" (id:%d).') % (po_line.product_id.name, po_line.product_id.id,))
else:
acc_id = property_obj.get(cr, uid, 'property_account_expense_categ', 'product.category').id
acc_id = property_obj.get(cr, uid, 'property_account_expense_categ', 'product.category', context=context).id
fpos = po_line.order_id.fiscal_position or False
return fiscal_obj.map_account(cr, uid, fpos, acc_id)
@ -518,15 +518,23 @@ class purchase_order(osv.osv):
:return: ID of created invoice.
:rtype: int
"""
res = False
if context is None:
context = {}
journal_obj = self.pool.get('account.journal')
inv_obj = self.pool.get('account.invoice')
inv_line_obj = self.pool.get('account.invoice.line')
res = False
uid_company_id = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id
for order in self.browse(cr, uid, ids, context=context):
context.pop('force_company', None)
if order.company_id.id != uid_company_id:
#if the company of the document is different than the current user company, force the company in the context
#then re-do a browse to read the property fields for the good company.
context['force_company'] = order.company_id.id
order = self.browse(cr, uid, order.id, context=context)
pay_acc_id = order.partner_id.property_account_payable.id
journal_ids = journal_obj.search(cr, uid, [('type', '=','purchase'),('company_id', '=', order.company_id.id)], limit=1)
journal_ids = journal_obj.search(cr, uid, [('type', '=', 'purchase'), ('company_id', '=', order.company_id.id)], limit=1)
if not journal_ids:
raise osv.except_osv(_('Error!'),
_('Define purchase journal for this company: "%s" (id:%d).') % (order.company_id.name, order.company_id.id))
@ -539,7 +547,7 @@ class purchase_order(osv.osv):
inv_line_id = inv_line_obj.create(cr, uid, inv_line_data, context=context)
inv_lines.append(inv_line_id)
po_line.write({'invoiced':True, 'invoice_lines': [(4, inv_line_id)]}, context=context)
po_line.write({'invoiced': True, 'invoice_lines': [(4, inv_line_id)]}, context=context)
# get invoice data and create invoice
inv_data = {
@ -720,6 +728,7 @@ class purchase_order(osv.osv):
'invoiced':False,
'invoice_ids': [],
'picking_ids': [],
'partner_ref': '',
'name': self.pool.get('ir.sequence').get(cr, uid, 'purchase.order'),
})
return super(purchase_order, self).copy(cr, uid, id, default, context)
@ -851,6 +860,14 @@ class purchase_order_line(osv.osv):
res[line.id] = cur_obj.round(cr, uid, cur, taxes['total'])
return res
def _get_uom_id(self, cr, uid, context=None):
try:
proxy = self.pool.get('ir.model.data')
result = proxy.get_object_reference(cr, uid, 'product', 'product_uom_unit')
return result[1]
except Exception, ex:
return False
_columns = {
'name': fields.text('Description', required=True),
'product_qty': fields.float('Quantity', digits_compute=dp.get_precision('Product Unit of Measure'), required=True),
@ -877,6 +894,7 @@ class purchase_order_line(osv.osv):
}
_defaults = {
'product_uom' : _get_uom_id,
'product_qty': lambda *a: 1.0,
'state': lambda *args: 'draft',
'invoiced': lambda *a: 0,
@ -1114,6 +1132,35 @@ class procurement_order(osv.osv):
seller_delay = int(procurement.product_id.seller_delay)
return schedule_date - relativedelta(days=seller_delay)
def _get_warehouse(self, procurement, user_company):
"""
Return the warehouse containing the procurment stock location (or one of it ancestors)
If none match, returns then first warehouse of the company
"""
# TODO refactor the domain once we implement the "parent_of" domain operator
# NOTE This method has been copied in the `purchase_requisition` module to ensure
# retro-compatibility. This code duplication will be deleted in next stable version.
# Do not forget to update both version in case of modification.
company_id = (procurement.company_id or user_company).id
domains = [
[
'&', ('company_id', '=', company_id),
'|', '&', ('lot_stock_id.parent_left', '<', procurement.location_id.parent_left),
('lot_stock_id.parent_right', '>', procurement.location_id.parent_right),
('lot_stock_id', '=', procurement.location_id.id)
],
[('company_id', '=', company_id)]
]
cr, uid = procurement._cr, procurement._uid
context = procurement._context
Warehouse = self.pool['stock.warehouse']
for domain in domains:
ids = Warehouse.search(cr, uid, domain, context=context)
if ids:
return ids[0]
return False
def make_po(self, cr, uid, ids, context=None):
""" Make purchase order from procurement
@return: New created Purchase Orders procurement wise
@ -1128,7 +1175,6 @@ class procurement_order(osv.osv):
prod_obj = self.pool.get('product.product')
acc_pos_obj = self.pool.get('account.fiscal.position')
seq_obj = self.pool.get('ir.sequence')
warehouse_obj = self.pool.get('stock.warehouse')
for procurement in self.browse(cr, uid, ids, context=context):
res_id = procurement.move_id.id
partner = procurement.product_id.seller_id # Taken Main Supplier of Product of Procurement.
@ -1136,7 +1182,6 @@ class procurement_order(osv.osv):
partner_id = partner.id
address_id = partner_obj.address_get(cr, uid, [partner_id], ['delivery'])['delivery']
pricelist_id = partner.property_product_pricelist_purchase.id
warehouse_id = warehouse_obj.search(cr, uid, [('company_id', '=', procurement.company_id.id or company.id)], context=context)
uom_id = procurement.product_id.uom_po_id.id
qty = uom_obj._compute_qty(cr, uid, procurement.product_uom.id, procurement.product_qty, uom_id)
@ -1175,7 +1220,7 @@ class procurement_order(osv.osv):
'origin': procurement.origin,
'partner_id': partner_id,
'location_id': procurement.location_id.id,
'warehouse_id': warehouse_id and warehouse_id[0] or False,
'warehouse_id': self._get_warehouse(procurement, company),
'pricelist_id': pricelist_id,
'date_order': purchase_date.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
'company_id': procurement.company_id.id,
@ -1253,8 +1298,8 @@ class account_invoice(osv.Model):
else:
user_id = uid
po_ids = purchase_order_obj.search(cr, user_id, [('invoice_ids', 'in', ids)], context=context)
if po_ids:
purchase_order_obj.message_post(cr, user_id, po_ids, body=_("Invoice paid"), context=context)
for po_id in po_ids:
purchase_order_obj.message_post(cr, user_id, po_id, body=_("Invoice paid"), context=context)
return res
class account_invoice_line(osv.Model):

View File

@ -199,7 +199,7 @@
</group>
<group>
<field name="date_order"/>
<field name="origin" attr="{'invisible': [('origin','=',False)]}"/>
<field name="origin" attrs="{'invisible': [('origin','=',False)]}"/>
<field name="warehouse_id" on_change="onchange_warehouse_id(warehouse_id)" widget="selection" groups="stock.group_locations"/>
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
</group>

View File

@ -13,7 +13,9 @@
-
!python {model: purchase.order}: |
import os
from openerp import netsvc, tools
(data, format) = netsvc.LocalService('report.purchase.order').create(cr, uid, [ref('purchase.purchase_order_1'),ref('purchase.purchase_order_2')], {}, {})
from openerp import tools
from openerp.report import render_report
ids = [ref('purchase.purchase_order_1'), ref('purchase.purchase_order_2')]
data, format = render_report(cr, uid, ids, 'purchase.order', {})
if tools.config['test_report_directory']:
file(os.path.join(tools.config['test_report_directory'], 'purchase-purchase_order_report'+format), 'wb+').write(data)

View File

@ -228,34 +228,69 @@ class product_product(osv.osv):
class procurement_order(osv.osv):
_inherit = 'procurement.order'
_columns = {
'requisition_id' : fields.many2one('purchase.requisition','Latest Requisition')
'requisition_id': fields.many2one('purchase.requisition', 'Latest Requisition')
}
def _get_warehouse(self, procurement, user_company):
"""
Return the warehouse containing the procurment stock location (or one of it ancestors)
If none match, returns then first warehouse of the company
"""
# NOTE This method is a copy of the one on the procurement.order defined in purchase
# module. It's been copied to ensure it been always available, even if module
# purchase is not up to date.
# Do not forget to update both version in case of modification.
company_id = (procurement.company_id or user_company).id
domains = [
[
'&', ('company_id', '=', company_id),
'|', '&', ('lot_stock_id.parent_left', '<', procurement.location_id.parent_left),
('lot_stock_id.parent_right', '>', procurement.location_id.parent_right),
('lot_stock_id', '=', procurement.location_id.id)
],
[('company_id', '=', company_id)]
]
cr, uid = procurement._cr, procurement._uid
context = procurement._context
Warehouse = self.pool['stock.warehouse']
for domain in domains:
ids = Warehouse.search(cr, uid, domain, context=context)
if ids:
return ids[0]
return False
def make_po(self, cr, uid, ids, context=None):
res = {}
requisition_obj = self.pool.get('purchase.requisition')
warehouse_obj = self.pool.get('stock.warehouse')
procurement = self.browse(cr, uid, ids, context=context)[0]
if procurement.product_id.purchase_requisition:
warehouse_id = warehouse_obj.search(cr, uid, [('company_id', '=', procurement.company_id.id or company.id)], context=context)
res[procurement.id] = requisition_obj.create(cr, uid,
{
non_requisition = []
for procurement in self.browse(cr, uid, ids, context=context):
if procurement.product_id.purchase_requisition:
user_company = self.pool['res.users'].browse(cr, uid, uid, context=context).company_id
req = res[procurement.id] = requisition_obj.create(cr, uid, {
'origin': procurement.origin,
'date_end': procurement.date_planned,
'warehouse_id':warehouse_id and warehouse_id[0] or False,
'company_id':procurement.company_id.id,
'line_ids': [(0,0,{
'warehouse_id': self._get_warehouse(procurement, user_company),
'company_id': procurement.company_id.id,
'line_ids': [(0, 0, {
'product_id': procurement.product_id.id,
'product_uom_id': procurement.product_uom.id,
'product_qty': procurement.product_qty
})],
})],
})
self.write(cr,uid,[procurement.id],{'state': 'running','requisition_id': res[procurement.id]},context=context)
else:
res = super(procurement_order, self).make_po(cr, uid, ids, context=context)
procurement.write({
'state': 'running',
'requisition_id': req
})
else:
non_requisition.append(procurement.id)
if non_requisition:
res.update(super(procurement_order, self).make_po(cr, uid, non_requisition, context=context))
return res

View File

@ -3,8 +3,9 @@
-
!python {model: ir.actions.report.xml}: |
import os
from openerp import netsvc, tools
from openerp import tools
from openerp.report import render_report
ids = self.pool['ir.actions.report.xml'].search(cr, uid, [], {})
(data, format) = netsvc.LocalService('report.webkit.ir.actions.report.xml').create(cr, uid, ids, {}, {})
data, format = render_report(cr, uid, ids, 'webkit.ir.actions.report.xml', {})
if tools.config['test_report_directory']:
file(os.path.join(tools.config['test_report_directory'], 'report_webkit_demo_report.'+format), 'wb+').write(data)

View File

@ -27,6 +27,7 @@ class sale_report(osv.osv):
_description = "Sales Orders Statistics"
_auto = False
_rec_name = 'date'
_columns = {
'date': fields.date('Date Order', readonly=True),
'date_confirm': fields.date('Date Confirm', readonly=True),
@ -60,12 +61,9 @@ class sale_report(osv.osv):
}
_order = 'date desc'
def init(self, cr):
tools.drop_view_if_exists(cr, 'sale_report')
cr.execute("""
create or replace view sale_report as (
select
min(l.id) as id,
def _select(self):
select_str = """
SELECT min(l.id) as id,
l.product_id as product_id,
t.uom_id as product_uom,
sum(l.product_uom_qty / u.factor * u2.factor) as product_uom_qty,
@ -84,15 +82,23 @@ class sale_report(osv.osv):
t.categ_id as categ_id,
s.pricelist_id as pricelist_id,
s.project_id as analytic_account_id
from
sale_order_line l
"""
return select_str
def _from(self):
from_str = """
sale_order_line l
join sale_order s on (l.order_id=s.id)
left join product_product p on (l.product_id=p.id)
left join product_template t on (p.product_tmpl_id=t.id)
left join product_uom u on (u.id=l.product_uom)
left join product_uom u2 on (u2.id=t.uom_id)
group by
l.product_id,
"""
return from_str
def _group_by(self):
group_by_str = """
GROUP BY l.product_id,
l.order_id,
t.uom_id,
t.categ_id,
@ -104,7 +110,16 @@ class sale_report(osv.osv):
s.state,
s.pricelist_id,
s.project_id
)
""")
"""
return group_by_str
def init(self, cr):
# self._table = sale_report
tools.drop_view_if_exists(cr, self._table)
cr.execute("""CREATE or REPLACE VIEW %s as (
%s
FROM ( %s )
%s
)""" % (self._table, self._select(), self._from(), self._group_by()))
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -47,10 +47,8 @@
<search string="Sales Analysis">
<field name="date"/>
<field name="date_confirm"/>
<filter icon="terp-document-new" string="Quotations" domain="[('state','=','draft')]"/>
<filter icon="terp-check" string="Sales" domain="[('state','not in',('draft','done','cancel'))]"/>
<separator/>
<filter icon="terp-accessories-archiver" string="Picked" domain="[('shipped','=',True)]"/>
<filter icon="terp-document-new" name="Quotations" domain="[('state','=','draft')]"/>
<filter icon="terp-check" name="Sales" domain="[('state','not in',('draft','done','cancel'))]"/>
<separator/>
<filter icon="terp-personal" string="My Sales" help="My Sales" domain="[('user_id','=',uid)]"/>
<field name="partner_id"/>

View File

@ -26,7 +26,7 @@ from openerp.osv import fields, osv
from openerp.tools.translate import _
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT, DATETIME_FORMATS_MAP, float_compare
import openerp.addons.decimal_precision as dp
from openerp import netsvc
from openerp import workflow
class sale_order(osv.osv):
_name = "sale.order"
@ -47,6 +47,7 @@ class sale_order(osv.osv):
'state': 'draft',
'invoice_ids': [],
'date_confirm': False,
'client_order_ref': '',
'name': self.pool.get('ir.sequence').get(cr, uid, 'sale.order'),
})
return super(sale_order, self).copy(cr, uid, id, default, context=context)
@ -791,9 +792,8 @@ class sale_order_line(osv.osv):
sales.add(line.order_id.id)
create_ids.append(inv_id)
# Trigger workflow events
wf_service = netsvc.LocalService("workflow")
for sale_id in sales:
wf_service.trg_write(uid, 'sale.order', sale_id, cr)
workflow.trg_write(uid, 'sale.order', sale_id, cr)
return create_ids
def button_cancel(self, cr, uid, ids, context=None):
@ -806,10 +806,9 @@ class sale_order_line(osv.osv):
return self.write(cr, uid, ids, {'state': 'confirmed'})
def button_done(self, cr, uid, ids, context=None):
wf_service = netsvc.LocalService("workflow")
res = self.write(cr, uid, ids, {'state': 'done'})
for line in self.browse(cr, uid, ids, context=context):
wf_service.trg_write(uid, 'sale.order', line.order_id.id, cr)
workflow.trg_write(uid, 'sale.order', line.order_id.id, cr)
return res
def uos_change(self, cr, uid, ids, product_uos, product_uos_qty=0, product_id=None):
@ -1001,9 +1000,8 @@ class account_invoice(osv.Model):
if len(invoice_ids) == len(ids):
#Cancel invoice(s) first before deleting them so that if any sale order is associated with them
#it will trigger the workflow to put the sale order in an 'invoice exception' state
wf_service = netsvc.LocalService("workflow")
for id in ids:
wf_service.trg_validate(uid, 'account.invoice', id, 'invoice_cancel', cr)
workflow.trg_validate(uid, 'account.invoice', id, 'invoice_cancel', cr)
return super(account_invoice, self).unlink(cr, uid, ids, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -78,6 +78,13 @@
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
</record>
<record model="ir.rule" id="sale_order_report_comp_rule">
<field name="name">Sales Order Analysis multi-company</field>
<field name="model_id" ref="model_sale_report"/>
<field name="global" eval="True"/>
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
</record>
<!-- Multi - Salesmen sales order assignation rules -->
<record id="sale_order_personal_rule" model="ir.rule">
@ -93,6 +100,19 @@
<field name="groups" eval="[(4, ref('base.group_sale_salesman_all_leads'))]"/>
</record>
<record id="sale_order_report_personal_rule" model="ir.rule">
<field name="name">Personal Orders Analysis</field>
<field ref="model_sale_report" name="model_id"/>
<field name="domain_force">['|',('user_id','=',user.id),('user_id','=',False)]</field>
<field name="groups" eval="[(4, ref('base.group_sale_salesman'))]"/>
</record>
<record id="sale_order_report_see_all" model="ir.rule">
<field name="name">All Orders Analysis</field>
<field ref="model_sale_report" name="model_id"/>
<field name="domain_force">[(1,'=',1)]</field>
<field name="groups" eval="[(4, ref('base.group_sale_salesman_all_leads'))]"/>
</record>
<record id="sale_order_line_personal_rule" model="ir.rule">
<field name="name">Personal Order Lines</field>

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