[MERGE] Latest trunk
bzr revid: odo@openerp.com-20120322150602-ljmp97npef2lby00
This commit is contained in:
@@ -1373,7 +1373,7 @@
|
||||
|
||||
<record id="INR" model="res.currency">
|
||||
<field name="name">INR</field>
|
||||
<field name="symbol">Rs</field>
|
||||
<field name="symbol">₹</field>
|
||||
<field name="rounding">0.01</field>
|
||||
<field name="accuracy">4</field>
|
||||
<field name="company_id" ref="main_company"/>
|
||||
|
||||
@@ -8,14 +8,14 @@ msgstr ""
|
||||
"Project-Id-Version: openobject-server\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:44+0000\n"
|
||||
"PO-Revision-Date: 2012-02-28 16:02+0000\n"
|
||||
"PO-Revision-Date: 2012-03-21 21:49+0000\n"
|
||||
"Last-Translator: Akira Hiyama <Unknown>\n"
|
||||
"Language-Team: Japanese <ja@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-03-10 04:49+0000\n"
|
||||
"X-Generator: Launchpad (build 14914)\n"
|
||||
"X-Launchpad-Export-Date: 2012-03-22 04:56+0000\n"
|
||||
"X-Generator: Launchpad (build 14981)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:res.country,name:base.sh
|
||||
@@ -8310,11 +8310,14 @@ msgid ""
|
||||
"interface, which has less features but is easier to use. You can switch to "
|
||||
"the other interface from the User/Preferences menu at any time."
|
||||
msgstr ""
|
||||
"OpenERPは簡易 / "
|
||||
"拡張の2種類のユーザインタフェースを提供します。最初にOpenERPを使う場合は,機能は少ないながらも使い易い簡易なユーザインタフェースを選択することを強"
|
||||
"くお勧めします。なお,いつでも設定メニューから拡張インタフェースに変更できます。"
|
||||
|
||||
#. module: base
|
||||
#: model:res.country,name:base.cc
|
||||
msgid "Cocos (Keeling) Islands"
|
||||
msgstr ""
|
||||
msgstr "ココス諸島"
|
||||
|
||||
#. module: base
|
||||
#: selection:base.language.install,state:0
|
||||
@@ -8326,22 +8329,22 @@ msgstr ""
|
||||
#. module: base
|
||||
#: view:res.lang:0
|
||||
msgid "11. %U or %W ==> 48 (49th week)"
|
||||
msgstr ""
|
||||
msgstr "11. %U or %W ==> 48(49番目の週)"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.model,name:base.model_res_partner_bank_type_field
|
||||
msgid "Bank type fields"
|
||||
msgstr ""
|
||||
msgstr "銀行タイプ項目"
|
||||
|
||||
#. module: base
|
||||
#: selection:base.language.install,lang:0
|
||||
msgid "Dutch / Nederlands"
|
||||
msgstr ""
|
||||
msgstr "オランダ"
|
||||
|
||||
#. module: base
|
||||
#: selection:res.company,paper_format:0
|
||||
msgid "US Letter"
|
||||
msgstr ""
|
||||
msgstr "US レター"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_stock_location
|
||||
@@ -8433,6 +8436,63 @@ msgid ""
|
||||
"from Gate A\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"このモジュールはプッシュ型プル型倉庫フローを効果的に実行する倉庫アプリケーションを補います。\n"
|
||||
"============================================================================="
|
||||
"===============================\n"
|
||||
"\n"
|
||||
"典型的な利用例:\n"
|
||||
" * 製品製造チェーンの管理\n"
|
||||
" * 製品ごとのデフォルトロケーションの管理\n"
|
||||
" * 以下のようなビジネス要求による倉庫の中の経路の定義:\n"
|
||||
" - 品質管理\n"
|
||||
" - 販売サービスの後\n"
|
||||
" - サプライヤ返品\n"
|
||||
"\n"
|
||||
" * レンタル製品の自動返品を生成することでレンタル管理を助けます。\n"
|
||||
"\n"
|
||||
"ひとたびこのモジュールがインストールされたら,製品フォームに追加タブが現れます。\n"
|
||||
"そこで,プッシュとプルのフローの仕様を加えることができます。\n"
|
||||
"CPU1製品のプッシュとプルのデモデータ:\n"
|
||||
"\n"
|
||||
"プッシュフロー\n"
|
||||
"----------\n"
|
||||
"プッシュフローは,一定の製品が常に必要に応じて他の場所に対応して動く到着する時,\n"
|
||||
"オプションとして一定の遅延がある時に役立ちます。\n"
|
||||
"オリジナルの倉庫アプリケーションは既にそれ自身にプッシュフローの仕様をサポートしています。\n"
|
||||
"しかし,これは製品ごとに改良されません。\n"
|
||||
"\n"
|
||||
"プッシュプローの仕様はどの場所がどの場所と何のパラメータでつながれているかを示します。\n"
|
||||
"製品の所定の量が供給元の場所で動きがあるや否や結び付けられた動作がフロー定義\n"
|
||||
"(目的地の場所,遅延,移動の種類,ジャーナル他)でセットされたパラメータにしたがって\n"
|
||||
"自動的に予測されます。\n"
|
||||
"この新しい動きはパラメータにしたがって自動的に実行されるか,手動確認を要求します。\n"
|
||||
"\n"
|
||||
"プルフロー\n"
|
||||
"----------\n"
|
||||
"プルフローはプッシュフローとは少し異なっています。これは製品の動きの処理には関係せず,\n"
|
||||
"むしろ獲得した注文の処理に関係します。直接の商品ではなくニーズに依ります。\n"
|
||||
"プルフローの古典的な例は,供給に責任を持つ親会社を持つアウトレット会社です。\n"
|
||||
"\n"
|
||||
" [ 顧客 ] <- A - [ アウトレット ] <- B - [ 親会社 ] <~ C ~ [ 供給者 ]\n"
|
||||
"\n"
|
||||
"新しい獲得注文(A:例として注文の確認が来ます)がアウトレットに到着すると,それは親会社から要求されたもう一つの獲得注文に変換されます(B:プルフローのタ"
|
||||
"イプは'move')。親会社により獲得注文Bが処理される時,そしてその製品が在庫切れの時,それは供給者からの受注(C:プルフローのタイプは購入)に変換され"
|
||||
"ます。結果として獲得注文,ニーズは顧客と供給者の間の全てにプッシュされる。\n"
|
||||
"\n"
|
||||
"専門的には,プルフローは獲得注文と別に処理することを許します。製品に対しての考慮に依存するのみならず,その製品のニーズを持つ場所(即ち獲得注文の目的地)に"
|
||||
"依存します。\n"
|
||||
"\n"
|
||||
"使用例\n"
|
||||
"--------\n"
|
||||
"\n"
|
||||
"以下のデモデータを使います:\n"
|
||||
" CPU1:ショップ1からいくらかのCPU1を売り,スケジューラを走らせます。\n"
|
||||
" - 倉庫:配達注文,ショップ1: 受付\n"
|
||||
" CPU3:\n"
|
||||
" - 商品を受け取る時,それは品質管理場所に行き,棚2に保管されます。\n"
|
||||
" - 顧客に配達する時:ピックリスト -> 梱包 -> GateAから配達注文\n"
|
||||
" "
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_marketing
|
||||
@@ -8444,11 +8504,17 @@ msgid ""
|
||||
"Contains the installer for marketing-related modules.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"マーケティングメニュー\n"
|
||||
"===================\n"
|
||||
"\n"
|
||||
"マーケティング関連のモジュールのインストーラを含んでいます。\n"
|
||||
" "
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.category,name:base.module_category_knowledge_management
|
||||
msgid "Knowledge Management"
|
||||
msgstr ""
|
||||
msgstr "知識管理"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.actions.act_window,name:base.bank_account_update
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
from email.MIMEText import MIMEText
|
||||
from email.MIMEBase import MIMEBase
|
||||
from email.MIMEMultipart import MIMEMultipart
|
||||
from email.Charset import Charset
|
||||
from email.Header import Header
|
||||
from email.Utils import formatdate, make_msgid, COMMASPACE
|
||||
from email import Encoders
|
||||
@@ -97,6 +98,26 @@ def encode_header(header_text):
|
||||
return header_text_ascii if header_text_ascii\
|
||||
else Header(header_text_utf8, 'utf-8')
|
||||
|
||||
def encode_header_param(param_text):
|
||||
"""Returns an appropriate RFC2047 encoded representation of the given
|
||||
header parameter value, suitable for direct assignation as the
|
||||
param value (e.g. via Message.set_param() or Message.add_header())
|
||||
RFC2822 assumes that headers contain only 7-bit characters,
|
||||
so we ensure it is the case, using RFC2047 encoding when needed.
|
||||
|
||||
:param param_text: unicode or utf-8 encoded string with header value
|
||||
:rtype: string
|
||||
:return: if ``param_text`` represents a plain ASCII string,
|
||||
return the same 7-bit string, otherwise returns an
|
||||
ASCII string containing the RFC2047 encoded text.
|
||||
"""
|
||||
# For details see the encode_header() method that uses the same logic
|
||||
if not param_text: return ""
|
||||
param_text_utf8 = tools.ustr(param_text).encode('utf-8')
|
||||
param_text_ascii = try_coerce_ascii(param_text_utf8)
|
||||
return param_text_ascii if param_text_ascii\
|
||||
else Charset('utf8').header_encode(param_text_utf8)
|
||||
|
||||
name_with_email_pattern = re.compile(r'("[^<@>]+")\s*<([^ ,<@]+@[^> ,]+)>')
|
||||
address_pattern = re.compile(r'([^ ,<@]+@[^> ,]+)')
|
||||
|
||||
@@ -309,7 +330,7 @@ class ir_mail_server(osv.osv):
|
||||
msg['Cc'] = encode_rfc2822_address_header(COMMASPACE.join(email_cc))
|
||||
if email_bcc:
|
||||
msg['Bcc'] = encode_rfc2822_address_header(COMMASPACE.join(email_bcc))
|
||||
msg['Date'] = formatdate(localtime=True)
|
||||
msg['Date'] = formatdate()
|
||||
# Custom headers may override normal headers or provide additional ones
|
||||
for key, value in headers.iteritems():
|
||||
msg[ustr(key).encode('utf-8')] = encode_header(value)
|
||||
@@ -334,14 +355,16 @@ class ir_mail_server(osv.osv):
|
||||
|
||||
if attachments:
|
||||
for (fname, fcontent) in attachments:
|
||||
filename_utf8 = ustr(fname).encode('utf-8')
|
||||
filename_rfc2047 = encode_header_param(fname)
|
||||
part = MIMEBase('application', "octet-stream")
|
||||
|
||||
# The default RFC2231 encoding of Message.add_header() works in Thunderbird but not GMail
|
||||
# so we fix it by using RFC2047 encoding for the filename instead.
|
||||
part.set_param('name', filename_rfc2047)
|
||||
part.add_header('Content-Disposition', 'attachment', filename=filename_rfc2047)
|
||||
|
||||
part.set_payload(fcontent)
|
||||
Encoders.encode_base64(part)
|
||||
# Force RFC2231 encoding for attachment filename
|
||||
# See email.message.Message.add_header doc
|
||||
part.add_header('Content-Disposition', 'attachment',
|
||||
filename=('utf-8',None,filename_utf8))
|
||||
msg.attach(part)
|
||||
return msg
|
||||
|
||||
|
||||
@@ -404,7 +404,7 @@ class ir_values(osv.osv):
|
||||
results[action['name']] = (action['id'], action['name'], action_def)
|
||||
except except_orm, e:
|
||||
continue
|
||||
return results.values()
|
||||
return sorted(results.values())
|
||||
|
||||
def _map_legacy_model_list(self, model_list, map_fn, merge_results=False):
|
||||
"""Apply map_fn to the various models passed, according to
|
||||
|
||||
@@ -466,6 +466,7 @@ class module(osv.osv):
|
||||
'sequence': terp.get('sequence', 100),
|
||||
'application': terp.get('application', False),
|
||||
'auto_install': terp.get('auto_install', False),
|
||||
'icon': terp.get('icon', False),
|
||||
}
|
||||
|
||||
# update the list of available packages
|
||||
|
||||
@@ -346,21 +346,35 @@ class res_partner_address(osv.osv):
|
||||
|
||||
def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=100):
|
||||
if not args:
|
||||
args=[]
|
||||
if not context:
|
||||
context={}
|
||||
if context.get('contact_display', 'contact')=='partner ' or context.get('contact_display', 'contact')=='partner_address ' :
|
||||
ids = self.search(cr, user, [('partner_id',operator,name)], limit=limit, context=context)
|
||||
args = []
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
if not name:
|
||||
ids = self.search(cr, user, args, limit=limit, context=context)
|
||||
elif context.get('contact_display', 'contact') == 'partner':
|
||||
ids = self.search(cr, user, [('partner_id', operator, name)] + args, limit=limit, context=context)
|
||||
else:
|
||||
if not name:
|
||||
ids = self.search(cr, user, args, limit=limit, context=context)
|
||||
# first lookup zip code, as it is a common and efficient way to search on these data
|
||||
ids = self.search(cr, user, [('zip', '=', name)] + args, limit=limit, context=context)
|
||||
# then search on other fields:
|
||||
if context.get('contact_display', 'contact') == 'partner_address':
|
||||
fields = ['partner_id', 'name', 'country_id', 'city', 'street']
|
||||
else:
|
||||
ids = self.search(cr, user, [('zip','=',name)] + args, limit=limit, context=context)
|
||||
if not ids:
|
||||
ids = self.search(cr, user, [('city',operator,name)] + args, limit=limit, context=context)
|
||||
if name:
|
||||
ids += self.search(cr, user, [('name',operator,name)] + args, limit=limit, context=context)
|
||||
ids += self.search(cr, user, [('partner_id',operator,name)] + args, limit=limit, context=context)
|
||||
fields = ['name', 'country_id', 'city', 'street']
|
||||
# Here we have to search the records that satisfy the domain:
|
||||
# OR([[(f, operator, name)] for f in fields])) + args
|
||||
# Searching on such a domain can be dramatically inefficient, due to the expansion made
|
||||
# for field translations, and the handling of the disjunction by the DB engine itself.
|
||||
# So instead, we search field by field until the search limit is reached.
|
||||
while len(ids) < limit and fields:
|
||||
f = fields.pop(0)
|
||||
new_ids = self.search(cr, user, [(f, operator, name)] + args, limit=limit, context=context)
|
||||
# extend ids with the ones in new_ids that are not in ids yet (and keep order)
|
||||
old_ids = set(ids)
|
||||
ids.extend([id for id in new_ids if id not in old_ids])
|
||||
|
||||
ids = ids[:limit]
|
||||
return self.name_get(cr, user, ids, context=context)
|
||||
|
||||
def get_city(self, cr, uid, id):
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
<field name="name">user rule</field>
|
||||
<field model="ir.model" name="model_id" ref="model_res_users"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="domain_force">['|',('company_id.child_ids','child_of',[user.company_id.id]),('company_id','child_of',[user.company_id.id])]</field>
|
||||
<field name="domain_force">[('company_ids','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
@@ -34,6 +34,9 @@ from service import security
|
||||
from tools.translate import _
|
||||
import openerp
|
||||
import openerp.exceptions
|
||||
from lxml import etree
|
||||
from lxml.builder import E
|
||||
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -728,29 +731,27 @@ class groups_view(osv.osv):
|
||||
# and introduces the reified group fields
|
||||
view = self.get_user_groups_view(cr, uid, context)
|
||||
if view:
|
||||
xml = u"""<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- GENERATED AUTOMATICALLY BY GROUPS -->
|
||||
<field name="groups_id" position="replace">
|
||||
%s
|
||||
%s
|
||||
</field>
|
||||
"""
|
||||
|
||||
xml1, xml2 = [], []
|
||||
xml1.append('<separator string="%s" colspan="4"/>' % _('Applications'))
|
||||
xml1.append(E.separator(string=_('Application'), colspan="4"))
|
||||
for app, kind, gs in self.get_groups_by_application(cr, uid, context):
|
||||
if kind == 'selection':
|
||||
# application name with a selection field
|
||||
field_name = name_selection_groups(map(int, gs))
|
||||
xml1.append('<field name="%s"/>' % field_name)
|
||||
xml1.append('<newline/>')
|
||||
xml1.append(E.field(name=field_name))
|
||||
xml1.append(E.newline())
|
||||
else:
|
||||
# application separator with boolean fields
|
||||
app_name = app and app.name or _('Other')
|
||||
xml2.append('<separator string="%s" colspan="4"/>' % app_name)
|
||||
xml2.append(E.separator(string=app_name, colspan="4"))
|
||||
for g in gs:
|
||||
field_name = name_boolean_group(g.id)
|
||||
xml2.append('<field name="%s"/>' % field_name)
|
||||
view.write({'arch': xml % ('\n'.join(xml1), '\n'.join(xml2))})
|
||||
xml2.append(E.field(name=field_name))
|
||||
|
||||
xml = E.field(*(xml1 + xml2), name="groups_id", position="replace")
|
||||
xml.addprevious(etree.Comment("GENERATED AUTOMATICALLY BY GROUPS"))
|
||||
xml_content = etree.tostring(xml, pretty_print=True, xml_declaration=True, encoding="utf-8")
|
||||
view.write({'arch': xml_content})
|
||||
return True
|
||||
|
||||
def get_user_groups_view(self, cr, uid, context=None):
|
||||
|
||||
@@ -173,6 +173,8 @@ class db(netsvc.ExportService):
|
||||
raise Exception, e
|
||||
|
||||
def exp_drop(self, db_name):
|
||||
if not self.exp_db_exist(db_name):
|
||||
return False
|
||||
openerp.modules.registry.RegistryManager.delete(db_name)
|
||||
sql_db.close_db(db_name)
|
||||
|
||||
@@ -180,6 +182,17 @@ class db(netsvc.ExportService):
|
||||
cr = db.cursor()
|
||||
cr.autocommit(True) # avoid transaction block
|
||||
try:
|
||||
# Try to terminate all other connections that might prevent
|
||||
# dropping the database
|
||||
try:
|
||||
cr.execute("""SELECT pg_terminate_backend(procpid)
|
||||
FROM pg_stat_activity
|
||||
WHERE datname = %s AND
|
||||
procpid != pg_backend_pid()""",
|
||||
(db_name,))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
cr.execute('DROP DATABASE "%s"' % db_name)
|
||||
except Exception, e:
|
||||
|
||||
+12
-16
@@ -313,7 +313,8 @@ class graph(object):
|
||||
self.order[level] = self.order[level]+1
|
||||
|
||||
for sec_end in self.transitions.get(node, []):
|
||||
self.init_order(sec_end, self.result[sec_end]['x'])
|
||||
if node!=sec_end:
|
||||
self.init_order(sec_end, self.result[sec_end]['x'])
|
||||
|
||||
|
||||
def order_heuristic(self):
|
||||
@@ -438,33 +439,27 @@ class graph(object):
|
||||
l.reverse()
|
||||
no = len(l)
|
||||
|
||||
if no%2==0:
|
||||
first_half = l[no/2:]
|
||||
factor = 1
|
||||
else:
|
||||
first_half = l[no/2+1:]
|
||||
factor = 0
|
||||
|
||||
rest = no%2
|
||||
first_half = l[no/2+rest:]
|
||||
last_half = l[:no/2]
|
||||
|
||||
i=1
|
||||
for child in first_half:
|
||||
self.result[child]['y'] = mid_pos - (i - (factor * 0.5))
|
||||
i += 1
|
||||
for i, child in enumerate(first_half):
|
||||
self.result[child]['y'] = mid_pos - (i+1 - (0 if rest else 0.5))
|
||||
|
||||
if self.transitions.get(child, False):
|
||||
if last:
|
||||
self.result[child]['y'] = last + len(self.transitions[child])/2 + 1
|
||||
last = self.tree_order(child, last)
|
||||
|
||||
if no%2:
|
||||
if rest:
|
||||
mid_node = l[no/2]
|
||||
self.result[mid_node]['y'] = mid_pos
|
||||
|
||||
if self.transitions.get((mid_node), False):
|
||||
if last:
|
||||
self.result[mid_node]['y'] = last + len(self.transitions[mid_node])/2 + 1
|
||||
last = self.tree_order(mid_node)
|
||||
if node!=mid_node:
|
||||
last = self.tree_order(mid_node)
|
||||
else:
|
||||
if last:
|
||||
self.result[mid_node]['y'] = last + 1
|
||||
@@ -474,13 +469,14 @@ class graph(object):
|
||||
i=1
|
||||
last_child = None
|
||||
for child in last_half:
|
||||
self.result[child]['y'] = mid_pos + (i - (factor * 0.5))
|
||||
self.result[child]['y'] = mid_pos + (i - (0 if rest else 0.5))
|
||||
last_child = child
|
||||
i += 1
|
||||
if self.transitions.get(child, False):
|
||||
if last:
|
||||
self.result[child]['y'] = last + len(self.transitions[child])/2 + 1
|
||||
last = self.tree_order(child, last)
|
||||
if node!=child:
|
||||
last = self.tree_order(child, last)
|
||||
|
||||
if last_child:
|
||||
last = self.result[last_child]['y']
|
||||
|
||||
Reference in New Issue
Block a user