merge
bzr revid: pap@tinyerp.co.in-20100721084846-ccj0hs7a9s629xdd bzr revid: pap@tinyerp.co.in-20100721085345-9wkqd3trnlhizbia
This commit is contained in:
commit
c976542d8f
|
@ -8,6 +8,7 @@
|
|||
<field name="view_type">form</field>
|
||||
<field name="domain">[('state','=','draft')]</field>
|
||||
<field name="view_id" ref="view_account_period_tree"/>
|
||||
<field name="help"> After closing a period, you will no longer be able to post entries to the period once it has been closed.</field>
|
||||
</record>
|
||||
<menuitem
|
||||
action="action_account_period_tree"
|
||||
|
|
|
@ -60,6 +60,8 @@
|
|||
<field name="account_payment"/>
|
||||
<field name="account_followup"/>
|
||||
<field name="account_asset"/>
|
||||
<field name="account_voucher"/>
|
||||
<field name="account_voucher_payment"/>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
|
|
|
@ -424,6 +424,7 @@
|
|||
<field name="domain">[('type','=','out_invoice')]</field>
|
||||
<field name="context">{'type':'out_invoice'}</field>
|
||||
<field name="search_view_id" ref="view_account_invoice_filter"/>
|
||||
<field name="help">Most of customer invoices are automatically generate in draft mode by OpenERP flows, following a purchase order for instance. Review, confirm or cancel, pay or refund yours customers invoices here. A manual invoice can be created here.</field>
|
||||
</record>
|
||||
|
||||
<record id="action_invoice_tree1_view1" model="ir.actions.act_window.view">
|
||||
|
@ -449,6 +450,7 @@
|
|||
<field name="domain">[('type','=','in_invoice')]</field>
|
||||
<field name="context">{'type':'in_invoice'}</field>
|
||||
<field name="search_view_id" ref="view_account_invoice_filter"/>
|
||||
<field name="help">Proposal for vendor invoices are usually automatically generate by OpenERP, following a procurement order or a production order for instance. To consult and to check for, or to manually create a customer invoice, use this menu. You can review, confirm or cancel, pay or refund an invoice from the view from of the invoices.</field>
|
||||
</record>
|
||||
<menuitem action="action_invoice_tree2" id="menu_action_invoice_tree2" parent="menu_finance_payables"/>
|
||||
|
||||
|
@ -461,6 +463,7 @@
|
|||
<field name="domain">[('type','=','out_refund')]</field>
|
||||
<field name="context">{'type':'out_refund'}</field>
|
||||
<field name="search_view_id" ref="view_account_invoice_filter"/>
|
||||
<field name="help">A customer refund is a credit note to your customer that cancel invoice or a part of it.</field>
|
||||
</record>
|
||||
|
||||
<record id="action_invoice_tree3_view1" model="ir.actions.act_window.view">
|
||||
|
@ -486,6 +489,7 @@
|
|||
<field name="domain">[('type','=','in_refund')]</field>
|
||||
<field name="context">{'type':'in_refund'}</field>
|
||||
<field name="search_view_id" ref="view_account_invoice_filter"/>
|
||||
<field name="help">A vendor refund is a credit note from your supplier indicating that he refunds part or totality of the invoice sent to you.</field>
|
||||
</record>
|
||||
<menuitem action="action_invoice_tree4" id="menu_action_invoice_tree4" parent="menu_finance_payables"/>
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
<field name="model">account.fiscalyear</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Fiscalyear">
|
||||
<tree colors="blue:state in ('draft');gray:state in ('done') " string="Fiscalyear">
|
||||
<field name="code"/>
|
||||
<field name="name"/>
|
||||
<field name="state"/>
|
||||
|
@ -113,7 +113,7 @@
|
|||
<field name="model">account.period</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Period">
|
||||
<tree colors="blue:state in ('draft');gray:state in ('done') " string="Period">
|
||||
<field name="code"/>
|
||||
<field name="name"/>
|
||||
<field name="date_start"/>
|
||||
|
@ -203,10 +203,9 @@
|
|||
<field name="type">tree</field>
|
||||
<field name="field_parent">child_id</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Chart of accounts" toolbar="1" colors="blue:type in ('view');black:type not in ('view')">
|
||||
<tree colors="blue:type in ('view');black:type in ('other','receivable','payable','consolidation');gray:type in ('closed')" string="Chart of accounts" toolbar="1" >
|
||||
<field name="code"/>
|
||||
<field name="name"/>
|
||||
<field name="parent_id" invisible="1"/>
|
||||
<field name="user_type" invisible="1"/>
|
||||
<field name="debit"/>
|
||||
<field name="credit"/>
|
||||
|
@ -234,7 +233,7 @@
|
|||
<field name="type">tree</field>
|
||||
<field name="field_parent">child_id</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Chart of accounts" toolbar="1" colors="blue:type in ('view');black:type not in ('view')">
|
||||
<tree colors="blue:type in ('view');black:type in ('other','receivable','payable','consolidation');gray:type in ('closed')" string="Chart of accounts" toolbar="1" >
|
||||
<field name="code"/>
|
||||
<field name="name"/>
|
||||
<field name="debit"/>
|
||||
|
@ -484,7 +483,7 @@
|
|||
<group col="6" colspan="4">
|
||||
<field name="name" select="1"/>
|
||||
<field name="date" select="1"/>
|
||||
<field name="journal_id" on_change="onchange_journal_id(journal_id)" select="1"/>
|
||||
<field name="journal_id" domain="[('type', '=', 'bank')]" on_change="onchange_journal_id(journal_id)" select="1"/>
|
||||
<field name="period_id"/>
|
||||
<field name="balance_start"/>
|
||||
<field name="balance_end_real"/>
|
||||
|
@ -657,7 +656,7 @@
|
|||
<field name="model">account.move</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Accounting Entries">
|
||||
<tree colors="blue:state in ('draft');black:state in ('posted')" string="Accounting Entries">
|
||||
<field name="name"/>
|
||||
<field name="date"/>
|
||||
<field name="ref"/>
|
||||
|
@ -851,6 +850,7 @@
|
|||
<field name="domain">[('parent_id','=',False)]</field>
|
||||
<field name="view_type">tree</field>
|
||||
<field name="view_id" ref="view_tax_code_tree"/>
|
||||
<field name="help">Chart of Taxes is a tree view reflecting the structure of the Tax Cases (or tax codes) and shows the current tax situation. The tax chart represents the amount of each area of the tax declaration for your country. It’s presented in a hierarchical structure, which can be modified to fit your needs.</field>
|
||||
</record>
|
||||
<menuitem
|
||||
action="action_tax_code_tree"
|
||||
|
@ -869,7 +869,7 @@
|
|||
<field name="type">tree</field>
|
||||
<field eval="4" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Account Entry Line" editable="top" on_write="on_create_write">
|
||||
<tree colors="blue:state in ('draft');black:state in ('valid')" string="Account Entry Line" editable="top" on_write="on_create_write">
|
||||
<field name="date"/>
|
||||
<field name="period_id"/>
|
||||
<field name="move_id"/>
|
||||
|
@ -1048,7 +1048,7 @@
|
|||
<field name="model">account.move</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Account Entry">
|
||||
<tree colors="blue:state in ('draft');black:state in ('posted')" string="Account Entry">
|
||||
<field name="name"/>
|
||||
<field name="date"/>
|
||||
<field name="ref"/>
|
||||
|
@ -1105,7 +1105,7 @@
|
|||
<field name="statement_id"/>
|
||||
<field name="state"/>
|
||||
</form>
|
||||
<tree editable="top" string="Account Entry Line">
|
||||
<tree colors="blue:state in ('draft');black:state in ('posted')" editable="top" string="Account Entry Line">
|
||||
<field name="ref"/>
|
||||
<field name="invoice"/>
|
||||
<field name="name"/>
|
||||
|
@ -1420,7 +1420,7 @@
|
|||
<field name="model">account.journal.period</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Journals">
|
||||
<tree colors="blue:state in ('draft');gray:state in ('done');black:state in ('printed')" string="Journals">
|
||||
<field icon="icon" name="fiscalyear_id"/>
|
||||
<field name="period_id"/>
|
||||
<field name="journal_id"/>
|
||||
|
@ -1433,6 +1433,7 @@
|
|||
<field name="name">Journals</field>
|
||||
<field name="res_model">account.journal.period</field>
|
||||
<field name="view_type">tree</field>
|
||||
<field name="help">You can look up individual account entries by searching for useful information. To search for account entries, open a journal, then select a record line.</field>
|
||||
</record>
|
||||
<menuitem action="action_account_journal_period_tree" id="menu_action_account_journal_period_tree" parent="account.menu_finance_generic_reporting" sequence="2"/>
|
||||
|
||||
|
@ -1634,7 +1635,7 @@
|
|||
<field name="model">account.subscription</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Entry Subscription">
|
||||
<tree colors="blue:state in ('draft');gray:state in ('done');black:state in ('running')" string="Entry Subscription">
|
||||
<field name="ref"/>
|
||||
<field name="name"/>
|
||||
<field name="date_start"/>
|
||||
|
@ -1736,7 +1737,7 @@
|
|||
<field name="type">tree</field>
|
||||
<field eval="4" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Account Entry Line">
|
||||
<tree colors="blue:state in ('draft');black:state in ('valid')" string="Account Entry Line">
|
||||
<field name="date"/>
|
||||
<field name="move_id"/>
|
||||
<field name="statement_id" string="St."/>
|
||||
|
@ -2290,7 +2291,7 @@
|
|||
<field name="model">account.bank.statement</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="red:balance_end_real!=balance_end;blue:state=='draft' and (balance_end_real==balance_end);black:state in ('open');blue:state in ('draft')" string="Statement">
|
||||
<tree colors="red:balance_end_real!=balance_end;blue:state=='draft' and (balance_end_real==balance_end);black:state in ('open')" string="Statement">
|
||||
<field name="date"/>
|
||||
<field name="name"/>
|
||||
<field name="journal_id"/>
|
||||
|
@ -2298,7 +2299,7 @@
|
|||
<field name="balance_start"/>
|
||||
<field name="balance_end_real"/>
|
||||
<field name="balance_end"/>
|
||||
<field name="user_id" select="1"/>
|
||||
<field name="user_id" select="1"/>
|
||||
<field name="state"/>
|
||||
<button type="object" string="Open" name="button_open" states="draft" icon="terp-camera_test"/>
|
||||
<button type="object" string="Confirm" name="button_confirm_cash" states="open" icon="terp-gtk-go-back-rtl"/>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -13,7 +13,7 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2010-07-19 03:41+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-07-21 03:43+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: account
|
||||
|
|
|
@ -8,13 +8,13 @@ msgstr ""
|
|||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
|
||||
"PO-Revision-Date: 2010-01-11 07:51+0000\n"
|
||||
"Last-Translator: Nguyễn Thịnh <thinhnverp@gmail.com>\n"
|
||||
"PO-Revision-Date: 2010-07-20 03:39+0000\n"
|
||||
"Last-Translator: Business Link Development Technologies <Unknown>\n"
|
||||
"Language-Team: Vietnamese <vi@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: 2010-06-22 04:06+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-07-21 03:43+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: account
|
||||
|
@ -25,28 +25,28 @@ msgstr "Tên nội bộ"
|
|||
#. module: account
|
||||
#: view:account.tax.code:0
|
||||
msgid "Account Tax Code"
|
||||
msgstr ""
|
||||
msgstr "Mã số thuế"
|
||||
|
||||
#. module: account
|
||||
#: model:ir.actions.act_window,name:account.action_invoice_tree9
|
||||
#: model:ir.ui.menu,name:account.menu_action_invoice_tree9
|
||||
msgid "Unpaid Supplier Invoices"
|
||||
msgstr ""
|
||||
msgstr "Hoá đơn từ nhà cung cấp chưa thanh toán"
|
||||
|
||||
#. module: account
|
||||
#: model:ir.ui.menu,name:account.menu_finance_entries
|
||||
msgid "Entries Encoding"
|
||||
msgstr "mục endoding"
|
||||
msgstr "Mã hoá mục"
|
||||
|
||||
#. module: account
|
||||
#: model:ir.actions.todo,note:account.config_wizard_account_base_setup_form
|
||||
msgid "Specify The Message for the Overdue Payment Report."
|
||||
msgstr ""
|
||||
msgstr "Chỉ định Thông báo cho Báo cáo thanh toán quá hạn"
|
||||
|
||||
#. module: account
|
||||
#: model:process.transition,name:account.process_transition_confirmstatementfromdraft0
|
||||
msgid "Confirm statement from draft"
|
||||
msgstr ""
|
||||
msgstr "Xác nhận kê khai tạm"
|
||||
|
||||
#. module: account
|
||||
#: model:account.account.type,name:account.account_type_asset
|
||||
|
@ -61,19 +61,21 @@ msgstr ""
|
|||
#. module: account
|
||||
#: help:account.journal,currency:0
|
||||
msgid "The currency used to enter statement"
|
||||
msgstr ""
|
||||
msgstr "Đơn vị tiền được sử dụng để nhập bảng kê khai"
|
||||
|
||||
#. module: account
|
||||
#: wizard_view:account_use_models,init_form:0
|
||||
msgid "Select Message"
|
||||
msgstr ""
|
||||
msgstr "Lựa chọn thông báo"
|
||||
|
||||
#. module: account
|
||||
#: help:product.category,property_account_income_categ:0
|
||||
msgid ""
|
||||
"This account will be used to value incoming stock for the current product "
|
||||
"category"
|
||||
msgstr "tài khoản này sẽ được dùng cho giá của sản phẩm đưa vào danh mục"
|
||||
msgstr ""
|
||||
"Tài khoản này sẽ được sử dụng để định giá tồn kho sắp đến đối với loại sản "
|
||||
"phẩm này."
|
||||
|
||||
#. module: account
|
||||
#: help:account.invoice,period_id:0
|
||||
|
@ -89,7 +91,7 @@ msgstr "kết quả hòa giả"
|
|||
#. module: account
|
||||
#: model:ir.actions.act_window,name:account.act_account_acount_move_line_open_unreconciled
|
||||
msgid "Unreconciled entries"
|
||||
msgstr "không thể hòa giải"
|
||||
msgstr "Mục chưa được tổng hợp"
|
||||
|
||||
#. module: account
|
||||
#: field:account.invoice.tax,base_code_id:0
|
||||
|
@ -107,7 +109,7 @@ msgstr "thống kê tài chính"
|
|||
#: model:ir.actions.wizard,name:account.wizard_vat_declaration
|
||||
#: model:ir.ui.menu,name:account.menu_wizard_vat_declaration
|
||||
msgid "Print Taxes Report"
|
||||
msgstr ""
|
||||
msgstr "in báo cáo thuế"
|
||||
|
||||
#. module: account
|
||||
#: field:account.account,parent_id:0
|
||||
|
@ -189,8 +191,6 @@ msgstr "di chuyển dòng lựa chọn"
|
|||
#. module: account
|
||||
#: rml:account.journal.period.print:0
|
||||
#: rml:account.tax.code.entries:0
|
||||
#: rml:account.third_party_ledger:0
|
||||
#: rml:account.third_party_ledger_other:0
|
||||
msgid "Entry label"
|
||||
msgstr "thử nhãn hàng"
|
||||
|
||||
|
@ -235,7 +235,6 @@ msgstr ""
|
|||
#: field:account.move,amount:0
|
||||
#: field:account.tax,amount:0
|
||||
#: field:account.tax.template,amount:0
|
||||
#: xsl:account.transfer:0
|
||||
msgid "Amount"
|
||||
msgstr "Số tiền"
|
||||
|
||||
|
@ -299,7 +298,6 @@ msgstr ""
|
|||
#. module: account
|
||||
#: wizard_view:account.account.balance.report,checktype:0
|
||||
#: wizard_view:account.analytic.account.analytic.check.report,init:0
|
||||
#: wizard_view:account.analytic.account.balance.report,init:0
|
||||
#: wizard_view:account.analytic.account.cost_ledger.report,init:0
|
||||
#: wizard_view:account.analytic.account.inverted.balance.report,init:0
|
||||
#: wizard_view:account.analytic.account.quantity_cost_ledger.report,init:0
|
||||
|
@ -339,6 +337,7 @@ msgid "Delta Debit"
|
|||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: model:account.account.type,name:account.account_type_tax
|
||||
#: rml:account.invoice:0
|
||||
#: field:account.invoice,amount_tax:0
|
||||
#: field:account.move.line,account_tax_id:0
|
||||
|
@ -353,7 +352,9 @@ msgstr "thay đổi báo có."
|
|||
#. module: account
|
||||
#: field:account.analytic.line,account_id:0
|
||||
#: field:account.invoice.line,account_analytic_id:0
|
||||
#: wizard_field:account.invoice.pay,addendum,analytic_id:0
|
||||
#: field:account.move.line,analytic_account_id:0
|
||||
#: wizard_field:account.move.line.reconcile,addendum,analytic_id:0
|
||||
#: field:report.hr.timesheet.invoice.journal,account_id:0
|
||||
msgid "Analytic Account"
|
||||
msgstr "truy vấn tài khoản"
|
||||
|
@ -675,8 +676,11 @@ msgstr ""
|
|||
#. module: account
|
||||
#: field:account.analytic.account,line_ids:0
|
||||
#: view:account.analytic.line:0
|
||||
#: code:addons/account/project/wizard/wizard_account_analytic_line.py:0
|
||||
#: model:ir.actions.act_window,name:account.action_account_analytic_line_form
|
||||
#: model:ir.actions.act_window,name:account.action_account_tree1
|
||||
#: model:ir.ui.menu,name:account.next_id_41
|
||||
#, python-format
|
||||
msgid "Analytic Entries"
|
||||
msgstr ""
|
||||
|
||||
|
@ -691,6 +695,7 @@ msgid "Associated Partner"
|
|||
msgstr "liên kết khách hàng"
|
||||
|
||||
#. module: account
|
||||
#: view:account.invoice:0
|
||||
#: field:account.invoice,comment:0
|
||||
msgid "Additional Information"
|
||||
msgstr "Thông tin bổ sung"
|
||||
|
@ -1460,6 +1465,9 @@ msgstr ""
|
|||
#: field:account.bank.statement.reconcile,line_new_ids:0
|
||||
#: wizard_view:account.move.line.reconcile,init_full:0
|
||||
#: wizard_view:account.move.line.reconcile,init_partial:0
|
||||
#: code:addons/account/wizard/wizard_pay_invoice.py:0
|
||||
#: code:addons/account/wizard/wizard_reconcile.py:0
|
||||
#, python-format
|
||||
msgid "Write-Off"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1865,7 +1873,6 @@ msgstr ""
|
|||
#: field:account.journal,type:0
|
||||
#: field:account.move,type:0
|
||||
#: field:account.move.reconcile,type:0
|
||||
#: xsl:account.transfer:0
|
||||
msgid "Type"
|
||||
msgstr ""
|
||||
|
||||
|
@ -2299,13 +2306,13 @@ msgstr ""
|
|||
#: selection:account.general.ledger.report,checktype,sortbydate:0
|
||||
#: rml:account.journal.period.print:0
|
||||
#: field:account.move,date:0
|
||||
#: wizard_field:account.move.line.reconcile,addendum,date_p:0
|
||||
#: rml:account.overdue:0
|
||||
#: wizard_field:account.subscription.generate,init,date:0
|
||||
#: field:account.subscription.line,date:0
|
||||
#: rml:account.tax.code.entries:0
|
||||
#: rml:account.third_party_ledger:0
|
||||
#: rml:account.third_party_ledger_other:0
|
||||
#: xsl:account.transfer:0
|
||||
msgid "Date"
|
||||
msgstr ""
|
||||
|
||||
|
@ -2422,6 +2429,7 @@ msgstr ""
|
|||
#: view:account.bank.statement:0
|
||||
#: field:account.move.reconcile,line_id:0
|
||||
#: model:ir.actions.act_window,name:account.action_move_line_search
|
||||
#: model:ir.actions.act_window,name:account.action_move_line_select
|
||||
#: model:ir.actions.act_window,name:account.action_move_line_tree1
|
||||
#: model:ir.ui.menu,name:account.menu_action_move_line_search
|
||||
msgid "Entry Lines"
|
||||
|
@ -2613,6 +2621,8 @@ msgstr ""
|
|||
|
||||
#. module: account
|
||||
#: rml:account.analytic.account.journal:0
|
||||
#: wizard_view:account.invoice.pay,addendum:0
|
||||
#: wizard_view:account.move.line.reconcile,addendum:0
|
||||
#: model:ir.ui.menu,name:account.next_id_40
|
||||
#: model:process.node,name:account.process_node_analytic0
|
||||
#: model:process.node,name:account.process_node_analyticcost0
|
||||
|
@ -2716,6 +2726,7 @@ msgid "Invoice Number"
|
|||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: wizard_field:account.analytic.account.balance.report,init,date2:0
|
||||
#: field:account.period,date_stop:0
|
||||
msgid "End of Period"
|
||||
msgstr ""
|
||||
|
@ -2899,8 +2910,6 @@ msgstr ""
|
|||
#: rml:account.journal.period.print:0
|
||||
#: rml:account.partner.balance:0
|
||||
#: rml:account.tax.code.entries:0
|
||||
#: rml:account.third_party_ledger:0
|
||||
#: rml:account.third_party_ledger_other:0
|
||||
#: rml:account.vat.declaration:0
|
||||
msgid "1cm 27.7cm 20cm 27.7cm"
|
||||
msgstr ""
|
||||
|
@ -2957,9 +2966,11 @@ msgstr ""
|
|||
#: wizard_view:account.move.line.reconcile,init_full:0
|
||||
#: wizard_view:account.move.line.reconcile,init_partial:0
|
||||
#: wizard_view:account.move.line.reconcile.select,init:0
|
||||
#: code:addons/account/wizard/wizard_reconcile_select.py:0
|
||||
#: model:ir.ui.menu,name:account.next_id_20
|
||||
#: model:process.node,name:account.process_node_reconciliation0
|
||||
#: model:process.node,name:account.process_node_supplierreconciliation0
|
||||
#, python-format
|
||||
msgid "Reconciliation"
|
||||
msgstr ""
|
||||
|
||||
|
@ -3019,7 +3030,6 @@ msgstr ""
|
|||
|
||||
#. module: account
|
||||
#: rml:account.invoice:0
|
||||
#: xsl:account.transfer:0
|
||||
msgid "Document"
|
||||
msgstr ""
|
||||
|
||||
|
@ -3067,6 +3077,8 @@ msgstr ""
|
|||
|
||||
#. module: account
|
||||
#: rml:account.general.ledger:0
|
||||
#: rml:account.third_party_ledger:0
|
||||
#: rml:account.third_party_ledger_other:0
|
||||
msgid "Entry Label"
|
||||
msgstr ""
|
||||
|
||||
|
@ -3258,6 +3270,7 @@ msgid "Generate Fiscal Year Opening Entries"
|
|||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: view:account.move.reconcile:0
|
||||
#: model:ir.actions.wizard,name:account.wizard_reconcile
|
||||
msgid "Reconcile Entries"
|
||||
msgstr ""
|
||||
|
@ -3605,7 +3618,6 @@ msgid ""
|
|||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: wizard_field:account.invoice.pay,addendum,comment:0
|
||||
#: wizard_field:account.invoice.pay,init,name:0
|
||||
msgid "Entry Name"
|
||||
msgstr ""
|
||||
|
@ -4912,6 +4924,7 @@ msgid "Invoice Lines"
|
|||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: wizard_field:account.analytic.account.balance.report,init,date1:0
|
||||
#: field:account.period,date_start:0
|
||||
msgid "Start of Period"
|
||||
msgstr ""
|
||||
|
@ -5304,8 +5317,6 @@ msgstr ""
|
|||
#: rml:account.journal.period.print:0
|
||||
#: rml:account.partner.balance:0
|
||||
#: rml:account.tax.code.entries:0
|
||||
#: rml:account.third_party_ledger:0
|
||||
#: rml:account.third_party_ledger_other:0
|
||||
#: rml:account.vat.declaration:0
|
||||
msgid "Page"
|
||||
msgstr ""
|
||||
|
@ -5387,7 +5398,6 @@ msgstr ""
|
|||
|
||||
#. module: account
|
||||
#: wizard_field:account.analytic.account.analytic.check.report,init,date2:0
|
||||
#: wizard_field:account.analytic.account.balance.report,init,date2:0
|
||||
#: wizard_field:account.analytic.account.cost_ledger.report,init,date2:0
|
||||
#: wizard_field:account.analytic.account.inverted.balance.report,init,date2:0
|
||||
#: wizard_field:account.analytic.account.journal.report,init,date2:0
|
||||
|
@ -5576,7 +5586,6 @@ msgstr ""
|
|||
#. module: account
|
||||
#: wizard_field:account.aged.trial.balance,init,date1:0
|
||||
#: wizard_field:account.analytic.account.analytic.check.report,init,date1:0
|
||||
#: wizard_field:account.analytic.account.balance.report,init,date1:0
|
||||
#: wizard_field:account.analytic.account.cost_ledger.report,init,date1:0
|
||||
#: wizard_field:account.analytic.account.inverted.balance.report,init,date1:0
|
||||
#: wizard_field:account.analytic.account.journal.report,init,date1:0
|
||||
|
@ -5934,6 +5943,335 @@ msgstr ""
|
|||
msgid "Compute Entry Dates"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: view:board.board:0
|
||||
msgid "Analytic accounts to close"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: view:board.board:0
|
||||
msgid "Draft invoices"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: model:ir.actions.act_window,name:account.open_board_account
|
||||
#: model:ir.ui.menu,name:account.menu_board_account
|
||||
msgid "Accounting Dashboard"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: view:board.board:0
|
||||
#: model:ir.actions.act_window,name:account.act_my_account
|
||||
msgid "Accounts to invoice"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: view:board.board:0
|
||||
#: model:ir.actions.act_window,name:account.action_account_analytic_line_to_invoice
|
||||
msgid "Costs to invoice"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: view:board.board:0
|
||||
msgid "Aged receivables"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: model:ir.module.module,shortdesc:account.module_meta_information
|
||||
msgid "Board for accountant"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: model:ir.actions.act_window,name:account.action_aged_income
|
||||
msgid "Income Accounts"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: view:board.board:0
|
||||
msgid "My indicators"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: view:board.board:0
|
||||
msgid "Account Board"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: view:board.board:0
|
||||
msgid "Aged income"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: wizard_field:account.balance.account.balance.report,init,show_columns:0
|
||||
msgid "Show Debit/Credit Information"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: selection:account.balance.account.balance.report,init,account_choice:0
|
||||
msgid "All accounts"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: wizard_field:account.balance.account.balance.report,init,period_manner:0
|
||||
msgid "Entries Selection Based on"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: wizard_view:account.balance.account.balance.report,backtoinit:0
|
||||
#: wizard_view:account.balance.account.balance.report,zero_years:0
|
||||
msgid "Notification"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: selection:account.balance.account.balance.report,init,period_manner:0
|
||||
msgid "Financial Period"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: model:ir.actions.report.xml,name:account.account_account_balance
|
||||
#: model:ir.actions.report.xml,name:account.account_account_balance_landscape
|
||||
msgid "Account balance"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: wizard_view:account.balance.account.balance.report,init:0
|
||||
msgid "Select Period(s)"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: selection:account.balance.account.balance.report,init,compare_pattern:0
|
||||
msgid "Percentage"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: wizard_field:account.balance.account.balance.report,init,compare_pattern:0
|
||||
msgid "Compare Selected Years In Terms Of"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: wizard_view:account.balance.account.balance.report,init:0
|
||||
msgid "Select Fiscal Year(s)(Maximum Three Years)"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: wizard_field:account.balance.account.balance.report,init,select_account:0
|
||||
msgid "Select Reference Account(for % comparision)"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: model:ir.actions.wizard,name:account.wizard_account_balance_report
|
||||
msgid "Account balance-Compare Years"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: model:ir.module.module,description:account.module_meta_information
|
||||
msgid ""
|
||||
"Account Balance Module is an added functionality to the Financial Management "
|
||||
"module.\n"
|
||||
"\n"
|
||||
" This module gives you the various options for printing balance sheet.\n"
|
||||
"\n"
|
||||
" 1. You can compare the balance sheet for different years.\n"
|
||||
"\n"
|
||||
" 2. You can set the cash or percentage comparison between two years.\n"
|
||||
"\n"
|
||||
" 3. You can set the referential account for the percentage comparison for "
|
||||
"particular years.\n"
|
||||
"\n"
|
||||
" 4. You can select periods as an actual date or periods as creation "
|
||||
"date.\n"
|
||||
"\n"
|
||||
" 5. You have an option to print the desired report in Landscape format.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: wizard_view:account.balance.account.balance.report,backtoinit:0
|
||||
msgid "You have to select 'Landscape' option. Please Check it."
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: wizard_field:account.balance.account.balance.report,init,landscape:0
|
||||
msgid "Show Report in Landscape Form"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: rml:account.account.balance.landscape:0
|
||||
#: rml:account.balance.account.balance:0
|
||||
msgid "Total :"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: wizard_field:account.balance.account.balance.report,init,format_perc:0
|
||||
msgid "Show Comparision in %"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: wizard_view:account.analytic.account.balance.report,init:0
|
||||
msgid "Select Period"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: wizard_view:account.balance.account.balance.report,init:0
|
||||
msgid "Report Options"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: selection:account.balance.account.balance.report,init,compare_pattern:0
|
||||
msgid "Don't Compare"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: wizard_field:account.balance.account.balance.report,init,account_choice:0
|
||||
msgid "Show Accounts"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: wizard_view:account.balance.account.balance.report,backtoinit:0
|
||||
msgid "1. You have selected more than 3 years in any case."
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: model:ir.module.module,shortdesc:account.module_meta_information
|
||||
msgid "Accounting and financial management-Compare Accounts"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: rml:account.account.balance.landscape:0
|
||||
#: rml:account.balance.account.balance:0
|
||||
msgid "Year :"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: wizard_view:account.balance.account.balance.report,backtoinit:0
|
||||
msgid "You can select maximum 3 years. Please check again."
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: wizard_view:account.balance.account.balance.report,backtoinit:0
|
||||
msgid ""
|
||||
"3. You have selected 'Percentage' option with more than 2 years, but you "
|
||||
"have not selected landscape format."
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: wizard_view:account.balance.account.balance.report,backtoinit:0
|
||||
msgid ""
|
||||
"You might have done following mistakes. Please correct them and try again."
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: help:account.balance.account.balance.report,init,select_account:0
|
||||
msgid "Keep empty for comparision to its parent"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: selection:account.balance.account.balance.report,init,period_manner:0
|
||||
msgid "Creation Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: wizard_view:account.balance.account.balance.report,backtoinit:0
|
||||
msgid ""
|
||||
"2. You have not selected 'Percentage' option, but you have selected more "
|
||||
"than 2 years."
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: wizard_view:account.balance.account.balance.report,zero_years:0
|
||||
msgid ""
|
||||
"You may have selected the compare options with more than 1 year with "
|
||||
"credit/debit columns and % option.This can lead contents to be printed out "
|
||||
"of the paper.Please try again."
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: wizard_view:account.balance.account.balance.report,zero_years:0
|
||||
msgid "You have to select at least 1 Fiscal Year. Try again."
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: wizard_view:account.balance.account.balance.report,init:0
|
||||
msgid "Customize Report"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: field:report.aged.receivable,name:0
|
||||
msgid "Month Range"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: model:ir.actions.act_window,name:report_account.action_view_created_invoice_dashboard
|
||||
msgid "Invoices Created Within Past 15 Days"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: model:ir.model,name:report_account.model_report_invoice_created
|
||||
msgid "Report of Invoices Created within Last 15 days"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: view:report.invoice.created:0
|
||||
msgid "Total Amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: view:report.account.receivable:0
|
||||
msgid "Accounts by type"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: model:ir.model,name:report_account.model_report_aged_receivable
|
||||
msgid "Aged Receivable Till Today"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: model:ir.model,name:report_account.model_report_account_receivable
|
||||
msgid "Receivable accounts"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: field:temp.range,name:0
|
||||
msgid "Range"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: model:ir.module.module,description:report_account.module_meta_information
|
||||
msgid "A module that adds new reports based on the account module."
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: model:ir.module.module,shortdesc:report_account.module_meta_information
|
||||
msgid "Account Reporting - Reporting"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: model:ir.actions.act_window,name:report_account.action_account_receivable_graph
|
||||
#: model:ir.ui.menu,name:report_account.menu_account_receivable_graph
|
||||
msgid "Balance by Type of Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: field:report.account.receivable,name:0
|
||||
msgid "Week of Year"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: field:report.invoice.created,create_date:0
|
||||
msgid "Create Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: model:ir.actions.act_window,name:report_account.action_aged_receivable_graph
|
||||
#: view:report.aged.receivable:0
|
||||
msgid "Aged Receivable"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
#: view:report.invoice.created:0
|
||||
msgid "Untaxed Amount"
|
||||
msgstr ""
|
||||
|
||||
#, python-format
|
||||
#~ msgid "Warning !"
|
||||
#~ msgstr "Cảnh báo"
|
||||
|
|
|
@ -67,6 +67,12 @@ class account_installer(osv.osv_memory):
|
|||
'account_asset':fields.boolean('Assets Management',
|
||||
help="Enables asset management in the accounting application, "
|
||||
"including asset categories and usage periods."),
|
||||
'account_voucher':fields.boolean('Voucher Management',
|
||||
help="Account Voucher module includes all the basic requirements of "
|
||||
"Voucher Entries for Bank, Cash, Sales, Purchase, Expanse, Contra, etc... "),
|
||||
'account_voucher_payment':fields.boolean('Voucher and Reconcile Management',
|
||||
help="Extension Account Voucher module includes allows to link payment / receipt "
|
||||
"entries with voucher, also automatically reconcile during the payment and receipt entries."),
|
||||
'date_start': fields.date('Start Date', required=True),
|
||||
'date_stop': fields.date('End Date', required=True),
|
||||
'period':fields.selection([('month','Monthly'), ('3months','3 Monthly')],
|
||||
|
|
|
@ -220,7 +220,7 @@ class account_invoice(osv.osv):
|
|||
_name = "account.invoice"
|
||||
_description = 'Invoice'
|
||||
_order = "number"
|
||||
_log_create = True
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Description', size=64, select=True, readonly=True, states={'draft':[('readonly',False)]}),
|
||||
'origin': fields.char('Source Document', size=64, help="Reference of the document that produced this invoice.", readonly=True, states={'draft':[('readonly',False)]}),
|
||||
|
@ -242,13 +242,13 @@ class account_invoice(osv.osv):
|
|||
('proforma','Pro-forma'),
|
||||
('proforma2','Pro-forma'),
|
||||
('open','Open'),
|
||||
('paid','Done'),
|
||||
('paid','Paid'),
|
||||
('cancel','Cancelled')
|
||||
],'State', select=True, readonly=True,
|
||||
help=' * The \'Draft\' state is used when a user is encoding a new and unconfirmed Invoice. \
|
||||
\n* The \'Pro-forma\' when invoice is in Pro-forma state,invoice does not have an invoice number. \
|
||||
\n* The \'Open\' state is used when user create invoice,a invoice number is generated.Its in open state till user does not pay invoice. \
|
||||
\n* The \'Done\' state is set automatically when invoice is paid.\
|
||||
\n* The \'Paid\' state is set automatically when invoice is paid.\
|
||||
\n* The \'Cancelled\' state is used when user cancel invoice.'),
|
||||
'date_invoice': fields.date('Date Invoiced', states={'paid':[('readonly',True)], 'open':[('readonly',True)], 'close':[('readonly',True)]}, help="Keep empty to use the current date"),
|
||||
'date_due': fields.date('Due Date', states={'paid':[('readonly',True)], 'open':[('readonly',True)], 'close':[('readonly',True)]},
|
||||
|
@ -344,6 +344,9 @@ class account_invoice(osv.osv):
|
|||
def create(self, cr, uid, vals, context=None):
|
||||
try:
|
||||
res = super(account_invoice, self).create(cr, uid, vals, context)
|
||||
for inv_id, name in self.name_get(cr, uid, [res], context=context):
|
||||
message = _('Invoice ') + " '" + name + "' "+ _("is waiting for validation.")
|
||||
self.log(cr, uid, inv_id, message)
|
||||
return res
|
||||
except Exception, e:
|
||||
if '"journal_id" viol' in e.args[0]:
|
||||
|
@ -354,9 +357,6 @@ class account_invoice(osv.osv):
|
|||
|
||||
def confirm_paid(self, cr, uid, ids, context=None):
|
||||
self.write(cr, uid, ids, {'state':'paid'}, context=context)
|
||||
for (id, name) in self.name_get(cr, uid, ids):
|
||||
message = _('Document ') + " '" + name + "' "+ _("has been paid.")
|
||||
self.log(cr, uid, id, message)
|
||||
return True
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
|
@ -922,7 +922,7 @@ class account_invoice(osv.osv):
|
|||
invtype = obj_inv.type
|
||||
number = obj_inv.number
|
||||
move_id = obj_inv.move_id and obj_inv.move_id.id or False
|
||||
reference = obj_inv.reference
|
||||
reference = obj_inv.reference or ''
|
||||
if not number:
|
||||
tmp_context = {
|
||||
'fiscalyear_id': obj_inv.period_id.fiscalyear_id.id
|
||||
|
@ -955,8 +955,9 @@ class account_invoice(osv.osv):
|
|||
'WHERE account_move_line.move_id = %s ' \
|
||||
'AND account_analytic_line.move_id = account_move_line.id',
|
||||
(ref, move_id))
|
||||
message = _('Invoice ') + " '" + number + "' "+ _("is confirm")
|
||||
self.log(cr, uid, id, message)
|
||||
for inv_id, name in self.name_get(cr, uid, [id]):
|
||||
message = _('Invoice ') + " '" + name + "' "+ _("is validated.")
|
||||
self.log(cr, uid, inv_id, message)
|
||||
return True
|
||||
|
||||
def action_cancel(self, cr, uid, ids, *args):
|
||||
|
@ -1175,9 +1176,15 @@ class account_invoice(osv.osv):
|
|||
if l.account_id.id==src_account_id:
|
||||
line_ids.append(l.id)
|
||||
total += (l.debit or 0.0) - (l.credit or 0.0)
|
||||
|
||||
inv_id, name = self.name_get(cr, uid, [invoice.id], context=context)[0]
|
||||
if (not round(total,self.pool.get('decimal.precision').precision_get(cr, uid, 'Account'))) or writeoff_acc_id:
|
||||
self.log(cr, uid, inv_id, _('Invoice ') + " '" + name + "' "+ _("is totally paid."))
|
||||
self.pool.get('account.move.line').reconcile(cr, uid, line_ids, 'manual', writeoff_acc_id, writeoff_period_id, writeoff_journal_id, context)
|
||||
else:
|
||||
code = invoice.currency_id.code
|
||||
amt = str(pay_amount) + code + ' on ' + str(invoice.amount_total) + code + ' (' + str(total) + code + ' remaining)'
|
||||
self.log(cr, uid, inv_id, _('Invoice ') + " '" + name + "' "+ _("is paid partially: ") + amt)
|
||||
self.pool.get('account.move.line').reconcile_partial(cr, uid, line_ids, 'manual', context)
|
||||
|
||||
# Update the stored value (fields.function), so we write to trigger recompute
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<openerp>
|
||||
<data noupdate="1">
|
||||
<record id="analytic_root" model="account.analytic.account">
|
||||
<field name="name">OpenERP S.A.</field>
|
||||
<field name="name" model="res.company" use="name" search="[('id', '=', 1)]"/>
|
||||
<field name="code">0</field>
|
||||
</record>
|
||||
<record id="analytic_absences" model="account.analytic.account">
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
<field name="quantity_max"/>
|
||||
<field name="parent_id" invisible="1"/>
|
||||
<field name="type" invisible="1"/>
|
||||
<field name="partner_id" invisible="1"/>
|
||||
<field name="partner_id" invisible="1"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
|
@ -131,8 +131,9 @@
|
|||
<field name="res_model">account.analytic.account</field>
|
||||
<field name="domain">[('parent_id','=',False)]</field>
|
||||
<field name="view_type">tree</field>
|
||||
<field name="view_mode">form,graph</field>
|
||||
<field name="view_mode">form,graph</field>
|
||||
<field name="view_id" ref="view_account_analytic_account_tree"/>
|
||||
<field name="help">Analytic Charts of Accounts allows you to access to reports by analytic accounts (or cost accounts) . From this menu you can access to analytic balance, a report that relates the analytic accounts to the general accounts. It is useful for analyzing the profitability of projects, giving you the profitability of a project for the different operations that you used to carry out the project.</field>
|
||||
</record>
|
||||
<!-- <menuitem-->
|
||||
<!-- action="action_account_analytic_account_tree2"-->
|
||||
|
@ -376,6 +377,7 @@
|
|||
<field name="name">Print Analytic Journals</field>
|
||||
<field name="res_model">account.analytic.journal</field>
|
||||
<field name="view_type">tree</field>
|
||||
<field name="help">To print an analytics (or costs) journal for a given period. The report give code, move name, account number, general amount and analytic amount.</field>
|
||||
</record>
|
||||
<menuitem action="action_account_analytic_journal_tree" id="account_analytic_journal_print" parent="account.next_id_40"/>
|
||||
|
||||
|
|
|
@ -104,6 +104,7 @@
|
|||
<field name="view_mode">tree,graph</field>
|
||||
<field name="context">{'search_default_month':1,'search_default_User':1,'group_by_no_leaf':1,'group_by':[]}</field>
|
||||
<field name="search_view_id" ref="view_analytic_entries_report_search"/>
|
||||
<field name="help">A tool search lets you know statistics on your analytics records that match your needs.</field>
|
||||
</record>
|
||||
|
||||
<menuitem action="action_analytic_entries_report" id="menu_action_analytic_entries_report" parent="account.menu_finance_statistic_report_statement" sequence="4"/>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<field name="model">account.entries.report</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Entries Analysis">
|
||||
<tree colors="blue:state in ('draft');black:state in ('posted')" string="Entries Analysis">
|
||||
<field name="date" invisible="1"/>
|
||||
<field name="date_created" invisible="1"/>
|
||||
<field name="date_maturity" invisible="1"/>
|
||||
|
@ -118,6 +118,7 @@
|
|||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,graph</field>
|
||||
<field name="context">{'search_default_profit': 1,'search_default_group_account':1,'search_default_group_month': 1, 'group_by_no_leaf':1,'group_by':[]}</field>
|
||||
<field name="help">A tool search lets you know statistics on your different financial accounts that match your needs.</field>
|
||||
</record>
|
||||
<menuitem action="action_account_entries_report_all" id="menu_action_account_entries_report_all" parent="account.menu_finance_statistic_report_statement" sequence="2"/>
|
||||
</data>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<field name="model">account.invoice.report</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Invoices Analysis">
|
||||
<tree colors="blue:state in ('draft');gray:state in ('cancel','paid');black:state in ('proforma','proforma2')" string="Invoices Analysis">
|
||||
<field name="date" invisible="1"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
<field name="year" invisible="1"/>
|
||||
|
@ -138,6 +138,8 @@
|
|||
<field name="view_mode">tree,graph</field>
|
||||
<field name="context">{'search_default_month':1,'search_default_product':1,'group_by_no_leaf':1,'group_by':[]}</field>
|
||||
<field name="search_view_id" ref="view_account_invoice_report_search"/>
|
||||
<field name="help">A tool search lets you know statistics on invoices that match your needs.</field>
|
||||
|
||||
</record>
|
||||
|
||||
<menuitem action="action_account_invoice_report_all" id="menu_action_account_invoice_report_all" parent="account.menu_finance_statistic_report_statement" sequence="0"/>
|
||||
|
|
|
@ -89,7 +89,7 @@
|
|||
<field name="model">report.invoice.created</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state in ('draft');black:state not in ('draft') " string="Invoices">
|
||||
<tree colors="blue:state in ('draft');black:state in ('proforma','proforma2','open');gray:state in('paid','cancel') " string="Invoices">
|
||||
<field name="create_date" select="1"/>
|
||||
<field name="name" select="1"/>
|
||||
<field name="type"/>
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
<field name="view_id" ref="account_aged_balance_view"/>
|
||||
<field name="context">{'record_id':active_id}</field>
|
||||
<field name="target">new</field>
|
||||
<field name="help">Aged Partner Balance is a more detailed report of your receivables by intervals. When opening that report, Open ERP asks for the name of the company, the fiscal period and the size of the interval to be analyzed (in days). Open ERP then calculates a table of credit balance by period. So if you request an interval of 30 days OpenERP generates an analysis of creditors for the past month, past two months, and so on. </field>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
<field name="view_id" ref="account_automatic_reconcile_view"/>
|
||||
<field name="context">{'record_id':active_id}</field>
|
||||
<field name="target">new</field>
|
||||
<field name="help">For an invoice to be considered as paid, the invoice entries must be reconciled with counterparts, usually payments. With the automatic reconciliation functionality, OpenERP make its own search for entries to reconcile in a series of accounts. It tries to find entries for each partner where the amounts correspond.</field>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
|
|
|
@ -25,9 +25,10 @@
|
|||
<field name="res_model">account.move.bank.reconcile</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="view_account_move_bank_reconcile"/>
|
||||
<field name="target">new</field>
|
||||
<field name="view_id" ref="view_account_move_bank_reconcile"/>
|
||||
<field name="target">new</field>
|
||||
<field name="help">Bank Reconciliation consists of verifying that your bank statement corresponds with the entries (or records) of that account in your accounting system.</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</openerp>
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
<field name="view_id" ref="account_partner_balance_view"/>
|
||||
<field name="context">{'record_id':active_id}</field>
|
||||
<field name="target">new</field>
|
||||
<field name="help">This report is analysis by partner. It is a PDF report containing one line per partner representing the cumulative credit balance.</field>
|
||||
</record>
|
||||
|
||||
<menuitem icon="STOCK_PRINT"
|
||||
|
@ -59,4 +60,4 @@
|
|||
parent="account.next_id_22"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</openerp>
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
<field name="res_model">account.period.close</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="view_account_period_close"/>
|
||||
<field name="target">new</field>
|
||||
<field name="view_id" ref="view_account_period_close"/>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
<record id="action_idea_post_vote_values" model="ir.values">
|
||||
|
@ -42,4 +42,4 @@
|
|||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</openerp>
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
<field name="view_id" ref="account_partner_ledger_view"/>
|
||||
<field name="context">{'record_id':active_id}</field>
|
||||
<field name="target">new</field>
|
||||
<field name="help">To get detailed information about a partner you can ask for the Partner Ledgers.</field>
|
||||
</record>
|
||||
|
||||
<menuitem icon="STOCK_PRINT"
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Use Model">
|
||||
<group colspan="4" col="6">
|
||||
<group colspan="4" col="6" width="300" height="70">
|
||||
<label string = "Entry Lines Created." colspan="2"/>
|
||||
<newline/>
|
||||
<button icon="gtk-ok" special="cancel" string="Ok"/>
|
||||
|
@ -66,7 +66,7 @@
|
|||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Use Model">
|
||||
<group colspan="4" col="6">
|
||||
<group colspan="4" col="6" width="300" height="70">
|
||||
<label string = "Are you sure you want to create entries?" colspan="2"/>
|
||||
<newline/>
|
||||
<button icon="terp-gtk-stop" special="cancel" string="Cancel"/>
|
||||
|
|
|
@ -27,8 +27,9 @@
|
|||
<field name="res_model">validate.account.move</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="validate_account_move_view"/>
|
||||
<field name="target">new</field>
|
||||
<field name="view_id" ref="validate_account_move_view"/>
|
||||
<field name="target">new</field>
|
||||
<field name="help">The process of ledger is the process of transferring debit and credit amounts from a journal of original entry to a ledger book.</field>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
<field name="help">This menu print a VAT declaration based on invoices or payments. You can select one or several periods of the fiscal year. Information required for a tax declaration is automatically generated by Open ERP from invoices (or payments, in some countries). This data is updated in real time. That’s very useful because it enables you to preview at any time the tax that you owe at the start and end of the month or quarter.</field>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
|
|
|
@ -1,23 +1,27 @@
|
|||
# Translation of OpenERP Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * account_analytic_analysis
|
||||
# Dutch (Belgium) translation for openobject-addons
|
||||
# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 5.0.4\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2009-08-28 15:34:14+0000\n"
|
||||
"PO-Revision-Date: 2009-08-28 15:34:14+0000\n"
|
||||
"Last-Translator: <>\n"
|
||||
"Language-Team: \n"
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
|
||||
"PO-Revision-Date: 2010-07-20 12:11+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Dutch (Belgium) <nl_BE@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: \n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2010-07-21 03:43+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: help:account.analytic.account,hours_qtt_invoiced:0
|
||||
msgid "Number of hours that can be invoiced plus those that already have been invoiced."
|
||||
msgid ""
|
||||
"Number of hours that can be invoiced plus those that already have been "
|
||||
"invoiced."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
|
@ -41,6 +45,7 @@ msgid "Computed using the formula: Maximum Quantity - Hours Tot."
|
|||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: model:ir.actions.act_window,name:account_analytic_analysis.action_account_analytic_all
|
||||
#: model:ir.ui.menu,name:account_analytic_analysis.menu_action_account_analytic_all
|
||||
msgid "All Analytic Accounts"
|
||||
msgstr ""
|
||||
|
@ -78,8 +83,10 @@ msgstr ""
|
|||
|
||||
#. module: account_analytic_analysis
|
||||
#: constraint:ir.model:0
|
||||
msgid "The Object name must start with x_ and not contain any special character !"
|
||||
msgstr "De objectnaam moet beginnen met x_ en mag geen speciale karakters bevatten !"
|
||||
msgid ""
|
||||
"The Object name must start with x_ and not contain any special character !"
|
||||
msgstr ""
|
||||
"De objectnaam moet beginnen met x_ en mag geen speciale karakters bevatten !"
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
#: model:ir.actions.act_window,name:account_analytic_analysis.action_account_analytic_new
|
||||
|
@ -110,7 +117,9 @@ msgstr ""
|
|||
|
||||
#. module: account_analytic_analysis
|
||||
#: help:account.analytic.account,last_worked_invoiced_date:0
|
||||
msgid "If invoice from the costs, this is the date of the latest work or cost that have been invoiced."
|
||||
msgid ""
|
||||
"If invoice from the costs, this is the date of the latest work or cost that "
|
||||
"have been invoiced."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
|
@ -130,7 +139,9 @@ msgstr ""
|
|||
|
||||
#. module: account_analytic_analysis
|
||||
#: help:account.analytic.account,hours_quantity:0
|
||||
msgid "Number of hours you spent on the analytic account (from timesheet). It computes on all journal of type 'general'."
|
||||
msgid ""
|
||||
"Number of hours you spent on the analytic account (from timesheet). It "
|
||||
"computes on all journal of type 'general'."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
|
@ -140,7 +151,10 @@ msgstr ""
|
|||
|
||||
#. module: account_analytic_analysis
|
||||
#: help:account.analytic.account,ca_theorical:0
|
||||
msgid "Based on the costs you had on the project, what would have been the revenue if all these costs have been invoiced at the normal sale price provided by the pricelist."
|
||||
msgid ""
|
||||
"Based on the costs you had on the project, what would have been the revenue "
|
||||
"if all these costs have been invoiced at the normal sale price provided by "
|
||||
"the pricelist."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
|
@ -174,7 +188,8 @@ msgstr ""
|
|||
|
||||
#. module: account_analytic_analysis
|
||||
#: model:ir.module.module,description:account_analytic_analysis.module_meta_information
|
||||
msgid "Modify account analytic view to show\n"
|
||||
msgid ""
|
||||
"Modify account analytic view to show\n"
|
||||
"important data for project manager of services companies.\n"
|
||||
"Add menu to show relevant information for each manager."
|
||||
msgstr ""
|
||||
|
@ -252,7 +267,9 @@ msgstr ""
|
|||
|
||||
#. module: account_analytic_analysis
|
||||
#: help:account.analytic.account,hours_qtt_non_invoiced:0
|
||||
msgid "Number of hours (from journal of type 'general') that can be invoiced if you invoice based on analytic account."
|
||||
msgid ""
|
||||
"Number of hours (from journal of type 'general') that can be invoiced if you "
|
||||
"invoice based on analytic account."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
|
@ -267,7 +284,9 @@ msgstr ""
|
|||
|
||||
#. module: account_analytic_analysis
|
||||
#: help:account.analytic.account,ca_to_invoice:0
|
||||
msgid "If invoice from analytic account, the remaining amount you can invoice to the customer based on the total costs."
|
||||
msgid ""
|
||||
"If invoice from analytic account, the remaining amount you can invoice to "
|
||||
"the customer based on the total costs."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_analysis
|
||||
|
@ -312,6 +331,7 @@ msgstr ""
|
|||
|
||||
#. module: account_analytic_analysis
|
||||
#: help:account.analytic.account,total_cost:0
|
||||
msgid "Total of costs for this account. It includes real costs (from invoices) and indirect costs, like time spent on timesheets."
|
||||
msgid ""
|
||||
"Total of costs for this account. It includes real costs (from invoices) and "
|
||||
"indirect costs, like time spent on timesheets."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -1,20 +1,21 @@
|
|||
# Translation of OpenERP Server.
|
||||
# Translation of OpenERP Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * account_analytic_plans
|
||||
# Vietnamese translation for openobject-addons
|
||||
# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 5.0.4\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2009-08-28 16:00:38+0000\n"
|
||||
"PO-Revision-Date: 2009-08-28 16:00:38+0000\n"
|
||||
"Last-Translator: <>\n"
|
||||
"Language-Team: \n"
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
|
||||
"PO-Revision-Date: 2010-07-20 03:43+0000\n"
|
||||
"Last-Translator: Business Link Development Technologies <Unknown>\n"
|
||||
"Language-Team: Vietnamese <vi@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: \n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2010-07-21 03:43+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: field:account.analytic.plan.instance,account4_ids:0
|
||||
|
@ -23,8 +24,9 @@ msgstr ""
|
|||
|
||||
#. module: account_analytic_plans
|
||||
#: constraint:ir.model:0
|
||||
msgid "The Object name must start with x_ and not contain any special character !"
|
||||
msgstr ""
|
||||
msgid ""
|
||||
"The Object name must start with x_ and not contain any special character !"
|
||||
msgstr "Tên đối tượng phải bắt đầu bằng chữ x_ và không chứa ký tự đặc biệt"
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: model:ir.actions.report.xml,name:account_analytic_plans.account_analytic_account_crossovered_analytic
|
||||
|
@ -222,374 +224,9 @@ msgstr ""
|
|||
|
||||
#. module: account_analytic_plans
|
||||
#: model:ir.module.module,description:account_analytic_plans.module_meta_information
|
||||
msgid "This module allows to use several analytic plans, according to the general journal,\n"
|
||||
"so that multiple analytic lines are created when the invoice or the entries\n"
|
||||
"are confirmed.\n"
|
||||
"\n"
|
||||
"For example, you can define the following analytic structure:\n"
|
||||
" Projects\n"
|
||||
" Project 1\n"
|
||||
" SubProj 1.1\n"
|
||||
" SubProj 1.2\n"
|
||||
" Project 2\n"
|
||||
" Salesman\n"
|
||||
" Eric\n"
|
||||
" Fabien\n"
|
||||
"\n"
|
||||
"Here, we have two plans: Projects and Salesman. An invoice line must\n"
|
||||
"be able to write analytic entries in the 2 plans: SubProj 1.1 and\n"
|
||||
"Fabien. The amount can also be split. The following example is for\n"
|
||||
"an invoice that touches the two subproject and assigned to one salesman:\n"
|
||||
"\n"
|
||||
"Plan1:\n"
|
||||
" SubProject 1.1 : 50%\n"
|
||||
" SubProject 1.2 : 50%\n"
|
||||
"Plan2:\n"
|
||||
" Eric: 100%\n"
|
||||
"\n"
|
||||
"So when this line of invoice will be confirmed, it will generate 3 analytic lines,\n"
|
||||
"for one account entry.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: model:ir.module.module,shortdesc:account_analytic_plans.module_meta_information
|
||||
msgid "Multiple-plans management in Analytic Accounting"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: view:account.analytic.plan.line:0
|
||||
#: model:ir.model,name:account_analytic_plans.model_account_analytic_plan_line
|
||||
msgid "Analytic Plan Lines"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: rml:account.analytic.account.crossovered.analytic:0
|
||||
msgid "Crossovered Analytic -"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: field:account.analytic.plan.instance,plan_id:0
|
||||
msgid "Model's Plan"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: field:account.analytic.plan.instance,account2_ids:0
|
||||
msgid "Account2 Id"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: rml:account.analytic.account.crossovered.analytic:0
|
||||
msgid "Amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: help:account.analytic.plan.line,root_analytic_id:0
|
||||
msgid "Root account of this plan."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: field:account.analytic.plan.instance,account6_ids:0
|
||||
msgid "Account6 Id"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: rml:account.analytic.account.crossovered.analytic:0
|
||||
msgid "Quantity"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: field:account.analytic.plan.instance,account_ids:0
|
||||
msgid "Account Id"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: rml:account.analytic.account.crossovered.analytic:0
|
||||
msgid "Code"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: wizard_button:create.model,info,end:0
|
||||
msgid "OK"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: field:account.analytic.plan.line,root_analytic_id:0
|
||||
msgid "Root Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: wizard_view:create.model,info:0
|
||||
msgid "This distribution model has been saved. You will be able to reuse it later."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: field:account.analytic.plan.line,sequence:0
|
||||
msgid "Sequence"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: field:account.analytic.plan.instance.line,analytic_account_id:0
|
||||
msgid "Analytic Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: field:account.analytic.default,analytics_id:0
|
||||
#: view:account.analytic.plan.instance:0
|
||||
#: field:account.analytic.plan.instance,name:0
|
||||
#: field:account.invoice.line,analytics_id:0
|
||||
#: field:account.move.line,analytics_id:0
|
||||
msgid "Analytic Distribution"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: model:ir.ui.menu,name:account_analytic_plans.menu_account_analytic_plan_instance_action
|
||||
msgid "Analytic Distribution's models"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: wizard_button:wizard.crossovered.analytic,init,end:0
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: wizard_field:wizard.crossovered.analytic,init,date1:0
|
||||
msgid "Start Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: rml:account.analytic.account.crossovered.analytic:0
|
||||
msgid "at"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: rml:account.analytic.account.crossovered.analytic:0
|
||||
msgid "From Date"
|
||||
msgstr ""
|
||||
|
||||
# This file contains the translation of the following modules:
|
||||
# * account_analytic_plans
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 5.0.4\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2009-08-28 16:00:38+0000\n"
|
||||
"PO-Revision-Date: 2009-08-28 16:00:38+0000\n"
|
||||
"Last-Translator: <>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: field:account.analytic.plan.instance,account4_ids:0
|
||||
msgid "Account4 Id"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: constraint:ir.model:0
|
||||
msgid "The Object name must start with x_ and not contain any special character !"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: model:ir.actions.report.xml,name:account_analytic_plans.account_analytic_account_crossovered_analytic
|
||||
#: model:ir.actions.wizard,name:account_analytic_plans.account_analytic_account_inverted_balance_report
|
||||
msgid "Crossovered Analytic"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: field:account.analytic.plan.instance,account5_ids:0
|
||||
msgid "Account5 Id"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: wizard_field:wizard.crossovered.analytic,init,date2:0
|
||||
msgid "End Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: field:account.analytic.plan.instance.line,rate:0
|
||||
msgid "Rate (%)"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: view:account.analytic.plan:0
|
||||
#: field:account.analytic.plan,name:0
|
||||
#: field:account.analytic.plan.line,plan_id:0
|
||||
#: model:ir.actions.act_window,name:account_analytic_plans.account_analytic_plan_form_action
|
||||
#: model:ir.ui.menu,name:account_analytic_plans.menu_account_analytic_plan_action
|
||||
msgid "Analytic Plan"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: model:ir.model,name:account_analytic_plans.model_account_analytic_plan_instance_line
|
||||
msgid "Analytic Instance Line"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: view:account.analytic.plan.instance.line:0
|
||||
msgid "Analytic Distribution Lines"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: wizard_button:wizard.crossovered.analytic,init,print:0
|
||||
msgid "Print"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: rml:account.analytic.account.crossovered.analytic:0
|
||||
msgid "To Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: field:account.analytic.plan.instance.line,plan_id:0
|
||||
msgid "Plan Id"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: model:ir.actions.act_window,name:account_analytic_plans.account_analytic_plan_instance_action
|
||||
msgid "Analytic Distribution's Models"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: rml:account.analytic.account.crossovered.analytic:0
|
||||
msgid "Account Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: view:account.analytic.plan.instance.line:0
|
||||
msgid "Analytic Distribution Line"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: field:account.analytic.plan.instance,code:0
|
||||
msgid "Distribution Code"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: constraint:ir.actions.act_window:0
|
||||
msgid "Invalid model name in the action definition."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: field:account.analytic.plan.line,name:0
|
||||
msgid "Plan Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: rml:account.analytic.account.crossovered.analytic:0
|
||||
msgid "Printing date"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: rml:account.analytic.account.crossovered.analytic:0
|
||||
msgid "Percentage"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: wizard_field:wizard.crossovered.analytic,init,empty_line:0
|
||||
msgid "Dont show empty lines"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: wizard_view:wizard.crossovered.analytic,init:0
|
||||
msgid "Select Information"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: field:account.analytic.plan.instance,account3_ids:0
|
||||
msgid "Account3 Id"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: field:account.analytic.plan.instance,journal_id:0
|
||||
#: wizard_field:wizard.crossovered.analytic,init,journal_ids:0
|
||||
msgid "Analytic Journal"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: rml:account.analytic.account.crossovered.analytic:0
|
||||
msgid "100.00%"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: wizard_field:wizard.crossovered.analytic,init,ref:0
|
||||
msgid "Analytic Account Ref."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: rml:account.analytic.account.crossovered.analytic:0
|
||||
msgid "Analytic Account :"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: view:account.analytic.plan.line:0
|
||||
msgid "Analytic Plan Line"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: rml:account.analytic.account.crossovered.analytic:0
|
||||
msgid "Analytic Account Reference:"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: model:ir.actions.wizard,name:account_analytic_plans.create_model
|
||||
msgid "Create Model"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: field:account.analytic.plan,default_instance_id:0
|
||||
msgid "Default Entries"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: view:account.analytic.plan:0
|
||||
#: field:account.analytic.plan,plan_ids:0
|
||||
#: field:account.journal,plan_id:0
|
||||
#: model:ir.model,name:account_analytic_plans.model_account_analytic_plan
|
||||
msgid "Analytic Plans"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: field:account.analytic.plan.line,min_required:0
|
||||
msgid "Minimum Allowed (%)"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: field:account.analytic.plan.instance,account1_ids:0
|
||||
msgid "Account1 Id"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: field:account.analytic.plan.line,max_required:0
|
||||
msgid "Maximum Allowed (%)"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: wizard_view:create.model,info:0
|
||||
msgid "Distribution Model Saved"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: model:ir.model,name:account_analytic_plans.model_account_analytic_plan_instance
|
||||
msgid "Analytic Plan Instance"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: constraint:ir.ui.view:0
|
||||
msgid "Invalid XML for View Architecture!"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: model:ir.actions.act_window,name:account_analytic_plans.account_analytic_instance_model_open
|
||||
msgid "Distribution Models"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
#: model:ir.module.module,description:account_analytic_plans.module_meta_information
|
||||
msgid "This module allows to use several analytic plans, according to the general journal,\n"
|
||||
"This module allows to use several analytic plans, according to the general "
|
||||
"journal,\n"
|
||||
"so that multiple analytic lines are created when the invoice or the entries\n"
|
||||
"are confirmed.\n"
|
||||
"\n"
|
||||
|
@ -614,7 +251,8 @@ msgid "This module allows to use several analytic plans, according to the genera
|
|||
"Plan2:\n"
|
||||
" Eric: 100%\n"
|
||||
"\n"
|
||||
"So when this line of invoice will be confirmed, it will generate 3 analytic lines,\n"
|
||||
"So when this line of invoice will be confirmed, it will generate 3 analytic "
|
||||
"lines,\n"
|
||||
"for one account entry.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
@ -687,7 +325,8 @@ msgstr ""
|
|||
|
||||
#. module: account_analytic_plans
|
||||
#: wizard_view:create.model,info:0
|
||||
msgid "This distribution model has been saved. You will be able to reuse it later."
|
||||
msgid ""
|
||||
"This distribution model has been saved. You will be able to reuse it later."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_analytic_plans
|
||||
|
@ -733,4 +372,3 @@ msgstr ""
|
|||
#: rml:account.analytic.account.crossovered.analytic:0
|
||||
msgid "From Date"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -163,7 +163,7 @@
|
|||
<field name="model">crossovered.budget</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Budget">
|
||||
<tree colors="blue:state in ('draft');gray:state in ('done','cancel');black:state in ('confirm','validate')" string="Budget">
|
||||
<field name="name" colspan="1" select="1"/>
|
||||
<field name="code" colspan="1" select="1" />
|
||||
<field name="state"/>
|
||||
|
|
|
@ -95,7 +95,7 @@
|
|||
<field name="type">tree</field>
|
||||
<field eval="32" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree editable="bottom" string="Partner entries">
|
||||
<tree colors="blue:state in ('draft');black:state in ('validate')" editable="bottom" string="Partner entries">
|
||||
<field name="date"/>
|
||||
<field name="move_id"/>
|
||||
<field name="ref"/>
|
||||
|
|
|
@ -177,7 +177,7 @@
|
|||
<field name="type">tree</field>
|
||||
<field eval="4" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Payment order">
|
||||
<tree colors="blue:state in ('draft');gray:state in ('cancel','done');black:state in ('open')" editable="bottom" string="Payment order">
|
||||
<field name="reference"/>
|
||||
<field name="mode"/>
|
||||
<field name="date_planned"/>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<field name="model">account.voucher</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Accounting Vouchers">
|
||||
<tree colors="blue:state in ('draft');gray:state in ('cancel','done');black:state in ('open','proforma','posted','recheck','audit')" string="Accounting Vouchers">
|
||||
<field name="date"/>
|
||||
<field name="number"/>
|
||||
<field name="name"/>
|
||||
|
|
|
@ -0,0 +1,275 @@
|
|||
# Chinese (Simplified) translation for openobject-addons
|
||||
# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2010-06-18 10:59+0000\n"
|
||||
"PO-Revision-Date: 2010-07-19 19:39+0000\n"
|
||||
"Last-Translator: Black Jack <onetimespeed@hotmail.com>\n"
|
||||
"Language-Team: Chinese (Simplified) <zh_CN@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: 2010-07-21 03:43+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.account,child_ids:0
|
||||
msgid "Child Accounts"
|
||||
msgstr "子项"
|
||||
|
||||
#. module: analytic
|
||||
#: help:account.analytic.line,amount_currency:0
|
||||
msgid ""
|
||||
"The amount expressed in the related account currency if not equal to the "
|
||||
"company one."
|
||||
msgstr "如果不是同一公司, 这金额表示相关项的货币"
|
||||
|
||||
#. module: analytic
|
||||
#: constraint:ir.model:0
|
||||
msgid ""
|
||||
"The Object name must start with x_ and not contain any special character !"
|
||||
msgstr "对象名必须以x_开头并且不能包含特殊字符"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.account,name:0
|
||||
msgid "Account Name"
|
||||
msgstr "项名称"
|
||||
|
||||
#. module: analytic
|
||||
#: help:account.analytic.line,unit_amount:0
|
||||
msgid "Specifies the amount of quantity to count."
|
||||
msgstr "指定金额的数量用来计算"
|
||||
|
||||
#. module: analytic
|
||||
#: help:account.analytic.line,currency_id:0
|
||||
msgid "The related account currency if not equal to the company one."
|
||||
msgstr "如果不是同一公司, 这相关项的货币"
|
||||
|
||||
#. module: analytic
|
||||
#: model:ir.module.module,description:analytic.module_meta_information
|
||||
msgid ""
|
||||
"Module for defining analytic accounting object.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"模块定义辅助核算对象\n"
|
||||
" "
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.account,state:0
|
||||
msgid "State"
|
||||
msgstr "状态"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.account,user_id:0
|
||||
msgid "Account Manager"
|
||||
msgstr "项管理"
|
||||
|
||||
#. module: analytic
|
||||
#: selection:account.analytic.account,state:0
|
||||
msgid "Draft"
|
||||
msgstr "草稿"
|
||||
|
||||
#. module: analytic
|
||||
#: selection:account.analytic.account,state:0
|
||||
msgid "Closed"
|
||||
msgstr "已关闭"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.account,debit:0
|
||||
msgid "Debit"
|
||||
msgstr "借方"
|
||||
|
||||
#. module: analytic
|
||||
#: help:account.analytic.account,state:0
|
||||
msgid ""
|
||||
"* When an account is created its in 'Draft' state. "
|
||||
" \n"
|
||||
"* If any associated partner is there, it can be in 'Open' state. "
|
||||
" \n"
|
||||
"* If any pending balance is there it can be in 'Pending'. "
|
||||
" \n"
|
||||
"* And finally when all the transactions are over, it can be in 'Close' "
|
||||
"state. \n"
|
||||
"* The project can be in either if the states 'Template' and 'Running'.\n"
|
||||
" If it is template then we can make projects based on the template projects. "
|
||||
"If its in 'Running' state it is a normal project. "
|
||||
" \n"
|
||||
" If it is to be reviewed then the state is 'Pending'.\n"
|
||||
" When the project is completed the state is set to 'Done'."
|
||||
msgstr ""
|
||||
"*当创建这项时为'草稿'状态.\n"
|
||||
"*如果有任何相关的业务伙伴它是'待处理'状态.\n"
|
||||
"*如果有任何悬而未决的差额它为'悬而未决'状态.\n"
|
||||
"*当所有交易已结束, 它是'关闭'状态\n"
|
||||
"\n"
|
||||
"*该项目状态可为其中之一, 如果是'模板'状态我们能按项目模板来建造项目, 如果为'运行中'它是一正常项目\n"
|
||||
"如果需要审查则状态为'悬而未决'\n"
|
||||
"当项目结束状态为'完成'"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.account,type:0
|
||||
msgid "Account Type"
|
||||
msgstr "项类型"
|
||||
|
||||
#. module: analytic
|
||||
#: selection:account.analytic.account,state:0
|
||||
msgid "Template"
|
||||
msgstr "模板"
|
||||
|
||||
#. module: analytic
|
||||
#: selection:account.analytic.account,state:0
|
||||
msgid "Pending"
|
||||
msgstr "悬而未决"
|
||||
|
||||
#. module: analytic
|
||||
#: model:ir.model,name:analytic.model_account_analytic_line
|
||||
msgid "Analytic Line"
|
||||
msgstr "辅助核算明细"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.account,description:0
|
||||
#: field:account.analytic.line,name:0
|
||||
msgid "Description"
|
||||
msgstr "说明"
|
||||
|
||||
#. module: analytic
|
||||
#: help:account.analytic.line,amount:0
|
||||
msgid ""
|
||||
"Calculated by multiplying the quantity and the price given in the Product's "
|
||||
"cost price."
|
||||
msgstr "乘与数量和价格, 提供产品的成本价格"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.account,company_id:0
|
||||
#: field:account.analytic.line,company_id:0
|
||||
msgid "Company"
|
||||
msgstr "公司"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.account,quantity_max:0
|
||||
msgid "Maximum Quantity"
|
||||
msgstr "最大数量"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.line,user_id:0
|
||||
msgid "User"
|
||||
msgstr "用户"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.account,parent_id:0
|
||||
msgid "Parent Analytic Account"
|
||||
msgstr "上级辅助核算项"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.line,date:0
|
||||
msgid "Date"
|
||||
msgstr "日期"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.account,currency_id:0
|
||||
#: field:account.analytic.line,currency_id:0
|
||||
msgid "Account currency"
|
||||
msgstr "辅助核算项货币"
|
||||
|
||||
#. module: analytic
|
||||
#: selection:account.analytic.account,type:0
|
||||
msgid "View"
|
||||
msgstr "视图"
|
||||
|
||||
#. module: analytic
|
||||
#: help:account.analytic.account,quantity_max:0
|
||||
msgid "Sets the higher limit of quantity of hours."
|
||||
msgstr "设置较高的小时数限制"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.account,credit:0
|
||||
msgid "Credit"
|
||||
msgstr "贷方"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.line,amount:0
|
||||
msgid "Amount"
|
||||
msgstr "金额"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.account,contact_id:0
|
||||
msgid "Contact"
|
||||
msgstr "联系方式"
|
||||
|
||||
#. module: analytic
|
||||
#: selection:account.analytic.account,state:0
|
||||
msgid "Cancelled"
|
||||
msgstr "已取消"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.account,balance:0
|
||||
msgid "Balance"
|
||||
msgstr "差额"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.account,date_start:0
|
||||
msgid "Date Start"
|
||||
msgstr "开始日期"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.account,quantity:0
|
||||
#: field:account.analytic.line,unit_amount:0
|
||||
msgid "Quantity"
|
||||
msgstr "数量"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.account,date:0
|
||||
msgid "Date End"
|
||||
msgstr "结束日期"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.account,code:0
|
||||
msgid "Account Code"
|
||||
msgstr "辅助核算项代码"
|
||||
|
||||
#. module: analytic
|
||||
#: selection:account.analytic.account,type:0
|
||||
msgid "Normal"
|
||||
msgstr "正常"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.account,complete_name:0
|
||||
msgid "Full Account Name"
|
||||
msgstr "所有项目名称"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.line,account_id:0
|
||||
#: model:ir.model,name:analytic.model_account_analytic_account
|
||||
#: model:ir.module.module,shortdesc:analytic.module_meta_information
|
||||
msgid "Analytic Account"
|
||||
msgstr "辅助核算项"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.account,company_currency_id:0
|
||||
msgid "Currency"
|
||||
msgstr "货币"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.line,amount_currency:0
|
||||
msgid "Amount currency"
|
||||
msgstr "货币金额"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.account,partner_id:0
|
||||
msgid "Associated Partner"
|
||||
msgstr "相关业务伙伴"
|
||||
|
||||
#. module: analytic
|
||||
#: selection:account.analytic.account,state:0
|
||||
msgid "Open"
|
||||
msgstr "待处理"
|
||||
|
||||
#. module: analytic
|
||||
#: field:account.analytic.account,line_ids:0
|
||||
msgid "Analytic Entries"
|
||||
msgstr "辅助核算记录"
|
|
@ -231,7 +231,7 @@
|
|||
<field name="type">tree</field>
|
||||
<field name="priority" eval="1"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Catalog">
|
||||
<tree colors="blue:state in ('unsold','draft');black:state in ('sold','taken_away');gray:state in ('paid') " string="Catalog">
|
||||
<field name="obj_num" string="Ref" select="1"/>
|
||||
<field name="name" select="1"/>
|
||||
<field name="ach_login"/>
|
||||
|
@ -1366,7 +1366,7 @@ Auction adjudication
|
|||
<field name="model">report.auction.adjudication</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Total adjudication">
|
||||
<tree colors="blue:state in ('draft');black:state in ('close')" string="Total adjudication">
|
||||
<field name="name" select="1"/>
|
||||
<field name="adj_total" select="1"/>
|
||||
<field name="state" select="1"/>
|
||||
|
@ -1540,7 +1540,7 @@ Object encoded
|
|||
<field name="model">report.unclassified.objects</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Unclassified objects">
|
||||
<tree colors="blue:state in ('draft','unsold');black:state in ('sold');gray:state in ('paid')"string="Unclassified objects">
|
||||
<field name="obj_num" string="Ref" select="1"/>
|
||||
<field name="name" select="1"/>
|
||||
<field name="ach_login"/>
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
<field name="model">audittrail.rule</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="AuditTrail Rules">
|
||||
<tree colors="blue:state in ('draft');black:state in ('subscribed')" string="AuditTrail Rules">
|
||||
<field name="name" />
|
||||
<field name="object_id"/>
|
||||
<field name="user_id" />
|
||||
|
@ -157,7 +157,7 @@
|
|||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<menuitem name="Logs" id="menu_action_audittrail_log_tree"
|
||||
action="action_audittrail_log_tree" parent="menu_action_audittrail" />
|
||||
action="action_audittrail_log_tree" parent="menu_action_audittrail" />
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -7,13 +7,13 @@ msgstr ""
|
|||
"Project-Id-Version: OpenERP Server 5.0.0\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
|
||||
"PO-Revision-Date: 2009-11-18 05:58+0000\n"
|
||||
"Last-Translator: Fabien (Open ERP) <fp@tinyerp.com>\n"
|
||||
"PO-Revision-Date: 2010-07-20 21:26+0000\n"
|
||||
"Last-Translator: Giedrius Slavinskas <giedrius.slavinskas@gmail.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: 2010-06-22 04:01+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-07-21 03:43+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: base_contact
|
||||
|
@ -292,7 +292,7 @@ msgstr "Partneriai"
|
|||
#: model:process.node,name:base_contact.process_node_addresses0
|
||||
#: view:res.partner:0
|
||||
msgid "Addresses"
|
||||
msgstr ""
|
||||
msgstr "Adresai"
|
||||
|
||||
#. module: base_contact
|
||||
#: model:process.node,note:base_contact.process_node_addresses0
|
||||
|
|
|
@ -23,18 +23,18 @@
|
|||
<attribute name="string">Install Generic Modules</attribute>
|
||||
</separator>
|
||||
<group colspan="8">
|
||||
<field name="crm" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,profile_association,profile_auction,profile_bookstore)"/> <field name="sale" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,profile_association,profile_auction,profile_bookstore)"/>
|
||||
<field name="project" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,profile_association,profile_auction,profile_bookstore)"/> <field name="knowledge" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,profile_association,profile_auction,profile_bookstore)"/>
|
||||
<field name="stock" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,profile_association,profile_auction,profile_bookstore)"/> <field name="mrp" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,profile_association,profile_auction,profile_bookstore)"/>
|
||||
<field name="account" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,profile_association,profile_auction,profile_bookstore)"/> <field name="purchase" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,profile_association,profile_auction,profile_bookstore)"/>
|
||||
<field name="hr" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,profile_association,profile_auction,profile_bookstore)"/> <field name="point_of_sale" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,profile_association,profile_auction,profile_bookstore)"/>
|
||||
<field name="marketing" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,profile_association,profile_auction,profile_bookstore)"/> <field name="misc_tools" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,profile_association,profile_auction,profile_bookstore)"/>
|
||||
<field name="report_designer" groups="base.group_extended" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,profile_association,profile_auction,profile_bookstore)"/>
|
||||
<field name="crm" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,association,profile_auction,profile_bookstore)"/> <field name="sale" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,association,profile_auction,profile_bookstore)"/>
|
||||
<field name="project" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,association,profile_auction,profile_bookstore)"/> <field name="knowledge" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,association,profile_auction,profile_bookstore)"/>
|
||||
<field name="stock" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,association,profile_auction,profile_bookstore)"/> <field name="mrp" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,association,profile_auction,profile_bookstore)"/>
|
||||
<field name="account" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,association,profile_auction,profile_bookstore)"/> <field name="purchase" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,association,profile_auction,profile_bookstore)"/>
|
||||
<field name="hr" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,association,profile_auction,profile_bookstore)"/> <field name="point_of_sale" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,association,profile_auction,profile_bookstore)"/>
|
||||
<field name="marketing" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,association,profile_auction,profile_bookstore)"/> <field name="misc_tools" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,association,profile_auction,profile_bookstore)"/>
|
||||
<field name="report_designer" groups="base.group_extended" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,association,profile_auction,profile_bookstore)"/>
|
||||
<separator string="Install Specific Business Modules" colspan="4"/>
|
||||
<field name="association" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,profile_association,profile_auction,profile_bookstore)"/>
|
||||
<field name="profile_auction" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,profile_association,profile_auction,profile_bookstore)"/>
|
||||
<field name="profile_bookstore" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,profile_association,profile_auction,profile_bookstore)"/>
|
||||
<field name="product_expiry" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,profile_association,profile_auction,profile_bookstore)"/>
|
||||
<field name="association" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,association,profile_auction,profile_bookstore)"/>
|
||||
<field name="profile_auction" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,association,profile_auction,profile_bookstore)"/>
|
||||
<field name="profile_bookstore" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,association,profile_auction,profile_bookstore)"/>
|
||||
<field name="product_expiry" on_change="onchange_moduleselection(crm,sale,project,knowledge,stock,mrp,account,purchase,hr,point_of_sale,marketing,misc_tools,report_designer,association,profile_auction,profile_bookstore)"/>
|
||||
</group>
|
||||
</data>
|
||||
</field>
|
||||
|
|
|
@ -7,13 +7,13 @@ msgstr ""
|
|||
"Project-Id-Version: OpenERP Server 5.0.0\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
|
||||
"PO-Revision-Date: 2009-11-18 06:43+0000\n"
|
||||
"Last-Translator: Fabien (Open ERP) <fp@tinyerp.com>\n"
|
||||
"PO-Revision-Date: 2010-07-20 22:26+0000\n"
|
||||
"Last-Translator: Paulius Sladkevičius <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: 2010-06-22 04:14+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-07-21 03:43+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: board
|
||||
|
@ -21,32 +21,34 @@ msgstr ""
|
|||
msgid ""
|
||||
"The Object name must start with x_ and not contain any special character !"
|
||||
msgstr ""
|
||||
"Objekto pavadinimas turi prasidėti x_ ir negali turėti jokių specialiųjų "
|
||||
"ženklų !"
|
||||
|
||||
#. module: board
|
||||
#: model:ir.model,name:board.model_board_board
|
||||
msgid "board.board"
|
||||
msgstr ""
|
||||
msgstr "Veiklos monitoringas"
|
||||
|
||||
#. module: board
|
||||
#: field:board.note,user_id:0
|
||||
msgid "Author"
|
||||
msgstr ""
|
||||
msgstr "Autorius"
|
||||
|
||||
#. module: board
|
||||
#: model:ir.module.module,shortdesc:board.module_meta_information
|
||||
msgid "Dashboard main module"
|
||||
msgstr ""
|
||||
msgstr "Veiklos monitoringo modulis"
|
||||
|
||||
#. module: board
|
||||
#: view:board.note:0
|
||||
#: field:board.note,note:0
|
||||
msgid "Note"
|
||||
msgstr ""
|
||||
msgstr "Pastaba"
|
||||
|
||||
#. module: board
|
||||
#: field:board.board.line,width:0
|
||||
msgid "Width"
|
||||
msgstr ""
|
||||
msgstr "Plotis"
|
||||
|
||||
#. module: board
|
||||
#: constraint:ir.actions.act_window:0
|
||||
|
@ -56,39 +58,39 @@ msgstr ""
|
|||
#. module: board
|
||||
#: field:board.board.line,name:0
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
msgstr "Antraštė"
|
||||
|
||||
#. module: board
|
||||
#: model:ir.actions.act_window,name:board.action_view_board_list_form
|
||||
#: model:ir.ui.menu,name:board.menu_view_board_form
|
||||
msgid "Dashboard Definition"
|
||||
msgstr ""
|
||||
msgstr "Veiklos monitoringo nustatymai"
|
||||
|
||||
#. module: board
|
||||
#: model:ir.actions.act_window,name:board.action_view_board_note_form
|
||||
#: model:ir.ui.menu,name:board.menu_view_board_note_form
|
||||
msgid "Publish a note"
|
||||
msgstr ""
|
||||
msgstr "Publikuoti pastabą"
|
||||
|
||||
#. module: board
|
||||
#: wizard_view:board.board.menu.create,init:0
|
||||
msgid "Menu Information"
|
||||
msgstr ""
|
||||
msgstr "Meniu informacija"
|
||||
|
||||
#. module: board
|
||||
#: field:board.board,line_ids:0
|
||||
msgid "Action Views"
|
||||
msgstr ""
|
||||
msgstr "Vaizdas"
|
||||
|
||||
#. module: board
|
||||
#: model:ir.model,name:board.model_board_note
|
||||
msgid "board.note"
|
||||
msgstr ""
|
||||
msgstr "Pastaba"
|
||||
|
||||
#. module: board
|
||||
#: field:board.note,date:0
|
||||
msgid "Date"
|
||||
msgstr ""
|
||||
msgstr "Data"
|
||||
|
||||
#. module: board
|
||||
#: model:ir.ui.menu,name:board.next_id_50
|
||||
|
@ -98,122 +100,125 @@ msgstr "Nustatymai"
|
|||
#. module: board
|
||||
#: field:board.note.type,name:0
|
||||
msgid "Note Type"
|
||||
msgstr ""
|
||||
msgstr "Pastabos tipas"
|
||||
|
||||
#. module: board
|
||||
#: wizard_view:board.board.menu.create,init:0
|
||||
msgid "Create Menu For Dashboard"
|
||||
msgstr ""
|
||||
msgstr "Sukurti meniu veiklos monitoringui"
|
||||
|
||||
#. module: board
|
||||
#: constraint:ir.ui.view:0
|
||||
msgid "Invalid XML for View Architecture!"
|
||||
msgstr ""
|
||||
msgstr "Netinkamas XML peržiūros strūkturai!"
|
||||
|
||||
#. module: board
|
||||
#: wizard_field:board.board.menu.create,init,menu_parent_id:0
|
||||
msgid "Parent Menu"
|
||||
msgstr ""
|
||||
msgstr "Bazinis meniu"
|
||||
|
||||
#. module: board
|
||||
#: view:board.note:0
|
||||
msgid "Notes"
|
||||
msgstr ""
|
||||
msgstr "Pastabos"
|
||||
|
||||
#. module: board
|
||||
#: model:ir.model,name:board.model_board_note_type
|
||||
msgid "board.note.type"
|
||||
msgstr ""
|
||||
msgstr "Monitoringo pastabų tipas"
|
||||
|
||||
#. module: board
|
||||
#: view:board.board:0
|
||||
#: field:board.board,name:0
|
||||
#: field:board.board.line,board_id:0
|
||||
msgid "Dashboard"
|
||||
msgstr ""
|
||||
msgstr "Veiklos monitoringas"
|
||||
|
||||
#. module: board
|
||||
#: model:ir.module.module,description:board.module_meta_information
|
||||
msgid "Base module for all dashboards."
|
||||
msgstr ""
|
||||
msgstr "Veiklos monitoringo pagrindinis modulis"
|
||||
|
||||
#. module: board
|
||||
#: field:board.board.line,position:0
|
||||
msgid "Position"
|
||||
msgstr ""
|
||||
msgstr "Pareigos"
|
||||
|
||||
#. module: board
|
||||
#: model:ir.actions.act_window,name:board.dashboard_open
|
||||
msgid "Open Dashboard"
|
||||
msgstr ""
|
||||
msgstr "Atidaryti veiklos monitoringą"
|
||||
|
||||
#. module: board
|
||||
#: wizard_field:board.board.menu.create,init,menu_name:0
|
||||
msgid "Menu Name"
|
||||
msgstr ""
|
||||
msgstr "Meniu pavadinimas"
|
||||
|
||||
#. module: board
|
||||
#: field:board.note,type:0
|
||||
msgid "Note type"
|
||||
msgstr ""
|
||||
msgstr "Pastabos tipas"
|
||||
|
||||
#. module: board
|
||||
#: selection:board.board.line,position:0
|
||||
msgid "Left"
|
||||
msgstr ""
|
||||
msgstr "Kairėje"
|
||||
|
||||
#. module: board
|
||||
#: field:board.board,view_id:0
|
||||
msgid "Board View"
|
||||
msgstr ""
|
||||
msgstr "Veiklos monitoringas"
|
||||
|
||||
#. module: board
|
||||
#: selection:board.board.line,position:0
|
||||
msgid "Right"
|
||||
msgstr ""
|
||||
msgstr "Dešinėje"
|
||||
|
||||
#. module: board
|
||||
#: field:board.board.line,sequence:0
|
||||
msgid "Sequence"
|
||||
msgstr ""
|
||||
msgstr "Seka"
|
||||
|
||||
#. module: board
|
||||
#: view:board.board:0
|
||||
#: wizard_button:board.board.menu.create,init,create_menu:0
|
||||
msgid "Create Menu"
|
||||
msgstr ""
|
||||
msgstr "Sukurti meniu"
|
||||
|
||||
#. module: board
|
||||
#: model:ir.ui.menu,name:board.dashboard_menu
|
||||
msgid "Dashboards"
|
||||
msgstr ""
|
||||
msgstr "Veiklos monitoringas"
|
||||
|
||||
#. module: board
|
||||
#: field:board.board.line,height:0
|
||||
msgid "Height"
|
||||
msgstr ""
|
||||
msgstr "Aukštis"
|
||||
|
||||
#. module: board
|
||||
#: model:ir.actions.wizard,name:board.wizard_board_create_menu
|
||||
msgid "Create Board Menu"
|
||||
msgstr ""
|
||||
msgstr "Sukurti veiklos monitoringo meniu"
|
||||
|
||||
#. module: board
|
||||
#: wizard_button:board.board.menu.create,init,end:0
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
msgstr "Atšaukti"
|
||||
|
||||
#. module: board
|
||||
#: view:board.board:0
|
||||
msgid "Dashboard View"
|
||||
msgstr ""
|
||||
msgstr "Veiklos monitoringo vaizdas"
|
||||
|
||||
#. module: board
|
||||
#: model:ir.model,name:board.model_board_board_line
|
||||
msgid "board.board.line"
|
||||
msgstr ""
|
||||
msgstr "Monitoringo eilutė"
|
||||
|
||||
#. module: board
|
||||
#: field:board.note,name:0
|
||||
msgid "Subject"
|
||||
msgstr ""
|
||||
msgstr "Tema"
|
||||
|
||||
#~ msgid "Action"
|
||||
#~ msgstr "Veiksmas"
|
||||
|
|
|
@ -198,7 +198,8 @@ class crm_lead(osv.osv, crm_case):
|
|||
self.write(cr, uid, ids, value)
|
||||
|
||||
for (id, name) in self.name_get(cr, uid, ids):
|
||||
message = _('The Lead') + " '" + name + "' "+ _("has been written as Open.")
|
||||
type = self.browse(cr, uid, id).type
|
||||
message = (_('The ') + type.title() or 'Lead') + " '" + name + "' "+ _("has been written as Open.")
|
||||
self.log(cr, uid, id, message)
|
||||
return res
|
||||
|
||||
|
@ -213,8 +214,10 @@ class crm_lead(osv.osv, crm_case):
|
|||
res = super(crm_lead, self).case_close(cr, uid, ids, args)
|
||||
self.write(cr, uid, ids, {'date_closed': time.strftime('%Y-%m-%d %H:%M:%S')})
|
||||
for (id, name) in self.name_get(cr, uid, ids):
|
||||
message = _('The Lead') + " '" + name + "' "+ _("has been written as Closed.")
|
||||
self.log(cr, uid, id, message)
|
||||
lead = self.browse(cr, uid, id)
|
||||
if lead.type == 'lead':
|
||||
message = _('The Lead') + " '" + name + "' "+ _("has been written as Closed.")
|
||||
self.log(cr, uid, id, message)
|
||||
return res
|
||||
|
||||
def convert_opportunity(self, cr, uid, ids, context=None):
|
||||
|
|
|
@ -93,8 +93,10 @@ class crm_opportunity(osv.osv):
|
|||
|
||||
res = self.write(cr, uid, ids, value)
|
||||
for (id, name) in self.name_get(cr, uid, ids):
|
||||
message = _('The Opportunity') + " '" + name + "' "+ _("has been written as Lost.")
|
||||
self.log(cr, uid, id, message)
|
||||
opp = self.browse(cr, uid, id)
|
||||
if opp.type == 'opportunity':
|
||||
message = _('The Opportunity') + " '" + name + "' "+ _("has been written as Lost.")
|
||||
self.log(cr, uid, id, message)
|
||||
return res
|
||||
|
||||
def case_cancel(self, cr, uid, ids, *args):
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
<field name="model">crm.phonecall</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Phone Calls" colors="grey:state in ('cancel','done');blue:state in ('pending',)">
|
||||
<tree colors="gray:state in ('cancel','done');blue:state in ('pending',)" string="Phone Calls">
|
||||
<field name="date" string="Date"/>
|
||||
<field name="name" string="Call Summary"/>
|
||||
<field name="partner_id" string="Partner"/>
|
||||
|
|
|
@ -14,7 +14,7 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2010-07-19 03:41+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-07-21 03:42+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: crm
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -9,7 +9,7 @@
|
|||
<field name="model">crm.lead.report</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Leads Analysis">
|
||||
<tree colors="blue:state in ('draft');black:state in ('open','pending','done');gray:state in ('cancel') " string="Leads Analysis">
|
||||
<field name="name" invisible="1"/>
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="stage_id" invisible="1"/>
|
||||
|
@ -154,7 +154,7 @@
|
|||
<field name="model">crm.lead.report</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Opportunities Analysis">
|
||||
<tree colors="blue:state in ('draft');black:state in ('open','pending','done');gray:state in ('cancel') " string="Opportunities Analysis">
|
||||
<field name="name" invisible="1"/>
|
||||
<field name="month" invisible="1"/>
|
||||
<field name="section_id" invisible="1" groups="base.group_extended"/>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<field name="model">crm.phonecall.report</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Phone calls">
|
||||
<tree colors="blue:state in ('draft');black:state in ('open','pending','done');gray:state in ('cancel') " string="Phone calls">
|
||||
<field name="name" invisible="1"/>
|
||||
<field name="month" invisible="1"/>
|
||||
<field name="section_id" invisible="1"/>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<field name="arch" type="xml">
|
||||
<page string="History" position="inside">
|
||||
<field name="opportunity_ids" colspan="4" nolabel="1">
|
||||
<tree string="Opportunities" colors="blue:state=='pending';grey:state=='cancel')">
|
||||
<tree string="Opportunities" colors="blue:state=='pending';gray:state=='cancel')">
|
||||
<field name="create_date"/>
|
||||
<field name="name"/>
|
||||
<field name="type"/>
|
||||
|
@ -45,7 +45,7 @@
|
|||
</tree>
|
||||
</field>
|
||||
<field name="opportunity_assigned_ids" colspan="4" nolabel="1">
|
||||
<tree string="Assigned Opportunities" colors="blue:state=='pending';grey:state=='cancel')">
|
||||
<tree string="Assigned Opportunities" colors="blue:state=='pending';gray:state=='cancel')">
|
||||
<field name="create_date"/>
|
||||
<field name="name"/>
|
||||
<field name="type"/>
|
||||
|
|
|
@ -187,12 +187,14 @@ class crm_lead_forward_to_partner(osv.osv_memory):
|
|||
email_re = r'([^ ,<@]+@[^> ,]+)'
|
||||
email_cc = re.findall(email_re, case.email_cc or '')
|
||||
new_cc = []
|
||||
if case.email_cc:
|
||||
new_cc.append(case.email_cc)
|
||||
for to in this.email_to.split(','):
|
||||
email_to = re.findall(email_re, to)
|
||||
email_to = email_to and email_to[0] or ''
|
||||
if email_to not in email_cc:
|
||||
new_cc.append(to)
|
||||
to_write.update({'email_cc' : case.email_cc or '' + ','.join(new_cc)})
|
||||
to_write.update({'email_cc' : ', '.join(new_cc) })
|
||||
case_pool.write(cr, uid, case.id, to_write, context=context)
|
||||
|
||||
return {}
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
<field name="model">crm.claim</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Claims" colors="blue:state=='pending';black:state=='open';grey:state in ('close', 'cancel')">
|
||||
<tree string="Claims" colors="blue:state=='pending';black:state=='open';gray:state in ('close', 'cancel')">
|
||||
<field name="name"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="user_id" />
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<field name="model">crm.fundraising.report</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Fundraising">
|
||||
<tree colors="blue:state in ('draft');black:state in ('open','pending');gray:state in ('done','cancel') " string="Fundraising">
|
||||
<field name="name" invisible="1"/>
|
||||
<field name="month" invisible="1"/>
|
||||
<field name="section_id" invisible="1"/>
|
||||
|
|
|
@ -168,7 +168,7 @@
|
|||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Helpdesk Support Tree"
|
||||
colors="black:state=='open';blue:state=='pending';grey:state in ('cancel','close')">
|
||||
colors="black:state=='open';blue:state=='pending';gray:state in ('cancel','close')">
|
||||
<field name="name" string="Query" />
|
||||
<field name="partner_id" string="Partner"/>
|
||||
<field name="date" string="Date"/>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<field name="model">crm.helpdesk.report</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Helpdesk">
|
||||
<tree colors="blue:state in ('draft');black:state in ('open','pending');gray:state in ('done','cancel') " string="Helpdesk">
|
||||
<field name="name" />
|
||||
<field name="month"/>
|
||||
<field name="section_id" />
|
||||
|
|
|
@ -7,58 +7,58 @@ msgstr ""
|
|||
"Project-Id-Version: OpenERP Server 5.0.4\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
|
||||
"PO-Revision-Date: 2010-01-10 01:56+0000\n"
|
||||
"Last-Translator: Wei \"oldrev\" Li <oldrev@gmail.com>\n"
|
||||
"PO-Revision-Date: 2010-07-19 19:55+0000\n"
|
||||
"Last-Translator: Black Jack <onetimespeed@hotmail.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: 2010-06-22 04:16+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-07-21 03:43+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: constraint:ir.model:0
|
||||
msgid ""
|
||||
"The Object name must start with x_ and not contain any special character !"
|
||||
msgstr "对象名称必须以“x_”起头且不能包含任何特殊字符!"
|
||||
msgstr "对象名称必须以“x_”开头且不能包含任何特殊字符!"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: field:crm_profiling.answer,question_id:0
|
||||
#: field:crm_profiling.question,name:0
|
||||
#: model:ir.model,name:crm_profiling.model_crm_profiling_question
|
||||
msgid "Question"
|
||||
msgstr ""
|
||||
msgstr "问题"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: wizard_button:open_questionnaire,init,open:0
|
||||
msgid "Open Questionnaire"
|
||||
msgstr ""
|
||||
msgstr "待处理调查问卷"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: field:crm.segmentation,child_ids:0
|
||||
msgid "Child Profiles"
|
||||
msgstr ""
|
||||
msgstr "子配置"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: model:ir.module.module,shortdesc:crm_profiling.module_meta_information
|
||||
msgid "crm_profiling management"
|
||||
msgstr ""
|
||||
msgstr "crm配置管理"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: constraint:ir.actions.act_window:0
|
||||
msgid "Invalid model name in the action definition."
|
||||
msgstr "在动作定义中输入的对象名称错误"
|
||||
msgstr "在动作定义中使用了无效的模快名。"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: field:crm_profiling.answer,name:0
|
||||
#: model:ir.model,name:crm_profiling.model_crm_profiling_answer
|
||||
msgid "Answer"
|
||||
msgstr ""
|
||||
msgstr "答案"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: view:res.partner:0
|
||||
msgid "Profiling"
|
||||
msgstr ""
|
||||
msgstr "配置中"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: field:crm_profiling.questionnaire,description:0
|
||||
|
@ -68,71 +68,73 @@ msgstr "说明"
|
|||
#. module: crm_profiling
|
||||
#: field:crm.segmentation,answer_no:0
|
||||
msgid "Excluded Answers"
|
||||
msgstr ""
|
||||
msgstr "排除的答案"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: view:crm_profiling.answer:0
|
||||
#: view:crm_profiling.question:0
|
||||
#: field:res.partner,answers_ids:0
|
||||
msgid "Answers"
|
||||
msgstr ""
|
||||
msgstr "答案"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: wizard_field:open_questionnaire,init,questionnaire_name:0
|
||||
msgid "Questionnaire name"
|
||||
msgstr ""
|
||||
msgstr "调查问卷名称"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: view:res.partner:0
|
||||
msgid "Use a questionnaire"
|
||||
msgstr ""
|
||||
msgstr "使用的调查问卷"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: constraint:ir.ui.view:0
|
||||
msgid "Invalid XML for View Architecture!"
|
||||
msgstr ""
|
||||
msgstr "无效的视图结构xml文件!"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: view:crm_profiling.questionnaire:0
|
||||
#: model:ir.actions.act_window,name:crm_profiling.open_questionnaires
|
||||
#: model:ir.ui.menu,name:crm_profiling.menu_segm_questionnaire
|
||||
msgid "Questionnaires"
|
||||
msgstr ""
|
||||
msgstr "调查问卷"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: code:addons/crm_profiling/crm_profiling.py:0
|
||||
#: field:crm_profiling.questionnaire,name:0
|
||||
#: model:ir.model,name:crm_profiling.model_crm_profiling_questionnaire
|
||||
#: wizard_view:open_questionnaire,init:0
|
||||
#, python-format
|
||||
msgid "Questionnaire"
|
||||
msgstr ""
|
||||
msgstr "调查问卷"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: constraint:crm.segmentation:0
|
||||
msgid "Error ! You can not create recursive profiles."
|
||||
msgstr ""
|
||||
msgstr "错误! 你不能创建递归的配置"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: field:crm.segmentation,profiling_active:0
|
||||
msgid "Use The Profiling Rules"
|
||||
msgstr ""
|
||||
msgstr "使用这配置规则"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: view:crm_profiling.question:0
|
||||
#: field:crm_profiling.question,answers_ids:0
|
||||
msgid "Avalaible answers"
|
||||
msgstr ""
|
||||
msgstr "可用答案"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: field:crm.segmentation,answer_yes:0
|
||||
msgid "Included Answers"
|
||||
msgstr ""
|
||||
msgstr "包括答案"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: help:crm.segmentation,profiling_active:0
|
||||
msgid ""
|
||||
"Check this box if you want to use this tab as part of the segmentation rule. "
|
||||
"If not checked, the criteria beneath will be ignored"
|
||||
msgstr ""
|
||||
msgstr "勾选此项, 如果你想使用这tab做为细分规则的一部分, 如果不选下面的标准将被忽略"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: view:crm_profiling.question:0
|
||||
|
@ -140,30 +142,30 @@ msgstr ""
|
|||
#: model:ir.actions.act_window,name:crm_profiling.open_questions
|
||||
#: model:ir.ui.menu,name:crm_profiling.menu_segm_answer
|
||||
msgid "Questions"
|
||||
msgstr ""
|
||||
msgstr "问题"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: field:crm.segmentation,parent_id:0
|
||||
msgid "Parent Profile"
|
||||
msgstr ""
|
||||
msgstr "上级配置"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: wizard_button:open_questionnaire,init,end:0
|
||||
#: wizard_button:open_questionnaire,open,end:0
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
msgstr "取消"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: view:crm.segmentation:0
|
||||
msgid "Partner Segmentations"
|
||||
msgstr "业务伙伴分类"
|
||||
msgstr "业务伙伴细分"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: model:ir.actions.wizard,name:crm_profiling.wizard_open_questionnaire
|
||||
msgid "Using a questionnaire"
|
||||
msgstr ""
|
||||
msgstr "使用一调查问卷"
|
||||
|
||||
#. module: crm_profiling
|
||||
#: wizard_button:open_questionnaire,open,compute:0
|
||||
msgid "Save Data"
|
||||
msgstr ""
|
||||
msgstr "保存日期"
|
||||
|
|
|
@ -7,13 +7,13 @@ msgstr ""
|
|||
"Project-Id-Version: OpenERP Server 5.0.6\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
|
||||
"PO-Revision-Date: 2010-03-20 07:47+0000\n"
|
||||
"PO-Revision-Date: 2010-07-20 03:54+0000\n"
|
||||
"Last-Translator: Black Jack <onetimespeed@hotmail.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: 2010-06-22 03:56+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-07-21 03:42+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: delivery
|
||||
|
@ -45,7 +45,7 @@ msgstr "邮递送货"
|
|||
#. module: delivery
|
||||
#: constraint:ir.ui.view:0
|
||||
msgid "Invalid XML for View Architecture!"
|
||||
msgstr "无效XML视图结构!"
|
||||
msgstr "无效的视图结构xml文件!"
|
||||
|
||||
#. module: delivery
|
||||
#: constraint:res.partner:0
|
||||
|
@ -60,17 +60,17 @@ msgstr "状态"
|
|||
#. module: delivery
|
||||
#: constraint:ir.actions.act_window:0
|
||||
msgid "Invalid model name in the action definition."
|
||||
msgstr "在这动作定义中有无效的模块名"
|
||||
msgstr "在动作定义中使用了无效的模快名。"
|
||||
|
||||
#. module: delivery
|
||||
#: help:res.partner,property_delivery_carrier:0
|
||||
msgid "This delivery method will be used when invoicing from packing."
|
||||
msgstr "这送货方式将用在包装的发票上"
|
||||
msgstr "这交货方式将用在包装的发票上"
|
||||
|
||||
#. module: delivery
|
||||
#: model:ir.model,name:delivery.model_delivery_grid
|
||||
msgid "Delivery Grid"
|
||||
msgstr "送货网"
|
||||
msgstr "交货表格"
|
||||
|
||||
#. module: delivery
|
||||
#: field:delivery.grid,zip_from:0
|
||||
|
@ -85,13 +85,13 @@ msgstr "固定的"
|
|||
#. module: delivery
|
||||
#: field:delivery.grid,line_ids:0
|
||||
msgid "Grid Line"
|
||||
msgstr "网格明细"
|
||||
msgstr "表格行"
|
||||
|
||||
#. module: delivery
|
||||
#: model:ir.actions.act_window,name:delivery.action_delivery_grid_form
|
||||
#: model:ir.ui.menu,name:delivery.menu_action_delivery_grid_form
|
||||
msgid "Delivery Pricelist"
|
||||
msgstr "送货价格表"
|
||||
msgstr "交货价格表"
|
||||
|
||||
#. module: delivery
|
||||
#: model:ir.actions.act_window,name:delivery.action_picking_tree5
|
||||
|
@ -102,38 +102,38 @@ msgstr "在接收产生发票草稿"
|
|||
#. module: delivery
|
||||
#: model:ir.model,name:delivery.model_delivery_grid_line
|
||||
msgid "Delivery line of grid"
|
||||
msgstr "运费表格行"
|
||||
msgstr "交货表格行"
|
||||
|
||||
#. module: delivery
|
||||
#: model:ir.ui.menu,name:delivery.menu_delivery
|
||||
msgid "Delivery"
|
||||
msgstr "送货"
|
||||
msgstr "交货"
|
||||
|
||||
#. module: delivery
|
||||
#: view:delivery.grid.line:0
|
||||
msgid "Grid Lines"
|
||||
msgstr "网格明细"
|
||||
msgstr "表格行"
|
||||
|
||||
#. module: delivery
|
||||
#: field:delivery.grid.line,grid_id:0
|
||||
msgid "Grid"
|
||||
msgstr "网格"
|
||||
msgstr "表格"
|
||||
|
||||
#. module: delivery
|
||||
#: view:res.partner:0
|
||||
msgid "Deliveries Properties"
|
||||
msgstr "送货属性"
|
||||
msgstr "交货属性"
|
||||
|
||||
#. module: delivery
|
||||
#: field:delivery.carrier,active:0
|
||||
#: field:delivery.grid,active:0
|
||||
msgid "Active"
|
||||
msgstr "现用"
|
||||
msgstr "有效"
|
||||
|
||||
#. module: delivery
|
||||
#: view:delivery.grid:0
|
||||
msgid "Grid definition"
|
||||
msgstr "网格定义"
|
||||
msgstr "表格定义"
|
||||
|
||||
#. module: delivery
|
||||
#: selection:delivery.grid.line,type:0
|
||||
|
@ -149,7 +149,7 @@ msgstr "="
|
|||
#. module: delivery
|
||||
#: field:delivery.carrier,product_id:0
|
||||
msgid "Delivery Product"
|
||||
msgstr "产品送货"
|
||||
msgstr "产品交货"
|
||||
|
||||
#. module: delivery
|
||||
#: view:delivery.grid.line:0
|
||||
|
@ -159,7 +159,7 @@ msgstr "条件"
|
|||
#. module: delivery
|
||||
#: model:ir.model,name:delivery.model_delivery_carrier
|
||||
msgid "Carrier and delivery grids"
|
||||
msgstr "货运公司和运费表格"
|
||||
msgstr "货运公司和交货表格"
|
||||
|
||||
#. module: delivery
|
||||
#: field:delivery.grid.line,standard_price:0
|
||||
|
@ -206,7 +206,7 @@ msgstr "可变的"
|
|||
#. module: delivery
|
||||
#: field:delivery.grid,name:0
|
||||
msgid "Grid Name"
|
||||
msgstr "运费表格名称"
|
||||
msgstr "表格名"
|
||||
|
||||
#. module: delivery
|
||||
#: view:delivery.carrier:0
|
||||
|
@ -231,7 +231,7 @@ msgstr "最大值"
|
|||
#. module: delivery
|
||||
#: wizard_button:delivery.sale.order,init,delivery:0
|
||||
msgid "Add Delivery Costs"
|
||||
msgstr "增加送货成本"
|
||||
msgstr "增加交货成本"
|
||||
|
||||
#. module: delivery
|
||||
#: wizard_field:delivery.sale.order,init,carrier_id:0
|
||||
|
@ -239,12 +239,12 @@ msgstr "增加送货成本"
|
|||
#: model:ir.ui.menu,name:delivery.menu_action_delivery_carrier_form
|
||||
#: field:res.partner,property_delivery_carrier:0
|
||||
msgid "Delivery Method"
|
||||
msgstr "送货方式"
|
||||
msgstr "交货方式"
|
||||
|
||||
#. module: delivery
|
||||
#: field:sale.order,id:0
|
||||
msgid "ID"
|
||||
msgstr "标识符"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: delivery
|
||||
#: field:delivery.grid.line,operator:0
|
||||
|
@ -254,12 +254,12 @@ msgstr "运算符"
|
|||
#. module: delivery
|
||||
#: model:ir.module.module,shortdesc:delivery.module_meta_information
|
||||
msgid "Carriers and deliveries"
|
||||
msgstr "运输公司和送货"
|
||||
msgstr "运输公司和交货"
|
||||
|
||||
#. module: delivery
|
||||
#: field:delivery.carrier,grids_id:0
|
||||
msgid "Delivery Grids"
|
||||
msgstr "送货网"
|
||||
msgstr "交货表格"
|
||||
|
||||
#. module: delivery
|
||||
#: selection:delivery.grid.line,type:0
|
||||
|
@ -284,7 +284,7 @@ msgid ""
|
|||
"Allows you to add delivery methods in sales orders and packing. You can "
|
||||
"define your own carrier and delivery grids for prices. When creating "
|
||||
"invoices from picking, Open ERP is able to add and compute the shipping line."
|
||||
msgstr "允许你在销售单和包装中增加送货方式.你能定义自己的运输公司和送货网的价格.当创建领料/提货发票时,系统可以增加和计算运输明细"
|
||||
msgstr "允许你在销售单和包装中增加交货方式. 你能定义自己的运输公司和交货表格的价格. 当创建包装发票时, 系统可以增加和计算运输明细"
|
||||
|
||||
#. module: delivery
|
||||
#: field:delivery.grid,zip_to:0
|
||||
|
@ -301,12 +301,12 @@ msgstr "包装要开发票"
|
|||
#: help:sale.order,carrier_id:0
|
||||
msgid ""
|
||||
"Complete this field if you plan to invoice the shipping based on packing."
|
||||
msgstr "如果你计划基于包装开运输发票请完整填写这字段"
|
||||
msgstr "如果你计划根据运输这包装开发票请完整填写这字段"
|
||||
|
||||
#. module: delivery
|
||||
#: model:ir.actions.wizard,name:delivery.wizard_deliver_line_add
|
||||
msgid "Delivery Costs"
|
||||
msgstr "送货成本"
|
||||
msgstr "交货成本"
|
||||
|
||||
#. module: delivery
|
||||
#: field:delivery.grid.line,list_price:0
|
||||
|
@ -321,7 +321,7 @@ msgstr "错误:无效EAN编码"
|
|||
#. module: delivery
|
||||
#: view:delivery.grid:0
|
||||
msgid "Delivery grids"
|
||||
msgstr "运费表格"
|
||||
msgstr "交货表格"
|
||||
|
||||
#. module: delivery
|
||||
#: wizard_button:delivery.sale.order,init,end:0
|
||||
|
@ -331,7 +331,7 @@ msgstr "取消"
|
|||
#. module: delivery
|
||||
#: field:sale.order,carrier_id:0
|
||||
msgid "Delivery method"
|
||||
msgstr "送货方式"
|
||||
msgstr "交货方式"
|
||||
|
||||
#. module: delivery
|
||||
#: field:delivery.carrier,price:0
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
],
|
||||
'demo_xml': [ 'document_demo.xml','board_document_demo.xml'],
|
||||
'test': [
|
||||
'test/document_test.yml',
|
||||
'test/document_test2.yml',
|
||||
],
|
||||
'installable': True,
|
||||
'active': False,
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
<menuitem id="menu_reporting" name="Reporting" sequence="2" parent="knowledge.menu_document"/>
|
||||
<menuitem
|
||||
name="Dashboard"
|
||||
id="menu_board_document"
|
||||
id="menu_reports_document"
|
||||
parent="menu_reporting"
|
||||
sequence="0"
|
||||
icon="terp-graph"
|
||||
|
@ -61,10 +61,10 @@
|
|||
|
||||
|
||||
<menuitem
|
||||
parent="menu_board_document"
|
||||
parent="menu_reports_document"
|
||||
action="open_board_document_manager"
|
||||
sequence="1"
|
||||
id="menu_board_document_manager"
|
||||
id="menu_reports_document_manager"
|
||||
icon="terp-graph"/>
|
||||
|
||||
<record model="ir.ui.view" id="board_document_manager_form1">
|
||||
|
@ -107,10 +107,10 @@
|
|||
</record>
|
||||
|
||||
<menuitem
|
||||
parent="menu_board_document"
|
||||
parent="menu_reports_document"
|
||||
action="open_board_document_manager1"
|
||||
sequence="1"
|
||||
id="menu_board_document_manager1"
|
||||
id="menu_reports_document_manager1"
|
||||
icon="terp-graph"/>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -153,7 +153,10 @@ class contentIndex(object):
|
|||
if realfname :
|
||||
fname = realfname
|
||||
else:
|
||||
bname,ext = os.path.splitext(filename)
|
||||
try:
|
||||
bname,ext = os.path.splitext(filename or 'test.tmp')
|
||||
except Exception:
|
||||
bname, ext = filename, 'tmp'
|
||||
fd, fname = tempfile.mkstemp(suffix=ext)
|
||||
os.write(fd, content)
|
||||
os.close(fd)
|
||||
|
|
|
@ -58,7 +58,9 @@ class document_directory_content(osv.osv):
|
|||
'suffix': fields.char('Suffix', size=16),
|
||||
'report_id': fields.many2one('ir.actions.report.xml', 'Report'),
|
||||
'extension': fields.selection(_extension_get, 'Document Type', required=True, size=4),
|
||||
'include_name': fields.boolean('Include Record Name', help="Check this field if you want that the name of the file start by the record name."),
|
||||
'include_name': fields.boolean('Include Record Name',
|
||||
help="Check this field if you want that the name of the file to contain the record name." \
|
||||
"\nIf set, the directory will have to be a resource one."),
|
||||
'directory_id': fields.many2one('document.directory', 'Directory'),
|
||||
}
|
||||
_defaults = {
|
||||
|
@ -88,12 +90,19 @@ class document_directory_content(osv.osv):
|
|||
tname = (content.prefix or '') + (content.suffix or '') + (content.extension or '')
|
||||
if tname.find('/'):
|
||||
tname=tname.replace('/', '_')
|
||||
act_id = False
|
||||
if 'dctx_res_id' in node.dctx:
|
||||
act_id = node.dctx['dctx_res_id']
|
||||
elif hasattr(node, 'res_id'):
|
||||
act_id = node.res_id
|
||||
else:
|
||||
act_id = node.context.context.get('res_id',False)
|
||||
if not nodename:
|
||||
n = nodes.node_content(tname, node, node.context,content)
|
||||
n = nodes.node_content(tname, node, node.context,content, act_id=act_id)
|
||||
res2.append( n)
|
||||
else:
|
||||
if nodename == tname:
|
||||
n = nodes.node_content(tname, node, node.context,content)
|
||||
n = nodes.node_content(tname, node, node.context,content, act_id=act_id)
|
||||
n.fill_fields(cr)
|
||||
res2.append(n)
|
||||
return res2
|
||||
|
@ -108,6 +117,10 @@ class document_directory_content(osv.osv):
|
|||
raise Exception("Invalid content: %s" % node.extension)
|
||||
report = self.pool.get('ir.actions.report.xml').browse(cr, uid, node.report_id)
|
||||
srv = netsvc.Service._services['report.'+report.report_name]
|
||||
pdf,pdftype = srv.create(cr, uid, [node.context.context['res_id']], {}, {})
|
||||
ctx = node.context.context.copy()
|
||||
ctx.update(node.dctx)
|
||||
pdf,pdftype = srv.create(cr, uid, [node.act_id,], {}, context=ctx)
|
||||
return pdf
|
||||
document_directory_content()
|
||||
|
||||
#eof
|
|
@ -28,6 +28,7 @@ import os
|
|||
|
||||
import pooler
|
||||
import netsvc
|
||||
from osv.orm import except_orm
|
||||
#import StringIO
|
||||
|
||||
from psycopg2 import Binary
|
||||
|
@ -46,7 +47,10 @@ class document_file(osv.osv):
|
|||
|
||||
def _data_get(self, cr, uid, ids, name, arg, context):
|
||||
fbrl = self.browse(cr, uid, ids, context=context)
|
||||
nctx = nodes.get_node_context(cr, uid, context)
|
||||
nctx = nodes.get_node_context(cr, uid, context={})
|
||||
# nctx will /not/ inherit the caller's context. Most of
|
||||
# it would be useless, anyway (like active_id, active_model,
|
||||
# bin_size etc.)
|
||||
result = {}
|
||||
bin_size = context.get('bin_size', False)
|
||||
for fbro in fbrl:
|
||||
|
@ -66,39 +70,38 @@ class document_file(osv.osv):
|
|||
if not value:
|
||||
return True
|
||||
fbro = self.browse(cr, uid, id, context=context)
|
||||
nctx = nodes.get_node_context(cr, uid, context)
|
||||
nctx = nodes.get_node_context(cr, uid, context={})
|
||||
fnode = nodes.node_file(None, None, nctx, fbro)
|
||||
res = fnode.set_data(cr, base64.decodestring(value), fbro)
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'user_id': fields.many2one('res.users', 'Owner', select=1),
|
||||
'group_ids': fields.many2many('res.groups', 'document_group_rel', 'item_id', 'group_id', 'Groups'),
|
||||
# the directory id now is mandatory. It can still be computed automatically.
|
||||
'parent_id': fields.many2one('document.directory', 'Directory', select=1),
|
||||
'file_size': fields.integer('File Size', required=True),
|
||||
'file_type': fields.char('Content Type', size=128),
|
||||
# Columns from ir.attachment:
|
||||
'create_date': fields.datetime('Date Created', readonly=True),
|
||||
'create_uid': fields.many2one('res.users', 'Creator', readonly=True),
|
||||
'write_date': fields.datetime('Date Modified', readonly=True),
|
||||
'write_uid': fields.many2one('res.users', 'Last Modification User', readonly=True),
|
||||
'res_model': fields.char('Attached Model', size=64, readonly=True),
|
||||
'res_id': fields.integer('Attached ID', readonly=True),
|
||||
|
||||
# If ir.attachment contained any data before document is installed, preserve
|
||||
# the data, don't drop the column!
|
||||
'db_datas': fields.binary('Data', oldname='datas'),
|
||||
'index_content': fields.text('Indexed Content'),
|
||||
'write_date': fields.datetime('Date Modified', readonly=True),
|
||||
'write_uid': fields.many2one('res.users', 'Last Modification User', readonly=True),
|
||||
'create_date': fields.datetime('Date Created', readonly=True),
|
||||
'create_uid': fields.many2one('res.users', 'Creator', readonly=True),
|
||||
'store_method': fields.selection([('db', 'Database'), ('fs', 'Filesystem'), ('link', 'Link')], "Storing Method"),
|
||||
'datas': fields.function(_data_get, method=True, fnct_inv=_data_set, string='File Content', type="binary", nodrop=True),
|
||||
'url': fields.char('File URL',size=64),
|
||||
'store_fname': fields.char('Stored Filename', size=200),
|
||||
'res_model': fields.char('Attached Model', size=64), #res_model
|
||||
'res_id': fields.integer('Attached ID'), #res_id
|
||||
'partner_id':fields.many2one('res.partner', 'Partner', select=1),
|
||||
'type':fields.selection([
|
||||
('url','URL'),
|
||||
('binary','Binary'),
|
||||
|
||||
],'Type', help="Type is used to separate URL and binary File"),
|
||||
# Fields of document:
|
||||
'user_id': fields.many2one('res.users', 'Owner', select=1),
|
||||
# 'group_ids': fields.many2many('res.groups', 'document_group_rel', 'item_id', 'group_id', 'Groups'),
|
||||
# the directory id now is mandatory. It can still be computed automatically.
|
||||
'parent_id': fields.many2one('document.directory', 'Directory', select=1, required=True),
|
||||
'index_content': fields.text('Indexed Content'),
|
||||
'partner_id':fields.many2one('res.partner', 'Partner', select=1),
|
||||
'company_id': fields.many2one('res.company', 'Company'),
|
||||
'file_size': fields.integer('File Size', required=True),
|
||||
'file_type': fields.char('Content Type', size=128),
|
||||
|
||||
# fields used for file storage
|
||||
'store_fname': fields.char('Stored Filename', size=200),
|
||||
}
|
||||
|
||||
def __get_def_directory(self, cr, uid, context=None):
|
||||
|
@ -109,8 +112,6 @@ class document_file(osv.osv):
|
|||
'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'ir.attachment', context=c),
|
||||
'user_id': lambda self, cr, uid, ctx:uid,
|
||||
'file_size': lambda self, cr, uid, ctx:0,
|
||||
'store_method': lambda *args: 'db',
|
||||
'type': 'binary',
|
||||
'parent_id': __get_def_directory
|
||||
}
|
||||
_sql_constraints = [
|
||||
|
@ -122,7 +123,7 @@ class document_file(osv.osv):
|
|||
res_model = vals.get('res_model', False)
|
||||
res_id = vals.get('res_id', 0)
|
||||
if op == 'write':
|
||||
for file in self.browse(cr, uid, ids):
|
||||
for file in self.browse(cr, uid, ids): # FIXME fields_only
|
||||
if not name:
|
||||
name = file.name
|
||||
if not parent_id:
|
||||
|
@ -156,8 +157,44 @@ class document_file(osv.osv):
|
|||
return False
|
||||
if not self._check_duplication(cr, uid, vals, ids, 'write'):
|
||||
raise osv.except_osv(_('ValidateError'), _('File name must be unique!'))
|
||||
result = super(document_file, self).write(cr, uid, ids, vals, context=context)
|
||||
cr.commit()
|
||||
|
||||
# if nodes call this write(), they must skip the code below
|
||||
from_node = context and context.get('__from_node', False)
|
||||
if (('parent_id' in vals) or ('name' in vals)) and not from_node:
|
||||
# perhaps this file is renaming or changing directory
|
||||
nctx = nodes.get_node_context(cr,uid,context={})
|
||||
dirobj = self.pool.get('document.directory')
|
||||
if 'parent_id' in vals:
|
||||
dbro = dirobj.browse(cr, uid, vals['parent_id'], context=context)
|
||||
dnode = nctx.get_dir_node(cr, dbro)
|
||||
else:
|
||||
dbro = None
|
||||
dnode = None
|
||||
ids2 = []
|
||||
result = False
|
||||
for fbro in self.browse(cr, uid, ids, context=context):
|
||||
if ('parent_id' not in vals or fbro.parent_id.id == vals['parent_id']) \
|
||||
and ('name' not in vals or fbro.name == vals['name']) :
|
||||
ids2.append(fbro.id)
|
||||
continue
|
||||
fnode = nctx.get_file_node(cr, fbro)
|
||||
res = fnode.move_to(cr, dnode or fnode.parent, vals.get('name', fbro.name), fbro, dbro, True)
|
||||
if isinstance(res, dict):
|
||||
vals2 = vals.copy()
|
||||
vals2.update(res)
|
||||
wid = res.get('id', fbro.id)
|
||||
result = super(document_file,self).write(cr,uid,wid,vals2,context=context)
|
||||
# TODO: how to handle/merge several results?
|
||||
elif res == True:
|
||||
ids2.append(fbro.id)
|
||||
elif res == False:
|
||||
pass
|
||||
ids = ids2
|
||||
if 'file_size' in vals: # only write that field using direct SQL calls
|
||||
del vals['file_size']
|
||||
if len(ids) and len(vals):
|
||||
result = super(document_file,self).write(cr, uid, ids, vals, context=context)
|
||||
cr.commit() # ?
|
||||
return result
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
|
@ -170,26 +207,10 @@ class document_file(osv.osv):
|
|||
vals['res_id'] = context.get('default_res_id', False)
|
||||
if not vals.get('res_model', False) and context.get('default_res_model', False):
|
||||
vals['res_model'] = context.get('default_res_model', False)
|
||||
if vals.get('res_id', False) and vals.get('res_model', False):
|
||||
obj_model = self.pool.get(vals['res_model'])
|
||||
result = obj_model.read(cr, uid, [vals['res_id']], ['name', 'partner_id', 'address_id'], context=context)
|
||||
if len(result):
|
||||
obj = result[0]
|
||||
if obj_model._name == 'res.partner':
|
||||
vals['partner_id'] = obj['id']
|
||||
elif obj.get('address_id', False):
|
||||
if isinstance(obj['address_id'], tuple) or isinstance(obj['address_id'], list):
|
||||
address_id = obj['address_id'][0]
|
||||
else:
|
||||
address_id = obj['address_id']
|
||||
address = self.pool.get('res.partner.address').read(cr, uid, [address_id], context=context)
|
||||
if len(address):
|
||||
vals['partner_id'] = address[0]['partner_id'][0] or False
|
||||
elif obj.get('partner_id', False):
|
||||
if isinstance(obj['partner_id'], tuple) or isinstance(obj['partner_id'], list):
|
||||
vals['partner_id'] = obj['partner_id'][0]
|
||||
else:
|
||||
vals['partner_id'] = obj['partner_id']
|
||||
if vals.get('res_id', False) and vals.get('res_model', False) \
|
||||
and not vals.get('partner_id', False):
|
||||
vals['partner_id'] = self.__get_partner_id(cr, uid, \
|
||||
vals['res_model'], vals['res_id'], context)
|
||||
|
||||
datas = None
|
||||
if vals.get('link', False) :
|
||||
|
@ -198,13 +219,33 @@ class document_file(osv.osv):
|
|||
else:
|
||||
datas = vals.get('datas', False)
|
||||
|
||||
vals['file_size'] = datas and len(datas) or 0
|
||||
if datas:
|
||||
vals['file_size'] = len(datas)
|
||||
else:
|
||||
if vals.get('file_size'):
|
||||
del vals['file_size']
|
||||
if not self._check_duplication(cr, uid, vals):
|
||||
raise osv.except_osv(_('ValidateError'), _('File name must be unique!'))
|
||||
result = super(document_file, self).create(cr, uid, vals, context)
|
||||
cr.commit()
|
||||
cr.commit() # ?
|
||||
return result
|
||||
|
||||
def __get_partner_id(self, cr, uid, res_model, res_id, context):
|
||||
""" A helper to retrieve the associated partner from any res_model+id
|
||||
It is a hack that will try to discover if the mentioned record is
|
||||
clearly associated with a partner record.
|
||||
"""
|
||||
obj_model = self.pool.get(res_model)
|
||||
if obj_model._name == 'res.partner':
|
||||
return res_id
|
||||
elif 'partner_id' in obj_model._columns and obj_model._columns['partner_id']._obj == 'res.partner':
|
||||
bro = obj_model.browse(cr, uid, res_id, context=context)
|
||||
return bro.partner_id.id
|
||||
elif 'address_id' in obj_model._columns and obj_model._columns['address_id']._obj == 'res.partner.address':
|
||||
bro = obj_model.browse(cr, uid, res_id, context=context)
|
||||
return bro.address_id.partner_id.id
|
||||
return False
|
||||
|
||||
def unlink(self, cr, uid, ids, context={}):
|
||||
stor = self.pool.get('document.storage')
|
||||
unres = []
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
</record>
|
||||
|
||||
<record model="document.storage" id="storage_default">
|
||||
<field name="name">Default DB storage</field>
|
||||
<field name="name">Database storage</field>
|
||||
<field name="type">db</field>
|
||||
<field name="user_id" ref="base.user_admin"/>
|
||||
</record>
|
||||
|
@ -17,7 +17,7 @@
|
|||
<record model="document.directory" id="dir_root">
|
||||
<field name="name">Documents</field>
|
||||
<field name="user_id" ref="base.user_admin"/>
|
||||
<field name="storage_id" ref="storage_default"/>
|
||||
<field name="storage_id" ref="storage_default"/>
|
||||
<field name="ressource_id">0</field>
|
||||
</record>
|
||||
|
||||
|
@ -25,7 +25,6 @@
|
|||
<field name="name">My Folder</field>
|
||||
<field name="parent_id" ref="dir_root"/>
|
||||
<field name="user_id" ref="base.user_admin"/>
|
||||
<field name="storage_id" ref="storage_default"/>
|
||||
<field name="ressource_id">0</field>
|
||||
|
||||
</record>
|
||||
|
@ -35,7 +34,6 @@
|
|||
<field name="parent_id" ref="dir_root"/>
|
||||
<field name="type">ressource</field>
|
||||
<field name="ressource_tree">1</field>
|
||||
<field name="storage_id" ref="storage_default"/>
|
||||
<field name="ressource_id">0</field>
|
||||
|
||||
<field name="ressource_type_id" search="[('model','=','res.partner.category')]" />
|
||||
|
@ -57,7 +55,6 @@
|
|||
<field name="name">Personal Folders</field>
|
||||
<field name="parent_id" ref="dir_root"/>
|
||||
<field name="type">ressource</field>
|
||||
<field name="storage_id" ref="storage_default"/>
|
||||
<field name="ressource_type_id" ref="base.model_res_users" />
|
||||
<field name="ressource_id">0</field>
|
||||
|
||||
|
|
|
@ -39,20 +39,27 @@ class document_directory(osv.osv):
|
|||
'write_uid': fields.many2one('res.users', 'Last Modification User', readonly=True),
|
||||
'create_date': fields.datetime('Date Created', readonly=True),
|
||||
'create_uid': fields.many2one('res.users', 'Creator', readonly=True),
|
||||
'file_type': fields.char('Content Type', size=32),
|
||||
'domain': fields.char('Domain', size=128, help="Use a domain if you want to apply an automatic filter on visible resources."),
|
||||
'user_id': fields.many2one('res.users', 'Owner'),
|
||||
'storage_id': fields.many2one('document.storage', 'Storage'),
|
||||
'group_ids': fields.many2many('res.groups', 'document_directory_group_rel', 'item_id', 'group_id', 'Groups'),
|
||||
'parent_id': fields.many2one('document.directory', 'Parent Item'),
|
||||
'parent_id': fields.many2one('document.directory', 'Parent Directory', select=1),
|
||||
'child_ids': fields.one2many('document.directory', 'parent_id', 'Children'),
|
||||
'file_ids': fields.one2many('ir.attachment', 'parent_id', 'Files'),
|
||||
'content_ids': fields.one2many('document.directory.content', 'directory_id', 'Virtual Files'),
|
||||
'type': fields.selection([('directory','Static Directory'),('ressource','Other Resources')], 'Type', required=True),
|
||||
'ressource_type_id': fields.many2one('ir.model', 'Directories Mapped to Objects',
|
||||
help="Select an object here and Open ERP will create a mapping for each of these " \
|
||||
"objects, using the given domain, when browsing through FTP."),
|
||||
'type': fields.selection([
|
||||
('directory','Static Directory'),
|
||||
('ressource','Folders per resource'),
|
||||
],
|
||||
'Type', required=True, select=1,
|
||||
help="Defines directory's behaviour."),
|
||||
|
||||
'ressource_type_id': fields.many2one('ir.model', 'Resource model',
|
||||
help="Select an object here and there will be one folder per record of that resource."),
|
||||
'resource_field': fields.many2one('ir.model.fields', 'Name field', help='Field to be used as name on resource directories. If empty, the "name" will be used.'),
|
||||
'resource_find_all': fields.boolean('Find all resources', required=True,
|
||||
help="If true, all attachments that match this resource will " \
|
||||
" be located. If false, only ones that have this as parent." ),
|
||||
'ressource_parent_type_id': fields.many2one('ir.model', 'Parent Model',
|
||||
help="If you put an object here, this directory template will appear bellow all of these objects. " \
|
||||
"Don't put a parent directory if you select a parent model."),
|
||||
|
@ -60,7 +67,7 @@ class document_directory(osv.osv):
|
|||
'ressource_tree': fields.boolean('Tree Structure',
|
||||
help="Check this if you want to use the same tree structure as the object selected in the system."),
|
||||
'dctx_ids': fields.one2many('document.directory.dctx', 'dir_id', 'Context fields'),
|
||||
'company_id': fields.many2one('res.company', 'Company'),
|
||||
'company_id': fields.many2one('res.company', 'Company'),
|
||||
}
|
||||
|
||||
|
||||
|
@ -99,10 +106,12 @@ class document_directory(osv.osv):
|
|||
'type': lambda *args: 'directory',
|
||||
'ressource_id': lambda *a: 0,
|
||||
'storage_id': _get_def_storage,
|
||||
'resource_find_all': True,
|
||||
}
|
||||
_sql_constraints = [
|
||||
('dirname_uniq', 'unique (name,parent_id,ressource_id,ressource_parent_type_id)', 'The directory name must be unique !'),
|
||||
('no_selfparent', 'check(parent_id <> id)', 'Directory cannot be parent of itself!')
|
||||
('no_selfparent', 'check(parent_id <> id)', 'Directory cannot be parent of itself!'),
|
||||
('dir_parented', 'check(parent_id IS NOT NULL OR storage_id IS NOT NULL)', 'Directory must have a parent or a storage')
|
||||
]
|
||||
def name_get(self, cr, uid, ids, context={}):
|
||||
res = []
|
||||
|
@ -190,18 +199,25 @@ class document_directory(osv.osv):
|
|||
"""
|
||||
if not context:
|
||||
context = {}
|
||||
lang = context.get('lang',False)
|
||||
if not lang:
|
||||
user = self.pool.get('res.users').browse(cr, uid, uid)
|
||||
lang = user.context_lang
|
||||
context['lang'] = lang
|
||||
|
||||
try: #just instrumentation
|
||||
return nodes.get_node_context(cr, uid, context).get_uri(cr, uri)
|
||||
except Exception,e:
|
||||
print "exception: ",e
|
||||
raise
|
||||
return nodes.get_node_context(cr, uid, context).get_uri(cr, uri)
|
||||
|
||||
def get_dir_permissions(self, cr, uid, ids ):
|
||||
"""Check what permission user 'uid' has on directory 'id'
|
||||
"""
|
||||
assert len(ids) == 1
|
||||
id = ids[0]
|
||||
|
||||
cr.execute( "SELECT count(dg.item_id) AS needs, count(ug.uid) AS has " \
|
||||
" FROM document_directory_group_rel dg " \
|
||||
" LEFT OUTER JOIN res_groups_users_rel ug " \
|
||||
" ON (dg.group_id = ug.gid AND ug.uid = %s) " \
|
||||
" WHERE dg.item_id = %s ", (uid, id))
|
||||
needs, has = cr.fetchone()
|
||||
if needs and not has:
|
||||
return 1 # still allow to descend into.
|
||||
else:
|
||||
return 15
|
||||
|
||||
def _locate_child(self, cr, uid, root_id, uri,nparent, ncontext):
|
||||
""" try to locate the node in uri,
|
||||
|
@ -274,6 +290,8 @@ class document_directory(osv.osv):
|
|||
raise osv.except_osv(_('ValidateError'), _('Directory name contains special characters!'))
|
||||
return super(document_directory,self).create(cr, uid, vals, context)
|
||||
|
||||
# TODO def unlink(...
|
||||
|
||||
document_directory()
|
||||
|
||||
class document_directory_dctx(osv.osv):
|
||||
|
|
|
@ -24,7 +24,10 @@ from osv import osv, fields
|
|||
import os
|
||||
import tools
|
||||
import base64
|
||||
import errno
|
||||
import logging
|
||||
from StringIO import StringIO
|
||||
import psycopg2
|
||||
|
||||
from tools.misc import ustr
|
||||
from tools.translate import _
|
||||
|
@ -33,7 +36,9 @@ from osv.orm import except_orm
|
|||
|
||||
import random
|
||||
import string
|
||||
import pooler
|
||||
import netsvc
|
||||
import nodes
|
||||
from content_index import cntIndex
|
||||
|
||||
DMS_ROOT_PATH = tools.config.get('document_path', os.path.join(tools.config.get('root_path'), 'filestore'))
|
||||
|
@ -84,6 +89,222 @@ def create_directory(path):
|
|||
os.makedirs(path)
|
||||
return dir_name
|
||||
|
||||
class nodefd_file(nodes.node_descriptor):
|
||||
""" A descriptor to a real file
|
||||
|
||||
Inheriting directly from file doesn't work, since file exports
|
||||
some read-only attributes (like 'name') that we don't like.
|
||||
"""
|
||||
def __init__(self, parent, path, mode):
|
||||
nodes.node_descriptor.__init__(self, parent)
|
||||
self.__file = open(path, mode)
|
||||
if mode.endswith('b'):
|
||||
mode = mode[:-1]
|
||||
self.mode = mode
|
||||
|
||||
for attr in ('closed', 'read', 'write', 'seek', 'tell'):
|
||||
setattr(self,attr, getattr(self.__file, attr))
|
||||
|
||||
def close(self):
|
||||
# TODO: locking in init, close()
|
||||
fname = self.__file.name
|
||||
self.__file.close()
|
||||
|
||||
if self.mode in ('w', 'w+', 'r+'):
|
||||
par = self._get_parent()
|
||||
cr = pooler.get_db(par.context.dbname).cursor()
|
||||
icont = ''
|
||||
mime = ''
|
||||
filename = par.path
|
||||
if isinstance(filename, (tuple, list)):
|
||||
filename = '/'.join(filename)
|
||||
|
||||
try:
|
||||
mime, icont = cntIndex.doIndex(None, filename=filename,
|
||||
content_type=None, realfname=fname)
|
||||
except Exception:
|
||||
logging.getLogger('document.storage').debug('Cannot index file:', exc_info=True)
|
||||
pass
|
||||
|
||||
try:
|
||||
icont_u = ustr(icont)
|
||||
except UnicodeError:
|
||||
icont_u = ''
|
||||
|
||||
try:
|
||||
fsize = os.stat(fname).st_size
|
||||
cr.execute("UPDATE ir_attachment " \
|
||||
" SET index_content = %s, file_type = %s, " \
|
||||
" file_size = %s " \
|
||||
" WHERE id = %s",
|
||||
(icont_u, mime, fsize, par.file_id))
|
||||
par.content_length = fsize
|
||||
par.content_type = mime
|
||||
cr.commit()
|
||||
cr.close()
|
||||
except Exception:
|
||||
logging.getLogger('document.storage').warning('Cannot save file indexed content:', exc_info=True)
|
||||
|
||||
elif self.mode in ('a', 'a+' ):
|
||||
try:
|
||||
par = self._get_parent()
|
||||
cr = pooler.get_db(par.context.dbname).cursor()
|
||||
fsize = os.stat(fname).st_size
|
||||
cr.execute("UPDATE ir_attachment SET file_size = %s " \
|
||||
" WHERE id = %s",
|
||||
(fsize, par.file_id))
|
||||
par.content_length = fsize
|
||||
cr.commit()
|
||||
cr.close()
|
||||
except Exception:
|
||||
logging.getLogger('document.storage').warning('Cannot save file appended content:', exc_info=True)
|
||||
|
||||
|
||||
|
||||
class nodefd_db(StringIO, nodes.node_descriptor):
|
||||
""" A descriptor to db data
|
||||
"""
|
||||
def __init__(self, parent, ira_browse, mode):
|
||||
nodes.node_descriptor.__init__(self, parent)
|
||||
if mode.endswith('b'):
|
||||
mode = mode[:-1]
|
||||
|
||||
if mode in ('r', 'r+'):
|
||||
cr = ira_browse._cr # reuse the cursor of the browse object, just now
|
||||
cr.execute('SELECT db_datas FROM ir_attachment WHERE id = %s',(ira_browse.id,))
|
||||
data = cr.fetchone()[0]
|
||||
StringIO.__init__(self, data)
|
||||
elif mode in ('w', 'w+'):
|
||||
StringIO.__init__(self, None)
|
||||
# at write, we start at 0 (= overwrite), but have the original
|
||||
# data available, in case of a seek()
|
||||
elif mode == 'a':
|
||||
StringIO.__init__(self, None)
|
||||
else:
|
||||
logging.getLogger('document.storage').error("Incorrect mode %s specified", mode)
|
||||
raise IOError(errno.EINVAL, "Invalid file mode")
|
||||
self.mode = mode
|
||||
|
||||
def close(self):
|
||||
# we now open a *separate* cursor, to update the data.
|
||||
# FIXME: this may be improved, for concurrency handling
|
||||
par = self._get_parent()
|
||||
uid = par.context.uid
|
||||
cr = pooler.get_db(par.context.dbname).cursor()
|
||||
try:
|
||||
if self.mode in ('w', 'w+', 'r+'):
|
||||
data = self.getvalue()
|
||||
icont = ''
|
||||
mime = ''
|
||||
filename = par.path
|
||||
if isinstance(filename, (tuple, list)):
|
||||
filename = '/'.join(filename)
|
||||
|
||||
try:
|
||||
mime, icont = cntIndex.doIndex(data, filename=filename,
|
||||
content_type=None, realfname=None)
|
||||
except Exception:
|
||||
logging.getLogger('document.storage').debug('Cannot index file:', exc_info=True)
|
||||
pass
|
||||
|
||||
try:
|
||||
icont_u = ustr(icont)
|
||||
except UnicodeError:
|
||||
icont_u = ''
|
||||
|
||||
out = psycopg2.Binary(data)
|
||||
cr.execute("UPDATE ir_attachment " \
|
||||
"SET db_datas = %s, file_size=%s, " \
|
||||
" index_content= %s, file_type=%s " \
|
||||
" WHERE id = %s",
|
||||
(out, len(data), icont_u, mime, par.file_id))
|
||||
elif self.mode == 'a':
|
||||
data = self.getvalue()
|
||||
out = psycopg2.Binary(data)
|
||||
cr.execute("UPDATE ir_attachment " \
|
||||
"SET db_datas = COALESCE(db_datas,'') || %s, " \
|
||||
" file_size = COALESCE(file_size, 0) + %s " \
|
||||
" WHERE id = %s",
|
||||
(out, len(data), par.file_id))
|
||||
cr.commit()
|
||||
except Exception, e:
|
||||
logging.getLogger('document.storage').exception('Cannot update db file #%d for close:', par.file_id)
|
||||
raise
|
||||
finally:
|
||||
cr.close()
|
||||
StringIO.close(self)
|
||||
|
||||
class nodefd_db64(StringIO, nodes.node_descriptor):
|
||||
""" A descriptor to db data, base64 (the old way)
|
||||
|
||||
It stores the data in base64 encoding at the db. Not optimal, but
|
||||
the transparent compression of Postgres will save the day.
|
||||
"""
|
||||
def __init__(self, parent, ira_browse, mode):
|
||||
nodes.node_descriptor.__init__(self, parent)
|
||||
if mode.endswith('b'):
|
||||
mode = mode[:-1]
|
||||
|
||||
if mode in ('r', 'r+'):
|
||||
StringIO.__init__(self, base64.decodestring(ira_browse.db_datas))
|
||||
elif mode in ('w', 'w+'):
|
||||
StringIO.__init__(self, None)
|
||||
# at write, we start at 0 (= overwrite), but have the original
|
||||
# data available, in case of a seek()
|
||||
elif mode == 'a':
|
||||
StringIO.__init__(self, None)
|
||||
else:
|
||||
logging.getLogger('document.storage').error("Incorrect mode %s specified", mode)
|
||||
raise IOError(errno.EINVAL, "Invalid file mode")
|
||||
self.mode = mode
|
||||
|
||||
def close(self):
|
||||
# we now open a *separate* cursor, to update the data.
|
||||
# FIXME: this may be improved, for concurrency handling
|
||||
par = self._get_parent()
|
||||
uid = par.context.uid
|
||||
cr = pooler.get_db(par.context.dbname).cursor()
|
||||
try:
|
||||
if self.mode in ('w', 'w+', 'r+'):
|
||||
data = self.getvalue()
|
||||
icont = ''
|
||||
mime = ''
|
||||
filename = par.path
|
||||
if isinstance(filename, (tuple, list)):
|
||||
filename = '/'.join(filename)
|
||||
|
||||
try:
|
||||
mime, icont = cntIndex.doIndex(data, filename=filename,
|
||||
content_type=None, realfname=None)
|
||||
except Exception:
|
||||
logging.getLogger('document.storage').debug('Cannot index file:', exc_info=True)
|
||||
pass
|
||||
|
||||
try:
|
||||
icont_u = ustr(icont)
|
||||
except UnicodeError:
|
||||
icont_u = ''
|
||||
|
||||
cr.execute('UPDATE ir_attachment SET db_datas = %s::bytea, file_size=%s, ' \
|
||||
'index_content = %s, file_type = %s ' \
|
||||
'WHERE id = %s',
|
||||
(base64.encodestring(out), len(out), icont_u, mime, par.file_id))
|
||||
elif self.mode == 'a':
|
||||
out = self.getvalue()
|
||||
# Yes, we're obviously using the wrong representation for storing our
|
||||
# data as base64-in-bytea
|
||||
cr.execute("UPDATE ir_attachment " \
|
||||
"SET db_datas = encode( (COALESCE(decode(encode(db_datas,'escape'),'base64'),'') || decode(%s, 'base64')),'base64')::bytea , " \
|
||||
" file_size = COALESCE(file_size, 0) + %s " \
|
||||
" WHERE id = %s",
|
||||
(base64.encodestring(out), len(out), par.file_id))
|
||||
cr.commit()
|
||||
except Exception, e:
|
||||
logging.getLogger('document.storage').exception('Cannot update db file #%d for close:', par.file_id)
|
||||
raise
|
||||
finally:
|
||||
cr.close()
|
||||
StringIO.close(self)
|
||||
|
||||
class document_storage(osv.osv):
|
||||
""" The primary object for data storage.
|
||||
|
@ -110,7 +331,7 @@ class document_storage(osv.osv):
|
|||
'group_ids': fields.many2many('res.groups', 'document_storage_group_rel', 'item_id', 'group_id', 'Groups'),
|
||||
'dir_ids': fields.one2many('document.directory', 'parent_id', 'Directories'),
|
||||
'type': fields.selection([('db', 'Database'), ('filestore', 'Internal File storage'),
|
||||
('realstore', 'External file storage'), ('virtual', 'Virtual storage')], 'Type', required=True),
|
||||
('realstore','External file storage'),], 'Type', required=True),
|
||||
'path': fields.char('Path', size=250, select=1, help="For file storage, the root path of the storage"),
|
||||
'online': fields.boolean('Online', help="If not checked, media is currently offline and its contents not available", required=True),
|
||||
'readonly': fields.boolean('Read Only', help="If set, media is for reading only"),
|
||||
|
@ -133,6 +354,49 @@ class document_storage(osv.osv):
|
|||
('path_uniq', 'UNIQUE(type,path)', "The storage path must be unique!")
|
||||
]
|
||||
|
||||
def __get_random_fname(self, path):
|
||||
flag = None
|
||||
# This can be improved
|
||||
if os.path.isdir(path):
|
||||
for dirs in os.listdir(path):
|
||||
if os.path.isdir(os.path.join(path, dirs)) and len(os.listdir(os.path.join(path, dirs))) < 4000:
|
||||
flag = dirs
|
||||
break
|
||||
flag = flag or create_directory(path)
|
||||
filename = random_name()
|
||||
return os.path.join(flag, filename)
|
||||
|
||||
def __prepare_realpath(self, cr, file_node, ira, store_path, do_create=True):
|
||||
""" Cleanup path for realstore, create dirs if needed
|
||||
|
||||
@param file_node the node
|
||||
@param ira ir.attachment browse of the file_node
|
||||
@param store_path the path of the parent storage object, list
|
||||
@param do_create create the directories, if needed
|
||||
|
||||
@return tuple(path "/var/filestore/real/dir/", npath ['dir','fname.ext'] )
|
||||
"""
|
||||
file_node.fix_ppath(cr, ira)
|
||||
npath = file_node.full_path() or []
|
||||
# npath may contain empty elements, for root directory etc.
|
||||
npath = filter(lambda x: x is not None, npath)
|
||||
|
||||
# if self._debug:
|
||||
# self._doclog.debug('Npath: %s', npath)
|
||||
for n in npath:
|
||||
if n == '..':
|
||||
raise ValueError("Invalid '..' element in path")
|
||||
for ch in ('*', '|', "\\", '/', ':', '"', '<', '>', '?',):
|
||||
if ch in n:
|
||||
raise ValueError("Invalid char %s in path %s" %(ch, n))
|
||||
dpath = [store_path,]
|
||||
dpath += npath[:-1]
|
||||
path = os.path.join(*dpath)
|
||||
if not os.path.isdir(path):
|
||||
self._doclog.debug("Create dirs: %s", path)
|
||||
os.makedirs(path)
|
||||
return path, npath
|
||||
|
||||
def get_data(self, cr, uid, id, file_node, context=None, fil_obj=None):
|
||||
""" retrieve the contents of some file_node having storage_id = id
|
||||
optionally, fil_obj could point to the browse object of the file
|
||||
|
@ -141,15 +405,71 @@ class document_storage(osv.osv):
|
|||
if not context:
|
||||
context = {}
|
||||
boo = self.browse(cr, uid, id, context)
|
||||
if not boo.online:
|
||||
raise IOError(errno.EREMOTE, 'medium offline')
|
||||
|
||||
if fil_obj:
|
||||
ira = fil_obj
|
||||
else:
|
||||
ira = self.pool.get('ir.attachment').browse(cr, uid, file_node.file_id, context=context)
|
||||
return self.__get_data_3(cr, uid, boo, ira, context)
|
||||
|
||||
def __get_data_3(self, cr, uid, boo, ira, context):
|
||||
def get_file(self, cr, uid, id, file_node, mode, context=None):
|
||||
""" Return a file-like object for the contents of some node
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
boo = self.browse(cr, uid, id, context)
|
||||
if not boo.online:
|
||||
raise RuntimeError('media offline')
|
||||
raise IOError(errno.EREMOTE, 'medium offline')
|
||||
|
||||
if boo.readonly and mode not in ('r', 'rb'):
|
||||
raise IOError(errno.EPERM, "Readonly medium")
|
||||
|
||||
ira = self.pool.get('ir.attachment').browse(cr, uid, file_node.file_id, context=context)
|
||||
if boo.type == 'filestore':
|
||||
if not ira.store_fname:
|
||||
# On a migrated db, some files may have the wrong storage type
|
||||
# try to fix their directory.
|
||||
if mode in ('r','r+'):
|
||||
if ira.file_size:
|
||||
self._doclog.warning( "ir.attachment #%d does not have a filename, but is at filestore, fix it!" % ira.id)
|
||||
raise IOError(errno.ENOENT, 'No file can be located')
|
||||
else:
|
||||
store_fname = self.__get_random_fname(boo.path)
|
||||
cr.execute('UPDATE ir_attachment SET store_fname = %s WHERE id = %s',
|
||||
(store_fname, ira.id))
|
||||
fpath = os.path.join(boo.path, store_fname)
|
||||
else:
|
||||
fpath = os.path.join(boo.path, ira.store_fname)
|
||||
return nodefd_file(file_node, path=fpath, mode=mode)
|
||||
|
||||
elif boo.type == 'db':
|
||||
# TODO: we need a better api for large files
|
||||
return nodefd_db(file_node, ira_browse=ira, mode=mode)
|
||||
|
||||
elif boo.type == 'db64':
|
||||
return nodefd_db64(file_node, ira_browse=ira, mode=mode)
|
||||
|
||||
elif boo.type == 'realstore':
|
||||
path, npath = self.__prepare_realpath(cr, file_node, ira, boo.path,
|
||||
do_create = (mode[1] in ('w','a')) )
|
||||
fpath = os.path.join(path, npath[-1])
|
||||
if (not os.path.exists(fpath)) and mode[1] == 'r':
|
||||
raise IOError("File not found: %s" % fpath)
|
||||
elif mode[1] in ('w', 'a') and not ira.store_fname:
|
||||
store_fname = os.path.join(*npath)
|
||||
cr.execute('UPDATE ir_attachment SET store_fname = %s WHERE id = %s',
|
||||
(store_fname, ira.id))
|
||||
return nodefd_file(file_node, path=fpath, mode=mode)
|
||||
|
||||
elif boo.type == 'virtual':
|
||||
raise ValueError('Virtual storage does not support static files')
|
||||
|
||||
else:
|
||||
raise TypeError("No %s storage" % boo.type)
|
||||
|
||||
def __get_data_3(self, cr, uid, boo, ira, context):
|
||||
if boo.type == 'filestore':
|
||||
if not ira.store_fname:
|
||||
# On a migrated db, some files may have the wrong storage type
|
||||
|
@ -159,13 +479,21 @@ class document_storage(osv.osv):
|
|||
return None
|
||||
fpath = os.path.join(boo.path, ira.store_fname)
|
||||
return file(fpath, 'rb').read()
|
||||
elif boo.type == 'db':
|
||||
elif boo.type == 'db64':
|
||||
# TODO: we need a better api for large files
|
||||
if ira.db_datas:
|
||||
out = base64.decodestring(ira.db_datas)
|
||||
else:
|
||||
out = ''
|
||||
return out
|
||||
elif boo.type == 'db':
|
||||
# We do an explicit query, to avoid type transformations.
|
||||
cr.execute('SELECT db_datas FROM ir_attachment WHERE id = %s', (ira.id,))
|
||||
res = cr.fetchone()
|
||||
if res:
|
||||
return res[0]
|
||||
else:
|
||||
return ''
|
||||
elif boo.type == 'realstore':
|
||||
if not ira.store_fname:
|
||||
# On a migrated db, some files may have the wrong storage type
|
||||
|
@ -179,7 +507,11 @@ class document_storage(osv.osv):
|
|||
elif not ira.store_fname:
|
||||
return None
|
||||
else:
|
||||
raise IOError("File not found: %s" % fpath)
|
||||
raise IOError(errno.ENOENT, "File not found: %s" % fpath)
|
||||
|
||||
elif boo.type == 'virtual':
|
||||
raise ValueError('Virtual storage does not support static files')
|
||||
|
||||
else:
|
||||
raise TypeError("No %s storage" % boo.type)
|
||||
|
||||
|
@ -197,30 +529,25 @@ class document_storage(osv.osv):
|
|||
ira = self.pool.get('ir.attachment').browse(cr, uid, file_node.file_id, context=context)
|
||||
|
||||
if not boo.online:
|
||||
raise RuntimeError('media offline')
|
||||
raise IOError(errno.EREMOTE, 'medium offline')
|
||||
|
||||
if boo.readonly:
|
||||
raise IOError(errno.EPERM, "Readonly medium")
|
||||
|
||||
self._doclog.debug( "Store data for ir.attachment #%d" % ira.id)
|
||||
store_fname = None
|
||||
fname = None
|
||||
if boo.type == 'filestore':
|
||||
path = boo.path
|
||||
try:
|
||||
flag = None
|
||||
# This can be improved
|
||||
if os.path.isdir(path):
|
||||
for dirs in os.listdir(path):
|
||||
if os.path.isdir(os.path.join(path, dirs)) and len(os.listdir(os.path.join(path, dirs))) < 4000:
|
||||
flag = dirs
|
||||
break
|
||||
flag = flag or create_directory(path)
|
||||
filename = random_name()
|
||||
fname = os.path.join(path, flag, filename)
|
||||
store_fname = self.__get_random_fname(path)
|
||||
fname = os.path.join(path, store_fname)
|
||||
fp = file(fname, 'wb')
|
||||
fp.write(data)
|
||||
fp.close()
|
||||
self._doclog.debug( "Saved data to %s" % fname)
|
||||
filesize = len(data) # os.stat(fname).st_size
|
||||
store_fname = os.path.join(flag, filename)
|
||||
|
||||
|
||||
# TODO Here, an old file would be left hanging.
|
||||
|
||||
except Exception, e:
|
||||
|
@ -228,27 +555,19 @@ class document_storage(osv.osv):
|
|||
raise except_orm(_('Error!'), str(e))
|
||||
elif boo.type == 'db':
|
||||
filesize = len(data)
|
||||
# will that work for huge data? TODO
|
||||
# will that work for huge data?
|
||||
out = psycopg2.Binary(data)
|
||||
cr.execute('UPDATE ir_attachment SET db_datas = %s WHERE id = %s',
|
||||
(out, file_node.file_id))
|
||||
elif boo.type == 'db64':
|
||||
filesize = len(data)
|
||||
# will that work for huge data?
|
||||
out = base64.encodestring(data)
|
||||
cr.execute('UPDATE ir_attachment SET db_datas = %s WHERE id = %s',
|
||||
(out, file_node.file_id))
|
||||
elif boo.type == 'realstore':
|
||||
try:
|
||||
file_node.fix_ppath(cr, ira)
|
||||
npath = file_node.full_path() or []
|
||||
# npath may contain empty elements, for root directory etc.
|
||||
for i, n in enumerate(npath):
|
||||
if n == None:
|
||||
del npath[i]
|
||||
for n in npath:
|
||||
for ch in ('*', '|', "\\", '/', ':', '"', '<', '>', '?', '..'):
|
||||
if ch in n:
|
||||
raise ValueError("Invalid char %s in path %s" %(ch, n))
|
||||
dpath = [boo.path,]
|
||||
dpath += npath[:-1]
|
||||
path = os.path.join(*dpath)
|
||||
if not os.path.isdir(path):
|
||||
os.makedirs(path)
|
||||
path, npath = self.__prepare_realpath(cr, file_node, ira, boo.path, do_create=True)
|
||||
fname = os.path.join(path, npath[-1])
|
||||
fp = file(fname,'wb')
|
||||
fp.write(data)
|
||||
|
@ -260,6 +579,10 @@ class document_storage(osv.osv):
|
|||
except Exception,e :
|
||||
self._doclog.warning("Couldn't save data:", exc_info=True)
|
||||
raise except_orm(_('Error!'), str(e))
|
||||
|
||||
elif boo.type == 'virtual':
|
||||
raise ValueError('Virtual storage does not support static files')
|
||||
|
||||
else:
|
||||
raise TypeError("No %s storage" % boo.type)
|
||||
|
||||
|
@ -276,16 +599,21 @@ class document_storage(osv.osv):
|
|||
self._doclog.debug('Cannot index file:', exc_info=True)
|
||||
pass
|
||||
|
||||
try:
|
||||
icont_u = ustr(icont)
|
||||
except UnicodeError:
|
||||
icont_u = ''
|
||||
|
||||
# a hack: /assume/ that the calling write operation will not try
|
||||
# to write the fname and size, and update them in the db concurrently.
|
||||
# We cannot use a write() here, because we are already in one.
|
||||
cr.execute('UPDATE ir_attachment SET store_fname = %s, file_size = %s, index_content = %s, file_type = %s WHERE id = %s',
|
||||
(store_fname, filesize, ustr(icont), mime, file_node.file_id))
|
||||
(store_fname, filesize, icont_u, mime, file_node.file_id))
|
||||
file_node.content_length = filesize
|
||||
file_node.content_type = mime
|
||||
return True
|
||||
except Exception, e :
|
||||
self._doclog.warning( "Couldn't save data:", exc_info=True)
|
||||
self._doclog.warning("Couldn't save data:", exc_info=True)
|
||||
# should we really rollback once we have written the actual data?
|
||||
# at the db case (only), that rollback would be safe
|
||||
raise except_orm(_('Error at doc write!'), str(e))
|
||||
|
@ -295,7 +623,10 @@ class document_storage(osv.osv):
|
|||
files that have to be removed, too. """
|
||||
|
||||
if not storage_bo.online:
|
||||
raise RuntimeError('media offline')
|
||||
raise IOError(errno.EREMOTE, 'medium offline')
|
||||
|
||||
if storage_bo.readonly:
|
||||
raise IOError(errno.EPERM, "Readonly medium")
|
||||
|
||||
if storage_bo.type == 'filestore':
|
||||
fname = fil_bo.store_fname
|
||||
|
@ -303,7 +634,7 @@ class document_storage(osv.osv):
|
|||
return None
|
||||
path = storage_bo.path
|
||||
return (storage_bo.id, 'file', os.path.join(path, fname))
|
||||
elif storage_bo.type == 'db':
|
||||
elif storage_bo.type in ('db', 'db64'):
|
||||
return None
|
||||
elif storage_bo.type == 'realstore':
|
||||
fname = fil_bo.store_fname
|
||||
|
@ -312,7 +643,7 @@ class document_storage(osv.osv):
|
|||
path = storage_bo.path
|
||||
return ( storage_bo.id, 'file', os.path.join(path, fname))
|
||||
else:
|
||||
raise TypeError("No %s storage" % boo.type)
|
||||
raise TypeError("No %s storage" % storage_bo.type)
|
||||
|
||||
def do_unlink(self, cr, uid, unres):
|
||||
for id, ktype, fname in unres:
|
||||
|
@ -326,6 +657,102 @@ class document_storage(osv.osv):
|
|||
|
||||
return True
|
||||
|
||||
def simple_rename(self, cr, uid, file_node, new_name, context=None):
|
||||
""" A preparation for a file rename.
|
||||
It will not affect the database, but merely check and perhaps
|
||||
rename the realstore file.
|
||||
|
||||
@return the dict of values that can safely be be stored in the db.
|
||||
"""
|
||||
sbro = self.browse(cr, uid, file_node.storage_id, context=context)
|
||||
assert sbro, "The file #%d didn't provide storage" % file_node.file_id
|
||||
|
||||
if not sbro.online:
|
||||
raise IOError(errno.EREMOTE, 'medium offline')
|
||||
|
||||
if sbro.readonly:
|
||||
raise IOError(errno.EPERM, "Readonly medium")
|
||||
|
||||
if sbro.type in ('filestore', 'db', 'db64'):
|
||||
# nothing to do for a rename, allow to change the db field
|
||||
return { 'name': new_name, 'datas_fname': new_name }
|
||||
elif sbro.type == 'realstore':
|
||||
ira = self.pool.get('ir.attachment').browse(cr, uid, file_node.file_id, context=context)
|
||||
|
||||
path, npath = self.__prepare_realpath(cr, file_node, ira, sbro.path, do_create=False)
|
||||
fname = ira.store_fname
|
||||
|
||||
if not fname:
|
||||
self._doclog.warning("Trying to rename a non-stored file")
|
||||
if fname != os.path.join(*npath):
|
||||
self._doclog.warning("inconsistency in realstore: %s != %s" , fname, repr(npath))
|
||||
|
||||
oldpath = os.path.join(path, npath[-1])
|
||||
newpath = os.path.join(path, new_name)
|
||||
os.rename(oldpath, newpath)
|
||||
store_path = npath[:-1]
|
||||
store_path.append(new_name)
|
||||
store_fname = os.path.join(*store_path)
|
||||
return { 'name': new_name, 'datas_fname': new_name, 'store_fname': store_fname }
|
||||
else:
|
||||
raise TypeError("No %s storage" % boo.type)
|
||||
|
||||
def simple_move(self, cr, uid, file_node, ndir_bro, context=None):
|
||||
""" A preparation for a file move.
|
||||
It will not affect the database, but merely check and perhaps
|
||||
move the realstore file.
|
||||
|
||||
@param ndir_bro a browse object of document.directory, where this
|
||||
file should move to.
|
||||
@return the dict of values that can safely be be stored in the db.
|
||||
"""
|
||||
sbro = self.browse(cr, uid, file_node.storage_id, context=context)
|
||||
assert sbro, "The file #%d didn't provide storage" % file_node.file_id
|
||||
|
||||
if not sbro.online:
|
||||
raise IOError(errno.EREMOTE, 'medium offline')
|
||||
|
||||
if sbro.readonly:
|
||||
raise IOError(errno.EPERM, "Readonly medium")
|
||||
|
||||
par = ndir_bro
|
||||
psto = None
|
||||
while par:
|
||||
if par.storage_id:
|
||||
psto = par.storage_id.id
|
||||
break
|
||||
par = par.parent_id
|
||||
if file_node.storage_id != psto:
|
||||
self._doclog.debug('Cannot move file %r from %r to %r', file_node, file_node.parent, ndir_bro.name)
|
||||
raise NotImplementedError('Cannot move files between storage media')
|
||||
|
||||
if sbro.type in ('filestore', 'db', 'db64'):
|
||||
# nothing to do for a rename, allow to change the db field
|
||||
return { 'parent_id': ndir_bro.id }
|
||||
elif sbro.type == 'realstore':
|
||||
raise NotImplementedError("Cannot move in realstore, yet") # TODO
|
||||
fname = fil_bo.store_fname
|
||||
if not fname:
|
||||
return ValueError("Tried to rename a non-stored file")
|
||||
path = storage_bo.path
|
||||
oldpath = os.path.join(path, fname)
|
||||
|
||||
for ch in ('*', '|', "\\", '/', ':', '"', '<', '>', '?', '..'):
|
||||
if ch in new_name:
|
||||
raise ValueError("Invalid char %s in name %s" %(ch, new_name))
|
||||
|
||||
file_node.fix_ppath(cr, ira)
|
||||
npath = file_node.full_path() or []
|
||||
dpath = [path,]
|
||||
dpath.extend(npath[:-1])
|
||||
dpath.append(new_name)
|
||||
newpath = os.path.join(*dpath)
|
||||
# print "old, new paths:", oldpath, newpath
|
||||
os.rename(oldpath, newpath)
|
||||
return { 'name': new_name, 'datas_fname': new_name, 'store_fname': new_name }
|
||||
else:
|
||||
raise TypeError("No %s storage" % boo.type)
|
||||
|
||||
|
||||
document_storage()
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<field name="online"/>
|
||||
<field name="readonly"/>
|
||||
</group>
|
||||
<group colspan="2" attrs="{'invisible':[('type','=','db')]}">
|
||||
<group colspan="2" attrs="{'invisible':[('type','in',['db', 'db64'])]}">
|
||||
<field name="path"/>
|
||||
</group>
|
||||
</form>
|
||||
|
@ -61,6 +61,7 @@
|
|||
name="Storage Media"
|
||||
action="action_document_storage_form"
|
||||
id="menu_document_storage_media"
|
||||
groups="base.group_extended"
|
||||
parent="menu_document_management_configuration"/>
|
||||
|
||||
<record model="ir.ui.view" id="view_document_directory_form">
|
||||
|
@ -68,27 +69,35 @@
|
|||
<field name="model">document.directory</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Directories">
|
||||
<form string="Directories" col="6">
|
||||
<field name="name" select="1" colspan="4"/>
|
||||
<field name="user_id"/>
|
||||
<field name="parent_id"/>
|
||||
<field name="storage_id" />
|
||||
<field name="storage_id" widget="selection" />
|
||||
<field name="user_id"/>
|
||||
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
|
||||
<notebook colspan="4">
|
||||
<page string="Definition">
|
||||
<separator string="Directory Type" colspan="4"/>
|
||||
<field name="type"/>
|
||||
<field name="ressource_type_id" on_change="onchange_content_id(ressource_type_id)" attrs="{'required': [('type','=','ressource')], 'readonly': [('type','=','static')]}"/>
|
||||
<newline/>
|
||||
<field name="domain" attrs="{'required': [('type','=','ressource')], 'readonly': [('type','=','static')]}"/>
|
||||
<field name="ressource_tree"/>
|
||||
<field name="resource_field" domain="[('model_id','=',ressource_type_id), ('ttype', 'in', ('char', 'selection', 'date', 'datetime'))]"/>
|
||||
<field name="ressource_id" select="2" readonly="1"/>
|
||||
<field name="ressource_parent_type_id"/>
|
||||
<group colspan="4" col="4" attrs="{'invisible': [('type','!=','ressource')]}">
|
||||
<field name="ressource_type_id" on_change="onchange_content_id(ressource_type_id)"
|
||||
attrs="{'required': [('type','=','ressource')] }"/>
|
||||
<field name="resource_find_all" groups="base.group_extended" />
|
||||
<newline/>
|
||||
<field name="resource_field" domain="[('model_id','=',ressource_type_id), ('ttype', 'in', ('char', 'selection', 'date', 'datetime'))]"/>
|
||||
<field name="ressource_tree"/>
|
||||
<newline/>
|
||||
<field name="domain" attrs="{'required': [('type','=','ressource')], 'readonly': [('type','=','static')]}"/>
|
||||
</group>
|
||||
<group colspan="4" col="4">
|
||||
<field name="ressource_parent_type_id"/>
|
||||
<field name="ressource_id" select="2" readonly="1"/>
|
||||
</group>
|
||||
|
||||
</page>
|
||||
<page string="Generated Files">
|
||||
<page string="Generated Files" groups="base.group_extended">
|
||||
<label colspan="4" string="For each entry here, virtual files will appear in this folder." />
|
||||
<field name="content_ids" nolabel="1" colspan="4" attrs="{'readonly': [('ressource_type_id','=',False)]}">
|
||||
<field name="content_ids" nolabel="1" colspan="4" >
|
||||
<form string="Contents">
|
||||
<field name="name"/>
|
||||
<field name="sequence"/>
|
||||
|
@ -108,6 +117,7 @@
|
|||
</field>
|
||||
</page>
|
||||
<page string="Dynamic context" groups="base.group_extended">
|
||||
<label colspan="4" string="Define words in the context, for all child directories and files" />
|
||||
<field name="dctx_ids" nolabel="1" colspan="4">
|
||||
<tree string="Fields" editable="bottom">
|
||||
<field name="field"/>
|
||||
|
@ -120,6 +130,8 @@
|
|||
</field>
|
||||
</page>
|
||||
<page string="Security">
|
||||
<label colspan="4" string="Only members of these groups will have access to this directory and its files." />
|
||||
<label colspan="4" string="These groups, however, do NOT apply to children directories, which must define their own groups." />
|
||||
<field name="group_ids" colspan="4" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
|
@ -213,44 +225,46 @@
|
|||
<field name="arch" type="xml">
|
||||
<form string="Documents">
|
||||
<group colspan="4" col="6">
|
||||
<field name="name" select="1" />
|
||||
<field name="type"/>
|
||||
<field name="name" select="1" colspan="4" />
|
||||
<field name="parent_id"/>
|
||||
<newline/>
|
||||
<field name="user_id"/>
|
||||
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Attachment">
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Data" colspan="2"/>
|
||||
<field name="type"/>
|
||||
<newline />
|
||||
<group col="2" colspan="2" attrs="{'invisible':[('type','=','url')]}">
|
||||
<field name="datas" filename="datas_fname"/>
|
||||
<field name="datas_fname" select="1"/>
|
||||
<field name="datas" filename="datas_fname"/>
|
||||
<field name="datas_fname" select="1"/>
|
||||
</group>
|
||||
<group col="2" colspan="2" attrs="{'invisible':[('type','=','binary')]}">
|
||||
<field name="url" widget="url"/>
|
||||
<field name="url" widget="url"/>
|
||||
</group>
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Relation" colspan="2"/>
|
||||
<field name="res_name" readonly="1"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="user_id"/>
|
||||
</group>
|
||||
<group col="4" colspan="4">
|
||||
<separator string="History" colspan="4"/>
|
||||
<group col="4" colspan="4">
|
||||
<field name="create_uid"/>
|
||||
<field name="create_date"/>
|
||||
</group>
|
||||
<group col="4" colspan="4">
|
||||
<field name="write_uid"/>
|
||||
<field name="write_date"/>
|
||||
<field name="res_id" invisible="True"/>
|
||||
<group col="2" colspan="2" attrs="{'invisible': [('res_id','=',0)]}">
|
||||
<separator string="Attached To" colspan="2"/>
|
||||
<field name="res_model" readonly="True" invisible="True"/>
|
||||
<field name="res_name" readonly="1"/>
|
||||
</group>
|
||||
<separator string="Related to" colspan="2"/>
|
||||
<field name="partner_id"/>
|
||||
</group>
|
||||
<group col="2" colspan="2" groups="base.group_extended">
|
||||
<separator string="Created" colspan="2"/>
|
||||
<field name="create_uid" readonly="1"/>
|
||||
<field name="create_date" readonly="1"/>
|
||||
</group>
|
||||
<group col="2" colspan="2" groups="base.group_extended">
|
||||
<separator string="Modified" colspan="2"/>
|
||||
<field name="write_uid" readonly="1"/>
|
||||
<field name="write_date" readonly="1"/>
|
||||
</group>
|
||||
|
||||
</page>
|
||||
<page string="Security">
|
||||
<field name="group_ids" colspan="4" nolabel="1"/>
|
||||
</page>
|
||||
<page string="Indexed Content" groups="base.group_extended">
|
||||
<field name="index_content" colspan="4" nolabel="1"/>
|
||||
|
@ -269,11 +283,13 @@
|
|||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="IR Attachment">
|
||||
<filter icon="terp-go-month" string="Recent"
|
||||
help="less 1 month modified/created attachments"
|
||||
<filter icon="terp-go-month" string="Recent Month"
|
||||
help="Attachment modified/created last 30 days"
|
||||
domain="[('create_date','<=', time.strftime('%%Y-%%m-%%d')),('create_date','>',(datetime.date.today()-datetime.timedelta(days=30)).strftime('%%Y-%%m-%%d'))]"
|
||||
/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="name"/>
|
||||
<field name="parent_id" />
|
||||
<field name="user_id">
|
||||
<filter icon="terp-personal"
|
||||
domain="[('user_id','=', False)]"
|
||||
|
@ -284,9 +300,9 @@
|
|||
<newline/>
|
||||
<group expand="0" string="Group By...">
|
||||
<filter string="Partner" icon="terp-personal" domain="[]"
|
||||
context="{'group_by':'partner_id'}" />
|
||||
context="{'group_by':'partner_id'}" groups="base.group_extended"/>
|
||||
<filter string="Directory" icon="terp-folder-green" domain="[]" context="{'group_by':'parent_id'}"/>
|
||||
<filter string="Type" domain="[]" context="{'group_by':'type'}"/>
|
||||
<filter string="Type" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'type'}" groups="base.group_extended"/>
|
||||
<filter string="Owner" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
|
||||
<filter string="Company" icon="terp-personal" domain="[]" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
|
||||
</group>
|
||||
|
@ -301,11 +317,12 @@
|
|||
<field name="arch" type="xml">
|
||||
<tree colors="blue:type in ('url',)">
|
||||
<field name="name"/>
|
||||
<field name="type"/>
|
||||
<field name="datas_fname"/>
|
||||
<field name="parent_id" />
|
||||
<field name="user_id"/>
|
||||
<field name="create_date"/>
|
||||
<field name="write_date"/>
|
||||
<field name="partner_id" groups="base.group_extended" />
|
||||
<field name="type" groups="base.group_extended"/>
|
||||
</tree>
|
||||
|
||||
</field>
|
||||
|
|
|
@ -1,76 +1,77 @@
|
|||
# Translation of OpenERP Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * document
|
||||
# * document
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 5.0.0\n"
|
||||
"Project-Id-Version: OpenERP Server 5.0.10\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
|
||||
"PO-Revision-Date: 2009-09-08 13:52+0000\n"
|
||||
"Last-Translator: Donatas Stonys TeraxIT <donatelonow@hotmail.com>\n"
|
||||
"PO-Revision-Date: 2010-07-20 22:11+0000\n"
|
||||
"Last-Translator: Paulius Sladkevičius <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: 2010-06-22 04:18+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-07-21 03:43+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,create_date:0
|
||||
msgid "Date Created"
|
||||
msgstr ""
|
||||
msgstr "Sukūrimo data"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,ressource_id:0
|
||||
msgid "Resource ID"
|
||||
msgstr ""
|
||||
msgstr "Šaltinio ID"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory.content,include_name:0
|
||||
msgid "Include Record Name"
|
||||
msgstr ""
|
||||
msgstr "Įtraukti įrašo pavadinimą"
|
||||
|
||||
#. module: document
|
||||
#: constraint:ir.model:0
|
||||
msgid ""
|
||||
"The Object name must start with x_ and not contain any special character !"
|
||||
msgstr ""
|
||||
"Objekto pavadinimas turi prasidėti x_ ir neturėti jokių specialių simbolių!"
|
||||
|
||||
#. module: document
|
||||
#: field:ir.actions.report.xml,model_id:0
|
||||
msgid "Model Id"
|
||||
msgstr ""
|
||||
msgstr "Modelio ID"
|
||||
|
||||
#. module: document
|
||||
#: constraint:document.directory:0
|
||||
msgid "Error! You can not create recursive Directories."
|
||||
msgstr ""
|
||||
msgstr "Klaida ! Jūs negalite sukurti pasikartojančių katalogų."
|
||||
|
||||
#. module: document
|
||||
#: model:ir.ui.menu,name:document.menu_document_configuration
|
||||
msgid "Document Configuration"
|
||||
msgstr ""
|
||||
msgstr "Dokumentų konfigūracija"
|
||||
|
||||
#. module: document
|
||||
#: view:ir.attachment:0
|
||||
msgid "Preview"
|
||||
msgstr ""
|
||||
msgstr "Peržiūrėti"
|
||||
|
||||
#. module: document
|
||||
#: field:ir.attachment,store_method:0
|
||||
msgid "Storing Method"
|
||||
msgstr ""
|
||||
msgstr "Laikymo metodas"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.actions.act_window,name:document.action_config_auto_directory
|
||||
msgid "Auto Configure Directory"
|
||||
msgstr ""
|
||||
msgstr "Automatinis katalogų konfigūravimas"
|
||||
|
||||
#. module: document
|
||||
#: field:ir.attachment,file_size:0
|
||||
msgid "File Size"
|
||||
msgstr ""
|
||||
msgstr "Failo dydis"
|
||||
|
||||
#. module: document
|
||||
#: help:document.directory.content,include_name:0
|
||||
|
@ -78,47 +79,50 @@ msgid ""
|
|||
"Check this field if you want that the name of the file start by the record "
|
||||
"name."
|
||||
msgstr ""
|
||||
"Pažymėkite šį lauką, jeigu norite kad failo pavadinimas prasidėtų taip pat "
|
||||
"kaip įrašo pavadinimas."
|
||||
|
||||
#. module: document
|
||||
#: selection:document.directory,type:0
|
||||
msgid "Other Resources"
|
||||
msgstr ""
|
||||
msgstr "Kiti ištekliai"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,ressource_parent_type_id:0
|
||||
msgid "Parent Model"
|
||||
msgstr ""
|
||||
msgstr "Tėvinis modelis"
|
||||
|
||||
#. module: document
|
||||
#: view:document.configuration.wizard:0
|
||||
msgid "Document Management System."
|
||||
msgstr ""
|
||||
msgstr "Dokumentų valdymo sistema"
|
||||
|
||||
#. module: document
|
||||
#: view:ir.attachment:0
|
||||
msgid "Attachment"
|
||||
msgstr ""
|
||||
msgstr "Priedas"
|
||||
|
||||
#. module: document
|
||||
#: constraint:ir.actions.act_window:0
|
||||
msgid "Invalid model name in the action definition."
|
||||
msgstr ""
|
||||
msgstr "Netinkamas modelio pavadinimas veiksmo apibrėžime."
|
||||
|
||||
#. module: document
|
||||
#: selection:document.directory,type:0
|
||||
msgid "Static Directory"
|
||||
msgstr ""
|
||||
msgstr "Statinis katalogas"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.model,name:document.model_document_directory_content_type
|
||||
msgid "Directory Content Type"
|
||||
msgstr ""
|
||||
msgstr "Katalogo turinio tipas"
|
||||
|
||||
#. module: document
|
||||
#: help:document.directory,domain:0
|
||||
msgid ""
|
||||
"Use a domain if you want to apply an automatic filter on visible resources."
|
||||
msgstr ""
|
||||
"Naudoti sritį, jei norite taikyti automatinį filtrą matomiems ištekliams."
|
||||
|
||||
#. module: document
|
||||
#: help:document.directory,ressource_tree:0
|
||||
|
@ -126,69 +130,73 @@ msgid ""
|
|||
"Check this if you want to use the same tree structure as the object selected "
|
||||
"in the system."
|
||||
msgstr ""
|
||||
"Pažymėkite, jeigu norite naudoti tokią pačią medžio struktūrą kaip "
|
||||
"pasirinkto objekto."
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,type:0
|
||||
msgid "Type"
|
||||
msgstr ""
|
||||
msgstr "Tipas"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.actions.act_window,name:document.action_document_directory_tree
|
||||
#: model:ir.ui.menu,name:document.menu_document_directories_tree
|
||||
msgid "Directorie's Structure"
|
||||
msgstr ""
|
||||
msgstr "Katalogų struktūra"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,parent_id:0
|
||||
msgid "Parent Item"
|
||||
msgstr ""
|
||||
msgstr "Tėvinis katalogas"
|
||||
|
||||
#. module: document
|
||||
#: view:ir.attachment:0
|
||||
msgid "File Information"
|
||||
msgstr ""
|
||||
msgstr "Failo informacija"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,file_ids:0 view:ir.attachment:0
|
||||
#: field:document.directory,file_ids:0
|
||||
#: view:ir.attachment:0
|
||||
msgid "Files"
|
||||
msgstr ""
|
||||
msgstr "Failai"
|
||||
|
||||
#. module: document
|
||||
#: field:ir.attachment,store_fname:0
|
||||
msgid "Stored Filename"
|
||||
msgstr ""
|
||||
msgstr "Išsaugotas failo vardas"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,write_uid:0 field:ir.attachment,write_uid:0
|
||||
#: field:document.directory,write_uid:0
|
||||
#: field:ir.attachment,write_uid:0
|
||||
msgid "Last Modification User"
|
||||
msgstr ""
|
||||
msgstr "Paskutinis pakeitęs naudotojas"
|
||||
|
||||
#. module: document
|
||||
#: view:document.configuration.wizard:0
|
||||
msgid "Configure"
|
||||
msgstr ""
|
||||
msgstr "Konfigūruoti"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,ressource_tree:0
|
||||
msgid "Tree Structure"
|
||||
msgstr ""
|
||||
msgstr "Medžio struktūra"
|
||||
|
||||
#. module: document
|
||||
#: field:ir.attachment,title:0
|
||||
msgid "Resource Title"
|
||||
msgstr ""
|
||||
msgstr "Resurso antraštė"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.actions.todo,note:document.config_auto_directory
|
||||
msgid ""
|
||||
"This wizard will configure the URL of the server of the document management "
|
||||
"system."
|
||||
msgstr ""
|
||||
msgstr "Šis vedlys konfigūruoja dokumentų valdymo sistemos serverio URL"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.model,name:document.model_document_directory_content
|
||||
msgid "Directory Content"
|
||||
msgstr ""
|
||||
msgstr "Katalogo turinys"
|
||||
|
||||
#. module: document
|
||||
#: help:document.directory,ressource_parent_type_id:0
|
||||
|
@ -196,31 +204,34 @@ msgid ""
|
|||
"If you put an object here, this directory template will appear bellow all of "
|
||||
"these objects. Don't put a parent directory if you select a parent model."
|
||||
msgstr ""
|
||||
"Jeigu jūs įtraukėte objektą čia, visi šio objekto katalogų šablonai atsiras "
|
||||
"apačioje. Nenaudokite tėvinio katalogo, jei pasirinksite tėvinį modelį."
|
||||
|
||||
#. module: document
|
||||
#: model:ir.ui.menu,name:document.menu_document
|
||||
msgid "Document Management"
|
||||
msgstr ""
|
||||
msgstr "Dokumentų valdymas"
|
||||
|
||||
#. module: document
|
||||
#: selection:ir.attachment,store_method:0
|
||||
msgid "Link"
|
||||
msgstr ""
|
||||
msgstr "Nuoroda"
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
msgid "Directory Type"
|
||||
msgstr ""
|
||||
msgstr "Katalogo tipas"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,group_ids:0 field:ir.attachment,group_ids:0
|
||||
#: field:document.directory,group_ids:0
|
||||
#: field:ir.attachment,group_ids:0
|
||||
msgid "Groups"
|
||||
msgstr ""
|
||||
msgstr "Grupės"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory.content,report_id:0
|
||||
msgid "Report"
|
||||
msgstr ""
|
||||
msgstr "Ataskaita"
|
||||
|
||||
#. module: document
|
||||
#: help:document.configuration.wizard,host:0
|
||||
|
@ -228,6 +239,8 @@ msgid ""
|
|||
"Put here the server address or IP. Keep localhost if you don't know what to "
|
||||
"write."
|
||||
msgstr ""
|
||||
"Įrašykite keletą adresų ar IP. Palikite localhost, jeigu nežinote, ką "
|
||||
"įrašyti."
|
||||
|
||||
#. module: document
|
||||
#: view:document.configuration.wizard:0
|
||||
|
@ -235,31 +248,34 @@ msgid ""
|
|||
"This wizard will automatically configure the document management system "
|
||||
"according to modules installed on your system."
|
||||
msgstr ""
|
||||
"Šis vedlys automatiškai konfigūruoja dokumentų valdymo sistemą pagal "
|
||||
"modulius įdiegtus joje."
|
||||
|
||||
#. module: document
|
||||
#: view:ir.attachment:0
|
||||
msgid "Data"
|
||||
msgstr ""
|
||||
msgstr "Duomenys"
|
||||
|
||||
#. module: document
|
||||
#: view:ir.attachment:0
|
||||
msgid "Notes"
|
||||
msgstr ""
|
||||
msgstr "Pastabos"
|
||||
|
||||
#. module: document
|
||||
#: view:ir.attachment:0 field:ir.attachment,index_content:0
|
||||
#: view:ir.attachment:0
|
||||
#: field:ir.attachment,index_content:0
|
||||
msgid "Indexed Content"
|
||||
msgstr ""
|
||||
msgstr "Indekso turinys"
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
msgid "Definition"
|
||||
msgstr ""
|
||||
msgstr "Aprašymas"
|
||||
|
||||
#. module: document
|
||||
#: constraint:ir.ui.view:0
|
||||
msgid "Invalid XML for View Architecture!"
|
||||
msgstr ""
|
||||
msgstr "Netinkamas XML peržiūros architektūrai!"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.module.module,description:document.module_meta_information
|
||||
|
@ -273,91 +289,93 @@ msgstr ""
|
|||
#. module: document
|
||||
#: field:document.directory,name:0
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
msgstr "Pavadinimas"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory.content.type,code:0
|
||||
msgid "Extension"
|
||||
msgstr ""
|
||||
msgstr "Plėtinys"
|
||||
|
||||
#. module: document
|
||||
#: selection:ir.attachment,store_method:0
|
||||
msgid "Database"
|
||||
msgstr ""
|
||||
msgstr "Duomenų bazė"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,content_ids:0
|
||||
msgid "Virtual Files"
|
||||
msgstr ""
|
||||
msgstr "Virtualūs failai"
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
#: model:ir.ui.menu,name:document.menu_document_directories
|
||||
msgid "Directories"
|
||||
msgstr ""
|
||||
msgstr "Katalogai"
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
msgid "Seq."
|
||||
msgstr ""
|
||||
msgstr "Seka"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.module.module,shortdesc:document.module_meta_information
|
||||
msgid "Integrated Document Management System"
|
||||
msgstr ""
|
||||
msgstr "Integruota dokumentų valdymo sistema"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory.content,directory_id:0
|
||||
#: field:ir.attachment,parent_id:0
|
||||
msgid "Directory"
|
||||
msgstr ""
|
||||
msgstr "Katalogas"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,user_id:0 field:ir.attachment,user_id:0
|
||||
#: field:document.directory,user_id:0
|
||||
#: field:ir.attachment,user_id:0
|
||||
msgid "Owner"
|
||||
msgstr ""
|
||||
msgstr "Savininkas"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.model,name:document.model_document_configuration_wizard
|
||||
msgid "document.configuration.wizard"
|
||||
msgstr ""
|
||||
msgstr "Dokumentų konfigūracija"
|
||||
|
||||
#. module: document
|
||||
#: view:ir.attachment:0
|
||||
msgid "Attached To"
|
||||
msgstr ""
|
||||
msgstr "Prisegtas"
|
||||
|
||||
#. module: document
|
||||
#: selection:ir.attachment,store_method:0
|
||||
msgid "Filesystem"
|
||||
msgstr ""
|
||||
msgstr "Failų sistema"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,file_type:0
|
||||
#: field:document.directory.content.type,name:0
|
||||
#: field:ir.attachment,file_type:0
|
||||
msgid "Content Type"
|
||||
msgstr ""
|
||||
msgstr "Turinio tipas"
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0 view:ir.attachment:0
|
||||
#: view:document.directory:0
|
||||
#: view:ir.attachment:0
|
||||
msgid "Security"
|
||||
msgstr ""
|
||||
msgstr "Saugumas"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.ui.menu,name:document.menu_document_browse
|
||||
msgid "Browse Files Using FTP"
|
||||
msgstr ""
|
||||
msgstr "Ieškoti failų naudojant FTP"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,ressource_type_id:0
|
||||
msgid "Directories Mapped to Objects"
|
||||
msgstr ""
|
||||
msgstr "Katalogai priskirti objektams"
|
||||
|
||||
#. module: document
|
||||
#: view:ir.attachment:0
|
||||
msgid "History"
|
||||
msgstr ""
|
||||
msgstr "Istorija"
|
||||
|
||||
#. module: document
|
||||
#: help:document.directory,ressource_type_id:0
|
||||
|
@ -365,102 +383,105 @@ msgid ""
|
|||
"Select an object here and Open ERP will create a mapping for each of these "
|
||||
"objects, using the given domain, when browsing through FTP."
|
||||
msgstr ""
|
||||
"Jei naršote per FTP, čia pasirinkite objektą, Open ERP sukurs aplanką "
|
||||
"kiekvienam iš jų, naudojant pasirinktą sritį."
|
||||
|
||||
#. module: document
|
||||
#: view:ir.attachment:0
|
||||
msgid "Others Info"
|
||||
msgstr ""
|
||||
msgstr "Kita informacija"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,domain:0
|
||||
msgid "Domain"
|
||||
msgstr ""
|
||||
msgstr "Sritis"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,write_date:0 field:ir.attachment,write_date:0
|
||||
#: field:document.directory,write_date:0
|
||||
#: field:ir.attachment,write_date:0
|
||||
msgid "Date Modified"
|
||||
msgstr ""
|
||||
msgstr "Modifikavimo data"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory.content,suffix:0
|
||||
msgid "Suffix"
|
||||
msgstr ""
|
||||
msgstr "Sufiksas"
|
||||
|
||||
#. module: document
|
||||
#: field:document.configuration.wizard,host:0
|
||||
msgid "Server Address"
|
||||
msgstr ""
|
||||
msgstr "Serverio adresas"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.actions.url,name:document.action_document_browse
|
||||
msgid "Browse Files"
|
||||
msgstr ""
|
||||
msgstr "Ieškoti failų"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory.content,name:0
|
||||
msgid "Content Name"
|
||||
msgstr ""
|
||||
msgstr "Turinio pavadinimas"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.model,name:document.model_document_directory
|
||||
#: field:process.node,directory_id:0
|
||||
msgid "Document directory"
|
||||
msgstr ""
|
||||
msgstr "Dokumentų katalogas"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,create_uid:0
|
||||
msgid "Creator"
|
||||
msgstr ""
|
||||
msgstr "Kūrėjas"
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
msgid "Auto-Generated Files"
|
||||
msgstr ""
|
||||
msgstr "Automatiškai sugeneruoti failai"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory.content,sequence:0
|
||||
msgid "Sequence"
|
||||
msgstr ""
|
||||
msgstr "Seka"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.ui.menu,name:document.menu_document_files
|
||||
msgid "Search a File"
|
||||
msgstr ""
|
||||
msgstr "Ieškoti failo"
|
||||
|
||||
#. module: document
|
||||
#: view:document.configuration.wizard:0
|
||||
msgid "Auto Configure"
|
||||
msgstr ""
|
||||
msgstr "Automatinis konfigūravimas"
|
||||
|
||||
#. module: document
|
||||
#: view:document.configuration.wizard:0
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
msgstr "Atšaukti"
|
||||
|
||||
#. module: document
|
||||
#: field:ir.attachment,partner_id:0
|
||||
msgid "Partner"
|
||||
msgstr ""
|
||||
msgstr "Partneris"
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
msgid "PDF Report"
|
||||
msgstr ""
|
||||
msgstr "PDF ataskaita"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory.content,extension:0
|
||||
msgid "Document Type"
|
||||
msgstr ""
|
||||
msgstr "Dokumento tipas"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,child_ids:0
|
||||
msgid "Children"
|
||||
msgstr ""
|
||||
msgstr "Vaikai"
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0
|
||||
msgid "Contents"
|
||||
msgstr ""
|
||||
msgstr "Turinys"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.actions.act_window,name:document.action_view_files_by_partner
|
||||
|
@ -623,3 +644,11 @@ msgstr ""
|
|||
#: field:report.document.wall,last:0
|
||||
msgid "Last Posted Time"
|
||||
msgstr ""
|
||||
|
||||
#, python-format
|
||||
#~ msgid "Directory name must be unique!"
|
||||
#~ msgstr "Katalogo pavadinimas turi būti unikalus!"
|
||||
|
||||
#, python-format
|
||||
#~ msgid "Directory name contains special characters!"
|
||||
#~ msgstr "Katalogo pavadinime yra specialiųjų simbolių!"
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
# Translation of OpenERP Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * document
|
||||
# * document
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 5.0.6\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
|
||||
"PO-Revision-Date: 2010-03-20 08:19+0000\n"
|
||||
"PO-Revision-Date: 2010-07-20 07:27+0000\n"
|
||||
"Last-Translator: Black Jack <onetimespeed@hotmail.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: 2010-06-22 04:18+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-07-21 03:43+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,create_date:0
|
||||
msgid "Date Created"
|
||||
msgstr "建立日期"
|
||||
msgstr "创建日期"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,ressource_id:0
|
||||
|
@ -77,7 +77,7 @@ msgstr "文件大小"
|
|||
msgid ""
|
||||
"Check this field if you want that the name of the file start by the record "
|
||||
"name."
|
||||
msgstr "如果你想文件名开始是记录名称请选择它."
|
||||
msgstr "如果你想文件名是这记录的名称请选择它."
|
||||
|
||||
#. module: document
|
||||
#: selection:document.directory,type:0
|
||||
|
@ -87,7 +87,7 @@ msgstr "其它资源"
|
|||
#. module: document
|
||||
#: field:document.directory,ressource_parent_type_id:0
|
||||
msgid "Parent Model"
|
||||
msgstr "上级式样"
|
||||
msgstr "上级模型"
|
||||
|
||||
#. module: document
|
||||
#: view:document.configuration.wizard:0
|
||||
|
@ -102,7 +102,7 @@ msgstr "附件"
|
|||
#. module: document
|
||||
#: constraint:ir.actions.act_window:0
|
||||
msgid "Invalid model name in the action definition."
|
||||
msgstr "在这动作定义中有无效的模块名"
|
||||
msgstr "在动作定义中使用了无效的模快名。"
|
||||
|
||||
#. module: document
|
||||
#: selection:document.directory,type:0
|
||||
|
@ -112,20 +112,20 @@ msgstr "静态目录"
|
|||
#. module: document
|
||||
#: model:ir.model,name:document.model_document_directory_content_type
|
||||
msgid "Directory Content Type"
|
||||
msgstr "目录内容分类"
|
||||
msgstr "目录内容类型"
|
||||
|
||||
#. module: document
|
||||
#: help:document.directory,domain:0
|
||||
msgid ""
|
||||
"Use a domain if you want to apply an automatic filter on visible resources."
|
||||
msgstr "如果你想使用可见资源的自动过滤这是使用的范围"
|
||||
msgstr "如果你想对可得到的资源自动过滤, 规定一个范围"
|
||||
|
||||
#. module: document
|
||||
#: help:document.directory,ressource_tree:0
|
||||
msgid ""
|
||||
"Check this if you want to use the same tree structure as the object selected "
|
||||
"in the system."
|
||||
msgstr "如果你想在系统中使用相同的对象树状结构请选择这"
|
||||
msgstr "如果你想使用树结构象系统选定对象, 请选择这"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,type:0
|
||||
|
@ -149,7 +149,8 @@ msgid "File Information"
|
|||
msgstr "文件信息"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,file_ids:0 view:ir.attachment:0
|
||||
#: field:document.directory,file_ids:0
|
||||
#: view:ir.attachment:0
|
||||
msgid "Files"
|
||||
msgstr "文件"
|
||||
|
||||
|
@ -159,7 +160,8 @@ msgid "Stored Filename"
|
|||
msgstr "保存文件名"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,write_uid:0 field:ir.attachment,write_uid:0
|
||||
#: field:document.directory,write_uid:0
|
||||
#: field:ir.attachment,write_uid:0
|
||||
msgid "Last Modification User"
|
||||
msgstr "最近修改用户"
|
||||
|
||||
|
@ -176,14 +178,14 @@ msgstr "树结构"
|
|||
#. module: document
|
||||
#: field:ir.attachment,title:0
|
||||
msgid "Resource Title"
|
||||
msgstr "标题"
|
||||
msgstr "资源标题"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.actions.todo,note:document.config_auto_directory
|
||||
msgid ""
|
||||
"This wizard will configure the URL of the server of the document management "
|
||||
"system."
|
||||
msgstr "这向导将配置文档管理系统的URL"
|
||||
msgstr "这向导将配置服务器文档管理系统的URL"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.model,name:document.model_document_directory_content
|
||||
|
@ -195,9 +197,7 @@ msgstr "目录内容"
|
|||
msgid ""
|
||||
"If you put an object here, this directory template will appear bellow all of "
|
||||
"these objects. Don't put a parent directory if you select a parent model."
|
||||
msgstr ""
|
||||
"如果你在这填上对象,这目录的模板将涵盖所有的对象.如果您选择母公司模式不要填入"
|
||||
"父目录"
|
||||
msgstr "如果你在这填上对象, 这目录的模板将出现在所有的对象. 如果您选择上级模式不要填入上级目录"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.ui.menu,name:document.menu_document
|
||||
|
@ -215,7 +215,8 @@ msgid "Directory Type"
|
|||
msgstr "目录类型"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,group_ids:0 field:ir.attachment,group_ids:0
|
||||
#: field:document.directory,group_ids:0
|
||||
#: field:ir.attachment,group_ids:0
|
||||
msgid "Groups"
|
||||
msgstr "组"
|
||||
|
||||
|
@ -249,7 +250,8 @@ msgid "Notes"
|
|||
msgstr "备注"
|
||||
|
||||
#. module: document
|
||||
#: view:ir.attachment:0 field:ir.attachment,index_content:0
|
||||
#: view:ir.attachment:0
|
||||
#: field:ir.attachment,index_content:0
|
||||
msgid "Indexed Content"
|
||||
msgstr "内容索引"
|
||||
|
||||
|
@ -261,7 +263,7 @@ msgstr "定义"
|
|||
#. module: document
|
||||
#: constraint:ir.ui.view:0
|
||||
msgid "Invalid XML for View Architecture!"
|
||||
msgstr "无效XML视图结构!"
|
||||
msgstr "无效的视图结构xml文件!"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.module.module,description:document.module_meta_information
|
||||
|
@ -284,7 +286,7 @@ msgstr "名称"
|
|||
#. module: document
|
||||
#: field:document.directory.content.type,code:0
|
||||
msgid "Extension"
|
||||
msgstr "延伸"
|
||||
msgstr "扩展"
|
||||
|
||||
#. module: document
|
||||
#: selection:ir.attachment,store_method:0
|
||||
|
@ -305,7 +307,7 @@ msgstr "目录"
|
|||
#. module: document
|
||||
#: view:document.directory:0
|
||||
msgid "Seq."
|
||||
msgstr "序号"
|
||||
msgstr "序列"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.module.module,shortdesc:document.module_meta_information
|
||||
|
@ -319,14 +321,15 @@ msgid "Directory"
|
|||
msgstr "说明"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,user_id:0 field:ir.attachment,user_id:0
|
||||
#: field:document.directory,user_id:0
|
||||
#: field:ir.attachment,user_id:0
|
||||
msgid "Owner"
|
||||
msgstr "拥有者"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.model,name:document.model_document_configuration_wizard
|
||||
msgid "document.configuration.wizard"
|
||||
msgstr "文档结构向导"
|
||||
msgstr ""
|
||||
|
||||
#. module: document
|
||||
#: view:ir.attachment:0
|
||||
|
@ -346,7 +349,8 @@ msgid "Content Type"
|
|||
msgstr "内容类型"
|
||||
|
||||
#. module: document
|
||||
#: view:document.directory:0 view:ir.attachment:0
|
||||
#: view:document.directory:0
|
||||
#: view:ir.attachment:0
|
||||
msgid "Security"
|
||||
msgstr "安全"
|
||||
|
||||
|
@ -370,10 +374,7 @@ msgstr "日志"
|
|||
msgid ""
|
||||
"Select an object here and Open ERP will create a mapping for each of these "
|
||||
"objects, using the given domain, when browsing through FTP."
|
||||
msgstr ""
|
||||
"选择一对象,系统将创建一个每个对象的列表,使用给定的域,通过FTP浏览\"\n"
|
||||
"document,view,document.directory,0,Seq.,序列\n"
|
||||
"document,field,document.directory.content"
|
||||
msgstr "通过FTP浏览, 使用给定的域, 在这选择一对象, 系统将创建一个每个对象的列表,"
|
||||
|
||||
#. module: document
|
||||
#: view:ir.attachment:0
|
||||
|
@ -383,10 +384,11 @@ msgstr "其它信息"
|
|||
#. module: document
|
||||
#: field:document.directory,domain:0
|
||||
msgid "Domain"
|
||||
msgstr "隶属"
|
||||
msgstr "域"
|
||||
|
||||
#. module: document
|
||||
#: field:document.directory,write_date:0 field:ir.attachment,write_date:0
|
||||
#: field:document.directory,write_date:0
|
||||
#: field:ir.attachment,write_date:0
|
||||
msgid "Date Modified"
|
||||
msgstr "修改日期"
|
||||
|
||||
|
@ -474,19 +476,19 @@ msgstr "内容"
|
|||
#. module: document
|
||||
#: model:ir.actions.act_window,name:document.action_view_files_by_partner
|
||||
msgid "Files Per Month"
|
||||
msgstr "月度文件"
|
||||
msgstr "每月文件"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.actions.act_window,name:document.action_view_wall
|
||||
#: model:ir.ui.menu,name:document.menu_action_view_my_document_report_shame
|
||||
#: view:report.document.wall:0
|
||||
msgid "Wall of Shame"
|
||||
msgstr "羞愧者名单"
|
||||
msgstr "耻辱之墙"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.model,name:document.model_report_files_partner
|
||||
msgid "Files details by Partners"
|
||||
msgstr "业务伙伴文件详细信息"
|
||||
msgstr "业务伙伴的文件详情"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.ui.menu,name:document.menu_action_view_my_document_report_all
|
||||
|
@ -502,7 +504,7 @@ msgstr "我的文件"
|
|||
#. module: document
|
||||
#: view:report.document.user:0
|
||||
msgid "Files by users"
|
||||
msgstr "用户文件"
|
||||
msgstr "用户的文件"
|
||||
|
||||
#. module: document
|
||||
#: view:report.files.partner:0
|
||||
|
@ -517,17 +519,17 @@ msgstr "我的文件(所有月份)"
|
|||
#. module: document
|
||||
#: field:report.document.wall,file_name:0
|
||||
msgid "Last Posted File Name"
|
||||
msgstr "最近发布的文件名"
|
||||
msgstr "最近上传的文件"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.ui.menu,name:document.menu_action_view_my_document_report
|
||||
msgid "Reporting"
|
||||
msgstr "内部报表"
|
||||
msgstr "报表"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.model,name:document.model_report_document_wall
|
||||
msgid "Users that did not inserted documents since one month"
|
||||
msgstr "一个月以来用户没有新文件"
|
||||
msgstr "一个月内没有新文件的用户"
|
||||
|
||||
#. module: document
|
||||
#: view:report.files.partner:0
|
||||
|
@ -548,28 +550,28 @@ msgstr "用户"
|
|||
#: model:ir.ui.menu,name:document.menu_action_view_my_document_report_all_userfile
|
||||
#: model:ir.ui.menu,name:document.menu_action_view_my_document_report_this_userfile
|
||||
msgid "All Users files"
|
||||
msgstr "所有用户文件"
|
||||
msgstr "所有用户的文件"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.actions.act_window,name:document.action_view_my_document_tree
|
||||
msgid "My files (This months)"
|
||||
msgstr "我的文件(这月)"
|
||||
msgstr "我的文件(本月)"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.model,name:document.model_report_document_user
|
||||
msgid "Files details by Users"
|
||||
msgstr "用户详细信息"
|
||||
msgstr "用户的文件详情"
|
||||
|
||||
#. module: document
|
||||
#: field:report.document.file,nbr:0 field:report.document.user,nbr:0
|
||||
#: field:report.files.partner,nbr:0
|
||||
msgid "# of Files"
|
||||
msgstr "文件号"
|
||||
msgstr "# 文件"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.actions.act_window,name:document.action_view_user_graph
|
||||
msgid "Files By Users"
|
||||
msgstr "用户文件"
|
||||
msgstr "用户的文件"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.module.module,shortdesc:report_document.module_meta_information
|
||||
|
@ -579,12 +581,12 @@ msgstr "文档管理 - 报表"
|
|||
#. module: document
|
||||
#: model:ir.actions.act_window,name:document.action_view_all_document_tree1
|
||||
msgid "All Users files (All months)"
|
||||
msgstr "所有文件(所有月份)"
|
||||
msgstr "所有用户的文件(所有月份)"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.model,name:document.model_report_document_file
|
||||
msgid "Files details by Directory"
|
||||
msgstr "文件详细目录"
|
||||
msgstr "目录文件详情"
|
||||
|
||||
#. module: document
|
||||
#: field:report.document.user,change_date:0
|
||||
|
@ -596,7 +598,7 @@ msgstr "修改日期"
|
|||
#: model:ir.actions.act_window,name:document.action_view_size_month
|
||||
#: view:report.document.file:0
|
||||
msgid "File Size by Month"
|
||||
msgstr "这月的文件大小"
|
||||
msgstr "按月度排列文件大小"
|
||||
|
||||
#. module: document
|
||||
#: field:report.document.user,file_title:0
|
||||
|
@ -609,13 +611,13 @@ msgstr "文件名"
|
|||
#: field:report.document.user,name:0 field:report.document.wall,month:0
|
||||
#: field:report.document.wall,name:0 field:report.files.partner,name:0
|
||||
msgid "Month"
|
||||
msgstr "月"
|
||||
msgstr "月份"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.actions.act_window,name:document.action_view_files_by_month_graph
|
||||
#: view:report.document.user:0
|
||||
msgid "Files by Month"
|
||||
msgstr "这月的文件"
|
||||
msgstr "按月度排列文件"
|
||||
|
||||
#. module: document
|
||||
#: model:ir.actions.act_window,name:document.action_view_document_by_resourcetype_graph
|
||||
|
@ -626,7 +628,7 @@ msgstr "文件的资源类型"
|
|||
#. module: document
|
||||
#: model:ir.actions.act_window,name:document.action_view_all_document_tree
|
||||
msgid "All Users files (This month)"
|
||||
msgstr "所有文件(所有月份)"
|
||||
msgstr "所有用户的文件(本月)"
|
||||
|
||||
#. module: document
|
||||
#: field:report.document.wall,last:0
|
||||
|
@ -635,19 +637,3 @@ msgstr "最近的发布时间"
|
|||
|
||||
#~ msgid "Active"
|
||||
#~ msgstr "生效"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "\n"
|
||||
#~ " Reporting for the Document Management module:\n"
|
||||
#~ " * My Files\n"
|
||||
#~ " * All users Files \n"
|
||||
#~ " "
|
||||
#~ msgstr ""
|
||||
#~ "\n"
|
||||
#~ " 报告文档管理模块:\n"
|
||||
#~ "\t\t- 我的文件\n"
|
||||
#~ "\t\t- 所有用户的文件 \n"
|
||||
#~ " "
|
||||
|
||||
#~ msgid "Files Per Partner"
|
||||
#~ msgstr "每个业务伙伴文件"
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -33,22 +33,22 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_report_document_user_search" model="ir.ui.view">
|
||||
<record id="view_report_document_user_search" model="ir.ui.view">
|
||||
<field name="name">report.document.user.search</field>
|
||||
<field name="model">report.document.user</field>
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="All users files">
|
||||
<group col="12" colspan="4">
|
||||
<group col="12" colspan="4">
|
||||
<separator orientation="vertical"/>
|
||||
<filter icon="terp-go-year" string="This Year" domain="[('name','=',time.localtime()[0])]" help="All Months Files"/>
|
||||
<filter icon="terp-go-month" string="This Month" domain="[('month','=',time.localtime()[1])]" help="This Months Files"/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="name" select="1"/>
|
||||
<field name="month" select="1"/>
|
||||
<field name="user" select="1"/>
|
||||
<field name="directory" select="1"/>
|
||||
</group>
|
||||
<filter icon="terp-go-year" string="This Year" domain="[('name','=',time.localtime()[0])]" help="All Months Files"/>
|
||||
<filter icon="terp-go-month" string="This Month" domain="[('month','=',time.localtime()[1])]" help="This Months Files"/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="name" select="1"/>
|
||||
<field name="month" select="1"/>
|
||||
<field name="user" select="1"/>
|
||||
<field name="directory" select="1"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -61,7 +61,7 @@
|
|||
<field name="res_model">report.document.user</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="context">{"search_default_user":uid}</field>
|
||||
<field name="context">{'search_default_user': 'user_id'}</field>
|
||||
<field name="search_view_id" ref="view_report_document_user_search"/>
|
||||
</record>
|
||||
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
-
|
||||
In order to test the document management
|
||||
-
|
||||
I make sure the default installation has some storage and root directory.
|
||||
-
|
||||
!assert {model: document.storage, id: storage_default }:
|
||||
- id != False
|
||||
-
|
||||
!assert {model: document.directory, id: dir_root}:
|
||||
- storage_id != False
|
||||
-
|
||||
I create a "Testing" folder where all the test data will go.
|
||||
-
|
||||
!record {model: document.directory, id: dir_tests }:
|
||||
name: 'Testing'
|
||||
parent_id: dir_root
|
||||
-
|
||||
I create an attachment into the root folder (w. empty fields, test that
|
||||
defaults work)
|
||||
-
|
||||
!record {model: ir.attachment, id: file_test1 }:
|
||||
name: Test file
|
||||
-
|
||||
I delete the attachment from the root folder
|
||||
-
|
||||
!delete {model: ir.attachment, id: file_test1, search: }
|
||||
-
|
||||
I create an attachment into the Testing folder.
|
||||
-
|
||||
!record {model: ir.attachment, id: file_test2 }:
|
||||
name: Test file 2
|
||||
parent_id: dir_tests
|
||||
-
|
||||
I update the attachment with data, namely "abcd"
|
||||
-
|
||||
!record {model: ir.attachment, id: file_test2 }:
|
||||
datas: "abcd"
|
||||
-
|
||||
I test that the datas of the attachment are correct
|
||||
-
|
||||
!assert {model: ir.attachment, id: file_test2 }:
|
||||
- datas == "abcd\n"
|
||||
- file_size == 5
|
||||
- file_type == 'text/plain'
|
||||
-
|
||||
I rename the attachment.
|
||||
-
|
||||
!record {model: ir.attachment, id: file_test2 }:
|
||||
name: Test renamed 2
|
||||
-
|
||||
I search the testing folder for attachments.
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
ids = self.search(cr, uid, [('parent_id.name','=', 'Testing'), ('name','=','Test renamed 2')])
|
||||
assert ids == [ ref("file_test2") ], ids
|
||||
-
|
||||
I create an attachment to a 3rd resource, eg. a res.country
|
||||
-
|
||||
!record {model: ir.attachment, id: attach_3rd }:
|
||||
name: 'Res country attachment.txt'
|
||||
parent_id: dir_tests
|
||||
datas: 'defg'
|
||||
res_model: res.country
|
||||
res_id: !eval ref("base.za")
|
||||
-
|
||||
I search for the res.country attachment
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
ids = self.search(cr, uid, [('res_model', '=', 'res.country'), ('res_id', '=', ref("base.za"))])
|
||||
assert ids == [ ref("attach_3rd")], ids
|
||||
-
|
||||
!delete {model: ir.attachment, id: attach_3rd, search: }
|
|
@ -26,20 +26,23 @@
|
|||
'category': 'Generic Modules/Others',
|
||||
'description': """This is a support FTP Interface with document management system.
|
||||
With this module you would not only be able to access documents through open erp
|
||||
but you would also be able to connect with them through the file system using the FTP protocol.
|
||||
but you would also be able to connect with them through the file system using the
|
||||
a FTP client.
|
||||
""",
|
||||
'author': 'Tiny',
|
||||
'website': 'http://www.openerp.com',
|
||||
'depends': ['base', 'document'],
|
||||
'init_xml': [],
|
||||
'update_xml': [
|
||||
'wizard/ftp_configuration_view.xml',
|
||||
'wizard/ftp_browse_view.xml',
|
||||
'wizard/ftp_configuration_view.xml',
|
||||
'wizard/ftp_browse_view.xml',
|
||||
'security/ir.model.access.csv'
|
||||
],
|
||||
'demo_xml': [],
|
||||
'test': [
|
||||
'test/document_ftp_test.yml',
|
||||
'test/document_ftp_test2.yml',
|
||||
# 'test/document_ftp_test2.yml',
|
||||
'test/document_ftp_test4.yml',
|
||||
],
|
||||
'installable': True,
|
||||
'active': False,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -221,6 +221,33 @@ def _strerror(err):
|
|||
else:
|
||||
return err.strerror
|
||||
|
||||
def _to_unicode(s):
|
||||
try:
|
||||
return s.decode('utf-8')
|
||||
except UnicodeError:
|
||||
pass
|
||||
try:
|
||||
return s.decode('latin')
|
||||
except UnicodeError:
|
||||
pass
|
||||
try:
|
||||
return s.encode('ascii')
|
||||
except UnicodeError:
|
||||
return s
|
||||
|
||||
def _to_decode(s):
|
||||
try:
|
||||
return s.encode('utf-8')
|
||||
except UnicodeError:
|
||||
pass
|
||||
try:
|
||||
return s.encode('latin')
|
||||
except UnicodeError:
|
||||
pass
|
||||
try:
|
||||
return s.decode('ascii')
|
||||
except UnicodeError:
|
||||
return s
|
||||
|
||||
# --- library defined exceptions
|
||||
|
||||
|
@ -793,7 +820,7 @@ class DTPHandler(asyncore.dispatcher):
|
|||
if self.transfer_finished:
|
||||
self.cmd_channel.respond("226 Transfer complete.")
|
||||
if self.file_obj:
|
||||
fname = self.cmd_channel.fs.fs2ftp(self.file_obj.name)
|
||||
fname = self.file_obj.name
|
||||
self.cmd_channel.log('"%s" %s.' %(fname, action))
|
||||
else:
|
||||
tot_bytes = self.get_transmitted_bytes()
|
||||
|
@ -1138,19 +1165,11 @@ class AbstractedFS:
|
|||
|
||||
# note: the following operations are no more blocking
|
||||
|
||||
def get_list_dir(self, path):
|
||||
def get_list_dir(self, datacr):
|
||||
""""Return an iterator object that yields a directory listing
|
||||
in a form suitable for LIST command.
|
||||
"""
|
||||
if self.isdir(path):
|
||||
listing = self.listdir(path)
|
||||
listing.sort()
|
||||
return self.format_list(path, listing)
|
||||
# if path is a file or a symlink we return information about it
|
||||
else:
|
||||
basedir, filename = os.path.split(path)
|
||||
self.lstat(path) # raise exc in case of problems
|
||||
return self.format_list(basedir, [filename])
|
||||
raise DeprecationWarning()
|
||||
|
||||
def get_stat_dir(self, rawline):
|
||||
"""Return an iterator object that yields a list of files
|
||||
|
@ -1335,6 +1354,11 @@ class AbstractedFS:
|
|||
|
||||
# --- FTP
|
||||
|
||||
class FTPExceptionSent(Exception):
|
||||
"""An FTP exception that FTPHandler has processed
|
||||
"""
|
||||
pass
|
||||
|
||||
class FTPHandler(asynchat.async_chat):
|
||||
"""Implements the FTP server Protocol Interpreter (see RFC-959),
|
||||
handling commands received from the client on the control channel.
|
||||
|
@ -1434,6 +1458,14 @@ class FTPHandler(asynchat.async_chat):
|
|||
self._epsvall = False
|
||||
self.__in_dtp_queue = None
|
||||
self.__out_dtp_queue = None
|
||||
|
||||
self.__errno_responses = {
|
||||
errno.EPERM: 553,
|
||||
errno.EINVAL: 504,
|
||||
errno.ENOENT: 550,
|
||||
errno.EREMOTE: 450,
|
||||
errno.EEXIST: 521,
|
||||
}
|
||||
|
||||
# mlsx facts attributes
|
||||
self.current_facts = ['type', 'perm', 'size', 'modify']
|
||||
|
@ -1591,26 +1623,8 @@ class FTPHandler(asynchat.async_chat):
|
|||
|
||||
def __check_path(self, cmd, line):
|
||||
"""Check whether a path is valid."""
|
||||
# For the following commands we have to make sure that the real
|
||||
# path destination belongs to the user's root directory.
|
||||
# If provided path is a symlink we follow its final destination
|
||||
# to do so.
|
||||
if cmd in ('APPE','CWD','DELE','MDTM','NLST','MLSD','MLST','RETR',
|
||||
'RMD','SIZE','STOR','XCWD','XRMD'):
|
||||
datacr = None
|
||||
datacr = self.fs.get_cr(line)
|
||||
try:
|
||||
if not self.fs.validpath(self.fs.ftp2fs(line, datacr)):
|
||||
line = self.fs.ftpnorm(line)
|
||||
err = '"%s" points to a path which is outside ' \
|
||||
"the user's root directory" %line
|
||||
self.respond("550 %s." %err)
|
||||
self.log('FAIL %s "%s". %s.' %(cmd, line, err))
|
||||
self.fs.close_cr(datacr)
|
||||
return False
|
||||
except:
|
||||
pass
|
||||
self.fs.close_cr(datacr)
|
||||
|
||||
# Always true, we will only check later, once we have a cursor
|
||||
return True
|
||||
|
||||
def __check_perm(self, cmd, line, datacr):
|
||||
|
@ -1623,6 +1637,7 @@ class FTPHandler(asynchat.async_chat):
|
|||
'RNFR':'f',
|
||||
'MKD':'m', 'XMKD':'m',
|
||||
'STOR':'w'}
|
||||
raise NotImplementedError
|
||||
if cmd in map:
|
||||
if cmd == 'STAT' and not line:
|
||||
return True
|
||||
|
@ -1813,6 +1828,58 @@ class FTPHandler(asynchat.async_chat):
|
|||
|
||||
# --- connection
|
||||
|
||||
def try_as_current_user(self, function, args=None, kwargs=None, line=None, errno_resp=None):
|
||||
"""run function as current user, auto-respond in exceptions
|
||||
@param args,kwargs the arguments, in list and dict respectively
|
||||
@param errno_resp a dictionary of responses to IOError, OSError
|
||||
"""
|
||||
if errno_resp:
|
||||
eresp = self.__errno_responses.copy()
|
||||
eresp.update(errno_resp)
|
||||
else:
|
||||
eresp = self.__errno_responses
|
||||
|
||||
uline = ''
|
||||
if line:
|
||||
uline = ' "%s"' % _to_unicode(line)
|
||||
try:
|
||||
if args is None:
|
||||
args = ()
|
||||
if kwargs is None:
|
||||
kwargs = {}
|
||||
return self.run_as_current_user(function, *args, **kwargs)
|
||||
except NotImplementedError, err:
|
||||
cmdname = function.__name__
|
||||
why = err.args[0] or 'Not implemented'
|
||||
self.log('FAIL %s() not implemented: %s.' %(cmdname, why))
|
||||
self.respond('502 %s.' %why)
|
||||
raise FTPExceptionSent(why)
|
||||
except EnvironmentError, err:
|
||||
cmdname = function.__name__
|
||||
try:
|
||||
logline(traceback.format_exc())
|
||||
except Exception:
|
||||
pass
|
||||
ret_code = eresp.get(err.errno, '451')
|
||||
why = (err.strerror) or 'Error in command'
|
||||
self.log('FAIL %s() %s errno=%s: %s.' %(cmdname, uline, err.errno, why))
|
||||
self.respond('%s %s.' % (str(ret_code), why))
|
||||
|
||||
raise FTPExceptionSent(why)
|
||||
except Exception, e:
|
||||
cmdname = function.__name__
|
||||
try:
|
||||
logerror(traceback.format_exc())
|
||||
except Exception:
|
||||
pass
|
||||
why = (err.args and err.args[0]) or 'Exception'
|
||||
self.log('FAIL %s() %s Exception: %s.' %(cmdname, uline, why))
|
||||
self.respond('451 %s.' % why)
|
||||
raise FTPExceptionSent(why)
|
||||
|
||||
def get_crdata2(self, *args, **kwargs):
|
||||
return self.try_as_current_user(self.fs.get_crdata, args, kwargs, line=args[0])
|
||||
|
||||
def _make_eport(self, ip, port):
|
||||
"""Establish an active data channel with remote client which
|
||||
issued a PORT or EPRT command.
|
||||
|
@ -2032,56 +2099,58 @@ class FTPHandler(asynchat.async_chat):
|
|||
# - Some older FTP clients erroneously issue /bin/ls-like LIST
|
||||
# formats in which case we fall back on cwd as default.
|
||||
if not line or line.lower() in ('-a', '-l', '-al', '-la'):
|
||||
line = self.fs.cwd
|
||||
line = ''
|
||||
datacr = None
|
||||
try:
|
||||
data = None
|
||||
data = self.fs.get_cr(line)
|
||||
path = self.fs.ftp2fs(line, data)
|
||||
line = self.fs.ftpnorm(line)
|
||||
iterator = self.run_as_current_user(self.fs.get_list_dir, path)
|
||||
except OSError, err:
|
||||
self.fs.close_cr(data)
|
||||
why = _strerror(err)
|
||||
self.log('FAIL LIST "%s". %s.' %(line, why))
|
||||
self.respond('550 %s.' %why)
|
||||
else:
|
||||
self.fs.close_cr(data)
|
||||
self.log('OK LIST "%s". Transfer starting.' %line)
|
||||
datacr = self.get_crdata2(line, mode='list')
|
||||
iterator = self.try_as_current_user(self.fs.get_list_dir, (datacr,))
|
||||
except FTPExceptionSent:
|
||||
self.fs.close_cr(datacr)
|
||||
return
|
||||
|
||||
try:
|
||||
self.log('OK LIST "%s". Transfer starting.' % line)
|
||||
producer = BufferedIteratorProducer(iterator)
|
||||
self.push_dtp_data(producer, isproducer=True)
|
||||
finally:
|
||||
self.fs.close_cr(datacr)
|
||||
|
||||
|
||||
def ftp_NLST(self, line):
|
||||
"""Return a list of files in the specified directory in a
|
||||
compact form to the client.
|
||||
"""
|
||||
if not line:
|
||||
line = self.fs.cwd
|
||||
line = ''
|
||||
|
||||
datacr = None
|
||||
try:
|
||||
data = None
|
||||
data = self.fs.get_cr(line)
|
||||
path = self.fs.ftp2fs(line, data)
|
||||
line = self.fs.ftpnorm(line)
|
||||
if self.fs.isdir(path):
|
||||
listing = self.run_as_current_user(self.fs.listdir, path)
|
||||
listing = map(lambda x:os.path.split(x.path)[1], listing)
|
||||
datacr = self.get_crdata2(line, mode='list')
|
||||
if not datacr:
|
||||
datacr = ( None, None, None )
|
||||
if self.fs.isdir(datacr[1]):
|
||||
nodelist = self.try_as_current_user(self.fs.listdir, (datacr,))
|
||||
else:
|
||||
# if path is a file we just list its name
|
||||
self.fs.lstat(path) # raise exc in case of problems
|
||||
basedir, filename = os.path.split(line)
|
||||
listing = [filename]
|
||||
except OSError, err:
|
||||
self.fs.close_cr(data)
|
||||
why = _strerror(err)
|
||||
self.log('FAIL NLST "%s". %s.' %(line, why))
|
||||
self.respond('550 %s.' %why)
|
||||
else:
|
||||
self.fs.close_cr(data)
|
||||
data = ''
|
||||
if listing:
|
||||
listing.sort()
|
||||
data = '\r\n'.join(listing) + '\r\n'
|
||||
self.log('OK NLST "%s". Transfer starting.' %line)
|
||||
self.push_dtp_data(data)
|
||||
nodelist = [datacr[1],]
|
||||
|
||||
listing = []
|
||||
for nl in nodelist:
|
||||
if isinstance(nl.path, (list, tuple)):
|
||||
listing.append(nl.path[-1])
|
||||
else:
|
||||
listing.append(nl.path) # assume string
|
||||
except FTPExceptionSent:
|
||||
self.fs.close_cr(datacr)
|
||||
return
|
||||
|
||||
self.fs.close_cr(datacr)
|
||||
data = ''
|
||||
if listing:
|
||||
listing.sort()
|
||||
data = ''.join([ _to_decode(x) + '\r\n' for x in listing ])
|
||||
self.log('OK NLST "%s". Transfer starting.' %line)
|
||||
self.push_dtp_data(data)
|
||||
|
||||
# --- MLST and MLSD commands
|
||||
|
||||
|
@ -2096,22 +2165,17 @@ class FTPHandler(asynchat.async_chat):
|
|||
"""
|
||||
# if no argument, fall back on cwd as default
|
||||
if not line:
|
||||
line = self.fs.cwd
|
||||
line = ''
|
||||
datacr = None
|
||||
try:
|
||||
datacr = None
|
||||
datacr = self.fs.get_cr(line)
|
||||
path = self.fs.ftp2fs(line, datacr)
|
||||
line = self.fs.ftpnorm(line)
|
||||
basedir, basename = os.path.split(path)
|
||||
datacr = self.get_crdata2(line, mode='list')
|
||||
perms = self.authorizer.get_perms(self.username)
|
||||
iterator = self.run_as_current_user(self.fs.format_mlsx, basedir,
|
||||
[basename], perms, self.current_facts, ignore_err=False)
|
||||
iterator = self.try_as_current_user(self.fs.format_mlsx, (datacr[0], datacr[1].parent,
|
||||
[datacr[1],], perms, self.current_facts), {'ignore_err':False})
|
||||
data = ''.join(iterator)
|
||||
except OSError, err:
|
||||
except FTPExceptionSent:
|
||||
self.fs.close_cr(datacr)
|
||||
why = _strerror(err)
|
||||
self.log('FAIL MLST "%s". %s.' %(line, why))
|
||||
self.respond('550 %s.' %why)
|
||||
return
|
||||
else:
|
||||
self.fs.close_cr(datacr)
|
||||
# since TVFS is supported (see RFC-3659 chapter 6), a fully
|
||||
|
@ -2129,28 +2193,25 @@ class FTPHandler(asynchat.async_chat):
|
|||
"""
|
||||
# if no argument, fall back on cwd as default
|
||||
if not line:
|
||||
line = self.fs.cwd
|
||||
line = ''
|
||||
|
||||
datacr = None
|
||||
try:
|
||||
datacr = None
|
||||
datacr = self.fs.get_cr(line)
|
||||
path = self.fs.ftp2fs(line, datacr)
|
||||
line = self.fs.ftpnorm(line)
|
||||
datacr = self.get_crdata2(line, mode='list')
|
||||
# RFC-3659 requires 501 response code if path is not a directory
|
||||
if not self.fs.isdir(path):
|
||||
if not self.fs.isdir(datacr[1]):
|
||||
err = 'No such directory'
|
||||
self.log('FAIL MLSD "%s". %s.' %(line, err))
|
||||
self.respond("501 %s." %err)
|
||||
return
|
||||
listing = self.run_as_current_user(self.fs.listdir, path)
|
||||
except OSError, err:
|
||||
listing = self.try_as_current_user(self.fs.listdir, (datacr,))
|
||||
except FTPExceptionSent:
|
||||
self.fs.close_cr(datacr)
|
||||
why = _strerror(err)
|
||||
self.log('FAIL MLSD "%s". %s.' %(line, why))
|
||||
self.respond('550 %s.' %why)
|
||||
return
|
||||
else:
|
||||
self.fs.close_cr(datacr)
|
||||
perms = self.authorizer.get_perms(self.username)
|
||||
iterator = self.fs.format_mlsx(path, listing, perms,
|
||||
iterator = self.fs.format_mlsx(datacr[0], datacr[1], listing, perms,
|
||||
self.current_facts)
|
||||
producer = BufferedIteratorProducer(iterator)
|
||||
self.log('OK MLSD "%s". Transfer starting.' %line)
|
||||
|
@ -2160,23 +2221,12 @@ class FTPHandler(asynchat.async_chat):
|
|||
"""Retrieve the specified file (transfer from the server to the
|
||||
client)
|
||||
"""
|
||||
datacr = None
|
||||
try:
|
||||
datacr = None
|
||||
datacr = self.fs.get_cr(line)
|
||||
file = self.fs.ftp2fs(line, datacr)
|
||||
line = self.fs.ftpnorm(line)
|
||||
fd = self.run_as_current_user(self.fs.open, file, 'rb')
|
||||
except OSError, err:
|
||||
datacr = self.get_crdata2(line, mode='file')
|
||||
fd = self.try_as_current_user(self.fs.open, (datacr, 'rb'))
|
||||
except FTPExceptionSent:
|
||||
self.fs.close_cr(datacr)
|
||||
why = _strerror(err)
|
||||
self.log('FAIL RETR "%s". %s.' %(line, why))
|
||||
self.respond('550 %s.' %why)
|
||||
return
|
||||
except IOError, err:
|
||||
self.fs.close_cr(datacr)
|
||||
why = _strerror(err)
|
||||
self.log('FAIL RETR "%s". %s.' %(line, why))
|
||||
self.respond('550 %s.' %why)
|
||||
return
|
||||
|
||||
if self.restart_position:
|
||||
|
@ -2187,7 +2237,7 @@ class FTPHandler(asynchat.async_chat):
|
|||
# the REST.
|
||||
ok = 0
|
||||
try:
|
||||
assert not self.restart_position > self.fs.getsize(file)
|
||||
assert not self.restart_position > self.fs.getsize(datacr)
|
||||
fd.seek(self.restart_position)
|
||||
ok = 1
|
||||
except AssertionError:
|
||||
|
@ -2217,30 +2267,14 @@ class FTPHandler(asynchat.async_chat):
|
|||
else:
|
||||
cmd = 'STOR'
|
||||
|
||||
line = self.fs.ftpnorm(line)
|
||||
basedir,basename = os.path.split(line)
|
||||
|
||||
datacr = None
|
||||
try:
|
||||
datacr = self.fs.get_cr(line)
|
||||
file = self.fs.ftp2fs(basedir, datacr)
|
||||
|
||||
except OSError, err:
|
||||
datacr = self.get_crdata2(line,mode='create')
|
||||
if self.restart_position:
|
||||
mode = 'r+'
|
||||
fd = self.try_as_current_user(self.fs.create, (datacr, datacr[2], mode + 'b'))
|
||||
except FTPExceptionSent:
|
||||
self.fs.close_cr(datacr)
|
||||
why = _strerror(err)
|
||||
self.log('FAIL %s "%s". %s.' %(cmd, line, why))
|
||||
self.respond('550 %s.' %why)
|
||||
return
|
||||
|
||||
if self.restart_position:
|
||||
mode = 'r+'
|
||||
try:
|
||||
fd = self.run_as_current_user(self.fs.create, file, basename, mode + 'b')
|
||||
except IOError, err:
|
||||
self.fs.close_cr(datacr)
|
||||
why = _strerror(err)
|
||||
self.log('FAIL %s "%s". %s.' %(cmd, line, why))
|
||||
self.respond('550 %s.' %why)
|
||||
return
|
||||
|
||||
if self.restart_position:
|
||||
|
@ -2251,7 +2285,7 @@ class FTPHandler(asynchat.async_chat):
|
|||
# specified in the REST.
|
||||
ok = 0
|
||||
try:
|
||||
assert not self.restart_position > self.fs.getsize(self.fs.ftp2fs(line, datacr))
|
||||
assert not self.restart_position > self.fs.getsize(datacr)
|
||||
fd.seek(self.restart_position)
|
||||
ok = 1
|
||||
except AssertionError:
|
||||
|
@ -2293,21 +2327,21 @@ class FTPHandler(asynchat.async_chat):
|
|||
self.respond("450 Can't STOU while REST request is pending.")
|
||||
return
|
||||
|
||||
datacr = None
|
||||
datacr = self.fs.get_cr(line)
|
||||
|
||||
if line:
|
||||
line = self.fs.ftpnorm(line)
|
||||
basedir,prefix = os.path.split(line)
|
||||
basedir = self.fs.ftp2fs(basedir, datacr)
|
||||
#prefix = prefix + '.'
|
||||
datacr = self.get_crdata2(line, mode='create')
|
||||
# TODO
|
||||
else:
|
||||
# TODO
|
||||
basedir = self.fs.ftp2fs(self.fs.cwd, datacr)
|
||||
prefix = 'ftpd.'
|
||||
try:
|
||||
fd = self.run_as_current_user(self.fs.mkstemp, prefix=prefix,
|
||||
dir=basedir)
|
||||
except IOError, err:
|
||||
fd = self.try_as_current_user(self.fs.mkstemp, kwargs={'prefix':prefix,
|
||||
'dir': basedir}, line=line )
|
||||
except FTPExceptionSent:
|
||||
self.fs.close_cr(datacr)
|
||||
return
|
||||
except IOError, err: # TODO
|
||||
# hitted the max number of tries to find out file with
|
||||
# unique name
|
||||
if err.errno == errno.EEXIST:
|
||||
|
@ -2500,33 +2534,25 @@ class FTPHandler(asynchat.async_chat):
|
|||
|
||||
def ftp_PWD(self, line):
|
||||
"""Return the name of the current working directory to the client."""
|
||||
self.respond('257 "%s" is the current directory.' %self.fs.cwd)
|
||||
cwd = self.fs.get_cwd()
|
||||
self.respond('257 "%s" is the current directory.' % cwd)
|
||||
|
||||
def ftp_CWD(self, line):
|
||||
"""Change the current working directory."""
|
||||
# TODO: a lot of FTP servers go back to root directory if no
|
||||
# check: a lot of FTP servers go back to root directory if no
|
||||
# arg is provided but this is not specified in RFC-959.
|
||||
# Search for official references about this behaviour.
|
||||
if not line:
|
||||
line = '/'
|
||||
datacr = None
|
||||
try:
|
||||
datacr = self.fs.get_cr(line)
|
||||
path = self.fs.ftp2fs(line, datacr)
|
||||
self.run_as_current_user(self.fs.chdir, path)
|
||||
except OSError, err:
|
||||
if err.errno==2:
|
||||
why = 'Authentication Required or Failed'
|
||||
self.log('FAIL CWD "%s". %s.' %(self.fs.ftpnorm(line), why))
|
||||
self.respond('530 %s.' %why)
|
||||
else:
|
||||
why = _strerror(err)
|
||||
self.log('FAIL CWD "%s". %s.' %(self.fs.ftpnorm(line), why))
|
||||
self.respond('550 %s.' %why)
|
||||
else:
|
||||
self.log('OK CWD "%s".' %self.fs.cwd)
|
||||
self.respond('250 "%s" is the current directory.' %self.fs.cwd)
|
||||
self.fs.close_cr(datacr)
|
||||
datacr = self.get_crdata2(line,'cwd')
|
||||
self.try_as_current_user(self.fs.chdir, (datacr,), line=line, errno_resp={2: 530})
|
||||
cwd = self.fs.get_cwd()
|
||||
self.log('OK CWD "%s".' % cwd)
|
||||
self.respond('250 "%s" is the current directory.' % cwd)
|
||||
except FTPExceptionSent:
|
||||
return
|
||||
finally:
|
||||
self.fs.close_cr(datacr)
|
||||
|
||||
def ftp_CDUP(self, line):
|
||||
"""Change into the parent directory."""
|
||||
|
@ -2554,20 +2580,17 @@ class FTPHandler(asynchat.async_chat):
|
|||
"""
|
||||
datacr = None
|
||||
try:
|
||||
datacr = self.fs.get_cr(line)
|
||||
path = self.fs.ftp2fs(line, datacr)
|
||||
line = self.fs.ftpnorm(line)
|
||||
if self.fs.isdir(path):
|
||||
why = "%s is not retrievable" %line
|
||||
self.log('FAIL SIZE "%s". %s.' %(line, why))
|
||||
self.respond("550 %s." %why)
|
||||
self.fs.close_cr(datacr)
|
||||
return
|
||||
size = self.run_as_current_user(self.fs.getsize, path)
|
||||
except OSError, err:
|
||||
why = _strerror(err)
|
||||
self.log('FAIL SIZE "%s". %s.' %(line, why))
|
||||
self.respond('550 %s.' %why)
|
||||
datacr = self.get_crdata2(line, mode='file')
|
||||
#if self.fs.isdir(datacr[1]):
|
||||
# why = "%s is not retrievable" %line
|
||||
# self.log('FAIL SIZE "%s". %s.' %(line, why))
|
||||
# self.respond("550 %s." %why)
|
||||
# self.fs.close_cr(datacr)
|
||||
# return
|
||||
size = self.try_as_current_user(self.fs.getsize,(datacr,), line=line)
|
||||
except FTPExceptionSent:
|
||||
self.fs.close_cr(datacr)
|
||||
return
|
||||
else:
|
||||
self.respond("213 %s" %size)
|
||||
self.log('OK SIZE "%s".' %line)
|
||||
|
@ -2578,40 +2601,35 @@ class FTPHandler(asynchat.async_chat):
|
|||
3307 style timestamp (YYYYMMDDHHMMSS) as defined in RFC-3659.
|
||||
"""
|
||||
datacr = None
|
||||
|
||||
try:
|
||||
datacr = self.fs.get_cr(line)
|
||||
path = self.fs.ftp2fs(line, datacr)
|
||||
line = self.fs.ftpnorm(line)
|
||||
if not self.fs.isfile(self.fs.realpath(path)):
|
||||
why = "%s is not retrievable" %line
|
||||
self.log('FAIL MDTM "%s". %s.' %(line, why))
|
||||
self.respond("550 %s." %why)
|
||||
self.fs.close_cr(datacr)
|
||||
return
|
||||
lmt = self.run_as_current_user(self.fs.getmtime, path)
|
||||
except OSError, err:
|
||||
why = _strerror(err)
|
||||
self.log('FAIL MDTM "%s". %s.' %(line, why))
|
||||
self.respond('550 %s.' %why)
|
||||
else:
|
||||
if line.find('/', 1) < 0:
|
||||
# root or db, just return local
|
||||
lmt = None
|
||||
else:
|
||||
datacr = self.get_crdata2(line)
|
||||
if not datacr:
|
||||
raise IOError(errno.ENOENT, "%s is not retrievable" %line)
|
||||
#if not self.fs.isfile(datacr[1]):
|
||||
# raise IOError(errno.EPERM, "%s is not a regular file" % line)
|
||||
|
||||
lmt = self.try_as_current_user(self.fs.getmtime, (datacr,), line=line)
|
||||
lmt = time.strftime("%Y%m%d%H%M%S", time.localtime(lmt))
|
||||
self.respond("213 %s" %lmt)
|
||||
self.log('OK MDTM "%s".' %line)
|
||||
self.fs.close_cr(datacr)
|
||||
except FTPExceptionSent:
|
||||
return
|
||||
finally:
|
||||
self.fs.close_cr(datacr)
|
||||
|
||||
def ftp_MKD(self, line):
|
||||
"""Create the specified directory."""
|
||||
datacr = None
|
||||
line = self.fs.ftpnorm(line)
|
||||
basedir,basename = os.path.split(line)
|
||||
try:
|
||||
datacr = self.fs.get_cr(line)
|
||||
path = self.fs.ftp2fs(basedir, datacr)
|
||||
self.run_as_current_user(self.fs.mkdir, path, basename)
|
||||
except OSError, err:
|
||||
why = _strerror(err)
|
||||
self.log('FAIL MKD "%s". %s.' %(line, why))
|
||||
self.respond('550 %s.' %why)
|
||||
datacr = self.get_crdata2(line, mode='create')
|
||||
self.try_as_current_user(self.fs.mkdir, (datacr, datacr[2]), line=line)
|
||||
except FTPExceptionSent:
|
||||
self.fs.close_cr(datacr)
|
||||
return
|
||||
else:
|
||||
self.log('OK MKD "%s".' %line)
|
||||
self.respond("257 Directory created.")
|
||||
|
@ -2621,40 +2639,30 @@ class FTPHandler(asynchat.async_chat):
|
|||
"""Remove the specified directory."""
|
||||
datacr = None
|
||||
try:
|
||||
datacr = self.fs.get_cr(line)
|
||||
path = self.fs.ftp2fs(line, datacr)
|
||||
line = self.fs.ftpnorm(line)
|
||||
if self.fs.realpath(path) == self.fs.realpath(self.fs.root):
|
||||
datacr = self.get_crdata2(line, mode='delete')
|
||||
if not datacr[1]:
|
||||
msg = "Can't remove root directory."
|
||||
self.respond("550 %s" %msg)
|
||||
self.respond("553 %s" %msg)
|
||||
self.log('FAIL MKD "/". %s' %msg)
|
||||
self.fs.close_cr(datacr)
|
||||
return
|
||||
self.run_as_current_user(self.fs.rmdir, path)
|
||||
except OSError, err:
|
||||
why = _strerror(err)
|
||||
self.log('FAIL RMD "%s". %s.' %(line, why))
|
||||
self.respond('550 %s.' %why)
|
||||
else:
|
||||
self.try_as_current_user(self.fs.rmdir, (datacr,), line=line)
|
||||
self.log('OK RMD "%s".' %line)
|
||||
self.respond("250 Directory removed.")
|
||||
except FTPExceptionSent:
|
||||
pass
|
||||
self.fs.close_cr(datacr)
|
||||
|
||||
def ftp_DELE(self, line):
|
||||
"""Delete the specified file."""
|
||||
datacr = None
|
||||
try:
|
||||
datacr = self.fs.get_cr(line)
|
||||
path = self.fs.ftp2fs(line, datacr)
|
||||
line = self.fs.ftpnorm(line)
|
||||
self.run_as_current_user(self.fs.remove, path)
|
||||
except OSError, err:
|
||||
why = _strerror(err)
|
||||
self.log('FAIL DELE "%s". %s.' %(line, why))
|
||||
self.respond('550 %s.' %why)
|
||||
else:
|
||||
datacr = self.get_crdata2(line, mode='delete')
|
||||
self.try_as_current_user(self.fs.remove, (datacr,), line=line)
|
||||
self.log('OK DELE "%s".' %line)
|
||||
self.respond("250 File removed.")
|
||||
except FTPExceptionSent:
|
||||
pass
|
||||
self.fs.close_cr(datacr)
|
||||
|
||||
def ftp_RNFR(self, line):
|
||||
|
@ -2662,18 +2670,16 @@ class FTPHandler(asynchat.async_chat):
|
|||
here, see RNTO command)"""
|
||||
datacr = None
|
||||
try:
|
||||
datacr = self.fs.get_cr(line)
|
||||
line = self.fs.ftpnorm(line)
|
||||
path = self.fs.ftp2fs(line, datacr)
|
||||
if not self.fs.lexists(path):
|
||||
datacr = self.get_crdata2(line, mode='rfnr')
|
||||
if not datacr[1]:
|
||||
self.respond("550 No such file or directory.")
|
||||
elif self.fs.realpath(path) == self.fs.realpath(self.fs.root):
|
||||
self.respond("550 Can't rename the home directory.")
|
||||
elif not datacr[1]:
|
||||
self.respond("553 Can't rename the home directory.")
|
||||
else:
|
||||
self.fs.rnfr = line
|
||||
self.fs.rnfr = datacr[1]
|
||||
self.respond("350 Ready for destination name.")
|
||||
except:
|
||||
self.respond("550 Can't find the file or directory.")
|
||||
except FTPExceptionSent:
|
||||
pass
|
||||
self.fs.close_cr(datacr)
|
||||
|
||||
def ftp_RNTO(self, line):
|
||||
|
@ -2685,22 +2691,17 @@ class FTPHandler(asynchat.async_chat):
|
|||
return
|
||||
datacr = None
|
||||
try:
|
||||
try:
|
||||
datacr = self.fs.get_cr(line)
|
||||
src = self.fs.ftp2fs(self.fs.rnfr, datacr)
|
||||
line = self.fs.ftpnorm(line)
|
||||
basedir,basename = os.path.split(line)
|
||||
dst = self.fs.ftp2fs(basedir, datacr)
|
||||
self.run_as_current_user(self.fs.rename, src, dst,basename)
|
||||
except OSError, err:
|
||||
why = _strerror(err)
|
||||
self.log('FAIL RNFR/RNTO "%s ==> %s". %s.' \
|
||||
%(self.fs.ftpnorm(self.fs.rnfr), line, why))
|
||||
self.respond('550 %s.' %why)
|
||||
else:
|
||||
self.log('OK RNFR/RNTO "%s ==> %s".' \
|
||||
%(self.fs.ftpnorm(self.fs.rnfr), line))
|
||||
self.respond("250 Renaming ok.")
|
||||
datacr = self.get_crdata2(line,'create')
|
||||
oldname = self.fs.rnfr.path
|
||||
if isinstance(oldname, (list, tuple)):
|
||||
oldname = '/'.join(oldname)
|
||||
self.try_as_current_user(self.fs.rename, (self.fs.rnfr, datacr), line=line)
|
||||
self.fs.rnfr = None
|
||||
self.log('OK RNFR/RNTO "%s ==> %s".' % \
|
||||
(_to_unicode(oldname), _to_unicode(line)))
|
||||
self.respond("250 Renaming ok.")
|
||||
except FTPExceptionSent:
|
||||
pass
|
||||
finally:
|
||||
self.fs.rnfr = None
|
||||
self.fs.close_cr(datacr)
|
||||
|
@ -2789,9 +2790,9 @@ class FTPHandler(asynchat.async_chat):
|
|||
datacr = None
|
||||
try:
|
||||
datacr = self.fs.get_cr(line)
|
||||
iterator = self.run_as_current_user(self.fs.get_stat_dir, line, datacr)
|
||||
except OSError, err:
|
||||
self.respond('550 %s.' %_strerror(err))
|
||||
iterator = self.try_as_current_user(self.fs.get_stat_dir, (line, datacr), line=line)
|
||||
except FTPExceptionSent:
|
||||
pass
|
||||
else:
|
||||
self.push('213-Status of "%s":\r\n' %self.fs.ftpnorm(line))
|
||||
self.push_with_producer(BufferedIteratorProducer(iterator))
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
-
|
||||
In order to test the document_ftp functionality
|
||||
-
|
||||
I open the 8021 port and see for ftp presence there
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
ftp = te.get_plain_ftp(timeout=2.0)
|
||||
assert ftp.sock and (ftp.lastresp == '220'), ftp.lastresp
|
||||
-
|
||||
I read the list of databases at port 8021 and confirm our db is
|
||||
there
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
ftp = te.get_ftp_login(cr, uid, self)
|
||||
assert cr.dbname in ftp.nlst("/")
|
||||
-
|
||||
I try to locate the default "Documents" folder in the db.
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
ftp = te.get_ftp_login(cr, uid, self)
|
||||
ftp.cwd('Documents')
|
||||
-
|
||||
I create a "test.txt" file at the server (directly). The file
|
||||
should have the "abcd" content
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
from cStringIO import StringIO
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents')
|
||||
fdata = StringIO('abcd')
|
||||
ftp.storbinary('STOR test.txt', fdata)
|
||||
-
|
||||
I look for the "test.txt" file at the server
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents')
|
||||
assert ftp.nlst("test.txt") == ['test.txt']
|
||||
-
|
||||
I check that the content of "test.txt" is "abcd"
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
from cStringIO import StringIO
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents')
|
||||
assert te.get_ftp_fulldata(ftp, "test.txt") == 'abcd'
|
||||
-
|
||||
I append the string 'defgh' into "test.txt"
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
from cStringIO import StringIO
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents')
|
||||
fdata = StringIO('defgh')
|
||||
ftp.storbinary('APPE test.txt', fdata)
|
||||
-
|
||||
I check that the content of "text.txt" is 'abcddefgh'
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
from cStringIO import StringIO
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents')
|
||||
assert te.get_ftp_fulldata(ftp, "test.txt") == 'abcddefgh'
|
||||
-
|
||||
I try to cd into an non-existing folder 'Not-This'
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
import ftplib
|
||||
ftp = te.get_ftp_login(cr, uid, self)
|
||||
try:
|
||||
ftp.cwd('/Not-This')
|
||||
assert False, "We should't be able to change here"
|
||||
except ftplib.error_perm:
|
||||
pass
|
||||
except OSError, err:
|
||||
assert err.errno == 2, err.errno
|
||||
-
|
||||
I create a "test2.txt" file through FTP.
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
from cStringIO import StringIO
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents')
|
||||
fdata = StringIO('abcd')
|
||||
ftp.storbinary('STOR test2.txt', fdata)
|
||||
-
|
||||
I look for the "test2.txt" file at the server
|
||||
-
|
||||
!python {model: ir.attachment }: |
|
||||
ids = self.search(cr, uid, [('name', '=', 'test2.txt')])
|
||||
assert ids
|
||||
-
|
||||
I delete the "test2.txt" file using FTP.
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
from cStringIO import StringIO
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents')
|
||||
ftp.delete('test2.txt')
|
||||
-
|
||||
I check at the server that test2.txt is deleted
|
||||
-
|
||||
!python {model: ir.attachment }: |
|
||||
ids = self.search(cr, uid, [('name', '=', 'test2.txt')])
|
||||
assert not ids
|
||||
-
|
||||
I create a test2.txt file again.
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
from cStringIO import StringIO
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents')
|
||||
fdata = StringIO('abcd')
|
||||
ftp.storbinary('STOR test2.txt', fdata)
|
||||
-
|
||||
I delete the test2.txt from the server (RPC).
|
||||
-
|
||||
!delete { model: ir.attachment, id:, search: "[('name','=','test2.txt')]" }
|
||||
-
|
||||
I check through FTP that test2.txt does not appear.
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents')
|
||||
assert ftp.nlst("test2.txt") == []
|
||||
-
|
||||
I create a "test-name.txt" file
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
from cStringIO import StringIO
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents')
|
||||
fdata = StringIO('abcd')
|
||||
ftp.storbinary('STOR test-name.txt', fdata)
|
||||
-
|
||||
I rename the "test-name.txt" file through ftp.
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents')
|
||||
ftp.rename("test-name.txt", "test-renamed.txt")
|
||||
-
|
||||
I check that test-name.txt has been renamed.
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
from ftplib import error_perm
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents')
|
||||
try:
|
||||
res = ftp.nlst("test-name.txt")
|
||||
assert res == []
|
||||
except error_perm, e:
|
||||
pass
|
||||
assert ftp.nlst("test-renamed.txt") == ['test-renamed.txt']
|
||||
-
|
||||
I create a new folder 'Test-Folder2' through FTP
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents')
|
||||
ftp.mkd("Test-Folder2")
|
||||
-
|
||||
I create a file 'test3.txt' at the 'Test-Folder2'
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
from cStringIO import StringIO
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents/Test-Folder2')
|
||||
fdata = StringIO('abcd')
|
||||
ftp.storbinary('STOR test3.txt', fdata)
|
||||
-
|
||||
I try to retrieve test3.txt
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents/Test-Folder2')
|
||||
assert ftp.nlst("test3.txt") == ['test3.txt']
|
||||
-
|
||||
I create a new folder, 'Test-Folder3', through FTP
|
||||
I try to move test3.txt to 'Test-Folder3'
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents')
|
||||
ftp.mkd("Test-Folder2")
|
||||
# TODO move
|
||||
-
|
||||
I remove the 'Test-Folder3'
|
||||
-
|
||||
I check that test3.txt is removed.
|
||||
-
|
||||
I create 200 files through FTP
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
from cStringIO import StringIO
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents/Test-Folder2')
|
||||
fdata = StringIO('abcd')
|
||||
# TODO speed
|
||||
for i in range(0, 200):
|
||||
fdata.seek(0)
|
||||
ftp.storbinary('STOR test-name%s.txt' %i, fdata)
|
||||
-
|
||||
I list the 200 files, check speed
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents/Test-Folder2')
|
||||
# TODO speed
|
||||
assert len(ftp.nlst()) > 200
|
||||
-
|
||||
I read the 200 files, check speed
|
||||
# TODO
|
||||
-
|
||||
I move the 200 files to 'Test-Folder2'
|
||||
# TODO
|
|
@ -0,0 +1,82 @@
|
|||
-
|
||||
In order to check international character functionality
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
ftp = te.get_plain_ftp(timeout=1.0)
|
||||
-
|
||||
I create in the server a folder called 'Äïêéìáóôéêüò ÖÜêåëëïò'
|
||||
-
|
||||
!record {model: document.directory, id: dir_itests }:
|
||||
name: 'Äïêéìáóôéêüò ÖÜêåëëïò'
|
||||
parent_id: document.dir_root
|
||||
-
|
||||
And then I create another folder, under it, through FTP
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
cr.commit()
|
||||
from document_ftp import test_easyftp as te
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents/Äïêéìáóôéêüò ÖÜêåëëïò')
|
||||
ftp.mkd("ÖÜêåëëïò áðü êÜôù")
|
||||
-
|
||||
I check that this folder exists at the server
|
||||
-
|
||||
!assert {model: document.directory, id: , search: "[('name','=','ÖÜêåëëïò áðü êÜôù')]" }:
|
||||
- parent_id != False
|
||||
-
|
||||
I login with FTP and check that 'Äïêéìáóôéêüò ÖÜêåëëïò' is there
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents/Äïêéìáóôéêüò ÖÜêåëëïò/ÖÜêåëëïò áðü êÜôù')
|
||||
-
|
||||
I create a file named 'ÄïêéìÞ' into that folder
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
from cStringIO import StringIO
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents/Äïêéìáóôéêüò ÖÜêåëëïò/ÖÜêåëëïò áðü êÜôù')
|
||||
fdata = StringIO('êåßìåíï ìå utf-8')
|
||||
ftp.storbinary('STOR ÄïêéìÞ.txt', fdata)
|
||||
-
|
||||
I remove the 'ÄïêéìÞ.txt' file
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
from cStringIO import StringIO
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents/Äïêéìáóôéêüò ÖÜêåëëïò/ÖÜêåëëïò áðü êÜôù')
|
||||
ftp.delete('ÄïêéìÞ.txt')
|
||||
-
|
||||
I rename 'ÖÜêåëëïò áðü êÜôù' into 'Üëëïò'
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents/Äïêéìáóôéêüò ÖÜêåëëïò')
|
||||
ftp.rename("ÖÜêåëëïò áðü êÜôù", "Üëëïò")
|
||||
-
|
||||
I place a file 'file Ö3' in 'Üëëïò'
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
from cStringIO import StringIO
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents/Äïêéìáóôéêüò ÖÜêåëëïò/Üëëïò')
|
||||
fdata = StringIO('êé Üëëï êåßìåíï')
|
||||
ftp.storbinary('STOR file Ö3.txt', fdata)
|
||||
-
|
||||
I rename the file into file+range(1..200) (large filename)
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
from cStringIO import StringIO
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents/Äïêéìáóôéêüò ÖÜêåëëïò/Üëëïò')
|
||||
vuvuzela = 'b'+''.join('z' * 200)+'!'
|
||||
ftp.rename("file Ö3.txt", vuvuzela)
|
||||
-
|
||||
I delete the file with the large name
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
from cStringIO import StringIO
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents/Äïêéìáóôéêüò ÖÜêåëëïò/Üëëïò')
|
||||
vuvuzela = 'b'+''.join('z' * 200)+'!'
|
||||
ftp.delete(vuvuzela)
|
|
@ -0,0 +1,120 @@
|
|||
-
|
||||
In order to check dynamic folder functionality of document + FTP
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
ftp = te.get_plain_ftp(timeout=1.0)
|
||||
- |
|
||||
I create two partners 'Partner1' and 'Partner2'.
|
||||
I create three partner categories: 'none', 'pat1' and 'all'
|
||||
I attach Partner1 to pat1, Partner1+Partner2 to 'all'
|
||||
-
|
||||
!record {model: res.partner.category, id: tpat_categ_none }:
|
||||
name: 'No partners'
|
||||
-
|
||||
!record {model: res.partner.category, id: tpat_categ_pat1 }:
|
||||
name: 'Pat 1'
|
||||
-
|
||||
!record {model: res.partner.category, id: tpat_categ_all }:
|
||||
name: 'All Partner1+2'
|
||||
-
|
||||
!record {model: res.partner, id: tpartner1 }:
|
||||
name: Partner 1
|
||||
category_id:
|
||||
- tpat_categ_pat1
|
||||
- tpat_categ_all
|
||||
-
|
||||
!record {model: res.partner, id: tpartner_2 }:
|
||||
name: 'Partner 2'
|
||||
category_id:
|
||||
- tpat_categ_all
|
||||
-
|
||||
I create a resource folder of partners, by the (none, pat1, all)
|
||||
categories.
|
||||
-
|
||||
!record {model: document.directory, id: dir_tests2 }:
|
||||
name: Partners Testing
|
||||
parent_id: document.dir_root
|
||||
type: ressource
|
||||
ressource_type_id: base.model_res_partner_category
|
||||
domain: [] # TODO
|
||||
-
|
||||
I commit (because FTP operations are on different transaction)
|
||||
-
|
||||
!python {model: document.directory, id: }: |
|
||||
cr.commit()
|
||||
-
|
||||
I browse through ftp in the resource folder, checking that three
|
||||
categories are there.
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents/Partners Testing')
|
||||
dirs = ftp.nlst()
|
||||
for dir in [ 'All Partner1+2', 'No partners', 'Pat 1' ]:
|
||||
assert dir in dirs, "Dir %s not in folder" % dir
|
||||
-
|
||||
I create a 'partners' folder by the first resource one.
|
||||
-
|
||||
!record {model: document.directory, id: dir_respart1 }:
|
||||
name: Partners of Test
|
||||
parent_id: dir_tests2
|
||||
type: ressource
|
||||
ressource_type_id: base.model_res_partner
|
||||
domain: "[('category_id','in',[active_id])]"
|
||||
ressource_parent_type_id : base.model_res_partner_category
|
||||
-
|
||||
!python {model: document.directory, id: }: |
|
||||
cr.commit()
|
||||
-
|
||||
I check through FTP that the correct partners are listed at each
|
||||
'partners' folder.
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents/Partners Testing')
|
||||
correct = { 'All Partner1+2': [ 'Partner 1', 'Partner 2' ],
|
||||
'No partners': [],
|
||||
'Pat 1': ['Partner 1',] }
|
||||
for dir in correct:
|
||||
res = ftp.nlst(dir+'/Partners of Test')
|
||||
assert res == correct[dir], "Dir %s falsely contains %s" %(dir, res)
|
||||
-
|
||||
I create an ir.attachment, attached (not related) to Partner1
|
||||
-
|
||||
!record {model: ir.attachment, id: file_test1 }:
|
||||
name: File of pat1
|
||||
res_model: res.partner
|
||||
res_id: !eval ref("tpartner1")
|
||||
-
|
||||
I check that pat1/Partner1 folder has the file.
|
||||
I check that all/Partner1 folder has the file
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents/Partners Testing')
|
||||
dirs = [ 'All Partner1+2', 'Pat 1' ]
|
||||
for dir in dirs:
|
||||
res = ftp.nlst(dir+'/Partners of Test/Partner 1')
|
||||
assert 'File of pat1' in res, "Dir %s contains only %s" %(dir, res)
|
||||
-
|
||||
I place a file at the 'pat1'/Partner1 folder, through FTP
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
from document_ftp import test_easyftp as te
|
||||
from cStringIO import StringIO
|
||||
ftp = te.get_ftp_folder(cr, uid, self, 'Documents/Partners Testing/Pat 1/Partners of Test/Partner 1')
|
||||
fdata = StringIO('abcd')
|
||||
ftp.storbinary('STOR pat1-dynamic.txt', fdata)
|
||||
-
|
||||
I check at the server that the file is attached to Partner1
|
||||
-
|
||||
!assert {model: ir.attachment, id: , search: "[('name','=','pat1-dynamic.txt')]" }:
|
||||
- parent_id.name == 'Partners of Test'
|
||||
- res_model == 'res.partner'
|
||||
- res_id != False
|
||||
-
|
||||
I check that all/Partner1 also has the file
|
||||
- |
|
||||
Bonus Piste:
|
||||
I create a 'Partner3' under 'all'
|
|
@ -0,0 +1,66 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
""" This is a testing module, which exports some functions for the YAML tests.
|
||||
Instead of repeating the same FTP code all over, we prefer to have
|
||||
it in this file
|
||||
"""
|
||||
|
||||
from ftplib import FTP
|
||||
from tools.misc import detect_ip_addr
|
||||
from tools import config
|
||||
|
||||
def get_plain_ftp(timeout=10.0):
|
||||
ftp = FTP()
|
||||
host = config.get('ftp_server_host', '127.0.0.1')
|
||||
port = config.get('ftp_server_port','8021')
|
||||
ftp.connect(host,port, timeout=timeout)
|
||||
return ftp
|
||||
|
||||
def get_ftp_login(cr, uid, ormobj):
|
||||
ftp = get_plain_ftp()
|
||||
user = ormobj.pool.get('res.users').read(cr, uid, uid)
|
||||
ftp.login(user.get('login',''),user.get('password',''))
|
||||
ftp.cwd("/" + cr.dbname)
|
||||
return ftp
|
||||
|
||||
def get_ftp_anonymous(cr):
|
||||
ftp = get_plain_ftp()
|
||||
ftp.login('anonymous', 'the-test')
|
||||
ftp.cwd("/")
|
||||
return ftp
|
||||
|
||||
def get_ftp_folder(cr, uid, ormobj, foldername):
|
||||
ftp = get_ftp_login(cr, uid, ormobj)
|
||||
ftp.cwd("/" + cr.dbname+"/"+foldername)
|
||||
return ftp
|
||||
|
||||
def get_ftp_fulldata(ftp, fname, limit=8192):
|
||||
from functools import partial
|
||||
data = []
|
||||
def ffp(data, ndata):
|
||||
if len(data)+ len(ndata) > limit:
|
||||
raise IndexError('Data over the limit')
|
||||
data.append(ndata)
|
||||
ftp.retrbinary('RETR %s' % fname, partial(ffp,data))
|
||||
return ''.join(data)
|
||||
|
||||
#eof
|
|
@ -7,25 +7,25 @@ msgstr ""
|
|||
"Project-Id-Version: OpenERP Server 5.0.6\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
|
||||
"PO-Revision-Date: 2010-03-20 08:19+0000\n"
|
||||
"PO-Revision-Date: 2010-07-20 07:47+0000\n"
|
||||
"Last-Translator: Black Jack <onetimespeed@hotmail.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: 2010-06-22 04:17+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-07-21 03:43+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: document_ics
|
||||
#: constraint:ir.model:0
|
||||
msgid ""
|
||||
"The Object name must start with x_ and not contain any special character !"
|
||||
msgstr "对象名必须要以X_开头并且不能含有特殊字符!"
|
||||
msgstr "对象名称必须以“x_”开头且不能包含任何特殊字符!"
|
||||
|
||||
#. module: document_ics
|
||||
#: selection:document.directory.ics.fields,name:0
|
||||
msgid "uid"
|
||||
msgstr "用户标识符"
|
||||
msgstr "用户ID"
|
||||
|
||||
#. module: document_ics
|
||||
#: constraint:document.directory:0
|
||||
|
@ -35,17 +35,17 @@ msgstr "错误:你无法建立递归的目录"
|
|||
#. module: document_ics
|
||||
#: field:document.ics.crm.wizard,jobs:0
|
||||
msgid "Jobs Hiring Process"
|
||||
msgstr "招聘过程"
|
||||
msgstr "招聘流程"
|
||||
|
||||
#. module: document_ics
|
||||
#: view:document.ics.crm.wizard:0
|
||||
msgid "Configure Calendars for CRM Sections"
|
||||
msgstr "客户关系管理部分设置日程表"
|
||||
msgstr "设置crm的日程表"
|
||||
|
||||
#. module: document_ics
|
||||
#: field:document.ics.crm.wizard,helpdesk:0
|
||||
msgid "Helpdesk"
|
||||
msgstr "求助"
|
||||
msgstr "帮助平台"
|
||||
|
||||
#. module: document_ics
|
||||
#: field:document.directory.ics.fields,field_id:0
|
||||
|
@ -55,7 +55,7 @@ msgstr "系统字段"
|
|||
#. module: document_ics
|
||||
#: view:document.ics.crm.wizard:0
|
||||
msgid "Next"
|
||||
msgstr "下一个"
|
||||
msgstr "下一步"
|
||||
|
||||
#. module: document_ics
|
||||
#: field:document.directory.ics.fields,content_id:0
|
||||
|
@ -80,7 +80,7 @@ msgstr "信息地址(url)"
|
|||
#. module: document_ics
|
||||
#: constraint:ir.actions.act_window:0
|
||||
msgid "Invalid model name in the action definition."
|
||||
msgstr "在这动作定义中有无效的模块名"
|
||||
msgstr "在动作定义中使用了无效的模快名。"
|
||||
|
||||
#. module: document_ics
|
||||
#: help:document.ics.crm.wizard,bugs:0
|
||||
|
@ -92,7 +92,7 @@ msgstr "公司用于跟踪缺陷和支持请求的软件"
|
|||
msgid ""
|
||||
"This Configuration step use to create Calendars in document for all Case "
|
||||
"Sections"
|
||||
msgstr "这设置步骤用于创建在所有业务个案项文档的日程表"
|
||||
msgstr "这设置步骤用于创建所有划分的业务个案的日程表"
|
||||
|
||||
#. module: document_ics
|
||||
#: selection:document.directory.ics.fields,name:0
|
||||
|
@ -114,28 +114,28 @@ msgstr "说明"
|
|||
#. module: document_ics
|
||||
#: model:ir.actions.act_window,name:document_ics.action_view_document_ics_config_directories
|
||||
msgid "Configure Calendars for Sections "
|
||||
msgstr "部分设置日程表 "
|
||||
msgstr "设置划分的业务个案的日程表 "
|
||||
|
||||
#. module: document_ics
|
||||
#: help:document.ics.crm.wizard,opportunity:0
|
||||
msgid "Tracks identified business opportunities for your sales pipeline."
|
||||
msgstr "从你的销售管线跟踪出销售机会"
|
||||
msgstr "从你的销售渠道跟踪出销售机会"
|
||||
|
||||
#. module: document_ics
|
||||
#: help:document.ics.crm.wizard,fund:0
|
||||
msgid ""
|
||||
"This may help associations in their fund raising process and tracking."
|
||||
msgstr "这可能有助于协会在资助和投资过程和跟踪"
|
||||
msgstr "这也许有助于协会筹款的进程和跟踪"
|
||||
|
||||
#. module: document_ics
|
||||
#: help:document.ics.crm.wizard,helpdesk:0
|
||||
msgid "Manages an Helpdesk service."
|
||||
msgstr "管理求助服务"
|
||||
msgstr "管理帮助平台服务"
|
||||
|
||||
#. module: document_ics
|
||||
#: field:document.ics.crm.wizard,fund:0
|
||||
msgid "Fund Raising Operations"
|
||||
msgstr "资助和投资行动"
|
||||
msgstr "筹款运作"
|
||||
|
||||
#. module: document_ics
|
||||
#: field:document.directory.content,ics_object_id:0
|
||||
|
@ -145,17 +145,17 @@ msgstr "对象"
|
|||
#. module: document_ics
|
||||
#: constraint:crm.case.section:0
|
||||
msgid "Error ! You cannot create recursive sections."
|
||||
msgstr "错误!你不能创建递归的项"
|
||||
msgstr "错误!你不能创建递归的细项"
|
||||
|
||||
#. module: document_ics
|
||||
#: model:ir.module.module,shortdesc:document_ics.module_meta_information
|
||||
msgid "Support for iCal based on Document Management System"
|
||||
msgstr "支持iCal的文档管理系统"
|
||||
msgstr "文档管理系统支持iCal"
|
||||
|
||||
#. module: document_ics
|
||||
#: selection:document.directory.ics.fields,name:0
|
||||
msgid "location"
|
||||
msgstr "本地"
|
||||
msgstr "位置"
|
||||
|
||||
#. module: document_ics
|
||||
#: view:document.directory:0
|
||||
|
@ -175,14 +175,14 @@ msgstr "允许的同步其它应用日程表"
|
|||
#. module: document_ics
|
||||
#: constraint:ir.ui.view:0
|
||||
msgid "Invalid XML for View Architecture!"
|
||||
msgstr "无效XML视图结构!"
|
||||
msgstr "无效的视图结构xml文件!"
|
||||
|
||||
#. module: document_ics
|
||||
#: help:document.ics.crm.wizard,lead:0
|
||||
msgid ""
|
||||
"Allows you to track and manage prospects which are pre-sales requests or "
|
||||
"contacts, the very first contact with a customer request."
|
||||
msgstr "允许你跟踪管理潜在客户的售前请求和联系,初次联系客户的请求"
|
||||
msgstr "允许你在响应潜在客户的售前请求和联系时跟踪管理, 首次联系客户的请求"
|
||||
|
||||
#. module: document_ics
|
||||
#: field:document.ics.crm.wizard,name:0
|
||||
|
@ -197,14 +197,14 @@ msgstr "管理用户的会议日程表"
|
|||
#. module: document_ics
|
||||
#: field:document.directory.content,ics_domain:0
|
||||
msgid "Domain"
|
||||
msgstr "隶属"
|
||||
msgstr "域"
|
||||
|
||||
#. module: document_ics
|
||||
#: help:document.ics.crm.wizard,claims:0
|
||||
msgid ""
|
||||
"Manages the supplier and customers claims, including your corrective or "
|
||||
"preventive actions."
|
||||
msgstr "管理这支援和客户服务要求包括你的纠正或预防"
|
||||
msgstr "管理客户和供应商的索赔, 包括您的纠正或预防措施"
|
||||
|
||||
#. module: document_ics
|
||||
#: selection:document.directory.ics.fields,name:0
|
||||
|
@ -229,7 +229,7 @@ msgstr "共享的日程表"
|
|||
#. module: document_ics
|
||||
#: field:document.ics.crm.wizard,claims:0
|
||||
msgid "Claims"
|
||||
msgstr "服务要求"
|
||||
msgstr "索赔"
|
||||
|
||||
#. module: document_ics
|
||||
#: help:document.ics.crm.wizard,phonecall:0
|
||||
|
@ -271,7 +271,7 @@ msgstr "创建预先设置的日程表"
|
|||
#. module: document_ics
|
||||
#: selection:document.directory.ics.fields,name:0
|
||||
msgid "created"
|
||||
msgstr "创建"
|
||||
msgstr "已创建"
|
||||
|
||||
#. module: document_ics
|
||||
#: field:crm.case,code:0
|
||||
|
@ -281,7 +281,7 @@ msgstr "日程表代码"
|
|||
#. module: document_ics
|
||||
#: selection:document.directory.ics.fields,name:0
|
||||
msgid "summary"
|
||||
msgstr "参考"
|
||||
msgstr "摘要"
|
||||
|
||||
#. module: document_ics
|
||||
#: model:ir.model,name:document_ics.model_document_ics_crm_wizard
|
||||
|
@ -296,7 +296,7 @@ msgstr "出勤者"
|
|||
#. module: document_ics
|
||||
#: model:ir.model,name:document_ics.model_document_directory_ics_fields
|
||||
msgid "document.directory.ics.fields"
|
||||
msgstr "字段"
|
||||
msgstr ""
|
||||
|
||||
#. module: document_ics
|
||||
#: field:document.directory.content,ics_field_ids:0
|
||||
|
@ -311,7 +311,7 @@ msgstr "取消"
|
|||
#. module: document_ics
|
||||
#: field:document.ics.crm.wizard,opportunity:0
|
||||
msgid "Business Opportunities"
|
||||
msgstr "销售机会"
|
||||
msgstr "商机"
|
||||
|
||||
#. module: document_ics
|
||||
#: selection:document.directory.ics.fields,name:0
|
||||
|
|
|
@ -46,6 +46,15 @@ CACHE_SIZE=20000
|
|||
urlparse.uses_netloc.append('webdav')
|
||||
urlparse.uses_netloc.append('webdavs')
|
||||
|
||||
class DAV_NotFound2(DAV_NotFound):
|
||||
"""404 exception, that accepts our list uris
|
||||
"""
|
||||
def __init__(self, *args):
|
||||
if len(args) and isinstance(args[0], (tuple, list)):
|
||||
path = ''.join([ '/' + x for x in args[0]])
|
||||
args = (path, )
|
||||
DAV_NotFound.__init__(self, *args)
|
||||
|
||||
class openerp_dav_handler(dav_interface):
|
||||
"""
|
||||
This class models a OpenERP interface for the DAV server
|
||||
|
@ -74,6 +83,38 @@ class openerp_dav_handler(dav_interface):
|
|||
cr.close()
|
||||
return props
|
||||
|
||||
def _try_function(self, funct, args, opname='run function', cr=None,
|
||||
default_exc=DAV_Forbidden):
|
||||
""" Try to run a function, and properly convert exceptions to DAV ones.
|
||||
|
||||
@objname the name of the operation being performed
|
||||
@param cr if given, the cursor to close at exceptions
|
||||
"""
|
||||
|
||||
try:
|
||||
funct(*args)
|
||||
except DAV_Error:
|
||||
if cr: cr.close()
|
||||
raise
|
||||
except NotImplementedError, e:
|
||||
if cr: cr.close()
|
||||
import traceback
|
||||
self.parent.log_error("Cannot %s: %s", opname, str(e))
|
||||
self.parent.log_message("Exc: %s",traceback.format_exc())
|
||||
# see par 9.3.1 of rfc
|
||||
raise DAV_Error(403, str(e) or 'Not supported at this path')
|
||||
except EnvironmentError, err:
|
||||
if cr: cr.close()
|
||||
import traceback
|
||||
self.parent.log_error("Cannot %s: %s", opname, err.strerror)
|
||||
self.parent.log_message("Exc: %s",traceback.format_exc())
|
||||
raise default_exc(err.strerror)
|
||||
except Exception,e:
|
||||
import traceback
|
||||
self.parent.log_error("Cannot create %s: %s", opname, str(e))
|
||||
self.parent.log_message("Exc: %s",traceback.format_exc())
|
||||
raise default_exc("Operation failed")
|
||||
|
||||
def _get_dav_lockdiscovery(self, uri):
|
||||
raise DAV_NotFound
|
||||
|
||||
|
@ -192,7 +233,7 @@ class openerp_dav_handler(dav_interface):
|
|||
|
||||
if not node:
|
||||
if cr: cr.close()
|
||||
raise DAV_NotFound(uri2)
|
||||
raise DAV_NotFound2(uri2)
|
||||
else:
|
||||
fp = node.full_path()
|
||||
if fp and len(fp):
|
||||
|
@ -255,26 +296,25 @@ class openerp_dav_handler(dav_interface):
|
|||
raise DAV_Error, 409
|
||||
node = self.uri2object(cr, uid, pool, uri2)
|
||||
if not node:
|
||||
raise DAV_NotFound(uri2)
|
||||
raise DAV_NotFound2(uri2)
|
||||
try:
|
||||
if rrange:
|
||||
self.parent.log_error("Doc get_data cannot use range")
|
||||
raise DAV_Error(409)
|
||||
datas = node.get_data(cr)
|
||||
except TypeError,e:
|
||||
import traceback
|
||||
self.parent.log_error("GET typeError: %s", str(e))
|
||||
self.parent.log_message("Exc: %s",traceback.format_exc())
|
||||
raise DAV_Forbidden
|
||||
# for the collections that return this error, the DAV standard
|
||||
# says we'd better just return 200 OK with empty data
|
||||
return ''
|
||||
except IndexError,e :
|
||||
self.parent.log_error("GET IndexError: %s", str(e))
|
||||
raise DAV_NotFound(uri2)
|
||||
raise DAV_NotFound2(uri2)
|
||||
except Exception,e:
|
||||
import traceback
|
||||
self.parent.log_error("GET exception: %s",str(e))
|
||||
self.parent.log_message("Exc: %s", traceback.format_exc())
|
||||
raise DAV_Error, 409
|
||||
return datas
|
||||
return str(datas) # FIXME!
|
||||
finally:
|
||||
if cr: cr.close()
|
||||
|
||||
|
@ -288,7 +328,7 @@ class openerp_dav_handler(dav_interface):
|
|||
return COLLECTION
|
||||
node = self.uri2object(cr,uid,pool, uri2)
|
||||
if not node:
|
||||
raise DAV_NotFound(uri2)
|
||||
raise DAV_NotFound2(uri2)
|
||||
if node.type in ('collection','database'):
|
||||
return COLLECTION
|
||||
return OBJECT
|
||||
|
@ -304,7 +344,7 @@ class openerp_dav_handler(dav_interface):
|
|||
node = self.uri2object(cr, uid, pool, uri2)
|
||||
if not node:
|
||||
cr.close()
|
||||
raise DAV_NotFound(uri2)
|
||||
raise DAV_NotFound2(uri2)
|
||||
cr.close()
|
||||
return node.displayname
|
||||
|
||||
|
@ -320,7 +360,7 @@ class openerp_dav_handler(dav_interface):
|
|||
node = self.uri2object(cr, uid, pool, uri2)
|
||||
if not node:
|
||||
cr.close()
|
||||
raise DAV_NotFound(uri2)
|
||||
raise DAV_NotFound2(uri2)
|
||||
result = node.content_length or 0
|
||||
cr.close()
|
||||
return str(result)
|
||||
|
@ -337,7 +377,7 @@ class openerp_dav_handler(dav_interface):
|
|||
node = self.uri2object(cr, uid, pool, uri2)
|
||||
if not node:
|
||||
cr.close()
|
||||
raise DAV_NotFound(uri2)
|
||||
raise DAV_NotFound2(uri2)
|
||||
result = node.get_etag(cr)
|
||||
cr.close()
|
||||
return str(result)
|
||||
|
@ -352,7 +392,7 @@ class openerp_dav_handler(dav_interface):
|
|||
try:
|
||||
node = self.uri2object(cr, uid, pool, uri2)
|
||||
if not node:
|
||||
raise DAV_NotFound(uri2)
|
||||
raise DAV_NotFound2(uri2)
|
||||
if node.write_date:
|
||||
return time.mktime(time.strptime(node.write_date,'%Y-%m-%d %H:%M:%S'))
|
||||
else:
|
||||
|
@ -369,7 +409,7 @@ class openerp_dav_handler(dav_interface):
|
|||
try:
|
||||
node = self.uri2object(cr, uid, pool, uri2)
|
||||
if not node:
|
||||
raise DAV_NotFound(uri2)
|
||||
raise DAV_NotFound2(uri2)
|
||||
if node.create_date:
|
||||
result = time.mktime(time.strptime(node.create_date,'%Y-%m-%d %H:%M:%S'))
|
||||
else:
|
||||
|
@ -387,7 +427,7 @@ class openerp_dav_handler(dav_interface):
|
|||
try:
|
||||
node = self.uri2object(cr, uid, pool, uri2)
|
||||
if not node:
|
||||
raise DAV_NotFound(uri2)
|
||||
raise DAV_NotFound2(uri2)
|
||||
result = str(node.mimetype)
|
||||
return result
|
||||
#raise DAV_NotFound, 'Could not find %s' % path
|
||||
|
@ -395,20 +435,28 @@ class openerp_dav_handler(dav_interface):
|
|||
if cr: cr.close()
|
||||
|
||||
def mkcol(self,uri):
|
||||
""" create a new collection """
|
||||
""" create a new collection
|
||||
see par. 9.3 of rfc4918
|
||||
"""
|
||||
self.parent.log_message('MKCOL: %s' % uri)
|
||||
uri = self.uri2local(uri)[1:]
|
||||
if uri[-1]=='/':uri=uri[:-1]
|
||||
parent = '/'.join(uri.split('/')[:-1])
|
||||
parent = self.baseuri + parent
|
||||
uri = self.baseuri + uri
|
||||
cr, uid, pool,dbname, uri2 = self.get_cr(uri)
|
||||
cr, uid, pool, dbname, uri2 = self.get_cr(uri)
|
||||
if not uri2[-1]:
|
||||
cr.close()
|
||||
raise DAV_Error(409, "Cannot create nameless collection")
|
||||
if not dbname:
|
||||
cr.close()
|
||||
raise DAV_Error, 409
|
||||
node = self.uri2object(cr,uid,pool, uri2[:-1])
|
||||
if node:
|
||||
node.create_child_collection(cr, uri2[-1])
|
||||
cr.commit()
|
||||
if not node:
|
||||
cr.close()
|
||||
raise DAV_Error(409, "Parent path %s does not exist" % uri2[:-1])
|
||||
nc = node.child(cr, uri2[-1])
|
||||
if nc:
|
||||
cr.close()
|
||||
raise DAV_Error(405, "Path already exists")
|
||||
self._try_function(node.create_child_collection, (cr, uri2[-1]),
|
||||
"create col %s" % uri2[-1], cr=cr)
|
||||
cr.commit()
|
||||
cr.close()
|
||||
return True
|
||||
|
||||
|
@ -430,22 +478,13 @@ class openerp_dav_handler(dav_interface):
|
|||
if not node:
|
||||
dir_node = self.uri2object(cr, uid, pool, uri2[:-1])
|
||||
if not dir_node:
|
||||
cr.close()
|
||||
raise DAV_NotFound('Parent folder not found')
|
||||
try:
|
||||
dir_node.create_child(cr, objname, data)
|
||||
except Exception,e:
|
||||
import traceback
|
||||
self.parent.log_error("Cannot create %s: %s", objname, str(e))
|
||||
self.parent.log_message("Exc: %s",traceback.format_exc())
|
||||
raise DAV_Forbidden
|
||||
|
||||
self._try_function(dir_node.create_child, (cr, objname, data),
|
||||
"create %s" % objname, cr=cr)
|
||||
else:
|
||||
try:
|
||||
node.set_data(cr, data)
|
||||
except Exception,e:
|
||||
import traceback
|
||||
self.parent.log_error("Cannot save %s: %s", objname, str(e))
|
||||
self.parent.log_message("Exc: %s",traceback.format_exc())
|
||||
raise DAV_Forbidden
|
||||
self._try_function(node.set_data, (cr, data), "save %s" % objname, cr=cr)
|
||||
|
||||
cr.commit()
|
||||
cr.close()
|
||||
|
@ -618,7 +657,6 @@ class openerp_dav_handler(dav_interface):
|
|||
advanced systems we might also have to copy properties from
|
||||
the source to the destination.
|
||||
"""
|
||||
print " copy a collection."
|
||||
return self.mkcol(dst)
|
||||
|
||||
|
||||
|
|
|
@ -48,6 +48,8 @@ def mk_prop_response(self, uri, good_props, bad_props, doc):
|
|||
# write href information
|
||||
uparts=urlparse.urlparse(uri)
|
||||
fileloc=uparts[2]
|
||||
if isinstance(fileloc, unicode):
|
||||
fileloc = fileloc.encode('utf-8')
|
||||
href=doc.createElement("D:href")
|
||||
davpath = self._dataclass.parent.get_davpath()
|
||||
hurl = '%s://%s%s%s' % (uparts[0], uparts[1], davpath, urllib.quote(fileloc))
|
||||
|
@ -126,6 +128,8 @@ def mk_propname_response(self,uri,propnames,doc):
|
|||
# write href information
|
||||
uparts=urlparse.urlparse(uri)
|
||||
fileloc=uparts[2]
|
||||
if isinstance(fileloc, unicode):
|
||||
fileloc = fileloc.encode('utf-8')
|
||||
href=doc.createElement("D:href")
|
||||
davpath = self._dataclass.parent.get_davpath()
|
||||
hurl = '%s://%s%s%s' % (uparts[0], uparts[1], davpath, urllib.quote(fileloc))
|
||||
|
|
|
@ -78,6 +78,18 @@ class DAVHandler(FixSendError,DAVRequestHandler):
|
|||
self.baseuri = "http://%s:%d/"% (self.server.server_name, self.server.server_port)
|
||||
self.IFACE_CLASS = openerp_dav_handler(self, self.verbose)
|
||||
|
||||
def copymove(self, CLASS):
|
||||
""" Our uri scheme removes the /webdav/ component from there, so we
|
||||
need to mangle the header, too.
|
||||
"""
|
||||
dest = self.headers['Destination']
|
||||
up = urlparse.urlparse(urllib.unquote(self.headers['Destination']))
|
||||
if up.path.startswith(self.davpath):
|
||||
self.headers['Destination'] = up.path[len(self.davpath):]
|
||||
else:
|
||||
raise DAV_Forbidden("Not allowed to copy/move outside webdav path")
|
||||
DAVRequestHandler.copymove(self, CLASS)
|
||||
|
||||
def get_davpath(self):
|
||||
return self.davpath
|
||||
|
||||
|
@ -175,6 +187,11 @@ class DAVHandler(FixSendError,DAVRequestHandler):
|
|||
|
||||
self.send_body(None, '201', 'Created', '', headers=headers)
|
||||
|
||||
def do_DELETE(self):
|
||||
try:
|
||||
DAVRequestHandler.do_DELETE(self)
|
||||
except DAV_Error, (ec, dd):
|
||||
return self.send_status(ec)
|
||||
|
||||
from service.http_server import reg_http_service,OpenERPAuthProvider
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
<field name="model">email_template.account</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="SMTP Server">
|
||||
<tree colors="blue:state in ('draft');black:state in ('suspended','approved')" string="SMTP Server">
|
||||
<field name="name" select="2" />
|
||||
<field name="email_id" select="2" />
|
||||
<field name="smtpuname" select="2" />
|
||||
|
|
|
@ -84,7 +84,7 @@
|
|||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="board_associations_manager_form"/>
|
||||
</record>
|
||||
<menuitem id="board_associations" icon="terp-graph" name="Dashboard" parent="menu_report_event" sequence="0"/>
|
||||
<menuitem id="board_associations" icon="terp-graph" name="Dashboard" parent="base.menu_report_association" sequence="0"/>
|
||||
<menuitem
|
||||
name="Associations" parent="board_associations"
|
||||
action="open_board_associations_manager"
|
||||
|
|
|
@ -226,7 +226,7 @@ class event_event(osv.osv):
|
|||
'note': fields.text('Notes', help="Description or Summary of Event", readonly=False, states={'done': [('readonly', True)]}),
|
||||
'pricelist_id': fields.many2one('product.pricelist', 'Pricelist', readonly=True, states={'draft': [('readonly', False)]}, help="Pricelist version for current event."),
|
||||
'unit_price': fields.related('product_id', 'list_price', type='float', string='Registration Cost', readonly=True, states={'draft':[('readonly',False)]}, help="This will be the default price used as registration cost when invoicing this event. Note that you can specify for each registration a specific amount if you want to"),
|
||||
'main_speaker_id': fields.many2one('res.partner','Main Speaker', readonly=False, states={'done': [('readonly', True)]}),
|
||||
'main_speaker_id': fields.many2one('res.partner','Main Speaker', readonly=False, states={'done': [('readonly', True)]}, help="Speaker who are giving speech on event."),
|
||||
'speaker_ids':fields.many2many('res.partner', 'event_speaker_rel', 'speaker_id', 'partner_id', 'Other Speakers', readonly=False, states={'done': [('readonly', True)]}),
|
||||
'address_id': fields.many2one('res.partner.address','Location Address', readonly=False, states={'done': [('readonly', True)]}),
|
||||
'speaker_confirmed': fields.boolean('Speaker Confirmed', readonly=False, states={'done': [('readonly', True)]}),
|
||||
|
@ -285,7 +285,7 @@ class event_registration(osv.osv):
|
|||
"""Event Registration"""
|
||||
_name= 'event.registration'
|
||||
_description = __doc__
|
||||
_inherit = 'crm.meeting'
|
||||
_inherit = 'mailgate.thread'
|
||||
|
||||
def _amount_line(self, cr, uid, ids, field_name, arg, context=None):
|
||||
cur_obj = self.pool.get('res.currency')
|
||||
|
@ -303,6 +303,7 @@ class event_registration(osv.osv):
|
|||
'email_cc': fields.text('CC', size=252 , readonly=False, states={'done': [('readonly', True)]}, help="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"),
|
||||
'nb_register': fields.integer('Quantity', required=True, readonly=True, states={'draft': [('readonly', False)]}, help="Number of Registrations or Tickets"),
|
||||
'event_id': fields.many2one('event.event', 'Event Related', required=True, readonly=True, states={'draft': [('readonly', False)]}),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner', states={'done': [('readonly', True)]}),
|
||||
"partner_invoice_id": fields.many2one('res.partner', 'Partner Invoiced', readonly=True, states={'draft': [('readonly', False)]}),
|
||||
"contact_id": fields.many2one('res.partner.contact', 'Partner Contact', readonly=False, states={'done': [('readonly', True)]}), #TODO: filter only the contacts that have a function into the selected partner_id
|
||||
"unit_price": fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Event Price'), readonly=True, states={'draft': [('readonly', False)]}),
|
||||
|
@ -314,16 +315,30 @@ class event_registration(osv.osv):
|
|||
'date_closed': fields.datetime('Closed', readonly=True),
|
||||
'ref': fields.reference('Reference', selection=crm._links_get, size=128),
|
||||
'ref2': fields.reference('Reference 2', selection=crm._links_get, size=128),
|
||||
'email_from': fields.char('Email', size=128, states={'done': [('readonly', True)]}, help="These people will receive email."),
|
||||
'create_date': fields.datetime('Creation Date' , readonly=True),
|
||||
'write_date': fields.datetime('Write Date' , readonly=True),
|
||||
'description': fields.text('Description', states={'done': [('readonly', True)]}),
|
||||
'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
|
||||
'log_ids': fields.one2many('mailgate.message', 'res_id', 'Logs', domain=[('history', '=', False),('model','=',_name)]),
|
||||
'date_deadline': fields.related('event_id','date_end', type='datetime', string="End Date", readonly=True, store=True),
|
||||
'date': fields.related('event_id', 'date_begin', type='datetime', string="Start Date", readonly=True, store=True),
|
||||
'section_id': fields.related('event_id', 'section_id', type='many2one', relation='crm.case.section', string='Sale Team', store=True, readonly=True, states={'draft':[('readonly',False)]}),
|
||||
'date_deadline': fields.related('event_id','date_end', type='datetime', string="End Date", readonly=True),
|
||||
'date': fields.related('event_id', 'date_begin', type='datetime', string="Start Date", readonly=True),
|
||||
'user_id': fields.many2one('res.users', 'Responsible', states={'done': [('readonly', True)]}),
|
||||
'active': fields.boolean('Active'),
|
||||
'section_id': fields.related('event_id', 'section_id', type='many2one', relation='crm.case.section', string='Sale Team', store=True, readonly=True),
|
||||
'company_id': fields.related('event_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True, states={'draft':[('readonly',False)]}),
|
||||
'state': fields.selection([('open', 'Confirmed'),
|
||||
('draft', 'Unconfirmed'),
|
||||
('cancel', 'Cancelled'),
|
||||
('done', 'Done')], 'State', \
|
||||
size=16, readonly=True)
|
||||
}
|
||||
_defaults = {
|
||||
'nb_register': 1,
|
||||
'tobe_invoiced': True,
|
||||
'state': lambda *a: 'draft',
|
||||
'active': lambda *a: 1,
|
||||
'user_id': lambda self, cr, uid, ctx: uid,
|
||||
}
|
||||
|
||||
def _make_invoice(self, cr, uid, reg, lines, context=None):
|
||||
|
@ -353,7 +368,7 @@ class event_registration(osv.osv):
|
|||
})
|
||||
inv_id = inv_pool.create(cr, uid, val_invoice['value'])
|
||||
inv_pool.button_compute(cr, uid, [inv_id])
|
||||
self._history(cr, uid, [reg], _('Invoiced'))
|
||||
self.history(cr, uid, [reg], _('Invoiced'))
|
||||
return inv_id
|
||||
|
||||
def action_invoice_create(self, cr, uid, ids, grouped=False, date_inv = False, context=None):
|
||||
|
@ -422,7 +437,7 @@ class event_registration(osv.osv):
|
|||
"""
|
||||
res = self.write(cr, uid, ids, {'state': 'open'}, context=context)
|
||||
self.mail_user(cr, uid, ids)
|
||||
self._history(cr, uid, ids, _('Open'))
|
||||
self.history(cr, uid, ids, _('Open'))
|
||||
return res
|
||||
|
||||
def do_close(self, cr, uid, ids, context=None):
|
||||
|
@ -436,7 +451,7 @@ class event_registration(osv.osv):
|
|||
if invoice_id:
|
||||
values['invoice_id'] = invoice_id
|
||||
res = self.write(cr, uid, ids, values)
|
||||
self._history(cr, uid, ids, msg)
|
||||
self.history(cr, uid, ids, msg)
|
||||
return res
|
||||
|
||||
def check_confirm(self, cr, uid, ids, context=None):
|
||||
|
@ -509,7 +524,7 @@ class event_registration(osv.osv):
|
|||
"""This Function Cancel Event Registration.
|
||||
"""
|
||||
registrations = self.browse(cr, uid, ids)
|
||||
self._history(cr, uid, registrations, _('Cancel'))
|
||||
self.history(cr, uid, registrations, _('Cancel'))
|
||||
self.write(cr, uid, ids, {'state': 'cancel'})
|
||||
return True
|
||||
|
||||
|
@ -606,7 +621,9 @@ class event_registration(osv.osv):
|
|||
|
||||
data_event = event_obj.browse(cr, uid, event_id)
|
||||
res = {'value': {'unit_price': False, 'event_product': False, 'user_id': False,
|
||||
'date': data_event.date_begin, 'date_deadline': data_event.date_end, 'description': data_event.note, 'name': data_event.name}}
|
||||
'date': data_event.date_begin, 'date_deadline': data_event.date_end, 'description': data_event.note, 'name': data_event.name,
|
||||
'section_id': data_event.section_id and data_event.section_id.id or False,
|
||||
}}
|
||||
if data_event.user_id.id:
|
||||
res['value'].update({'user_id':data_event.user_id.id})
|
||||
if data_event.product_id:
|
||||
|
@ -615,6 +632,8 @@ class event_registration(osv.osv):
|
|||
partner = res_obj.browse(cr, uid, partner_invoice_id, context=context)
|
||||
pricelist_id = pricelist_id or partner.property_product_pricelist.id
|
||||
unit_price = prod_obj._product_price(cr, uid, [data_event.product_id.id], False, False, {'pricelist': pricelist_id})[data_event.product_id.id]
|
||||
if not unit_price:
|
||||
unit_price = data_event.unit_price
|
||||
res['value'].update({'unit_price': unit_price, 'event_product': data_event.product_id.name})
|
||||
return res
|
||||
|
||||
|
@ -675,7 +694,10 @@ class event_registration(osv.osv):
|
|||
if partner_invoice_id:
|
||||
partner = res_obj.browse(cr, uid, partner_invoice_id, context=context)
|
||||
pricelist_id = pricelist_id or partner.property_product_pricelist.id
|
||||
data['unit_price'] = prod_obj._product_price(cr, uid, [data_event.product_id.id], False, False, {'pricelist': pricelist_id})[data_event.product_id.id]
|
||||
unit_price = prod_obj._product_price(cr, uid, [data_event.product_id.id], False, False, {'pricelist': pricelist_id})[data_event.product_id.id]
|
||||
if not unit_price:
|
||||
unit_price = data_event.unit_price
|
||||
data['unit_price'] = unit_price
|
||||
return {'value': data}
|
||||
|
||||
event_registration()
|
||||
|
|
|
@ -131,21 +131,23 @@
|
|||
<page string="Mailing">
|
||||
<field name="reply_to" />
|
||||
<newline/>
|
||||
|
||||
<group col="3" colspan="2" expand="1">
|
||||
<separator string="Auto Registration Email" colspan="2"/>
|
||||
<newline/>
|
||||
<field name="mail_auto_registr"/>
|
||||
<separator string="Registration Email Body" colspan="2"/>
|
||||
<newline/>
|
||||
<field name="mail_registr" colspan="2" nolabel="1" attrs="{'readonly':[('mail_auto_registr','=',False)]}"/>
|
||||
</group>
|
||||
<group col="2" colspan="2" >
|
||||
<separator string="Auto Confirmation Email" colspan="2"/>
|
||||
<field name="mail_auto_confirm"/>
|
||||
<newline/>
|
||||
<separator string="Confirmation Email Body" colspan="2"/>
|
||||
<field name="mail_confirm" colspan="2" nolabel="1" attrs="{'readonly':[('mail_auto_confirm','=',False)]}"/>
|
||||
<group col="4" colspan="4">
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Auto Registration Email" colspan="4"/>
|
||||
<field name="mail_auto_registr" colspan="4"/>
|
||||
<group colspan="4" attrs="{'readonly':[('mail_auto_registr','=',False)]}">
|
||||
<separator string="Registration Email Body" colspan="4"/>
|
||||
<field name="mail_registr" colspan="4" nolabel="1" />
|
||||
</group>
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Auto Confirmation Email" colspan="4"/>
|
||||
<field name="mail_auto_confirm" colspan="4"/>
|
||||
<group colspan="4" attrs="{'readonly':[('mail_auto_confirm','=',False)]}">
|
||||
<separator string="Confirmation Email Body" colspan="4"/>
|
||||
<field name="mail_confirm" nolabel="1" colspan="4"/>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
|
@ -330,9 +332,8 @@
|
|||
</group>
|
||||
<separator string="Description" colspan="4"/>
|
||||
<field name="description" colspan="4" nolabel="1"/>
|
||||
<group col="8" colspan="4">
|
||||
<separator string="" colspan="4"/>
|
||||
<newline/>
|
||||
<separator string="" colspan="4"/>
|
||||
<group col="8" colspan="4">
|
||||
<field name="state" select="1" colspan="2"/>
|
||||
<button name="button_reg_close" string="Close Registration" states="open" type="object" icon="gtk-close"/>
|
||||
<button name="check_confirm" string="Confirm Registration" states="draft" type="object" icon="gtk-apply"/>
|
||||
|
@ -488,6 +489,6 @@
|
|||
name="Registrations"
|
||||
id="menu_action_registration" parent="menu_event_main"
|
||||
action="action_registration"/>
|
||||
<menuitem name="Reporting" id="menu_report_event" parent="base.menu_association" sequence="20"/>
|
||||
<menuitem name="Reporting" id="base.menu_report_association" parent="base.menu_association" sequence="20"/>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -7,13 +7,13 @@ msgstr ""
|
|||
"Project-Id-Version: OpenERP Server 5.0.6\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
|
||||
"PO-Revision-Date: 2010-03-20 08:22+0000\n"
|
||||
"PO-Revision-Date: 2010-07-20 08:56+0000\n"
|
||||
"Last-Translator: Black Jack <onetimespeed@hotmail.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: 2010-06-22 03:58+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-07-21 03:42+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: event
|
||||
|
@ -30,7 +30,7 @@ msgstr "最小记录"
|
|||
#. module: event
|
||||
#: constraint:ir.actions.act_window:0
|
||||
msgid "Invalid model name in the action definition."
|
||||
msgstr "在这动作定义中有无效的模块名"
|
||||
msgstr "在动作定义中使用了无效的模快名。"
|
||||
|
||||
#. module: event
|
||||
#: field:event.event,mail_registr:0
|
||||
|
@ -45,12 +45,12 @@ msgstr "Bon Jovi音乐会"
|
|||
#. module: event
|
||||
#: field:event.event,mail_confirm:0
|
||||
msgid "Confirmation Email"
|
||||
msgstr "确认邮件"
|
||||
msgstr "确认Email"
|
||||
|
||||
#. module: event
|
||||
#: constraint:crm.case.section:0
|
||||
msgid "Error ! You cannot create recursive sections."
|
||||
msgstr "错误!你不能创建递归的项"
|
||||
msgstr "错误! 你不能创建递归的部分"
|
||||
|
||||
#. module: event
|
||||
#: model:ir.model,name:event.model_event_registration
|
||||
|
@ -60,7 +60,7 @@ msgstr "事件记录"
|
|||
#. module: event
|
||||
#: model:ir.actions.wizard,name:event.event_reg_invoice
|
||||
msgid "Make Invoice"
|
||||
msgstr "创建发票"
|
||||
msgstr "生成发票"
|
||||
|
||||
#. module: event
|
||||
#: field:report.event.type.registration,draft_state:0
|
||||
|
@ -131,10 +131,13 @@ msgid ""
|
|||
" Events / Reporting\n"
|
||||
msgstr ""
|
||||
"组织和事件管理\n"
|
||||
"这模块允许你\n"
|
||||
"* 管理你的事务\n"
|
||||
"* 使用电子邮件自动确认和发送致谢到登记的每个事务\n"
|
||||
" 这模块允许你\n"
|
||||
" * 管理你的事务和它的记录\n"
|
||||
" * 使用电子邮件自动确认和发送确认登记的每个事务\n"
|
||||
"....\n"
|
||||
" 注意:\n"
|
||||
" - 你能在事件/ 设置/ 事件类型, 中定义新类型的事件\n"
|
||||
" - 你能在事件/ 报表, 中访问到与定义的报表\n"
|
||||
|
||||
#. module: event
|
||||
#: view:event.registration:0
|
||||
|
@ -163,7 +166,7 @@ msgstr "事件"
|
|||
#. module: event
|
||||
#: selection:event.event,state:0
|
||||
msgid "Confirmed"
|
||||
msgstr "确认"
|
||||
msgstr "已确认"
|
||||
|
||||
#. module: event
|
||||
#: wizard_view:event.confirm_registration,split:0
|
||||
|
@ -195,12 +198,12 @@ msgstr "标志"
|
|||
#. module: event
|
||||
#: field:event.event,section_id:0
|
||||
msgid "Case section"
|
||||
msgstr "业务个案项"
|
||||
msgstr "划分的业务个案"
|
||||
|
||||
#. module: event
|
||||
#: field:event.registration,tobe_invoiced:0
|
||||
msgid "To be Invoiced"
|
||||
msgstr "开发票"
|
||||
msgstr "待开票"
|
||||
|
||||
#. module: event
|
||||
#: model:ir.ui.menu,name:event.menu_event_event
|
||||
|
@ -210,7 +213,7 @@ msgstr "所有事件"
|
|||
#. module: event
|
||||
#: model:ir.ui.menu,name:event.menu_report_event
|
||||
msgid "Reporting"
|
||||
msgstr "内部报表"
|
||||
msgstr "报表"
|
||||
|
||||
#. module: event
|
||||
#: view:event.registration:0
|
||||
|
@ -225,7 +228,7 @@ msgstr "事件分类"
|
|||
#. module: event
|
||||
#: wizard_view:event.confirm_registration,split:0
|
||||
msgid "The event limit is reached. What do you want to do?"
|
||||
msgstr "这事件到达限制.你想要怎么做?"
|
||||
msgstr "事件到达限制. 你想要怎么做?"
|
||||
|
||||
#. module: event
|
||||
#: field:report.event.type.registration,confirm_state:0
|
||||
|
@ -252,12 +255,12 @@ msgstr "设置"
|
|||
#. module: event
|
||||
#: constraint:ir.ui.view:0
|
||||
msgid "Invalid XML for View Architecture!"
|
||||
msgstr "无效XML视图结构!"
|
||||
msgstr "无效的视图结构xml文件!"
|
||||
|
||||
#. module: event
|
||||
#: wizard_button:event.confirm_registration,split,confirm:0
|
||||
msgid "Confirm Anyway"
|
||||
msgstr "无论如何确认"
|
||||
msgstr "总是确认"
|
||||
|
||||
#. module: event
|
||||
#: constraint:product.template:0
|
||||
|
@ -267,7 +270,7 @@ msgstr "错误:销售单位必须和计量单位在不同的分类."
|
|||
#. module: event
|
||||
#: view:event.event:0
|
||||
msgid "Parent Category"
|
||||
msgstr "业务伙伴分类"
|
||||
msgstr "上级分类"
|
||||
|
||||
#. module: event
|
||||
#: view:event.registration:0
|
||||
|
@ -287,7 +290,7 @@ msgstr "取消事件"
|
|||
#. module: event
|
||||
#: wizard_field:event.reg_make_invoice,init,inv_rej_reason:0
|
||||
msgid "Error Messages"
|
||||
msgstr "错误信息"
|
||||
msgstr "错误消息"
|
||||
|
||||
#. module: event
|
||||
#: view:event.event:0
|
||||
|
@ -297,7 +300,7 @@ msgstr "邮递"
|
|||
#. module: event
|
||||
#: model:product.template,name:event.event_product_0_product_template
|
||||
msgid "Ticket for Concert"
|
||||
msgstr "音乐会门票"
|
||||
msgstr "演唱会票"
|
||||
|
||||
#. module: event
|
||||
#: field:event.event,register_prospect:0
|
||||
|
@ -309,7 +312,7 @@ msgstr "不确认记录"
|
|||
#. module: event
|
||||
#: field:event.registration,partner_invoice_id:0
|
||||
msgid "Partner Invoiced"
|
||||
msgstr "业务伙伴发票"
|
||||
msgstr "已开票业务伙伴"
|
||||
|
||||
#. module: event
|
||||
#: view:event.registration:0
|
||||
|
@ -319,7 +322,7 @@ msgstr "沟通日志"
|
|||
#. module: event
|
||||
#: selection:event.event,state:0
|
||||
msgid "Canceled"
|
||||
msgstr "取消"
|
||||
msgstr "已取消"
|
||||
|
||||
#. module: event
|
||||
#: view:event.event:0
|
||||
|
@ -341,7 +344,7 @@ msgstr "记录的事件"
|
|||
#: constraint:product.template:0
|
||||
msgid ""
|
||||
"Error: The default UOM and the purchase UOM must be in the same category."
|
||||
msgstr "错误:默认的计量单位和这货物的计量单位必须是同一类型."
|
||||
msgstr "错误:默认的计量单位和采购的计量单位必须是同一类型."
|
||||
|
||||
#. module: event
|
||||
#: wizard_field:event.reg_make_invoice,init,inv_created:0
|
||||
|
@ -372,12 +375,12 @@ msgstr "记录的事件类型"
|
|||
#: constraint:ir.model:0
|
||||
msgid ""
|
||||
"The Object name must start with x_ and not contain any special character !"
|
||||
msgstr "对象名必须要以X_开头并且不能含有特殊字符!"
|
||||
msgstr "对象名称必须以“x_”开头且不能包含任何特殊字符!"
|
||||
|
||||
#. module: event
|
||||
#: field:event.registration,event_id:0
|
||||
msgid "Event Related"
|
||||
msgstr "有关事件"
|
||||
msgstr "关联的事件"
|
||||
|
||||
#. module: event
|
||||
#: model:crm.case.section,name:event.case_section_event
|
||||
|
@ -412,7 +415,7 @@ msgstr "所有记录"
|
|||
#: help:event.event,mail_auto_registr:0
|
||||
msgid ""
|
||||
"Check this box if you want to use the automatic mailing for new registration"
|
||||
msgstr "如果你使用自动邮递一个新记录"
|
||||
msgstr "勾选此项, 如果你使用自动邮递一个新记录"
|
||||
|
||||
#. module: event
|
||||
#: view:event.event:0
|
||||
|
@ -439,7 +442,7 @@ msgstr "事件类型"
|
|||
#. module: event
|
||||
#: field:event.registration,contact_id:0
|
||||
msgid "Partner Contact"
|
||||
msgstr "业务伙伴联系人"
|
||||
msgstr "业务伙伴联系方式"
|
||||
|
||||
#. module: event
|
||||
#: view:event.event:0
|
||||
|
@ -450,7 +453,7 @@ msgstr "自动确认邮件"
|
|||
#: view:event.event:0
|
||||
#: view:event.registration:0
|
||||
msgid "General"
|
||||
msgstr "一般"
|
||||
msgstr "通用"
|
||||
|
||||
#. module: event
|
||||
#: view:event.registration:0
|
||||
|
@ -507,7 +510,7 @@ msgstr "单价"
|
|||
#. module: event
|
||||
#: model:crm.case.section,name:event.event_2_crm_case_section
|
||||
msgid "Conference on ERP Buisness"
|
||||
msgstr "ERP Buisness会议"
|
||||
msgstr "商业会议"
|
||||
|
||||
#. module: event
|
||||
#: field:event.registration,badge_partner:0
|
||||
|
@ -534,7 +537,7 @@ msgstr "类型"
|
|||
#. module: event
|
||||
#: help:event.event,mail_registr:0
|
||||
msgid "This email will be sent when someone subscribes to the event."
|
||||
msgstr "有人赞同确认事件将发送这邮件"
|
||||
msgstr "有人赞同事件将发送这邮件"
|
||||
|
||||
#. module: event
|
||||
#: model:product.template,name:event.event_product_2_product_template
|
||||
|
@ -556,7 +559,7 @@ msgstr "名称"
|
|||
msgid ""
|
||||
"Check this box if you want ot use the automatic confirmation emailing or the "
|
||||
"reminder"
|
||||
msgstr "如果你使用自动邮件确认或提醒"
|
||||
msgstr "勾选此项, 如果你使用自动邮件确认或提醒"
|
||||
|
||||
#. module: event
|
||||
#: help:event.event,mail_confirm:0
|
||||
|
@ -564,7 +567,7 @@ msgid ""
|
|||
"This email will be sent when the event gets confimed or when someone "
|
||||
"subscribes to a confirmed event. This is also the email sent to remind "
|
||||
"someone about the event."
|
||||
msgstr "当有人确认这事件或赞同这确认时这邮件将被发送以提醒有关人等"
|
||||
msgstr "当有人确认这事件或赞同这确认事件时, 这邮件将发送以提醒有关人员"
|
||||
|
||||
#. module: event
|
||||
#: field:event.event,product_id:0
|
||||
|
@ -603,7 +606,7 @@ msgstr "事件草稿"
|
|||
#. module: event
|
||||
#: model:ir.ui.menu,name:event.menu_event_main
|
||||
msgid "Events Organisation"
|
||||
msgstr "事件系统"
|
||||
msgstr "事件组织"
|
||||
|
||||
#. module: event
|
||||
#: view:event.registration:0
|
||||
|
|
|
@ -51,6 +51,7 @@ class report_event_registration(osv.osv):
|
|||
initialize the sql view for the event registration
|
||||
cr -- the cursor
|
||||
"""
|
||||
tools.drop_view_if_exists(cr, 'report_event_registration')
|
||||
cr.execute("""
|
||||
create or replace view report_event_registration as (
|
||||
select
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<field name="model">report.event.registration</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Event on Registration">
|
||||
<tree colors="blue:state in ('draft');black:state in ('confirm','approved');gray:state in('done','cancel')" string="Event on Registration">
|
||||
<field name="date" invisible="1"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
<field name="speaker_id" invisible="1"/>
|
||||
|
@ -124,7 +124,7 @@
|
|||
</record>
|
||||
|
||||
<!--<menuitem parent="menu_report_event" action="action_event_registration" id="menu_report_event_registration"/>-->
|
||||
<menuitem parent="menu_report_event" action="action_report_event_registration" id="menu_report_event_registration" />
|
||||
<menuitem parent="base.menu_report_association" action="action_report_event_registration" id="menu_report_event_registration" />
|
||||
|
||||
<!-- end... -->
|
||||
</data>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<field name="project_id"/>
|
||||
<button string="Create Retro-Planning" name="%(action_event_project)d" type="action" icon="gtk-execute"/>
|
||||
<field name="task_ids" colspan="4" nolabel="1" widget="one2many_list" >
|
||||
<tree string="All tasks" colors="red:date_deadline<current_date and state=='draft';blue:date_deadline==current_date and state=='draft';grey:state in ('cancel','done');black:state not in ('cancel','done')">
|
||||
<tree string="All tasks" colors="red:date_deadline<current_date and state=='draft';blue:date_deadline==current_date and state=='draft';gray:state in ('cancel','done')">
|
||||
<field name="sequence"/>
|
||||
<field name="name"/>
|
||||
<field name="user_id" />
|
||||
|
@ -37,7 +37,7 @@
|
|||
src_model="event.event"
|
||||
view_mode="tree,form,calendar,graph"
|
||||
domain="[('project_id', '=', project_id)]"
|
||||
view_type="form"/>
|
||||
view_type="form"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -7,19 +7,19 @@ msgstr ""
|
|||
"Project-Id-Version: OpenERP Server 5.0.4\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
|
||||
"PO-Revision-Date: 2010-03-20 08:22+0000\n"
|
||||
"PO-Revision-Date: 2010-07-20 08:59+0000\n"
|
||||
"Last-Translator: Black Jack <onetimespeed@hotmail.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: 2010-06-22 04:17+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-07-21 03:43+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: event_project
|
||||
#: constraint:ir.ui.view:0
|
||||
msgid "Invalid XML for View Architecture!"
|
||||
msgstr "无效 View XML"
|
||||
msgstr "无效的视图结构xml文件!"
|
||||
|
||||
#. module: event_project
|
||||
#: model:ir.actions.wizard,name:event_project.wizard_event_task
|
||||
|
@ -29,7 +29,7 @@ msgstr "任务"
|
|||
#. module: event_project
|
||||
#: wizard_button:event.project,init,done:0
|
||||
msgid "Ok"
|
||||
msgstr ""
|
||||
msgstr "确定"
|
||||
|
||||
#. module: event_project
|
||||
#: model:ir.module.module,description:event_project.module_meta_information
|
||||
|
|
|
@ -27,7 +27,8 @@
|
|||
from osv import fields, osv
|
||||
from tools.translate import _
|
||||
import time
|
||||
|
||||
from datetime import date, datetime
|
||||
|
||||
class event_project(osv.osv_memory):
|
||||
"""
|
||||
Event Project
|
||||
|
@ -36,23 +37,46 @@ class event_project(osv.osv_memory):
|
|||
_description = "Event Project"
|
||||
|
||||
_columns = {
|
||||
'project_id': fields.many2one('project.project', 'Template of Project', domain = [('active', '<>', False), ('state', '=', 'template')], required =True, help="This is Template Project. Project of event is a duplicate of this Template. After click on 'Create Retro-planning', New Project will be duplicated from this template project.")
|
||||
'project_id': fields.many2one('project.project', 'Template of Project',
|
||||
domain = [('active', '<>', False), ('state', '=', 'template')],
|
||||
required =True,
|
||||
help="This is Template Project. Project of event is a duplicate of this Template. After click on 'Create Retro-planning', New Project will be duplicated from this template project."),
|
||||
'date_start': fields.date('Date Start'),
|
||||
'date': fields.date('Date End'),
|
||||
}
|
||||
|
||||
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
"""
|
||||
This function gets default values
|
||||
@param fields: List of fields for default value
|
||||
@param context: A standard dictionary for contextual values
|
||||
|
||||
@return : default values of fields.
|
||||
"""
|
||||
event_obj=self.pool.get('event.event')
|
||||
project_obj = self.pool.get('project.project')
|
||||
event = event_obj.browse(cr, uid, context.get('active_id', False))
|
||||
res = super(event_project, self).default_get(cr, uid, fields, context=context)
|
||||
if 'date_start' in fields:
|
||||
res.update({'date_start': time.strftime('%Y-%m-%d')})
|
||||
if 'date' in fields:
|
||||
res.update({'date': datetime.strptime(event.date_end, "%Y-%m-%d %H:%M:%S").strftime("%Y-%m-%d")})
|
||||
|
||||
return res
|
||||
|
||||
def create_duplicate(self, cr, uid, ids, context):
|
||||
event_obj=self.pool.get('event.event')
|
||||
project_obj = self.pool.get('project.project')
|
||||
event = event_obj.browse(cr, uid, context.get('active_id', False))
|
||||
for current in self.browse(cr, uid, ids):
|
||||
duplicate_project_id = project_obj.copy(cr, uid, current.project_id.id, {'active': True})
|
||||
duplicate_project = project_obj.browse(cr, uid, duplicate_project_id, context)
|
||||
project_obj.write(cr, uid, [duplicate_project_id], {
|
||||
'name': duplicate_project.name ,
|
||||
'date_start':time.strftime('%Y-%m-%d'),
|
||||
'date': event.date_begin[0:10] })
|
||||
for current in self.browse(cr, uid, ids):
|
||||
duplicate_project_id = project_obj.copy(cr, uid, current.project_id.id, {
|
||||
'active': True,
|
||||
'date_start':current.date_start,
|
||||
'date': current.date,
|
||||
})
|
||||
event_obj.write(cr, uid, [event.id], {'project_id': duplicate_project_id })
|
||||
|
||||
|
||||
return {}
|
||||
|
||||
|
||||
event_project()
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Retro-Planning">
|
||||
<field name="project_id" />
|
||||
<field name="project_id" colspan="4"/>
|
||||
<field name="date_start"/>
|
||||
<field name="date"/>
|
||||
<separator string="" colspan="4"/>
|
||||
<group colspan="4" col="6">
|
||||
<button icon="gtk-close" special="cancel" string="Close"/>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<field name="model">email.server</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="POP/IMAP Servers">
|
||||
<tree colors="blue:state in ('draft');black:state in ('wating');gray:state in('done')" string="POP/IMAP Servers">
|
||||
<field name="name" select="1"/>
|
||||
<field name="type" select="1"/>
|
||||
<field name="user" select="1"/>
|
||||
|
|
|
@ -7,30 +7,30 @@ msgstr ""
|
|||
"Project-Id-Version: OpenERP Server 5.0.0\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
|
||||
"PO-Revision-Date: 2009-09-08 16:42+0000\n"
|
||||
"Last-Translator: Donatas Stonys TeraxIT <donatelonow@hotmail.com>\n"
|
||||
"PO-Revision-Date: 2010-07-20 20:31+0000\n"
|
||||
"Last-Translator: Giedrius Slavinskas <giedrius.slavinskas@gmail.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: 2010-06-22 03:53+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-07-21 03:42+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: google_map
|
||||
#: model:ir.actions.wizard,name:google_map.wizard_google_map
|
||||
msgid "Launch Google Map"
|
||||
msgstr ""
|
||||
msgstr "Paleisti Google Žemėlapį"
|
||||
|
||||
#. module: google_map
|
||||
#: constraint:ir.ui.view:0
|
||||
msgid "Invalid XML for View Architecture!"
|
||||
msgstr ""
|
||||
msgstr "Netinkamas XML peržiūros architektūrai!"
|
||||
|
||||
#. module: google_map
|
||||
#: view:res.partner:0
|
||||
#: view:res.partner.address:0
|
||||
msgid "Street2 : "
|
||||
msgstr ""
|
||||
msgstr "Gatvė (2): "
|
||||
|
||||
#. module: google_map
|
||||
#: model:ir.module.module,description:google_map.module_meta_information
|
||||
|
@ -39,9 +39,12 @@ msgid ""
|
|||
"so that we can directly open google map from the\n"
|
||||
"url widget."
|
||||
msgstr ""
|
||||
"Šis modulis įtraukia Google žemėlapio laukelį partnerio \n"
|
||||
"adrese, todėl galime tiesiogiai atidaryti Google \n"
|
||||
"žemėlapį sekdami nuoroda (URL)."
|
||||
|
||||
#. module: google_map
|
||||
#: view:res.partner:0
|
||||
#: view:res.partner.address:0
|
||||
msgid "Map"
|
||||
msgstr ""
|
||||
msgstr "Žemėlapis"
|
||||
|
|
|
@ -7,13 +7,13 @@ msgstr ""
|
|||
"Project-Id-Version: OpenERP Server 5.0.6\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
|
||||
"PO-Revision-Date: 2010-03-20 08:22+0000\n"
|
||||
"PO-Revision-Date: 2010-07-20 09:04+0000\n"
|
||||
"Last-Translator: Black Jack <onetimespeed@hotmail.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: 2010-06-22 03:53+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-07-21 03:42+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: google_map
|
||||
|
@ -24,7 +24,7 @@ msgstr "启动Google地图"
|
|||
#. module: google_map
|
||||
#: constraint:ir.ui.view:0
|
||||
msgid "Invalid XML for View Architecture!"
|
||||
msgstr "无效XML视图结构!"
|
||||
msgstr "无效的视图结构xml文件!"
|
||||
|
||||
#. module: google_map
|
||||
#: view:res.partner:0
|
||||
|
@ -38,7 +38,9 @@ msgid ""
|
|||
"The module adds google map field in partner address\n"
|
||||
"so that we can directly open google map from the\n"
|
||||
"url widget."
|
||||
msgstr "这模块增加google地图到业务伙伴地址你能在google地图直接打开网址"
|
||||
msgstr ""
|
||||
"该模块在业务伙伴字段新增谷歌地图\n"
|
||||
"使我们可以从这URL直接打开谷歌地图"
|
||||
|
||||
#. module: google_map
|
||||
#: view:res.partner:0
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
<field name="res_model">hr.department</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="search_view_id" ref="view_department_filter"/>
|
||||
<field name="help">Your Company's Departments Structure is used to manage all documents related to employees by departments: expenses and timesheet validation, leaves management, recruitements, etc.</field>
|
||||
</record>
|
||||
|
||||
<menuitem action="open_module_tree_department" id="menu_department_def" parent="hr.menu_department_tree"/>
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
<field name="hr_contract"/>
|
||||
<field name="hr_evaluation"/>
|
||||
<field name="hr_attendance"/>
|
||||
<field name="hr_payroll"/>
|
||||
<field name="hr_payroll_account"/>
|
||||
</group>
|
||||
<xpath expr="//button[@string='Install Modules']" position="attributes">
|
||||
<attribute name="string">Configure</attribute>
|
||||
|
|
|
@ -147,6 +147,7 @@
|
|||
<field name="domain">[]</field>
|
||||
<field name="view_id" ref="view_employee_tree"/>
|
||||
<field name="search_view_id" ref="view_employee_filter"/>
|
||||
<field name="help">The employee directory contains all data related to your employees: from their photo up to their hourly estimated costs for the timesheets. Employees are managed by departments and can be linked to users to manage their access rights.</field>
|
||||
</record>
|
||||
|
||||
<menuitem action="open_view_employee_list_my" id="menu_open_view_employee_list_my" sequence="3" parent="menu_hr_main"/>
|
||||
|
@ -386,6 +387,7 @@
|
|||
<field name="res_model">hr.job</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help">Job Positions are used to define the jobs, the requirements. You can attach a survey to a job position. This survey will be used in the recruitement process to evaluate the applicants for this job position.</field>
|
||||
</record>
|
||||
|
||||
<menuitem name="Recruitment" id="base.menu_crm_case_job_req_main" parent="menu_hr_root"/>
|
||||
|
|
|
@ -7,13 +7,13 @@ msgstr ""
|
|||
"Project-Id-Version: OpenERP Server 5.0.6\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
|
||||
"PO-Revision-Date: 2010-03-20 08:23+0000\n"
|
||||
"PO-Revision-Date: 2010-07-20 09:26+0000\n"
|
||||
"Last-Translator: Black Jack <onetimespeed@hotmail.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: 2010-06-22 04:15+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-07-21 03:43+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: hr
|
||||
|
@ -57,7 +57,7 @@ msgstr "上级"
|
|||
#. module: hr
|
||||
#: constraint:ir.actions.act_window:0
|
||||
msgid "Invalid model name in the action definition."
|
||||
msgstr "在这动作定义中有无效的模块名"
|
||||
msgstr "在动作定义中使用了无效的模快名。"
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.department:0
|
||||
|
@ -72,7 +72,7 @@ msgstr "员工分类"
|
|||
#. module: hr
|
||||
#: field:hr.employee,work_email:0
|
||||
msgid "Work Email"
|
||||
msgstr "工作电子邮件"
|
||||
msgstr "工作Email"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.timesheet.group,name:0
|
||||
|
@ -136,12 +136,12 @@ msgstr "工作时间分类"
|
|||
#: model:ir.actions.act_window,name:hr.open_view_employee_tree
|
||||
#: model:ir.ui.menu,name:hr.menu_open_view_employee_tree
|
||||
msgid "Employees Structure"
|
||||
msgstr "员工组织结构"
|
||||
msgstr "员工架构"
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Social IDs"
|
||||
msgstr "身份ID"
|
||||
msgstr "社保ID"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,work_phone:0
|
||||
|
@ -151,7 +151,7 @@ msgstr "办公电话"
|
|||
#. module: hr
|
||||
#: field:hr.employee.category,child_ids:0
|
||||
msgid "Child Categories"
|
||||
msgstr "子类别"
|
||||
msgstr "子类"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,work_location:0
|
||||
|
@ -179,7 +179,7 @@ msgstr "下属"
|
|||
#. module: hr
|
||||
#: model:ir.ui.menu,name:hr.menu_hr_reporting
|
||||
msgid "Reporting"
|
||||
msgstr "内部报表"
|
||||
msgstr "报表"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.department,member_ids:0
|
||||
|
@ -199,7 +199,7 @@ msgstr "填写联系信息"
|
|||
#. module: hr
|
||||
#: constraint:ir.ui.view:0
|
||||
msgid "Invalid XML for View Architecture!"
|
||||
msgstr "无效XML视图结构!"
|
||||
msgstr "无效的视图结构xml文件!"
|
||||
|
||||
#. module: hr
|
||||
#: selection:hr.employee,marital:0
|
||||
|
@ -209,7 +209,7 @@ msgstr "离婚"
|
|||
#. module: hr
|
||||
#: field:hr.employee.category,parent_id:0
|
||||
msgid "Parent Category"
|
||||
msgstr "上级类别"
|
||||
msgstr "上级分类"
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,name:hr.open_module_tree_department
|
||||
|
@ -222,7 +222,7 @@ msgstr "部门"
|
|||
#. module: hr
|
||||
#: model:process.node,name:hr.process_node_employeecontact0
|
||||
msgid "Employee Contact"
|
||||
msgstr "员工联系"
|
||||
msgstr "员工联系方式"
|
||||
|
||||
#. module: hr
|
||||
#: selection:hr.employee,marital:0
|
||||
|
@ -232,7 +232,7 @@ msgstr "已婚"
|
|||
#. module: hr
|
||||
#: field:hr.timesheet,tgroup_id:0
|
||||
msgid "Employee's timesheet group"
|
||||
msgstr "员工工作时间表组"
|
||||
msgstr "员工工作时间表"
|
||||
|
||||
#. module: hr
|
||||
#: selection:hr.employee,gender:0
|
||||
|
@ -248,7 +248,7 @@ msgstr "创建系统用户"
|
|||
#: view:hr.employee.category:0
|
||||
#: model:ir.model,name:hr.model_hr_employee_category
|
||||
msgid "Employee Category"
|
||||
msgstr "员工类型"
|
||||
msgstr "员工类别"
|
||||
|
||||
#. module: hr
|
||||
#: selection:hr.timesheet,dayofweek:0
|
||||
|
@ -258,7 +258,7 @@ msgstr "二"
|
|||
#. module: hr
|
||||
#: model:ir.model,name:hr.model_hr_department
|
||||
msgid "hr.department"
|
||||
msgstr "人力资源"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,user_id:0
|
||||
|
@ -310,12 +310,12 @@ msgstr "出生日期"
|
|||
#. module: hr
|
||||
#: field:hr.employee,active:0
|
||||
msgid "Active"
|
||||
msgstr "在职"
|
||||
msgstr "有效"
|
||||
|
||||
#. module: hr
|
||||
#: constraint:hr.employee:0
|
||||
msgid "Error ! You cannot create recursive Hierarchy of Employees."
|
||||
msgstr "错误!你不能创建递归的员工"
|
||||
msgstr "错误:你不能创建递归的员工"
|
||||
|
||||
#. module: hr
|
||||
#: model:process.process,name:hr.process_process_employeecontractprocess0
|
||||
|
@ -356,7 +356,7 @@ msgstr "开始日期"
|
|||
#. module: hr
|
||||
#: field:res.users,parent_id:0
|
||||
msgid "Parent Users"
|
||||
msgstr "用用户"
|
||||
msgstr "上级用户"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,address_id:0
|
||||
|
@ -382,7 +382,7 @@ msgstr "个人信息"
|
|||
#: constraint:ir.model:0
|
||||
msgid ""
|
||||
"The Object name must start with x_ and not contain any special character !"
|
||||
msgstr "对象名必须要以X_开头并且不能含有特殊字符!"
|
||||
msgstr "对象名称必须以“x_”开头且不能包含任何特殊字符!"
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.timesheet:0
|
||||
|
@ -404,7 +404,7 @@ msgstr "工作到"
|
|||
#. module: hr
|
||||
#: selection:hr.employee,marital:0
|
||||
msgid "Other"
|
||||
msgstr "其他"
|
||||
msgstr "其它"
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee.category:0
|
||||
|
@ -434,7 +434,7 @@ msgstr "其它ID"
|
|||
#. module: hr
|
||||
#: field:hr.timesheet,name:0
|
||||
msgid "Name"
|
||||
msgstr "姓名"
|
||||
msgstr "名称"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,gender:0
|
||||
|
@ -461,7 +461,7 @@ msgstr "子部门"
|
|||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Job Information"
|
||||
msgstr "职位信息"
|
||||
msgstr "工作信息"
|
||||
|
||||
#. module: hr
|
||||
#: model:process.node,note:hr.process_node_employeecontact0
|
||||
|
@ -472,7 +472,7 @@ msgstr "填写员工联系信息"
|
|||
#: field:hr.department,manager_id:0
|
||||
#: field:hr.employee,parent_id:0
|
||||
msgid "Manager"
|
||||
msgstr "上司"
|
||||
msgstr "主管"
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,name:hr.open_view_employee_list_my
|
||||
|
|
|
@ -46,6 +46,10 @@ class hr_installer(osv.osv_memory):
|
|||
"performance review of employees."),
|
||||
'hr_attendance': fields.boolean('Attendances (Sign In/Out)',
|
||||
help="Simplifies the management of employee attendances."),
|
||||
'hr_payroll': fields.boolean('Payroll' ,
|
||||
help="Generic Payroll system"),
|
||||
'hr_payroll_account': fields.boolean('Payroll with Accounting',
|
||||
help="Generic Payroll system Integrated with Accountings."),
|
||||
}
|
||||
_defaults = {
|
||||
'hr_holidays': True,
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
<field name="view_mode">tree,form</field>
|
||||
<field name="context">{"search_default_employee":1}</field>
|
||||
<field name="search_view_id" ref="view_hr_attendance_filter" />
|
||||
<field name="help">Time Tracking functionality aims to manage employee's attendances on the basis of the actions (Sign in/Sign out) performed by them. You can also link this to an attndance machine using OpenERP's webservices features.</field>
|
||||
</record>
|
||||
|
||||
<!--<menuitem id="menu_hr_attendance" name="Attendances" parent="hr.menu_hr_root"
|
||||
|
|
|
@ -7,13 +7,13 @@ msgstr ""
|
|||
"Project-Id-Version: OpenERP Server 5.0.6\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
|
||||
"PO-Revision-Date: 2010-03-20 08:23+0000\n"
|
||||
"PO-Revision-Date: 2010-07-20 10:01+0000\n"
|
||||
"Last-Translator: Black Jack <onetimespeed@hotmail.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: 2010-06-22 04:17+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-07-21 03:43+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: hr_attendance
|
||||
|
@ -35,7 +35,7 @@ msgstr "对象名必须要以X_开头并且不能含有特殊字符!"
|
|||
#: model:ir.actions.wizard,name:hr_attendance.si_so
|
||||
#: model:ir.ui.menu,name:hr_attendance.menu_si_so
|
||||
msgid "Sign in / Sign out"
|
||||
msgstr "签出"
|
||||
msgstr "签入/ 签出"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: rml:report.hr.timesheet.attendance.error:0
|
||||
|
@ -51,12 +51,12 @@ msgstr "员工出勤"
|
|||
#. module: hr_attendance
|
||||
#: constraint:ir.ui.view:0
|
||||
msgid "Invalid XML for View Architecture!"
|
||||
msgstr "无效XML视图结构!"
|
||||
msgstr "无效的视图结构xml文件!"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: wizard_view:hr.si_so,init:0
|
||||
msgid "You are now ready to sign in or out of the attendance follow up"
|
||||
msgstr "你现在出勤跟踪准备签入/签出"
|
||||
msgstr "你现在准备签入或签出"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: selection:hr.action.reason,action_type:0
|
||||
|
@ -68,14 +68,14 @@ msgstr "签出"
|
|||
#. module: hr_attendance
|
||||
#: rml:report.hr.timesheet.attendance.error:0
|
||||
msgid "Delay"
|
||||
msgstr "延迟"
|
||||
msgstr "推延"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: wizard_field:hr.si_so,init,name:0
|
||||
#: wizard_field:hr.si_so,si_ask_so,name:0
|
||||
#: wizard_field:hr.si_so,so_ask_si,name:0
|
||||
msgid "Employee's name"
|
||||
msgstr "员工名"
|
||||
msgstr "员工姓名"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: wizard_button:hr.attendance.print_month,init,print:0
|
||||
|
@ -86,12 +86,12 @@ msgstr "打印时间表"
|
|||
#. module: hr_attendance
|
||||
#: model:ir.actions.wizard,name:hr_attendance.wizard_attendance_error
|
||||
msgid "Print Attendance Error Report"
|
||||
msgstr "出勤错误报表"
|
||||
msgstr "打印出勤错误报表"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: constraint:ir.actions.act_window:0
|
||||
msgid "Invalid model name in the action definition."
|
||||
msgstr "在这动作定义中有无效的模块名"
|
||||
msgstr "在动作定义中使用了无效的模快名。"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: model:ir.actions.wizard,name:hr_attendance.print_week
|
||||
|
@ -107,7 +107,7 @@ msgstr "员工"
|
|||
#: wizard_view:hr.attendance.print_week,init:0
|
||||
#: wizard_view:hr.attendance.report,init:0
|
||||
msgid "Select a time span"
|
||||
msgstr "选择一时间长度"
|
||||
msgstr "选择时间长度"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: rml:report.hr.timesheet.attendance.error:0
|
||||
|
@ -129,22 +129,22 @@ msgstr "总周期:"
|
|||
#: field:hr.attendance,action_desc:0
|
||||
#: model:ir.model,name:hr_attendance.model_hr_action_reason
|
||||
msgid "Action reason"
|
||||
msgstr "行动理由"
|
||||
msgstr "动作理由"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: selection:hr.attendance.print_month,init,month:0
|
||||
msgid "March"
|
||||
msgstr "三月"
|
||||
msgstr "3月"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: selection:hr.attendance.print_month,init,month:0
|
||||
msgid "August"
|
||||
msgstr "八月"
|
||||
msgstr "8月"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: selection:hr.attendance.print_month,init,month:0
|
||||
msgid "May"
|
||||
msgstr "五月"
|
||||
msgstr "5月"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: wizard_field:hr.si_so,so_ask_si,last_time:0
|
||||
|
@ -154,7 +154,7 @@ msgstr "你最近的签入"
|
|||
#. module: hr_attendance
|
||||
#: selection:hr.attendance.print_month,init,month:0
|
||||
msgid "June"
|
||||
msgstr "六月"
|
||||
msgstr "6月"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: model:ir.actions.wizard,name:hr_attendance.print_month
|
||||
|
@ -180,7 +180,7 @@ msgstr "原因"
|
|||
#. module: hr_attendance
|
||||
#: constraint:hr.attendance:0
|
||||
msgid "Error: Sign in (resp. Sign out) must follow Sign out (resp. Sign in)"
|
||||
msgstr "错误签入前先签出同样签出前先签入"
|
||||
msgstr "错误: 签入前先签出同样签出前先签入"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: rml:report.hr.timesheet.attendance.error:0
|
||||
|
@ -195,14 +195,14 @@ msgstr "日期"
|
|||
#. module: hr_attendance
|
||||
#: selection:hr.attendance.print_month,init,month:0
|
||||
msgid "July"
|
||||
msgstr "七月"
|
||||
msgstr "7月"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: wizard_view:hr.si_so,si_ask_so:0
|
||||
msgid ""
|
||||
"You did not signed out the last time. Please enter the date and time you "
|
||||
"signed out."
|
||||
msgstr "最近没有签到请输入签到的日期和时间"
|
||||
msgstr "你最近没有签出的最后时间, 请输入签出的日期和时间"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: view:hr.action.reason:0
|
||||
|
@ -228,12 +228,12 @@ msgstr "缺勤"
|
|||
#. module: hr_attendance
|
||||
#: selection:hr.attendance.print_month,init,month:0
|
||||
msgid "February"
|
||||
msgstr "二月"
|
||||
msgstr "2月"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: selection:hr.attendance.print_month,init,month:0
|
||||
msgid "October"
|
||||
msgstr "十月"
|
||||
msgstr "10月"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: wizard_field:hr.si_so,si_ask_so,last_time:0
|
||||
|
@ -243,17 +243,17 @@ msgstr "你最近的签出"
|
|||
#. module: hr_attendance
|
||||
#: rml:report.hr.timesheet.attendance.error:0
|
||||
msgid "Min Delay"
|
||||
msgstr "主要延迟"
|
||||
msgstr "主要推延"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: field:hr.action.reason,action_type:0
|
||||
msgid "Action's type"
|
||||
msgstr "行动;类型"
|
||||
msgstr "动作类型"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: view:hr.action.reason:0
|
||||
msgid "Define attendance reason"
|
||||
msgstr "出勤原因"
|
||||
msgstr "定义出勤原因"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: selection:hr.action.reason,action_type:0
|
||||
|
@ -275,12 +275,12 @@ msgstr "当前状态"
|
|||
#. module: hr_attendance
|
||||
#: selection:hr.attendance.print_month,init,month:0
|
||||
msgid "January"
|
||||
msgstr "一月"
|
||||
msgstr "1月"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: selection:hr.attendance.print_month,init,month:0
|
||||
msgid "April"
|
||||
msgstr "四月"
|
||||
msgstr "4月"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: model:ir.actions.act_window,name:hr_attendance.open_view_attendance
|
||||
|
@ -298,12 +298,12 @@ msgstr "出勤错误"
|
|||
#: field:hr.attendance,action:0
|
||||
#: selection:hr.attendance,action:0
|
||||
msgid "Action"
|
||||
msgstr "行动"
|
||||
msgstr "动作"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: wizard_button:hr.attendance.report,init,print:0
|
||||
msgid "Print Attendance Report"
|
||||
msgstr "出勤报表"
|
||||
msgstr "打印出勤报表"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: model:ir.actions.act_window,name:hr_attendance.open_view_attendance_reason
|
||||
|
@ -314,17 +314,17 @@ msgstr "出勤原因"
|
|||
#. module: hr_attendance
|
||||
#: selection:hr.attendance.print_month,init,month:0
|
||||
msgid "November"
|
||||
msgstr "十一月"
|
||||
msgstr "11月"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: wizard_view:hr.attendance.report,init:0
|
||||
msgid "Bellow this delay, the error is considered to be voluntary"
|
||||
msgstr "延迟错误被认为是自动的"
|
||||
msgstr "Bellow这种推延, 这错误被认为是自愿的"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: wizard_field:hr.attendance.report,init,max_delay:0
|
||||
msgid "Max. Delay (Min)"
|
||||
msgstr "最大延迟(最小)"
|
||||
msgstr "最大推延(最小)"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: wizard_view:hr.attendance.print_week,init:0
|
||||
|
@ -342,17 +342,17 @@ msgstr "结束日期"
|
|||
msgid ""
|
||||
"You did not signed in the last time. Please enter the date and time you "
|
||||
"signed in."
|
||||
msgstr "你在最近没有签到请输入签到的日期和时间"
|
||||
msgstr "你没有签入的最后时间, 请输入签入的日期和时间"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: selection:hr.attendance.print_month,init,month:0
|
||||
msgid "September"
|
||||
msgstr "九月"
|
||||
msgstr "9月"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: selection:hr.attendance.print_month,init,month:0
|
||||
msgid "December"
|
||||
msgstr "十二月"
|
||||
msgstr "12月"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: view:hr.attendance:0
|
||||
|
@ -367,7 +367,7 @@ msgstr "选择月份"
|
|||
#. module: hr_attendance
|
||||
#: wizard_field:hr.attendance.print_month,init,month:0
|
||||
msgid "Month"
|
||||
msgstr "月"
|
||||
msgstr "月份"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: model:ir.module.module,description:hr_attendance.module_meta_information
|
||||
|
@ -382,7 +382,7 @@ msgstr "出勤错误报表"
|
|||
#. module: hr_attendance
|
||||
#: wizard_field:hr.attendance.print_month,init,year:0
|
||||
msgid "Year"
|
||||
msgstr "年"
|
||||
msgstr "年份"
|
||||
|
||||
#. module: hr_attendance
|
||||
#: wizard_button:hr.attendance.print_month,init,end:0
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="view_hr_attendance_sigh_in_out"/>
|
||||
<field name="target">new</field>
|
||||
<field name="help">Sign in / Sign out. In some companies, staff have to sign in when they arrive at work and sign out again at the end of the day. If each employee has been linked to a system user, then they can encode their time with this action button.</field>
|
||||
</record>
|
||||
|
||||
<menuitem action="action_hr_attendance_sigh_in_out" id="menu_hr_attendance_sigh_in_out"
|
||||
|
|
|
@ -7,19 +7,19 @@ msgstr ""
|
|||
"Project-Id-Version: OpenERP Server 5.0.6\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2009-08-28 16:01+0000\n"
|
||||
"PO-Revision-Date: 2010-03-20 08:26+0000\n"
|
||||
"PO-Revision-Date: 2010-07-20 10:15+0000\n"
|
||||
"Last-Translator: Black Jack <onetimespeed@hotmail.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: 2010-06-22 04:13+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-07-21 03:43+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: hr_contract
|
||||
#: view:hr.contract.wage.type:0
|
||||
msgid "Hourly cost computation"
|
||||
msgstr "小时数成本计算"
|
||||
msgstr "每小时成本计算"
|
||||
|
||||
#. module: hr_contract
|
||||
#: selection:hr.contract.wage.type,type:0
|
||||
|
@ -46,7 +46,7 @@ msgstr "下级数"
|
|||
#. module: hr_contract
|
||||
#: field:hr.contract.wage.type,factor_type:0
|
||||
msgid "Factor for hour cost"
|
||||
msgstr "小时成本系数"
|
||||
msgstr "每小时成本系数"
|
||||
|
||||
#. module: hr_contract
|
||||
#: view:hr.contract.wage.type:0
|
||||
|
@ -56,7 +56,7 @@ msgstr "工资类型"
|
|||
#. module: hr_contract
|
||||
#: constraint:ir.actions.act_window:0
|
||||
msgid "Invalid model name in the action definition."
|
||||
msgstr "在这动作定义中有无效的模块名"
|
||||
msgstr "在动作定义使用了无效的模块名。"
|
||||
|
||||
#. module: hr_contract
|
||||
#: field:hr.contract,employee_id:0
|
||||
|
@ -66,7 +66,7 @@ msgstr "员工"
|
|||
#. module: hr_contract
|
||||
#: selection:hr.contract.wage.type,type:0
|
||||
msgid "Net"
|
||||
msgstr "净"
|
||||
msgstr "净值"
|
||||
|
||||
#. module: hr_contract
|
||||
#: model:ir.module.module,shortdesc:hr_contract.module_meta_information
|
||||
|
@ -81,7 +81,7 @@ msgstr "周期的小时数"
|
|||
#. module: hr_contract
|
||||
#: field:hr.contract,function:0
|
||||
msgid "Function"
|
||||
msgstr "功能"
|
||||
msgstr "职能"
|
||||
|
||||
#. module: hr_contract
|
||||
#: field:hr.employee,marital_status:0
|
||||
|
@ -95,7 +95,7 @@ msgstr "婚姻状况"
|
|||
#. module: hr_contract
|
||||
#: view:hr.employee:0
|
||||
msgid "Miscelleanous"
|
||||
msgstr "其他"
|
||||
msgstr "杂项"
|
||||
|
||||
#. module: hr_contract
|
||||
#: view:hr.contract:0
|
||||
|
@ -119,7 +119,7 @@ msgstr "工资类型"
|
|||
#. module: hr_contract
|
||||
#: field:hr.contract.wage.type.period,name:0
|
||||
msgid "Period Name"
|
||||
msgstr "周期名"
|
||||
msgstr "周期名称"
|
||||
|
||||
#. module: hr_contract
|
||||
#: model:ir.model,name:hr_contract.model_hr_employee_marital_status
|
||||
|
@ -154,7 +154,7 @@ msgstr "结束日期"
|
|||
#. module: hr_contract
|
||||
#: constraint:ir.ui.view:0
|
||||
msgid "Invalid XML for View Architecture!"
|
||||
msgstr "无效XML视图结构!"
|
||||
msgstr "无效的视图结构xml文件!"
|
||||
|
||||
#. module: hr_contract
|
||||
#: view:hr.contract:0
|
||||
|
@ -213,7 +213,7 @@ msgstr "出生地"
|
|||
#. module: hr_contract
|
||||
#: field:hr.employee,manager:0
|
||||
msgid "Manager"
|
||||
msgstr "管理"
|
||||
msgstr "经理"
|
||||
|
||||
#. module: hr_contract
|
||||
#: view:hr.contract.wage.type.period:0
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue