diff --git a/openerp/addons/base/__openerp__.py b/openerp/addons/base/__openerp__.py index 802a0510e28..a353344190f 100644 --- a/openerp/addons/base/__openerp__.py +++ b/openerp/addons/base/__openerp__.py @@ -75,6 +75,7 @@ 'security/base_security.xml', 'publisher_warranty/publisher_warranty_view.xml', 'security/ir.model.access.csv', + 'security/ir.model.access-1.csv', # res.partner.address is deprecated; it is still there for backward compability only and will be removed in next version 'res/res_widget_view.xml', 'res/res_widget_data.xml', 'publisher_warranty/publisher_warranty_data.xml', diff --git a/openerp/addons/base/base_data.xml b/openerp/addons/base/base_data.xml index a0e66de8dba..7f5b4dec109 100644 --- a/openerp/addons/base/base_data.xml +++ b/openerp/addons/base/base_data.xml @@ -1058,14 +1058,9 @@ Your Company - - - - - default - + @@ -1102,9 +1097,6 @@ - - - diff --git a/openerp/addons/base/base_demo.xml b/openerp/addons/base/base_demo.xml index 3d1eae3c4bc..a0149096902 100644 --- a/openerp/addons/base/base_demo.xml +++ b/openerp/addons/base/base_demo.xml @@ -2,8 +2,8 @@ - - Fabien Dupont + + Fabien D'souza Chaussee de Namur 1367 Gerompont diff --git a/openerp/addons/base/i18n/ja.po b/openerp/addons/base/i18n/ja.po index e2dbfc9e831..df57e0cb835 100644 --- a/openerp/addons/base/i18n/ja.po +++ b/openerp/addons/base/i18n/ja.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: openobject-server\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-03-30 02:15+0000\n" +"PO-Revision-Date: 2012-03-31 07:17+0000\n" "Last-Translator: Akira Hiyama \n" "Language-Team: Japanese \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-30 04:34+0000\n" +"X-Launchpad-Export-Date: 2012-04-01 04:38+0000\n" "X-Generator: Launchpad (build 15032)\n" #. module: base @@ -25,7 +25,7 @@ msgstr "セントヘレナ" #. module: base #: view:ir.actions.report.xml:0 msgid "Other Configuration" -msgstr "その他コンフィギュレーション" +msgstr "その他の設定" #. module: base #: selection:ir.property,type:0 @@ -188,7 +188,7 @@ msgstr "ターゲットウィンドウ" #. module: base #: model:ir.module.module,shortdesc:base.module_sale_analytic_plans msgid "Sales Analytic Distribution" -msgstr "販売分析された流通" +msgstr "販売分析の配布" #. module: base #: model:ir.module.module,shortdesc:base.module_web_process @@ -448,7 +448,7 @@ msgstr "" #. module: base #: view:ir.actions.todo:0 msgid "Config Wizard Steps" -msgstr "コンフィグウィザードステップ" +msgstr "設定ウィザードステップ" #. module: base #: model:ir.model,name:base.model_ir_ui_view_sc @@ -586,7 +586,7 @@ msgstr "ここをチェックした場合、ユーザが同じ名前で2回目 #. module: base #: model:ir.module.module,shortdesc:base.module_sale_layout msgid "Sales Orders Print Layout" -msgstr "受注のプリントレイアウト" +msgstr "受注オーダーのプリントレイアウト" #. module: base #: selection:base.language.install,lang:0 @@ -666,7 +666,7 @@ msgstr "" #. module: base #: view:res.partner:0 msgid "Sales & Purchases" -msgstr "セールスと購入" +msgstr "受注と発注" #. module: base #: view:ir.translation:0 @@ -1364,7 +1364,7 @@ msgstr "クレーム管理" #. module: base #: model:ir.ui.menu,name:base.menu_purchase_root msgid "Purchases" -msgstr "購入" +msgstr "発注" #. module: base #: model:res.country,name:base.md @@ -1404,10 +1404,10 @@ msgid "" " * Effective Date\n" msgstr "" "\n" -"注文のための追加の日付情報を追加してください。\n" +"受注オーダーのための追加の日付情報を追加してください。\n" "===================================================\n" "\n" -"注文のために以下のような日付情報を加えることができます:\n" +"受注オーダーのために以下のような日付情報を加えることができます:\n" " ・ 要求日\n" " ・ 確認日\n" " ・ 有効日\n" @@ -1549,7 +1549,7 @@ msgstr "" msgid "" "Helps you manage your purchase-related processes such as requests for " "quotations, supplier invoices, etc..." -msgstr "見積り要求や仕入先請求書といった購入関係のプロセスの管理を手助けします。" +msgstr "見積り要求や仕入先請求書といった発注関係のプロセスの管理を手助けします。" #. module: base #: help:base.language.install,overwrite:0 @@ -1848,7 +1848,7 @@ msgstr "" " ・ デフォルトでは国のための知られている検査ルール、通常は簡単なチェックディジットを\n" "  使って簡便なオフラインチェックが実行されます。これは簡単でいつでも利用できますが、\n" "  割り当て済みの番号や正しくない値を許してしまいます。\n" -" ・ 'VAT VIES Check' オプションが使用可能(ユーザの会社のコンフィギュレーションにある)な\n" +" ・ 'VAT VIES Check' オプションが使用可能(ユーザの会社の設定にある)な\n" "  時は、VAT番号はEU VIESデータベースに問い合わせて、その番号がEU会社として実際に割り当て\n" "  られているかを検査します。これは単純なオフラインチェックに比較して多少時間がかり、\n" "  インターネット接続も必要です。全ての時間に利用可能ではないため、サービスが利用可能でき\n" @@ -1870,7 +1870,8 @@ msgid "" "Helps you get the most out of your points of sales with fast sale encoding, " "simplified payment mode encoding, automatic picking lists generation and " "more." -msgstr "迅速な販売のコード化、単純化された支払モードのコード化、自動採取リストの生成などにより、販売時点管理の大きな手助けを行います。" +msgstr "" +"迅速な販売のコード化、単純化された支払モードのコード化、自動ピッキングリストの生成などにより、販売時点管理のために大いなる手助けをします。" #. module: base #: model:res.country,name:base.mv @@ -1981,7 +1982,7 @@ msgstr "左括弧" #. module: base #: model:ir.module.module,shortdesc:base.module_project_mrp msgid "Create Tasks on SO" -msgstr "タスク作成(受注)" +msgstr "タスク作成(受注オーダー)" #. module: base #: field:ir.attachment,res_model:0 @@ -2288,23 +2289,20 @@ msgid "" " " msgstr "" "\n" -"この販売ジャーナルモジュールは販売と配達(選択リスト)を異なったジャーナルに分類することができます。\n" +"この受注ジャーナルモジュールは受注と配達(選択リスト)を異なったジャーナルに分類することができます。\n" "======================================================================\n" "このモジュールは部門を持つ大きな会社にとても役立ちます。\n" "\n" "以下のような異なる目的のためにジャーナルを使うことができます:\n" -"\n" -" ・ 別部門の販売の分離\n" +" ・ 別部門の受注の分離\n" " ・ 配達がトラックなのかUPSなのかの仕訳\n" "\n" "ジャーナルは責任を持ち、異なる状態に展開する:\n" -"\n" " ・ ドラフト、オープン、キャンセル、完了\n" "\n" -"バッチ操作は一度に全ての販売の確認、有効化、請求書の梱包といった異なるジャーナルを処理できます。\n" -"\n" -"バッチ請求方法はパートナごとや受注ごとに構成することもできます。例:\n" +"バッチ操作は一度に全ての受注の確認、検証、請求書のピッキングといった異なるジャーナルを処理できます。\n" "\n" +"バッチ請求方法はパートナごとや受注オーダーごとに構成することもできます。例:\n" " ・ 日々の送付\n" " ・ 月次の送付など\n" "\n" @@ -2543,7 +2541,7 @@ msgid "" "`object.order_line`." msgstr "" "リストが返される項目 / 式を入力して下さい。例えば、 " -"オブジェクトの販売オーダーを選択し、販売オーダーの繰り返しができます。式=`object.order_line`" +"オブジェクトの受注オーダーを選択し、受注オーダーの繰り返しができます。式=`object.order_line`" #. module: base #: field:ir.mail_server,smtp_debug:0 @@ -2584,6 +2582,15 @@ msgid "" "\n" " " msgstr "" +"\n" +"リソース管理のためのモジュール\n" +"===============================\n" +"\n" +"リソースはスケジュールすることのできるものを意味します(タスクの開発者や製造オーダーのワークセンタ)。\n" +"このモジュールは全てのリソースのためにカレンダーに関連するリソースを管理します。\n" +"また、全てのリソースに対する許可も管理します。\n" +"\n" +" " #. module: base #: view:ir.rule:0 @@ -2681,10 +2688,10 @@ msgid "" " " msgstr "" "\n" -"分析的な流通と受注管理のための基本モジュール\n" +"分析的な流通と受注オーダーを管理するための基本モジュール\n" "=================================================================\n" "\n" -"このモジュールを使うことで、受注に対して分析アカウントを結びつけることができます。\n" +"このモジュールを使うことで、受注オーダーに対して分析アカウントを結びつけることができます。\n" " " #. module: base @@ -3070,7 +3077,7 @@ msgid "" "The decimal precision is configured per company.\n" msgstr "" "\n" -"あなたが必要とする異なった用途の価格を正確に設定してください:会計、販売、購入など\n" +"あなたが必要とする異なった用途の価格を正確に設定してください:会計、受注、発注など\n" "=============================================================================" "=========================\n" "\n" @@ -3329,7 +3336,7 @@ msgid "" "separated list of valid field names (optionally followed by asc/desc for the " "direction)" msgstr "" -"無効な注文が指定されました。正しい注文の仕様は正しい項目名によるカンマ区切りのリストです(オプションで asc / desc が続きます)。" +"無効なオーダーが指定されました。正しいオーダーの仕様は正しい項目名によるカンマ区切りのリストです(オプションで asc / desc が続きます)。" #. module: base #: model:ir.model,name:base.model_ir_module_module_dependency @@ -3590,16 +3597,16 @@ msgid "" " " msgstr "" "\n" -"この基本モジュールは見積りと受注を管理します。\n" +"この基本モジュールは見積りと受注オーダーを管理します。\n" "======================================================\n" "\n" "確認のワークフロー:\n" "-------------------------------\n" -" ・ 見積り -> 受注 -> 請求書\n" +" ・ 見積り -> 受注オーダー -> 請求書\n" "\n" "請求方法:\n" "------------------\n" -" ・ 注文時に請求(発送前または発送後)\n" +" ・ オーダー時に請求(発送前または発送後)\n" " ・ 配達時に請求\n" " ・ タイムシートによる請求\n" " ・ 前請求\n" @@ -3622,10 +3629,10 @@ msgstr "" "セールス管理のダッシュボードに含むもの:\n" "------------------------------------------\n" " ・ 見積り\n" -" ・ 月別販売\n" -" ・ 直近90日間の販売員別販売グラフ\n" -" ・ 直近90日間の顧客別販売グラフ\n" -" ・ 直近90日間の商品分類別販売グラフ\n" +" ・ 月別受注\n" +" ・ 直近90日間の販売員別受注グラフ\n" +" ・ 直近90日間の顧客別受注グラフ\n" +" ・ 直近90日間の商品分類別受注グラフ\n" " " #. module: base @@ -3878,7 +3885,7 @@ msgstr "" "\n" "次のような機能があります:\n" "--------------------------------\n" -" ・ 請求書の全行の注文\n" +" ・ 請求書の全行のオーダー\n" " ・ タイトル、コメント欄、小計の追加\n" " ・ 罫線の描画、改ページ\n" "\n" @@ -4349,7 +4356,7 @@ msgid "" " " msgstr "" "\n" -"会計証明モジュールは銀行、現金、販売、購入、経費、契約などの証明の全ての基本要求を含みます。\n" +"会計証明モジュールは銀行、現金、受注、発注、経費、契約などの証明の全ての基本要求を含みます。\n" "=============================================================================" "=======================================================\n" "\n" @@ -4661,15 +4668,15 @@ msgid "" " " msgstr "" "\n" -"仕入モジュールは仕入先から商品購入のために仕入注文を生成します。\n" +"発注モジュールは仕入先から商品の購入のために発注オーダーを生成します。\n" "=============================================================================" "============\n" "\n" -"特定の仕入注文に応じた仕入先の請求が作成されます。\n" +"特定の発注オーダーに応じた仕入先の請求が作成されます。\n" "\n" "発注管理のダッシュボードは以下を含みます:\n" -" ・ 最新の仕入注文\n" -" ・ ドラフトの仕入注文\n" +" ・ 最新の発注オーダー\n" +" ・ ドラフトの発注オーダー\n" " ・ 月別の発注量と金額のグラフ\n" "\n" " " @@ -5160,7 +5167,7 @@ msgstr "アブハジア語 / аҧсуа" #. module: base #: view:base.module.configuration:0 msgid "System Configuration Done" -msgstr "システムコンフィギュレーション完了" +msgstr "システム設定完了" #. module: base #: code:addons/orm.py:1459 @@ -5176,7 +5183,7 @@ msgstr "一般的" #. module: base #: view:ir.actions.server:0 msgid "SMS Configuration" -msgstr "SMSコンフィギュレーション" +msgstr "SMSの設定" #. module: base #: model:ir.module.module,description:base.module_document_webdav @@ -5212,8 +5219,8 @@ msgstr "" "\n" "その後、OpenObjectに装着されたものを遠隔地からどの互換ブラウザからでも見ることができます。\n" "\n" -"インストールの後、WebDAVサーバはサーバコンフィグの[webdav]セクションによってコントロールが可能です。\n" -"サーバーコンフィギュレーションパラメータ:\n" +"インストールの後、WebDAVサーバはサーバ設定の[webdav]セクションによってコントロールが可能です。\n" +"サーバ設定パラメータ:\n" "\n" " [webdav]\n" " ; enable = True ; Serve webdav over the http(s) servers\n" @@ -5227,7 +5234,7 @@ msgstr "" " ; these options on\n" "\n" "httpサーバのサービスディスカバリのためにIETF RFC 5785が実装されます。\n" -"これは openerp-server.conf に明確なコンフィギュレーションを必要とします。\n" +"これは openerp-server.conf に明確な設定を必要とします。\n" #. module: base #: model:res.country,name:base.sm @@ -5424,11 +5431,11 @@ msgid "" "order all your purchase orders.\n" msgstr "" "\n" -"このモジュールは仕入要求を管理します。\n" +"このモジュールは発注要求を管理します。\n" "===========================================================\n" "\n" -"仕入注文が作られるときに、あなたは関連する要求を保存する機会を持ちます。\n" -"新しいオブジェクトは再グループ化され容易に追跡を続けることができるので、全ての仕入注文をすることができます。\n" +"発注オーダーが作られるときに、関連する要求を保存する機会を持ちます。\n" +"新しいオブジェクトは再グループ化され容易に追跡を続けることができるので、全ての発注オーダーをオーダーすることができます。\n" #. module: base #: model:res.country,name:base.hu @@ -5521,12 +5528,12 @@ msgid "" " " msgstr "" "\n" -"このモジュールはユーザにMRPと販売モジュールを一度にインストールする便宜を提供します。\n" +"このモジュールはユーザにMRPと受注モジュールを一度にインストールする便宜を提供します。\n" "=============================================================================" "=======\n" "\n" -"受注から生成された生産注文を追跡したい時に基本的に利用されます。\n" -"これは生産注文の販売名や販売リファレンスを追加します。\n" +"受注オーダーから生成された製造オーダーを追跡したい時に基本的に利用されます。\n" +"これは製造オーダーの受注名や受注リファレンスを追加します。\n" " " #. module: base @@ -5739,7 +5746,7 @@ msgstr "" "=============================================================================" "=\n" "\n" -"このモジュールをインストール後、会計のコンフィギュレーションウィザードが自動起動します。\n" +"このモジュールをインストール後、会計の設定ウィザードが自動起動します。\n" " ・ 会計表作成を補助する会計テンプレートがあります。\n" " ・ " "特定のウィザードでは会社の名前、従うべき表のテンプレート、生成するための桁数、あなたのアカウントと銀行口座、ジャーナル作成のための通貨が尋ねられます。\n" @@ -5789,7 +5796,7 @@ msgstr "ザンビア" #. module: base #: view:ir.actions.todo:0 msgid "Launch Configuration Wizard" -msgstr "起動コンフィギュレーションウィザード" +msgstr "起動設定ウィザード" #. module: base #: help:res.partner,user_id:0 @@ -6672,7 +6679,7 @@ msgstr "ジャーナル入力のキャンセル" #. module: base #: view:ir.actions.server:0 msgid "Client Action Configuration" -msgstr "クライアントアクションのコンフィギュレーション" +msgstr "クライアントアクションの設定" #. module: base #: model:ir.model,name:base.model_res_partner_address @@ -6795,8 +6802,8 @@ msgstr "" " ・ おそらく異なった機能の上でそれぞれの仕事の住所の連絡先\n" "\n" "次の場所にも新しいメニュー項目を追加します:\n" -" ・ 購入 / アドレスブック / コンタクト\n" -" ・ 販売 / アドレスブック / コンタクト\n" +" ・ 発注 / アドレスブック / コンタクト\n" +" ・ 受注 / アドレスブック / コンタクト\n" "\n" "このモジュールが既存の住所を”住所+連絡先”の中に変換することに注意してください。この意味は、これらは\n" "他のオブジェクトの中で定義することになっているため、住所の中の幾つかの項目は失われます(連絡先名など)。\n" @@ -7900,11 +7907,11 @@ msgstr "" "このモジュールはCRMに一つあるいは幾つかのオポチュニティに近道を加えます。\n" "===========================================================================\n" "\n" -"この方法は選択されたケースに基づき受注を作成します。\n" -"異なったケースが開いている(リスト)場合は、ケースによる一つの受注を作成します。\n" -"そのケースがそれから閉じられ作成された受注に結び付けられます。\n" +"この方法は選択されたケースに基づき受注オーダーを作成します。\n" +"異なったケースが開いている(リスト)場合は、ケースによる一つの受注オーダーを作成します。\n" +"そのケースがそれから閉じられ作成された受注オーダーに結び付けられます。\n" "\n" -"すでに販売とCRMの両方のモジュールをインストールしているなら、このモジュールのインストールを薦めます。\n" +"すでに受注とCRMの両方のモジュールをインストールしているなら、このモジュールのインストールを薦めます。\n" " " #. module: base @@ -8020,11 +8027,11 @@ msgid "" " " msgstr "" "\n" -"受注と引き取りに関する配送方法を追加することができます。\n" +"受注オーダーとピッキングに関する配送方法を追加することができます。\n" "==============================================================\n" "\n" "価格によるあなた自身の運搬人や配送グリッドの定義ができます。\n" -"引き取りから請求書を作成する場合は、OpenERPは配送の行を追加し計算を行います。\n" +"ピッキングから請求書を作成する場合は、OpenERPは配送の行を追加し計算を行います。\n" "\n" " " @@ -8078,7 +8085,7 @@ msgstr "" "商品が出荷された時に原価を計上します。\n" "このモジュールは中間勘定を使うことによってこの機能を加えます。借方または貸方アカウントにその総額を転送\n" "するために請求書が作成された時に、出荷された商品の価値を保存し、そしてこの中間勘定を反対記帳します。\n" -"第2に、実際の購入価格と固定の製品標準価格の差は分離された勘定に記帳されます。" +"第2に、実際の仕入価格と固定の製品標準価格の差は分離された勘定に記帳されます。" #. module: base #: field:res.partner,title:0 @@ -8197,11 +8204,11 @@ msgid "" " " msgstr "" "\n" -"最低額を超える購入のための二重検証\n" +"最低額を超える発注のための二重検証\n" "=========================================================\n" "\n" -"このモジュールは、コンフィギュレーションウィザードによって設定される最低額を超えた購入を\n" -"検証するための購入ワークフローを変更します。\n" +"このモジュールは、設定ウィザードによって設定される最低額を超えた発注を\n" +"検証するための発注ワークフローを変更します。\n" " " #. module: base @@ -8463,10 +8470,10 @@ msgstr "" "しかし、これは製品ごとに改良されません。\n" "\n" "プッシュプローの仕様は、どの場所がどの場所と何のパラメータでつながれているかを示します。\n" -"製品の所定の量が供給元の場所で動きがあるや否や結び付けられた動作がフロー定義\n" +"製品の所定の量が供給元の場所で動きがあるや否や、結び付けられた動作が、フロー定義\n" "(目的地の場所、遅延、移動の種類、ジャーナル他)でセットされたパラメータにしたがって\n" "自動的に予測されます。\n" -"この新しい動きはパラメータにしたがって自動的に実行されるか、手動確認を要求します。\n" +"この新しい動きは、パラメータにしたがって自動的に実行されるか、手動確認を要求します。\n" "\n" "プルフロー\n" "----------\n" @@ -8476,22 +8483,22 @@ msgstr "" "\n" " [ 顧客 ] <- A - [ アウトレット ] <- B - [ 親会社 ] <~ C ~ [ 仕入先 ]\n" "\n" -"新しい調達注文(A:注文の確認がくる例)がアウトレットに到着すると、それは親会社から要求されたもう一つの調達注文に変換されます(B:プルフローのタイプは'" -"move')。親会社により調達注文Bが処理される時、そしてその製品が在庫切れの時、それは仕入先からの仕入注文(C:プルフローのタイプは仕入)に変換されます" -"。結果として調達注文、ニーズは顧客と仕入先の間の全てにプッシュされます。\n" +"新しい調達オーダー(A:例として受注オーダーの確認がくる)がアウトレットに到着すると、それは親会社から要求されたもう一つの調達に変換されます(B:プルフロ" +"ーのタイプは'move')。親会社により調達オーダーBが処理される時、そしてその製品が在庫切れの時、それは仕入先への発注オーダー(C:プルフローのタイプは" +"発注)に変換されます。結果として調達オーダー、ニーズは顧客と仕入先の間の全てにプッシュされます。\n" "\n" -"技術的には、プルフローは調達注文と別に処理することを許します。製品に対しての考慮に依存するのみならず、その製品のニーズを持つ場所(即ち調達注文の目的地)に" -"依存します。\n" +"専門的には、プルフローは調達オーダーと別に処理することを許します。製品に対しての考慮に依存するのみならず、その製品のニーズを持つ場所(即ち調達オーダーの目" +"的地)に依存します。\n" "\n" "使用例\n" "--------\n" "\n" "以下のデモデータを使います:\n" " CPU1:ショップ1からいくらかのCPU1を売り、スケジューラを走らせます。\n" -" - 倉庫:配達注文,ショップ1: 受付\n" +" - 倉庫:配達オーダー,ショップ1: 受付\n" " CPU3:\n" " - 商品を受け取る時、それは品質管理場所に行き、棚2に保管されます。\n" -" - 顧客に配達する時:ピックリスト -> 梱包 -> GateAから配達注文\n" +" - 顧客に配達する時:ピックリスト -> 梱包 -> GateAから配達オーダー\n" " " #. module: base @@ -8558,23 +8565,23 @@ msgid "" "\n" msgstr "" "\n" -"自動的に調達ラインからプロジェクトタスクの生成します。\n" +"自動的に調達行からプロジェクトタスクを生成します。\n" "==========================================================\n" "\n" -"対応する製品が以下の特徴を満たす場合、このモジュールはそれぞれの調達注文ライン\n" -"(例えば販売注文ライン)のための新しいタスクを作成します。\n" +"対応する製品が以下の特徴を満たす場合、このモジュールはそれぞれの調達オーダー行\n" +"(例えば受注オーダー行)のための新しいタスクを作成します。\n" "\n" " ・ タイプ = サービス\n" -" ・ 調達手法(注文実現) = MTO(受注生産)\n" -" ・ 供給 / 調達手法 = 産物\n" +" ・ 調達手法(オーダー実現) = MTO(受注生産)\n" +" ・ 供給 / 調達方法 = 製造\n" "\n" "もし先頭のプロジェクトが製品フォーム(調達タブ)で定義されているなら、新しいタスクは\n" "その特定のプロジェクトの中に作られます。\n" "それ以外の場合は、新しいタスクはどんなプロジェクトにも属さず、後で手作業でプロジェクトに\n" "追加されるかも知れません。\n" "\n" -"プロジェクトのタスクが完了するか、中止される時、調達ラインに対応するワークフローはそれに応じて更新されます。\n" -"例えば、もしこの調達が受注ラインに対応するなら、仕事が完了する時に受注ラインは配達されたと考えられます。\n" +"プロジェクトのタスクが完了するか、中止される時、調達行に対応するワークフローはそれに応じて更新されます。\n" +"例えば、もしこの調達が受注オーダー行に対応するなら、仕事が完了する時に受注オーダー行は配達されたと考えられます。\n" "\n" #. module: base @@ -8677,7 +8684,7 @@ msgstr "" "・ 有料会員\n" "・ 特別な会員価格など\n" "\n" -"メンバーシップ更新のための請求書を作り、条件書を送付するために、これは販売と会計と統合されます。\n" +"メンバーシップ更新のための請求書を作り、条件書を送付するために、これは受注と会計と統合されます。\n" " " #. module: base @@ -9393,13 +9400,13 @@ msgstr "" "このモジュールはコンピュータ調達のためのモジュールです。\n" "==============================================\n" "\n" -"MRPプロセスでは、製造注文、仕入注文、在庫割り当てなどを起動されるために調達指示が作成されます。\n" -"調達注文はシステムにより自動的に生成され、そして問題がある場合を除きユーザには通知されません。\n" +"MRPプロセスでは、製造オーダー、発注オーダー、在庫割り当てなどを起動されるために調達オーダーが作成されます。\n" +"調達オーダーはシステムにより自動的に生成され、そして問題がある場合を除きユーザには通知されません。\n" "問題は生じた場合には、システムは手作業で解決されるべき阻害要因について(組み立てBoM(部品表)の欠如、仕入先の欠落の類い)、ユーザに知らせるために幾つか" "の調達例外を発生させます。\n" "\n" -"調達指示は補充を必要とする製品の自動調達のための提案をスケジュールします。この調達は仕入先の仕入注文書かまたは製品の構成に応じてた製造注文のタスクを開始し" -"ます。\n" +"調達オーダーは補充を必要とする製品の自動調達のための提案をスケジュールします。この調達は仕入先の発注オーダーかまたは製品の構成に応じてた製造オーダーのタス" +"クを開始します。\n" " " #. module: base @@ -10148,25 +10155,25 @@ msgstr "" "\n" "簡単な用語集\n" "--------------\n" -"・ 在庫期間 - 販売と在庫を予測し計画するための時間の境界(開始日と終了日の間)\n" -"・ 販売予測 - 関連する在庫期間の間に販売する予定の製品の個数\n" -"・ 在庫計画 - 関連する在庫期間のために購入または製造する予定の製品の個数\n" +"・ 在庫期間 - 受注と在庫を予測し計画するための時間の境界(開始日と終了日の間)\n" +"・ 受注予測 - 関連する在庫期間の間に販売する予定の製品の個数\n" +"・ 在庫計画 - 関連する在庫期間のために発注または製造する予定の製品の個数\n" "\n" -"s​​ale_forecastモジュール(\"販売予測\"と\"計画\"は総額)によって使用される用語との混同を避けるために、量の値を使用することを強調す" -"る用語、\"在庫および販売予測\"と\"在庫計画\"を使用します。\n" +"s​​ale_forecastモジュール(\"受注予測\"と\"計画\"は総額)によって使用される用語との混同を避けるために、量の値を使用することを強調す" +"る用語、\"在庫および受注予測\"と\"在庫計画\"を使用します。\n" "\n" "どこで開始されるか\n" "--------------\n" "このモジュールは以下の3つのステップでなされます:\n" "\n" -"・ 在庫期間を作成 倉庫 > コンフィギュレーション > 在庫期間メニュー(必須のステップ)\n" -"・ 予測数量を埋めた販売予測の作成 販売 > 販売予測メニュー\n" +"・ 在庫期間を作成 倉庫 > 設定 > 在庫期間メニュー(必須のステップ)\n" +"・ 予測数量を埋めた受注予測の作成 受注 > 受注予測メニュー\n" "  (オプションのステップ。しかし将来計画に役立つ)\n" "・ 実際のMPS計画の作成、残高をチェック、必要な調達を行う。実際の調達は在庫期間の最後のステップ\n" "\n" -"在庫期間のコンフィギュレーション\n" +"在庫期間の設定\n" "--------------------------\n" -"倉庫 > コンフィギュレーション > 在庫期間 に期間のために2つのメニューがあります:\n" +"倉庫 > 設定 > 在庫期間 に期間のために2つのメニューがあります:\n" "\n" "・ 在庫期間作成 - 日次、週次、月次の自動作成が可能\n" "・ 在庫期間 - どんな期間のタイプの作成も日付の変更も期間の状態の変更も可能\n" @@ -10182,69 +10189,65 @@ msgstr "" "とを望む場合は、それらは重複を許すため望むように期間を定義して下さい。以下のテキストはそのような期間をどのように使うかを示します。\n" "・ " "自動的に作成される場合、開始時間は00:00:00、終了時間は23:59:00となります。日々の期間を作成する場合、開始日時は2010年1月31日00:0" -"0:00、終了日時は2010年1月31日29:59:00となります。それは期間の自動作成の\n" -"\n" -"みで機能します。期間を手動で作成する場合は、販売や在庫において間違った値を持つことになるため、その時間には注意しなければなりません。\n" +"0:00、終了日時は2010年1月31日29:59:00となります。それは期間の自動作成のみで機能します。期間を手動で作成する場合は、受注や在庫において間" +"違った値を持つことになるため、その時間には注意しなければなりません。\n" "・ 同じ製品に対して重複する期間を使う場合、倉庫と会社の結果は予測できません。\n" "・ 現在日付がどの期間にも属さない場合や期間の間に空きがある場合にはその結果は予測できません。\n" "\n" -"販売予測コンフィギュレーション\n" +"受注予測の設定\n" "-----------------------------\n" -"販売 > 販売予測 に販売予測のための幾つかのメニューがあります:\n" +"受注 > 受注予測 に受注予測のための幾つかのメニューがあります:\n" "\n" -"・ 販売予測作成 - 自動的にあなたのニーズによる予測ラインを作成できます。\n" -"・ 販売予測 - 販売予測の管理\n" +"・ 受注予測作成 - 自動的にあなたのニーズによる予測行を作成できます。\n" +"・ 受注予測 - 受注予測の管理\n" "\n" -"\"販売予測作成\"メニューは選択された分類の製品の選択された期間、選択された倉庫の予測を作成します。以前の予測をコピーすることも可能です。\n" +"\"受注予測作成\"メニューは選択された分類の製品の選択された期間、選択された倉庫の予測を作成します。以前の予測をコピーすることも可能です。\n" "\n" "備考:\n" "\n" "・ " -"すでに同じ製品、期間、倉庫の入力が同じユーザにより作られるか検証されている場合、このツールは重複ラインを作りません。もし、他の予測を作成したい場合や適切な" -"ラインが存在する場合は、以下に示すように手作業で行う必要があります。\n" -"・ 作成されたラインが他の誰かにより検証された場合、同じ期間、製品、倉庫の他のラインをこのツールを使って作る事ができます。\n" +"すでに同じ製品、期間、倉庫の入力が同じユーザにより作られるか検証されている場合、このツールは重複行を作りません。もし、他の予測を作成したい場合や適切な行が" +"存在する場合は、以下に示すように手作業で行う必要があります。\n" +"・ 作成された行が他の誰かにより検証された場合、同じ期間、製品、倉庫の他の行をこのツールを使って作る事ができます。\n" "・ " -"\"前回の予測をコピー\"を選択した場合、作成されたラインの数量と他の設定は、あなたの(あなたが検証したもの、まだ検証されていないがあなたが作成したもの)" -"以前作成した予測の最後の期間の予測が使われます。\n" +"\"前回の予測をコピー\"を選択した場合、作成された行の数量と他の設定は、あなたの(あなたが検証したもの、まだ検証されていないがあなたが作成したもの)以前" +"作成した予測の最後の期間の予測が使われます。\n" "\n" -"\"販売予測フォーム\"の上では主にあなたが\"製品数量\"の予測数量を入力しなければなりません。\n" +"\"受注予測フォーム\"の上では主にあなたが\"製品数量\"の予測数量を入力しなければなりません。\n" "さらに計算はドラフト予測のために有効です。しかし、検証に設定することでどんな事故的な変更からもあなたのデータを救うことが可能です。\n" "検証ボタンのクリックは可能ですが、必須ではありません。\n" "\n" -"数量の予測の代わりに\"製品数量\"項目による予測販売の総額を入力することもできます。\n" +"数量の予測の代わりに\"製品数量\"項目による予測受注の総額を入力することもできます。\n" "システムは製品の販売価格に応じた総額から数量を計算します。\n" "\n" "フォームの全ての値はフォームで選択した計量単位で表現されます。\n" "デフォルトの分類または第二の分類から計量単位を選択することができます。\n" "計量単位を変更した場合は、予測製品数量は 新しい計量単位によって再計算されます。\n" "\n" -"販売予測の解決のために製品の\"販売履歴\"を使うことができます。\n" +"受注予測の解決のために製品の\"受注履歴\"を使うことができます。\n" "あなたはこのテーブルの先頭と左のパラメータを入力しなければなりません。そして、システムはそれらのパラメータにより販売数量を計算します。\n" "そして、所定の販売チームや期間のための結果を得ることができます。\n" "\n" "MPSまたは調達計画\n" "---------------------------\n" -"MPS計画は、各適切な在庫期間と倉庫のための製品の調達を分析し、状態により駆動させる在庫計画ラインによって構成されます。\n" +"MPS計画は、各適切な在庫期間と倉庫のための製品の調達を分析し、状態により駆動させる在庫計画行によって構成されます。\n" "このメニューは、倉庫 > スケジュール > マスタ調達スケジュール にあります:\n" "\n" -"・ 在庫計画ライン作成 - 多数の計画ラインの自動作成を手助けするウィザード\n" -"・ マスタ調達スケジュール - 計画ラインの管理\n" +"・ 在庫計画行作成 - 多数の計画行の自動作成を手助けするウィザード\n" +"・ マスタ調達スケジュール - 計画行の管理\n" "\n" -"同様に、販売予測は販売計画を定義することを提供する方法であり、MPSは調達(購入/製造)を立案することができます。\n" -"\"在庫計画ライン作成\"ウィザードはMPSを素早く使いこなすことができます。それから\"マスタ調達スケジュール\"メニューからレビューを続行できます。" +"同様に、受注予測は受注計画を定義することを提供する方法であり、MPSは調達(発注 / 製造)を立案することができます。\n" +"\"在庫計画行作成\"ウィザードはMPSを素早く使いこなすことができます。それから\"マスタ調達スケジュール\"メニューからレビューを続行できます。\n" "\n" -"\n" -"\"在庫計画ライン作成\"ウィザードによって、所定の製品分類、所定の期間と倉庫のために全てのMPSラインを迅速に作成できます。\n" -"ウィザードの\"全ての製品の予測\"オプションを有効にした場合、システムは選択された期間と倉庫(このケースには選択された分類は無視されます)の販売予測を持" -"つ全ての製品のラインを作成します。\n" +"\"在庫計画行作成\"ウィザードによって、所定の製品分類、所定の期間と倉庫のために全てのMPS行を迅速に作成できます。\n" +"ウィザードの\"全ての製品の予測\"オプションを有効にした場合、システムは選択された期間と倉庫(このケースには選択された分類は無視されます)の受注予測を持" +"つ全ての製品の行を作成します。\n" "\n" "メニューの\"マスタ調達スケジュール\"の下にある、\"計画出庫\"(Planned Out)と\"計画入庫\"(Planned " "In)の数量はいつでも変更できます。そして、もし所定の期間でもっと多くの製品を入手する必要があるかどうかを決めるために\"在庫シミュレーション\"の値の結" "果を注視して下さい。\n" "\"計画出庫\"は、最初にすでに計画された期間と倉庫のために全て出て行く在庫の動きの合計である\"倉庫予測\"を基にします。\n" -"もちろん、あなた自身の数量を与えるためにその値を変更することができます。予測を持つ必要はありません\n" -"\n" -"。\n" +"もちろん、あなた自身の数量を与えるためにその値を変更することができます。予測を持つ必要はありません。\n" "\"計画入庫\"の数量は期間の終わりにおける\"在庫シミュレーション\"に到達するために入手されるべき数量である項目の\"入って来る残り\"を計算するため" "に使われます。\n" "\"在庫シミュレーション\"数量とフォーム上に見える最小在庫ルールを比較することができます。\n" @@ -10297,11 +10300,11 @@ msgstr "" "・ 年代順にしたがって各期間の計画が継続して作成されなければなりません。そうでない場合の数値は現実を反映していないでしょう。\n" "・ " "将来の期間のために計画を実行し、本物の確認出庫がいくらか前の計画出庫よりも大きくなった場合は、計画を再度行って他の調達を作ることができます。それは同じ計画" -"ラインの中で行わねばなりません。もし他の計画ラインで行った場合は、その提案は誤っている可能性があります。\n" +"行の中で行わねばなりません。もし他の計画行で行った場合は、その提案は誤っている可能性があります。\n" "・ " "幾つかの製品に対して異なった期間を適用したい場合は、2種類の期間(例えば週次と月次)を定義して、異なった期間でそれを使って下さい。例として、いつも製品Aに" "は週次を使い、製品Bには月次を使う場合、全ての計算は正しく行われます。異なった倉庫や会社であれば、同じ商品に異なった期間を使うこともできます。しかし、同じ" -"製品、倉庫、会社で期間が重複するのは結果が予想できないので許されません。同じことは予測ラインにも適用されます。\n" +"製品、倉庫、会社で期間が重複するのは結果が予想できないので許されません。同じことは予測行にも適用されます。\n" #. module: base #: model:res.country,name:base.mp @@ -10624,7 +10627,7 @@ msgstr "" "\n" "特徴:\n" "---------\n" -" ・ 在庫の作成 / 注文の作成(ラインによる)\n" +" ・ 在庫の作成 / オーダーの作成(行単位)\n" " ・ 複数レベルのBoMs(Mill of Materials:部品表)、制限なし\n" " ・ 複数レベルの経路、制限なし\n" " ・ 経路とワークセンターが分析的な会計とともに統合されます。\n" @@ -10638,7 +10641,7 @@ msgstr "" "\n" "完全な統合と在庫可能商品の計画化、サービスの消耗品をサポートします。\n" "サービスは完全にソフトウェアの残り部分と統合されています。\n" -"例えば、製品の組み立てオーダーの上で自動購入するためにBoMの中にサブ契約サービスを設定できます。\n" +"例えば、製品の組み立てオーダーの上で自動発注するためにBoMの中にサブ契約サービスを設定できます。\n" "\n" "このモジュールで提供されるレポート:\n" "--------------------------------\n" @@ -10897,7 +10900,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_sale_margin msgid "Margins in Sales Orders" -msgstr "販売注文のマージン" +msgstr "受注オーダーのマージン" #. module: base #: model:res.partner.category,name:base.res_partner_category_9 @@ -10908,7 +10911,7 @@ msgstr "部品仕入先" #: model:ir.module.category,name:base.module_category_purchase_management #: model:ir.module.module,shortdesc:base.module_purchase msgid "Purchase Management" -msgstr "購入管理" +msgstr "発注管理" #. module: base #: field:ir.module.module,published_version:0 @@ -11203,7 +11206,7 @@ msgstr "" "隠されたレポーティングのインストーラ\n" "==============================\n" "\n" -"レポーティングの隠されたコンフィグレーションを有効にすることで、base_report_designer や base_report_creator " +"レポーティングの隠された設定を有効にすることで、base_report_designer や base_report_creator " "のようなモジュールのインストールが可能です。\n" " " @@ -11266,7 +11269,7 @@ msgstr "ビュー" #. module: base #: model:ir.module.module,shortdesc:base.module_wiki_sale_faq msgid "Wiki: Sale FAQ" -msgstr "Wiki:販売FAQ" +msgstr "Wiki:受注FAQ" #. module: base #: selection:ir.module.module,state:0 @@ -11420,7 +11423,7 @@ msgstr "レポートのプレビュー" #. module: base #: model:ir.module.module,shortdesc:base.module_purchase_analytic_plans msgid "Purchase Analytic Plans" -msgstr "分析計画の購入" +msgstr "発注分析計画" #. module: base #: model:ir.module.module,description:base.module_analytic_journal_billing_rate @@ -11475,8 +11478,7 @@ msgstr "スペイン語(コロンビア)/ Español (CO)" msgid "" "All pending configuration wizards have been executed. You may restart " "individual wizards via the list of configuration wizards." -msgstr "" -"全ての保留中のコンフィギュレーションウィザードは実行されました。あなたはコンフィグレーションウィザードのリストを介して、個別ウィザードの再起動ができます。" +msgstr "全ての保留中の設定ウィザードは実行されました。あなたは設定ウィザードのリストを介して、個別ウィザードの再起動ができます。" #. module: base #: view:ir.sequence:0 @@ -11827,10 +11829,10 @@ msgid "" "Adds a Claim link to the delivery order.\n" msgstr "" "\n" -"配達注文からクレームを作成します。\n" +"配達オーダーからクレームを作成します。\n" "=====================================\n" "\n" -"配達注文にクレームのリンクを加えます。\n" +"配達オーダーにクレームのリンクを加えます。\n" #. module: base #: view:ir.model:0 @@ -11921,7 +11923,7 @@ msgstr "この会社に関連した銀行口座" #: model:ir.ui.menu,name:base.menu_sale_config_sales #: model:ir.ui.menu,name:base.menu_sales msgid "Sales" -msgstr "販売" +msgstr "受注" #. module: base #: field:ir.actions.server,child_ids:0 @@ -12133,7 +12135,7 @@ msgstr "" #. module: base #: model:ir.model,name:base.model_ir_actions_todo_category msgid "Configuration Wizard Category" -msgstr "コンフィギュレーションウィザードの分類" +msgstr "設定ウィザードの分類" #. module: base #: view:base.module.update:0 @@ -12310,17 +12312,17 @@ msgid "" " " msgstr "" "\n" -"このモジュールは迅速で簡単な販売プロセスを提供します。\n" +"このモジュールは迅速で簡単な受注プロセスを提供します。\n" "===================================================\n" "\n" "主な特徴:\n" "---------------\n" -" ・ 販売の高速なエンコーディング\n" +" ・ 受注の高速なエンコーディング\n" " ・ 1回支払いモード(簡単な方法)、または幾つかの支払いモード間に支払いを分割する選択を許可\n" " ・ 返金総額の計算\n" " ・ 自動的に抽出リストの作成と確認\n" " ・ ユーザが自動的に請求書を作成することを許可\n" -" ・ 前の売上の返金を許可\n" +" ・ 前の受注の返金を許可\n" " " #. module: base @@ -12396,10 +12398,10 @@ msgid "" " " msgstr "" "\n" -"このモジュールはWiki販売FAQテンプレートを提供します。\n" +"このモジュールはWiki受注FAQテンプレートを提供します。\n" "===============================================\n" "\n" -"Wiki販売FAQのために、WikiグループとWikiページを作成し、デモデータを提供します。\n" +"Wiki受注FAQのために、WikiグループとWikiページを作成し、デモデータを提供します。\n" " " #. module: base @@ -12475,7 +12477,7 @@ msgid "" "you need.\n" msgstr "" "\n" -"請求書に基づき、販売、購入、マージン、他の興味深いインジケーターを計算するレポートメニューを追加します。=========================" +"請求書に基づき、受注、発注、マージン、他の興味深いインジケーターを計算するレポートメニューを追加します。=========================" "=============================================================================" "=======================\n" "\n" @@ -12520,7 +12522,7 @@ msgstr "子ID" #: code:addons/base/ir/ir_actions.py:751 #, python-format msgid "Problem in configuration `Record Id` in Server Action!" -msgstr "サーバアクションのレコードIDコンフィギュレーションの問題です。" +msgstr "サーバアクションのレコードID設定の問題です。" #. module: base #: code:addons/orm.py:2682 @@ -12547,7 +12549,7 @@ msgid "" " " msgstr "" "\n" -"このモジュールは販売注文に\"マージン\"を追加します。\n" +"このモジュールは受注オーダーに\"マージン\"を追加します。\n" "=============================================\n" "\n" "ユニット価格とコスト価格の差を計算し利益を求めます。\n" @@ -12755,7 +12757,7 @@ msgstr "" #. module: base #: view:ir.actions.configuration.wizard:0 msgid "Next Configuration Step" -msgstr "次のコンフィギュレーションステップ" +msgstr "次の設定ステップ" #. module: base #: field:res.groups,comment:0 @@ -12918,7 +12920,7 @@ msgstr "通常" #. module: base #: model:ir.module.module,shortdesc:base.module_purchase_double_validation msgid "Double Validation on Purchases" -msgstr "購入時の二重検証" +msgstr "発注時の二重検証" #. module: base #: field:res.bank,street2:0 @@ -13001,7 +13003,7 @@ msgstr "グレナダ" #. module: base #: view:ir.actions.server:0 msgid "Trigger Configuration" -msgstr "トリガーコンフィギュレーション" +msgstr "トリガー設定" #. module: base #: view:base.language.install:0 @@ -13024,7 +13026,7 @@ msgstr "" "OpenERPオブジェクトの中の警告トリガーのモジュール\n" "==============================================\n" "\n" -"警告メッセージは購入注文、仕入注文、収集、請求のようなオブジェクトのために表示させることができます。\n" +"警告メッセージは受注オーダー、発注オーダー、ピッキング、請求書のようなオブジェクトのために表示させることができます。\n" "このメッセージはフォームのonChangeイベントによってトリガーとなります。\n" " " @@ -13217,7 +13219,7 @@ msgid "" " " msgstr "" "\n" -"このモジュールでは、パートナの価格リストを基に販売注文の行や請求書の行での割引計算ができます。\n" +"このモジュールでは、パートナの価格リストを基に受注オーダーの行や請求書の行での割引計算ができます。\n" "=============================================================================" "==================================\n" "\n" @@ -13225,8 +13227,8 @@ msgstr "" "\n" "例:\n" " 製品PC1とパートナAsustek:リスト価格=450で、Asustekの価格リストを使って計算された価格=225の場合\n" -" チェックボックスがチェックありの時、販売注文の行:ユニット価格=450、割引=50.00、ネット価格=225\n" -" チェックボックスがチェックなしの時、販売注文と請求書の行:ユニット価格=225、割引=0.00、ネット価格=225\n" +" チェックボックスがチェックありの時、受注オーダーの行:ユニット価格=450、割引=50.00、ネット価格=225\n" +" チェックボックスがチェックなしの時、受注オーダーと請求書の行:ユニット価格=225、割引=0.00、ネット価格=225\n" " " #. module: base @@ -13287,50 +13289,50 @@ msgstr "月:%(month)s" #: field:res.widget.user,sequence:0 #: field:wizard.ir.model.menu.create.line,sequence:0 msgid "Sequence" -msgstr "" +msgstr "順序" #. module: base #: model:res.country,name:base.tn msgid "Tunisia" -msgstr "" +msgstr "チュニジア" #. module: base #: view:ir.actions.todo:0 msgid "Wizards to be Launched" -msgstr "" +msgstr "ウィザードの開始" #. module: base #: model:ir.module.category,name:base.module_category_manufacturing #: model:ir.ui.menu,name:base.menu_mrp_root msgid "Manufacturing" -msgstr "" +msgstr "製造" #. module: base #: model:res.country,name:base.km msgid "Comoros" -msgstr "" +msgstr "コモロ" #. module: base #: view:res.request:0 msgid "Draft and Active" -msgstr "" +msgstr "ドラフトとアクティブ" #. module: base #: model:ir.actions.act_window,name:base.action_server_action #: view:ir.actions.server:0 #: model:ir.ui.menu,name:base.menu_server_action msgid "Server Actions" -msgstr "" +msgstr "サーバーアクション" #. module: base #: field:res.partner.bank.type,format_layout:0 msgid "Format Layout" -msgstr "" +msgstr "フォーマットレイアウト" #. module: base #: field:ir.model.fields,selection:0 msgid "Selection Options" -msgstr "" +msgstr "選択オプション" #. module: base #: field:res.partner.category,parent_right:0 @@ -13340,7 +13342,7 @@ msgstr "右括弧" #. module: base #: model:ir.module.module,shortdesc:base.module_auth_openid msgid "OpenID Authentification" -msgstr "" +msgstr "OpenID認証" #. module: base #: model:ir.module.module,description:base.module_plugin_thunderbird @@ -13356,33 +13358,42 @@ msgid "" "HR Applicant and Project Issue from selected mails.\n" " " msgstr "" +"\n" +"このモジュールは適切に動作するためにThuderbird プラグインが必要とされます。\n" +"====================================================================\n" +"\n" +"プラグインは選択されたOpenERPオブジェクトにEメールと添付ファイルのアーカイブを許可します。\n" +"パートナ、タスク、プロジェクト、分析アカウント、またはどんな他のオブジェクトでも選択して、\n" +"選択されたメールを 選択されたレコードの添付ファイルの中に.emlファイルとして添付できます。\n" +"選択されたメールからCRMのリード、HRの応募者、プロジェクトの問題のドキュメントを作成できます。\n" +" " #. module: base #: view:res.lang:0 msgid "Legends for Date and Time Formats" -msgstr "" +msgstr "日付と時刻フォーマットの凡例" #. module: base #: selection:ir.actions.server,state:0 msgid "Copy Object" -msgstr "" +msgstr "オブジェクトのコピー" #. module: base #: model:ir.module.module,shortdesc:base.module_mail msgid "Emails Management" -msgstr "" +msgstr "Eメール管理" #. module: base #: field:ir.actions.server,trigger_name:0 msgid "Trigger Signal" -msgstr "" +msgstr "トリガーのシグナル" #. module: base #: code:addons/base/res/res_users.py:119 #, python-format msgid "" "Group(s) cannot be deleted, because some user(s) still belong to them: %s !" -msgstr "" +msgstr "グループの削除はできません。なぜなら一部のユーザはまだそのグループに属しています:%s" #. module: base #: model:ir.module.module,description:base.module_mrp_repair @@ -13400,18 +13411,29 @@ msgid "" " * Repair quotation report\n" " * Notes for the technician and for the final customer\n" msgstr "" +"\n" +"全ての製品修理管理の完全なモジュールを持つことを目的にしています。以下のトピックはこのモジュールでカバーする必要があります:\n" +"=============================================================================" +"==============================================\n" +"\n" +" ・ 賠償製品の追加と削除\n" +" ・ 在庫の影響\n" +" ・ 請求書(製品またはサービス)\n" +" ・ 保証のコンセプト\n" +" ・ 修理見積書\n" +" ・ 技術者のため、最終顧客のための記録\n" #. module: base #: model:ir.actions.act_window,name:base.action_country_state #: model:ir.ui.menu,name:base.menu_country_state_partner msgid "Fed. States" -msgstr "" +msgstr "連邦" #. module: base #: view:ir.model:0 #: view:res.groups:0 msgid "Access Rules" -msgstr "" +msgstr "アクセスルール" #. module: base #: model:ir.module.module,description:base.module_knowledge @@ -13425,11 +13447,17 @@ msgid "" "document and Wiki based Hidden.\n" " " msgstr "" +"\n" +"知識ベースHiddenのインストーラ\n" +"====================================\n" +"\n" +"Hiddenに基づくドキュメントやWikiのインストールすることで、知識アプリケーション設定が提供されます。\n" +" " #. module: base #: field:res.groups,trans_implied_ids:0 msgid "Transitively inherits" -msgstr "" +msgstr "推移的継承" #. module: base #: field:ir.default,ref_table:0 @@ -13440,7 +13468,7 @@ msgstr "テーブルの参照" #: code:addons/base/ir/ir_mail_server.py:443 #, python-format msgid "Mail delivery failed" -msgstr "" +msgstr "メールの配信が失敗しました。" #. module: base #: field:ir.actions.act_window,res_model:0 @@ -13463,7 +13491,7 @@ msgstr "" #: field:res.request.link,object:0 #: field:workflow.triggers,model:0 msgid "Object" -msgstr "" +msgstr "オブジェクト" #. module: base #: code:addons/osv.py:147 @@ -13473,6 +13501,9 @@ msgid "" "\n" "[object with reference: %s - %s]" msgstr "" +"\n" +"\n" +"[オブジェクトの参照: %s - %s]" #. module: base #: model:ir.module.module,shortdesc:base.module_account_analytic_plans @@ -13493,21 +13524,29 @@ msgid "" "\n" " " msgstr "" +"\n" +"タイムシートエントリーとプロジェクトタスクワークエントリーの同期\n" +"====================================================================\n" +"\n" +"このモジュールは特定の日付の特定のユーザのタイムシート行エントリーの作成、編集、削除\n" +"の反映とともに、プロジェクト管理のために定義されたタスクの元にそのエントリーの転送ができます。\n" +"\n" +" " #. module: base #: view:ir.sequence:0 msgid "Minute: %(min)s" -msgstr "" +msgstr "分:%(min)s" #. module: base #: model:ir.ui.menu,name:base.next_id_10 msgid "Scheduler" -msgstr "" +msgstr "スケジューラ" #. module: base #: model:ir.module.module,shortdesc:base.module_base_tools msgid "Base Tools" -msgstr "" +msgstr "基本ツール" #. module: base #: help:res.country,address_format:0 @@ -13526,6 +13565,18 @@ msgid "" " \n" "%(country_code)s: the code of the country" msgstr "" +"ここでは、この国に属する住所に使うための通常のフォーマットを決めることができます。\n" +"\n" +"住所の全ての項目にPythonスタイルの文字パターンを使うことができます(例:'%(street)s'を使うと\"street\"項目を表示します)。加え" +"て\n" +" \n" +"%(state_name)s:州の名前\n" +" \n" +"%(state_code)s:州のコード\n" +" \n" +"%(country_name)s:国の名前\n" +" \n" +"%(country_code)s:国のコード" #. module: base #: model:ir.module.module,description:base.module_pad @@ -13539,6 +13590,13 @@ msgid "" "(by default, http://ietherpad.com/).\n" " " msgstr "" +"\n" +"WebクライアントにEtherPadのための拡張をサポートします。\n" +"===================================================================\n" +"\n" +"PADはカスタマイズできます。Padのインストールは新しいPadのためのリンクを使って下さい。\n" +"デフォルトでは http://ietherpad.com/ です。\n" +" " #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_uk @@ -13574,6 +13632,30 @@ msgid "" " * http://controlchaos.com\n" " " msgstr "" +"\n" +"このモジュールはIT会社のためにScrumプロジェクト管理により定義された全てのコンセプトを実装しています。\n" +"=============================================================================" +"============================\n" +"\n" +" ・ スプリントプロジェクト、プロダクトオーナー、スクラムマスター\n" +" ・スプリントの レビュー、デイリーミーティング、フィードバック\n" +" ・ 製品バックログ\n" +" ・ スプリントバックログ\n" +"\n" +"それは、プロジェクト管理モジュールに幾つかのコンセプトを追加します:\n" +" ・ 中期、長期のロードマップ\n" +" ・ 顧客 / 機能の要求 VS 技術的な要求\n" +"\n" +"それは新しいレポートも作成します:\n" +" ・ バーンダウンチャート\n" +"\n" +"Scrumプロジェクトとタスクは実際のプロジェクトとタスクから継承されています。\n" +"通常のタスクにはScrumプロジェクトからのタスクも含まれているため、その仕事を\n" +"続ける事ができます。\n" +"\n" +"方法論についてのさらなる情報:\n" +" ・ http://controlchaos.com\n" +" " #. module: base #: code:addons/base/ir/ir_model.py:371 @@ -13581,7 +13663,7 @@ msgstr "" msgid "" "Changing the type of a column is not yet supported. Please drop it and " "create it again!" -msgstr "" +msgstr "列のタイプの変更は現在サポートされていません。削除後、再作成して下さい。" #. module: base #: field:ir.ui.view_sc,user_id:0 @@ -13592,12 +13674,12 @@ msgstr "ユーザの参照" #: code:addons/base/res/res_users.py:118 #, python-format msgid "Warning !" -msgstr "" +msgstr "警告!" #. module: base #: model:res.widget,title:base.google_maps_widget msgid "Google Maps" -msgstr "" +msgstr "Google マップ" #. module: base #: model:ir.ui.menu,name:base.menu_base_config @@ -13609,7 +13691,7 @@ msgstr "" #: view:res.company:0 #: model:res.groups,name:base.group_system msgid "Configuration" -msgstr "" +msgstr "設定" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_in @@ -13619,12 +13701,12 @@ msgstr "インド-会計" #. module: base #: field:ir.actions.server,expression:0 msgid "Loop Expression" -msgstr "" +msgstr "ループ式" #. module: base #: field:publisher_warranty.contract,date_start:0 msgid "Starting Date" -msgstr "" +msgstr "開始日" #. module: base #: model:ir.module.module,shortdesc:base.module_l10n_gt @@ -13634,12 +13716,12 @@ msgstr "グアテマラ-会計" #. module: base #: help:ir.cron,args:0 msgid "Arguments to be passed to the method, e.g. (uid,)." -msgstr "" +msgstr "メソッドに渡される引数、例(UID)。" #. module: base #: model:res.partner.category,name:base.res_partner_category_5 msgid "Gold Partner" -msgstr "" +msgstr "ゴールドパートナ" #. module: base #: model:ir.model,name:base.model_res_partner @@ -13649,34 +13731,34 @@ msgstr "" #: selection:res.partner.title,domain:0 #: model:res.request.link,name:base.req_link_partner msgid "Partner" -msgstr "" +msgstr "パートナ" #. module: base #: field:ir.model.fields,complete_name:0 #: field:ir.ui.menu,complete_name:0 msgid "Complete Name" -msgstr "" +msgstr "完全な名前" #. module: base #: model:res.country,name:base.tr msgid "Turkey" -msgstr "" +msgstr "トルコ" #. module: base #: model:res.country,name:base.fk msgid "Falkland Islands" -msgstr "" +msgstr "フォークランド諸島" #. module: base #: model:res.country,name:base.lb msgid "Lebanon" -msgstr "" +msgstr "レバノン" #. module: base #: view:ir.actions.report.xml:0 #: field:ir.actions.report.xml,report_type:0 msgid "Report Type" -msgstr "" +msgstr "レポートタイプ" #. module: base #: field:ir.actions.todo,state:0 @@ -13689,7 +13771,7 @@ msgstr "" #: field:workflow.instance,state:0 #: field:workflow.workitem,state:0 msgid "State" -msgstr "" +msgstr "状態" #. module: base #: model:ir.module.module,description:base.module_hr_evaluation @@ -13707,6 +13789,16 @@ msgid "" "in the form of pdf file. Implements a dashboard for My Current Evaluations\n" " " msgstr "" +"\n" +"従業員の評価を作成する機能\n" +"=======================================\n" +"\n" +"評価は彼の管理者と同様に部下や後輩のために従業員によって作成することができます。\n" +"その評価は様々な調査を作成され、そして従業員階層のどのレベルが何を満たすかを定義\n" +"された計画の下で実行されます。そして最終レビューと評価は管理者によって実行されます。\n" +"全ての評価は従業員によってファイルされ、それはPDFファイルの形式で見ることができます。\n" +"自身の現在の評価のためにダッシュボードを実装しています。\n" +" " #. module: base #: selection:base.language.install,lang:0 @@ -13716,7 +13808,7 @@ msgstr "ガリラヤ語 / Galego" #. module: base #: model:res.country,name:base.no msgid "Norway" -msgstr "" +msgstr "ノルウェー" #. module: base #: view:res.lang:0 @@ -13727,17 +13819,17 @@ msgstr "" #: view:base.language.install:0 #: model:ir.ui.menu,name:base.menu_view_base_language_install msgid "Load an Official Translation" -msgstr "" +msgstr "公式の翻訳をロード" #. module: base #: view:res.currency:0 msgid "Miscelleanous" -msgstr "" +msgstr "その他" #. module: base #: model:res.partner.category,name:base.res_partner_category_10 msgid "Open Source Service Company" -msgstr "" +msgstr "オープンソースサービス会社" #. module: base #: selection:base.language.install,lang:0 @@ -13747,12 +13839,12 @@ msgstr "シンハラ語 / සිංහල" #. module: base #: selection:res.request,state:0 msgid "waiting" -msgstr "" +msgstr "待機中" #. module: base #: field:ir.actions.report.xml,report_file:0 msgid "Report file" -msgstr "" +msgstr "レポートファイル" #. module: base #: model:ir.model,name:base.model_workflow_triggers @@ -13763,24 +13855,24 @@ msgstr "" #: code:addons/base/ir/ir_model.py:74 #, python-format msgid "Invalid search criterions" -msgstr "" +msgstr "検索基準が無効です。" #. module: base #: view:ir.mail_server:0 msgid "Connection Information" -msgstr "" +msgstr "接続情報" #. module: base #: view:ir.attachment:0 msgid "Created" -msgstr "" +msgstr "作成済" #. module: base #: help:ir.actions.wizard,multi:0 msgid "" "If set to true, the wizard will not be displayed on the right toolbar of a " "form view." -msgstr "" +msgstr "Trueにセットする場合、ウィザードはフォームビューの右のツールバー上には表示されません。" #. module: base #: view:base.language.import:0 @@ -13790,7 +13882,7 @@ msgstr "" #. module: base #: model:res.country,name:base.hm msgid "Heard and McDonald Islands" -msgstr "" +msgstr "ハード島とマクドナルド諸島" #. module: base #: help:ir.model.data,name:0 @@ -15067,11 +15159,11 @@ msgid "" " " msgstr "" "\n" -"この基本モジュールは分析的な分類と仕入注文を管理します。\n" +"この基本モジュールは分析的な分類と発注オーダーを管理します。\n" "====================================================================\n" "\n" "ユーザは複数の分析計画を維持することができます。\n" -"これはあなたに仕入先の仕入注文のラインを複数のアカウントと分析計画に分割させます。\n" +"仕入先の発注オーダーのラインを複数のアカウントと分析計画に分割します。\n" " " #. module: base @@ -15223,7 +15315,7 @@ msgstr "スペイン-会計(PGCE 2008)" #. module: base #: model:ir.module.module,shortdesc:base.module_stock_no_autopicking msgid "Picking Before Manufacturing" -msgstr "" +msgstr "製造前のピッキング" #. module: base #: model:res.country,name:base.wf @@ -15668,8 +15760,8 @@ msgid "" "Check this box if the partner is a supplier. If it's not checked, purchase " "people will not see it when encoding a purchase order." msgstr "" -"パートナが仕入先である場合は、このチェックボックスをオンにして下さい。それをチェックしない場合は、仕入注文をエンコードする際に、仕入の人々はそれを見ること" -"はできません。" +"パートナが仕入先である場合は、このチェックボックスをオンにして下さい。それをチェックしない場合は、発注オーダーをエンコードする際に、仕入の人々はそれを見る" +"ことはできません。" #. module: base #: field:ir.actions.server,trigger_obj_id:0 @@ -16881,7 +16973,7 @@ msgstr "" msgid "" "Helps you manage your manufacturing processes and generate reports on those " "processes." -msgstr "" +msgstr "製造プロセスを管理し、それらのプロセスのレポート作成を手助けします。" #. module: base #: help:ir.sequence,number_increment:0 @@ -16983,7 +17075,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_stock_invoice_directly msgid "Invoice Picking Directly" -msgstr "" +msgstr "直接ピッキングの請求書" #. module: base #: selection:base.language.install,lang:0 diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py index 236c6af7119..db3c7fcdbae 100644 --- a/openerp/addons/base/ir/ir_actions.py +++ b/openerp/addons/base/ir/ir_actions.py @@ -510,7 +510,7 @@ class actions_server(osv.osv): 'code':fields.text('Python Code', help="Python code to be executed if condition is met.\n" "It is a Python block that can use the same values as for the condition field"), 'sequence': fields.integer('Sequence', help="Important when you deal with multiple actions, the execution order will be decided based on this, low number is higher priority."), - 'model_id': fields.many2one('ir.model', 'Object', required=True, help="Select the object on which the action will work (read, write, create)."), + 'model_id': fields.many2one('ir.model', 'Object', required=True, help="Select the object on which the action will work (read, write, create).", ondelete='cascade'), 'action_id': fields.many2one('ir.actions.actions', 'Client Action', help="Select the Action Window, Report, Wizard to be executed."), 'trigger_name': fields.selection(_select_signals, string='Trigger Signal', size=128, help="The workflow signal to trigger"), 'wkf_model_id': fields.many2one('ir.model', 'Target Object', help="The object that should receive the workflow signal (must have an associated workflow)"), diff --git a/openerp/addons/base/ir/ir_model.py b/openerp/addons/base/ir/ir_model.py index fdce0d7c483..1af5818438a 100644 --- a/openerp/addons/base/ir/ir_model.py +++ b/openerp/addons/base/ir/ir_model.py @@ -1,8 +1,9 @@ # -*- coding: utf-8 -*- + ############################################################################## # -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2009 Tiny SPRL (). +# OpenERP, Open Source Business Applications +# Copyright (C) 2004-2012 OpenERP S.A. (). # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -23,20 +24,21 @@ import re import time import types -from osv import fields,osv -import netsvc -from osv.orm import except_orm, browse_record -import tools -from tools.safe_eval import safe_eval as eval -from tools import config -from tools.translate import _ -import pooler +from openerp.osv import fields,osv +from openerp import netsvc, pooler, tools +from openerp.tools.safe_eval import safe_eval as eval +from openerp.tools import config +from openerp.tools.translate import _ +from openerp.osv.orm import except_orm, browse_record, EXT_ID_PREFIX_FK, \ + EXT_ID_PREFIX_M2M_TABLE, EXT_ID_PREFIX_CONSTRAINT _logger = logging.getLogger(__name__) +MODULE_UNINSTALL_FLAG = '_force_unlink' + def _get_fields_type(self, cr, uid, context=None): # Avoid too many nested `if`s below, as RedHat's Python 2.6 - # break on it. See bug 939653. + # break on it. See bug 939653. return sorted([(k,k) for k,v in fields.__dict__.iteritems() if type(v) == types.TypeType and \ issubclass(v, fields._column) and \ @@ -73,7 +75,7 @@ class ir_model(osv.osv): def _search_osv_memory(self, cr, uid, model, name, domain, context=None): if not domain: return [] - field, operator, value = domain[0] + __, operator, value = domain[0] if operator not in ['=', '!=']: raise osv.except_osv(_('Invalid search criterions'), _('The osv_memory field can only be compared with = and != operator.')) value = bool(value) if operator == '=' else not bool(value) @@ -136,13 +138,33 @@ class ir_model(osv.osv): super(ir_model, self).search(cr, uid, domain, limit=limit, context=context), context=context) + def _drop_table(self, cr, uid, ids, context=None): + for model in self.browse(cr, uid, ids, context): + model_pool = self.pool.get(model.model) + cr.execute('select relkind from pg_class where relname=%s', (model_pool._table,)) + result = cr.fetchone() + if result and result[0] == 'v': + cr.execute('DROP view %s' % (model_pool._table,)) + elif result and result[0] == 'r': + cr.execute('DROP TABLE %s' % (model_pool._table,)) + return True def unlink(self, cr, user, ids, context=None): - for model in self.browse(cr, user, ids, context): - if model.state != 'manual': - raise except_orm(_('Error'), _("You can not remove the model '%s' !") %(model.name,)) + # Prevent manual deletion of module tables + if context is None: context = {} + if isinstance(ids, (int, long)): + ids = [ids] + if not context.get(MODULE_UNINSTALL_FLAG) and \ + any(model.state != 'manual' for model in self.browse(cr, user, ids, context)): + raise except_orm(_('Error'), _("Model '%s' contains module data and cannot be removed!") % (model.name,)) + + self._drop_table(cr, user, ids, context) res = super(ir_model, self).unlink(cr, user, ids, context) - pooler.restart_pool(cr.dbname) + if not context.get(MODULE_UNINSTALL_FLAG): + # only reload pool for normal unlink. For module uninstall the + # reload is done independently in openerp.modules.loading + pooler.restart_pool(cr.dbname) + return res def write(self, cr, user, ids, vals, context=None): @@ -266,16 +288,30 @@ class ir_model_fields(osv.osv): ('size_gt_zero', 'CHECK (size>0)',_size_gt_zero_msg ), ] + def _drop_column(self, cr, uid, ids, context=None): + for field in self.browse(cr, uid, ids, context): + model = self.pool.get(field.model) + cr.execute('select relkind from pg_class where relname=%s', (model._table,)) + result = cr.fetchone() + cr.execute("SELECT column_name FROM information_schema.columns WHERE table_name ='%s' and column_name='%s'" %(model._table, field.name)) + column_name = cr.fetchone() + if column_name and (result and result[0] == 'r'): + cr.execute('ALTER table "%s" DROP column "%s" cascade' % (model._table, field.name)) + model._columns.pop(field.name, None) + return True + def unlink(self, cr, user, ids, context=None): - for field in self.browse(cr, user, ids, context): - if field.state <> 'manual': - raise except_orm(_('Error'), _("You cannot remove the field '%s' !") %(field.name,)) - # - # MAY BE ADD A ALTER TABLE DROP ? - # - #Removing _columns entry for that table - self.pool.get(field.model)._columns.pop(field.name,None) - return super(ir_model_fields, self).unlink(cr, user, ids, context) + # Prevent manual deletion of module columns + if context is None: context = {} + if isinstance(ids, (int, long)): + ids = [ids] + if not context.get(MODULE_UNINSTALL_FLAG) and \ + any(field.state != 'manual' for field in self.browse(cr, user, ids, context)): + raise except_orm(_('Error'), _("This column contains module data and cannot be removed!")) + + self._drop_column(cr, user, ids, context) + res = super(ir_model_fields, self).unlink(cr, user, ids, context) + return res def create(self, cr, user, vals, context=None): if 'model_id' in vals: @@ -295,7 +331,7 @@ class ir_model_fields(osv.osv): raise except_orm(_('Error'), _("Custom fields must have a name that starts with 'x_' !")) if vals.get('relation',False) and not self.pool.get('ir.model').search(cr, user, [('model','=',vals['relation'])]): - raise except_orm(_('Error'), _("Model %s does not exist!") % vals['relation']) + raise except_orm(_('Error'), _("Model %s does not exist!") % vals['relation']) if self.pool.get(vals['model']): self.pool.get(vals['model']).__init__(self.pool, cr) @@ -414,7 +450,7 @@ class ir_model_fields(osv.osv): ctx = context.copy() ctx.update({'select': vals.get('select_level','0'),'update_custom_fields':True}) - for model_key, patch_struct in models_patch.items(): + for __, patch_struct in models_patch.items(): obj = patch_struct[0] for col_name, col_prop, val in patch_struct[1]: setattr(obj._columns[col_name], col_prop, val) @@ -622,10 +658,10 @@ class ir_model_data(osv.osv): def __init__(self, pool, cr): osv.osv.__init__(self, pool, cr) self.doinit = True - # also stored in pool to avoid being discarded along with this osv instance if getattr(pool, 'model_data_reference_ids', None) is None: self.pool.model_data_reference_ids = {} + self.loads = self.pool.model_data_reference_ids def _auto_init(self, cr, context=None): @@ -670,6 +706,7 @@ class ir_model_data(osv.osv): id = False return id + def unlink(self, cr, uid, ids, context=None): """ Regular unlink method, but make sure to clear the caches. """ self._get_id.clear_cache(self) @@ -680,17 +717,14 @@ class ir_model_data(osv.osv): model_obj = self.pool.get(model) if not context: context = {} - # records created during module install should result in res.log entries that are already read! context = dict(context, res_log_read=True) - if xml_id and ('.' in xml_id): assert len(xml_id.split('.'))==2, _("'%s' contains too many dots. XML ids should not contain dots ! These are used to refer to other modules data, as in module.reference_id") % (xml_id) module, xml_id = xml_id.split('.') if (not xml_id) and (not self.doinit): return False action_id = False - if xml_id: cr.execute('''SELECT imd.id, imd.res_id, md.id, imd.model FROM ir_model_data imd LEFT JOIN %s md ON (imd.res_id = md.id) @@ -794,52 +828,139 @@ class ir_model_data(osv.osv): cr.execute('UPDATE ir_values set value=%s WHERE model=%s and key=%s and name=%s'+where,(value, model, key, name)) return True + def _module_data_uninstall(self, cr, uid, ids, context=None): + """Deletes all the records referenced by the ir.model.data entries + ``ids`` along with their corresponding database backed (including + dropping tables, columns, FKs, etc, as long as there is no other + ir.model.data entry holding a reference to them (which indicates that + they are still owned by another module). + Attempts to perform the deletion in an appropriate order to maximize + the chance of gracefully deleting all records. + This step is performed as part of the full uninstallation of a module. + """ + + if uid != 1 and not self.pool.get('ir.model.access').check_groups(cr, uid, "base.group_system"): + raise except_orm(_('Permission Denied'), (_('Administrator access is required to uninstall a module'))) + + context = dict(context or {}) + context[MODULE_UNINSTALL_FLAG] = True # enable model/field deletion + + ids_set = set(ids) + wkf_todo = [] + to_unlink = [] + to_drop_table = [] + ids.sort() + ids.reverse() + for data in self.browse(cr, uid, ids, context): + model = data.model + res_id = data.res_id + model_obj = self.pool.get(model) + name = tools.ustr(data.name) + + if name.startswith(EXT_ID_PREFIX_FK) or name.startswith(EXT_ID_PREFIX_M2M_TABLE)\ + or name.startswith(EXT_ID_PREFIX_CONSTRAINT): + # double-check we are really going to delete all the owners of this schema element + cr.execute("""SELECT id from ir_model_data where name = %s and res_id IS NULL""", (data.name,)) + external_ids = [x[0] for x in cr.fetchall()] + if (set(external_ids)-ids_set): + # as installed modules have defined this element we must not delete it! + continue + + if name.startswith(EXT_ID_PREFIX_FK): + name = name[len(EXT_ID_PREFIX_FK):] + # test if FK exists on this table (it could be on a related m2m table, in which case we ignore it) + cr.execute("""SELECT 1 from pg_constraint cs JOIN pg_class cl ON (cs.conrelid = cl.oid) + WHERE cs.contype=%s and cs.conname=%s and cl.relname=%s""", ('f', name, model_obj._table)) + if cr.fetchone(): + cr.execute('ALTER TABLE "%s" DROP CONSTRAINT "%s"' % (model_obj._table, name),) + _logger.info('Dropped FK CONSTRAINT %s@%s', name, model) + continue + + if name.startswith(EXT_ID_PREFIX_M2M_TABLE): + name = name[len(EXT_ID_PREFIX_M2M_TABLE):] + cr.execute("SELECT 1 FROM information_schema.tables WHERE table_name=%s", (name,)) + if cr.fetchone() and not name in to_drop_table: + to_drop_table.append(name) + continue + + if name.startswith(EXT_ID_PREFIX_CONSTRAINT): + name = name[len(EXT_ID_PREFIX_CONSTRAINT):] + # test if constraint exists + cr.execute("""SELECT 1 from pg_constraint cs JOIN pg_class cl ON (cs.conrelid = cl.oid) + WHERE cs.contype=%s and cs.conname=%s and cl.relname=%s""", ('u', name, model_obj._table)) + if cr.fetchone(): + cr.execute('ALTER TABLE "%s" DROP CONSTRAINT "%s"' % (model_obj._table, name),) + _logger.info('Dropped CONSTRAINT %s@%s', name, model) + continue + + pair_to_unlink = (model, res_id) + if pair_to_unlink not in to_unlink: + to_unlink.append(pair_to_unlink) + + if model == 'workflow.activity': + # Special treatment for workflow activities: temporarily revert their + # incoming transition and trigger an update to force all workflow items + # to move out before deleting them + cr.execute('select res_type,res_id from wkf_instance where id IN (select inst_id from wkf_workitem where act_id=%s)', (res_id,)) + wkf_todo.extend(cr.fetchall()) + cr.execute("update wkf_transition set condition='True', group_id=NULL, signal=NULL,act_to=act_from,act_from=%s where act_to=%s", (res_id,res_id)) + + wf_service = netsvc.LocalService("workflow") + for model,res_id in wkf_todo: + try: + wf_service.trg_write(uid, model, res_id, cr) + except: + _logger.info('Unable to force processing of workflow for item %s@%s in order to leave activity to be deleted', res_id, model) + + # drop m2m relation tables + for table in to_drop_table: + cr.execute('DROP TABLE %s CASCADE'% (table),) + _logger.info('Dropped table %s', table) + + def unlink_if_refcount(to_unlink): + for model, res_id in to_unlink: + external_ids = self.search(cr, uid, [('model', '=', model),('res_id', '=', res_id)]) + if (set(external_ids)-ids_set): + # if other modules have defined this record, we must not delete it + return + _logger.info('Deleting %s@%s', res_id, model) + try: + self.pool.get(model).unlink(cr, uid, [res_id], context=context) + except: + _logger.info('Unable to delete %s@%s', res_id, model, exc_info=True) + + # Remove non-model records first, then model fields, and finish with models + unlink_if_refcount((model, res_id) for model, res_id in to_unlink + if model not in ('ir.model','ir.model.fields')) + unlink_if_refcount((model, res_id) for model, res_id in to_unlink + if model == 'ir.model.fields') + unlink_if_refcount((model, res_id) for model, res_id in to_unlink + if model == 'ir.model') + + cr.commit() + def _process_end(self, cr, uid, modules): """ Clear records removed from updated module data. - This method is called at the end of the module loading process. It is meant to removed records that are no longer present in the updated data. Such records are recognised as the one with an xml id and a module in ir_model_data and noupdate set to false, but not present in self.loads. - """ if not modules: return True - modules = list(modules) - module_in = ",".join(["%s"] * len(modules)) - cr.execute('select id,name,model,res_id,module from ir_model_data where module IN (' + module_in + ') and noupdate=%s', modules + [False]) - wkf_todo = [] to_unlink = [] - for (id, name, model, res_id,module) in cr.fetchall(): + cr.execute("""SELECT id,name,model,res_id,module FROM ir_model_data + WHERE module IN %s AND res_id IS NOT NULL AND noupdate=%s""", + (tuple(modules), False)) + for (id, name, model, res_id, module) in cr.fetchall(): if (module,name) not in self.loads: to_unlink.append((model,res_id)) - if model=='workflow.activity': - cr.execute('select res_type,res_id from wkf_instance where id IN (select inst_id from wkf_workitem where act_id=%s)', (res_id,)) - wkf_todo.extend(cr.fetchall()) - cr.execute("update wkf_transition set condition='True', group_id=NULL, signal=NULL,act_to=act_from,act_from=%s where act_to=%s", (res_id,res_id)) - cr.execute("delete from wkf_transition where act_to=%s", (res_id,)) - - for model,id in wkf_todo: - wf_service = netsvc.LocalService("workflow") - wf_service.trg_write(uid, model, id, cr) - - cr.commit() if not config.get('import_partial'): for (model, res_id) in to_unlink: if self.pool.get(model): _logger.info('Deleting %s@%s', res_id, model) - try: - self.pool.get(model).unlink(cr, uid, [res_id]) - cr.commit() - except Exception: - cr.rollback() - _logger.warning( - 'Could not delete obsolete record with id: %d of model %s\n' - 'There should be some relation that points to this resource\n' - 'You should manually fix this and restart with --update=module', - res_id, model) - return True -ir_model_data() + self.pool.get(model).unlink(cr, uid, [res_id]) + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/base/ir/workflow/workflow.py b/openerp/addons/base/ir/workflow/workflow.py index edd070ae50d..925d4700663 100644 --- a/openerp/addons/base/ir/workflow/workflow.py +++ b/openerp/addons/base/ir/workflow/workflow.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- ############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2009 Tiny SPRL (). +# +# OpenERP, Open Source Business Applications +# Copyright (C) 2004-2012 OpenERP S.A. (). # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -15,19 +15,18 @@ # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . +# along with this program. If not, see . # ############################################################################## -from osv import fields, osv -from tools import graph -import netsvc +from openerp.osv import fields, osv +from openerp.tools.translate import _ +from openerp import netsvc class workflow(osv.osv): _name = "workflow" _table = "wkf" _order = "name" - # _log_access = False _columns = { 'name': fields.char('Name', size=64, required=True), 'osv': fields.char('Resource Object', size=64, required=True,select=True), @@ -46,78 +45,33 @@ class workflow(osv.osv): return super(workflow, self).write(cr, user, ids, vals, context=context) def get_active_workitems(self, cr, uid, res, res_id, context=None): - cr.execute('select * from wkf where osv=%s limit 1',(res,)) wkfinfo = cr.dictfetchone() workitems = [] - if wkfinfo: cr.execute('SELECT id FROM wkf_instance \ WHERE res_id=%s AND wkf_id=%s \ ORDER BY state LIMIT 1', (res_id, wkfinfo['id'])) inst_id = cr.fetchone() - + cr.execute('select act_id,count(*) from wkf_workitem where inst_id=%s group by act_id', (inst_id,)) - workitems = dict(cr.fetchall()) - + workitems = dict(cr.fetchall()) return {'wkf': wkfinfo, 'workitems': workitems} - - # - # scale = (vertical-distance, horizontal-distance, min-node-width(optional), min-node-height(optional), margin(default=20)) - # - - -# def graph_get(self, cr, uid, id, scale, context={}): -# -# nodes= [] -# nodes_name = [] -# transitions = [] -# start = [] -# tres = {} -# no_ancester = [] -# workflow = self.browse(cr, uid, id, context) -# for a in workflow.activities: -# nodes_name.append((a.id,a.name)) -# nodes.append(a.id) -# if a.flow_start: -# start.append(a.id) -# else: -# if not a.in_transitions: -# no_ancester.append(a.id) -# -# for t in a.out_transitions: -# transitions.append((a.id, t.act_to.id)) -# tres[t.id] = (a.id, t.act_to.id) -# -# -# g = graph(nodes, transitions, no_ancester) -# g.process(start) -# g.scale(*scale) -# result = g.result_get() -# results = {} -# -# for node in nodes_name: -# results[str(node[0])] = result[node[0]] -# results[str(node[0])]['name'] = node[1] -# -# return {'nodes': results, 'transitions': tres} - - def create(self, cr, user, vals, context=None): if not context: context={} wf_service = netsvc.LocalService("workflow") wf_service.clear_cache(cr, user) return super(workflow, self).create(cr, user, vals, context=context) + workflow() class wkf_activity(osv.osv): _name = "workflow.activity" _table = "wkf_activity" _order = "name" - # _log_access = False _columns = { 'name': fields.char('Name', size=64, required=True), 'wkf_id': fields.many2one('workflow', 'Workflow', required=True, select=True, ondelete='cascade'), @@ -138,22 +92,29 @@ class wkf_activity(osv.osv): 'join_mode': lambda *a: 'XOR', 'split_mode': lambda *a: 'XOR', } + + def unlink(self, cr, uid, ids, context=None): + if context is None: context = {} + if not context.get('_force_unlink') and self.pool.get('workflow.workitem').search(cr, uid, [('act_id', 'in', ids)]): + raise osv.except_osv(_('Operation forbidden'), + _('Please make sure no workitems refer to an activity before deleting it!')) + super(wkf_activity, self).unlink(cr, uid, ids, context=context) + wkf_activity() class wkf_transition(osv.osv): _table = "wkf_transition" _name = "workflow.transition" - # _log_access = False _rec_name = 'signal' _columns = { 'trigger_model': fields.char('Trigger Object', size=128), 'trigger_expr_id': fields.char('Trigger Expression', size=128), - 'signal': fields.char('Signal (button Name)', size=64, + 'signal': fields.char('Signal (button Name)', size=64, help="When the operation of transition comes from a button pressed in the client form, "\ "signal tests the name of the pressed button. If signal is NULL, no button is necessary to validate this transition."), - 'group_id': fields.many2one('res.groups', 'Group Required', + 'group_id': fields.many2one('res.groups', 'Group Required', help="The group that a user must have to be authorized to validate this transition."), - 'condition': fields.char('Condition', required=True, size=128, + 'condition': fields.char('Condition', required=True, size=128, help="Expression to be satisfied if we want the transition done."), 'act_from': fields.many2one('workflow.activity', 'Source Activity', required=True, select=True, ondelete='cascade', help="Source activity. When this activity is over, the condition is tested to determine if we can start the ACT_TO activity."), @@ -194,7 +155,7 @@ class wkf_workitem(osv.osv): _log_access = False _rec_name = 'state' _columns = { - 'act_id': fields.many2one('workflow.activity', 'Activity', required=True, ondelete="restrict", select=True), + 'act_id': fields.many2one('workflow.activity', 'Activity', required=True, ondelete="cascade", select=True), 'wkf_id': fields.related('act_id','wkf_id', type='many2one', relation='workflow', string='Workflow'), 'subflow_id': fields.many2one('workflow.instance', 'Subflow', ondelete="cascade", select=True), 'inst_id': fields.many2one('workflow.instance', 'Instance', required=True, ondelete="cascade", select=True), diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index cb484520058..acf22923d14 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -2,8 +2,7 @@ ############################################################################## # # OpenERP, Open Source Management Solution -# Copyright (C) 2004-2009 Tiny SPRL (). -# Copyright (C) 2010 OpenERP s.a. (). +# Copyright (C) 2004-2012 OpenERP S.A. (). # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -19,26 +18,16 @@ # along with this program. If not, see . # ############################################################################## -import base64 -import cStringIO import imp import logging -import os import re -import StringIO import urllib -import zipfile import zipimport -import openerp.modules as addons -import pooler -import release -import tools - -from tools.parse_version import parse_version -from tools.translate import _ - -from osv import fields, osv, orm +from openerp import modules, pooler, release, tools +from openerp.tools.parse_version import parse_version +from openerp.tools.translate import _ +from openerp.osv import fields, osv, orm _logger = logging.getLogger(__name__) @@ -95,7 +84,7 @@ class module(osv.osv): def get_module_info(cls, name): info = {} try: - info = addons.load_information_from_description_file(name) + info = modules.load_information_from_description_file(name) info['version'] = release.major_version + '.' + info['version'] except Exception: _logger.debug('Error when trying to fetch informations for ' @@ -123,7 +112,7 @@ class module(osv.osv): if field_name is None or 'menus_by_module' in field_name: dmodels.append('ir.ui.menu') assert dmodels, "no models for %s" % field_name - + for module_rec in self.browse(cr, uid, ids, context=context): res[module_rec.id] = { 'menus_by_module': [], @@ -165,7 +154,7 @@ class module(osv.osv): except Exception, e: _logger.warning('Unknown error while fetching data of %s', module_rec.name, exc_info=True) - for key, value in res.iteritems(): + for key, _ in res.iteritems(): for k, v in res[key].iteritems(): res[key][k] = "\n".join(sorted(v)) return res @@ -184,7 +173,7 @@ class module(osv.osv): # installed_version refer the latest version (the one on disk) # latest_version refer the installed version (the one in database) # published_version refer the version available on the repository - 'installed_version': fields.function(_get_latest_version, + 'installed_version': fields.function(_get_latest_version, string='Latest version', type='char'), 'latest_version': fields.char('Installed version', size=64, readonly=True), 'published_version': fields.char('Published Version', size=64, readonly=True), @@ -276,7 +265,7 @@ class module(osv.osv): while parts: part = parts.pop() try: - f, path, descr = imp.find_module(part, path and [path] or None) + _, path, _ = imp.find_module(part, path and [path] or None) except ImportError: raise ImportError('No module named %s' % (pydep,)) @@ -343,7 +332,6 @@ class module(osv.osv): # Mark them to be installed. if to_install_ids: self.button_install(cr, uid, to_install_ids, context=context) - return dict(ACTION_DICT, name=_('Install')) def button_immediate_install(self, cr, uid, ids, context=None): @@ -356,7 +344,7 @@ class module(osv.osv): """ self.button_install(cr, uid, ids, context=context) cr.commit() - db, pool = pooler.restart_pool(cr.dbname, update_module=True) + _, pool = pooler.restart_pool(cr.dbname, update_module=True) config = pool.get('res.config').next(cr, uid, [], context=context) or {} if config.get('type') not in ('ir.actions.reload', 'ir.actions.act_window_close'): @@ -376,20 +364,49 @@ class module(osv.osv): self.write(cr, uid, ids, {'state': 'uninstalled', 'demo':False}) return True + def module_uninstall(self, cr, uid, ids, context=None): + """Perform the various steps required to uninstall a module completely + including the deletion of all database structures created by the module: + tables, columns, constraints, etc.""" + ir_model_data = self.pool.get('ir.model.data') + modules_to_remove = [m.name for m in self.browse(cr, uid, ids, context)] + data_ids = ir_model_data.search(cr, uid, [('module', 'in', modules_to_remove)]) + ir_model_data._module_data_uninstall(cr, uid, data_ids, context) + ir_model_data.unlink(cr, uid, data_ids, context) + self.write(cr, uid, ids, {'state': 'uninstalled'}) + return True + + def downstream_dependencies(self, cr, uid, ids, known_dep_ids=None, + exclude_states=['uninstalled','uninstallable','to remove'], + context=None): + """Return the ids of all modules that directly or indirectly depend + on the given module `ids`, and that satisfy the `exclude_states` + filter""" + if not ids: return [] + known_dep_ids = set(known_dep_ids or []) + cr.execute('''SELECT DISTINCT m.id + FROM + ir_module_module_dependency d + JOIN + ir_module_module m ON (d.module_id=m.id) + WHERE + d.name IN (SELECT name from ir_module_module where id in %s) AND + m.state NOT IN %s AND + m.id NOT IN %s ''', + (tuple(ids),tuple(exclude_states), tuple(known_dep_ids or ids))) + new_dep_ids = set([m[0] for m in cr.fetchall()]) + missing_mod_ids = new_dep_ids - known_dep_ids + known_dep_ids |= new_dep_ids + if missing_mod_ids: + known_dep_ids |= set(self.downstream_dependencies(cr, uid, list(missing_mod_ids), + known_dep_ids, exclude_states,context)) + return list(known_dep_ids) + def button_uninstall(self, cr, uid, ids, context=None): - for module in self.browse(cr, uid, ids): - cr.execute('''select m.state,m.name - from - ir_module_module_dependency d - join - ir_module_module m on (d.module_id=m.id) - where - d.name=%s and - m.state not in ('uninstalled','uninstallable','to remove')''', (module.name,)) - res = cr.fetchall() - if res: - raise orm.except_orm(_('Error'), _('Some installed modules depend on the module you plan to Uninstall :\n %s') % '\n'.join(map(lambda x: '\t%s: %s' % (x[0], x[1]), res))) - self.write(cr, uid, ids, {'state': 'to remove'}) + if any(m.name == 'base' for m in self.browse(cr, uid, ids)): + raise orm.except_orm(_('Error'), _("The `base` module cannot be uninstalled")) + dep_ids = self.downstream_dependencies(cr, uid, ids, context=context) + self.write(cr, uid, ids + dep_ids, {'state': 'to remove'}) return dict(ACTION_DICT, name=_('Uninstall')) def button_uninstall_cancel(self, cr, uid, ids, context=None): @@ -463,7 +480,7 @@ class module(osv.osv): known_mods_names = dict([(m.name, m) for m in known_mods]) # iterate through detected modules and update/create them in db - for mod_name in addons.get_modules(): + for mod_name in modules.get_modules(): mod = known_mods_names.get(mod_name) terp = self.get_module_info(mod_name) values = self.get_values_from_terp(terp) @@ -472,7 +489,7 @@ class module(osv.osv): updated_values = {} for key in values: old = getattr(mod, key) - updated = isinstance(values[key], basestring) and tools.ustr(values[key]) or values[key] + updated = isinstance(values[key], basestring) and tools.ustr(values[key]) or values[key] if not old == updated: updated_values[key] = values[key] if terp.get('installable', True) and mod.state == 'uninstallable': @@ -482,7 +499,7 @@ class module(osv.osv): if updated_values: self.write(cr, uid, mod.id, updated_values) else: - mod_path = addons.get_module_path(mod_name) + mod_path = modules.get_module_path(mod_name) if not mod_path: continue if not terp or not terp.get('installable', True): @@ -511,7 +528,7 @@ class module(osv.osv): if not download: continue zip_content = urllib.urlopen(mod.url).read() - fname = addons.get_module_path(str(mod.name)+'.zip', downloaded=True) + fname = modules.get_module_path(str(mod.name)+'.zip', downloaded=True) try: with open(fname, 'wb') as fp: fp.write(zip_content) @@ -581,17 +598,17 @@ class module(osv.osv): for mod in self.browse(cr, uid, ids): if mod.state != 'installed': continue - modpath = addons.get_module_path(mod.name) + modpath = modules.get_module_path(mod.name) if not modpath: # unable to find the module. we skip continue for lang in filter_lang: iso_lang = tools.get_iso_codes(lang) - f = addons.get_module_resource(mod.name, 'i18n', iso_lang + '.po') + f = modules.get_module_resource(mod.name, 'i18n', iso_lang + '.po') context2 = context and context.copy() or {} if f and '_' in iso_lang: iso_lang2 = iso_lang.split('_')[0] - f2 = addons.get_module_resource(mod.name, 'i18n', iso_lang2 + '.po') + f2 = modules.get_module_resource(mod.name, 'i18n', iso_lang2 + '.po') if f2: _logger.info('module %s: loading base translation file %s for language %s', mod.name, iso_lang2, lang) tools.trans_load(cr, f2, lang, verbose=False, context=context) @@ -601,7 +618,7 @@ class module(osv.osv): # like "en". if (not f) and '_' in iso_lang: iso_lang = iso_lang.split('_')[0] - f = addons.get_module_resource(mod.name, 'i18n', iso_lang + '.po') + f = modules.get_module_resource(mod.name, 'i18n', iso_lang + '.po') if f: _logger.info('module %s: loading translation file (%s) for language %s', mod.name, iso_lang, lang) tools.trans_load(cr, f, lang, verbose=False, context=context2) @@ -660,8 +677,12 @@ class module_dependency(osv.osv): return result _columns = { + # The dependency name 'name': fields.char('Name', size=128, select=True), + + # The module that depends on it 'module_id': fields.many2one('ir.module.module', 'Module', select=True, ondelete='cascade'), + 'state': fields.function(_state, type='selection', selection=[ ('uninstallable','Uninstallable'), ('uninstalled','Not Installed'), diff --git a/openerp/addons/base/module/module_view.xml b/openerp/addons/base/module/module_view.xml index c1361401414..0005aee98ff 100644 --- a/openerp/addons/base/module/module_view.xml +++ b/openerp/addons/base/module/module_view.xml @@ -153,7 +153,9 @@